deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
在 Chrome 侧边栏里直接嵌入完整的 DSH Web,让浏览器里的真实页面成为当前开发对话中的一等公民:DSH 既能像往常一样读写文件、执行命令,也能通过你显式授权的标签页,直接观察、操作和验证页面,而不必换到另一个“浏览器专用对话”里。

在完整 DSH Web 对话中通过 @当前标签页 附加左侧开发页面,DSH 可以沿用已有的代码上下文继续观察、操作和验证页面。
@当前标签页 按钮(或 @ 引用源 browser-tabs)把当前页面显式授权给这一条 prompt,DSH 就能在同一个上下文里继续检查、交互、定位问题、修改代码并验证。这是本项目的首要使用场景——开发反馈回路:
@当前标签页 授权。 在同一个对话的输入框上方点击 @当前标签页,把正在显示的页面授权给当前 prompt,然后发送。整个过程中只有一个对话:上下文不丢失,页面只是被显式授权的“证据与操作对象”。例如可以直接接着刚才的开发过程说:
刚才改的按钮 hover 还是不对。
@当前标签页请在当前页面悬停检查;如果有问题,继续修改源码并复验。
同样的原语也适用于问题复现、信息提取、表单操作等轻量浏览器自动化场景——它不只是一个验收工具,也不是全局的 Computer Use。
dsh-browser 与本项目同属 ycp424c 名下,定位互补,面向不同的工作流:
| 维度 | dsh-browser | dsh-browser-bridge |
|---|---|---|
| 定位 | 浏览器操作优先的轻量侧栏入口 | 嵌入完整 DSH Web 的开发闭环桥梁 |
| 对话形态 | 配套的模型对话侧栏,页面以纯文本呈现 | 直接嵌入完整 DSH Web,复用已有开发对话与上下文 |
| 目标标签页 | 操作当前活动标签页 | 页面按 prompt 显式授权,可同时附加多个标签页 |
| 多页支持 | — | 每个附加页面获得稳定别名(page_1、page_2……)并附带净化后的标题/URL 元数据 |
| 页面表示与定位 | 编号交互元素清单、跨快照稳定编号与 delta 增量,全程无截图 | DOM/无障碍内容、短生命周期元素引用或选择器 |
| 页面证据 | 结构化纯文本快照 | DOM、计算样式、几何信息、截图、console、network |
简单说:需要轻量、即时的浏览器操作时,dsh-browser 更直接;需要在已有的开发对话里让 DSH 检查、修改并验证页面时,dsh-browser-bridge 是延续上下文的那一条路。两者并非替代关系,按工作流选择即可。
Chrome side panel
└─ embedded DSH Web (iframe)
└─ DSH client plugin
├─ @ tab references and shortcut
└─ origin-checked postMessage
↕
Chrome extension service worker
├─ prompt grant vault
├─ CDP session manager (chrome.debugger)
└─ authenticated WebSocket
↕
DSH host plugin (pairing, grants, tools)
↕
DSH agent runtime
三个组成部分共享同一个与传输无关的协议包(packages/protocol):
extension/ —— Manifest V3 侧边栏扩展(React + shadcn 壳),负责标签页发现、prompt 授权(grant)与 chrome.debugger 会话;它不实现聊天界面。packages/dsh-plugin/ —— 一个可安装的外部 DSH 插件,包含客户端一半(composer 集成)与宿主一半(配对、授权、工具)。packages/protocol/ —— 双方共享的带版本号线上协议 schema(配对、授权、桥接请求、工具结果、错误、版本协商)。@当前标签页 按钮一键附加当前 Chrome 标签页到 prompt。按钮通过 DSH 官方 conversation.input.dock slot(注册序 30)显示在输入框正上方:排在 Todo(0)、Goal(10)、Queue(20) 等输入 dock 条目之后、最靠近输入框,左边缘与输入卡片对齐、垂直间距 6px;空白首页(hero)下宿主间距为 12px,由插件 CSS 补偿为同样的 6px,因此空白首页与已有对话中位置一致。@ 引用源(browser-tabs)列出可附加的标签页,可以一次附加多个;每个附加页面获得稳定别名(如 page_1、page_2),并在 prompt 中附带净化后的标题/URL 元数据。turn/end(包括完成、错误、取消与 dispose)、引用标签页关闭或终态桥接断开都会立即撤销。Chrome 扩展授权另有 10 分钟滑动空闲超时:新的、已通过校验的浏览器工具调用在执行期间不计 idle,最后一个调用结束后重新开始 10 分钟倒计时,但整条 prompt 最长不超过 6 小时。相同 request 的并发、失败或延迟重传只重放原结果,不执行、不续租;短暂断线期间产生的撤销会在同一 logical session 重连时优先送达。下一条 prompt 仍需重新附加。当一个 prompt 拥有至少一个有效授权时,以下工具仅在该 turn 内存在:browser_observe、browser_inspect、browser_screenshot、browser_act、browser_navigate、browser_wait、browser_console、browser_network。
| 工具 | 作用 |
|---|---|
browser_observe |
返回页面身份、生命周期状态、语义化 DOM/无障碍内容,以及短生命周期的元素引用;默认不含整段文本(text: true 显式请求),过滤 InlineTextBox 与重复 StaticText |
browser_inspect |
查询指定元素(引用/选择器/批量 targets)的表单状态(value/checked/selected 等)、属性、文本、几何与可见性;计算样式仅在显式请求 properties 时返回;密码/secret 字段不泄漏明文 |
browser_screenshot |
截取当前视口或指定元素,并返回图片附件证据;仅当前模型明确支持图片输入时执行 |
browser_act |
点击、输入(type 追加/replace: true 覆盖)、fill(原生 setter 可靠覆盖 input/textarea/select/datetime-local)、选择、悬停、聚焦、按键、滚动;可用 actions 批量顺序执行并附带 expect 后置条件 |
browser_navigate |
打开 HTTP(S) 地址、后退/前进、刷新 |
browser_wait |
等待元素、文本、URL、生命周期状态,或一段有界的页面稳定窗口 |
browser_console |
返回标签页被附加以来观察到的 console 错误与相关日志 |
browser_network |
返回标签页被附加以来失败的请求与加载错误(不含请求头与请求体) |
browser_screenshot 会在访问浏览器前检查当前 DSH provider/model 的图片输入能力。DeepSeek chat-completions 等纯文本模型会收到可恢复的文本工具错误,并可继续改用 browser_observe / browser_inspect;截图不会写入会话历史,也不会导致后续轮次持续失败。
元素引用是短生命周期的:页面导航会使全部引用失效,DOM 替换可能使个别引用失效,工具此时返回 stale_element 而不是猜测其他目标。
console 与 network 证据有界:从 debugger 附加时开始记录,随授权一起删除;任何情况下都不会返回请求头、请求体、cookie 或密码值。
debugger —— CDP 会话:首次工具调用时懒附加,授权结束时断开。打开 DevTools 会分离会话,并返回可恢复的 debugger_detached 错误。tabs —— 仅用于读取标签页标题/URL 供 @ 引用使用,不记录任何常驻浏览历史。storage —— 本地设置,以及 chrome.storage.session 中用于 service worker 启动对账的非机密归属台账。localhost、127.0.0.1)与 Chrome 118+。navigation_requires_confirmation),读取仍然可用,直到新的 prompt 显式附加新页面。插件已发布到 npm:@ycp424c/dsh-browser-bridge。适用于 DSH 0.0.1-rc.2+ 的 web profile:
# 1. 安装依赖(等价于在 profile 目录执行 pnpm add)
dsh plugin add --profile web @ycp424c/dsh-browser-bridge
# 2. 挂载插件:把包名追加到 ~/.dsh/profiles/web/package.json 的 bundles
# "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "@ycp424c/dsh-browser-bridge"] } }
# 3. 重启
dsh web
插件的 peerDependencies(@deepseek-ai/cordis、@deepseek-ai/schemastery 及 @deepseek-ai/dsh-*)由 DSH 本体提供,无需单独安装。
浏览器扩展(extension/)不发布 npm;需要扩展能力的场景仍按下方源码方式构建并“加载已解压的扩展程序”。只用 Vite Provider 的场景不需要扩展。
环境要求:Node.js ^22.19.0 || >=24.0.0(启用 Corepack)、pnpm 11.7.0、Chrome 118+,以及一份本地 DSH 源码检出。
# 1. 将 DSH 插件链接到本地 DSH 源码检出
pnpm link:dsh -- /absolute/path/to/dsh
# 2. 安装依赖并验证(类型检查 + 单元测试 + 构建)
pnpm install --frozen-lockfile
pnpm check
# 3. 构建插件并安装到 DSH 的 web profile
pnpm --filter @ycp424c/dsh-browser-bridge build
dsh plugin --profile web add /absolute/path/to/dsh-browser-bridge/packages/dsh-plugin
dsh web
# 4. 构建扩展,然后在 chrome://extensions 中启用开发者模式并"加载已解压的扩展程序"
pnpm --filter @ycp424c/dsh-browser-bridge-extension build
pnpm --filter @ycp424c/dsh-browser-bridge-extension zip
扩展输出目录为 extension/output/chrome-mv3。加载后点击工具栏图标打开侧边栏,第一个界面会让你配置本地 DSH Web 来源(默认 http://127.0.0.1:3080),面板随后在 iframe 中嵌入 DSH Web 并显示连接横幅。
完整的分步清单(本地链接、冻结安装、pnpm check、插件 profile 安装、解压扩展加载、更新、卸载及逐错误排查)见 INSTALL.md。
Chrome Extension 与 Vite provider 是互补的接入方式,而非替代关系:
| 维度 | Chrome Extension | Vite Provider |
|---|---|---|
| 安装 | 加载解压扩展 | 零安装,Vite 插件注入 |
| 页面 | 任意标签页(CDP) | 由当前 Vite 构建承载的页面 |
| 能力 | 全部 browser_*(含截图、network) |
可靠子集:observe、inspect、act、navigate、wait、console |
| 证据 | DOM、CDP、原生截图、浏览器级 console/network | DOM 语义投影、合成输入、HMR generation、console 缓冲 |
| 前提 | Chrome 118+ | 页面由你的 Vite 构建注入 Runtime |
pnpm add -D @ycp424c/dsh-browser-bridge-vite
import { dshBrowserBridge } from '@ycp424c/dsh-browser-bridge-vite'
export default defineConfig({
plugins: [
dshBrowserBridge({
dshOrigin: 'http://127.0.0.1:3080',
bridge: {
enabled: true,
injectInBuild: false, // 生产构建默认不注入
autoConnectInBuild: false, // 显式注入后默认休眠
},
panel: {
enabled: true, // false 只关闭嵌入 UI,bridge 仍可用
visible: false, // true 仅做健康探测,成功后显示入口
shortcut: 'Alt+Shift+D',
queryParameter: 'dsh',
},
}),
],
})
panel.visible: false(默认)保持 UI 完全隐藏;panel.visible: true 也只允许在本地健康探测成功后显示 launcher 入口,抽屉始终只在显式激活(快捷键、?dsh=1、launcher 点击)时打开。injectInBuild: true 后仍默认休眠(零本地网络请求),只有快捷键、?dsh=1 或本地激活开关才会激活;autoConnectInBuild: true 才允许每个访问者主动探测并连接;panel.visible: true 只做健康探测并在成功后显示入口,不注册 target。panel.enabled: false 只关闭嵌入 UI,bridge 激活管线照常运行,仍可从独立 DSH Web 的 @开发页面 附加。dshOrigin 只接受回环地址:localhost、*.localhost、127.0.0.0/8、::1。配置拒绝凭据、非 HTTP(S) 与远程地址,且不扫描端口。@开发页面:从本地 Host 回读所有已连接的 Vite target,可一次附加多个。@当前开发页:仅当 DSH Web 嵌在目标页面(Shadow DOM 面板)中出现,指向承载当前面板的 target,且 targetId 与 origin 必须通过 Host 回读校验。| 工具 | Vite 支持 | 说明 |
|---|---|---|
browser_observe |
✅ | 有界语义 DOM 投影、ARIA、短生命周期引用;去重后的节点列表,text 按需返回 |
browser_inspect |
✅ | 表单状态/属性/文本/按需计算样式/几何/可见性,敏感值遮罩 |
browser_act |
✅ | click/type/fill/select/focus/press/scroll;受控输入走原生 setter + input/change;hover 为合成事件(synthetic: true, cssPseudoState: false) |
browser_navigate |
✅ | 仅同源 URL/前进/后退/刷新;跨 origin 在导航前拒绝 |
browser_wait |
✅ | selector/text/url/ready/稳定窗口/下一 generation |
browser_console |
✅ | 注入后的 console、window error、unhandledrejection,有界 200 条并带 generation |
browser_screenshot |
❌ | 返回稳定 unsupported_operation |
browser_network |
❌ | 返回稳定 unsupported_operation |
HMR 会使旧元素引用失效(stale_element),并递增 generation;断线后的写操作绝不自动重放。生产页面没有 HMR capability,generation 等待返回 unsupported_operation。
localhost、*.localhost、127/8、::1),远程站点页面无法注册为 target;确需放行非回环 origin 时,可在插件配置中显式设置 viteAllowedOrigins: ['https://example.com']。/targets、/grants 一样要求回环 Host 头(防 DNS rebinding),且握手 Origin 必须与页面声明 origin 精确一致(浏览器必带 Origin,缺失即拒绝)。frame-src http://127.0.0.1:* http://localhost:*;
connect-src http://127.0.0.1:* http://localhost:*
ws://127.0.0.1:* ws://localhost:*;
插件不会放宽服务器响应头中的 CSP,只会给出文档与运行时诊断:面板嵌入失败显示 embedding_blocked 诊断与“在新标签页打开本地 DSH”的降级入口;本地网络/连接被阻止时显示失败横幅与重试。
Chromium 自动化(Playwright)已覆盖注入、观察/操作、React/Vue 受控输入、HMR、多页面路由、unsupported 能力、HTTPS 生产 fixture 与 CSP 诊断(e2e/vite-provider.spec.ts、e2e/vite-security.spec.ts)。真实 Chrome 与 Arc 人工门禁按计划单独记录在
docs/testing/vite-provider-manual.md,截至 2026-08-11 状态为未完成(需要运行中的真实 DSH 实例),不得以 Chromium 结果推断通过。
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。