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

桌面封装版 Easyhoov/deepseek-harness-desktop-windows

DeepSeek Harnessv0.2.0
Easyhoov3 天前有提交已提供中文文档扫描:高危

把 DeepSeek Harness 装进 Windows 桌面的应用:不用安装…

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

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

自动兼容检查未通过:要求 dsh 0.1.0-rc.6,而最新版为 0.2.1-rc.5。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Easyhoov/deepseek-harness-desktop-windows
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · security
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/10/24·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/05·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 3 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

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

验证判据与等级说明 →

可信度证据

安装兼容性检查需源码安装

要求 dsh 0.1.0-rc.6,而最新版为 0.2.1-rc.5

展开查看检查明细 ↓

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

✓npm 包dsh-desktop @ 0.2.0
✓Node 引擎未声明 engines.node
✗dsh CLI 依赖要求 0.1.0-rc.6 · 最新 0.2.1-rc.5 不兼容
✓入口文件main/exports/bin 已声明

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

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/11/2 23:03:25

🔴 安全扫描发现高危能力自动 · 静态分析源码
v2.7.0
🔴 扫描:高危尚无人工评估

静态扫描发现安装期即执行代码,或命令参数由运行时变量拼接(参数来源无法静态判定,从严处理)。

安装时即执行脚本可执行外部命令读写/删除本地文件写入剪贴板(不计风险)读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 108 处,展示前 102 条)
  • 执行外部命令来自配置/变量
    src/main.mjs:61
    const r = spawnSync(process.execPath, [dshBinPath(), ...rest], {
  • 写入本地文件
    src/main.mjs:78
    appendFileSync(join(app.getPath('userData'), 'dsh-desktop.log'), `${new Date().toISOString()} ${line}\n`);
  • 读取本地文件
    src/main.mjs:264
    const icon = readFile(join(app.getAppPath(), 'assets', 'icon.png')).then((data) => data.toString('base64'));
  • 写入本地文件
    src/main.mjs:330
    await writeFile(filePath, body);
  • 写入本地文件
    src/main.mjs:384
    void writeFile(capturePath, image.toPNG()).then(() => {
  • 读取本地文件
    src/main.mjs:724
    const data = await readFile(join(wwwDir, pathname));
  • 读取本地文件
    scripts/apply-official-patches.mjs:41
    source = readFileSync(patch.target, 'utf8');
  • 写入本地文件
    scripts/apply-official-patches.mjs:60
    writeFileSync(patch.target, source, 'utf8');
  • 读取本地文件
    src/boot.mjs:72
    const DESKTOP_PATCHES = parseYaml(readFileSync(DESKTOP_PATCH_PATH, 'utf8'));
  • 读取本地文件
    src/boot.mjs:123
    const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
  • 读取本地文件
    src/boot.mjs:147
    manifest = JSON.parse(readFileSync(join(profileDir, 'package.json'), 'utf8'));
  • 写入本地文件
    src/boot.mjs:167
    writeFileSync(join(profileDir, 'package.json'), `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
  • 读取本地文件
    src/boot.mjs:180
    manifest = JSON.parse(readFileSync(join(profileDir, 'package.json'), 'utf8'));
  • 读取本地文件
    src/boot.mjs:196
    const after = JSON.parse(readFileSync(join(profileDir, 'package.json'), 'utf8'));
  • 读取本地文件
    src/boot.mjs:213
    if (existsSync(join(vendorDir, 'node_modules', '.modules.yaml'))) return;
  • 写入本地文件
    src/boot.mjs:246
    writeFileSync(join(bootProfile.dir, PROFILE_ROOT_FILENAME), PROFILE_ROOT_CONFIG);
  • 读取本地文件
    src/site.mjs:38
    const s = statSync(source);
  • 读取本地文件
    src/site.mjs:40
    const d = statSync(dest);
  • 写入本地文件
    src/site.mjs:45
    mkdirSync(dirname(dest), { recursive: true });
  • 写入本地文件
    src/site.mjs:46
    copyFileSync(source, dest);
  • 读取本地文件
    src/site.mjs:73
    let html = readFileSync(distIndex, 'utf8');
  • 写入本地文件
    src/site.mjs:88
    writeFileSync(join(wwwDir, 'index.html'), html, 'utf8');
  • 读取本地文件
    src/home.mjs:24
    const parsed = JSON.parse(readFileSync(configPath(userData), 'utf8'));
  • 写入本地文件
    src/home.mjs:32
    mkdirSync(userData, { recursive: true });
  • 写入本地文件
    src/home.mjs:33
    writeFileSync(configPath(userData), `${JSON.stringify({ home }, null, 2)}\n`, 'utf8');
  • 执行外部命令固定命令
    src/home.mjs:44
    execFile(
  • 执行外部命令来自配置/变量
    src/npm-runner.mjs:34
    child = spawn(process.execPath, [npmCliPath(), ...args], {
  • 写入本地文件
    src/dsh-runner.mjs:36
    mkdirSync(dir, { recursive: true });
  • 写入本地文件
    src/dsh-runner.mjs:37
    writeFileSync(join(dir, 'pnpm.cmd'), `@echo off\r\n"${process.execPath}" "${pnpmPath()}" %*\r\n`, 'utf8');
  • 执行外部命令来自配置/变量
    src/dsh-runner.mjs:72
    child = spawn(process.execPath, [pnpmPath(), ...args], {
  • 读取本地文件
    src/dsh-runner.mjs:136
    return JSON.parse(readFileSync(join(profileDir, 'package.json'), 'utf8'));
  • 写入本地文件
    src/dsh-runner.mjs:143
    writeFileSync(join(profileDir, 'package.json'), `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
  • 读取本地文件
    src/dsh-runner.mjs:152
    const pkg = JSON.parse(readFileSync(join(bundleDir(profileDir, packageName), 'package.json'), 'utf8'));
  • 读取本地文件
    src/dsh-overlay.mjs:34
    const parsed = JSON.parse(readFileSync(overlayAnchor(userData), 'utf8'));
  • 读取本地文件
    src/dsh-overlay.mjs:43
    const parsed = JSON.parse(readFileSync(INSTALL_ANCHOR, 'utf8'));
  • 删除本地文件递归
    src/dsh-overlay.mjs:63
    rmSync(staging, { recursive: true, force: true });
  • 写入本地文件
    src/dsh-overlay.mjs:64
    mkdirSync(staging, { recursive: true });
  • 读取本地文件
    src/dsh-overlay.mjs:71
    if (!existsSync(stagingAnchor)) {
  • 删除本地文件递归
    src/dsh-overlay.mjs:73
    rmSync(staging, { recursive: true, force: true });
  • 删除本地文件递归
    src/dsh-overlay.mjs:77
    rmSync(backup, { recursive: true, force: true });
  • 读取本地文件
    src/dsh-overlay.mjs:78
    if (existsSync(overlay)) renameSync(overlay, backup);
  • 写入本地文件
    src/dsh-overlay.mjs:78
    if (existsSync(overlay)) renameSync(overlay, backup);
  • 写入本地文件
    src/dsh-overlay.mjs:79
    renameSync(staging, overlay);
  • 删除本地文件递归
    src/dsh-overlay.mjs:85
    rmSync(overlay, { recursive: true, force: true });
  • 读取密钥环境变量
    plugins/desktop-balance/lib/index.js:33
    const envKey = process.env.DEEPSEEK_API_KEY;
  • 读取本地文件
    plugins/desktop-balance/lib/index.js:36
    const text = readFileSync(join(resolveDshHome(), '.credentials.yaml'), 'utf8');
  • 发起网络请求
    plugins/desktop-balance/lib/index.js:103
    const response = await fetch(BALANCE_ENDPOINT, {
  • 读取本地文件
    plugins/desktop-file-changes/lib/index.js:143
    return readFileSync(target, 'utf8');
  • 写入本地文件
    plugins/desktop-file-changes/lib/index.js:158
    writeFileSync(op.path, current.slice(0, at) + op.oldText + current.slice(at + op.newText.length), 'utf8');
  • 写入本地文件
    plugins/desktop-file-changes/lib/index.js:166
    writeFileSync(op.path, current.slice(0, at) + current.slice(at + op.newText.length), 'utf8');
  • 写入本地文件
    plugins/desktop-file-changes/lib/index.js:173
    writeFileSync(op.path, previous, 'utf8');
  • 删除本地文件
    plugins/desktop-file-changes/lib/index.js:179
    unlinkSync(op.path);
  • 读取本地文件
    plugins/desktop-file-changes/lib/index.js:252
    if (existsSync(viewTarget)) {
  • 读取本地文件
    plugins/desktop-file-changes/lib/index.js:253
    record.viewed.set(norm(viewTarget), readFileSync(viewTarget, 'utf8'));
  • 写入剪贴板
    plugins/desktop-marketplace/lib/client.js:421
    void navigator.clipboard.writeText(text).then(() => { done = true; onDone && onDone(); }, () => {});
  • 读取本地文件
    plugins/desktop-marketplace/lib/index.js:37
    const onDisk = JSON.parse(readFileSync(cachePath(), 'utf8'));
  • 发起网络请求
    plugins/desktop-marketplace/lib/index.js:48
    const response = await fetch(CATALOG_URL, { signal: AbortSignal.timeout(15_000) });
  • 写入本地文件
    plugins/desktop-marketplace/lib/index.js:55
    writeFileSync(cachePath(), JSON.stringify(data), 'utf8');
  • 发起网络请求
    plugins/desktop-marketplace/lib/index.js:70
    const response = await fetch(url, { signal: AbortSignal.timeout(15_000) });
  • 请求外部主机registry.npmjs.org
    plugins/desktop-marketplace/lib/index.js:132
    const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(name)}`, {
  • 发起网络请求
    plugins/desktop-marketplace/lib/index.js:132
    const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(name)}`, {
  • 请求外部主机raw.githubusercontent.com
    plugins/desktop-marketplace/lib/index.js:177
    response = await fetch(`https://raw.githubusercontent.com/${fullName}/${branch}/${path}`, {
  • 发起网络请求
    plugins/desktop-marketplace/lib/index.js:177
    response = await fetch(`https://raw.githubusercontent.com/${fullName}/${branch}/${path}`, {
  • 请求外部主机api.github.com
    plugins/desktop-marketplace/lib/index.js:185
    response = await fetch(`https://api.github.com/repos/${fullName}/contents/${path}?ref=${encodeURIComponent(branch)}`, {
  • 发起网络请求
    plugins/desktop-marketplace/lib/index.js:185
    response = await fetch(`https://api.github.com/repos/${fullName}/contents/${path}?ref=${encodeURIComponent(branch)}`, {
  • 请求外部主机api.github.com
    plugins/desktop-marketplace/lib/index.js:246
    const response = await fetch(`https://api.github.com/repos/${fullName}/contents/${dir}?ref=${encodeURIComponent(branch)}`, {
  • 发起网络请求
    plugins/desktop-marketplace/lib/index.js:246
    const response = await fetch(`https://api.github.com/repos/${fullName}/contents/${dir}?ref=${encodeURIComponent(branch)}`, {
  • 请求外部主机registry.npmjs.org
    plugins/desktop-marketplace/lib/index.js:439
    const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(name)}`, { signal: AbortSignal.timeout(10_000) });
  • 读取本地文件
    plugins/desktop-marketplace/lib/index.js:472
    const manifest = JSON.parse(readFileSync(join(ui.profileDir, 'package.json'), 'utf8'));
  • 读取本地文件
    plugins/dsh-better-sidebar/lib/index.js:172
    level = await opendir(path);
  • 读取本地文件
    plugins/dsh-better-sidebar/lib/index.js:399
    const info = await stat(path);
  • 读取本地文件
    plugins/dsh-better-sidebar/lib/index.js:402
    const etag = `"${shortHash(await readFile(path))}"`;
  • 读取本地文件
    plugins/dsh-better-sidebar/lib/index.js:452
    const body = await readFile(join(chunkDir, `client-${name}.js`));
  • 执行外部命令固定命令
    plugins/dsh-better-sidebar/lib/index.js:544
    const child = spawn("git", full, {
  • 写入本地文件
    plugins/dsh-better-sidebar/lib/index.js:768
    for (const helper of candidates) if (existsSync(helper)) chmodSync(helper, 493);
  • 读取本地文件
    plugins/dsh-better-sidebar/lib/index.js:768
    for (const helper of candidates) if (existsSync(helper)) chmodSync(helper, 493);
  • 读取本地文件
    plugins/dsh-better-sidebar/lib/index.js:2088
    const info = await stat(path).catch((error) => {
  • 写入本地文件
    plugins/dsh-better-sidebar/lib/index.js:2160
    await mkdir(dirname(path), { recursive: true });
  • 写入本地文件
    plugins/dsh-better-sidebar/lib/index.js:2161
    await writeFile(tmp, content, "utf8");
  • 写入本地文件
    plugins/dsh-better-sidebar/lib/index.js:2162
    await rename(tmp, path);
  • 删除本地文件
    plugins/dsh-better-sidebar/lib/index.js:2164
    await rm(tmp, { force: true }).catch(() => {});
  • 发起网络请求
    plugins/dsh-better-sidebar/lib/index.js:2277
    let response = await fetch(parsed, {
  • 发起网络请求
    plugins/dsh-better-sidebar/lib/index.js:2282
    if (response.status === 405 || response.status === 501) response = await fetch(parsed, {
  • 读取密钥环境变量
    scripts/build-catalog.mjs:22
    ...(process.env.GITHUB_TOKEN ? { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` } : {}),
  • 发起网络请求
    scripts/build-catalog.mjs:29
    const response = await fetch(url, { headers, signal: AbortSignal.timeout(20_000) });
  • 写入本地文件
    scripts/build-catalog.mjs:95
    mkdirSync(dirname(OUT), { recursive: true });
  • 写入本地文件
    scripts/build-catalog.mjs:96
    writeFileSync(OUT, `${JSON.stringify(catalog, null, 1)}\n`, 'utf8');
  • 读取密钥环境变量
    scripts/fetch-dsh-docs.mjs:14
    if (process.env.DSH_GITHUB_TOKEN) return process.env.DSH_GITHUB_TOKEN;
  • 执行外部命令固定命令
    scripts/fetch-dsh-docs.mjs:16
    const out = spawnSync('git', ['credential', 'fill'], { input: 'host=github.com\nprotocol=https\n', encoding: 'utf8' });
  • 请求外部主机api.github.com
    scripts/fetch-dsh-docs.mjs:36
    const r = await fetch(`https://api.github.com/repos/${REPO}/contents/${path}`, { headers, signal: AbortSignal.timeout(25000) });
  • 发起网络请求
    scripts/fetch-dsh-docs.mjs:36
    const r = await fetch(`https://api.github.com/repos/${REPO}/contents/${path}`, { headers, signal: AbortSignal.timeout(25000) });
  • 请求外部主机api.github.com
    scripts/fetch-dsh-docs.mjs:49
    const r = await fetch(`https://api.github.com/repos/${REPO}/contents/${path}`, { headers: h, signal: AbortSignal.timeout(25000) });
  • 发起网络请求
    scripts/fetch-dsh-docs.mjs:49
    const r = await fetch(`https://api.github.com/repos/${REPO}/contents/${path}`, { headers: h, signal: AbortSignal.timeout(25000) });
  • 写入本地文件
    scripts/fetch-dsh-docs.mjs:77
    mkdirSync(dirname(outPath), { recursive: true });
  • 写入本地文件
    scripts/fetch-dsh-docs.mjs:78
    writeFileSync(outPath, text, 'utf8');
  • 读取本地文件
    scripts/inspect-log.mjs:9
    const compressed = readFileSync(file);
  • 读取本地文件
    scripts/rasterize.mjs:25
    let svg = readFileSync(svgPath, 'utf8');
  • 写入本地文件
    scripts/rasterize.mjs:41
    writeFileSync(outPath, image.toPNG());
  • 读取本地文件
    scripts/repair-log.mjs:29
    const compressed = readFileSync(file);
  • 写入本地文件
    scripts/repair-log.mjs:105
    copyFileSync(file, `${file}.bak`);
  • 写入本地文件
    scripts/repair-log.mjs:106
    writeFileSync(file, recompressed);
  • 写入本地文件
    scripts/repair-log.mjs:109
    writeFileSync(`${file}.repaired`, recompressed);
扫描于 2026/11/5(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库
涉及外部主机:registry.npmjs.org、raw.githubusercontent.com、api.github.com

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

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh@deepseek-ai/cordis-plugin-group@deepseek-ai/dsh-anonymous-user-id@deepseek-ai/dsh-atomic-write@deepseek-ai/dsh-bash-local@deepseek-ai/dsh-code-runtime@deepseek-ai/dsh-compaction@deepseek-ai/dsh-fs@deepseek-ai/dsh-invariants@deepseek-ai/dsh-output-retention@deepseek-ai/dsh-sandbox@deepseek-ai/dsh-scope
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

界面预览

1 张 · 点击查看大图

功能亮点

  • 双击启动免装环境
  • 进程内集成官方DSH
  • 零端口IPC传输
展开完整介绍(147 字)↓

把 DeepSeek Harness 装进 Windows 桌面的应用:不用装 Node.js、不用敲命令,双击启动即用。进程内集成官方 DSH、零端口 IPC 传输;内置侧边栏工作台(文件 / 终端 / Git / 浏览器)与社区插件商店,托盘常驻、一键更新。非官方,仅供开源 DSH 封装。

README

由 DeepSeek 最新模型翻译生成
DeepSeek Harness Desktop(Windows) GitHub stars GitHub release License: MIT Platform Topics 把 DeepSeek Harness 装进 Windows 桌面的应用:不用安装 Node.js、不用敲命令,双击启动即用,官方 DSH 的 Web 界面与插件生态完整保留。 ⚠️ 非官方:本项目与 DeepSeek 无任何隶属或背书关系,仅对开源发行版 @deepseek-ai/dsh 做原样封装。鲸鱼标识取自官方 DeepSeek Harness favicon,仅用于视觉一致性,商标归 DeepSeek 所有。 中文 · English 为什么又一个桌面封装? 多数社区桌面版是拉起 dsh web 子进程、再把浏览器窗口指到 127.0.0.1:3080。本项目的做法不同:整份官方组合跑在 Electron 主进程内部(进程内集成),前端从本地加载,全部 /api 请求与事件走 IPC 桥——零端口、零子进程、无本地 HTTP 服务。会话、目标、后台任务、插件都是应用内的一等状态:关掉窗口(驻留托盘)它们照常运行。
展开完整文档(README 剩余 1 节)
DeepSeek Harness Desktop(Windows)

GitHub stars
GitHub release
License: MIT
Platform
Topics

把 DeepSeek Harness 装进 Windows 桌面的应用:不用安装 Node.js、不用敲命令,双击启动即用,官方 DSH 的 Web 界面与插件生态完整保留。

⚠️ 非官方:本项目与 DeepSeek 无任何隶属或背书关系,仅对开源发行版 @deepseek-ai/dsh 做原样封装。鲸鱼标识取自官方 DeepSeek Harness favicon,仅用于视觉一致性,商标归 DeepSeek 所有。

中文 · English

为什么又一个桌面封装?

多数社区桌面版是拉起 dsh web 子进程、再把浏览器窗口指到 127.0.0.1:3080。本项目的做法不同:整份官方组合跑在 Electron 主进程内部(进程内集成),前端从本地加载,全部 /api 请求与事件走 IPC 桥——零端口、零子进程、无本地 HTTP 服务。会话、目标、后台任务、插件都是应用内的一等状态:关掉窗口(驻留托盘)它们照常运行。

DeepSeek Harness Desktop

核心特性

| 🧬 进程内集成 | 用 dsh-app-boot 在 Electron 主进程内启动官方 web profile;无子进程、无端口、无 HTTP 服务器 |
| 🔌 IPC 传输 | preload 的 fetch / WebSocket shim 把所有 RPC 走 Electron IPC,官方客户端插件原样运行 |
| 🪟 无边框玻璃界面 | 自绘 36px 玻璃标题栏(鲸鱼图标、版本徽章、⋯ 菜单、最小化/最大化/关闭)、Win11 圆角、启动画面,主题跟随 DSH 自身 CSS 变量 |
| 🛍️ 插件商店 | 内置社区插件商店(ZASENJC):/store 或 设置 → 插件 → 插件商店 浏览、搜索、一键安装/卸载;安装走官方 dsh plugin add(npm / GitHub / monorepo 子目录 / tarball),自带 pnpm,无黑框、有实时进度,装完重启生效 |
| 💰 会话余额 | 输入框下方实时显示余额与本轮成本(随用量滚动),点击直达充值页 |
| 📝 文件改动 + 一键还原 | 会话标题栏"文件"按钮列出 Agent 的每次写入/编辑(带 +/− 行数),可逐个或全部还原——硬围栏保护(仅会话工作目录、拒绝危险扩展名、片段校验) |
| 🗂️ 侧边栏工作台 | 内置 better-sidebar:文件资源管理器 / 编辑器与预览 / 真实终端 / Git 面板 / 沙箱浏览器 / 子代理拓扑,按会话隔离;位置兼容模式默认开启——侧边栏按钮与 Tab 栏整体下移,避开顶部标题栏遮挡(下移距离可在 设置 → 侧边卡片 调整) |
| ⬆️ 双通道更新 | 通道一:electron-updater 从 GitHub Releases 自更新(实时下载进度 + 可见安装器);通道二:⋯ 菜单"更新 dsh"可安装更新的官方 @deepseek-ai/dsh 并整体切换,一键回退内置版 |
| 🪟 托盘常驻 | 关闭窗口不退出,会话继续;托盘菜单显示/隐藏窗口、检查更新、退出 |
| 🔔 原生通知 | 由宿主事件流驱动:审批、提问、Agent 报错、动态插件运行请求;窗口在后台时才通知回复完成 |
| 🏠 首启数据目录向导 | 选择独立数据目录或复用命令行 dsh 的 ~/.dsh;共享目录被 dsh web 占用时给出冲突警告 |
| 🛡️ 崩溃恢复 | 渲染进程崩溃自动重建窗口并重载界面,宿主状态不丢(每分钟 3 次则放弃) |
| 📦 会话导出 | 进程内执行、任务栏进度、原生保存对话框、完成通知 |
| 🐋 官方鲸鱼图标 | DeepSeek Harness favicon(黑鲸)栅格化为 PNG,随应用分发 |
| 🧰 日志修复工具 | scripts/repair-log.mjs 修复上游"中断刷盘乱序"导致的会话日志损坏 |

插件生态

DeepSeek Harness 基于 Cordis,采用 "一切皆插件" 架构:模型适配器、工具、会话、Agent 循环等核心能力都以插件参与运行,外部插件通过 profile 与 bundle 接入。

本项目的桌面功能本身就是标准 DSH 插件(bundle + 声明式补丁),与 profile 组合,dsh web 同样可以识别。命令行安装(与 dsh web 共用同一个 profile):

dsh plugin --profile web add
dsh plugin --profile web add github:

下载

| 产物 | 说明 |
| DeepSeek-Harness-Desktop-Setup-.exe | NSIS 安装包(可选安装目录),自动更新使用 |
| DeepSeek-Harness-Desktop-Portable-.exe | 便携版 |
| latest.yml | 自动更新元数据,随每个 Release 发布 |

最新构建:GitHub Releases(Windows 10/11,x64,GitHub Actions 在每个 v* 标签构建)。未做代码签名,SmartScreen 会提示;签名已通过 CSC_LINK / CSC_KEY_PASSWORD 预留。

快速开始

1. 启动应用,首次运行选择数据目录(默认独立,或复用 ~/.dsh)
2. 打开 设置 → 模型,填入 DeepSeek API Key(或自定义 OpenAI 兼容端点),即时生效无需重启
3. 选择工作目录(原生系统对话框)并开始会话

与官方 Quickstart 流程一致——桌面版启动的就是 CLI 用的同一套 web profile 组合,模型配置、工作区、审批、插件开发行为完全一致。

一处刻意差异:CLI 默认用调用目录作为工作目录;桌面版从用户主目录启动(可用 DSH_DESKTOP_CWD 覆盖),工作区在界面中选择。

从源码构建

需要 Node.js ≥ 20:

npm ci
npm start # 开发运行
npm run dist # 构建安装包(输出到 release/)

更多

- 更新日志 · English
- 问题与建议:在 Issues 反馈
预览分享卡片长什么样 ↓Easyhoov/deepseek-harness-desktop-windows
分享 · DeepSeek Harness Hub
Easyhoov/deepseek-harness-desktop-windows

把 DeepSeek Harness 装进 Windows 桌面的应用:不用安装…

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部