Dyad 鸿蒙 PC 适配全记录:让本地 AI 应用构建器进入 HarmonyOS PC
欢迎加入开源鸿蒙 PC 社区:https://harmonypc.csdn.net/
欢迎在 PC 社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
适配开源地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_dyad
环境搭建文章:https://blog.csdn.net/lbcyllqj/article/details/161286249?sharetype=blogdetail&sharerId=161286249&sharerefer=PC&sharesource=lbcyllqj&spm=1011.2480.3001.8118
一、为什么选择适配 Dyad
生成式 AI 正在改变桌面开发工具的形态。传统代码助手主要负责补全和问答,而 Dyad 把需求输入、工程创建、代码修改、运行预览、版本管理和模型接入集中到一个本地应用中。用户描述想要的产品后,Dyad 会围绕真实项目目录组织后续工作,而不是只返回一段脱离工程上下文的代码。
这类工具对 HarmonyOS PC 具有两方面价值。一方面,它可以补充面向个人开发者和轻量团队的本地 AI 应用构建能力;另一方面,Dyad 的技术复杂度足以检验 OpenHarmony Electron 运行时在真实桌面应用中的承载能力。它不仅包含 React 页面,还依赖 Electron 主进程、Preload 安全桥、IPC、本地 SQLite 数据库、PTY 终端、Git、Node.js 运行时以及多种外部模型服务。首屏能够显示,只能说明渲染链路已经接通,并不能代表工程导入、终端和预览同样可用。
本次适配基于 Dyad 1.12.0-beta.1,没有将原项目重写为 ArkTS,而是保留现有 React、Vite 和 Electron 业务代码,在外层增加 HarmonyOS HAP 宿主。鸿蒙应用的 Bundle Name 为 com.codex.migrated.dyad,支持 2in1 与 tablet 设备,应用版本与上游保持一致。
二、项目架构与适配路线
Dyad 的桌面端采用典型的 Electron 多进程架构,但主进程承担的职责比普通网页壳更重:数据库初始化、IPC 注册、项目进程管理、Git 操作、终端和应用运行服务都在这一侧完成。适配时必须把这些模块作为一条完整链路处理。
| 层次 | 原项目职责 | HarmonyOS PC 侧处理 |
|---|---|---|
| React 渲染进程 | 首页、聊天、设置、工程管理和预览界面 | 保留 Vite 构建产物,由 Chromium 渲染 |
| Preload | 通过 contextBridge 暴露受控能力 | 随应用资源注入,继续维持安全 IPC 边界 |
| Electron 主进程 | 窗口、IPC、数据库、Git、运行时与进程管理 | 由 OpenHarmony Electron 37.2.1 承载 |
| 原生模块 | better-sqlite3、node-pty 等 Node 扩展 | 面向 aarch64-linux-ohos 重新编译并部署 |
| HAP 宿主 | 原项目不存在 | 新增 Ability、窗口承载、权限、签名与安装包结构 |
适配后的启动链路如下:
EntryAbility
└── OpenHarmony Electron Runtime
└── ohos-main-wrapper.js
├── 加载 platform-openharmony.js
├── 加载 ohos-electron-shims.js
└── 动态导入 app_dist/build/main_bootstrap.js
├── 初始化 better-sqlite3
├── 注册 IPC handlers
├── 创建 BrowserWindow
└── 加载 React 渲染进程
这里有两个关键取舍。第一,平台差异集中在 HAP、wrapper、shim 和少量 process.platform === "openharmony" 分支中,避免长期维护一套独立 UI。第二,不具备鸿蒙等价语义的桌面能力明确降级,例如自动更新改由 HAP 分发体系负责,macOS Dock、Touch Bar、Keychain 和 fsevents 不进入鸿蒙关键路径。
三、鸿蒙适配工程的目录组织
适配内容集中在 dyad-ohos-migration/ 工作区,原有 src/ 业务代码仍保留上游结构。主要目录如下:
ohos_dyad/
├── src/ # React、Electron 主进程与 Preload
├── README.OpenHarmony_CN.md # 仓库内适配说明
└── dyad-ohos-migration/
├── source/ # 用于迁移和构建的源码副本
├── native-build/ # OHOS ARM64 原生模块产物
│ ├── better_sqlite3.node
│ └── pty.node
├── reports/ # 扫描、审计、能力矩阵和真机报告
├── evidence/ # 真机截图与运行日志
└── ohos_hap/
├── AppScope/app.json5 # Bundle、版本、应用名与图标
├── build-profile.json5 # 产品、SDK 与构建配置
├── electron/ # EntryAbility 与 Electron 原生库
└── web_engine/ # Electron 运行时适配层
运行时注入的应用目录中,原项目的 .vite 被改名为 app_dist。这是一个看起来很小、实际十分关键的变化:HAP 打包过程中点目录会被排除,如果仍沿用 .vite/build/main_bootstrap.js,开发机上存在的文件不会进入安装包,真机最终只会得到“找不到主进程入口”的错误。
四、HarmonyOS PC 真机核心流程
以下 5 张截图均在 2026 年 8 月 25 日重新冷启动应用后采集,设备分辨率为 3120×2080。测试过程中先结束旧进程,再通过 aa start 拉起 EntryAbility,随后依次操作首页、系统文件选择器、导入确认、运行时设置和模型提供方设置。
1. 冷启动进入 Dyad 应用创建首页
应用启动后进入“What do you want to build?”首页,需求输入框、Basic Agent、模型入口、AI 连接提示和 Import App 按钮均正常显示。窗口最大化后,React 页面能够随可用空间完成布局,左侧应用、设置、资料库、模板和插件入口保持可见。

