把 DeepSeek Harness 塞进鸿蒙 HAP:架构零改动,只换了运行时
鸿蒙没有官方 Electron,可一个 Electron 写的 Agent 工作台,几乎没改架构跑上了真机——多会话、工具调用、文件读写、插件市场全可用。看完这篇,你拿到可照抄的规划。主线:架构为什么不动、动了什么、鸿蒙逼出什么代价、真机结果。
上篇结尾我立了 flag:把 dsh 搬上鸿蒙真机,这篇兑现。
先泼盆冷水:三层难点
我必须说实话:这是我最「绕」的一次鸿蒙化。 难点分三层。
第一层,系统级差异。 沙箱禁 symlink、禁硬链接,loopback 网络隔离,HAP 打包 5 万小文件会卡死,不是改两行代码能解决的。
第二层,权限。 ACL 审核严格,「二进制证书」个人开发者拿不到,堵死「随包自带 Node / npm / pnpm / Python / pip / uv 等运行时和工具」这条路。
第三层,合规上线。 商标撞名、ArkWeb 合规、AI 资质、APP 备案,一道坎接一道,我还在跑流程。
好在有底牌:harmonypc-electron 已把 Electron(Node + Chromium)跑进鸿蒙 HAP,否则光「跑起 Electron 桌面壳」就得啃 SO 交叉编译、ArkTS 桥接、渲染面三块硬骨头。
真正的问题:怎么既复用 desktop 架构,又扛得住这三层坑?
一、目标:鸿蒙上的一等公民
目标很朴素:让 dsh 在鸿蒙 2in1 / 平板上像一等公民一样运行。
注意,不是「套个浏览器壳指向 localhost」的粗壳——那样只能露个网页,桌面能力插不进来。而是对标 desktop 版:dsh Host 跑在应用进程里,桌面能力直接订阅它的内部事件。
二、为什么架构能不动:同源数据面
搬到鸿蒙,我最担心 desktop 架构还能不能用——能,题眼没变。
说人话:dsh 早已完成 Host/Client 分层,自己起 webserver,同时吐 SPA 页面和 /api 接口。渲染进程加载同一地址,fetch('/api/xxx') 和 WebSocket 就是同源的——零 CORS、零鉴权、零自定义协议、零新增 IPC。
鸿蒙版直接抄 desktop:主进程 runProfile('desktop') 挂起 Host,渲染进程 loadURL 到同一个端口,跑未经修改的标准 dsh Web UI。
架构能不动,靠的是 dsh 当初的分层。
三、唯一动了什么:换运行时
与 desktop 只差一处本质:官方 Electron 换成 Electron-on-鸿蒙运行时(harmonypc-electron)。
| 维度 | desktop | harmony |
|---|---|---|
| 运行时 | 官方 Electron(npm 依赖) | harmonypc-electron(构建期 copy) |
| UI 加载 | loadURL(localhost) 同源 | 同(局域网 IP + Host 改写) |
| 后端进程 | 主进程内 Host | 同 |
| 构建分发 | Electron Forge | hvigor 产 HAP + hdc 安装 |
除运行时和构建外,其余维度同构——「只换壳」。
为什么选它?dsh 依赖 Node 22+ 的 zlib.createZstdDecompress 解压会话产物——说人话,会话产物用 zstd 压缩,解压靠 Node 22 才有的 API;Electron 34 只带 Node 20.18.1,harmonypc-electron 的 Electron 37 / Node 22.17.0 刚好满足。选型就此钉死。
四、4 阶段流水线
鸿蒙不认 Electron Forge,构建拆 4 阶段:
⓪ collect-runtime 同步 Electron-on-鸿蒙运行时
① build-dsh patch + 构建 dsh + dsh-market
② collect-dsh 收集 dsh 产物 + 注入 better-sqlite3 + 写 sharp stub
③ tar 压成 dsh-dist.tar.gz
④ hvigor 构建 + 签名 → HAP
第③步最反直觉:dsh 产物有 5 万多个小文件,hvigor 打包卡死;先压成 约 143MB 的 tar.gz,运行时流式解压。
记住:桌面端一条命令的事,鸿蒙端得先「归一化」成大文件才配进 HAP。
五、补丁从 6 到 14+
构建只是外功,补丁才是内功。desktop 只需 2 个补丁,鸿蒙版规划 6 个,落地涨到 14+ 个——鸿蒙的沙箱和网络模型跟桌面 Linux 不是一回事:
- 沙箱禁 symlink(EACCES)→ dsh 初始化失败,回退 cpSync 递归拷贝
- 沙箱禁硬链接 → 会话日志发布回退 rename
- loopback 网络隔离 → 127.0.0.1 被拦,绑 0.0.0.0 + 走局域网 IP
- 给
ctx.fs补删除 / 写字节 / chmod 原语、lefthook、欢迎页、fsync 兜底……
这些坑后面「适配踩坑」篇逐个展开。记住:补丁数量不是越少越好,它是「鸿蒙跟桌面差异有多大」的直接度量。
六、MVP 取舍:三桩一换
鸿蒙 aarch64 上,dsh 三个原生模块都没有二进制——补丁解决「能不能跑」,取舍解决「先砍什么」:
| 能力 | 依赖 | 取舍 |
|---|---|---|
| 图片附件 | sharp(libvips) | 纯 JS stub(解析容器头,不解码) |
| 终端(bash 工具) | node-pty | 禁用 |
| 进程沙箱 | koffi(landlock) | 禁用 |
| 会话持久化 | better-sqlite3 | ✅ 换用 Electron 37 / ABI v138 成品 |
「三桩一换」:三个能力牺牲,最关键的会话持久化用 better-sqlite3 的 aarch64 成品保住——这是底线。
七、真机验证
带着这套取舍,包装进了真机:鸿蒙 2in1 真机(HarmonyOS 6.1.0.135 / API 24)验证通过,Electron 37 / Node 22.17.0,dsh Host 启动,渲染进程加载 Web UI 成功,多会话、agent、工具调用全可用。
八、写在最后
这就是完整规划:架构抄 desktop,只换运行时,4 阶段构建,14+ 个补丁,三桩一换,真机跑通。
想把 Electron 应用或 Node agent 框架搬进鸿蒙?这套「进程内 Host + 同源数据面 + 换运行时」思路可直接抄。
代码已开源:https://github.com/fellow99/dsh-desktop-hos 。4 阶段脚本、补丁、真机步骤都在里面,点个 star 顺着抄就能跑通。
下一篇我写 Electron-on-鸿蒙运行时拆解:把 Electron 跑进鸿蒙电脑的运行时怎么搭的。关注我,别错过。
相关开源工程:
- DeepSeek Harness(上游项目):https://github.com/deepseek-ai/deepseek-harness
- dsh-market(插件市场):https://github.com/dsh-market/dsh-market
- harmonypc-electron(Electron-on-鸿蒙运行时):https://atomgit.com/jianguoxu/harmonypc-electron.git
- deepseek-harness-workspace(工作区总览):https://github.com/fellow99/deepseek-harness-workspace
- dsh-desktop(桌面端):https://github.com/fellow99/dsh-desktop
- dsh-desktop-hos(鸿蒙端):https://github.com/fellow99/dsh-desktop-hos
感谢各位关注,欢迎访问我的GitHub主页:https://fellow99.github.io/