bb-browser 0.6.0 → 0.7.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/README.md +18 -5
- package/README.zh-CN.md +18 -5
- package/dist/cli.js +40 -2
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,11 +52,6 @@ bb-browser flips this: **instead of forcing websites to provide machine interfac
|
|
|
52
52
|
npm install -g bb-browser
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
### Chrome Extension
|
|
56
|
-
|
|
57
|
-
1. Download from [Releases](https://github.com/epiral/bb-browser/releases/latest)
|
|
58
|
-
2. Unzip → `chrome://extensions/` → Developer Mode → Load unpacked
|
|
59
|
-
|
|
60
55
|
### Use
|
|
61
56
|
|
|
62
57
|
```bash
|
|
@@ -65,6 +60,24 @@ bb-browser site recommend # see which adapters match your browsing habits
|
|
|
65
60
|
bb-browser site zhihu/hot # go
|
|
66
61
|
```
|
|
67
62
|
|
|
63
|
+
### OpenClaw (no extension needed)
|
|
64
|
+
|
|
65
|
+
If you use [OpenClaw](https://openclaw.ai), bb-browser runs directly through OpenClaw's built-in browser — no Chrome extension or daemon required:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
bb-browser site reddit/hot --openclaw
|
|
69
|
+
bb-browser site xueqiu/hot-stock 5 --openclaw --jq '.items[] | {name, changePercent}'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Skill on ClawHub: [bb-browser-openclaw](https://clawhub.ai/yan5xu/bb-browser)
|
|
73
|
+
|
|
74
|
+
### Chrome Extension (standalone mode)
|
|
75
|
+
|
|
76
|
+
For use without OpenClaw (Claude Code MCP, standalone CLI):
|
|
77
|
+
|
|
78
|
+
1. Download from [Releases](https://github.com/epiral/bb-browser/releases/latest)
|
|
79
|
+
2. Unzip → `chrome://extensions/` → Developer Mode → Load unpacked
|
|
80
|
+
|
|
68
81
|
### MCP (Claude Code / Cursor)
|
|
69
82
|
|
|
70
83
|
```json
|
package/README.zh-CN.md
CHANGED
|
@@ -52,11 +52,6 @@ bb-browser 翻转了这个逻辑:**不是让网站适配机器,而是让机
|
|
|
52
52
|
npm install -g bb-browser
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
### Chrome 扩展
|
|
56
|
-
|
|
57
|
-
1. 从 [Releases](https://github.com/epiral/bb-browser/releases/latest) 下载 zip
|
|
58
|
-
2. 解压 → `chrome://extensions/` → 开发者模式 → 加载已解压的扩展程序
|
|
59
|
-
|
|
60
55
|
### 使用
|
|
61
56
|
|
|
62
57
|
```bash
|
|
@@ -65,6 +60,24 @@ bb-browser site recommend # 看看哪些和你的浏览习惯匹配
|
|
|
65
60
|
bb-browser site zhihu/hot # 开搞
|
|
66
61
|
```
|
|
67
62
|
|
|
63
|
+
### OpenClaw(无需安装扩展)
|
|
64
|
+
|
|
65
|
+
如果你使用 [OpenClaw](https://openclaw.ai),bb-browser 可以直接通过 OpenClaw 内置浏览器运行,不需要额外安装 Chrome 扩展或 daemon:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
bb-browser site reddit/hot --openclaw
|
|
69
|
+
bb-browser site xueqiu/hot-stock 5 --openclaw --jq '.items[] | {name, changePercent}'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
ClawHub Skill: [bb-browser-openclaw](https://clawhub.ai/yan5xu/bb-browser)
|
|
73
|
+
|
|
74
|
+
### Chrome 扩展(独立模式)
|
|
75
|
+
|
|
76
|
+
不使用 OpenClaw 时(Claude Code MCP、独立 CLI)需要安装扩展:
|
|
77
|
+
|
|
78
|
+
1. 从 [Releases](https://github.com/epiral/bb-browser/releases/latest) 下载 zip
|
|
79
|
+
2. 解压 → `chrome://extensions/` → 开发者模式 → 加载已解压的扩展程序
|
|
80
|
+
|
|
68
81
|
### MCP 接入(Claude Code / Cursor)
|
|
69
82
|
|
|
70
83
|
```json
|
package/dist/cli.js
CHANGED
|
@@ -9,6 +9,9 @@ import {
|
|
|
9
9
|
} from "./chunk-AHGAQEFO.js";
|
|
10
10
|
import "./chunk-D4HDZEJT.js";
|
|
11
11
|
|
|
12
|
+
// packages/cli/src/index.ts
|
|
13
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
14
|
+
|
|
12
15
|
// packages/cli/src/client.ts
|
|
13
16
|
var jqExpression;
|
|
14
17
|
function setJqExpression(expression) {
|
|
@@ -201,6 +204,17 @@ var BB_DIR = join(homedir(), ".bb-browser");
|
|
|
201
204
|
var LOCAL_SITES_DIR = join(BB_DIR, "sites");
|
|
202
205
|
var COMMUNITY_SITES_DIR = join(BB_DIR, "bb-sites");
|
|
203
206
|
var COMMUNITY_REPO = "https://github.com/epiral/bb-sites.git";
|
|
207
|
+
function checkCliUpdate() {
|
|
208
|
+
try {
|
|
209
|
+
const current = execSync("bb-browser --version", { timeout: 3e3, stdio: ["pipe", "pipe", "pipe"] }).toString().trim();
|
|
210
|
+
const latest = execSync("npm view bb-browser version", { timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] }).toString().trim();
|
|
211
|
+
if (latest && current && latest !== current && latest.localeCompare(current, void 0, { numeric: true }) > 0) {
|
|
212
|
+
console.log(`
|
|
213
|
+
\u{1F4E6} bb-browser ${latest} available (current: ${current}). Run: npm install -g bb-browser`);
|
|
214
|
+
}
|
|
215
|
+
} catch {
|
|
216
|
+
}
|
|
217
|
+
}
|
|
204
218
|
function parseSiteMeta(filePath, source) {
|
|
205
219
|
let content;
|
|
206
220
|
try {
|
|
@@ -405,6 +419,8 @@ function siteUpdate() {
|
|
|
405
419
|
}
|
|
406
420
|
const sites = scanSites(COMMUNITY_SITES_DIR, "community");
|
|
407
421
|
console.log(`\u5DF2\u5B89\u88C5 ${sites.length} \u4E2A\u793E\u533A adapter\u3002`);
|
|
422
|
+
console.log(`\u2B50 Like bb-browser? \u2192 bb-browser star`);
|
|
423
|
+
checkCliUpdate();
|
|
408
424
|
}
|
|
409
425
|
function findSiteByName(name) {
|
|
410
426
|
return getAllSites().find((site) => site.name === name);
|
|
@@ -2299,7 +2315,7 @@ async function historyCommand(subCommand, options = {}) {
|
|
|
2299
2315
|
}
|
|
2300
2316
|
|
|
2301
2317
|
// packages/cli/src/index.ts
|
|
2302
|
-
var VERSION = "0.
|
|
2318
|
+
var VERSION = "0.7.0";
|
|
2303
2319
|
var HELP_TEXT = `
|
|
2304
2320
|
bb-browser - AI Agent \u6D4F\u89C8\u5668\u81EA\u52A8\u5316\u5DE5\u5177
|
|
2305
2321
|
|
|
@@ -2318,6 +2334,7 @@ bb-browser - AI Agent \u6D4F\u89C8\u5668\u81EA\u52A8\u5316\u5DE5\u5177
|
|
|
2318
2334
|
site <name> [args] \u8FD0\u884C adapter
|
|
2319
2335
|
site update \u66F4\u65B0\u793E\u533A adapter \u5E93
|
|
2320
2336
|
guide \u5982\u4F55\u628A\u4EFB\u4F55\u7F51\u7AD9\u53D8\u6210 adapter
|
|
2337
|
+
star \u2B50 Star bb-browser on GitHub
|
|
2321
2338
|
|
|
2322
2339
|
\u6D4F\u89C8\u5668\u64CD\u4F5C\uFF1A
|
|
2323
2340
|
open <url> [--tab] \u6253\u5F00 URL
|
|
@@ -2441,7 +2458,7 @@ async function main() {
|
|
|
2441
2458
|
return;
|
|
2442
2459
|
}
|
|
2443
2460
|
if (process.argv.includes("--mcp")) {
|
|
2444
|
-
const mcpPath = new URL("./mcp.js", import.meta.url)
|
|
2461
|
+
const mcpPath = fileURLToPath2(new URL("./mcp.js", import.meta.url));
|
|
2445
2462
|
const { spawn: spawn3 } = await import("child_process");
|
|
2446
2463
|
const child = spawn3(process.execPath, [mcpPath], { stdio: "inherit" });
|
|
2447
2464
|
child.on("exit", (code) => process.exit(code ?? 0));
|
|
@@ -2800,6 +2817,27 @@ async function main() {
|
|
|
2800
2817
|
});
|
|
2801
2818
|
break;
|
|
2802
2819
|
}
|
|
2820
|
+
case "star": {
|
|
2821
|
+
const { execSync: execSync2 } = await import("child_process");
|
|
2822
|
+
try {
|
|
2823
|
+
execSync2("gh auth status", { stdio: "pipe" });
|
|
2824
|
+
} catch {
|
|
2825
|
+
console.error("\u9700\u8981\u5148\u5B89\u88C5\u5E76\u767B\u5F55 GitHub CLI: https://cli.github.com");
|
|
2826
|
+
console.error(" brew install gh && gh auth login");
|
|
2827
|
+
process.exit(1);
|
|
2828
|
+
}
|
|
2829
|
+
const repos = ["epiral/bb-browser", "epiral/bb-sites"];
|
|
2830
|
+
for (const repo of repos) {
|
|
2831
|
+
try {
|
|
2832
|
+
execSync2(`gh api user/starred/${repo} -X PUT`, { stdio: "pipe" });
|
|
2833
|
+
console.log(`\u2B50 Starred ${repo}`);
|
|
2834
|
+
} catch {
|
|
2835
|
+
console.log(`Already starred or failed: ${repo}`);
|
|
2836
|
+
}
|
|
2837
|
+
}
|
|
2838
|
+
console.log("\nThanks for your support! \u{1F64F}");
|
|
2839
|
+
break;
|
|
2840
|
+
}
|
|
2803
2841
|
case "guide": {
|
|
2804
2842
|
console.log(`How to turn any website into a bb-browser site adapter
|
|
2805
2843
|
=======================================================
|
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/site.ts","../packages/cli/src/commands/open.ts","../packages/cli/src/commands/snapshot.ts","../packages/cli/src/commands/click.ts","../packages/cli/src/commands/hover.ts","../packages/cli/src/commands/fill.ts","../packages/cli/src/commands/type.ts","../packages/cli/src/commands/close.ts","../packages/cli/src/commands/get.ts","../packages/cli/src/commands/screenshot.ts","../packages/cli/src/commands/wait.ts","../packages/cli/src/commands/press.ts","../packages/cli/src/commands/scroll.ts","../packages/cli/src/commands/daemon.ts","../packages/cli/src/commands/reload.ts","../packages/cli/src/commands/nav.ts","../packages/cli/src/commands/check.ts","../packages/cli/src/commands/select.ts","../packages/cli/src/commands/eval.ts","../packages/cli/src/commands/tab.ts","../packages/cli/src/commands/frame.ts","../packages/cli/src/commands/dialog.ts","../packages/cli/src/commands/network.ts","../packages/cli/src/commands/console.ts","../packages/cli/src/commands/errors.ts","../packages/cli/src/commands/trace.ts","../packages/cli/src/commands/fetch.ts","../packages/cli/src/commands/history.ts","../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\";\nimport { applyJq } from \"./jq.js\";\n\nlet jqExpression: string | undefined;\n\nexport function setJqExpression(expression?: string): void {\n jqExpression = expression;\n}\n\nfunction printJqResults(response: Response): never {\n const target = response.data ?? response;\n const results = applyJq(target, jqExpression || \".\");\n for (const result of results) {\n console.log(typeof result === \"string\" ? result : JSON.stringify(result));\n }\n process.exit(0);\n}\n\nexport function handleJqResponse(response: Response): void {\n if (jqExpression) {\n printJqResults(response);\n }\n}\n\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 const response = (await res.json()) as Response;\n\n return 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 * 检查 Chrome 扩展是否已连接\n */\nasync function isExtensionConnected(): 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 if (!response.ok) return false;\n const data = await response.json();\n return !!data.extensionConnected;\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 // 等待 Chrome 扩展连接(最多 10 秒)\n const extStart = Date.now();\n while (Date.now() - extStart < 10000) {\n if (await isExtensionConnected()) return;\n await new Promise((r) => setTimeout(r, POLL_INTERVAL));\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 * site 命令 - 管理和运行社区/私有网站适配器\n *\n * 用法:\n * bb-browser site list 列出所有可用 site adapter\n * bb-browser site search <query> 搜索\n * bb-browser site <name> [args...] 运行(简写)\n * bb-browser site run <name> [args...] 运行\n * bb-browser site update 更新社区 adapter 库\n *\n * 目录:\n * ~/.bb-browser/sites/ 私有 adapter(优先)\n * ~/.bb-browser/bb-sites/ 社区 adapter(bb-browser site update 拉取)\n */\n\nimport { generateId, type Request, type Response, type TabInfo } from \"@bb-browser/shared\";\nimport { handleJqResponse, sendCommand } from \"../client.js\";\nimport { 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 days?: number;\n jq?: string;\n openclaw?: boolean;\n}\n\n/** Adapter 参数定义 */\ninterface ArgDef {\n required?: boolean;\n description?: string;\n}\n\n/** Adapter 元数据 */\ninterface SiteMeta {\n name: string;\n description: string;\n domain: string;\n args: Record<string, ArgDef>;\n capabilities?: string[];\n readOnly?: boolean;\n example?: string;\n filePath: string;\n source: \"local\" | \"community\";\n}\n\ninterface HistoryDomain {\n domain: string;\n visits: number;\n}\n\ninterface SiteRecommendation {\n domain: string;\n visits: number;\n adapterCount: number;\n adapters: Array<{\n name: string;\n description: string;\n example: string;\n }>;\n}\n\n/**\n * 从 JS 文件的 /* @meta JSON * / 块解析元数据\n */\nfunction parseSiteMeta(filePath: string, source: \"local\" | \"community\"): SiteMeta | null {\n let content: string;\n try {\n content = readFileSync(filePath, \"utf-8\");\n } catch {\n return null;\n }\n\n // 从文件路径推断默认 name\n const sitesDir = source === \"local\" ? LOCAL_SITES_DIR : COMMUNITY_SITES_DIR;\n const relPath = relative(sitesDir, filePath);\n const defaultName = relPath.replace(/\\.js$/, \"\").replace(/\\\\/g, \"/\");\n\n // 解析 /* @meta { ... } */ 块\n const metaMatch = content.match(/\\/\\*\\s*@meta\\s*\\n([\\s\\S]*?)\\*\\//);\n if (metaMatch) {\n try {\n const metaJson = JSON.parse(metaMatch[1]);\n return {\n name: metaJson.name || defaultName,\n description: metaJson.description || \"\",\n domain: metaJson.domain || \"\",\n args: metaJson.args || {},\n capabilities: metaJson.capabilities,\n readOnly: metaJson.readOnly,\n example: metaJson.example,\n filePath,\n source,\n };\n } catch {\n // JSON 解析失败,回退到 @tag 模式\n }\n }\n\n // 回退:解析 // @tag 格式(兼容旧格式)\n const meta: SiteMeta = {\n name: defaultName,\n description: \"\",\n domain: \"\",\n args: {},\n filePath,\n source,\n };\n\n const tagPattern = /\\/\\/\\s*@(\\w+)[ \\t]+(.*)/g;\n let match;\n while ((match = tagPattern.exec(content)) !== null) {\n const [, key, value] = match;\n switch (key) {\n case \"name\": meta.name = value.trim(); break;\n case \"description\": meta.description = value.trim(); break;\n case \"domain\": meta.domain = value.trim(); break;\n case \"args\":\n for (const arg of value.trim().split(/[,\\s]+/).filter(Boolean)) {\n meta.args[arg] = { required: true };\n }\n break;\n case \"example\": meta.example = value.trim(); break;\n }\n }\n\n return meta;\n}\n\n/**\n * 扫描目录下所有 .js 文件\n */\nfunction scanSites(dir: string, source: \"local\" | \"community\"): SiteMeta[] {\n if (!existsSync(dir)) return [];\n const sites: SiteMeta[] = [];\n\n function walk(currentDir: string): void {\n let entries;\n try { entries = readdirSync(currentDir, { withFileTypes: true }); } catch { return; }\n for (const entry of entries) {\n const fullPath = join(currentDir, entry.name);\n if (entry.isDirectory() && !entry.name.startsWith(\".\")) {\n walk(fullPath);\n } else if (entry.isFile() && entry.name.endsWith(\".js\")) {\n const meta = parseSiteMeta(fullPath, source);\n if (meta) sites.push(meta);\n }\n }\n }\n\n walk(dir);\n return sites;\n}\n\n/**\n * 根据 URL 检查是否有对应的 site adapter,返回提示文本\n */\nexport function getSiteHintForDomain(url: string): string | null {\n try {\n const hostname = new URL(url).hostname;\n const sites = getAllSites();\n const matched = sites.filter(s => s.domain && (hostname === s.domain || hostname.endsWith(\".\" + s.domain)));\n if (matched.length === 0) return null;\n const names = matched.map(s => s.name);\n const example = matched[0].example || `bb-browser site ${names[0]}`;\n return `该网站有 ${names.length} 个 site adapter 可直接获取数据,无需手动操作浏览器。试试: ${example}`;\n } catch {\n return null;\n }\n}\n\n/**\n * 获取所有 adapter(私有优先)\n */\nfunction getAllSites(): SiteMeta[] {\n const community = scanSites(COMMUNITY_SITES_DIR, \"community\");\n const local = scanSites(LOCAL_SITES_DIR, \"local\");\n\n const byName = new Map<string, SiteMeta>();\n for (const s of community) byName.set(s.name, s);\n for (const s of local) byName.set(s.name, s);\n\n return Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * 精确匹配 tab 的 origin\n */\nfunction matchTabOrigin(tabUrl: string, domain: string): boolean {\n try {\n const tabOrigin = new URL(tabUrl).hostname;\n return tabOrigin === domain || tabOrigin.endsWith(\".\" + domain);\n } catch {\n return false;\n }\n}\n\n// ── 子命令 ──────────────────────────────────────────────────────\n\nfunction siteList(options: SiteOptions): void {\n const sites = getAllSites();\n\n if (sites.length === 0) {\n console.log(\"未找到任何 site adapter。\");\n console.log(\" 安装社区 adapter: bb-browser site update\");\n console.log(` 私有 adapter 目录: ${LOCAL_SITES_DIR}`);\n return;\n }\n\n if (options.json) {\n console.log(JSON.stringify(sites.map(s => ({\n name: s.name, description: s.description, domain: s.domain,\n args: s.args, source: s.source,\n })), null, 2));\n return;\n }\n\n const groups = new Map<string, SiteMeta[]>();\n for (const s of sites) {\n const platform = s.name.split(\"/\")[0];\n if (!groups.has(platform)) groups.set(platform, []);\n groups.get(platform)!.push(s);\n }\n\n for (const [platform, items] of groups) {\n console.log(`\\n${platform}/`);\n for (const s of items) {\n const cmd = s.name.split(\"/\").slice(1).join(\"/\");\n const src = s.source === \"local\" ? \" (local)\" : \"\";\n const desc = s.description ? ` - ${s.description}` : \"\";\n console.log(` ${cmd.padEnd(20)}${desc}${src}`);\n }\n }\n console.log();\n}\n\nfunction siteSearch(query: string, options: SiteOptions): void {\n const sites = getAllSites();\n const q = query.toLowerCase();\n const matches = sites.filter(s =>\n s.name.toLowerCase().includes(q) ||\n s.description.toLowerCase().includes(q) ||\n s.domain.toLowerCase().includes(q)\n );\n\n if (matches.length === 0) {\n console.log(`未找到匹配 \"${query}\" 的 adapter。`);\n console.log(\" 查看所有: bb-browser site list\");\n return;\n }\n\n if (options.json) {\n console.log(JSON.stringify(matches.map(s => ({\n name: s.name, description: s.description, domain: s.domain, source: s.source,\n })), null, 2));\n return;\n }\n\n for (const s of matches) {\n const src = s.source === \"local\" ? \" (local)\" : \"\";\n console.log(`${s.name.padEnd(24)} ${s.description}${src}`);\n }\n}\n\nfunction siteUpdate(): void {\n mkdirSync(BB_DIR, { recursive: true });\n\n if (existsSync(join(COMMUNITY_SITES_DIR, \".git\"))) {\n console.log(\"更新社区 site adapter 库...\");\n try {\n execSync(\"git pull --ff-only\", { cwd: COMMUNITY_SITES_DIR, stdio: \"pipe\" });\n console.log(\"更新完成。\");\n console.log(\"\");\n console.log(\"💡 运行 bb-browser site recommend 看看哪些和你的浏览习惯匹配\");\n } catch (e) {\n console.error(`更新失败: ${e instanceof Error ? e.message : e}`);\n console.error(\" 手动修复: cd ~/.bb-browser/bb-sites && git pull\");\n process.exit(1);\n }\n } else {\n console.log(`克隆社区 adapter 库: ${COMMUNITY_REPO}`);\n try {\n execSync(`git clone ${COMMUNITY_REPO} ${COMMUNITY_SITES_DIR}`, { stdio: \"pipe\" });\n console.log(\"克隆完成。\");\n console.log(\"\");\n console.log(\"💡 运行 bb-browser site recommend 看看哪些和你的浏览习惯匹配\");\n } catch (e) {\n console.error(`克隆失败: ${e instanceof Error ? e.message : e}`);\n console.error(` 手动修复: git clone ${COMMUNITY_REPO} ~/.bb-browser/bb-sites`);\n process.exit(1);\n }\n }\n\n const sites = scanSites(COMMUNITY_SITES_DIR, \"community\");\n console.log(`已安装 ${sites.length} 个社区 adapter。`);\n}\n\nfunction findSiteByName(name: string): SiteMeta | undefined {\n return getAllSites().find((site) => site.name === name);\n}\n\nfunction siteInfo(name: string, options: SiteOptions): void {\n const site = findSiteByName(name);\n\n if (!site) {\n console.error(`[error] site info: adapter \"${name}\" not found.`);\n console.error(\" Try: bb-browser site list\");\n process.exit(1);\n }\n\n const meta = {\n name: site.name,\n description: site.description,\n domain: site.domain,\n args: site.args,\n example: site.example,\n readOnly: site.readOnly,\n };\n\n if (options.json) {\n console.log(JSON.stringify(meta, null, 2));\n return;\n }\n\n console.log(`${site.name} — ${site.description}`);\n console.log();\n console.log(\"参数:\");\n\n const argEntries = Object.entries(site.args);\n if (argEntries.length === 0) {\n console.log(\" (无)\");\n } else {\n for (const [argName, argDef] of argEntries) {\n const requiredText = argDef.required ? \"必填\" : \"可选\";\n const description = argDef.description || \"\";\n console.log(` ${argName} (${requiredText}) ${description}`.trimEnd());\n }\n }\n\n console.log();\n console.log(\"示例:\");\n console.log(` ${site.example || `bb-browser site ${site.name}`}`);\n console.log();\n console.log(`域名:${site.domain || \"(未声明)\"}`);\n console.log(`只读:${site.readOnly ? \"是\" : \"否\"}`);\n}\n\nasync function siteRecommend(options: SiteOptions): Promise<void> {\n const days = options.days ?? 30;\n const response = await sendCommand({\n id: generateId(),\n action: \"history\",\n historyCommand: \"domains\",\n ms: days,\n });\n\n if (!response.success) {\n throw new Error(response.error || \"History command failed\");\n }\n\n const historyDomains: HistoryDomain[] = response.data?.historyDomains || [];\n const sites = getAllSites();\n const sitesByDomain = new Map<string, SiteMeta[]>();\n\n for (const site of sites) {\n if (!site.domain) continue;\n const domain = site.domain.toLowerCase();\n const existing = sitesByDomain.get(domain) || [];\n existing.push(site);\n sitesByDomain.set(domain, existing);\n }\n\n const available: SiteRecommendation[] = [];\n const notAvailable: HistoryDomain[] = [];\n\n for (const item of historyDomains) {\n const adapters = sitesByDomain.get(item.domain.toLowerCase());\n if (adapters && adapters.length > 0) {\n const sortedAdapters = [...adapters].sort((a, b) => a.name.localeCompare(b.name));\n available.push({\n domain: item.domain,\n visits: item.visits,\n adapterCount: sortedAdapters.length,\n adapters: sortedAdapters.map((site) => ({\n name: site.name,\n description: site.description,\n example: site.example || `bb-browser site ${site.name}`,\n })),\n });\n } else if (item.visits >= 5 && item.domain && !item.domain.includes('localhost') && item.domain.includes('.')) {\n notAvailable.push(item);\n }\n }\n\n const jsonData = {\n days,\n available,\n not_available: notAvailable,\n };\n\n if (options.jq) {\n handleJqResponse({ id: generateId(), success: true, data: jsonData });\n }\n\n if (options.json) {\n console.log(JSON.stringify(jsonData, null, 2));\n return;\n }\n\n console.log(`基于你最近 ${days} 天的浏览记录:`);\n console.log();\n\n console.log(\"🎯 你常用这些网站,可以直接用:\");\n console.log();\n if (available.length === 0) {\n console.log(\" (暂无匹配的 adapter)\");\n } else {\n for (const item of available) {\n console.log(` ${item.domain.padEnd(20)} ${item.visits} 次访问 ${item.adapterCount} 个命令`);\n console.log(` 试试: ${item.adapters[0]?.example || `bb-browser site ${item.adapters[0]?.name || \"\"}`}`);\n console.log();\n }\n }\n\n console.log(\"📋 你常用但还没有 adapter:\");\n console.log();\n if (notAvailable.length === 0) {\n console.log(\" (暂无)\");\n } else {\n for (const item of notAvailable) {\n console.log(` ${item.domain.padEnd(20)} ${item.visits} 次访问`);\n }\n }\n\n console.log();\n console.log('💡 跟你的 AI Agent 说 \"把 notion.so CLI 化\",它就能自动完成。');\n console.log();\n console.log(`所有分析纯本地完成。用 --days 7 只看最近一周。`);\n}\n\nasync function siteRun(\n name: string,\n args: string[],\n options: SiteOptions\n): Promise<void> {\n const sites = getAllSites();\n const site = sites.find(s => s.name === name);\n\n if (!site) {\n const fuzzy = sites.filter(s => s.name.includes(name));\n console.error(`[error] site: \"${name}\" not found.`);\n if (fuzzy.length > 0) {\n console.error(\" Did you mean:\");\n for (const s of fuzzy.slice(0, 5)) {\n console.error(` bb-browser site ${s.name}`);\n }\n } else {\n console.error(\" Try: bb-browser site list\");\n console.error(\" Or: bb-browser site update\");\n }\n process.exit(1);\n }\n\n // 解析参数\n const argNames = Object.keys(site.args);\n const argMap: Record<string, string> = {};\n\n // 过滤掉 --flag value 对,收集位置参数\n const positionalArgs: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i].startsWith(\"--\")) {\n const flagName = args[i].slice(2);\n if (flagName in site.args && args[i + 1]) {\n argMap[flagName] = args[i + 1];\n i++; // 跳过值\n }\n } else {\n positionalArgs.push(args[i]);\n }\n }\n\n // 位置参数按 argNames 顺序填入(跳过已通过 --flag 提供的)\n let posIdx = 0;\n for (const argName of argNames) {\n if (!argMap[argName] && posIdx < positionalArgs.length) {\n argMap[argName] = positionalArgs[posIdx++];\n }\n }\n\n // 只检查 required 参数\n for (const [argName, argDef] of Object.entries(site.args)) {\n if (argDef.required && !argMap[argName]) {\n console.error(`[error] site ${name}: missing required argument \"${argName}\".`);\n const usage = argNames.map(a => {\n const def = site.args[a];\n return def.required ? `<${a}>` : `[${a}]`;\n }).join(\" \");\n console.error(` Usage: bb-browser site ${name} ${usage}`);\n if (site.example) console.error(` Example: ${site.example}`);\n process.exit(1);\n }\n }\n\n // 读取并解析 JS\n const jsContent = readFileSync(site.filePath, \"utf-8\");\n\n // 移除 /* @meta ... */ 块,保留函数体\n const jsBody = jsContent.replace(/\\/\\*\\s*@meta[\\s\\S]*?\\*\\//, \"\").trim();\n\n // 构造执行脚本\n const argsJson = JSON.stringify(argMap);\n const script = `(${jsBody})(${argsJson})`;\n\n if (options.openclaw) {\n const { ocGetTabs, ocFindTabByDomain, ocOpenTab, ocEvaluate } = await import(\"../openclaw-bridge.js\");\n\n let targetId: string;\n\n if (site.domain) {\n const tabs = ocGetTabs();\n const existing = ocFindTabByDomain(tabs, site.domain);\n if (existing) {\n targetId = existing.targetId;\n } else {\n targetId = ocOpenTab(`https://${site.domain}`);\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n } else {\n const tabs = ocGetTabs();\n if (tabs.length === 0) {\n throw new Error(\"No tabs open in OpenClaw browser\");\n }\n targetId = tabs[0].targetId;\n }\n\n const wrappedFn = `async () => { const __fn = ${jsBody}; return await __fn(${argsJson}); }`;\n const parsed = ocEvaluate(targetId, wrappedFn);\n\n if (typeof parsed === \"object\" && parsed !== null && \"error\" in parsed) {\n const errObj = parsed as { error: string; hint?: string };\n const checkText = `${errObj.error} ${errObj.hint || \"\"}`;\n const isAuthError = /401|403|unauthorized|forbidden|not.?logged|login.?required|sign.?in|auth/i.test(checkText);\n const loginHint = isAuthError && site.domain\n ? `Please log in to https://${site.domain} in your OpenClaw browser first, then retry.`\n : undefined;\n const hint = loginHint || errObj.hint;\n const reportHint = `If this is an adapter bug, report via: gh issue create --repo epiral/bb-sites --title \"[${name}] <description>\" OR: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] <description>\"`;\n\n if (options.json) {\n console.log(JSON.stringify({ id: \"openclaw\", success: false, error: errObj.error, hint, reportHint }));\n } else {\n console.error(`[error] site ${name}: ${errObj.error}`);\n if (hint) console.error(` Hint: ${hint}`);\n console.error(` Report: gh issue create --repo epiral/bb-sites --title \"[${name}] ...\"`);\n console.error(` or: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] ...\"`);\n }\n process.exit(1);\n }\n\n if (options.jq) {\n const { applyJq } = await import(\"../jq.js\");\n const expr = options.jq.replace(/^\\.data\\./, '.');\n const results = applyJq(parsed, expr);\n for (const r of results) {\n console.log(typeof r === \"string\" ? r : JSON.stringify(r));\n }\n } else if (options.json) {\n console.log(JSON.stringify({ id: \"openclaw\", success: true, data: parsed }));\n } else {\n console.log(JSON.stringify(parsed, null, 2));\n }\n return;\n }\n\n await ensureDaemonRunning();\n\n // 确定目标 tab\n let targetTabId: number | undefined = options.tabId;\n\n // 如果用户没指定 --tab,自动查找匹配域名的 tab\n if (!targetTabId && site.domain) {\n const listReq: Request = { id: generateId(), action: \"tab_list\" };\n const listResp: Response = await sendCommand(listReq);\n\n if (listResp.success && listResp.data?.tabs) {\n const matchingTab = listResp.data.tabs.find((tab: TabInfo) =>\n matchTabOrigin(tab.url, site.domain)\n );\n if (matchingTab) {\n targetTabId = matchingTab.tabId;\n }\n }\n\n if (!targetTabId) {\n const newResp = await sendCommand({\n id: generateId(),\n action: \"tab_new\",\n url: `https://${site.domain}`,\n });\n targetTabId = newResp.data?.tabId;\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n }\n\n // 执行\n const evalReq: Request = { id: generateId(), action: \"eval\", script, tabId: targetTabId };\n const evalResp: Response = await sendCommand(evalReq);\n\n if (!evalResp.success) {\n const hint = site.domain\n ? `Open https://${site.domain} in your browser, make sure you are logged in, then retry.`\n : undefined;\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: false, error: evalResp.error || \"eval failed\", hint }));\n } else {\n console.error(`[error] site ${name}: ${evalResp.error || \"eval failed\"}`);\n if (hint) console.error(` Hint: ${hint}`);\n }\n process.exit(1);\n }\n\n const result = evalResp.data?.result;\n if (result === undefined || result === null) {\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: true, data: null }));\n } else {\n console.log(\"(no output)\");\n }\n return;\n }\n\n // 解析输出\n let parsed: unknown;\n try {\n parsed = typeof result === \"string\" ? JSON.parse(result) : result;\n } catch {\n parsed = result;\n }\n\n // 检查 adapter 返回的 error\n if (typeof parsed === \"object\" && parsed !== null && \"error\" in parsed) {\n const errObj = parsed as { error: string; hint?: string };\n\n // 检测是否为登录问题(检查 error 和 hint 文本)\n const checkText = `${errObj.error} ${errObj.hint || \"\"}`;\n const isAuthError = /401|403|unauthorized|forbidden|not.?logged|login.?required|sign.?in|auth/i.test(checkText);\n const loginHint = isAuthError && site.domain\n ? `Please log in to https://${site.domain} in your browser first, then retry.`\n : undefined;\n const hint = loginHint || errObj.hint;\n const reportHint = `If this is an adapter bug, report via: gh issue create --repo epiral/bb-sites --title \"[${name}] <description>\" OR: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] <description>\"`;\n\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: false, error: errObj.error, hint, reportHint }));\n } else {\n console.error(`[error] site ${name}: ${errObj.error}`);\n if (hint) console.error(` Hint: ${hint}`);\n console.error(` Report: gh issue create --repo epiral/bb-sites --title \"[${name}] ...\"`);\n console.error(` or: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] ...\"`);\n }\n process.exit(1);\n }\n\n if (options.jq) {\n const { applyJq } = await import(\"../jq.js\");\n // Tolerate \".data.\" prefix — Agent may copy from --json envelope structure\n const expr = options.jq.replace(/^\\.data\\./, '.');\n const results = applyJq(parsed, expr);\n for (const r of results) {\n console.log(typeof r === \"string\" ? r : JSON.stringify(r));\n }\n } else if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: true, data: parsed }));\n } else {\n console.log(JSON.stringify(parsed, null, 2));\n }\n}\n\n// ── 入口 ────────────────────────────────────────────────────────\n\nexport async function siteCommand(\n args: string[],\n options: SiteOptions = {}\n): Promise<void> {\n const subCommand = args[0];\n\n if (!subCommand || subCommand === \"--help\" || subCommand === \"-h\") {\n console.log(`bb-browser site - 网站 CLI 化(管理和运行 site adapter)\n\n用法:\n bb-browser site list 列出所有可用 adapter\n bb-browser site info <name> 查看 adapter 元信息\n bb-browser site recommend 基于历史记录推荐 adapter\n bb-browser site search <query> 搜索 adapter\n bb-browser site <name> [args...] 运行 adapter(简写)\n bb-browser site run <name> [args...] 运行 adapter\n bb-browser site update 更新社区 adapter 库 (git clone/pull)\n\n目录:\n ${LOCAL_SITES_DIR} 私有 adapter(优先)\n ${COMMUNITY_SITES_DIR} 社区 adapter\n\n示例:\n bb-browser site update\n bb-browser site list\n bb-browser site reddit/thread https://www.reddit.com/r/LocalLLaMA/comments/...\n bb-browser site twitter/user yan5xu\n bb-browser site search reddit\n\n创建新 adapter: bb-browser guide\n报告问题: gh issue create --repo epiral/bb-sites --title \"[adapter-name] 描述\"\n贡献社区: https://github.com/epiral/bb-sites`);\n return;\n }\n\n switch (subCommand) {\n case \"list\": siteList(options); break;\n case \"search\":\n if (!args[1]) {\n console.error(\"[error] site search: <query> is required.\");\n console.error(\" Usage: bb-browser site search <query>\");\n process.exit(1);\n }\n siteSearch(args[1], options);\n break;\n case \"info\":\n if (!args[1]) {\n console.error(\"[error] site info: <name> is required.\");\n console.error(\" Usage: bb-browser site info <name>\");\n process.exit(1);\n }\n siteInfo(args[1], options);\n break;\n case \"recommend\":\n await siteRecommend(options);\n break;\n case \"update\": siteUpdate(); break;\n case \"run\":\n if (!args[1]) {\n console.error(\"[error] site run: <name> is required.\");\n console.error(\" Usage: bb-browser site run <name> [args...]\");\n console.error(\" Try: bb-browser site list\");\n process.exit(1);\n }\n await siteRun(args[1], args.slice(2), options);\n break;\n default:\n if (subCommand.includes(\"/\")) {\n await siteRun(subCommand, args.slice(1), options);\n } else {\n console.error(`[error] site: unknown subcommand \"${subCommand}\".`);\n console.error(\" Available: list, info, recommend, search, run, update\");\n console.error(\" Try: bb-browser site --help\");\n process.exit(1);\n }\n break;\n }\n\n // 静默后台更新社区 adapter\n silentUpdate();\n}\n\nfunction silentUpdate(): void {\n const gitDir = join(COMMUNITY_SITES_DIR, \".git\");\n if (!existsSync(gitDir)) return;\n import(\"node:child_process\").then(({ spawn }) => {\n const child = spawn(\"git\", [\"pull\", \"--ff-only\"], {\n cwd: COMMUNITY_SITES_DIR,\n stdio: \"ignore\",\n detached: true,\n });\n child.unref();\n }).catch(() => {});\n}\n","/**\n * open 命令 - 打开指定 URL\n * \n * 用法:\n * bb-browser open <url> # 在新 tab 中打开\n * bb-browser open <url> --tab current # 在当前 tab 中打开\n * bb-browser open <url> --tab 123 # 在指定 tabId 的 tab 中打开\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\nimport { getSiteHintForDomain } from \"./site.js\";\n\nexport interface OpenOptions {\n json?: boolean;\n tab?: string; // \"current\" | tabId 数字字符串 | undefined(新建 tab)\n}\n\nexport async function openCommand(\n url: string,\n options: OpenOptions = {}\n): Promise<void> {\n // 验证 URL\n if (!url) {\n throw new Error(\"缺少 URL 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 补全 URL 协议\n let normalizedUrl = url;\n if (!url.startsWith(\"http://\") && !url.startsWith(\"https://\")) {\n normalizedUrl = \"https://\" + url;\n }\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"open\",\n url: normalizedUrl,\n };\n\n // 处理 --tab 参数\n if (options.tab !== undefined) {\n if (options.tab === \"current\") {\n // 使用当前活动 tab\n (request as Record<string, unknown>).tabId = \"current\";\n } else {\n // 使用指定 tabId\n const tabId = parseInt(options.tab, 10);\n if (isNaN(tabId)) {\n throw new Error(`无效的 tabId: ${options.tab}`);\n }\n (request as Record<string, unknown>).tabId = tabId;\n }\n }\n // 不指定 --tab 时,tabId 为 undefined,扩展会创建新 tab\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`已打开: ${response.data?.url ?? normalizedUrl}`);\n if (response.data?.title) {\n console.log(`标题: ${response.data.title}`);\n }\n if (response.data?.tabId) {\n console.log(`Tab ID: ${response.data.tabId}`);\n }\n // 提示:如果该域名有 site adapter,引导使用\n const siteHint = getSiteHintForDomain(normalizedUrl);\n if (siteHint) {\n console.log(`\\n💡 ${siteHint}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * snapshot 命令 - 获取当前页面快照\n * 用法:bb-browser snapshot [-i|--interactive] [-c|--compact] [-d|--depth N] [-s|--selector SEL]\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface SnapshotOptions {\n json?: boolean;\n /** 只输出可交互元素 */\n interactive?: boolean;\n /** 移除空结构节点 */\n compact?: boolean;\n /** 限制树深度 */\n maxDepth?: number;\n /** CSS 选择器范围 */\n selector?: string;\n tabId?: number;\n}\n\nexport async function snapshotCommand(\n options: SnapshotOptions = {}\n): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"snapshot\",\n interactive: options.interactive,\n compact: options.compact,\n maxDepth: options.maxDepth,\n selector: options.selector,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`标题: ${response.data?.title ?? \"(无标题)\"}`);\n console.log(`URL: ${response.data?.url ?? \"(未知)\"}`);\n // 输出 snapshot 文本\n if (response.data?.snapshotData?.snapshot) {\n console.log(\"\");\n console.log(response.data.snapshotData.snapshot);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * click 命令 - 点击元素\n * 用法:bb-browser click <ref>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ClickOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function clickCommand(\n ref: string,\n options: ClickOptions = {}\n): Promise<void> {\n // 验证 ref\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"click\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已点击: ${role} \"${name}\"`);\n } else {\n console.log(`已点击: ${role}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * hover 命令 - 悬停在元素上\n * 用法:bb-browser hover <ref>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface HoverOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function hoverCommand(\n ref: string,\n options: HoverOptions = {}\n): Promise<void> {\n // 验证 ref\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"hover\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已悬停: ${role} \"${name}\"`);\n } else {\n console.log(`已悬停: ${role}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * fill 命令 - 填充输入框\n * 用法:bb-browser fill <ref> <text>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface FillOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function fillCommand(\n ref: string,\n text: string,\n options: FillOptions = {}\n): Promise<void> {\n // 验证参数\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n if (text === undefined || text === null) {\n throw new Error(\"缺少 text 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"fill\",\n ref: parsedRef,\n text: text,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已填充: ${role} \"${name}\"`);\n } else {\n console.log(`已填充: ${role}`);\n }\n console.log(`内容: \"${text}\"`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * type 命令 - 在元素中逐字符输入文本(不清空原有内容)\n * 用法:bb-browser type <ref> <text>\n * \n * 与 fill 命令的区别:\n * - fill:先清空再填入\n * - type:不清空,逐字符追加输入\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface TypeOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function typeCommand(\n ref: string,\n text: string,\n options: TypeOptions = {}\n): Promise<void> {\n // 验证参数\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n if (text === undefined || text === null) {\n throw new Error(\"缺少 text 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"type\",\n ref: parsedRef,\n text: text,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已输入: ${role} \"${name}\"`);\n } else {\n console.log(`已输入: ${role}`);\n }\n console.log(`内容: \"${text}\"`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * close 命令 - 关闭当前标签页\n * 用法:bb-browser close\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface CloseOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport async function closeCommand(options: CloseOptions = {}): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"close\",\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const title = response.data?.title ?? \"\";\n if (title) {\n console.log(`已关闭: \"${title}\"`);\n } else {\n console.log(\"已关闭当前标签页\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * get 命令 - 获取页面或元素信息\n * 用法:\n * bb-browser get text <ref> 获取元素文本\n * bb-browser get url 获取当前页面 URL\n * bb-browser get title 获取页面标题\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface GetOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/** 支持的 get 属性类型 */\nexport type GetAttribute = \"text\" | \"url\" | \"title\";\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function getCommand(\n attribute: GetAttribute,\n ref: string | undefined,\n options: GetOptions = {}\n): Promise<void> {\n // 验证参数\n if (attribute === \"text\" && !ref) {\n throw new Error(\"get text 需要 ref 参数,如: get text @5\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"get\",\n attribute,\n ref: ref ? parseRef(ref) : undefined,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const value = response.data?.value ?? \"\";\n console.log(value);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * screenshot 命令 - 截取当前页面\n * 用法:\n * bb-browser screenshot # 保存到临时目录\n * bb-browser screenshot ./page.png # 保存到指定路径\n * bb-browser screenshot --json # 返回 { path, base64 }\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ScreenshotOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 生成默认截图路径\n */\nfunction getDefaultPath(): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const filename = `bb-screenshot-${timestamp}.png`;\n return path.join(os.tmpdir(), filename);\n}\n\n/**\n * 解码 data URL 并保存为文件\n */\nfunction saveBase64Image(dataUrl: string, filePath: string): void {\n const base64Data = dataUrl.replace(/^data:image\\/png;base64,/, \"\");\n const buffer = Buffer.from(base64Data, \"base64\");\n \n // 确保目录存在\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n \n fs.writeFileSync(filePath, buffer);\n}\n\nexport async function screenshotCommand(\n outputPath?: string,\n options: ScreenshotOptions = {}\n): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 确定保存路径\n const filePath = outputPath ? path.resolve(outputPath) : getDefaultPath();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"screenshot\",\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 处理结果\n if (response.success && response.data?.dataUrl) {\n const dataUrl = response.data.dataUrl as string;\n \n // 保存文件\n saveBase64Image(dataUrl, filePath);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify({\n success: true,\n path: filePath,\n base64: dataUrl,\n }, null, 2));\n } else {\n console.log(`截图已保存: ${filePath}`);\n }\n } else {\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n console.error(`错误: ${response.error}`);\n }\n process.exit(1);\n }\n}\n","/**\n * wait 命令 - 等待指定时间或元素出现\n * 用法:\n * bb-browser wait <ms> 等待指定毫秒数\n * bb-browser wait @<ref> 等待元素出现(最多 10 秒)\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface WaitOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 判断是否是等待时间(纯数字)\n */\nfunction isTimeWait(target: string): boolean {\n return /^\\d+$/.test(target);\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function waitCommand(\n target: string,\n options: WaitOptions = {}\n): Promise<void> {\n if (!target) {\n throw new Error(\"缺少等待目标参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n let request: Request;\n\n if (isTimeWait(target)) {\n // 等待时间模式\n const ms = parseInt(target, 10);\n request = {\n id: generateId(),\n action: \"wait\",\n waitType: \"time\",\n ms,\n tabId: options.tabId,\n };\n } else {\n // 等待元素模式\n const ref = parseRef(target);\n request = {\n id: generateId(),\n action: \"wait\",\n waitType: \"element\",\n ref,\n tabId: options.tabId,\n };\n }\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n if (isTimeWait(target)) {\n console.log(`已等待 ${target}ms`);\n } else {\n console.log(`元素 @${parseRef(target)} 已出现`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * press 命令 - 发送键盘按键\n * 用法:bb-browser press <key>\n *\n * key 支持格式:\n * - 单键:\"Enter\", \"Tab\", \"Escape\", \"Backspace\", \"ArrowUp\" 等\n * - 组合键:\"Control+a\", \"Control+c\", \"Control+v\"(用 + 分隔)\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface PressOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析按键字符串,提取修饰键和主键\n * 例如:\n * \"Enter\" -> { key: \"Enter\", modifiers: [] }\n * \"Control+a\" -> { key: \"a\", modifiers: [\"Control\"] }\n * \"Control+Shift+Delete\" -> { key: \"Delete\", modifiers: [\"Control\", \"Shift\"] }\n */\nfunction parseKey(keyString: string): { key: string; modifiers: string[] } {\n const parts = keyString.split(\"+\");\n const modifierNames = [\"Control\", \"Alt\", \"Shift\", \"Meta\"];\n\n const modifiers: string[] = [];\n let key = \"\";\n\n for (const part of parts) {\n if (modifierNames.includes(part)) {\n modifiers.push(part);\n } else {\n key = part;\n }\n }\n\n return { key, modifiers };\n}\n\nexport async function pressCommand(\n keyString: string,\n options: PressOptions = {}\n): Promise<void> {\n // 验证参数\n if (!keyString) {\n throw new Error(\"缺少 key 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析按键\n const { key, modifiers } = parseKey(keyString);\n\n if (!key) {\n throw new Error(\"无效的按键格式\");\n }\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"press\",\n key,\n modifiers,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const displayKey = modifiers.length > 0 ? `${modifiers.join(\"+\")}+${key}` : key;\n console.log(`已按下: ${displayKey}`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * scroll 命令 - 滚动页面\n * 用法:bb-browser scroll <direction> [pixels]\n *\n * direction: up | down | left | right\n * pixels: 滚动像素数,默认 300\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ScrollOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport type ScrollDirection = \"up\" | \"down\" | \"left\" | \"right\";\n\nconst VALID_DIRECTIONS: ScrollDirection[] = [\"up\", \"down\", \"left\", \"right\"];\nconst DEFAULT_PIXELS = 300;\n\nexport async function scrollCommand(\n direction: string,\n pixels?: string,\n options: ScrollOptions = {}\n): Promise<void> {\n // 验证 direction\n if (!direction) {\n throw new Error(\"缺少 direction 参数\");\n }\n\n if (!VALID_DIRECTIONS.includes(direction as ScrollDirection)) {\n throw new Error(\n `无效的滚动方向: ${direction},支持: ${VALID_DIRECTIONS.join(\", \")}`\n );\n }\n\n // 解析 pixels\n let pixelValue = DEFAULT_PIXELS;\n if (pixels !== undefined) {\n pixelValue = parseInt(pixels, 10);\n if (isNaN(pixelValue) || pixelValue <= 0) {\n throw new Error(`无效的像素值: ${pixels}`);\n }\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"scroll\",\n direction: direction as ScrollDirection,\n pixels: pixelValue,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`已滚动: ${direction} ${pixelValue}px`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * 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 * history 命令 - 查询 Chrome 浏览历史\n *\n * 用法:\n * bb-browser history search [query] 搜索历史记录\n * bb-browser history domains 查看访问最多的域名\n */\n\nimport { sendCommand } from \"../client.js\";\n\ninterface HistoryOptions {\n json?: boolean;\n days?: number;\n query?: string;\n}\n\nexport async function historyCommand(\n subCommand: 'search' | 'domains',\n options: HistoryOptions = {}\n): Promise<void> {\n const response = await sendCommand({\n id: crypto.randomUUID(),\n action: \"history\",\n historyCommand: subCommand,\n text: options.query,\n ms: options.days,\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 || \"History command failed\");\n }\n\n const data = response.data;\n\n switch (subCommand) {\n case \"search\": {\n const items = data?.historyItems || [];\n\n console.log(`找到 ${items.length} 条历史记录\\n`);\n\n if (items.length === 0) {\n console.log(\"没有找到匹配的历史记录\");\n break;\n }\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n console.log(`${i + 1}. ${item.title || '(无标题)'}`);\n console.log(` ${item.url}`);\n console.log(` 访问次数: ${item.visitCount}`);\n }\n break;\n }\n\n case \"domains\": {\n const domains = data?.historyDomains || [];\n\n console.log(`找到 ${domains.length} 个域名\\n`);\n\n if (domains.length === 0) {\n console.log(\"没有找到历史记录\");\n break;\n }\n\n for (let i = 0; i < domains.length; i++) {\n const domain = domains[i];\n console.log(`${i + 1}. ${domain.domain}`);\n console.log(` 访问次数: ${domain.visits}`);\n }\n break;\n }\n\n default:\n throw new Error(`未知的 history 子命令: ${subCommand}`);\n }\n}\n","/**\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\";\nimport { historyCommand } from \"./commands/history.js\";\nimport { setJqExpression } from \"./client.js\";\n\nconst VERSION = \"0.3.0\";\n\nconst HELP_TEXT = `\nbb-browser - AI Agent 浏览器自动化工具\n\n提示:大多数数据获取任务请直接使用 site 命令,无需手动操作浏览器:\n bb-browser site list 查看所有可用命令\n bb-browser site twitter/search \"AI\" 示例:搜索推文\n bb-browser site xueqiu/hot-stock 5 示例:获取人气股票\n\n用法:\n bb-browser <command> [options]\n\n开始使用:\n site recommend 推荐你可能需要的 adapter(基于浏览历史)\n site list 列出所有 adapter\n site info <name> 查看 adapter 用法(参数、返回值、示例)\n site <name> [args] 运行 adapter\n site update 更新社区 adapter 库\n guide 如何把任何网站变成 adapter\n\n浏览器操作:\n open <url> [--tab] 打开 URL\n snapshot [-i] [-c] [-d <n>] 获取页面快照\n click <ref> 点击元素\n hover <ref> 悬停元素\n fill <ref> <text> 填充输入框(清空后填入)\n type <ref> <text> 逐字符输入(不清空)\n check/uncheck <ref> 勾选/取消复选框\n select <ref> <val> 下拉框选择\n press <key> 发送按键\n scroll <dir> [px] 滚动页面\n\n页面信息:\n get text|url|title <ref> 获取页面内容\n screenshot [path] 截图\n eval \"<js>\" 执行 JavaScript\n fetch <url> 带登录态的 HTTP 请求\n\n标签页:\n tab [list|new|close|<n>] 管理标签页\n\n导航:\n back / forward / refresh 后退 / 前进 / 刷新\n\n调试:\n network requests [filter] 查看网络请求\n console [--clear] 查看/清空控制台\n errors [--clear] 查看/清空 JS 错误\n trace start|stop|status 录制用户操作\n history search|domains 查看浏览历史\n\n选项:\n --json 以 JSON 格式输出\n --jq <expr> 对 JSON 输出应用 jq 过滤(直接作用于数据,跳过 id/success 信封)\n -i, --interactive 只输出可交互元素(snapshot 命令)\n -c, --compact 移除空结构节点(snapshot 命令)\n -d, --depth <n> 限制树深度(snapshot 命令)\n -s, --selector <sel> 限定 CSS 选择器范围(snapshot 命令)\n --tab <tabId> 指定操作的标签页 ID\n --mcp 启动 MCP server(用于 Claude Code / Cursor 等 AI 工具)\n --help, -h 显示帮助信息\n --version, -v 显示版本号\n`.trim();\n\ninterface ParsedArgs {\n command: string | null;\n args: string[];\n flags: {\n json: boolean;\n help: boolean;\n version: boolean;\n interactive: boolean;\n compact: boolean;\n depth?: number;\n selector?: string;\n tab?: string;\n days?: number;\n jq?: string;\n openclaw?: boolean;\n };\n}\n\n/**\n * 解析命令行参数\n */\nfunction parseArgs(argv: string[]): ParsedArgs {\n const args = argv.slice(2); // 跳过 node 和脚本路径\n\n const result: ParsedArgs = {\n command: null,\n args: [],\n flags: {\n json: false,\n help: false,\n version: false,\n interactive: false,\n compact: false,\n },\n };\n\n let skipNext = false;\n for (const arg of args) {\n if (skipNext) {\n skipNext = false;\n continue;\n }\n if (arg === \"--json\") {\n result.flags.json = true;\n } else if (arg === \"--jq\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.jq = args[nextIdx];\n result.flags.json = true;\n }\n } else if (arg === \"--openclaw\") {\n result.flags.openclaw = true;\n } else if (arg === \"--help\" || arg === \"-h\") {\n result.flags.help = true;\n } else if (arg === \"--version\" || arg === \"-v\") {\n result.flags.version = true;\n } else if (arg === \"--interactive\" || arg === \"-i\") {\n result.flags.interactive = true;\n } else if (arg === \"--compact\" || arg === \"-c\") {\n result.flags.compact = true;\n } else if (arg === \"--depth\" || arg === \"-d\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.depth = parseInt(args[nextIdx], 10);\n }\n } else if (arg === \"--selector\" || arg === \"-s\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.selector = args[nextIdx];\n }\n } else if (arg === \"--days\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.days = parseInt(args[nextIdx], 10);\n }\n } else if (arg === \"--id\") {\n // --id 及其值由子命令通过 process.argv 自行解析,这里跳过\n skipNext = true;\n } else if (arg === \"--tab\") {\n // --tab 参数及其值,无论出现在命令前后都跳过\n skipNext = true;\n } else if (arg.startsWith(\"-\")) {\n // 未知选项,忽略\n } else if (result.command === null) {\n result.command = arg;\n } else {\n result.args.push(arg);\n }\n }\n\n return result;\n}\n\n/**\n * 主函数\n */\nasync function main(): Promise<void> {\n const parsed = parseArgs(process.argv);\n setJqExpression(parsed.flags.jq);\n\n // 解析全局 --tab 参数\n const tabArgIdx = process.argv.indexOf('--tab');\n const globalTabId = tabArgIdx >= 0 && process.argv[tabArgIdx + 1]\n ? parseInt(process.argv[tabArgIdx + 1], 10)\n : undefined;\n\n // 处理全局选项\n if (parsed.flags.version) {\n console.log(VERSION);\n return;\n }\n\n if (process.argv.includes(\"--mcp\")) {\n const mcpPath = 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 \"history\": {\n const subCmd = parsed.args[0] as 'search' | 'domains' | undefined;\n if (!subCmd || !['search', 'domains'].includes(subCmd)) {\n console.error(\"错误:缺少或无效的子命令\");\n console.error(\"用法:bb-browser history <search|domains> [query] [--days <n>]\");\n console.error(\"示例:bb-browser history search github\");\n console.error(\" bb-browser history domains --days 7\");\n process.exit(1);\n }\n const query = parsed.args.slice(1).join(' ');\n await historyCommand(subCmd, {\n json: parsed.flags.json,\n days: parsed.flags.days || 30,\n query,\n });\n break;\n }\n\n case \"fetch\": {\n const fetchUrl = parsed.args[0];\n if (!fetchUrl) {\n console.error(\"[error] fetch: <url> is required.\");\n console.error(\" Usage: bb-browser fetch <url> [--json] [--method POST] [--body '{...}']\");\n console.error(\" Example: bb-browser fetch https://www.reddit.com/api/me.json --json\");\n process.exit(1);\n }\n // 解析 fetch 特有选项\n const methodIdx = process.argv.findIndex(a => a === \"--method\");\n const fetchMethod = methodIdx >= 0 ? process.argv[methodIdx + 1] : undefined;\n const fetchBodyIdx = process.argv.findIndex(a => a === \"--body\");\n const fetchBody = fetchBodyIdx >= 0 ? process.argv[fetchBodyIdx + 1] : undefined;\n const headersIdx = process.argv.findIndex(a => a === \"--headers\");\n const fetchHeaders = headersIdx >= 0 ? process.argv[headersIdx + 1] : undefined;\n const outputIdx = process.argv.findIndex(a => a === \"--output\");\n const fetchOutput = outputIdx >= 0 ? process.argv[outputIdx + 1] : undefined;\n await fetchCommand(fetchUrl, {\n json: parsed.flags.json,\n method: fetchMethod,\n body: fetchBody,\n headers: fetchHeaders,\n output: fetchOutput,\n tabId: globalTabId,\n });\n break;\n }\n\n case \"site\": {\n await siteCommand(parsed.args, {\n json: parsed.flags.json,\n jq: parsed.flags.jq,\n days: parsed.flags.days,\n tabId: globalTabId,\n openclaw: parsed.flags.openclaw,\n });\n break;\n }\n\n case \"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","existsSync","resolve","parsed","applyJq","spawn","parseRef","parseRef","parseRef","parseRef","parseRef","spawn","resolve","spawn","resolve","parseRef","parseRef","index","matchTabOrigin","resolve","spawn"]}
|
|
1
|
+
{"version":3,"sources":["../packages/cli/src/index.ts","../packages/cli/src/client.ts","../packages/cli/src/daemon-manager.ts","../packages/cli/src/commands/site.ts","../packages/cli/src/commands/open.ts","../packages/cli/src/commands/snapshot.ts","../packages/cli/src/commands/click.ts","../packages/cli/src/commands/hover.ts","../packages/cli/src/commands/fill.ts","../packages/cli/src/commands/type.ts","../packages/cli/src/commands/close.ts","../packages/cli/src/commands/get.ts","../packages/cli/src/commands/screenshot.ts","../packages/cli/src/commands/wait.ts","../packages/cli/src/commands/press.ts","../packages/cli/src/commands/scroll.ts","../packages/cli/src/commands/daemon.ts","../packages/cli/src/commands/reload.ts","../packages/cli/src/commands/nav.ts","../packages/cli/src/commands/check.ts","../packages/cli/src/commands/select.ts","../packages/cli/src/commands/eval.ts","../packages/cli/src/commands/tab.ts","../packages/cli/src/commands/frame.ts","../packages/cli/src/commands/dialog.ts","../packages/cli/src/commands/network.ts","../packages/cli/src/commands/console.ts","../packages/cli/src/commands/errors.ts","../packages/cli/src/commands/trace.ts","../packages/cli/src/commands/fetch.ts","../packages/cli/src/commands/history.ts"],"sourcesContent":["/**\n * bb-browser CLI 入口\n *\n * 用法:\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 { fileURLToPath } from \"node:url\";\nimport { openCommand } from \"./commands/open.js\";\nimport { snapshotCommand } from \"./commands/snapshot.js\";\nimport { clickCommand } from \"./commands/click.js\";\nimport { hoverCommand } from \"./commands/hover.js\";\nimport { fillCommand } from \"./commands/fill.js\";\nimport { typeCommand } from \"./commands/type.js\";\nimport { closeCommand } from \"./commands/close.js\";\nimport { getCommand, type GetAttribute } from \"./commands/get.js\";\nimport { screenshotCommand } from \"./commands/screenshot.js\";\nimport { waitCommand } from \"./commands/wait.js\";\nimport { pressCommand } from \"./commands/press.js\";\nimport { scrollCommand } from \"./commands/scroll.js\";\nimport { 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\";\nimport { historyCommand } from \"./commands/history.js\";\nimport { setJqExpression } from \"./client.js\";\n\nconst VERSION = \"0.7.0\";\n\nconst HELP_TEXT = `\nbb-browser - AI Agent 浏览器自动化工具\n\n提示:大多数数据获取任务请直接使用 site 命令,无需手动操作浏览器:\n bb-browser site list 查看所有可用命令\n bb-browser site twitter/search \"AI\" 示例:搜索推文\n bb-browser site xueqiu/hot-stock 5 示例:获取人气股票\n\n用法:\n bb-browser <command> [options]\n\n开始使用:\n site recommend 推荐你可能需要的 adapter(基于浏览历史)\n site list 列出所有 adapter\n site info <name> 查看 adapter 用法(参数、返回值、示例)\n site <name> [args] 运行 adapter\n site update 更新社区 adapter 库\n guide 如何把任何网站变成 adapter\n star ⭐ Star bb-browser on GitHub\n\n浏览器操作:\n open <url> [--tab] 打开 URL\n snapshot [-i] [-c] [-d <n>] 获取页面快照\n click <ref> 点击元素\n hover <ref> 悬停元素\n fill <ref> <text> 填充输入框(清空后填入)\n type <ref> <text> 逐字符输入(不清空)\n check/uncheck <ref> 勾选/取消复选框\n select <ref> <val> 下拉框选择\n press <key> 发送按键\n scroll <dir> [px] 滚动页面\n\n页面信息:\n get text|url|title <ref> 获取页面内容\n screenshot [path] 截图\n eval \"<js>\" 执行 JavaScript\n fetch <url> 带登录态的 HTTP 请求\n\n标签页:\n tab [list|new|close|<n>] 管理标签页\n\n导航:\n back / forward / refresh 后退 / 前进 / 刷新\n\n调试:\n network requests [filter] 查看网络请求\n console [--clear] 查看/清空控制台\n errors [--clear] 查看/清空 JS 错误\n trace start|stop|status 录制用户操作\n history search|domains 查看浏览历史\n\n选项:\n --json 以 JSON 格式输出\n --jq <expr> 对 JSON 输出应用 jq 过滤(直接作用于数据,跳过 id/success 信封)\n -i, --interactive 只输出可交互元素(snapshot 命令)\n -c, --compact 移除空结构节点(snapshot 命令)\n -d, --depth <n> 限制树深度(snapshot 命令)\n -s, --selector <sel> 限定 CSS 选择器范围(snapshot 命令)\n --tab <tabId> 指定操作的标签页 ID\n --mcp 启动 MCP server(用于 Claude Code / Cursor 等 AI 工具)\n --help, -h 显示帮助信息\n --version, -v 显示版本号\n`.trim();\n\ninterface ParsedArgs {\n command: string | null;\n args: string[];\n flags: {\n json: boolean;\n help: boolean;\n version: boolean;\n interactive: boolean;\n compact: boolean;\n depth?: number;\n selector?: string;\n tab?: string;\n days?: number;\n jq?: string;\n openclaw?: boolean;\n };\n}\n\n/**\n * 解析命令行参数\n */\nfunction parseArgs(argv: string[]): ParsedArgs {\n const args = argv.slice(2); // 跳过 node 和脚本路径\n\n const result: ParsedArgs = {\n command: null,\n args: [],\n flags: {\n json: false,\n help: false,\n version: false,\n interactive: false,\n compact: false,\n },\n };\n\n let skipNext = false;\n for (const arg of args) {\n if (skipNext) {\n skipNext = false;\n continue;\n }\n if (arg === \"--json\") {\n result.flags.json = true;\n } else if (arg === \"--jq\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.jq = args[nextIdx];\n result.flags.json = true;\n }\n } else if (arg === \"--openclaw\") {\n result.flags.openclaw = true;\n } else if (arg === \"--help\" || arg === \"-h\") {\n result.flags.help = true;\n } else if (arg === \"--version\" || arg === \"-v\") {\n result.flags.version = true;\n } else if (arg === \"--interactive\" || arg === \"-i\") {\n result.flags.interactive = true;\n } else if (arg === \"--compact\" || arg === \"-c\") {\n result.flags.compact = true;\n } else if (arg === \"--depth\" || arg === \"-d\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.depth = parseInt(args[nextIdx], 10);\n }\n } else if (arg === \"--selector\" || arg === \"-s\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.selector = args[nextIdx];\n }\n } else if (arg === \"--days\") {\n skipNext = true;\n const nextIdx = args.indexOf(arg) + 1;\n if (nextIdx < args.length) {\n result.flags.days = parseInt(args[nextIdx], 10);\n }\n } else if (arg === \"--id\") {\n // --id 及其值由子命令通过 process.argv 自行解析,这里跳过\n skipNext = true;\n } else if (arg === \"--tab\") {\n // --tab 参数及其值,无论出现在命令前后都跳过\n skipNext = true;\n } else if (arg.startsWith(\"-\")) {\n // 未知选项,忽略\n } else if (result.command === null) {\n result.command = arg;\n } else {\n result.args.push(arg);\n }\n }\n\n return result;\n}\n\n/**\n * 主函数\n */\nasync function main(): Promise<void> {\n const parsed = parseArgs(process.argv);\n setJqExpression(parsed.flags.jq);\n\n // 解析全局 --tab 参数\n const tabArgIdx = process.argv.indexOf('--tab');\n const globalTabId = tabArgIdx >= 0 && process.argv[tabArgIdx + 1]\n ? parseInt(process.argv[tabArgIdx + 1], 10)\n : undefined;\n\n // 处理全局选项\n if (parsed.flags.version) {\n console.log(VERSION);\n return;\n }\n\n if (process.argv.includes(\"--mcp\")) {\n const mcpPath = fileURLToPath(new URL(\"./mcp.js\", import.meta.url));\n const { spawn } = await import(\"node:child_process\");\n const child = spawn(process.execPath, [mcpPath], { stdio: \"inherit\" });\n child.on(\"exit\", (code) => process.exit(code ?? 0));\n return;\n }\n\n if (parsed.flags.help || !parsed.command) {\n console.log(HELP_TEXT);\n return;\n }\n\n // 路由到对应命令\n try {\n switch (parsed.command) {\n case \"open\": {\n const url = parsed.args[0];\n if (!url) {\n console.error(\"错误:缺少 URL 参数\");\n console.error(\"用法:bb-browser open <url> [--tab current|<tabId>]\");\n process.exit(1);\n }\n // 解析 --tab 参数\n const tabIndex = process.argv.findIndex(a => a === \"--tab\");\n const tab = tabIndex >= 0 ? process.argv[tabIndex + 1] : undefined;\n await openCommand(url, { json: parsed.flags.json, tab });\n break;\n }\n\n case \"snapshot\": {\n await snapshotCommand({\n json: parsed.flags.json,\n interactive: parsed.flags.interactive,\n compact: parsed.flags.compact,\n maxDepth: parsed.flags.depth,\n selector: parsed.flags.selector,\n tabId: globalTabId,\n });\n break;\n }\n\n case \"click\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser click <ref>\");\n console.error(\"示例:bb-browser click @5\");\n process.exit(1);\n }\n await clickCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"hover\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser hover <ref>\");\n console.error(\"示例:bb-browser hover @5\");\n process.exit(1);\n }\n await hoverCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"check\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser check <ref>\");\n console.error(\"示例:bb-browser check @5\");\n process.exit(1);\n }\n await checkCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"uncheck\": {\n const ref = parsed.args[0];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser uncheck <ref>\");\n console.error(\"示例:bb-browser uncheck @5\");\n process.exit(1);\n }\n await uncheckCommand(ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"fill\": {\n const ref = parsed.args[0];\n const text = parsed.args[1];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser fill <ref> <text>\");\n console.error('示例:bb-browser fill @3 \"hello world\"');\n process.exit(1);\n }\n if (text === undefined) {\n console.error(\"错误:缺少 text 参数\");\n console.error(\"用法:bb-browser fill <ref> <text>\");\n console.error('示例:bb-browser fill @3 \"hello world\"');\n process.exit(1);\n }\n await fillCommand(ref, text, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"type\": {\n const ref = parsed.args[0];\n const text = parsed.args[1];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser type <ref> <text>\");\n console.error('示例:bb-browser type @3 \"append text\"');\n process.exit(1);\n }\n if (text === undefined) {\n console.error(\"错误:缺少 text 参数\");\n console.error(\"用法:bb-browser type <ref> <text>\");\n console.error('示例:bb-browser type @3 \"append text\"');\n process.exit(1);\n }\n await typeCommand(ref, text, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"select\": {\n const ref = parsed.args[0];\n const value = parsed.args[1];\n if (!ref) {\n console.error(\"错误:缺少 ref 参数\");\n console.error(\"用法:bb-browser select <ref> <value>\");\n console.error('示例:bb-browser select @4 \"option1\"');\n process.exit(1);\n }\n if (value === undefined) {\n console.error(\"错误:缺少 value 参数\");\n console.error(\"用法:bb-browser select <ref> <value>\");\n console.error('示例:bb-browser select @4 \"option1\"');\n process.exit(1);\n }\n await selectCommand(ref, value, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"eval\": {\n const script = parsed.args[0];\n if (!script) {\n console.error(\"错误:缺少 script 参数\");\n console.error(\"用法:bb-browser eval <script>\");\n console.error('示例:bb-browser eval \"document.title\"');\n process.exit(1);\n }\n await evalCommand(script, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"get\": {\n const attribute = parsed.args[0] as GetAttribute | undefined;\n if (!attribute) {\n console.error(\"错误:缺少属性参数\");\n console.error(\"用法:bb-browser get <text|url|title> [ref]\");\n console.error(\"示例:bb-browser get text @5\");\n console.error(\" bb-browser get url\");\n process.exit(1);\n }\n if (![\"text\", \"url\", \"title\"].includes(attribute)) {\n console.error(`错误:未知属性 \"${attribute}\"`);\n console.error(\"支持的属性:text, url, title\");\n process.exit(1);\n }\n const ref = parsed.args[1];\n await getCommand(attribute, ref, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"daemon\":\n case \"start\": {\n const hostIdx = process.argv.findIndex(a => a === \"--host\");\n const host = hostIdx >= 0 ? process.argv[hostIdx + 1] : undefined;\n await daemonCommand({ json: parsed.flags.json, host });\n break;\n }\n\n case \"stop\": {\n await stopCommand({ json: parsed.flags.json });\n break;\n }\n\n case \"status\": {\n await statusCommand({ json: parsed.flags.json });\n break;\n }\n\n case \"reload\": {\n await reloadCommand({ json: parsed.flags.json });\n break;\n }\n\n case \"close\": {\n await closeCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"back\": {\n await backCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"forward\": {\n await forwardCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"refresh\": {\n await refreshCommand({ json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"screenshot\": {\n const outputPath = parsed.args[0];\n await screenshotCommand(outputPath, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"wait\": {\n const target = parsed.args[0];\n if (!target) {\n console.error(\"错误:缺少等待目标参数\");\n console.error(\"用法:bb-browser wait <ms|@ref>\");\n console.error(\"示例:bb-browser wait 2000\");\n console.error(\" bb-browser wait @5\");\n process.exit(1);\n }\n await waitCommand(target, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"press\": {\n const key = parsed.args[0];\n if (!key) {\n console.error(\"错误:缺少 key 参数\");\n console.error(\"用法:bb-browser press <key>\");\n console.error(\"示例:bb-browser press Enter\");\n console.error(\" bb-browser press Control+a\");\n process.exit(1);\n }\n await pressCommand(key, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"scroll\": {\n const direction = parsed.args[0];\n const pixels = parsed.args[1]; // 传 string,scrollCommand 内部解析\n if (!direction) {\n console.error(\"错误:缺少方向参数\");\n console.error(\"用法:bb-browser scroll <up|down|left|right> [pixels]\");\n console.error(\"示例:bb-browser scroll down\");\n console.error(\" bb-browser scroll up 500\");\n process.exit(1);\n }\n await scrollCommand(direction, pixels, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"tab\": {\n await tabCommand(parsed.args, { json: parsed.flags.json });\n break;\n }\n\n case \"frame\": {\n const selectorOrMain = parsed.args[0];\n if (!selectorOrMain) {\n console.error(\"错误:缺少 selector 参数\");\n console.error(\"用法:bb-browser frame <selector>\");\n console.error('示例:bb-browser frame \"iframe#editor\"');\n console.error(\" bb-browser frame main\");\n process.exit(1);\n }\n if (selectorOrMain === \"main\") {\n await frameMainCommand({ json: parsed.flags.json, tabId: globalTabId });\n } else {\n await frameCommand(selectorOrMain, { json: parsed.flags.json, tabId: globalTabId });\n }\n break;\n }\n\n case \"dialog\": {\n const subCommand = parsed.args[0];\n if (!subCommand) {\n console.error(\"错误:缺少子命令\");\n console.error(\"用法:bb-browser dialog <accept|dismiss> [text]\");\n console.error(\"示例:bb-browser dialog accept\");\n console.error(' bb-browser dialog accept \"my input\"');\n console.error(\" bb-browser dialog dismiss\");\n process.exit(1);\n }\n const promptText = parsed.args[1]; // accept 时可选的 prompt 文本\n await dialogCommand(subCommand, promptText, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"network\": {\n const subCommand = parsed.args[0] || \"requests\";\n const urlOrFilter = parsed.args[1];\n // 解析 network 特有的选项\n const abort = process.argv.includes(\"--abort\");\n const withBody = process.argv.includes(\"--with-body\");\n const bodyIndex = process.argv.findIndex(a => a === \"--body\");\n const body = bodyIndex >= 0 ? process.argv[bodyIndex + 1] : undefined;\n await networkCommand(subCommand, urlOrFilter, { json: parsed.flags.json, abort, body, withBody, tabId: globalTabId });\n break;\n }\n\n case \"console\": {\n const clear = process.argv.includes(\"--clear\");\n await consoleCommand({ json: parsed.flags.json, clear, tabId: globalTabId });\n break;\n }\n\n case \"errors\": {\n const clear = process.argv.includes(\"--clear\");\n await errorsCommand({ json: parsed.flags.json, clear, tabId: globalTabId });\n break;\n }\n\n case \"trace\": {\n const subCmd = parsed.args[0] as 'start' | 'stop' | 'status' | undefined;\n if (!subCmd || !['start', 'stop', 'status'].includes(subCmd)) {\n console.error(\"错误:缺少或无效的子命令\");\n console.error(\"用法:bb-browser trace <start|stop|status>\");\n console.error(\"示例:bb-browser trace start\");\n console.error(\" bb-browser trace stop\");\n console.error(\" bb-browser trace status\");\n process.exit(1);\n }\n await traceCommand(subCmd, { json: parsed.flags.json, tabId: globalTabId });\n break;\n }\n\n case \"history\": {\n const subCmd = parsed.args[0] as 'search' | 'domains' | undefined;\n if (!subCmd || !['search', 'domains'].includes(subCmd)) {\n console.error(\"错误:缺少或无效的子命令\");\n console.error(\"用法:bb-browser history <search|domains> [query] [--days <n>]\");\n console.error(\"示例:bb-browser history search github\");\n console.error(\" bb-browser history domains --days 7\");\n process.exit(1);\n }\n const query = parsed.args.slice(1).join(' ');\n await historyCommand(subCmd, {\n json: parsed.flags.json,\n days: parsed.flags.days || 30,\n query,\n });\n break;\n }\n\n case \"fetch\": {\n const fetchUrl = parsed.args[0];\n if (!fetchUrl) {\n console.error(\"[error] fetch: <url> is required.\");\n console.error(\" Usage: bb-browser fetch <url> [--json] [--method POST] [--body '{...}']\");\n console.error(\" Example: bb-browser fetch https://www.reddit.com/api/me.json --json\");\n process.exit(1);\n }\n // 解析 fetch 特有选项\n const methodIdx = process.argv.findIndex(a => a === \"--method\");\n const fetchMethod = methodIdx >= 0 ? process.argv[methodIdx + 1] : undefined;\n const fetchBodyIdx = process.argv.findIndex(a => a === \"--body\");\n const fetchBody = fetchBodyIdx >= 0 ? process.argv[fetchBodyIdx + 1] : undefined;\n const headersIdx = process.argv.findIndex(a => a === \"--headers\");\n const fetchHeaders = headersIdx >= 0 ? process.argv[headersIdx + 1] : undefined;\n const outputIdx = process.argv.findIndex(a => a === \"--output\");\n const fetchOutput = outputIdx >= 0 ? process.argv[outputIdx + 1] : undefined;\n await fetchCommand(fetchUrl, {\n json: parsed.flags.json,\n method: fetchMethod,\n body: fetchBody,\n headers: fetchHeaders,\n output: fetchOutput,\n tabId: globalTabId,\n });\n break;\n }\n\n case \"site\": {\n await siteCommand(parsed.args, {\n json: parsed.flags.json,\n jq: parsed.flags.jq,\n days: parsed.flags.days,\n tabId: globalTabId,\n openclaw: parsed.flags.openclaw,\n });\n break;\n }\n\n case \"star\": {\n const { execSync } = await import(\"node:child_process\");\n try {\n execSync(\"gh auth status\", { stdio: \"pipe\" });\n } catch {\n console.error(\"需要先安装并登录 GitHub CLI: https://cli.github.com\");\n console.error(\" brew install gh && gh auth login\");\n process.exit(1);\n }\n const repos = [\"epiral/bb-browser\", \"epiral/bb-sites\"];\n for (const repo of repos) {\n try {\n execSync(`gh api user/starred/${repo} -X PUT`, { stdio: \"pipe\" });\n console.log(`⭐ Starred ${repo}`);\n } catch {\n console.log(`Already starred or failed: ${repo}`);\n }\n }\n console.log(\"\\nThanks for your support! 🙏\");\n break;\n }\n\n case \"guide\": {\n console.log(`How to turn any website into a bb-browser site adapter\n=======================================================\n\n1. REVERSE ENGINEER the API\n bb-browser network clear --tab <tabId>\n bb-browser refresh --tab <tabId>\n bb-browser network requests --filter \"api\" --with-body --json --tab <tabId>\n\n2. TEST if direct fetch works (Tier 1)\n bb-browser eval \"fetch('/api/endpoint',{credentials:'include'}).then(r=>r.json())\" --tab <tabId>\n\n If it works → Tier 1 (Cookie auth, like Reddit/GitHub/Zhihu/Bilibili)\n If needs extra headers → Tier 2 (like Twitter: Bearer + CSRF token)\n If needs request signing → Tier 3 (like Xiaohongshu: Pinia store actions)\n\n3. WRITE the adapter (one JS file per operation)\n\n /* @meta\n {\n \"name\": \"platform/command\",\n \"description\": \"What it does\",\n \"domain\": \"www.example.com\",\n \"args\": { \"query\": {\"required\": true, \"description\": \"Search query\"} },\n \"readOnly\": true,\n \"example\": \"bb-browser site platform/command value\"\n }\n */\n async function(args) {\n if (!args.query) return {error: 'Missing argument: query'};\n const resp = await fetch('/api/search?q=' + encodeURIComponent(args.query), {credentials: 'include'});\n if (!resp.ok) return {error: 'HTTP ' + resp.status, hint: 'Not logged in?'};\n return await resp.json();\n }\n\n4. TEST it\n Save to ~/.bb-browser/sites/platform/command.js (private, takes priority)\n bb-browser site platform/command \"test query\" --json\n\n5. CONTRIBUTE\n Option A (with gh CLI):\n git clone https://github.com/epiral/bb-sites && cd bb-sites\n git checkout -b feat-platform\n # add adapter files\n git push -u origin feat-platform\n gh pr create --repo epiral/bb-sites\n\n Option B (without gh CLI, using bb-browser itself):\n bb-browser site github/fork epiral/bb-sites\n git clone https://github.com/YOUR_USER/bb-sites && cd bb-sites\n git checkout -b feat-platform\n # add adapter files\n git push -u origin feat-platform\n bb-browser site github/pr-create epiral/bb-sites --title \"feat(platform): add adapters\" --head \"YOUR_USER:feat-platform\"\n\nPrivate adapters: ~/.bb-browser/sites/<platform>/<command>.js\nCommunity: ~/.bb-browser/bb-sites/ (via bb-browser site update)\nFull guide: https://github.com/epiral/bb-sites/blob/main/SKILL.md`);\n break;\n }\n\n default: {\n console.error(`错误:未知命令 \"${parsed.command}\"`);\n console.error(\"运行 bb-browser --help 查看可用命令\");\n process.exit(1);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n if (parsed.flags.json) {\n console.log(\n JSON.stringify({\n success: false,\n error: message,\n })\n );\n } else {\n console.error(`错误:${message}`);\n }\n\n process.exit(1);\n }\n}\n\nmain();\n","/**\n * HTTP 客户端 - 与 Daemon 通信\n */\n\nimport type { Request, Response } from \"@bb-browser/shared\";\nimport { DAEMON_BASE_URL, COMMAND_TIMEOUT } from \"@bb-browser/shared\";\nimport { applyJq } from \"./jq.js\";\n\nlet jqExpression: string | undefined;\n\nexport function setJqExpression(expression?: string): void {\n jqExpression = expression;\n}\n\nfunction printJqResults(response: Response): never {\n const target = response.data ?? response;\n const results = applyJq(target, jqExpression || \".\");\n for (const result of results) {\n console.log(typeof result === \"string\" ? result : JSON.stringify(result));\n }\n process.exit(0);\n}\n\nexport function handleJqResponse(response: Response): void {\n if (jqExpression) {\n printJqResults(response);\n }\n}\n\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 const response = (await res.json()) as Response;\n\n return 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 * 检查 Chrome 扩展是否已连接\n */\nasync function isExtensionConnected(): 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 if (!response.ok) return false;\n const data = await response.json();\n return !!data.extensionConnected;\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 // 等待 Chrome 扩展连接(最多 10 秒)\n const extStart = Date.now();\n while (Date.now() - extStart < 10000) {\n if (await isExtensionConnected()) return;\n await new Promise((r) => setTimeout(r, POLL_INTERVAL));\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 * site 命令 - 管理和运行社区/私有网站适配器\n *\n * 用法:\n * bb-browser site list 列出所有可用 site adapter\n * bb-browser site search <query> 搜索\n * bb-browser site <name> [args...] 运行(简写)\n * bb-browser site run <name> [args...] 运行\n * bb-browser site update 更新社区 adapter 库\n *\n * 目录:\n * ~/.bb-browser/sites/ 私有 adapter(优先)\n * ~/.bb-browser/bb-sites/ 社区 adapter(bb-browser site update 拉取)\n */\n\nimport { generateId, type Request, type Response, type TabInfo } from \"@bb-browser/shared\";\nimport { handleJqResponse, sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\nimport { readFileSync, readdirSync, existsSync, mkdirSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { execSync } from \"node:child_process\";\n\nconst BB_DIR = join(homedir(), \".bb-browser\");\nconst LOCAL_SITES_DIR = join(BB_DIR, \"sites\");\nconst COMMUNITY_SITES_DIR = join(BB_DIR, \"bb-sites\");\nconst COMMUNITY_REPO = \"https://github.com/epiral/bb-sites.git\";\n\nfunction checkCliUpdate(): void {\n try {\n const current = execSync(\"bb-browser --version\", { timeout: 3000, stdio: [\"pipe\", \"pipe\", \"pipe\"] }).toString().trim();\n const latest = execSync(\"npm view bb-browser version\", { timeout: 5000, stdio: [\"pipe\", \"pipe\", \"pipe\"] }).toString().trim();\n if (latest && current && latest !== current && latest.localeCompare(current, undefined, { numeric: true }) > 0) {\n console.log(`\\n📦 bb-browser ${latest} available (current: ${current}). Run: npm install -g bb-browser`);\n }\n } catch {}\n}\n\nexport interface SiteOptions {\n json?: boolean;\n tabId?: number;\n days?: number;\n jq?: string;\n openclaw?: boolean;\n}\n\n/** Adapter 参数定义 */\ninterface ArgDef {\n required?: boolean;\n description?: string;\n}\n\n/** Adapter 元数据 */\ninterface SiteMeta {\n name: string;\n description: string;\n domain: string;\n args: Record<string, ArgDef>;\n capabilities?: string[];\n readOnly?: boolean;\n example?: string;\n filePath: string;\n source: \"local\" | \"community\";\n}\n\ninterface HistoryDomain {\n domain: string;\n visits: number;\n}\n\ninterface SiteRecommendation {\n domain: string;\n visits: number;\n adapterCount: number;\n adapters: Array<{\n name: string;\n description: string;\n example: string;\n }>;\n}\n\n/**\n * 从 JS 文件的 /* @meta JSON * / 块解析元数据\n */\nfunction parseSiteMeta(filePath: string, source: \"local\" | \"community\"): SiteMeta | null {\n let content: string;\n try {\n content = readFileSync(filePath, \"utf-8\");\n } catch {\n return null;\n }\n\n // 从文件路径推断默认 name\n const sitesDir = source === \"local\" ? LOCAL_SITES_DIR : COMMUNITY_SITES_DIR;\n const relPath = relative(sitesDir, filePath);\n const defaultName = relPath.replace(/\\.js$/, \"\").replace(/\\\\/g, \"/\");\n\n // 解析 /* @meta { ... } */ 块\n const metaMatch = content.match(/\\/\\*\\s*@meta\\s*\\n([\\s\\S]*?)\\*\\//);\n if (metaMatch) {\n try {\n const metaJson = JSON.parse(metaMatch[1]);\n return {\n name: metaJson.name || defaultName,\n description: metaJson.description || \"\",\n domain: metaJson.domain || \"\",\n args: metaJson.args || {},\n capabilities: metaJson.capabilities,\n readOnly: metaJson.readOnly,\n example: metaJson.example,\n filePath,\n source,\n };\n } catch {\n // JSON 解析失败,回退到 @tag 模式\n }\n }\n\n // 回退:解析 // @tag 格式(兼容旧格式)\n const meta: SiteMeta = {\n name: defaultName,\n description: \"\",\n domain: \"\",\n args: {},\n filePath,\n source,\n };\n\n const tagPattern = /\\/\\/\\s*@(\\w+)[ \\t]+(.*)/g;\n let match;\n while ((match = tagPattern.exec(content)) !== null) {\n const [, key, value] = match;\n switch (key) {\n case \"name\": meta.name = value.trim(); break;\n case \"description\": meta.description = value.trim(); break;\n case \"domain\": meta.domain = value.trim(); break;\n case \"args\":\n for (const arg of value.trim().split(/[,\\s]+/).filter(Boolean)) {\n meta.args[arg] = { required: true };\n }\n break;\n case \"example\": meta.example = value.trim(); break;\n }\n }\n\n return meta;\n}\n\n/**\n * 扫描目录下所有 .js 文件\n */\nfunction scanSites(dir: string, source: \"local\" | \"community\"): SiteMeta[] {\n if (!existsSync(dir)) return [];\n const sites: SiteMeta[] = [];\n\n function walk(currentDir: string): void {\n let entries;\n try { entries = readdirSync(currentDir, { withFileTypes: true }); } catch { return; }\n for (const entry of entries) {\n const fullPath = join(currentDir, entry.name);\n if (entry.isDirectory() && !entry.name.startsWith(\".\")) {\n walk(fullPath);\n } else if (entry.isFile() && entry.name.endsWith(\".js\")) {\n const meta = parseSiteMeta(fullPath, source);\n if (meta) sites.push(meta);\n }\n }\n }\n\n walk(dir);\n return sites;\n}\n\n/**\n * 根据 URL 检查是否有对应的 site adapter,返回提示文本\n */\nexport function getSiteHintForDomain(url: string): string | null {\n try {\n const hostname = new URL(url).hostname;\n const sites = getAllSites();\n const matched = sites.filter(s => s.domain && (hostname === s.domain || hostname.endsWith(\".\" + s.domain)));\n if (matched.length === 0) return null;\n const names = matched.map(s => s.name);\n const example = matched[0].example || `bb-browser site ${names[0]}`;\n return `该网站有 ${names.length} 个 site adapter 可直接获取数据,无需手动操作浏览器。试试: ${example}`;\n } catch {\n return null;\n }\n}\n\n/**\n * 获取所有 adapter(私有优先)\n */\nfunction getAllSites(): SiteMeta[] {\n const community = scanSites(COMMUNITY_SITES_DIR, \"community\");\n const local = scanSites(LOCAL_SITES_DIR, \"local\");\n\n const byName = new Map<string, SiteMeta>();\n for (const s of community) byName.set(s.name, s);\n for (const s of local) byName.set(s.name, s);\n\n return Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * 精确匹配 tab 的 origin\n */\nfunction matchTabOrigin(tabUrl: string, domain: string): boolean {\n try {\n const tabOrigin = new URL(tabUrl).hostname;\n return tabOrigin === domain || tabOrigin.endsWith(\".\" + domain);\n } catch {\n return false;\n }\n}\n\n// ── 子命令 ──────────────────────────────────────────────────────\n\nfunction siteList(options: SiteOptions): void {\n const sites = getAllSites();\n\n if (sites.length === 0) {\n console.log(\"未找到任何 site adapter。\");\n console.log(\" 安装社区 adapter: bb-browser site update\");\n console.log(` 私有 adapter 目录: ${LOCAL_SITES_DIR}`);\n return;\n }\n\n if (options.json) {\n console.log(JSON.stringify(sites.map(s => ({\n name: s.name, description: s.description, domain: s.domain,\n args: s.args, source: s.source,\n })), null, 2));\n return;\n }\n\n const groups = new Map<string, SiteMeta[]>();\n for (const s of sites) {\n const platform = s.name.split(\"/\")[0];\n if (!groups.has(platform)) groups.set(platform, []);\n groups.get(platform)!.push(s);\n }\n\n for (const [platform, items] of groups) {\n console.log(`\\n${platform}/`);\n for (const s of items) {\n const cmd = s.name.split(\"/\").slice(1).join(\"/\");\n const src = s.source === \"local\" ? \" (local)\" : \"\";\n const desc = s.description ? ` - ${s.description}` : \"\";\n console.log(` ${cmd.padEnd(20)}${desc}${src}`);\n }\n }\n console.log();\n}\n\nfunction siteSearch(query: string, options: SiteOptions): void {\n const sites = getAllSites();\n const q = query.toLowerCase();\n const matches = sites.filter(s =>\n s.name.toLowerCase().includes(q) ||\n s.description.toLowerCase().includes(q) ||\n s.domain.toLowerCase().includes(q)\n );\n\n if (matches.length === 0) {\n console.log(`未找到匹配 \"${query}\" 的 adapter。`);\n console.log(\" 查看所有: bb-browser site list\");\n return;\n }\n\n if (options.json) {\n console.log(JSON.stringify(matches.map(s => ({\n name: s.name, description: s.description, domain: s.domain, source: s.source,\n })), null, 2));\n return;\n }\n\n for (const s of matches) {\n const src = s.source === \"local\" ? \" (local)\" : \"\";\n console.log(`${s.name.padEnd(24)} ${s.description}${src}`);\n }\n}\n\nfunction siteUpdate(): void {\n mkdirSync(BB_DIR, { recursive: true });\n\n if (existsSync(join(COMMUNITY_SITES_DIR, \".git\"))) {\n console.log(\"更新社区 site adapter 库...\");\n try {\n execSync(\"git pull --ff-only\", { cwd: COMMUNITY_SITES_DIR, stdio: \"pipe\" });\n console.log(\"更新完成。\");\n console.log(\"\");\n console.log(\"💡 运行 bb-browser site recommend 看看哪些和你的浏览习惯匹配\");\n } catch (e) {\n console.error(`更新失败: ${e instanceof Error ? e.message : e}`);\n console.error(\" 手动修复: cd ~/.bb-browser/bb-sites && git pull\");\n process.exit(1);\n }\n } else {\n console.log(`克隆社区 adapter 库: ${COMMUNITY_REPO}`);\n try {\n execSync(`git clone ${COMMUNITY_REPO} ${COMMUNITY_SITES_DIR}`, { stdio: \"pipe\" });\n console.log(\"克隆完成。\");\n console.log(\"\");\n console.log(\"💡 运行 bb-browser site recommend 看看哪些和你的浏览习惯匹配\");\n } catch (e) {\n console.error(`克隆失败: ${e instanceof Error ? e.message : e}`);\n console.error(` 手动修复: git clone ${COMMUNITY_REPO} ~/.bb-browser/bb-sites`);\n process.exit(1);\n }\n }\n\n const sites = scanSites(COMMUNITY_SITES_DIR, \"community\");\n console.log(`已安装 ${sites.length} 个社区 adapter。`);\n console.log(`⭐ Like bb-browser? → bb-browser star`);\n\n // Check for CLI updates\n checkCliUpdate();\n}\n\nfunction findSiteByName(name: string): SiteMeta | undefined {\n return getAllSites().find((site) => site.name === name);\n}\n\nfunction siteInfo(name: string, options: SiteOptions): void {\n const site = findSiteByName(name);\n\n if (!site) {\n console.error(`[error] site info: adapter \"${name}\" not found.`);\n console.error(\" Try: bb-browser site list\");\n process.exit(1);\n }\n\n const meta = {\n name: site.name,\n description: site.description,\n domain: site.domain,\n args: site.args,\n example: site.example,\n readOnly: site.readOnly,\n };\n\n if (options.json) {\n console.log(JSON.stringify(meta, null, 2));\n return;\n }\n\n console.log(`${site.name} — ${site.description}`);\n console.log();\n console.log(\"参数:\");\n\n const argEntries = Object.entries(site.args);\n if (argEntries.length === 0) {\n console.log(\" (无)\");\n } else {\n for (const [argName, argDef] of argEntries) {\n const requiredText = argDef.required ? \"必填\" : \"可选\";\n const description = argDef.description || \"\";\n console.log(` ${argName} (${requiredText}) ${description}`.trimEnd());\n }\n }\n\n console.log();\n console.log(\"示例:\");\n console.log(` ${site.example || `bb-browser site ${site.name}`}`);\n console.log();\n console.log(`域名:${site.domain || \"(未声明)\"}`);\n console.log(`只读:${site.readOnly ? \"是\" : \"否\"}`);\n}\n\nasync function siteRecommend(options: SiteOptions): Promise<void> {\n const days = options.days ?? 30;\n const response = await sendCommand({\n id: generateId(),\n action: \"history\",\n historyCommand: \"domains\",\n ms: days,\n });\n\n if (!response.success) {\n throw new Error(response.error || \"History command failed\");\n }\n\n const historyDomains: HistoryDomain[] = response.data?.historyDomains || [];\n const sites = getAllSites();\n const sitesByDomain = new Map<string, SiteMeta[]>();\n\n for (const site of sites) {\n if (!site.domain) continue;\n const domain = site.domain.toLowerCase();\n const existing = sitesByDomain.get(domain) || [];\n existing.push(site);\n sitesByDomain.set(domain, existing);\n }\n\n const available: SiteRecommendation[] = [];\n const notAvailable: HistoryDomain[] = [];\n\n for (const item of historyDomains) {\n const adapters = sitesByDomain.get(item.domain.toLowerCase());\n if (adapters && adapters.length > 0) {\n const sortedAdapters = [...adapters].sort((a, b) => a.name.localeCompare(b.name));\n available.push({\n domain: item.domain,\n visits: item.visits,\n adapterCount: sortedAdapters.length,\n adapters: sortedAdapters.map((site) => ({\n name: site.name,\n description: site.description,\n example: site.example || `bb-browser site ${site.name}`,\n })),\n });\n } else if (item.visits >= 5 && item.domain && !item.domain.includes('localhost') && item.domain.includes('.')) {\n notAvailable.push(item);\n }\n }\n\n const jsonData = {\n days,\n available,\n not_available: notAvailable,\n };\n\n if (options.jq) {\n handleJqResponse({ id: generateId(), success: true, data: jsonData });\n }\n\n if (options.json) {\n console.log(JSON.stringify(jsonData, null, 2));\n return;\n }\n\n console.log(`基于你最近 ${days} 天的浏览记录:`);\n console.log();\n\n console.log(\"🎯 你常用这些网站,可以直接用:\");\n console.log();\n if (available.length === 0) {\n console.log(\" (暂无匹配的 adapter)\");\n } else {\n for (const item of available) {\n console.log(` ${item.domain.padEnd(20)} ${item.visits} 次访问 ${item.adapterCount} 个命令`);\n console.log(` 试试: ${item.adapters[0]?.example || `bb-browser site ${item.adapters[0]?.name || \"\"}`}`);\n console.log();\n }\n }\n\n console.log(\"📋 你常用但还没有 adapter:\");\n console.log();\n if (notAvailable.length === 0) {\n console.log(\" (暂无)\");\n } else {\n for (const item of notAvailable) {\n console.log(` ${item.domain.padEnd(20)} ${item.visits} 次访问`);\n }\n }\n\n console.log();\n console.log('💡 跟你的 AI Agent 说 \"把 notion.so CLI 化\",它就能自动完成。');\n console.log();\n console.log(`所有分析纯本地完成。用 --days 7 只看最近一周。`);\n}\n\nasync function siteRun(\n name: string,\n args: string[],\n options: SiteOptions\n): Promise<void> {\n const sites = getAllSites();\n const site = sites.find(s => s.name === name);\n\n if (!site) {\n const fuzzy = sites.filter(s => s.name.includes(name));\n console.error(`[error] site: \"${name}\" not found.`);\n if (fuzzy.length > 0) {\n console.error(\" Did you mean:\");\n for (const s of fuzzy.slice(0, 5)) {\n console.error(` bb-browser site ${s.name}`);\n }\n } else {\n console.error(\" Try: bb-browser site list\");\n console.error(\" Or: bb-browser site update\");\n }\n process.exit(1);\n }\n\n // 解析参数\n const argNames = Object.keys(site.args);\n const argMap: Record<string, string> = {};\n\n // 过滤掉 --flag value 对,收集位置参数\n const positionalArgs: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i].startsWith(\"--\")) {\n const flagName = args[i].slice(2);\n if (flagName in site.args && args[i + 1]) {\n argMap[flagName] = args[i + 1];\n i++; // 跳过值\n }\n } else {\n positionalArgs.push(args[i]);\n }\n }\n\n // 位置参数按 argNames 顺序填入(跳过已通过 --flag 提供的)\n let posIdx = 0;\n for (const argName of argNames) {\n if (!argMap[argName] && posIdx < positionalArgs.length) {\n argMap[argName] = positionalArgs[posIdx++];\n }\n }\n\n // 只检查 required 参数\n for (const [argName, argDef] of Object.entries(site.args)) {\n if (argDef.required && !argMap[argName]) {\n console.error(`[error] site ${name}: missing required argument \"${argName}\".`);\n const usage = argNames.map(a => {\n const def = site.args[a];\n return def.required ? `<${a}>` : `[${a}]`;\n }).join(\" \");\n console.error(` Usage: bb-browser site ${name} ${usage}`);\n if (site.example) console.error(` Example: ${site.example}`);\n process.exit(1);\n }\n }\n\n // 读取并解析 JS\n const jsContent = readFileSync(site.filePath, \"utf-8\");\n\n // 移除 /* @meta ... */ 块,保留函数体\n const jsBody = jsContent.replace(/\\/\\*\\s*@meta[\\s\\S]*?\\*\\//, \"\").trim();\n\n // 构造执行脚本\n const argsJson = JSON.stringify(argMap);\n const script = `(${jsBody})(${argsJson})`;\n\n if (options.openclaw) {\n const { ocGetTabs, ocFindTabByDomain, ocOpenTab, ocEvaluate } = await import(\"../openclaw-bridge.js\");\n\n let targetId: string;\n\n if (site.domain) {\n const tabs = ocGetTabs();\n const existing = ocFindTabByDomain(tabs, site.domain);\n if (existing) {\n targetId = existing.targetId;\n } else {\n targetId = ocOpenTab(`https://${site.domain}`);\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n } else {\n const tabs = ocGetTabs();\n if (tabs.length === 0) {\n throw new Error(\"No tabs open in OpenClaw browser\");\n }\n targetId = tabs[0].targetId;\n }\n\n const wrappedFn = `async () => { const __fn = ${jsBody}; return await __fn(${argsJson}); }`;\n const parsed = ocEvaluate(targetId, wrappedFn);\n\n if (typeof parsed === \"object\" && parsed !== null && \"error\" in parsed) {\n const errObj = parsed as { error: string; hint?: string };\n const checkText = `${errObj.error} ${errObj.hint || \"\"}`;\n const isAuthError = /401|403|unauthorized|forbidden|not.?logged|login.?required|sign.?in|auth/i.test(checkText);\n const loginHint = isAuthError && site.domain\n ? `Please log in to https://${site.domain} in your OpenClaw browser first, then retry.`\n : undefined;\n const hint = loginHint || errObj.hint;\n const reportHint = `If this is an adapter bug, report via: gh issue create --repo epiral/bb-sites --title \"[${name}] <description>\" OR: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] <description>\"`;\n\n if (options.json) {\n console.log(JSON.stringify({ id: \"openclaw\", success: false, error: errObj.error, hint, reportHint }));\n } else {\n console.error(`[error] site ${name}: ${errObj.error}`);\n if (hint) console.error(` Hint: ${hint}`);\n console.error(` Report: gh issue create --repo epiral/bb-sites --title \"[${name}] ...\"`);\n console.error(` or: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] ...\"`);\n }\n process.exit(1);\n }\n\n if (options.jq) {\n const { applyJq } = await import(\"../jq.js\");\n const expr = options.jq.replace(/^\\.data\\./, '.');\n const results = applyJq(parsed, expr);\n for (const r of results) {\n console.log(typeof r === \"string\" ? r : JSON.stringify(r));\n }\n } else if (options.json) {\n console.log(JSON.stringify({ id: \"openclaw\", success: true, data: parsed }));\n } else {\n console.log(JSON.stringify(parsed, null, 2));\n }\n return;\n }\n\n await ensureDaemonRunning();\n\n // 确定目标 tab\n let targetTabId: number | undefined = options.tabId;\n\n // 如果用户没指定 --tab,自动查找匹配域名的 tab\n if (!targetTabId && site.domain) {\n const listReq: Request = { id: generateId(), action: \"tab_list\" };\n const listResp: Response = await sendCommand(listReq);\n\n if (listResp.success && listResp.data?.tabs) {\n const matchingTab = listResp.data.tabs.find((tab: TabInfo) =>\n matchTabOrigin(tab.url, site.domain)\n );\n if (matchingTab) {\n targetTabId = matchingTab.tabId;\n }\n }\n\n if (!targetTabId) {\n const newResp = await sendCommand({\n id: generateId(),\n action: \"tab_new\",\n url: `https://${site.domain}`,\n });\n targetTabId = newResp.data?.tabId;\n await new Promise((resolve) => setTimeout(resolve, 3000));\n }\n }\n\n // 执行\n const evalReq: Request = { id: generateId(), action: \"eval\", script, tabId: targetTabId };\n const evalResp: Response = await sendCommand(evalReq);\n\n if (!evalResp.success) {\n const hint = site.domain\n ? `Open https://${site.domain} in your browser, make sure you are logged in, then retry.`\n : undefined;\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: false, error: evalResp.error || \"eval failed\", hint }));\n } else {\n console.error(`[error] site ${name}: ${evalResp.error || \"eval failed\"}`);\n if (hint) console.error(` Hint: ${hint}`);\n }\n process.exit(1);\n }\n\n const result = evalResp.data?.result;\n if (result === undefined || result === null) {\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: true, data: null }));\n } else {\n console.log(\"(no output)\");\n }\n return;\n }\n\n // 解析输出\n let parsed: unknown;\n try {\n parsed = typeof result === \"string\" ? JSON.parse(result) : result;\n } catch {\n parsed = result;\n }\n\n // 检查 adapter 返回的 error\n if (typeof parsed === \"object\" && parsed !== null && \"error\" in parsed) {\n const errObj = parsed as { error: string; hint?: string };\n\n // 检测是否为登录问题(检查 error 和 hint 文本)\n const checkText = `${errObj.error} ${errObj.hint || \"\"}`;\n const isAuthError = /401|403|unauthorized|forbidden|not.?logged|login.?required|sign.?in|auth/i.test(checkText);\n const loginHint = isAuthError && site.domain\n ? `Please log in to https://${site.domain} in your browser first, then retry.`\n : undefined;\n const hint = loginHint || errObj.hint;\n const reportHint = `If this is an adapter bug, report via: gh issue create --repo epiral/bb-sites --title \"[${name}] <description>\" OR: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] <description>\"`;\n\n if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: false, error: errObj.error, hint, reportHint }));\n } else {\n console.error(`[error] site ${name}: ${errObj.error}`);\n if (hint) console.error(` Hint: ${hint}`);\n console.error(` Report: gh issue create --repo epiral/bb-sites --title \"[${name}] ...\"`);\n console.error(` or: bb-browser site github/issue-create epiral/bb-sites --title \"[${name}] ...\"`);\n }\n process.exit(1);\n }\n\n if (options.jq) {\n const { applyJq } = await import(\"../jq.js\");\n // Tolerate \".data.\" prefix — Agent may copy from --json envelope structure\n const expr = options.jq.replace(/^\\.data\\./, '.');\n const results = applyJq(parsed, expr);\n for (const r of results) {\n console.log(typeof r === \"string\" ? r : JSON.stringify(r));\n }\n } else if (options.json) {\n console.log(JSON.stringify({ id: evalReq.id, success: true, data: parsed }));\n } else {\n console.log(JSON.stringify(parsed, null, 2));\n }\n}\n\n// ── 入口 ────────────────────────────────────────────────────────\n\nexport async function siteCommand(\n args: string[],\n options: SiteOptions = {}\n): Promise<void> {\n const subCommand = args[0];\n\n if (!subCommand || subCommand === \"--help\" || subCommand === \"-h\") {\n console.log(`bb-browser site - 网站 CLI 化(管理和运行 site adapter)\n\n用法:\n bb-browser site list 列出所有可用 adapter\n bb-browser site info <name> 查看 adapter 元信息\n bb-browser site recommend 基于历史记录推荐 adapter\n bb-browser site search <query> 搜索 adapter\n bb-browser site <name> [args...] 运行 adapter(简写)\n bb-browser site run <name> [args...] 运行 adapter\n bb-browser site update 更新社区 adapter 库 (git clone/pull)\n\n目录:\n ${LOCAL_SITES_DIR} 私有 adapter(优先)\n ${COMMUNITY_SITES_DIR} 社区 adapter\n\n示例:\n bb-browser site update\n bb-browser site list\n bb-browser site reddit/thread https://www.reddit.com/r/LocalLLaMA/comments/...\n bb-browser site twitter/user yan5xu\n bb-browser site search reddit\n\n创建新 adapter: bb-browser guide\n报告问题: gh issue create --repo epiral/bb-sites --title \"[adapter-name] 描述\"\n贡献社区: https://github.com/epiral/bb-sites`);\n return;\n }\n\n switch (subCommand) {\n case \"list\": siteList(options); break;\n case \"search\":\n if (!args[1]) {\n console.error(\"[error] site search: <query> is required.\");\n console.error(\" Usage: bb-browser site search <query>\");\n process.exit(1);\n }\n siteSearch(args[1], options);\n break;\n case \"info\":\n if (!args[1]) {\n console.error(\"[error] site info: <name> is required.\");\n console.error(\" Usage: bb-browser site info <name>\");\n process.exit(1);\n }\n siteInfo(args[1], options);\n break;\n case \"recommend\":\n await siteRecommend(options);\n break;\n case \"update\": siteUpdate(); break;\n case \"run\":\n if (!args[1]) {\n console.error(\"[error] site run: <name> is required.\");\n console.error(\" Usage: bb-browser site run <name> [args...]\");\n console.error(\" Try: bb-browser site list\");\n process.exit(1);\n }\n await siteRun(args[1], args.slice(2), options);\n break;\n default:\n if (subCommand.includes(\"/\")) {\n await siteRun(subCommand, args.slice(1), options);\n } else {\n console.error(`[error] site: unknown subcommand \"${subCommand}\".`);\n console.error(\" Available: list, info, recommend, search, run, update\");\n console.error(\" Try: bb-browser site --help\");\n process.exit(1);\n }\n break;\n }\n\n // 静默后台更新社区 adapter\n silentUpdate();\n}\n\nfunction silentUpdate(): void {\n const gitDir = join(COMMUNITY_SITES_DIR, \".git\");\n if (!existsSync(gitDir)) return;\n import(\"node:child_process\").then(({ spawn }) => {\n const child = spawn(\"git\", [\"pull\", \"--ff-only\"], {\n cwd: COMMUNITY_SITES_DIR,\n stdio: \"ignore\",\n detached: true,\n });\n child.unref();\n }).catch(() => {});\n}\n","/**\n * open 命令 - 打开指定 URL\n * \n * 用法:\n * bb-browser open <url> # 在新 tab 中打开\n * bb-browser open <url> --tab current # 在当前 tab 中打开\n * bb-browser open <url> --tab 123 # 在指定 tabId 的 tab 中打开\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\nimport { getSiteHintForDomain } from \"./site.js\";\n\nexport interface OpenOptions {\n json?: boolean;\n tab?: string; // \"current\" | tabId 数字字符串 | undefined(新建 tab)\n}\n\nexport async function openCommand(\n url: string,\n options: OpenOptions = {}\n): Promise<void> {\n // 验证 URL\n if (!url) {\n throw new Error(\"缺少 URL 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 补全 URL 协议\n let normalizedUrl = url;\n if (!url.startsWith(\"http://\") && !url.startsWith(\"https://\")) {\n normalizedUrl = \"https://\" + url;\n }\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"open\",\n url: normalizedUrl,\n };\n\n // 处理 --tab 参数\n if (options.tab !== undefined) {\n if (options.tab === \"current\") {\n // 使用当前活动 tab\n (request as Record<string, unknown>).tabId = \"current\";\n } else {\n // 使用指定 tabId\n const tabId = parseInt(options.tab, 10);\n if (isNaN(tabId)) {\n throw new Error(`无效的 tabId: ${options.tab}`);\n }\n (request as Record<string, unknown>).tabId = tabId;\n }\n }\n // 不指定 --tab 时,tabId 为 undefined,扩展会创建新 tab\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`已打开: ${response.data?.url ?? normalizedUrl}`);\n if (response.data?.title) {\n console.log(`标题: ${response.data.title}`);\n }\n if (response.data?.tabId) {\n console.log(`Tab ID: ${response.data.tabId}`);\n }\n // 提示:如果该域名有 site adapter,引导使用\n const siteHint = getSiteHintForDomain(normalizedUrl);\n if (siteHint) {\n console.log(`\\n💡 ${siteHint}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * snapshot 命令 - 获取当前页面快照\n * 用法:bb-browser snapshot [-i|--interactive] [-c|--compact] [-d|--depth N] [-s|--selector SEL]\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface SnapshotOptions {\n json?: boolean;\n /** 只输出可交互元素 */\n interactive?: boolean;\n /** 移除空结构节点 */\n compact?: boolean;\n /** 限制树深度 */\n maxDepth?: number;\n /** CSS 选择器范围 */\n selector?: string;\n tabId?: number;\n}\n\nexport async function snapshotCommand(\n options: SnapshotOptions = {}\n): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"snapshot\",\n interactive: options.interactive,\n compact: options.compact,\n maxDepth: options.maxDepth,\n selector: options.selector,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`标题: ${response.data?.title ?? \"(无标题)\"}`);\n console.log(`URL: ${response.data?.url ?? \"(未知)\"}`);\n // 输出 snapshot 文本\n if (response.data?.snapshotData?.snapshot) {\n console.log(\"\");\n console.log(response.data.snapshotData.snapshot);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * click 命令 - 点击元素\n * 用法:bb-browser click <ref>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ClickOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function clickCommand(\n ref: string,\n options: ClickOptions = {}\n): Promise<void> {\n // 验证 ref\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"click\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已点击: ${role} \"${name}\"`);\n } else {\n console.log(`已点击: ${role}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * hover 命令 - 悬停在元素上\n * 用法:bb-browser hover <ref>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface HoverOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function hoverCommand(\n ref: string,\n options: HoverOptions = {}\n): Promise<void> {\n // 验证 ref\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"hover\",\n ref: parsedRef,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已悬停: ${role} \"${name}\"`);\n } else {\n console.log(`已悬停: ${role}`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * fill 命令 - 填充输入框\n * 用法:bb-browser fill <ref> <text>\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface FillOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function fillCommand(\n ref: string,\n text: string,\n options: FillOptions = {}\n): Promise<void> {\n // 验证参数\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n if (text === undefined || text === null) {\n throw new Error(\"缺少 text 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"fill\",\n ref: parsedRef,\n text: text,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已填充: ${role} \"${name}\"`);\n } else {\n console.log(`已填充: ${role}`);\n }\n console.log(`内容: \"${text}\"`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * type 命令 - 在元素中逐字符输入文本(不清空原有内容)\n * 用法:bb-browser type <ref> <text>\n * \n * 与 fill 命令的区别:\n * - fill:先清空再填入\n * - type:不清空,逐字符追加输入\n * \n * ref 支持格式:\n * - \"@5\" 或 \"5\":使用 snapshot 返回的 ref ID\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface TypeOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n // 移除 @ 前缀(如果有)\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function typeCommand(\n ref: string,\n text: string,\n options: TypeOptions = {}\n): Promise<void> {\n // 验证参数\n if (!ref) {\n throw new Error(\"缺少 ref 参数\");\n }\n\n if (text === undefined || text === null) {\n throw new Error(\"缺少 text 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析 ref\n const parsedRef = parseRef(ref);\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"type\",\n ref: parsedRef,\n text: text,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const role = response.data?.role ?? \"element\";\n const name = response.data?.name;\n if (name) {\n console.log(`已输入: ${role} \"${name}\"`);\n } else {\n console.log(`已输入: ${role}`);\n }\n console.log(`内容: \"${text}\"`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * close 命令 - 关闭当前标签页\n * 用法:bb-browser close\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface CloseOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport async function closeCommand(options: CloseOptions = {}): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"close\",\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const title = response.data?.title ?? \"\";\n if (title) {\n console.log(`已关闭: \"${title}\"`);\n } else {\n console.log(\"已关闭当前标签页\");\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * get 命令 - 获取页面或元素信息\n * 用法:\n * bb-browser get text <ref> 获取元素文本\n * bb-browser get url 获取当前页面 URL\n * bb-browser get title 获取页面标题\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface GetOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/** 支持的 get 属性类型 */\nexport type GetAttribute = \"text\" | \"url\" | \"title\";\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function getCommand(\n attribute: GetAttribute,\n ref: string | undefined,\n options: GetOptions = {}\n): Promise<void> {\n // 验证参数\n if (attribute === \"text\" && !ref) {\n throw new Error(\"get text 需要 ref 参数,如: get text @5\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"get\",\n attribute,\n ref: ref ? parseRef(ref) : undefined,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const value = response.data?.value ?? \"\";\n console.log(value);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * screenshot 命令 - 截取当前页面\n * 用法:\n * bb-browser screenshot # 保存到临时目录\n * bb-browser screenshot ./page.png # 保存到指定路径\n * bb-browser screenshot --json # 返回 { path, base64 }\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport os from \"os\";\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ScreenshotOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 生成默认截图路径\n */\nfunction getDefaultPath(): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const filename = `bb-screenshot-${timestamp}.png`;\n return path.join(os.tmpdir(), filename);\n}\n\n/**\n * 解码 data URL 并保存为文件\n */\nfunction saveBase64Image(dataUrl: string, filePath: string): void {\n const base64Data = dataUrl.replace(/^data:image\\/png;base64,/, \"\");\n const buffer = Buffer.from(base64Data, \"base64\");\n \n // 确保目录存在\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n \n fs.writeFileSync(filePath, buffer);\n}\n\nexport async function screenshotCommand(\n outputPath?: string,\n options: ScreenshotOptions = {}\n): Promise<void> {\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 确定保存路径\n const filePath = outputPath ? path.resolve(outputPath) : getDefaultPath();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"screenshot\",\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 处理结果\n if (response.success && response.data?.dataUrl) {\n const dataUrl = response.data.dataUrl as string;\n \n // 保存文件\n saveBase64Image(dataUrl, filePath);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify({\n success: true,\n path: filePath,\n base64: dataUrl,\n }, null, 2));\n } else {\n console.log(`截图已保存: ${filePath}`);\n }\n } else {\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n console.error(`错误: ${response.error}`);\n }\n process.exit(1);\n }\n}\n","/**\n * wait 命令 - 等待指定时间或元素出现\n * 用法:\n * bb-browser wait <ms> 等待指定毫秒数\n * bb-browser wait @<ref> 等待元素出现(最多 10 秒)\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface WaitOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 判断是否是等待时间(纯数字)\n */\nfunction isTimeWait(target: string): boolean {\n return /^\\d+$/.test(target);\n}\n\n/**\n * 解析 ref 参数,支持 \"@5\" 或 \"5\" 格式\n */\nfunction parseRef(ref: string): string {\n return ref.startsWith(\"@\") ? ref.slice(1) : ref;\n}\n\nexport async function waitCommand(\n target: string,\n options: WaitOptions = {}\n): Promise<void> {\n if (!target) {\n throw new Error(\"缺少等待目标参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n let request: Request;\n\n if (isTimeWait(target)) {\n // 等待时间模式\n const ms = parseInt(target, 10);\n request = {\n id: generateId(),\n action: \"wait\",\n waitType: \"time\",\n ms,\n tabId: options.tabId,\n };\n } else {\n // 等待元素模式\n const ref = parseRef(target);\n request = {\n id: generateId(),\n action: \"wait\",\n waitType: \"element\",\n ref,\n tabId: options.tabId,\n };\n }\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n if (isTimeWait(target)) {\n console.log(`已等待 ${target}ms`);\n } else {\n console.log(`元素 @${parseRef(target)} 已出现`);\n }\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * press 命令 - 发送键盘按键\n * 用法:bb-browser press <key>\n *\n * key 支持格式:\n * - 单键:\"Enter\", \"Tab\", \"Escape\", \"Backspace\", \"ArrowUp\" 等\n * - 组合键:\"Control+a\", \"Control+c\", \"Control+v\"(用 + 分隔)\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface PressOptions {\n json?: boolean;\n tabId?: number;\n}\n\n/**\n * 解析按键字符串,提取修饰键和主键\n * 例如:\n * \"Enter\" -> { key: \"Enter\", modifiers: [] }\n * \"Control+a\" -> { key: \"a\", modifiers: [\"Control\"] }\n * \"Control+Shift+Delete\" -> { key: \"Delete\", modifiers: [\"Control\", \"Shift\"] }\n */\nfunction parseKey(keyString: string): { key: string; modifiers: string[] } {\n const parts = keyString.split(\"+\");\n const modifierNames = [\"Control\", \"Alt\", \"Shift\", \"Meta\"];\n\n const modifiers: string[] = [];\n let key = \"\";\n\n for (const part of parts) {\n if (modifierNames.includes(part)) {\n modifiers.push(part);\n } else {\n key = part;\n }\n }\n\n return { key, modifiers };\n}\n\nexport async function pressCommand(\n keyString: string,\n options: PressOptions = {}\n): Promise<void> {\n // 验证参数\n if (!keyString) {\n throw new Error(\"缺少 key 参数\");\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 解析按键\n const { key, modifiers } = parseKey(keyString);\n\n if (!key) {\n throw new Error(\"无效的按键格式\");\n }\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"press\",\n key,\n modifiers,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n const displayKey = modifiers.length > 0 ? `${modifiers.join(\"+\")}+${key}` : key;\n console.log(`已按下: ${displayKey}`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * scroll 命令 - 滚动页面\n * 用法:bb-browser scroll <direction> [pixels]\n *\n * direction: up | down | left | right\n * pixels: 滚动像素数,默认 300\n */\n\nimport { generateId, type Request, type Response } from \"@bb-browser/shared\";\nimport { sendCommand } from \"../client.js\";\nimport { ensureDaemonRunning } from \"../daemon-manager.js\";\n\nexport interface ScrollOptions {\n json?: boolean;\n tabId?: number;\n}\n\nexport type ScrollDirection = \"up\" | \"down\" | \"left\" | \"right\";\n\nconst VALID_DIRECTIONS: ScrollDirection[] = [\"up\", \"down\", \"left\", \"right\"];\nconst DEFAULT_PIXELS = 300;\n\nexport async function scrollCommand(\n direction: string,\n pixels?: string,\n options: ScrollOptions = {}\n): Promise<void> {\n // 验证 direction\n if (!direction) {\n throw new Error(\"缺少 direction 参数\");\n }\n\n if (!VALID_DIRECTIONS.includes(direction as ScrollDirection)) {\n throw new Error(\n `无效的滚动方向: ${direction},支持: ${VALID_DIRECTIONS.join(\", \")}`\n );\n }\n\n // 解析 pixels\n let pixelValue = DEFAULT_PIXELS;\n if (pixels !== undefined) {\n pixelValue = parseInt(pixels, 10);\n if (isNaN(pixelValue) || pixelValue <= 0) {\n throw new Error(`无效的像素值: ${pixels}`);\n }\n }\n\n // 确保 Daemon 运行\n await ensureDaemonRunning();\n\n // 构造请求\n const request: Request = {\n id: generateId(),\n action: \"scroll\",\n direction: direction as ScrollDirection,\n pixels: pixelValue,\n tabId: options.tabId,\n };\n\n // 发送请求\n const response: Response = await sendCommand(request);\n\n // 输出结果\n if (options.json) {\n console.log(JSON.stringify(response, null, 2));\n } else {\n if (response.success) {\n console.log(`已滚动: ${direction} ${pixelValue}px`);\n } else {\n console.error(`错误: ${response.error}`);\n process.exit(1);\n }\n }\n}\n","/**\n * 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 * history 命令 - 查询 Chrome 浏览历史\n *\n * 用法:\n * bb-browser history search [query] 搜索历史记录\n * bb-browser history domains 查看访问最多的域名\n */\n\nimport { sendCommand } from \"../client.js\";\n\ninterface HistoryOptions {\n json?: boolean;\n days?: number;\n query?: string;\n}\n\nexport async function historyCommand(\n subCommand: 'search' | 'domains',\n options: HistoryOptions = {}\n): Promise<void> {\n const response = await sendCommand({\n id: crypto.randomUUID(),\n action: \"history\",\n historyCommand: subCommand,\n text: options.query,\n ms: options.days,\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 || \"History command failed\");\n }\n\n const data = response.data;\n\n switch (subCommand) {\n case \"search\": {\n const items = data?.historyItems || [];\n\n console.log(`找到 ${items.length} 条历史记录\\n`);\n\n if (items.length === 0) {\n console.log(\"没有找到匹配的历史记录\");\n break;\n }\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n console.log(`${i + 1}. ${item.title || '(无标题)'}`);\n console.log(` ${item.url}`);\n console.log(` 访问次数: ${item.visitCount}`);\n }\n break;\n }\n\n case \"domains\": {\n const domains = data?.historyDomains || [];\n\n console.log(`找到 ${domains.length} 个域名\\n`);\n\n if (domains.length === 0) {\n console.log(\"没有找到历史记录\");\n break;\n }\n\n for (let i = 0; i < domains.length; i++) {\n const domain = domains[i];\n console.log(`${i + 1}. ${domain.domain}`);\n console.log(` 访问次数: ${domain.visits}`);\n }\n break;\n }\n\n default:\n throw new Error(`未知的 history 子命令: ${subCommand}`);\n }\n}\n"],"mappings":"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","names":["fileURLToPath","resolve","existsSync","resolve","parsed","applyJq","spawn","parseRef","parseRef","parseRef","parseRef","parseRef","spawn","resolve","spawn","resolve","parseRef","parseRef","index","matchTabOrigin","resolve","fileURLToPath","spawn","execSync"]}
|