bb-browser 0.4.3 → 0.4.5
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/README.md +74 -108
- package/README.zh-CN.md +73 -107
- package/dist/cli.js +71 -77
- 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/client.ts","../packages/cli/src/daemon-manager.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/site.ts","../packages/cli/src/index.ts"],"sourcesContent":["/**\n * HTTP 客户端 - 与 Daemon 通信\n */\n\nimport type { Request, Response } from \"@bb-browser/shared\";\nimport { DAEMON_BASE_URL, COMMAND_TIMEOUT } from \"@bb-browser/shared\";\n\n/**\n * 发送命令到 Daemon 并等待响应\n */\nexport async function sendCommand(request: Request): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), COMMAND_TIMEOUT);\n\n try {\n const res = await fetch(`${DAEMON_BASE_URL}/command`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!res.ok) {\n // 根据 HTTP 状态码返回错误\n if (res.status === 408) {\n return {\n id: request.id,\n success: false,\n error: \"命令执行超时\",\n };\n }\n if (res.status === 503) {\n return {\n id: request.id,\n success: false,\n error: [\n \"Chrome extension not connected.\",\n \"\",\n \"1. Download extension: https://github.com/epiral/bb-browser/releases/latest\",\n \"2. Unzip the downloaded file\",\n \"3. Open chrome://extensions/ → Enable Developer Mode\",\n \"4. Click \\\"Load unpacked\\\" → select the unzipped folder\",\n ].join(\"\\n\"),\n };\n }\n return {\n id: request.id,\n success: false,\n error: `HTTP 错误: ${res.status} ${res.statusText}`,\n };\n }\n\n return (await res.json()) as Response;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n return {\n id: request.id,\n success: false,\n error: \"请求超时\",\n };\n }\n // 连接错误\n if (\n error.message.includes(\"fetch failed\") ||\n error.message.includes(\"ECONNREFUSED\")\n ) {\n throw new Error([\n \"Cannot connect to daemon.\",\n \"\",\n \"Start the daemon first:\",\n \" bb-browser daemon\",\n \"\",\n \"Then load the Chrome extension:\",\n \" chrome://extensions/ → Developer Mode → Load unpacked → node_modules/bb-browser/extension/\",\n ].join(\"\\n\"));\n }\n throw error;\n }\n throw error;\n }\n}\n","/**\n * Daemon 管理器 - 检测、启动和停止 Daemon\n */\n\nimport { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, resolve } from \"node:path\";\nimport { DAEMON_BASE_URL } from \"@bb-browser/shared\";\n\n/** 获取 daemon dist 路径 */\nexport function getDaemonPath(): string {\n const currentFile = fileURLToPath(import.meta.url);\n const currentDir = dirname(currentFile);\n \n // npm 发布后:cli.js 和 daemon.js 在同一目录 (dist/)\n const sameDirPath = resolve(currentDir, \"daemon.js\");\n if (existsSync(sameDirPath)) {\n return sameDirPath;\n }\n \n // 开发模式:CLI dist 在 packages/cli/dist/,Daemon dist 在 packages/daemon/dist/\n return resolve(currentDir, \"../../daemon/dist/index.js\");\n}\n\n/** Daemon 启动超时时间(毫秒) */\nconst DAEMON_START_TIMEOUT = 5000;\n\n/** 轮询间隔(毫秒) */\nconst POLL_INTERVAL = 200;\n\n/**\n * 检查 Daemon 是否正在运行\n */\nexport async function isDaemonRunning(): Promise<boolean> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(`${DAEMON_BASE_URL}/status`, {\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n return response.ok;\n } catch {\n return false;\n }\n}\n\n/**\n * 等待 Daemon 就绪\n */\nasync function waitForDaemon(timeoutMs: number): Promise<boolean> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n if (await isDaemonRunning()) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));\n }\n\n return false;\n}\n\n/**\n * 启动 Daemon 后台进程\n */\nfunction spawnDaemon(): void {\n const daemonPath = getDaemonPath();\n \n const daemonProcess = spawn(process.execPath, [daemonPath], {\n detached: true,\n stdio: \"ignore\",\n env: { ...process.env },\n });\n\n // 让进程在后台运行\n daemonProcess.unref();\n}\n\n/**\n * 确保 Daemon 正在运行\n * 如果未运行,自动启动并等待就绪\n */\nexport async function ensureDaemonRunning(): Promise<void> {\n if (await isDaemonRunning()) {\n return;\n }\n\n // 启动 Daemon\n spawnDaemon();\n\n // 等待 Daemon 就绪\n const ready = await waitForDaemon(DAEMON_START_TIMEOUT);\n\n if (!ready) {\n throw new Error(\n \"无法启动 Daemon。请手动运行 bb-browser daemon 或 bb-daemon 启动服务\"\n );\n }\n}\n\n/**\n * 停止 Daemon\n */\nexport async function stopDaemon(): Promise<boolean> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5000);\n\n const response = await fetch(`${DAEMON_BASE_URL}/shutdown`, {\n method: \"POST\",\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n return response.ok;\n } catch {\n return false;\n }\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\";\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 } 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 * daemon 命令 - Daemon 管理\n * 用法:\n * bb-browser daemon 前台启动 Daemon\n * bb-browser start 前台启动 Daemon(别名)\n * bb-browser stop 停止 Daemon\n */\n\nimport { spawn } from \"node:child_process\";\nimport { isDaemonRunning, stopDaemon, getDaemonPath } from \"../daemon-manager.js\";\n\nexport interface DaemonOptions {\n json?: boolean;\n host?: string;\n}\n\n/**\n * 前台启动 Daemon\n * 通过 spawn 启动 daemon.js,stdio 继承到当前终端\n */\nexport async function daemonCommand(\n options: DaemonOptions = {}\n): Promise<void> {\n // 检查是否已经运行\n if (await isDaemonRunning()) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: \"Daemon 已在运行\" }));\n } else {\n console.log(\"Daemon 已在运行\");\n }\n return;\n }\n\n const daemonPath = getDaemonPath();\n const args = [daemonPath];\n if (options.host) {\n args.push(\"--host\", options.host);\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true, message: \"Daemon 启动中...\" }));\n } else {\n console.log(\"Daemon 启动中...\");\n }\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(process.execPath, args, {\n stdio: \"inherit\",\n });\n child.on(\"exit\", (code) => {\n if (code && code !== 0) {\n reject(new Error(`Daemon exited with code ${code}`));\n } else {\n resolve();\n }\n });\n child.on(\"error\", reject);\n });\n}\n\n/**\n * 停止 Daemon\n */\nexport async function stopCommand(options: DaemonOptions = {}): Promise<void> {\n // 检查是否运行中\n if (!(await isDaemonRunning())) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: \"Daemon 未运行\" }));\n } else {\n console.log(\"Daemon 未运行\");\n }\n return;\n }\n\n // 发送停止信号\n const stopped = await stopDaemon();\n\n if (stopped) {\n if (options.json) {\n console.log(JSON.stringify({ success: true, message: \"Daemon 已停止\" }));\n } else {\n console.log(\"Daemon 已停止\");\n }\n } else {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: \"无法停止 Daemon\" }));\n } else {\n console.error(\"无法停止 Daemon\");\n }\n process.exit(1);\n }\n}\n\n/**\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 ? \"Daemon 运行中\" : \"Daemon 未运行\");\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 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 * 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 { sendCommand } from \"../client.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\nexport interface SiteOptions {\n json?: boolean;\n tabId?: number;\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\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 * 获取所有 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 } 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 } 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}\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 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.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 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\nAdapter 结果不符合预期?报告问题:\n gh issue create --repo epiral/bb-sites --title \"[adapter-name] 描述\"\n 或: https://github.com/epiral/bb-sites/issues\n贡献新 adapter: 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 \"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, search, run, update\");\n console.error(\" Try: bb-browser site --help\");\n process.exit(1);\n }\n break;\n }\n}\n","/**\n * bb-browser CLI 入口\n *\n * 用法:\n * bb-browser open <url> 打开指定 URL\n * bb-browser snapshot 获取当前页面快照\n * bb-browser daemon 前台启动 Daemon\n * bb-browser start 前台启动 Daemon(别名)\n * bb-browser stop 停止 Daemon\n * bb-browser status 查看 Daemon 状态\n * bb-browser --help 显示帮助信息\n * bb-browser --version 显示版本号\n *\n * 全局选项:\n * --json 以 JSON 格式输出\n */\n\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 { daemonCommand, stopCommand, 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\";\n\nconst VERSION = \"0.3.0\";\n\nconst HELP_TEXT = `\nbb-browser - AI Agent 浏览器自动化工具\n\n用法:\n bb-browser <command> [options]\n\n命令:\n open <url> [--tab] 打开指定 URL(默认新 tab,--tab current 当前 tab)\n snapshot 获取当前页面快照(默认完整树)\n click <ref> 点击元素(ref 如 @5 或 5)\n hover <ref> 悬停在元素上\n fill <ref> <text> 填充输入框(清空后填入)\n type <ref> <text> 逐字符输入(不清空)\n check <ref> 勾选复选框\n uncheck <ref> 取消勾选复选框\n select <ref> <val> 下拉框选择\n eval \"<js>\" 执行 JavaScript\n close 关闭当前标签页\n get text <ref> 获取元素文本\n get url 获取当前页面 URL\n get title 获取页面标题\n screenshot [path] 截取当前页面\n wait <ms|@ref> 等待时间或元素\n press <key> 发送键盘按键(如 Enter, Tab, Control+a)\n scroll <dir> [px] 滚动页面(up/down/left/right,默认 300px)\n daemon 前台启动 Daemon\n start 前台启动 Daemon(daemon 的别名)\n stop 停止 Daemon\n status 查看 Daemon 状态\n reload 重载扩展(需要 CDP 模式)\n back 后退\n forward 前进\n refresh 刷新页面\n tab 列出所有标签页\n tab new [url] 新建标签页\n tab <n> 切换到第 n 个标签页(按 index)\n tab select --id <id> 切换到指定 tabId 的标签页\n tab close [n] 关闭标签页(按 index,默认当前)\n tab close --id <id> 关闭指定 tabId 的标签页\n frame <selector> 切换到指定 iframe\n frame main 返回主 frame\n dialog accept [text] 接受对话框(alert/confirm/prompt)\n dialog dismiss 拒绝/关闭对话框\n network requests [filter] 查看网络请求\n network route <url> [--abort|--body <json>] 拦截请求\n network unroute [url] 移除拦截规则\n network clear 清空请求记录\n console 查看控制台消息\n console --clear 清空控制台\n errors 查看 JS 错误\n errors --clear 清空错误记录\n trace start 开始录制用户操作\n trace stop 停止录制,输出事件列表\n trace status 查看录制状态\n fetch <url> 在浏览器上下文中 fetch(自动同源路由,带登录态)\n site 网站 CLI 化 — 管理和运行 site adapter\n site list 列出所有可用 adapter\n site search <q> 搜索 adapter\n site <name> 运行 adapter(如 site reddit/thread <url>)\n site update 更新社区 adapter 库\n\n选项:\n --json 以 JSON 格式输出\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\n示例:\n bb-browser open https://example.com\n bb-browser snapshot --json\n bb-browser click @5\n bb-browser fill @3 \"hello world\"\n bb-browser type @3 \"append text\"\n bb-browser get text @5\n bb-browser get url\n bb-browser press Enter\n bb-browser press Control+a\n bb-browser daemon\n bb-browser stop\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 };\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 === \"--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 === \"--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\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 = new URL(\"./mcp.js\", import.meta.url).pathname;\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 \"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, { json: parsed.flags.json, tabId: globalTabId });\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();\n"],"mappings":"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","names":["resolve","parseRef","parseRef","parseRef","parseRef","parseRef","spawn","resolve","spawn","resolve","parseRef","parseRef","index","resolve","existsSync","matchTabOrigin","resolve","spawn"]}
|
|
1
|
+
{"version":3,"sources":["../packages/cli/src/client.ts","../packages/cli/src/daemon-manager.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/site.ts","../packages/cli/src/index.ts"],"sourcesContent":["/**\n * HTTP 客户端 - 与 Daemon 通信\n */\n\nimport type { Request, Response } from \"@bb-browser/shared\";\nimport { DAEMON_BASE_URL, COMMAND_TIMEOUT } from \"@bb-browser/shared\";\n\n/**\n * 发送命令到 Daemon 并等待响应\n */\nexport async function sendCommand(request: Request): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), COMMAND_TIMEOUT);\n\n try {\n const res = await fetch(`${DAEMON_BASE_URL}/command`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(request),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!res.ok) {\n // 根据 HTTP 状态码返回错误\n if (res.status === 408) {\n return {\n id: request.id,\n success: false,\n error: \"命令执行超时\",\n };\n }\n if (res.status === 503) {\n return {\n id: request.id,\n success: false,\n error: [\n \"Chrome extension not connected.\",\n \"\",\n \"1. Download extension: https://github.com/epiral/bb-browser/releases/latest\",\n \"2. Unzip the downloaded file\",\n \"3. Open chrome://extensions/ → Enable Developer Mode\",\n \"4. Click \\\"Load unpacked\\\" → select the unzipped folder\",\n ].join(\"\\n\"),\n };\n }\n return {\n id: request.id,\n success: false,\n error: `HTTP 错误: ${res.status} ${res.statusText}`,\n };\n }\n\n return (await res.json()) as Response;\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof Error) {\n if (error.name === \"AbortError\") {\n return {\n id: request.id,\n success: false,\n error: \"请求超时\",\n };\n }\n // 连接错误\n if (\n error.message.includes(\"fetch failed\") ||\n error.message.includes(\"ECONNREFUSED\")\n ) {\n throw new Error([\n \"Cannot connect to daemon.\",\n \"\",\n \"Start the daemon first:\",\n \" bb-browser daemon\",\n \"\",\n \"Then load the Chrome extension:\",\n \" chrome://extensions/ → Developer Mode → Load unpacked → node_modules/bb-browser/extension/\",\n ].join(\"\\n\"));\n }\n throw error;\n }\n throw error;\n }\n}\n","/**\n * Daemon 管理器 - 检测、启动和停止 Daemon\n */\n\nimport { spawn } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { dirname, resolve } from \"node:path\";\nimport { DAEMON_BASE_URL } from \"@bb-browser/shared\";\n\n/** 获取 daemon dist 路径 */\nexport function getDaemonPath(): string {\n const currentFile = fileURLToPath(import.meta.url);\n const currentDir = dirname(currentFile);\n \n // npm 发布后:cli.js 和 daemon.js 在同一目录 (dist/)\n const sameDirPath = resolve(currentDir, \"daemon.js\");\n if (existsSync(sameDirPath)) {\n return sameDirPath;\n }\n \n // 开发模式:CLI dist 在 packages/cli/dist/,Daemon dist 在 packages/daemon/dist/\n return resolve(currentDir, \"../../daemon/dist/index.js\");\n}\n\n/** Daemon 启动超时时间(毫秒) */\nconst DAEMON_START_TIMEOUT = 5000;\n\n/** 轮询间隔(毫秒) */\nconst POLL_INTERVAL = 200;\n\n/**\n * 检查 Daemon 是否正在运行\n */\nexport async function isDaemonRunning(): Promise<boolean> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(`${DAEMON_BASE_URL}/status`, {\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n return response.ok;\n } catch {\n return false;\n }\n}\n\n/**\n * 等待 Daemon 就绪\n */\nasync function waitForDaemon(timeoutMs: number): Promise<boolean> {\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeoutMs) {\n if (await isDaemonRunning()) {\n return true;\n }\n await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));\n }\n\n return false;\n}\n\n/**\n * 启动 Daemon 后台进程\n */\nfunction spawnDaemon(): void {\n const daemonPath = getDaemonPath();\n \n const daemonProcess = spawn(process.execPath, [daemonPath], {\n detached: true,\n stdio: \"ignore\",\n env: { ...process.env },\n });\n\n // 让进程在后台运行\n daemonProcess.unref();\n}\n\n/**\n * 确保 Daemon 正在运行\n * 如果未运行,自动启动并等待就绪\n */\nexport async function ensureDaemonRunning(): Promise<void> {\n if (await isDaemonRunning()) {\n return;\n }\n\n // 启动 Daemon\n spawnDaemon();\n\n // 等待 Daemon 就绪\n const ready = await waitForDaemon(DAEMON_START_TIMEOUT);\n\n if (!ready) {\n throw new Error(\n \"无法启动 Daemon。请手动运行 bb-browser daemon 或 bb-daemon 启动服务\"\n );\n }\n}\n\n/**\n * 停止 Daemon\n */\nexport async function stopDaemon(): Promise<boolean> {\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5000);\n\n const response = await fetch(`${DAEMON_BASE_URL}/shutdown`, {\n method: \"POST\",\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n return response.ok;\n } catch {\n return false;\n }\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\";\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 } 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 * daemon 命令 - Daemon 管理\n * 用法:\n * bb-browser daemon 前台启动 Daemon\n * bb-browser start 前台启动 Daemon(别名)\n * bb-browser stop 停止 Daemon\n */\n\nimport { spawn } from \"node:child_process\";\nimport { isDaemonRunning, stopDaemon, getDaemonPath } from \"../daemon-manager.js\";\n\nexport interface DaemonOptions {\n json?: boolean;\n host?: string;\n}\n\n/**\n * 前台启动 Daemon\n * 通过 spawn 启动 daemon.js,stdio 继承到当前终端\n */\nexport async function daemonCommand(\n options: DaemonOptions = {}\n): Promise<void> {\n // 检查是否已经运行\n if (await isDaemonRunning()) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: \"Daemon 已在运行\" }));\n } else {\n console.log(\"Daemon 已在运行\");\n }\n return;\n }\n\n const daemonPath = getDaemonPath();\n const args = [daemonPath];\n if (options.host) {\n args.push(\"--host\", options.host);\n }\n\n if (options.json) {\n console.log(JSON.stringify({ success: true, message: \"Daemon 启动中...\" }));\n } else {\n console.log(\"Daemon 启动中...\");\n }\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(process.execPath, args, {\n stdio: \"inherit\",\n });\n child.on(\"exit\", (code) => {\n if (code && code !== 0) {\n reject(new Error(`Daemon exited with code ${code}`));\n } else {\n resolve();\n }\n });\n child.on(\"error\", reject);\n });\n}\n\n/**\n * 停止 Daemon\n */\nexport async function stopCommand(options: DaemonOptions = {}): Promise<void> {\n // 检查是否运行中\n if (!(await isDaemonRunning())) {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: \"Daemon 未运行\" }));\n } else {\n console.log(\"Daemon 未运行\");\n }\n return;\n }\n\n // 发送停止信号\n const stopped = await stopDaemon();\n\n if (stopped) {\n if (options.json) {\n console.log(JSON.stringify({ success: true, message: \"Daemon 已停止\" }));\n } else {\n console.log(\"Daemon 已停止\");\n }\n } else {\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: \"无法停止 Daemon\" }));\n } else {\n console.error(\"无法停止 Daemon\");\n }\n process.exit(1);\n }\n}\n\n/**\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 ? \"Daemon 运行中\" : \"Daemon 未运行\");\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 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 * 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 { sendCommand } from \"../client.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\nexport interface SiteOptions {\n json?: boolean;\n tabId?: number;\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\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 * 获取所有 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 } 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 } 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}\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 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.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 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 \"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, search, run, update\");\n console.error(\" Try: bb-browser site --help\");\n process.exit(1);\n }\n break;\n }\n}\n","/**\n * bb-browser CLI 入口\n *\n * 用法:\n * bb-browser open <url> 打开指定 URL\n * bb-browser snapshot 获取当前页面快照\n * bb-browser daemon 前台启动 Daemon\n * bb-browser start 前台启动 Daemon(别名)\n * bb-browser stop 停止 Daemon\n * bb-browser status 查看 Daemon 状态\n * bb-browser --help 显示帮助信息\n * bb-browser --version 显示版本号\n *\n * 全局选项:\n * --json 以 JSON 格式输出\n */\n\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 { daemonCommand, stopCommand, 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\";\n\nconst VERSION = \"0.3.0\";\n\nconst HELP_TEXT = `\nbb-browser - AI Agent 浏览器自动化工具\n\n用法:\n bb-browser <command> [options]\n\n网站 CLI 化(把任何网站变成命令行 API):\n site list 列出所有可用 adapter(50+)\n site search <q> 搜索 adapter\n site <name> [args] 运行 adapter(如 site reddit/thread <url>)\n site update 更新社区 adapter 库\n guide 如何创建新 adapter(开发指南)\n\n 示例:\n bb-browser site twitter/search \"claude code\"\n bb-browser site reddit/thread <url>\n bb-browser site github/pr-create owner/repo --title \"feat: ...\"\n\n页面导航:\n open <url> [--tab] 打开指定 URL(默认新 tab,--tab current 当前 tab)\n back / forward 后退 / 前进\n refresh 刷新页面\n close 关闭当前标签页\n tab 列出所有标签页\n tab new [url] 新建标签页\n tab <n> 切换到第 n 个标签页(按 index)\n tab select --id <id> 切换到指定 tabId 的标签页\n tab close [n|--id <id>] 关闭标签页\n frame <selector> 切换到指定 iframe\n frame main 返回主 frame\n wait <ms|@ref> 等待时间或元素\n\n页面交互:\n click <ref> 点击元素(ref 如 @5 或 5)\n hover <ref> 悬停在元素上\n fill <ref> <text> 填充输入框(清空后填入)\n type <ref> <text> 逐字符输入(不清空)\n check <ref> 勾选复选框\n uncheck <ref> 取消勾选复选框\n select <ref> <val> 下拉框选择\n press <key> 发送键盘按键(如 Enter, Tab, Control+a)\n scroll <dir> [px] 滚动页面(up/down/left/right,默认 300px)\n dialog accept [text] 接受对话框\n dialog dismiss 拒绝/关闭对话框\n\n页面信息:\n snapshot 获取当前页面快照(默认完整树)\n get text <ref> 获取元素文本\n get url 获取当前页面 URL\n get title 获取页面标题\n screenshot [path] 截取当前页面\n eval \"<js>\" 执行 JavaScript\n fetch <url> 在浏览器上下文中 fetch(自动同源路由,带登录态)\n\n网络与调试:\n network requests [filter] 查看网络请求\n network route <url> [--abort|--body <json>] 拦截请求\n network unroute [url] 移除拦截规则\n network clear 清空请求记录\n console [--clear] 查看/清空控制台消息\n errors [--clear] 查看/清空 JS 错误\n trace start|stop|status 录制用户操作\n\nDaemon 管理:\n daemon / start 前台启动 Daemon\n stop 停止 Daemon\n status 查看 Daemon 状态\n reload 重载扩展(需要 CDP 模式)\n\n选项:\n --json 以 JSON 格式输出\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 };\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 === \"--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 === \"--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\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 = new URL(\"./mcp.js\", import.meta.url).pathname;\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 \"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, { json: parsed.flags.json, tabId: globalTabId });\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();\n"],"mappings":"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","names":["resolve","parseRef","parseRef","parseRef","parseRef","parseRef","spawn","resolve","spawn","resolve","parseRef","parseRef","index","resolve","existsSync","matchTabOrigin","resolve","spawn"]}
|