deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
一个笨蛋用dsh自己做了个GUi,其实按理来讲就是electron套壳
你不能指望一个笨蛋能写出什么好东西
但是考虑到我取名都叫trash了,我写得多烂你都不应该骂我,难道你没有心理准备吗
哦对了,应该只有Windows能用?我没在其它地方测试过
DeepSeek Harness 的桌面 GUI:把 dsh web 的界面装进一个原生窗口(Electron)
⚠️⚠️⚠️AI领域神人警告⚠️⚠️⚠️

哦对了,其实我根本没怎么测试
dsh-gui-trash 的上一级目录dsh
├── deepseek-harness\ ← harness(提供 WebUI)
└── dsh-gui-trash\ ← 本插件
cd E:\dsh\dsh-gui-trash
pnpm install # ① 装依赖(首次下载 Electron,约 100MB)
pnpm dsh-gui-trash # ② 启动
就这两步:它会自动找到 deepseek-harness → 拉起 dsh web → 弹出桌面窗口。你不需要先手动开 WebUI。
如果想要装载到harness的话(当然我用的是源码)
pnpm dsh plugin --profile web add -w ..\dsh-gui-trash
挂载 + 启动
pnpm dsh web --patch ..\dsh-gui-trash\cordis.patch.yml
在插件里它是这个样子
(它会拉起窗口,如果不想每次都拉起的话,最好记得disable,哦是的,如果纯插件的话你需要先开web再开GUI,如果使用命令行启动或者打包成exe或许就没这个顾虑了)

