前言
先说结论:在鸿蒙 7 这一代,"改代码 → 编译 → 装机 → 点开 → 看效果"这条链,已经可以完整交给一个不会看屏幕的 Agent 去跑。人手只需要出现在两个地方——第一次登录 AGC,和最后确认那两张真机截图。
我把这条链在 MatePad Pro 上重跑了一遍,每一步的真实输出都留了图。为什么要留图?因为这条链上有三个地方,退出码会骗人:
create缺参数时不告诉你合法格式;build没签名照样BUILD SUCCESSFUL;--hotreload-apply会静静地卡死。
如果你打算让 CI 或者 Agent 替你干活,这三处就是必须写断言的地方。下面按执行顺序走。
先做环境自检
三条命令,顺序无所谓,但必须都在。
| 命令 | 看什么 | 我这次的输出 |
|---|---|---|
devecocli --version |
CLI 是否够新 | 1.3.2(提示可升级到 1.3.4) |
devecocli device list |
序列号 + Kind + Device Type | 平板 device/tablet、nova 12 device/phone |
devecocli auth team list |
团队 ID | 四个团队,挑自己的那个 |
两个细节:
device list里Kind是device才算授权完成。出现unauthorized就是签名 Profile 里没有这台机器的 UDID,跟 USB 线没关系,别去插拔。team list请自己看清楚,别把输出贴进文章或仓库。团队 ID 后面会用到,我这里一律写成30**********70。
第 1 步:create,先在参数上摔两次

第一次失败:Error: --app-name is required。--bundle-name 可以省(自动推导成 com.example.<app-name>),--app-name 反而是必填的。这个反直觉,因为大家习惯先想包名。
第二次失败:cli-demo 不合法。App 名只允许字母开头 + 字母/数字/下划线,连字符不行。这条报错值得夸一句——它把正则用文字写全了,看一眼就能改对。
改成 cli_demo 之后一次过:

生成的骨架只有 6 个顶层条目(AppScope/、entry/、build-profile.json5、code-linter.json5、hvigor/、hvigorfile.ts、oh-package.json5),没有 .gitignore。Agent 在这里要主动补一个,原因马上就会看到。
第 2 步:build 成功,但包是空的
先跑一次 build,故意不配签名。

上半段全是绿的:BUILD SUCCESSFUL in 3 s 167 ms,Build completed successfully.。真正的判据在最后单独一行:
Target device is a real device, but the artifact for 'entry' is not signed.
Real devices cannot install unsigned packages.所以写脚本时,不要拿 build 的退出码当"能装机"的依据。要判断的是 run 的最后一行有没有 start ability successfully。同理,hvigor WARN: Will skip sign 'hos_hap' 这条 WARN 是唯一的早期信号,值得在日志里 grep 一次。
第 3 步:signature generate,一次性的事
devecocli signature generate --product default --team-id 30**********70输出是四行进度 + 两行结果:p12 → csr → certificate → profile,然后 Signing config written to ...\build-profile.json5。

这里有三条硬约束,踩过一次就会记住:
- **Profile 绑 bundleName,也绑设备 UDID 列表。**换一台真机、或者换包名,都要
--force重签。 - **它把密钥口令明文写进
build-profile.json5。**生成完立刻检查.gitignore是否覆盖到签名材料;仓库里绝对不要出现这个文件的 material 段。 - **材料落在
C:\Users\<你>\.ohos\config\下,配置里是绝对路径。**换台机器、换个用户名,这套签名直接失效。别指望把build-profile.json5提交给同事就能跑。
补完签名再 run,这一次才真的落到屏幕上:
Installing artifacts to device 59HYD***2258...
App installed successfully
Launching com.example.hmos7series/EntryAbility...
Application 'com.example.hmos7series': start ability successfully.第 4 步:让 Agent 自己看屏幕
devecocli ui 是这条链上真正的价值所在。它给的不是像素,是一棵带坐标的节点树:
devecocli ui layout --device 59HYD***2258
[0,0,1840,2800]
Stack#ContainerModalStack [0,83,1840,2800]
Text#HelloWorld [622,1349,1218,1474] "Hello World" clickableid、边界框、文本、clickable 全在里面。Agent 拿到的是一句"把 (622,1349)-(1218,1474) 这个可点击节点的中心点敲一下",也就是 ui click 920 1411。敲完再 dump 一次,文本变了、框也变窄了——闭环成立,全程不需要 OCR 一张图。

对应的两张真机截图,这是这条链唯一需要人眼确认的地方:


