Back to home

Kimoiran

dsh-gui-trash

一个笨蛋写的gui?本质是套壳,而且有点麻烦,只算是提供一种像人的思路

Stars
0
Language
JavaScript
Created
Aug 14, 2026
Updated
Aug 14, 2026

Introduction

dsh-gui-trash

一个笨蛋用dsh自己做了个GUi,其实按理来讲就是electron套壳

你不能指望一个笨蛋能写出什么好东西

但是考虑到我取名都叫trash了,我写得多烂你都不应该骂我,难道你没有心理准备吗

哦对了,应该只有Windows能用?我没在其它地方测试过

DeepSeek Harness 的桌面 GUI:把 dsh web 的界面装进一个原生窗口(Electron)

⚠️⚠️⚠️AI领域神人警告⚠️⚠️⚠️

1786740068790

快速开始

哦对了,其实我根本没怎么测试

0. 前提

  • 装了 Node.js ≥ 22pnpm
  • harness 源码放在 dsh-gui-trash上一级目录
  • 如果在不往harness里装载插件的情况下使用的话是需要的
dsh
├── deepseek-harness\      ← harness(提供 WebUI)
└── dsh-gui-trash\         ← 本插件

1. 两步启动(源码,最简单)

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或许就没这个顾虑了)

1786740217963

2. 常见问题

其实是我猪鼻导致的一些幽默问题

现象处理
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,哦我的朋友这不是bug这是特性
打包 exe 报Cannot create symbolic linkWindows 没开开发者模式: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-trashnpx dsh-gui-trash开发 / 临时启动electron(作为依赖)
③ exe双击dsh-gui-trash.exe双击即用先在插件目录pnpm run build:exe

三种方式的行为完全一致:Web-UI 已在运行 → 附着开窗;没在运行 → 拉起 dsh web 并开窗;之后每 ~3s 探活、掉线自动拉起(守护);关窗即退出;最小化到任务栏;无托盘。


方式一:作为插件装进 harness

装进 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.bundlescordis.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.jsondependencieslink:... + dsh.profile.bundles 挂载层),关掉 dsh web、甚至重启电脑都不会消失;只有 dsh plugin remove 才会同时移除依赖和挂载层。

📦 挂载层已自动持久:因为声明了 dsh.bundleadd 时挂载层就写进 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-trashpnpm包管理器。这条命令执行的是 package.jsonscripts.dsh-gui-trash 定义的脚本(内容 electron electron/)。它要求你当前在 dsh-gui-trash 源码仓库里、且已 pnpm install(electron 在 node_modules)。用于源码开发/调试
  • npx dsh-gui-trashnpx 是 Node 自带的**"运行某包命令"工具。它按 package.jsonbin 字段找到入口 bin/dsh-gui-trash.js 并执行;包已安装就用本地的,没有就临时下载。因为 electron 声明在 dependencies,会一并就位。用于安装后**的场景。

一句话:pnpm 走的是"仓库里的开发脚本",npx 走的是"包发布的命令行入口"。


方式三:打包 exe(可选)

注:目前不保证能够正常运行,我还是建议在trash目录使用pnpm dsh-gui-trash,或者写个脚本什么的,exe目前不太稳定,后续我可能会改(如果我能想起来的话)

cd dsh-gui-trash
pnpm install
pnpm run build:exe        # electron-builder → dist/dsh-gui-trash.exe
  • 原理:electron-builder 把 Electron 运行时 + electron/main.js 打成一个 portable exe。它"自包含"的只是 Electron 运行时(运行 GUI 窗口不需要 node/electron/pnpm);但不含 harness——仍需一份可用的 dsh(源码 checkout 或已安装的 dsh web)来提供实际 WebUI 与 AI 功能。exe 能做的是:没运行时替你 spawn 起 harness,但它自己不"是" harness。
  • 价值:双击即用;可放进 Windows 开机自启(Win+Rshell:startup,把 exe 快捷方式放进去)。
  • 可选:不打 exe 也有全部功能(方式一、二照常)。
  • 代价:exe 体积 ~100MB+(就是 Electron 运行时本身);electron-builder 首次运行要下载打包工具链,国内可用镜像 electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/
  • :Windows 打包报 Cannot create symbolic link 是没开"开发者模式"(electron-builder 解压 winCodeSign 时含 macOS 符号链接)——start ms-settings:developers 打开开发者模式,或用管理员终端重跑。产物在 dist\dsh-gui-trash.exe(portable 单文件)。

与 DeepSeek Harness 的关系(原理)

dsh-gui-trashdsh 是两个平级、互不知情的进程,唯一联系是 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 的端口
launchModesource(源码 checkout)/ installed(npm 安装)/ 留空自动
launchRootsource 模式下 harness checkout 根目录
launchCommand拉起 dsh 的命令(pnpm dsh webdsh web

如何找到 harness(查找优先级)

启动时按这个顺序决定"从哪拉起 dsh web":

  1. 默认:自动探测兄弟文件夹。独立模式(方式二 / 三)扫描本插件上一级目录里带 pnpm-workspace.yaml 的兄弟 checkout,例如:

    E:\dsh
    ├── deepseek-harness\   ← 自动找到这里
    └── dsh-gui-trash\      ← 本插件
    

    找到就自动写回 config.jsonlaunchMode: source + 正确的 launchRoot + pnpm dsh web)。插件模式同理:跑在 dsh 进程里,从 process.argv[1] 向上找。

  2. 自愈:如果 config.json 里的 launchRoot 已经失效——搬家了、原目录只剩 .git、或路径带空格——下次启动会自动重新探测并纠正,不用手动改。

  3. 都找不到 → 自己改:harness 既不是兄弟目录、也没装成全局 dsh,就在 config.json 手写 launchCommand + launchRoot(绝对路径):

    {
      "launchMode": "source",
      "launchRoot": "D:\\wherever\\deepseek-harness",
      "launchCommand": "pnpm dsh web"
    }
    

    手写的 launchCommand 优先;launchModeinstalled 或留空时,不会用自动探测覆盖你的手写值。

端口约定(重要)

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