这张首页背后已经经过 Ability、libelectron.so、主进程 wrapper、SQLite 初始化、IPC 注册和 BrowserWindow 创建。真机日志中没有出现 ERR_DLOPEN_FAILED、ELF 架构不匹配或主进程入口缺失,说明应用从原生宿主到渲染进程的基础启动链路已经接通。
2. Import App 拉起 HarmonyOS 系统目录选择器
点击 Import App 并选择 Local Folder 后,应用能够调用 HarmonyOS PC 系统目录选择器。测试选择桌面上已经存在的真实 demo 工程,界面明确提示应用仅能访问用户授权的项目。

这一环节验证了 dialog.showOpenDialog 对应的真实系统交互。原项目不能假设自己可以直接遍历用户桌面,文件访问必须经过系统授权;选择器返回的路径随后通过 IPC 交给主进程继续检查。
3. 工程路径、名称和复制策略能够进入导入流程
系统选择完成后,Dyad 正确取得 /storage/Users/currentUser/Desktop/demo,自动填入应用名,并展示复制策略、Advanced options 和 AI_RULES.md 检查结果。为了避开当前沙箱中不可写的默认 dyad-apps 目录,本次实测取消“Copy to the dyad-apps folder”,按原目录导入。

继续点击 Import 后,主进程确实收到 import-app IPC,但数据库映射阶段出现 Cannot mix BigInt and other types。因此当前版本已经完成“系统授权、路径返回、工程检查、参数确认”这一段,尚未完成“写入应用记录并进入工作区”这一段。这个问题与 better-sqlite3 在当前宿主上的整数返回类型有关,不能仅凭导入对话框正常显示就声明完整导入成功。
4. 设置页面能够读取运行模式与 Node.js 状态
进入 Settings 后,主题、语言、缩放、发布通道和 Runtime Mode 均能正常渲染。页面能够读取当前运行时状态,并明确显示 Active: No usable Node.js found,同时提供托管 Node.js 安装和手动浏览入口。

这个状态反映了鸿蒙适配中的另一条边界:Electron 自带的 Node.js 用于主进程执行,并不等同于可供用户工程运行的外部 Node.js。后续要让应用预览和终端形成完整闭环,还需要打通 HarmonyOS PC 上的托管 Node.js 下载、路径识别和子进程启动。
5. 多模型提供方配置界面完整呈现
Model Providers 页面能够列出 OpenAI、Anthropic、Google、Google Vertex AI、OpenRouter、xAI、Azure OpenAI、AWS Bedrock、MiniMax 和自定义提供方入口,并分别标记配置状态。

