为桌面应用补齐 Linux 打包与 macOS 一致行为
30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/1 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查未通过:仓库根目录及浅层子目录均无 dsh 插件清单,无法用 dsh 插件安装命令安装。以下命令仍可尝试,但可能失败。
无法用 dsh 插件命令安装(仓库内无 dsh 插件清单)
git clone https://github.com/lql341/deepseek-harness-linux-desktop.git按该仓库 README 的原生方式安装;若作者另行发布了 DSH 插件包,请以其文档为准
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
是什么
dsh 原生插件 · vision
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 34 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
⚠︎ 实装验证未通过(unknown · 2026/10/1) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装仓库根目录及浅层子目录均无 dsh 插件清单,无法用 dsh 插件安装命令安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包deepseek-harness-linux-desktop(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/11 22:26:57
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量
查看扫描证据(共 90 处,展示前 67 条)
- 读取本地文件ci/check-docs.mjs:5
const read = path => readFileSync(path, 'utf8') - 读取本地文件ci/check-docs.mjs:26
if (!existsSync(resolve(root, path))) fail(`missing translation: ${path}`) - 读取本地文件ci/check-docs.mjs:31
for (const entry of readdirSync(directory, { withFileTypes: true })) { - 读取本地文件ci/check-docs.mjs:44
if (!existsSync(enPath) || !existsSync(zhPath)) continue - 读取本地文件ci/check-docs.mjs:62
if (targetPath.startsWith('../') || !existsSync(absolute)) { fail(`broken local link: ${path}: ${target}`); continue } - 读取本地文件ci/check-docs.mjs:65
if (anchor && extname(absolute) === '.md' && statSync(absolute).isFile()) { - 删除本地文件递归ci/check-docs.test.mjs:13
t.after(() => rmSync(root, { recursive: true, force: true })) - 读取本地文件ci/check-docs.test.mjs:18
const content = readFileSync(file, 'utf8') - 写入本地文件ci/check-docs.test.mjs:20
writeFileSync(file, content.replace(before, after)) - 删除本地文件ci/check-docs.test.mjs:27
['missing translation', root => unlinkSync(join(root, 'docs/DOCUMENTATION.zh-CN.md')), /missing translation/], - 写入本地文件ci/check-docs.test.mjs:28
['unpaired page', root => writeFileSync(join(root, 'unpaired.md'), '# Unpaired\n'), /unpaired Markdown/], - 写入本地文件ci/check-docs.test.mjs:37
['invalid pinned base', root => writeFileSync(join(root, 'ci/upstream-base-tag'), 'not-a-tag\n'), /invalid pinned base/], - 写入本地文件ci/check-docs.test.mjs:46
writeFileSync(join(root, 'ci/upstream-base-tag'), 'dsh-v9.9.9-rc.1\n') - 写入本地文件ci/desktop-operation-audit.mjs:28
mkdirSync(packageDir, { recursive: true }) - 写入本地文件ci/desktop-operation-audit.mjs:29
writeFileSync(join(packageDir, 'package.json'), JSON.stringify({ name, version: '1.0.0', dsh: { bundle: { patch: './cordis.patch.yml' } } })) - 写入本地文件ci/desktop-operation-audit.mjs:30
writeFileSync(join(packageDir, 'cordis.patch.yml'), JSON.stringify([{ insert: name === 'core' - 写入本地文件ci/desktop-operation-audit.mjs:32
writeFileSync(join(packageDir, 'plugin.mjs'), 'export function apply(ctx) { ctx.provide("operationAuditProbe", true) }\n') - 写入本地文件ci/desktop-operation-audit.mjs:36
writeFileSync(join(profileDir, 'package.json'), JSON.stringify(manifest)) - 写入本地文件ci/desktop-operation-audit.mjs:38
writeFileSync(config, '[]\n') - 读取本地文件ci/desktop-operation-audit.mjs:67
assert.ok(existsSync(entry), 'The isolated Worker must be a physical packaged file') - 读取本地文件ci/desktop-operation-audit.mjs:85
const report = readFileSync(reportPath, 'utf8') - 删除本地文件递归ci/desktop-operation-audit.mjs:99
rmSync(directory, { recursive: true, force: true }) - 写入本地文件ci/release-signature.test.mjs:17
writeFileSync(join(directory, 'key.pem'), privateKey.export({ type: 'pkcs8', format: 'pem' })) - 写入本地文件ci/release-signature.test.mjs:18
writeFileSync(join(directory, 'key.pub.pem'), publicKey.export({ type: 'spki', format: 'pem' })) - 写入本地文件ci/release-signature.test.mjs:20
writeFileSync(artifact, 'release bytes') - 写入本地文件ci/release-signature.test.mjs:21
writeFileSync(join(directory, 'SHA256SUMS'), - 删除本地文件递归ci/release-signature.test.mjs:28
t.after(() => rmSync(directory, { recursive: true, force: true })) - 执行外部命令来自配置/变量ci/release-signature.test.mjs:29
execFileSync(process.execPath, [sign, '--manifest', join(directory, 'SHA256SUMS'), - 执行外部命令来自配置/变量ci/release-signature.test.mjs:31
execFileSync(process.execPath, [verify, '--manifest', join(directory, 'SHA256SUMS'), - 写入本地文件ci/release-signature.test.mjs:34
writeFileSync(join(directory, 'package.deb'), 'tampered bytes') - 执行外部命令来自配置/变量ci/release-signature.test.mjs:35
assert.throws(() => execFileSync(process.execPath, [verify, '--manifest', join(directory, 'SHA256SUMS'), - 删除本地文件递归ci/release-signature.test.mjs:41
t.after(() => rmSync(directory, { recursive: true, force: true })) - 执行外部命令来自配置/变量ci/release-signature.test.mjs:42
execFileSync(process.execPath, [sign, '--manifest', join(directory, 'SHA256SUMS'), - 删除本地文件递归ci/release-signature.test.mjs:45
t.after(() => rmSync(other, { recursive: true, force: true })) - 写入本地文件ci/release-signature.test.mjs:47
writeFileSync(join(other, 'other.pub.pem'), publicKey.export({ type: 'spki', format: 'pem' })) - 执行外部命令来自配置/变量ci/release-signature.test.mjs:48
assert.throws(() => execFileSync(process.execPath, [verify, '--manifest', join(directory, 'SHA256SUMS'), - 删除本地文件递归ci/release-signature.test.mjs:54
t.after(() => rmSync(directory, { recursive: true, force: true })) - 执行外部命令来自配置/变量ci/release-signature.test.mjs:57
assert.throws(() => execFileSync(process.execPath, [sign, '--manifest', join(directory, 'SHA256SUMS'), - 读取本地文件ci/scnet-release-audit.mjs:60
return JSON.parse(readFileSync(path, 'utf8')) - 读取本地文件ci/scnet-release-audit.mjs:67
return createHash('sha256').update(readFileSync(path)).digest('hex') - 读取本地文件ci/scnet-release-audit.mjs:71
return lstatSync(path).isDirectory() ? sha256(join(path, 'dsh', 'desktop-runtime.json')) : sha256(path) - 读取本地文件ci/scnet-release-audit.mjs:75
return `sha512-${createHash('sha512').update(readFileSync(path)).digest('base64')}` - 读取本地文件ci/scnet-release-audit.mjs:85
for (const entry of readdirSync(directory, { withFileTypes: true })) { - 读取本地文件ci/scnet-release-audit.mjs:102
const root = statSync(path).isDirectory() ? path : dirname(path) - 执行外部命令固定命令ci/scnet-release-audit.mjs:248
const help = spawnSync('python3', [script, '--help'], { - 执行外部命令来自配置/变量ci/scnet-release-audit.mjs:310
const result = spawnSync(runtime, args, { - 写入本地文件ci/scnet-release-audit.mjs:335
if (options.output) writeFileSync(options.output, `${JSON.stringify(evidence, undefined, 2)}\n`) - 执行外部命令固定命令ci/scnet-release-audit.mjs:365
const unpack = spawnSync('dpkg-deb', ['-x', deb, extracted], { stdio: 'inherit' }) - 删除本地文件递归ci/scnet-release-audit.mjs:370
rmSync(extracted, { recursive: true, force: true }) - 删除本地文件递归ci/scnet-setup-audit.test.mjs:11
t.after(() => rmSync(root, { recursive: true, force: true })) - 写入本地文件ci/scnet-setup-audit.test.mjs:24
mkdirSync(join(bundle, path, '..'), { recursive: true }); writeFileSync(join(bundle, path), content) - 写入本地文件ci/scnet-setup-audit.test.mjs:24
mkdirSync(join(bundle, path, '..'), { recursive: true }); writeFileSync(join(bundle, path), content) - 写入本地文件ci/scnet-setup-audit.test.mjs:26
writeFileSync(join(runtime, 'package.json'), JSON.stringify({ dependencies: { 'dsh-scnet': '0.6.13' } })) - 写入本地文件ci/scnet-setup-audit.test.mjs:27
writeFileSync(join(runtime, 'desktop-runtime.json'), JSON.stringify({ schemaVersion: 1, - 执行外部命令来自配置/变量ci/scnet-setup-audit.test.mjs:34
const run = (required = true) => spawnSync(process.execPath, [new URL('./scnet-release-audit.mjs', import.meta.url).pathname, - 删除本地文件ci/scnet-setup-audit.test.mjs:45
const f = fixture(t); unlinkSync(join(f.unpacked, 'skills/scnet-hpc/scripts/scnet.py')) - 写入本地文件ci/scnet-setup-audit.test.mjs:49
const f = fixture(t); writeFileSync(join(f.unpacked, 'connector/callback.mjs'), 'changed') - 删除本地文件递归ci/scnet-setup-audit.test.mjs:57
const f = fixture(t); rmSync(f.unpacked, { recursive: true }) - 读取本地文件ci/sign-release.mjs:31
const keyPem = keyPath === undefined ? process.env.DSH_RELEASE_SIGNING_KEY : readFileSync(keyPath, 'utf8') - 读取密钥环境变量ci/sign-release.mjs:31
const keyPem = keyPath === undefined ? process.env.DSH_RELEASE_SIGNING_KEY : readFileSync(keyPath, 'utf8') - 读取本地文件ci/sign-release.mjs:39
const manifest = readFileSync(manifestPath) - 写入本地文件ci/sign-release.mjs:42
writeFileSync(outputPath, `${detached}\n`, { mode: 0o644 }) - 读取本地文件ci/sign-release.mjs:46
const expected = readFileSync(publicKeyHint, 'utf8').trim() - 读取本地文件ci/verify-release-signature.mjs:28
const manifest = readFileSync(manifestPath) - 读取本地文件ci/verify-release-signature.mjs:29
const detached = Buffer.from(readFileSync(signaturePath, 'utf8').trim(), 'base64') - 读取本地文件ci/verify-release-signature.mjs:30
if (!verify(null, manifest, createPublicKey(readFileSync(publicKeyPath, 'utf8')), detached)) { - 读取本地文件ci/verify-release-signature.mjs:45
const actual = createHash('sha256').update(readFileSync(join(directory, name))).digest('hex')
扫描于 2026/11/4(0 天前) · 范围 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- Linuxx64打包补丁
- 对齐macOS使用体验
DeepSeek Harness 桌面应用的非官方 Linux x64(AppImage/deb)移植补丁集,力求接近 macOS 的使用体验
README
由 DeepSeek 最新模型翻译生成deepseek-harness-linux-desktop
非官方补丁集,为 DeepSeek Harness 桌面应用 提供 Linux x64 发布目标(AppImage + deb),并使其行为与 macOS 构建保持一致。
上游仅发布 macOS 和 Windows —— 其自身的 apps/desktop/README.md 中声明 “Linux 不是受支持的桌面发布目标”,并且打包测试断言必须拒绝 linux-x64 目标。本仓库就是打开这条路径的差异补丁集。
状态:仅补丁,未在 Linux 上验证。
这些补丁是针对上游标签编写的,并在 macOS 上进行了检查(语法层面,外加树哈希验证其可干净应用)。它们从未在 Linux 上编译、打包或运行过。首次构建时请预留一些小的修复工作 ——故障排查表列出了预期会遇到的问题。
基线:上游标签 dsh-v0.2.0-rc.2(提交 639ed0153972),5 个补丁,33 个文件, +798 / −119。
展开完整文档(README 剩余 1 节)
deepseek-harness-linux-desktop
非官方补丁集,为 DeepSeek Harness 桌面应用 提供 Linux x64 发布目标(AppImage + deb),并使其行为与 macOS 构建保持一致。
上游仅发布 macOS 和 Windows —— 其自身的 apps/desktop/README.md 中声明 “Linux 不是受支持的桌面发布目标”,并且打包测试断言必须拒绝 linux-x64 目标。本仓库就是打开这条路径的差异补丁集。
状态:仅补丁,未在 Linux 上验证。
这些补丁是针对上游标签编写的,并在 macOS 上进行了检查(语法层面,外加树哈希验证其可干净应用)。它们从未在 Linux 上编译、打包或运行过。首次构建时请预留一些小的修复工作 ——故障排查表列出了预期会遇到的问题。
基线:上游标签 dsh-v0.2.0-rc.2(提交 639ed0153972),5 个补丁,33 个文件, +798 / −119。
目录
- 1. 你将获得什么
- 2. 要求与固定路径
- 3. 构建 —— 一键脚本
- 4. 构建 —— 分步进行(含成功条件)
- 5. 验收清单(7 项行为)
- 6. 产物及其落盘位置
- 7. 故障排查
- 8. 已验证 / 未验证
- 9. 已知限制
- 10. 布局、许可证、署名
1. 你将获得什么
| # | macOS 行为 | 补丁集如何在 Linux 上实现 |
| 1 | 应用启动 | 桌面策略门禁在 Linux 上不再抛出 desktop policy: unsupported platform |
| 2 | 窗口边框 | titleBarStyle: 'hidden' + titleBarOverlay(与 Windows 使用的相同机制),因此页面拥有标题栏区域;DSH_DESKTOP_LINUX_NATIVE_FRAME=1 可恢复桌面边框 |
| 3 | 关闭最后一个窗口后任务继续运行 | window-all-closed 现在仅在 Windows 上退出;应用程序及其 Host 保持存活,并提供 Show Window 菜单项以恢复窗口 |
| 4 | PATH 上的 dsh 命令 | 新增 POSIX 启动器以及命令安装器的 Linux 分支(~/.local/bin/dsh);已存在的外部命令会被报告并备份,绝不会被静默覆盖 |
| 5 | dsh:// 深链接 | 桌面条目带有 MimeType=x-scheme-handler/dsh;shell 已注册该 scheme |
| 6 | 捆绑运行时 | 运行时准备按目标平台选择 Linux 载荷(Node/pnpm/Python、Electron 二进制、原生包),而不是假定 macOS 或 Windows |
| 7 | 更新 | Linux 包不带 feed;设置 DSH_DESKTOP_LINUX_UPDATE_ORIGIN 可选择加入自托管的通用(AppImage)feed |
Office 文档转换开箱即用:Linux 使用捆绑的 WASM LibreOffice 引擎(@deepseek-ai/libreoffice-kit-wasm),而非系统 LibreOffice。
2. 要求与固定路径
构建主机必须是 Linux x86_64。 该补丁保留了上游的规则,即 linux-x64 拒绝在其他任何地方构建,因此无法从 macOS 交叉构建。linux-arm64 不属于本系列。
| 要求 | 值 | 检查 |
| 主机 | Linux x86_64 | uname -sm → Linux x86_64 |
| Node | ^22.19.0 \|\| >=24.0.0 | node -v |
| pnpm | 11.7.0 | corepack enable && pnpm -v |
| git | 任意较新版本 | git --version |
| 可用磁盘 | ≥ 15 GB(检出约 200 MB,依赖 + Electron + 运行时负载数 GB) | df -h "$HOME" |
| 网络 | registry.npmjs.org、nodejs.org、Python 独立构建、github.com(Electron)、electron-builder 自身的下载 | 取决于代理;参见故障排查 |
| 冒烟运行所需的显示 | X11/Wayland,或 xvfb-run | echo "$DISPLAY$WAYLAND_DISPLAY" |
本文档通篇使用的路径——请先设置它们:
export PATCH_REPO="$HOME/src/deepseek-harness-linux-desktop" # 本仓库
export SRC="$HOME/src/deepseek-harness" # 上游检出(在下方创建)
export TARGET_DIR="$SRC/apps/desktop/.desktop-build/targets/linux-x64"
export ARTIFACTS="$TARGET_DIR/artifacts"
3. 构建——一次性脚本
代理可以按原样执行此代码块(它会在第一个失败的断言处中止):
set -euo pipefail
--- 预检 -------------------------------------------------------------
[ "$(uname -s)" = "Linux" ] || { echo "FAIL: host is not Linux"; exit 1; }
[ "$(uname -m)" = "x86_64" ] || { echo "FAIL: host is not x86_64"; exit 1; }
command -v git >/dev/null || { echo "FAIL: git missing"; exit 1; }
command -v node >/dev/null || { echo "FAIL: node missing"; exit 1; }
corepack enable >/dev/null 2>&1 || true
[ "$(pnpm -v)" = "11.7.0" ] || echo "WARN: pnpm is $(pnpm -v), expected 11.7.0"
export PATCH_REPO="${PATCH_REPO:-$HOME/src/deepseek-harness-linux-desktop}"
export SRC="${SRC:-$HOME/src/deepseek-harness}"
--- 获取补丁集并应用它 --------------------------------------
[ -d "$PATCH_REPO/.git" ] || git clone https://github.com/lql341/deepseek-harness-linux-desktop.git "$PATCH_REPO"
sh "$PATCH_REPO/apply.sh" "$SRC"
--- 证明补丁已落地 ---------------------------------------------
[ "$(git -C "$SRC" rev-parse HEAD^{tree})" = "0c006d75f9a36f3e428f51364b59bf3e63770484" ] \
|| { echo "FAIL: patched tree hash mismatch"; exit 1; }
[ -f "$SRC/apps/desktop/.env.linux" ] || { echo "FAIL: .env.linux missing"; exit 1; }
--- 依赖 ----------------------------------------------------------
cd "$SRC"
pnpm install --frozen-lockfile
--- 低成本预检:验证 .env.linux 和构建工具链 ---------
pnpm --dir apps/desktop run check:package # 预期:"would publish 0.2.0-rc.2 ... valid"
--- 先做目录构建:它到底能不能启动? ----------------------------
pnpm --dir apps/desktop run package:linux:x64:dir
--- 真实产物 --------------------------------------------------------
pnpm --dir apps/desktop run package:linux:x64
ls -l "$SRC/apps/desktop/.desktop-build/targets/linux-x64/artifacts"
4. 构建 — 分步进行(含成功条件)
步骤 0 — 主机预检
uname -sm # 预期:Linux x86_64
node -v # 预期:v22.19+ 或 v24+
corepack enable && pnpm -v # 预期:11.7.0
df -h "$HOME" # 预期:可用空间 >= 15G
如果 uname -m 是 aarch64,或者 uname -s 是 Darwin,请停止:本补丁集不涵盖该组合。在 macOS 上你仍然可以应用这些补丁(步骤 1 在任何系统上都可用),但 package:linux:x64 会拒绝运行。
步骤 1 — 克隆本仓库并应用补丁系列
git clone https://github.com/lql341/deepseek-harness-linux-desktop.git "$PATCH_REPO"
sh "$PATCH_REPO/apply.sh" "$SRC"
apply.sh 会在标签 dsh-v0.2.0-rc.2 处克隆上游,创建分支 linux-desktop,对所有 5 个补丁运行 git am,并将 .env.linux.example 复制为 .env.linux(打包代码需要该文件,缺少它会中止)。
成功条件 — 以下四项必须全部成立:
git -C "$SRC" log --oneline | head -1
预期:"docs(desktop): describe the Linux build and its known limits"
git -C "$SRC" rev-parse HEAD^{tree}
预期:0c006d75f9a36f3e428f51364b59bf3e63770484
git -C "$SRC" status --porcelain # 预期:为空
test -f "$SRC/apps/desktop/.env.linux" && echo env-ok
若要审查而非直接信任:git -C "$SRC" log --stat 会显示这 5 个主题提交。
步骤 2 — 安装依赖
cd "$SRC"
pnpm install --frozen-lockfile
预期退出码为 0。如果默认 registry 较慢,可以使用镜像 — 要么在 apps/desktop/.env.linux 中设置 DSH_DESKTOP_NPM_REGISTRY(供捆绑运行时安装使用),要么为 Electron 下载设置 ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/。
步骤 3 — 低成本预检(不构建,仅需数秒)
pnpm --dir apps/desktop run check:package
这会校验 .env.linux、发布设置和主机工具链,然后打印类似 desktop package: linux-x64 would publish 0.2.0-rc.2; local configuration and toolchain valid 的内容。在花费时间进行真实构建之前,先修复它报告的任何问题 — 这是发现 pnpm 版本错误、缺少 .env.linux 或其中条目有误的最廉价方式。
步骤 4 — 目录构建(第一次真实构建)
pnpm --dir apps/desktop run package:linux:x64:dir
每个打包命令都会自行构建整个仓库、准备 Electron 发行版、从 registry 安装生产运行时闭包,并写入解包后的应用程序。预期需要数分钟并产生大量输出;退出码为 0 即通过条件。
成功条件:
ls -d "$ARTIFACTS"/linux-unpacked # 解包后的应用程序markdown
ls -l "$ARTIFACTS/linux-unpacked/DeepSeek Harness" # Electron 二进制文件,可执行
步骤 5 — AppImage + deb sh
pnpm --dir apps/desktop run package:linux:x64
ls -l "$ARTIFACTS"/.AppImage "$ARTIFACTS"/.deb
预期恰好有两个产物,名称来自产品版本(参见 §6)。
Linux 不运行签名或公证,因此这里不需要其他操作。
如果你想使用自己的编号,请传入 --build-version,例如
pnpm --dir apps/desktop run package:linux:x64 -- --build-version 0.2.0-rc.2.linux.1;
如果不传,产物将携带上游产品版本。
步骤 6 — 冒烟运行 sh 目录构建,无头主机: xvfb-run -a "$ARTIFACTS/linux-unpacked/DeepSeek Harness"
或者安装 deb(这也是让 dsh 命令可用的方式,参见 §9):
sudo apt install ./"$ARTIFACTS"/deepseek-harness--linux-x64.deb
dpkg -L deepseek-harness | grep -E '/(bin|opt)/' # 找到已安装的可执行文件然后从桌面菜单启动它,或运行上面打印的路径(要加引号:它包含一个空格)
前 30 秒内需要观察的事项:
- 它必须到达工作区/欢迎界面,并且不能打印 desktop policy: unsupported platform;
- 窗口不应有系统标题栏,并且原生控件位于右上角(如果桌面环境绘制了奇怪的东西,请使用
DSH_DESKTOP_LINUX_NATIVE_FRAME=1 重试);
- 在没有用户命名空间的容器中,Chromium 的沙箱可能拒绝启动——优先使用 deb,或者仅作为最后手段添加 --no-sandbox(这会降低安全性)。
5. 验收清单(7 项行为)
按顺序运行这些检查;每一项都对应 patches/ 中的一个补丁。
| # | 检查 | 命令 / 观察 | 预期 |
| 1 | 启动 | 按步骤 6 启动 | 工作区打开,没有 unsupported platform 错误 |
| 2 | 窗口镶边 | 查看窗口;切换 DSH_DESKTOP_LINUX_NATIVE_FRAME=1 | 叠加式标题栏 + 原生控件;环境变量可恢复边框 |
| 3 | 保持存活 | 关闭最后一个窗口,然后运行 pgrep -af "DeepSeek Harness" | 进程仍在运行;Show Window* 菜单项会重新显示窗口;显式 Quit 会真正退出 |
| 4 | dsh 在 PATH 中 | 从应用 UI 安装命令,然后在一个新 shell 中运行:command -v dsh && dsh --version | ~/.local/bin/dsh,运行捆绑的 CLI(确保 ~/.local/bin 在 PATH 中) |
| 5 | 深度链接 | xdg-mime query default x-scheme-handler/dsh 然后 xdg-open 'dsh://open' | 已注册 desktop 文件,并且窗口获得焦点 |
| 6 | 运行时 + Office | 在会话中运行 shell 工具;请求 DOCX→PDF 转换 | bash 工具可用(Landlock,内核 ≥ 5.13);通过捆绑的 WASM 引擎转换成功 |
| 7 | 更新 | 在没有 DSH_DESKTOP_LINUX_UPDATE_ORIGIN 的情况下启动 | 不检查更新;设置自托管的通用 feed origin 后,应用会读取 latest-linux.yml |
6. 产物及其落盘位置
所有内容都写入 apps/desktop/.desktop-build/targets/linux-x64/ 下:
| 路径 | 内容 |
| artifacts/linux-unpacked/ | 解包后的应用程序(来自 :dir);可执行文件 DeepSeek Harness |
| artifacts/deepseek-harness--linux-x64.AppImage | AppImage |
| artifacts/deepseek-harness--linux-x64.deb | Debian 包 |
| runtime/ | 为此目标准备的 Electron + pnpm + 启动器 |
| dsh/ | 捆绑的 dsh 运行时树,将成为 app.asar/dsh |
| package-set/、downloads/ | 中间包集合和已下载的归档 |
| packaging-runs/ | 每次运行的日志和发布记录 |
使用默认版本时,这些是 deepseek-harness-0.2.0-rc.2-linux-x64.AppImage 和 …-linux-x64.deb。
7. 故障排查
| 症状 | 原因 | 操作 |
| desktop package: unsupported target "linux-x64" | 补丁未应用 | 重新运行步骤 1;验证树哈希 |
| desktop package: cannot read …/.env.linux; copy … | 缺少必需的环境文件 | cp apps/desktop/.env.linux.example apps/desktop/.env.linux |
| desktop package: linux-x64 requires a Linux x64 build host | 在 macOS/arm64 上构建 | 在 Linux x86_64 上构建 |
| desktop package: unsupported setting X in …/.env.linux | 键不在 Linux 模板中 | 仅使用 DSH_DESKTOP_APP_ID、DSH_DESKTOP_NPM_REGISTRY、DSH_DESKTOP_LINUX_UPDATE_ORIGIN、策略来源 |
| ERR_PNPM_UNSUPPORTED_ENGINE / 奇怪的依赖错误 | Node 或 pnpm 错误 | Node ^22.19 \|\| >=24,pnpm 11.7.0 |
| Electron 下载超时 / 404 | 代理或镜像 | ELECTRON_MIRROR,或导出 HTTPS_PROXY |
| missing required LibreOffice engine wasm | 运行时树中缺少 WASM 套件 | 确认已安装 @deepseek-ai/libreoffice-kit-wasm(它是 @deepseek-ai/libreoffice-kit 的可选依赖) |
| main.ts 中来自 tsc 的类型错误 | 第一次真正的类型检查 | 报告它们;策略分支收窄是最可能的位置 |
| AppImage 拒绝启动(沙箱 / 用户命名空间) | Ubuntu 23.10+ AppArmor 限制 | 安装 deb,或添加 AppArmor 配置文件;--no-sandbox 仅作为最后手段 |
| dsh 安装被拒绝,提示 "transient AppImage mount" | AppImage 资源位于临时挂载中 | 安装 deb,或解压 AppImage 并设置 DSH_DESKTOP_RESOURCES |
| 深度链接无任何作用 | 桌面文件未注册 | 确认 xdg-mime query default x-scheme-handler/dsh;重新安装 deb |
8. 已验证 / 未验证
已验证:
- 该系列补丁在 dsh-v0.2.0-rc.2 上干净应用;git am 后生成的树哈希为 0c006d75f9a36f3e428f51364b59bf3e63770484,没有遗留更改。
- apply.sh 在 C locale 且未配置 git 身份的情况下端到端运行:全新浅克隆 → 5 个补丁 → 创建 .env.linux → 退出码 0。
- 每个更改的文件都通过语法检查;所有原生依赖均已针对
npm registry 解析(存在 Linux 变体,node-pty 提供 linux-x64/arm64 预构建)。
未验证(需要 Linux 主机):
- pnpm install、check:package、编译和类型检查。
- Electron 的 titleBarOverlay 在各桌面环境下的外观;两种主题下的窗口拖拽/调整大小和标题栏尺寸。
- landlock-run 解包和 bash 沙箱、deb 元数据、XDG 深度链接关联。
- 桌面测试套件,上游从未在 Linux 上运行过,且可能存在预先存在的失败。在未打补丁的标签上运行一次以获取基线,然后再进行比较。
9. 已知限制
- 无法 1:1 实现:macOS 红绿灯按钮、侧边栏 vibrancy、Dock 弹跳。该补丁集以原生覆盖窗口控件、扁平侧边栏和通知作为替代。
- dsh 命令需要 deb:AppImage 的资源位于临时挂载中,因此从中安装命令会被拒绝,并给出可操作的提示信息(DSH_DESKTOP_RESOURCES 是用于已解包目录树的逃生通道)。
- 平台标识:Linux 构建会向 DeepSeek Platform 报告 macOS 桌面标识,因为共享账户包只为 x-client-platform 定义了 darwin/win32(省略它会降级为 web)。
- 强制更新策略在 Linux 上无效(没有官方 Linux 更新源)。
- 仅支持 linux-x64;linux-arm64 不属于本系列。
- 欢迎窗口的标题栏颜色仅在创建时跟随系统调色板。
- deb 维护者字段是占位符(DeepSeek Harness)。
10. 布局、许可证、署名
patches/0001..0005*.patch git format-patch 系列,按文件名顺序应用 apply.sh 在基础标签处克隆上游,应用该系列,创建 .env.linux LINUX-DESKTOP.md 长篇指南:逐文件说明、已验证事实、待办事项 LICENSE MIT(上游 DeepSeek + 本补丁集)
每个补丁对应一个主题:(1) 接受目标,(2) 安装 dsh 命令,
(3) 准备 Linux 运行时负载,(4) 类 macOS 外壳行为,(5) 文档。
本补丁集在 MIT 许可证下分发(见 LICENSE)。这些补丁是针对 deepseek-ai/deepseek-harness 的差异补丁,该项目采用 MIT 许可证,版权所有 (c) 2026 DeepSeek;该声明在此保留。
与 DeepSeek 无关联、未获其认可或支持。上游处于开发者预览阶段且迭代迅速,因此在变基到更新的标签时预计会出现冲突。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
lql341/deepseek-harness-linux-desktop
为桌面应用补齐 Linux 打包与 macOS 一致行为
相关插件 · 视觉能力
智能体工作台Devin-AXIS/iPolloWork
企业级、本地优先的智能体工作台,面向个人和智能体团队——一个工作区,容纳多个智能体引擎;一套统一体系,管理插件和技能;支…
★ 7,364已汉化DSH
72
开源设计工作台nexu-io/open-design
OpenDesign:首个协作式 AI 设计智能体工作区
★ 105,709已汉化DSH
71.8
GPT 图像提示词库freestylefly/awesome-gpt-image-2
Prompt as Code | GPT Image 2 / 2.5 提示词与案例库,530+ 个案例、20+…
★ 34,534已汉化DSH
71.5
多智能体编码工作区spacering-net/codeg
多智能体协作的 AI 编程工作区:汇总 Claude Code、Codex、OpenCode、Pi、Grok Build 等来源的会话。支持桌面应用、自托管服务器或 Docker。
★ 4,319已汉化DSH
71.5
AI 用量桌面小部件Javis603/token-monitor
EN | 简 | 繁 | KO | JA | PT
★ 3,533已汉化DSH
71.1
架构图生成器tt-a1i/archify
把你想理解、规划或分享的事,变成可以互动的可视化作品。
★ 93,105已汉化DSH
71.1
这是你的仓库?认领条目