deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
让 DeepSeek Harness 直接使用你已经登录的 Chrome。
dsh-chrome 是一个面向 DeepSeek Harness 的 Chrome 控制插件。它把 chrome_repl 工具、control-chrome Skill、通用审批和 /chrome 管理命令打包成可安装的 DSH Bundle,让 Agent 能在用户授权后复用真实 Chrome Profile 中的登录态、标签页和扩展环境。
适合这些任务:操作登录后的后台、复用当前网页、检查页面状态、点击和输入、截图、上传文件、验证 Web UI,以及读取虚拟列表或无限滚动内容。
[!TIP] 用自然语言,不要用
/chrome。/chrome只是桥的管理开关(授权、诊断),它不接受自然语言;真正的浏览器任务直接说人话即可 —— 比如「看下我 Chrome 里开了几个 tab」。详见两种入口。
[!IMPORTANT] 本项目是非官方社区插件,与 DeepSeek AI、DeepSeek Harness 和万卷 Work 均无官方隶属或背书关系。DeepSeek Harness 当前仍处于开发者预览阶段,可能发生破坏性变更;本项目目前适配
@deepseek-ai/dsh-* >= 0.1.0-rc.6。
DeepSeek Harness 采用“一切皆插件”的架构。dsh-chrome 沿用这套机制,不修改 Agent Loop:
ctx.tools 注册原生 chrome_repl 工具;ctx.skills 注册内置 control-chrome Skill;tools/pre-execute 接入 DSH 通用审批;ctx.commands 提供完整 /chrome 文本命令;dsh.bundle.patch 安装到 web 或其他 Profile;SessionId 隔离不同 Agent 的授权、REPL binding 和浏览器任务。它控制的不是一个空白自动化浏览器,而是用户正在使用的 Chrome。Agent 可以复用现有登录态,但每次调用仍受 DSH 审批或显式限时授权约束。
eval。markHandoff() 和 markDeliverable() 可以保留需要交给用户的标签页。chrome_repl 调用进入 DSH 审批;也可以用 /chrome authorize 建立当前 Session 的限时授权。^22.19 或 >=24pnpm(DSH 的 Profile 插件命令会调用它)DeepSeek Harness 官方 Web UI 可以直接这样启动:
npx @deepseek-ai/dsh web
在 dsh-chrome 目录执行:
pnpm install
pnpm run build
npx @deepseek-ai/dsh plugin --profile web add .
dsh-chrome 的 package.json 声明了 dsh.bundle.patch。安装成功后,它会自动加入 web Profile 的 Bundle 层。
然后重新启动 Web UI:
npx @deepseek-ai/dsh web
确保 Chrome 正在运行且万卷扩展已启用,然后在 DSH 会话中执行:
/chrome doctor
看到 Chrome is connected 后即可使用。无需手写 chrome_repl:直接用自然语言描述任务,Agent 会在需要时加载 Skill 并调用工具。
打开我 Chrome 里已经登录的后台,检查今天有没有失败任务。
用 Chrome 打开本地页面,检查表单布局并截图。
找到我已经打开的文档页面,把标题改成“周报”,保存后确认结果。
默认情况下,每次 chrome_repl 调用都会通过 DSH 通用审批询问用户。这是推荐设置,因为工具操作的是带真实登录态的浏览器。
如果一个任务需要连续调用,可以给当前 Session 一个限时授权:
/chrome authorize 15m
也支持 30m、纯分钟数和 indefinite。撤销授权:
/chrome revoke
显式授权和 background 偏好只保存在当前进程内,不写入 Session Log 或配置文件;重启后需要重新授权。
这是最容易踩的坑。插件提供两个完全不同的入口:
/chrome 命令 |
自然语言 | |
|---|---|---|
| 用途 | 管理桥:授权、诊断、background | 实际操作浏览器 |
| 谁调用 | 你手动输入 | Agent 自动调用 chrome_repl |
| 接受自然语言 | 不接受 | 就是自然语言 |
/chrome 的子命令是固定白名单(authorize/revoke/status/doctor/onboard/background)。传入其他内容会被拒绝:
❌ /chrome 看下我的 Google 上打开了几个 tab
→ Unknown subcommand '看下我的google'.
✅ 看下我的 Google 上打开了几个 tab
补充一点常见误解:/ 菜单里列出的是命令,chrome_repl 工具和 control-chrome Skill 不会出现在那里 —— 它们由 Agent 按需自动调用,不需要你去点。
/chrome 命令/chrome 只管理 Bridge。真正的浏览器任务应直接用自然语言交给 Agent。
| 命令 | 作用 |
|---|---|
/chrome |
显示连接状态和帮助 |
/chrome authorize [15m\|30m\|分钟\|indefinite] |
为当前 Session 建立显式授权 |
/chrome revoke |
撤销授权并清理当前 Agent-owned 浏览器任务 |
/chrome status |
查看连接、授权和 background 状态 |
/chrome doctor |
执行协议、页面脚本和连接诊断 |
/chrome onboard |
返回配套 Chrome 扩展的商店地址 |
/chrome background on |
后台操作,不主动抢占 Chrome 焦点 |
/chrome background off |
操作时将 Chrome 带到前台,便于观察 |
/chrome background toggle |
切换 background 模式 |
/chrome background status |
查看 background 模式 |
chrome_repl 概览Agent 首次使用时会初始化持久 binding:
const chrome = await browser.get("chrome")
await chrome.nameSession("🔎 检查管理后台")
使用用户已有标签页:
const openTabs = await chrome.user.openTabs({ urlIncludes: "example.com", limit: 5 })
const tab = await chrome.user.claimTab(openTabs[0])
await tab.snapshot()
创建当前 Turn 独享的标签页:
const tab = await chrome.tabs.open("https://example.com")
await tab.find("登录按钮")
await tab.click({ uid: "el-12", includeSnapshot: true })
外层 chrome_repl 是受限语法环境;完整页面 JavaScript 应放在 tab.evaluate() 中执行。更完整的操作规范位于 control-chrome Skill。
dsh-chrome 区分两种标签页:
| 类型 | 来源 | Turn 结束时 |
|---|---|---|
| 用户标签页 | chrome.user.claimTab() |
释放控制权;不移动、不分组、不关闭 |
| Agent-created 标签页 | chrome.tabs.open/create() |
默认关闭 |
需要保留 Agent-created 标签页时,必须显式标记:
await tab.markHandoff() // 用户还需要继续操作
await tab.markDeliverable() // 标签页本身就是交付物
普通搜索、资料阅读和临时验证页面不应保留。
flowchart LR
A["DeepSeek Harness Agent"] --> T["chrome_repl Tool"]
S["control-chrome Skill"] --> A
P["DSH Approval"] --> T
C["/chrome Commands"] --> R["Per-Session Controller"]
T --> R
R --> B["127.0.0.1:17318 Bridge"]
B --> E["WanJuan Chrome Extension"]
E --> X["User's signed-in Chrome"]
C -.命令输入投影.-> W["dist/client.js (Web GUI)"]
代码分为三层:
src/kernel/:Bridge、协议握手、Chrome API、格式化和 Restricted REPL,不依赖 DSH UI。src/adapter/:工具、Skill、审批、命令、生命周期和 per-Session Controller。src/client/:浏览器半侧,把 /chrome 的命令输入投影成一个会话节点(见下)。Bridge 是机器级共享连接:第一个进程监听 127.0.0.1:17318,后续进程以 client 模式转发;Agent 的授权、binding、任务 key、保留标签页和 pending finalization 则按 Session 隔离。
DSH 刻意让「控制类命令」在全新会话里保留 Hero 页 —— 通用 command 节点不会激活会话,因此在一个还没有任何内容的新会话里执行 /chrome status,结果会被隐藏。
src/client/ 通过注册一个 feature-owned Conversation Definition 解决这个问题:它把 /chrome 的输入投影成 chrome-command-input 节点(不是 command),从而激活会话、让结果一并显示。这与官方 /goal 的做法一致。完整说明见 docs/command-input-projection.md。
[!NOTE] 客户端半侧是 closure-factory bundle(
dist/client.js),由dsh.client声明下发。DSH 的客户端注册表会缓存「无客户端」的判定直到进程结束,所以首次加入客户端半侧后必须重启dsh web,仅重新构建无效。
默认 Bundle 配置:
- id: chrome-profile-bridge
name: dsh-chrome
config:
host: 127.0.0.1
port: 17318
可以在 Profile 的 cordis.patch.yml 中覆盖该行。DSH Patch 会整体替换 config,因此覆盖时请同时保留 host 和 port。
配套商店扩展固定访问 127.0.0.1:17318。除非同时维护并重新构建 Chrome 扩展,否则不要修改端口,也不要把 Bridge 绑定到非 loopback 地址。
chrome_repl 能操作真实登录态,首次使用应保留 DSH 审批。tab.evaluate() 仍在目标页面内执行 JavaScript。close/group/ungroup 操作会被拒绝。.dsh/chrome-screenshots/。pnpm run test # vitest,8 个测试文件
pnpm run typecheck # 同时检查 node 半侧与 client 半侧
pnpm run build # tsc 产出 dist/,再用 esbuild 产出 dist/client.js
pnpm run build:client # 只重建浏览器半侧
修改 src/client/ 后,重建并重启 dsh web,然后刷新页面 —— GUI 加载的是 dist/client.js,不是源码。
连接真实 Chrome 的端到端验证:
node scripts/e2e-verify.mjs
该脚本需要已连接的配套扩展,会打开一个临时百度标签页,验证导航、页面执行、snapshot 和 Turn finalization,最后自动清理 Agent-created 标签页。
测试重点覆盖:Bridge 长轮询与多进程共享、握手兼容性、配置校验、受限 REPL、Chrome API、审批组合、多 Session 隔离、Turn 清理、finalization 重试,以及插件装载/卸载。
/chrome 完成。chrome:// 页面仍需要用户处理。如果把本项目发布到 GitHub,建议为仓库添加 dsh-plugin、deepseek-harness、chrome-extension、browser-automation 和 agent-tools Topics,方便 DeepSeek Harness 用户发现。
MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。