# dsh-browser-cdp — 看得见的 Agent 浏览器(CDP 接入) [简体中文](README.md) | [Français](README.fr.md) | [Deutsch](README.de.md) | [Italiano](README.it.md) | [Русский](README.ru.md) | [Español](README.es.md)

DSH >= 0.2.0-rc.1 dsh-better-sidebar >= 0.12.2 (optional) Node >= 22

> **仓库**:`github.com/drscrewdriver/dsh-browser-cdp`(原名 `dsh-ego-browser`,源自上游 [Fisfzy/dsh-ego-browser](https://github.com/Fisfzy/dsh-ego-browser))|版本历史见 [CHANGELOG.md](CHANGELOG.md) ### 版本兼容矩阵 | 依赖 | 最低版本 | 推荐版本 | 说明 | |---|---|---|---| | **DSH** (DeepSeek Harness) | `0.2.0-rc.1` | `≥ 0.2.0-rc.1 <0.2.1-0` | 0.2.0 线:peer 依赖同步锁定 `>=0.2.0-rc.1 <0.2.1-0`;宿主对插件 API 向后兼容(0.2.0 的 composer/`forkSession` 为签名扩展,插件仅作调用方,免改)。声明式设置面自 0.1.7 引入(Config `.volatile()` 字段自动生成设置表单),0.2.0 延续该形态。DSH `0.1.2-rc.1` ~ `0.1.7` 请使用 **0.17.x** 版本线,0.1.0-rc.x / 0.1.1-rc.x 请使用 v0.8.0 及更早版本 | | **dsh-better-sidebar** | `0.12.2`(可选) | `≥ 0.17.1` | 未安装时自动回退浮动观察球;`< 0.12.2` 可运行但外部链接拦截(`urlTarget`)静默降级 | | **Node.js** | `22` | — | harness 环境自带 | **DSH 全版本适配说明**:本版本(**v0.18.0 起,0.2.0 线**)面向 DSH `0.2.0-rc.1+`:相对 0.1.7 线(v0.17.x)**零代码改动**,纯依赖/元数据换代——0.2.0 宿主对插件 API 向后兼容,本插件经 `ctx.get('conversation').input` 门面投递选区(不调 `submit()`、不 override),不在 0.2.0 变更影响面内。声明式设置面自 0.1.7 引入:插件不再注册任何设置节(`ctx.settings` 注册类 API 已被宿主删除),改为在 Config schema 上以 `.volatile()` 标记可配置字段,由宿主设置页自动生成表单;volatile 字段变更通过 `loader/volatile-update` 事件热生效,无需重载插件。核心宿主 API(`defineTool`、`ctx.tools.register`、`ctx.subprocess.spawn`、`ctx.webServer.register`、`ctx.inject`、`ModuleLoader` CJS factory、`cordis.patch.yml`)沿用 0.1.2 以来形态。DSH `0.1.2-rc.1` ~ `0.1.7` 请使用 **0.17.x** 版本线。 **dsh-better-sidebar 适配说明**:本插件通过 `ctx.betterSidebar` 服务(try-catch 防御性获取)注册侧边栏 Tab 并监听外部链接。关键 API 引入版本: | API | 本插件用法 | better-sidebar 引入版本 | |---|---|---| | `registerTab()` / `openTab()` / `ctx.betterSidebar` | Tab 注册 + 打开 | v0.9.0+ | | `TabDescriptor.single` | 单实例 Tab | v0.9.0+ | | `TabDescriptor.urlTarget` | 外部链接拦截 | **v0.12.2+**(低于此版本链接拦截静默失效) | --- **DSH 版本支持详情**:v0.8.2 → v0.8.3 主要变更:合并 6 个社区 PR(root/xvfb/macOS headless 适配、rc.1 兼容、Windows 稳定性),修复无认证 `/api/bcdp/*` 路由安全漏洞、无 dsh-better-sidebar 宿主 client 启动失败(#29)、Windows 冷启动回归(#22 引入的 Xvfb 误判),并修复 gateway 设置白名单缺 `runtimeArgs`/`chromeArgs`。适配点:client 运行时改名(`@deepseek-ai/dsh-client-store`)、client 模块注册 id 与装载行名按声明包名、`dsh.client.inject` 仅声明真实模块图行、`webServer` 以嵌套注入交付(可选服务),并同步侧边栏 Tab(dsh-better-sidebar)模式。 **侧边栏支持([dsh-better-sidebar](https://www.npmjs.com/package/dsh-better-sidebar))**:当宿主安装了 `dsh-better-sidebar`(推荐 ≥ v0.12.2)时,实时观察窗注册为**侧边栏原生 Tab**——「Agent 浏览器」出现在侧边栏「+」菜单中,点击即打开并随侧边栏抽屉固定展示;agent 首次调用 `bcdp_*` 工具时会自动打开该 Tab(v0.8.5 起按调用会话作用域打开,多会话不再弹错位置)。未安装 `dsh-better-sidebar` 时自动回退为右下角**浮动观察球**(`#dsh-ego-fab`)模式。两种形态共用同一套 SSE 实时推流 / 点击 / 输入 / 下载捕获能力。观察窗还提供一个「弹出窗口」按钮:无头(headless)运行的 agent 浏览器可一键替换为同 Profile 的有头窗口(标签页保留),方便手动接管。 **登录态导入(v0.8.5 新增)**:工具 `bcdp_login_import`,把你日常 Chrome/Edge/Brave 里的登录 cookie **按域名**复制进 agent 浏览器(真实二进制无头启动 + CDP 透传读取,兼容 Chrome 127+ 的 App-Bound Encryption,不做离线解密;源浏览器运行中可选择优雅关闭后导入,窗口下次启动自动恢复)。cookie 值不出现在任何日志与输出中;导入前自动备份源 cookie 库,异常清空自动还原。配合默认的磁盘持久化 Profile,导入的登录态跨重启永久保留。 一款 **CDP 浏览器代理**:把 [CitroLabs/ego-lite](https://github.com/CitroLabs/ego-lite)(给 AI Agent 用的 Chromium)作为内置运行时接入 DeepSeek Harness,以 **38 个结构化 `bcdp_*` 工具**驱动浏览器,并配一套**实时观察前端口**——agent 后台操作网页时,你能像看直播一样看到它正在浏览的每个页面,还能直接操作它。 **一点私藏的独特之处(self-observation)**:agent 用的就是这一个 Chromium——连它操作 **DSH 自身**(管理会话、任务看板、调设置)时,观察窗也实时显示、你能随时接手。不只是"看得见 agent 在网页上干活",连 agent 操作 DSH 界面本身都是全程可见、可掌控的。 **开箱即用**:插件包内置 ego 运行时(`runtime/`,MIT,见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md))——无需克隆官方仓库、无需手动构建,`--no-sandbox` wrapper 随包自带,root / Docker / 无显示器一键跑。 --- ## 我们的真正优势(不是口号,是能对照代码和竞品核实的能力) 同样把 ego-lite 接进 DSH,市面上已有同类插件用它**只做了 3 个工具**——一个 `run` 脚本、一个 `help` 指南、一个 `status` 体检,浏览器仍是**后台黑盒**。本插件走的是另一条路:**把黑盒打开,并且一上来就把"看"和"控"的能力做到位**。 | 能力 | 本插件(本仓库) | 同类插件(Da1dr1em/dsh-ego-browser) | |---|---|---| | 结构化工具数 | **38 个**,职责单一、可确定性调用 | **3 个**(`run`/`help`/`status`) | | 实时观察窗(CDP JPEG / FFmpeg H.264 双后端 + 标签条 + 历史抽屉) | ✅ 有 | ❌ 无 | | 监控窗鼠标**直接操作**真实浏览器(点击/拖拽/滚动回传 CDP) | ✅ 有 | ❌ 无 | | **观察窗点选元素 → 捕获并引用进对话输入框**(`[CDP-PICKS]` 结构化块,人工指认目标) | ✅ 有 | ❌ 无 | | worker 单实例守卫 + 崩溃/重复自愈 | ✅ 有 | ❌ 无 | | 下载捕获 `bcdp_download` / 人机验证检测 `bcdp_captcha`/`bcdp_page_info` | ✅ 有 | ❌ 无 | | 平台自适应(Linux/macOS/Windows 自动探测 + root/无头/`--no-sandbox` 兜底) | ✅ 全平台 | 仅 Windows 预览宿主,需手动配 | | 登录态落盘持久化 `bcdp_auth_flush` | ✅ 有 | ⚠️ 仅文档级说明 | **关键差异三条:** - **看得到**:别家是"跑完告诉你结果"的黑盒;我们实时推流,你**看着 agent 操作**,卡在验证码/走岔立刻发现。 - **控得住**:别家只读;我们监控窗**直接驱动**同一个 agent 浏览器,需要时你亲手接管(缩放/拖拽/点击),不必打断 agent 重来。 - **指得准**:你在观察窗里**点选**页面元素,插件捕获其 `backendNodeId`/`tag`/`id` 与语义描述,以 `[CDP-PICKS]` 结构化块并入对话输入框草稿(同页多元素自动合并编号)——agent 拿到的是精确目标,不用猜"你说的按钮是哪个"。 > 以上对比基于公开可见的可核实事实:本仓库代码(`bin/cdp-cast-worker.mjs` 实时推流 + CDP 输入回传、`lib/index.js` 38 个注册工具、`lib/cast-server.js` host 桥接、`lib/client.js` 的 `deliverPickToConversation` 点选引用)与同类插件的源码/README(其 `src/tools.ts` 仅注册 `ego_browser_run` / `ego_browser_help` / `ego_browser_status`)。此文档不含对任何他人的贬低——我们只陈述自己多实现并验证了哪些能力。 **相对 [ego-lite](https://github.com/CitroLabs/ego-lite) 本体,我们多做了这些(都可对照本仓库代码核实):** | 能力 | 说明(对应代码) | |---|---| | **观察窗前端口** | ego-lite 本体是无头 CLI(只有 heredoc 脚本 + 文本输出);我们在其上加了 **SSE 实时推流 + 标签条 + 历史抽屉 + 监控窗鼠标直操 + 点选元素引用进输入框**(`bin/cdp-cast-worker.mjs`、`lib/cast-server.js`、`lib/client.js` 的 `createPickControl`/`deliverPickToConversation`),让"看"、"控"、"指"成为一等能力 | | **开箱即用 + 跨平台自足** | `resolveEgoEnv` 自动探测 Chrome/Edge/Brave,内置 `--no-sandbox` wrapper,root / Docker / 无显示器免配置(`lib/index.js`);不必像官方那样先装一个 GUI 宿主 | | **健壮性层** | 冷启动自动重试(只重试 CDP 瞬态,不吞真错)、worker 单实例守卫 + 崩溃自动重启、插件卸载 fire-and-forget 不阻塞宿主退出、前端帧缓存上限(`withWarmupRetry` / `makeEnsureWorker` / `frameCache`) | | **运维型工具** | `bcdp_doctor`(环境体检)、`bcdp_captcha`(人机验证探测)、`bcdp_auth_flush`(登录落盘)、`bcdp_login_import`(系统浏览器登录态导入)、`bcdp_http`(浏览器上下文请求)等,是原生 CLI helper 没有的一层 | | **self-observation** | agent 操作 DSH 自身界面时同样实时可见、可接手 | > 我们不声称媲美官方 macOS App 的内核级快照或原生多窗口体验;本仓库解决的是"把同一套浏览器能力带进 DSH + Linux/WSL + 看得见"这件事。 --- ## 它解决什么问题 通用浏览器不是为 agent 设计的,而 Web 上大量交互(登录态、验证码、动态渲染、表单、需真人会话的站点)只有真浏览器能面对——这正是本插件继承自上游 ego 系的 **"让 agent 用你已登录的浏览器,而不打扰你"**([官网](https://github.com/CitroLabs/ego-lite))的由来。 本插件把它接进 DSH,并把最痛的一点——**你看不见 agent 在干什么、也插不上手**——用一套观察窗解决: > 🌐 小球一点看直播;🟦 标签条切换/关闭;🕘 历史抽屉回看;🔍 缩放拖拽;🖱️ 监控窗直接接管真实浏览器。**一句话:让 agent 在浏览器里干活,你在旁边既看得见、又随时能接手。** ### 几个常见的上手场景 - **文献 / 数据抓取**:让 agent 登录知网 / 谷歌学术翻页收集,你在观察窗看着它滚动、点下一页、下载 PDF,中途卡住立刻能发现。 - **表单与登录**:agent 填表到一半,观察窗弹出验证码——你直接接管把验证码点了,再交还给 agent 继续。 - **QA / 冒烟测试**:让 agent 在自己产品上点一圈,观察窗等于一台"会说话的录屏",顺手还能回看历史轨迹。 - **看 agent 操作 DSH 自身**(self-observation):agent 在管理会话 / 调设置时,观察窗同样全程可见、可接手。 --- --- ## 前置条件 | 要求 | 说明 | |---|---| | Node ≥ 22 | harness 环境自带 | | **任意 Chrome / Chromium / Brave / Edge** | 自动发现,或 `EGO_LINUX_CHROME` 指定;root 下用自带 wrapper | | DSH + dshx | 插件装载机制 | | 带图形界面的 DSH Web(观察窗) | headless 会话仍可用 `bcdp_*` 工具,仅无观察窗 | ## 安装 **方式一:GitHub 直装(推荐)** ```sh dsh plugin --profile web add github:drscrewdriver/dsh-browser-cdp # 也可锁定到某个 commit / tag: dsh plugin --profile web add github:drscrewdriver/dsh-browser-cdp#v0.9.0 ``` > `github:` 安装由 pnpm 经 `codeload.github.com` 拉取仓库 tarball,**无需向 npm registry 发包**;直接使用仓库中**预构建入库的 `lib/`**(`files` 仅含 `lib/`、`bin/`、`runtime/`、`cordis.patch.yml`、`dsh-plugin.json`),因此**不触发任何构建脚本**,也不需要 devDependencies。host 入口 `lib/index.js`、客户端 `lib/client.js`、worker `bin/cdp-cast-worker.mjs` 均随仓库分发。 **方式二:本地 tarball / git URL** ```sh dshx install dsh-browser-cdp # tarball 或 git URL 均可 dshx list # 应显示:[on] dsh-browser-cdp ``` > **包名迁移说明**:本插件包名是 **`dsh-browser-cdp`**(曾用名 `dsh-ego-browser`、别名 `@dsh-external/ego-browser`)。DSH Desktop 2.0.5 起增加了「profile 依赖名 == 包实际 name」的一致性校验,若 profile 仍用旧名引用,启动会挂进恢复模式。升级后请把 profile 的 `package.json` 依赖键 **和** `dsh.profile.bundles` 条目**两处**都改为 `dsh-browser-cdp`: ```diff - "dsh-ego-browser": "github:Fisfzy/ego-browser", + "dsh-browser-cdp": "github:drscrewdriver/dsh-browser-cdp", ``` ```diff - "dsh-ego-browser", + "dsh-browser-cdp", ``` 观察窗设置中可选 `captureBackend=auto|cdp|ffmpeg`(默认 `auto`,当前解析为 CDP)、画质档位、CDP FPS/JPEG 质量/最大宽度,以及 FFmpeg FPS/最大宽度/码率/编码器/自定义路径。插件先检测自定义路径、系统 PATH 和托管缓存;GitHub 下载可用 `githubMirror` 替换 `https://github.com`,例如 `https://gh-proxy.com/github.com`。FFmpeg 码率范围为 500-20000 kbps,低/平衡/高档默认 2000/4000/8000 kbps。 无需宿主侧任何配置:`resolveEgoEnv` 自动探测 root / 无显示器并兜底。观察窗 host 路由(`/api/bcdp/spaces` 等)仅在有 HTTP server 时注册,headless 是安全 no-op。 ## 连接方式:CDP 端点 / 本机 ego CLI **连接目标直接在设置里增删改**(0.18.1 起,与 0.17.x 线同源):设置卡有两处入口——「起子插件设置」family 区的本插件 tab(装了 `dsh-thinking-levels` 时),以及**插件详情页**的设置卡(`plugins.bundle.config`,不装 thinking-levels 时的独立入口);两处渲染同一份组件。每行支持:启用开关、激活、标签/端点/CLI 路径就位编辑、逐行**探测**、上移/下移、删除(删激活行会同时清空激活,**绝不顺延**);底部内联表单直接添加 CDP 端点或本机 ego CLI(第二条本机 CLI 会被拒绝)。写回落在活动 profile 的 `cordis.patch.yml`,跨重启保留。0.18.1 之前,连接序列只能在 profile 的 `cordis.patch.yml` `links` 中手工维护。 设置面板里的连接列表是**有序**的——**顺序即优先级**,被激活的那一项驱动每一次 `bcdp_*` 调用。列表元素有两种类型: | 类型 | 它做什么 | 约束 | |---|---|---| | **CDP 端点** | 把一个已开调试端口的浏览器地址交给内置运行时(注入 `EGO_LINUX_CDP_URL`),运行时**附着**上去 | 可多条 | | **本机 ego CLI** | 由本机 ego CLI **自己**驱动它本机的 ego-lite 浏览器——**不注入任何端点** | **仅限本机,全局至多一条** | **为什么需要第二种**:注入用的 `EGO_LINUX_CDP_URL` 是**内置 Linux 移植版**的私有契约,macOS 上用 `ego lite` app 附带的那个原生 `ego-browser` **根本不读它**。所以在只有"CDP 端点"这一种类型时,macOS 用户无法用上自己那个已登录的 ego-lite——只能连远端端口,或让移植版另起一个 stock Chromium。本机 CLI 类型补的就是这条路。 解析顺序(`cliPath` 留空时):显式路径 → PATH 上的 `ego-browser` → macOS app 包内 helper(`/Applications/ego lite.app/…/Helpers/ego-browser`)→ 插件内置运行时。 两个默认值值得知道: - **`--sdk-path` 默认关闭**:默认用 CLI 自带的 harness(官方配对的那套);打开后才注入本插件的 harness 包。若 CLI 不认这个旗标,插件会记一条提示并**自动重试一次不带它**——不会因此废掉整条链路。 - **就绪探测会走一次真实的 heredoc**(与我们干活用的是同一条通道),所以它**不是免费的**:探测可能冷启动后端浏览器(实测内置移植版约 1.3 s)。 与其它开关的关系: - `cdpMode`:`auto` 按激活项(两种类型都行);`remote` **只接受 CDP 端点**,激活项是本机 CLI 时会显式报 `mode-kind-mismatch`;`local` 走受管本地启动器。 - `remoteEnabled`(远端总开关)**只管远端 CDP**,不影响本机 CLI 连接。 - `allowLocalFallback` / `localHeadless` / `localUserDataDir` 只作用于 CDP 端点的回落与受管启动。 `bcdp_doctor` 会报告当前序列类型计数、CLI 实际解析到的路径与形态,以及(若同机装了上游 `dsh-ego-browser`)一条共存提示。 ## 工具清单(38 个,前缀 `bcdp_`,完整索引见 `bcdp_help`) | 类别 | 工具 | |---|---| | 任务空间 | `bcdp_space_open` `bcdp_space_close` `bcdp_status` | | 页面读取 | `bcdp_snapshot`(语义树) `bcdp_page_info` `bcdp_read_element` | | 导航/等待 | `bcdp_navigate`(复用 tab) `bcdp_wait` `bcdp_wait_for_selector` `bcdp_wait_for_url` `bcdp_wait_for_response` | | 交互 | `bcdp_click` `bcdp_fill` `bcdp_hover` `bcdp_drag` `bcdp_select` `bcdp_check` `bcdp_key` `bcdp_scroll` | | 执行/调试 | `bcdp_js`(页面求值) `bcdp_cdp`(原始 CDP) `bcdp_cli`(任意 heredoc) `bcdp_script`(多步脚本) | | 输出 | `bcdp_screenshot` `bcdp_download` `bcdp_upload` | | 会话/安全 | `bcdp_auth_flush`(登录落盘) `bcdp_login_import`(跨浏览器登录态导入) `bcdp_captcha` `bcdp_dialog` | | 元工具 | `bcdp_help` `bcdp_doctor` `bcdp_http` | | 评审(JEV/Laya,外接判定服务可选) | `bcdp_jev_status` `bcdp_jev_frame` `bcdp_jev_ask` `bcdp_jev_run` `bcdp_jev_attempt` | ## 观察窗怎么用 右下角 **🌐 常驻小球** → 点开: - **主画面**:agent 当前页面实况;点击/拖动/滚轮直接操作页面,Ctrl+滚轮缩放视图、Ctrl+拖动平移,双击复位。点击画面后可直接键盘输入,支持中文 IME、粘贴、Tab/Enter/方向键及 Ctrl/Cmd 快捷键。 - **选择元素**(点选引用):点一下工具条进入点选模式,再点实时画面里的任意元素——插件捕获其 `backendNodeId`/`tag`/`id` 与语义描述,以 `[CDP-PICKS]` 结构化块并入对话输入框草稿;同一页面的多次点选自动合并进同一块并依次编号,agent 按编号精确取用。浮动观察球与侧边栏 Tab 均可用。 - **标签页条**:顶部横排,点选切换,`×` 关闭。 - **历史抽屉**(🕘):按时间回看访问轨迹。 - 操作时下方网址行就地显示提示,2 秒后恢复。 - 面板关闭、sidebar Tab 隐藏或组件卸载后,1.5 秒宽限结束即停止画面生产。仅把 DSH 窗口切到后台不会停止串流,避免回前台时反复重建 WGC/FFmpeg;异常关闭由 120 秒 worker lease 超时兜底。 ### 画面后端 - `cdp`:`Page.startScreencast` JPEG,默认 20 FPS。每个源帧立即按 Chrome 提供的帧 ID ACK,只保留最新待发帧;仅捕获当前观看标签,静态页恢复截图默认 3 秒一次。 - `ffmpeg`:Windows 以 `gfxcapture(hwnd)` 直接采集目标 Chrome 窗口的 D3D11 surface;其他平台使用显示来源 crop。随后编码 H.264 fragmented MP4 → HTTP 二进制 chunk → MediaSource `