内容
# @ulpi/browse
用于 AI 编程代理的快速无头浏览器和原生应用自动化 CLI。 通过 Playwright 实现持久的 Chromium 守护进程,平均每个命令耗时约 100 毫秒。 通过相同的接口自动化 Android、iOS 和 macOS 应用。
## 安装
### 全局安装(推荐)
```bash
npm install -g @ulpi/browse
```
需要 Node.js 18+。 Chromium 会在首次 `npm install` 时通过 Playwright 自动安装。 如果安装了 [Bun](https://bun.sh),browse 会自动使用它来执行命令,速度提升约 2 倍。
### 项目安装(本地依赖)
```bash
npm install @ulpi/browse
```
然后通过 `package.json` 脚本或直接调用 `browse` 来使用。
### 从源码安装
```bash
git clone https://github.com/ulpi-io/browse
cd browse
npm install
npx tsx src/cli.ts goto https://example.com # 开发模式
npm run build # 构建 bundle
```
## 快速入门
```bash
browse goto https://example.com
browse snapshot -i # 获取带有引用(refs)的交互元素
browse click @e2 # 点击引用(ref)元素
browse fill @e3 "test@example.com" # 填充输入框
browse text # 获取可见页面文本
browse screenshot page.png
browse stop
```
### 引用工作流
每次 `snapshot` 命令都会为元素分配引用(refs,如 `@e1`、`@e2` 等)。 在任何命令中使用引用作为选择器,无需构造 CSS 选择器:
```bash
$ browse snapshot -i
@e1 [button] "Submit"
@e2 [link] "Home"
@e3 [textbox] "Email"
$ browse click @e1 # 点击提交按钮
Clicked @e1
$ browse fill @e3 "user@example.com" # 填充邮箱字段
Filled @e3
```
### 传统选择器(也支持)
```bash
browse click "#submit"
browse fill ".email-input" "test@example.com"
browse click "text=Submit"
```
## 命令
### 导航
```bash
browse goto <url> # 导航到 URL
browse back # 后退
browse forward # 前进
browse reload # 重新加载页面
browse url # 获取当前 URL
```
### 内容提取
```bash
browse text # 可见文本(干净,无 DOM 变更)
browse html [sel] # 完整 HTML 或元素 innerHTML
browse links # 所有链接,格式为 "文本 -> 地址"
browse forms # 表单结构,JSON 格式
browse accessibility # 原始 ARIA 快照树
browse schema # JSON-LD、Microdata、RDFa 结构化数据
browse meta # 页面元标签(标题、描述、OG、canonical、hreflang)
browse headings # H1-H6 章节层次结构及计数
```
### 交互
```bash
browse click <sel> # 点击元素
browse rightclick <sel> # 右键点击元素(上下文菜单)
browse dblclick <sel> # 双击元素
browse fill <sel> <val> # 清除并填充输入框
browse select <sel> <val> # 选择下拉选项
browse hover <sel> # 悬停元素
browse focus <sel> # 聚焦元素
browse tap <sel> # 点击元素(需要通过模拟触摸上下文)
browse check <sel> # 选中复选框
browse uncheck <sel> # 取消选中复选框
browse type <text> # 通过键盘输入文本(当前焦点)
browse press <key> # 按键(Enter、Tab 等)
browse keydown <key> # 键入事件
browse keyup <key> # 键释放事件
browse keyboard inserttext <text> # 插入文本,无键入事件
browse scroll [sel|up|down] # 滚动元素到视图或方向
browse scrollinto <sel> # 滚动元素到视图(显式)
browse swipe <dir> [px] # 向上/向下/向左/向右滑动(触摸事件)
browse drag <src> <tgt> # 拖放
browse highlight <sel> # 高亮元素,视觉叠加层
browse download <sel> [path] # 下载文件,通过点击触发
browse upload <sel> <files...> # 上传文件到输入框
```
### 鼠标控制
```bash
browse mouse move <x> <y> # 移动鼠标到坐标
browse mouse down [button] # 按下鼠标按钮(左/右/中)
browse mouse up [button] # 释放鼠标按钮
browse mouse wheel <dy> [dx] # 滚动鼠标滚轮
```
### 设置
```bash
browse set geo <lat> <lng> # 设置地理位置
browse set media <scheme> # 设置颜色方案(暗色/亮色/无偏好)
```
### 等待
```bash
browse wait <selector> # 等待元素出现
browse wait <selector> --state hidden # 等待元素消失
browse wait <ms> # 等待毫秒数
browse wait --url <pattern> # 等待 URL 匹配
browse wait --text "Welcome" # 等待文本出现在页面中
browse wait --fn "js expr" # 等待 JavaScript 条件成立
browse wait --load <state> # 等待加载状态(load/domcontentloaded/networkidle)
browse wait --network-idle # 等待网络空闲
browse wait --download [path] # 等待下载完成
```
### 快照
```bash
browse snapshot # 完整可访问性树
browse snapshot -i # 仅交互元素(简洁的扁平列表)
browse snapshot -i -f # 交互元素,完整缩进树
browse snapshot -i -C # 包含光标交互元素(onclick,cursor:pointer)
browse snapshot -V # 仅视口 - 当前屏幕可见元素
browse snapshot -c # 紧凑 - 删除空结构元素
browse snapshot -d 3 # 限制深度到 3 级
browse snapshot -s "#main" # 限定在 CSS 选择器范围内
browse snapshot -i -c -d 5 # 组合选项
```
| 标志 | 描述 |
|------|-------------|
| `-i` | 仅交互元素(按钮、链接、输入框)- 简洁的扁平列表 |
| `-f` | 完整 - 带属性和子元素的缩进树(与 `-i` 一起使用) |
| `-V` | 视口 - 当前视口内可见元素 |
| `-c` | 紧凑 - 删除空结构元素 |
| `-C` | 光标交互 - 检测具有 `cursor:pointer`、`onclick`、`tabindex` 的 div |
| `-d N` | 限制树深度 |
| `-s <sel>` | 限定在 CSS 选择器范围内 |
`-C` 标志捕获现代 SPA 模式,ARIA 树会忽略 - `<div onclick>`、`cursor: pointer`、`tabindex` 和 `data-action` 元素。
### 查找元素
```bash
browse find role <role> [name] # 按 ARIA 角色查找
browse find text <text> # 按文本内容查找
browse find label <label> # 按标签查找
browse find placeholder <placeholder> # 按占位符查找
browse find testid <id> # 按 data-testid 查找
browse find alt <text> # 按 alt 文本查找
browse find title <text> # 按标题属性查找
browse find first <sel> # 查找第一个匹配元素
browse find last <sel> # 查找最后一个匹配元素
browse find nth <n> <sel> # 查找第 n 个匹配元素(0 索引)
```
### 检查
```bash
browse js <expr> # 评估 JavaScript 表达式
browse eval <file> # 评估 JavaScript 文件
browse css <sel> <prop> # 获取计算后的 CSS 属性
browse attrs <sel> # 获取元素属性,JSON 格式
browse element-state <sel> # 元素状态(可见、启用、选中等)
browse value <sel> # 获取输入/选择值
browse count <sel> # 计数匹配选择器的元素
browse box <sel> # 获取边界框,JSON 格式 {x, y, width, height}
browse clipboard [write <text>] # 读取或写入剪贴板
browse console [--clear] # 控制台日志缓冲区
browse errors [--clear] # 页面错误,仅过滤自控制台
browse network [--clear] # 网络请求缓冲区
browse cookies # 浏览器 cookie,JSON 格式
browse storage [set <k> <v>] # localStorage/sessionStorage
browse perf # 导航计时(dns, ttfb, load)
browse devices [filter] # 列出可用设备名称
browse images [sel] [--inline] # 列出页面图像,带 src、alt、尺寸
```
### 视觉
```bash
browse screenshot [path] # 截图(视口)
browse screenshot --full [path] # 全页截图
browse screenshot <sel|@ref> [path] # 截图特定元素
browse screenshot --clip x,y,w,h [path] # 截图剪辑区域
browse screenshot --annotate [path] # 带编号标签的注释截图
browse pdf [path] # 保存页面为 PDF
browse responsive [prefix] # 移动/平板/桌面截图
```
### 比较
```bash
browse diff <url1> <url2> # 两页面之间的文本差异
browse snapshot-diff # 当前快照与上一次快照的差异
browse screenshot-diff <baseline> [current] # 像素级视觉差异
```
### 标签页
```bash
browse tabs # 列出所有标签页
browse tab <id> # 切换到标签页
browse newtab [url] # 打开新标签页
browse closetab [id] # 关闭标签页
```
### 帧
```bash
browse frame <sel> # 切换到 iframe
browse frame main # 回到主帧
```
### 设备模拟
```bash
browse emulate "iPhone 14" # 模拟设备
browse emulate reset # 重置为桌面(1920x1080)
browse devices # 列出所有可用设备
browse devices iphone # 筛选设备列表
browse viewport 1280x720 # 设置视口大小
```
100+ 设备:iPhone 12–17,Pixel 5–7,iPad,Galaxy,以及所有 Playwright 内置设备。
### Cookie
```bash
browse cookie <name>=<value> # 设置 cookie(简单)
browse cookie set <n> <v> [--domain --secure ...] # 设置 cookie,带选项
browse cookie clear # 清除所有 cookie
browse cookie export <file> # 导出 cookie 为 JSON
browse cookie import <file> # 从 JSON 导入 cookie
browse cookies # 读取所有 cookie
```
### 网络
```bash
browse route <pattern> block # 阻止匹配的请求
browse route <pattern> fulfill <status> [body] # 模拟响应
browse route clear # 删除所有路由
browse offline [on|off] # 切换离线模式
browse header <name>:<value> # 设置额外的 HTTP 头
browse useragent <string> # 设置用户代理
```
### 对话框
```bash
browse dialog # 最后的对话框信息
browse dialog-accept [text] # 接受下一个对话框(可选的提示文本)
browse dialog-dismiss # 忽略下一个对话框
```
### 记录
```bash
browse har start # 开始 HAR 记录
browse har stop [path] # 停止并保存 HAR 文件
browse video start [dir] # 开始视频记录(WebM)
browse video stop # 停止记录
browse video status # 检查记录状态
browse record start # 记录浏览命令
browse record stop # 停止记录
browse record status # 检查记录状态
browse record export browse [path] # 导出为 chain-compatible JSON(重放 browse chain)
browse record export flow [path] # 导出为 YAML flow(重放 browse flow)
browse record export replay [path] # 导出为 Chrome DevTools Recorder(仅浏览器)
browse record export playwright [path] # 导出为 Playwright Test(仅浏览器)
browse record export replay --selectors css,aria [path] # 筛选导出中的选择器类型
```
### React DevTools
```bash
browse react-devtools enable # 启用(下载钩子时)
browse react-devtools tree # 组件树
browse react-devtools props <sel> # 组件的属性/状态
browse react-devtools suspense # Suspense 边界状态
browse react-devtools errors # 错误边界
browse react-devtools profiler # 渲染计时
browse react-devtools hydration # 液压计时
browse react-devtools renders # 渲染了什么
browse react-devtools owners <sel> # 父组件链
browse react-devtools context <sel> # 上下文值
browse react-devtools disable # 禁用
```
### 性能审计
```bash
browse perf-audit [url] # 完整的性能审计,带有可行的报告
browse perf-audit [url] --no-coverage # 跳过 JS/CSS 覆盖率(更快)
browse perf-audit [url] --no-detect # 跳过堆栈检测
browse perf-audit [url] --json # 结构化 JSON 输出
browse perf-audit save [name] # 保存审计报告以备后续比较
browse perf-audit compare <base> [curr] # 比较保存的基准 vs 当前或保存的审计
browse perf-audit list # 列出已保存的审计报告
browse perf-audit delete <name> # 删除已保存的审计
browse detect # 技术栈指纹(框架,SaaS,CDN,基础设施)
browse coverage start # 开始 JS/CSS 代码覆盖率收集
browse coverage stop # 停止并报告每个文件使用的/未使用的字节
browse initscript set <code> # 在每个页面加载前注入 JS
browse initscript show # 显示当前的初始化脚本
browse initscript clear # 删除初始化脚本
```
`perf-audit` 运行一个完整的性能分析,命令如下:
- **核心 Web 重要指标** - LCP、CLS、TBT、FCP、TTFB、INP,带有 Google 的良好/需要改进/糟糕的阈值
- **LCP 分析** - 确定 LCP 元素、其网络条目、阻塞链和关键路径
- **布局偏移属性** - 每个偏移量追踪到字体交换、缺少图像尺寸或动态内容
- **长时间任务属性** - 将阻塞 JS 映射到源脚本和域名,每个域名 TBT
- **资源分解** - JS/CSS/图像/字体/API 分类,带有大小和最大文件
- **阻塞检测** - `<head>` 中的同步脚本和阻塞样式表
- **图像审计** - 格式(JPEG vs WebP)、缺少尺寸、缺少 lazy-load、缺少 fetchpriority、图像过大、srcset 用法
- **字体审计** - 每个字体的 font-display 值、preload 状态、FOIT/FOUT 风险
- **DOM 复杂度** - 节点计数、最大深度、最大子树(标志 >1,500 和 >3,000 阈值)
- **堆栈检测** - 108 个框架(React、Vue、Angular、Next.js、Nuxt.js、Laravel、WordPress、Magento 等)、55 个 SaaS 平台(Shopify、Wix、Squarespace 等)、CDN、协议、压缩、缓存
- **第三方影响** - 每个域的库存,大小、请求数量和类别(分析/广告/社交聊天/监控)
- **覆盖率** - 每个文件 JS/CSS 已使用 vs 未使用的字节
- **关联引擎** - 连接 LCP 到阻塞 CSS、长时间任务到脚本、CLS 到字体交换、字体到 FCP 阻塞
- **建议** - 优先、基于数据的行动项(平台特定,当检测到 SaaS)
```bash
$ browse perf-audit https://example.com --no-coverage
核心 Web 重要指标:
TTFB 580ms good
FCP 696ms good
LCP 696ms good
CLS 0.015 good
TBT 599ms needs improvement
LCP 分析:
元素: <img src='hero.webp'>
关键路径: TTFB(580ms) -> CSS(styles.css) -> JS(vendor.js) -> Image(hero.webp) -> LCP(696ms)
复杂度:
总节点数: 4,476
警告: 超过 3000 阈值(糟糕)
推荐:
1. 为 LCP 图像添加 fetchpriority="high"
2. 为备用字体添加 font-display:swap(FOIT 风险)
3. Lazy-load YouTube 嵌入(click-to-play facade)
审计完成 13.2s(reload: 10.0s,settle: 3.0s,collect: 41ms,检测: 75ms)
```
`detect` 提供快速的堆栈指纹,无需完整的审计:
```bash
$ browse detect
堆栈:
meta-framework Next.js(生产),router: app,rsc: true
css-framework Tailwind CSS
build-tool Turbopack
基础设施:
CDN: Amazon CloudFront
协议: h2(64%)
缓存率: 74%(134/180)
DNS 域名: 24 unique(15 missing preconnect)
DOM: 4,476 节点,深度 23
第三方(4.4MB 总计):
www.youtube.com 3.0MB 45 reqs video
www.googletagmanager.com 331KB 331KB 3 reqs analytics
connect.facebook.net 214KB 2 reqs ads
```
### 转移(人工接管)
```bash
browse handoff [reason] # 切换到 Chrome 进行 CAPTCHA/MFA/OAuth(回退到 Chromium)
browse handoff --chromium # 强制使用 Playwright Chromium 而不是 Chrome
browse resume # 切回无头浏览器,返回新鲜快照
```
### 云服务提供商
```bash
browse provider save browserbase <api-key> # 保存 API 密钥(加密)
browse provider save browserless <token> # 保存令牌(加密)
browse --provider browserbase goto https://... # 使用云浏览器
browse provider list # 列出已保存的提供商
browse provider delete <name> # 删除已保存的密钥
```
API 密钥存储在 `.browse/providers/` 中以加密形式保存 - 永不向代理可见。
### 状态与身份验证
```bash
browse state save [名称] # 保存 Cookie + localStorage
browse state load [名称] # 恢复已保存的状态
browse state list # 列出已保存的状态
browse state show [名称] # 显示状态详细信息
browse auth save <名称> <网址> <用户> <密码> # 保存加密凭证
browse auth save <名称> <网址> <用户> --password-stdin # 从标准输入读取密码
browse auth login <名称> # 自动登录,使用已保存的凭证
browse auth list # 列出已保存的凭证
browse auth delete <名称> # 删除凭证
browse cookie-import --list # 列出带有 Cookie 的浏览器
browse cookie-import chrome [--domain .example.com] # 从 Chrome 导入 Cookie
browse cookie-import chrome --profile "Profile 1" # 特定浏览器配置文件
```
### 多步骤(链式)
在一调用中执行一系列命令:
```bash
echo '[["goto","https://example.com"],["snapshot","-i"],["text"]]' | browse chain
```
### 服务器控制
```bash
browse status # 服务器健康报告
browse instances # 列出所有正在运行的 browse 服务器
browse version # 打印 CLI 版本
browse doctor # 系统检查(Node、Playwright、Chromium)
browse upgrade # 通过 npm 自我更新
browse stop # 停止服务器
browse restart # 重启服务器
browse inspect # 打开 DevTools(需要 BROWSE_DEBUG_PORT)
```
### 安装
```bash
browse install-skill [路径] # 安装 Claude Code 技能
```
## 会话
并行运行多个 AI 代理,每个代理都有隔离的浏览器状态,共享一个 Chromium 进程:
```bash
# 代理 A
browse --session agent-a goto https://site-a.com
browse --session agent-a snapshot -i
browse --session agent-a click @e3
# 代理 B(同时)
browse --session agent-b goto https://site-b.com
browse --session agent-b snapshot -i
browse --session agent-b fill @e2 "query"
# 或通过环境变量设置一次
export BROWSE_SESSION=agent-a
browse text
```
每个会话都有自己的:
- 浏览器上下文(Cookie、存储、缓存)
- 标签页和导航历史
- 快照引用
- 控制台和网络缓冲区
```bash
browse sessions # 列出活动会话
browse session-close agent-a # 关闭会话
browse status # 显示总会话数
```
会话在空闲超时后自动关闭(默认为 30 分钟)。如果没有 `--session`,所有操作都在一个名为 `"default"` 的会话中运行。
对于完全的进程隔离(独立的 Chromium 实例),使用 `BROWSE_PORT` 运行独立的服务器。
### 配置文件与会话
| | `--session` | `--profile` |
|---|---|---|
| Chromium | 共享(一个进程) | 独有(每个配置文件一个) |
| 内存 | ~5MB 每会话 | ~200MB 每配置文件 |
| 状态 | 临时(自动持久化 Cookie) | 完全持久化(Cookie、缓存、IndexedDB) |
| 多路复用 | 是(并行代理) | 否(每个配置文件一个代理) |
| 用例 | 并行浏览,轻量级 | 真实登录状态,重度 |
## 原生应用自动化
通过相同的 CLI 和参考工作流,自动化 Android、iOS 和 macOS 应用:
### 启用平台
```bash
browse enable android # 安装 adb、JDK、Android SDK、模拟器、系统镜像、驱动程序 APK
browse enable ios # 构建 iOS 运行器(需要 Xcode)
browse enable macos # 构建 macOS AX 桥(需要 Xcode CLI 工具)
browse enable all # 启用所有平台
```
每个 `enable` 命令都安装所有依赖项并为该平台构建原生驱动程序。运行一次 - 所有内容都缓存以供未来使用。
### 模拟器/模拟器生命周期
```bash
browse sim start --platform ios --app com.apple.Preferences --visible
browse sim start --platform android --app com.android.settings --visible
browse sim stop --platform ios
browse sim stop --platform android
browse sim status --platform ios
browse sim status --platform android
```
- `sim start` 启动模拟器/模拟器,启动目标应用,并启动自动化驱动程序
- `--visible` 打开模拟器/模拟器窗口(默认:无头)
- 切换 `--app` 在正在运行的模拟器上重新配置目标,无需重启
- **自动安装**:Android `sim start` 在缺少时自动安装 `adb`、Java、Android SDK、系统镜像和模拟器 via Homebrew
### Android
```bash
browse sim start --platform android --app com.android.settings --visible
browse --platform android --app com.android.settings snapshot -i
browse --platform android --app com.android.settings tap @e3
browse --platform android --app com.android.settings swipe up
browse --platform android --app com.android.settings press back
browse --platform android --app com.android.settings text
browse --platform android --app com.android.settings screenshot app.png
browse sim stop --platform android
```
自动安装完整的工具链(adb、JDK 21、Android SDK、模拟器、系统镜像、AVD)。无需手动设置。
```bash
browse doctor --platform android # 检查设置
```
### iOS
```bash
browse sim start --platform ios --app com.apple.Preferences --visible
browse --platform ios --app com.apple.Preferences snapshot -i
browse --platform ios --app com.apple.Preferences tap @e2
browse --platform ios --app com.apple.Preferences swipe up
browse --platform ios --app com.apple.Preferences press home
browse --platform ios --app com.apple.mobilesafari snapshot -i # 切换应用
browse sim stop --platform ios
```
需要:Xcode。模拟器自动启动。
### macOS
```bash
browse --app "System Settings" snapshot -i
browse --app "System Settings" tap @e5
browse --app "System Settings" swipe up
browse --app TextEdit type "Hello"
browse --app TextEdit press "cmd+n" # 支持修饰键组合
```
需要:macOS,终端授予 Accessibility 权限。
### 平台标志
| 标志 | 描述 |
|------|-------------|
| `--platform android\|ios\|macos` | 目标平台(默认:浏览器) |
| `--app <名称>` | 应用包名称(Android),包 ID(iOS),或进程名称(macOS) |
| `--device <serial>` | 设备序列号(Android),模拟器 UDID(iOS) |
| `--visible` | 显示模拟器/模拟器窗口(默认:无头) |
### 统一命令界面
所有平台都支持相同的命令:`snapshot`、`text`、`tap`、`fill`、`type`、`press`、`swipe`、`screenshot`。 `@ref` 工作流是相同的 - `snapshot -i` 分配引用,然后 `tap @e1`、`fill @e2 "text"` 等。需要浏览器功能的命令在应用目标上被阻止,并显示清晰的错误。
## 工作流命令
### 流
```bash
browse flow run.yaml # 执行 YAML 自动化脚本
browse flow save login-flow # 保存当前录制为命名流
browse flow run login-flow # 执行已保存的流
browse flow list # 列出已保存的流
browse retry # 重试命令,带有回退(仅限浏览器)
browse watch # 监视 DOM 元素变化(仅限浏览器)
```
流在所有平台(浏览器、Android、iOS、macOS)上工作。每个流步骤都通过 `executeCommand()` 管道 - 按目标能力分级。录制捕获单个流步骤,而不是流包装器。
**仅限浏览器的工作流命令:** `retry`、`watch`、`har start/stop`、`video start/stop`
**仅限浏览器的导出格式:** `record export replay`、`record export playwright`
### 断言
```bash
browse expect "text 'Welcome'" # 断言页面存在文本
browse expect "count .item > 3" # 断言元素计数
browse expect "url contains /dashboard" # 断言 URL
browse expect "title 'My App'" # 断言页面标题
```
### SDK 模式
```typescript
import { createBrowser } from '@ulpi/browse/sdk';
const browser = await createBrowser();
await browser.goto('https://example.com');
const text = await browser.text();
await browser.close();
```
## 自定义可扩展性
使用 `.browse/` 中的项目本地 JSON/YAML 配置来扩展 browse:
### 自定义审计规则
`.browse/rules/my-rules.json`:
```json
[
{ "kind": "metric-threshold", "metric": "lcp", "max": 2000, "severity": "critical" },
{ "kind": "selector-count", "selector": "img:not([alt])", "max": 0, "severity": "warning" }
]
```
### 自定义检测签名
`.browse/detections/my-framework.json`:
```json
[
{ "name": "MyFramework", "detect": "!!window.__MY_FRAMEWORK__", "versionExpr": "window.__MY_FRAMEWORK__.version", "category": "custom" }
]
```
### 项目配置
`browse.json`:
```json
{
"detectionPaths": [".browse/detections"],
"rulePaths": [".browse/rules"],
"flowPaths": [".browse/flows"],
"startupFlows": ["setup.yaml"]
}
```
## 安全
所有安全功能都是可选的 - 现有工作流在您明确启用功能之前不会受到影响。
### 域名允许列表
限制导航和子资源请求到受信任的域名:
```bash
browse --allowed-domains "example.com,*.example.com" goto https://example.com
# 或通过环境变量
BROWSE_ALLOWED_DOMAINS="example.com,*.api.io" browse goto https://example.com
```
阻止 HTTP 请求、WebSocket、EventSource 和 `sendBeacon` 到非允许的域名。通配符如 `*.example.com` 匹配裸域名和所有子域名。
### 操作策略
使用 `browse-policy.json` 文件控制命令:
```json
{ "default": "allow", "deny": ["js", "eval"], "confirm": ["goto"] }
```
优先级:deny > confirm > allow > default。文件更改时热重载 - 无需重启服务器。
### 凭证保险箱
加密凭证存储(AES-256-GCM)。LLM 永远不会看到密码:
```bash
echo "mypassword" | browse auth save github https://github.com/login myuser --password-stdin
browse auth login github # 自动导航,检测表单,填充 + 提交
browse auth list # 列出已保存的凭证(不显示密码)
```
密钥在 `.browse/.encryption-key` 处自动生成或通过 `BROWSE_ENCRYPTION_KEY` 设置。
### 内容边界
用 CSPRNG 随机数分隔符包装页面输出,以便 LLM 可以区分工具输出和不受信任的页面内容:
```bash
browse --content-boundaries text
```
### JSON 输出
适用于代理框架的机器可读输出:
```bash
browse --json snapshot -i
# 返回:{"success": true, "data": "...", "command": "snapshot"}
```
## 配置
在项目根目录创建 `browse.json` 文件以设置持久性默认值:
```json
{
"session": "my-agent",
"json": true,
"contentBoundaries": true,
"allowedDomains": ["example.com", "*.api.io"],
"idleTimeout": 3600000,
"viewport": "1280x720",
"device": "iPhone 14",
"runtime": "playwright",
"detectionPaths": [".browse/detections"],
"rulePaths": [".browse/rules"],
"flowPaths": [".browse/flows"],
"startupFlows": ["setup.yaml"]
}
```
CLI 标志和环境变量覆盖配置文件值。
## 与 AI 代理一起使用
### Claude Code(推荐)
作为 Claude Code 技能通过 [skills.sh](https://skills.sh) 安装:
```bash
npx skills add https://github.com/ulpi-io/skills --skill browse
```
或直接安装:
```bash
browse install-skill
```
两个都将技能定义复制到 `.claude/skills/browse/SKILL.md` 并将所有 browse 命令添加到权限中 - 不再需要审批提示。
### CLAUDE.md / AGENTS.md
将以下内容添加到您的项目说明:
```markdown
## 浏览器自动化
使用 `browse` 进行网页自动化。运行 `browse --help` 获取所有命令。
核心工作流:
1. `browse goto <url>` - 导航到页面
2. `browse snapshot -i` - 获取交互式元素并引用(@e1,@e2)
3. `browse click @e1` / `fill @e2 "text"` - 使用引用交互
4. 页面更改后重新快照
```
### 直接询问代理
```
使用 browse 测试登录流程。运行 browse --help 查看可用命令。
```
## MCP 服务器模式
以 [MCP](https://modelcontextprotocol.io/) 服务器模式运行 browse,以便支持 Model Context Protocol 编辑器。所有 CLI 命令都可用作 MCP 工具 - 浏览器自动化、应用自动化、性能审计、检测、覆盖率、流程等。
```bash
browse --mcp
```
使用 `--json` 和 `--mcp` 获取结构化响应(`{success, data, command}`)。
> **注意:** 需要 `npm install @modelcontextprotocol/sdk` 与 browse 一起使用。
### 游标
`.cursor/mcp.json`:
```json
{
"mcpServers": {
"browse": {
"command": "browse",
"args": ["--mcp"]
}
}
}
```
### Claude Desktop
`claude_desktop_config.json`:
```json
{
"mcpServers": {
"browse": {
"command": "browse",
"args": ["--mcp"]
}
}
}
### Windsurf
```json
{
"mcpServers": {
"browse": {
"command": "browse",
"args": ["--mcp"]
}
}
}
```
## 选项
| 标志 | 描述 |
|------|-------------|
| `--session <id>` | 命名会话(隔离标签页、引用、Cookie) |
| `--profile <name>` | 持久性浏览器配置文件(自己的 Chromium,完整状态) |
| `--context [state\|delta\|full]` | 操作上下文:`state` = 页面更改,`delta` = ARIA 差异与引用,`full` = 完整的快照与引用 |
| `--json` | 将输出包装为 `{success, data, command}` |
| `--content-boundaries` | 将页面内容包装在随机数分隔符标记中 |
| `--allowed-domains <d,d>` | 阻止导航/资源超出允许列表 |
| `--max-output <n>` | 将输出截断为 N 个字符 |
| `--headed` | 显示浏览器窗口(非无头) |
| `--chrome` | 快捷方式 `--runtime chrome --headed` |
| `--cdp <port>` | 连接到 Chrome 上特定的调试端口 |
| `--connect` | 自动发现并连接到正在运行的 Chrome 实例 |
| `--provider <name>` | 云浏览器提供商(browserless,browserbase) |
| `--runtime <name>` | 浏览器运行时:playwright(默认),rebrowser(隐身),lightpanda,camoufox(反检测 Firefox),chrome |
| `--camoufox-profile <name>` | 命名 camoufox 配置文件 `.browse/camoufox-profiles/<name>.json`(仅限服务器启动) |
## 环境变量
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `BROWSE_PORT` | 自动(9400–10400) | 固定服务器端口 |
| `BROWSE_PORT_START` | 9400 | 端口扫描范围起点 |
| `BROWSE_SESSION` | (无) | 默认会话 ID 所有命令 |
| `BROWSE_INSTANCE` | 自动(PPID) | 多代理隔离实例 |
| `BROWSE_IDLE_TIMEOUT` | 1800000(30m) | 空闲自动关闭毫秒 |
| `BROWSE_TIMEOUT` | (无) | 覆盖所有命令超时(毫秒) |
| `BROWSE_LOCAL_DIR` | `.browse/` 或 `/tmp` | 状态/日志/截图目录 |
| `BROWSE_JSON` | (无) | 设置为 `1` 为 JSON 输出模式 |
| `BROWSE_CONTEXT` | (无) | 设置为 `1` / `state` | (无) | 设置为 `1`/`state`/`delta`/`full` 为动作上下文级别 |
| `BROWSE_CONTENT_BOUNDARIES` | (无) | 设置为 `1` 为随机数分隔符输出 |
| `BROWSE_ALLOWED_DOMAINS` | (无) | 以逗号分隔的域名允许列表 |
| `BROWSE_MAX_OUTPUT` | (无) | 将输出截断为 N 个字符 |
| `BROWSE_HEADED` | (无) | 设置为 `1` 为头部浏览器模式 |
| `BROWSE_CDP_URL` | (无) | 通过 CDP 连接到远程 Chrome |
| `BROWSE_PROXY` | (无) | 代理服务器 URL |
| `BROWSE_PROXY_BYPASS` | (无) | 代理绕过列表 |
| `BROWSE_SERVER_SCRIPT` | 自动检测 | 服务器 ts 路径覆盖 |
| `BROWSE_DEBUG_PORT` | (无) | DevTools 调试端口 |
| `BROWSE_POLICY` | browse-policy.json | 操作策略文件路径 |
| `BROWSE_CONFIRM_ACTIONS` | (无) | 需要确认的命令 |
| `BROWSE_ENCRYPTION_KEY` | 自动生成 | 64 个字符的十六进制 AES 密钥,用于凭证保险箱 |
| `BROWSE_AUTH_PASSWORD` | (无) | `auth save` 的密码(替代 `--password-stdin`) |
| `BROWSE_RUNTIME` | playwright | 浏览器运行时(playwright,rebrowser,lightpanda,camoufox,chrome) |
| `BROWSE_CAMOUFOX_PROFILE` | (无) | 命名的 camoufox 配置文件来自 `.browse/camoufox-profiles/` |
| `BROWSE_CHROME` | (无) | 设置为 `1` 以使用系统 Chrome |
| `BROWSE_CHROME_PATH` | 自动检测 | Chrome 可执行文件路径覆盖 |
## 架构
```
browse [--session <id>] [--platform <p>] [--app <name>] <command>
|
CLI(薄 HTTP 客户端)
|
持久性服务器(localhost,自动启动)
|
会话管理器 + 命令注册表 + executeCommand()
├── 浏览器会话:
│ ├── “default” → 浏览器管理器 → Chromium(Playwright)
│ ├── “agent-a” → 浏览器管理器 → Chromium(共享)
│ └── “agent-b” → 布浏览器管理器 → Chromium(共享)
├── 应用会话:
│ ├── “app:com.example” → AndroidAppManager → adb → 设备驱动程序
│ ├── “app:com.example.ios” → IOSAppManager → simctl → 模拟器
│ └── “app:Safari” → AppManager → browse-ax → macOS AX
└── 所有目标都实现了 AutomationTarget 接口
```
- **第一次命令:** ~2s(服务器 + Chromium 启动,一次)
- **之后每个命令:** ~100–200ms(到 localhost 的 HTTP 请求)
- 服务器在第一个命令时自动启动,在空闲 30 分钟后自动关闭
- 崩溃恢复:CLI 检测到死服务器并透明地重启
- 状态文件:`.browse/browse-server.json`(pid,端口,令牌)
## 基准测试
### vs Agent Browser & Browser-Use(令牌成本)
在多步骤浏览流程中测试了 3 个站点 - 导航,截图,滚动,搜索,提取文本:
| 工具 | 总令牌 | 总时间 | 使用的上下文(200K) |
|------|-------------:|-----------:|--------------------:|
| **browse** | **14,134** | **28.5s** | **7.1%** |
| agent-browser | 39,414 | 36.2s | 19.7% |
| browser-use | 34,281 | 72.7s | 17.1% |
browse 使用的 **令牌比 browser-use 少 2.4 倍**,比 agent-browser 少 **2.8 倍**,并且比 browser-use **快 2.5 倍**。
### 对比 @playwright/mcp(架构)
@playwright/mcp 在每次操作时转储完整的无障碍快照。browse 返回每次操作约 15 个令牌 - 代理仅在需要时请求快照:
| | @playwright/mcp | browse |
|---|---:|---:|
| `navigate` 上的令牌 | ~14,578(自动转储) | **~11** |
| `click` 上的令牌 | ~14,578(自动转储) | **~15** |
| 10 次操作会话 | ~145,780 | **~11,388** |
| 上下文消耗(200K) | **73%** | **6%** |
重新运行:`npm run benchmark`
## 更新日志
请参阅 [CHANGELOG.md](CHANGELOG.md) 以获取完整的发行历史。
## 致谢
灵感来自并最初源自 Garry Tan 的 [gstack](https://github.com/garrytan/gstack) 中的 `/browse` 技能。
## 许可证
Apache-2.0
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器