# BrowserSkill

> 把 BrowserSkill (bsk) 命令行包成 DSH 原生 browser_* 工具，让 AI 在不退出你浏览器的情况下驱动真实 Chromium。

## Metadata

- Author: [@Tencent](https://github.com/Tencent)
- Repo: <https://github.com/Tencent/BrowserSkill.git>
- GitHub: [Tencent/BrowserSkill](https://github.com/Tencent/BrowserSkill)
- Stars: 1,222
- Language: TypeScript
- License: [MIT](https://spdx.org/licenses/MIT.html)
- Topics: `agent`, `browser-use`, `dsh-plugin`
- Forks: 99
- Open Issues: 29
- Last push: 2026-08-20T12:45:25.000Z
- Added: 2026-08-20T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:Tencent/BrowserSkill/packages/dsh-plugin-browserskill
```

## Wiki

## 一句话定位
把 BrowserSkill（命令行叫 bsk）的浏览器自动化能力包成 DeepSeek Harness 的原生模型工具，让 AI 在你已有的浏览器里完成任务而不打断你日常浏览。

## 核心能力
- 在 DSH 进程内注册 11 个 `browser_*` 模型工具：会话启停 / 列表、导航、快照、语义观察、点击、填写、按键、截图、设备模拟，每个工具对应一次 `bsk <cmd> --json` 调用
- 同时驱动多个浏览器会话：每次 `browser_session_start` 返回独立的会话 id，最多 5 个并发；不传 `session` 参数时落到最近一次操作过的那个会话
- 严格的所有权边界：插件只跟踪自己启动的会话，传外部会话 id 会被直接拒绝；列表工具也只显示自己拥有的会话，卸载时只会清理自家会话，绝不误伤其他程序共享的 bsk 守护进程里的会话
- 每会话串行执行命令：bsk 守护进程一次只接受一个未完成的命令，插件用每会话 FIFO 把模型工具调用和后台观察流量排进同一条队列
- 渐进式披露：默认 `lazyTools=true` 时，11 个工具的 schema 不会出现在系统提示里，等模型真的调一次 `browser-skill`（或用户输入 `/browser-skill`）后整套工具才会在当前进程剩余生命周期里全部现身
- 取消语义打通：DSH 的取消信号会传到 runner，SIGTERM 杀掉正在执行的 bsk 子进程（2 秒不退就 SIGKILL），模型这边可以继续下一步
- DSH Web UI 浮窗观察：每个自有会话有一张实时缩略图、当前动作、计时，可拖动 / 缩放、可一键中断当前命令、可升级为原生画中画窗口；前端通过宿主 webServer 提供的 loopback 路由拿数据
- 启动时做一次轻量探针：插件加载后立刻跑 `bsk --version`，缺失时提前打 warning，第一次工具调用会返回安装指引而不是裸的 spawn 错误

## 技术实现
- **语言**: TypeScript
- **关键依赖**: `@deepseek-ai/cordis`（^4.0.1，插件注入与配置校验）、`@deepseek-ai/dsh-tools` + `@deepseek-ai/dsh-llm`（^0.1.0-rc.6，工具注册与内容块类型）、`@deepseek-ai/schemastery`（^3.18.1，Config Schema）、`node:child_process`（spawn bsk 子进程）
- **架构模式**: 双面 Cordis 插件（`dsh.bundle.patch` 注入 `tools` 服务；`dsh.client` 注入 web 前端 React 工具视图），通过 Schemastery `Config` 校验配置；启动时建立会话注册表 + 每会话 FIFO 执行器 + 观察服务三件套，再用 `ctx.inject(["webServer"], ...)` 延后挂载 HTTP 路由；模型可见的工具集走"渐进式披露"，skill 调用前只挂目录项、不挂 11 个工具 schema
- **入口文件**: `src/index.ts`（插件 apply 入口 + Config Schema）、`src/tools.ts`（11 个模型工具定义）、`src/runner.ts`（bsk 子进程 spawn + 取消 / 超时 / 错误信封解析）、`src/sessions.ts`（会话所有权注册表）、`src/lazy-tools.ts`（技能调用的工具套揭示监听）、`src/observation.ts` + `src/observation-http.ts`（观察服务与 loopback HTTP 路由）

## 适用场景
当你希望 AI 在你的真实浏览器里完成需要登录态、需要看到视觉界面的任务（比如抓取需要登录的内容、跨页面表单填写、模拟移动端表现、操作你自己已有的标签），又不想为它单独再开一个测试浏览器账号时，这个插件就是桥梁。它借走的是浏览器扩展隔离出来的窗口，你日常用的标签页不受影响，AI 完成动作或你按中断后窗口会被归还。

## 前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DeepSeek Harness | 0.1.0-rc.6+ | 由 `peerDependencies` 中 `@deepseek-ai/cordis ^4.0.1` 与 `@deepseek-ai/dsh-* ^0.1.0-rc.6` 推导；需要在同时挂载 `tools`、`skills` 与 `webServer`（仅 Web 端需要）服务的宿主里运行 |
| Node.js | 未声明 | package.json 未声明 `engines`；源码仅使用 `node:child_process` / `node:fs/promises` / `node:os` / `node:http` 等内置模块，无原生依赖 |
| 浏览器运行时 | macOS（Apple Silicon / Intel）、Linux（x64 / ARM64）、Windows x64 | 由 bsk CLI 决定，插件本身跨平台（无 `os` / `cpu` 限制） |
| 浏览器 | Chrome、Microsoft Edge | 其他 Chromium 内核浏览器理论可用，Firefox 暂未支持 |
| 原生模块 | 无 | 纯 TypeScript，零原生依赖 |

## 安装方式
```bash
dsh plugin --profile web add github:Tencent/BrowserSkill/packages/dsh-plugin-browserskill
```

## 配置项
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| bskPath | string | bsk 可执行文件路径，默认从 PATH 里找 `bsk` | `bsk` |
| defaultTimeoutMs | number | 每次 bsk 命令的超时（毫秒） | `120000` |
| maxSessions | number | 允许同时开启的浏览器会话上限 | `5` |
| observationEnabled | boolean | 是否跟踪每个会话的动作 / 链接 / 缩略图状态，用于 Web 端浮窗 | `true` |
| thumbnailIntervalMs | number | 会话活跃时的缩略图刷新节奏（毫秒） | `1500` |
| idleIntervalMs | number | 会话空闲时的缩略图刷新节奏（毫秒），也是"最近活动"窗口 | `8000` |
| lazyTools | boolean | 是否启用渐进式披露——把 11 个 `browser_*` 工具的 schema 隐藏在系统提示里，直到 `browser-skill` 被调用一次再揭示 | `true` |

## 常见问题

**Q: 不装 bsk CLI 和浏览器扩展能跑这个插件吗？**

A: 能加载，但所有 `browser_*` 工具调用都会失败。插件加载时只会打一条 warning；第一次工具调用时 runner 会捕获到 spawn 错误，并返回一条带安装链接的人话指引，而不是裸的 ENOENT。

**Q: 一个会话结束后，浏览器扩展里的 Agent Window 会自动关掉吗？**

A: 会。`browser_session_stop` 会调用 `bsk session stop <id>`，由浏览器扩展回收对应的 Agent Window；插件卸载（unload）时会按 owned 列表把所有还活着的会话一并关掉，释放 bsk 子进程。

**Q: 插件会把浏览器会话存到哪里？跨次启动还在吗？**

A: 只存内存。`SessionRegistry` 是一个进程内的 Map，卸载插件即丢失；下次再启动需要重新走 `browser_session_start`。`lazyTools` 在会话恢复时会扫描持久化事件日志，发现历史里已经成功调用过 `browser-skill` 也会自动揭示工具套，但已关闭的会话不会复活。

**Q: 观察浮窗的截图会被外网访问到吗？**

A: 不会。这几条路由只接受 loopback 请求（`localhost` / `127.0.0.0/8` / `[::1]`），且复制了 DSH 给自家 `/api` 路由加的浏览器信任栅栏：Origin 与 Host 必须一致，`sec-fetch-site: cross-site` 一律拒绝，POST 必须 `application/json`。如果把 DSH webServer 绑到 `0.0.0.0` 再通过 LAN 访问，栅栏会主动失败——这是设计要求，不是 bug。

**Q: 我能不能绕过插件，直接 `bash` 调用 `bsk`？**

A: 不要。skill 的 prelude 里明确写了：DSH 里的浏览器任务必须走注入的 `browser_*` 工具，绕过插件直接调 `bsk` 会丢失会话所有权、观察浮窗、工具卡片和卸载清理；模型视角下这种"绕过去"的调用被认为是错误行为。

**Q: 浮窗里的"中断"按钮和聊天里的 Stop 按钮是一回事吗？**

A: 行为等价，都是给当前正在运行的 bsk 子进程发 SIGTERM，中断这一次命令；agent 主循环不会因为一次命令被中断就停下，会按既定逻辑继续。

## 上手难度
进阶 — 需要先装好 bsk CLI 和浏览器扩展两件本地依赖，并理解插件只跟踪"自己启动"的会话这条边界规则，但配置项少且全部可选，开箱即可工作。

## 已知问题与限制
- 长时运行类命令（如 `bsk record`）目前还**不会**通过 `ctx.jobs` 走后台任务通道，仍作为同步工具调用阻塞到完成，已在 README 中列为后续工作
- `bsk console` 与 `bsk network` 这两个 CLI 动词目前**还没有**对应的 `browser_*` 工具，skill prelude 明确写了这点
- Web UI 的画中画（Document PiP）按钮依赖浏览器原生能力，Chrome / Edge 支持但需要一次用户手势触发；不支持 Document PiP 的浏览器会直接隐藏该按钮而非降级
- 观察浮窗相关 HTTP 路由要求宿主绑定在 loopback 地址；试图把 DSH webServer 绑到 `0.0.0.0` 再走 LAN 访问会被浏览器信任栅栏主动拒绝——这是预期行为，需要跨网访问必须自行在前面再加一层鉴权
- 工具调用必须通过 `browser_session_start` 拿到自家会话 id 之后才能用，其他工具在"还没有任何会话"时会直接报错；`browser_session_list` 不会显示其他程序共享 bsk 守护进程创建的会话（这是设计而非 bug）

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [BrowserSkill](https://deepseek-plugin.org/plugins/Tencent/BrowserSkill/packages/dsh-plugin-browserskill)
Wiki generated by AI (model: `MiniMax-M3`)
