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

桌面套壳工具 yanxi-lu/dsh-desktop

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

DeepSeek Harness (dsh) 的 Windows 桌面套壳:轻量壳 + 首次引导 + 托盘驻留

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

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

自动兼容检查有告警:npm 同名包「dsh-desktop」归属 snowcrescenter-tech/dsh-desktop,装到的可能不是本插件。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add yanxi-lu/dsh-desktop
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · desktop
装得上吗
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 40 天前
档位由哪些信号合成

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

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

npm 同名包「dsh-desktop」归属 snowcrescenter-tech/dsh-desktop,装到的可能不是本插件

展开查看检查明细 ↓

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

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

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/7 04:11:14

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

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

可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 84 处,展示前 64 条)
  • 读取本地文件
    src/main/balance.ts:98
    return parser(readFileSync(path, 'utf8'));
  • 读取本地文件
    src/main/diagnostics.ts:22
    check('数据目录', '检查目录是否存在、权限或选择正确配置方案', async () => { await access(home, constants.R_OK | constants.W_OK); return home; });
  • 发起网络请求
    src/main/diagnostics.ts:23
    check('本机服务', '检查端口占用或重启 Harness', async () => { const res = await fetch(`http://127.0.0.1:${port}`, { signal: AbortSignal.timeout(5000) });
  • 发起网络请求
    src/main/diagnostics.ts:31
    check(name, '检查网络、代理或防火墙;诊断不发送计费模型请求', async () => { const res = await fetch(url, { method: 'HEAD', signal: AbortSignal.timeout(8000) });
  • 读取本地文件
    src/main/dsh.ts:32
    if (existsSync(cand)) return cand;
  • 发起网络请求
    src/main/dsh.ts:179
    const res = await fetch(url);
  • 发起网络请求
    src/main/index.ts:69
    const bridge = new HarnessBridge(() => dshProc?.url ?? null, (url, options) => session.defaultSession.fetch(url instanceof URL ? url.toString() : url,
  • 写入剪贴板
    src/main/index.ts:105
    notification.on('click', () => { if (alert.sessionId) { clipboard.writeText(alert.sessionId); showCurrentWindow(); } else openManagement(); });
  • 写入剪贴板
    src/main/index.ts:543
    if (typeof id === 'string' && /^[ -]{1,180}$/.test(id)) clipboard.writeText(id);
  • 写入本地文件
    src/main/index.ts:567
    const backupRoot = join(app.getPath('userData'), 'plugin-backups'); await mkdir(backupRoot, { recursive: true });
  • 读取本地文件
    src/main/index.ts:601
    const path = selected.filePaths[0]; if (!(await stat(path)).isDirectory()) throw new Error('选择的路径不是文件夹');
  • 读取本地文件
    src/main/index.ts:631
    if ((await stat(selected.filePaths[0])).size > 2 * 1024 * 1024) throw new Error('设置文件过大');
  • 读取本地文件
    src/main/index.ts:632
    const raw = JSON.parse(await readFile(selected.filePaths[0], 'utf8'));
  • 写入本地文件
    src/main/index.ts:640
    await writeFile(selected.filePath, content, { mode: 0o600 }); return { ok: true, path: selected.filePath };
  • 读取本地文件
    src/main/install-cleanup.ts:12
    try { return await realpath(path); }
  • 读取本地文件
    src/main/install-cleanup.ts:20
    const info = await lstat(folder);
  • 读取本地文件
    src/main/install-cleanup.ts:24
    return realpath(root);
  • 读取本地文件
    src/main/install-cleanup.ts:38
    const info = await lstat(folder);
  • 读取本地文件
    src/main/install-cleanup.ts:39
    if (!info.isDirectory() || info.isSymbolicLink() || normalized(await realpath(folder)) !== normalized(folder)) throw new Error('安装目录包含链接,未清理');
  • 读取本地文件
    src/main/install-cleanup.ts:44
    const info = await lstat(marker);
  • 写入本地文件
    src/main/install-cleanup.ts:80
    await writeFile(marker, JSON.stringify({ app: 'dsh-desktop', kind: 'harness-install', id: basename(target) }), { flag: 'wx' });
  • 删除本地文件
    src/main/install-cleanup.ts:84
    await unlink(file);
  • 删除本地文件
    src/main/install-cleanup.ts:89
    await rmdir(directory);
  • 删除本地文件
    src/main/install-cleanup.ts:92
    await unlink(marker);
  • 删除本地文件
    src/main/install-cleanup.ts:93
    await rmdir(target);
  • 读取本地文件
    src/main/managed-install.ts:19
    const stat = await lstat(from);
  • 读取本地文件
    src/main/managed-install.ts:21
    const target = resolve(dirname(from), await readlink(from));
  • 读取本地文件
    src/main/managed-install.ts:24
    const targetStat = await lstat(target);
  • 写入本地文件
    src/main/managed-install.ts:29
    await mkdir(to, { recursive: false });
  • 读取本地文件
    src/main/managed-install.ts:30
    for (const entry of await readdir(from)) await copy(join(from, entry), join(to, entry));
  • 写入本地文件
    src/main/managed-install.ts:31
    } else if (stat.isFile()) await copyFile(from, to, 1);
  • 写入本地文件
    src/main/managed-install.ts:33
    try { await lstat(src); } catch (e: any) { if (e.code === 'ENOENT') { await mkdir(dest); return; } throw e; }
  • 读取本地文件
    src/main/managed-install.ts:33
    try { await lstat(src); } catch (e: any) { if (e.code === 'ENOENT') { await mkdir(dest); return; } throw e; }
  • 读取本地文件
    src/main/managed-install.ts:45
    const old = JSON.parse(readFileSync(this.file, 'utf8'));
  • 写入本地文件
    src/main/managed-install.ts:58
    await mkdir(this.root, { recursive: true });
  • 写入本地文件
    src/main/managed-install.ts:59
    await writeFile(`${this.file}.tmp`, JSON.stringify(this.state, null, 2), { mode: 0o600 });
  • 写入本地文件
    src/main/managed-install.ts:60
    await rename(`${this.file}.tmp`, this.file);
  • 读取本地文件
    src/main/node-installer.ts:56
    const executable = hits.find((path) => /\.exe$/i.test(path) && existsSync(path));
  • 读取本地文件
    src/main/node-installer.ts:58
    return commonNodeCandidates(env).find((path) => existsSync(path)) ?? null;
  • 读取本地文件
    src/main/notifications.ts:19
    constructor(private readonly file: string) { try { this.seen = new Set(JSON.parse(readFileSync(file, 'utf8'))); } catch { } }
  • 写入本地文件
    src/main/notifications.ts:26
    mkdirSync(dirname(this.file), { recursive: true });
  • 写入本地文件
    src/main/notifications.ts:27
    writeFileSync(`${this.file}.tmp`, JSON.stringify([...this.seen]), { mode: 0o600 }); renameSync(`${this.file}.tmp`, this.file);
  • 写入本地文件
    src/main/notifications.ts:27
    writeFileSync(`${this.file}.tmp`, JSON.stringify([...this.seen]), { mode: 0o600 }); renameSync(`${this.file}.tmp`, this.file);
  • 读取本地文件
    src/main/preferences.ts:64
    try { this.value = validatePreferences(JSON.parse(readFileSync(file, 'utf8'))); } catch { this.value = defaults(); }
  • 写入本地文件
    src/main/preferences.ts:69
    mkdirSync(dirname(this.file), { recursive: true });
  • 写入本地文件
    src/main/preferences.ts:70
    writeFileSync(`${this.file}.tmp`, JSON.stringify(value, null, 2), { mode: 0o600 });
  • 写入本地文件
    src/main/preferences.ts:71
    renameSync(`${this.file}.tmp`, this.file);
  • 执行外部命令来自配置/变量
    src/main/service-supervisor.ts:47
    const child = spawn(process.execPath, ['--eval', SUPERVISOR_SOURCE], {
  • 读取本地文件
    src/main/usage-analytics.ts:382
    const entries = readdirSync(directory, { withFileTypes: true });
  • 读取本地文件
    src/main/usage-analytics.ts:436
    if (statSync(this.cacheFile).size > 128 * 1024 * 1024) return;
  • 读取本地文件
    src/main/usage-analytics.ts:437
    const text = readFileSync(this.cacheFile, 'utf8');
  • 写入本地文件
    src/main/usage-analytics.ts:452
    mkdirSync(dirname(this.cacheFile), { recursive: true });
  • 写入本地文件
    src/main/usage-analytics.ts:454
    writeFileSync(`${this.cacheFile}.tmp`, `${digest(payload)}\n${payload}`, { mode: 0o600 });
  • 写入本地文件
    src/main/usage-analytics.ts:455
    renameSync(`${this.cacheFile}.tmp`, this.cacheFile);
  • 读取本地文件
    src/main/usage-analytics.ts:463
    cacheBytes(): number { try { return this.cacheFile ? statSync(this.cacheFile).size : 0; } catch { return 0; } }
  • 读取本地文件
    src/main/usage-analytics.ts:560
    const stat = statSync(filePath);
  • 读取本地文件
    src/main/usage.ts:201
    parsed = parseUsageProjectionCache(readFileSync(filePath, 'utf8'));
  • 读取本地文件
    src/main/usage.ts:203
    updatedAt = statSync(filePath).mtime.toISOString();
  • 读取本地文件
    src/main/windows.ts:49
    if (!existsSync(file)) return { ...DEFAULT_STATE };
  • 读取本地文件
    src/main/windows.ts:50
    return sanitizeWindowState(JSON.parse(readFileSync(file, 'utf-8')));
  • 写入本地文件
    src/main/windows.ts:59
    mkdirSync(dirname(file), { recursive: true });
  • 写入本地文件
    src/main/windows.ts:60
    writeFileSync(file, JSON.stringify(state), 'utf-8');
  • 发起网络请求
    src/renderer/workbench.js:201
    for (const format of ['Csv', 'Json']) task(`export${format}`, async () => { const result = await api.exportUsage(usage.request(), format.toLowerCase()
  • 发起网络请求
    src/renderer/workbench.js:214
    task('rebuildIndex', async () => { $('indexStatus').textContent = '正在后台重建,原始会话不会改动…'; const result = await api.rebuild(usage.request()); usage.render(
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

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

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

功能亮点

  • Windows桌面套壳
  • 首次引导
  • 托盘驻留

README

由 DeepSeek 最新模型翻译生成
dsh-desktop DeepSeek Harness(dsh)的 Windows 桌面套壳:一键启动、更新、重启与托盘驻留。 当前代码版本 0.5.2,修复升级后残留服务占用端口和失败页持续转圈。变更及验证见 0.5.2 交付说明;侧栏与安装清理变更见 0.5.1 说明。已发布的安装包和校验文件见 GitHub Releases。 Harness 官方上游:deepseek-ai/deepseek-harness。 功能 - 一键启动:自动拉起本机 dsh web --no-open(127.0.0.1:3080)并在桌面窗口中使用 - 桌面一键启动:安装器自动创建“DeepSeek Harness”桌面图标和开始菜单快捷方式 - 官方版本检查:启动后查询 DeepSeek 官方 npm latest 版本,发现新版时在控制栏提示 - 版本列表与切换:展示官方 npm 已发布版本,可选择指定版本安装、重装或回退 - 一键安装/更新 Harness:安装官方 npm 包 @deepseek-ai/dsh@latest,完成后自动恢复服务 - 预发布版启动兼容:自动读取 Harness 0.1.2+ 输出的一次性 Token URL,兼容旧版裸地址且不把 Token 发送到桌面控制页
展开完整文档(README 剩余 1 节)
dsh-desktop

DeepSeek Harness(dsh)的 Windows 桌面套壳:一键启动、更新、重启与托盘驻留。

当前代码版本 0.5.2,修复升级后残留服务占用端口和失败页持续转圈。变更及验证见 0.5.2 交付说明;侧栏与安装清理变更见 0.5.1 说明。已发布的安装包和校验文件见 GitHub Releases。

Harness 官方上游:deepseek-ai/deepseek-harness。

功能

- 一键启动:自动拉起本机 dsh web --no-open(127.0.0.1:3080)并在桌面窗口中使用
- 桌面一键启动:安装器自动创建“DeepSeek Harness”桌面图标和开始菜单快捷方式
- 官方版本检查:启动后查询 DeepSeek 官方 npm latest 版本,发现新版时在控制栏提示
- 版本列表与切换:展示官方 npm 已发布版本,可选择指定版本安装、重装或回退
- 一键安装/更新 Harness:安装官方 npm 包 @deepseek-ai/dsh@latest,完成后自动恢复服务
- 预发布版启动兼容:自动读取 Harness 0.1.2+ 输出的一次性 Token URL,兼容旧版裸地址且不把 Token 发送到桌面控制页
- 可视化用量统计:提供调用次数、实际总 Tokens、缓存命中率、会话数、费用概览,以及按小时/日期趋势、模型统计、会话统计和可分页的最近调用
- 官方账户余额:自动复用 Harness 已配置的 DeepSeek Key,展示总余额、充值余额、赠送余额和账户可用状态;Key 不进入页面
- 分时与自定义估价:按每次调用的时间和实际模型自动套用官方价格,也可固定高峰/空闲档或设置本机自定义单价
- Node.js 一键安装:目标主机未安装 Node.js 时,可通过 Windows Package Manager 一键安装官方 Node.js LTS
- 可见安装进度:首次安装下载内容较多时每 5 秒更新状态,下载阶段可取消,最长等待 15 分钟;进入切换/启动阶段后需等待完成
- 首次启动耐心等待:Harness 初次初始化可能超过 30 秒,桌面壳最多等待 120 秒并持续显示用时
- 双重重启:可单独重启 Harness 服务,也可重启整个桌面应用
- 独立控制栏:即使 Harness 页面异常,顶部更新/重启按钮仍可操作
- 首次引导:未装 dsh/Node 时显示引导页,可一键安装或复制安装命令
- 托盘驻留:关闭窗口后服务在后台运行,托盘可重新打开;「退出」会连同 dsh 进程树一起结束
- 退出保护:正常退出等待服务树结束;独立隐藏监护进程在桌面主进程被强制关闭后清理其管理的服务树,不按端口杀死未知程序
- 启动诊断:启动前检查端口占用;失败立即停止转圈,提供重试与工作台诊断入口
- 单实例:重复启动只会聚焦已有窗口
- 崩溃恢复:dsh 意外退出时弹窗提示,可一键重启服务
- 分栏工作台:总览、用量与费用、会话、插件、更新与诊断、设置分别加载;支持浅色、深色和跟随系统
- 预算提醒:每日/月度预算 80% 和 100% 提醒、官方余额下限、高费用会话;支持免打扰和持久化去重
- 会话管理:本地名称、标签、项目分类、搜索与排序;用量详情联动筛选;官方会话归档/恢复
- 插件中心:真实已安装清单、启停/卸载、npm 发现/版本检查、收藏、安装前官方识别、变更前本机配置备份
- 安装管理:新版本独立下载安装,启动成功后仅保留当前托管安装;旧版按需重新下载,不覆盖系统全局 Harness,不自动创建升级快照
- 运行诊断:环境、端口进程、目录、网络及脱敏错误分类;支持更换可用端口、重选工作文件夹和导出报告
- 统计导出:按当前筛选导出全部调用或模型/会话/概览 CSV/JSON,而非只导出可见页
- 设置备份:主题、预算、价格、会话标签和收藏可备份恢复;费用方案不改动 Key 或官方运行配置

安装

1. 可预先安装 Node.js(https://nodejs.org);若未安装,首次启动页可点击“一键安装 Node.js LTS”
2. 可预先安装 dsh:npm install -g @deepseek-ai/dsh;也可启动桌面壳后点击“一键安装/更新 dsh”
3. 从 GitHub Releases 下载 dsh-desktop-setup-x.y.z.exe,安装完成后双击桌面“DeepSeek Harness”图标即可

安装包未做代码签名。请核对来源与 SHA-256;不确定来源时不要忽略系统安全提示。

从 0.5.1 或更早版本升级前,请先在托盘菜单选择“退出”,再安装新版。旧版缺少强制关闭保护,直接由安装器结束可能留下服务占用 3080;关闭主窗口只会最小化到托盘。

图标

应用图标与托盘图标来自项目根目录的高清源图(2048×2048 鲸鱼娘 PNG)。
npm run icon(scripts/gen-icon.ps1)会从源图重新生成:

- assets/icon.ico — 多尺寸 ICO(16~512),嵌入 exe、安装包与桌面/开始菜单快捷方式
- assets/icon.png — 1024×1024 应用 PNG
- assets/tray.png — 32×32 托盘图标

本项目为非官方套壳,与 DeepSeek 无隶属关系。

开发

npm install
npm test # 单元测试(vitest)
npm start # 开发运行
npm run icon # 重新生成图标
npm run dist # 打 NSIS 安装包

更新机制

- 版本来源:官方 npm 包 @deepseek-ai/dsh 的已发布版本与 dist-tags;latest 不等同于稳定版。更新中心区分 Alpha/RC/Release,并链接对应官方 GitHub 发布说明。仅有 Git 标签、未发布到 npm 的版本不能直接安装。
- 更新 Harness:先独立下载并校验 npm 包及可执行版本,再停止服务、切换并等待就绪。下载期间旧服务继续运行,运行任务可排队;下载阶段支持取消,进入切换阶段后不再中断。启动成功后清理旧的托管安装,不覆盖或卸载系统全局 npm 安装。
- 旧版本按需重装:不再创建升级快照或保留版本恢复入口。需要旧版时,从官方 npm 版本列表重新下载。继续使用当前 DSH_HOME,不回滚、不删除会话与配置;较低版本安装会提示兼容风险,重要数据请先自行备份。启动失败时可重试或重新安装,不自动以旧程序读取可能已迁移的数据。
- 清理范围与失败保护:仅清理桌面壳 harness-runtime/versions 中确认归属的非当前 UUID 安装目录,校验路径、数据目录和文件类型,不遍历链接。清理失败立即停止自动重试,页面提供明确确认后的重试。下载失败/取消清理本次暂存安装。0.5.0 已生成的数据快照、正在使用的 restored-data 和插件配置备份不会被当作安装文件自动删除;没有获得确认前不会清理这些用户数据。
- 桌面壳自身更新:与 Harness 更新分开。本版没有启用壳自动更新;需要配置所属发布渠道、签名与安装包校验后另行交付。
- 为什么不直接 git pull:官方源码运行还需要 Git、pnpm、依赖安装和完整构建;普通用户使用官方 README 推荐的 npm 发布包更稳定。Git 仓库只作为官方源码上游,不作为终端用户的运行目录。

用量与预估价格

- 数据来源:只从 Harness 本机会话日志提取时间、Provider、模型和 usage 元数据,不返回或展示提示词、回复正文、工具参数、工作目录或 API Key。
- 统计范围:默认查询今天,支持近 7 天、近 30 天和自定义起止日期,并可按 Provider/模型筛选。概览展示调用次数、实际总 Tokens、缓存命中率、涉及会话和预估费用。
- 统计明细:趋势图今天按小时、其他范围按日期展示四类 Token 与费用;最近调用后台分页,每页 10/20/50/100 条。会话管理可搜索本地名称/标签/项目并进入单会话费用详情;加载官方标题需要在设置中单独开启。不索引提示词或回答正文,也不虚构没有数据支持的 HTTP 成功率或响应耗时。
- 统计性能:日志读取、解压和汇总在独立工作线程执行。首次打开建立索引,后续仅处理新增或变化的日志;索引保存在应用数据目录的 usage-cache,重启后可复用。缓存仅包含用量元数据,不含对话正文、工具参数、工作目录或密钥;缓存损坏会自动重建。快速切换筛选条件会合并查询,相同趋势不会重复绘制。
- 图表实现:趋势图使用随安装包本地分发的 Apache ECharts 6.1.0,支持双轴、平滑曲线、悬浮明细、图例开关、滚轮缩放和窗口自适应,不依赖在线 CDN。第三方许可证随图表文件一同保留。
- 日志适配与完整性:兼容已核对的 V0–V4 日志及 V4 compact stream;同一目录只读取最高代际日志。流式/最终 usage 按同一调用替换,重试独立计数,分叉继承的历史不重复计数。损坏行、无法读取、未知格式会标记不完整。更新与诊断页可查看耗时、缓存占用和重建索引;重建不删除会话日志。
- 历史估价:按提供商、实际模型、调用时间及规则生效区间匹配,支持已核对的 V4、V4.1 Flash 与别名。默认保留历史价格;“按现价模拟”明确标注,不冒充历史账单。未知模型/提供商或缺少历史依据的区间标为待定价,不静默套用 Flash 单价。
- 官方分时价格:北京时间工作日 9:00–12:00、14:00–18:00 为高峰,其余时段、周末及已核对的 2026 法定节假日为空闲时段。未维护的年度会提示节假日资料不完整。
- 自定义价格:支持 Provider/完整模型名、生效起止时间、命中/未命中/输出“元/百万 Tokens”单价,拒绝重叠区间。也保留明确标注的全局自定义单价。按模型规则优先于全局规则,自定义规则不会被内置官方规则覆盖。
- 价格来源:DeepSeek API 官方定价、更新日志、9 月 10 日公告。规则版本 2026-09-24.1,核对日期 2026-09-24。本版随安装包更新规则,不在后台自动抓取并覆盖价格。
- 对比与导出:与紧邻的前一等长时段对比,展示具体对比时间;费用不完整时不显示误导性增长率。导出包含币种、时区、筛选、规则版本、自定义价格快照、完整性及更新时间;CSV 防公式注入。
- 重要说明:估算值不是官方账单。非 DeepSeek 模型、第三方代理加价、失败重试、分叉或导入会话都可能造成差异;实际费用以服务商账单为准。

性能回归:构建后可运行 node scripts/check-usage-performance.cjs,只读本机日志,对比首次建索引、重复查询、重启缓存以及工作线程响应性。electron scripts/smoke-usage-ui.cjs 使用独立隐藏窗口和合成日志验证分页、筛选合并及图表更新;增加 --packaged 可验证 release/win-unpacked/resources/app.asar 中的实际代码。

官方账户余额

- 查询来源:固定请求 DeepSeek 官方 GET https://api.deepseek.com/user/balance 接口,不支持第三方中转服务余额。
- 展示内容:账户是否可用,以及接口返回的人民币/美元总余额、充值余额和未过期赠送余额。
- 密钥来源:自动按 Harness 的优先级解析启动环境、$DSH_HOME/.credentials.yaml、项目 .env 和用户 .env 中现有的 DEEPSEEK_API_KEY,页面不再要求重复输入。
- 安全说明:API Key 只在主进程内解析并发送到 DeepSeek 官方接口,不会进入页面、日志或统计结果,桌面壳也不会额外保存副本。

此处“不保存副本”指余额功能。插件变更前的本机配置备份及 0.5.0 遗留的升级快照可能包含官方原有凭据,不属于可导出的桌面设置备份。0.5.1 不再创建升级快照。

插件、通知与权限边界

- 插件和会话管理通过实际测试的官方 0.1.7-rc.1 本机接口适配,不直接改写官方数据库。旧版没有相应接口时会显示能力错误。
- npm 搜索结果不等于官方精选或安全审核。安装前必须通过官方插件识别;安装/启停/卸载会弹出本机确认,不自动批准依赖构建脚本。配置项继续使用官方页面。
- 会话“回到 Harness”在没有稳定直达接口时复制会话 ID 并打开主窗口。仅提供归档/恢复,不提供永久删除。
- 通知默认关闭;开启后应用驻留期间每分钟检查预算、余额和官方任务事件,支持免打扰及去重。关闭程序后不继续监控,不依靠日志更新时间猜测完成状态。
- 桌面管理 IPC 仅允许本应用登记的本地窗口和页面使用;官方 Web 页面及插件拿不到桌面管理权限。
- 费用方案只保存预算及价格,不切换模型、提供商、Key、插件或数据目录。多环境方案、远程实例和签名壳更新不在本版中。

手动验收清单

- [ ] 未装 dsh → 引导页,状态显示正确,复制命令可用
- [ ] 未装 Node.js → 点击一键安装 LTS → 安装完成后无需重启电脑即可继续安装 dsh
- [ ] 装好 dsh 点「重新检测」→ 自动进入主窗
- [ ] 启动后检测官方 npm latest → 有新版时控制栏提示当前版与最新版
- [ ] 顶部「更新 Harness」→ npm 升级后版本号刷新,服务恢复
- [ ] 顶部「工作台」→ 六个分栏独立加载,默认今天,图表和明细正常显示
- [ ] 自定义时间范围 → 首尾日期均计入统计,最近模型调用可连续翻页且跨页不重复
- [ ] Harness 已配置官方 DeepSeek Key → 查询余额后总余额、充值余额、赠送余额和账户状态正确显示
- [ ] 选择指定 Harness 版本 → 安装完成后当前版本刷新且服务恢复
- [ ] 顶部「重启 Harness」→ 服务停止并重新启动,页面恢复
- [ ] 顶部「重启应用」→ 桌面壳与 Harness 均正常重新启动
- [ ] 主窗关闭 → 托盘驻留,dsh 进程仍在
- [ ] 托盘「退出」→ node/dsh 进程树被杀净
- [ ] 二次启动 → 聚焦已有窗口
- [ ] 安装包安装/卸载正常,桌面“DeepSeek Harness”快捷方式存在且可启动
- [ ] 全新主机安装、Windows 系统通知、真实第三方插件安装后业务可用性:必须在目标设备单独验收,不能用单元测试代替

常见问题

- 端口 3080 被占用:在“更新与诊断”检查监听 PID;选择可用端口并重启,不会结束其他应用的进程
- 提示 30000ms 内未就绪:这是 0.2.1 及更早版本等待时间过短造成的误判;升级桌面壳至 0.2.2 后会等待 120 秒并显示启动进度
- Node.js 一键安装不可用:该功能依赖 Windows 10/11 的 winget;请从 Microsoft Store 安装“应用安装程序”,或从 nodejs.org 手动安装 LTS
- 用量显示为 0:先检查时间/模型/会话筛选及完整性状态;无记录、未完成索引和日志不兼容不是同一情况。必要时重建统计索引,不能通过删除会话日志“修复”
- 余额无法查询:余额功能只支持 DeepSeek 官方 API Key。确认密钥有效、网络可访问 api.deepseek.com,并避免使用第三方中转服务的 Key
- 主窗空白:dsh 服务正常时按 Ctrl+Shift+I 打开开发者工具查看报错(开发模式)
- DSH_BIN/DSH_HOME:首次接入时可显式指定。完成桌面壳托管版本切换后,会优先使用持久化的托管安装/数据副本,不再跟随全局 npm 安装变化
预览分享卡片长什么样 ↓yanxi-lu/dsh-desktop
分享 · DeepSeek Harness Hub
yanxi-lu/dsh-desktop

DeepSeek Harness (dsh) 的 Windows 桌面套壳:轻量壳 + 首次引导 + 托盘驻留

这是你的仓库?认领条目

回到顶部