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

鸿蒙桌面版 fellow99/dsh-desktop-ark

DeepSeek Harness
fellow999 天前有提交已提供中文文档扫描:含敏感能力

DeepSeek Harness(DSH)官方 Web UI 原样运行在 HarmonyOS 2in1 / 平板上的系统 ArkWeb 里,dsh Host 跑在同一进程内嵌的真实 Node.js 运行时上。不用 Electron…

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

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add fellow99/dsh-desktop-ark
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

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

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

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/10/22) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 94 处,展示前 89 条)
  • 读取本地文件
    hvigorfile.ts:51
    parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
  • 读取本地文件
    hvigorfile.ts:89
    if (fs.existsSync(file)) {
  • 写入本地文件
    packages/attachment-image-ohos/lib/index.js:43
    appendFileSync(path, `${new Date().toISOString()} SHARP ${line}${String.fromCharCode(10)}`)
  • 读取本地文件
    packages/attachment-image-ohos/lib/index.js:70
    if (typeof input === 'string') return readFileSync(input)
  • 读取本地文件
    packages/attachment-image-ohos/lib/index.js:71
    if (input !== null && typeof input === 'object' && typeof input.path === 'string') return readFileSync(input.path)
  • 读取本地文件
    packages/git-ohos/lib/git-credentials.js:162
    return { path, exists: true, entries: parseCredentials(readFileSync(path, 'utf8')) }
  • 读取本地文件
    packages/git-ohos/lib/git-credentials.js:187
    text = readFileSync(path, 'utf8')
  • 写入本地文件
    packages/git-ohos/lib/git-credentials.js:211
    mkdirSync(dirname(path), { recursive: true })
  • 写入本地文件
    packages/git-ohos/lib/git-credentials.js:213
    writeFileSync(temp, body, { mode: 0o600 })
  • 写入本地文件
    packages/git-ohos/lib/git-credentials.js:215
    chmodSync(temp, 0o600)
  • 写入本地文件
    packages/git-ohos/lib/git-credentials.js:220
    renameSync(temp, path)
  • 读取本地文件
    packages/git-ohos/lib/git-credentials.js:237
    text = readFileSync(path, 'utf8')
  • 删除本地文件
    packages/git-ohos/lib/git-credentials.js:257
    unlinkSync(path)
  • 写入本地文件
    packages/git-ohos/lib/git-credentials.js:259
    writeFileSync(path, '', { mode: 0o600 })
  • 写入本地文件
    packages/git-ohos/lib/git-credentials.js:264
    writeFileSync(temp, body, { mode: 0o600 })
  • 读取本地文件
    packages/git-ohos/lib/runtime.js:159
    return JSON.parse(readFileSync(manifest, 'utf8')).version ?? 'unknown'
  • 读取本地文件
    packages/host-bridge-ohos/lib/index.js:157
    stat = statSync(dir)
  • 删除本地文件
    packages/host-bridge-ohos/lib/index.js:182
    unlinkSync(path)
  • 读取本地文件
    packages/host-bridge-ohos/lib/index.js:191
    text = readFileSync(path, 'utf8')
  • 写入本地文件
    packages/host-bridge-ohos/lib/index.js:296
    writeFileSync(tmpPath, payload, 'utf8')
  • 写入本地文件
    packages/host-bridge-ohos/lib/index.js:297
    renameSync(tmpPath, reqPath)
  • 读取本地文件
    packages/market-ohos/lib/index.js:52
    if (!existsSync(dir) || !statSync(dir).isDirectory()) return null
  • 读取本地文件
    packages/market-ohos/lib/index.js:52
    if (!existsSync(dir) || !statSync(dir).isDirectory()) return null
  • 读取本地文件
    packages/market-ohos/lib/index.js:66
    return JSON.parse(readFileSync(file, 'utf8'))
  • 读取本地文件
    packages/market-ohos/lib/index.js:94
    const installed = (name) => existsSync(join(profileDir, 'node_modules', ...name.split('/'), 'package.json'))
  • 写入本地文件
    packages/market-ohos/lib/index.js:122
    writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`)
  • 读取本地文件
    packages/market-ohos/lib/pnpm-inprocess.js:59
    const stat = statSync(entry)
  • 读取本地文件
    packages/open-in-app-ohos/lib/index.js:284
    info = await stat(target.path)
  • 写入本地文件
    packages/shell-ohos/lib/output.js:79
    mkdirSync(spill.dir, { recursive: true })
  • 删除本地文件
    packages/shell-ohos/lib/output.js:107
    unlinkSync(file)
  • 读取本地文件
    packages/subprocess-ohos/lib/index.js:206
    const stat = statSync(path)
  • 读取本地文件
    packages/subprocess-ohos/lib/index.js:208
    accessSync(path, fsConstants.X_OK)
  • 读取本地文件
    packages/subprocess-ohos/lib/index.js:251
    accessSync(candidate, fsConstants.X_OK)
  • 读取本地文件
    packages/subprocess-ohos/lib/index.js:275
    stat = statSync(canonical)
  • 执行外部命令来自配置/变量
    packages/subprocess-ohos/lib/index.js:375
    child = nodeSpawn(program, spec.argv.slice(1), {
  • 写入本地文件
    packages/subprocess-ohos/lib/output.js:79
    mkdirSync(spill.dir, { recursive: true })
  • 删除本地文件
    packages/subprocess-ohos/lib/output.js:107
    unlinkSync(file)
  • 发起网络请求
    packages/workspace-picker-client-ohos/lib/client.js:118
    const response = await fetch(ROUTES + path, body === undefined
  • 写入本地文件
    packages/workspace-picker-ohos/lib/index.js:304
    await mkdir(target)
  • 写入本地文件
    packages/workspace-picker-ohos/lib/index.js:324
    await mkdir(root.path, { recursive: true })
  • 读取本地文件
    packages/workspace-picker-ohos/lib/index.js:337
    info = await stat(canonical)
  • 写入本地文件
    packages/workspace-picker-ohos/lib/index.js:380
    if (root.id === 'sandbox') await mkdir(root.path, { recursive: true }).catch(() => {})
  • 读取本地文件
    packages/workspace-picker-ohos/lib/index.js:410
    await readdir(root.path)
  • 读取本地文件
    packages/workspace-picker-ohos/lib/index.js:656
    const dirents = await readdir(target, { withFileTypes: true })
  • 读取本地文件
    packages/workspace-picker-ohos/lib/index.js:663
    enterable = (await stat(join(target, dirent.name))).isDirectory()
  • 写入本地文件
    payload/bootstrap.js:39
    fs.mkdirSync(PAYLOAD_ROOT, { recursive: true });
  • 写入本地文件
    payload/bootstrap.js:40
    fs.appendFileSync(APP_LOG, text);
  • 写入本地文件
    payload/bootstrap.js:51
    fs.mkdirSync(PAYLOAD_ROOT, { recursive: true });
  • 删除本地文件
    payload/bootstrap.js:52
    fs.rmSync(tmp, { force: true });
  • 写入本地文件
    payload/bootstrap.js:55
    fs.writeFileSync(fd, body);
  • 写入本地文件
    payload/bootstrap.js:61
    fs.renameSync(tmp, READY_FILE);
  • 读取本地文件
    payload/bootstrap.js:137
    const first = fs.readFileSync(VERSION_FILE, 'utf8').split('\n')[0].trim();
  • 读取本地文件
    payload/bootstrap.js:169
    if (fs.existsSync(path.join(devRoot, 'node_modules', '@deepseek-ai', 'dsh', 'package.json'))) {
  • 读取本地文件
    payload/bootstrap.js:173
    if (!ARCHIVE || !fs.existsSync(ARCHIVE)) {
  • 读取本地文件
    payload/bootstrap.js:183
    if (fs.existsSync(marker) && fs.existsSync(target)) {
  • 删除本地文件
    payload/bootstrap.js:195
    fs.rmSync(staging, { recursive: true, force: true });
  • 删除本地文件
    payload/bootstrap.js:197
    fs.rmSync(target, { recursive: true, force: true });
  • 写入本地文件
    payload/bootstrap.js:198
    fs.renameSync(staging, path.dirname(target));
  • 读取本地文件
    payload/bootstrap.js:211
    if (!fs.existsSync(file)) {
  • 读取本地文件
    payload/bootstrap.js:262
    if (!fs.existsSync(path.join(profileDir, 'package.json'))) {
  • 读取本地文件
    payload/host.js:51
    if (!fs.existsSync(configFile)) {
  • 写入本地文件
    payload/host.js:66
    fs.writeFileSync(configFile, body);
  • 读取本地文件
    payload/host.js:72
    const current = fs.readFileSync(configFile, 'utf8');
  • 写入本地文件
    payload/host.js:79
    fs.writeFileSync(configFile, rewritten);
  • 写入本地文件
    payload/host.js:91
    fs.mkdirSync(dir, { recursive: true });
  • 读取本地文件
    payload/host.js:111
    if (!fs.existsSync(dshManifest)) {
  • 读取本地文件
    payload/host.js:143
    patchFiles: userPatch !== '' && fs.existsSync(userPatch) ? [userPatch] : [],
  • 发起网络请求
    payload/jitless/fetch-shim.js:748
    req = mod.request(parsed, options, (res) => {
  • 发起网络请求
    payload/jitless/selftest.mjs:68
    const response = await fetch(`http://127.0.0.1:${String(server.address().port)}/`);
  • 读取本地文件
    payload/lib/tar-extract.js:64
    const compressed = fs.readFileSync(archive);
  • 写入本地文件
    payload/lib/tar-extract.js:66
    fs.mkdirSync(destDir, { recursive: true });
  • 写入本地文件
    payload/lib/tar-extract.js:87
    fs.mkdirSync(target, { recursive: true });
  • 写入本地文件
    payload/lib/tar-extract.js:89
    fs.mkdirSync(path.dirname(target), { recursive: true });
  • 写入本地文件
    payload/lib/tar-extract.js:94
    fs.writeFileSync(target, body);
  • 写入本地文件
    payload/selfcheck.js:54
    fs.mkdirSync(PAYLOAD_ROOT, { recursive: true });
  • 写入本地文件
    payload/selfcheck.js:56
    fs.writeFileSync(probe, 'ok');
  • 删除本地文件
    payload/selfcheck.js:57
    fs.rmSync(probe, { force: true });
  • 读取本地文件
    payload/selfcheck.js:66
    if (!fs.existsSync(readyFile)) {
  • 读取本地文件
    payload/selfcheck.js:71
    const parsed = JSON.parse(fs.readFileSync(readyFile, 'utf8'));
  • 读取本地文件
    payload/shims/flock.js:34
    const present = fs.existsSync(manifest);
  • 读取本地文件
    payload/shims/flock.js:39
    } else if (!fs.existsSync(file)) {
  • 读取本地文件
    payload/shims/flock.js:43
    replaced = fs.readFileSync(file, 'utf8').includes(STUB_MARKER);
  • 写入本地文件
    payload/shims/fs-link.js:25
    fs.renameSync(existingPath, newPath);
  • 读取本地文件
    payload/shims/fs-symlink.js:19
    const stat = fs.lstatSync(source);
  • 写入本地文件
    payload/shims/fs-symlink.js:21
    fs.mkdirSync(target, { recursive: true });
  • 读取本地文件
    payload/shims/fs-symlink.js:22
    for (const entry of fs.readdirSync(source)) {
  • 写入本地文件
    payload/shims/fs-symlink.js:27
    fs.copyFileSync(source, target);
  • 读取本地文件
    payload/shims/sharp.js:32
    if (!fs.existsSync(manifestPath)) {
  • 读取本地文件
    payload/shims/sharp.js:37
    const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
扫描于 2026/10/31(1 天前) · 范围 全包扫描 · 来源 GitHub 仓库

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

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

README

由 DeepSeek 最新模型翻译生成
| English DSH Desktop · HarmonyOS Edition 官方 DeepSeek Harness(dsh)Web UI,原样未改,跑在 HarmonyOS 2in1 / 平板上的系统 ArkWeb 里——dsh Host 则运行在同一进程内嵌的真实 Node.js 运行时上。不用 Electron,不打包 Chromium,也不用 ArkUI 重写。 你能得到什么 - 还是你熟悉的那个 dsh——会话、工具、插件、设置、主题全都在。前端来自上游,原样未动;智能体宿主在本地运行,所以没有中转,没有 CORS,也没有账号门槛。 - 渲染不占体积——界面由系统 WebView 绘制,安装包只带智能体运行时(载荷约 42 MB),不带浏览器引擎。HAP 约 88 MB。 - 安装不需要受限权限——默认构建不含 JIT(compat),侧载无需 ACL 绑定的权限。另有 jit 变体,供已授予可写代码内存权限的设备使用。 - 上游零改动——HarmonyOS 的差异都收在 ohos 配置档、一层 bundle、接缝插件和六个经审计的 shim 里。升级 dsh 只需重跑流水线,不用重做补丁。 - 以本产品名义呈现——独立图标、名称和窗口标题;上游预览提示和 DeepSeek 首次运行对话框不再自动弹出(两者仍可在设置里打开)。
展开完整文档(README 剩余 1 节)
| English

DSH Desktop · HarmonyOS Edition

官方 DeepSeek Harness(dsh)Web UI,原样未改,跑在 HarmonyOS 2in1 / 平板上的系统 ArkWeb 里——dsh Host 则运行在同一进程内嵌的真实 Node.js 运行时上。不用 Electron,不打包 Chromium,也不用 ArkUI 重写。

你能得到什么

- 还是你熟悉的那个 dsh——会话、工具、插件、设置、主题全都在。前端来自上游,原样未动;智能体宿主在本地运行,所以没有中转,没有 CORS,也没有账号门槛。
- 渲染不占体积——界面由系统 WebView 绘制,安装包只带智能体运行时(载荷约 42 MB),不带浏览器引擎。HAP 约 88 MB。
- 安装不需要受限权限——默认构建不含 JIT(compat),侧载无需 ACL 绑定的权限。另有 jit 变体,供已授予可写代码内存权限的设备使用。
- 上游零改动——HarmonyOS 的差异都收在 ohos 配置档、一层 bundle、接缝插件和六个经审计的 shim 里。升级 dsh 只需重跑流水线,不用重做补丁。
- 以本产品名义呈现——独立图标、名称和窗口标题;上游预览提示和 DeepSeek 首次运行对话框不再自动弹出(两者仍可在设置里打开)。

两个 HarmonyOS 版本

HarmonyOS 上有两个独立版本,外壳架构相同,Web UI 同样原样未改,数据面也相同;区别在于由哪个运行时提供 Node:

| | HarmonyOS Edition(本仓库) | Electron on HarmonyOS Edition(dsh-desktop-hos) |
| 渲染器 | 系统 ArkWeb——不打包任何东西 | Chromium,随 Electron 37 一起打包 |
| Node.js | libnode.so 在应用自身进程内启动(v24.2.0) | 在 Electron 运行时内(Node 22.17) |
| 运行时管线 | @fellow99/node-bridge + @fellow99/node-runtime(ohpm) | harmonypc-electron |
| 上游 dsh 补丁 | 0——配置档 + bundle 层 + 经审计的 shim | 13 个源码补丁 |
| 安装要求 | 无(默认不含 JIT) | JIT 受限权限(ACL) |
| 包体积 | 约 88 MB | Electron 级别(数百 MB) |
| 成熟度 | 0.2.1——已在 HarmonyOS 6.1.0.135(API 24)上实机验证 | 0.2.1——已实机验证(0.2.0 基线) |
两者互不替代:Electron 版换来最高的桌面还原度,代价是打包 Chromium 和 JIT;本版换来小体积和免权限安装,代价是平台差异要在 shim 层补齐。

能力一览

| 领域 | 状态 |
| dsh Web UI、会话、工具、技能、子代理 | ✅ 与上游一致 |
| 文件读 / 写 / 编辑、图片附件 | ✅ |
| 工作区选择器,含 Documents 与 Downloads(授权 → 读写) | ✅ |
| Git(21 个工具,纯 JS,无需 git 二进制) | ✅ |
| 从配置档加载本地插件、自有品牌 | ✅ |
| 命令执行(bash) | ⚠️ 执行器已随包发布;路径解析修复待合入 |
| 内容搜索(grep / glob) | ⚠️ 需要纯 JS 后端(arm64 上没有 ripgrep 二进制) |
| 删除 / 移动 / 复制 / chmod | ⚠️ 上游 ctx.fs 尚无这些原语 |
| 插件市场、托盘图标、窗口状态记忆 | — 本版不含 |

完整对照表——每项能力、两个版本并排、附根因——见 docs/鸿蒙环境能力清单-0.2.1.md。

状态

0.2.1(versionCode 201)——已在真机跑通。在 HarmonyOS 6.1.0.135(API 24,2in1)上验证:零 ACL 安装,载荷自解压并上报 ready,所有 shim 安装成功,node:sqlite/FTS5 可用,文本与图片对话正常,工作区选择器覆盖三个根目录,git clone(公网与内网)可用,品牌窗口正常(经 WebView 调试器确认)。已知缺口及修复点见上面的能力清单。

构建

前置条件:DevEco Command Line Tools(SDK API 24)和同级子模块 ../deepseek-harness。Node 运行时从 OpenHarmony ohpm 中心仓库拉取:@fellow99/node-bridge(API + NAPI 引导)和 @fellow99/node-runtime@24.2.0(libnode.so 引擎,由随包的 runtime.lock.json 做 SHA-256 锁定)。

node scripts/assemble-payload.mjs --deploy --apply # ① materialize the dsh runtime
bash scripts/build-hap.sh # ② ohpm install → payload archive + HAP build/sign
hdc app install -r entry/build/default/outputs/default/entry-default-signed.hap

OHOS_CLT 可覆盖 Command Line Tools 根目录;node scripts/verify-upstream.mjs 校验上游锁定未被破坏(tag、干净工作树、补丁 id、品牌/引导门禁)。

文档

| 文档 | 回答什么 |
| 能力清单 0.2.1 | 哪些能用、哪些不能用,以及与 Electron 版的对比 |
| 工程规划 | 为什么选这套架构、否决了哪些方案、shim 白名单 |
| 真机调试记录 | 真机上出了什么问题、怎么定位的 |
| JIT 与 ACL · 免 JIT 决策 | 两种运行时形态,以及各自的代价 |
| 规格说明 | 11 个规格模块(101–109、204、205),含方案与验收关卡 |

相关项目

- dsh-desktop — 面向 Windows / Linux / macOS 的 Electron 外壳
- dsh-desktop-hos — HarmonyOS Edition 上的 Electron
- @fellow99/node-bridge / @fellow99/node-runtime — 把 Node(node::Start)嵌入进程内的 ohpm 包
- deepseek-harness — 被包装的智能体宿主

许可证

MIT
预览分享卡片长什么样 ↓fellow99/dsh-desktop-ark
分享 · DeepSeek Harness Hub
fellow99/dsh-desktop-ark

DeepSeek Harness(DSH)官方 Web UI 原样运行在 HarmonyOS 2in1 / 平板上的系统 ArkWeb 里,dsh Host 跑在同一进程内嵌的真实 Node.js 运行时上。不用 Electron…

回到顶部