bb-browser 0.8.2 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +4 -138
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../packages/cli/src/index.ts","../packages/cli/src/cdp-client.ts","../packages/cli/src/cdp-discovery.ts","../packages/cli/src/client.ts","../packages/cli/src/daemon-manager.ts","../packages/cli/src/history-sqlite.ts","../packages/cli/src/commands/site.ts","../packages/cli/src/commands/open.ts","../packages/cli/src/commands/snapshot.ts","../packages/cli/src/commands/click.ts","../packages/cli/src/commands/hover.ts","../packages/cli/src/commands/fill.ts","../packages/cli/src/commands/type.ts","../packages/cli/src/commands/close.ts","../packages/cli/src/commands/get.ts","../packages/cli/src/commands/screenshot.ts","../packages/cli/src/commands/wait.ts","../packages/cli/src/commands/press.ts","../packages/cli/src/commands/scroll.ts","../packages/cli/src/commands/daemon.ts","../packages/cli/src/commands/reload.ts","../packages/cli/src/commands/nav.ts","../packages/cli/src/commands/check.ts","../packages/cli/src/commands/select.ts","../packages/cli/src/commands/eval.ts","../packages/cli/src/commands/tab.ts","../packages/cli/src/commands/frame.ts","../packages/cli/src/commands/dialog.ts","../packages/cli/src/commands/network.ts","../packages/cli/src/commands/console.ts","../packages/cli/src/commands/errors.ts","../packages/cli/src/commands/trace.ts","../packages/cli/src/commands/fetch.ts","../packages/cli/src/commands/history.ts"],"sourcesContent":["/**\n * bb-browser CLI 入口\n */\n\nimport { fileURLToPath } from \"node:url\";\nimport { openCommand } from \"./commands/open.js\";\nimport { snapshotCommand } from \"./commands/snapshot.js\";\nimport { clickCommand } from \"./commands/click.js\";\nimport { hoverCommand } from \"./commands/hover.js\";\nimport { fillCommand } from \"./commands/fill.js\";\nimport { typeCommand } from \"./commands/type.js\";\nimport { closeCommand } from \"./commands/close.js\";\nimport { getCommand, type GetAttribute } from \"./commands/get.js\";\nimport { screenshotCommand } from \"./commands/screenshot.js\";\nimport { waitCommand } from \"./commands/wait.js\";\nimport { pressCommand } from \"./commands/press.js\";\nimport { scrollCommand } from \"./commands/scroll.js\";\nimport { statusCommand } from \"./commands/daemon.js\";\nimport { reloadCommand } from \"./commands/reload.js\";\nimport { backCommand, forwardCommand, refreshCommand } from \"./commands/nav.js\";\nimport { checkCommand, uncheckCommand } from \"./commands/check.js\";\nimport { selectCommand } from \"./commands/select.js\";\nimport { evalCommand } from \"./commands/eval.js\";\nimport { tabCommand } from \"./commands/tab.js\";\nimport { frameCommand, frameMainCommand } from \"./commands/frame.js\";\nimport { dialogCommand } from \"./commands/dialog.js\";\nimport { networkCommand } from \"./commands/network.js\";\nimport { consoleCommand } from \"./commands/console.js\";\nimport { errorsCommand } from \"./commands/errors.js\";\nimport { traceCommand } from \"./commands/trace.js\";\nimport { fetchCommand } from \"./commands/fetch.js\";\nimport { siteCommand } from \"./commands/site.js\";\nimport { historyCommand } from \"./commands/history.js\";\nimport { setJqExpression } from \"./client.js\";\n\nconst VERSION = \"0.8.2\";\n\nconst HELP_TEXT = `\nbb-browser - AI Agent 浏览器自动化工具\n\n安装:\n npm install -g bb-browser\n\n提示:大多数数据获取任务请直接使用 site 命令,无需手动操作浏览器:\n bb-browser site list 查看所有可用命令\n bb-browser site twitter/search \"AI\" 示例:搜索推文\n bb-browser site xueqiu/hot-stock 5 示例:获取人气股票\n\n用法:\n bb-browser <command> [options]\n\n开始使用:\n site recommend 推荐你可能需要的 adapter(基于浏览历史)\n site list 列出所有 adapter\n site info <name> 查看 adapter 用法(参数、返回值、示例)\n site <name> [args] 运行 adapter\n site update 更新社区 adapter 库\n guide 如何把任何网站变成 adapter\n star ⭐ Star bb-browser on GitHub\n\n浏览器操作:\n open <url> [--tab] 打开 URL\n snapshot [-i] [-c] [-d <n>] 获取页面快照\n click <ref> 点击元素\n hover <ref> 悬停元素\n fill <ref> <text> 填充输入框(清空后填入)\n type <ref> <text> 逐字符输入(不清空)\n check/uncheck <ref> 勾选/取消复选框\n select <ref> <val> 下拉框选择\n press <key> 发送按键\n scroll <dir> [px] 滚动页面\n\n页面信息:\n get text|url|title <ref> 获取页面内容\n screenshot [path] 截图\n eval \"<js>\" 执行 JavaScript\n fetch <url> 带登录态的 HTTP 请求\n\n标签页:\n tab [list|new|close|<n>] 管理标签页\n status 查看受管浏览器状态\n\n导航:\n back / forward / refresh 后退 / 前进 / 刷新\n\n调试:\n network requests [filter] 查看网络请求\n console [--clear] 查看/清空控制台\n errors [--clear] 查看/清空 JS 错误\n trace start|stop|status 录制用户操作\n history search|domains 查看浏览历史\n\n选项:\n --json 以 JSON 格式输出\n --port <n> 指定 Chrome CDP 端口\n --openclaw 优先复用 OpenClaw 浏览器实例\n --jq <expr> 对 JSON 输出应用 jq 过滤(直接作用于数据,跳过 id/success 信封)\n -i, --interactive 只输出可交互元素(snapshot 命令)\n -c, --compact 移除空结构节点(snapshot 命令)\n -d, --depth <n> 限制树深度(snapshot 命令)\n -s, --selector <sel> 限定 CSS 选择器范围(snapshot 命令)\n --tab <tabId> 指定操作的标签页 ID\n --mcp 启动 MCP server(用于 Claude Code / Cursor 等 AI 工具)\n --help, -h 显示帮助信息\n --version, -v 显示版本号\n`.trim();\n\ninterface ParsedArgs {\n command: string | null;\n args: string[];\n flags: {\n json: boolean;\n help: boolean;\n version: boolean;\n interactive: boolean;\n compact: boolean;\n depth?: number;\n selector?: string;\n tab?: string;\n days?: number;\n jq?: string;\n openclaw?: boolean;\n port?: number;\n };\n}\n\n/**\n * 解析命令行参数\n */\nfunction parseArgs(argv: string[]): ParsedArgs {\n const args = argv.slice(2); // 跳过 node 和脚本路径\n\n const result: ParsedArgs = {\n command: null,\n args: [],\n flags: {\n json: false,\n help: false,\n version: false,\n interactive: false,\n compact: false,\n },\n };\n\n let skipNext = false;\n for (const arg of args) {\n if (skipNext) {\n skipNext = false;\n continue;\n }\n if (arg === \"--json\") {\n result.flags.json = true;\n } else if (arg === \"--jq\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.jq = args[nextIdx];\n result.flags.json = true;\n }\n } else if (arg === \"--openclaw\") {\n result.flags.openclaw = true;\n } else if (arg === \"--port\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.port = parseInt(args[nextIdx], 10);\n }\n } else if (arg === \"--help\" || arg === \"-h\") {\n result.flags.help = true;\n } else if (arg === \"--version\" || arg === \"-v\") {\n result.flags.version = true;\n } else if (arg === \"--interactive\" || arg === \"-i\") {\n result.flags.interactive = true;\n } else if (arg === \"--compact\" || arg === \"-c\") {\n result.flags.compact = true;\n } else if (arg === \"--depth\" || arg === \"-d\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.depth = parseInt(args[nextIdx], 10);\n }\n } else if (arg === \"--selector\" || arg === \"-s\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.selector = args[nextIdx];\n }\n } else if (arg === \"--days\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.days = parseInt(args[nextIdx], 10);\n }\n } else if (arg === \"--id\") {\n // --id 及其值由子命令通过 process.argv 自行解析,这里跳过\n skipNext = true;\n } else if (arg === \"--tab\") {\n // --tab 参数及其值,无论出现在命令前后都跳过\n skipNext = true;\n } else if (arg.startsWith(\"-\")) {\n // 未知选项,忽略\n } else if (result.command === null) {\n result.command = arg;\n } else {\n result.args.push(arg);\n }\n }\n\n return result;\n}\n\n/**\n * 主函数\n */\nasync function main(): Promise<void> {\n const parsed = parseArgs(process.argv);\n setJqExpression(parsed.flags.jq);\n\n // 解析全局 --tab 参数\n const tabArgIdx = process.argv.indexOf('--tab');\n const globalTabId = tabArgIdx >= 0 && process.argv[tabArgIdx + 1]\n ? parseInt(process.argv[tabArgIdx + 1], 10)\n : undefined;\n\n // 处理全局选项\n if (parsed.flags.version) {\n console.log(VERSION);\n return;\n }\n\n if (process.argv.includes(\"--mcp\")) {\n const mcpPath = fileURLToPath(new URL(\"./mcp.js\", import.meta.url));\n const { spawn } = await import(\"node:child_process\");\n const child = spawn(process.execPath, [mcpPath], { stdio: \"inherit\" });\n child.on(\"exit\", (code) => process.exit(code ?? 0));\n return;\n }\n\n if (parsed.flags.help || !parsed.command) {\n console.log(HELP_TEXT);\n return;\n }\n\n // 路由到对应命令\n try {\n switch (parsed.command) {\n case \"open\": {\n const url = parsed.args[0];\n if (!url) {\n console.error(\"错误:缺少 URL 参数\");\n console.error(\"用法:bb-browser open <url> [--tab current|<tabId>]\");\n process.exit(1);\n }\n // 解析 --tab 参数\n const tabIndex = process.argv.findIndex(a => a === \"--tab\");\n const tab = tabIndex >= 0 ? process.argv[tabIndex + 1] : undefined;\n await openCommand(url, { json: parsed.flags.json, tab });\n break;\n }\n\n case \"snapshot\": {\n await snapshotCommand({\n json: parsed.flags.json,\n interactive: parsed.flags.interactive,\n compact: parsed.flags.compact,\n maxDepth: parsed.flags.depth,\n selector: parsed.flags.selector,\n tabId: globalTabId,\n });\n break;\n }\n\n case \"click\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser click <ref>\");\n console.error(\"示例:bb-browser click @5\");\n process.exit(1);\n }\n await clickCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"hover\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser hover <ref>\");\n console.error(\"示例:bb-browser hover @5\");\n process.exit(1);\n }\n await hoverCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"check\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser check <ref>\");\n console.error(\"示例:bb-browser check @5\");\n process.exit(1);\n }\n await checkCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"uncheck\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser uncheck <ref>\");\n console.error(\"示例:bb-browser uncheck @5\");\n process.exit(1);\n }\n await uncheckCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"fill\": {\n const ref = parsed.args[0];\n const text = parsed.args[1];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser fill <ref> <text>\");\n console.error('示例:bb-browser fill @3 \"hello world\"');\n process.exit(1);\n }\n if (text === undefined) {\n console.error(\"错误:缺少 text 参数\");\n console.error(\"用法:bb-browser fill <ref> <text>\");\n console.error('示例:bb-browser fill @3 \"hello world\"');\n process.exit(1);\n }\n await fillCommand(ref, text, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"type\": {\n const ref = parsed.args[0];\n const text = parsed.args[1];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser type <ref> <text>\");\n console.error('示例:bb-browser type @3 \"append text\"');\n process.exit(1);\n }\n if (text === undefined) {\n console.error(\"错误:缺少 text 参数\");\n console.error(\"用法:bb-browser type <ref> <text>\");\n console.error('示例:bb-browser type @3 \"append text\"');\n process.exit(1);\n }\n await typeCommand(ref, text, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"select\": {\n const ref = parsed.args[0];\n const value = parsed.args[1];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser select <ref> <value>\");\n console.error('示例:bb-browser select @4 \"option1\"');\n process.exit(1);\n }\n if (value === undefined) {\n console.error(\"错误:缺少 value 参数\");\n console.error(\"用法:bb-browser select <ref> <value>\");\n console.error('示例:bb-browser select @4 \"option1\"');\n process.exit(1);\n }\n await selectCommand(ref, value, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"eval\": {\n const script = parsed.args[0];\n if (!script) {\n console.error(\"错误:缺少 script 参数\");\n console.error(\"用法:bb-browser eval <script>\");\n console.error('示例:bb-browser eval \"document.title\"');\n process.exit(1);\n }\n await evalCommand(script, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"get\": {\n const attribute = parsed.args[0] as GetAttribute | undefined;\n if (!attribute) {\n console.error(\"错误:缺少属性参数\");\n console.error(\"用法:bb-browser get <text|url|title> [ref]\");\n console.error(\"示例:bb-browser get text @5\");\n console.error(\" bb-browser get url\");\n process.exit(1);\n }\n if (![\"text\", \"url\", \"title\"].includes(attribute)) {\n console.error(`错误:未知属性 \"${attribute}\"`);\n console.error(\"支持的属性:text, url, title\");\n process.exit(1);\n }\n const ref = parsed.args[1];\n await getCommand(attribute, ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"daemon\":\n case \"start\": {\n const hostIdx = process.argv.findIndex(a => a === \"--host\");\n const host = hostIdx >= 0 ? process.argv[hostIdx + 1] : undefined;\n await daemonCommand({ json: parsed.flags.json, host });\n break;\n }\n\n case \"stop\": {\n await stopCommand({ json: parsed.flags.json });\n break;\n }\n\n case \"status\": {\n await statusCommand({ json: parsed.flags.json });\n break;\n }\n\n case \"reload\": {\n await reloadCommand({ json: parsed.flags.json });\n break;\n }\n\n case \"close\": {\n await closeCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"back\": {\n await backCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"forward\": {\n await forwardCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"refresh\": {\n await refreshCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"screenshot\": {\n const outputPath = parsed.args[0];\n await screenshotCommand(outputPath, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"wait\": {\n const target = parsed.args[0];\n if (!target) {\n console.error(\"错误:缺少等待目标参数\");\n console.error(\"用法:bb-browser wait <ms|@ref>\");\n console.error(\"示例:bb-browser wait 2000\");\n console.error(\" bb-browser wait @5\");\n process.exit(1);\n }\n await waitCommand(target, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"press\": {\n const key = parsed.args[0];\n if (!key) {\n console.error(\"错误:缺少 key 参数\");\n console.error(\"用法:bb-browser press <key>\");\n console.error(\"示例:bb-browser press Enter\");\n console.error(\" bb-browser press Control+a\");\n process.exit(1);\n }\n await pressCommand(key, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"scroll\": {\n const direction = parsed.args[0];\n const pixels = parsed.args[1]; // 传 string,scrollCommand 内部解析\n if (!direction) {\n console.error(\"错误:缺少方向参数\");\n console.error(\"用法:bb-browser scroll <up|down|left|right> [pixels]\");\n console.error(\"示例:bb-browser scroll down\");\n console.error(\" bb-browser scroll up 500\");\n process.exit(1);\n }\n await scrollCommand(direction, pixels, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"tab\": {\n await tabCommand(parsed.args, { json: parsed.flags.json });\n break;\n }\n\n case \"frame\": {\n const selectorOrMain = parsed.args[0];\n if (!selectorOrMain) {\n console.error(\"错误:缺少 selector 参数\");\n console.error(\"用法:bb-browser frame <selector>\");\n console.error('示例:bb-browser frame \"iframe#editor\"');\n console.error(\" bb-browser frame main\");\n process.exit(1);\n }\n if (selectorOrMain === \"main\") {\n await frameMainCommand({ json: parsed.flags.json, tabId: globalTabId });\n } else {\n await frameCommand(selectorOrMain, { json: parsed.flags.json, tabId: globalTabId });\n }\n break;\n }\n\n case \"dialog\": {\n const subCommand = parsed.args[0];\n if (!subCommand) {\n console.error(\"错误:缺少子命令\");\n console.error(\"用法:bb-browser dialog <accept|dismiss> [text]\");\n console.error(\"示例:bb-browser dialog accept\");\n console.error(' bb-browser dialog accept \"my input\"');\n console.error(\" bb-browser dialog dismiss\");\n process.exit(1);\n }\n const promptText = parsed.args[1]; // accept 时可选的 prompt 文本\n await dialogCommand(subCommand, promptText, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"network\": {\n const subCommand = parsed.args[0] || \"requests\";\n const urlOrFilter = parsed.args[1];\n // 解析 network 特有的选项\n const abort = process.argv.includes(\"--abort\");\n const withBody = process.argv.includes(\"--with-body\");\n const bodyIndex = process.argv.findIndex(a => a === \"--body\");\n const body = bodyIndex >= 0 ? process.argv[bodyIndex + 1] : undefined;\n await networkCommand(subCommand, urlOrFilter, { json: parsed.flags.json, abort, body, withBody, tabId: globalTabId });\n break;\n }\n\n case \"console\": {\n const clear = process.argv.includes(\"--clear\");\n await consoleCommand({ json: parsed.flags.json, clear, tabId: globalTabId });\n break;\n }\n\n case \"errors\": {\n const clear = process.argv.includes(\"--clear\");\n await errorsCommand({ json: parsed.flags.json, clear, tabId: globalTabId });\n break;\n }\n\n case \"trace\": {\n const subCmd = parsed.args[0] as 'start' | 'stop' | 'status' | undefined;\n if (!subCmd || !['start', 'stop', 'status'].includes(subCmd)) {\n console.error(\"错误:缺少或无效的子命令\");\n console.error(\"用法:bb-browser trace <start|stop|status>\");\n console.error(\"示例:bb-browser trace start\");\n console.error(\" bb-browser trace stop\");\n console.error(\" bb-browser trace status\");\n process.exit(1);\n }\n await traceCommand(subCmd, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"history\": {\n const subCmd = parsed.args[0] as 'search' | 'domains' | undefined;\n if (!subCmd || !['search', 'domains'].includes(subCmd)) {\n console.error(\"错误:缺少或无效的子命令\");\n console.error(\"用法:bb-browser history <search|domains> [query] [--days <n>]\");\n console.error(\"示例:bb-browser history search github\");\n console.error(\" bb-browser history domains --days 7\");\n process.exit(1);\n }\n const query = parsed.args.slice(1).join(' ');\n await historyCommand(subCmd, {\n json: parsed.flags.json,\n days: parsed.flags.days || 30,\n query,\n });\n break;\n }\n\n case \"fetch\": {\n const fetchUrl = parsed.args[0];\n if (!fetchUrl) {\n console.error(\"[error] fetch: <url> is required.\");\n console.error(\" Usage: bb-browser fetch <url> [--json] [--method POST] [--body '{...}']\");\n console.error(\" Example: bb-browser fetch https://www.reddit.com/api/me.json --json\");\n process.exit(1);\n }\n // 解析 fetch 特有选项\n const methodIdx = process.argv.findIndex(a => a === \"--method\");\n const fetchMethod = methodIdx >= 0 ? process.argv[methodIdx + 1] : undefined;\n const fetchBodyIdx = process.argv.findIndex(a => a === \"--body\");\n const fetchBody = fetchBodyIdx >= 0 ? process.argv[fetchBodyIdx + 1] : undefined;\n const headersIdx = process.argv.findIndex(a => a === \"--headers\");\n const fetchHeaders = headersIdx >= 0 ? process.argv[headersIdx + 1] : undefined;\n const outputIdx = process.argv.findIndex(a => a === \"--output\");\n const fetchOutput = outputIdx >= 0 ? process.argv[outputIdx + 1] : undefined;\n await fetchCommand(fetchUrl, {\n json: parsed.flags.json,\n method: fetchMethod,\n body: fetchBody,\n headers: fetchHeaders,\n output: fetchOutput,\n tabId: globalTabId,\n });\n break;\n }\n\n case \"site\": {\n await siteCommand(parsed.args, {\n json: parsed.flags.json,\n jq: parsed.flags.jq,\n days: parsed.flags.days,\n tabId: globalTabId,\n openclaw: parsed.flags.openclaw,\n });\n break;\n }\n\n case \"star\": {\n const { execSync } = await import(\"node:child_process\");\n try {\n execSync(\"gh auth status\", { stdio: \"pipe\" });\n } catch {\n console.error(\"需要先安装并登录 GitHub CLI: https://cli.github.com\");\n console.error(\" brew install gh && gh auth login\");\n process.exit(1);\n }\n const repos = [\"epiral/bb-browser\", \"epiral/bb-sites\"];\n for (const repo of repos) {\n try {\n execSync(`gh api user/starred/${repo} -X PUT`, { stdio: \"pipe\" });\n console.log(`⭐ Starred ${repo}`);\n } catch {\n console.log(`Already starred or failed: ${repo}`);\n }\n }\n console.log(\"\\nThanks for your support! 🙏\");\n break;\n }\n\n case \"guide\": {\n console.log(`How to turn any website into a bb-browser site adapter\n=======================================================\n\n1. REVERSE ENGINEER the API\n bb-browser network clear --tab <tabId>\n bb-browser refresh --tab <tabId>\n bb-browser network requests --filter \"api\" --with-body --json --tab <tabId>\n\n2. TEST if direct fetch works (Tier 1)\n bb-browser eval \"fetch('/api/endpoint',{credentials:'include'}).then(r=>r.json())\" --tab <tabId>\n\n If it works → Tier 1 (Cookie auth, like Reddit/GitHub/Zhihu/Bilibili)\n If needs extra headers → Tier 2 (like Twitter: Bearer + CSRF token)\n If needs request signing → Tier 3 (like Xiaohongshu: Pinia store actions)\n\n3. WRITE the adapter (one JS file per operation)\n\n /* @meta\n {\n \"name\": \"platform/command\",\n \"description\": \"What it does\",\n \"domain\": \"www.example.com\",\n \"args\": { \"query\": {\"required\": true, \"description\": \"Search query\"} },\n \"readOnly\": true,\n \"example\": \"bb-browser site platform/command value\"\n }\n */\n async function(args) {\n if (!args.query) return {error: 'Missing argument: query'};\n const resp = await fetch('/api/search?q=' + encodeURIComponent(args.query), {credentials: 'include'});\n if (!resp.ok) return {error: 'HTTP ' + resp.status, hint: 'Not logged in?'};\n return await resp.json();\n }\n\n4. TEST it\n Save to ~/.bb-browser/sites/platform/command.js (private, takes priority)\n bb-browser site platform/command \"test query\" --json\n\n5. CONTRIBUTE\n Option A (with gh CLI):\n git clone https://github.com/epiral/bb-sites && cd bb-sites\n git checkout -b feat-platform\n # add adapter files\n git push -u origin feat-platform\n gh pr create --repo epiral/bb-sites\n\n Option B (without gh CLI, using bb-browser itself):\n bb-browser site github/fork epiral/bb-sites\n git clone https://github.com/YOUR_USER/bb-sites && cd bb-sites\n git checkout -b feat-platform\n # add adapter files\n git push -u origin feat-platform\n bb-browser site github/pr-create epiral/bb-sites --title \"feat(platform): add adapters\" --head \"YOUR_USER:feat-platform\"\n\nPrivate adapters: ~/.bb-browser/sites/<platform>/<command>.js\nCommunity: ~/.bb-browser/bb-sites/ (via bb-browser site update)\nFull guide: https://github.com/epiral/bb-sites/blob/main/SKILL.md`);\n break;\n }\n\n default: {\n console.error(`错误:未知命令 \"${parsed.command}\"`);\n console.error(\"运行 bb-browser --help 查看可用命令\");\n process.exit(1);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n if (parsed.flags.json) {\n console.log(\n JSON.stringify({\n success: false,\n error: message,\n })\n );\n } else {\n console.error(`错误:${message}`);\n }\n\n process.exit(1);\n }\n}\n\nmain().then(() => process.exit(0));\n","import { readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { request as httpRequest } from \"node:http\";\nimport { request as httpsRequest } from \"node:https\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport WebSocket from \"ws\";\nimport type { Request, Response, ResponseData, TabInfo, SnapshotData, RefInfo, NetworkRequestInfo, ConsoleMessageInfo, JSErrorInfo, TraceEvent, TraceStatus } from \"@bb-browser/shared\";\nimport { COMMAND_TIMEOUT } from \"@bb-browser/shared\";\nimport { discoverCdpPort } from \"./cdp-discovery.js\";\n\ninterface CdpTargetInfo {\n id: string;\n type: string;\n title: string;\n url: string;\n webSocketDebuggerUrl?: string;\n}\n\ntype JsonObject = Record<string, unknown>;\n\ninterface PendingCommand {\n resolve: (value: unknown) => void;\n reject: (reason?: unknown) => void;\n method: string;\n}\n\ninterface RawDomTextNode {\n type: \"TEXT_NODE\";\n text: string;\n isVisible: boolean;\n}\n\ninterface RawDomElementNode {\n tagName: string;\n xpath: string | null;\n attributes: Record<string, string>;\n children: string[];\n isVisible?: boolean;\n isInteractive?: boolean;\n isTopElement?: boolean;\n isInViewport?: boolean;\n highlightIndex?: number;\n shadowRoot?: boolean;\n}\n\ntype RawDomTreeNode = RawDomTextNode | RawDomElementNode;\n\ninterface BuildDomTreeResult {\n rootId: string;\n map: Record<string, RawDomTreeNode>;\n}\n\ninterface DialogHandlerConfig {\n accept: boolean;\n promptText?: string;\n}\n\ninterface ConnectionState {\n host: string;\n port: number;\n browserWsUrl: string;\n browserSocket: WebSocket;\n browserPending: Map<number, PendingCommand>;\n nextMessageId: number;\n sessions: Map<string, string>;\n attachedTargets: Map<string, string>;\n refsByTarget: Map<string, Record<string, RefInfo>>;\n currentTargetId?: string;\n activeFrameIdByTarget: Map<string, string | null>;\n dialogHandlers: Map<string, DialogHandlerConfig>;\n}\n\nlet connectionState: ConnectionState | null = null;\nlet reconnecting: Promise<void> | null = null;\n\nconst networkRequests = new Map<string, NetworkRequestInfo>();\nlet networkEnabled = false;\n\nconst consoleMessages: ConsoleMessageInfo[] = [];\nlet consoleEnabled = false;\n\nconst jsErrors: JSErrorInfo[] = [];\nlet errorsEnabled = false;\n\nlet traceRecording = false;\nconst traceEvents: TraceEvent[] = [];\n\nfunction buildRequestError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction fetchJson(url: string): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const requester = url.startsWith(\"https:\") ? httpsRequest : httpRequest;\n const req = requester(url, { method: \"GET\" }, (res) => {\n const chunks: Buffer[] = [];\n res.on(\"data\", (chunk) => chunks.push(Buffer.from(chunk)));\n res.on(\"end\", () => {\n const raw = Buffer.concat(chunks).toString(\"utf8\");\n if ((res.statusCode ?? 500) >= 400) {\n reject(new Error(`HTTP ${(res.statusCode ?? 500)}: ${raw}`));\n return;\n }\n try {\n resolve(JSON.parse(raw));\n } catch (error) {\n reject(error);\n }\n });\n });\n req.on(\"error\", reject);\n req.end();\n });\n}\n\nasync function getJsonList(host: string, port: number): Promise<CdpTargetInfo[]> {\n const data = await fetchJson(`http://${host}:${port}/json/list`);\n return Array.isArray(data) ? (data as CdpTargetInfo[]) : [];\n}\n\nasync function getJsonVersion(host: string, port: number): Promise<{ webSocketDebuggerUrl: string }> {\n const data = await fetchJson(`http://${host}:${port}/json/version`) as JsonObject;\n const url = data.webSocketDebuggerUrl;\n if (typeof url !== \"string\" || !url) {\n throw new Error(\"CDP endpoint missing webSocketDebuggerUrl\");\n }\n return { webSocketDebuggerUrl: url };\n}\n\nfunction connectWebSocket(url: string): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(url);\n ws.once(\"open\", () => {\n // Allow Node.js to exit even if the WebSocket is still open\n const socket = (ws as any)._socket;\n if (socket && typeof socket.unref === \"function\") {\n socket.unref();\n }\n resolve(ws);\n });\n ws.once(\"error\", reject);\n });\n}\n\nfunction createState(host: string, port: number, browserWsUrl: string, browserSocket: WebSocket): ConnectionState {\n const state: ConnectionState = {\n host,\n port,\n browserWsUrl,\n browserSocket,\n browserPending: new Map(),\n nextMessageId: 1,\n sessions: new Map(),\n attachedTargets: new Map(),\n refsByTarget: new Map(),\n activeFrameIdByTarget: new Map(),\n dialogHandlers: new Map(),\n };\n\n browserSocket.on(\"message\", (raw) => {\n const message = JSON.parse(raw.toString()) as JsonObject;\n if (typeof message.id === \"number\") {\n const pending = state.browserPending.get(message.id);\n if (!pending) return;\n state.browserPending.delete(message.id);\n if (message.error) {\n pending.reject(new Error(`${pending.method}: ${(message.error as JsonObject).message ?? \"Unknown CDP error\"}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n if (message.method === \"Target.attachedToTarget\") {\n const params = message.params as JsonObject;\n const sessionId = params.sessionId;\n const targetInfo = params.targetInfo as JsonObject;\n if (typeof sessionId === \"string\" && typeof targetInfo?.targetId === \"string\") {\n state.sessions.set(targetInfo.targetId, sessionId);\n state.attachedTargets.set(sessionId, targetInfo.targetId);\n }\n return;\n }\n\n if (message.method === \"Target.detachedFromTarget\") {\n const params = message.params as JsonObject;\n const sessionId = params.sessionId;\n if (typeof sessionId === \"string\") {\n const targetId = state.attachedTargets.get(sessionId);\n if (targetId) {\n state.sessions.delete(targetId);\n state.attachedTargets.delete(sessionId);\n state.activeFrameIdByTarget.delete(targetId);\n state.dialogHandlers.delete(targetId);\n }\n }\n return;\n }\n\n if (message.method === \"Target.receivedMessageFromTarget\") {\n // Legacy non-flat protocol\n const params = message.params as JsonObject;\n const sessionId = params.sessionId;\n const messageText = params.message;\n if (typeof sessionId === \"string\" && typeof messageText === \"string\") {\n const targetId = state.attachedTargets.get(sessionId);\n if (targetId) {\n handleSessionEvent(targetId, JSON.parse(messageText) as JsonObject).catch(() => {});\n }\n }\n return;\n }\n\n // Flat protocol: session events come with sessionId directly on the message\n if (typeof message.sessionId === \"string\" && typeof message.method === \"string\") {\n const targetId = state.attachedTargets.get(message.sessionId as string);\n if (targetId) {\n handleSessionEvent(targetId, message).catch(() => {});\n }\n }\n });\n\n browserSocket.on(\"close\", () => {\n if (connectionState === state) {\n connectionState = null;\n }\n for (const pending of state.browserPending.values()) {\n pending.reject(new Error(\"CDP connection closed\"));\n }\n state.browserPending.clear();\n });\n\n browserSocket.on(\"error\", () => {});\n\n return state;\n}\n\nasync function browserCommand<T>(method: string, params: JsonObject = {}): Promise<T> {\n const state = connectionState;\n if (!state) throw new Error(\"CDP connection not initialized\");\n const id = state.nextMessageId++;\n const payload = JSON.stringify({ id, method, params });\n const promise = new Promise<T>((resolve, reject) => {\n state.browserPending.set(id, { resolve, reject, method });\n });\n state.browserSocket.send(payload);\n return promise;\n}\n\nasync function sessionCommand<T>(targetId: string, method: string, params: JsonObject = {}): Promise<T> {\n const state = connectionState;\n if (!state) throw new Error(\"CDP connection not initialized\");\n const sessionId = state.sessions.get(targetId) ?? await attachTarget(targetId);\n const id = state.nextMessageId++;\n // Flat protocol: send with sessionId directly on the message\n const payload = JSON.stringify({ id, method, params, sessionId });\n return new Promise<T>((resolve, reject) => {\n const check = (raw: WebSocket.RawData) => {\n const msg = JSON.parse(raw.toString()) as JsonObject;\n // Flat protocol responses come back with the same sessionId\n if (msg.id === id && msg.sessionId === sessionId) {\n state.browserSocket.off(\"message\", check);\n if (msg.error) reject(new Error(`${method}: ${(msg.error as JsonObject).message ?? \"Unknown CDP error\"}`));\n else resolve(msg.result as T);\n }\n };\n state.browserSocket.on(\"message\", check);\n state.browserSocket.send(payload);\n });\n}\n\n\nfunction getActiveFrameId(targetId: string): string | undefined {\n const frameId = connectionState?.activeFrameIdByTarget.get(targetId);\n return frameId ?? undefined;\n}\n\nasync function pageCommand<T>(targetId: string, method: string, params: JsonObject = {}): Promise<T> {\n const frameId = getActiveFrameId(targetId);\n return sessionCommand<T>(targetId, method, frameId ? { ...params, frameId } : params);\n}\n\nfunction normalizeHeaders(headers: unknown): Record<string, string> | undefined {\n if (!headers || typeof headers !== \"object\") return undefined;\n return Object.fromEntries(Object.entries(headers as Record<string, unknown>).map(([key, value]) => [key, String(value)]));\n}\n\nasync function handleSessionEvent(targetId: string, event: JsonObject): Promise<void> {\n const method = event.method;\n const params = (event.params ?? {}) as JsonObject;\n if (typeof method !== \"string\") return;\n\n if (method === \"Page.javascriptDialogOpening\") {\n const handler = connectionState?.dialogHandlers.get(targetId);\n if (handler) {\n await sessionCommand(targetId, \"Page.handleJavaScriptDialog\", {\n accept: handler.accept,\n ...(handler.promptText !== undefined ? { promptText: handler.promptText } : {}),\n });\n }\n return;\n }\n\n if (method === \"Network.requestWillBeSent\") {\n const requestId = typeof params.requestId === \"string\" ? params.requestId : undefined;\n const request = params.request as JsonObject | undefined;\n if (!requestId || !request) return;\n networkRequests.set(requestId, {\n requestId,\n url: String(request.url ?? \"\"),\n method: String(request.method ?? \"GET\"),\n type: String(params.type ?? \"Other\"),\n timestamp: Math.round(Number(params.timestamp ?? Date.now()) * 1000),\n requestHeaders: normalizeHeaders(request.headers),\n requestBody: typeof request.postData === \"string\" ? request.postData : undefined,\n });\n return;\n }\n\n if (method === \"Network.responseReceived\") {\n const requestId = typeof params.requestId === \"string\" ? params.requestId : undefined;\n const response = params.response as JsonObject | undefined;\n if (!requestId || !response) return;\n const existing = networkRequests.get(requestId);\n if (!existing) return;\n existing.status = typeof response.status === \"number\" ? response.status : undefined;\n existing.statusText = typeof response.statusText === \"string\" ? response.statusText : undefined;\n existing.responseHeaders = normalizeHeaders(response.headers);\n existing.mimeType = typeof response.mimeType === \"string\" ? response.mimeType : undefined;\n networkRequests.set(requestId, existing);\n return;\n }\n\n if (method === \"Network.loadingFailed\") {\n const requestId = typeof params.requestId === \"string\" ? params.requestId : undefined;\n if (!requestId) return;\n const existing = networkRequests.get(requestId);\n if (!existing) return;\n existing.failed = true;\n existing.failureReason = typeof params.errorText === \"string\" ? params.errorText : \"Unknown error\";\n networkRequests.set(requestId, existing);\n return;\n }\n\n if (method === \"Runtime.consoleAPICalled\") {\n const type = String(params.type ?? \"log\");\n const args = Array.isArray(params.args) ? params.args as JsonObject[] : [];\n const text = args.map((arg) => {\n if (typeof arg.value === \"string\") return arg.value;\n if (arg.value !== undefined) return String(arg.value);\n if (typeof arg.description === \"string\") return arg.description;\n return \"\";\n }).filter(Boolean).join(\" \");\n const stack = params.stackTrace as JsonObject | undefined;\n const firstCallFrame = Array.isArray(stack?.callFrames) ? stack?.callFrames[0] as JsonObject | undefined : undefined;\n consoleMessages.push({\n type: [\"log\", \"info\", \"warn\", \"error\", \"debug\"].includes(type) ? type as ConsoleMessageInfo[\"type\"] : \"log\",\n text,\n timestamp: Math.round(Number(params.timestamp ?? Date.now())),\n url: typeof firstCallFrame?.url === \"string\" ? firstCallFrame.url : undefined,\n lineNumber: typeof firstCallFrame?.lineNumber === \"number\" ? firstCallFrame.lineNumber : undefined,\n });\n return;\n }\n\n if (method === \"Runtime.exceptionThrown\") {\n const details = params.exceptionDetails as JsonObject | undefined;\n if (!details) return;\n const exception = details.exception as JsonObject | undefined;\n const stackTrace = details.stackTrace as JsonObject | undefined;\n const callFrames = Array.isArray(stackTrace?.callFrames) ? stackTrace.callFrames as JsonObject[] : [];\n jsErrors.push({\n message: typeof exception?.description === \"string\" ? exception.description : String(details.text ?? \"JavaScript exception\"),\n url: typeof details.url === \"string\" ? details.url : (typeof callFrames[0]?.url === \"string\" ? String(callFrames[0].url) : undefined),\n lineNumber: typeof details.lineNumber === \"number\" ? details.lineNumber : undefined,\n columnNumber: typeof details.columnNumber === \"number\" ? details.columnNumber : undefined,\n stackTrace: callFrames.length > 0 ? callFrames.map((frame) => `${String(frame.functionName ?? \"<anonymous>\")} (${String(frame.url ?? \"\")}:${String(frame.lineNumber ?? 0)}:${String(frame.columnNumber ?? 0)})`).join(\"\\n\") : undefined,\n timestamp: Date.now(),\n });\n }\n}\n\nasync function ensureNetworkMonitoring(targetId: string): Promise<void> {\n if (networkEnabled) return;\n await sessionCommand(targetId, \"Network.enable\");\n networkEnabled = true;\n}\n\nasync function ensureConsoleMonitoring(targetId: string): Promise<void> {\n if (consoleEnabled && errorsEnabled) return;\n await sessionCommand(targetId, \"Runtime.enable\");\n consoleEnabled = true;\n errorsEnabled = true;\n}\n\nasync function attachTarget(targetId: string): Promise<string> {\n const result = await browserCommand<{ sessionId: string }>(\"Target.attachToTarget\", {\n targetId,\n flatten: true,\n });\n connectionState?.sessions.set(targetId, result.sessionId);\n connectionState?.attachedTargets.set(result.sessionId, targetId);\n connectionState?.activeFrameIdByTarget.set(targetId, connectionState?.activeFrameIdByTarget.get(targetId) ?? null);\n await sessionCommand(targetId, \"Page.enable\");\n await sessionCommand(targetId, \"Runtime.enable\");\n await sessionCommand(targetId, \"DOM.enable\");\n await sessionCommand(targetId, \"Accessibility.enable\");\n return result.sessionId;\n}\n\nasync function getTargets(): Promise<CdpTargetInfo[]> {\n const state = connectionState;\n if (!state) throw new Error(\"CDP connection not initialized\");\n try {\n const result = await browserCommand<{ targetInfos: Array<{ targetId: string; type: string; title: string; url: string }> }>(\"Target.getTargets\");\n return (result.targetInfos || []).map((target) => ({\n id: target.targetId,\n type: target.type,\n title: target.title,\n url: target.url,\n webSocketDebuggerUrl: \"\",\n }));\n } catch {\n return getJsonList(state.host, state.port);\n }\n}\n\n\nasync function ensurePageTarget(targetId?: string | number): Promise<CdpTargetInfo> {\n const targets = (await getTargets()).filter((target) => target.type === \"page\");\n if (targets.length === 0) throw new Error(\"No page target found\");\n\n let target: CdpTargetInfo | undefined;\n if (typeof targetId === \"number\") {\n target = targets[targetId] ?? targets.find((item) => Number(item.id) === targetId);\n } else if (typeof targetId === \"string\") {\n target = targets.find((item) => item.id === targetId);\n if (!target) {\n const numericTargetId = Number(targetId);\n if (!Number.isNaN(numericTargetId)) {\n target = targets[numericTargetId] ?? targets.find((item) => Number(item.id) === numericTargetId);\n }\n }\n }\n target ??= targets[0];\n connectionState!.currentTargetId = target.id;\n await attachTarget(target.id);\n return target;\n}\n\nasync function resolveBackendNodeIdByXPath(targetId: string, xpath: string): Promise<number> {\n // Populate the DOM agent's node map — required before performSearch/describeNode\n await sessionCommand(targetId, \"DOM.getDocument\", { depth: 0 });\n\n const search = await sessionCommand<{ searchId: string; resultCount: number }>(targetId, \"DOM.performSearch\", {\n query: xpath,\n includeUserAgentShadowDOM: true,\n });\n\n try {\n if (!search.resultCount) {\n throw new Error(`Unknown ref xpath: ${xpath}`);\n }\n\n const { nodeIds } = await sessionCommand<{ nodeIds: number[] }>(targetId, \"DOM.getSearchResults\", {\n searchId: search.searchId,\n fromIndex: 0,\n toIndex: search.resultCount,\n });\n\n for (const nodeId of nodeIds) {\n const described = await sessionCommand<{ node: { backendNodeId?: number; nodeName?: string } }>(targetId, \"DOM.describeNode\", {\n nodeId,\n });\n if (described.node.backendNodeId) {\n return described.node.backendNodeId;\n }\n }\n\n throw new Error(`XPath resolved but no backend node id found: ${xpath}`);\n } finally {\n await sessionCommand(targetId, \"DOM.discardSearchResults\", { searchId: search.searchId }).catch(() => {});\n }\n}\n\nasync function parseRef(ref: string): Promise<number> {\n const targetId = connectionState?.currentTargetId ?? \"\";\n let refs = connectionState?.refsByTarget.get(targetId) ?? {};\n if (!refs[ref] && targetId) {\n const persistedRefs = loadPersistedRefs(targetId);\n if (persistedRefs) {\n connectionState?.refsByTarget.set(targetId, persistedRefs);\n refs = persistedRefs;\n }\n }\n const found = refs[ref];\n if (!found) {\n throw new Error(`Unknown ref: ${ref}. Run snapshot first.`);\n }\n if (found.backendDOMNodeId) {\n return found.backendDOMNodeId;\n }\n if (targetId && found.xpath) {\n const backendDOMNodeId = await resolveBackendNodeIdByXPath(targetId, found.xpath);\n found.backendDOMNodeId = backendDOMNodeId;\n connectionState?.refsByTarget.set(targetId, refs);\n const pageUrl = await evaluate<string>(targetId, \"location.href\", true).catch(() => undefined);\n if (pageUrl) {\n persistRefs(targetId, pageUrl, refs);\n }\n return backendDOMNodeId;\n }\n throw new Error(`Unknown ref: ${ref}. Run snapshot first.`);\n}\n\nfunction getRefsFilePath(targetId: string): string {\n return path.join(os.tmpdir(), `bb-browser-refs-${targetId}.json`);\n}\n\nfunction getCurrentTargetUrl(targetId: string): string | null {\n const state = connectionState;\n if (!state) return null;\n const pages = Array.from(state.sessions.keys());\n void pages;\n return null;\n}\n\nfunction loadPersistedRefs(targetId: string, expectedUrl?: string): Record<string, RefInfo> | null {\n try {\n const data = JSON.parse(readFileSync(getRefsFilePath(targetId), \"utf-8\")) as {\n targetId?: unknown;\n url?: unknown;\n refs?: unknown;\n };\n if (data.targetId !== targetId) return null;\n if (expectedUrl !== undefined && data.url !== expectedUrl) return null;\n if (!data.refs || typeof data.refs !== \"object\") return null;\n return data.refs as Record<string, RefInfo>;\n } catch {\n return null;\n }\n}\n\nfunction persistRefs(targetId: string, url: string, refs: Record<string, RefInfo>): void {\n try {\n writeFileSync(getRefsFilePath(targetId), JSON.stringify({ targetId, url, timestamp: Date.now(), refs }));\n } catch {}\n}\n\nfunction clearPersistedRefs(targetId: string): void {\n try {\n unlinkSync(getRefsFilePath(targetId));\n } catch {}\n}\n\nfunction loadBuildDomTreeScript(): string {\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(currentDir, \"./extension/buildDomTree.js\"),\n // npm installed: dist/cli.js → ../extension/buildDomTree.js\n path.resolve(currentDir, \"../extension/buildDomTree.js\"),\n path.resolve(currentDir, \"../extension/dist/buildDomTree.js\"),\n path.resolve(currentDir, \"../packages/extension/public/buildDomTree.js\"),\n path.resolve(currentDir, \"../packages/extension/dist/buildDomTree.js\"),\n // dev mode: packages/cli/dist/ → ../../../extension/\n path.resolve(currentDir, \"../../../extension/buildDomTree.js\"),\n path.resolve(currentDir, \"../../../extension/dist/buildDomTree.js\"),\n // dev mode: packages/cli/src/ → ../../extension/\n path.resolve(currentDir, \"../../extension/buildDomTree.js\"),\n path.resolve(currentDir, \"../../../packages/extension/dist/buildDomTree.js\"),\n path.resolve(currentDir, \"../../../packages/extension/public/buildDomTree.js\"),\n ];\n for (const candidate of candidates) {\n try {\n return readFileSync(candidate, \"utf8\");\n } catch {\n }\n }\n throw new Error(\"Cannot find buildDomTree.js\");\n}\n\nasync function evaluate<T>(targetId: string, expression: string, returnByValue = true): Promise<T> {\n const result = await sessionCommand<{ result: { value?: T; objectId?: string }; exceptionDetails?: { text?: string } }>(targetId, \"Runtime.evaluate\", {\n expression,\n awaitPromise: true,\n returnByValue,\n });\n if (result.exceptionDetails) {\n throw new Error(result.exceptionDetails.text || \"Runtime.evaluate failed\");\n }\n return (result.result.value ?? result.result) as T;\n}\n\nasync function resolveNode(targetId: string, backendNodeId: number): Promise<number> {\n const result = await sessionCommand<{ nodeId: number }>(targetId, \"DOM.pushNodesByBackendIdsToFrontend\", {\n backendNodeIds: [backendNodeId],\n });\n return result.nodeId;\n}\n\nasync function focusNode(targetId: string, backendNodeId: number): Promise<void> {\n await sessionCommand(targetId, \"DOM.focus\", { backendNodeId });\n}\n\nasync function insertTextIntoNode(targetId: string, backendNodeId: number, text: string, clearFirst: boolean): Promise<void> {\n const resolved = await sessionCommand<{ object: { objectId: string } }>(targetId, \"DOM.resolveNode\", { backendNodeId });\n\n await sessionCommand(targetId, \"Runtime.callFunctionOn\", {\n objectId: resolved.object.objectId,\n functionDeclaration: `function(value, clearFirst) {\n if (typeof this.focus === 'function') this.focus();\n if (clearFirst && ('value' in this)) {\n this.value = '';\n this.dispatchEvent(new Event('input', { bubbles: true }));\n }\n if ('value' in this) {\n this.value = clearFirst ? value : String(this.value ?? '') + value;\n this.dispatchEvent(new Event('input', { bubbles: true }));\n this.dispatchEvent(new Event('change', { bubbles: true }));\n return true;\n }\n return false;\n }`,\n arguments: [\n { value: text },\n { value: clearFirst },\n ],\n returnByValue: true,\n });\n\n await focusNode(targetId, backendNodeId);\n await sessionCommand(targetId, \"Input.insertText\", { text });\n}\n\nasync function getNodeBox(targetId: string, backendNodeId: number): Promise<{ x: number; y: number }> {\n const result = await sessionCommand<{ model: { content: number[]; border: number[] } }>(targetId, \"DOM.getBoxModel\", {\n backendNodeId,\n });\n const quad = result.model.content.length >= 8 ? result.model.content : result.model.border;\n const xs = [quad[0], quad[2], quad[4], quad[6]];\n const ys = [quad[1], quad[3], quad[5], quad[7]];\n return {\n x: xs.reduce((a, b) => a + b, 0) / xs.length,\n y: ys.reduce((a, b) => a + b, 0) / ys.length,\n };\n}\n\nasync function mouseClick(targetId: string, x: number, y: number): Promise<void> {\n await sessionCommand(targetId, \"Input.dispatchMouseEvent\", { type: \"mouseMoved\", x, y, button: \"none\" });\n await sessionCommand(targetId, \"Input.dispatchMouseEvent\", { type: \"mousePressed\", x, y, button: \"left\", clickCount: 1 });\n await sessionCommand(targetId, \"Input.dispatchMouseEvent\", { type: \"mouseReleased\", x, y, button: \"left\", clickCount: 1 });\n}\n\nasync function getAttributeValue(targetId: string, backendNodeId: number, attribute: string): Promise<string> {\n const nodeId = await resolveNode(targetId, backendNodeId);\n if (attribute === \"text\") {\n return evaluate<string>(targetId, `(() => { const n = this; return n.innerText ?? n.textContent ?? ''; }).call(document.querySelector('[data-bb-node-id=\"${nodeId}\"]'))`);\n }\n const result = await sessionCommand<{ object: { objectId: string } }>(targetId, \"DOM.resolveNode\", { backendNodeId });\n const call = await sessionCommand<{ result: { value: string } }>(targetId, \"Runtime.callFunctionOn\", {\n objectId: result.object.objectId,\n functionDeclaration: `function() { if (${JSON.stringify(attribute)} === 'url') return this.href || this.src || location.href; if (${JSON.stringify(attribute)} === 'title') return document.title; return this.getAttribute(${JSON.stringify(attribute)}) || ''; }`,\n returnByValue: true,\n });\n return String(call.result.value ?? \"\");\n}\n\nasync function buildSnapshot(targetId: string, request: Request): Promise<SnapshotData> {\n const script = loadBuildDomTreeScript();\n const buildArgs = {\n showHighlightElements: true,\n focusHighlightIndex: -1,\n viewportExpansion: -1,\n debugMode: false,\n startId: 0,\n startHighlightIndex: 0,\n };\n const expression = `(() => { ${script}; const fn = globalThis.buildDomTree ?? (typeof window !== 'undefined' ? window.buildDomTree : undefined); if (typeof fn !== 'function') { throw new Error('buildDomTree is not available after script injection'); } return fn(${JSON.stringify({\n ...buildArgs,\n })}); })()`;\n const value = await evaluate<BuildDomTreeResult | null>(targetId, expression, true);\n if (!value || !value.map || !value.rootId) {\n const title = await evaluate<string>(targetId, \"document.title\", true);\n const pageUrl = await evaluate<string>(targetId, \"location.href\", true);\n const fallbackSnapshot: SnapshotData = {\n title,\n url: pageUrl,\n lines: [title || pageUrl],\n refs: {},\n };\n connectionState?.refsByTarget.set(targetId, {});\n persistRefs(targetId, pageUrl, {});\n return fallbackSnapshot;\n }\n\n const snapshot = convertBuildDomTreeResult(value, {\n interactiveOnly: !!request.interactive,\n compact: !!request.compact,\n maxDepth: request.maxDepth,\n selector: request.selector,\n });\n const pageUrl = await evaluate<string>(targetId, \"location.href\", true);\n connectionState?.refsByTarget.set(targetId, snapshot.refs || {});\n persistRefs(targetId, pageUrl, snapshot.refs || {});\n return snapshot;\n}\n\nfunction convertBuildDomTreeResult(\n result: BuildDomTreeResult,\n options: { interactiveOnly: boolean; compact: boolean; maxDepth?: number; selector?: string },\n): SnapshotData {\n const { interactiveOnly, compact, maxDepth, selector } = options;\n const { rootId, map } = result;\n const refs: Record<string, RefInfo> = {};\n const lines: string[] = [];\n\n const getRole = (node: RawDomElementNode): string => {\n const tagName = node.tagName.toLowerCase();\n const role = node.attributes?.role;\n if (role) return role;\n const type = node.attributes?.type?.toLowerCase() || \"text\";\n const inputRoleMap: Record<string, string> = {\n text: \"textbox\", password: \"textbox\", email: \"textbox\", url: \"textbox\", tel: \"textbox\",\n search: \"searchbox\", number: \"spinbutton\", range: \"slider\", checkbox: \"checkbox\",\n radio: \"radio\", button: \"button\", submit: \"button\", reset: \"button\", file: \"button\",\n };\n const roleMap: Record<string, string> = {\n a: \"link\", button: \"button\", input: inputRoleMap[type] || \"textbox\", select: \"combobox\",\n textarea: \"textbox\", img: \"image\", nav: \"navigation\", main: \"main\", header: \"banner\",\n footer: \"contentinfo\", aside: \"complementary\", form: \"form\", table: \"table\", ul: \"list\",\n ol: \"list\", li: \"listitem\", h1: \"heading\", h2: \"heading\", h3: \"heading\", h4: \"heading\",\n h5: \"heading\", h6: \"heading\", dialog: \"dialog\", article: \"article\", section: \"region\",\n label: \"label\", details: \"group\", summary: \"button\",\n };\n return roleMap[tagName] || tagName;\n };\n\n const collectTextContent = (node: RawDomElementNode, nodeMap: Record<string, RawDomTreeNode>, depthLimit = 5): string => {\n const texts: string[] = [];\n const visit = (nodeId: string, depth: number): void => {\n if (depth > depthLimit) return;\n const currentNode = nodeMap[nodeId];\n if (!currentNode) return;\n if (\"type\" in currentNode && currentNode.type === \"TEXT_NODE\") {\n const text = currentNode.text.trim();\n if (text) texts.push(text);\n return;\n }\n for (const childId of (currentNode as RawDomElementNode).children || []) visit(childId, depth + 1);\n };\n for (const childId of node.children || []) visit(childId, 0);\n return texts.join(\" \").trim();\n };\n\n const getName = (node: RawDomElementNode): string | undefined => {\n const attrs = node.attributes || {};\n return attrs[\"aria-label\"] || attrs.title || attrs.placeholder || attrs.alt || attrs.value || collectTextContent(node, map) || attrs.name || undefined;\n };\n\n const truncateText = (text: string, length = 50): string => text.length <= length ? text : `${text.slice(0, length - 3)}...`;\n\n const selectorText = selector?.trim().toLowerCase();\n const matchesSelector = (node: RawDomElementNode, role: string, name?: string): boolean => {\n if (!selectorText) return true;\n const haystack = [node.tagName, role, name, node.xpath || \"\", ...Object.values(node.attributes || {})].join(\" \").toLowerCase();\n return haystack.includes(selectorText);\n };\n\n if (interactiveOnly) {\n const interactiveNodes = Object.entries(map)\n .filter(([, node]) => !(\"type\" in node) && node.highlightIndex !== undefined && node.highlightIndex !== null)\n .map(([id, node]) => ({ id, node: node as RawDomElementNode }))\n .sort((a, b) => (a.node.highlightIndex ?? 0) - (b.node.highlightIndex ?? 0));\n\n for (const { node } of interactiveNodes) {\n const refId = String(node.highlightIndex);\n const role = getRole(node);\n const name = getName(node);\n if (!matchesSelector(node, role, name)) continue;\n let line = `${role} [ref=${refId}]`;\n if (name) line += ` ${JSON.stringify(truncateText(name))}`;\n lines.push(line);\n refs[refId] = {\n xpath: node.xpath || \"\",\n role,\n name,\n tagName: node.tagName.toLowerCase(),\n } as RefInfo;\n }\n\n return { snapshot: lines.join(\"\\n\"), refs };\n }\n\n const walk = (nodeId: string, depth: number): void => {\n if (maxDepth !== undefined && depth > maxDepth) return;\n const node = map[nodeId];\n if (!node) return;\n\n if (\"type\" in node && node.type === \"TEXT_NODE\") {\n const text = node.text.trim();\n if (!text) return;\n lines.push(`${\" \".repeat(depth)}- text ${JSON.stringify(truncateText(text, compact ? 80 : 120))}`);\n return;\n }\n\n const role = getRole(node);\n const name = getName(node);\n if (!matchesSelector(node, role, name)) {\n for (const childId of node.children || []) walk(childId, depth + 1);\n return;\n }\n\n const indent = \" \".repeat(depth);\n const refId = node.highlightIndex !== undefined && node.highlightIndex !== null ? String(node.highlightIndex) : null;\n let line = `${indent}- ${role}`;\n if (refId) line += ` [ref=${refId}]`;\n if (name) line += ` ${JSON.stringify(truncateText(name, compact ? 50 : 80))}`;\n if (!compact) line += ` <${node.tagName.toLowerCase()}>`;\n lines.push(line);\n\n if (refId) {\n refs[refId] = {\n xpath: node.xpath || \"\",\n role,\n name,\n tagName: node.tagName.toLowerCase(),\n } as RefInfo;\n }\n\n for (const childId of node.children || []) walk(childId, depth + 1);\n };\n\n walk(rootId, 0);\n return { snapshot: lines.join(\"\\n\"), refs };\n}\n\nfunction ok(id: string, data?: ResponseData): Response {\n return { id, success: true, data };\n}\n\nfunction fail(id: string, error: unknown): Response {\n return { id, success: false, error: buildRequestError(error).message };\n}\n\nexport async function ensureCdpConnection(): Promise<void> {\n if (connectionState) return;\n if (reconnecting) return reconnecting;\n reconnecting = (async () => {\n const discovered = await discoverCdpPort();\n if (!discovered) {\n throw new Error(\"No browser connection found\");\n }\n const version = await getJsonVersion(discovered.host, discovered.port);\n const wsUrl = version.webSocketDebuggerUrl;\n const socket = await connectWebSocket(wsUrl);\n connectionState = createState(discovered.host, discovered.port, wsUrl, socket);\n })();\n try {\n await reconnecting;\n } finally {\n reconnecting = null;\n }\n}\n\n\nexport async function sendCommand(request: Request): Promise<Response> {\n try {\n await ensureCdpConnection();\n const timeout = new Promise<never>((_, reject) => setTimeout(() => reject(new Error(\"请求超时\")), COMMAND_TIMEOUT));\n return await Promise.race([dispatchRequest(request), timeout]);\n } catch (error) {\n return fail(request.id, error);\n }\n}\n\nasync function dispatchRequest(request: Request): Promise<Response> {\n const target = await ensurePageTarget(request.tabId);\n switch (request.action) {\n case \"open\": {\n if (!request.url) return fail(request.id, \"Missing url parameter\");\n if (request.tabId === undefined) {\n const created = await browserCommand<{ targetId: string }>(\"Target.createTarget\", { url: request.url });\n const newTarget = await ensurePageTarget(created.targetId);\n return ok(request.id, { url: request.url, tabId: newTarget.id });\n }\n await pageCommand(target.id, \"Page.navigate\", { url: request.url });\n connectionState?.refsByTarget.delete(target.id);\n clearPersistedRefs(target.id);\n return ok(request.id, { url: request.url, title: target.title, tabId: target.id });\n }\n case \"snapshot\": {\n const snapshotData = await buildSnapshot(target.id, request);\n return ok(request.id, { title: target.title, url: target.url, snapshotData });\n }\n case \"click\":\n case \"hover\": {\n if (!request.ref) return fail(request.id, \"Missing ref parameter\");\n const backendNodeId = await parseRef(request.ref);\n const point = await getNodeBox(target.id, backendNodeId);\n await sessionCommand(target.id, \"Input.dispatchMouseEvent\", { type: \"mouseMoved\", x: point.x, y: point.y, button: \"none\" });\n if (request.action === \"click\") await mouseClick(target.id, point.x, point.y);\n return ok(request.id, {});\n }\n case \"fill\":\n case \"type\": {\n if (!request.ref) return fail(request.id, \"Missing ref parameter\");\n if (request.text == null) return fail(request.id, \"Missing text parameter\");\n const backendNodeId = await parseRef(request.ref);\n await insertTextIntoNode(target.id, backendNodeId, request.text, request.action === \"fill\");\n return ok(request.id, { value: request.text });\n }\n case \"check\":\n case \"uncheck\": {\n if (!request.ref) return fail(request.id, \"Missing ref parameter\");\n const backendNodeId = await parseRef(request.ref);\n const desired = request.action === \"check\";\n const resolved = await sessionCommand<{ object: { objectId: string } }>(target.id, \"DOM.resolveNode\", { backendNodeId });\n await sessionCommand(target.id, \"Runtime.callFunctionOn\", {\n objectId: resolved.object.objectId,\n functionDeclaration: `function() { this.checked = ${desired}; this.dispatchEvent(new Event('input', { bubbles: true })); this.dispatchEvent(new Event('change', { bubbles: true })); }`,\n });\n return ok(request.id, {});\n }\n case \"select\": {\n if (!request.ref || request.value == null) return fail(request.id, \"Missing ref or value parameter\");\n const backendNodeId = await parseRef(request.ref);\n const resolved = await sessionCommand<{ object: { objectId: string } }>(target.id, \"DOM.resolveNode\", { backendNodeId });\n await sessionCommand(target.id, \"Runtime.callFunctionOn\", {\n objectId: resolved.object.objectId,\n functionDeclaration: `function() { this.value = ${JSON.stringify(request.value)}; this.dispatchEvent(new Event('input', { bubbles: true })); this.dispatchEvent(new Event('change', { bubbles: true })); }`,\n });\n return ok(request.id, { value: request.value });\n }\n case \"get\": {\n if (!request.ref || !request.attribute) return fail(request.id, \"Missing ref or attribute parameter\");\n const value = await getAttributeValue(target.id, await parseRef(request.ref), request.attribute);\n return ok(request.id, { value });\n }\n case \"screenshot\": {\n const result = await sessionCommand<{ data: string }>(target.id, \"Page.captureScreenshot\", { format: \"png\", fromSurface: true });\n return ok(request.id, { dataUrl: `data:image/png;base64,${result.data}` });\n }\n case \"close\": {\n await browserCommand(\"Target.closeTarget\", { targetId: target.id });\n connectionState?.refsByTarget.delete(target.id);\n clearPersistedRefs(target.id);\n return ok(request.id, {});\n }\n case \"wait\": {\n await new Promise((resolve) => setTimeout(resolve, request.ms ?? 1000));\n return ok(request.id, {});\n }\n case \"press\": {\n if (!request.key) return fail(request.id, \"Missing key parameter\");\n await sessionCommand(target.id, \"Input.dispatchKeyEvent\", { type: \"keyDown\", key: request.key });\n if (request.key.length === 1) {\n await sessionCommand(target.id, \"Input.dispatchKeyEvent\", { type: \"char\", text: request.key, key: request.key });\n }\n await sessionCommand(target.id, \"Input.dispatchKeyEvent\", { type: \"keyUp\", key: request.key });\n return ok(request.id, {});\n }\n case \"scroll\": {\n const deltaY = request.direction === \"up\" ? -(request.pixels ?? 300) : (request.pixels ?? 300);\n await sessionCommand(target.id, \"Input.dispatchMouseEvent\", { type: \"mouseWheel\", x: 0, y: 0, deltaX: 0, deltaY });\n return ok(request.id, {});\n }\n case \"back\": {\n await evaluate(target.id, \"history.back(); undefined\");\n return ok(request.id, {});\n }\n case \"forward\": {\n await evaluate(target.id, \"history.forward(); undefined\");\n return ok(request.id, {});\n }\n case \"refresh\": {\n await sessionCommand(target.id, \"Page.reload\", { ignoreCache: false });\n return ok(request.id, {});\n }\n case \"eval\": {\n if (!request.script) return fail(request.id, \"Missing script parameter\");\n const result = await evaluate<unknown>(target.id, request.script, true);\n return ok(request.id, { result });\n }\n case \"tab_list\": {\n const tabs = (await getTargets()).filter((item) => item.type === \"page\").map((item, index): TabInfo => ({ index, url: item.url, title: item.title, active: item.id === connectionState?.currentTargetId || (!connectionState?.currentTargetId && index === 0), tabId: item.id }));\n return ok(request.id, { tabs, activeIndex: tabs.findIndex((tab) => tab.active) });\n }\n case \"tab_new\": {\n const created = await browserCommand<{ targetId: string }>(\"Target.createTarget\", { url: request.url ?? \"about:blank\" });\n return ok(request.id, { tabId: created.targetId, url: request.url ?? \"about:blank\" });\n }\n case \"tab_select\": {\n const tabs = (await getTargets()).filter((item) => item.type === \"page\");\n const selected = request.tabId !== undefined\n ? tabs.find((item) => item.id === String(request.tabId) || Number(item.id) === request.tabId)\n : tabs[request.index ?? 0];\n if (!selected) return fail(request.id, \"Tab not found\");\n connectionState!.currentTargetId = selected.id;\n await attachTarget(selected.id);\n return ok(request.id, { tabId: selected.id, url: selected.url, title: selected.title });\n }\n case \"tab_close\": {\n const tabs = (await getTargets()).filter((item) => item.type === \"page\");\n const selected = request.tabId !== undefined\n ? tabs.find((item) => item.id === String(request.tabId) || Number(item.id) === request.tabId)\n : tabs[request.index ?? 0];\n if (!selected) return fail(request.id, \"Tab not found\");\n await browserCommand(\"Target.closeTarget\", { targetId: selected.id });\n connectionState?.refsByTarget.delete(selected.id);\n clearPersistedRefs(selected.id);\n return ok(request.id, { tabId: selected.id });\n }\n case \"frame\": {\n if (!request.selector) return fail(request.id, \"Missing selector parameter\");\n const document = await pageCommand<{ root: { nodeId: number } }>(target.id, \"DOM.getDocument\", {});\n const node = await pageCommand<{ nodeId: number }>(target.id, \"DOM.querySelector\", { nodeId: document.root.nodeId, selector: request.selector });\n if (!node.nodeId) return fail(request.id, `找不到 iframe: ${request.selector}`);\n const described = await pageCommand<{ node: { frameId?: string; nodeName?: string; attributes?: string[] } }>(target.id, \"DOM.describeNode\", { nodeId: node.nodeId });\n const frameId = described.node.frameId;\n const nodeName = String(described.node.nodeName ?? \"\").toLowerCase();\n if (!frameId) return fail(request.id, `无法获取 iframe frameId: ${request.selector}`);\n if (nodeName && nodeName !== \"iframe\" && nodeName !== \"frame\") return fail(request.id, `元素不是 iframe: ${nodeName}`);\n connectionState?.activeFrameIdByTarget.set(target.id, frameId);\n const attributes = described.node.attributes ?? [];\n const attrMap: Record<string, string> = {};\n for (let i = 0; i < attributes.length; i += 2) attrMap[String(attributes[i])] = String(attributes[i + 1] ?? \"\");\n return ok(request.id, { frameInfo: { selector: request.selector, name: attrMap.name ?? \"\", url: attrMap.src ?? \"\", frameId } });\n }\n case \"frame_main\": {\n connectionState?.activeFrameIdByTarget.set(target.id, null);\n return ok(request.id, { frameInfo: { frameId: 0 } });\n }\n case \"dialog\": {\n connectionState?.dialogHandlers.set(target.id, { accept: request.dialogResponse !== \"dismiss\", ...(request.promptText !== undefined ? { promptText: request.promptText } : {}) });\n await sessionCommand(target.id, \"Page.enable\");\n return ok(request.id, { dialog: { armed: true, response: request.dialogResponse ?? \"accept\" } as ResponseData[keyof ResponseData] });\n }\n case \"network\": {\n const subCommand = request.networkCommand ?? \"requests\";\n switch (subCommand) {\n case \"requests\": {\n await ensureNetworkMonitoring(target.id);\n const requests = Array.from(networkRequests.values()).filter((item) => !request.filter || item.url.includes(request.filter));\n if (request.withBody) {\n await Promise.all(requests.map(async (item) => {\n if (item.failed || item.responseBody !== undefined || item.bodyError !== undefined) return;\n try {\n const body = await sessionCommand<{ body: string; base64Encoded: boolean }>(target.id, \"Network.getResponseBody\", { requestId: item.requestId });\n item.responseBody = body.body;\n item.responseBodyBase64 = body.base64Encoded;\n } catch (error) {\n item.bodyError = error instanceof Error ? error.message : String(error);\n }\n }));\n }\n return ok(request.id, { networkRequests: requests });\n }\n case \"route\":\n return ok(request.id, { routeCount: 0 });\n case \"unroute\":\n return ok(request.id, { routeCount: 0 });\n case \"clear\":\n networkRequests.clear();\n return ok(request.id, {});\n default:\n return fail(request.id, `Unknown network subcommand: ${subCommand}`);\n }\n }\n case \"console\": {\n const subCommand = request.consoleCommand ?? \"get\";\n await ensureConsoleMonitoring(target.id);\n switch (subCommand) {\n case \"get\":\n return ok(request.id, { consoleMessages: consoleMessages.filter((item) => !request.filter || item.text.includes(request.filter)) });\n case \"clear\":\n consoleMessages.length = 0;\n return ok(request.id, {});\n default:\n return fail(request.id, `Unknown console subcommand: ${subCommand}`);\n }\n }\n case \"errors\": {\n const subCommand = request.errorsCommand ?? \"get\";\n await ensureConsoleMonitoring(target.id);\n switch (subCommand) {\n case \"get\":\n return ok(request.id, { jsErrors: jsErrors.filter((item) => !request.filter || item.message.includes(request.filter) || item.url?.includes(request.filter)) });\n case \"clear\":\n jsErrors.length = 0;\n return ok(request.id, {});\n default:\n return fail(request.id, `Unknown errors subcommand: ${subCommand}`);\n }\n }\n case \"trace\": {\n const subCommand = request.traceCommand ?? \"status\";\n switch (subCommand) {\n case \"start\":\n traceRecording = true;\n traceEvents.length = 0;\n return ok(request.id, { traceStatus: { recording: true, eventCount: 0 } satisfies TraceStatus });\n case \"stop\": {\n traceRecording = false;\n return ok(request.id, { traceEvents: [...traceEvents] satisfies TraceEvent[], traceStatus: { recording: false, eventCount: traceEvents.length } satisfies TraceStatus });\n }\n case \"status\":\n return ok(request.id, { traceStatus: { recording: traceRecording, eventCount: traceEvents.length } satisfies TraceStatus });\n default:\n return fail(request.id, `Unknown trace subcommand: ${subCommand}`);\n }\n }\n default:\n return fail(request.id, `Action not yet supported in direct CDP mode: ${request.action}`);\n }\n}\n","import { execFile, execSync, spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nconst DEFAULT_CDP_PORT = 19825;\nconst MANAGED_BROWSER_DIR = path.join(os.homedir(), \".bb-browser\", \"browser\");\nconst MANAGED_USER_DATA_DIR = path.join(MANAGED_BROWSER_DIR, \"user-data\");\nconst MANAGED_PORT_FILE = path.join(MANAGED_BROWSER_DIR, \"cdp-port\");\n\nfunction execFileAsync(command: string, args: string[], timeout: number): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(command, args, { encoding: \"utf8\", timeout }, (error, stdout) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(stdout.trim());\n });\n });\n}\n\nfunction getArgValue(flag: string): string | undefined {\n const index = process.argv.indexOf(flag);\n if (index < 0) return undefined;\n return process.argv[index + 1];\n}\n\nasync function tryOpenClaw(): Promise<{ host: string; port: number } | null> {\n try {\n const raw = await execFileAsync(\"npx\", [\"openclaw\", \"browser\", \"status\", \"--json\"], 5000);\n const parsed = JSON.parse(raw);\n const port = Number(parsed?.cdpPort);\n if (Number.isInteger(port) && port > 0) {\n return { host: \"127.0.0.1\", port };\n }\n } catch {\n }\n return null;\n}\n\nasync function canConnect(host: string, port: number): Promise<boolean> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 1200);\n const response = await fetch(`http://${host}:${port}/json/version`, { signal: controller.signal });\n clearTimeout(timeout);\n return response.ok;\n } catch {\n return false;\n }\n}\n\nexport function findBrowserExecutable(): string | null {\n if (process.platform === \"darwin\") {\n const candidates = [\n \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\",\n \"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge\",\n \"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser\",\n ];\n return candidates.find((candidate) => existsSync(candidate)) ?? null;\n }\n\n if (process.platform === \"linux\") {\n const candidates = [\"google-chrome\", \"google-chrome-stable\", \"chromium-browser\", \"chromium\"];\n for (const candidate of candidates) {\n try {\n const resolved = execSync(`which ${candidate}`, { encoding: \"utf8\", stdio: [\"ignore\", \"pipe\", \"ignore\"] }).trim();\n if (resolved) {\n return resolved;\n }\n } catch {\n }\n }\n return null;\n }\n\n if (process.platform === \"win32\") {\n const candidates = [\n \"C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe\",\n ];\n return candidates.find((candidate) => existsSync(candidate)) ?? null;\n }\n\n return null;\n}\n\nexport async function isManagedBrowserRunning(): Promise<boolean> {\n try {\n const rawPort = await readFile(MANAGED_PORT_FILE, \"utf8\");\n const port = Number.parseInt(rawPort.trim(), 10);\n if (!Number.isInteger(port) || port <= 0) {\n return false;\n }\n return await canConnect(\"127.0.0.1\", port);\n } catch {\n return false;\n }\n}\n\nexport async function launchManagedBrowser(port: number = DEFAULT_CDP_PORT): Promise<{ host: string; port: number } | null> {\n const executable = findBrowserExecutable();\n if (!executable) {\n return null;\n }\n\n await mkdir(MANAGED_USER_DATA_DIR, { recursive: true });\n\n // Set profile name so the Chrome window shows \"bb-browser\" in the title bar\n const defaultProfileDir = path.join(MANAGED_USER_DATA_DIR, \"Default\");\n const prefsPath = path.join(defaultProfileDir, \"Preferences\");\n await mkdir(defaultProfileDir, { recursive: true });\n try {\n let prefs: Record<string, unknown> = {};\n try { prefs = JSON.parse(await readFile(prefsPath, \"utf8\")); } catch {}\n if (!(prefs.profile as Record<string, unknown>)?.name || (prefs.profile as Record<string, unknown>).name !== \"bb-browser\") {\n prefs.profile = { ...(prefs.profile as Record<string, unknown> || {}), name: \"bb-browser\" };\n await writeFile(prefsPath, JSON.stringify(prefs), \"utf8\");\n }\n } catch {}\n\n const args = [\n `--remote-debugging-port=${port}`,\n `--user-data-dir=${MANAGED_USER_DATA_DIR}`,\n \"--no-first-run\",\n \"--no-default-browser-check\",\n \"--disable-sync\",\n \"--disable-background-networking\",\n \"--disable-component-update\",\n \"--disable-features=Translate,MediaRouter\",\n \"--disable-session-crashed-bubble\",\n \"--hide-crash-restore-bubble\",\n \"about:blank\",\n ];\n\n try {\n const child = spawn(executable, args, {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n } catch {\n return null;\n }\n\n await mkdir(MANAGED_BROWSER_DIR, { recursive: true });\n await writeFile(MANAGED_PORT_FILE, String(port), \"utf8\");\n\n const deadline = Date.now() + 8000;\n while (Date.now() < deadline) {\n if (await canConnect(\"127.0.0.1\", port)) {\n return { host: \"127.0.0.1\", port };\n }\n await new Promise((resolve) => setTimeout(resolve, 250));\n }\n\n return null;\n}\n\nexport async function discoverCdpPort(): Promise<{ host: string; port: number } | null> {\n const explicitPort = Number.parseInt(getArgValue(\"--port\") ?? \"\", 10);\n if (Number.isInteger(explicitPort) && explicitPort > 0 && await canConnect(\"127.0.0.1\", explicitPort)) {\n return { host: \"127.0.0.1\", port: explicitPort };\n }\n\n try {\n const rawPort = await readFile(MANAGED_PORT_FILE, \"utf8\");\n const managedPort = Number.parseInt(rawPort.trim(), 10);\n if (Number.isInteger(managedPort) && managedPort > 0 && await canConnect(\"127.0.0.1\", managedPort)) {\n return { host: \"127.0.0.1\", port: managedPort };\n }\n } catch {\n }\n\n if (process.argv.includes(\"--openclaw\")) {\n const viaOpenClaw = await tryOpenClaw();\n if (viaOpenClaw && await canConnect(viaOpenClaw.host, viaOpenClaw.port)) {\n return viaOpenClaw;\n }\n }\n\n const launched = await launchManagedBrowser();\n if (launched) {\n return launched;\n }\n\n if (!process.argv.includes(\"--openclaw\")) {\n const detectedOpenClaw = await tryOpenClaw();\n if (detectedOpenClaw && await canConnect(detectedOpenClaw.host, detectedOpenClaw.port)) {\n return detectedOpenClaw;\n }\n }\n\n return null;\n}\n","/**\n * CDP 客户端 - 与 Chrome DevTools Protocol 通信\n */\n\nimport type { Request, Response } from \"@bb-browser/shared\";\nimport { applyJq } from \"./jq.js\";\nimport { sendCommand as sendCdpCommand } from \"./cdp-client.js\";\n\nlet jqExpression: string | undefined;\n\nexport function setJqExpression(expression?: string): void {\n jqExpression = expression;\n}\n\nfunction printJqResults(response: Response): never {\n const target = response.data ?? response;\n const results = applyJq(target, jqExpression || \".\");\n for (const result of results) {\n console.log(typeof result === \"string\" ? result : JSON.stringify(result));\n }\n process.exit(0);\n}\n\nexport function handleJqResponse(response: Response): void {\n if (jqExpression) {\n printJqResults(response);\n }\n}\n\nexport async function sendCommand(request: Request): Promise<Response> {\n return sendCdpCommand(request);\n}\n","/**\n * 浏览器连接管理器 - 检测并连接 CDP\n */\n\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, resolve } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { ensureCdpConnection } from \"./cdp-client.js\";\nimport { discoverCdpPort } from \"./cdp-discovery.js\";\n\nexport function getDaemonPath(): string {\n const currentFile = fileURLToPath(import.meta.url);\n const currentDir = dirname(currentFile);\n const sameDirPath = resolve(currentDir, \"daemon.js\");\n if (existsSync(sameDirPath)) {\n return sameDirPath;\n }\n return resolve(currentDir, \"../../daemon/dist/index.js\");\n}\n\nexport async function isDaemonRunning(): Promise<boolean> {\n return (await discoverCdpPort()) !== null;\n}\n\nexport async function stopDaemon(): Promise<boolean> {\n return false;\n}\n\nexport async function ensureDaemonRunning(): Promise<void> {\n try {\n await ensureCdpConnection();\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"No browser connection found\")) {\n throw new Error([\n \"bb-browser: Could not start browser.\",\n \"\",\n \"Make sure Chrome is installed, then try again.\",\n \"Or specify a CDP port manually: bb-browser --port 9222\",\n ].join(\"\\n\"));\n }\n throw error;\n }\n}\n\n","import { copyFileSync, existsSync, unlinkSync } from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface HistorySearchResult {\n url: string;\n title: string;\n visitCount: number;\n lastVisitTime: number;\n}\n\nexport interface HistoryDomainResult {\n domain: string;\n visits: number;\n titles: string[];\n}\n\nfunction getHistoryPathCandidates(): string[] {\n const home = homedir();\n const localAppData = process.env.LOCALAPPDATA || \"\";\n const candidates: string[] = [\n join(home, \"Library/Application Support/Google/Chrome/Default/History\"),\n join(home, \"Library/Application Support/Microsoft Edge/Default/History\"),\n join(home, \"Library/Application Support/BraveSoftware/Brave-Browser/Default/History\"),\n join(home, \"Library/Application Support/Arc/User Data/Default/History\"),\n join(home, \".config/google-chrome/Default/History\"),\n ];\n\n if (localAppData) {\n candidates.push(\n join(localAppData, \"Google/Chrome/User Data/Default/History\"),\n join(localAppData, \"Microsoft/Edge/User Data/Default/History\")\n );\n }\n\n return candidates;\n}\n\nfunction findHistoryPath(): string | null {\n for (const historyPath of getHistoryPathCandidates()) {\n if (existsSync(historyPath)) {\n return historyPath;\n }\n }\n return null;\n}\n\nfunction sqlEscape(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\nfunction buildTimeWhere(days?: number): string {\n if (!days || days <= 0) {\n return \"\";\n }\n\n return `last_visit_time > (strftime('%s', 'now') - ${Math.floor(days)}*86400) * 1000000 + 11644473600000000`;\n}\n\nfunction runHistoryQuery<T>(sql: string, mapRow: (row: string[]) => T | null): T[] {\n const historyPath = findHistoryPath();\n if (!historyPath) {\n return [];\n }\n\n const tmpPath = join(tmpdir(), `bb-history-${Date.now()}-${Math.random().toString(36).slice(2)}.db`);\n\n try {\n copyFileSync(historyPath, tmpPath);\n const escapedTmpPath = tmpPath.replace(/\"/g, '\\\\\"');\n const escapedSql = sql.replace(/\"/g, '\\\\\"');\n const output = execSync(`sqlite3 -separator $'\\\\t' \"${escapedTmpPath}\" \"${escapedSql}\"`, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n return output\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => mapRow(line.split(\"\\t\")))\n .filter((item): item is T => item !== null);\n } catch {\n return [];\n } finally {\n try {\n unlinkSync(tmpPath);\n } catch {}\n }\n}\n\nexport function searchHistory(query?: string, days?: number): HistorySearchResult[] {\n const conditions: string[] = [];\n const trimmedQuery = query?.trim();\n\n if (trimmedQuery) {\n const escapedQuery = sqlEscape(trimmedQuery);\n conditions.push(`(url LIKE '%${escapedQuery}%' OR title LIKE '%${escapedQuery}%')`);\n }\n\n const timeWhere = buildTimeWhere(days);\n if (timeWhere) {\n conditions.push(timeWhere);\n }\n\n const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n const sql = `\n SELECT\n url,\n REPLACE(IFNULL(title, ''), char(9), ' '),\n IFNULL(visit_count, 0),\n IFNULL(last_visit_time, 0)\n FROM urls\n ${whereClause}\n ORDER BY last_visit_time DESC\n LIMIT 100;\n `.trim();\n\n return runHistoryQuery(sql, (row) => {\n if (row.length < 4) {\n return null;\n }\n\n const chromeTimestamp = Number(row[3]) || 0;\n return {\n url: row[0] || \"\",\n title: row[1] || \"\",\n visitCount: Number(row[2]) || 0,\n lastVisitTime: chromeTimestamp > 0 ? chromeTimestamp / 1000000 - 11644473600 : 0,\n };\n });\n}\n\nexport function getHistoryDomains(days?: number): HistoryDomainResult[] {\n const timeWhere = buildTimeWhere(days);\n const whereClause = timeWhere ? `WHERE ${timeWhere}` : \"\";\n const sql = `\n SELECT\n domain,\n SUM(visit_count) AS visits,\n GROUP_CONCAT(title, char(31)) AS titles\n FROM (\n SELECT\n CASE\n WHEN instr(url, '//') > 0 AND instr(substr(url, instr(url, '//') + 2), '/') > 0\n THEN substr(\n substr(url, instr(url, '//') + 2),\n 1,\n instr(substr(url, instr(url, '//') + 2), '/') - 1\n )\n WHEN instr(url, '//') > 0 THEN substr(url, instr(url, '//') + 2)\n WHEN instr(url, '/') > 0 THEN substr(url, 1, instr(url, '/') - 1)\n ELSE url\n END AS domain,\n IFNULL(visit_count, 0) AS visit_count,\n REPLACE(IFNULL(title, ''), char(31), ' ') AS title\n FROM urls\n ${whereClause}\n )\n WHERE domain != ''\n GROUP BY domain\n ORDER BY visits DESC\n LIMIT 50;\n `.trim();\n\n return runHistoryQuery(sql, (row) => {\n if (row.length < 3) {\n return null;\n }\n\n const titles = row[2]\n ? Array.from(new Set(row[2].split(String.fromCharCode(31)).map((title) => title.trim()).filter(Boolean))).slice(0, 10)\n : [];\n\n return {\n domain: row[0] || \"\",\n visits: Number(row[1]) || 0,\n titles,\n };\n });\n}\n","/**\n * site 命令 - 管理和运行社区/私有网站适配器\n *\n * 用法:\n * bb-browser site list 列出所有可用 site adapter\n * bb-browser site search <query> 搜索\n * bb-browser site <name> [args...] 运行(简写)\n * bb-browser site run <name> [args...] 运行\n * bb-browser site update 更新社区 adapter 库\n *\n * 目录:\n * ~/.bb-browser/sites/ 私有 adapter(优先)\n * ~/.bb-browser/bb-sites/ 社区 adapter(bb-browser site update 拉取)\n */\n\nimport { generateId, type Request, type Response, type TabInfo } from \"@bb-browser/shared\";\nimport { handleJqResponse, sendCommand } from \"../client.js\";\nimport { getHistoryDomains } from \"../history-sqlite.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\nimport { readFileSync, readdirSync, existsSync, mkdirSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { execSync } from \"node:child_process\";\n\nconst BB_DIR = join(homedir(), \".bb-browser\");\nconst LOCAL_SITES_DIR = join(BB_DIR, \"sites\");\nconst COMMUNITY_SITES_DIR = join(BB_DIR, \"bb-sites\");\nconst COMMUNITY_REPO = \"https://github.com/epiral/bb-sites.git\";\n\nfunction checkCliUpdate(): void {\n try {\n const current = execSync(\"bb-browser --version\", { timeout: 3000, stdio: [\"pipe\", \"pipe\", \"pipe\"] }).toString().trim();\n const latest = execSync(\"npm view bb-browser version\", { timeout: 5000, stdio: [\"pipe\", \"pipe\", \"pipe\"] }).toString().trim();\n if (latest && current && latest !== current && latest.localeCompare(current, undefined, { numeric: true }) > 0) {\n console.log(`\\n📦 bb-browser ${latest} available (current: ${current}). Run: npm install -g bb-browser`);\n }\n } catch {}\n}\n\nexport interface SiteOptions {\n json?: boolean;\n tabId?: number;\n days?: number;\n jq?: string;\n openclaw?: boolean;\n}\n\n/** Adapter 参数定义 */\ninterface ArgDef {\n required?: boolean;\n description?: string;\n}\n\n/** Adapter 元数据 */\ninterface SiteMeta {\n name: string;\n description: string;\n domain: string;\n args: Record<string, ArgDef>;\n capabilities?: string[];\n readOnly?: boolean;\n example?: string;\n filePath: string;\n source: \"local\" | \"community\";\n}\n\ninterface HistoryDomain {\n domain: string;\n visits: number;\n}\n\ninterface SiteRecommendation {\n domain: string;\n visits: number;\n adapterCount: number;\n adapters: Array<{\n name: string;\n description: string;\n example: string;\n }>;\n}\n\n/**\n * 从 JS 文件的 /* @meta JSON * / 块解析元数据\n */\nfunction parseSiteMeta(filePath: string, source: \"local\" | \"community\"): SiteMeta | null {\n let content: string;\n try {\n content = readFileSync(filePath, \"utf-8\");\n } catch {\n return null;\n }\n\n // 从文件路径推断默认 name\n const sitesDir = source === \"local\" ? LOCAL_SITES_DIR : COMMUNITY_SITES_DIR;\n const relPath = relative(sitesDir, filePath);\n const defaultName = relPath.replace(/\\.js$/, \"\").replace(/\\\\/g, \"/\");\n\n // 解析 /* @meta { ... } */ 块\n const metaMatch = content.match(/\\/\\*\\s*@meta\\s*\\n([\\s\\S]*?)\\*\\//);\n if (metaMatch) {\n try {\n const metaJson = JSON.parse(metaMatch[1]);\n return {\n name: metaJson.name || defaultName,\n description: metaJson.description || \"\",\n domain: metaJson.domain || \"\",\n args: metaJson.args || {},\n capabilities: metaJson.capabilities,\n readOnly: metaJson.readOnly,\n example: metaJson.example,\n filePath,\n source,\n };\n } catch {\n // JSON 解析失败,回退到 @tag 模式\n }\n }\n\n // 回退:解析 // @tag 格式(兼容旧格式)\n const meta: SiteMeta = {\n name: defaultName,\n description: \"\",\n domain: \"\",\n args: {},\n filePath,\n source,\n };\n\n const tagPattern = /\\/\\/\\s*@(\\w+)[ \\t]+(.*)/g;\n let match;\n while ((match = tagPattern.exec(content)) !== null) {\n const [, key, value] = match;\n switch (key) {\n case \"name\": meta.name = value.trim(); break;\n case \"description\": meta.description = value.trim(); break;\n case \"domain\": meta.domain = value.trim(); break;\n case \"args\":\n for (const arg of value.trim().split(/[,\\s]+/).filter(Boolean)) {\n meta.args[arg] = { required: true };\n }\n break;\n case \"example\": meta.example = value.trim(); break;\n }\n }\n\n return meta;\n}\n\n/**\n * 扫描目录下所有 .js 文件\n */\nfunction scanSites(dir: string, source: \"local\" | \"community\"): SiteMeta[] {\n if (!existsSync(dir)) return [];\n const sites: SiteMeta[] = [];\n\n function walk(currentDir: string): void {\n let entries;\n try { entries = readdirSync(currentDir, { withFileTypes: true }); } catch { return; }\n for (const entry of entries) {\n const fullPath = join(currentDir, entry.name);\n if (entry.isDirectory() && !entry.name.startsWith(\".\")) {\n walk(fullPath);\n } else if (entry.isFile() && entry.name.endsWith(\".js\")) {\n const meta = parseSiteMeta(fullPath, source);\n if (meta) sites.push(meta);\n }\n }\n }\n\n walk(dir);\n return sites;\n}\n\n/**\n * 根据 URL 检查是否有对应的 site adapter,返回提示文本\n */\nexport function getSiteHintForDomain(url: string): string | null {\n try {\n const hostname = new URL(url).hostname;\n const sites = getAllSites();\n const matched = sites.filter(s => s.domain && (hostname === s.domain || hostname.endsWith(\".\" + s.domain)));\n if (matched.length === 0) return null;\n const names = matched.map(s => s.name);\n const example = matched[0].example || `bb-browser site ${names[0]}`;\n return `该网站有 ${names.length} 个 site adapter 可直接获取数据,无需手动操作浏览器。试试: ${example}`;\n } catch {\n return null;\n }\n}\n\n/**\n * 获取所有 adapter(私有优先)\n */\nfunction getAllSites(): SiteMeta[] {\n const community = scanSites(COMMUNITY_SITES_DIR, \"community\");\n const local = scanSites(LOCAL_SITES_DIR, \"local\");\n\n const byName = new Map<string, SiteMeta>();\n for (const s of community) byName.set(s.name, s);\n for (const s of local) byName.set(s.name, s);\n\n return Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * 精确匹配 tab 的 origin\n */\nfunction matchTabOrigin(tabUrl: string, domain: string): boolean {\n try {\n const tabOrigin = new URL(tabUrl).hostname;\n return tabOrigin === domain || tabOrigin.endsWith(\".\" + domain);\n } catch {\n return false;\n }\n}\n\n// ── 子命令 ──────────────────────────────────────────────────────\n\nfunction siteList(options: SiteOptions): void {\n const sites = getAllSites();\n\n if (sites.length === 0) {\n console.log(\"未找到任何 site adapter。\");\n console.log(\" 安装社区 adapter: bb-browser site update\");\n console.log(` 私有 adapter 目录: ${LOCAL_SITES_DIR}`);\n return;\n }\n\n if (options.json) {\n console.log(JSON.stringify(sites.map(s => ({\n name: s.name, description: s.description, domain: s.domain,\n args: s.args, source: s.source,\n })), null, 2));\n return;\n }\n\n const groups = new Map<string, SiteMeta[]>();\n for (const s of sites) {\n const platform = s.name.split(\"/\")[0];\n if (!groups.has(platform)) groups.set(platform, []);\n groups.get(platform)!.push(s);\n }\n\n for (const [platform, items] of groups) {\n console.log(`\\n${platform}/`);\n for (const s of items) {\n const cmd = s.name.split(\"/\").slice(1).join(\"/\");\n const src = s.source === \"local\" ? \" (local)\" : \"\";\n const desc = s.description ? ` - ${s.description}` : \"\";\n console.log(` ${cmd.padEnd(20)}${desc}${src}`);\n }\n }\n console.log();\n}\n\nfunction siteSearch(query: string, options: SiteOptions): void {\n const sites = getAllSites();\n const q = query.toLowerCase();\n const matches = sites.filter(s =>\n s.name.toLowerCase().includes(q) ||\n s.description.toLowerCase().includes(q) ||\n s.domain.toLowerCase().includes(q)\n );\n\n if (matches.length === 0) {\n console.log(`未找到匹配 \"${query}\" 的 adapter。`);\n console.log(\" 查看所有: bb-browser site list\");\n return;\n }\n\n if (options.json) {\n console.log(JSON.stringify(matches.map(s => ({\n name: s.name, description: s.description, domain: s.domain, source: s.source,\n })), null, 2));\n return;\n }\n\n for (const s of matches) {\n const src = s.source === \"local\" ? \" (local)\" : \"\";\n console.log(`${s.name.padEnd(24)} ${s.description}${src}`);\n }\n}\n\nfunction siteUpdate(): void {\n mkdirSync(BB_DIR, { recursive: true });\n\n if (existsSync(join(COMMUNITY_SITES_DIR, \".git\"))) {\n console.log(\"更新社区 site adapter 库...\");\n try {\n execSync(\"git pull --ff-only\", { cwd: COMMUNITY_SITES_DIR, stdio: \"pipe\" });\n console.log(\"更新完成。\");\n console.log(\"\");\n console.log(\"💡 运行 bb-browser site recommend 看看哪些和你的浏览习惯匹配\");\n } catch (e) {\n console.error(`更新失败: ${e instanceof Error ? e.message : e}`);\n console.error(\" 手动修复: cd ~/.bb-browser/bb-sites && git pull\");\n process.exit(1);\n }\n } else {\n console.log(`克隆社区 adapter 库: ${COMMUNITY_REPO}`);\n try {\n execSync(`git clone ${COMMUNITY_REPO} ${COMMUNITY_SITES_DIR}`, { stdio: \"pipe\" });\n console.log(\"克隆完成。\");\n console.log(\"\");\n console.log(\"💡 运行 bb-browser site recommend 看看哪些和你的浏览习惯匹配\");\n } catch (e) {\n console.error(`克隆失败: ${e instanceof Error ? e.message : e}`);\n console.error(` 手动修复: git clone ${COMMUNITY_REPO} ~/.bb-browser/bb-sites`);\n process.exit(1);\n }\n }\n\n const sites = scanSites(COMMUNITY_SITES_DIR, \"community\");\n console.log(`已安装 ${sites.length} 个社区 adapter。`);\n console.log(`⭐ Like bb-browser? → bb-browser star`);\n\n // Check for CLI updates\n checkCliUpdate();\n}\n\nfunction findSiteByName(name: string): SiteMeta | undefined {\n return getAllSites().find((site) => site.name === name);\n}\n\nfunction siteInfo(name: string, options: SiteOptions): void {\n const site = findSiteByName(name);\n\n if (!site) {\n console.error(`[error] site info: adapter \"${name}\" not found.`);\n console.error(\" Try: bb-browser site list\");\n process.exit(1);\n }\n\n const meta = {\n name: site.name,\n description: site.description,\n domain: site.domain,\n args: site.args,\n example: site.example,\n readOnly: site.readOnly,\n };\n\n if (options.json) {\n console.log(JSON.stringify(meta, null, 2));\n return;\n }\n\n console.log(`${site.name} — ${site.description}`);\n console.log();\n console.log(\"参数:\");\n\n const argEntries = Object.entries(site.args);\n if (argEntries.length === 0) {\n console.log(\" (无)\");\n } else {\n for (const [argName, argDef] of argEntries) {\n const requiredText = argDef.required ? \"必填\" : \"可选\";\n const description = argDef.description || \"\";\n console.log(` ${argName} (${requiredText}) ${description}`.trimEnd());\n }\n }\n\n console.log();\n console.log(\"示例:\");\n console.log(` ${site.example || `bb-browser site ${site.name}`}`);\n console.log();\n console.log(`域名:${site.domain || \"(未声明)\"}`);\n console.log(`只读:${site.readOnly ? \"是\" : \"否\"}`);\n}\n\nasync function siteRecommend(options: SiteOptions): Promise<void> {\n const days = options.days ?? 30;\n const historyDomains: HistoryDomain[] = getHistoryDomains(days);\n const sites = getAllSites();\n const sitesByDomain = new Map<string, SiteMeta[]>();\n\n for (const site of sites) {\n if (!site.domain) continue;\n const domain = site.domain.toLowerCase();\n const existing = sitesByDomain.get(domain) || [];\n existing.push(site);\n sitesByDomain.set(domain, existing);\n }\n\n const available: SiteRecommendation[] = [];\n const notAvailable: HistoryDomain[] = [];\n\n for (const item of historyDomains) {\n const adapters = sitesByDomain.get(item.domain.toLowerCase());\n if (adapters && adapters.length > 0) {\n const sortedAdapters = [...adapters].sort((a, b) => a.name.localeCompare(b.name));\n available.push({\n domain: item.domain,\n visits: item.visits,\n adapterCount: sortedAdapters.length,\n adapters: sortedAdapters.map((site) => ({\n name: site.name,\n description: site.description,\n example: site.example || `bb-browser site ${site.name}`,\n })),\n });\n } else if (item.visits >= 5 && item.domain && !item.domain.includes('localhost') && item.domain.includes('.')) {\n notAvailable.push(item);\n }\n }\n\n const jsonData = {\n days,\n available,\n not_available: notAvailable,\n };\n\n if (options.jq) {\n handleJqResponse({ id: generateId(), success: true, data: jsonData as any });\n }\n\n if (options.json) {\n console.log(JSON.stringify(jsonData, null, 2));\n return;\n }\n\n console.log(`基于你最近 ${days} 天的浏览记录:`);\n console.log();\n\n console.log(\"🎯 你常用这些网站,可以直接用:\");\n console.log();\n if (available.length === 0) {\n console.log(\" (暂无匹配的 adapter)\");\n } else {\n for (const item of available) {\n console.log(` ${item.domain.padEnd(20)} ${item.visits} 次访问 ${item.adapterCount} 个命令`);\n console.log(` 试试: ${item.adapters[0]?.example || `bb-browser site ${item.adapters[0]?.name || \"\"}`}`);\n console.log();\n }\n }\n\n console.log(\"📋 你常用但还没有 adapter:\");\n console.log();\n if (notAvailable.length === 0) {\n console.log(\" (暂无)\");\n } else {\n for (const item of notAvailable) {\n console.log(` ${item.domain.padEnd(20)} ${item.visits} 次访问`);\n }\n }\n\n console.log();\n console.log('💡 跟你的 AI Agent 说 \"把 notion.so CLI 化\",它就能自动完成。');\n console.log();\n console.log(`所有分析纯本地完成。用 --days 7 只看最近一周。`);\n}\n\nasync function siteRun(\n name: string,\n args: string[],\n options: SiteOptions\n): Promise<void> {\n const sites = getAllSites();\n const site = sites.find(s => s.name === name);\n\n if (!site) {\n const fuzzy = sites.filter(s => s.name.includes(name));\n console.error(`[error] site: \"${name}\" not found.`);\n if (fuzzy.length > 0) {\n console.error(\" Did you mean:\");\n for (const s of fuzzy.slice(0, 5)) {\n console.error(` bb-browser site ${s.name}`);\n }\n } else {\n console.error(\" Try: bb-browser site list\");\n console.error(\" Or: bb-browser site update\");\n }\n process.exit(1);\n }\n\n // 解析参数\n const argNames = Object.keys(site.args);\n const argMap: Record<string, string> = {};\n\n // 过滤掉 --flag value 对,收集位置参数\n const positionalArgs: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i].startsWith(\"--\")) {\n const flagName = args[i].slice(2);\n if (flagName in site.args && args[i + 1]) {\n argMap[flagName] = args[i + 1];\n i++; // 跳过值\n }\n } else {\n positionalArgs.push(args[i]);\n }\n }\n\n // 位置参数按 argNames 顺序填入(跳过已通过 --flag 提供的)\n let posIdx = 0;\n for (const argName of argNames) {\n if (!argMap[argName] && posIdx < positionalArgs.length) {\n argMap[argName] = positionalArgs[posIdx++];\n }\n }\n\n // 只检查 required 参数\n for (const [argName, argDef] of Object.entries(site.args)) {\n if (argDef.required && !argMap[argName]) {\n console.error(`[error] site ${name}: missing required argument \"${argName}\".`);\n const usage = argNames.map(a => {\n const def = site.args[a];\n return def.required ? `<${a}>` : `[${a}]`;\n }).join(\" \");\n console.error(` Usage: bb-browser site ${name} ${usage}`);\n if (site.example) console.error(` Example: ${site.example}`);\n process.exit(1);\n }\n }\n\n // 读取并解析 JS\n const jsContent = readFileSync(site.filePath, \"utf-8\");\n\n // 移除 /* @meta ... */ 块,保留函数体\n const jsBody = jsContent.replace(/\\/\\*\\s*@meta[\\s\\S]*?\\*\\//, \"\").trim();\n\n // 构造执行脚本\n const argsJson = JSON.stringify(argMap);\n const script = `(${jsBody})(${argsJson})`;\n\n if (options.openclaw) {\n const { ocGetTabs, ocFindTabByDomain, ocOpenTab, ocEvaluate } = await import(\"../openclaw-bridge.js\");\n\n let targetId: string;\n\n if (site.domain) {\n const tabs = ocGetTabs();\n const existing = ocFindTabByDomain(tabs, site.domain);\n if (existing) {\n targetId = existing.targetId;\n } else {\n targetId = ocOpenTab(`https://${site.domain}`);\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n } else {\n const tabs = ocGetTabs();\n if (tabs.length === 0) {\n throw new Error(\"No tabs open in OpenClaw browser\");\n }\n targetId = tabs[0].targetId;\n }\n\n const wrappedFn = `async () => { const __fn = ${jsBody}; return await __fn(${argsJson}); }`;\n const parsed = ocEvaluate(targetId, wrappedFn);\n\n if (typeof parsed === \"object\" && parsed !== null && \"error\" in parsed) {\n const errObj = parsed as { error: string; hint?: string };\n const checkText = `${errObj.error} ${errObj.hint || \"\"}`;\n const isAuthError = /401|403|unauthorized|forbidden|not.?logged|login.?required|sign.?in|auth/i.test(checkText);\n const loginHint = isAuthError && site.domain\n ? `Please log in to https://${site.domain} in your OpenClaw browser first, then retry.`\n : undefined;\n const hint = loginHint || errObj.hint;\n const reportHint = `If this is an adapter bug, report via: gh issue create --repo epiral/bb-sites --title \"[${name}] <description>\" OR: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] <description>\"`;\n\n if (options.json) {\n console.log(JSON.stringify({ id: \"openclaw\", success: false, error: errObj.error, hint, reportHint }));\n } else {\n console.error(`[error] site ${name}: ${errObj.error}`);\n if (hint) console.error(` Hint: ${hint}`);\n console.error(` Report: gh issue create --repo epiral/bb-sites --title \"[${name}] ...\"`);\n console.error(` or: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] ...\"`);\n }\n process.exit(1);\n }\n\n if (options.jq) {\n const { applyJq } = await import(\"../jq.js\");\n const expr = options.jq.replace(/^\\.data\\./, '.');\n const results = applyJq(parsed, expr);\n for (const r of results) {\n console.log(typeof r === \"string\" ? r : JSON.stringify(r));\n }\n } else if (options.json) {\n console.log(JSON.stringify({ id: \"openclaw\", success: true, data: parsed }));\n } else {\n console.log(JSON.stringify(parsed, null, 2));\n }\n return;\n }\n\n await ensureDaemonRunning();\n\n // 确定目标 tab\n let targetTabId: number | undefined = options.tabId;\n\n // 如果用户没指定 --tab,自动查找匹配域名的 tab\n if (!targetTabId && site.domain) {\n const listReq: Request = { id: generateId(), action: \"tab_list\" };\n const listResp: Response = await sendCommand(listReq);\n\n if (listResp.success && listResp.data?.tabs) {\n const matchingTab = listResp.data.tabs.find((tab: TabInfo) =>\n matchTabOrigin(tab.url, site.domain)\n );\n if (matchingTab) {\n targetTabId = matchingTab.tabId;\n }\n }\n\n if (!targetTabId) {\n const newResp = await sendCommand({\n id: generateId(),\n action: \"tab_new\",\n url: `https://${site.domain}`,\n });\n targetTabId = newResp.data?.tabId;\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n }\n\n // 执行\n const evalReq: Request = { id: generateId(), action: \"eval\", script, tabId: targetTabId };\n const evalResp: Response = await sendCommand(evalReq);\n\n if (!evalResp.success) {\n const hint = site.domain\n ? `Open https://${site.domain} in your browser, make sure you are logged in, then retry.`\n : undefined;\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: false, error: evalResp.error || \"eval failed\", hint }));\n } else {\n console.error(`[error] site ${name}: ${evalResp.error || \"eval failed\"}`);\n if (hint) console.error(` Hint: ${hint}`);\n }\n process.exit(1);\n }\n\n const result = evalResp.data?.result;\n if (result === undefined || result === null) {\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: true, data: null }));\n } else {\n console.log(\"(no output)\");\n }\n return;\n }\n\n // 解析输出\n let parsed: unknown;\n try {\n parsed = typeof result === \"string\" ? JSON.parse(result) : result;\n } catch {\n parsed = result;\n }\n\n // 检查 adapter 返回的 error\n if (typeof parsed === \"object\" && parsed !== null && \"error\" in parsed) {\n const errObj = parsed as { error: string; hint?: string };\n\n // 检测是否为登录问题(检查 error 和 hint 文本)\n const checkText = `${errObj.error} ${errObj.hint || \"\"}`;\n const isAuthError = /401|403|unauthorized|forbidden|not.?logged|login.?required|sign.?in|auth/i.test(checkText);\n const loginHint = isAuthError && site.domain\n ? `Please log in to https://${site.domain} in your browser first, then retry.`\n : undefined;\n const hint = loginHint || errObj.hint;\n const reportHint = `If this is an adapter bug, report via: gh issue create --repo epiral/bb-sites --title \"[${name}] <description>\" OR: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] <description>\"`;\n\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: false, error: errObj.error, hint, reportHint }));\n } else {\n console.error(`[error] site ${name}: ${errObj.error}`);\n if (hint) console.error(` Hint: ${hint}`);\n console.error(` Report: gh issue create --repo epiral/bb-sites --title \"[${name}] ...\"`);\n console.error(` or: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] ...\"`);\n }\n process.exit(1);\n }\n\n if (options.jq) {\n const { applyJq } = await import(\"../jq.js\");\n // Tolerate \".data.\" prefix — Agent may copy from --json envelope structure\n const expr = options.jq.replace(/^\\.data\\./, '.');\n const results = applyJq(parsed, expr);\n for (const r of results) {\n console.log(typeof r === \"string\" ? r : JSON.stringify(r));\n }\n } else if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: true, data: parsed }));\n } else {\n console.log(JSON.stringify(parsed, null, 2));\n }\n}\n\n// ── 入口 ────────────────────────────────────────────────────────\n\nexport async function siteCommand(\n args: string[],\n options: SiteOptions = {}\n): Promise<void> {\n const subCommand = args[0];\n\n if (!subCommand || subCommand === \"--help\" || subCommand === \"-h\") {\n console.log(`bb-browser site - 网站 CLI 化(管理和运行 site adapter)\n\n用法:\n bb-browser site list 列出所有可用 adapter\n bb-browser site info <name> 查看 adapter 元信息\n bb-browser site recommend 基于历史记录推荐 adapter\n bb-browser site search <query> 搜索 adapter\n bb-browser site <name> [args...] 运行 adapter(简写)\n bb-browser site run <name> [args...] 运行 adapter\n bb-browser site update 更新社区 adapter 库 (git clone/pull)\n\n目录:\n ${LOCAL_SITES_DIR} 私有 adapter(优先)\n ${COMMUNITY_SITES_DIR} 社区 adapter\n\n示例:\n bb-browser site update\n bb-browser site list\n bb-browser site reddit/thread https://www.reddit.com/r/LocalLLaMA/comments/...\n bb-browser site twitter/user yan5xu\n bb-browser site search reddit\n\n创建新 adapter: bb-browser guide\n报告问题: gh issue create --repo epiral/bb-sites --title \"[adapter-name] 描述\"\n贡献社区: https://github.com/epiral/bb-sites`);\n return;\n }\n\n switch (subCommand) {\n case \"list\": siteList(options); break;\n case \"search\":\n if (!args[1]) {\n console.error(\"[error] site search: <query> is required.\");\n console.error(\" Usage: bb-browser site search <query>\");\n process.exit(1);\n }\n siteSearch(args[1], options);\n break;\n case \"info\":\n if (!args[1]) {\n console.error(\"[error] site info: <name> is required.\");\n console.error(\" Usage: bb-browser site info <name>\");\n process.exit(1);\n }\n siteInfo(args[1], options);\n break;\n case \"recommend\":\n await siteRecommend(options);\n break;\n case \"update\": siteUpdate(); break;\n case \"run\":\n if (!args[1]) {\n console.error(\"[error] site run: <name> is required.\");\n console.error(\" Usage: bb-browser site run <name> [args...]\");\n console.error(\" Try: bb-browser site list\");\n process.exit(1);\n }\n await siteRun(args[1], args.slice(2), options);\n break;\n default:\n if (subCommand.includes(\"/\")) {\n await siteRun(subCommand, args.slice(1), options);\n } else {\n console.error(`[error] site: unknown subcommand \"${subCommand}\".`);\n console.error(\" Available: list, info, recommend, search, run, update\");\n console.error(\" Try: bb-browser site --help\");\n process.exit(1);\n }\n break;\n }\n\n // 静默后台更新社区 adapter\n silentUpdate();\n}\n\nfunction silentUpdate(): void {\n const gitDir = join(COMMUNITY_SITES_DIR, \".git\");\n if (!existsSync(gitDir)) return;\n import(\"node:child_process\").then(({ spawn }) => {\n const child = spawn(\"git\", [\"pull\", \"--ff-only\"], {\n cwd: COMMUNITY_SITES_DIR,\n stdio: \"ignore\",\n detached: true,\n });\n child.unref();\n }).catch(() => {});\n}\n","/**\n * open 命令 - 打开指定 URL\n * \n * 用法:\n * bb-browser open <url> # 在新 tab 中打开\n * bb-browser open <url> --tab current # 在当前 tab 中打开\n * bb-browser open <url> --tab 123 # 在指定 tabId 的 tab 中打开\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\nimport { getSiteHintForDomain } from \"./site.js\";\n\nexport interface OpenOptions {\n json?: boolean;\n tab?: string; // \"current\" | tabId 数字字符串 | undefined(新建 tab)\n}\n\nexport async function openCommand(\n url: string,\n options: OpenOptions = {}\n): Promise<void> {\n // 验证 URL\n if (!url) {\n throw new Error(\"缺少 URL 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 补全 URL 协议\n let normalizedUrl = url;\n if (!url.startsWith(\"http://\") && !url.startsWith(\"https://\")) {\n normalizedUrl = \"https://\" + url;\n }\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"open\",\n url: normalizedUrl,\n };\n\n // 处理 --tab 参数\n if (options.tab !== undefined) {\n if (options.tab === \"current\") {\n // 使用当前活动 tab\n (request as Record<string, unknown>).tabId = \"current\";\n } else {\n // 使用指定 tabId\n const tabId = parseInt(options.tab, 10);\n if (isNaN(tabId)) {\n throw new Error(`无效的 tabId: ${options.tab}`);\n }\n (request as Record<string, unknown>).tabId = tabId;\n }\n }\n // 不指定 --tab 时,tabId 为 undefined,扩展会创建新 tab\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`已打开: ${response.data?.url ?? normalizedUrl}`);\n if (response.data?.title) {\n console.log(`标题: ${response.data.title}`);\n }\n if (response.data?.tabId) {\n console.log(`Tab ID: ${response.data.tabId}`);\n }\n // 提示:如果该域名有 site adapter,引导使用\n const siteHint = getSiteHintForDomain(normalizedUrl);\n if (siteHint) {\n console.log(`\\n💡 ${siteHint}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * snapshot 命令 - 获取当前页面快照\n * 用法:bb-browser snapshot [-i|--interactive] [-c|--compact] [-d|--depth N] [-s|--selector SEL]\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface SnapshotOptions {\n json?: boolean;\n /** 只输出可交互元素 */\n interactive?: boolean;\n /** 移除空结构节点 */\n compact?: boolean;\n /** 限制树深度 */\n maxDepth?: number;\n /** CSS 选择器范围 */\n selector?: string;\n tabId?: number;\n}\n\nexport async function snapshotCommand(\n options: SnapshotOptions = {}\n): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"snapshot\",\n interactive: options.interactive,\n compact: options.compact,\n maxDepth: options.maxDepth,\n selector: options.selector,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`标题: ${response.data?.title ?? \"(无标题)\"}`);\n console.log(`URL: ${response.data?.url ?? \"(未知)\"}`);\n // 输出 snapshot 文本\n if (response.data?.snapshotData?.snapshot) {\n console.log(\"\");\n console.log(response.data.snapshotData.snapshot);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * click 命令 - 点击元素\n * 用法:bb-browser click <ref>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ClickOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function clickCommand(\n ref: string,\n options: ClickOptions = {}\n): Promise<void> {\n // 验证 ref\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"click\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已点击: ${role} \"${name}\"`);\n } else {\n console.log(`已点击: ${role}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * hover 命令 - 悬停在元素上\n * 用法:bb-browser hover <ref>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface HoverOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function hoverCommand(\n ref: string,\n options: HoverOptions = {}\n): Promise<void> {\n // 验证 ref\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"hover\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已悬停: ${role} \"${name}\"`);\n } else {\n console.log(`已悬停: ${role}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * fill 命令 - 填充输入框\n * 用法:bb-browser fill <ref> <text>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface FillOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function fillCommand(\n ref: string,\n text: string,\n options: FillOptions = {}\n): Promise<void> {\n // 验证参数\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n if (text === undefined || text === null) {\n throw new Error(\"缺少 text 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"fill\",\n ref: parsedRef,\n text: text,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已填充: ${role} \"${name}\"`);\n } else {\n console.log(`已填充: ${role}`);\n }\n console.log(`内容: \"${text}\"`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * type 命令 - 在元素中逐字符输入文本(不清空原有内容)\n * 用法:bb-browser type <ref> <text>\n * \n * 与 fill 命令的区别:\n * - fill:先清空再填入\n * - type:不清空,逐字符追加输入\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface TypeOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function typeCommand(\n ref: string,\n text: string,\n options: TypeOptions = {}\n): Promise<void> {\n // 验证参数\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n if (text === undefined || text === null) {\n throw new Error(\"缺少 text 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"type\",\n ref: parsedRef,\n text: text,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已输入: ${role} \"${name}\"`);\n } else {\n console.log(`已输入: ${role}`);\n }\n console.log(`内容: \"${text}\"`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * close 命令 - 关闭当前标签页\n * 用法:bb-browser close\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface CloseOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport async function closeCommand(options: CloseOptions = {}): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"close\",\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const title = response.data?.title ?? \"\";\n if (title) {\n console.log(`已关闭: \"${title}\"`);\n } else {\n console.log(\"已关闭当前标签页\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * get 命令 - 获取页面或元素信息\n * 用法:\n * bb-browser get text <ref> 获取元素文本\n * bb-browser get url 获取当前页面 URL\n * bb-browser get title 获取页面标题\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface GetOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/** 支持的 get 属性类型 */\nexport type GetAttribute = \"text\" | \"url\" | \"title\";\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function getCommand(\n attribute: GetAttribute,\n ref: string | undefined,\n options: GetOptions = {}\n): Promise<void> {\n // 验证参数\n if (attribute === \"text\" && !ref) {\n throw new Error(\"get text 需要 ref 参数,如: get text @5\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"get\",\n attribute,\n ref: ref ? parseRef(ref) : undefined,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const value = response.data?.value ?? \"\";\n console.log(value);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * screenshot 命令 - 截取当前页面\n * 用法:\n * bb-browser screenshot # 保存到临时目录\n * bb-browser screenshot ./page.png # 保存到指定路径\n * bb-browser screenshot --json # 返回 { path, base64 }\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ScreenshotOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 生成默认截图路径\n */\nfunction getDefaultPath(): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const filename = `bb-screenshot-${timestamp}.png`;\n return path.join(os.tmpdir(), filename);\n}\n\n/**\n * 解码 data URL 并保存为文件\n */\nfunction saveBase64Image(dataUrl: string, filePath: string): void {\n const base64Data = dataUrl.replace(/^data:image\\/png;base64,/, \"\");\n const buffer = Buffer.from(base64Data, \"base64\");\n \n // 确保目录存在\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n \n fs.writeFileSync(filePath, buffer);\n}\n\nexport async function screenshotCommand(\n outputPath?: string,\n options: ScreenshotOptions = {}\n): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 确定保存路径\n const filePath = outputPath ? path.resolve(outputPath) : getDefaultPath();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"screenshot\",\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 处理结果\n if (response.success && response.data?.dataUrl) {\n const dataUrl = response.data.dataUrl as string;\n \n // 保存文件\n saveBase64Image(dataUrl, filePath);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify({\n success: true,\n path: filePath,\n base64: dataUrl,\n }, null, 2));\n } else {\n console.log(`截图已保存: ${filePath}`);\n }\n } else {\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n console.error(`错误: ${response.error}`);\n }\n process.exit(1);\n }\n}\n","/**\n * wait 命令 - 等待指定时间或元素出现\n * 用法:\n * bb-browser wait <ms> 等待指定毫秒数\n * bb-browser wait @<ref> 等待元素出现(最多 10 秒)\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface WaitOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 判断是否是等待时间(纯数字)\n */\nfunction isTimeWait(target: string): boolean {\n return /^\\d+$/.test(target);\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function waitCommand(\n target: string,\n options: WaitOptions = {}\n): Promise<void> {\n if (!target) {\n throw new Error(\"缺少等待目标参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n let request: Request;\n\n if (isTimeWait(target)) {\n // 等待时间模式\n const ms = parseInt(target, 10);\n request = {\n id: generateId(),\n action: \"wait\",\n waitType: \"time\",\n ms,\n tabId: options.tabId,\n };\n } else {\n // 等待元素模式\n const ref = parseRef(target);\n request = {\n id: generateId(),\n action: \"wait\",\n waitType: \"element\",\n ref,\n tabId: options.tabId,\n };\n }\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n if (isTimeWait(target)) {\n console.log(`已等待 ${target}ms`);\n } else {\n console.log(`元素 @${parseRef(target)} 已出现`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * press 命令 - 发送键盘按键\n * 用法:bb-browser press <key>\n *\n * key 支持格式:\n * - 单键:\"Enter\", \"Tab\", \"Escape\", \"Backspace\", \"ArrowUp\" 等\n * - 组合键:\"Control+a\", \"Control+c\", \"Control+v\"(用 + 分隔)\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface PressOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析按键字符串,提取修饰键和主键\n * 例如:\n * \"Enter\" -> { key: \"Enter\", modifiers: [] }\n * \"Control+a\" -> { key: \"a\", modifiers: [\"Control\"] }\n * \"Control+Shift+Delete\" -> { key: \"Delete\", modifiers: [\"Control\", \"Shift\"] }\n */\nfunction parseKey(keyString: string): { key: string; modifiers: string[] } {\n const parts = keyString.split(\"+\");\n const modifierNames = [\"Control\", \"Alt\", \"Shift\", \"Meta\"];\n\n const modifiers: string[] = [];\n let key = \"\";\n\n for (const part of parts) {\n if (modifierNames.includes(part)) {\n modifiers.push(part);\n } else {\n key = part;\n }\n }\n\n return { key, modifiers };\n}\n\nexport async function pressCommand(\n keyString: string,\n options: PressOptions = {}\n): Promise<void> {\n // 验证参数\n if (!keyString) {\n throw new Error(\"缺少 key 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析按键\n const { key, modifiers } = parseKey(keyString);\n\n if (!key) {\n throw new Error(\"无效的按键格式\");\n }\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"press\",\n key,\n modifiers,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const displayKey = modifiers.length > 0 ? `${modifiers.join(\"+\")}+${key}` : key;\n console.log(`已按下: ${displayKey}`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * scroll 命令 - 滚动页面\n * 用法:bb-browser scroll <direction> [pixels]\n *\n * direction: up | down | left | right\n * pixels: 滚动像素数,默认 300\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ScrollOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport type ScrollDirection = \"up\" | \"down\" | \"left\" | \"right\";\n\nconst VALID_DIRECTIONS: ScrollDirection[] = [\"up\", \"down\", \"left\", \"right\"];\nconst DEFAULT_PIXELS = 300;\n\nexport async function scrollCommand(\n direction: string,\n pixels?: string,\n options: ScrollOptions = {}\n): Promise<void> {\n // 验证 direction\n if (!direction) {\n throw new Error(\"缺少 direction 参数\");\n }\n\n if (!VALID_DIRECTIONS.includes(direction as ScrollDirection)) {\n throw new Error(\n `无效的滚动方向: ${direction},支持: ${VALID_DIRECTIONS.join(\", \")}`\n );\n }\n\n // 解析 pixels\n let pixelValue = DEFAULT_PIXELS;\n if (pixels !== undefined) {\n pixelValue = parseInt(pixels, 10);\n if (isNaN(pixelValue) || pixelValue <= 0) {\n throw new Error(`无效的像素值: ${pixels}`);\n }\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"scroll\",\n direction: direction as ScrollDirection,\n pixels: pixelValue,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`已滚动: ${direction} ${pixelValue}px`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","import { isDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface DaemonOptions {\n json?: boolean;\n host?: string;\n}\n\nexport async function statusCommand(\n options: DaemonOptions = {}\n): Promise<void> {\n const running = await isDaemonRunning();\n\n if (options.json) {\n console.log(JSON.stringify({ running }));\n } else {\n console.log(running ? \"浏览器运行中\" : \"浏览器未运行\");\n }\n}\n","/**\n * reload 命令 - 通过 CDP 重载扩展\n * 用法:bb-browser reload\n * \n * 需要 Chrome 以 --remote-debugging-port=9222 启动\n * 并且 chrome://extensions 页面需要打开\n */\n\nimport WebSocket from \"ws\";\n\nexport interface ReloadOptions {\n json?: boolean;\n port?: number;\n}\n\nconst EXTENSION_NAME = \"bb-browser\";\n\nexport async function reloadCommand(\n options: ReloadOptions = {}\n): Promise<void> {\n const port = options.port || 9222;\n \n try {\n // 获取所有 targets\n const listRes = await fetch(`http://127.0.0.1:${port}/json/list`);\n if (!listRes.ok) {\n throw new Error(`CDP 未启用。请用 --remote-debugging-port=${port} 启动 Chrome`);\n }\n const list = await listRes.json();\n \n // 找到 chrome://extensions 页面\n const extPage = list.find((t: any) => \n t.type === \"page\" && \n t.url.includes(\"chrome://extensions\")\n );\n \n if (!extPage) {\n throw new Error(\"请先打开 chrome://extensions 页面\");\n }\n \n // 连接到 chrome://extensions 页面\n const result = await new Promise<{ success: boolean; message: string; extensionId?: string }>((resolve, reject) => {\n const ws = new WebSocket(extPage.webSocketDebuggerUrl);\n let resolved = false;\n \n const timeout = setTimeout(() => {\n if (!resolved) {\n resolved = true;\n ws.close();\n reject(new Error(\"CDP 连接超时\"));\n }\n }, 10000);\n \n ws.on(\"open\", () => {\n // 通过 developerPrivate API 查找 bb-browser 扩展并重载\n const script = `\n (async function() {\n if (!chrome || !chrome.developerPrivate) {\n return { error: 'developerPrivate API not available' };\n }\n \n try {\n const exts = await chrome.developerPrivate.getExtensionsInfo();\n const bbExt = exts.find(e => e.name === '${EXTENSION_NAME}');\n \n if (!bbExt) {\n return { error: '${EXTENSION_NAME} 扩展未安装' };\n }\n \n if (bbExt.state !== 'ENABLED') {\n return { error: '${EXTENSION_NAME} 扩展已禁用' };\n }\n \n await chrome.developerPrivate.reload(bbExt.id, {failQuietly: true});\n return { success: true, extensionId: bbExt.id };\n } catch (e) {\n return { error: e.message };\n }\n })()\n `;\n \n ws.send(JSON.stringify({\n id: 1,\n method: \"Runtime.evaluate\",\n params: { \n expression: script,\n awaitPromise: true,\n returnByValue: true\n }\n }));\n });\n \n ws.on(\"message\", (data) => {\n const msg = JSON.parse(data.toString());\n \n if (msg.id === 1) {\n clearTimeout(timeout);\n resolved = true;\n ws.close();\n \n const value = msg.result?.result?.value;\n if (value?.success) {\n resolve({ \n success: true, \n message: \"扩展已重载\",\n extensionId: value.extensionId \n });\n } else if (value?.error) {\n reject(new Error(value.error));\n } else {\n reject(new Error(`重载失败: ${JSON.stringify(value)}`));\n }\n }\n });\n \n ws.on(\"error\", (err) => {\n clearTimeout(timeout);\n if (!resolved) {\n resolved = true;\n reject(new Error(`CDP 连接失败: ${err.message}`));\n }\n });\n });\n \n if (options.json) {\n console.log(JSON.stringify(result));\n } else {\n console.log(`${result.message} (${result.extensionId})`);\n }\n \n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n \n if (options.json) {\n console.log(JSON.stringify({ success: false, error: message }));\n } else {\n console.error(`错误: ${message}`);\n }\n process.exit(1);\n }\n}\n","/**\n * 导航命令 - back/forward/refresh\n * 用法:\n * bb-browser back 后退\n * bb-browser forward 前进\n * bb-browser refresh 刷新页面\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface NavOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * back 命令 - 后退\n */\nexport async function backCommand(options: NavOptions = {}): Promise<void> {\n await ensureDaemonRunning();\n\n const request: Request = {\n id: generateId(),\n action: \"back\",\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const url = response.data?.url ?? \"\";\n if (url) {\n console.log(`后退至: ${url}`);\n } else {\n console.log(\"已后退\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n\n/**\n * forward 命令 - 前进\n */\nexport async function forwardCommand(options: NavOptions = {}): Promise<void> {\n await ensureDaemonRunning();\n\n const request: Request = {\n id: generateId(),\n action: \"forward\",\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const url = response.data?.url ?? \"\";\n if (url) {\n console.log(`前进至: ${url}`);\n } else {\n console.log(\"已前进\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n\n/**\n * refresh 命令 - 刷新页面\n */\nexport async function refreshCommand(options: NavOptions = {}): Promise<void> {\n await ensureDaemonRunning();\n\n const request: Request = {\n id: generateId(),\n action: \"refresh\",\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const title = response.data?.title ?? \"\";\n if (title) {\n console.log(`已刷新: \"${title}\"`);\n } else {\n console.log(\"已刷新页面\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * check/uncheck 命令 - 勾选/取消勾选复选框\n * 用法:\n * bb-browser check <ref> 勾选复选框\n * bb-browser uncheck <ref> 取消勾选复选框\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface CheckOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\n/**\n * 勾选复选框\n */\nexport async function checkCommand(\n ref: string,\n options: CheckOptions = {}\n): Promise<void> {\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n await ensureDaemonRunning();\n\n const parsedRef = parseRef(ref);\n\n const request: Request = {\n id: generateId(),\n action: \"check\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"checkbox\";\n const name = response.data?.name;\n const wasAlreadyChecked = response.data?.wasAlreadyChecked;\n \n if (wasAlreadyChecked) {\n if (name) {\n console.log(`已勾选(之前已勾选): ${role} \"${name}\"`);\n } else {\n console.log(`已勾选(之前已勾选): ${role}`);\n }\n } else {\n if (name) {\n console.log(`已勾选: ${role} \"${name}\"`);\n } else {\n console.log(`已勾选: ${role}`);\n }\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n\n/**\n * 取消勾选复选框\n */\nexport async function uncheckCommand(\n ref: string,\n options: CheckOptions = {}\n): Promise<void> {\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n await ensureDaemonRunning();\n\n const parsedRef = parseRef(ref);\n\n const request: Request = {\n id: generateId(),\n action: \"uncheck\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"checkbox\";\n const name = response.data?.name;\n const wasAlreadyUnchecked = response.data?.wasAlreadyUnchecked;\n \n if (wasAlreadyUnchecked) {\n if (name) {\n console.log(`已取消勾选(之前未勾选): ${role} \"${name}\"`);\n } else {\n console.log(`已取消勾选(之前未勾选): ${role}`);\n }\n } else {\n if (name) {\n console.log(`已取消勾选: ${role} \"${name}\"`);\n } else {\n console.log(`已取消勾选: ${role}`);\n }\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * select 命令 - 在下拉框中选择选项\n * 用法:bb-browser select <ref> <value>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n * \n * value:选项的 value 属性值或显示文本(label)\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface SelectOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function selectCommand(\n ref: string,\n value: string,\n options: SelectOptions = {}\n): Promise<void> {\n // 验证参数\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n if (value === undefined || value === null) {\n throw new Error(\"缺少 value 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"select\",\n ref: parsedRef,\n value: value,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"combobox\";\n const name = response.data?.name;\n const selectedValue = response.data?.selectedValue;\n const selectedLabel = response.data?.selectedLabel;\n if (name) {\n console.log(`已选择: ${role} \"${name}\"`);\n } else {\n console.log(`已选择: ${role}`);\n }\n if (selectedLabel && selectedLabel !== selectedValue) {\n console.log(`选项: \"${selectedLabel}\" (value=\"${selectedValue}\")`);\n } else {\n console.log(`选项: \"${selectedValue}\"`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * eval 命令 - 在当前页面执行 JavaScript\n * 用法:bb-browser eval \"<js>\"\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface EvalOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport async function evalCommand(\n script: string,\n options: EvalOptions = {}\n): Promise<void> {\n // 验证 script\n if (!script) {\n throw new Error(\"缺少 script 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"eval\",\n script,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const result = response.data?.result;\n if (result !== undefined) {\n // 如果结果是对象,格式化输出\n if (typeof result === \"object\" && result !== null) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(result);\n }\n } else {\n console.log(\"undefined\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * tab 命令 - 标签页管理\n * 用法:\n * bb-browser tab 列出所有标签页\n * bb-browser tab new [url] 新建标签页\n * bb-browser tab <n> 切换到第 n 个标签页(按 index)\n * bb-browser tab close [n] 关闭标签页(按 index)\n * bb-browser tab select --id <id> 切换到指定 tabId 的标签页\n * bb-browser tab close --id <id> 关闭指定 tabId 的标签页\n */\n\nimport { generateId, type Request, type Response, type TabInfo } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface TabOptions {\n json?: boolean;\n}\n\n/**\n * 解析 tab 子命令\n * @param args 命令参数数组(已去掉 flags)\n * @param rawArgv 原始 process.argv(用于提取 --id)\n * @returns 解析后的子命令和参数\n */\nfunction parseTabSubcommand(args: string[], rawArgv?: string[]): {\n action: \"tab_list\" | \"tab_new\" | \"tab_select\" | \"tab_close\";\n url?: string;\n index?: number;\n tabId?: number;\n} {\n // 提取 --id 参数\n let tabId: number | undefined;\n if (rawArgv) {\n const idIdx = rawArgv.indexOf(\"--id\");\n if (idIdx >= 0 && rawArgv[idIdx + 1]) {\n tabId = parseInt(rawArgv[idIdx + 1], 10);\n if (isNaN(tabId)) {\n throw new Error(`无效的 tabId: ${rawArgv[idIdx + 1]}`);\n }\n }\n }\n\n if (args.length === 0) {\n return { action: \"tab_list\" };\n }\n\n const first = args[0];\n\n // tab list\n if (first === \"list\") {\n return { action: \"tab_list\" };\n }\n\n // tab new [url]\n if (first === \"new\") {\n return { action: \"tab_new\", url: args[1] };\n }\n\n // tab select --id <tabId>\n if (first === \"select\") {\n if (tabId !== undefined) {\n return { action: \"tab_select\", tabId };\n }\n throw new Error(\"tab select 需要 --id 参数,用法:bb-browser tab select --id <tabId>\");\n }\n\n // tab close [n | --id <tabId>]\n if (first === \"close\") {\n if (tabId !== undefined) {\n return { action: \"tab_close\", tabId };\n }\n const indexArg = args[1];\n if (indexArg !== undefined) {\n const index = parseInt(indexArg, 10);\n if (isNaN(index) || index < 0) {\n throw new Error(`无效的标签页索引: ${indexArg}`);\n }\n return { action: \"tab_close\", index };\n }\n return { action: \"tab_close\" };\n }\n\n // tab <n> - 切换到第 n 个标签页\n const index = parseInt(first, 10);\n if (!isNaN(index) && index >= 0) {\n return { action: \"tab_select\", index };\n }\n\n throw new Error(`未知的 tab 子命令: ${first}`);\n}\n\n/**\n * 格式化标签页列表输出\n */\nfunction formatTabList(tabs: TabInfo[], activeIndex: number): string {\n const lines: string[] = [];\n lines.push(`标签页列表(共 ${tabs.length} 个,当前 #${activeIndex}):`);\n\n for (const tab of tabs) {\n const prefix = tab.active ? \"*\" : \" \";\n const title = tab.title || \"(无标题)\";\n lines.push(`${prefix} [${tab.index}] ${tab.url} - ${title}`);\n }\n\n return lines.join(\"\\n\");\n}\n\nexport async function tabCommand(\n args: string[],\n options: TabOptions = {}\n): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析子命令\n const parsed = parseTabSubcommand(args, process.argv);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: parsed.action,\n url: parsed.url,\n index: parsed.index,\n tabId: parsed.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n switch (parsed.action) {\n case \"tab_list\": {\n const tabs = response.data?.tabs ?? [];\n const activeIndex = response.data?.activeIndex ?? 0;\n console.log(formatTabList(tabs, activeIndex));\n break;\n }\n case \"tab_new\": {\n const url = response.data?.url ?? \"about:blank\";\n console.log(`已创建新标签页: ${url}`);\n break;\n }\n case \"tab_select\": {\n const title = response.data?.title ?? \"(无标题)\";\n const url = response.data?.url ?? \"\";\n console.log(`已切换到标签页 #${parsed.index}: ${title}`);\n console.log(` URL: ${url}`);\n break;\n }\n case \"tab_close\": {\n const closedTitle = response.data?.title ?? \"(无标题)\";\n console.log(`已关闭标签页: ${closedTitle}`);\n break;\n }\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * frame 命令 - 切换到 iframe 或返回主 frame\n * 用法:\n * bb-browser frame <selector> 切换到指定 iframe\n * bb-browser frame main 返回主 frame\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface FrameOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 切换到指定 iframe\n * @param selector CSS 选择器,用于定位 iframe 元素\n */\nexport async function frameCommand(\n selector: string,\n options: FrameOptions = {}\n): Promise<void> {\n if (!selector) {\n throw new Error(\"缺少 selector 参数\");\n }\n\n await ensureDaemonRunning();\n\n const request: Request = {\n id: generateId(),\n action: \"frame\",\n selector,\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const frameInfo = response.data?.frameInfo;\n if (frameInfo?.url) {\n console.log(`已切换到 frame: ${selector} (${frameInfo.url})`);\n } else {\n console.log(`已切换到 frame: ${selector}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n\n/**\n * 返回主 frame\n */\nexport async function frameMainCommand(\n options: FrameOptions = {}\n): Promise<void> {\n await ensureDaemonRunning();\n\n const request: Request = {\n id: generateId(),\n action: \"frame_main\",\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(\"已返回主 frame\");\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * dialog 命令 - 处理浏览器对话框(alert/confirm/prompt)\n * 用法:\n * bb-browser dialog accept [text] 接受对话框,可传入 prompt 文本\n * bb-browser dialog dismiss 拒绝/关闭对话框\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface DialogOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport async function dialogCommand(\n subCommand: string,\n promptText?: string,\n options: DialogOptions = {}\n): Promise<void> {\n // 验证子命令\n if (!subCommand || ![\"accept\", \"dismiss\"].includes(subCommand)) {\n throw new Error(\"请使用 'dialog accept [text]' 或 'dialog dismiss'\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"dialog\",\n dialogResponse: subCommand as \"accept\" | \"dismiss\",\n promptText: subCommand === \"accept\" ? promptText : undefined,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const dialogInfo = response.data?.dialogInfo;\n if (dialogInfo) {\n const action = subCommand === \"accept\" ? \"已接受\" : \"已拒绝\";\n console.log(`${action}对话框(${dialogInfo.type}): \"${dialogInfo.message}\"`);\n } else {\n console.log(\"对话框已处理\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * network 命令 - 网络监控和拦截\n */\n\nimport { sendCommand } from \"../client.js\";\n\ninterface NetworkOptions {\n json?: boolean;\n abort?: boolean;\n body?: string;\n withBody?: boolean;\n tabId?: number;\n}\n\nexport async function networkCommand(\n subCommand: string,\n urlOrFilter?: string,\n options: NetworkOptions = {}\n): Promise<void> {\n const response = await sendCommand({\n id: crypto.randomUUID(),\n action: \"network\",\n networkCommand: subCommand as \"requests\" | \"route\" | \"unroute\" | \"clear\",\n url: subCommand === \"route\" || subCommand === \"unroute\" ? urlOrFilter : undefined,\n filter: subCommand === \"requests\" ? urlOrFilter : undefined,\n routeOptions: subCommand === \"route\" ? {\n abort: options.abort,\n body: options.body,\n } : undefined,\n withBody: subCommand === \"requests\" ? options.withBody : undefined,\n tabId: options.tabId,\n });\n\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n\n if (!response.success) {\n throw new Error(response.error || \"Network command failed\");\n }\n\n const data = response.data;\n\n switch (subCommand) {\n case \"requests\": {\n const requests = data?.networkRequests || [];\n if (requests.length === 0) {\n console.log(\"没有网络请求记录\");\n console.log(\"提示: 使用 network requests 会自动开始监控\");\n } else {\n console.log(`网络请求 (${requests.length} 条):\\n`);\n for (const req of requests) {\n const status = req.failed \n ? `FAILED (${req.failureReason})` \n : (req.status ? `${req.status} ${req.statusText || ''}` : 'pending');\n console.log(`${req.method} ${req.url}`);\n console.log(` 类型: ${req.type}, 状态: ${status}`);\n if (options.withBody) {\n const requestHeaderCount = req.requestHeaders ? Object.keys(req.requestHeaders).length : 0;\n const responseHeaderCount = req.responseHeaders ? Object.keys(req.responseHeaders).length : 0;\n console.log(` 请求头: ${requestHeaderCount}, 响应头: ${responseHeaderCount}`);\n if (req.requestBody !== undefined) {\n const preview = req.requestBody.length > 200 ? `${req.requestBody.slice(0, 200)}...` : req.requestBody;\n console.log(` 请求体: ${preview}`);\n }\n if (req.responseBody !== undefined) {\n const preview = req.responseBody.length > 200 ? `${req.responseBody.slice(0, 200)}...` : req.responseBody;\n console.log(` 响应体: ${preview}`);\n }\n if (req.bodyError) {\n console.log(` Body错误: ${req.bodyError}`);\n }\n }\n console.log(\"\");\n }\n }\n break;\n }\n\n case \"route\": {\n console.log(`已添加拦截规则: ${urlOrFilter}`);\n if (options.abort) {\n console.log(\" 行为: 阻止请求\");\n } else if (options.body) {\n console.log(\" 行为: 返回 mock 数据\");\n } else {\n console.log(\" 行为: 继续请求\");\n }\n console.log(`当前规则数: ${data?.routeCount || 0}`);\n break;\n }\n\n case \"unroute\": {\n if (urlOrFilter) {\n console.log(`已移除拦截规则: ${urlOrFilter}`);\n } else {\n console.log(\"已移除所有拦截规则\");\n }\n console.log(`剩余规则数: ${data?.routeCount || 0}`);\n break;\n }\n\n case \"clear\": {\n console.log(\"已清空网络请求记录\");\n break;\n }\n\n default:\n throw new Error(`未知的 network 子命令: ${subCommand}`);\n }\n}\n","/**\n * console 命令 - 查看控制台消息\n */\n\nimport { sendCommand } from \"../client.js\";\n\ninterface ConsoleOptions {\n json?: boolean;\n clear?: boolean;\n tabId?: number;\n}\n\nexport async function consoleCommand(options: ConsoleOptions = {}): Promise<void> {\n const response = await sendCommand({\n id: crypto.randomUUID(),\n action: \"console\",\n consoleCommand: options.clear ? \"clear\" : \"get\",\n tabId: options.tabId,\n });\n\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n\n if (!response.success) {\n throw new Error(response.error || \"Console command failed\");\n }\n\n if (options.clear) {\n console.log(\"已清空控制台消息\");\n return;\n }\n\n const messages = response.data?.consoleMessages || [];\n \n if (messages.length === 0) {\n console.log(\"没有控制台消息\");\n console.log(\"提示: console 命令会自动开始监控\");\n return;\n }\n\n console.log(`控制台消息 (${messages.length} 条):\\n`);\n\n const typeColors: Record<string, string> = {\n log: \"\",\n info: \"[INFO]\",\n warn: \"[WARN]\",\n error: \"[ERROR]\",\n debug: \"[DEBUG]\",\n };\n\n for (const msg of messages) {\n const prefix = typeColors[msg.type] || `[${msg.type.toUpperCase()}]`;\n const location = msg.url ? ` (${msg.url}${msg.lineNumber ? `:${msg.lineNumber}` : \"\"})` : \"\";\n \n if (prefix) {\n console.log(`${prefix} ${msg.text}${location}`);\n } else {\n console.log(`${msg.text}${location}`);\n }\n }\n}\n","/**\n * errors 命令 - 查看 JS 错误\n */\n\nimport { sendCommand } from \"../client.js\";\n\ninterface ErrorsOptions {\n json?: boolean;\n clear?: boolean;\n tabId?: number;\n}\n\nexport async function errorsCommand(options: ErrorsOptions = {}): Promise<void> {\n const response = await sendCommand({\n id: crypto.randomUUID(),\n action: \"errors\",\n errorsCommand: options.clear ? \"clear\" : \"get\",\n tabId: options.tabId,\n });\n\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n\n if (!response.success) {\n throw new Error(response.error || \"Errors command failed\");\n }\n\n if (options.clear) {\n console.log(\"已清空 JS 错误记录\");\n return;\n }\n\n const errors = response.data?.jsErrors || [];\n \n if (errors.length === 0) {\n console.log(\"没有 JS 错误\");\n console.log(\"提示: errors 命令会自动开始监控\");\n return;\n }\n\n console.log(`JS 错误 (${errors.length} 条):\\n`);\n\n for (const err of errors) {\n console.log(`[ERROR] ${err.message}`);\n if (err.url) {\n console.log(` 位置: ${err.url}:${err.lineNumber || 0}:${err.columnNumber || 0}`);\n }\n if (err.stackTrace) {\n console.log(` 堆栈:`);\n console.log(err.stackTrace.split('\\n').map(line => ` ${line}`).join('\\n'));\n }\n console.log(\"\");\n }\n}\n","/**\n * trace 命令 - 录制用户操作\n * \n * 用法:\n * bb-browser trace start 开始录制\n * bb-browser trace stop 停止录制,输出事件列表\n * bb-browser trace status 查看录制状态\n */\n\nimport { sendCommand } from \"../client.js\";\n\ninterface TraceOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport async function traceCommand(\n subCommand: 'start' | 'stop' | 'status',\n options: TraceOptions = {}\n): Promise<void> {\n const response = await sendCommand({\n id: crypto.randomUUID(),\n action: \"trace\",\n traceCommand: subCommand,\n tabId: options.tabId,\n });\n\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n\n if (!response.success) {\n throw new Error(response.error || \"Trace command failed\");\n }\n\n const data = response.data;\n\n switch (subCommand) {\n case \"start\": {\n const status = data?.traceStatus;\n console.log(\"开始录制用户操作\");\n console.log(`标签页 ID: ${status?.tabId || 'N/A'}`);\n console.log(\"\\n在浏览器中进行操作,完成后运行 'bb-browser trace stop' 停止录制\");\n break;\n }\n\n case \"stop\": {\n const events = data?.traceEvents || [];\n const status = data?.traceStatus;\n \n console.log(`录制完成,共 ${events.length} 个事件\\n`);\n \n if (events.length === 0) {\n console.log(\"没有录制到任何操作\");\n break;\n }\n \n // 输出事件列表\n for (let i = 0; i < events.length; i++) {\n const event = events[i];\n const refStr = event.ref !== undefined ? `@${event.ref}` : '';\n \n switch (event.type) {\n case 'navigation':\n console.log(`${i + 1}. 导航到: ${event.url}`);\n break;\n case 'click':\n console.log(`${i + 1}. 点击 ${refStr} [${event.elementRole}] \"${event.elementName || ''}\"`);\n break;\n case 'fill':\n console.log(`${i + 1}. 填充 ${refStr} [${event.elementRole}] \"${event.elementName || ''}\" <- \"${event.value}\"`);\n break;\n case 'select':\n console.log(`${i + 1}. 选择 ${refStr} [${event.elementRole}] \"${event.elementName || ''}\" <- \"${event.value}\"`);\n break;\n case 'check':\n console.log(`${i + 1}. ${event.checked ? '勾选' : '取消勾选'} ${refStr} [${event.elementRole}] \"${event.elementName || ''}\"`);\n break;\n case 'press':\n console.log(`${i + 1}. 按键 ${event.key}`);\n break;\n case 'scroll':\n console.log(`${i + 1}. 滚动 ${event.direction} ${event.pixels}px`);\n break;\n default:\n console.log(`${i + 1}. ${event.type}`);\n }\n }\n \n console.log(`\\n状态: ${status?.recording ? '录制中' : '已停止'}`);\n break;\n }\n\n case \"status\": {\n const status = data?.traceStatus;\n if (status?.recording) {\n console.log(`录制中 (标签页 ${status.tabId})`);\n console.log(`已录制 ${status.eventCount} 个事件`);\n } else {\n console.log(\"未在录制\");\n }\n break;\n }\n\n default:\n throw new Error(`未知的 trace 子命令: ${subCommand}`);\n }\n}\n","/**\n * fetch 命令 - 在浏览器上下文中执行 fetch(),自动处理同源路由\n *\n * 用法:\n * bb-browser fetch <url> [options]\n * bb-browser fetch https://www.reddit.com/api/me.json\n * bb-browser fetch /api/me.json # 相对路径,用当前 tab 的 origin\n * bb-browser fetch https://www.reddit.com/... --json\n * bb-browser fetch https://x.com/... --method POST --body '{\"query\":\"...\"}'\n *\n * 本质:curl,但带浏览器登录态。\n */\n\nimport { generateId, type Request, type Response, type TabInfo } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface FetchOptions {\n json?: boolean;\n method?: string;\n body?: string;\n headers?: string;\n output?: string;\n tabId?: number;\n}\n\n/**\n * 精确匹配 tab 的 origin\n */\nfunction matchTabOrigin(tabUrl: string, targetHostname: string): boolean {\n try {\n const tabHostname = new URL(tabUrl).hostname;\n return tabHostname === targetHostname || tabHostname.endsWith(\".\" + targetHostname);\n } catch {\n return false;\n }\n}\n\n/**\n * 找到匹配域名的 tab,如果没有则新建\n */\nasync function ensureTabForOrigin(origin: string, hostname: string): Promise<number | undefined> {\n const listReq: Request = { id: generateId(), action: \"tab_list\" };\n const listResp: Response = await sendCommand(listReq);\n\n if (listResp.success && listResp.data?.tabs) {\n const matchingTab = listResp.data.tabs.find((tab: TabInfo) =>\n matchTabOrigin(tab.url, hostname)\n );\n\n if (matchingTab) {\n return matchingTab.tabId;\n }\n }\n\n const newResp: Response = await sendCommand({ id: generateId(), action: \"tab_new\", url: origin });\n if (!newResp.success) {\n throw new Error(`无法打开 ${origin}: ${newResp.error}`);\n }\n await new Promise((resolve) => setTimeout(resolve, 3000));\n return newResp.data?.tabId;\n}\n\n/**\n * 构造浏览器内执行的 fetch JS 代码\n * 修复 Codex review: headers 通过 JSON.stringify 传入,不做字符串拼接\n */\nfunction buildFetchScript(url: string, options: FetchOptions): string {\n const method = (options.method || \"GET\").toUpperCase();\n const hasBody = options.body && method !== \"GET\" && method !== \"HEAD\";\n\n // headers 通过 JSON.parse 安全传入,避免代码注入\n let headersExpr = \"{}\";\n if (options.headers) {\n try {\n // 验证是合法 JSON\n JSON.parse(options.headers);\n headersExpr = options.headers;\n } catch {\n throw new Error(`--headers must be valid JSON. Got: ${options.headers}`);\n }\n }\n\n return `(async () => {\n try {\n const resp = await fetch(${JSON.stringify(url)}, {\n method: ${JSON.stringify(method)},\n credentials: 'include',\n headers: ${headersExpr}${hasBody ? `,\\n body: ${JSON.stringify(options.body)}` : \"\"}\n });\n const contentType = resp.headers.get('content-type') || '';\n let body;\n if (contentType.includes('application/json') && resp.status !== 204) {\n try { body = await resp.json(); } catch { body = await resp.text(); }\n } else {\n body = await resp.text();\n }\n return JSON.stringify({\n status: resp.status,\n contentType,\n body\n });\n } catch (e) {\n return JSON.stringify({ error: e.message });\n }\n })()`;\n}\n\nexport async function fetchCommand(\n url: string,\n options: FetchOptions = {}\n): Promise<void> {\n if (!url) {\n throw new Error(\n \"缺少 URL 参数\\n\" +\n \" 用法: bb-browser fetch <url> [--json] [--method POST] [--body '{...}']\\n\" +\n \" 示例: bb-browser fetch https://www.reddit.com/api/me.json --json\"\n );\n }\n\n await ensureDaemonRunning();\n\n const isAbsolute = url.startsWith(\"http://\") || url.startsWith(\"https://\");\n let targetTabId = options.tabId;\n\n if (isAbsolute) {\n let origin: string;\n let hostname: string;\n try {\n const parsed = new URL(url);\n origin = parsed.origin;\n hostname = parsed.hostname;\n } catch {\n throw new Error(`无效的 URL: ${url}`);\n }\n\n if (!targetTabId) {\n targetTabId = await ensureTabForOrigin(origin, hostname);\n }\n }\n\n const script = buildFetchScript(url, options);\n const evalReq: Request = { id: generateId(), action: \"eval\", script, tabId: targetTabId };\n const evalResp: Response = await sendCommand(evalReq);\n\n if (!evalResp.success) {\n throw new Error(`Fetch 失败: ${evalResp.error}`);\n }\n\n const rawResult = evalResp.data?.result;\n if (rawResult === undefined || rawResult === null) {\n throw new Error(\"Fetch 未返回结果\");\n }\n\n let result: { status?: number; contentType?: string; body?: unknown; error?: string };\n try {\n result = typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult as typeof result;\n } catch {\n console.log(rawResult);\n return;\n }\n\n if (result.error) {\n throw new Error(`Fetch error: ${result.error}`);\n }\n\n // 写文件\n if (options.output) {\n const { writeFileSync } = await import(\"node:fs\");\n const content = typeof result.body === \"object\"\n ? JSON.stringify(result.body, null, 2)\n : String(result.body);\n writeFileSync(options.output, content, \"utf-8\");\n console.log(`已写入 ${options.output} (${result.status}, ${content.length} bytes)`);\n return;\n }\n\n // 输出\n if (typeof result.body === \"object\") {\n console.log(JSON.stringify(result.body, null, 2));\n } else {\n console.log(result.body);\n }\n}\n","/**\n * history 命令 - 查询 Chrome 浏览历史\n *\n * 用法:\n * bb-browser history search [query] 搜索历史记录\n * bb-browser history domains 查看访问最多的域名\n */\n\nimport { getHistoryDomains, searchHistory } from \"../history-sqlite.js\";\n\ninterface HistoryOptions {\n json?: boolean;\n days?: number;\n query?: string;\n}\n\nexport async function historyCommand(\n subCommand: 'search' | 'domains',\n options: HistoryOptions = {}\n): Promise<void> {\n const days = options.days || 30;\n const data = subCommand === \"search\"\n ? { historyItems: searchHistory(options.query, days) }\n : { historyDomains: getHistoryDomains(days) };\n\n if (options.json) {\n console.log(JSON.stringify({\n id: crypto.randomUUID(),\n success: true,\n data,\n }));\n return;\n }\n\n switch (subCommand) {\n case \"search\": {\n const items = data?.historyItems || [];\n\n console.log(`找到 ${items.length} 条历史记录\\n`);\n\n if (items.length === 0) {\n console.log(\"没有找到匹配的历史记录\");\n break;\n }\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n console.log(`${i + 1}. ${item.title || '(无标题)'}`);\n console.log(` ${item.url}`);\n console.log(` 访问次数: ${item.visitCount}`);\n }\n break;\n }\n\n case \"domains\": {\n const domains = data?.historyDomains || [];\n\n console.log(`找到 ${domains.length} 个域名\\n`);\n\n if (domains.length === 0) {\n console.log(\"没有找到历史记录\");\n break;\n }\n\n for (let i = 0; i < domains.length; i++) {\n const domain = domains[i];\n console.log(`${i + 1}. ${domain.domain}`);\n console.log(` 访问次数: ${domain.visits}`);\n }\n break;\n }\n\n default:\n throw new Error(`未知的 history 子命令: ${subCommand}`);\n }\n}\n"],"mappings":"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","names":["fileURLToPath","os","path","resolve","resolve","resolve","target","path","os","path","pageUrl","resolve","sendCommand","fileURLToPath","existsSync","existsSync","unlinkSync","execSync","readFileSync","existsSync","join","homedir","execSync","resolve","parsed","applyJq","sendCommand","spawn","sendCommand","sendCommand","parseRef","sendCommand","parseRef","sendCommand","parseRef","sendCommand","parseRef","sendCommand","sendCommand","parseRef","sendCommand","path","os","path","os","sendCommand","parseRef","sendCommand","sendCommand","sendCommand","WebSocket","resolve","sendCommand","parseRef","sendCommand","parseRef","sendCommand","sendCommand","index","sendCommand","sendCommand","sendCommand","sendCommand","sendCommand","sendCommand","sendCommand","matchTabOrigin","sendCommand","resolve","writeFileSync","fileURLToPath","spawn","execSync"]}
|
|
1
|
+
{"version":3,"sources":["../packages/cli/src/index.ts","../packages/cli/src/cdp-client.ts","../packages/cli/src/cdp-discovery.ts","../packages/cli/src/client.ts","../packages/cli/src/daemon-manager.ts","../packages/cli/src/history-sqlite.ts","../packages/cli/src/commands/site.ts","../packages/cli/src/commands/open.ts","../packages/cli/src/commands/snapshot.ts","../packages/cli/src/commands/click.ts","../packages/cli/src/commands/hover.ts","../packages/cli/src/commands/fill.ts","../packages/cli/src/commands/type.ts","../packages/cli/src/commands/close.ts","../packages/cli/src/commands/get.ts","../packages/cli/src/commands/screenshot.ts","../packages/cli/src/commands/wait.ts","../packages/cli/src/commands/press.ts","../packages/cli/src/commands/scroll.ts","../packages/cli/src/commands/nav.ts","../packages/cli/src/commands/check.ts","../packages/cli/src/commands/select.ts","../packages/cli/src/commands/eval.ts","../packages/cli/src/commands/tab.ts","../packages/cli/src/commands/frame.ts","../packages/cli/src/commands/dialog.ts","../packages/cli/src/commands/network.ts","../packages/cli/src/commands/console.ts","../packages/cli/src/commands/errors.ts","../packages/cli/src/commands/trace.ts","../packages/cli/src/commands/fetch.ts","../packages/cli/src/commands/history.ts"],"sourcesContent":["/**\n * bb-browser CLI 入口\n */\n\nimport { fileURLToPath } from \"node:url\";\nimport { openCommand } from \"./commands/open.js\";\nimport { snapshotCommand } from \"./commands/snapshot.js\";\nimport { clickCommand } from \"./commands/click.js\";\nimport { hoverCommand } from \"./commands/hover.js\";\nimport { fillCommand } from \"./commands/fill.js\";\nimport { typeCommand } from \"./commands/type.js\";\nimport { closeCommand } from \"./commands/close.js\";\nimport { getCommand, type GetAttribute } from \"./commands/get.js\";\nimport { screenshotCommand } from \"./commands/screenshot.js\";\nimport { waitCommand } from \"./commands/wait.js\";\nimport { pressCommand } from \"./commands/press.js\";\nimport { scrollCommand } from \"./commands/scroll.js\";\nimport { backCommand, forwardCommand, refreshCommand } from \"./commands/nav.js\";\nimport { checkCommand, uncheckCommand } from \"./commands/check.js\";\nimport { selectCommand } from \"./commands/select.js\";\nimport { evalCommand } from \"./commands/eval.js\";\nimport { tabCommand } from \"./commands/tab.js\";\nimport { frameCommand, frameMainCommand } from \"./commands/frame.js\";\nimport { dialogCommand } from \"./commands/dialog.js\";\nimport { networkCommand } from \"./commands/network.js\";\nimport { consoleCommand } from \"./commands/console.js\";\nimport { errorsCommand } from \"./commands/errors.js\";\nimport { traceCommand } from \"./commands/trace.js\";\nimport { fetchCommand } from \"./commands/fetch.js\";\nimport { siteCommand } from \"./commands/site.js\";\nimport { historyCommand } from \"./commands/history.js\";\nimport { setJqExpression } from \"./client.js\";\n\nconst VERSION = \"0.8.2\";\n\nconst HELP_TEXT = `\nbb-browser - AI Agent 浏览器自动化工具\n\n安装:\n npm install -g bb-browser\n\n提示:大多数数据获取任务请直接使用 site 命令,无需手动操作浏览器:\n bb-browser site list 查看所有可用命令\n bb-browser site twitter/search \"AI\" 示例:搜索推文\n bb-browser site xueqiu/hot-stock 5 示例:获取人气股票\n\n用法:\n bb-browser <command> [options]\n\n开始使用:\n site recommend 推荐你可能需要的 adapter(基于浏览历史)\n site list 列出所有 adapter\n site info <name> 查看 adapter 用法(参数、返回值、示例)\n site <name> [args] 运行 adapter\n site update 更新社区 adapter 库\n guide 如何把任何网站变成 adapter\n star ⭐ Star bb-browser on GitHub\n\n浏览器操作:\n open <url> [--tab] 打开 URL\n snapshot [-i] [-c] [-d <n>] 获取页面快照\n click <ref> 点击元素\n hover <ref> 悬停元素\n fill <ref> <text> 填充输入框(清空后填入)\n type <ref> <text> 逐字符输入(不清空)\n check/uncheck <ref> 勾选/取消复选框\n select <ref> <val> 下拉框选择\n press <key> 发送按键\n scroll <dir> [px] 滚动页面\n\n页面信息:\n get text|url|title <ref> 获取页面内容\n screenshot [path] 截图\n eval \"<js>\" 执行 JavaScript\n fetch <url> 带登录态的 HTTP 请求\n\n标签页:\n tab [list|new|close|<n>] 管理标签页\n status 查看受管浏览器状态\n\n导航:\n back / forward / refresh 后退 / 前进 / 刷新\n\n调试:\n network requests [filter] 查看网络请求\n console [--clear] 查看/清空控制台\n errors [--clear] 查看/清空 JS 错误\n trace start|stop|status 录制用户操作\n history search|domains 查看浏览历史\n\n选项:\n --json 以 JSON 格式输出\n --port <n> 指定 Chrome CDP 端口\n --openclaw 优先复用 OpenClaw 浏览器实例\n --jq <expr> 对 JSON 输出应用 jq 过滤(直接作用于数据,跳过 id/success 信封)\n -i, --interactive 只输出可交互元素(snapshot 命令)\n -c, --compact 移除空结构节点(snapshot 命令)\n -d, --depth <n> 限制树深度(snapshot 命令)\n -s, --selector <sel> 限定 CSS 选择器范围(snapshot 命令)\n --tab <tabId> 指定操作的标签页 ID\n --mcp 启动 MCP server(用于 Claude Code / Cursor 等 AI 工具)\n --help, -h 显示帮助信息\n --version, -v 显示版本号\n`.trim();\n\ninterface ParsedArgs {\n command: string | null;\n args: string[];\n flags: {\n json: boolean;\n help: boolean;\n version: boolean;\n interactive: boolean;\n compact: boolean;\n depth?: number;\n selector?: string;\n tab?: string;\n days?: number;\n jq?: string;\n openclaw?: boolean;\n port?: number;\n };\n}\n\n/**\n * 解析命令行参数\n */\nfunction parseArgs(argv: string[]): ParsedArgs {\n const args = argv.slice(2); // 跳过 node 和脚本路径\n\n const result: ParsedArgs = {\n command: null,\n args: [],\n flags: {\n json: false,\n help: false,\n version: false,\n interactive: false,\n compact: false,\n },\n };\n\n let skipNext = false;\n for (const arg of args) {\n if (skipNext) {\n skipNext = false;\n continue;\n }\n if (arg === \"--json\") {\n result.flags.json = true;\n } else if (arg === \"--jq\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.jq = args[nextIdx];\n result.flags.json = true;\n }\n } else if (arg === \"--openclaw\") {\n result.flags.openclaw = true;\n } else if (arg === \"--port\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.port = parseInt(args[nextIdx], 10);\n }\n } else if (arg === \"--help\" || arg === \"-h\") {\n result.flags.help = true;\n } else if (arg === \"--version\" || arg === \"-v\") {\n result.flags.version = true;\n } else if (arg === \"--interactive\" || arg === \"-i\") {\n result.flags.interactive = true;\n } else if (arg === \"--compact\" || arg === \"-c\") {\n result.flags.compact = true;\n } else if (arg === \"--depth\" || arg === \"-d\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.depth = parseInt(args[nextIdx], 10);\n }\n } else if (arg === \"--selector\" || arg === \"-s\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.selector = args[nextIdx];\n }\n } else if (arg === \"--days\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.days = parseInt(args[nextIdx], 10);\n }\n } else if (arg === \"--id\") {\n // --id 及其值由子命令通过 process.argv 自行解析,这里跳过\n skipNext = true;\n } else if (arg === \"--tab\") {\n // --tab 参数及其值,无论出现在命令前后都跳过\n skipNext = true;\n } else if (arg.startsWith(\"-\")) {\n // 未知选项,忽略\n } else if (result.command === null) {\n result.command = arg;\n } else {\n result.args.push(arg);\n }\n }\n\n return result;\n}\n\n/**\n * 主函数\n */\nasync function main(): Promise<void> {\n const parsed = parseArgs(process.argv);\n setJqExpression(parsed.flags.jq);\n\n // 解析全局 --tab 参数\n const tabArgIdx = process.argv.indexOf('--tab');\n const globalTabId = tabArgIdx >= 0 && process.argv[tabArgIdx + 1]\n ? parseInt(process.argv[tabArgIdx + 1], 10)\n : undefined;\n\n // 处理全局选项\n if (parsed.flags.version) {\n console.log(VERSION);\n return;\n }\n\n if (process.argv.includes(\"--mcp\")) {\n const mcpPath = fileURLToPath(new URL(\"./mcp.js\", import.meta.url));\n const { spawn } = await import(\"node:child_process\");\n const child = spawn(process.execPath, [mcpPath], { stdio: \"inherit\" });\n child.on(\"exit\", (code) => process.exit(code ?? 0));\n return;\n }\n\n if (parsed.flags.help || !parsed.command) {\n console.log(HELP_TEXT);\n return;\n }\n\n // 路由到对应命令\n try {\n switch (parsed.command) {\n case \"open\": {\n const url = parsed.args[0];\n if (!url) {\n console.error(\"错误:缺少 URL 参数\");\n console.error(\"用法:bb-browser open <url> [--tab current|<tabId>]\");\n process.exit(1);\n }\n // 解析 --tab 参数\n const tabIndex = process.argv.findIndex(a => a === \"--tab\");\n const tab = tabIndex >= 0 ? process.argv[tabIndex + 1] : undefined;\n await openCommand(url, { json: parsed.flags.json, tab });\n break;\n }\n\n case \"snapshot\": {\n await snapshotCommand({\n json: parsed.flags.json,\n interactive: parsed.flags.interactive,\n compact: parsed.flags.compact,\n maxDepth: parsed.flags.depth,\n selector: parsed.flags.selector,\n tabId: globalTabId,\n });\n break;\n }\n\n case \"click\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser click <ref>\");\n console.error(\"示例:bb-browser click @5\");\n process.exit(1);\n }\n await clickCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"hover\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser hover <ref>\");\n console.error(\"示例:bb-browser hover @5\");\n process.exit(1);\n }\n await hoverCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"check\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser check <ref>\");\n console.error(\"示例:bb-browser check @5\");\n process.exit(1);\n }\n await checkCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"uncheck\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser uncheck <ref>\");\n console.error(\"示例:bb-browser uncheck @5\");\n process.exit(1);\n }\n await uncheckCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"fill\": {\n const ref = parsed.args[0];\n const text = parsed.args[1];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser fill <ref> <text>\");\n console.error('示例:bb-browser fill @3 \"hello world\"');\n process.exit(1);\n }\n if (text === undefined) {\n console.error(\"错误:缺少 text 参数\");\n console.error(\"用法:bb-browser fill <ref> <text>\");\n console.error('示例:bb-browser fill @3 \"hello world\"');\n process.exit(1);\n }\n await fillCommand(ref, text, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"type\": {\n const ref = parsed.args[0];\n const text = parsed.args[1];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser type <ref> <text>\");\n console.error('示例:bb-browser type @3 \"append text\"');\n process.exit(1);\n }\n if (text === undefined) {\n console.error(\"错误:缺少 text 参数\");\n console.error(\"用法:bb-browser type <ref> <text>\");\n console.error('示例:bb-browser type @3 \"append text\"');\n process.exit(1);\n }\n await typeCommand(ref, text, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"select\": {\n const ref = parsed.args[0];\n const value = parsed.args[1];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser select <ref> <value>\");\n console.error('示例:bb-browser select @4 \"option1\"');\n process.exit(1);\n }\n if (value === undefined) {\n console.error(\"错误:缺少 value 参数\");\n console.error(\"用法:bb-browser select <ref> <value>\");\n console.error('示例:bb-browser select @4 \"option1\"');\n process.exit(1);\n }\n await selectCommand(ref, value, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"eval\": {\n const script = parsed.args[0];\n if (!script) {\n console.error(\"错误:缺少 script 参数\");\n console.error(\"用法:bb-browser eval <script>\");\n console.error('示例:bb-browser eval \"document.title\"');\n process.exit(1);\n }\n await evalCommand(script, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"get\": {\n const attribute = parsed.args[0] as GetAttribute | undefined;\n if (!attribute) {\n console.error(\"错误:缺少属性参数\");\n console.error(\"用法:bb-browser get <text|url|title> [ref]\");\n console.error(\"示例:bb-browser get text @5\");\n console.error(\" bb-browser get url\");\n process.exit(1);\n }\n if (![\"text\", \"url\", \"title\"].includes(attribute)) {\n console.error(`错误:未知属性 \"${attribute}\"`);\n console.error(\"支持的属性:text, url, title\");\n process.exit(1);\n }\n const ref = parsed.args[1];\n await getCommand(attribute, ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"daemon\":\n\n case \"close\": {\n await closeCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"back\": {\n await backCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"forward\": {\n await forwardCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"refresh\": {\n await refreshCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"screenshot\": {\n const outputPath = parsed.args[0];\n await screenshotCommand(outputPath, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"wait\": {\n const target = parsed.args[0];\n if (!target) {\n console.error(\"错误:缺少等待目标参数\");\n console.error(\"用法:bb-browser wait <ms|@ref>\");\n console.error(\"示例:bb-browser wait 2000\");\n console.error(\" bb-browser wait @5\");\n process.exit(1);\n }\n await waitCommand(target, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"press\": {\n const key = parsed.args[0];\n if (!key) {\n console.error(\"错误:缺少 key 参数\");\n console.error(\"用法:bb-browser press <key>\");\n console.error(\"示例:bb-browser press Enter\");\n console.error(\" bb-browser press Control+a\");\n process.exit(1);\n }\n await pressCommand(key, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"scroll\": {\n const direction = parsed.args[0];\n const pixels = parsed.args[1]; // 传 string,scrollCommand 内部解析\n if (!direction) {\n console.error(\"错误:缺少方向参数\");\n console.error(\"用法:bb-browser scroll <up|down|left|right> [pixels]\");\n console.error(\"示例:bb-browser scroll down\");\n console.error(\" bb-browser scroll up 500\");\n process.exit(1);\n }\n await scrollCommand(direction, pixels, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"tab\": {\n await tabCommand(parsed.args, { json: parsed.flags.json });\n break;\n }\n\n case \"frame\": {\n const selectorOrMain = parsed.args[0];\n if (!selectorOrMain) {\n console.error(\"错误:缺少 selector 参数\");\n console.error(\"用法:bb-browser frame <selector>\");\n console.error('示例:bb-browser frame \"iframe#editor\"');\n console.error(\" bb-browser frame main\");\n process.exit(1);\n }\n if (selectorOrMain === \"main\") {\n await frameMainCommand({ json: parsed.flags.json, tabId: globalTabId });\n } else {\n await frameCommand(selectorOrMain, { json: parsed.flags.json, tabId: globalTabId });\n }\n break;\n }\n\n case \"dialog\": {\n const subCommand = parsed.args[0];\n if (!subCommand) {\n console.error(\"错误:缺少子命令\");\n console.error(\"用法:bb-browser dialog <accept|dismiss> [text]\");\n console.error(\"示例:bb-browser dialog accept\");\n console.error(' bb-browser dialog accept \"my input\"');\n console.error(\" bb-browser dialog dismiss\");\n process.exit(1);\n }\n const promptText = parsed.args[1]; // accept 时可选的 prompt 文本\n await dialogCommand(subCommand, promptText, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"network\": {\n const subCommand = parsed.args[0] || \"requests\";\n const urlOrFilter = parsed.args[1];\n // 解析 network 特有的选项\n const abort = process.argv.includes(\"--abort\");\n const withBody = process.argv.includes(\"--with-body\");\n const bodyIndex = process.argv.findIndex(a => a === \"--body\");\n const body = bodyIndex >= 0 ? process.argv[bodyIndex + 1] : undefined;\n await networkCommand(subCommand, urlOrFilter, { json: parsed.flags.json, abort, body, withBody, tabId: globalTabId });\n break;\n }\n\n case \"console\": {\n const clear = process.argv.includes(\"--clear\");\n await consoleCommand({ json: parsed.flags.json, clear, tabId: globalTabId });\n break;\n }\n\n case \"errors\": {\n const clear = process.argv.includes(\"--clear\");\n await errorsCommand({ json: parsed.flags.json, clear, tabId: globalTabId });\n break;\n }\n\n case \"trace\": {\n const subCmd = parsed.args[0] as 'start' | 'stop' | 'status' | undefined;\n if (!subCmd || !['start', 'stop', 'status'].includes(subCmd)) {\n console.error(\"错误:缺少或无效的子命令\");\n console.error(\"用法:bb-browser trace <start|stop|status>\");\n console.error(\"示例:bb-browser trace start\");\n console.error(\" bb-browser trace stop\");\n console.error(\" bb-browser trace status\");\n process.exit(1);\n }\n await traceCommand(subCmd, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"history\": {\n const subCmd = parsed.args[0] as 'search' | 'domains' | undefined;\n if (!subCmd || !['search', 'domains'].includes(subCmd)) {\n console.error(\"错误:缺少或无效的子命令\");\n console.error(\"用法:bb-browser history <search|domains> [query] [--days <n>]\");\n console.error(\"示例:bb-browser history search github\");\n console.error(\" bb-browser history domains --days 7\");\n process.exit(1);\n }\n const query = parsed.args.slice(1).join(' ');\n await historyCommand(subCmd, {\n json: parsed.flags.json,\n days: parsed.flags.days || 30,\n query,\n });\n break;\n }\n\n case \"fetch\": {\n const fetchUrl = parsed.args[0];\n if (!fetchUrl) {\n console.error(\"[error] fetch: <url> is required.\");\n console.error(\" Usage: bb-browser fetch <url> [--json] [--method POST] [--body '{...}']\");\n console.error(\" Example: bb-browser fetch https://www.reddit.com/api/me.json --json\");\n process.exit(1);\n }\n // 解析 fetch 特有选项\n const methodIdx = process.argv.findIndex(a => a === \"--method\");\n const fetchMethod = methodIdx >= 0 ? process.argv[methodIdx + 1] : undefined;\n const fetchBodyIdx = process.argv.findIndex(a => a === \"--body\");\n const fetchBody = fetchBodyIdx >= 0 ? process.argv[fetchBodyIdx + 1] : undefined;\n const headersIdx = process.argv.findIndex(a => a === \"--headers\");\n const fetchHeaders = headersIdx >= 0 ? process.argv[headersIdx + 1] : undefined;\n const outputIdx = process.argv.findIndex(a => a === \"--output\");\n const fetchOutput = outputIdx >= 0 ? process.argv[outputIdx + 1] : undefined;\n await fetchCommand(fetchUrl, {\n json: parsed.flags.json,\n method: fetchMethod,\n body: fetchBody,\n headers: fetchHeaders,\n output: fetchOutput,\n tabId: globalTabId,\n });\n break;\n }\n\n case \"site\": {\n await siteCommand(parsed.args, {\n json: parsed.flags.json,\n jq: parsed.flags.jq,\n days: parsed.flags.days,\n tabId: globalTabId,\n openclaw: parsed.flags.openclaw,\n });\n break;\n }\n\n case \"star\": {\n const { execSync } = await import(\"node:child_process\");\n try {\n execSync(\"gh auth status\", { stdio: \"pipe\" });\n } catch {\n console.error(\"需要先安装并登录 GitHub CLI: https://cli.github.com\");\n console.error(\" brew install gh && gh auth login\");\n process.exit(1);\n }\n const repos = [\"epiral/bb-browser\", \"epiral/bb-sites\"];\n for (const repo of repos) {\n try {\n execSync(`gh api user/starred/${repo} -X PUT`, { stdio: \"pipe\" });\n console.log(`⭐ Starred ${repo}`);\n } catch {\n console.log(`Already starred or failed: ${repo}`);\n }\n }\n console.log(\"\\nThanks for your support! 🙏\");\n break;\n }\n\n case \"guide\": {\n console.log(`How to turn any website into a bb-browser site adapter\n=======================================================\n\n1. REVERSE ENGINEER the API\n bb-browser network clear --tab <tabId>\n bb-browser refresh --tab <tabId>\n bb-browser network requests --filter \"api\" --with-body --json --tab <tabId>\n\n2. TEST if direct fetch works (Tier 1)\n bb-browser eval \"fetch('/api/endpoint',{credentials:'include'}).then(r=>r.json())\" --tab <tabId>\n\n If it works → Tier 1 (Cookie auth, like Reddit/GitHub/Zhihu/Bilibili)\n If needs extra headers → Tier 2 (like Twitter: Bearer + CSRF token)\n If needs request signing → Tier 3 (like Xiaohongshu: Pinia store actions)\n\n3. WRITE the adapter (one JS file per operation)\n\n /* @meta\n {\n \"name\": \"platform/command\",\n \"description\": \"What it does\",\n \"domain\": \"www.example.com\",\n \"args\": { \"query\": {\"required\": true, \"description\": \"Search query\"} },\n \"readOnly\": true,\n \"example\": \"bb-browser site platform/command value\"\n }\n */\n async function(args) {\n if (!args.query) return {error: 'Missing argument: query'};\n const resp = await fetch('/api/search?q=' + encodeURIComponent(args.query), {credentials: 'include'});\n if (!resp.ok) return {error: 'HTTP ' + resp.status, hint: 'Not logged in?'};\n return await resp.json();\n }\n\n4. TEST it\n Save to ~/.bb-browser/sites/platform/command.js (private, takes priority)\n bb-browser site platform/command \"test query\" --json\n\n5. CONTRIBUTE\n Option A (with gh CLI):\n git clone https://github.com/epiral/bb-sites && cd bb-sites\n git checkout -b feat-platform\n # add adapter files\n git push -u origin feat-platform\n gh pr create --repo epiral/bb-sites\n\n Option B (without gh CLI, using bb-browser itself):\n bb-browser site github/fork epiral/bb-sites\n git clone https://github.com/YOUR_USER/bb-sites && cd bb-sites\n git checkout -b feat-platform\n # add adapter files\n git push -u origin feat-platform\n bb-browser site github/pr-create epiral/bb-sites --title \"feat(platform): add adapters\" --head \"YOUR_USER:feat-platform\"\n\nPrivate adapters: ~/.bb-browser/sites/<platform>/<command>.js\nCommunity: ~/.bb-browser/bb-sites/ (via bb-browser site update)\nFull guide: https://github.com/epiral/bb-sites/blob/main/SKILL.md`);\n break;\n }\n\n default: {\n console.error(`错误:未知命令 \"${parsed.command}\"`);\n console.error(\"运行 bb-browser --help 查看可用命令\");\n process.exit(1);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n if (parsed.flags.json) {\n console.log(\n JSON.stringify({\n success: false,\n error: message,\n })\n );\n } else {\n console.error(`错误:${message}`);\n }\n\n process.exit(1);\n }\n}\n\nmain().then(() => process.exit(0));\n","import { readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { request as httpRequest } from \"node:http\";\nimport { request as httpsRequest } from \"node:https\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport WebSocket from \"ws\";\nimport type { Request, Response, ResponseData, TabInfo, SnapshotData, RefInfo, NetworkRequestInfo, ConsoleMessageInfo, JSErrorInfo, TraceEvent, TraceStatus } from \"@bb-browser/shared\";\nimport { COMMAND_TIMEOUT } from \"@bb-browser/shared\";\nimport { discoverCdpPort } from \"./cdp-discovery.js\";\n\ninterface CdpTargetInfo {\n id: string;\n type: string;\n title: string;\n url: string;\n webSocketDebuggerUrl?: string;\n}\n\ntype JsonObject = Record<string, unknown>;\n\ninterface PendingCommand {\n resolve: (value: unknown) => void;\n reject: (reason?: unknown) => void;\n method: string;\n}\n\ninterface RawDomTextNode {\n type: \"TEXT_NODE\";\n text: string;\n isVisible: boolean;\n}\n\ninterface RawDomElementNode {\n tagName: string;\n xpath: string | null;\n attributes: Record<string, string>;\n children: string[];\n isVisible?: boolean;\n isInteractive?: boolean;\n isTopElement?: boolean;\n isInViewport?: boolean;\n highlightIndex?: number;\n shadowRoot?: boolean;\n}\n\ntype RawDomTreeNode = RawDomTextNode | RawDomElementNode;\n\ninterface BuildDomTreeResult {\n rootId: string;\n map: Record<string, RawDomTreeNode>;\n}\n\ninterface DialogHandlerConfig {\n accept: boolean;\n promptText?: string;\n}\n\ninterface ConnectionState {\n host: string;\n port: number;\n browserWsUrl: string;\n browserSocket: WebSocket;\n browserPending: Map<number, PendingCommand>;\n nextMessageId: number;\n sessions: Map<string, string>;\n attachedTargets: Map<string, string>;\n refsByTarget: Map<string, Record<string, RefInfo>>;\n currentTargetId?: string;\n activeFrameIdByTarget: Map<string, string | null>;\n dialogHandlers: Map<string, DialogHandlerConfig>;\n}\n\nlet connectionState: ConnectionState | null = null;\nlet reconnecting: Promise<void> | null = null;\n\nconst networkRequests = new Map<string, NetworkRequestInfo>();\nlet networkEnabled = false;\n\nconst consoleMessages: ConsoleMessageInfo[] = [];\nlet consoleEnabled = false;\n\nconst jsErrors: JSErrorInfo[] = [];\nlet errorsEnabled = false;\n\nlet traceRecording = false;\nconst traceEvents: TraceEvent[] = [];\n\nfunction buildRequestError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction fetchJson(url: string): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const requester = url.startsWith(\"https:\") ? httpsRequest : httpRequest;\n const req = requester(url, { method: \"GET\" }, (res) => {\n const chunks: Buffer[] = [];\n res.on(\"data\", (chunk) => chunks.push(Buffer.from(chunk)));\n res.on(\"end\", () => {\n const raw = Buffer.concat(chunks).toString(\"utf8\");\n if ((res.statusCode ?? 500) >= 400) {\n reject(new Error(`HTTP ${(res.statusCode ?? 500)}: ${raw}`));\n return;\n }\n try {\n resolve(JSON.parse(raw));\n } catch (error) {\n reject(error);\n }\n });\n });\n req.on(\"error\", reject);\n req.end();\n });\n}\n\nasync function getJsonList(host: string, port: number): Promise<CdpTargetInfo[]> {\n const data = await fetchJson(`http://${host}:${port}/json/list`);\n return Array.isArray(data) ? (data as CdpTargetInfo[]) : [];\n}\n\nasync function getJsonVersion(host: string, port: number): Promise<{ webSocketDebuggerUrl: string }> {\n const data = await fetchJson(`http://${host}:${port}/json/version`) as JsonObject;\n const url = data.webSocketDebuggerUrl;\n if (typeof url !== \"string\" || !url) {\n throw new Error(\"CDP endpoint missing webSocketDebuggerUrl\");\n }\n return { webSocketDebuggerUrl: url };\n}\n\nfunction connectWebSocket(url: string): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(url);\n ws.once(\"open\", () => {\n // Allow Node.js to exit even if the WebSocket is still open\n const socket = (ws as any)._socket;\n if (socket && typeof socket.unref === \"function\") {\n socket.unref();\n }\n resolve(ws);\n });\n ws.once(\"error\", reject);\n });\n}\n\nfunction createState(host: string, port: number, browserWsUrl: string, browserSocket: WebSocket): ConnectionState {\n const state: ConnectionState = {\n host,\n port,\n browserWsUrl,\n browserSocket,\n browserPending: new Map(),\n nextMessageId: 1,\n sessions: new Map(),\n attachedTargets: new Map(),\n refsByTarget: new Map(),\n activeFrameIdByTarget: new Map(),\n dialogHandlers: new Map(),\n };\n\n browserSocket.on(\"message\", (raw) => {\n const message = JSON.parse(raw.toString()) as JsonObject;\n if (typeof message.id === \"number\") {\n const pending = state.browserPending.get(message.id);\n if (!pending) return;\n state.browserPending.delete(message.id);\n if (message.error) {\n pending.reject(new Error(`${pending.method}: ${(message.error as JsonObject).message ?? \"Unknown CDP error\"}`));\n } else {\n pending.resolve(message.result);\n }\n return;\n }\n\n if (message.method === \"Target.attachedToTarget\") {\n const params = message.params as JsonObject;\n const sessionId = params.sessionId;\n const targetInfo = params.targetInfo as JsonObject;\n if (typeof sessionId === \"string\" && typeof targetInfo?.targetId === \"string\") {\n state.sessions.set(targetInfo.targetId, sessionId);\n state.attachedTargets.set(sessionId, targetInfo.targetId);\n }\n return;\n }\n\n if (message.method === \"Target.detachedFromTarget\") {\n const params = message.params as JsonObject;\n const sessionId = params.sessionId;\n if (typeof sessionId === \"string\") {\n const targetId = state.attachedTargets.get(sessionId);\n if (targetId) {\n state.sessions.delete(targetId);\n state.attachedTargets.delete(sessionId);\n state.activeFrameIdByTarget.delete(targetId);\n state.dialogHandlers.delete(targetId);\n }\n }\n return;\n }\n\n if (message.method === \"Target.receivedMessageFromTarget\") {\n // Legacy non-flat protocol\n const params = message.params as JsonObject;\n const sessionId = params.sessionId;\n const messageText = params.message;\n if (typeof sessionId === \"string\" && typeof messageText === \"string\") {\n const targetId = state.attachedTargets.get(sessionId);\n if (targetId) {\n handleSessionEvent(targetId, JSON.parse(messageText) as JsonObject).catch(() => {});\n }\n }\n return;\n }\n\n // Flat protocol: session events come with sessionId directly on the message\n if (typeof message.sessionId === \"string\" && typeof message.method === \"string\") {\n const targetId = state.attachedTargets.get(message.sessionId as string);\n if (targetId) {\n handleSessionEvent(targetId, message).catch(() => {});\n }\n }\n });\n\n browserSocket.on(\"close\", () => {\n if (connectionState === state) {\n connectionState = null;\n }\n for (const pending of state.browserPending.values()) {\n pending.reject(new Error(\"CDP connection closed\"));\n }\n state.browserPending.clear();\n });\n\n browserSocket.on(\"error\", () => {});\n\n return state;\n}\n\nasync function browserCommand<T>(method: string, params: JsonObject = {}): Promise<T> {\n const state = connectionState;\n if (!state) throw new Error(\"CDP connection not initialized\");\n const id = state.nextMessageId++;\n const payload = JSON.stringify({ id, method, params });\n const promise = new Promise<T>((resolve, reject) => {\n state.browserPending.set(id, { resolve, reject, method });\n });\n state.browserSocket.send(payload);\n return promise;\n}\n\nasync function sessionCommand<T>(targetId: string, method: string, params: JsonObject = {}): Promise<T> {\n const state = connectionState;\n if (!state) throw new Error(\"CDP connection not initialized\");\n const sessionId = state.sessions.get(targetId) ?? await attachTarget(targetId);\n const id = state.nextMessageId++;\n // Flat protocol: send with sessionId directly on the message\n const payload = JSON.stringify({ id, method, params, sessionId });\n return new Promise<T>((resolve, reject) => {\n const check = (raw: WebSocket.RawData) => {\n const msg = JSON.parse(raw.toString()) as JsonObject;\n // Flat protocol responses come back with the same sessionId\n if (msg.id === id && msg.sessionId === sessionId) {\n state.browserSocket.off(\"message\", check);\n if (msg.error) reject(new Error(`${method}: ${(msg.error as JsonObject).message ?? \"Unknown CDP error\"}`));\n else resolve(msg.result as T);\n }\n };\n state.browserSocket.on(\"message\", check);\n state.browserSocket.send(payload);\n });\n}\n\n\nfunction getActiveFrameId(targetId: string): string | undefined {\n const frameId = connectionState?.activeFrameIdByTarget.get(targetId);\n return frameId ?? undefined;\n}\n\nasync function pageCommand<T>(targetId: string, method: string, params: JsonObject = {}): Promise<T> {\n const frameId = getActiveFrameId(targetId);\n return sessionCommand<T>(targetId, method, frameId ? { ...params, frameId } : params);\n}\n\nfunction normalizeHeaders(headers: unknown): Record<string, string> | undefined {\n if (!headers || typeof headers !== \"object\") return undefined;\n return Object.fromEntries(Object.entries(headers as Record<string, unknown>).map(([key, value]) => [key, String(value)]));\n}\n\nasync function handleSessionEvent(targetId: string, event: JsonObject): Promise<void> {\n const method = event.method;\n const params = (event.params ?? {}) as JsonObject;\n if (typeof method !== \"string\") return;\n\n if (method === \"Page.javascriptDialogOpening\") {\n const handler = connectionState?.dialogHandlers.get(targetId);\n if (handler) {\n await sessionCommand(targetId, \"Page.handleJavaScriptDialog\", {\n accept: handler.accept,\n ...(handler.promptText !== undefined ? { promptText: handler.promptText } : {}),\n });\n }\n return;\n }\n\n if (method === \"Network.requestWillBeSent\") {\n const requestId = typeof params.requestId === \"string\" ? params.requestId : undefined;\n const request = params.request as JsonObject | undefined;\n if (!requestId || !request) return;\n networkRequests.set(requestId, {\n requestId,\n url: String(request.url ?? \"\"),\n method: String(request.method ?? \"GET\"),\n type: String(params.type ?? \"Other\"),\n timestamp: Math.round(Number(params.timestamp ?? Date.now()) * 1000),\n requestHeaders: normalizeHeaders(request.headers),\n requestBody: typeof request.postData === \"string\" ? request.postData : undefined,\n });\n return;\n }\n\n if (method === \"Network.responseReceived\") {\n const requestId = typeof params.requestId === \"string\" ? params.requestId : undefined;\n const response = params.response as JsonObject | undefined;\n if (!requestId || !response) return;\n const existing = networkRequests.get(requestId);\n if (!existing) return;\n existing.status = typeof response.status === \"number\" ? response.status : undefined;\n existing.statusText = typeof response.statusText === \"string\" ? response.statusText : undefined;\n existing.responseHeaders = normalizeHeaders(response.headers);\n existing.mimeType = typeof response.mimeType === \"string\" ? response.mimeType : undefined;\n networkRequests.set(requestId, existing);\n return;\n }\n\n if (method === \"Network.loadingFailed\") {\n const requestId = typeof params.requestId === \"string\" ? params.requestId : undefined;\n if (!requestId) return;\n const existing = networkRequests.get(requestId);\n if (!existing) return;\n existing.failed = true;\n existing.failureReason = typeof params.errorText === \"string\" ? params.errorText : \"Unknown error\";\n networkRequests.set(requestId, existing);\n return;\n }\n\n if (method === \"Runtime.consoleAPICalled\") {\n const type = String(params.type ?? \"log\");\n const args = Array.isArray(params.args) ? params.args as JsonObject[] : [];\n const text = args.map((arg) => {\n if (typeof arg.value === \"string\") return arg.value;\n if (arg.value !== undefined) return String(arg.value);\n if (typeof arg.description === \"string\") return arg.description;\n return \"\";\n }).filter(Boolean).join(\" \");\n const stack = params.stackTrace as JsonObject | undefined;\n const firstCallFrame = Array.isArray(stack?.callFrames) ? stack?.callFrames[0] as JsonObject | undefined : undefined;\n consoleMessages.push({\n type: [\"log\", \"info\", \"warn\", \"error\", \"debug\"].includes(type) ? type as ConsoleMessageInfo[\"type\"] : \"log\",\n text,\n timestamp: Math.round(Number(params.timestamp ?? Date.now())),\n url: typeof firstCallFrame?.url === \"string\" ? firstCallFrame.url : undefined,\n lineNumber: typeof firstCallFrame?.lineNumber === \"number\" ? firstCallFrame.lineNumber : undefined,\n });\n return;\n }\n\n if (method === \"Runtime.exceptionThrown\") {\n const details = params.exceptionDetails as JsonObject | undefined;\n if (!details) return;\n const exception = details.exception as JsonObject | undefined;\n const stackTrace = details.stackTrace as JsonObject | undefined;\n const callFrames = Array.isArray(stackTrace?.callFrames) ? stackTrace.callFrames as JsonObject[] : [];\n jsErrors.push({\n message: typeof exception?.description === \"string\" ? exception.description : String(details.text ?? \"JavaScript exception\"),\n url: typeof details.url === \"string\" ? details.url : (typeof callFrames[0]?.url === \"string\" ? String(callFrames[0].url) : undefined),\n lineNumber: typeof details.lineNumber === \"number\" ? details.lineNumber : undefined,\n columnNumber: typeof details.columnNumber === \"number\" ? details.columnNumber : undefined,\n stackTrace: callFrames.length > 0 ? callFrames.map((frame) => `${String(frame.functionName ?? \"<anonymous>\")} (${String(frame.url ?? \"\")}:${String(frame.lineNumber ?? 0)}:${String(frame.columnNumber ?? 0)})`).join(\"\\n\") : undefined,\n timestamp: Date.now(),\n });\n }\n}\n\nasync function ensureNetworkMonitoring(targetId: string): Promise<void> {\n if (networkEnabled) return;\n await sessionCommand(targetId, \"Network.enable\");\n networkEnabled = true;\n}\n\nasync function ensureConsoleMonitoring(targetId: string): Promise<void> {\n if (consoleEnabled && errorsEnabled) return;\n await sessionCommand(targetId, \"Runtime.enable\");\n consoleEnabled = true;\n errorsEnabled = true;\n}\n\nasync function attachTarget(targetId: string): Promise<string> {\n const result = await browserCommand<{ sessionId: string }>(\"Target.attachToTarget\", {\n targetId,\n flatten: true,\n });\n connectionState?.sessions.set(targetId, result.sessionId);\n connectionState?.attachedTargets.set(result.sessionId, targetId);\n connectionState?.activeFrameIdByTarget.set(targetId, connectionState?.activeFrameIdByTarget.get(targetId) ?? null);\n await sessionCommand(targetId, \"Page.enable\");\n await sessionCommand(targetId, \"Runtime.enable\");\n await sessionCommand(targetId, \"DOM.enable\");\n await sessionCommand(targetId, \"Accessibility.enable\");\n return result.sessionId;\n}\n\nasync function getTargets(): Promise<CdpTargetInfo[]> {\n const state = connectionState;\n if (!state) throw new Error(\"CDP connection not initialized\");\n try {\n const result = await browserCommand<{ targetInfos: Array<{ targetId: string; type: string; title: string; url: string }> }>(\"Target.getTargets\");\n return (result.targetInfos || []).map((target) => ({\n id: target.targetId,\n type: target.type,\n title: target.title,\n url: target.url,\n webSocketDebuggerUrl: \"\",\n }));\n } catch {\n return getJsonList(state.host, state.port);\n }\n}\n\n\nasync function ensurePageTarget(targetId?: string | number): Promise<CdpTargetInfo> {\n const targets = (await getTargets()).filter((target) => target.type === \"page\");\n if (targets.length === 0) throw new Error(\"No page target found\");\n\n let target: CdpTargetInfo | undefined;\n if (typeof targetId === \"number\") {\n target = targets[targetId] ?? targets.find((item) => Number(item.id) === targetId);\n } else if (typeof targetId === \"string\") {\n target = targets.find((item) => item.id === targetId);\n if (!target) {\n const numericTargetId = Number(targetId);\n if (!Number.isNaN(numericTargetId)) {\n target = targets[numericTargetId] ?? targets.find((item) => Number(item.id) === numericTargetId);\n }\n }\n }\n target ??= targets[0];\n connectionState!.currentTargetId = target.id;\n await attachTarget(target.id);\n return target;\n}\n\nasync function resolveBackendNodeIdByXPath(targetId: string, xpath: string): Promise<number> {\n // Populate the DOM agent's node map — required before performSearch/describeNode\n await sessionCommand(targetId, \"DOM.getDocument\", { depth: 0 });\n\n const search = await sessionCommand<{ searchId: string; resultCount: number }>(targetId, \"DOM.performSearch\", {\n query: xpath,\n includeUserAgentShadowDOM: true,\n });\n\n try {\n if (!search.resultCount) {\n throw new Error(`Unknown ref xpath: ${xpath}`);\n }\n\n const { nodeIds } = await sessionCommand<{ nodeIds: number[] }>(targetId, \"DOM.getSearchResults\", {\n searchId: search.searchId,\n fromIndex: 0,\n toIndex: search.resultCount,\n });\n\n for (const nodeId of nodeIds) {\n const described = await sessionCommand<{ node: { backendNodeId?: number; nodeName?: string } }>(targetId, \"DOM.describeNode\", {\n nodeId,\n });\n if (described.node.backendNodeId) {\n return described.node.backendNodeId;\n }\n }\n\n throw new Error(`XPath resolved but no backend node id found: ${xpath}`);\n } finally {\n await sessionCommand(targetId, \"DOM.discardSearchResults\", { searchId: search.searchId }).catch(() => {});\n }\n}\n\nasync function parseRef(ref: string): Promise<number> {\n const targetId = connectionState?.currentTargetId ?? \"\";\n let refs = connectionState?.refsByTarget.get(targetId) ?? {};\n if (!refs[ref] && targetId) {\n const persistedRefs = loadPersistedRefs(targetId);\n if (persistedRefs) {\n connectionState?.refsByTarget.set(targetId, persistedRefs);\n refs = persistedRefs;\n }\n }\n const found = refs[ref];\n if (!found) {\n throw new Error(`Unknown ref: ${ref}. Run snapshot first.`);\n }\n if (found.backendDOMNodeId) {\n return found.backendDOMNodeId;\n }\n if (targetId && found.xpath) {\n const backendDOMNodeId = await resolveBackendNodeIdByXPath(targetId, found.xpath);\n found.backendDOMNodeId = backendDOMNodeId;\n connectionState?.refsByTarget.set(targetId, refs);\n const pageUrl = await evaluate<string>(targetId, \"location.href\", true).catch(() => undefined);\n if (pageUrl) {\n persistRefs(targetId, pageUrl, refs);\n }\n return backendDOMNodeId;\n }\n throw new Error(`Unknown ref: ${ref}. Run snapshot first.`);\n}\n\nfunction getRefsFilePath(targetId: string): string {\n return path.join(os.tmpdir(), `bb-browser-refs-${targetId}.json`);\n}\n\nfunction getCurrentTargetUrl(targetId: string): string | null {\n const state = connectionState;\n if (!state) return null;\n const pages = Array.from(state.sessions.keys());\n void pages;\n return null;\n}\n\nfunction loadPersistedRefs(targetId: string, expectedUrl?: string): Record<string, RefInfo> | null {\n try {\n const data = JSON.parse(readFileSync(getRefsFilePath(targetId), \"utf-8\")) as {\n targetId?: unknown;\n url?: unknown;\n refs?: unknown;\n };\n if (data.targetId !== targetId) return null;\n if (expectedUrl !== undefined && data.url !== expectedUrl) return null;\n if (!data.refs || typeof data.refs !== \"object\") return null;\n return data.refs as Record<string, RefInfo>;\n } catch {\n return null;\n }\n}\n\nfunction persistRefs(targetId: string, url: string, refs: Record<string, RefInfo>): void {\n try {\n writeFileSync(getRefsFilePath(targetId), JSON.stringify({ targetId, url, timestamp: Date.now(), refs }));\n } catch {}\n}\n\nfunction clearPersistedRefs(targetId: string): void {\n try {\n unlinkSync(getRefsFilePath(targetId));\n } catch {}\n}\n\nfunction loadBuildDomTreeScript(): string {\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n const candidates = [\n path.resolve(currentDir, \"./extension/buildDomTree.js\"),\n // npm installed: dist/cli.js → ../extension/buildDomTree.js\n path.resolve(currentDir, \"../extension/buildDomTree.js\"),\n path.resolve(currentDir, \"../extension/dist/buildDomTree.js\"),\n path.resolve(currentDir, \"../packages/extension/public/buildDomTree.js\"),\n path.resolve(currentDir, \"../packages/extension/dist/buildDomTree.js\"),\n // dev mode: packages/cli/dist/ → ../../../extension/\n path.resolve(currentDir, \"../../../extension/buildDomTree.js\"),\n path.resolve(currentDir, \"../../../extension/dist/buildDomTree.js\"),\n // dev mode: packages/cli/src/ → ../../extension/\n path.resolve(currentDir, \"../../extension/buildDomTree.js\"),\n path.resolve(currentDir, \"../../../packages/extension/dist/buildDomTree.js\"),\n path.resolve(currentDir, \"../../../packages/extension/public/buildDomTree.js\"),\n ];\n for (const candidate of candidates) {\n try {\n return readFileSync(candidate, \"utf8\");\n } catch {\n }\n }\n throw new Error(\"Cannot find buildDomTree.js\");\n}\n\nasync function evaluate<T>(targetId: string, expression: string, returnByValue = true): Promise<T> {\n const result = await sessionCommand<{ result: { value?: T; objectId?: string }; exceptionDetails?: { text?: string } }>(targetId, \"Runtime.evaluate\", {\n expression,\n awaitPromise: true,\n returnByValue,\n });\n if (result.exceptionDetails) {\n throw new Error(result.exceptionDetails.text || \"Runtime.evaluate failed\");\n }\n return (result.result.value ?? result.result) as T;\n}\n\nasync function resolveNode(targetId: string, backendNodeId: number): Promise<number> {\n const result = await sessionCommand<{ nodeId: number }>(targetId, \"DOM.pushNodesByBackendIdsToFrontend\", {\n backendNodeIds: [backendNodeId],\n });\n return result.nodeId;\n}\n\nasync function focusNode(targetId: string, backendNodeId: number): Promise<void> {\n await sessionCommand(targetId, \"DOM.focus\", { backendNodeId });\n}\n\nasync function insertTextIntoNode(targetId: string, backendNodeId: number, text: string, clearFirst: boolean): Promise<void> {\n const resolved = await sessionCommand<{ object: { objectId: string } }>(targetId, \"DOM.resolveNode\", { backendNodeId });\n\n await sessionCommand(targetId, \"Runtime.callFunctionOn\", {\n objectId: resolved.object.objectId,\n functionDeclaration: `function(value, clearFirst) {\n if (typeof this.focus === 'function') this.focus();\n if (clearFirst && ('value' in this)) {\n this.value = '';\n this.dispatchEvent(new Event('input', { bubbles: true }));\n }\n if ('value' in this) {\n this.value = clearFirst ? value : String(this.value ?? '') + value;\n this.dispatchEvent(new Event('input', { bubbles: true }));\n this.dispatchEvent(new Event('change', { bubbles: true }));\n return true;\n }\n return false;\n }`,\n arguments: [\n { value: text },\n { value: clearFirst },\n ],\n returnByValue: true,\n });\n\n await focusNode(targetId, backendNodeId);\n await sessionCommand(targetId, \"Input.insertText\", { text });\n}\n\nasync function getNodeBox(targetId: string, backendNodeId: number): Promise<{ x: number; y: number }> {\n const result = await sessionCommand<{ model: { content: number[]; border: number[] } }>(targetId, \"DOM.getBoxModel\", {\n backendNodeId,\n });\n const quad = result.model.content.length >= 8 ? result.model.content : result.model.border;\n const xs = [quad[0], quad[2], quad[4], quad[6]];\n const ys = [quad[1], quad[3], quad[5], quad[7]];\n return {\n x: xs.reduce((a, b) => a + b, 0) / xs.length,\n y: ys.reduce((a, b) => a + b, 0) / ys.length,\n };\n}\n\nasync function mouseClick(targetId: string, x: number, y: number): Promise<void> {\n await sessionCommand(targetId, \"Input.dispatchMouseEvent\", { type: \"mouseMoved\", x, y, button: \"none\" });\n await sessionCommand(targetId, \"Input.dispatchMouseEvent\", { type: \"mousePressed\", x, y, button: \"left\", clickCount: 1 });\n await sessionCommand(targetId, \"Input.dispatchMouseEvent\", { type: \"mouseReleased\", x, y, button: \"left\", clickCount: 1 });\n}\n\nasync function getAttributeValue(targetId: string, backendNodeId: number, attribute: string): Promise<string> {\n const nodeId = await resolveNode(targetId, backendNodeId);\n if (attribute === \"text\") {\n return evaluate<string>(targetId, `(() => { const n = this; return n.innerText ?? n.textContent ?? ''; }).call(document.querySelector('[data-bb-node-id=\"${nodeId}\"]'))`);\n }\n const result = await sessionCommand<{ object: { objectId: string } }>(targetId, \"DOM.resolveNode\", { backendNodeId });\n const call = await sessionCommand<{ result: { value: string } }>(targetId, \"Runtime.callFunctionOn\", {\n objectId: result.object.objectId,\n functionDeclaration: `function() { if (${JSON.stringify(attribute)} === 'url') return this.href || this.src || location.href; if (${JSON.stringify(attribute)} === 'title') return document.title; return this.getAttribute(${JSON.stringify(attribute)}) || ''; }`,\n returnByValue: true,\n });\n return String(call.result.value ?? \"\");\n}\n\nasync function buildSnapshot(targetId: string, request: Request): Promise<SnapshotData> {\n const script = loadBuildDomTreeScript();\n const buildArgs = {\n showHighlightElements: true,\n focusHighlightIndex: -1,\n viewportExpansion: -1,\n debugMode: false,\n startId: 0,\n startHighlightIndex: 0,\n };\n const expression = `(() => { ${script}; const fn = globalThis.buildDomTree ?? (typeof window !== 'undefined' ? window.buildDomTree : undefined); if (typeof fn !== 'function') { throw new Error('buildDomTree is not available after script injection'); } return fn(${JSON.stringify({\n ...buildArgs,\n })}); })()`;\n const value = await evaluate<BuildDomTreeResult | null>(targetId, expression, true);\n if (!value || !value.map || !value.rootId) {\n const title = await evaluate<string>(targetId, \"document.title\", true);\n const pageUrl = await evaluate<string>(targetId, \"location.href\", true);\n const fallbackSnapshot: SnapshotData = {\n title,\n url: pageUrl,\n lines: [title || pageUrl],\n refs: {},\n };\n connectionState?.refsByTarget.set(targetId, {});\n persistRefs(targetId, pageUrl, {});\n return fallbackSnapshot;\n }\n\n const snapshot = convertBuildDomTreeResult(value, {\n interactiveOnly: !!request.interactive,\n compact: !!request.compact,\n maxDepth: request.maxDepth,\n selector: request.selector,\n });\n const pageUrl = await evaluate<string>(targetId, \"location.href\", true);\n connectionState?.refsByTarget.set(targetId, snapshot.refs || {});\n persistRefs(targetId, pageUrl, snapshot.refs || {});\n return snapshot;\n}\n\nfunction convertBuildDomTreeResult(\n result: BuildDomTreeResult,\n options: { interactiveOnly: boolean; compact: boolean; maxDepth?: number; selector?: string },\n): SnapshotData {\n const { interactiveOnly, compact, maxDepth, selector } = options;\n const { rootId, map } = result;\n const refs: Record<string, RefInfo> = {};\n const lines: string[] = [];\n\n const getRole = (node: RawDomElementNode): string => {\n const tagName = node.tagName.toLowerCase();\n const role = node.attributes?.role;\n if (role) return role;\n const type = node.attributes?.type?.toLowerCase() || \"text\";\n const inputRoleMap: Record<string, string> = {\n text: \"textbox\", password: \"textbox\", email: \"textbox\", url: \"textbox\", tel: \"textbox\",\n search: \"searchbox\", number: \"spinbutton\", range: \"slider\", checkbox: \"checkbox\",\n radio: \"radio\", button: \"button\", submit: \"button\", reset: \"button\", file: \"button\",\n };\n const roleMap: Record<string, string> = {\n a: \"link\", button: \"button\", input: inputRoleMap[type] || \"textbox\", select: \"combobox\",\n textarea: \"textbox\", img: \"image\", nav: \"navigation\", main: \"main\", header: \"banner\",\n footer: \"contentinfo\", aside: \"complementary\", form: \"form\", table: \"table\", ul: \"list\",\n ol: \"list\", li: \"listitem\", h1: \"heading\", h2: \"heading\", h3: \"heading\", h4: \"heading\",\n h5: \"heading\", h6: \"heading\", dialog: \"dialog\", article: \"article\", section: \"region\",\n label: \"label\", details: \"group\", summary: \"button\",\n };\n return roleMap[tagName] || tagName;\n };\n\n const collectTextContent = (node: RawDomElementNode, nodeMap: Record<string, RawDomTreeNode>, depthLimit = 5): string => {\n const texts: string[] = [];\n const visit = (nodeId: string, depth: number): void => {\n if (depth > depthLimit) return;\n const currentNode = nodeMap[nodeId];\n if (!currentNode) return;\n if (\"type\" in currentNode && currentNode.type === \"TEXT_NODE\") {\n const text = currentNode.text.trim();\n if (text) texts.push(text);\n return;\n }\n for (const childId of (currentNode as RawDomElementNode).children || []) visit(childId, depth + 1);\n };\n for (const childId of node.children || []) visit(childId, 0);\n return texts.join(\" \").trim();\n };\n\n const getName = (node: RawDomElementNode): string | undefined => {\n const attrs = node.attributes || {};\n return attrs[\"aria-label\"] || attrs.title || attrs.placeholder || attrs.alt || attrs.value || collectTextContent(node, map) || attrs.name || undefined;\n };\n\n const truncateText = (text: string, length = 50): string => text.length <= length ? text : `${text.slice(0, length - 3)}...`;\n\n const selectorText = selector?.trim().toLowerCase();\n const matchesSelector = (node: RawDomElementNode, role: string, name?: string): boolean => {\n if (!selectorText) return true;\n const haystack = [node.tagName, role, name, node.xpath || \"\", ...Object.values(node.attributes || {})].join(\" \").toLowerCase();\n return haystack.includes(selectorText);\n };\n\n if (interactiveOnly) {\n const interactiveNodes = Object.entries(map)\n .filter(([, node]) => !(\"type\" in node) && node.highlightIndex !== undefined && node.highlightIndex !== null)\n .map(([id, node]) => ({ id, node: node as RawDomElementNode }))\n .sort((a, b) => (a.node.highlightIndex ?? 0) - (b.node.highlightIndex ?? 0));\n\n for (const { node } of interactiveNodes) {\n const refId = String(node.highlightIndex);\n const role = getRole(node);\n const name = getName(node);\n if (!matchesSelector(node, role, name)) continue;\n let line = `${role} [ref=${refId}]`;\n if (name) line += ` ${JSON.stringify(truncateText(name))}`;\n lines.push(line);\n refs[refId] = {\n xpath: node.xpath || \"\",\n role,\n name,\n tagName: node.tagName.toLowerCase(),\n } as RefInfo;\n }\n\n return { snapshot: lines.join(\"\\n\"), refs };\n }\n\n const walk = (nodeId: string, depth: number): void => {\n if (maxDepth !== undefined && depth > maxDepth) return;\n const node = map[nodeId];\n if (!node) return;\n\n if (\"type\" in node && node.type === \"TEXT_NODE\") {\n const text = node.text.trim();\n if (!text) return;\n lines.push(`${\" \".repeat(depth)}- text ${JSON.stringify(truncateText(text, compact ? 80 : 120))}`);\n return;\n }\n\n const role = getRole(node);\n const name = getName(node);\n if (!matchesSelector(node, role, name)) {\n for (const childId of node.children || []) walk(childId, depth + 1);\n return;\n }\n\n const indent = \" \".repeat(depth);\n const refId = node.highlightIndex !== undefined && node.highlightIndex !== null ? String(node.highlightIndex) : null;\n let line = `${indent}- ${role}`;\n if (refId) line += ` [ref=${refId}]`;\n if (name) line += ` ${JSON.stringify(truncateText(name, compact ? 50 : 80))}`;\n if (!compact) line += ` <${node.tagName.toLowerCase()}>`;\n lines.push(line);\n\n if (refId) {\n refs[refId] = {\n xpath: node.xpath || \"\",\n role,\n name,\n tagName: node.tagName.toLowerCase(),\n } as RefInfo;\n }\n\n for (const childId of node.children || []) walk(childId, depth + 1);\n };\n\n walk(rootId, 0);\n return { snapshot: lines.join(\"\\n\"), refs };\n}\n\nfunction ok(id: string, data?: ResponseData): Response {\n return { id, success: true, data };\n}\n\nfunction fail(id: string, error: unknown): Response {\n return { id, success: false, error: buildRequestError(error).message };\n}\n\nexport async function ensureCdpConnection(): Promise<void> {\n if (connectionState) return;\n if (reconnecting) return reconnecting;\n reconnecting = (async () => {\n const discovered = await discoverCdpPort();\n if (!discovered) {\n throw new Error(\"No browser connection found\");\n }\n const version = await getJsonVersion(discovered.host, discovered.port);\n const wsUrl = version.webSocketDebuggerUrl;\n const socket = await connectWebSocket(wsUrl);\n connectionState = createState(discovered.host, discovered.port, wsUrl, socket);\n })();\n try {\n await reconnecting;\n } finally {\n reconnecting = null;\n }\n}\n\n\nexport async function sendCommand(request: Request): Promise<Response> {\n try {\n await ensureCdpConnection();\n const timeout = new Promise<never>((_, reject) => setTimeout(() => reject(new Error(\"请求超时\")), COMMAND_TIMEOUT));\n return await Promise.race([dispatchRequest(request), timeout]);\n } catch (error) {\n return fail(request.id, error);\n }\n}\n\nasync function dispatchRequest(request: Request): Promise<Response> {\n const target = await ensurePageTarget(request.tabId);\n switch (request.action) {\n case \"open\": {\n if (!request.url) return fail(request.id, \"Missing url parameter\");\n if (request.tabId === undefined) {\n const created = await browserCommand<{ targetId: string }>(\"Target.createTarget\", { url: request.url });\n const newTarget = await ensurePageTarget(created.targetId);\n return ok(request.id, { url: request.url, tabId: newTarget.id });\n }\n await pageCommand(target.id, \"Page.navigate\", { url: request.url });\n connectionState?.refsByTarget.delete(target.id);\n clearPersistedRefs(target.id);\n return ok(request.id, { url: request.url, title: target.title, tabId: target.id });\n }\n case \"snapshot\": {\n const snapshotData = await buildSnapshot(target.id, request);\n return ok(request.id, { title: target.title, url: target.url, snapshotData });\n }\n case \"click\":\n case \"hover\": {\n if (!request.ref) return fail(request.id, \"Missing ref parameter\");\n const backendNodeId = await parseRef(request.ref);\n const point = await getNodeBox(target.id, backendNodeId);\n await sessionCommand(target.id, \"Input.dispatchMouseEvent\", { type: \"mouseMoved\", x: point.x, y: point.y, button: \"none\" });\n if (request.action === \"click\") await mouseClick(target.id, point.x, point.y);\n return ok(request.id, {});\n }\n case \"fill\":\n case \"type\": {\n if (!request.ref) return fail(request.id, \"Missing ref parameter\");\n if (request.text == null) return fail(request.id, \"Missing text parameter\");\n const backendNodeId = await parseRef(request.ref);\n await insertTextIntoNode(target.id, backendNodeId, request.text, request.action === \"fill\");\n return ok(request.id, { value: request.text });\n }\n case \"check\":\n case \"uncheck\": {\n if (!request.ref) return fail(request.id, \"Missing ref parameter\");\n const backendNodeId = await parseRef(request.ref);\n const desired = request.action === \"check\";\n const resolved = await sessionCommand<{ object: { objectId: string } }>(target.id, \"DOM.resolveNode\", { backendNodeId });\n await sessionCommand(target.id, \"Runtime.callFunctionOn\", {\n objectId: resolved.object.objectId,\n functionDeclaration: `function() { this.checked = ${desired}; this.dispatchEvent(new Event('input', { bubbles: true })); this.dispatchEvent(new Event('change', { bubbles: true })); }`,\n });\n return ok(request.id, {});\n }\n case \"select\": {\n if (!request.ref || request.value == null) return fail(request.id, \"Missing ref or value parameter\");\n const backendNodeId = await parseRef(request.ref);\n const resolved = await sessionCommand<{ object: { objectId: string } }>(target.id, \"DOM.resolveNode\", { backendNodeId });\n await sessionCommand(target.id, \"Runtime.callFunctionOn\", {\n objectId: resolved.object.objectId,\n functionDeclaration: `function() { this.value = ${JSON.stringify(request.value)}; this.dispatchEvent(new Event('input', { bubbles: true })); this.dispatchEvent(new Event('change', { bubbles: true })); }`,\n });\n return ok(request.id, { value: request.value });\n }\n case \"get\": {\n if (!request.ref || !request.attribute) return fail(request.id, \"Missing ref or attribute parameter\");\n const value = await getAttributeValue(target.id, await parseRef(request.ref), request.attribute);\n return ok(request.id, { value });\n }\n case \"screenshot\": {\n const result = await sessionCommand<{ data: string }>(target.id, \"Page.captureScreenshot\", { format: \"png\", fromSurface: true });\n return ok(request.id, { dataUrl: `data:image/png;base64,${result.data}` });\n }\n case \"close\": {\n await browserCommand(\"Target.closeTarget\", { targetId: target.id });\n connectionState?.refsByTarget.delete(target.id);\n clearPersistedRefs(target.id);\n return ok(request.id, {});\n }\n case \"wait\": {\n await new Promise((resolve) => setTimeout(resolve, request.ms ?? 1000));\n return ok(request.id, {});\n }\n case \"press\": {\n if (!request.key) return fail(request.id, \"Missing key parameter\");\n await sessionCommand(target.id, \"Input.dispatchKeyEvent\", { type: \"keyDown\", key: request.key });\n if (request.key.length === 1) {\n await sessionCommand(target.id, \"Input.dispatchKeyEvent\", { type: \"char\", text: request.key, key: request.key });\n }\n await sessionCommand(target.id, \"Input.dispatchKeyEvent\", { type: \"keyUp\", key: request.key });\n return ok(request.id, {});\n }\n case \"scroll\": {\n const deltaY = request.direction === \"up\" ? -(request.pixels ?? 300) : (request.pixels ?? 300);\n await sessionCommand(target.id, \"Input.dispatchMouseEvent\", { type: \"mouseWheel\", x: 0, y: 0, deltaX: 0, deltaY });\n return ok(request.id, {});\n }\n case \"back\": {\n await evaluate(target.id, \"history.back(); undefined\");\n return ok(request.id, {});\n }\n case \"forward\": {\n await evaluate(target.id, \"history.forward(); undefined\");\n return ok(request.id, {});\n }\n case \"refresh\": {\n await sessionCommand(target.id, \"Page.reload\", { ignoreCache: false });\n return ok(request.id, {});\n }\n case \"eval\": {\n if (!request.script) return fail(request.id, \"Missing script parameter\");\n const result = await evaluate<unknown>(target.id, request.script, true);\n return ok(request.id, { result });\n }\n case \"tab_list\": {\n const tabs = (await getTargets()).filter((item) => item.type === \"page\").map((item, index): TabInfo => ({ index, url: item.url, title: item.title, active: item.id === connectionState?.currentTargetId || (!connectionState?.currentTargetId && index === 0), tabId: item.id }));\n return ok(request.id, { tabs, activeIndex: tabs.findIndex((tab) => tab.active) });\n }\n case \"tab_new\": {\n const created = await browserCommand<{ targetId: string }>(\"Target.createTarget\", { url: request.url ?? \"about:blank\" });\n return ok(request.id, { tabId: created.targetId, url: request.url ?? \"about:blank\" });\n }\n case \"tab_select\": {\n const tabs = (await getTargets()).filter((item) => item.type === \"page\");\n const selected = request.tabId !== undefined\n ? tabs.find((item) => item.id === String(request.tabId) || Number(item.id) === request.tabId)\n : tabs[request.index ?? 0];\n if (!selected) return fail(request.id, \"Tab not found\");\n connectionState!.currentTargetId = selected.id;\n await attachTarget(selected.id);\n return ok(request.id, { tabId: selected.id, url: selected.url, title: selected.title });\n }\n case \"tab_close\": {\n const tabs = (await getTargets()).filter((item) => item.type === \"page\");\n const selected = request.tabId !== undefined\n ? tabs.find((item) => item.id === String(request.tabId) || Number(item.id) === request.tabId)\n : tabs[request.index ?? 0];\n if (!selected) return fail(request.id, \"Tab not found\");\n await browserCommand(\"Target.closeTarget\", { targetId: selected.id });\n connectionState?.refsByTarget.delete(selected.id);\n clearPersistedRefs(selected.id);\n return ok(request.id, { tabId: selected.id });\n }\n case \"frame\": {\n if (!request.selector) return fail(request.id, \"Missing selector parameter\");\n const document = await pageCommand<{ root: { nodeId: number } }>(target.id, \"DOM.getDocument\", {});\n const node = await pageCommand<{ nodeId: number }>(target.id, \"DOM.querySelector\", { nodeId: document.root.nodeId, selector: request.selector });\n if (!node.nodeId) return fail(request.id, `找不到 iframe: ${request.selector}`);\n const described = await pageCommand<{ node: { frameId?: string; nodeName?: string; attributes?: string[] } }>(target.id, \"DOM.describeNode\", { nodeId: node.nodeId });\n const frameId = described.node.frameId;\n const nodeName = String(described.node.nodeName ?? \"\").toLowerCase();\n if (!frameId) return fail(request.id, `无法获取 iframe frameId: ${request.selector}`);\n if (nodeName && nodeName !== \"iframe\" && nodeName !== \"frame\") return fail(request.id, `元素不是 iframe: ${nodeName}`);\n connectionState?.activeFrameIdByTarget.set(target.id, frameId);\n const attributes = described.node.attributes ?? [];\n const attrMap: Record<string, string> = {};\n for (let i = 0; i < attributes.length; i += 2) attrMap[String(attributes[i])] = String(attributes[i + 1] ?? \"\");\n return ok(request.id, { frameInfo: { selector: request.selector, name: attrMap.name ?? \"\", url: attrMap.src ?? \"\", frameId } });\n }\n case \"frame_main\": {\n connectionState?.activeFrameIdByTarget.set(target.id, null);\n return ok(request.id, { frameInfo: { frameId: 0 } });\n }\n case \"dialog\": {\n connectionState?.dialogHandlers.set(target.id, { accept: request.dialogResponse !== \"dismiss\", ...(request.promptText !== undefined ? { promptText: request.promptText } : {}) });\n await sessionCommand(target.id, \"Page.enable\");\n return ok(request.id, { dialog: { armed: true, response: request.dialogResponse ?? \"accept\" } as ResponseData[keyof ResponseData] });\n }\n case \"network\": {\n const subCommand = request.networkCommand ?? \"requests\";\n switch (subCommand) {\n case \"requests\": {\n await ensureNetworkMonitoring(target.id);\n const requests = Array.from(networkRequests.values()).filter((item) => !request.filter || item.url.includes(request.filter));\n if (request.withBody) {\n await Promise.all(requests.map(async (item) => {\n if (item.failed || item.responseBody !== undefined || item.bodyError !== undefined) return;\n try {\n const body = await sessionCommand<{ body: string; base64Encoded: boolean }>(target.id, \"Network.getResponseBody\", { requestId: item.requestId });\n item.responseBody = body.body;\n item.responseBodyBase64 = body.base64Encoded;\n } catch (error) {\n item.bodyError = error instanceof Error ? error.message : String(error);\n }\n }));\n }\n return ok(request.id, { networkRequests: requests });\n }\n case \"route\":\n return ok(request.id, { routeCount: 0 });\n case \"unroute\":\n return ok(request.id, { routeCount: 0 });\n case \"clear\":\n networkRequests.clear();\n return ok(request.id, {});\n default:\n return fail(request.id, `Unknown network subcommand: ${subCommand}`);\n }\n }\n case \"console\": {\n const subCommand = request.consoleCommand ?? \"get\";\n await ensureConsoleMonitoring(target.id);\n switch (subCommand) {\n case \"get\":\n return ok(request.id, { consoleMessages: consoleMessages.filter((item) => !request.filter || item.text.includes(request.filter)) });\n case \"clear\":\n consoleMessages.length = 0;\n return ok(request.id, {});\n default:\n return fail(request.id, `Unknown console subcommand: ${subCommand}`);\n }\n }\n case \"errors\": {\n const subCommand = request.errorsCommand ?? \"get\";\n await ensureConsoleMonitoring(target.id);\n switch (subCommand) {\n case \"get\":\n return ok(request.id, { jsErrors: jsErrors.filter((item) => !request.filter || item.message.includes(request.filter) || item.url?.includes(request.filter)) });\n case \"clear\":\n jsErrors.length = 0;\n return ok(request.id, {});\n default:\n return fail(request.id, `Unknown errors subcommand: ${subCommand}`);\n }\n }\n case \"trace\": {\n const subCommand = request.traceCommand ?? \"status\";\n switch (subCommand) {\n case \"start\":\n traceRecording = true;\n traceEvents.length = 0;\n return ok(request.id, { traceStatus: { recording: true, eventCount: 0 } satisfies TraceStatus });\n case \"stop\": {\n traceRecording = false;\n return ok(request.id, { traceEvents: [...traceEvents] satisfies TraceEvent[], traceStatus: { recording: false, eventCount: traceEvents.length } satisfies TraceStatus });\n }\n case \"status\":\n return ok(request.id, { traceStatus: { recording: traceRecording, eventCount: traceEvents.length } satisfies TraceStatus });\n default:\n return fail(request.id, `Unknown trace subcommand: ${subCommand}`);\n }\n }\n default:\n return fail(request.id, `Action not yet supported in direct CDP mode: ${request.action}`);\n }\n}\n","import { execFile, execSync, spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport os from \"node:os\";\nimport path from \"node:path\";\n\nconst DEFAULT_CDP_PORT = 19825;\nconst MANAGED_BROWSER_DIR = path.join(os.homedir(), \".bb-browser\", \"browser\");\nconst MANAGED_USER_DATA_DIR = path.join(MANAGED_BROWSER_DIR, \"user-data\");\nconst MANAGED_PORT_FILE = path.join(MANAGED_BROWSER_DIR, \"cdp-port\");\n\nfunction execFileAsync(command: string, args: string[], timeout: number): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(command, args, { encoding: \"utf8\", timeout }, (error, stdout) => {\n if (error) {\n reject(error);\n return;\n }\n resolve(stdout.trim());\n });\n });\n}\n\nfunction getArgValue(flag: string): string | undefined {\n const index = process.argv.indexOf(flag);\n if (index < 0) return undefined;\n return process.argv[index + 1];\n}\n\nasync function tryOpenClaw(): Promise<{ host: string; port: number } | null> {\n try {\n const raw = await execFileAsync(\"npx\", [\"openclaw\", \"browser\", \"status\", \"--json\"], 5000);\n const parsed = JSON.parse(raw);\n const port = Number(parsed?.cdpPort);\n if (Number.isInteger(port) && port > 0) {\n return { host: \"127.0.0.1\", port };\n }\n } catch {\n }\n return null;\n}\n\nasync function canConnect(host: string, port: number): Promise<boolean> {\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 1200);\n const response = await fetch(`http://${host}:${port}/json/version`, { signal: controller.signal });\n clearTimeout(timeout);\n return response.ok;\n } catch {\n return false;\n }\n}\n\nexport function findBrowserExecutable(): string | null {\n if (process.platform === \"darwin\") {\n const candidates = [\n \"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome\",\n \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\",\n \"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary\",\n \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\",\n \"/Applications/Arc.app/Contents/MacOS/Arc\",\n \"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge\",\n \"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser\",\n ];\n return candidates.find((candidate) => existsSync(candidate)) ?? null;\n }\n\n if (process.platform === \"linux\") {\n const candidates = [\"google-chrome\", \"google-chrome-stable\", \"chromium-browser\", \"chromium\"];\n for (const candidate of candidates) {\n try {\n const resolved = execSync(`which ${candidate}`, { encoding: \"utf8\", stdio: [\"ignore\", \"pipe\", \"ignore\"] }).trim();\n if (resolved) {\n return resolved;\n }\n } catch {\n }\n }\n return null;\n }\n\n if (process.platform === \"win32\") {\n const candidates = [\n \"C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe\",\n \"C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe\",\n ];\n return candidates.find((candidate) => existsSync(candidate)) ?? null;\n }\n\n return null;\n}\n\nexport async function isManagedBrowserRunning(): Promise<boolean> {\n try {\n const rawPort = await readFile(MANAGED_PORT_FILE, \"utf8\");\n const port = Number.parseInt(rawPort.trim(), 10);\n if (!Number.isInteger(port) || port <= 0) {\n return false;\n }\n return await canConnect(\"127.0.0.1\", port);\n } catch {\n return false;\n }\n}\n\nexport async function launchManagedBrowser(port: number = DEFAULT_CDP_PORT): Promise<{ host: string; port: number } | null> {\n const executable = findBrowserExecutable();\n if (!executable) {\n return null;\n }\n\n await mkdir(MANAGED_USER_DATA_DIR, { recursive: true });\n\n // Set profile name so the Chrome window shows \"bb-browser\" in the title bar\n const defaultProfileDir = path.join(MANAGED_USER_DATA_DIR, \"Default\");\n const prefsPath = path.join(defaultProfileDir, \"Preferences\");\n await mkdir(defaultProfileDir, { recursive: true });\n try {\n let prefs: Record<string, unknown> = {};\n try { prefs = JSON.parse(await readFile(prefsPath, \"utf8\")); } catch {}\n if (!(prefs.profile as Record<string, unknown>)?.name || (prefs.profile as Record<string, unknown>).name !== \"bb-browser\") {\n prefs.profile = { ...(prefs.profile as Record<string, unknown> || {}), name: \"bb-browser\" };\n await writeFile(prefsPath, JSON.stringify(prefs), \"utf8\");\n }\n } catch {}\n\n const args = [\n `--remote-debugging-port=${port}`,\n `--user-data-dir=${MANAGED_USER_DATA_DIR}`,\n \"--no-first-run\",\n \"--no-default-browser-check\",\n \"--disable-sync\",\n \"--disable-background-networking\",\n \"--disable-component-update\",\n \"--disable-features=Translate,MediaRouter\",\n \"--disable-session-crashed-bubble\",\n \"--hide-crash-restore-bubble\",\n \"about:blank\",\n ];\n\n try {\n const child = spawn(executable, args, {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n } catch {\n return null;\n }\n\n await mkdir(MANAGED_BROWSER_DIR, { recursive: true });\n await writeFile(MANAGED_PORT_FILE, String(port), \"utf8\");\n\n const deadline = Date.now() + 8000;\n while (Date.now() < deadline) {\n if (await canConnect(\"127.0.0.1\", port)) {\n return { host: \"127.0.0.1\", port };\n }\n await new Promise((resolve) => setTimeout(resolve, 250));\n }\n\n return null;\n}\n\nexport async function discoverCdpPort(): Promise<{ host: string; port: number } | null> {\n const explicitPort = Number.parseInt(getArgValue(\"--port\") ?? \"\", 10);\n if (Number.isInteger(explicitPort) && explicitPort > 0 && await canConnect(\"127.0.0.1\", explicitPort)) {\n return { host: \"127.0.0.1\", port: explicitPort };\n }\n\n try {\n const rawPort = await readFile(MANAGED_PORT_FILE, \"utf8\");\n const managedPort = Number.parseInt(rawPort.trim(), 10);\n if (Number.isInteger(managedPort) && managedPort > 0 && await canConnect(\"127.0.0.1\", managedPort)) {\n return { host: \"127.0.0.1\", port: managedPort };\n }\n } catch {\n }\n\n if (process.argv.includes(\"--openclaw\")) {\n const viaOpenClaw = await tryOpenClaw();\n if (viaOpenClaw && await canConnect(viaOpenClaw.host, viaOpenClaw.port)) {\n return viaOpenClaw;\n }\n }\n\n const launched = await launchManagedBrowser();\n if (launched) {\n return launched;\n }\n\n if (!process.argv.includes(\"--openclaw\")) {\n const detectedOpenClaw = await tryOpenClaw();\n if (detectedOpenClaw && await canConnect(detectedOpenClaw.host, detectedOpenClaw.port)) {\n return detectedOpenClaw;\n }\n }\n\n return null;\n}\n","/**\n * CDP 客户端 - 与 Chrome DevTools Protocol 通信\n */\n\nimport type { Request, Response } from \"@bb-browser/shared\";\nimport { applyJq } from \"./jq.js\";\nimport { sendCommand as sendCdpCommand } from \"./cdp-client.js\";\n\nlet jqExpression: string | undefined;\n\nexport function setJqExpression(expression?: string): void {\n jqExpression = expression;\n}\n\nfunction printJqResults(response: Response): never {\n const target = response.data ?? response;\n const results = applyJq(target, jqExpression || \".\");\n for (const result of results) {\n console.log(typeof result === \"string\" ? result : JSON.stringify(result));\n }\n process.exit(0);\n}\n\nexport function handleJqResponse(response: Response): void {\n if (jqExpression) {\n printJqResults(response);\n }\n}\n\nexport async function sendCommand(request: Request): Promise<Response> {\n return sendCdpCommand(request);\n}\n","/**\n * 浏览器连接管理器 - 检测并连接 CDP\n */\n\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, resolve } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { ensureCdpConnection } from \"./cdp-client.js\";\nimport { discoverCdpPort } from \"./cdp-discovery.js\";\n\nexport function getDaemonPath(): string {\n const currentFile = fileURLToPath(import.meta.url);\n const currentDir = dirname(currentFile);\n const sameDirPath = resolve(currentDir, \"daemon.js\");\n if (existsSync(sameDirPath)) {\n return sameDirPath;\n }\n return resolve(currentDir, \"../../daemon/dist/index.js\");\n}\n\nexport async function isDaemonRunning(): Promise<boolean> {\n return (await discoverCdpPort()) !== null;\n}\n\nexport async function stopDaemon(): Promise<boolean> {\n return false;\n}\n\nexport async function ensureDaemonRunning(): Promise<void> {\n try {\n await ensureCdpConnection();\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"No browser connection found\")) {\n throw new Error([\n \"bb-browser: Could not start browser.\",\n \"\",\n \"Make sure Chrome is installed, then try again.\",\n \"Or specify a CDP port manually: bb-browser --port 9222\",\n ].join(\"\\n\"));\n }\n throw error;\n }\n}\n\n","import { copyFileSync, existsSync, unlinkSync } from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport interface HistorySearchResult {\n url: string;\n title: string;\n visitCount: number;\n lastVisitTime: number;\n}\n\nexport interface HistoryDomainResult {\n domain: string;\n visits: number;\n titles: string[];\n}\n\nfunction getHistoryPathCandidates(): string[] {\n const home = homedir();\n const localAppData = process.env.LOCALAPPDATA || \"\";\n const candidates: string[] = [\n join(home, \"Library/Application Support/Google/Chrome/Default/History\"),\n join(home, \"Library/Application Support/Microsoft Edge/Default/History\"),\n join(home, \"Library/Application Support/BraveSoftware/Brave-Browser/Default/History\"),\n join(home, \"Library/Application Support/Arc/User Data/Default/History\"),\n join(home, \".config/google-chrome/Default/History\"),\n ];\n\n if (localAppData) {\n candidates.push(\n join(localAppData, \"Google/Chrome/User Data/Default/History\"),\n join(localAppData, \"Microsoft/Edge/User Data/Default/History\")\n );\n }\n\n return candidates;\n}\n\nfunction findHistoryPath(): string | null {\n for (const historyPath of getHistoryPathCandidates()) {\n if (existsSync(historyPath)) {\n return historyPath;\n }\n }\n return null;\n}\n\nfunction sqlEscape(value: string): string {\n return value.replace(/'/g, \"''\");\n}\n\nfunction buildTimeWhere(days?: number): string {\n if (!days || days <= 0) {\n return \"\";\n }\n\n return `last_visit_time > (strftime('%s', 'now') - ${Math.floor(days)}*86400) * 1000000 + 11644473600000000`;\n}\n\nfunction runHistoryQuery<T>(sql: string, mapRow: (row: string[]) => T | null): T[] {\n const historyPath = findHistoryPath();\n if (!historyPath) {\n return [];\n }\n\n const tmpPath = join(tmpdir(), `bb-history-${Date.now()}-${Math.random().toString(36).slice(2)}.db`);\n\n try {\n copyFileSync(historyPath, tmpPath);\n const escapedTmpPath = tmpPath.replace(/\"/g, '\\\\\"');\n const escapedSql = sql.replace(/\"/g, '\\\\\"');\n const output = execSync(`sqlite3 -separator $'\\\\t' \"${escapedTmpPath}\" \"${escapedSql}\"`, {\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n\n return output\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => mapRow(line.split(\"\\t\")))\n .filter((item): item is T => item !== null);\n } catch {\n return [];\n } finally {\n try {\n unlinkSync(tmpPath);\n } catch {}\n }\n}\n\nexport function searchHistory(query?: string, days?: number): HistorySearchResult[] {\n const conditions: string[] = [];\n const trimmedQuery = query?.trim();\n\n if (trimmedQuery) {\n const escapedQuery = sqlEscape(trimmedQuery);\n conditions.push(`(url LIKE '%${escapedQuery}%' OR title LIKE '%${escapedQuery}%')`);\n }\n\n const timeWhere = buildTimeWhere(days);\n if (timeWhere) {\n conditions.push(timeWhere);\n }\n\n const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n const sql = `\n SELECT\n url,\n REPLACE(IFNULL(title, ''), char(9), ' '),\n IFNULL(visit_count, 0),\n IFNULL(last_visit_time, 0)\n FROM urls\n ${whereClause}\n ORDER BY last_visit_time DESC\n LIMIT 100;\n `.trim();\n\n return runHistoryQuery(sql, (row) => {\n if (row.length < 4) {\n return null;\n }\n\n const chromeTimestamp = Number(row[3]) || 0;\n return {\n url: row[0] || \"\",\n title: row[1] || \"\",\n visitCount: Number(row[2]) || 0,\n lastVisitTime: chromeTimestamp > 0 ? chromeTimestamp / 1000000 - 11644473600 : 0,\n };\n });\n}\n\nexport function getHistoryDomains(days?: number): HistoryDomainResult[] {\n const timeWhere = buildTimeWhere(days);\n const whereClause = timeWhere ? `WHERE ${timeWhere}` : \"\";\n const sql = `\n SELECT\n domain,\n SUM(visit_count) AS visits,\n GROUP_CONCAT(title, char(31)) AS titles\n FROM (\n SELECT\n CASE\n WHEN instr(url, '//') > 0 AND instr(substr(url, instr(url, '//') + 2), '/') > 0\n THEN substr(\n substr(url, instr(url, '//') + 2),\n 1,\n instr(substr(url, instr(url, '//') + 2), '/') - 1\n )\n WHEN instr(url, '//') > 0 THEN substr(url, instr(url, '//') + 2)\n WHEN instr(url, '/') > 0 THEN substr(url, 1, instr(url, '/') - 1)\n ELSE url\n END AS domain,\n IFNULL(visit_count, 0) AS visit_count,\n REPLACE(IFNULL(title, ''), char(31), ' ') AS title\n FROM urls\n ${whereClause}\n )\n WHERE domain != ''\n GROUP BY domain\n ORDER BY visits DESC\n LIMIT 50;\n `.trim();\n\n return runHistoryQuery(sql, (row) => {\n if (row.length < 3) {\n return null;\n }\n\n const titles = row[2]\n ? Array.from(new Set(row[2].split(String.fromCharCode(31)).map((title) => title.trim()).filter(Boolean))).slice(0, 10)\n : [];\n\n return {\n domain: row[0] || \"\",\n visits: Number(row[1]) || 0,\n titles,\n };\n });\n}\n","/**\n * site 命令 - 管理和运行社区/私有网站适配器\n *\n * 用法:\n * bb-browser site list 列出所有可用 site adapter\n * bb-browser site search <query> 搜索\n * bb-browser site <name> [args...] 运行(简写)\n * bb-browser site run <name> [args...] 运行\n * bb-browser site update 更新社区 adapter 库\n *\n * 目录:\n * ~/.bb-browser/sites/ 私有 adapter(优先)\n * ~/.bb-browser/bb-sites/ 社区 adapter(bb-browser site update 拉取)\n */\n\nimport { generateId, type Request, type Response, type TabInfo } from \"@bb-browser/shared\";\nimport { handleJqResponse, sendCommand } from \"../client.js\";\nimport { getHistoryDomains } from \"../history-sqlite.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\nimport { readFileSync, readdirSync, existsSync, mkdirSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { execSync } from \"node:child_process\";\n\nconst BB_DIR = join(homedir(), \".bb-browser\");\nconst LOCAL_SITES_DIR = join(BB_DIR, \"sites\");\nconst COMMUNITY_SITES_DIR = join(BB_DIR, \"bb-sites\");\nconst COMMUNITY_REPO = \"https://github.com/epiral/bb-sites.git\";\n\nfunction checkCliUpdate(): void {\n try {\n const current = execSync(\"bb-browser --version\", { timeout: 3000, stdio: [\"pipe\", \"pipe\", \"pipe\"] }).toString().trim();\n const latest = execSync(\"npm view bb-browser version\", { timeout: 5000, stdio: [\"pipe\", \"pipe\", \"pipe\"] }).toString().trim();\n if (latest && current && latest !== current && latest.localeCompare(current, undefined, { numeric: true }) > 0) {\n console.log(`\\n📦 bb-browser ${latest} available (current: ${current}). Run: npm install -g bb-browser`);\n }\n } catch {}\n}\n\nexport interface SiteOptions {\n json?: boolean;\n tabId?: number;\n days?: number;\n jq?: string;\n openclaw?: boolean;\n}\n\n/** Adapter 参数定义 */\ninterface ArgDef {\n required?: boolean;\n description?: string;\n}\n\n/** Adapter 元数据 */\ninterface SiteMeta {\n name: string;\n description: string;\n domain: string;\n args: Record<string, ArgDef>;\n capabilities?: string[];\n readOnly?: boolean;\n example?: string;\n filePath: string;\n source: \"local\" | \"community\";\n}\n\ninterface HistoryDomain {\n domain: string;\n visits: number;\n}\n\ninterface SiteRecommendation {\n domain: string;\n visits: number;\n adapterCount: number;\n adapters: Array<{\n name: string;\n description: string;\n example: string;\n }>;\n}\n\n/**\n * 从 JS 文件的 /* @meta JSON * / 块解析元数据\n */\nfunction parseSiteMeta(filePath: string, source: \"local\" | \"community\"): SiteMeta | null {\n let content: string;\n try {\n content = readFileSync(filePath, \"utf-8\");\n } catch {\n return null;\n }\n\n // 从文件路径推断默认 name\n const sitesDir = source === \"local\" ? LOCAL_SITES_DIR : COMMUNITY_SITES_DIR;\n const relPath = relative(sitesDir, filePath);\n const defaultName = relPath.replace(/\\.js$/, \"\").replace(/\\\\/g, \"/\");\n\n // 解析 /* @meta { ... } */ 块\n const metaMatch = content.match(/\\/\\*\\s*@meta\\s*\\n([\\s\\S]*?)\\*\\//);\n if (metaMatch) {\n try {\n const metaJson = JSON.parse(metaMatch[1]);\n return {\n name: metaJson.name || defaultName,\n description: metaJson.description || \"\",\n domain: metaJson.domain || \"\",\n args: metaJson.args || {},\n capabilities: metaJson.capabilities,\n readOnly: metaJson.readOnly,\n example: metaJson.example,\n filePath,\n source,\n };\n } catch {\n // JSON 解析失败,回退到 @tag 模式\n }\n }\n\n // 回退:解析 // @tag 格式(兼容旧格式)\n const meta: SiteMeta = {\n name: defaultName,\n description: \"\",\n domain: \"\",\n args: {},\n filePath,\n source,\n };\n\n const tagPattern = /\\/\\/\\s*@(\\w+)[ \\t]+(.*)/g;\n let match;\n while ((match = tagPattern.exec(content)) !== null) {\n const [, key, value] = match;\n switch (key) {\n case \"name\": meta.name = value.trim(); break;\n case \"description\": meta.description = value.trim(); break;\n case \"domain\": meta.domain = value.trim(); break;\n case \"args\":\n for (const arg of value.trim().split(/[,\\s]+/).filter(Boolean)) {\n meta.args[arg] = { required: true };\n }\n break;\n case \"example\": meta.example = value.trim(); break;\n }\n }\n\n return meta;\n}\n\n/**\n * 扫描目录下所有 .js 文件\n */\nfunction scanSites(dir: string, source: \"local\" | \"community\"): SiteMeta[] {\n if (!existsSync(dir)) return [];\n const sites: SiteMeta[] = [];\n\n function walk(currentDir: string): void {\n let entries;\n try { entries = readdirSync(currentDir, { withFileTypes: true }); } catch { return; }\n for (const entry of entries) {\n const fullPath = join(currentDir, entry.name);\n if (entry.isDirectory() && !entry.name.startsWith(\".\")) {\n walk(fullPath);\n } else if (entry.isFile() && entry.name.endsWith(\".js\")) {\n const meta = parseSiteMeta(fullPath, source);\n if (meta) sites.push(meta);\n }\n }\n }\n\n walk(dir);\n return sites;\n}\n\n/**\n * 根据 URL 检查是否有对应的 site adapter,返回提示文本\n */\nexport function getSiteHintForDomain(url: string): string | null {\n try {\n const hostname = new URL(url).hostname;\n const sites = getAllSites();\n const matched = sites.filter(s => s.domain && (hostname === s.domain || hostname.endsWith(\".\" + s.domain)));\n if (matched.length === 0) return null;\n const names = matched.map(s => s.name);\n const example = matched[0].example || `bb-browser site ${names[0]}`;\n return `该网站有 ${names.length} 个 site adapter 可直接获取数据,无需手动操作浏览器。试试: ${example}`;\n } catch {\n return null;\n }\n}\n\n/**\n * 获取所有 adapter(私有优先)\n */\nfunction getAllSites(): SiteMeta[] {\n const community = scanSites(COMMUNITY_SITES_DIR, \"community\");\n const local = scanSites(LOCAL_SITES_DIR, \"local\");\n\n const byName = new Map<string, SiteMeta>();\n for (const s of community) byName.set(s.name, s);\n for (const s of local) byName.set(s.name, s);\n\n return Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * 精确匹配 tab 的 origin\n */\nfunction matchTabOrigin(tabUrl: string, domain: string): boolean {\n try {\n const tabOrigin = new URL(tabUrl).hostname;\n return tabOrigin === domain || tabOrigin.endsWith(\".\" + domain);\n } catch {\n return false;\n }\n}\n\n// ── 子命令 ──────────────────────────────────────────────────────\n\nfunction siteList(options: SiteOptions): void {\n const sites = getAllSites();\n\n if (sites.length === 0) {\n console.log(\"未找到任何 site adapter。\");\n console.log(\" 安装社区 adapter: bb-browser site update\");\n console.log(` 私有 adapter 目录: ${LOCAL_SITES_DIR}`);\n return;\n }\n\n if (options.json) {\n console.log(JSON.stringify(sites.map(s => ({\n name: s.name, description: s.description, domain: s.domain,\n args: s.args, source: s.source,\n })), null, 2));\n return;\n }\n\n const groups = new Map<string, SiteMeta[]>();\n for (const s of sites) {\n const platform = s.name.split(\"/\")[0];\n if (!groups.has(platform)) groups.set(platform, []);\n groups.get(platform)!.push(s);\n }\n\n for (const [platform, items] of groups) {\n console.log(`\\n${platform}/`);\n for (const s of items) {\n const cmd = s.name.split(\"/\").slice(1).join(\"/\");\n const src = s.source === \"local\" ? \" (local)\" : \"\";\n const desc = s.description ? ` - ${s.description}` : \"\";\n console.log(` ${cmd.padEnd(20)}${desc}${src}`);\n }\n }\n console.log();\n}\n\nfunction siteSearch(query: string, options: SiteOptions): void {\n const sites = getAllSites();\n const q = query.toLowerCase();\n const matches = sites.filter(s =>\n s.name.toLowerCase().includes(q) ||\n s.description.toLowerCase().includes(q) ||\n s.domain.toLowerCase().includes(q)\n );\n\n if (matches.length === 0) {\n console.log(`未找到匹配 \"${query}\" 的 adapter。`);\n console.log(\" 查看所有: bb-browser site list\");\n return;\n }\n\n if (options.json) {\n console.log(JSON.stringify(matches.map(s => ({\n name: s.name, description: s.description, domain: s.domain, source: s.source,\n })), null, 2));\n return;\n }\n\n for (const s of matches) {\n const src = s.source === \"local\" ? \" (local)\" : \"\";\n console.log(`${s.name.padEnd(24)} ${s.description}${src}`);\n }\n}\n\nfunction siteUpdate(): void {\n mkdirSync(BB_DIR, { recursive: true });\n\n if (existsSync(join(COMMUNITY_SITES_DIR, \".git\"))) {\n console.log(\"更新社区 site adapter 库...\");\n try {\n execSync(\"git pull --ff-only\", { cwd: COMMUNITY_SITES_DIR, stdio: \"pipe\" });\n console.log(\"更新完成。\");\n console.log(\"\");\n console.log(\"💡 运行 bb-browser site recommend 看看哪些和你的浏览习惯匹配\");\n } catch (e) {\n console.error(`更新失败: ${e instanceof Error ? e.message : e}`);\n console.error(\" 手动修复: cd ~/.bb-browser/bb-sites && git pull\");\n process.exit(1);\n }\n } else {\n console.log(`克隆社区 adapter 库: ${COMMUNITY_REPO}`);\n try {\n execSync(`git clone ${COMMUNITY_REPO} ${COMMUNITY_SITES_DIR}`, { stdio: \"pipe\" });\n console.log(\"克隆完成。\");\n console.log(\"\");\n console.log(\"💡 运行 bb-browser site recommend 看看哪些和你的浏览习惯匹配\");\n } catch (e) {\n console.error(`克隆失败: ${e instanceof Error ? e.message : e}`);\n console.error(` 手动修复: git clone ${COMMUNITY_REPO} ~/.bb-browser/bb-sites`);\n process.exit(1);\n }\n }\n\n const sites = scanSites(COMMUNITY_SITES_DIR, \"community\");\n console.log(`已安装 ${sites.length} 个社区 adapter。`);\n console.log(`⭐ Like bb-browser? → bb-browser star`);\n\n // Check for CLI updates\n checkCliUpdate();\n}\n\nfunction findSiteByName(name: string): SiteMeta | undefined {\n return getAllSites().find((site) => site.name === name);\n}\n\nfunction siteInfo(name: string, options: SiteOptions): void {\n const site = findSiteByName(name);\n\n if (!site) {\n console.error(`[error] site info: adapter \"${name}\" not found.`);\n console.error(\" Try: bb-browser site list\");\n process.exit(1);\n }\n\n const meta = {\n name: site.name,\n description: site.description,\n domain: site.domain,\n args: site.args,\n example: site.example,\n readOnly: site.readOnly,\n };\n\n if (options.json) {\n console.log(JSON.stringify(meta, null, 2));\n return;\n }\n\n console.log(`${site.name} — ${site.description}`);\n console.log();\n console.log(\"参数:\");\n\n const argEntries = Object.entries(site.args);\n if (argEntries.length === 0) {\n console.log(\" (无)\");\n } else {\n for (const [argName, argDef] of argEntries) {\n const requiredText = argDef.required ? \"必填\" : \"可选\";\n const description = argDef.description || \"\";\n console.log(` ${argName} (${requiredText}) ${description}`.trimEnd());\n }\n }\n\n console.log();\n console.log(\"示例:\");\n console.log(` ${site.example || `bb-browser site ${site.name}`}`);\n console.log();\n console.log(`域名:${site.domain || \"(未声明)\"}`);\n console.log(`只读:${site.readOnly ? \"是\" : \"否\"}`);\n}\n\nasync function siteRecommend(options: SiteOptions): Promise<void> {\n const days = options.days ?? 30;\n const historyDomains: HistoryDomain[] = getHistoryDomains(days);\n const sites = getAllSites();\n const sitesByDomain = new Map<string, SiteMeta[]>();\n\n for (const site of sites) {\n if (!site.domain) continue;\n const domain = site.domain.toLowerCase();\n const existing = sitesByDomain.get(domain) || [];\n existing.push(site);\n sitesByDomain.set(domain, existing);\n }\n\n const available: SiteRecommendation[] = [];\n const notAvailable: HistoryDomain[] = [];\n\n for (const item of historyDomains) {\n const adapters = sitesByDomain.get(item.domain.toLowerCase());\n if (adapters && adapters.length > 0) {\n const sortedAdapters = [...adapters].sort((a, b) => a.name.localeCompare(b.name));\n available.push({\n domain: item.domain,\n visits: item.visits,\n adapterCount: sortedAdapters.length,\n adapters: sortedAdapters.map((site) => ({\n name: site.name,\n description: site.description,\n example: site.example || `bb-browser site ${site.name}`,\n })),\n });\n } else if (item.visits >= 5 && item.domain && !item.domain.includes('localhost') && item.domain.includes('.')) {\n notAvailable.push(item);\n }\n }\n\n const jsonData = {\n days,\n available,\n not_available: notAvailable,\n };\n\n if (options.jq) {\n handleJqResponse({ id: generateId(), success: true, data: jsonData as any });\n }\n\n if (options.json) {\n console.log(JSON.stringify(jsonData, null, 2));\n return;\n }\n\n console.log(`基于你最近 ${days} 天的浏览记录:`);\n console.log();\n\n console.log(\"🎯 你常用这些网站,可以直接用:\");\n console.log();\n if (available.length === 0) {\n console.log(\" (暂无匹配的 adapter)\");\n } else {\n for (const item of available) {\n console.log(` ${item.domain.padEnd(20)} ${item.visits} 次访问 ${item.adapterCount} 个命令`);\n console.log(` 试试: ${item.adapters[0]?.example || `bb-browser site ${item.adapters[0]?.name || \"\"}`}`);\n console.log();\n }\n }\n\n console.log(\"📋 你常用但还没有 adapter:\");\n console.log();\n if (notAvailable.length === 0) {\n console.log(\" (暂无)\");\n } else {\n for (const item of notAvailable) {\n console.log(` ${item.domain.padEnd(20)} ${item.visits} 次访问`);\n }\n }\n\n console.log();\n console.log('💡 跟你的 AI Agent 说 \"把 notion.so CLI 化\",它就能自动完成。');\n console.log();\n console.log(`所有分析纯本地完成。用 --days 7 只看最近一周。`);\n}\n\nasync function siteRun(\n name: string,\n args: string[],\n options: SiteOptions\n): Promise<void> {\n const sites = getAllSites();\n const site = sites.find(s => s.name === name);\n\n if (!site) {\n const fuzzy = sites.filter(s => s.name.includes(name));\n console.error(`[error] site: \"${name}\" not found.`);\n if (fuzzy.length > 0) {\n console.error(\" Did you mean:\");\n for (const s of fuzzy.slice(0, 5)) {\n console.error(` bb-browser site ${s.name}`);\n }\n } else {\n console.error(\" Try: bb-browser site list\");\n console.error(\" Or: bb-browser site update\");\n }\n process.exit(1);\n }\n\n // 解析参数\n const argNames = Object.keys(site.args);\n const argMap: Record<string, string> = {};\n\n // 过滤掉 --flag value 对,收集位置参数\n const positionalArgs: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i].startsWith(\"--\")) {\n const flagName = args[i].slice(2);\n if (flagName in site.args && args[i + 1]) {\n argMap[flagName] = args[i + 1];\n i++; // 跳过值\n }\n } else {\n positionalArgs.push(args[i]);\n }\n }\n\n // 位置参数按 argNames 顺序填入(跳过已通过 --flag 提供的)\n let posIdx = 0;\n for (const argName of argNames) {\n if (!argMap[argName] && posIdx < positionalArgs.length) {\n argMap[argName] = positionalArgs[posIdx++];\n }\n }\n\n // 只检查 required 参数\n for (const [argName, argDef] of Object.entries(site.args)) {\n if (argDef.required && !argMap[argName]) {\n console.error(`[error] site ${name}: missing required argument \"${argName}\".`);\n const usage = argNames.map(a => {\n const def = site.args[a];\n return def.required ? `<${a}>` : `[${a}]`;\n }).join(\" \");\n console.error(` Usage: bb-browser site ${name} ${usage}`);\n if (site.example) console.error(` Example: ${site.example}`);\n process.exit(1);\n }\n }\n\n // 读取并解析 JS\n const jsContent = readFileSync(site.filePath, \"utf-8\");\n\n // 移除 /* @meta ... */ 块,保留函数体\n const jsBody = jsContent.replace(/\\/\\*\\s*@meta[\\s\\S]*?\\*\\//, \"\").trim();\n\n // 构造执行脚本\n const argsJson = JSON.stringify(argMap);\n const script = `(${jsBody})(${argsJson})`;\n\n if (options.openclaw) {\n const { ocGetTabs, ocFindTabByDomain, ocOpenTab, ocEvaluate } = await import(\"../openclaw-bridge.js\");\n\n let targetId: string;\n\n if (site.domain) {\n const tabs = ocGetTabs();\n const existing = ocFindTabByDomain(tabs, site.domain);\n if (existing) {\n targetId = existing.targetId;\n } else {\n targetId = ocOpenTab(`https://${site.domain}`);\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n } else {\n const tabs = ocGetTabs();\n if (tabs.length === 0) {\n throw new Error(\"No tabs open in OpenClaw browser\");\n }\n targetId = tabs[0].targetId;\n }\n\n const wrappedFn = `async () => { const __fn = ${jsBody}; return await __fn(${argsJson}); }`;\n const parsed = ocEvaluate(targetId, wrappedFn);\n\n if (typeof parsed === \"object\" && parsed !== null && \"error\" in parsed) {\n const errObj = parsed as { error: string; hint?: string };\n const checkText = `${errObj.error} ${errObj.hint || \"\"}`;\n const isAuthError = /401|403|unauthorized|forbidden|not.?logged|login.?required|sign.?in|auth/i.test(checkText);\n const loginHint = isAuthError && site.domain\n ? `Please log in to https://${site.domain} in your OpenClaw browser first, then retry.`\n : undefined;\n const hint = loginHint || errObj.hint;\n const reportHint = `If this is an adapter bug, report via: gh issue create --repo epiral/bb-sites --title \"[${name}] <description>\" OR: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] <description>\"`;\n\n if (options.json) {\n console.log(JSON.stringify({ id: \"openclaw\", success: false, error: errObj.error, hint, reportHint }));\n } else {\n console.error(`[error] site ${name}: ${errObj.error}`);\n if (hint) console.error(` Hint: ${hint}`);\n console.error(` Report: gh issue create --repo epiral/bb-sites --title \"[${name}] ...\"`);\n console.error(` or: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] ...\"`);\n }\n process.exit(1);\n }\n\n if (options.jq) {\n const { applyJq } = await import(\"../jq.js\");\n const expr = options.jq.replace(/^\\.data\\./, '.');\n const results = applyJq(parsed, expr);\n for (const r of results) {\n console.log(typeof r === \"string\" ? r : JSON.stringify(r));\n }\n } else if (options.json) {\n console.log(JSON.stringify({ id: \"openclaw\", success: true, data: parsed }));\n } else {\n console.log(JSON.stringify(parsed, null, 2));\n }\n return;\n }\n\n await ensureDaemonRunning();\n\n // 确定目标 tab\n let targetTabId: number | undefined = options.tabId;\n\n // 如果用户没指定 --tab,自动查找匹配域名的 tab\n if (!targetTabId && site.domain) {\n const listReq: Request = { id: generateId(), action: \"tab_list\" };\n const listResp: Response = await sendCommand(listReq);\n\n if (listResp.success && listResp.data?.tabs) {\n const matchingTab = listResp.data.tabs.find((tab: TabInfo) =>\n matchTabOrigin(tab.url, site.domain)\n );\n if (matchingTab) {\n targetTabId = matchingTab.tabId;\n }\n }\n\n if (!targetTabId) {\n const newResp = await sendCommand({\n id: generateId(),\n action: \"tab_new\",\n url: `https://${site.domain}`,\n });\n targetTabId = newResp.data?.tabId;\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n }\n\n // 执行\n const evalReq: Request = { id: generateId(), action: \"eval\", script, tabId: targetTabId };\n const evalResp: Response = await sendCommand(evalReq);\n\n if (!evalResp.success) {\n const hint = site.domain\n ? `Open https://${site.domain} in your browser, make sure you are logged in, then retry.`\n : undefined;\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: false, error: evalResp.error || \"eval failed\", hint }));\n } else {\n console.error(`[error] site ${name}: ${evalResp.error || \"eval failed\"}`);\n if (hint) console.error(` Hint: ${hint}`);\n }\n process.exit(1);\n }\n\n const result = evalResp.data?.result;\n if (result === undefined || result === null) {\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: true, data: null }));\n } else {\n console.log(\"(no output)\");\n }\n return;\n }\n\n // 解析输出\n let parsed: unknown;\n try {\n parsed = typeof result === \"string\" ? JSON.parse(result) : result;\n } catch {\n parsed = result;\n }\n\n // 检查 adapter 返回的 error\n if (typeof parsed === \"object\" && parsed !== null && \"error\" in parsed) {\n const errObj = parsed as { error: string; hint?: string };\n\n // 检测是否为登录问题(检查 error 和 hint 文本)\n const checkText = `${errObj.error} ${errObj.hint || \"\"}`;\n const isAuthError = /401|403|unauthorized|forbidden|not.?logged|login.?required|sign.?in|auth/i.test(checkText);\n const loginHint = isAuthError && site.domain\n ? `Please log in to https://${site.domain} in your browser first, then retry.`\n : undefined;\n const hint = loginHint || errObj.hint;\n const reportHint = `If this is an adapter bug, report via: gh issue create --repo epiral/bb-sites --title \"[${name}] <description>\" OR: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] <description>\"`;\n\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: false, error: errObj.error, hint, reportHint }));\n } else {\n console.error(`[error] site ${name}: ${errObj.error}`);\n if (hint) console.error(` Hint: ${hint}`);\n console.error(` Report: gh issue create --repo epiral/bb-sites --title \"[${name}] ...\"`);\n console.error(` or: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] ...\"`);\n }\n process.exit(1);\n }\n\n if (options.jq) {\n const { applyJq } = await import(\"../jq.js\");\n // Tolerate \".data.\" prefix — Agent may copy from --json envelope structure\n const expr = options.jq.replace(/^\\.data\\./, '.');\n const results = applyJq(parsed, expr);\n for (const r of results) {\n console.log(typeof r === \"string\" ? r : JSON.stringify(r));\n }\n } else if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: true, data: parsed }));\n } else {\n console.log(JSON.stringify(parsed, null, 2));\n }\n}\n\n// ── 入口 ────────────────────────────────────────────────────────\n\nexport async function siteCommand(\n args: string[],\n options: SiteOptions = {}\n): Promise<void> {\n const subCommand = args[0];\n\n if (!subCommand || subCommand === \"--help\" || subCommand === \"-h\") {\n console.log(`bb-browser site - 网站 CLI 化(管理和运行 site adapter)\n\n用法:\n bb-browser site list 列出所有可用 adapter\n bb-browser site info <name> 查看 adapter 元信息\n bb-browser site recommend 基于历史记录推荐 adapter\n bb-browser site search <query> 搜索 adapter\n bb-browser site <name> [args...] 运行 adapter(简写)\n bb-browser site run <name> [args...] 运行 adapter\n bb-browser site update 更新社区 adapter 库 (git clone/pull)\n\n目录:\n ${LOCAL_SITES_DIR} 私有 adapter(优先)\n ${COMMUNITY_SITES_DIR} 社区 adapter\n\n示例:\n bb-browser site update\n bb-browser site list\n bb-browser site reddit/thread https://www.reddit.com/r/LocalLLaMA/comments/...\n bb-browser site twitter/user yan5xu\n bb-browser site search reddit\n\n创建新 adapter: bb-browser guide\n报告问题: gh issue create --repo epiral/bb-sites --title \"[adapter-name] 描述\"\n贡献社区: https://github.com/epiral/bb-sites`);\n return;\n }\n\n switch (subCommand) {\n case \"list\": siteList(options); break;\n case \"search\":\n if (!args[1]) {\n console.error(\"[error] site search: <query> is required.\");\n console.error(\" Usage: bb-browser site search <query>\");\n process.exit(1);\n }\n siteSearch(args[1], options);\n break;\n case \"info\":\n if (!args[1]) {\n console.error(\"[error] site info: <name> is required.\");\n console.error(\" Usage: bb-browser site info <name>\");\n process.exit(1);\n }\n siteInfo(args[1], options);\n break;\n case \"recommend\":\n await siteRecommend(options);\n break;\n case \"update\": siteUpdate(); break;\n case \"run\":\n if (!args[1]) {\n console.error(\"[error] site run: <name> is required.\");\n console.error(\" Usage: bb-browser site run <name> [args...]\");\n console.error(\" Try: bb-browser site list\");\n process.exit(1);\n }\n await siteRun(args[1], args.slice(2), options);\n break;\n default:\n if (subCommand.includes(\"/\")) {\n await siteRun(subCommand, args.slice(1), options);\n } else {\n console.error(`[error] site: unknown subcommand \"${subCommand}\".`);\n console.error(\" Available: list, info, recommend, search, run, update\");\n console.error(\" Try: bb-browser site --help\");\n process.exit(1);\n }\n break;\n }\n\n // 静默后台更新社区 adapter\n silentUpdate();\n}\n\nfunction silentUpdate(): void {\n const gitDir = join(COMMUNITY_SITES_DIR, \".git\");\n if (!existsSync(gitDir)) return;\n import(\"node:child_process\").then(({ spawn }) => {\n const child = spawn(\"git\", [\"pull\", \"--ff-only\"], {\n cwd: COMMUNITY_SITES_DIR,\n stdio: \"ignore\",\n detached: true,\n });\n child.unref();\n }).catch(() => {});\n}\n","/**\n * open 命令 - 打开指定 URL\n * \n * 用法:\n * bb-browser open <url> # 在新 tab 中打开\n * bb-browser open <url> --tab current # 在当前 tab 中打开\n * bb-browser open <url> --tab 123 # 在指定 tabId 的 tab 中打开\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\nimport { getSiteHintForDomain } from \"./site.js\";\n\nexport interface OpenOptions {\n json?: boolean;\n tab?: string; // \"current\" | tabId 数字字符串 | undefined(新建 tab)\n}\n\nexport async function openCommand(\n url: string,\n options: OpenOptions = {}\n): Promise<void> {\n // 验证 URL\n if (!url) {\n throw new Error(\"缺少 URL 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 补全 URL 协议\n let normalizedUrl = url;\n if (!url.startsWith(\"http://\") && !url.startsWith(\"https://\")) {\n normalizedUrl = \"https://\" + url;\n }\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"open\",\n url: normalizedUrl,\n };\n\n // 处理 --tab 参数\n if (options.tab !== undefined) {\n if (options.tab === \"current\") {\n // 使用当前活动 tab\n (request as Record<string, unknown>).tabId = \"current\";\n } else {\n // 使用指定 tabId\n const tabId = parseInt(options.tab, 10);\n if (isNaN(tabId)) {\n throw new Error(`无效的 tabId: ${options.tab}`);\n }\n (request as Record<string, unknown>).tabId = tabId;\n }\n }\n // 不指定 --tab 时,tabId 为 undefined,扩展会创建新 tab\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`已打开: ${response.data?.url ?? normalizedUrl}`);\n if (response.data?.title) {\n console.log(`标题: ${response.data.title}`);\n }\n if (response.data?.tabId) {\n console.log(`Tab ID: ${response.data.tabId}`);\n }\n // 提示:如果该域名有 site adapter,引导使用\n const siteHint = getSiteHintForDomain(normalizedUrl);\n if (siteHint) {\n console.log(`\\n💡 ${siteHint}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * snapshot 命令 - 获取当前页面快照\n * 用法:bb-browser snapshot [-i|--interactive] [-c|--compact] [-d|--depth N] [-s|--selector SEL]\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface SnapshotOptions {\n json?: boolean;\n /** 只输出可交互元素 */\n interactive?: boolean;\n /** 移除空结构节点 */\n compact?: boolean;\n /** 限制树深度 */\n maxDepth?: number;\n /** CSS 选择器范围 */\n selector?: string;\n tabId?: number;\n}\n\nexport async function snapshotCommand(\n options: SnapshotOptions = {}\n): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"snapshot\",\n interactive: options.interactive,\n compact: options.compact,\n maxDepth: options.maxDepth,\n selector: options.selector,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`标题: ${response.data?.title ?? \"(无标题)\"}`);\n console.log(`URL: ${response.data?.url ?? \"(未知)\"}`);\n // 输出 snapshot 文本\n if (response.data?.snapshotData?.snapshot) {\n console.log(\"\");\n console.log(response.data.snapshotData.snapshot);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * click 命令 - 点击元素\n * 用法:bb-browser click <ref>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ClickOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function clickCommand(\n ref: string,\n options: ClickOptions = {}\n): Promise<void> {\n // 验证 ref\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"click\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已点击: ${role} \"${name}\"`);\n } else {\n console.log(`已点击: ${role}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * hover 命令 - 悬停在元素上\n * 用法:bb-browser hover <ref>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface HoverOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function hoverCommand(\n ref: string,\n options: HoverOptions = {}\n): Promise<void> {\n // 验证 ref\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"hover\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已悬停: ${role} \"${name}\"`);\n } else {\n console.log(`已悬停: ${role}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * fill 命令 - 填充输入框\n * 用法:bb-browser fill <ref> <text>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface FillOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function fillCommand(\n ref: string,\n text: string,\n options: FillOptions = {}\n): Promise<void> {\n // 验证参数\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n if (text === undefined || text === null) {\n throw new Error(\"缺少 text 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"fill\",\n ref: parsedRef,\n text: text,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已填充: ${role} \"${name}\"`);\n } else {\n console.log(`已填充: ${role}`);\n }\n console.log(`内容: \"${text}\"`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * type 命令 - 在元素中逐字符输入文本(不清空原有内容)\n * 用法:bb-browser type <ref> <text>\n * \n * 与 fill 命令的区别:\n * - fill:先清空再填入\n * - type:不清空,逐字符追加输入\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface TypeOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function typeCommand(\n ref: string,\n text: string,\n options: TypeOptions = {}\n): Promise<void> {\n // 验证参数\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n if (text === undefined || text === null) {\n throw new Error(\"缺少 text 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"type\",\n ref: parsedRef,\n text: text,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已输入: ${role} \"${name}\"`);\n } else {\n console.log(`已输入: ${role}`);\n }\n console.log(`内容: \"${text}\"`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * close 命令 - 关闭当前标签页\n * 用法:bb-browser close\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface CloseOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport async function closeCommand(options: CloseOptions = {}): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"close\",\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const title = response.data?.title ?? \"\";\n if (title) {\n console.log(`已关闭: \"${title}\"`);\n } else {\n console.log(\"已关闭当前标签页\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * get 命令 - 获取页面或元素信息\n * 用法:\n * bb-browser get text <ref> 获取元素文本\n * bb-browser get url 获取当前页面 URL\n * bb-browser get title 获取页面标题\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface GetOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/** 支持的 get 属性类型 */\nexport type GetAttribute = \"text\" | \"url\" | \"title\";\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function getCommand(\n attribute: GetAttribute,\n ref: string | undefined,\n options: GetOptions = {}\n): Promise<void> {\n // 验证参数\n if (attribute === \"text\" && !ref) {\n throw new Error(\"get text 需要 ref 参数,如: get text @5\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"get\",\n attribute,\n ref: ref ? parseRef(ref) : undefined,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const value = response.data?.value ?? \"\";\n console.log(value);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * screenshot 命令 - 截取当前页面\n * 用法:\n * bb-browser screenshot # 保存到临时目录\n * bb-browser screenshot ./page.png # 保存到指定路径\n * bb-browser screenshot --json # 返回 { path, base64 }\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ScreenshotOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 生成默认截图路径\n */\nfunction getDefaultPath(): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const filename = `bb-screenshot-${timestamp}.png`;\n return path.join(os.tmpdir(), filename);\n}\n\n/**\n * 解码 data URL 并保存为文件\n */\nfunction saveBase64Image(dataUrl: string, filePath: string): void {\n const base64Data = dataUrl.replace(/^data:image\\/png;base64,/, \"\");\n const buffer = Buffer.from(base64Data, \"base64\");\n \n // 确保目录存在\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n \n fs.writeFileSync(filePath, buffer);\n}\n\nexport async function screenshotCommand(\n outputPath?: string,\n options: ScreenshotOptions = {}\n): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 确定保存路径\n const filePath = outputPath ? path.resolve(outputPath) : getDefaultPath();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"screenshot\",\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 处理结果\n if (response.success && response.data?.dataUrl) {\n const dataUrl = response.data.dataUrl as string;\n \n // 保存文件\n saveBase64Image(dataUrl, filePath);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify({\n success: true,\n path: filePath,\n base64: dataUrl,\n }, null, 2));\n } else {\n console.log(`截图已保存: ${filePath}`);\n }\n } else {\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n console.error(`错误: ${response.error}`);\n }\n process.exit(1);\n }\n}\n","/**\n * wait 命令 - 等待指定时间或元素出现\n * 用法:\n * bb-browser wait <ms> 等待指定毫秒数\n * bb-browser wait @<ref> 等待元素出现(最多 10 秒)\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface WaitOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 判断是否是等待时间(纯数字)\n */\nfunction isTimeWait(target: string): boolean {\n return /^\\d+$/.test(target);\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function waitCommand(\n target: string,\n options: WaitOptions = {}\n): Promise<void> {\n if (!target) {\n throw new Error(\"缺少等待目标参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n let request: Request;\n\n if (isTimeWait(target)) {\n // 等待时间模式\n const ms = parseInt(target, 10);\n request = {\n id: generateId(),\n action: \"wait\",\n waitType: \"time\",\n ms,\n tabId: options.tabId,\n };\n } else {\n // 等待元素模式\n const ref = parseRef(target);\n request = {\n id: generateId(),\n action: \"wait\",\n waitType: \"element\",\n ref,\n tabId: options.tabId,\n };\n }\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n if (isTimeWait(target)) {\n console.log(`已等待 ${target}ms`);\n } else {\n console.log(`元素 @${parseRef(target)} 已出现`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * press 命令 - 发送键盘按键\n * 用法:bb-browser press <key>\n *\n * key 支持格式:\n * - 单键:\"Enter\", \"Tab\", \"Escape\", \"Backspace\", \"ArrowUp\" 等\n * - 组合键:\"Control+a\", \"Control+c\", \"Control+v\"(用 + 分隔)\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface PressOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析按键字符串,提取修饰键和主键\n * 例如:\n * \"Enter\" -> { key: \"Enter\", modifiers: [] }\n * \"Control+a\" -> { key: \"a\", modifiers: [\"Control\"] }\n * \"Control+Shift+Delete\" -> { key: \"Delete\", modifiers: [\"Control\", \"Shift\"] }\n */\nfunction parseKey(keyString: string): { key: string; modifiers: string[] } {\n const parts = keyString.split(\"+\");\n const modifierNames = [\"Control\", \"Alt\", \"Shift\", \"Meta\"];\n\n const modifiers: string[] = [];\n let key = \"\";\n\n for (const part of parts) {\n if (modifierNames.includes(part)) {\n modifiers.push(part);\n } else {\n key = part;\n }\n }\n\n return { key, modifiers };\n}\n\nexport async function pressCommand(\n keyString: string,\n options: PressOptions = {}\n): Promise<void> {\n // 验证参数\n if (!keyString) {\n throw new Error(\"缺少 key 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析按键\n const { key, modifiers } = parseKey(keyString);\n\n if (!key) {\n throw new Error(\"无效的按键格式\");\n }\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"press\",\n key,\n modifiers,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const displayKey = modifiers.length > 0 ? `${modifiers.join(\"+\")}+${key}` : key;\n console.log(`已按下: ${displayKey}`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * scroll 命令 - 滚动页面\n * 用法:bb-browser scroll <direction> [pixels]\n *\n * direction: up | down | left | right\n * pixels: 滚动像素数,默认 300\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ScrollOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport type ScrollDirection = \"up\" | \"down\" | \"left\" | \"right\";\n\nconst VALID_DIRECTIONS: ScrollDirection[] = [\"up\", \"down\", \"left\", \"right\"];\nconst DEFAULT_PIXELS = 300;\n\nexport async function scrollCommand(\n direction: string,\n pixels?: string,\n options: ScrollOptions = {}\n): Promise<void> {\n // 验证 direction\n if (!direction) {\n throw new Error(\"缺少 direction 参数\");\n }\n\n if (!VALID_DIRECTIONS.includes(direction as ScrollDirection)) {\n throw new Error(\n `无效的滚动方向: ${direction},支持: ${VALID_DIRECTIONS.join(\", \")}`\n );\n }\n\n // 解析 pixels\n let pixelValue = DEFAULT_PIXELS;\n if (pixels !== undefined) {\n pixelValue = parseInt(pixels, 10);\n if (isNaN(pixelValue) || pixelValue <= 0) {\n throw new Error(`无效的像素值: ${pixels}`);\n }\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"scroll\",\n direction: direction as ScrollDirection,\n pixels: pixelValue,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`已滚动: ${direction} ${pixelValue}px`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * 导航命令 - back/forward/refresh\n * 用法:\n * bb-browser back 后退\n * bb-browser forward 前进\n * bb-browser refresh 刷新页面\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface NavOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * back 命令 - 后退\n */\nexport async function backCommand(options: NavOptions = {}): Promise<void> {\n await ensureDaemonRunning();\n\n const request: Request = {\n id: generateId(),\n action: \"back\",\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const url = response.data?.url ?? \"\";\n if (url) {\n console.log(`后退至: ${url}`);\n } else {\n console.log(\"已后退\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n\n/**\n * forward 命令 - 前进\n */\nexport async function forwardCommand(options: NavOptions = {}): Promise<void> {\n await ensureDaemonRunning();\n\n const request: Request = {\n id: generateId(),\n action: \"forward\",\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const url = response.data?.url ?? \"\";\n if (url) {\n console.log(`前进至: ${url}`);\n } else {\n console.log(\"已前进\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n\n/**\n * refresh 命令 - 刷新页面\n */\nexport async function refreshCommand(options: NavOptions = {}): Promise<void> {\n await ensureDaemonRunning();\n\n const request: Request = {\n id: generateId(),\n action: \"refresh\",\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const title = response.data?.title ?? \"\";\n if (title) {\n console.log(`已刷新: \"${title}\"`);\n } else {\n console.log(\"已刷新页面\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * check/uncheck 命令 - 勾选/取消勾选复选框\n * 用法:\n * bb-browser check <ref> 勾选复选框\n * bb-browser uncheck <ref> 取消勾选复选框\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface CheckOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\n/**\n * 勾选复选框\n */\nexport async function checkCommand(\n ref: string,\n options: CheckOptions = {}\n): Promise<void> {\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n await ensureDaemonRunning();\n\n const parsedRef = parseRef(ref);\n\n const request: Request = {\n id: generateId(),\n action: \"check\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"checkbox\";\n const name = response.data?.name;\n const wasAlreadyChecked = response.data?.wasAlreadyChecked;\n \n if (wasAlreadyChecked) {\n if (name) {\n console.log(`已勾选(之前已勾选): ${role} \"${name}\"`);\n } else {\n console.log(`已勾选(之前已勾选): ${role}`);\n }\n } else {\n if (name) {\n console.log(`已勾选: ${role} \"${name}\"`);\n } else {\n console.log(`已勾选: ${role}`);\n }\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n\n/**\n * 取消勾选复选框\n */\nexport async function uncheckCommand(\n ref: string,\n options: CheckOptions = {}\n): Promise<void> {\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n await ensureDaemonRunning();\n\n const parsedRef = parseRef(ref);\n\n const request: Request = {\n id: generateId(),\n action: \"uncheck\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"checkbox\";\n const name = response.data?.name;\n const wasAlreadyUnchecked = response.data?.wasAlreadyUnchecked;\n \n if (wasAlreadyUnchecked) {\n if (name) {\n console.log(`已取消勾选(之前未勾选): ${role} \"${name}\"`);\n } else {\n console.log(`已取消勾选(之前未勾选): ${role}`);\n }\n } else {\n if (name) {\n console.log(`已取消勾选: ${role} \"${name}\"`);\n } else {\n console.log(`已取消勾选: ${role}`);\n }\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * select 命令 - 在下拉框中选择选项\n * 用法:bb-browser select <ref> <value>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n * \n * value:选项的 value 属性值或显示文本(label)\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface SelectOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function selectCommand(\n ref: string,\n value: string,\n options: SelectOptions = {}\n): Promise<void> {\n // 验证参数\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n if (value === undefined || value === null) {\n throw new Error(\"缺少 value 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"select\",\n ref: parsedRef,\n value: value,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"combobox\";\n const name = response.data?.name;\n const selectedValue = response.data?.selectedValue;\n const selectedLabel = response.data?.selectedLabel;\n if (name) {\n console.log(`已选择: ${role} \"${name}\"`);\n } else {\n console.log(`已选择: ${role}`);\n }\n if (selectedLabel && selectedLabel !== selectedValue) {\n console.log(`选项: \"${selectedLabel}\" (value=\"${selectedValue}\")`);\n } else {\n console.log(`选项: \"${selectedValue}\"`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * eval 命令 - 在当前页面执行 JavaScript\n * 用法:bb-browser eval \"<js>\"\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface EvalOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport async function evalCommand(\n script: string,\n options: EvalOptions = {}\n): Promise<void> {\n // 验证 script\n if (!script) {\n throw new Error(\"缺少 script 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"eval\",\n script,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const result = response.data?.result;\n if (result !== undefined) {\n // 如果结果是对象,格式化输出\n if (typeof result === \"object\" && result !== null) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(result);\n }\n } else {\n console.log(\"undefined\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * tab 命令 - 标签页管理\n * 用法:\n * bb-browser tab 列出所有标签页\n * bb-browser tab new [url] 新建标签页\n * bb-browser tab <n> 切换到第 n 个标签页(按 index)\n * bb-browser tab close [n] 关闭标签页(按 index)\n * bb-browser tab select --id <id> 切换到指定 tabId 的标签页\n * bb-browser tab close --id <id> 关闭指定 tabId 的标签页\n */\n\nimport { generateId, type Request, type Response, type TabInfo } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface TabOptions {\n json?: boolean;\n}\n\n/**\n * 解析 tab 子命令\n * @param args 命令参数数组(已去掉 flags)\n * @param rawArgv 原始 process.argv(用于提取 --id)\n * @returns 解析后的子命令和参数\n */\nfunction parseTabSubcommand(args: string[], rawArgv?: string[]): {\n action: \"tab_list\" | \"tab_new\" | \"tab_select\" | \"tab_close\";\n url?: string;\n index?: number;\n tabId?: number;\n} {\n // 提取 --id 参数\n let tabId: number | undefined;\n if (rawArgv) {\n const idIdx = rawArgv.indexOf(\"--id\");\n if (idIdx >= 0 && rawArgv[idIdx + 1]) {\n tabId = parseInt(rawArgv[idIdx + 1], 10);\n if (isNaN(tabId)) {\n throw new Error(`无效的 tabId: ${rawArgv[idIdx + 1]}`);\n }\n }\n }\n\n if (args.length === 0) {\n return { action: \"tab_list\" };\n }\n\n const first = args[0];\n\n // tab list\n if (first === \"list\") {\n return { action: \"tab_list\" };\n }\n\n // tab new [url]\n if (first === \"new\") {\n return { action: \"tab_new\", url: args[1] };\n }\n\n // tab select --id <tabId>\n if (first === \"select\") {\n if (tabId !== undefined) {\n return { action: \"tab_select\", tabId };\n }\n throw new Error(\"tab select 需要 --id 参数,用法:bb-browser tab select --id <tabId>\");\n }\n\n // tab close [n | --id <tabId>]\n if (first === \"close\") {\n if (tabId !== undefined) {\n return { action: \"tab_close\", tabId };\n }\n const indexArg = args[1];\n if (indexArg !== undefined) {\n const index = parseInt(indexArg, 10);\n if (isNaN(index) || index < 0) {\n throw new Error(`无效的标签页索引: ${indexArg}`);\n }\n return { action: \"tab_close\", index };\n }\n return { action: \"tab_close\" };\n }\n\n // tab <n> - 切换到第 n 个标签页\n const index = parseInt(first, 10);\n if (!isNaN(index) && index >= 0) {\n return { action: \"tab_select\", index };\n }\n\n throw new Error(`未知的 tab 子命令: ${first}`);\n}\n\n/**\n * 格式化标签页列表输出\n */\nfunction formatTabList(tabs: TabInfo[], activeIndex: number): string {\n const lines: string[] = [];\n lines.push(`标签页列表(共 ${tabs.length} 个,当前 #${activeIndex}):`);\n\n for (const tab of tabs) {\n const prefix = tab.active ? \"*\" : \" \";\n const title = tab.title || \"(无标题)\";\n lines.push(`${prefix} [${tab.index}] ${tab.url} - ${title}`);\n }\n\n return lines.join(\"\\n\");\n}\n\nexport async function tabCommand(\n args: string[],\n options: TabOptions = {}\n): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析子命令\n const parsed = parseTabSubcommand(args, process.argv);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: parsed.action,\n url: parsed.url,\n index: parsed.index,\n tabId: parsed.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n switch (parsed.action) {\n case \"tab_list\": {\n const tabs = response.data?.tabs ?? [];\n const activeIndex = response.data?.activeIndex ?? 0;\n console.log(formatTabList(tabs, activeIndex));\n break;\n }\n case \"tab_new\": {\n const url = response.data?.url ?? \"about:blank\";\n console.log(`已创建新标签页: ${url}`);\n break;\n }\n case \"tab_select\": {\n const title = response.data?.title ?? \"(无标题)\";\n const url = response.data?.url ?? \"\";\n console.log(`已切换到标签页 #${parsed.index}: ${title}`);\n console.log(` URL: ${url}`);\n break;\n }\n case \"tab_close\": {\n const closedTitle = response.data?.title ?? \"(无标题)\";\n console.log(`已关闭标签页: ${closedTitle}`);\n break;\n }\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * frame 命令 - 切换到 iframe 或返回主 frame\n * 用法:\n * bb-browser frame <selector> 切换到指定 iframe\n * bb-browser frame main 返回主 frame\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface FrameOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 切换到指定 iframe\n * @param selector CSS 选择器,用于定位 iframe 元素\n */\nexport async function frameCommand(\n selector: string,\n options: FrameOptions = {}\n): Promise<void> {\n if (!selector) {\n throw new Error(\"缺少 selector 参数\");\n }\n\n await ensureDaemonRunning();\n\n const request: Request = {\n id: generateId(),\n action: \"frame\",\n selector,\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const frameInfo = response.data?.frameInfo;\n if (frameInfo?.url) {\n console.log(`已切换到 frame: ${selector} (${frameInfo.url})`);\n } else {\n console.log(`已切换到 frame: ${selector}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n\n/**\n * 返回主 frame\n */\nexport async function frameMainCommand(\n options: FrameOptions = {}\n): Promise<void> {\n await ensureDaemonRunning();\n\n const request: Request = {\n id: generateId(),\n action: \"frame_main\",\n tabId: options.tabId,\n };\n\n const response: Response = await sendCommand(request);\n\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(\"已返回主 frame\");\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * dialog 命令 - 处理浏览器对话框(alert/confirm/prompt)\n * 用法:\n * bb-browser dialog accept [text] 接受对话框,可传入 prompt 文本\n * bb-browser dialog dismiss 拒绝/关闭对话框\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface DialogOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport async function dialogCommand(\n subCommand: string,\n promptText?: string,\n options: DialogOptions = {}\n): Promise<void> {\n // 验证子命令\n if (!subCommand || ![\"accept\", \"dismiss\"].includes(subCommand)) {\n throw new Error(\"请使用 'dialog accept [text]' 或 'dialog dismiss'\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"dialog\",\n dialogResponse: subCommand as \"accept\" | \"dismiss\",\n promptText: subCommand === \"accept\" ? promptText : undefined,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const dialogInfo = response.data?.dialogInfo;\n if (dialogInfo) {\n const action = subCommand === \"accept\" ? \"已接受\" : \"已拒绝\";\n console.log(`${action}对话框(${dialogInfo.type}): \"${dialogInfo.message}\"`);\n } else {\n console.log(\"对话框已处理\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * network 命令 - 网络监控和拦截\n */\n\nimport { sendCommand } from \"../client.js\";\n\ninterface NetworkOptions {\n json?: boolean;\n abort?: boolean;\n body?: string;\n withBody?: boolean;\n tabId?: number;\n}\n\nexport async function networkCommand(\n subCommand: string,\n urlOrFilter?: string,\n options: NetworkOptions = {}\n): Promise<void> {\n const response = await sendCommand({\n id: crypto.randomUUID(),\n action: \"network\",\n networkCommand: subCommand as \"requests\" | \"route\" | \"unroute\" | \"clear\",\n url: subCommand === \"route\" || subCommand === \"unroute\" ? urlOrFilter : undefined,\n filter: subCommand === \"requests\" ? urlOrFilter : undefined,\n routeOptions: subCommand === \"route\" ? {\n abort: options.abort,\n body: options.body,\n } : undefined,\n withBody: subCommand === \"requests\" ? options.withBody : undefined,\n tabId: options.tabId,\n });\n\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n\n if (!response.success) {\n throw new Error(response.error || \"Network command failed\");\n }\n\n const data = response.data;\n\n switch (subCommand) {\n case \"requests\": {\n const requests = data?.networkRequests || [];\n if (requests.length === 0) {\n console.log(\"没有网络请求记录\");\n console.log(\"提示: 使用 network requests 会自动开始监控\");\n } else {\n console.log(`网络请求 (${requests.length} 条):\\n`);\n for (const req of requests) {\n const status = req.failed \n ? `FAILED (${req.failureReason})` \n : (req.status ? `${req.status} ${req.statusText || ''}` : 'pending');\n console.log(`${req.method} ${req.url}`);\n console.log(` 类型: ${req.type}, 状态: ${status}`);\n if (options.withBody) {\n const requestHeaderCount = req.requestHeaders ? Object.keys(req.requestHeaders).length : 0;\n const responseHeaderCount = req.responseHeaders ? Object.keys(req.responseHeaders).length : 0;\n console.log(` 请求头: ${requestHeaderCount}, 响应头: ${responseHeaderCount}`);\n if (req.requestBody !== undefined) {\n const preview = req.requestBody.length > 200 ? `${req.requestBody.slice(0, 200)}...` : req.requestBody;\n console.log(` 请求体: ${preview}`);\n }\n if (req.responseBody !== undefined) {\n const preview = req.responseBody.length > 200 ? `${req.responseBody.slice(0, 200)}...` : req.responseBody;\n console.log(` 响应体: ${preview}`);\n }\n if (req.bodyError) {\n console.log(` Body错误: ${req.bodyError}`);\n }\n }\n console.log(\"\");\n }\n }\n break;\n }\n\n case \"route\": {\n console.log(`已添加拦截规则: ${urlOrFilter}`);\n if (options.abort) {\n console.log(\" 行为: 阻止请求\");\n } else if (options.body) {\n console.log(\" 行为: 返回 mock 数据\");\n } else {\n console.log(\" 行为: 继续请求\");\n }\n console.log(`当前规则数: ${data?.routeCount || 0}`);\n break;\n }\n\n case \"unroute\": {\n if (urlOrFilter) {\n console.log(`已移除拦截规则: ${urlOrFilter}`);\n } else {\n console.log(\"已移除所有拦截规则\");\n }\n console.log(`剩余规则数: ${data?.routeCount || 0}`);\n break;\n }\n\n case \"clear\": {\n console.log(\"已清空网络请求记录\");\n break;\n }\n\n default:\n throw new Error(`未知的 network 子命令: ${subCommand}`);\n }\n}\n","/**\n * console 命令 - 查看控制台消息\n */\n\nimport { sendCommand } from \"../client.js\";\n\ninterface ConsoleOptions {\n json?: boolean;\n clear?: boolean;\n tabId?: number;\n}\n\nexport async function consoleCommand(options: ConsoleOptions = {}): Promise<void> {\n const response = await sendCommand({\n id: crypto.randomUUID(),\n action: \"console\",\n consoleCommand: options.clear ? \"clear\" : \"get\",\n tabId: options.tabId,\n });\n\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n\n if (!response.success) {\n throw new Error(response.error || \"Console command failed\");\n }\n\n if (options.clear) {\n console.log(\"已清空控制台消息\");\n return;\n }\n\n const messages = response.data?.consoleMessages || [];\n \n if (messages.length === 0) {\n console.log(\"没有控制台消息\");\n console.log(\"提示: console 命令会自动开始监控\");\n return;\n }\n\n console.log(`控制台消息 (${messages.length} 条):\\n`);\n\n const typeColors: Record<string, string> = {\n log: \"\",\n info: \"[INFO]\",\n warn: \"[WARN]\",\n error: \"[ERROR]\",\n debug: \"[DEBUG]\",\n };\n\n for (const msg of messages) {\n const prefix = typeColors[msg.type] || `[${msg.type.toUpperCase()}]`;\n const location = msg.url ? ` (${msg.url}${msg.lineNumber ? `:${msg.lineNumber}` : \"\"})` : \"\";\n \n if (prefix) {\n console.log(`${prefix} ${msg.text}${location}`);\n } else {\n console.log(`${msg.text}${location}`);\n }\n }\n}\n","/**\n * errors 命令 - 查看 JS 错误\n */\n\nimport { sendCommand } from \"../client.js\";\n\ninterface ErrorsOptions {\n json?: boolean;\n clear?: boolean;\n tabId?: number;\n}\n\nexport async function errorsCommand(options: ErrorsOptions = {}): Promise<void> {\n const response = await sendCommand({\n id: crypto.randomUUID(),\n action: \"errors\",\n errorsCommand: options.clear ? \"clear\" : \"get\",\n tabId: options.tabId,\n });\n\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n\n if (!response.success) {\n throw new Error(response.error || \"Errors command failed\");\n }\n\n if (options.clear) {\n console.log(\"已清空 JS 错误记录\");\n return;\n }\n\n const errors = response.data?.jsErrors || [];\n \n if (errors.length === 0) {\n console.log(\"没有 JS 错误\");\n console.log(\"提示: errors 命令会自动开始监控\");\n return;\n }\n\n console.log(`JS 错误 (${errors.length} 条):\\n`);\n\n for (const err of errors) {\n console.log(`[ERROR] ${err.message}`);\n if (err.url) {\n console.log(` 位置: ${err.url}:${err.lineNumber || 0}:${err.columnNumber || 0}`);\n }\n if (err.stackTrace) {\n console.log(` 堆栈:`);\n console.log(err.stackTrace.split('\\n').map(line => ` ${line}`).join('\\n'));\n }\n console.log(\"\");\n }\n}\n","/**\n * trace 命令 - 录制用户操作\n * \n * 用法:\n * bb-browser trace start 开始录制\n * bb-browser trace stop 停止录制,输出事件列表\n * bb-browser trace status 查看录制状态\n */\n\nimport { sendCommand } from \"../client.js\";\n\ninterface TraceOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport async function traceCommand(\n subCommand: 'start' | 'stop' | 'status',\n options: TraceOptions = {}\n): Promise<void> {\n const response = await sendCommand({\n id: crypto.randomUUID(),\n action: \"trace\",\n traceCommand: subCommand,\n tabId: options.tabId,\n });\n\n if (options.json) {\n console.log(JSON.stringify(response));\n return;\n }\n\n if (!response.success) {\n throw new Error(response.error || \"Trace command failed\");\n }\n\n const data = response.data;\n\n switch (subCommand) {\n case \"start\": {\n const status = data?.traceStatus;\n console.log(\"开始录制用户操作\");\n console.log(`标签页 ID: ${status?.tabId || 'N/A'}`);\n console.log(\"\\n在浏览器中进行操作,完成后运行 'bb-browser trace stop' 停止录制\");\n break;\n }\n\n case \"stop\": {\n const events = data?.traceEvents || [];\n const status = data?.traceStatus;\n \n console.log(`录制完成,共 ${events.length} 个事件\\n`);\n \n if (events.length === 0) {\n console.log(\"没有录制到任何操作\");\n break;\n }\n \n // 输出事件列表\n for (let i = 0; i < events.length; i++) {\n const event = events[i];\n const refStr = event.ref !== undefined ? `@${event.ref}` : '';\n \n switch (event.type) {\n case 'navigation':\n console.log(`${i + 1}. 导航到: ${event.url}`);\n break;\n case 'click':\n console.log(`${i + 1}. 点击 ${refStr} [${event.elementRole}] \"${event.elementName || ''}\"`);\n break;\n case 'fill':\n console.log(`${i + 1}. 填充 ${refStr} [${event.elementRole}] \"${event.elementName || ''}\" <- \"${event.value}\"`);\n break;\n case 'select':\n console.log(`${i + 1}. 选择 ${refStr} [${event.elementRole}] \"${event.elementName || ''}\" <- \"${event.value}\"`);\n break;\n case 'check':\n console.log(`${i + 1}. ${event.checked ? '勾选' : '取消勾选'} ${refStr} [${event.elementRole}] \"${event.elementName || ''}\"`);\n break;\n case 'press':\n console.log(`${i + 1}. 按键 ${event.key}`);\n break;\n case 'scroll':\n console.log(`${i + 1}. 滚动 ${event.direction} ${event.pixels}px`);\n break;\n default:\n console.log(`${i + 1}. ${event.type}`);\n }\n }\n \n console.log(`\\n状态: ${status?.recording ? '录制中' : '已停止'}`);\n break;\n }\n\n case \"status\": {\n const status = data?.traceStatus;\n if (status?.recording) {\n console.log(`录制中 (标签页 ${status.tabId})`);\n console.log(`已录制 ${status.eventCount} 个事件`);\n } else {\n console.log(\"未在录制\");\n }\n break;\n }\n\n default:\n throw new Error(`未知的 trace 子命令: ${subCommand}`);\n }\n}\n","/**\n * fetch 命令 - 在浏览器上下文中执行 fetch(),自动处理同源路由\n *\n * 用法:\n * bb-browser fetch <url> [options]\n * bb-browser fetch https://www.reddit.com/api/me.json\n * bb-browser fetch /api/me.json # 相对路径,用当前 tab 的 origin\n * bb-browser fetch https://www.reddit.com/... --json\n * bb-browser fetch https://x.com/... --method POST --body '{\"query\":\"...\"}'\n *\n * 本质:curl,但带浏览器登录态。\n */\n\nimport { generateId, type Request, type Response, type TabInfo } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface FetchOptions {\n json?: boolean;\n method?: string;\n body?: string;\n headers?: string;\n output?: string;\n tabId?: number;\n}\n\n/**\n * 精确匹配 tab 的 origin\n */\nfunction matchTabOrigin(tabUrl: string, targetHostname: string): boolean {\n try {\n const tabHostname = new URL(tabUrl).hostname;\n return tabHostname === targetHostname || tabHostname.endsWith(\".\" + targetHostname);\n } catch {\n return false;\n }\n}\n\n/**\n * 找到匹配域名的 tab,如果没有则新建\n */\nasync function ensureTabForOrigin(origin: string, hostname: string): Promise<number | undefined> {\n const listReq: Request = { id: generateId(), action: \"tab_list\" };\n const listResp: Response = await sendCommand(listReq);\n\n if (listResp.success && listResp.data?.tabs) {\n const matchingTab = listResp.data.tabs.find((tab: TabInfo) =>\n matchTabOrigin(tab.url, hostname)\n );\n\n if (matchingTab) {\n return matchingTab.tabId;\n }\n }\n\n const newResp: Response = await sendCommand({ id: generateId(), action: \"tab_new\", url: origin });\n if (!newResp.success) {\n throw new Error(`无法打开 ${origin}: ${newResp.error}`);\n }\n await new Promise((resolve) => setTimeout(resolve, 3000));\n return newResp.data?.tabId;\n}\n\n/**\n * 构造浏览器内执行的 fetch JS 代码\n * 修复 Codex review: headers 通过 JSON.stringify 传入,不做字符串拼接\n */\nfunction buildFetchScript(url: string, options: FetchOptions): string {\n const method = (options.method || \"GET\").toUpperCase();\n const hasBody = options.body && method !== \"GET\" && method !== \"HEAD\";\n\n // headers 通过 JSON.parse 安全传入,避免代码注入\n let headersExpr = \"{}\";\n if (options.headers) {\n try {\n // 验证是合法 JSON\n JSON.parse(options.headers);\n headersExpr = options.headers;\n } catch {\n throw new Error(`--headers must be valid JSON. Got: ${options.headers}`);\n }\n }\n\n return `(async () => {\n try {\n const resp = await fetch(${JSON.stringify(url)}, {\n method: ${JSON.stringify(method)},\n credentials: 'include',\n headers: ${headersExpr}${hasBody ? `,\\n body: ${JSON.stringify(options.body)}` : \"\"}\n });\n const contentType = resp.headers.get('content-type') || '';\n let body;\n if (contentType.includes('application/json') && resp.status !== 204) {\n try { body = await resp.json(); } catch { body = await resp.text(); }\n } else {\n body = await resp.text();\n }\n return JSON.stringify({\n status: resp.status,\n contentType,\n body\n });\n } catch (e) {\n return JSON.stringify({ error: e.message });\n }\n })()`;\n}\n\nexport async function fetchCommand(\n url: string,\n options: FetchOptions = {}\n): Promise<void> {\n if (!url) {\n throw new Error(\n \"缺少 URL 参数\\n\" +\n \" 用法: bb-browser fetch <url> [--json] [--method POST] [--body '{...}']\\n\" +\n \" 示例: bb-browser fetch https://www.reddit.com/api/me.json --json\"\n );\n }\n\n await ensureDaemonRunning();\n\n const isAbsolute = url.startsWith(\"http://\") || url.startsWith(\"https://\");\n let targetTabId = options.tabId;\n\n if (isAbsolute) {\n let origin: string;\n let hostname: string;\n try {\n const parsed = new URL(url);\n origin = parsed.origin;\n hostname = parsed.hostname;\n } catch {\n throw new Error(`无效的 URL: ${url}`);\n }\n\n if (!targetTabId) {\n targetTabId = await ensureTabForOrigin(origin, hostname);\n }\n }\n\n const script = buildFetchScript(url, options);\n const evalReq: Request = { id: generateId(), action: \"eval\", script, tabId: targetTabId };\n const evalResp: Response = await sendCommand(evalReq);\n\n if (!evalResp.success) {\n throw new Error(`Fetch 失败: ${evalResp.error}`);\n }\n\n const rawResult = evalResp.data?.result;\n if (rawResult === undefined || rawResult === null) {\n throw new Error(\"Fetch 未返回结果\");\n }\n\n let result: { status?: number; contentType?: string; body?: unknown; error?: string };\n try {\n result = typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult as typeof result;\n } catch {\n console.log(rawResult);\n return;\n }\n\n if (result.error) {\n throw new Error(`Fetch error: ${result.error}`);\n }\n\n // 写文件\n if (options.output) {\n const { writeFileSync } = await import(\"node:fs\");\n const content = typeof result.body === \"object\"\n ? JSON.stringify(result.body, null, 2)\n : String(result.body);\n writeFileSync(options.output, content, \"utf-8\");\n console.log(`已写入 ${options.output} (${result.status}, ${content.length} bytes)`);\n return;\n }\n\n // 输出\n if (typeof result.body === \"object\") {\n console.log(JSON.stringify(result.body, null, 2));\n } else {\n console.log(result.body);\n }\n}\n","/**\n * history 命令 - 查询 Chrome 浏览历史\n *\n * 用法:\n * bb-browser history search [query] 搜索历史记录\n * bb-browser history domains 查看访问最多的域名\n */\n\nimport { getHistoryDomains, searchHistory } from \"../history-sqlite.js\";\n\ninterface HistoryOptions {\n json?: boolean;\n days?: number;\n query?: string;\n}\n\nexport async function historyCommand(\n subCommand: 'search' | 'domains',\n options: HistoryOptions = {}\n): Promise<void> {\n const days = options.days || 30;\n const data = subCommand === \"search\"\n ? { historyItems: searchHistory(options.query, days) }\n : { historyDomains: getHistoryDomains(days) };\n\n if (options.json) {\n console.log(JSON.stringify({\n id: crypto.randomUUID(),\n success: true,\n data,\n }));\n return;\n }\n\n switch (subCommand) {\n case \"search\": {\n const items = data?.historyItems || [];\n\n console.log(`找到 ${items.length} 条历史记录\\n`);\n\n if (items.length === 0) {\n console.log(\"没有找到匹配的历史记录\");\n break;\n }\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n console.log(`${i + 1}. ${item.title || '(无标题)'}`);\n console.log(` ${item.url}`);\n console.log(` 访问次数: ${item.visitCount}`);\n }\n break;\n }\n\n case \"domains\": {\n const domains = data?.historyDomains || [];\n\n console.log(`找到 ${domains.length} 个域名\\n`);\n\n if (domains.length === 0) {\n console.log(\"没有找到历史记录\");\n break;\n }\n\n for (let i = 0; i < domains.length; i++) {\n const domain = domains[i];\n console.log(`${i + 1}. ${domain.domain}`);\n console.log(` 访问次数: ${domain.visits}`);\n }\n break;\n }\n\n default:\n throw new Error(`未知的 history 子命令: ${subCommand}`);\n }\n}\n"],"mappings":"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","names":["fileURLToPath","os","path","resolve","resolve","resolve","target","path","os","path","pageUrl","resolve","sendCommand","fileURLToPath","existsSync","existsSync","unlinkSync","execSync","readFileSync","existsSync","join","homedir","execSync","resolve","parsed","applyJq","sendCommand","spawn","sendCommand","sendCommand","parseRef","sendCommand","parseRef","sendCommand","parseRef","sendCommand","parseRef","sendCommand","sendCommand","parseRef","sendCommand","path","os","path","os","sendCommand","parseRef","sendCommand","sendCommand","sendCommand","sendCommand","parseRef","sendCommand","parseRef","sendCommand","sendCommand","index","sendCommand","sendCommand","sendCommand","sendCommand","sendCommand","sendCommand","sendCommand","matchTabOrigin","sendCommand","resolve","writeFileSync","fileURLToPath","spawn","execSync"]}
|