dsh-site-bridge
Verifieddsh-site-bridge · v0.11.2 · MIT
Chrome/Edge MV3 bridge for DeepSeek Harness: capture page markup (DOM, styles, selectors) and BFF traffic (xhr/fetch with headers and bodies) into a workspace snapshot bundle, drive the page with trusted CDP input, and verify injected scripts. Authorizati
Install
dsh plugin add dsh-site-bridge Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Creators
Readme
dsh-site-bridge
把 DeepSeek Harness 的眼睛和双手放进你自己的浏览器。 把页面的结构与其 BFF 流量抓取成智能体可读的文件,用可信输入驱动页面,并在同一个标签页里验证你刚写好的扩展。
两部分,一座桥:
| 部分 | 作用 |
|---|---|
DSH 插件(lib/) |
维护本机回环桥接,向模型提供八个工具,并把快照包写入会话工作区。 |
MV3 扩展(extension/) |
运行在你的 Chrome/Edge 配置中,使用你的 Cookie,通过 CDP 抓取结构与网络,用真实输入事件驱动页面。已本地化:English、Русский、中文。 |
两者缺一不可:插件承载面向模型的接口与文件,扩展承载浏览器会话与保真度。
为什么需要它
写一个嵌入别人网站的扩展,本质上是一场考古:页面结构到底是什么、哪个选择器能活过下次发版、这个按钮调用了哪个 BFF 接口、请求体长什么样。手工做这些就是 DevTools、复制粘贴和猜测。
这个项目把考古变成一次抓取:
site_capture → captures/<host>/<timestamp>/
dom.html 被抓区域序列化后的结构
dom.json 元素树:盒子、属性、选择器候选
styles.json 关键节点的计算样式 + 主题 CSS 变量
selectors.md 稳定选择器清单,并说明每个为什么稳定
network.jsonl 每个抓到的 xhr/fetch,每行一个 JSON
api.md 按 method+path 分组的接口,以及请求/响应契约
screenshot.png 可选的整页截图
智能体像读普通源码一样读这些文件,然后写扩展。接着 site_inject 把这段代码跑在活页面上,"应该能用" 就变成 "在这里能用"。
功能
- 结构 —— 带盒子与可见性的元素树、交互节点的计算样式、主题 CSS 变量,以及按稳定性排序的选择器候选(
data-testid>id>name>aria-label> class 路径 > 位置路径),每个都在活的 DOM 上检查过唯一性。 - BFF 流量 ——
xhr/fetch的方法、状态、请求头、请求体、响应头、响应体,且只针对被检查的站点。 - 可信输入 —— 通过 CDP
Input.*/DOM.setFileInputFiles完成点击、输入、下拉、按键、滚动和文件上传:这些事件页面无法与真人操作区分。 - 虚拟光标 —— 一个移动到目标的 DOM 覆盖层,并在该坐标发出真实鼠标事件,用于忽略合成
click()的控件。 - 深层选择器 ——
host >>> inner可以穿过开放的 shadow root 与同源 iframe;点击坐标会按 iframe 偏移校正。 - 后台标签页可用 —— 标签页不在前台时,读取、点击、输入和截图仍然可用(Chrome 只在后台限制定时器与动画)。
- 不保存任何凭据 —— 见安全。
与浏览器自动化插件的区别
有些插件给智能体提供 browser_* 工具:导航、点击、输入、读取页面。本项目不是其中之一,虽然这些都
能做——这里的输入是用来验证抓取结果的工具,而不是产品本身。
产品是抓取:带盒子与计算样式的 DOM、主题 CSS 变量、经过唯一性校验的选择器候选,以及站点自身的 xhr/fetch(含请求头与请求体),全部写成智能体可读的文件。自动化的作用是让「这个选择器可用」和 「这个 BFF 调用能带着我的 Cookie 通过」在活页面上被验证,而不是被假设。
实际后果:本项目是为编写面向某个具体网站的扩展而做的,输入工具用来在活页面上验证这些工作,而不是 用来浏览网页。
环境要求
- 带
dshCLI 与配置档(Desktop 或 Web)的 DeepSeek Harness。 - Chrome 或 Edge 125+(扩展依赖
chrome.debugger与 MV3 service worker)。 - Node.js 22+,用于
tools/里的工具和测试。
安装
1. 宿主部分
dsh plugin --profile desktop add dsh-site-bridge
以上会安装已发布的 npm 包。从本地克隆安装则用:
# 在仓库根目录
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\install.ps1
脚本会把插件链接进你的配置档、写入 dsh.profile.bundles,并把扩展复制到 %USERPROFILE%\.dsh\site-bridge\extension。等价的手工步骤:
dsh plugin --profile desktop add <本仓库路径>
如果 CLI 没写入,请把 "dsh-site-bridge" 加到 %USERPROFILE%\.dsh\profiles\desktop\package.json 的 dsh.profile.bundles 中,然后重启 DSH —— 宿主部分在配置档启动时加载。
2. 浏览器部分
chrome://extensions→ 打开开发者模式 → 加载已解压的扩展程序 →%USERPROFILE%\.dsh\site-bridge\extension。- 打开扩展弹窗。它会显示端口和
bridge.json的路径(site_status也会打印同样内容)。 - 点击 导入 bridge.json(Import bridge.json)并选择该文件,或直接粘贴令牌 —— 会自动保存,无需按钮。
- 打开要操作的页面,点击 连接此标签页。
Chrome 会显示「已开始调试此浏览器」提示条:这正是全部功能所依赖的 CDP 会话。点击断开后消失。
弹窗界面跟随浏览器语言:英语、俄语、简体中文位于 extension/_locales。
用法
site_status → 网桥状态、配对路径、标签页
site_tabs {action:"list"} → 标签页;claim/use/release/open/close/focus
site_network {action:"start"} → 开始录制,然后在页面上操作
site_capture {screenshot:true} → 把快照包写入工作区
site_snapshot {limit:40} → 带稳定选择器的可交互元素
site_text {selector:"#cart"} → 可见文本(带上限),用于验证
site_act {steps:"[...]"} → click/fill/type/press/scroll/upload/wait/back/eval
site_pick {action:"wait"} → 由人点击元素并写备注
site_cursor {x,y,click:true} → 虚拟光标,真实鼠标事件
site_shot {fullPage:true} → 截图保存到 captures/shots/*.png
site_inject {js:"..."} → 在页面里执行你的脚本以验证
编写页内扩展的典型循环:
site_tabs→ 绑定页面。site_capture→ 阅读selectors.md、styles.json、api.md。- 在你自己的仓库里写 userscript / content script。
- 用
site_inject注入脚本体 → 确认锚点能找到、BFF 调用能带着浏览器 Cookie 通过。 - 针对快照标记为脆弱的选择器继续调整。
弹出窗口与工具是同一条通道
弹出窗口是给键盘前的人的双手控制:连接标签页、断开、开始录制、选择元素。智能体通过工具可以做同样
的事,包括对 list 中任意标签页执行 site_tabs {action:"claim"}。连接按钮是人的操作,而不是权限
闸门——能否驱动浏览器只由网桥令牌决定。
弹出窗口中的暂停按钮从浏览器一侧切断连接:扩展停止轮询并拒绝所有命令,任何工具都无法访问它,也无法恢复。只有该按钮可以恢复,且状态在 worker 重启后仍然保留。
架构
┌──────────────────────────── DSH 宿主 ────────────────────────────┐
│ tools (site_*) ──► 网桥:127.0.0.1、令牌、long-poll 队列 │
│ 写入时脱敏 ──► 内存缓冲 ──► 快照包写入 │
└───────────────────────────────┬───────────────────────────────────┘
│ HTTP long-poll(不使用 websocket)
┌───────────────────────────────┴───────────────────────────────────┐
│ MV3 service worker: chrome.debugger ──► CDP │
│ Network domain → 带请求头与请求体的请求 │
│ Input domain → 可信鼠标/键盘、文件上传 │
│ Runtime domain → DOM 快照、选择器、注入脚本 │
│ popup:配对、目标标签页、录制开关(ru / en / zh) │
└────────────────────────────────────────────────────────────────────┘
协议很小,详见 docs/protocol.md。
安全
- 凭据不离开浏览器。 扩展不读取 Cookie 或令牌:页面自己发请求,浏览器自动附带。网桥能看到传输中的值,但
cookie、authorization、x-csrf-token、x-api-key、set-cookie等请求头的值、形似凭据的查询参数与 JSON/表单字段,都会在接收时替换为«redacted»—— 早于任何保存动作。 - 磁盘上不写任何凭据类内容。 请求头的名字会保留,因为「这个接口需要
x-csrf-token」属于契约的一部分;值不会。 - 录制限定站点。 只记录被检查站点自身的
xhr/fetch(同主机、同可注册域,或第三方 JSON)。把整页 HTML 转储到自己服务器的遥测与安全代理会被过滤掉 —— 否则含内联令牌的页面源码就会落进快照包。 - 仅回环。 网桥只绑定
127.0.0.1,任何没有 32 字节配对令牌的请求都会被拒绝。site_status打印的是令牌文件路径,而不是令牌本身。 - 残余风险。 请求头与请求体仍会经过 DSH 进程的内存。如果站点把密钥放在非常规字段名下,脱敏无法识别。请像对待任何流量转储一样,把快照包视为敏感数据。
信任模型
网桥只接受携带配对令牌的请求。扩展申请 debugger 而不是 <all_urls>,也不会向每个页面注入
content script。代价是配对步骤与 Chrome 的调试提示条。换来的是:权限按标签页、按会话授予,请求在
产生的地方被读取,凭据不离开浏览器。
用户同意
默认情况下,连接标签页是人的决定。智能体可以自由列出标签页,但对用户未连接的标签页调用
site_tabs {action:"claim"} 会被拒绝,除非调用带有 confirmed: true——拒绝信息会指出具体标签页,便于
智能体询问。关闭用户自己连接的标签页同样需要确认。这是插件内部的规则,而不是操作系统权限:它让智能体
停下来询问,而不是悄悄扩大可达范围。
限制
跨域 iframe、封闭的 shadow root 与响应体大小上限在 docs/limitations.md 中逐条分析 —— 包含代码位置、消除方案与预估成本。
测试
node test\redact.test.mjs # 8 —— 脱敏规则
node test\bridge.test.mjs # 8 —— 协议、令牌、在线判定
node test\artifacts.test.mjs # 5 —— 快照包布局与大体积响应体外置
node test\plugin.test.mjs # 2 —— 工具注册与完整工具路径
node test\e2e.mjs # 31 —— 真实 Chrome,走协议层
node test\tools-chrome.mjs # 19 —— 真实 Chrome,走工具层
e2e.mjs 与 tools-chrome.mjs 会启动一次性 Chrome,通过 Extensions.loadUnpacked 加载扩展,并针对带真实 BFF 接口的本地页面验证抓取、可信输入、虚拟光标、文件上传、注入与截图。
仓库结构
lib/ DSH 插件:工具、网桥、脱敏、快照包写入
extension/ MV3:service worker(CDP)、弹窗、图标、多语言
docs/ 协议、限制、详细指南
scripts/ install.ps1
tools/ 图标栅格化、弹窗/图标预览、asar 读取(仅开发用)
test/ 单元、集成、端到端
MIT —— 见 LICENSE。
版本管理
版本号保存在 package.json,并同步到 extension/manifest.json;历史记录在 CHANGELOG.md。
任何改动发布代码的提交都要提升版本号,仅文档的提交不需要:
node tools\version.mjs check # 三个文件不一致时报错
node tools\version.mjs bump minor # 同步更新 package.json、manifest.json 与 CHANGELOG 条目
发布使用 vX.Y.Z 标签。0.3.0 之前的版本是按提交历史回溯标注的,因此旧标签指向的内容里
可能仍写着 0.1.0。
许可证
MIT —— 见 LICENSE。