deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:bruc3van/dsh-desktop
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
中文 | English
让 Agent 安全地常驻在你的桌面上:官方 Web UI 原封不动,长任务不再被终端和浏览器标签页绑架,精选插件先审查、再安装。
DeepSeek Harness Desktop 是一个独立的 dsh Electron 客户端。窗口里呈现的是官方 Web UI 本体——不是仿制版,官方产品什么样,窗口里就是什么样;而真正的工程投入都在窗口之外:关闭窗口任务照跑、托盘常驻随点随开、Agent 跑在经过治理的执行环境里、插件安装走「先审查、再安装」的内置市场、连接与更新链路逐层加固。
[!IMPORTANT] 这是社区维护的非官方第三方项目。 本项目并非 DeepSeek 官方产品,不由 DeepSeek 开发、发布、背书或提供支持,也不代表 DeepSeek 的立场。
DeepSeek、DeepSeek Harness、dsh及相关名称、标识和商标归其各自权利人所有。桌面客户端的问题请提交到本仓库,不要联系 DeepSeek 官方支持。
发布安装包内置固定版本的官方 @deepseek-ai/dsh 运行时;普通用户无需另外安装 Node.js、pnpm 或 dsh CLI。桌面外壳、安装包、连接增强与发布签名均由本项目独立负责,不属于官方运行时的一部分。桌面客户端与官方 dsh 使用各自独立的版本号;应用的连接设置页会同时显示两个版本号,便于排查兼容问题。

