🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

桌面客户端套件 puddingfish/dsh-desktop

DeepSeek Harness
puddingfish16 天前有提交已提供中文文档扫描:含敏感能力

DSH Desktop —— DeepSeek Harness 的 Windows 桌面客户端 + 模型路由 / mmx 图像理解插件(绿色免安装 · 自动更新)

32.3/100
综合分
3
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/19 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add puddingfish/dsh-desktop
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · vision
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 16 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-desktop-repo(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/21 15:42:21

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 56 处,展示前 43 条)
  • 读取本地文件
    desktop/dsh-desktop/src/main.js:63
    return JSON.parse(readFileSync(configPath(), 'utf8'))
  • 写入本地文件
    desktop/dsh-desktop/src/main.js:70
    writeFileSync(configPath(), JSON.stringify(config, null, 2))
  • 读取本地文件
    desktop/dsh-desktop/src/main.js:76
    if (existsSync(devPath)) return devPath
  • 读取本地文件
    desktop/dsh-desktop/src/runtime.js:51
    if (typeof override === 'string' && override !== '' && existsSync(override)) return override
  • 读取本地文件
    desktop/dsh-desktop/src/runtime.js:63
    return existsSync(entry) ? entry : ''
  • 读取本地文件
    desktop/dsh-desktop/src/runtime.js:118
    return JSON.parse(readFileSync(paths().state, 'utf8'))
  • 写入本地文件
    desktop/dsh-desktop/src/runtime.js:125
    mkdirSync(dataDir, { recursive: true })
  • 写入本地文件
    desktop/dsh-desktop/src/runtime.js:126
    writeFileSync(paths().state, JSON.stringify(state, null, 2))
  • 读取本地文件
    desktop/dsh-desktop/src/runtime.js:132
    return typeof state.nodeExe === 'string' && state.nodeExe !== '' && existsSync(state.nodeExe)
  • 写入本地文件
    desktop/dsh-desktop/src/runtime.js:140
    mkdirSync(dir, { recursive: true })
  • 发起网络请求
    desktop/dsh-desktop/src/runtime.js:153
    const response = await fetch(url, { redirect: 'follow' })
  • 写入本地文件
    desktop/dsh-desktop/src/runtime.js:166
    await fs.writeFile(dest, Buffer.concat(chunks))
  • 写入本地文件
    desktop/dsh-desktop/src/runtime.js:177
    mkdirSync(paths().tmp, { recursive: true })
  • 执行外部命令来自配置/变量
    desktop/dsh-desktop/src/runtime.js:191
    child = spawn(exe, args, {
  • 读取本地文件
    desktop/dsh-desktop/src/runtime.js:229
    return readFileSync(file, 'utf8')
  • 删除本地文件
    desktop/dsh-desktop/src/runtime.js:236
    for (const file of files) fs.rm(file, { force: true }).catch(() => {})
  • 执行外部命令固定命令
    desktop/dsh-desktop/src/runtime.js:242
    const killer = spawn('taskkill', ['/pid', String(pid), '/T', '/F'], {
  • 请求外部主机nodejs.org
    desktop/dsh-desktop/src/runtime.js:252
    const response = await fetch('https://nodejs.org/dist/index.json', { signal: AbortSignal.timeout(15000) })
  • 发起网络请求
    desktop/dsh-desktop/src/runtime.js:252
    const response = await fetch('https://nodejs.org/dist/index.json', { signal: AbortSignal.timeout(15000) })
  • 发起网络请求
    desktop/dsh-desktop/src/runtime.js:318
    const response = await fetch(`${registry}/-/package/${DSH_PACKAGE}/dist-tags`, { signal: AbortSignal.timeout(8000) })
  • 读取本地文件
    desktop/dsh-desktop/src/runtime.js:335
    if (!existsSync(entry)) return undefined
  • 发起网络请求
    desktop/dsh-desktop/src/runtime.js:366
    const response = await fetch(url, { method: 'HEAD', redirect: 'follow', signal: AbortSignal.timeout(10_000) })
  • 写入本地文件
    desktop/dsh-desktop/src/runtime.js:466
    mkdirSync(paths().runtimes, { recursive: true })
  • 删除本地文件
    desktop/dsh-desktop/src/runtime.js:474
    await fs.rm(zipPath, { force: true })
  • 发起网络请求
    desktop/dsh-desktop/src/runtime.js:638
    const request = http.get({ host: '127.0.0.1', port, path: '/', timeout: timeoutMs }, (response) => {
  • 执行外部命令来自配置/变量
    desktop/dsh-desktop/src/runtime.js:707
    const child = spawn(nodeExe, [dshEntry, ...args], {
  • 执行外部命令固定命令
    desktop/dsh-desktop/src/runtime.js:780
    const killer = spawn('taskkill', ['/pid', String(child.pid), '/T', '/F'], {
  • 读取本地文件
    desktop/dsh-desktop/src/updater.js:21
    return JSON.parse(readFileSync(file, 'utf8'))
  • 写入本地文件
    desktop/dsh-desktop/src/updater.js:29
    writeFileSync(path.join(app.getPath('userData'), 'update-config.json'), JSON.stringify(config, null, 2))
  • 读取本地文件
    desktop/dsh-desktop/src/updater.js:35
    return !readdirSync(path.dirname(process.execPath)).some((name) => /^uninstall/i.test(name) && name.endsWith('.exe'))
  • 读取本地文件
    desktop/dsh-desktop/src/updater.js:78
    const yml = readFileSync(path.join(process.resourcesPath, 'app-update.yml'), 'utf8')
  • 发起网络请求
    plugins/dsh-mmx-vision/lib/client.js:150
    response = await fetch(ATTACH_ENDPOINT, {
  • 发起网络请求
    plugins/dsh-mmx-vision/lib/client.js:688
    const response = await fetch("/mmx-vision/status", { headers: { accept: "application/json" } });
  • 读取本地文件
    plugins/dsh-mmx-vision/lib/mmx-client.js:132
    const info = await stat(trimmed, { bigint: false })
  • 读取本地文件
    plugins/dsh-mmx-vision/lib/mmx-client.js:137
    const bytes = await readFile(trimmed, { signal })
  • 写入本地文件
    plugins/dsh-mmx-vision/lib/mmx-client.js:149
    await writeFile(path, bytes)
  • 删除本地文件递归
    plugins/dsh-mmx-vision/lib/mmx-client.js:150
    return { path, cleanup: () => rm(dir, { recursive: true, force: true }) }
  • 读取本地文件
    plugins/dsh-mmx-vision/lib/mmx-client.js:184
    if (existsSync(candidate)) return { packageDir: undefined, entry: resolve(candidate) }
  • 读取本地文件
    plugins/dsh-mmx-vision/lib/mmx-client.js:195
    if (!existsSync(manifestPath)) return undefined
  • 读取本地文件
    plugins/dsh-mmx-vision/lib/mmx-client.js:207
    if (!existsSync(entry)) return undefined
  • 读取本地文件
    plugins/dsh-mmx-vision/lib/mmx-client.js:239
    if (existsSync(candidate)) return candidate
  • 执行外部命令来自配置/变量
    plugins/dsh-mmx-vision/lib/mmx-client.js:387
    ? spawn(command.command, [...command.prefix, ...args], {
  • 执行外部命令来自配置/变量
    plugins/dsh-mmx-vision/lib/mmx-client.js:391
    : spawn(command.command, [...command.prefix, ...args], {
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库
涉及外部主机:nodejs.org

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 双击启动桌面客户端
  • 自动路由模型
  • 图像理解

README

由 DeepSeek 最新模型翻译生成
DSH Desktop DeepSeek Harness 的 Windows 桌面客户端与本地增强插件套件双击即用 · 绿色免安装 · 自动更新 为 DeepSeek Harness (DSH) 打造的三件套:一个桌面壳 + 两个功能插件。桌面端是官方 Web 版的外壳(套壳,不是重新实现)——功能与网页版完全一致,外加原生的窗口体验、托盘常驻与自动更新;插件按需安装,没有的环境依赖会自动「静默休眠」,不打扰任何人。 | 组件 | 位置 | 一句话 | | 🖥 dsh-desktop | desktop/dsh-desktop | Electron Windows 桌面客户端:双击启动、自定义标题栏跟随页面主题、托盘常驻、DSH 运行时 npm 自动升级、壳自动更新(安装版全自动 / 绿色版提示下载) | | 🔀 dsh-model-router | plugins/dsh-model-router | 模型路由插件:侧边栏独立「模型路由」入口,按任务类型自动选模型——主会话 / 子代理角色路由 + 轻量/重型关键词规则,简单任务用便宜模型,重型任务用贵模型 |
展开完整文档(README 剩余 1 节)
DSH Desktop

DeepSeek Harness 的 Windows 桌面客户端与本地增强插件套件双击即用 · 绿色免安装 · 自动更新

为 DeepSeek Harness (DSH) 打造的三件套:一个桌面壳 + 两个功能插件。桌面端是官方 Web 版的外壳(套壳,不是重新实现)——功能与网页版完全一致,外加原生的窗口体验、托盘常驻与自动更新;插件按需安装,没有的环境依赖会自动「静默休眠」,不打扰任何人。

| 组件 | 位置 | 一句话 |
| 🖥 dsh-desktop | desktop/dsh-desktop | Electron Windows 桌面客户端:双击启动、自定义标题栏跟随页面主题、托盘常驻、DSH 运行时 npm 自动升级、壳自动更新(安装版全自动 / 绿色版提示下载) |
| 🔀 dsh-model-router | plugins/dsh-model-router | 模型路由插件:侧边栏独立「模型路由」入口,按任务类型自动选模型——主会话 / 子代理角色路由 + 轻量/重型关键词规则,简单任务用便宜模型,重型任务用贵模型 |
| 👁 dsh-mmx-vision | plugins/dsh-mmx-vision | 图像理解插件:describe_image 后端换成本地 mmx CLI(MiniMax VLM),复用 mmx 登录态零配置;本机没有 mmx 时自动静默休眠(不注册工具、不显示配置、零报错) |

📥 下载安装

到 Releases 下载最新版,两种形态任选:

| 形态 | 文件 | 适合 | 更新方式 |
| NSIS 安装版 | DSH-Desktop-Setup-<版本>.exe | 日常主力机 | 全自动:启动 10 秒后静默检查 → 后台下载 → 询问「现在重启 / 退出时自动安装」 |
| 绿色免安装版 | DSH-Desktop-<版本>-portable-win-x64.zip | U 盘 / 受限环境 | 只提示:发现新版弹窗给发布页链接,下载新 zip 覆盖解压目录(数据都在 %APPDATA%,不受影响) |

- 无需管理员权限;首次启动自动准备 DSH 运行时(优先复用系统 Node.js 22.19+/24+,没有则从镜像下载独立运行时,约 30 MB,仅一次)。
- 用户数据与更新缓存在 %APPDATA%\DSH Desktop\,与安装目录无关。
- 默认端口 3080,被占用时自动落到 3081+。

详细操作见 docs/使用说明.md。

🧩 安装插件

git clone https://github.com/puddingfish/dsh-desktop.git
cd dsh-desktop
.\install-plugins.ps1 # 打包 + 安装两个插件到 web 与 headless profile(幂等可重跑)

重启 dsh web / DSH Desktop 后生效:侧边栏出现「模型路由」入口;本机装有 mmx CLI 的话,设置 → Web UI 插件里出现「图像理解(mmx)」卡片,带图消息自动走 MiniMax VLM。

本机没有 mmx(MiniMax 订阅)? 完全没关系:安装脚本检测不到 mmx 会直接跳过 dsh-mmx-vision(不写任何配置);已装的副本也会在运行时静默休眠——不注册 describe_image、不显示设置卡片、控制台零告警零报错。装好 mmx 后重跑脚本并重启即可启用。

🧭 多模型配置推荐(模型路由怎么配)

模型路由的核心思想:按任务类型把请求分流到不同档位的模型——杂活走便宜模型,硬活走旗舰,在不牺牲体验的前提下把费用降下来。先理解四个角色:

| 角色 | 负责什么 | 选型原则 |
| 主会话 | 你直接对话的模型:理解需求、规划、写关键代码 | 综合能力优先——它决定体验下限 |
| 子代理 | 后台委派任务(research、独立小任务) | 便宜 + 快即可;调用频率最高,是省钱大头 |
| 轻量任务 | 命中关键词的杂活(总结/翻译/格式化…) | 全线最便宜档 |
| 重型任务 | 命中关键词的硬活(重构/架构/调试…) | 旗舰档,只在需要时出场 |

下拉选项 = 你在 DSH 中已配置的模型。先把模型加进 DSH(设置 → 模型),再来「模型路由」页分配角色。

按需求选一套

| 方案 | 主会话 | 子代理 | 轻量 | 重型 | 适合谁 |
| ⚖️ 均衡省钱(推荐起步) | 标准档 | flash 档 | flash 档 | 旗舰档 | 大多数人:日常够用,硬活上旗舰 |
| 💰 预算优先 | 标准档 | flash 档 | flash 档 | 留空 | 轻度使用,成本压到最低 |
| 🚀 性能优先 | 旗舰档 | 标准档 | flash 档 | 旗舰档 | 重度编码、质量第一 |
| 🪶 极简尝鲜 | flash 档 | flash 档 | flash 档 | 标准档 | 简单场景先跑起来再说 |

示例(按你实际配置的模型替换):主会话 GLM-5.3,子代理/轻量 DeepSeek-v4-flash,重型 KIMI-K3。

配置五步

1. 侧边栏打开「模型路由」→ 打开「启用路由」开关;
2. 按上表给各角色选 Provider / 模型(留空 = 不改写,安全默认);
3. 轻量关键词建议:总结, 翻译, 格式化, 改名, 写文档, 列大纲;
4. 重型关键词建议:重构, 架构, 性能, 优化, 调试, 疑难;
5. 保存 → 看 dsh web 控制台,出现 model-router: … A/B -> C/D (light: keyword "总结") 即生效。

边界(知道这些更踏实)

- 你在会话里手动切过模型的请求不会被覆盖(「尊重显式选择」默认开);
- 路由器自身异常自动回退原配置,绝不阻断请求;
- 上下文压缩、会话标题生成有各自的模型设置(~/.dsh/settings.yaml),不走此路由——同样可以单独设成便宜模型,进一步省钱。

完整配置项语义与已知边界见 插件 README。

🚀 快速开始(开发)

插件:改代码后重跑 install-plugins.ps1 + 重启 dsh web 生效 .\install-plugins.ps1

桌面客户端:开发模式
cd desktop\dsh-desktop
npm install
npm start

桌面客户端:打包(NSIS 安装版 + 绿色 zip) $env:ELECTRON_MIRROR = "https://npmmirror.com/mirrors/electron/"
npm run dist

📚 文档

| 文档 | 内容 |
| docs/使用说明.md | 终用户手册:安装、启动、托盘与窗口、自动更新、两个插件的配置与使用、故障排查 |
| desktop/dsh-desktop/README.zh.md | 桌面客户端细节:数据位置、运行时管理、更新策略、自定义更新源 |
| plugins/dsh-model-router/README.zh.md | 模型路由:配置项语义、路由规则、生效日志 |
| plugins/dsh-mmx-vision/README.zh.md | mmx 图像理解:前置要求、软检测行为、配置项 |

📁 目录结构

dsh-desktop/
├── install-plugins.ps1 # 插件一键安装/更新(含 mmx 软检测) ├── docs/ │ └── 使用说明.md # 终用户手册 ├── plugins/ │ ├── dsh-model-router/ # 模型路由插件 │ └── dsh-mmx-vision/ # mmx 图像理解插件(软检测,无 mmx 自动休眠) └── desktop/ └── dsh-desktop/ # Electron 桌面客户端(release\ 下为打包产物)

❓ 常见问题

Q:桌面端和直接开 dsh web 有什么区别? 功能完全一致——桌面端是官方 Web 版的壳,额外提供:双击启动、独立窗口与自定义标题栏(跟随页面明暗主题)、托盘常驻、DSH 运行时自动升级、壳自动更新。

Q:没有 MiniMax 订阅,mmx 插件会不会报错? 不会。mmx 检测贯穿安装与运行两层:安装脚本直接跳过;已安装的运行时静默休眠(不显示配置、不注册工具、零告警)。想恢复原版 describe-image 见 插件 README。

Q:更新检查会不会打扰我? 未配置仓库 / 网络不可达时静默跳过(日志里有原因);绿色版只弹一次提示,可选「忽略此版本(本次运行)」。

Q:日志在哪? %APPDATA%\DSH Desktop\logs\dsh-web.log(本次)/ dsh-web.prev.log(上次)。

☕ 赞助

如果这个项目帮到了你,欢迎去 爱发电 请作者喝杯咖啡——这是持续维护的动力。

不赞助也完全没关系:点个 ⭐ Star、提个 Issue、分享给朋友,同样是对项目最大的支持。

✨ 赞助者

感谢每一位支持者(名单每天自动从爱发电同步):

暂无赞助者——也许第一位就是你 ☕

📄 许可与致谢

- 本仓库(桌面客户端 + 插件 + 文档)以 Apache-2.0 协议开源。
- dsh-mmx-vision 移植自 dsh-web-ui 的 @linxin666/dsh-tool-describe-image(Apache-2.0):附件路由 / 发送改写 / 缩略图预览 / 设置卡片骨架。
- 感谢 DeepSeek Harness 与 Electron。
预览分享卡片长什么样 ↓puddingfish/dsh-desktop
分享 · DeepSeek Harness Hub
puddingfish/dsh-desktop

DSH Desktop —— DeepSeek Harness 的 Windows 桌面客户端 + 模型路由 / mmx 图像理解插件(绿色免安装 · 自动更新)

这是你的仓库?认领条目

回到顶部