目标:不用手动开终端跑
dsh web,点图标即用;官方一发版就能跟上,永不停留在旧版。 本方案基于对本机环境的实际调研(路径、版本、升级链路均已验证),不是泛泛设想。
| 事实 | 值 |
|---|---|
| dsh 安装方式 | npm 全局,prefix = ~/.local(升级无需 sudo) |
| 安装位置 | ~/.local/lib/node_modules/@deepseek-ai/dsh,bin 在 ~/.local/bin/dsh |
| 本机版本 | 0.1.0-rc.6 |
| npm 官方最新 | 0.1.1-rc.2(dist-tags:latest 与 next 同版本)→ 本机已落后,升级需求真实存在 |
| Web 服务 | dsh web → http://127.0.0.1:3080,支持 --host / --port(--port 0 让 OS 分配空闲端口)/ --trusted-host |
| 数据目录 | ~/.dsh(profiles / sessions / settings.yaml / storages / web.log) |
| 优雅停机 | dsh 内建 SIGINT/SIGTERM 有界停机(5 秒优雅退出),可被安全托管 |
| 痛点 1 | 无 daemon 模式:必须手动开终端、终端不能关 |
| 痛点 2 | 升级全靠手记:要自己记得查 npm、跑 npm i -g、重启服务 |
| 环境坑 | ~/.npm 缓存里有 root 属主文件,npm 目前报 EPERM;用独立 --cache 目录可绕过(已验证),彻底修复需一次性 sudo chown -R 501:20 ~/.npm |
dsh-base、dsh-web-app 等几十个 bundle)都是 CLI 包 @deepseek-ai/dsh 的依赖,profile(~/.dsh/profiles/web)只引用 bundle 名,实际解析到 CLI 安装目录的 node_modules。npm install -g @deepseek-ai/dsh@latest + 重启 dsh web = 整个 Web UI 立即变成官方最新版。官方 UI 必须由 dsh web 服务注入 window.__DSH_BOOT__ 才能跑,任何"把 UI 打包进桌面端"的做法都会造成分叉。dsh-voice-client,file: 本地依赖)在 profile 自己的 node_modules 里,不受 CLI 升级影响,但 rc 版本间 plugin API 可能不兼容 → 升级后必须做启动冒烟检查 + 可回滚。~/.dsh/sessions(按工作区目录分片),服务重启不丢。| 方案 | 做法 | 与本需求的差距 |
|---|---|---|
| LBurny/deepseek-harness-desktop | Tauri,安装包内置 Node + dsh(Windows) | 升级 = 重下安装包,无法实时跟随官方 |
| sdkwork-ai/deepseek-harness-desktop | 跨平台安装包,随发版打包 dsh | 同上:官方发版到桌面端跟上有时差,且替换了你自己的 npm 安装 |
| 本方案 | 薄壳监督者:不打包 dsh,托管你本机的 npm 安装,通过 npm 原地升级 | 官方发版 → 桌面端检测(小时级)→ 一键/自动升级 → 重启即最新 |
"薄壳 + 管家":桌面端不复制、不分发、不 fork 任何官方代码。它只做三件事:
dsh web,崩溃自动重启http://127.0.0.1:<port>一句话:官方代码永远只有一个来源——npm;桌面端只是让它"开机即在、永不过期"的那层壳。
运行中 · 0.1.1-rc.2 · 端口 3080⬆ 新版 0.1.2 可用,点击升级~/.npm 权限问题┌────────────────────────────────────────────────┐
│ DSH Desktop(Electron,约 200 行主进程代码) │
│ │
│ ┌──────────┐ ┌────────────┐ ┌───────────┐ │
│ │ Supervisor│ │ Window │ │ Updater │ │
│ │ 进程托管 │ │ BrowserWindow│ │ 升级管家 │ │
│ └────┬─────┘ └─────┬──────┘ └─────┬─────┘ │
└───────┼──────────────┼───────────────┼────────┘
│ spawn/守护 │ load URL │ npm view / npm i -g
▼ ▼ ▼
dsh web --port 3080 http://127.0.0.1:3080 npm registry
(官方代码,npm 安装) (官方 UI,随包升级) (@deepseek-ai/dsh)
spawn('dsh', ['web', '--port', '3080']),detached=false,stdio 管道(日志 → 内存 ring buffer + ~/.dsh/web.log 落盘)GET http://127.0.0.1:3080 直至 2xx 再显示窗口(避免白屏);--port 0 + 从 stdout 解析实际端口作为端口冲突时的降级方案--port 0BrowserWindow 加载 http://127.0.0.1:<port>,启动期显示 splash(阶段进度)Cmd+Shift+D 唤起/隐藏(可配置)npm view @deepseek-ai/dsh dist-tags --cache <独立缓存目录>(独立 cache 规避 ~/.npm 权限坑,已验证可用)。频率:启动时 + 每 6 小时(可配 1h/6h/24h)+ 手动"立即检查"。可选跟随 latest 或 next tagdsh -V(读本地真实版本)vs registrynpm install -g @deepseek-ai/dsh@<tag>(prefix ~/.local,无需 sudo,不动你的 profile 与插件)已升级到 0.1.2npm i -g @deepseek-ai/dsh@<旧版本> 回滚并通知npm i -g 指定版本)| 维度 | Electron(推荐 MVP) | Tauri 2 |
|---|---|---|
| 语言 | 全 JS,与 dsh 生态一致 | 主进程 Rust,需 Rust 工具链 |
| 体积/内存 | ~90MB / ~150MB | ~10MB / ~80MB |
| 托盘/窗口/子进程 | 全部成熟 API,~200 行搞定 | 需在 Rust 侧写进程监督 |
| 迭代速度 | 快(你本人可维护) | 慢 |
推荐:Electron 起步。 壳极薄(三个模块),日后若嫌重,迁移 Tauri 的成本也很低——因为所有复杂度都在 dsh 侧,壳里没有业务逻辑。Tauri 版可作为二期优化。
dsh web、就绪探测、崩溃退避重启、优雅退出127.0.0.1:3080,splash 引导,关窗隐藏~/.npm 权限检测与修复引导~/.dsh/web.log)、端口/PID、一键重启dsh plugin --profile web add/remove/update,流式输出~/.dsh/sessions 最近会话,直达恢复dsh desktop 子命令| 风险 | 对策 |
|---|---|
| rc 版本破坏性变更(官方明确 developer preview 会有) | 升级后启动冒烟 + 自动回滚;保守用户可锁版本不自动升 |
| 本地插件(dsh-voice-client)与新版本 API 不兼容 | 同上冒烟回滚;日志面板能直接看到插件加载错误 |
| 3080 端口冲突 | 先探测 attach 健康实例,否则 --port 0 动态端口 |
~/.npm root 属主文件(当前真实存在) |
首启检测 + 引导一次性 sudo chown;日常升级走独立 cache |
| npm 网络失败 | 升级是幂等的 npm i -g,失败保留旧版运行中,仅提示重试 |
用户终端里已有 dsh web 在跑 |
端口探测 attach,不重复拉起 |