其实是我猪鼻导致的一些幽默问题
| 现象 | 处理 |
|---|---|
pnpm install 报证书错误 / 卡在下载 Electron |
用镜像 |
| 启动后窗口一直连不上 | 打开%USERPROFILE%\.dsh\desktop\config.json,把 launchCommand 改成能拉起你 harness 的命令 |
| 想彻底停掉 | 关窗口即可(它拉起的 harness 一起关);或装成插件后用/dsh-gui-trash disable |
/dsh-gui-trash 提示"未找到 Electron" |
迁移目录/新环境后 node_modules 丢了:回dsh-gui-trash 目录再跑一次 pnpm install |
| 每次启动web端都会自动拉起GUI | 我写的大份的逻辑就是:enable就会拉起GUI,哦我的朋友 |
打包 exe 报Cannot create symbolic link |
Windows 没开开发者模式:start ms-settings:developers 打开"开发者模式",或改用管理员身份运行终端再 pnpm run build:exe |
想更精细地控制(在 dsh 里启停/删除、打包 exe、开机自启),看下面"三种使用方式"。
它有三种启动方式,最终都启动同一个 Electron 守护(electron/main.js),区别只是"怎么把它拉起来":
| 方式 | 命令 | 适用场景 | 前置条件 |
|---|---|---|---|
| ① 插件 | 装进 harness,用/dsh-gui-trash 命令 |
想在 dsh 里统一启用/停用/删除 | dsh plugin add + 挂载行 |
| ② 命令行 | pnpm dsh-gui-trash 或 npx dsh-gui-trash |
开发 / 临时启动 | electron(作为依赖) |
| ③ exe | 双击dsh-gui-trash.exe |
双击即用 | 先在插件目录pnpm run build:exe |
三种方式的行为完全一致:Web-UI 已在运行 → 附着开窗;没在运行 → 拉起 dsh web 并开窗;之后每 ~3s 探活、掉线自动拉起(守护);关窗即退出;最小化到任务栏;无托盘。
装进 harness 后,它成为 dsh 的宿主插件,可在 dsh 内统一控制。
cd deepseek-harness
pnpm dsh plugin --profile web add -w ../dsh-gui-trash # 源码:pnpm dsh;-w 因 profile 是 pnpm workspace 根;发布后:dsh plugin --profile web add -w dsh-gui-trash
pnpm dsh web # cordis.patch.yml 由 dsh.bundle 自动应用,无需再 --patch
源码环境是
pnpm dsh,npm/npx 安装后才直接是dsh。本包声明了dsh.bundle(见package.json),add会把它追加进 profile 的dsh.profile.bundles,cordis.patch.yml随之自动生效——不再有 "declares no dsh.bundle" 警告,也无需手动--patch。⚠️
dsh plugin add的坑:如果dsh-gui-trash路径含空格(如C:\Program Files\...),命令会被 shell 劈成两段装错。务必用无空格路径(如E:\dsh\...)。若已装坏,手动打开$DSH_HOME\profiles\web\package.json,把dependencies改成"dsh-gui-trash": "link:E:/dsh/dsh-gui-trash"(正斜杠),再在 profile 目录pnpm install。 不过我建议最好一开始就下在没有空格的路径里,虽然不知道这是不是bug🔄 插件会持久保留,重启不丢:插件被写进 profile 的
package.json(dependencies的link:...+dsh.profile.bundles挂载层),关掉dsh web、甚至重启电脑都不会消失;只有dsh plugin remove才会同时移除依赖和挂载层。📦 挂载层已自动持久:因为声明了
dsh.bundle,add时挂载层就写进 profile 的dsh.profile.bundles,之后每次pnpm dsh web都自动带上,无需再手动--patch或编辑cordis.patch.yml。
挂载后,聊天框 / 菜单里多出 dsh-gui-trash 命令:
| 操作 | 命令 |
|---|---|
| 启用 | /dsh-gui-trash enable |
| 停用 | /dsh-gui-trash disable |
| 查看状态 | /dsh-gui-trash status |
| 立即启动 | /dsh-gui-trash launch(或 /dsh-gui-trash) |
| 删除插件 | dsh plugin --profile web remove dsh-gui-trash + 移除组合行;可选删 %USERPROFILE%\.dsh\desktop\ |
enabled=true 写入 config.json,Electron 守护被拉起。enabled=false,守护被杀;此后 npx dsh-gui-trash 与 exe 都会因读到 false 而拒绝启动。dsh plugin remove 移除包;插件 dispose() 杀掉它拉起的守护进程。注意:插件挂载后
enabled默认true,所以dsh web启动时(含插件)会自动弹窗。想关掉自动弹窗,用/dsh-gui-trash disable(该状态会写进 config.json 持久保存,之后重开不再自动弹)。
npx 与 pnpm 的区别
两者最终都启动同一个守护,区别在于"从哪找到并启动 Electron":
# 源码 / 开发态
cd dsh-gui-trash
pnpm install
pnpm dsh-gui-trash
# 安装后
npx dsh-gui-trash
pnpm dsh-gui-trash:pnpm 是包管理器。这条命令执行的是 package.json 里 scripts.dsh-gui-trash 定义的脚本(内容 electron electron/)。它要求你当前在 dsh-gui-trash 源码仓库里、且已 pnpm install(electron 在 node_modules)。用于源码开发/调试。npx dsh-gui-trash:npx 是 Node 自带的"运行某包命令"工具。它按 package.json 的 bin 字段找到入口 bin/dsh-gui-trash.js 并执行;包已安装就用本地的,没有就临时下载。因为 electron 声明在 dependencies,会一并就位。用于安装后的场景。一句话:pnpm 走的是"仓库里的开发脚本",npx 走的是"包发布的命令行入口"。
注:目前不保证能够正常运行,我还是建议在trash目录使用pnpm dsh-gui-trash,或者写个脚本什么的,exe目前不太稳定,后续我可能会改(如果我能想起来的话)
cd dsh-gui-trash
pnpm install
pnpm run build:exe # electron-builder → dist/dsh-gui-trash.exe
dsh(源码 checkout 或已安装的 dsh web)来提供实际 WebUI 与 AI 功能。exe 能做的是:没运行时替你 spawn 起 harness,但它自己不"是" harness。Win+R → shell:startup,把 exe 快捷方式放进去)。electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/。Cannot create symbolic link 是没开"开发者模式"(electron-builder 解压 winCodeSign 时含 macOS 符号链接)——start ms-settings:developers 打开开发者模式,或用管理员终端重跑。产物在 dist\dsh-gui-trash.exe(portable 单文件)。dsh-gui-trash 与 dsh 是两个平级、互不知情的进程,唯一联系是 HTTP:
dsh web 照常运行,把前端界面与 /api 服务在 http://127.0.0.1:<port> 上(Electron 窗口就是一个 Chromium 浏览器,加载的正是这个地址)。dsh-gui-trash 负责:探测该端口 → 没跑就按 launchCommand 拉起 dsh web → 开窗并守护它。所以运行只需两样:① dsh 可用(源码 checkout 用 pnpm dsh web,或 npm 安装后 PATH 有 dsh);② dsh-gui-trash 有 Electron。不需要改 harness 源码、不需要 cordis.patch.yml(方式二、三)、不需要 dsh plugin add(方式二、三)。
$DSH_HOME/desktop/config.json(Windows 默认 %USERPROFILE%\.dsh\desktop\config.json),首次运行自动生成:
{
"enabled": true,
"port": 3080,
"launchMode": "source",
"launchRoot": "不管你在哪\\deepseek-harness",
"launchCommand": "pnpm dsh web"
}
| 字段 | 含义 |
|---|---|
enabled |
总开关,false 时一切 GUI 入口拒绝启动 |
port |
探测/连接dsh web 的端口 |
launchMode |
source(源码 checkout)/ installed(npm 安装)/ 留空自动 |
launchRoot |
source 模式下 harness checkout 根目录 |
launchCommand |
拉起 dsh 的命令(pnpm dsh web 或 dsh web) |
启动时按这个顺序决定"从哪拉起 dsh web":
默认:自动探测兄弟文件夹。独立模式(方式二 / 三)扫描本插件上一级目录里带 pnpm-workspace.yaml 的兄弟 checkout,例如:
E:\dsh
├── deepseek-harness\ ← 自动找到这里
└── dsh-gui-trash\ ← 本插件
找到就自动写回 config.json(launchMode: source + 正确的 launchRoot + pnpm dsh web)。插件模式同理:跑在 dsh 进程里,从 process.argv[1] 向上找。
自愈:如果 config.json 里的 launchRoot 已经失效——搬家了、原目录只剩 .git、或路径带空格——下次启动会自动重新探测并纠正,不用手动改。
都找不到 → 自己改:harness 既不是兄弟目录、也没装成全局 dsh,就在 config.json 手写 launchCommand + launchRoot(绝对路径):
{
"launchMode": "source",
"launchRoot": "D:\\wherever\\deepseek-harness",
"launchCommand": "pnpm dsh web"
}
手写的 launchCommand 优先;launchMode 为 installed 或留空时,不会用自动探测覆盖你的手写值。
exe / 守护用 config.json 的 port 探测 dsh web。手动 dsh web --port 8080 会被判为"未运行"并另起一个 3080 实例。解决:两者端口一致。暂不支持随机端口自动发现。
其实是不会写
dsh-gui-trash/
├── package.json # name + bin + scripts + deps(electron → dependencies)
├── lib/index.js # Cordis 宿主插件(ESM)
├── bin/dsh-gui-trash.js # npx 命令行入口(ESM)
├── electron/
│ ├── package.json # 嵌套 CJS 入口(electron-builder 用)
│ ├── main.js # Electron 守护主进程(CJS)
│ └── preload.js # 标题栏:拖拽条 + 主题上报(CJS)
├── electron-builder.yml # 可选 exe 打包
├── cordis.patch.yml # 挂进 harness 的组合行
└── README.md CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。