bb-browser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +240 -0
- package/dist/chunk-KATHFDYJ.js +20 -0
- package/dist/chunk-KATHFDYJ.js.map +1 -0
- package/dist/cli.js +1800 -0
- package/dist/cli.js.map +1 -0
- package/dist/daemon.js +441 -0
- package/dist/daemon.js.map +1 -0
- package/extension/background.js +2943 -0
- package/extension/background.js.map +1 -0
- package/extension/buildDomTree.js +1505 -0
- package/extension/content/trace.js +339 -0
- package/extension/content/trace.js.map +1 -0
- package/extension/dist/background.js +2943 -0
- package/extension/dist/background.js.map +1 -0
- package/extension/dist/buildDomTree.js +1505 -0
- package/extension/dist/content/trace.js +339 -0
- package/extension/dist/content/trace.js.map +1 -0
- package/extension/dist/manifest.json +25 -0
- package/extension/manifest.json +25 -0
- package/package.json +60 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +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/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 };\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(\"无法连接到 Daemon,请确保 Daemon 正在运行\");\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 路径 */\nfunction 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]\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\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 };\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}\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 };\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}\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 };\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}\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 };\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}\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 };\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}\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 };\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}\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 };\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}\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 };\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}\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 };\n } else {\n // 等待元素模式\n const ref = parseRef(target);\n request = {\n id: generateId(),\n action: \"wait\",\n waitType: \"element\",\n ref,\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}\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 };\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}\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 };\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 { isDaemonRunning, stopDaemon } from \"../daemon-manager.js\";\n\nexport interface DaemonOptions {\n json?: boolean;\n}\n\n/**\n * 前台启动 Daemon\n * 注意:实际的 Daemon 逻辑在 @bb-browser/daemon 包中\n * 此命令作为入口,启动 daemon 包的主函数\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 // 动态导入 daemon 包并启动\n try {\n const { startDaemon } = await import(\"@bb-browser/daemon\");\n \n if (options.json) {\n console.log(JSON.stringify({ success: true, message: \"Daemon 启动中...\" }));\n } else {\n console.log(\"Daemon 启动中...\");\n }\n \n await startDaemon();\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/**\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}\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 };\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 };\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 };\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}\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 };\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 };\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}\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 };\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}\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 };\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 个标签页\n * bb-browser tab close [n] 关闭标签页\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 命令参数数组\n * @returns 解析后的子命令和参数\n */\nfunction parseTabSubcommand(args: string[]): {\n action: \"tab_list\" | \"tab_new\" | \"tab_select\" | \"tab_close\";\n url?: string;\n index?: number;\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 close [n]\n if (first === \"close\") {\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);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: parsed.action,\n url: parsed.url,\n index: parsed.index,\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}\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 };\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 };\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}\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 };\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}\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 });\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 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}\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 });\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}\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 });\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}\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 });\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 * 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\";\n\nconst VERSION = \"0.1.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 个标签页\n tab close [n] 关闭标签页(默认当前)\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\n选项:\n --json 以 JSON 格式输出\n -i, --interactive 只输出可交互元素(snapshot 命令)\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 };\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 },\n };\n\n for (const arg of args) {\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.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 // 处理全局选项\n if (parsed.flags.version) {\n console.log(VERSION);\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({ json: parsed.flags.json, interactive: parsed.flags.interactive });\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 });\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 });\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 });\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 });\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 });\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 });\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 });\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 });\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 });\n break;\n }\n\n case \"daemon\":\n case \"start\": {\n await daemonCommand({ json: parsed.flags.json });\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 });\n break;\n }\n\n case \"back\": {\n await backCommand({ json: parsed.flags.json });\n break;\n }\n\n case \"forward\": {\n await forwardCommand({ json: parsed.flags.json });\n break;\n }\n\n case \"refresh\": {\n await refreshCommand({ json: parsed.flags.json });\n break;\n }\n\n case \"screenshot\": {\n const outputPath = parsed.args[0];\n await screenshotCommand(outputPath, { json: parsed.flags.json });\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 });\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 });\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 });\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 });\n } else {\n await frameCommand(selectorOrMain, { json: parsed.flags.json });\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 });\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 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 });\n break;\n }\n\n case \"console\": {\n const clear = process.argv.includes(\"--clear\");\n await consoleCommand({ json: parsed.flags.json, clear });\n break;\n }\n\n case \"errors\": {\n const clear = process.argv.includes(\"--clear\");\n await errorsCommand({ json: parsed.flags.json, clear });\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 });\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","resolve","parseRef","parseRef","index"]}
|