Back to home@MoonlitDropOfBlood

DSH-Desktop

为DeepSeek Harness 打造的桌面端,没有打包DeepSeek Harness,核心可以独立更新

Stars
1
Language
JavaScript
Created
Aug 15, 2026
Updated
Sep 4, 2026

Introduction

鲸港 WhaleHarbor

鲸港 WhaleHarbor

为 DeepSeek Harness 打造的桌面端体验

Desktop application MIT License Platforms DSH core not bundled

中文


鲸港 WhaleHarborDeepSeek Harness(DSH) 包装成一个原生桌面应用。它负责窗口、托盘、更新与桌面运行环境,同时完整保留官方 DSH 的智能体、模型、工具、会话与 Web UI。

显示品牌为「鲸港 WhaleHarbor」;包名与内部标识(dsh-desktopDSH_DESKTOP_* 环境变量等)沿用历史命名,行为不变。

DSH 核心不打进安装包:目标机器首次启动时自动通过内置 pnpm 安装最新版 DSH,之后直接复用本机已有的完整安装——既保持轻量,又能随时更新到最新。

零依赖运行:DSH 核心直接跑在 Electron 内嵌的 Node 运行时上(ELECTRON_RUN_AS_NODE),核心的安装/更新用内置 pnpm——最终用户机器上不需要安装 node/npm。(注:MCP 子进程依赖用户 PATH 里的 node/npx,常规开发机均满足。)

DSH 来自哪个 npm 仓库? 核心 @deepseek-ai/dsh 发布在官方 npmjs.orghttps://registry.npmjs.org)。国内网络下默认使用 npmmirror 镜像(registry.npmmirror.com),探测不可用或安装失败时会自动回退 npmjs.org,也可用 DSH_DESKTOP_NPM_REGISTRY 指定。安装过程会显示实时进度条与已下载大小

主要功能

沉浸式桌面窗口

无边框(frameless)窗口,DSH Web UI 占满整个屏幕;最小化/最大化/关闭按钮以半透明方式融入界面右上角,不遮挡任何 DSH 内容。

系统托盘

DeepSeek 鲸鱼托盘图标,右键「打开 / 退出」。开启「常驻通知栏」后,关闭窗口最小化到托盘,后台持续运行。

保持最新

内置「核心」设置页显示 DSH 版本、一键检查更新,支持自动更新(新版本自动下载并提示重启)。

任务通知

主任务完成、失败或需要确认时发送桌面通知(子任务完成不打扰);可选「阻止休眠」,任务运行期间防止系统睡眠。

继承终端 Profile

自动加载终端里的环境变量(PATH 等)传给 DSH,MCP 服务等外部进程能正常找到可执行文件;macOS 从 Finder 启动时没有终端环境变量,此开关默认开启。

与官方项目的关系

本项目基于 deepseek-ai/deepseek-harness 构建,并借助 Cordis 的插件化能力。

官方项目提供核心的智能体能力、插件系统与 Web UI;本项目负责:

  • Electron 桌面应用封装(窗口、托盘、生命周期、崩溃重启、进程树清理)
  • DSH 的自动安装、定位与更新
  • 嵌入 DSH UI 的桌面插件(窗口控制条、设置页、更新徽章)
  • Windows / macOS / Linux 安装包构建与 GitHub Actions 自动发布

如果你希望通过命令行运行 Harness,或参与核心功能开发,请优先查看官方仓库

安装

GitHub Releases 下载对应平台安装包:

平台格式
WindowsNSIS 安装器(x64)
macOSdmg(Apple Silicon / Intel)
LinuxAppImage · deb · rpm

首次启动会自动安装最新版 DSH(约 250MB,由内置 pnpm 安装,通常几十秒)。最终用户无需安装 Node.js;从源码开发需要 Node ≥ 18。

从源码运行 / 开发

npm install          # 安装依赖(首次)
npm start            # 启动桌面应用
npm run icon         # 重新生成鲸鱼图标(改配色/边距后)

打包

npm run pack         # 打包目录到 dist/(快速验证)
npm run dist:win     # Windows NSIS 安装器
npm run dist:mac     # macOS dmg
npm run dist:linux   # Linux AppImage + deb + rpm

GitHub Actions(.github/workflows/build-installers.yml)可在打 v* 标签或手动触发时,跨平台构建并自动发布到 Releases。

工作原理

npm start
  └─ Electron 主进程
       └─ 定位 DSH:应用托管目录 → node_modules → npm _npx 缓存(最新完整安装)
       └─ 没有则 pnpm add @deepseek-ai/dsh@latest(内置 pnpm;registry 探测 + 失败重试/换镜像 + 实时进度条)
       └─ 端口预检:被占用则弹「换端口并重试」面板(端口持久化)
       └─ spawn: Electron 自身 (ELECTRON_RUN_AS_NODE=1) <dsh>/lib/bin.js --patch <desktop-plugin> --profile web --port X [--no-open]
            └─ 桌面插件嵌入 DSH UI:窗口控制条 / 设置页 / 更新徽章
            └─ DSH 打印 URL → 应用解析 → loadURL 到 frameless 窗口
       └─ 启动/加载失败或插件未挂载 → 回到启动页(自带窗口控制条 + 重试/换端口/退出),
           另注入兜底控制条,窗口永远可关闭
       └─ 更新:先停 DSH 核心 → 安装新版本(防 Windows 下覆盖运行中文件导致崩溃)→ 重启核心
       └─ 退出时 kill 整棵进程树;崩溃时一键重启
       └─ 任务事件经本地桥转发 → 桌面通知(可开关)