ui 家族完整能力:layout / screenshot / window / click / doubleclick / longclick / swipe / fling / dircfling / drag / text。三个坑:
screenshot的参数是--path,不是--output;目标文件已存在会拒绝覆盖,脚本里先rm -f。- 多台设备在线时
--device是必填,不填它会自己猜。 fling只吃 4 个坐标参数,速度得走hdc shell uitest uiInput fling ...。
第 5 步:热重载,能用但别依赖它
CLI 有 --hotreload / --hotreload-apply 一对,看着是给 Agent 量身定做的:起一个 watch 会话,之后只推增量。

实测结果分两半。
--hotreload 起会话是好的:BUILD SUCCESSFUL in 5 s 894 ms,HotReloadArkTS 4 s 230 ms,最后明确打印"写 .hvigor/<file> 再到另一个终端 apply"。
--hotreload-apply 我没跑通。第一次报 Hot reload requires --module <name>——它前面刚打印完 Auto-selected module: entry,却又要求你显式传,这个自相矛盾值得留意。补上 --module entry 之后,卡在:
[DaemonClient] Compiling, waiting for hot compile to finish...七分钟没有任何进展,最后我终止了守护进程。顺带在它的构建参数里看到 requiredDeviceType=phone——脚手架生成的 module.json5 里 deviceTypes 默认只有 phone,而目标是一台平板。这条线索我没有继续挖,不能断定是它导致的。
结论很实用主义:**Agent 批量迭代时直接重跑 run。**增量编译只占 3~7 秒,比一个会卡死的守护进程好维护得多。热重载留给"改一行文案反复看"这种人手场景。
把这条链写成断言
上面五步串起来,Agent 侧真正需要的其实只有四条判断。我把它们按"错了会怎样"排在一起,方便直接抄进脚本:
| 断言 | 通过条件 | 失败时的真实现象 |
|---|---|---|
| 工程存在 | create 后 oh-package.json5 可见 |
报 Error 后目录根本不创建,ls 才是唯一可靠判断 |
| 包名合法 | --app-name 匹配 [A-Za-z][A-Za-z0-9_]* |
只打印一句 Failed to create project. |
| 产物已签名 | 日志里不出现 Will skip sign |
装机时最后一行才告诉你没签名 |
| 应用已拉起 | run 输出含 start ability successfully |
退出码 1,但前面的 build 段全是绿的 |
第四条之后还可以再加一条业务断言:ui layout 里目标节点的文本等于预期值。这一步是整条链唯一能证明"功能真的对了"的判据,前面四条只证明"装上了"。
顺带一条经验:ui layout 输出的边界框是 [left,top,right,bottom],不是 x,y,w,h。第一次拿到就把第三个数字当宽度用,点击坐标会飘到屏幕外,而且不报错——只会得到一棵纹丝不动的树,很容易误判成"应用卡死了"。
真机数据
| 环节 | 首次 | 后续(增量) |
|---|---|---|
create |
未计时,生成 6 项骨架 | — |
build |
BUILD SUCCESSFUL in 20 s 805 ms,33 tasks 全执行 |
— |
CompileArkTS |
11 s 433 ms | 424 ms |
PackageHap |
1 s 785 ms | 993 ms |
run(含装机 + 拉起) |
签名后那次编译 6 s 869 ms,26 executed / 7 up-to-date | 未签名那次 3 s 167 ms,18 executed / 15 up-to-date |
ui layout |
未计时,人感"秒回" | 同左 |
--hotreload 会话 |
5 s 894 ms,34 tasks(20 executed) | apply 未完成 |
测试机:MatePad Pro(API 26,1840×2800,序列号已打码)。对照机 nova 12 仅用于验证 device list 的多设备行为。
总结
这条链适合两类活:一是夜间批量回归——Agent 自己 create、自己签名、自己装机、自己点完一圈再截图;二是多设备适配验证,ui layout 的坐标树比人眼快得多。
不适合的是首次接手一台新机器:签名材料绑机器、绑包名、绑 UDID 列表,这一段必须有人登录一次 AGC。把这条规则写进流程,剩下的都可以交给命令。
💡 一句话:
build的退出码不代表能装机,run最后一行的start ability successfully才是;剩下的判断交给ui layout的坐标树,而不是截图。
参考文献
- DevEco Studio 工具概览:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-tools-overview
- @deveco/deveco-cli(npm 包页):https://www.npmjs.com/package/@deveco/deveco-cli
- DevEcoCode 鸿蒙专属 AI 智能体:https://atomgit.com/openharmony-sig/deveco-code