# dsh-desktop-deepin **Repository Path**: westanke/dsh-desktop-deepin ## Basic Information - **Project Name**: dsh-desktop-deepin - **Description**: DeepSeek Harness 桌面壳(Deepin/UOS/Linux deb,amd64+arm64) - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-01 - **Last Updated**: 2026-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: dsh-plugin, dsh-desktop, dsh, UOS ## README # DeepSeek Harness Desktop · Deepin / UOS / Linux 版
**English (short).** A community Electron desktop shell for the [DeepSeek Harness (dsh)](https://github.com/deepseek-ai/deepseek-harness) agent runtime, built for Deepin / UOS / Linux. It ships a shell-only deb (amd64 + arm64) that bootstraps Electron/Node/kernel on first run from China mirrors; an offline variant with everything bundled can be built locally for air-gapped machines. Linux is not an afterthought here: timezone quirks, `apt` dependency handling, multi-user config layering, kernel process-group management and orphaned MCP-server reaping are all first-class, and a unit-test suite plus a real-kernel e2e keep it that way. 面向 Deepin / UOS / Linux 的 DeepSeek Harness 桌面壳。把命令行 agent 运行时 `dsh` 包进一个 Electron 窗口:双击即用,不必开终端。 > **状态**:可用。单元测试全绿、`tsc --noEmit` 零错误、内核 e2e 通过(见上方 CI 徽章, > 本地跑 `npm run test:all` 复现),已在 > UOS Desktop 20 Professional(glibc 2.31)与 Deepin 25 上真机验证(窗口加载、内核就绪、 > 托盘、菜单)。内核是上游开发预览版,配置面仍在变化。 --- ## 项目特色 同类 DSH 桌面壳不止一个,取舍各不相同。本壳把三件事放在首位:**跑在中国 Linux 上**、 **安装包尽可能小**、**崩了也退得回去**。 ### Linux ARM64:同类壳里目前只有这一家出包 同类壳的 Linux 产物都只覆盖 x64——`anywhere-labs/dsh-desktop` 的 release notes 直接写着 「ARM64 packages are not provided」;`dsh-tauri/deepseek-harness-desktop` 的 Linux 资产只有 `amd64.deb` 与 `amd64.AppImage`;`dataelement/dsh-desktop` 最新版只挂了 macOS 与 Windows 产物。 (三家都有 `aarch64` 文件,但那是 macOS 的 `.dmg`,不是 Linux。) 本壳同时发布 `amd64` 与 `arm64` 两个 deb,覆盖国产 ARM 整机、ARM 云主机与 arm64 开发板。 两个包文件名按架构区分、内容一致,首启各自下载对应架构的运行时。 ### Deepin / UOS 是第一目标平台,不是顺带 | 坑 | 本壳的处理 | |---|---| | `/etc/timezone` 是 `Asia/Beijing`、`PRC` 等 Chromium 不认的名字 | 开窗前映射为 `Asia/Shanghai`,否则页面时间全错 | | 缺终端模拟器 | 按 `deepin-terminal → x-terminal-emulator → gnome-terminal → konsole → xfce4-terminal` 依次降级,都没有则回退后台补齐 | | 原生目录对话框不一定存在 | 有 `zenity` / `kdialog` 才用原生,否则自动降级为浏览模式 | | 首次双击被问「是否信任该应用」 | 已写入文档——「点了没反应」通常是这个询问,不是启动失败 | **验证环境**:UOS Desktop 20 Professional(专业版 `Y2020E0001`,内核 `4.19.0-amd64-desktop`, 海光 C86-3G,x86_64,**glibc 2.31** / GLIBC 符号上限 2.30,libstdc++ 上限 GLIBCXX_3.4.25) 与 Deepin 25——窗口加载、内核就绪、托盘、菜单均通过。 ### 为什么是 Electron 而不是 Tauri 2 Tauri 体积小、内存低,看着是更"现代"的选择,社区里也有同类壳走了这条路。但它在 **本项目的目标系统上根本装不上**,原因都是实测出来的: | 障碍 | 实测数据 | |---|---| | **Tauri 2 强制依赖 `libwebkit2gtk-4.1`**(Tauri 2.0 起在 Linux 上从 4.0 迁到 4.1,见 [官方迁移说明](https://tauri.ubitools.com/fr/blog/tauri-2-0-0-alpha-3/)) | UOS 20 的 apt 源里**只有 `libwebkit2gtk-4.0-37`**;`apt-cache search webkit2gtk` 搜遍仓库,**没有任何 4.1 包**,也装不上 | | 系统 WebView 版本碎片化 | 各发行版的 webkit2gtk 版本差得远(4.0 / 4.1、2.38 / 2.44),同一份产物在不同系统上行为不一致 | | 老系统的库基线 | 本系统 glibc **2.31**、GLIBCXX 上限 3.4.25;社区预编译二进制普遍要求更高(实测过别的预编译工具因 `libffi.so.8`、`GLIBCXX_3.4.29` 直接加载失败) | | 同类壳的对照 | 走 Tauri 2 的那个壳,其 Linux 包自述「基于 Ubuntu 22.04 构建」——glibc 2.35 基线,与本类系统存在代差 | **Electron 的取舍正好相反**:它自带 Chromium,**不依赖系统 WebView**,所以 Deepin 20 / UOS 20 这类老系统与 Deepin 25 / UOS 25 这类新系统跑的是**同一个浏览器内核**,行为可预期; 代价是首次启动要下载约 180 MB 运行时——而这一点被「deb 只装约 160 KB 壳代码 + 装完后台 预下载」抵掉了。 ### 界面与官方壳同源:`dsh-app://` 与原生右键菜单 内核页面加载在 `dsh-app://app/` 下,与官方桌面壳同一形态:页面的相对路径请求由协议层 拦截、转发到内核 origin 并带上当次启动的令牌,WebSocket 走独立通道。对外表现是 DevTools 里看到的请求域名是壳域,而不是每换一个内核端口就变一次的 `127.0.0.1:<端口>`。 附带 Electron 默认不给的原生右键菜单:按当前编辑状态动态给项——可编辑处给 撤销/重做/剪切/复制/粘贴/全选(各项按实际可用性置灰),选中文字时只给复制, 无选中不弹,文案为中文。没有它,输入框无法右键粘贴、回答无法右键复制。 > 一句话:选 Electron 不是因为它小(它不小),而是因为它**把不确定性从用户的系统搬进了 > 自己的包**。对一个以国产老系统为首要目标的壳,这个交换是划算的。 > > 补一句实话:本壳的代码基线本就来自一个 Electron 壳,改用 Tauri 意味着重写窗口、托盘、 > 菜单与进程治理全部上层——但即便从零开始,上面第一条(WebView 依赖)也足以让 Tauri 2 出局。 ### 安装包约 160 KB,运行时按需获取 deb 里**只有壳的代码**,不含 Electron(约 364 MB)、Node(约 25 MB)与 dsh 内核(约 30 MB)。 装完后 `postinst` 会**以你自己的账号**在后台预下载,等你去点启动器时通常已经就绪—— 「装完即用」的体验,而包还是 160 KB。机器上已有可复用的运行时则完全不下。 ### 开箱自带四个插件,不用去市场翻 首次启动(以及每次 deb 升级)会自动补齐下面四个社区插件。已装的**不覆盖你的版本**, 升级后缺失的会被补回。四个都各自解决一件「用得下去」的刚需,其中 `dshmarket`(★5.5k) 与 `dsh-im`(★1.6k)是社区里最热的两块: | 插件 | 它让你能做什么 | |---|---| | **dsh-im** | 把 agent 接进你已经在用的聊天软件——飞书、微信、企业微信、钉钉、QQ、Slack、Telegram、Discord、WhatsApp 共 9 个通道,扫码或凭据即可接入。人不必坐在电脑前,在 IM 里就能使唤 agent | | **dshmarket** | 内置可视化插件市场:浏览、搜索、一键安装。想再要点什么,不必去记 npm 包名 | | **dsh-remote-bridge** | 把 DSH 桥接给可信客户端:聊天、文件、设备等远程访问都走带版本的 REST 接口,并在 WebUI 设置里带一个「手机设置」面板 | | **dsh-mcp-panel** | MCP 管理控制台:`/mcp` 查看各 MCP 服务器的健康状态与连接诊断;设置页带服务器增删改(写入需审批、自动备份)与工具试调用台 | **为什么值得默认装**:这四个恰好覆盖「能远程使唤」(`dsh-im` / `dsh-remote-bridge`)、 **能自己找插件**(`dshmarket`)、**出问题能自己诊断**(`dsh-mcp-panel`)四件刚需—— 装完就有,不必先知道它们存在。补装/强制重装见下文「推荐插件」。 > 不想要某个?`dsh plugin --profile web remove <包名>`。注意升级 deb 后会按「在不在」 > 补回,除非改 `tools/install-plugins.sh`。 ### 失败路径都被认真对待 | 问题 | 处理 | |---|---| | 插件把内核搞崩,壳自己进不去、也没法卸插件(死锁) | **安全模式**:停用全部第三方 bundle,用户 patch 层备份改名,且不持久化 | | 内核非正常退出后,`npm exec` 拉起的 MCP 服务器被 init 收养、永远活着 | **孤儿收割**:给内核注入进程印记,退出后扫描 `/proc` 按印记收割整棵进程树(24 个单测) | | 端口开着但其实不是我们的内核 | **就绪判定必须拿到真实 HTTP 响应**,端口占用不算 | | 崩溃后一片空白 | 崩溃报告落盘(保留最新 10 份、目录 0700 文件 0600、同毫秒不覆盖)+ 日志进缓冲区即脱敏 + 渲染进程 60 秒内自愈 3 次 | | 内核反复退出,窗口里只剩一张错误页 | **原生恢复对话框**:报告先落盘再弹窗(写入上限 1 秒,慢盘不把人扣住),给「退出 / 重启 / 禁用第三方插件并重启」三条路;端口占用单独识别——那是另一个 dsh 还在跑,不是插件问题,所以那条路上不提供「禁用插件」 | ### 供应链可验证,且失败时不静默 Electron 与 Node 的下载都校验对应版本的 `SHASUMS256.txt`;国内镜像若未同步该清单, 会**大声降级为「仅信任 HTTPS 来源」**并提示,而不是悄悄跳过校验。 ### 多用户机器不掉坑 全局配置 `/opt/.../config.json` 只读、所有人共用;每用户覆盖份在 `~/.config/dsh-desktop/config.json`,键级合并。运行时下载到用户家目录, **不需要 root、不碰系统目录**,卸载也不动你的会话数据。 --- ## 下载与安装 发布包在 [GitHub Releases](https://github.com/westanke/dsh-desktop-deepin/releases) 与 [Gitee Releases](https://gitee.com/westanke/dsh-desktop-deepin/releases)(国内网络推荐 Gitee)。 | 格式 | 覆盖系统 | 说明 | |---|---|---| | `*.deb`(amd64 / arm64) | Debian / Ubuntu / **UOS / Deepin** / 麒麟 | 在线版,约 160 KB;装到 `/opt`,注册启动器与图标,首启下载运行时 | | `*-offline-*.deb`(自建) | 同上 | **不在 release 提供**。有内网/离线机需求时自己打:见下文「离线双通道」 | ### 安装包只有约 160 KB——因为运行时按需获取 **这一点必须在安装前知道:首次启动会下载 Electron(约 180 MB),需要等几分钟。** 这个 deb 里**只有壳的代码**,不含 Electron、Node 与 dsh 内核。原因很直接: | 组件 | 单独体积 | 为什么不打包 | |---|---|---| | Electron 运行时 | 约 364 MB | **包体积的主要来源**,占了原本 250 MB 安装包的绝大部分 | | Node 运行时 | 约 25 MB | 你机器上多半已经有了,内核可以直接用系统的 | | dsh 内核 | 约 30 MB | 同上;而且内核升级频繁,打进包会很快过时 | 把这三样打进去,安装包会从 **约 160 KB 膨胀到 250 MB 以上**,而其中 90% 的内容对 「已经装过 dsh 的机器」是重复的。所以本包采取按需获取: ```sh # 装完后首次启动前,先跑一次自检(会告诉你要不要下载) bash /opt/deepseek-harness-desktop/tools/bootstrap.sh check # 缺什么就下什么,国内镜像优先 bash /opt/deepseek-harness-desktop/tools/bootstrap.sh install ``` 安装器(deb 的 postinst)也会在装完后自动跑一次检测,并在缺失时明确提示你执行上面的命令。 **下载耗时预期**(取决于网络): | 缺什么 | 下载量 | 大致耗时 | |---|---|---| | 只缺 Node | 约 25 MB | 十几秒 | | 只缺 dsh 内核 | 约 30 MB | 几十秒 | | **只缺 Electron** | **约 180 MB** | **几分钟** ← 最常见的情况 | | 三者都缺 | 约 235 MB | 几分钟 | 下载**只发生一次**。全部就绪后会把解析出的绝对路径写回 `config.json`(备份为 `config.json.bak-bootstrap`),之后每次启动都是零检测、秒开。 下载内容与来源(写入 `~/.dsh-desktop/runtime/`,不碰系统目录、不需要 root): | 组件 | 国内源 | |---|---| | Node | `npmmirror.com/mirrors/node`,备用 `mirrors.huaweicloud.com/nodejs` | | Electron | `npmmirror.com/mirrors/electron`,备用 `mirrors.huaweicloud.com/electron` | | dsh 内核 | `registry.npmmirror.com`(npm 全局安装) | > 为什么优先国内源:上游 `nodejs.org`、GitHub Releases 与 `registry.npmjs.org` 在大陆 > 网络下经常超时或极慢,而上述镜像是同步的完整副本。脚本会在主源失败时自动切备用源。 **想避开首次下载?** 如果你的机器上已经有 Electron ≥ 33、Node ≥ 22.15 和任意可用的 `dsh`,`bootstrap.sh check` 会全部识别为已就绪,**不会有任何下载**。检测顺序是 `config.json` 指定路径 → `PATH` → 常见安装位置,命中即复用。 ### 请用 apt 安装 deb,不要用 dpkg -i `dpkg -i` 不解析依赖,缺库时直接失败。本包声明的运行时依赖: ``` libgtk-3-0 libnotify4 libnss3 libxss1 libxtst6 xdg-utils libatspi2.0-0 libayatana-appindicator3-1 ``` ```sh sudo apt install ./DeepSeek-Harness-Desktop-<版本>-amd64.deb ``` > 该结论来自 anywhere-labs PR #1120 的 Ubuntu 24.04 真机验证,非推测。 ### 装完就会在后台预下载,不用干等 `apt install` 结束后,安装脚本会以**你自己的账号**(不是 root)在后台自动开始 下载运行时 —— 所以绝大多数情况下,等你双击启动器时它已经就绪,跟「装完即用」 没区别,而包还是只有 160 KB。 - 下载在后台跑,`apt install` 立即返回,不会卡住安装进度 - 日志:`~/.dsh-desktop/bootstrap-postinst.log` - 不想装时就下载(比如批量部署、离线机): `sudo DSH_NO_POSTINST_DOWNLOAD=1 apt install ./xxx.deb` - 若你双击时它还没下完,启动器会显示等待进度并排队,不会重复下载 Deepin/UOS 上首次双击启动器可能询问「是否信任该应用」,确认即可。信任按用户记录, 所以「点了没反应」通常是这个询问,不是启动失败。 卸载: ```sh sudo apt remove deepseek-harness-desktop ``` 卸载**不会**动你的内核数据(`~/.dsh` 或 `$DSH_HOME`:会话、设置、凭据、插件), 也不会删 `~/.dsh-desktop/runtime/`(已下载的运行时留着,重装后可直接复用)。 如要彻底清理,手动删该目录即可。 --- ## 推荐插件(默认随运行时自动安装) 以下四个社区插件由 `tools/install-plugins.sh` 在**运行时就绪后自动安装** (升级 deb 时 postinst 也会补装缺失的;已装的跳过、不覆盖你的版本)。 不想要某个?`dsh plugin --profile web remove <包名>` 即可——注意升级后会 被自动补回(查重只认「在不在」)。 | 插件 | 干什么 | 链接 | |---|---|---| | **dsh-im** | 把微信、飞书、企业微信、钉钉、QQ、Telegram、WhatsApp、Slack、Discord、Matrix 等 IM 接入 DSH——在聊天软件里直接使唤你的 agent | [xmanrui/dsh-im](https://github.com/xmanrui/dsh-im) | | **dsh-remote-bridge** | 把 DSH 桥接给可信客户端:聊天、文件、设备等远程访问走带版本的 REST 接口,并在 DSH WebUI 里提供「手机设置」面板 | [westanke/dsh-remote-bridge](https://github.com/westanke/dsh-remote-bridge) | | **dsh-mcp-panel** | MCP 管理控制台:`/mcp` 命令查看 MCP 服务器健康状态、诊断连接问题 | [PerryLink/dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel) | | **dshmarket** | 内置可视化插件市场:浏览、搜索、一键安装社区插件 | [dsh-market/dsh-market](https://github.com/dsh-market/dsh-market) | 手动补装 / 强制重装: ```sh bash /opt/deepseek-harness-desktop/tools/install-plugins.sh # 补缺的 bash /opt/deepseek-harness-desktop/tools/install-plugins.sh force # 全部重装 ``` --- ## 功能(按实际实现) ### 内核与进程 | 功能 | 实现位置 | 说明 | |---|---|---| | 内核启动与就绪判定 | `src/kernel-process.js` `src/readiness.js` | 必须拿到真实 HTTP 响应才算就绪;端口开着不算 | | 崩溃自动重启 | `src/kernel-supervisor.js` `src/restart-policy.js` | 指数退避,10 分钟窗口内最多 5 次,超出则放弃并报错 | | 进程组整体回收 | `src/kernel-process.js` | Unix 下子进程自任组长,退出时 `kill(-pid)` 连孙进程一起收 | | 系统内核模式 | `src/main.js` `resolveKernelPaths` | 设 `DSH_KERNEL_BIN` 即可驱动系统已装的 `dsh`,用真 Node 跑 | | 固定端口 | `src/main.js` `preferredPort` | 默认 `19387`(官方同款);被占用则自动退回随机端口 | | 崩溃报告 | `src/diagnostics.js` | 写 `userData/logs/crash-