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

桌面发行版 Links2008/DeepSeek-Harness-Desktop

DeepSeek Harnessv0.2.0
Links200812 天前有提交已提供中文文档扫描:含敏感能力

Windows 桌面版 DeepSeek Harness 发行版,支持原生通知、流畅的窗口控制、捆绑运行时和自动更新。追踪官方主分支。针对官方版本进行了桌面美化和功能补充

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

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

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

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · desktop
装得上吗
静态安装检查未通过,可能需要源码安装
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 12 天前
档位由哪些信号合成

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

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

仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

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

✓npm 包dsh-desktop @ 0.2.0
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

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

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/29 22:39:18

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

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 102 处,展示前 83 条)
  • 写入本地文件
    main.js:90
    fs.appendFileSync(logFile, `[${new Date().toISOString()}] ${msg}\n`);
  • 读取本地文件
    main.js:116
    if (!fs.existsSync(lockPath)) return;
  • 读取本地文件
    main.js:117
    const pid = parseInt(fs.readFileSync(lockPath, "utf8").trim(), 10);
  • 删除本地文件
    main.js:119
    fs.unlinkSync(lockPath);
  • 删除本地文件
    main.js:126
    fs.unlinkSync(lockPath);
  • 读取本地文件
    main.js:296
    return require("node:crypto").createHash("sha1").update(fs.readFileSync(file)).digest("hex");
  • 读取本地文件
    main.js:944
    if (!fs.existsSync(settingsPath) || !fs.existsSync(credentialsPath)) return;
  • 读取本地文件
    main.js:945
    const settings = fs.readFileSync(settingsPath, "utf8");
  • 读取本地文件
    main.js:947
    const credentials = fs.readFileSync(credentialsPath, "utf8");
  • 写入本地文件
    main.js:956
    try { fs.copyFileSync(settingsPath, backupPath); } catch (e) {}
  • 写入本地文件
    main.js:961
    fs.writeFileSync(settingsPath, newSettings, "utf8");
  • 写入本地文件
    main.js:997
    fs.writeFileSync(controlStatePath(), JSON.stringify({ expanded: Boolean(expanded) }));
  • 执行外部命令来自配置/变量
    main.js:1344
    spawn(installer, ["/S"], { detached: true, stdio: "ignore", windowsHide: true }).unref();
  • 读取本地文件
    runtime/daemon-controller.cjs:22
    try { return JSON.parse(fs.readFileSync(file, "utf8")); }
  • 写入本地文件
    runtime/daemon-controller.cjs:27
    fs.mkdirSync(path.dirname(file), { recursive: true });
  • 写入本地文件
    runtime/daemon-controller.cjs:29
    fs.writeFileSync(temporary, JSON.stringify(value, null, 2) + "\n", "utf8");
  • 写入本地文件
    runtime/daemon-controller.cjs:30
    fs.renameSync(temporary, file);
  • 写入本地文件
    runtime/daemon-controller.cjs:40
    fs.mkdirSync(path.dirname(file), { recursive: true });
  • 写入本地文件
    runtime/daemon-controller.cjs:44
    fs.writeFileSync(descriptor, JSON.stringify({ pid: process.pid, createdAt: Date.now() }) + "\n");
  • 删除本地文件
    runtime/daemon-controller.cjs:51
    try { fs.unlinkSync(file); } catch (_unlinkError) { return false; }
  • 删除本地文件
    runtime/daemon-controller.cjs:60
    try { fs.unlinkSync(file); } catch (_error) {}
  • 发起网络请求
    runtime/daemon-controller.cjs:101
    const request = http.get({
  • 执行外部命令固定命令
    runtime/daemon-controller.cjs:157
    spawnSync("taskkill", ["/F", "/T", "/PID", String(state.pid)], {
  • 执行外部命令来自配置/变量
    runtime/daemon-controller.cjs:238
    const child = spawn(this.execPath, [host, "--config", this.paths.launch], {
  • 读取本地文件
    runtime/window-state.cjs:10
    try { saved = JSON.parse(fs.readFileSync(file, 'utf8')); } catch (_) {}
  • 写入本地文件
    runtime/window-state.cjs:34
    fs.writeFileSync(temporary, JSON.stringify({ ...bounds, maximized: window.isMaximized() }) + '\n');
  • 写入本地文件
    runtime/window-state.cjs:35
    fs.renameSync(temporary, file);
  • 读取本地文件
    scripts/patch-harness-runtime.cjs:162
    if (!fs.existsSync(file)) return false;
  • 读取本地文件
    scripts/patch-harness-runtime.cjs:163
    const before = fs.readFileSync(file, "utf8").replace(/ /g, "\n");
  • 写入本地文件
    scripts/patch-harness-runtime.cjs:166
    fs.writeFileSync(file, after, "utf8");
  • 读取本地文件
    scripts/patch-harness-runtime.cjs:173
    if (!fs.existsSync(manifestPath) || !fs.existsSync(patchPath)) return [];
  • 读取本地文件
    scripts/patch-harness-runtime.cjs:174
    const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
  • 读取本地文件
    scripts/patch-harness-runtime.cjs:175
    let patch = fs.readFileSync(patchPath, "utf8");
  • 读取本地文件
    scripts/patch-harness-runtime.cjs:179
    if (!fs.existsSync(packagePath)) continue;
  • 写入本地文件
    scripts/patch-harness-runtime.cjs:188
    if (activated.length > 0) fs.writeFileSync(patchPath, patch, "utf8");
  • 写入本地文件
    scripts/patch-harness-runtime.cjs:237
    fs.writeFileSync(patchPath, patch, "utf8");
  • 写入本地文件
    scripts/prepare-compile-cache.cjs:7
    fs.mkdirSync(packagedDir, { recursive: true });
  • 读取本地文件
    scripts/prepare-compile-cache.cjs:8
    fs.accessSync(packagedDir, fs.constants.W_OK);
  • 写入本地文件
    scripts/prepare-compile-cache.cjs:12
    fs.mkdirSync(fallbackDir, { recursive: true });
  • 读取本地文件
    scripts/prepare-desktop-profile.cjs:7
    if (fs.existsSync(manifestPath)) return false;
  • 读取本地文件
    scripts/prepare-desktop-profile.cjs:8
    if (!fs.existsSync(path.join(runtimeRoot, 'node_modules', 'dshmarket', 'package.json'))) return false;
  • 写入本地文件
    scripts/prepare-desktop-profile.cjs:9
    fs.mkdirSync(profileDir, { recursive: true });
  • 写入本地文件
    scripts/prepare-desktop-profile.cjs:14
    fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n', { flag: 'wx' });
  • 读取本地文件
    scripts/prepare-profile-prebundles.cjs:14
    hash.update(fs.readFileSync(path.join(profileDir, name)));
  • 读取本地文件
    scripts/prepare-profile-prebundles.cjs:83
    fs.existsSync(path.join(item.root, "package.json"))
  • 读取本地文件
    scripts/prepare-profile-prebundles.cjs:84
    && fs.existsSync(path.join(item.root, item.entry)));
  • 读取本地文件
    scripts/prepare-profile-prebundles.cjs:89
    return JSON.parse(fs.readFileSync(markerPath, "utf8"));
  • 读取本地文件
    scripts/prepare-profile-prebundles.cjs:102
    source: fs.readFileSync(manifestPath, "utf8"),
  • 读取本地文件
    scripts/prepare-profile-prebundles.cjs:103
    value: JSON.parse(fs.readFileSync(manifestPath, "utf8")),
  • 写入本地文件
    scripts/prepare-profile-prebundles.cjs:131
    fs.writeFileSync(file, JSON.stringify(value, null, 2) + "\n", "utf8");
  • 写入本地文件
    scripts/prepare-profile-prebundles.cjs:148
    fs.mkdirSync(stateDir, { recursive: true });
  • 删除本地文件
    scripts/prepare-profile-prebundles.cjs:158
    fs.rmSync(stage, { force: true });
  • 删除本地文件
    scripts/prepare-profile-prebundles.cjs:175
    fs.rmSync(item.outfile, { force: true });
  • 写入本地文件
    scripts/prepare-profile-prebundles.cjs:176
    fs.renameSync(item.stage, item.outfile);
  • 删除本地文件
    scripts/prepare-profile-prebundles.cjs:189
    for (const item of staging) fs.rmSync(item.stage, { force: true });
  • 写入本地文件
    scripts/prepare-profile-prebundles.cjs:191
    try { fs.writeFileSync(item.path, item.source, "utf8"); } catch (_restoreError) {}
  • 读取本地文件
    scripts/prebundle-runtime-startup.cjs:51
    const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
  • 写入本地文件
    scripts/prebundle-runtime-startup.cjs:71
    fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n", "utf8");
  • 读取本地文件
    scripts/prebundle-runtime-startup.cjs:72
    return { name: spec.name, bytes: fs.statSync(outfile).size };
  • 读取本地文件
    scripts/prebundle-runtime-startup.cjs:78
    if (!fs.existsSync(dir)) return;
  • 读取本地文件
    scripts/prebundle-runtime-startup.cjs:79
    for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
  • 读取本地文件
    scripts/prebundle-runtime-startup.cjs:83
    for (const scoped of fs.readdirSync(candidate, { withFileTypes: true })) {
  • 读取本地文件
    scripts/prebundle-runtime-startup.cjs:93
    if (!fs.existsSync(manifestPath)) return;
  • 写入本地文件
    scripts/prebundle-runtime-startup.cjs:139
    fs.writeFileSync(cliManifestPath, JSON.stringify(cliManifest, null, 2) + '\n', 'utf8');
  • 删除本地文件
    scripts/prebundle-runtime-startup.cjs:152
    fs.rmSync(path.join(piAiDir, generated), { force: true });
  • 写入本地文件
    scripts/prebundle-runtime-startup.cjs:154
    fs.writeFileSync(piAiManifestPath, JSON.stringify(piAiManifest, null, 2) + "\n", "utf8");
  • 读取本地文件
    runtime/daemon-host.cjs:11
    const config = JSON.parse(fs.readFileSync(process.argv[configIndex + 1], "utf8"));
  • 写入本地文件
    runtime/daemon-host.cjs:55
    fs.writeFileSync(temporary, JSON.stringify(state, null, 2) + "\n", "utf8");
  • 写入本地文件
    runtime/daemon-host.cjs:56
    fs.renameSync(temporary, config.statePath);
  • 读取本地文件
    runtime/daemon-host.cjs:63
    if (fs.existsSync(logPath)) {
  • 写入本地文件
    runtime/daemon-host.cjs:64
    try { fs.renameSync(logPath, `${logPath}.prev`); } catch (_error) {}
  • 写入本地文件
    runtime/daemon-host.cjs:66
    fs.writeFileSync(logPath, `[${new Date().toISOString()}] dsh daemon backend log start\n`);
  • 读取本地文件
    runtime/daemon-host.cjs:67
    logBytes = fs.statSync(logPath).size;
  • 写入本地文件
    runtime/daemon-host.cjs:79
    fs.appendFileSync(logPath, "\n[dsh-daemon] log size limit reached\n");
  • 写入本地文件
    runtime/daemon-host.cjs:83
    fs.appendFileSync(logPath, text);
  • 执行外部命令固定命令
    runtime/daemon-host.cjs:95
    spawnSync("taskkill", ["/F", "/T", "/PID", String(pid)], {
  • 执行外部命令来自配置/变量
    runtime/daemon-host.cjs:124
    backend = spawn(spec.command, spec.args, {
  • 读取本地文件
    runtime/plugin-recovery.cjs:29
    if (!fs.existsSync(manifestPath)) return null;
  • 读取本地文件
    runtime/plugin-recovery.cjs:30
    const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
  • 写入本地文件
    runtime/plugin-recovery.cjs:39
    fs.copyFileSync(manifestPath, backupPath, fs.constants.COPYFILE_EXCL);
  • 写入本地文件
    runtime/plugin-recovery.cjs:43
    fs.writeFileSync(temporary, JSON.stringify(manifest, null, 2) + "\n", { flag: 'wx' });
  • 写入本地文件
    runtime/plugin-recovery.cjs:44
    try { fs.renameSync(temporary, manifestPath); }
  • 删除本地文件
    runtime/plugin-recovery.cjs:45
    finally { fs.rmSync(temporary, { force: true }); }
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

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

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

界面预览

4 张 · 点击查看大图

功能亮点

  • 原生通知
  • 窗口控制
  • 自动更新

README

由 DeepSeek 最新模型翻译生成
DeepSeek Harness Desktop 轻量、快速、完整离线的 DeepSeek Harness Windows 桌面发行版。 下载最新已发布版本 · 重大升级 · 软件优点 · 源码构建 · 问题反馈 [!TIP] 如果这个项目对你有帮助,欢迎点个 Star 支持一下——制作不易,你的 Star 是持续维护的最大动力。 桌面版功能与相对官方版的增强 提供哪些功能 - 开箱即用的 Windows 应用:一个安装包内提供 Harness runtime、原生终端、图片处理与插件能力,无需自备 Node,也不用手敲命令行启动。 - 常驻后台 daemon:后端独立于窗口运行,关闭窗口不中断正在执行的任务,再次点击快捷方式即可恢复会话。 - 原生 Windows 集成:单实例、系统通知、无边框窗口、桌面与开始菜单快捷方式、完整卸载。 - 内置插件商店与 IM 接入:新 profile 开箱具备 dshmarket 入口,并通过 DSH-IM 配置企业协作与个人消息渠道。 - 自动更新闭环:检查新版本、差分或完整下载、SHA 校验、退出进程树、静默覆盖安装并恢复快捷方式。 - 默认启用 Computer Use:随安装包提供官方 Computer Use 服务与 Cua Driver 原生提供方,无需手动安装。
展开完整文档(README 剩余 1 节)
DeepSeek Harness Desktop

轻量、快速、完整离线的 DeepSeek Harness Windows 桌面发行版。

下载最新已发布版本
· 重大升级
· 软件优点
· 源码构建
· 问题反馈

[!TIP]
如果这个项目对你有帮助,欢迎点个 Star 支持一下——制作不易,你的 Star 是持续维护的最大动力。

桌面版功能与相对官方版的增强

提供哪些功能

- 开箱即用的 Windows 应用:一个安装包内提供 Harness runtime、原生终端、图片处理与插件能力,无需自备 Node,也不用手敲命令行启动。
- 常驻后台 daemon:后端独立于窗口运行,关闭窗口不中断正在执行的任务,再次点击快捷方式即可恢复会话。
- 原生 Windows 集成:单实例、系统通知、无边框窗口、桌面与开始菜单快捷方式、完整卸载。
- 内置插件商店与 IM 接入:新 profile 开箱具备 dshmarket 入口,并通过 DSH-IM 配置企业协作与个人消息渠道。
- 自动更新闭环:检查新版本、差分或完整下载、SHA 校验、退出进程树、静默覆盖安装并恢复快捷方式。
- 默认启用 Computer Use:随安装包提供官方 Computer Use 服务与 Cua Driver 原生提供方,无需手动安装。

相对官方版做了什么

- 把环境打包好:官方以 CLI / 服务形态提供内核,桌面版连同运行时、原生模块和依赖一起打包,用户只需安装一个 exe。
- 从“每次冷启”到“常驻 + 预热”:后端拆分为独立 daemon,具备跨进程启动锁、版本/PID/端口握手、随机 token 的 named-pipe 控制通道和三次退避恢复;Windows 登录后静默预热。
- 构建产物与运行态 ABI 对齐:compile cache 改由正式 Electron Node 生成,并锁定 Electron 版本以匹配原生模块的 V8 指纹白名单,避免启动即崩。
- 精简发行体积:移除与 Electron 内置 Node 重复的 node.exe,语言包只保留简体中文、繁体中文和英文,runtime 剔除 PDB、ARM64 预构建、测试夹具、TypeScript 类型源码与包内示例文档。
- 桌面细节适配:深浅色跟随系统,兼容 Aqua 主题注册形式,侧栏切换只提交一次原生控件位置,避免逐帧重排造成卡顿。
- 不污染用户数据:升级不重置 ~/.dsh,不把个人插件、配置和凭据写入公共制品。
- 内核跟随官方最新:当前锁定 dsh-v0.2.1-rc.2(见 upstream-lock.json),兼容主题、字体和批量字号写入,保留断线失败的收尾处理与并发保护校验。v4.5 更新内容见发布说明。

优势在哪里

- 一次下载即可离线使用:不在首次启动时临时下载运行时,安装完成即可启用。
- 重开速度接近网页:常驻 daemon、登录预热、compile cache 与主界面预加载共同缩短等待。
- 保留用户配置:沿用同一份配置档,安装器不会清除插件、会话或凭据;上游 0.2 的自定义插件兼容性和旧模型 ID 变更见发布说明。
- 更新可靠且可复核:Release 同时公布 SHA-256,差分更新显著减小下载量。
- 隐私边界清晰:后端只监听本机 127.0.0.1:3080,仓库与安装包不含 API Key、Cookie、凭据、会话或本机日志。

产品预览

Agent 预设与模式切换紧凑侧栏与沉浸工作区

v4 重大升级

1. 安装包轻量化

- 移除重复打包的独立 node.exe,直接用 Electron 43 内置的 Node 24 启动 Harness。
- Chromium 只保留简体中文、繁体中文和英文语言包。
- runtime 不再携带 PDB、ARM64 预构建、测试夹具、TypeScript 类型源码和包内示例文档。
- 保留完整离线安装:Harness runtime、原生终端、图片处理和插件能力仍随安装包提供。
- NSIS 使用 7z 与 blockmap 差分更新,不再使用易卡住且体积更大的 ZIP 载荷。
- v4.0.1 安装包为 125,255,184 字节(119.45 MiB),较 v3 基线减少 94.95 MiB / 44.29%;Release 同时公布 SHA-256 供复核。

2. 冷启动和首屏响应

- 桌面窗口与 Harness 后端彻底解耦:常驻 daemon 独立管理后端、插件恢复和会话,关闭窗口不终止正在运行的任务。
- Windows 登录后静默预热 daemon;用户再次打开时跳过后端冷启动,直接连接本机 127.0.0.1:3080。
- daemon 具备跨进程启动锁、版本/PID/端口握手、随机 token 的 named-pipe 控制通道和三次退避恢复。
- compile cache 改由正式 Electron Node 生成,构建态与运行态 ABI、Node 版本完全一致。
- 启动依赖预打包并按配置档指纹复用,依赖未变化时跳过重复编译。
- 3080 端口开放后立即预加载主界面,插件树 settle 后再释放启动遮罩。
- 非关键桌面注入后置,不再阻塞编辑器首屏;启动阶段仍保留可诊断时序。

以下是 v4 架构升级时的历史基线,不代表 v4.0.2 新内核的性能承诺:三次隔离解包态实测(毫秒,中位数 / 最差值),完整冷启动 HTTP 3224 / 3231,冷启动首屏 4628 / 4736,普通关窗后快捷方式重开 141 / 143,强制结束前台壳后复用 daemon 457 / 459。全新安装后第一次首屏会受 Windows 新文件扫描影响,当时本机验收为 31120 ms。

3. 浅色 UI 与兼容模式

- 启动页、窗口背景和系统标题区域跟随 Windows 深浅色偏好。
- 设置页兼容 Aqua 主题注册形式,避免主题插件升级后的设置入口失配。
- 侧栏状态经同一事件循环消抖后只提交一次原生控件位置,避免逐帧 WebContentsView 重排。
- 兼容模式保留必要的菜单、对话框和窗口控件动效,不强行启用高成本背景效果。

4. 稳定性大幅提升与数据安全

- 保留 ~/.dsh 中已有的 DSH-IM、Aqua、会话、模型配置和凭据;升级不会重置配置档。
- 单个第三方插件缺失构建产物时可隔离故障项,避免拖垮整个后端。
- DSH-IM 等社区插件仍由用户配置档管理,桌面安装包不把个人插件和配置写入公共制品。

当前源码版本为 v4.4.1,已通过 Windows 功能验收;可下载的安装包以 Releases 页面为准。更新内容见 v4.4.1 Release Notes,历史架构说明见 v4.0.1 Release Notes。

为什么选择桌面版

| 优点 | 带来的体验 |
| 轻量离线安装 | 一次下载即可使用,不在首启临时下载运行时 |
| 原生 Windows 壳 | 单实例、系统通知、无边框窗口、快捷方式和完整卸载 |
| 接近网页的重开速度 | 常驻 daemon、登录预热、compile cache 和主界面预加载共同缩短等待 |
| 插件兼容 | 保留现有配置档,支持 DSH-IM、Aqua 与 Harness 插件生态 |
| 内置插件商店 | 新配置档开箱具备 dshmarket 入口,按需扩展社区插件 |
| 多 IM 连接 | 通过 DSH-IM 配置企业协作和个人消息渠道 |
| 更新可靠 | 下载、校验、退出进程树、静默覆盖安装和快捷方式恢复形成闭环 |
| 隐私明确 | 公共仓库和安装包不包含 API Key、Cookie、凭据、会话或本机日志 |

一分钟开始

1. 打开 Latest Release。
2. 下载该 Release 的 DeepSeekHarness-Setup-<版本>.exe(版本以 Release 页面为准)。
3. 运行安装向导并选择安装目录。
4. 从桌面快捷方式或开始菜单启动 DeepSeek Harness。

关闭窗口会隐藏并保留已就绪页面,后台任务继续运行;再次点击快捷方式可瞬时恢复。需要完全退出桌面壳时按 Ctrl+Q。

[!NOTE]
安装包暂未使用商业代码签名证书,SmartScreen 可能显示“未知发布者”。请在 Release 页面核对安装包字节数和 SHA-256。

自动更新

用户点击侧栏更新按钮后,桌面端从本仓库 Releases 检查并下载差分或完整安装包。只有进入安装流程时才停止 daemon 和后端进程树;普通关窗不会中断任务。安装完成后会补齐缺失的桌面和开始菜单快捷方式。

GitHub Actions 仅以只读权限执行测试、归档、SHA-512、隔离安装、AppID、Harness 版本、HTTP 200、原生模块、端口释放和卸载验收,不提交代码或发布 Release。通过后由 Links2008 身份人工核对制品并发布为 Latest。

维护者可在本机安装并登录 GitHub CLI 后运行 npm run release:github。该命令会在发布前校验账号不是 bot、工作树和 origin/main 一致、当前 HEAD 的非定时 Actions 已成功、标签未被占用、EXE/blockmap/latest.yml 完整且 SHA-512 相符;任何一项不满足都会拒绝发布。建议直接发布该次 CI 已验收的制品:

powershell -NoProfile -ExecutionPolicy Bypass -File scripts/publish-release.ps1 -UseValidatedArtifact -Publish

提交和人工触发验收使用 upstream-lock.json 的固定 commit。每日定时兼容性监控选取上游官方最新发布的 DSH 标签(含预发布、排除草稿),不追逐未发布的 master 提交。监控通过不等于自动安装或自动发布:维护者核对结果、更新锁文件并再次验收后,才发布新的桌面版本。这样既保持跟进,也避免把未经验证的上游变化直接推给用户。

排查特定上游版本时,可在手动验收的 upstream_ref 中填写标签或 commit,并勾选 force;留空仍使用锁文件。该选项仅用于验收,不提交锁文件或发布 Release。若存在 release-notes-unreleased.md,发布前须将其中条目归入实际版本的更新说明并删除待发布文件,否则发布脚本会拒绝创建新 Release。

verify-installed-runtime.ps1 的安装/卸载测试只应在干净 CI runner 或虚拟机运行;检测到已有正式安装时会拒绝执行,避免测试清理影响实际安装及快捷方式。

上游与版本谱系

本仓库是独立的 Windows 桌面发行仓库,核心能力来自官方 deepseek-ai/deepseek-harness。

| 项目 | 当前值 |
| 桌面源码版本 | 4.4.1 |
| Harness 版本 | 0.2.1-alpha.2,以 upstream-lock.json 为准 |
| 跟进策略 | 官方最新发布标签 → 兼容性验收 → 锁定并发布桌面更新 |
| 上游分支 | master |
| 锁定提交 | 见 upstream-lock.json |
| 状态文件 | upstream-lock.json |

从源码构建

npm ci
npm test
npm run build:installer

本地完整构建需要先在 bundle/dsh-runtime 组装官方 Harness runtime。Electron 依赖同时提供桌面壳和后端 Node 运行时,不再需要 bundle/node/node.exe。只读自动验收流程见 upstream-sync.yml。

安全与隐私

- 不打包 API Key、Token、Cookie、.credentials.yaml、~/.dsh、用户会话或日志。
- 后端只监听本机 127.0.0.1:3080。
- Release 发布前验证安装、启动、原生模块、清理和卸载。
- 请勿在公开 Issue 中粘贴凭据或完整用户日志。

贡献与许可证

欢迎通过 Issues 反馈 Windows 安装、启动、界面、插件兼容或更新问题。提交代码前请运行 npm test。

桌面壳、构建脚本和配置遵循 MIT License;DeepSeek Harness 与第三方依赖继续遵循各自许可证。
预览分享卡片长什么样 ↓Links2008/DeepSeek-Harness-Desktop
分享 · DeepSeek Harness Hub
Links2008/DeepSeek-Harness-Desktop

Windows 桌面版 DeepSeek Harness 发行版,支持原生通知、流畅的窗口控制、捆绑运行时和自动更新。追踪官方主分支。针对官方版本进行了桌面美化和功能补充

回到顶部