模型密钥需要用户自行配置,本次截图没有写入任何凭据,也没有把配置页面能够显示等同于外部模型请求已经成功。当前结果证明提供方列表、设置导航和配置入口在鸿蒙渲染进程中可用;模型对话仍取决于合法密钥和真机网络环境。
五、适配过程中最棘手的问题
难点一:主进程入口在 HAP 中被静默排除
Electron Forge 默认将主进程产物放在 .vite/。HAP 打包器会过滤点目录,构建过程本身仍可能成功,但真机启动时找不到 .vite/build/main_bootstrap.js。适配中将目录改为 app_dist,同时修改 wrapper 的动态导入路径,才让主进程代码真正进入 HAP。
难点二:原生模块必须同时满足架构、ABI 和加载路径
Dyad 的 SQLite 和终端分别依赖 better-sqlite3 与 node-pty,macOS 或 Linux 预编译产物不能直接复用。两者使用 HarmonyOS Native SDK 交叉编译为 ELF64 AArch64,分别生成约 1.9 MB 的 better_sqlite3.node 和 85 KB 的 pty.node,再放入 electron/libs/arm64-v8a/。真机代码签名检查和动态加载已经通过,但“模块能加载”仍不等于所有行为兼容:本次导入触发的 BigInt 问题说明数据库读写类型还需要继续收口,PTY 的 spawn 与读写也需要在终端场景中单独验证。
难点三:桌面系统信息调用可能直接导致原生崩溃
应用首次在真机启动时曾在 node::os::GetUserInfo 路径发生 SIGSEGV。原因不是 JavaScript 异常,而是宿主对 os.userInfo()、os.homedir() 的实现无法提供桌面 Node.js 所预期的数据。适配层增加 patchNodeOs(),为鸿蒙沙箱返回安全的用户目录和用户信息,避免主进程在窗口创建前退出。
难点四:桌面目录语义与鸿蒙沙箱并不一致
原项目默认把应用复制到用户主目录下的 dyad-apps。真机返回的逻辑路径为 /storage/Users/currentUser/...,但 Electron 主进程对该默认目标目录没有直接写权限。本次实测中复制模式明确返回“custom apps folder inaccessible”,切换为原目录后才继续进入数据库阶段。后续应让默认应用目录落在可写沙箱,或把目录授权结果持久化后再执行复制。
难点五:平台返回值差异会进入业务数据模型
真机性能监控中,系统 CPU 百分比返回 NaN,设置 Schema 拒绝写入;工程导入中,SQLite 整数又以 BigInt 进入只接受普通 number 的映射逻辑。这两类问题都不会在静态 API 扫描中出现,却会在真实数据流里持续触发。适配不能停留在“方法存在”,还要对每个跨进程、跨原生边界的值做类型归一化和异常兜底。
六、关键适配改动
1. 新增 HAP 宿主与应用配置
AppScope/app.json5 配置 com.codex.migrated.dyad、版本 1.12.0-beta.1、应用图标和多实例上限;module.json5 声明 EntryAbility、2in1/tablet 设备类型,并申请网络与剪贴板读取权限。ArkTS 侧只承担生命周期和窗口承载,业务仍由 Electron 应用处理。
2. 用 wrapper 固定平台补丁的加载顺序
资源目录中的 package.json 将入口指向 ohos-main-wrapper.js。wrapper 先加载 Node.js 与 Electron shim,再导入真实主进程,确保业务代码第一次访问 autoUpdater、Notification、powerMonitor、os.userInfo() 等能力时,平台降级逻辑已经生效。
3. 重建并部署 OHOS ARM64 原生扩展
better_sqlite3.node 和 pty.node 均通过 AArch64 ELF 审计,并同时部署到 HAP 原生库目录和模块的 build/Release 兜底位置。加载器优先使用设备原生库路径,避免依赖桌面端 bindings 对目录结构的假设。
4. 清理不应进入设备的依赖
fsevents 属于 macOS 文件监听能力,直接从注入包移除;dyad-keychain-reader 是 macOS Keychain 专用模块,在鸿蒙上走降级路径;sharp 经依赖分析确认不在 Dyad 自身运行路径中加载,因此没有为不发生的调用引入体积较大的 libvips 工具链。
5. 将平台差异限制在最小范围
源项目只在启动、窗口和路径相关位置增加少量 OpenHarmony 分支。自动更新、Dock、Touch Bar、通知和电源监控等桌面专属能力不伪造成功,统一从核心启动路径退出;React 页面、TanStack Router、TanStack Query 和现有 IPC 语义继续沿用。
七、编译、安装与启动
1. 准备 Electron 项目依赖
Dyad 要求 Node.js 24,并使用 npm 管理依赖。首次准备源码时执行:
npm install
mkdir -p userData
本地开发可通过以下命令确认原始 Electron 应用能够启动:
npm start
2. 构建 HarmonyOS HAP
确认 DevEco Studio 已安装 HarmonyOS API 22 SDK,并完成签名配置。在 dyad-ohos-migration/ohos_hap 目录执行:
export DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk
export OHOS_BASE_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk
/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw \
--mode module \
-p module=electron@default \
-p product=default \
assembleHap --no-daemon
签名产物位于:
dyad-ohos-migration/ohos_hap/electron/build/default/outputs/default/
└── electron-default-signed.hap
3. 安装并在真机启动
hdc list targets
hdc install -r electron-default-signed.hap
hdc shell aa start -a EntryAbility -b com.codex.migrated.dyad
本次设备返回 install bundle successfully 与 start ability successfully。通过 bm dump -n com.codex.migrated.dyad 可确认安装版本为 1.12.0-beta.1、CPU ABI 为 arm64-v8a,应用进程和渲染窗口在操作期间保持运行。
八、当前可用范围与边界
当前版本已经在真机确认以下能力:
- 签名 HAP 可以安装,
EntryAbility可以冷启动; - OpenHarmony Electron 主进程、Preload 和 React UI 可以加载;
BrowserWindow、contextBridge、IPC 注册和窗口事件进入真实启动链路;better-sqlite3.node与pty.node通过设备代码签名和动态加载;- 首页、设置、模型提供方列表和导入对话框能够正常交互;
- HarmonyOS 系统目录选择器能够打开,并返回用户授权的真实工程路径;
- 主题、语言、运行模式、发布通道和 Node.js 状态能够在设置页读取。
仍需注意以下限制:
- 工程导入在数据库映射阶段遇到 BigInt 与 number 混用,尚未进入完整工作区;
- 默认
dyad-apps目标目录在当前沙箱中不可写,需要调整目录策略; - 真机尚未发现可供用户工程使用的 Node.js,因此终端、依赖安装和预览未形成闭环;
node-pty已加载,但 PTY spawn、输入和输出仍需结合真实终端继续验证;- AI 对话依赖用户配置合法的模型服务凭据,本次没有写入或展示密钥;
- 自动更新、macOS Dock、Touch Bar、Keychain、
fsevents、通知和电源监控按平台差异降级; - 性能监控取得的系统 CPU 值可能为
NaN,应在写入设置前归一化; - 当前能力矩阵覆盖 131/156 项,其中仍有需要 UI 交互或终端场景才能完成的验证项。
九、总结
Dyad 的 HarmonyOS PC 适配已经完成从 Electron/Vite 产物注入、HAP 构建签名、原生模块交叉编译,到真机安装启动和 React UI 渲染的主链路。本次重新实测还确认了系统文件选择器、导入参数页、运行时设置和模型提供方页面能够进入真实交互流程。
更重要的是,真机操作把后续工作边界暴露得很清楚:应用记录写入仍受 SQLite 整数类型影响,默认工程目录需要适配沙箱权限,用户项目运行还缺少可用 Node.js,PTY 也需要完成行为级验证。对于这类复杂 Electron 工具,可靠的适配标准不应是“首页亮起来”,而应是窗口、IPC、数据库、文件授权、运行时和外部服务在同一条用户路径上连续工作。当前版本已经具备稳定的鸿蒙宿主和可继续演进的业务基础,下一阶段应优先修复 BigInt 映射与应用目录策略,再打通托管 Node.js、终端和预览闭环。
更多推荐




所有评论(0)