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

桌面客户端 liguobao/dsh-desktop

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

推荐插件:ds-harness-remote,支持从另一台电脑、手机或浏览器继续 Harness 会话,兼容官方…

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

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

自动兼容检查未通过:engines.node 要求 >=24,不满足 Node 22.19.0;要求 dsh 0.2.0-rc.1,而最新版为 0.2.1-rc.5;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add liguobao/dsh-desktop
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · security
装得上吗
实装验证未通过(dependency_conflict),装前请到仓库确认最近更新与 issue
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 33 天前
档位由哪些信号合成

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

验证判据与等级说明 →
⚠︎ 实装验证未通过(dependency_conflict · 2026/9/27) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

engines.node 要求 >=24,不满足 Node 22.19.0;要求 dsh 0.2.0-rc.1,而最新版为 0.2.1-rc.5;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

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

✓npm 包dsh-desktop @ 0.2.0
✗Node 引擎要求 >=24 · 基线 Node 22.19 不满足
✗dsh CLI 依赖要求 0.2.0-rc.1 · 最新 0.2.1-rc.5 不兼容
✓入口文件main/exports/bin 已声明

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

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

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

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

安装时即执行脚本可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 82 处,展示前 62 条)
  • 发起网络请求
    src/main.js:173
    fetchImpl: (url, options) => net.fetch(url, options),
  • 读取本地文件
    src/main.js:237
    const stats = statSync(target)
  • 发起网络请求
    src/main.js:373
    fetchImpl: (url, options) => net.fetch(url, options),
  • 读取本地文件
    src/main.js:461
    if (!existsSync(entry)) throw new Error(`DeepSeek Harness entry point is missing: ${entry}`)
  • 读取本地文件
    src/main.js:466
    const manifest = JSON.parse(readFileSync(require.resolve(`${packageName}/package.json`), 'utf8'))
  • 读取本地文件
    src/main.js:549
    if (!existsSync(entry)) throw new Error(`Bundled pnpm entry point is missing: ${entry}`)
  • 写入本地文件
    src/main.js:722
    mkdirSync(diagnosticDirectory, { recursive: true })
  • 写入本地文件
    src/main.js:1152
    mkdirSync(logsDirectory, { recursive: true })
  • 写入本地文件
    src/main.js:1154
    logStream = createWriteStream(logPath, { flags: 'a' })
  • 读取本地文件
    scripts/patch-node-pty-windows.mjs:232
    for (const entry of readdirSync(scope, { withFileTypes: true })) {
  • 读取本地文件
    scripts/patch-node-pty-windows.mjs:241
    if (!existsSync(lib)) continue
  • 读取本地文件
    scripts/patch-node-pty-windows.mjs:278
    if (!existsSync(target.path)) {
  • 读取本地文件
    scripts/patch-node-pty-windows.mjs:284
    const source = readFileSync(target.path, 'utf8')
  • 写入本地文件
    scripts/patch-node-pty-windows.mjs:316
    writeFileSync(target.path, result.source)
  • 读取本地文件
    src/auto-update.js:125
    await access(path)
  • 写入本地文件
    src/auto-update.js:163
    await mkdir(downloadsDirectory, { recursive: true })
  • 写入本地文件
    src/auto-update.js:194
    if (platform === 'linux') await chmod(destination, 0o755)
  • 删除本地文件
    src/auto-update.js:200
    if (!completed) await rm(destination, { force: true })
  • 写入本地文件
    src/desktop-integration.js:41
    mkdirSync(directory, { recursive: true })
  • 写入本地文件
    src/desktop-integration.js:43
    writeFileSync(join(directory, 'node.cmd'), `@echo off\r\nset ELECTRON_RUN_AS_NODE=1\r\n"${execPath}" %*\r\n`)
  • 写入本地文件
    src/desktop-integration.js:44
    writeFileSync(join(directory, 'pnpm.cmd'), `@echo off\r\nset ELECTRON_RUN_AS_NODE=1\r\n"${execPath}" "${pnpmEntry}" %*\r\n`)
  • 写入本地文件
    src/desktop-integration.js:47
    writeFileSync(join(directory, 'node'), `#!/bin/sh\nELECTRON_RUN_AS_NODE=1 exec ${executable} "$@"\n`)
  • 写入本地文件
    src/desktop-integration.js:48
    writeFileSync(join(directory, 'pnpm'), `#!/bin/sh\nELECTRON_RUN_AS_NODE=1 exec ${executable} ${quoteShellArgument(pnpmEntry)} "$@"\n`)
  • 写入本地文件
    src/desktop-integration.js:49
    chmodSync(join(directory, 'node'), 0o755)
  • 读取本地文件
    src/desktop-integration.js:85
    const manifest = JSON.parse(readFileSync(join(sourceDir, 'package.json'), 'utf8'))
  • 读取本地文件
    src/desktop-integration.js:111
    if (!statSync(canonical).isDirectory()) throw new Error('Workspace root is not a directory')
  • 读取本地文件
    src/desktop-integration.js:149
    statSync(target)
  • 读取本地文件
    src/desktop-integration.js:161
    accessSync(path, constants.X_OK)
  • 读取本地文件
    src/desktop-integration.js:162
    return statSync(path).isFile()
  • 读取本地文件
    src/desktop-integration.js:273
    const parsed = JSON.parse(readFileSync(path, 'utf8'))
  • 读取本地文件
    src/environment-repair.js:71
    const wasPresent = existsSync(dshHome)
  • 写入本地文件
    src/environment-repair.js:72
    mkdirSync(dshHome, { recursive: true })
  • 读取本地文件
    src/environment-repair.js:76
    if (!existsSync(directory)) missing.push(name)
  • 写入本地文件
    src/environment-repair.js:77
    mkdirSync(directory, { recursive: true })
  • 读取本地文件
    src/environment-repair.js:89
    const manifestExisted = existsSync(join(profileDir, 'package.json'))
  • 读取本地文件
    src/environment-repair.js:90
    const workspaceExisted = existsSync(join(profileDir, 'pnpm-workspace.yaml'))
  • 执行外部命令固定命令
    src/harness-server.js:77
    const killer = nodeSpawn('taskkill.exe', ['/pid', String(child.pid), '/t', '/f'], {
  • 读取本地文件
    src/harness-crash-log.js:30
    stats = statSync(path)
  • 读取本地文件
    src/harness-crash-log.js:57
    return statSync(path).size
  • 读取本地文件
    src/harness-crash-log.js:67
    entries = readdirSync(directory)
  • 读取本地文件
    src/harness-crash-log.js:77
    stats = statSync(path)
  • 读取本地文件
    src/harness-crash-log.js:102
    report = JSON.parse(readFileSync(path, 'utf8'))
  • 读取本地文件
    src/plugin-catalog.js:148
    return normalizePluginCatalog(JSON.parse(readFileSync(path, 'utf8')))
  • 读取本地文件
    src/plugin-catalog.js:155
    parsed = JSON.parse(readFileSync(path, 'utf8'))
  • 读取本地文件
    src/plugin-management.js:80
    return JSON.parse(readFileSync(path, 'utf8'))
  • 写入本地文件
    src/plugin-management.js:84
    mkdirSync(dirname(path), { recursive: true })
  • 写入本地文件
    src/plugin-management.js:86
    writeFileSync(temporary, `${JSON.stringify(value, undefined, 2)}\n`, { mode: 0o600 })
  • 写入本地文件
    src/plugin-management.js:87
    renameSync(temporary, path)
  • 写入本地文件
    src/plugin-management.js:92
    writeFileSync(temporary, value, { mode: 0o600 })
  • 写入本地文件
    src/plugin-management.js:93
    renameSync(temporary, path)
  • 读取本地文件
    src/plugin-management.js:189
    return declaresBuildScript || existsSync(join(profileDir, 'node_modules', ...packageName.split('/'), 'binding.gyp'))
  • 写入本地文件
    src/plugin-management.js:221
    mkdirSync(profileDir, { recursive: true })
  • 读取本地文件
    src/plugin-management.js:223
    if (!existsSync(manifestPath)) {
  • 读取本地文件
    src/plugin-management.js:232
    if (!existsSync(workspacePath)) writeTextAtomic(workspacePath, PROFILE_PNPM_WORKSPACE)
  • 读取本地文件
    src/plugin-management.js:241
    if (existsSync(join(candidate, 'package.json'))) return candidate
  • 读取本地文件
    src/plugin-management.js:266
    typeof path !== 'string' || path.trim() === '' || existsSync(join(directory, path)),
  • 删除本地文件递归
    src/plugin-management.js:336
    await rm(join(profileDir, 'node_modules', ...legacyPackageName.split('/')), { recursive: true, force: true })
  • 删除本地文件递归
    src/plugin-management.js:351
    await rm(targetPlugin, { recursive: true, force: true })
  • 发起网络请求
    scripts/generate-plugin-catalog.mjs:20
    const response = await fetch(url, { headers: { ...headers, accept }, redirect: 'error' })
  • 写入本地文件
    scripts/generate-plugin-catalog.mjs:36
    writeFileSync(outputPath, `${JSON.stringify(catalog, undefined, 2)}\n`)
  • 写入本地文件
    src/parent-watch.cjs:36
    mkdirSync(LOG_DIRECTORY, { recursive: true })
  • 写入本地文件
    src/parent-watch.cjs:51
    appendFileSync(LOG_PATH, `[${new Date().toISOString()}] ${body}\n`)
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

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

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis-plugin-group@deepseek-ai/dsh@deepseek-ai/dsh-anonymous-user-id@deepseek-ai/dsh-atomic-write@deepseek-ai/dsh-attachment@deepseek-ai/dsh-authorization@deepseek-ai/dsh-bash-local@deepseek-ai/dsh-brand@deepseek-ai/dsh-compaction@deepseek-ai/dsh-credentials@deepseek-ai/dsh-fs@deepseek-ai/dsh-hook-protocol
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 本地启动内置WebUI
  • 加载进加固窗口
  • 跨平台桌面封装

独立开源的 DeepSeek Harness 桌面封装,在本地启动内置的 @deepseek-ai/dsh Web UI,并加载进加固过的 Electron 窗口,支持 Linux、macOS 和 Windows。

README

由 DeepSeek 最新模型翻译生成
DSH Desktop 推荐插件:ds-harness-remote,支持从另一台电脑、手机或浏览器继续 Harness 会话,兼容官方 DeepSeek Harness 桌面版。安装方式见插件安装指南。 Android 客户端:下载 ds-harness-remote APK(v0.4.27) · 获取最新版本 本项目已归档,停止维护。 推荐使用官方 DeepSeek Harness,安装和使用方式请参考官方文档。本仓库及已有发布版本仅作为历史资料保留,后续不再提供更新或修复。 以下文档介绍的是已归档的社区桌面应用。 一个独立、开源的 DeepSeek Harness 桌面应用。它内置经过验证的 Harness 版本,并通过经过安全限制的 Electron 窗口在 Windows、macOS 和 Linux 本地运行。 当前内置 Harness 0.2.0-rc.1(标签 dsh-v0.2.0-rc.1)。本项目继续使用自己的 Electron 桌面方案,启动 Harness Web profile 并加载桌面适配插件,不使用上游的 Desktop 应用或 Desktop host。 内置的 dsh-file-viewer 插件已移除,当前版本不再提供文件预览功能。 DSH Desktop 是社区项目,并非 DeepSeek 官方产品。
展开完整文档(README 剩余 1 节)
DSH Desktop

推荐插件:ds-harness-remote,支持从另一台电脑、手机或浏览器继续 Harness 会话,兼容官方 DeepSeek Harness 桌面版。安装方式见插件安装指南。

Android 客户端:下载 ds-harness-remote APK(v0.4.27) · 获取最新版本

本项目已归档,停止维护。 推荐使用官方 DeepSeek Harness,安装和使用方式请参考官方文档。本仓库及已有发布版本仅作为历史资料保留,后续不再提供更新或修复。

以下文档介绍的是已归档的社区桌面应用。

一个独立、开源的 DeepSeek Harness 桌面应用。它内置经过验证的 Harness 版本,并通过经过安全限制的 Electron 窗口在 Windows、macOS 和 Linux 本地运行。

当前内置 Harness 0.2.0-rc.1(标签 dsh-v0.2.0-rc.1)。本项目继续使用自己的 Electron 桌面方案,启动 Harness Web profile 并加载桌面适配插件,不使用上游的 Desktop 应用或 Desktop host。

内置的 dsh-file-viewer 插件已移除,当前版本不再提供文件预览功能。

DSH Desktop 是社区项目,并非 DeepSeek 官方产品。DeepSeek Harness 目前仍处于开发者预览阶段,后续可能出现破坏兼容性的变更。

主要功能

- 安装包开箱即用,无需另外安装 Node.js、npm 或执行 npx。
- 内置版本匹配的 DeepSeek Harness 和 Remote 组件。
- 从另一台已授权的电脑、手机、平板或浏览器继续远程会话。
- 从 npm 或 GitHub 搜索和安装插件。
- 使用 VS Code、Cursor、VSCodium、Zed 或系统文件管理器打开工作区。
- Harness 服务仅监听本机,Electron 渲染进程受限,外部链接交给系统浏览器。
- 自动检查新版 DSH Desktop,并对下载的安装包进行 SHA-256 校验。

历史版本下载

已有版本仍可从 GitHub Releases 下载。这些社区构建已停止更新,新安装请使用官方 DeepSeek Harness。

中国大陆用户可使用 Quark Cloud Drive / 夸克网盘 下载。

| 平台 | 安装包 |
| Windows x64 安装版 | DSH-Desktop-vX.Y.Z-windows-x64-setup.exe |
| Windows x64 便携版 | DSH-Desktop-vX.Y.Z-windows-x64-portable.exe |
| macOS Apple Silicon | DSH-Desktop-vX.Y.Z-macos-arm64.dmg |
| macOS Intel | DSH-Desktop-vX.Y.Z-macos-x64.dmg |
| Linux x64 | DSH-Desktop-vX.Y.Z-linux-x64.AppImage |
| DSH Remote Android 客户端 | dsh-remote-android-vA.B.C.apk |

Android 客户端 APK 版本号跟随内置 Remote 组件。macOS 安装包已使用 Developer ID 签名并完成 Apple 公证。Windows 仍可能显示 SmartScreen 提示,请仅安装来自本仓库 Release 页面或上述镜像的文件。

运行 AppImage:

chmod +x DSH-Desktop-.AppImage
./DSH-Desktop-.AppImage

快速开始

1. 启动 DSH Desktop,等待 Harness 就绪。
2. 打开设置 → 模型,配置 DeepSeek API Key 或其他受支持的模型提供方。
3. 添加或选择工作区。
4. 创建会话并开始任务。

模型、工作区和会话的使用方式可参考上游 Harness Web UI 指南。

通过插件菜单搜索或管理插件。插件拥有与 Harness 相同的本机权限,请仅安装可信来源;修改插件后需重启 Harness。

Windows 下可通过帮助 → 开机自启动直接切换登录后自动启动,勾选表示已开启。

DSH Desktop 会检查 GitHub Releases。下载并校验对应平台的安装包后,可以直接打开安装包,应用会退出以便系统完成更新。DeepSeek Harness 及其他内置组件随 DSH Desktop 一起更新。

本地开发

需要 Node.js 24 或更高版本,以及 npm 10 或更高版本。

git clone https://github.com/liguobao/dsh-desktop.git
cd dsh-desktop
npm ci
npm start

npm test
npm run check
npm run dist:linux
npm run dist:mac
npm run dist:windows

安装包应在对应的目标操作系统上构建。推送匹配的 vX.Y.Z Tag 后,GitHub Actions 会构建全部支持的平台。

安全与许可

Harness 可以读取和修改所选工作区中的文件,并按授权执行命令。开始任务前,请检查当前工作区、模型提供方、已安装插件和权限提示。安全设计与漏洞报告方式见 SECURITY.md。

DSH Desktop 使用 MIT License,第三方声明见 NOTICE.md。
预览分享卡片长什么样 ↓liguobao/dsh-desktop
分享 · DeepSeek Harness Hub
liguobao/dsh-desktop

推荐插件:ds-harness-remote,支持从另一台电脑、手机或浏览器继续 Harness 会话,兼容官方…

回到顶部