先说清楚我们为什么这样做。Harness 的使用形态正在从「对话」变成「委派长任务」,而长任务的痛点全在窗口之外:任务跑着的时候不敢关标签页、关掉终端服务就停、Agent 的执行环境里找不到 node 和你 shell 里配好的工具、一个有文件读写权限的进程更新链路却裸奔。界面本身反而是最不需要重做的部分——官方 Web UI 一直在快速演进,用户要的正是它原封不动。
因此本项目把界面完整交还给官方,把全部工程投入放在窗口之外:常驻与长任务、Agent 执行环境、内置安全市场、安全加固、连接与更新。 这样做的好处是天然成立的:
| 用户需要什么 | 我们的做法 |
|---|---|
| 长任务不被终端和浏览器标签页绑架 | 关闭窗口不退出应用,服务继续后台运行;托盘常驻,随点随开 |
| Agent 要跑在你自己的环境里 | 优先复用你的实例 / PATH 上的 dsh / npx 缓存包;macOS 对齐登录 shell 的 PATH;node 始终可用 |
| 安全与隐私是底线 | 小边界 + 逐层加固:只用公开接口;更新链路防劫持;权限最小化 |
| 装插件之前想知道它安不安全 | 内置安全市场:目录每日自动采集 + 人工精选,安装前先由 Agent 审查代码 |
| Harness 的全部能力,一个都不能少 | 窗口里就是官方 Web UI 本体,不用重写界面 |
| 官方新功能要当天可用 | 跟进速度与自己的发版解耦:智能模式复用你已有的最新 dsh;内置运行时只是回退 |
| 装好就能用,不折腾环境 | 安装包自带官方运行时:不用装 Node.js、不用敲命令,双击即用 |
| 工作要在终端与桌面之间延续 | 智能模式与 CLI、浏览器共享 ~/.dsh;固定地址模式连接你自行维护的 Web UI 地址 |
这些落到产品上:
dsh,Agent 跑在你自己的完整 shell 环境里;内置运行时下没装 Node.js 的用户也能执行 node;ELECTRON_RUN_AS_NODE 不会泄漏给 Agent(否则 code 等 Electron 工具会启动失败);从 Finder/Dock 启动也能找到 Homebrew、~/.local/bin 和写在 ~/.zshrc 里的工具。详见内置运行时下的 Agent 执行环境。dsh web 接口,不碰官方仓库内部;窗口开沙箱、关 Node 集成、导航锁在官方源站;打包后更新源与数据目录禁止被环境变量劫持;应用内更新下载后先校验 SHA-256 再安装;渲染进程只放行剪贴板与全屏;外链一律交给系统浏览器。详见安全与隐私。127.0.0.1:3080 上的官方实例(含 ~/.dsh/profiles/web/cordis.patch.yml 里配置的其他端口)→ PATH 上的 dsh → npx 缓存 → 内置运行时。浏览器、CLI 与桌面端共享同一个 Harness 进程,会话状态实时同步。127.0.0.1,暴露到网络的 0.0.0.0 绑定会被明确拒绝(会带来远程代码执行风险),远程或容器内实例并非官方支持场景。从 GitHub Releases 下载适合当前系统的安装包并启动即可。发布版内置官方 dsh 运行时,不依赖开发环境,也不会在首次启动时执行 npm 安装。
当前安装包尚未经过正式的开发者签名认证,首次打开时系统可能会弹出提示,按下方说明操作一次即可正常使用。
macOS:把应用拖入「应用程序」后双击打开。系统会提示无法打开,去「系统设置 → 隐私与安全性」,在「安全性」区域点击「仍要打开」,输入密码即可。
极少数情况下如果提示「已损坏,无法打开」、且系统设置里没有「仍要打开」按钮,打开「终端」执行以下命令后再双击打开应用:
xattr -dr com.apple.quarantine "/Applications/DeepSeek Harness Desktop.app"
Windows:如果 Microsoft Defender SmartScreen 弹出提示,点击「更多信息」,再点击「仍要运行」即可。
[!TIP] 全新数据目录下,官方 Web UI 可能默认显示英文。可从 Settings → General → Language 切换为中文。
客户端同时服务两类用户,两条路径都是一等公民:
dsh CLI,双击即可开始对话。dsh web,桌面端只作为窗口连上去,运行时版本、插件与环境完全由你掌控。官方 dsh 目前只面向本机使用(默认监听 127.0.0.1,暴露到网络的 0.0.0.0 绑定会被拒绝),远程机器或容器内的实例不在官方支持范围内。| 模式 | 适合场景 | 实际行为 |
|---|---|---|
| 智能模式(默认) | 大多数本机用户 | 依次尝试:复用 127.0.0.1:3080 上的官方实例 → PATH 上的 dsh → npx 缓存中的官方包 → 内置运行时。连接设置里可单独关闭其中任何一种。 |
| 固定地址模式 | 自行维护的 Web UI 实例(官方 dsh 目前只面向本机使用) | 直接连接你填写的 Web UI 地址,不启动任何运行时。 |
在智能模式下,只要你已经在终端里跑着官方 Web UI,桌面端就会直接复用它——这正是开发者路径:会话与桌面端实时共享,而 Agent 跑在你自己的完整 shell 环境里。
智能模式只使用你机器上已经存在的东西——PATH 上的 dsh、npx 缓存过的官方包——不联网、不下载、也不替你安装 Node.js。官方 dsh web 的端口除 --port 外也可写在 web profile 补丁层(~/.dsh/profiles/web/cordis.patch.yml)里,客户端会读取并一并探测,不会因为实例挪了端口就在旁边另起一个 harness。npx 缓存里的官方包版本低于内置运行时时,连接设置里会说明(缓存仍优先使用——那是你上次 npx @deepseek-ai/dsh 留下的,重新跑一次即可刷新)。客户端启动的都是纯后台服务进程(dsh web --port 0),退出桌面端时一并关闭;选中的运行时启动失败会按仍启用的来源依次回退(默认最后是内置运行时)。四种来源都可以在连接设置里用多选按钮单独关闭,方便测试时固定到某一种;缺省全部开启,至少保留一种。页面完全加载不出来时,启动界面会直接给出「Web UI 连接…」按钮。运行时选择顺序的完整细节见开发指南。
输入地址后点击「保存并连接」,客户端会保存并立即使用该地址。当前使用固定地址时,会额外显示「切换到智能模式」;切换后地址仍会保留,之后再次点击「保存并连接」即可重新使用。
连接状态按谁启动了这个运行时来描述,避免「本地」和「内置」混用:
| 状态 | 含义 |
|---|---|
| 复用你已启动的 dsh | 复用你自己在终端里跑起来的实例(默认 127.0.0.1:3080) |
| 客户端启动·内置运行时 | 客户端用安装包自带的运行时起的后台子进程 |
| 客户端启动·npx 缓存的 dsh | 客户端用 npx 缓存里那份官方包起的后台子进程 |
| 客户端启动·本机安装的 dsh | 客户端用 PATH 上你自己装的 dsh 起的后台子进程 |
| 固定地址 | 直连你填写的地址,客户端不启动任何运行时 |
填入
127.0.0.1:3080(即默认探测地址)并点击「保存并连接」时,客户端仍保持智能模式——智能模式本来就优先使用它,并且能在该实例停止时自动回落。
清空 Web UI 地址即可恢复智能模式。连接设置位于官方设置弹窗「通用设置」里的「连接」增强区块。
[!TIP] 连接本机之外的实例目前不在官方支持范围内;若你确实这样做(例如自行通过 SSH 隧道转发),请使用可信网络,并在条件允许时使用 HTTPS。这里填写的是客户端直连地址,本项目不会通过第三方中转你的请求。
桌面外壳和 Harness 运行时各自管理不同的数据:
| 数据 | 默认位置 | 管理方 |
|---|---|---|
| 会话、凭据、模型配置与其他官方 Harness 状态 | ~/.dsh |
官方 dsh 运行时 |
| 桌面端连接偏好 | ~/.dsh-desktop/settings.json |
桌面客户端 |
可以分别通过 DSH_HOME 和 DSH_DESKTOP_HOME 覆盖这两个目录(仅开发/未打包运行时生效;打包后见下文「更新链路防劫持」)。
客户端在安全上采取小边界 + 逐层加固的策略:
dsh web CLI 和 /api 协议,不修改官方仓库,也不依赖 Harness 私有内部包。DSH_HOME、DSH_DESKTOP_HOME)及连接探测开关均禁止被环境变量覆盖(唯一的调试后门是 DSH_DESKTOP_ALLOW_UNSAFE=1,只在刻意排查打包产物时使用,请勿在日常环境常驻);校验更新清单中的安装包文件名,防止路径穿越写出到下载目录之外。使用本客户端仍需遵守 DeepSeek、模型提供方和所连接服务各自的条款与隐私政策。API Key、模型请求、费用、生成内容以及 Agent 对本机文件或命令的操作由用户和对应服务负责。本软件按 MIT 许可证「原样」提供,不承诺适用于特定用途,也不对数据丢失、服务中断、模型输出或第三方费用承担保证责任;法律另有强制规定的除外。
Cmd+Q 完全退出。Windows、Linux 窗口内不显示菜单栏。dsh web 不会被动到(这种情况下重启的只是客户端外壳)。DSH_HOME 下绝不同时跑两个写入者:客户端把自己启动的运行时记录在 DSH_HOME 下,下次启动优先接管仍在服务的遗留进程(复用同一个 harness,会话照常共享),接管不了才清理后重启;遗留进程既连不上也结束不掉时,客户端会拒绝启动并说明原因,而不是在它旁边再写一份——两个 harness 同时写同一份会话日志会造成永久损坏。127.0.0.1:3080 官方实例失联时,客户端会自动改用自己启动的运行时;固定地址连接失败不会擅自改用其他服务,但报错页会提供「切换到智能模式」出口。PATH(先尝试交互式登录 shell,最长 3 秒;失败再退回非交互登录 shell,最长 2 秒),只合并绝对路径目录,使 Agent 从 Finder/Dock 启动时仍能找到 Homebrew、~/.local/bin 以及写在 ~/.zshrc 里的工具目录。使用内置运行时时,Agent 的能力与官方 dsh 一致(同一份运行时、同一个 ~/.dsh、同样的系统级沙箱机制),执行环境按以下方式对齐到「你在终端里跑 dsh」的效果:
node 始终可用:发布版把 Electron 内置的 Node 以 node 之名发布到 ~/.dsh-desktop/bin,并追加到运行时的 PATH 末尾。没装过 Node 的用户,Agent 也能执行 node script.js;装过 Node 的用户仍优先使用自己的版本。该目录不提供 npm/npx——需要它们的场景(例如用 npx 启动 MCP 服务)请自行安装 Node.js,或改用固定地址模式。这个 shim 依靠设置 ELECTRON_RUN_AS_NODE 让 Electron 以 Node 方式运行,因此经它启动的 node 进程及其子进程会带上该变量:如果你的 node 脚本里还要再启动基于 Electron 的工具,需自行清除该变量,或安装一份真正的 Node.js。ELECTRON_RUN_AS_NODE 跑在 Electron 的 Node 上,这是启动方式的实现细节。客户端会在运行时启动后将其从环境中摘除,只在运行时自身需要重新拉起 Node 子进程时(原生文件夹选择器、Windows ACL 沙箱执行器)临时补回,因此 Agent 执行的命令不会继承它——否则 Agent 运行任何基于 Electron 的工具(如 code)都会失败。客户端把随安装包发布的安全市场(dsh-desktop-safe-market)按官方 in-box bundle 的方式接入当前 profile:把插件复制到 <DSH_HOME>/profiles/node_modules、并往 profile 的 dsh.profile.bundles 里加一项——不写依赖、不改锁文件、不跑 pnpm、不联网;升级插件即升级客户端。客户端启动的任何一种运行时都能用上:内置的、你装在 PATH 上的 dsh、以及 npx @deepseek-ai/dsh web 留下的缓存。插件复制进 profile 而不是软链到闭包,它的 @deepseek-ai/* 依赖便向上解析到正在服务的那份运行时——和你用 dsh plugin add 装的插件走同一条路。设置里随之出现「插件市场」导航项,分两页:「插件」页上半是已安装面板(查看、停用/启用、卸载当前 profile 通过包安装的插件),下半是社区市场;「技能」页列出当前会话实际能解析到的技能。固定地址连接时客户端会撤回条目——那种运行时不由客户端启动(甚至可能不在本机),无从知道改动何时生效。复用本机 3080 上已在运行的实例则会保守地重新接入(只恢复名字,不换插件目录):该实例正在服务这个 profile;它停止后客户端回落,并在下一次由自己启动运行时重新按版本门禁接入。
不想要它:连接设置里有「接入内置插件市场」开关,关掉就会立即移除市场插件,之后启动也不会再装回。就算客户端已经卸载了,市场自己的「已安装」面板也能把它卸载掉——官方 dsh plugin 命令不管这份插件,所以面板是最后的入口。

市场有三个刻意的设计:
market.json:上游每天自动爬取带 dsh-plugin 标签的仓库,要求有简介、剔除已归档/停用的项目,再套用 curated.json 人工排除名单;分类与排序做均衡发牌——每类先出最强、再出次强,而不是纯按 star 让两三个分类吃掉几乎所有席位。市场在 Host 侧逐行重新校验后才交给页面。装插件本质上是在自己机器上跑别人写的代码,这份目录把「有哪些插件」和「哪些至少过了第一道人工关」分开。$DSH_HOME/storages/safe_market.json),之后走 ETag 条件请求,连不上 GitHub 时继续用上次的目录。一个装上就开始联网的插件等于替你做了决定,这个开关把决定还给你。postinstall 等安装脚本、无对应源码的混淆文件,以及权限是否远超其声称的功能;发现可疑处必须停下来说清原因并询问你。确认干净后,Agent 才会用官方命令 dsh plugin --profile web add 安装。审查与安装因此绑在一起、绕不过去;发不发送由你决定,收录不代表安全背书——请自己看过再决定。
目录里已经装过的插件会标出「已安装 vX.Y.Z」,按钮也随之变成「安全升级」——走的是同一套「先审查、再动手」的流程,只是提示词第一步先让 Agent 确认上游到底有没有新版本,没有就原样不动。已装插件的日常管理则在同一页顶部的已安装面板:

「技能」页列出当前会话实际能解析到的技能。它按会话寻址,因为技能发现是随各个 Agent 预设分层的——从插件根上下文读只能看到全局层,会对着一堆技能报告「没有技能」:

桌面端对这次接入与其他工程投入同样谨慎:接入失败可自愈——插件在加载期抛错会让整棵插件树启动失败、共用同一 profile 的 CLI 也会跟着起不来,因此失败即撤回并在本会话不再重试;插件目录缺失、或 profiles/node_modules 上已有非软链目录时不写 bundles,绝不写坏你的 profile;你自己装过该插件(作为 profile 依赖)且版本不低于内置时,客户端完全不插手;更旧的覆盖会改用闭包那份。运行时比客户端自带的 dsh 更旧时不接入——插件按自带的那版编译,更旧的运行时可能缺它需要的导出;更新的一律放行。插件自身还有一道自保:它的入口只经受保护的动态载入触达真正的实现,所以万一遇上不兼容的运行时,损失的只是市场本身。市场的完整设计(配置项、目录协议、安全边界与已知限制)见其仓库。
Q:这是浏览器套壳,还是用 SDK 重新实现?
都不是:窗口加载的是官方 Web UI 本体,但客户端并不是「打开一个网页」——运行时启动与复用、连接管理、窗口与导航加固、托盘与应用内更新都做在外壳层,仓库不维护第二套产品界面(取舍与备选方案见架构文档)。Harness 生态里的桌面客户端大致分三条路线,本项目选择第三条:
| 路线 | 做法 | 结构性的代价 |
|---|---|---|
| ① 自研工作台界面(如 RongleCat/deepseek-app) | Harness 引擎跑在应用内,界面是自研的三栏工作台,不使用官方 Web UI | 官方产品表面的每个新功能都要在自己的界面里重新实现一遍 |
| ② 打包封装(如 anywhere-labs/deepseek-harness-desktop) | 基于官方仓库构建桌面端,负责服务生命周期、窗口与托盘集成、界面适配与安装包发布 | 官方更新要先合并上游、重新发版才能跟进 |
| ③ 原装直连(本项目) | 窗口直接加载官方 Web UI,工程投入放在常驻与长任务、Agent 执行环境、安全与连接上 | 不做自研界面,桌面增强以官方界面能承载的为界 |
Q:对用户来说,主要价值是什么?
node 始终可用;dsh CLI;智能模式复用你正在跑的实例并共享 ~/.dsh 会话,固定地址模式直连你自行维护的地址。Q:和直接用浏览器访问 Web UI 有什么区别?除了不用装 Node.js 之外
官方浏览器用法是装好 Node.js 后执行 npx @deepseek-ai/dsh web,再手动打开它给出的地址——关掉这个终端,服务就停了。客户端把这件事工程化:关闭窗口不退出应用,托盘常驻随时唤回,长任务不再依赖一个不敢关的终端;安装包自带运行时,双击即用;智能模式先探测你已在跑的实例,没有时依次用 PATH 上的 dsh、npx 缓存包在后台启动,兜底才用内置运行时;另有浏览器没有的应用内更新、连接来源与版本透明展示。
Q:为什么强调「官方发版当天就能用上」?
自研界面或魔改源码的客户端,官方更新后要等重新实现或合并上游、重新发版才能跟进;本项目的窗口直接加载官方 Web UI,官方界面怎么改,窗口里就是什么样。就版本更新路径而言:智能模式复用你已更新的 dsh、固定地址直连你自维护的最新实例,都是官方发版当天可用;内置运行时固定为发布时锁定的官方版本,随应用内更新推送,会稍晚于官方发版。
Q:内置了插件市场吗?之后还有什么计划?
内置了:随安装包发布的安全市场,设置里叫「插件市场」。它按官方 in-box bundle 的方式接入当前 profile(复制进 profiles/node_modules 并写入 dsh.profile.bundles),客户端启动的任一运行时都能用上;市场默认关闭、开启后才联网;固定地址连接时会撤回(该运行时不由客户端启动);复用本机已在运行的实例则会保守地重新接入(只恢复条目、不换插件目录)。目录的每日自动采集 + 人工精选、以及「先审查、再安装」的完整流程见内置安全市场。官方 Web UI 自身的能力(技能、插件、交互等)仍随官方发版直接出现在窗口里。桌面外壳自身的后续工作见开发指南与 TODO:macOS/Windows 签名与公证、系统通知、OS Keychain、语音输入,以及内置运行时的独立更新通道、运行中实例的周期探测提示等。
源码开发需要 Node.js ^22.19.0 || >=24.0.0 和 pnpm;不需要另外安装 dsh:
git clone https://github.com/bruc3van/dsh-desktop.git
cd dsh-desktop
pnpm install
pnpm run dev
构建与门禁脚本、运行时选择细节、版本发布流程与项目当前状态见开发指南;进程模型、信任边界和设计取舍见桌面客户端架构。欢迎提交贡献与问题反馈,尤其是 Windows 使用、固定地址连接和打包方面的反馈。
作者维护
dsh-plugin 标签的仓库由脚本每天自动抓取,再经人工逐个核实——真插件进目录,蹭热度的进黑名单,每条剔除理由公开可查;并告诉你每个插件适合谁、从哪里开始。本客户端内置安全市场的目录数据即来源于它,详见内置安全市场。官方仓库
dsh 与 Web UI 的上游项目:本客户端窗口里加载的正是官方 Web UI,随安装包分发的运行时即官方 @deepseek-ai/dsh——本项目是它的非官方第三方桌面客户端。MIT 许可证仅适用于本仓库自行维护的代码和素材。随安装包分发的官方 @deepseek-ai/dsh 及其他第三方依赖分别适用其自身许可证。本项目名称中的 “DeepSeek Harness” 仅用于说明兼容对象,不表示官方关系。
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。