为DeepSeek Harness 打造的桌面端,没有打包DeepSeek Harness,核心可以独立更新
32.2/100
综合分
3
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/29 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查未通过:仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add MoonlitDropOfBlood/DSH-Desktop该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · desktop
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 5 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装仓库 package.json 标记 private,未发布到 npm,需从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-desktop @ 0.2.0
✓Node 引擎要求 >=18 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/21 15:44:43
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件写入剪贴板(不计风险)读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 120 处,展示前 57 条)
- 写入本地文件main.js:231
fs.mkdirSync(process.env.DSH_DESKTOP_USER_DATA, { recursive: true }); - 读取本地文件main.js:338
if (fs.existsSync(mainLogPath) && fs.statSync(mainLogPath).size > 1024 * 1024) { - 写入本地文件main.js:339
fs.renameSync(mainLogPath, mainLogPath + ".old"); - 写入本地文件main.js:342
fs.appendFileSync(mainLogPath, `[${new Date().toISOString()}] === shell ${app.getVersion()} starting, pid ${process.pid} ===\n`); - 写入本地文件main.js:344
fs.appendFileSync(mainLogPath, `[${new Date().toISOString()}] ${line}\n`); - 执行外部命令固定命令main.js:420
const out = execFileSync("netstat", ["-ano"], { timeout: 8000, windowsHide: true, encoding: "utf8" }); - 执行外部命令固定命令main.js:432
const out = execFileSync("lsof", ["-nP", `-iTCP:${port}`, "-sTCP:LISTEN", "-t"], { timeout: 8000, encoding: "utf8" }); - 读取本地文件main.js:449
fs.readdir(p, { withFileTypes: true }, (err, ents) => { - 读取本地文件main.js:457
if (ent.isFile()) return fs.stat(fp, (e, st) => { if (!e) total += st.size; next(); }); - 读取本地文件main.js:772
try { if (fs.existsSync(c)) return c; } catch { } - 执行外部命令来自配置/变量main.js:781
const out = execFileSync(bin, ["--version"], { encoding: "utf8", timeout: 10000 }); - 读取本地文件main.js:804
const m = fs.readFileSync(path.join(path.dirname(bin), ".version"), "utf8").trim().match(/^( +) ( +) ( +)$/); - 读取本地文件main.js:826
try { if (fs.existsSync(override)) return (_dshRuntime = { command: override, runAsNode: false }); } catch { } - 执行外部命令来自配置/变量main.js:933
const out = execFileSync(shell, [...flags, "-c", "env"], { - 删除本地文件main.js:1038
fs.rmSync(target, { recursive: true, force: true }); - 写入本地文件main.js:1086
fs.mkdirSync(dshDir(), { recursive: true }); - 删除本地文件main.js:1097
try { fs.rmSync(path.join(dshDir(), "package-lock.json"), { force: true }); } catch { } - 删除本地文件main.js:1107
try { fs.rmSync(path.join(dshDir(), "pnpm-lock.yaml"), { force: true }); } catch { } - 写入本地文件main.js:1110
fs.writeFileSync(pj, JSON.stringify({ name: "dsh-managed", private: true }, null, 2) + "\n", "utf8"); - 执行外部命令来自配置/变量main.js:1142
execFileSync(process.platform === "win32" ? "where" : "which", ["npm"], { stdio: "ignore" }); - 执行外部命令来自配置/变量main.js:1297
const child = spawn(plan.command, plan.args, { - 删除本地文件main.js:1407
fs.rmSync(dst, { recursive: true, force: true }); - 发起网络请求main.js:2053
const req = http.get(url, (res) => { - 读取密钥环境变量main.js:2713
notifyToken = process.env.DSH_DESKTOP_NOTIFY_TOKEN || crypto.randomBytes(24).toString("hex"); - 发起网络请求main.js:2888
const req = http.request({ - 删除本地文件main.js:3708
fs.rmSync(prev, { recursive: true, force: true }); - 删除本地文件main.js:3775
if (movedAside) fs.rm(side, { recursive: true, force: true }, () => { }); - 发起网络请求main.js:3913
const req = http.get(printedUrl || bareUrl, (res) => { - 发起网络请求main.js:4338
const req = https.get(candidates[i], { - 发起网络请求main.js:4387
const req = https.get(u, { headers: { "User-Agent": SHELL_UA } }, (res) => { - 写入剪贴板main.js:4595
if (typeof text === "string" && text.length > 0) clipboard.writeText(text); - 读取本地文件plugin-recovery.js:113
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); - 读取本地文件plugin-recovery.js:116
const patchText = fs.readFileSync(path.join(path.dirname(pkgPath), declared), "utf8"); - 读取本地文件plugin-recovery.js:141
const pkg = JSON.parse(fs.readFileSync(path.join(profileDir, "package.json"), "utf8")); - 读取本地文件plugin-recovery.js:189
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); - 写入本地文件plugin-recovery.js:209
fs.writeFileSync(tmp, JSON.stringify(pkg, null, 2) + "\n", "utf8"); - 写入本地文件plugin-recovery.js:210
fs.renameSync(tmp, pkgPath); - 读取密钥环境变量dsh-desktop-plugin/index.js:41
const TOKEN = process.env.DSH_DESKTOP_NOTIFY_TOKEN || ""; - 发起网络请求dsh-desktop-plugin/index.js:67
fetch(NOTIFY_URL, { - 发起网络请求plugins/whaleharbor-promo/client.js:218
return fetch(`http://127.0.0.1:${bridge.port}${path}`, { - 发起网络请求plugins/whaleharbor-promo/index.js:76
const req = https.get(u, { headers: { "User-Agent": UA, Accept: "application/vnd.github+json" } }, (res) => { - 写入本地文件plugins/whaleharbor-promo/index.js:152
fs.mkdirSync(path.dirname(dest), { recursive: true }); - 发起网络请求plugins/whaleharbor-promo/index.js:164
const req = https.get(u, { headers: { "User-Agent": UA } }, (res) => { - 写入本地文件plugins/whaleharbor-promo/index.js:174
const out = fs.createWriteStream(dest); - 读取本地文件plugins/whaleharbor-promo/index.js:192
const s = fs.createReadStream(file); - 写入本地文件plugins/whaleharbor-promo/index.js:204
try { fs.renameSync(file, file + ".sha256-mismatch"); return; } catch { } - 删除本地文件plugins/whaleharbor-promo/index.js:205
try { fs.rmSync(file, { force: true }); } catch { } - 读取本地文件plugins/whaleharbor-promo/index.js:248
state.got = (() => { try { return fs.statSync(state.file).size; } catch { return state.got; } })(); - 读取本地文件plugins/whaleharbor-promo/index.js:276
try { existsSize = fs.statSync(state.file).size; } catch { } - 执行外部命令固定命令plugins/whaleharbor-promo/index.js:319
execFile("where.exe", [names[i]], { windowsHide: true }, (err, stdout) => { - 读取本地文件plugins/whaleharbor-promo/index.js:321
if (!err && first && fs.existsSync(first)) cb(first); - 读取本地文件plugins/whaleharbor-promo/index.js:330
if (fs.existsSync(c)) cb(c); - 执行外部命令固定命令plugins/whaleharbor-promo/index.js:336
execFile("which", [c], { windowsHide: true }, (err) => { - 执行外部命令来自配置/变量plugins/whaleharbor-promo/index.js:348
const child = spawn(browser, [`--app=${url}`], { detached: true, stdio: "ignore" }); - 执行外部命令固定命令plugins/whaleharbor-promo/index.js:405
if (process.platform === "win32") spawn("explorer.exe", ["/select,", state.file], { detached: true, stdio: "ignore" }).unref(); - 执行外部命令固定命令plugins/whaleharbor-promo/index.js:406
else if (process.platform === "darwin") spawn("open", ["-R", state.file], { detached: true, stdio: "ignore" }).unref(); - 执行外部命令固定命令plugins/whaleharbor-promo/index.js:407
else spawn("xdg-open", [path.dirname(state.file)], { detached: true, stdio: "ignore" }).unref();
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 桌面端运行环境
- 核心独立更新
README
由 DeepSeek 最新模型翻译生成鲸港 WhaleHarbor
为 DeepSeek Harness 打造的桌面端体验
鲸港 WhaleHarbor 把 DeepSeek Harness(DSH) 包装成一个原生桌面应用。它负责窗口、托盘、更新与桌面运行环境,同时完整保留官方 DSH 的智能体、模型、工具、会话与 Web UI。
显示品牌为「鲸港 WhaleHarbor」;包名与内部标识(dsh-desktop、DSH_DESKTOP_ 环境变量等)沿用历史命名,行为不变。
DSH 核心不打进安装包:目标机器首次启动时自动通过内置 pnpm 安装最新版 DSH,之后直接复用本机已有的完整安装——既保持轻量,又能随时更新到最新。
零依赖运行:DSH 核心跑在应用内置的独立 Node 24 运行时上(真实的 Console 子系统 node.exe,随安装包分发,保证 Windows 下整棵进程树无弹窗),Electron 内嵌 Node 仅作回退;核心的安装/更新用内置 pnpm——最终用户机器上不需要安装 node/npm。(注:MCP 子进程依赖用户 PATH 里的 node/npx,常规开发机均满足。)
DSH 来自哪个 npm 仓库? 核心 @deepseek-ai/dsh 发布在官方 npmjs.org(https://registry.npmjs.org)。
展开完整文档(README 剩余 1 节)
鲸港 WhaleHarbor
为 DeepSeek Harness 打造的桌面端体验
鲸港 WhaleHarbor 把 DeepSeek Harness(DSH) 包装成一个原生桌面应用。它负责窗口、托盘、更新与桌面运行环境,同时完整保留官方 DSH 的智能体、模型、工具、会话与 Web UI。
显示品牌为「鲸港 WhaleHarbor」;包名与内部标识(dsh-desktop、DSH_DESKTOP_ 环境变量等)沿用历史命名,行为不变。
DSH 核心不打进安装包:目标机器首次启动时自动通过内置 pnpm 安装最新版 DSH,之后直接复用本机已有的完整安装——既保持轻量,又能随时更新到最新。
零依赖运行:DSH 核心跑在应用内置的独立 Node 24 运行时上(真实的 Console 子系统 node.exe,随安装包分发,保证 Windows 下整棵进程树无弹窗),Electron 内嵌 Node 仅作回退;核心的安装/更新用内置 pnpm——最终用户机器上不需要安装 node/npm。(注:MCP 子进程依赖用户 PATH 里的 node/npx,常规开发机均满足。)
DSH 来自哪个 npm 仓库? 核心 @deepseek-ai/dsh 发布在官方 npmjs.org(https://registry.npmjs.org)。国内网络下默认使用 npmmirror 镜像(registry.npmmirror.com),探测不可用或安装失败时会自动回退 npmjs.org,也可用 DSH_DESKTOP_NPM_REGISTRY 指定。安装过程会显示实时进度条与已下载大小。
主要功能
沉浸式桌面窗口无边框(frameless)窗口,DSH Web UI 占满整个屏幕;最小化/最大化/关闭按钮以半透明方式融入界面右上角,不遮挡任何 DSH 内容。
系统托盘鲸鱼托盘图标,右键「打开 / 重启核心 / 退出」(插件还可贡献自己的菜单分区)。开启「常驻通知栏」后,关闭窗口最小化到托盘,后台持续运行。
保持最新内置「核心」设置页显示 DSH 版本、一键检查更新、稳定/体验/实验三条更新渠道,支持自动更新(新版本自动下载安装,失败自动回滚)。
任务通知主任务完成、失败或需要确认时发送桌面通知(子任务完成不打扰);可选「阻止休眠」,任务运行期间防止系统睡眠。
内置插件市场 + 插件生态随壳自带 dshmarket 插件市场(免下载安装),可浏览/搜索/一键安装社区插件;插件还能调用桌面壳的 RPC 扩展面:桌面通知、托盘菜单、任务栏进度/角标、桌面浮窗(桌面宠物)等。
继承终端 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 下载对应平台安装包:
| 平台 | 格式 |
| Windows | NSIS 安装器(x64) |
| macOS | dmg(Apple Silicon / Intel) |
| Linux | AppImage · 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: 内置 Node 24 (resources/node) /lib/bin.js --patch --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:/,带 x-dsh-notify-token 头,body 为 { "method": "...", "params": { ... } };响应 { ok: true, ... } 或 { ok: false, error }。网络失败按 1.5s~20s 退避重试几次;收到 ok:false 说明对端壳无此方法(旧版本),不必重试。
| 方法 | 参数 | 说明 |
| bridge.register | plugin, 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.show | kind?, title?, body?, force? | 桌面通知。kind=done/error/approval 有默认文案;force:true 绕过「窗口聚焦时不弹」抑制(用户显式动作的回执用);受设置「任务通知」总开关约束 |
| tray.setMenu | plugin, items | 贡献托盘右键菜单分区([{id, label, enabled?}],≤10 项),点击回投 {event:"tray.click", id} |
| settings.get / settings.set | plugin, 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) 里js 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 槽挂一个整页(桌面版设置区自身就是这么挂的): js // 客户端插件,需 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_REGISTRY | npm 镜像(默认 npmmirror) |
| DSH_DESKTOP_NPM_CACHE | npm 缓存目录 |
| DSH_DESKTOP_SPEC | DSH 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 签名与公证:
- 不买账号也能签(自制自签名证书):在 Windows 上用 New-SelfSignedCertificate -Type CodeSigningCert 生成并导出 .p12,仓库 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 官方产品。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
MoonlitDropOfBlood/DSH-Desktop
为DeepSeek Harness 打造的桌面端,没有打包DeepSeek Harness,核心可以独立更新
相关插件 · 桌面端
Codex 任务面板chuspeeism/dashi-taskboard
现代化可灵活嵌入的任务面板,支持 Codex、DeepSeek Harness
★ 3,409已汉化DSH
71.7
多智能体自进化开发平台Prism-Shadow/penguin-harness
统一、稳定的 Agent 自进化框架全自动优化:任意模型 · 任意算法 · 任意 Benchmark
★ 3,111已汉化DSH
71.1
桌面宠物PC2005-cloud/dsh-pet
DSH 桌面宠物:一行命令装好即用的透明动画小桌宠,支持多开、大小位置随心配置;还内置 DIY 素材链,能用 AI…
★ 5,341已汉化DSH
71
多端 Agent 工作台GCWing/OpenBitFun
OpenBitFun 是一个高度可定制的开源 Agent 工作台,让任务按你的方式持续推进。
★ 3,449已汉化DSH
70.8
DSH Desktopanywhere-labs/dsh-desktop
为 DeepSeek Harness DSH 插件生态打造的现代化桌面端解决方案。万物皆「插件」,桌面本身也是「插件」。
★ 34,532已汉化DSH
70.7
桌面宠物伴侣OpenPetsHQ/openpets
桌面伴侣平台,带宠物、插件,还能选配本地智能体集成。
★ 1,353已汉化DSH
70.2