插件扩展点(RPC 桥)

DSH 插件可以调用桌面壳的能力:桌面通知、托盘右键菜单、插件设置 KV、窗口/任务栏控制、壳事件订阅。壳在本地起一个 HTTP JSON-RPC 桥——只绑 127.0.0.1、每次启动随机端口 + 随机令牌,令牌只通过环境变量传给 DSH 进程,网页与无关本地进程无法调用。

Host 半部(运行在 DSH 进程内的插件)

process.env.DSH_DESKTOP_NOTIFY_PORT / DSH_DESKTOP_NOTIFY_TOKEN 读地址与令牌,POST http://127.0.0.1:<port>/,带 x-dsh-notify-token 头,body 为 { "method": "...", "params": { ... } };响应 { ok: true, ... }{ ok: false, error }。网络失败按 1.5s~20s 退避重试几次;收到 ok:false 说明对端壳无此方法(旧版本),不必重试。

方法参数说明
bridge.registerplugin, eventPort?, events?注册插件(notify/tray/window.* 前先注册;settings.* 不要求)。eventPort 是插件自起的 127.0.0.1 HTTP 端口,壳把托盘点击与订阅事件回投到它(POST {event, data},同一令牌);events 可订阅 window.visibility(显示/聚焦/最小化快照)、core.lifecycle(starting/ready/restarting/exited)
notify.showkind?, title?, body?, force?桌面通知。kind=done/error/approval 有默认文案;force:true 绕过「窗口聚焦时不弹」抑制(用户显式动作的回执用);受设置「任务通知」总开关约束
tray.setMenuplugin, items贡献托盘右键菜单分区([{id, label, enabled?}],≤10 项),点击回投 {event:"tray.click", id}
settings.get / settings.setplugin, key? / plugin, key, value插件设置 KV(value 限 string/number/boolean,null 删除该 key),持久化在壳的设置文件里
window.*见左列window.progress {value}(任务栏进度:-1 清除 / 0..1 确定 / >1 不确定)、window.flash {flag}(闪烁,窗口获焦自动停)、window.badge {text}(macOS Dock / Linux 角标数)、window.overlay {dataUrl}(Windows 任务栏角标图)、window.alwaysOnTop {flag}window.show / window.hide / window.minimize
float.window.*create / state / move / close / closeAll插件浮窗(桌面宠物、迷你状态条等):创建小型透明置顶悬浮窗——永不抢焦点、不进任务栏;state 下行推送 JSON 状态(宠物页面 __dshFloat.onState 接收),页面点击经 __dshFloat.send 回投;核心重启/退出自动清理,限额每插件 3 个,设置「允许插件浮窗」可整体关闭

最小示例(注册 + 托盘菜单 + 通知):

// DSH 插件 Host 半部的 apply(ctx) 里
const port = process.env.DSH_DESKTOP_NOTIFY_PORT;
const token = process.env.DSH_DESKTOP_NOTIFY_TOKEN;
if (!port || !token) return; // 非桌面壳环境(裸 dsh 命令行),静默跳过
const call = (method, params = {}) => fetch(`http://127.0.0.1:${port}/`, {
  method: "POST",
  headers: { "content-type": "application/json", "x-dsh-notify-token": token },
  body: JSON.stringify({ method, params })
}).then((r) => r.json()).catch(() => {});

call("bridge.register", { plugin: "my-plugin", eventPort: myEventServerPort, events: ["core.lifecycle"] });
call("tray.setMenu", { plugin: "my-plugin", items: [{ id: "hello", label: "打个招呼" }] });
call("notify.show", { kind: "done", title: "任务完成" });

托盘点击与订阅的事件会 POST 到你上报的 eventPort(同一个令牌头),自行起个小 HTTP 服务接收即可。

Client 半部(运行在 DSH 页面里的插件)

桌面壳给页面注入 window.dshDesktop(普通浏览器直接访问同一页面时不存在,用前判空):

  • windowAction(action, params) —— 与 window.* RPC 同一实现
  • pluginSettingsGet(plugin, key) / pluginSettingsSet(plugin, key, value) —— 同一 KV
  • onShellEvent(cb) —— 接收壳事件

设置页

插件需要设置 UI 时,用核心 Cordis 的 settings.section 槽挂一个整页(桌面版设置区自身就是这么挂的):

// 客户端插件,需 exports.inject = ["slots"]
ctx.slots.register({ name: "settings.section", id: "my-plugin", order: 50, label: "我的插件" }, MySettingsPage);

持久化用上面的插件设置 KV(Host 侧 settings.get/set,页面侧 dshDesktop.pluginSettingsGet/Set)。壳刻意不提供行级声明式设置项——整页槽能覆盖全部场景。

