deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:Icather/dsh-clean-desktop-shell
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
DeepSeek Harness 的纯净桌面壳(DSH 插件形态)
只做一件事:给已配置好的 DSH Web 加一层干净的桌面窗口——系统托盘、单实例、像普通软件一样用。无毛玻璃、无花哨材质,纯净。
dsh-clean-desktop-shell 是一个 DSH 插件形态 的纯净桌面壳:它给已经跑起来的 DSH Web(默认 http://127.0.0.1:3080)套一层原生桌面窗口——系统托盘、单实例,像普通桌面软件一样使用。不做任何视觉改造:不加毛玻璃、不改界面,纯粹是"窗口壳"。
与生态里其他桌面端方案的最大区别:
| 其他桌面端(如 dsh-desktop 系列) | 本插件 | |
|---|---|---|
| 形态 | 独立 Electron 应用,自带独立 profile | DSH 插件,挂载进现有 profile |
| Profile | 新建 desktop profile,插件/配置要重装 | 复用现有 web profile,零迁移 |
| 视觉改造 | 自绘标题栏 / 毛玻璃等 | 零改造,纯净窗口壳 |
| 跟随上游 | 固定版本 | 已适配 DSH 0.1.2 BrowserAuth(冷启动自动认证;不接管、不杀外部后端) |
① 像双击桌面应用一样,一键启动 DSH
不用开终端、不用记命令。双击桌面快捷方式,DSH 窗口立刻弹出,和启动任何一个普通软件一样自然:
② 后端活性实时监测 · 快捷手动自主启停
托盘实时显示后端状态(运行中 / 启动中 / 未运行 / 错误),一键启停:
dsh 自动弹出桌面窗口;也可通过插件创建的桌面快捷方式双击,媲美原生桌面端的体验。后端启停等管理操作在托盘右键:
窗口的可靠性(保留页面的连接恢复):
壳不会因探测失败重建已加载文档,但第三方插件自身的断线处理仍可能改变其局部视图。确认退出与显式重载仍会离开当前页面。
v0.1.7 修复了插件形态在 macOS 上无法定位 Electron.app 路径的问题(该 bug 导致窗口在 Mac 上完全静默失败)。
但当前开发者没有 Mac 实机,以下事项仍然依赖 Mac 用户验证/贡献:
.dmg 安装包未签名、未公证:Apple 要求年度开发者计划($99/年)才能给安装包签名+公证。首次打开 .dmg 里的应用,很可能提示「已损坏,无法打开」或「无法验证开发者」。这不是应用本身损坏,是 Gatekeeper 拦截了未签名应用。
xattr -cr "/Applications/DSH Clean Desktop Shell.app",然后右键 → 打开。Electron.app 解压后的可执行位、quarantine 扩展属性等只有真机能确认行为是否完全正确。
如果窗口还是没弹出来:启动失败时会把诊断信息写到 DSH home 下的 desktop-shell-launch.log:
cat "${DSH_HOME:-$HOME/.dsh}/desktop-shell-launch.log"
把内容贴到 Issue 即可——里面记录了平台、架构、Node 版本、DSH home、运行时目录和具体报错。没有界面时,这是唯一能回传的信息。
诚挚邀请有 Mac 环境、愿意一起打磨的同学参与:能帮忙验证安装流程、补充签名配置、或者把开机自启/登录项做进 Electron 托盘,欢迎直接提 PR 或在 Issue 里 @ 我,我会把你加入 CONTRIBUTORS.md。
第三方安全扫描器(如 dsh-xray)会给本项目打出「高能力 + 敏感行为」的评级。这个评级没有误报——列出的每一条都属实,但每一条都有明确且必要的原因。既然要装进你的机器,就该摊开讲清楚。
| 行为 | 为什么必须这么做 | 代码位置 |
|---|---|---|
| 执行系统命令(spawn) | 壳的核心功能就是启动 / 重启 / 停止 dsh web 后端,以及探测 3080 端口占用。不调用系统命令无法实现。 |
electron/service.js |
| 下载约 100MB 的 Electron 运行时 | 首次启动需要。两个源按网络环境自动竞速(3 秒超时):github.com 与 npmmirror.com——后者是国内镜像,CN 网络下通常更快。 |
src/host/runtime.js |
访问 api.github.com |
仅用于托盘「检查更新」拉取最新 Release 信息。 | electron/update.js |
| 读取环境变量 | 只用于定位路径和功能开关:DSH_HOME(DSH 主目录)、DSH_SHELL_ELECTRON_DIR(复用本地 Electron,跳过下载)、DSH_SHELL_AUTO_LAUNCH=0(关闭自动弹窗)、USERPROFILE / APPDATA(Windows 下定位 dsh.cmd 与快捷方式目录)。 |
src/host/common.js、src/host/index.js、electron/shortcut.js |
修改 DSH 运行时(cordis.patch.yml) |
DSH 官方的插件注册机制,所有 DSH 插件都靠它挂载,并非本项目特有行为。 | cordis.patch.yml |
边界:不上传任何数据、不读取会话内容、不回传遥测。全部网络请求只有上面两类(下载运行时 / 查更新),且都可通过设置 DSH_SHELL_ELECTRON_DIR 完全避免。
安装包的未签名警告(Windows SmartScreen、macOS Gatekeeper)来自缺少代码签名证书,与上述行为无关。
扫描器给出的「高能力」评级来自上一节那四类能力(文件 / 网络 / 命令 / 凭据)。下面把兼容范围、依赖、外部服务与失败边界摊开声明,供人工审阅——声明不等于验收,逐条注明证据。
| 项 | 声明 | 依据 |
|---|---|---|
| Node.js | >=20.0.0(engines.node) |
host 半边用全局 fetch 与 AbortSignal.timeout;Electron 半边跑在 Electron 33 内嵌的 Node 20.18 上。没有更新 API 的依赖。 |
| DSH | >=0.1.1 <0.2.0(dsh.compatibility.dsh) |
面向 0.1.x 的插件契约;0.1.2 之前没有 BrowserAuth,host 半边对该代有显式守卫(拿不到 authenticatedUrl() 时照常拉起窗口,只是不带 bootstrap URL)。 |
dsh.compatibility.dshReleases 逐版本标注实测状态:
| DSH 版本 | 状态 | 证据 |
|---|---|---|
0.1.5-rc.1 |
compatible |
真机端到端:token 横幅 → 插件自动弹壳 → 窗口渲染 UI 并写入 dsh-auth cookie;掉线保留页面、确认退出切离线页均实测通过 |
0.1.5-rc.2、0.1.5-alpha.2 |
unknown |
未做运行验收 |
0.1.1-rc.2 |
unknown |
「0.1.2 之前」这条代码路径有独立断言(真实 host 模块 + 无 authenticatedUrl 的 connection),但没在真实该版本上跑完整验收 |
| 类型 | 内容 |
|---|---|
| 运行时依赖 | electron-updater(托盘「检查更新」)、semver(版本比较)。两者都只在 Electron 半边使用;host 半边不加载任何第三方依赖。 |
| peer 依赖 | @deepseek-ai/dsh(可选)——宿主由 DSH 提供,不随本包安装。 |
| 开发依赖 | electron、electron-builder、sharp、png-to-ico(仅构建与图标生成)。 |
| 生命周期脚本 | 无。 本包不声明 preinstall / install / postinstall / prepare;scripts 只有 build / check / dev / icons / pack 这些手动入口。 |
| 安装期脚本例外 | pnpm.allowScripts 放行了 electron 自身的 postinstall(它要下载 Electron 二进制)。这是依赖的脚本、不是本包的,且只在装开发依赖时出现。 |
| 端点 | 何时访问 | 失败后果 |
|---|---|---|
github.com / npmmirror.com |
首次准备 Electron 运行时,两源 3 秒竞速下载(约 100MB) | 两源都失败 → 窗口不启动,并写入 <DSH_HOME>/desktop-shell-launch.log(含平台、错误原文与替代方案) |
github.com(rcedit) |
首次给 runtime exe 打任务栏图标(约 1.3MB) | 下载限时 20 秒、整步限时 25 秒,超时只损失自定义图标,不影响出窗;下次启动重试 |
api.github.com |
托盘「检查更新」/ 自动更新 | 静默失败,不影响使用 |
| 其他 | 无。不上传数据、不读会话内容、无遥测。 | — |
patchExeIcon 首行 isWin 判断)。dsh CLI:托盘「设置后端文件夹」手动指定,或设 DSH_BACKEND_DIR。在一台干净的一次性 DSH home + 一次性 profile 上跑完整安装 / 启动 / 卸载循环(不触碰日常 profile),DSH 0.1.5-rc.1、Windows 11:
| 步骤 | 命令 | 结果 |
|---|---|---|
| 安装 | dsh plugin --profile web add file:<repo> |
退出码 0(pnpm 2.2s);--dump-config 出现插件条目 |
| 启动 | dsh web --no-open |
打印 launch token 横幅;裸 / → 401、带 token → 303 + Set-Cookie: dsh-auth-…、带 cookie → 200;首页 manifest 含 dsh-clean-desktop-shell/client.js(插件在前端已挂载) |
| 插件拉起窗口 | 同上 | host 半边完整走通:inject(['connection']) 触发 → webServer 可解析 → 铸出 launch URL → launchShell() 被调用(用临时探针逐点断言)。窗口是否可见未在本环境验收:验收机是 CI 式无 GPU 沙箱,Electron 报 FATAL: GPU process isn't usable 后退出,与本插件无关(同一台机器上不带任何 GPU 参数的空白 Electron 应用同样退出,带 --in-process-gpu 则正常)。窗口渲染本身在此前用带 GPU 参数的 harness 单独验证过。 |
| 卸载 | dsh plugin --profile web remove dsh-clean-desktop-shell |
退出码 0(pnpm 1.4s);--dump-config 中插件条目归零 |
| 回滚 | 卸载即回滚:dsh.profile.bundles 与 dependencies 同步移除,后端与窗口行为回到未安装状态 |
— |
方式一:从 Release 下载安装包(想要独立桌面应用的用户)
DSH-Clean-Desktop-Shell-Setup-<版本>.exeDSH-Clean-Desktop-Shell-<版本>.dmg(Intel)或 -arm64.dmg(Apple Silicon)安装包会自动创建桌面快捷方式,并提供系统托盘等完整桌面体验。
方式二:作为 DSH 插件安装(DSH 生态用户)
dsh plugin --profile web add dsh-clean-desktop-shell
重启 dsh web 后,桌面壳窗口会自动弹出(首次运行需联网准备 Electron 运行时,约 1-2 分钟)。
方式二得到的是"随 DSH 启动的桌面壳":窗口由插件在
dsh web启动时自动拉起,不产生独立安装包 / 桌面图标。想要可双击启动、带桌面快捷方式和自动更新的独立应用,请用方式一。两种方式的核心窗口体验一致。
桌面壳需要本机有可用的
dsh web服务(或配置的远程地址)。见下方「使用」。
为什么会看到警告?
我们的安装包没有代码签名证书(个人开源项目暂未购买,证书年费约数百美元)。Windows 的 Microsoft Defender SmartScreen 是一个信誉系统——它根据"下载量 + 干净运行的记录"判断一个程序是否可信。对下载量少、未签名的 exe,它无法确认信誉,就会警告。这不代表文件有病毒:本项目完全开源,代码可审阅,也可本地构建比对(见下)。
Edge 下载时会看到:
下载面板里该文件被标记为"不常下载的文件",需要手动保留:
... 菜单双击安装时会看到:
蓝色对话框「Windows 已保护你的电脑」——Microsoft Defender SmartScreen 阻止了无法识别的应用启动:
DSH-Clean-Desktop-Shell-Setup-<版本>.exe备选:一次性解除锁定(推荐)
右键安装包 → 属性 → 常规 → 底部勾选「解除锁定」→ 确定。之后双击不再有警告。
或 PowerShell 批量解除:
Unblock-File -Path "$env:USERPROFILE\Downloads\DSH-Clean-Desktop-Shell-Setup-*.exe"
关于文件安全性的说明
安装包由 GitHub Actions 从本仓库源码自动构建(见 .github/workflows/build.yml),代码完全开源可审阅。如仍有疑虑,可自行 git clone 后按「开发」一节本地构建比对,或稍等下载量积累——SmartScreen 信誉度上去后警告会自动消失。
说明:代码签名证书(EV 或 Azure Trusted Signing)可以彻底消除这个警告,但需要付费且对个人开源维护者不划算。本仓库会在条件允许时考虑接入签名。
┌────────────── 内核(dsh web / headless 服务)──────────────┐
│ 会话 · Agent · 插件 · 记忆 都在这层,与界面解耦 │
└───────────────────────────┬──────────────────────────────┘
│ http://127.0.0.1:3080(或远程地址)
▼
┌───────────────────────────────────────────────────────────┐
│ dsh-clean-desktop-shell(Electron 壳) │
│ 托盘 · 单实例 · 离线自动重连 · 桌面快捷方式 │
│ │
│ 同一份壳代码,两种分发形态: │
│ ├─ 安装包版:独立 exe,双击即用,自动更新 │
│ └─ 插件版:随 dsh web 启动自动弹窗(自管 Electron 运行时)│
└───────────────────────────────────────────────────────────┘
127.0.0.1:3080(已配置好的 web profile,零迁移)。dsh web 启动)共用 electron/ 壳代码,仅运行时来源与启动方式不同(见「安装」)。| 平台 | 壳 | 状态 |
|---|---|---|
| Windows | ✅ Electron(无边框 + 原生窗口按钮) | 已发布(NSIS 安装包) |
| macOS | ✅ Electron(hiddenInset) | 已发布(CI 构建 Intel + Apple Silicon DMG) |
| Linux | —(浏览器 / PWA 直连内核) | 不做 |
| Termux / 手机 / 平板 | —(headless / PWA 直连内核) | 由内核远程访问支持 |
npm install
npm run build # 构建插件 bundle
npm run dev # 启动壳(开发模式)
npm run pack # 打包 NSIS (Win) / DMG (mac)
npm run check 运行语法和 Node 自检。用 Electron 运行 scripts/selftest-recovery.mjs 还会验证真实启动失败后的重试、连续手动重试及即时失败不会形成重连循环;建议通过 --user-data-dir 指定临时目录。
以下为 sh/bash 示例;ELECTRON 指向预先安装的 Electron 可执行文件。用独立 user-data 目录运行,不启动日常应用、不发送模型请求:
test -n "$ELECTRON" && "$ELECTRON" --user-data-dir="$(mktemp -d)" scripts/selftest-recovery.mjs
该入口使用临时无执行权限文件与随机端口的本地页面验证恢复边界;不是完整真实会话或性能验收的替代品。
shell.writeShortcutLink 在若干失败场景下是抛异常而不是返回 false,而托盘菜单与首次运行提示两处调用都没有接住它,异常变成无人处理的 Promise rejection,界面上什么都不显示。现在两处都捕获异常并显示错误原文。…\OneDrive\桌面),此时快捷方式确实创建成功、只是不在用户习惯查看的「桌面」文件夹里。成功与失败弹窗现在都会写明路径,这个歧义不再存在。dshReleases["0.1.5-rc.3"] = "compatible"——该状态来自一台真实 Electron 窗口对着 0.1.5-rc.3 后端的端到端复验(launch token 交换 → 落到干净根路径 → 真实 UI 渲染 → dsh-auth cookie 落位),未经验证的版本一律保持 unknown。package-lock.json 中陈旧的 version 字段(0.1.10 → 0.1.13)。engines.node: ">=20.0.0" 与 dsh.compatibility(含逐版本实测状态),并补齐依赖、生命周期脚本(无)、外部服务、失败边界与一次性 profile 的安装 / 启动 / 卸载验收记录——满足 DSH STORE 的上架契约。shellAPI.connectionReport / onReconnectRequest):HTTP 活着但页面 WebSocket 已断的情况不再被掩盖;手动与自动重试共用同一次检查,避免即时失败反馈成重连循环。?token= → Cookie 认证,无需手动重启后端。此前只有「壳自己启动后端」这条路能拿到 token,插件形态(dsh web 自动弹壳)与「先手动跑 dsh web 再开壳」都会停在未认证页。dsh web: 横幅并保留完整 ?token=(只接受 loopback,token 属本机进程机密),对 0.1.2 之前的裸 URL 保留回退解析以免退化成等待超时;外部已运行的 backend 不会被擅自重启或杀掉。config.json 反而会在下次重启后失效。dsh-desktop-mode / dsh-desktop-platform / dsh-desktop-titlebar-inset,供 better-sidebar 等可停靠面板按拖拽条高度避让。semver.coerce + semver.gt),替换手写元组比较。AbortSignal.timeout(标准自清理 API,无泄漏风险)。D:\deepseek-harness\prod\... 开发机路径:改用 config backendPath + DSH_BACKEND_DIR 环境变量 + npm 全局目录候选。taskkill /T /F 树杀(.cmd shim 留下的孤儿 node 进程不再占端口);POSIX 先 SIGTERM 再 SIGKILL 优雅降级。shell.writeShortcutLink / readShortcutLink,移除 PowerShell + COM 依赖(顺带修复 OneDrive 桌面重定向问题)。uncaughtException / unhandledRejection 写入 userData/shell-crash.log(128KB 上限自动截断),便于附在 bug 报告中。includes('error.html') 改为精确 URL 比对。npm run check 扩展到覆盖全部 17 个发布 JS 文件的语法门禁(此前只检查 lib/index.js)。shell:true + windowsHide 执行,兼容 .cmd shim 与 PowerShell / cmd 环境。dist-tags.latest,与本地版本同源对比;不再错爬 GitHub /releases/latest(此前 GitHub Latest 标记未及时挪动时会弹出「当前 0.1.7 已是最新(v0.1.6)」的自相矛盾提示)。Electron.app 应用包,可执行文件位于 Electron.app/Contents/MacOS/Electron;此前按 Linux 布局去找顶层 electron,导致 Mac 上必然启动失败且无任何提示。desktop-shell-launch.log,并在提示中给出完整路径。CONTRIBUTORS.md,公开招募 Mac 合作开发者(代码签名 / 公证 / 实机验证)。dsh plugin add 装插件 → 重启 dsh web → 桌面壳自动弹出;Electron 运行时由插件自管理(本地复用 / 按网络环境自动选源下载)。spawn EINVAL、卡「启动中」的问题;「关闭后端」现在能真正停掉后端(含外部启动的实例);启动 / 重启 / 关闭带进度弹窗。欢迎任何形式的贡献——修 bug、加功能、改进文档都行。请先阅读 CONTRIBUTING.md(含项目结构、开发约定、提交规范、PR 流程),并遵守 CODE_OF_CONDUCT.md。安全漏洞请走 SECURITY.md 的私密报告流程。
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。