桌面客户端 hx876298682-tech/deepseek-harness-desktop
DeepSeek Harness把 Web 界面打包成开箱即用的桌面应用
25.9/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/11 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add hx876298682-tech/deepseek-harness-desktop该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:待复验
是什么
dsh 原生插件 · ui
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 74 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 117 处,展示前 100 条)
- 写入本地文件main.js:48
try { appendFileSync(logPath, line + String.fromCharCode(10)); } catch { } - 发起网络请求main.js:53
const response = await fetch(DSH_PLUGIN_TOPIC_API, { headers: { Accept: "application/vnd.github+json", "User-Agent": "deepseek-harness-desktop" } }); - 写入本地文件main.js:83
try { appendFileSync(logPath, "--- launch ---" + String.fromCharCode(10)); } catch { } - 读取本地文件main.js:118
if (existsSync(managedBin)) process.env.DSH_BIN = managedBin; - 发起网络请求main.js:145
const response = await fetch("http://127.0.0.1:" + DSH_WEB_DEFAULT_PORT + "/", { - 读取本地文件main.js:185
if (npmPath && existsSync(npmPath)) return { nodePath: systemNode, npmPath, managed: false, version: systemVersion }; - 读取本地文件main.js:191
if (!npmPath || !existsSync(npmPath)) throw new Error("托管 Node.js 的 npm 不可用"); - 读取本地文件main.js:195
if (!existsSync(managedBin)) throw new Error("dsh 安装完成但找不到 CLI 入口"); - 执行外部命令来自配置/变量main.js:264
child = spawn(cmd, args, { detached: true, cwd: process.env.DSH_DESKTOP_SERVER_CWD || homedir(), env: process.env, stdio: ["ignore", "pipe", "pipe"] } - 读取本地文件main.js:298
if (process.env.DSH_DESKTOP_NPM && existsSync(process.env.DSH_DESKTOP_NPM)) return process.env.DSH_DESKTOP_NPM; - 读取本地文件main.js:299
if (info && info.npmPath && existsSync(info.npmPath)) return info.npmPath; - 执行外部命令来自配置/变量main.js:313
const commandChild = spawn(command, args, { - 发起网络请求main.js:344
const response = await fetch(url, { - 请求外部主机github.commain.js:360
const response = await fetch("https://github.com/" + DESKTOP_REPOSITORY + "/releases/latest", { - 发起网络请求main.js:360
const response = await fetch("https://github.com/" + DESKTOP_REPOSITORY + "/releases/latest", { - 发起网络请求main.js:434
const response = await fetch(asset.browser_download_url, { - 写入本地文件main.js:439
await mkdir(updateDir, { recursive: true }); - 写入本地文件main.js:449
await pipeline(nodeStream, createWriteStream(assetPath)); - 执行外部命令来自配置/变量main.js:454
const helperChild = spawn(helper.command, helper.args, { detached: true, stdio: "ignore", windowsHide: true }); - 执行外部命令固定命令main.js:557
const taskkill = spawn("taskkill", ["/pid", String(pid), "/T", "/F"], { stdio: "ignore", windowsHide: true }); - 读取本地文件resolve-dsh.js:39
for (const v of readdirSync(join(nvmRoot, "versions", "node"))) dirs.add(join(nvmRoot, "versions", "node", v, "bin")); - 读取本地文件resolve-dsh.js:43
for (const v of readdirSync("/usr/local/n/versions/node")) dirs.add(join("/usr/local/n/versions/node", v, "bin")); - 读取本地文件resolve-dsh.js:54
try { const st = statSync(p); if (st.isFile() || st.isSymbolicLink()) return p; } catch { } - 读取本地文件resolve-dsh.js:70
for (const dir of readdirSync(root)) { - 读取本地文件resolve-dsh.js:73
const st = statSync(p); - 读取本地文件resolve-dsh.js:86
if (!existsSync(npm)) return null; - 执行外部命令来自配置/变量resolve-dsh.js:87
const r = spawnSync(npm, ["root", "-g"], { encoding: "utf8", timeout: 15000 }); - 执行外部命令来自配置/变量resolve-dsh.js:108
const r = spawnSync(nodePath, [binJs, "--version"], { encoding: "utf8", timeout: 15000 }); - 执行外部命令来自配置/变量runtime.js:54
const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"], shell: process.platform === "win32" }); - 执行外部命令来自配置/变量runtime.js:83
const result = spawnSync(nodePath, ["--version"], { encoding: "utf8", timeout: 15000 }); - 请求外部主机nodejs.orgruntime.js:89
const response = await fetch(`https://nodejs.org/dist/index.json`, { - 发起网络请求runtime.js:89
const response = await fetch(`https://nodejs.org/dist/index.json`, { - 发起网络请求runtime.js:106
const response = await fetch(url, { - 写入本地文件runtime.js:119
await pipeline(stream, createWriteStream(destination)); - 发起网络请求runtime.js:124
const response = await fetch(url, { headers: { Accept: "text/plain", "User-Agent": "deepseek-harness-desktop" } }); - 读取本地文件runtime.js:135
const stream = createReadStream(path); - 写入本地文件runtime.js:143
await mkdir(destination, { recursive: true }); - 读取本地文件runtime.js:157
const entries = readdirSync(directory); - 读取本地文件runtime.js:159
try { return statSync(entry).isDirectory() && existsSync(runtimeNodePath(entry)); } catch { return false; } - 读取本地文件runtime.js:159
try { return statSync(entry).isDirectory() && existsSync(runtimeNodePath(entry)); } catch { return false; } - 写入本地文件runtime.js:167
await mkdir(runtimeBase, { recursive: true }); - 读取本地文件runtime.js:170
if (existsSync(existingNode)) return { nodePath: existingNode, npmPath: runtimeNpmPath(marker), managed: true }; - 删除本地文件递归runtime.js:187
await rm(marker, { recursive: true, force: true }); - 写入本地文件runtime.js:188
await rename(root, marker); - 删除本地文件递归runtime.js:190
await rm(work, { recursive: true, force: true }); - 读取本地文件runtime.js:192
if (!existsSync(existingNode)) throw new Error("Node.js 安装完成但找不到 node 可执行文件"); - 读取本地文件image-input-defaults.js:69
if (!existsSync(path)) return { path, changed: false, providers: [] }; - 读取本地文件image-input-defaults.js:70
const source = readFileSync(path, "utf8"); - 写入本地文件image-input-defaults.js:73
writeFileSync(path, result.source, "utf8"); - 写入本地文件image-input-defaults.js:84
mkdirSync(home, { recursive: true }); - 读取本地文件usage-stats-plugin.js:35
const pkg = JSON.parse(await readFile(join(bundledPluginRoot(), "package.json"), "utf8")); - 读取本地文件usage-stats-plugin.js:44
return await readFile(path, "utf8"); - 读取本地文件usage-stats-plugin.js:103
const pkg = JSON.parse(await readFile(join(target, "package.json"), "utf8")); - 读取本地文件usage-stats-plugin.js:109
const patch = await readFile(patchPath, "utf8"); - 读取本地文件usage-stats-plugin.js:123
const sourcePackage = JSON.parse(await readFile(join(sourceRoot, "package.json"), "utf8")); - 写入本地文件usage-stats-plugin.js:128
await mkdir(target, { recursive: true }); - 写入本地文件usage-stats-plugin.js:132
await mkdir(join(target, "scripts"), { recursive: true }); - 写入本地文件usage-stats-plugin.js:135
await mkdir(dirname(patchPath), { recursive: true }); - 写入本地文件usage-stats-plugin.js:140
await writeFile(patchPath, enabledPatch, "utf8"); - 写入本地文件_extracted/main.js:39
try { appendFileSync(logPath, line + String.fromCharCode(10)); } catch { } - 读取本地文件_extracted/main.js:60
if (existsSync(managedBin)) process.env.DSH_BIN = managedBin; - 写入本地文件_extracted/main.js:62
try { appendFileSync(logPath, "--- launch ---" + String.fromCharCode(10)); } catch { } - 执行外部命令来自配置/变量_extracted/main.js:127
child = spawn(cmd, args, { detached: true, cwd: process.env.DSH_DESKTOP_SERVER_CWD || homedir(), env: process.env, stdio: ["ignore", "pipe", "pipe"] } - 读取本地文件_extracted/main.js:157
if (process.env.DSH_DESKTOP_NPM && existsSync(process.env.DSH_DESKTOP_NPM)) return process.env.DSH_DESKTOP_NPM; - 读取本地文件_extracted/main.js:158
if (info && info.npmPath && existsSync(info.npmPath)) return info.npmPath; - 读取本地文件_extracted/main.js:161
if (existsSync(sibling)) return sibling; - 读取本地文件_extracted/main.js:165
if (existsSync(candidate)) return candidate; - 执行外部命令来自配置/变量_extracted/main.js:172
const commandChild = spawn(command, args, { - 发起网络请求_extracted/main.js:202
const response = await fetch(url, { - 发起网络请求_extracted/main.js:262
const response = await fetch(asset.browser_download_url, { - 写入本地文件_extracted/main.js:267
await mkdir(updateDir, { recursive: true }); - 写入本地文件_extracted/main.js:277
await pipeline(nodeStream, createWriteStream(assetPath)); - 读取本地文件_extracted/main.js:298
if (!existsSync(managedBin)) throw new Error("安装完成后找不到新的 dsh CLI"); - 读取本地文件_extracted/resolve-dsh.js:36
for (const v of readdirSync(join(nvmRoot, "versions", "node"))) dirs.add(join(nvmRoot, "versions", "node", v, "bin")); - 读取本地文件_extracted/resolve-dsh.js:40
for (const v of readdirSync("/usr/local/n/versions/node")) dirs.add(join("/usr/local/n/versions/node", v, "bin")); - 读取本地文件_extracted/resolve-dsh.js:48
try { const st = statSync(p); if (st.isFile() || st.isSymbolicLink()) return p; } catch { } - 读取本地文件_extracted/resolve-dsh.js:63
for (const dir of readdirSync(root)) { - 读取本地文件_extracted/resolve-dsh.js:66
const st = statSync(p); - 读取本地文件_extracted/resolve-dsh.js:79
if (!existsSync(npm)) return null; - 执行外部命令来自配置/变量_extracted/resolve-dsh.js:80
const r = spawnSync(npm, ["root", "-g"], { encoding: "utf8", timeout: 15000 }); - 执行外部命令来自配置/变量_extracted/resolve-dsh.js:101
const r = spawnSync(nodePath, [binJs, "--version"], { encoding: "utf8", timeout: 15000 }); - 读取本地文件plugins/dsh-usage-stats/lib/index.js:211
const raw = await readFile(cachePath(), "utf8"); - 写入本地文件plugins/dsh-usage-stats/lib/index.js:233
await mkdir(dirname(path), { recursive: true }); - 写入本地文件plugins/dsh-usage-stats/lib/index.js:237
await writeFile(tmp, JSON.stringify(serialized), "utf8"); - 写入本地文件plugins/dsh-usage-stats/lib/index.js:238
await rename(tmp, path); - 写入本地文件usage-stats-plugin.test.js:18
await mkdir(join(root, "lib"), { recursive: true }); - 写入本地文件usage-stats-plugin.test.js:19
await mkdir(join(root, "scripts"), { recursive: true }); - 写入本地文件usage-stats-plugin.test.js:20
await writeFile(join(root, "package.json"), JSON.stringify(FAKE_PACKAGE)); - 写入本地文件usage-stats-plugin.test.js:21
await writeFile(join(root, "lib", "index.js"), "export default 1;\n"); - 写入本地文件usage-stats-plugin.test.js:22
await writeFile(join(root, "scripts", "install.mjs"), "// installer\n"); - 写入本地文件usage-stats-plugin.test.js:23
await writeFile(join(root, "cordis.patch.yml"), "- insert:\n - id: usage-stats\n name: dsh-usage-stats\n"); - 读取本地文件usage-stats-plugin.test.js:43
const installed = JSON.parse(await readFile(join(home, "profiles", "node_modules", "dsh-usage-stats", "package.json"), "utf8")); - 读取本地文件usage-stats-plugin.test.js:46
const patch = await readFile(join(home, "profiles", "web", "cordis.patch.yml"), "utf8"); - 删除本地文件递归usage-stats-plugin.test.js:55
await rm(source, { recursive: true, force: true }); - 删除本地文件递归usage-stats-plugin.test.js:56
await rm(home, { recursive: true, force: true }); - 读取本地文件usage-stats-plugin.test.js:65
const first = await readFile(join(home, "profiles", "web", "cordis.patch.yml"), "utf8"); - 读取本地文件usage-stats-plugin.test.js:67
const second = await readFile(join(home, "profiles", "web", "cordis.patch.yml"), "utf8"); - 删除本地文件递归usage-stats-plugin.test.js:72
await rm(source, { recursive: true, force: true }); - 删除本地文件递归usage-stats-plugin.test.js:73
await rm(home, { recursive: true, force: true }); - 删除本地文件递归usage-stats-plugin.test.js:101
await rm(home, { recursive: true, force: true });
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库
涉及外部主机:github.com、nodejs.org
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 打包Web界面为桌面应用
- Electron桌面外壳
README
由 DeepSeek 最新模型翻译生成DeepSeek Harness Desktop
把 DeepSeek Harness 变成一个更方便使用的桌面应用。
当前版本:v0.1.8
支持 macOS、Windows 和 Linux。
实际界面
主界面
DeepSeek Harness Desktop 主界面
设置与更新
DeepSeek Harness Desktop 设置与更新页面
它能做什么?
- 像普通桌面软件一样打开 DeepSeek Harness
- 第一次打开时,自动准备 Node.js 和 DeepSeek Harness
- 不需要用户提前安装 DeepSeek Harness
- 支持在设置里更新 Harness 和桌面应用
- 在设置 → 插件中增加“论坛插件”,可以浏览 GitHub 上的 DSH 插件
- 支持复制、粘贴和常用快捷键
- 支持发送图片
- DeepSeek 模型保持官方的纯文本限制
- 其他模型默认尝试发送图片,如果模型不支持,会显示服务商返回的错误
- 支持发送文本和代码文件
- 点击输入框左下角的回形针按钮选择文件
- 也可以把文件直接拖到输入框
- 支持 TXT、Markdown、JSON、CSV 和常见代码文件
- 单个文件最大 1 MB,一次最多 5 个文件
- PDF、Word、Excel 等文件暂时不支持
展开完整文档(README 剩余 1 节)
DeepSeek Harness Desktop 把 DeepSeek Harness 变成一个更方便使用的桌面应用。 当前版本:v0.1.8 支持 macOS、Windows 和 Linux。 实际界面 主界面 DeepSeek Harness Desktop 主界面 设置与更新 DeepSeek Harness Desktop 设置与更新页面 它能做什么? - 像普通桌面软件一样打开 DeepSeek Harness - 第一次打开时,自动准备 Node.js 和 DeepSeek Harness - 不需要用户提前安装 DeepSeek Harness - 支持在设置里更新 Harness 和桌面应用 - 在设置 → 插件中增加“论坛插件”,可以浏览 GitHub 上的 DSH 插件 - 支持复制、粘贴和常用快捷键 - 支持发送图片 - DeepSeek 模型保持官方的纯文本限制 - 其他模型默认尝试发送图片,如果模型不支持,会显示服务商返回的错误 - 支持发送文本和代码文件 - 点击输入框左下角的回形针按钮选择文件 - 也可以把文件直接拖到输入框 - 支持 TXT、Markdown、JSON、CSV 和常见代码文件 - 单个文件最大 1 MB,一次最多 5 个文件 - PDF、Word、Excel 等文件暂时不支持 - 支持 macOS、Windows 和 Linux 内置插件:用量统计(dsh-usage-stats) 应用自带 dsh-usage-stats 插件(多供应商余额、订阅额度与 Token 用量分析)。每次启动应用时,它会自动把插件安装/同步到当前 dsh 环境(DSH_HOME 或 ~/.dsh)的 profiles/web,并幂等启用: - 设置 → 插件 → “用量统计”标签页可查看安装状态,手动点击“安装 / 更新”可重新同步。 - 安装后重启 dsh web 并在浏览器硬刷新,侧边栏底部会出现“用量/余额”(Usage/Balance)入口。 - 插件源码位于 plugins/dsh-usage-stats,安装逻辑见 usage-stats-plugin.js。 安装使用 普通用户 从 Releases 下载对应系统的安装包: - macOS Apple Silicon:下载 arm64.dmg - macOS Intel:下载 x64.dmg - Windows:下载 .exe - Linux:下载 .AppImage 安装后直接打开即可。 第一次打开时需要联网,软件会自动下载运行所需的文件。以后打开不需要重复下载。 macOS 提示 目前安装包没有 Apple 官方签名。如果系统提示无法打开: 1. 右键点击应用 2. 选择“打开” 3. 再点击“打开”确认 更新软件 打开应用左下角的“设置”,进入“更新”: - DeepSeek Harness CLI:更新官方 Harness - DeepSeek Harness Desktop:更新桌面应用 桌面应用更新会下载新版本,自动退出、替换旧版本并重新打开应用。若应用正从 DMG 挂载盘运行,请先将它拖入 Applications 文件夹;没有写入权限时会提示你手动安装。 从源码运行 需要安装 Node.js 和 npm: npm ci npm start 运行测试: npm run test:update-utils 构建安装包: macOS Apple Silicon npm run dist:mac-arm64 macOS Intel npm run dist:mac-x64 Linux npm run dist:linux Windows npm run dist:win 常见问题 需要提前安装 DeepSeek Harness 吗? 不需要。桌面应用第一次启动时会自动准备 Node.js,并自动安装官方 Harness。 第一次打开失败怎么办? 请确认网络正常,然后重新打开应用。如果仍然失败,可以查看应用日志: dsh-desktop.log 关闭桌面应用时,dsh web 会一起关闭吗? 会。桌面应用启动的 dsh web 是它的子进程,关闭应用时会先给它发 SIGTERM 等待优雅退出(最长约 5 秒),超时再强制结束,不会留下后台孤儿进程。 只有一种情况例外:如果 dsh web 是在打开桌面应用之前就已经由其他方式(例如终端)启动的,桌面应用只是复用它,关闭时不会动它。 如何发送文件? 点击输入框左下角的回形针按钮,选择文本或代码文件。也可以直接把文件拖到输入框里。 目前支持 TXT、Markdown、JSON、CSV 和常见代码文件。文件内容会以文字的形式放进消息,并带上文件名。 单个文件不能超过 1 MB,一次最多选择 5 个文件。PDF、Word、Excel 等文件暂时不支持。 为什么有些模型不能发图片? 不同模型的能力不一样。桌面端会先尝试发送图片,如果模型或服务商不支持,接口会返回错误。DeepSeek 官方模型仍按官方规则只支持文本。 说明 本项目是官方 DeepSeek Harness 的桌面外壳,不是官方 Harness 核心代码的复制版。官方项目仍在持续开发中,后续可能会有功能变化。 官方仓库:deepseek-ai/deepseek-harness DSH 插件论坛:github.com/topics/dsh-plugin 本项目仓库:deepseek-harness-desktop 许可证 MIT License
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
hx876298682-tech/deepseek-harness-desktop
把 Web 界面打包成开箱即用的桌面应用
相关插件 · UI / 主题
破甲增强版JeffKeeping/dsh-purge-plus
dsh-purge 的非官方分支fork:适配 DeepSeek Harness 0.2.1-rc.2、破甲内核…
★ 387已汉化DeepSeek 客户端
71.9
无代码业务系统平台nocobase/nocobase
NocoBase 是什么
★ 24,804已汉化DSH
71.8
1Panel 服务器面板1Panel-dev/1Panel
全球 250 万+ 自托管用户共同喜爱。
★ 37,350已汉化DSH
71.5
工作状态行动态ccch1mneyyy/working-activity
作者:chimney@ccch1mneyyy。社区项目,非 DeepSeek 官方项目。
★ 664已汉化DSH
71.2
多模型配置管家farion1231/cc-switch
跨平台桌面一体化助手,支持 Claude Code、Codex、OpenCode、DeepSeek Harness 等工具,唯一官网 ccswitch.io
★ 151,506已汉化DSH
71.1
AI 矢量设计工具ZSeven-W/openpencil
全球首个 AI 原生开源矢量设计工具。
★ 7,027已汉化DSH
71.1
这是你的仓库?认领条目