环境变量(可选)

变量作用
DSH_DESKTOP_PORT指定端口(默认 3080)
DSH_DESKTOP_HOME覆盖 DSH_HOME(默认 ~/.dsh
DSH_DESKTOP_NPM_REGISTRYnpm 镜像(默认 npmmirror)
DSH_DESKTOP_NPM_CACHEnpm 缓存目录
DSH_DESKTOP_SPECDSH npm 规格(默认 @deepseek-ai/dsh@latest
DSH_DESKTOP_TIMEOUT启动看门狗超时秒数(默认 1800s)
DSH_DESKTOP_INSTALL_ESTIMATE_MB安装进度条估算总大小(默认 250MB)
DSH_DESKTOP_PNPM_VERSION构建期打包的内置 pnpm 版本(默认 10.33.0)

常见问题

  • 端口冲突:应用启动前会预检端口。若 3080 被占用(如浏览器里开着另一个 DSH),会弹出「端口已被占用」面板,可直接换一个端口并重试(端口会记住);或设 DSH_DESKTOP_PORT 换端口。
  • 首次安装慢/卡住:DSH 核心由内置 pnpm 安装(解析+下载通常几十秒),启动页有进度条 + 已下载大小。若网络下载慢,设镜像:$env:npm_config_registry = "https://registry.npmmirror.com"
  • 启动失败看不到原因:所有启动/崩溃错误都会显示在启动页的错误面板(含最近日志),提供「重试 / 换端口并重试 / 退出」。
  • 点更新没反应或崩溃:更新会先停掉 DSH 核心再安装新版本(避免 Windows 下覆盖运行中文件导致崩溃),失败时可选择「用当前版本继续」。
  • 常驻通知栏看不到托盘图标:开启「常驻通知栏」后立即创建托盘图标(无需先点一次关闭)。
  • electron 下载超时(GitHub 不可达)npm install 前设 $env:ELECTRON_MIRROR = "https://npmmirror.com/mirrors/electron/"
  • 任务通知不弹:在「设置 → 桌面版」确认「任务通知」已开启;另外应用窗口有焦点且可见时不弹(你正在看着界面,任务状态已内联显示),只在后台/最小化/藏托盘时才通知。
  • 通知安全:任务通知走本机回环 HTTP 桥(127.0.0.1),每次启动使用随机端口 + 随机令牌,网页和无关本地进程无法伪造或刷屏通知。
  • macOS 报"已损坏,无法打开" / "无法验证开发者":当前未签名,这是 macOS Gatekeeper 对下载的未签名 App 的拦截(Apple Silicon 上 arm64 版最常显示"已损坏")。不是包坏了,壳有完整的 x64 和 arm64 版本(release 里的 *-arm64.dmg)。临时绕过:右键应用 → 打开,或终端执行 xattr -dr com.apple.quarantine "/Applications/DeepSeek Harness Desktop.app"。要彻底解决需给 macOS 包签名+公证(见下文「macOS 签名与公证」)。
  • macOS 签名与公证
    • 不买账号也能签(自制自签名证书):仓库 Secrets 配 CSC_LINK(.p12 的 base64)+ CSC_KEY_PASSWORD + CSC_NAME(证书名)。本仓库已附一个生成好的自签名证书(见工作流注释)。注意自签名证书只在本机/信任它的 Mac 上免提示打开,其他用户仍需右键 → 打开。
    • 彻底解决(付费 Apple Developer 账号):Developer ID 证书 + 公证凭据 APPLE_ID/APPLE_APP_SPECIFIC_PASSWORD/APPLE_TEAM_ID(或 APPLE_API_KEY/APPLE_API_KEY_ID/APPLE_API_ISSUER),配齐后 GitHub Actions 自动签名并 notarytool 公证,所有 Mac 双击即开。
    • 什么都没配时:scripts/mac-sign.js 自动做 ad-hoc 自签名,"已损坏" → "无法验证开发者"(右键 → 打开 可用)。
  • 与浏览器里的 DSH 共用数据:默认共用 ~/.dsh,会话互通。

目录结构

dsh-desktop/
├── main.js                 # Electron 主进程:生命周期、IPC、托盘、设置、通知桥
├── preload.js              # contextBridge:暴露 dshDesktop.* 给 DSH 页面
├── splash.html             # 启动页
├── dsh-desktop-plugin/     # 嵌入 DSH UI 的桌面插件(窗口控制条/设置页/更新徽章)
│   ├── client.js           #   浏览器端:Slot UI
│   └── index.js            #   Host 端:任务事件 → 通知桥
├── scripts/                # 图标生成 / exe 图标嵌入 / 插件市场、pnpm 拉取
├── build/                  # 鲸鱼 SVG 与各平台图标
├── .github/workflows/      # GitHub Actions 跨平台构建发布
├── AGENTS.md               # 面向 AI agent 的开发指南(含踩坑记录)
└── LICENSE                 # MIT

License

本项目遵循 MIT License

本项目是基于 DeepSeek Harness 构建的社区桌面版本,并非 DeepSeek 官方产品。