browser-web-search 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -58,12 +58,26 @@ Raw (preview): ${buildPreview(trimmed)}`);
58
58
  // src/openclaw-bridge.ts
59
59
  var OPENCLAW_EVALUATE_TIMEOUT_MS = 12e4;
60
60
  var EXEC_TIMEOUT_BUFFER_MS = 5e3;
61
+ var GLOBAL_FLAGS = /* @__PURE__ */ new Set(["--json", "--timeout"]);
61
62
  function buildOpenClawArgs(args, timeout) {
62
63
  const [subcommand, ...rest] = args;
63
64
  if (!subcommand) {
64
65
  throw new Error("OpenClaw browser command requires a subcommand");
65
66
  }
66
- return ["openclaw", "browser", subcommand, "--timeout", String(timeout), ...rest];
67
+ const globalFlags = ["--timeout", String(timeout)];
68
+ const subcommandArgs = [];
69
+ for (let i = 0; i < rest.length; i++) {
70
+ const arg = rest[i];
71
+ if (GLOBAL_FLAGS.has(arg)) {
72
+ globalFlags.push(arg);
73
+ if (arg !== "--json" && i + 1 < rest.length) {
74
+ globalFlags.push(rest[++i]);
75
+ }
76
+ } else {
77
+ subcommandArgs.push(arg);
78
+ }
79
+ }
80
+ return ["openclaw", "browser", ...globalFlags, subcommand, ...subcommandArgs];
67
81
  }
68
82
  function getOpenClawExecTimeout(timeout) {
69
83
  return timeout + EXEC_TIMEOUT_BUFFER_MS;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/commands/site.ts","../src/openclaw-bridge.ts","../src/openclaw-json.ts","../src/jq.ts","../src/index.ts"],"sourcesContent":["/**\n * site 命令 - 管理和运行网站适配器\n *\n * 用法:\n * bws site list 列出所有可用 adapter\n * bws site search <query> 搜索 adapter\n * bws site info <name> 查看 adapter 详情\n * bws site <name> [args...] 运行 adapter\n *\n * 目录:\n * 内置 adapter:随项目发布\n * ~/.bws/sites/:用户私有 adapter(优先级更高)\n */\n\nimport { readFileSync, readdirSync, existsSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { ocGetTabs, ocFindTabByDomain, ocOpenTab, ocEvaluate } from \"../openclaw-bridge.js\";\nimport { applyJq } from \"../jq.js\";\n\nconst BWS_DIR = join(homedir(), \".bws\");\nconst LOCAL_SITES_DIR = join(BWS_DIR, \"sites\"); // 用户私有 adapter(优先级最高)\n\n// 内置 adapter 目录(项目自带)\nimport { fileURLToPath } from \"node:url\";\nimport { dirname } from \"node:path\";\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst BUILTIN_SITES_DIR = join(__dirname, \"../sites\"); // 项目内置 adapter\n\nexport interface SiteOptions {\n json?: boolean;\n jq?: string;\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\" | \"builtin\";\n}\n\nfunction exitJsonError(error: string, extra: Record<string, unknown> = {}): never {\n console.log(JSON.stringify({ success: false, error, ...extra }, null, 2));\n process.exit(1);\n}\n\n/**\n * 从 JS 文件的 /* @meta JSON * / 块解析元数据\n */\nfunction parseSiteMeta(filePath: string, source: \"local\" | \"builtin\"): 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 : BUILTIN_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\" | \"builtin\"): SiteMeta[] {\n if (!existsSync(dir)) return [];\n const sites: SiteMeta[] = [];\n\n function walk(currentDir: string): void {\n let entries;\n try { entries = readdirSync(currentDir, { withFileTypes: true }); } catch { return; }\n for (const entry of entries) {\n const fullPath = join(currentDir, entry.name);\n if (entry.isDirectory() && !entry.name.startsWith(\".\")) {\n walk(fullPath);\n } else if (entry.isFile() && entry.name.endsWith(\".js\")) {\n const meta = parseSiteMeta(fullPath, source);\n if (meta) sites.push(meta);\n }\n }\n }\n\n walk(dir);\n return sites;\n}\n\n/**\n * 获取所有 adapter(用户私有 > 内置)\n */\nfunction getAllSites(): SiteMeta[] {\n const builtin = scanSites(BUILTIN_SITES_DIR, \"builtin\");\n const local = scanSites(LOCAL_SITES_DIR, \"local\");\n\n const byName = new Map<string, SiteMeta>();\n for (const s of builtin) 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\nfunction siteList(options: SiteOptions): void {\n const sites = getAllSites();\n\n if (sites.length === 0) {\n if (options.json) {\n console.log(\"[]\");\n return;\n }\n console.log(\"未找到任何 site adapter。\");\n console.log(` 内置 adapter 目录: ${BUILTIN_SITES_DIR}`);\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 if (options.json) {\n console.log(\"[]\");\n return;\n }\n console.log(`未找到匹配 \"${query}\" 的 adapter。`);\n console.log(\" 查看所有: bws 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 siteInfo_showDirs(options: SiteOptions): void {\n const builtin = scanSites(BUILTIN_SITES_DIR, \"builtin\");\n const local = scanSites(LOCAL_SITES_DIR, \"local\");\n \n if (options.json) {\n console.log(JSON.stringify({\n builtinDir: BUILTIN_SITES_DIR,\n localDir: LOCAL_SITES_DIR,\n builtinCount: builtin.length,\n localCount: local.length,\n }, null, 2));\n return;\n }\n \n console.log(`内置 adapter: ${BUILTIN_SITES_DIR} (${builtin.length} 个)`);\n console.log(`私有 adapter: ${LOCAL_SITES_DIR} (${local.length} 个)`);\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 if (options.json) {\n exitJsonError(`adapter \"${name}\" not found`, { action: \"bws site list\" });\n }\n console.error(`[error] site info: adapter \"${name}\" not found.`);\n console.error(\" Try: bws 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 || `bws site ${site.name}`}`);\n console.log();\n console.log(`域名:${site.domain || \"(未声明)\"}`);\n console.log(`只读:${site.readOnly ? \"是\" : \"否\"}`);\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 if (options.json) {\n exitJsonError(`site \"${name}\" not found`, {\n suggestions: fuzzy.slice(0, 5).map(s => s.name),\n action: fuzzy.length > 0 ? undefined : \"bws site update\",\n });\n }\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(` bws site ${s.name}`);\n }\n } else {\n console.error(\" Try: bws site list\");\n console.error(\" Or: bws 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 const usage = argNames.map(a => {\n const def = site.args[a];\n return def.required ? `<${a}>` : `[${a}]`;\n }).join(\" \");\n if (options.json) {\n exitJsonError(`missing required argument \"${argName}\"`, {\n usage: `bws site ${name} ${usage}`,\n example: site.example,\n });\n }\n console.error(`[error] site ${name}: missing required argument \"${argName}\".`);\n console.error(` Usage: bws 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\n // OpenClaw 模式执行\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\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: errObj.error, hint }));\n } else {\n console.error(`[error] site ${name}: ${errObj.error}`);\n if (hint) console.error(` Hint: ${hint}`);\n }\n process.exit(1);\n }\n\n if (options.jq) {\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({ 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(`bws site - 网站 CLI 化\n\n用法:\n bws site list 列出所有可用 adapter\n bws site info <name> 查看 adapter 详情\n bws site search <query> 搜索 adapter\n bws site <name> [args...] 运行 adapter\n\n示例:\n bws site list\n bws site zhihu/hot\n bws site xiaohongshu/search \"旅行\"\n bws site bilibili/popular`);\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: bws 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: bws site info <name>\");\n process.exit(1);\n }\n siteInfo(args[1], options);\n break;\n case \"run\":\n if (!args[1]) {\n console.error(\"[error] site run: <name> is required.\");\n console.error(\" Usage: bws site run <name> [args...]\");\n console.error(\" Try: bws 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, search, run\");\n console.error(\" Try: bws site --help\");\n process.exit(1);\n }\n break;\n }\n\n}\n","import { execFileSync } from \"node:child_process\";\nimport { parseOpenClawJson } from \"./openclaw-json.js\";\n\nconst OPENCLAW_EVALUATE_TIMEOUT_MS = 120000;\nconst EXEC_TIMEOUT_BUFFER_MS = 5000;\n\nexport interface OCTab {\n targetId: string;\n url: string;\n title: string;\n type: string;\n}\n\nexport function buildOpenClawArgs(args: string[], timeout: number): string[] {\n const [subcommand, ...rest] = args;\n if (!subcommand) {\n throw new Error(\"OpenClaw browser command requires a subcommand\");\n }\n\n return [\"openclaw\", \"browser\", subcommand, \"--timeout\", String(timeout), ...rest];\n}\n\nexport function getOpenClawExecTimeout(timeout: number): number {\n return timeout + EXEC_TIMEOUT_BUFFER_MS;\n}\n\nfunction runOpenClaw(args: string[], timeout: number): string {\n return execFileSync(\"npx\", buildOpenClawArgs(args, timeout), {\n encoding: \"utf-8\",\n timeout: getOpenClawExecTimeout(timeout),\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n}\n\nexport function ocGetTabs(): OCTab[] {\n const raw = runOpenClaw([\"tabs\", \"--json\"], 15000);\n const data = parseOpenClawJson<{ tabs?: OCTab[] }>(raw);\n return (data.tabs || []).filter((tab: OCTab) => tab.type === \"page\");\n}\n\nexport function ocFindTabByDomain(tabs: OCTab[], domain: string): OCTab | undefined {\n return tabs.find((tab) => {\n try {\n const hostname = new URL(tab.url).hostname;\n return hostname === domain || hostname.endsWith(`.${domain}`);\n } catch {\n return false;\n }\n });\n}\n\nexport function ocOpenTab(url: string): string {\n const raw = runOpenClaw([\"open\", url, \"--json\"], 30000);\n const data = parseOpenClawJson<{ id?: string; targetId?: string }>(raw);\n return data.id || data.targetId || \"\";\n}\n\nexport function ocEvaluate(targetId: string, fn: string): unknown {\n const raw = runOpenClaw([\"evaluate\", \"--fn\", fn, \"--target-id\", targetId], OPENCLAW_EVALUATE_TIMEOUT_MS);\n return parseOpenClawJson(raw);\n}\n","interface ParseSuccess<T> {\n ok: true;\n value: T;\n}\n\ninterface ParseFailure {\n ok: false;\n error: Error;\n}\n\nfunction buildPreview(raw: string): string {\n return raw.length > 200 ? `${raw.slice(0, 200)}...` : raw;\n}\n\nfunction tryParseJson<T>(raw: string): ParseSuccess<T> | ParseFailure {\n try {\n return { ok: true, value: JSON.parse(raw) as T };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n}\n\nfunction tryParseLastJsonLineBlock<T>(raw: string): ParseSuccess<T> | null {\n const lines = raw.split(/\\r?\\n/);\n\n // OpenClaw diagnostics are emitted as extra lines around the JSON payload,\n // so prefer the last contiguous block of lines that parses cleanly as JSON.\n for (let end = lines.length; end > 0; end -= 1) {\n for (let start = end - 1; start >= 0; start -= 1) {\n const candidate = lines.slice(start, end).join(\"\\n\").trim();\n if (!candidate) {\n continue;\n }\n\n const parsed = tryParseJson<T>(candidate);\n if (parsed.ok) {\n return parsed;\n }\n }\n }\n\n return null;\n}\n\nexport function parseOpenClawJson<T>(raw: string): T {\n const trimmed = raw.trim();\n if (!trimmed) {\n throw new Error(\"OpenClaw returned empty output\");\n }\n\n const direct = tryParseJson<T>(trimmed);\n if (direct.ok) {\n return direct.value;\n }\n\n const lineBlock = tryParseLastJsonLineBlock<T>(trimmed);\n if (lineBlock) {\n return lineBlock.value;\n }\n\n throw new Error(`Failed to parse OpenClaw JSON output: ${direct.error.message}\\nRaw (preview): ${buildPreview(trimmed)}`);\n}\n","function splitTopLevel(input: string, separator: string): string[] {\n const parts: string[] = [];\n let current = \"\";\n let depth = 0;\n let inString = false;\n\n for (let i = 0; i < input.length; i++) {\n const char = input[i];\n const prev = input[i - 1];\n if (char === '\"' && prev !== '\\\\') inString = !inString;\n if (!inString) {\n if (char === '{' || char === '(' || char === '[') depth++;\n if (char === '}' || char === ')' || char === ']') depth--;\n if (depth === 0 && input.slice(i, i + separator.length) === separator) {\n parts.push(current.trim());\n current = \"\";\n i += separator.length - 1;\n continue;\n }\n }\n current += char;\n }\n\n if (current.trim()) parts.push(current.trim());\n return parts;\n}\n\nfunction parseLiteral(value: string): unknown {\n const trimmed = value.trim();\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) return JSON.parse(trimmed);\n if (trimmed === \"true\") return true;\n if (trimmed === \"false\") return false;\n if (trimmed === \"null\") return null;\n return Number(trimmed);\n}\n\nfunction getField(value: unknown, field: string): unknown {\n return value !== null && typeof value === \"object\" ? (value as Record<string, unknown>)[field] : undefined;\n}\n\nfunction applySegment(inputs: unknown[], expr: string): unknown[] {\n if (expr === \".\") return inputs;\n if (expr.startsWith(\"select(\")) {\n const match = expr.match(/^select\\((.+?)\\s*(==|>)\\s*(.+)\\)$/);\n if (!match) throw new Error(`不支持的 jq 表达式: ${expr}`);\n const [, leftExpr, op, rightExpr] = match;\n const expected = parseLiteral(rightExpr);\n return inputs.filter((item) => {\n const left = applyExpression([item], leftExpr)[0];\n return op === \"==\" ? left === expected : Number(left) > Number(expected);\n });\n }\n if (expr.startsWith(\"{\") && expr.endsWith(\"}\")) {\n const body = expr.slice(1, -1).trim();\n if (!body) return inputs.map(() => ({}));\n const entries = splitTopLevel(body, \",\");\n return inputs.map((item) => {\n const obj: Record<string, unknown> = {};\n for (const entry of entries) {\n const colon = entry.indexOf(\":\");\n if (colon === -1) {\n const key = entry.trim().replace(/^\\./, \"\");\n obj[key] = applyExpression([item], `.${key}`)[0];\n } else {\n const key = entry.slice(0, colon).trim();\n const valueExpr = entry.slice(colon + 1).trim();\n obj[key] = applyExpression([item], valueExpr)[0];\n }\n }\n return obj;\n });\n }\n if (!expr.startsWith(\".\")) throw new Error(`不支持的 jq 表达式: ${expr}`);\n\n let current = inputs;\n let remaining = expr.slice(1);\n while (remaining.length > 0) {\n if (remaining.startsWith(\"[]\")) {\n current = current.flatMap((item) => Array.isArray(item) ? item : []);\n remaining = remaining.slice(2);\n } else if (remaining.startsWith(\"[\")) {\n const match = remaining.match(/^\\[(-?\\d+)\\]/);\n if (!match) throw new Error(`不支持的 jq 表达式: .${remaining}`);\n const index = Number(match[1]);\n current = current.map((item) => {\n if (!Array.isArray(item)) return undefined;\n return item[index >= 0 ? index : item.length + index];\n });\n remaining = remaining.slice(match[0].length);\n } else if (remaining.startsWith(\".\")) {\n remaining = remaining.slice(1);\n } else {\n const match = remaining.match(/^([A-Za-z_][A-Za-z0-9_]*)/);\n if (!match) throw new Error(`不支持的 jq 表达式: .${remaining}`);\n const field = match[1];\n current = current.map((item) => getField(item, field));\n remaining = remaining.slice(field.length);\n }\n }\n return current;\n}\n\nfunction applyExpression(inputs: unknown[], expression: string): unknown[] {\n const segments = splitTopLevel(expression.trim(), \"|\");\n return segments.reduce((current, segment) => applySegment(current, segment.trim()), inputs);\n}\n\nexport function applyJq(data: unknown, expression: string): unknown[] {\n return applyExpression([data], expression).filter((item) => item !== undefined);\n}\n","#!/usr/bin/env node\n\n/**\n * Browser Web Search (BWS) - Turn any website into a CLI command\n * \n * 基于 OpenClaw 浏览器,复用用户登录态访问网站数据\n */\n\nimport { siteCommand } from \"./commands/site.js\";\n\nconst VERSION = \"0.2.0\";\n\nconst HELP_TEXT = `\nBrowser Web Search (BWS) v${VERSION}\n\n把任何网站变成命令行 API,使用 OpenClaw 浏览器 + 用户登录态。\n\n用法:\n bws site list 列出所有可用 adapter\n bws site info <name> 查看 adapter 元信息\n bws site search <query> 搜索 adapter\n bws site <name> [args...] 运行 adapter\n bws <name> [args...] 运行 adapter(简写)\n\n示例:\n bws site list # 查看所有可用命令\n bws zhihu/hot # 知乎热榜\n bws xiaohongshu/search \"旅行\" # 小红书搜索\n bws bilibili/popular # B站热门\n\n选项:\n --json 以 JSON 格式输出\n --jq <expr> 对 JSON 输出应用 jq 过滤\n --help, -h 显示帮助信息\n --version, -v 显示版本号\n\n需要 OpenClaw 环境运行。\n`.trim();\n\ninterface ParsedArgs {\n command: string;\n args: string[];\n flags: {\n json?: boolean;\n jq?: string;\n };\n}\n\nfunction parseArgs(args: string[]): ParsedArgs {\n const result: ParsedArgs = {\n command: \"\",\n args: [],\n flags: {},\n };\n\n let skipNext = false;\n\n for (let i = 0; i < args.length; i++) {\n if (skipNext) {\n skipNext = false;\n continue;\n }\n\n const arg = args[i];\n\n if (arg === \"--json\") {\n result.flags.json = true;\n } else if (arg === \"--jq\") {\n skipNext = true;\n const nextIdx = i + 1;\n if (nextIdx < args.length) {\n result.flags.jq = args[nextIdx];\n result.flags.json = true;\n }\n } else if (arg === \"--help\" || arg === \"-h\") {\n console.log(HELP_TEXT);\n process.exit(0);\n } else if (arg === \"--version\" || arg === \"-v\") {\n console.log(VERSION);\n process.exit(0);\n } else if (!result.command) {\n result.command = arg;\n } else {\n result.args.push(arg);\n }\n }\n\n return result;\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n\n if (args.length === 0) {\n console.log(HELP_TEXT);\n process.exit(0);\n }\n\n const parsed = parseArgs(args);\n\n switch (parsed.command) {\n case \"site\":\n await siteCommand(parsed.args, {\n json: parsed.flags.json,\n jq: parsed.flags.jq,\n });\n break;\n\n default:\n // 如果命令包含 /,当作 site 命令的简写\n if (parsed.command.includes(\"/\")) {\n await siteCommand([parsed.command, ...parsed.args], {\n json: parsed.flags.json,\n jq: parsed.flags.jq,\n });\n } else {\n console.error(`[error] 未知命令: ${parsed.command}`);\n console.error(\" 运行 bws --help 查看帮助\");\n process.exit(1);\n }\n break;\n }\n}\n\nmain().catch((error) => {\n console.error(`[error] ${error.message || error}`);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/commands/site.ts","../src/openclaw-bridge.ts","../src/openclaw-json.ts","../src/jq.ts","../src/index.ts"],"sourcesContent":["/**\n * site 命令 - 管理和运行网站适配器\n *\n * 用法:\n * bws site list 列出所有可用 adapter\n * bws site search <query> 搜索 adapter\n * bws site info <name> 查看 adapter 详情\n * bws site <name> [args...] 运行 adapter\n *\n * 目录:\n * 内置 adapter:随项目发布\n * ~/.bws/sites/:用户私有 adapter(优先级更高)\n */\n\nimport { readFileSync, readdirSync, existsSync } from \"node:fs\";\nimport { join, relative } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { ocGetTabs, ocFindTabByDomain, ocOpenTab, ocEvaluate } from \"../openclaw-bridge.js\";\nimport { applyJq } from \"../jq.js\";\n\nconst BWS_DIR = join(homedir(), \".bws\");\nconst LOCAL_SITES_DIR = join(BWS_DIR, \"sites\"); // 用户私有 adapter(优先级最高)\n\n// 内置 adapter 目录(项目自带)\nimport { fileURLToPath } from \"node:url\";\nimport { dirname } from \"node:path\";\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst BUILTIN_SITES_DIR = join(__dirname, \"../sites\"); // 项目内置 adapter\n\nexport interface SiteOptions {\n json?: boolean;\n jq?: string;\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\" | \"builtin\";\n}\n\nfunction exitJsonError(error: string, extra: Record<string, unknown> = {}): never {\n console.log(JSON.stringify({ success: false, error, ...extra }, null, 2));\n process.exit(1);\n}\n\n/**\n * 从 JS 文件的 /* @meta JSON * / 块解析元数据\n */\nfunction parseSiteMeta(filePath: string, source: \"local\" | \"builtin\"): 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 : BUILTIN_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\" | \"builtin\"): SiteMeta[] {\n if (!existsSync(dir)) return [];\n const sites: SiteMeta[] = [];\n\n function walk(currentDir: string): void {\n let entries;\n try { entries = readdirSync(currentDir, { withFileTypes: true }); } catch { return; }\n for (const entry of entries) {\n const fullPath = join(currentDir, entry.name);\n if (entry.isDirectory() && !entry.name.startsWith(\".\")) {\n walk(fullPath);\n } else if (entry.isFile() && entry.name.endsWith(\".js\")) {\n const meta = parseSiteMeta(fullPath, source);\n if (meta) sites.push(meta);\n }\n }\n }\n\n walk(dir);\n return sites;\n}\n\n/**\n * 获取所有 adapter(用户私有 > 内置)\n */\nfunction getAllSites(): SiteMeta[] {\n const builtin = scanSites(BUILTIN_SITES_DIR, \"builtin\");\n const local = scanSites(LOCAL_SITES_DIR, \"local\");\n\n const byName = new Map<string, SiteMeta>();\n for (const s of builtin) 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\nfunction siteList(options: SiteOptions): void {\n const sites = getAllSites();\n\n if (sites.length === 0) {\n if (options.json) {\n console.log(\"[]\");\n return;\n }\n console.log(\"未找到任何 site adapter。\");\n console.log(` 内置 adapter 目录: ${BUILTIN_SITES_DIR}`);\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 if (options.json) {\n console.log(\"[]\");\n return;\n }\n console.log(`未找到匹配 \"${query}\" 的 adapter。`);\n console.log(\" 查看所有: bws 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 siteInfo_showDirs(options: SiteOptions): void {\n const builtin = scanSites(BUILTIN_SITES_DIR, \"builtin\");\n const local = scanSites(LOCAL_SITES_DIR, \"local\");\n \n if (options.json) {\n console.log(JSON.stringify({\n builtinDir: BUILTIN_SITES_DIR,\n localDir: LOCAL_SITES_DIR,\n builtinCount: builtin.length,\n localCount: local.length,\n }, null, 2));\n return;\n }\n \n console.log(`内置 adapter: ${BUILTIN_SITES_DIR} (${builtin.length} 个)`);\n console.log(`私有 adapter: ${LOCAL_SITES_DIR} (${local.length} 个)`);\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 if (options.json) {\n exitJsonError(`adapter \"${name}\" not found`, { action: \"bws site list\" });\n }\n console.error(`[error] site info: adapter \"${name}\" not found.`);\n console.error(\" Try: bws 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 || `bws site ${site.name}`}`);\n console.log();\n console.log(`域名:${site.domain || \"(未声明)\"}`);\n console.log(`只读:${site.readOnly ? \"是\" : \"否\"}`);\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 if (options.json) {\n exitJsonError(`site \"${name}\" not found`, {\n suggestions: fuzzy.slice(0, 5).map(s => s.name),\n action: fuzzy.length > 0 ? undefined : \"bws site update\",\n });\n }\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(` bws site ${s.name}`);\n }\n } else {\n console.error(\" Try: bws site list\");\n console.error(\" Or: bws 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 const usage = argNames.map(a => {\n const def = site.args[a];\n return def.required ? `<${a}>` : `[${a}]`;\n }).join(\" \");\n if (options.json) {\n exitJsonError(`missing required argument \"${argName}\"`, {\n usage: `bws site ${name} ${usage}`,\n example: site.example,\n });\n }\n console.error(`[error] site ${name}: missing required argument \"${argName}\".`);\n console.error(` Usage: bws 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\n // OpenClaw 模式执行\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\n if (options.json) {\n console.log(JSON.stringify({ success: false, error: errObj.error, hint }));\n } else {\n console.error(`[error] site ${name}: ${errObj.error}`);\n if (hint) console.error(` Hint: ${hint}`);\n }\n process.exit(1);\n }\n\n if (options.jq) {\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({ 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(`bws site - 网站 CLI 化\n\n用法:\n bws site list 列出所有可用 adapter\n bws site info <name> 查看 adapter 详情\n bws site search <query> 搜索 adapter\n bws site <name> [args...] 运行 adapter\n\n示例:\n bws site list\n bws site zhihu/hot\n bws site xiaohongshu/search \"旅行\"\n bws site bilibili/popular`);\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: bws 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: bws site info <name>\");\n process.exit(1);\n }\n siteInfo(args[1], options);\n break;\n case \"run\":\n if (!args[1]) {\n console.error(\"[error] site run: <name> is required.\");\n console.error(\" Usage: bws site run <name> [args...]\");\n console.error(\" Try: bws 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, search, run\");\n console.error(\" Try: bws site --help\");\n process.exit(1);\n }\n break;\n }\n\n}\n","import { execFileSync } from \"node:child_process\";\nimport { parseOpenClawJson } from \"./openclaw-json.js\";\n\nconst OPENCLAW_EVALUATE_TIMEOUT_MS = 120000;\nconst EXEC_TIMEOUT_BUFFER_MS = 5000;\n\nexport interface OCTab {\n targetId: string;\n url: string;\n title: string;\n type: string;\n}\n\n// Global flags that should be placed after \"browser\" but before subcommand\nconst GLOBAL_FLAGS = new Set([\"--json\", \"--timeout\"]);\n\nexport function buildOpenClawArgs(args: string[], timeout: number): string[] {\n const [subcommand, ...rest] = args;\n if (!subcommand) {\n throw new Error(\"OpenClaw browser command requires a subcommand\");\n }\n\n // Separate global flags from subcommand-specific args\n const globalFlags: string[] = [\"--timeout\", String(timeout)];\n const subcommandArgs: string[] = [];\n\n for (let i = 0; i < rest.length; i++) {\n const arg = rest[i];\n if (GLOBAL_FLAGS.has(arg)) {\n globalFlags.push(arg);\n // If this flag takes a value (not --json), include the next arg too\n if (arg !== \"--json\" && i + 1 < rest.length) {\n globalFlags.push(rest[++i]);\n }\n } else {\n subcommandArgs.push(arg);\n }\n }\n\n return [\"openclaw\", \"browser\", ...globalFlags, subcommand, ...subcommandArgs];\n}\n\nexport function getOpenClawExecTimeout(timeout: number): number {\n return timeout + EXEC_TIMEOUT_BUFFER_MS;\n}\n\nfunction runOpenClaw(args: string[], timeout: number): string {\n return execFileSync(\"npx\", buildOpenClawArgs(args, timeout), {\n encoding: \"utf-8\",\n timeout: getOpenClawExecTimeout(timeout),\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }).trim();\n}\n\nexport function ocGetTabs(): OCTab[] {\n const raw = runOpenClaw([\"tabs\", \"--json\"], 15000);\n const data = parseOpenClawJson<{ tabs?: OCTab[] }>(raw);\n return (data.tabs || []).filter((tab: OCTab) => tab.type === \"page\");\n}\n\nexport function ocFindTabByDomain(tabs: OCTab[], domain: string): OCTab | undefined {\n return tabs.find((tab) => {\n try {\n const hostname = new URL(tab.url).hostname;\n return hostname === domain || hostname.endsWith(`.${domain}`);\n } catch {\n return false;\n }\n });\n}\n\nexport function ocOpenTab(url: string): string {\n const raw = runOpenClaw([\"open\", url, \"--json\"], 30000);\n const data = parseOpenClawJson<{ id?: string; targetId?: string }>(raw);\n return data.id || data.targetId || \"\";\n}\n\nexport function ocEvaluate(targetId: string, fn: string): unknown {\n const raw = runOpenClaw([\"evaluate\", \"--fn\", fn, \"--target-id\", targetId], OPENCLAW_EVALUATE_TIMEOUT_MS);\n return parseOpenClawJson(raw);\n}\n","interface ParseSuccess<T> {\n ok: true;\n value: T;\n}\n\ninterface ParseFailure {\n ok: false;\n error: Error;\n}\n\nfunction buildPreview(raw: string): string {\n return raw.length > 200 ? `${raw.slice(0, 200)}...` : raw;\n}\n\nfunction tryParseJson<T>(raw: string): ParseSuccess<T> | ParseFailure {\n try {\n return { ok: true, value: JSON.parse(raw) as T };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n}\n\nfunction tryParseLastJsonLineBlock<T>(raw: string): ParseSuccess<T> | null {\n const lines = raw.split(/\\r?\\n/);\n\n // OpenClaw diagnostics are emitted as extra lines around the JSON payload,\n // so prefer the last contiguous block of lines that parses cleanly as JSON.\n for (let end = lines.length; end > 0; end -= 1) {\n for (let start = end - 1; start >= 0; start -= 1) {\n const candidate = lines.slice(start, end).join(\"\\n\").trim();\n if (!candidate) {\n continue;\n }\n\n const parsed = tryParseJson<T>(candidate);\n if (parsed.ok) {\n return parsed;\n }\n }\n }\n\n return null;\n}\n\nexport function parseOpenClawJson<T>(raw: string): T {\n const trimmed = raw.trim();\n if (!trimmed) {\n throw new Error(\"OpenClaw returned empty output\");\n }\n\n const direct = tryParseJson<T>(trimmed);\n if (direct.ok) {\n return direct.value;\n }\n\n const lineBlock = tryParseLastJsonLineBlock<T>(trimmed);\n if (lineBlock) {\n return lineBlock.value;\n }\n\n throw new Error(`Failed to parse OpenClaw JSON output: ${direct.error.message}\\nRaw (preview): ${buildPreview(trimmed)}`);\n}\n","function splitTopLevel(input: string, separator: string): string[] {\n const parts: string[] = [];\n let current = \"\";\n let depth = 0;\n let inString = false;\n\n for (let i = 0; i < input.length; i++) {\n const char = input[i];\n const prev = input[i - 1];\n if (char === '\"' && prev !== '\\\\') inString = !inString;\n if (!inString) {\n if (char === '{' || char === '(' || char === '[') depth++;\n if (char === '}' || char === ')' || char === ']') depth--;\n if (depth === 0 && input.slice(i, i + separator.length) === separator) {\n parts.push(current.trim());\n current = \"\";\n i += separator.length - 1;\n continue;\n }\n }\n current += char;\n }\n\n if (current.trim()) parts.push(current.trim());\n return parts;\n}\n\nfunction parseLiteral(value: string): unknown {\n const trimmed = value.trim();\n if (trimmed.startsWith('\"') && trimmed.endsWith('\"')) return JSON.parse(trimmed);\n if (trimmed === \"true\") return true;\n if (trimmed === \"false\") return false;\n if (trimmed === \"null\") return null;\n return Number(trimmed);\n}\n\nfunction getField(value: unknown, field: string): unknown {\n return value !== null && typeof value === \"object\" ? (value as Record<string, unknown>)[field] : undefined;\n}\n\nfunction applySegment(inputs: unknown[], expr: string): unknown[] {\n if (expr === \".\") return inputs;\n if (expr.startsWith(\"select(\")) {\n const match = expr.match(/^select\\((.+?)\\s*(==|>)\\s*(.+)\\)$/);\n if (!match) throw new Error(`不支持的 jq 表达式: ${expr}`);\n const [, leftExpr, op, rightExpr] = match;\n const expected = parseLiteral(rightExpr);\n return inputs.filter((item) => {\n const left = applyExpression([item], leftExpr)[0];\n return op === \"==\" ? left === expected : Number(left) > Number(expected);\n });\n }\n if (expr.startsWith(\"{\") && expr.endsWith(\"}\")) {\n const body = expr.slice(1, -1).trim();\n if (!body) return inputs.map(() => ({}));\n const entries = splitTopLevel(body, \",\");\n return inputs.map((item) => {\n const obj: Record<string, unknown> = {};\n for (const entry of entries) {\n const colon = entry.indexOf(\":\");\n if (colon === -1) {\n const key = entry.trim().replace(/^\\./, \"\");\n obj[key] = applyExpression([item], `.${key}`)[0];\n } else {\n const key = entry.slice(0, colon).trim();\n const valueExpr = entry.slice(colon + 1).trim();\n obj[key] = applyExpression([item], valueExpr)[0];\n }\n }\n return obj;\n });\n }\n if (!expr.startsWith(\".\")) throw new Error(`不支持的 jq 表达式: ${expr}`);\n\n let current = inputs;\n let remaining = expr.slice(1);\n while (remaining.length > 0) {\n if (remaining.startsWith(\"[]\")) {\n current = current.flatMap((item) => Array.isArray(item) ? item : []);\n remaining = remaining.slice(2);\n } else if (remaining.startsWith(\"[\")) {\n const match = remaining.match(/^\\[(-?\\d+)\\]/);\n if (!match) throw new Error(`不支持的 jq 表达式: .${remaining}`);\n const index = Number(match[1]);\n current = current.map((item) => {\n if (!Array.isArray(item)) return undefined;\n return item[index >= 0 ? index : item.length + index];\n });\n remaining = remaining.slice(match[0].length);\n } else if (remaining.startsWith(\".\")) {\n remaining = remaining.slice(1);\n } else {\n const match = remaining.match(/^([A-Za-z_][A-Za-z0-9_]*)/);\n if (!match) throw new Error(`不支持的 jq 表达式: .${remaining}`);\n const field = match[1];\n current = current.map((item) => getField(item, field));\n remaining = remaining.slice(field.length);\n }\n }\n return current;\n}\n\nfunction applyExpression(inputs: unknown[], expression: string): unknown[] {\n const segments = splitTopLevel(expression.trim(), \"|\");\n return segments.reduce((current, segment) => applySegment(current, segment.trim()), inputs);\n}\n\nexport function applyJq(data: unknown, expression: string): unknown[] {\n return applyExpression([data], expression).filter((item) => item !== undefined);\n}\n","#!/usr/bin/env node\n\n/**\n * Browser Web Search (BWS) - Turn any website into a CLI command\n * \n * 基于 OpenClaw 浏览器,复用用户登录态访问网站数据\n */\n\nimport { siteCommand } from \"./commands/site.js\";\n\nconst VERSION = \"0.2.0\";\n\nconst HELP_TEXT = `\nBrowser Web Search (BWS) v${VERSION}\n\n把任何网站变成命令行 API,使用 OpenClaw 浏览器 + 用户登录态。\n\n用法:\n bws site list 列出所有可用 adapter\n bws site info <name> 查看 adapter 元信息\n bws site search <query> 搜索 adapter\n bws site <name> [args...] 运行 adapter\n bws <name> [args...] 运行 adapter(简写)\n\n示例:\n bws site list # 查看所有可用命令\n bws zhihu/hot # 知乎热榜\n bws xiaohongshu/search \"旅行\" # 小红书搜索\n bws bilibili/popular # B站热门\n\n选项:\n --json 以 JSON 格式输出\n --jq <expr> 对 JSON 输出应用 jq 过滤\n --help, -h 显示帮助信息\n --version, -v 显示版本号\n\n需要 OpenClaw 环境运行。\n`.trim();\n\ninterface ParsedArgs {\n command: string;\n args: string[];\n flags: {\n json?: boolean;\n jq?: string;\n };\n}\n\nfunction parseArgs(args: string[]): ParsedArgs {\n const result: ParsedArgs = {\n command: \"\",\n args: [],\n flags: {},\n };\n\n let skipNext = false;\n\n for (let i = 0; i < args.length; i++) {\n if (skipNext) {\n skipNext = false;\n continue;\n }\n\n const arg = args[i];\n\n if (arg === \"--json\") {\n result.flags.json = true;\n } else if (arg === \"--jq\") {\n skipNext = true;\n const nextIdx = i + 1;\n if (nextIdx < args.length) {\n result.flags.jq = args[nextIdx];\n result.flags.json = true;\n }\n } else if (arg === \"--help\" || arg === \"-h\") {\n console.log(HELP_TEXT);\n process.exit(0);\n } else if (arg === \"--version\" || arg === \"-v\") {\n console.log(VERSION);\n process.exit(0);\n } else if (!result.command) {\n result.command = arg;\n } else {\n result.args.push(arg);\n }\n }\n\n return result;\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n\n if (args.length === 0) {\n console.log(HELP_TEXT);\n process.exit(0);\n }\n\n const parsed = parseArgs(args);\n\n switch (parsed.command) {\n case \"site\":\n await siteCommand(parsed.args, {\n json: parsed.flags.json,\n jq: parsed.flags.jq,\n });\n break;\n\n default:\n // 如果命令包含 /,当作 site 命令的简写\n if (parsed.command.includes(\"/\")) {\n await siteCommand([parsed.command, ...parsed.args], {\n json: parsed.flags.json,\n jq: parsed.flags.jq,\n });\n } else {\n console.error(`[error] 未知命令: ${parsed.command}`);\n console.error(\" 运行 bws --help 查看帮助\");\n process.exit(1);\n }\n break;\n }\n}\n\nmain().catch((error) => {\n console.error(`[error] ${error.message || error}`);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-web-search",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "把任何网站变成命令行 API,专为 OpenClaw 设计,复用浏览器登录态",
5
5
  "type": "module",
6
6
  "bin": {