@harmonyos-arkts/d2h 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +36 -180
- package/agents/d2h.md +7 -15
- package/dist/bin/install-opencode.js +12 -0
- package/dist/src/install-opencode.js +66 -3
- package/dist/src/install-vscode.js +3 -2
- package/package.json +1 -1
- package/skills/d2h-page-develop/SKILL.md +1 -1
- package/skills/d2h-page-spec-generate/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -1,213 +1,69 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
Android 应用迁移到 HarmonyOS 的报告驱动 AI 插件,支持 Claude Code 与 OpenCode。
|
|
4
|
-
|
|
5
|
-
插件以 Android 源码、外部依赖和 AppGraph 确定性 facts 为防遗漏基线,由一个主 Agent 持续完成原生 HarmonyOS 实现、测试和端到端验证。迁移报告只记录 Android→HarmonyOS 映射与测试证据,不替代真实实现。
|
|
6
|
-
|
|
7
|
-
## 主流程
|
|
8
|
-
|
|
9
|
-
1. 检查 Android 技术栈、构建基线和设备环境。HarmonyOS HDC 设备是必需门禁;Android 运行环境依赖(SDK/adb/模拟器/Android 侧构建测试)已移除,相关检查固定为 `not_applicable`。
|
|
10
|
-
2. 运行 AppGraph 纯源码静态分析(无需编译 Android 工程),生成只读 `.migration/spec/facts/` 与人工查看的 `spec.html`。
|
|
11
|
-
3. 加载 `appgraph-rule-audit`,只读分析页面、跳转、归属、规则贡献和未解析结果,生成 `.migration/rule-audit/` 规则提升候选;它不修改 facts 或规则,也不阻塞迁移。
|
|
12
|
-
4. 从 facts 初始化 `.migration/report/` 报告分片。
|
|
13
|
-
5. 从 `.migration/spec/` 的 Facts 分片契约 `2.0.0` 与受管 correction/review 编译 `.migration/tasks/`,校验 Launcher、行为闭包、Fact 所有权和 Task DAG。
|
|
14
|
-
6. AI 通过 `task next`/`task show` 在 Resolution 阶段取得裁决 Task,在 Execution 阶段取得一个完整 Page Work Package;以 Android 源码和运行行为为权威持续实现 HarmonyOS 应用。
|
|
15
|
-
7. 每完成一个可验证 Page Work Package,同步填写内部 Work Item/Behavior 的实现映射和测试证据,并创建 Git 检查点。
|
|
16
|
-
8. 在 HarmonyOS 模拟器或真机上执行端到端功能验证。Android 运行时对照能力已移除,一致性基准为 Android 源码、静态 facts 与 `evidence compare` 对既有证据目录的比较;发现 facts 遗漏时写入报告 discoveries。
|
|
17
|
-
9. 使用 Task Plan 与报告门禁检查已知 facts 覆盖;最终完成必须同时满足真实应用验收。
|
|
18
|
-
|
|
19
|
-
Task Planning 的跨仓实现映射、架构图、Agent 生效检查和端到端运行命令见 [`docs/task-planning-implementation-and-runbook.md`](docs/task-planning-implementation-and-runbook.md)。
|
|
20
|
-
Task 从真实入口到提取、闭包、合并、所有权、依赖、推荐和执行的完整原则见 [`docs/task-planning-principles.md`](docs/task-planning-principles.md)。
|
|
21
|
-
|
|
22
|
-
## 保留结构
|
|
23
|
-
|
|
24
|
-
```text
|
|
25
|
-
android-to-hmos-migration/
|
|
26
|
-
├── .claude-plugin/ # Claude Code 插件清单
|
|
27
|
-
├── agents/ # 报告驱动主 Agent
|
|
28
|
-
├── docs/ # 流程与 Task Planning Strategy 设计
|
|
29
|
-
├── opencode/agents.json # OpenCode Agent 权限
|
|
30
|
-
├── schemas/ # facts、报告与 Preflight 契约
|
|
31
|
-
├── skills/ # 工作区准备、工程架构规范、报告、经验和流程复盘
|
|
32
|
-
└── install-opencode.sh # OpenCode Agent/Skill 安装器
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## 安装
|
|
1
|
+
# d2h
|
|
36
2
|
|
|
37
|
-
|
|
3
|
+
`@harmonyos-arkts/d2h` 为 Android 应用迁移到 HarmonyOS 安装 AI Agent、Skill 和配套命令行工具。
|
|
38
4
|
|
|
39
|
-
|
|
40
|
-
npx --yes @harmonyos-arkts/d2h@0.1.11 install --agent opencode
|
|
41
|
-
npx --yes @harmonyos-arkts/d2h@0.1.11 install --agent vscode
|
|
42
|
-
npx --yes @harmonyos-arkts/d2h@0.1.11 install --agent vscode --remote
|
|
43
|
-
npx --yes @harmonyos-arkts/d2h@0.1.11 doctor --agent vscode
|
|
44
|
-
npx --yes @harmonyos-arkts/d2h@0.1.11 upgrade --check
|
|
45
|
-
npx --yes @harmonyos-arkts/d2h@0.1.11 --check-env --output-dir ./environment-report
|
|
46
|
-
```
|
|
5
|
+
安装后,`d2h` Agent 会通过 AppGraph 分析 Android 源码,规划迁移页面与功能,辅助生成 HarmonyOS 实现,并通过 droid2hmos 执行环境检查、构建、测试和迁移报告维护。
|
|
47
6
|
|
|
48
|
-
|
|
7
|
+
## 环境要求
|
|
49
8
|
|
|
50
|
-
|
|
9
|
+
- Node.js 22.5–24.x
|
|
10
|
+
- OpenCode、DevEco Code,或安装了 HarmonyOS Dev Assistant 的 VS Code
|
|
51
11
|
|
|
52
|
-
|
|
53
|
-
/plugin marketplace add D:/code/a2h/android-to-hmos-migration
|
|
54
|
-
/plugin install android-to-hmos-migration@android-to-hmos-migration-local
|
|
55
|
-
```
|
|
12
|
+
## 安装
|
|
56
13
|
|
|
57
|
-
OpenCode
|
|
14
|
+
默认安装到 OpenCode:
|
|
58
15
|
|
|
59
|
-
```
|
|
60
|
-
npx --yes @harmonyos-arkts/d2h@
|
|
16
|
+
```bash
|
|
17
|
+
npx --yes @harmonyos-arkts/d2h@latest install --agent opencode --force
|
|
61
18
|
```
|
|
62
19
|
|
|
63
|
-
|
|
20
|
+
安装到 DevEco Code:
|
|
64
21
|
|
|
65
|
-
```
|
|
66
|
-
npx --yes @harmonyos-arkts/d2h@
|
|
22
|
+
```bash
|
|
23
|
+
npx --yes @harmonyos-arkts/d2h@latest install --agent deveco --force
|
|
67
24
|
```
|
|
68
25
|
|
|
69
|
-
|
|
26
|
+
安装到 VS Code 的 HarmonyOS Dev Assistant:
|
|
70
27
|
|
|
71
|
-
```
|
|
72
|
-
npx --yes @harmonyos-arkts/d2h@
|
|
73
|
-
npx --yes @harmonyos-arkts/d2h@0.1.11 --config-dir /path/to/opencode
|
|
28
|
+
```bash
|
|
29
|
+
npx --yes @harmonyos-arkts/d2h@latest install --agent vscode --force
|
|
74
30
|
```
|
|
75
31
|
|
|
76
|
-
|
|
32
|
+
默认使用本地轻量指标插件 `opencode-metrics-plugin-lite`。需要远端指标能力时增加 `--remote`:
|
|
77
33
|
|
|
78
|
-
```
|
|
79
|
-
npx --yes @harmonyos-arkts/d2h@
|
|
80
|
-
npx --yes @harmonyos-arkts/d2h@0.1.11 --agent deveco --force
|
|
34
|
+
```bash
|
|
35
|
+
npx --yes @harmonyos-arkts/d2h@latest install --agent vscode --force --remote
|
|
81
36
|
```
|
|
82
37
|
|
|
83
|
-
|
|
38
|
+
安装器会安装清单中验证过的 AppGraph 和 droid2hmos 版本,并安装迁移 Skill 和 `d2h` Agent。安装完成后请完全退出并重新启动对应应用。
|
|
84
39
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
从仓库安装仍可使用原 Shell 脚本:
|
|
88
|
-
|
|
89
|
-
```sh
|
|
90
|
-
sh ./install-opencode.sh
|
|
91
|
-
```
|
|
40
|
+
## 检查与升级
|
|
92
41
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
npm 安装器支持同样的参数,完整说明见 `npx --yes @harmonyos-arkts/d2h@0.1.11 --help`。本地开发可使用 `npm run build && node dist/bin/install-opencode.js --source-dir /path/to/repository --link --force`。Windows 下 Agent 文件符号链接需要开发者模式或管理员权限;默认复制模式不需要。不要将 `npx` 缓存作为长期链接来源,缓存清理后链接可能失效。
|
|
96
|
-
|
|
97
|
-
维护者发布:安装开发依赖后运行 `npm run build`,将 TypeScript 源码编译到 `dist/`;`npm run check && npm test` 检查类型并测试编译后的 CLI,然后 `npm publish`。npm 包使用 `dist/bin/install-opencode.js` 作为入口,包含编译后的运行代码、Agent、完整 Skill 资源树及 schema,不包含 TypeScript 源码、研发文档和测试;发布时不会自动修改用户配置,只有显式执行 `npx` 安装器才会安装。
|
|
98
|
-
|
|
99
|
-
完全退出并重新启动 OpenCode 后,选择 `d2h_v2` 执行完整迁移。`android-to-hmos-00-orchestrator` 和 `d2h` 仅为旧名称兼容入口。
|
|
100
|
-
|
|
101
|
-
## 命令
|
|
102
|
-
|
|
103
|
-
```text
|
|
104
|
-
droid2hmos init <android-project> [--target <harmony-project>]
|
|
105
|
-
droid2hmos status <android-project>
|
|
106
|
-
droid2hmos complete <android-project>
|
|
107
|
-
droid2hmos analyze <android|harmony|all> <android-project>
|
|
108
|
-
droid2hmos report init <android-project>
|
|
109
|
-
droid2hmos report validate <android-project> [--require-complete]
|
|
110
|
-
droid2hmos report update <android-project> --ref <ref> [--status <status>] [--harmony-file <path>] [--android-source <path>] [--evidence <path>]
|
|
111
|
-
droid2hmos report <android-project> [--require-complete]
|
|
112
|
-
droid2hmos report render <android-project>
|
|
113
|
-
droid2hmos task plan <android-project>
|
|
114
|
-
droid2hmos task validate <android-project>
|
|
115
|
-
droid2hmos task status <android-project>
|
|
116
|
-
droid2hmos task next <android-project>
|
|
117
|
-
droid2hmos task show <android-project> <task-id> [--cursor <cursor>] [--max-source-context <count>]
|
|
118
|
-
droid2hmos build harmony <android-project>
|
|
119
|
-
droid2hmos test harmony <android-project> --runner python --hypium-project <path> (--test-list <name>...|--all) [--target <id>] [--ref <report-ref>...]
|
|
120
|
-
droid2hmos test harmony <android-project> --class <class> [--case <case>] [--target <id>] [--case-timeout-ms <ms>] [--ref <report-ref>...]
|
|
121
|
-
droid2hmos test harmony <android-project> --all [--target <id>] [--case-timeout-ms <ms>] [--ref <report-ref>...]
|
|
122
|
-
droid2hmos service start <name> <android-project> [--health-url <url>] -- <command> [args...]
|
|
123
|
-
droid2hmos service status <name> <android-project>
|
|
124
|
-
droid2hmos service stop <name> <android-project>
|
|
125
|
-
```
|
|
42
|
+
检查安装和环境:
|
|
126
43
|
|
|
127
|
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
|
|
131
|
-
- `report init`:从 facts 初始化报告 `1.2.0`;存量 `1.1.0` 报告原地升级但不会伪造来源。
|
|
132
|
-
- `report update/validate`:为 implemented/verified 条目强制记录 Android `sourceProvenance`,校验受管成员、文件 hash、可用 Task closure 和 HarmonyOS 路径;项目内事件文件不被当作可信 D1 来源,缺少运行器集成时返回 `unavailable`,D2 抽样只产生 warning。当前不拦截宿主普通文件写入,最高默认证据级别为 `declared-hash-validated`。
|
|
133
|
-
- `report`:校验后生成 `.migration/report/report.html`。HTML 主体面向用户展示迁移结论、未完成内容、下一步、端到端测试、差异和阻塞;页面/控件/导航、内部 ref 与文件映射仅作为默认折叠的技术追溯附录。
|
|
134
|
-
- `task plan/validate`:确定性生成并校验 `.migration/tasks/`;计划基线绑定 Facts、correction/review 和 Android 指纹,并按可观察行为而不是单个 Entry/Issue 聚合责任。
|
|
135
|
-
- `task status/next/show`:只读推导 Task 运行态、选择 Ready Frontier,并按需分页返回源码上下文;不写新的状态机文件。
|
|
136
|
-
- `build harmony`:直接读取 DevEco JSON5 配置生成应用构建命令;Hvigor 增量命中时可复用不早于当前构建输入的非空 HAP,过期产物会失败;`config.json` 不保存 HarmonyOS 构建命令。
|
|
137
|
-
- `test harmony`:确定性构建应用 HAP 并运行 Hypium。迁移流程统一使用 `--runner python --hypium-project <path> --test-list <name>...` 执行 `d2h-hypium-forge` 生成的 `.hypium_forge/` Python 用例(定向执行、无 `--all`,需 `python -m pip install hypium -U`);`--class/--case/--all` 的 ArkTS ohosTest runner 仅用于存量资产。多设备时必须传 `--target`,测试失败、忽略、零执行或缺少结果摘要都会失败。用重复的 `--ref` 声明本次测试实际覆盖的报告项,未覆盖的 `verified` 项不能通过 `complete`。
|
|
138
|
-
|
|
139
|
-
## 核心产物
|
|
140
|
-
|
|
141
|
-
迁移产物统一存放在安卓工程父目录下的独立工作区 `<AndroidProject>-migration/` 中,不再写入安卓工程内部。CLI 在创建 `.migration/` 前会自动在工作区根目录生成 `.gitignore`(内容 `.migration/`),防止迁移产物被上层 Git 仓库提交到远端:
|
|
142
|
-
|
|
143
|
-
```text
|
|
144
|
-
AndroidProject/.migration/
|
|
145
|
-
├── preflight-report.json
|
|
146
|
-
├── spec/
|
|
147
|
-
│ ├── index.json
|
|
148
|
-
│ ├── facts/
|
|
149
|
-
│ └── spec.html
|
|
150
|
-
├── report/
|
|
151
|
-
│ ├── index.json
|
|
152
|
-
│ ├── pages/
|
|
153
|
-
│ ├── interactions/
|
|
154
|
-
│ ├── discoveries.json
|
|
155
|
-
│ ├── summary.json # AI填写的用户总结
|
|
156
|
-
│ ├── final-acceptance.json
|
|
157
|
-
│ ├── validation.json
|
|
158
|
-
│ └── report.html # 脚本生成的用户报告
|
|
159
|
-
├── tasks/
|
|
160
|
-
│ ├── graph.json # droid2hmos 生成的派生 Task DAG
|
|
161
|
-
│ ├── index.json
|
|
162
|
-
│ ├── briefs/*.md
|
|
163
|
-
│ └── acceptance/*.json
|
|
164
|
-
├── evidence/
|
|
165
|
-
│ ├── index.json # 最近一次受管动作证据索引
|
|
166
|
-
│ ├── blobs/<sha256>/ # 完成门禁校验的内容寻址证据产物
|
|
167
|
-
│ └── managed/*.json # 与 facts/源码指纹绑定的 CLI 收据
|
|
168
|
-
├── audit/
|
|
169
|
-
│ ├── source-events.jsonl # 可选可信有序事件输入
|
|
170
|
-
│ ├── android-source-manifest.json # 受管 Android 成员与 hash
|
|
171
|
-
│ ├── checkpoint-provenance.json # 随受管 checkpoint 强制进入 Git commit
|
|
172
|
-
│ ├── source-order-audit.json
|
|
173
|
-
│ └── literal-drift-audit.json
|
|
174
|
-
└── experience/lessons.md
|
|
44
|
+
```bash
|
|
45
|
+
npx --yes @harmonyos-arkts/d2h@latest doctor --agent opencode
|
|
46
|
+
npx --yes @harmonyos-arkts/d2h@latest doctor --agent deveco
|
|
47
|
+
npx --yes @harmonyos-arkts/d2h@latest doctor --agent vscode
|
|
175
48
|
```
|
|
176
49
|
|
|
177
|
-
|
|
50
|
+
查看升级状态并重新安装:
|
|
178
51
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
droid2hmos --version
|
|
183
|
-
droid2hmos --help
|
|
52
|
+
```bash
|
|
53
|
+
npx --yes @harmonyos-arkts/d2h@latest upgrade --check --agent opencode
|
|
54
|
+
npx --yes @harmonyos-arkts/d2h@latest upgrade --agent opencode --force
|
|
184
55
|
```
|
|
185
56
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
Migration Kernel 在独立 CLI 中实现 `inspect → guard → execute → record`:阶段只是解释性快照,AI 仍自主决定批次和实现方式;命令前置条件、失败重试分类、证据新鲜度和最终完成条件由确定性代码检查。正常流程不依赖 AI 猜测“已经到达哪个节点”,也不要求写入 `.migration/state.json`。
|
|
189
|
-
|
|
190
|
-
报告通过只证明已知 facts 有记录,不证明迁移成功。最终标准始终是:HarmonyOS 应用中的所有页面、控件、导航、Dialog 和业务功能与 Android 的外部可观察行为一致,并通过真实设备端到端验证。
|
|
191
|
-
|
|
192
|
-
Windows 下所有 Gradle/Hvigor 测试与构建均由 Preflight 的有限命令运行器执行:禁用 Daemon、禁止输出管道、日志直接落盘并设置超时,避免构建成功后 OpenCode 因继承的输出句柄永久卡死。
|
|
193
|
-
|
|
194
|
-
## AppGraph 静态 UTG
|
|
195
|
-
|
|
196
|
-
AppGraph 与 droid2hmos 的包、精确版本和命令能力只在 `skills/managing-d2h-toolchain/toolchain.json` 中声明。其他 Agent/Skill 直接使用已检查的 CLI,不再维护依赖块;`npm run check` 验证清单与环境约束一致。D2H 安装器与 `managing-d2h-toolchain/scripts/manage-toolchain.mjs` 均使用这份清单;Skill 脚本可在没有 D2H 命令时独立执行。
|
|
197
|
-
|
|
198
|
-
主流程加载 `d2h-utg-static-generate` 完成 Android 静态分析,由 Skill 内部调用 `droid2hmos analyze android` 生成受管 Facts,再复用本次 AppGraph 构建基础 UTG、完成 AI 源码核验与独立修补,统一重建并输出离线 `utg.html`。主流程不另行调用分析 CLI,图生成不重复执行 AppGraph 分析。生成后的原始图和 facts 保持只读,不操作设备。
|
|
199
|
-
|
|
200
|
-
主流程操作步骤见 [Skill 的迁移主流程入口](skills/d2h-utg-static-generate/SKILL.md)。独立生成 UTG 可运行:
|
|
57
|
+
只检查主机环境:
|
|
201
58
|
|
|
202
59
|
```bash
|
|
203
|
-
|
|
60
|
+
npx --yes @harmonyos-arkts/d2h@latest --check-env --output-dir ./environment-report
|
|
204
61
|
```
|
|
205
62
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
验证:
|
|
63
|
+
查看全部参数:
|
|
209
64
|
|
|
210
65
|
```bash
|
|
211
|
-
|
|
212
|
-
python -X utf8 -m unittest discover -s skills/d2h-utg-ai-generate/tests -v
|
|
66
|
+
npx --yes @harmonyos-arkts/d2h@latest --help
|
|
213
67
|
```
|
|
68
|
+
|
|
69
|
+
项目地址:<https://github.com/Harmony-Ai-Tool/android-to-hmos-migration>
|
package/agents/d2h.md
CHANGED
|
@@ -15,7 +15,7 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
|
|
|
15
15
|
|
|
16
16
|
## 产物边界
|
|
17
17
|
|
|
18
|
-
- `.migration/spec/` 中的 Facts
|
|
18
|
+
- `.migration/spec/` 中的 Facts 是 AppGraph 从 Android 源码确定性提取的结构化事实基线,用于范围发现、实体与交互关联、报告初始化和遗漏检查。Facts 可能包含 unresolved 项或存在抽取遗漏,不能替代对 Android 源码及必要运行行为的阅读核验。
|
|
19
19
|
- `.migration/utg/page.json` 是页面、到达路径和导航计划的输入,也是页面 Spec 使用的运行路径依据。
|
|
20
20
|
- `.migration/page-specs/pages.json` 保存 AI 作出的页面范围、顺序、评分和证据决策。
|
|
21
21
|
- 每个 `.migration/page-specs/page_NNNN_<name>-<id>/` 只包含 `spec.md`。不得生成 `ui-design.md`,也不得复制截图或 `view.xml` 到页面包。
|
|
@@ -85,14 +85,14 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
|
|
|
85
85
|
|
|
86
86
|
### 五、逐页代码串行开发
|
|
87
87
|
|
|
88
|
-
加载 `d2h-page-develop
|
|
88
|
+
加载 `d2h-page-develop`,由当前主 Agent 以严格串行方式执行页面开发。任意时刻最多只能有一个页面处于开发或修复状态,页面实现、构建、测试、报告、提交和账本更新不得委派给独立 worker 或其他子 Agent:
|
|
89
89
|
|
|
90
90
|
1. 主 Agent 按 `batch_report.md` 选择顺序最前且未达到 `implemented/passed/passed` 的页面。
|
|
91
|
-
2.
|
|
91
|
+
2. 主 Agent 只处理当前一个页面,不得领取、预研或修改后续页面,并负责执行 `d2h-page-develop` 定义的完整单页闭环。
|
|
92
92
|
3. 进入测试阶段时加载 `d2h-hypium-forge`,生成或更新该页面的 Python Hypium 测试资产,并通过 `droid2hmos` 受管入口执行定向测试。
|
|
93
93
|
4. 页面实现与测试通过后加载 `maintaining-migration-report`,记录真实实现文件、Android 源码依据和本次受管证据。
|
|
94
|
-
5.
|
|
95
|
-
6.
|
|
94
|
+
5. 主 Agent 完成当前页面的实现提交,原位更新 `batch_report.md`,并按 Skill 的页面完成清单复核实现、构建、测试、证据、提交和工作区状态。
|
|
95
|
+
6. 当前页面未闭环、仍有页面所属未提交修改或复核失败时,只能继续修复当前页面。当前页面完整闭环并通过复核后,才能按顺序选择下一页。
|
|
96
96
|
|
|
97
97
|
### 六、批次回归与最终门禁
|
|
98
98
|
|
|
@@ -101,20 +101,13 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
|
|
|
101
101
|
1. 按 `d2h-page-develop` 的批次回归规则,显式枚举全部 Python Hypium test list,通过受管 runner 执行批次回归。Python runner 不使用 `--all`。
|
|
102
102
|
2. 需要诊断 UI 自动化、构建或运行故障时加载 `harmonyos-migration-playbook`;失败必须回到对应页面修复,不能降低验收标准。
|
|
103
103
|
3. 更新并校验迁移报告及 final acceptance。
|
|
104
|
-
4.
|
|
105
|
-
|
|
106
|
-
```text
|
|
107
|
-
droid2hmos test harmony <ANDROID_PROJECT> --runner arkts --all ...
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
5. 执行 `droid2hmos complete <ANDROID_PROJECT>`。只有成功退出后才能宣布迁移完成。
|
|
111
|
-
6. 执行 `droid2hmos report render <ANDROID_PROJECT>` 生成交付报告。
|
|
112
|
-
7. 完整结束或明确中止后加载 `reviewing-migration-process` 生成流程复盘;复盘不是完成条件。
|
|
104
|
+
4. 完整结束或明确中止后加载 `reviewing-migration-process` 生成流程复盘;复盘不是完成条件。
|
|
113
105
|
|
|
114
106
|
## 持续执行与人工介入
|
|
115
107
|
|
|
116
108
|
迁移开始后默认连续执行,不得在页面或阶段之间询问“是否继续”。只有以下情况允许暂停:
|
|
117
109
|
|
|
110
|
+
- 禁止依据模型自行估算的“剩余 token”“上下文百分比”“本轮剩余容量”等决定停止、收尾、汇报后等待或要求用户开启新会话。此类估算不可信。
|
|
118
111
|
- 用户主动中断、修改需求或发出新指令。
|
|
119
112
|
- 真机签名、开发者账号、权限或凭据必须由用户完成,且没有可用替代方案。
|
|
120
113
|
- 设备、CLI、构建环境或外部服务持续不可用,完成自诊和有限重试后仍确认是外部问题。
|
|
@@ -152,6 +145,5 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
|
|
|
152
145
|
- Facts 或 UTG 遗漏、但经源码或运行时发现的行为也已实现并验证。
|
|
153
146
|
- 无法等价的差异已经明确呈现,没有被静默标记为完成。
|
|
154
147
|
- 每个页面实现都有可恢复提交,用户已有和无关改动未被覆盖。
|
|
155
|
-
- ArkTS full-run 和 `droid2hmos complete <ANDROID_PROJECT>` 均成功。
|
|
156
148
|
|
|
157
149
|
完成报告不等于完成迁移;机器门禁成功也不能替代对真实用户可观察结果的 AI 审查。
|
|
@@ -150,6 +150,18 @@ try {
|
|
|
150
150
|
installVSCode({ sourceDir: options.sourceDir, extensionDir, remote, dryRun: options.dryRun });
|
|
151
151
|
else
|
|
152
152
|
installOpenCode({ ...options, remote });
|
|
153
|
+
if (!options.dryRun) {
|
|
154
|
+
const target = options.agent === 'vscode' ? 'VS Code HarmonyOS Dev Assistant' :
|
|
155
|
+
options.agent === 'deveco' ? 'DevEco Code' : 'OpenCode';
|
|
156
|
+
const packageVersion = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8')).version;
|
|
157
|
+
console.log('\n============================================================');
|
|
158
|
+
console.log(`[D2H] Installation successful / 安装成功`);
|
|
159
|
+
console.log(`Target / 目标: ${target}`);
|
|
160
|
+
console.log(`Version / 版本: ${packageVersion}`);
|
|
161
|
+
console.log('Agent: d2h');
|
|
162
|
+
console.log(`Next / 下一步: restart ${target}, then select the d2h Agent.`);
|
|
163
|
+
console.log('============================================================');
|
|
164
|
+
}
|
|
153
165
|
}
|
|
154
166
|
}
|
|
155
167
|
}
|
|
@@ -41,6 +41,57 @@ function digest(file) {
|
|
|
41
41
|
hash.update(name).update(digest(path.join(file, name)));
|
|
42
42
|
return hash.digest('hex');
|
|
43
43
|
}
|
|
44
|
+
function parseJsonConfig(source) {
|
|
45
|
+
let output = '';
|
|
46
|
+
let quoted = false;
|
|
47
|
+
let escaped = false;
|
|
48
|
+
for (let index = 0; index < source.length; index++) {
|
|
49
|
+
const character = source[index];
|
|
50
|
+
if (quoted) {
|
|
51
|
+
output += character;
|
|
52
|
+
if (escaped)
|
|
53
|
+
escaped = false;
|
|
54
|
+
else if (character === '\\')
|
|
55
|
+
escaped = true;
|
|
56
|
+
else if (character === '"')
|
|
57
|
+
quoted = false;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (character === '"') {
|
|
61
|
+
quoted = true;
|
|
62
|
+
output += character;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (character === '/' && source[index + 1] === '/') {
|
|
66
|
+
while (index < source.length && source[index] !== '\n')
|
|
67
|
+
index++;
|
|
68
|
+
output += '\n';
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (character === '/' && source[index + 1] === '*') {
|
|
72
|
+
index += 2;
|
|
73
|
+
while (index < source.length && !(source[index] === '*' && source[index + 1] === '/'))
|
|
74
|
+
index++;
|
|
75
|
+
index++;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
output += character;
|
|
79
|
+
}
|
|
80
|
+
return JSON.parse(output.replace(/,\s*([}\]])/g, '$1'));
|
|
81
|
+
}
|
|
82
|
+
function configFileFor(root, agent) {
|
|
83
|
+
return path.join(root, agent === 'deveco' ? 'deveco.jsonc' : 'opencode.json');
|
|
84
|
+
}
|
|
85
|
+
function updateAgentConfig(config, remote) {
|
|
86
|
+
updateMetricsPlugin(config, remote);
|
|
87
|
+
config.agent ??= {};
|
|
88
|
+
const previous = config.agent.d2h ?? {};
|
|
89
|
+
config.agent.d2h = {
|
|
90
|
+
...previous,
|
|
91
|
+
tools: { ...previous.tools, read: true, write: true, edit: true, bash: true },
|
|
92
|
+
permission: { ...previous.permission, edit: 'allow', bash: 'allow', external_directory: 'allow' },
|
|
93
|
+
};
|
|
94
|
+
}
|
|
44
95
|
export function inspectInstallation(configDir) {
|
|
45
96
|
const root = path.resolve(configDir);
|
|
46
97
|
const receipt = path.join(root, '.d2h-installation.json');
|
|
@@ -55,6 +106,18 @@ export function inspectInstallation(configDir) {
|
|
|
55
106
|
const target = path.join(root, entry.kind, entry.name);
|
|
56
107
|
return !stat(target) || digest(target) !== entry.digest;
|
|
57
108
|
}).map(entry => `${entry.kind}/${entry.name}`);
|
|
109
|
+
const configFile = configFileFor(root, value.agent);
|
|
110
|
+
try {
|
|
111
|
+
const config = parseJsonConfig(fs.readFileSync(configFile, 'utf8'));
|
|
112
|
+
const d2h = config.agent?.d2h;
|
|
113
|
+
if (!d2h || !['read', 'write', 'edit', 'bash'].every(tool => d2h.tools?.[tool] === true) ||
|
|
114
|
+
!['edit', 'bash', 'external_directory'].every(permission => d2h.permission?.[permission] === 'allow')) {
|
|
115
|
+
changed.push(path.basename(configFile));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
changed.push(path.basename(configFile));
|
|
120
|
+
}
|
|
58
121
|
return { status: changed.length ? 'failed' : 'passed', packageVersion: value.packageVersion, agent: value.agent,
|
|
59
122
|
summary: changed.length ? `changed or missing: ${changed.join(', ')}` : `${value.entries.length} installed definitions verified` };
|
|
60
123
|
}
|
|
@@ -81,12 +144,12 @@ export function installOpenCode({ sourceDir, configDir, agent = 'opencode', link
|
|
|
81
144
|
contains(sourceRoot, configRoot) || contains(configRoot, sourceRoot)) {
|
|
82
145
|
throw new Error(`refusing unsafe OpenCode config directory: ${configDir}`);
|
|
83
146
|
}
|
|
84
|
-
const configFile =
|
|
147
|
+
const configFile = configFileFor(configRoot, agent);
|
|
85
148
|
const existingConfig = stat(configFile);
|
|
86
149
|
if (existingConfig?.isSymbolicLink())
|
|
87
150
|
throw new Error(`refusing linked OpenCode config file: ${configFile}`);
|
|
88
|
-
const config = existingConfig ?
|
|
89
|
-
|
|
151
|
+
const config = existingConfig ? parseJsonConfig(fs.readFileSync(configFile, 'utf8')) : {};
|
|
152
|
+
updateAgentConfig(config, remote);
|
|
90
153
|
const configText = JSON.stringify(config, null, 2) + '\n';
|
|
91
154
|
const entries = [];
|
|
92
155
|
for (const kind of ['skills', 'agents']) {
|
|
@@ -77,8 +77,9 @@ function updateConfig(source, remote) {
|
|
|
77
77
|
const value = JSON.parse(source);
|
|
78
78
|
value.agent ??= {};
|
|
79
79
|
value.agent.d2h = { ...value.agent.d2h, description: modeLabel,
|
|
80
|
-
tools: { ...value.agent.d2h?.tools, read: true, write: true, edit: true },
|
|
81
|
-
permission: { ...value.agent.d2h?.permission, read: 'allow', edit: 'allow'
|
|
80
|
+
tools: { ...value.agent.d2h?.tools, read: true, write: true, edit: true, bash: true },
|
|
81
|
+
permission: { ...value.agent.d2h?.permission, read: 'allow', edit: 'allow',
|
|
82
|
+
bash: 'allow', external_directory: 'allow' } };
|
|
82
83
|
delete value.agent.d2h.permission.write;
|
|
83
84
|
value.plugin ??= [];
|
|
84
85
|
if (!Array.isArray(value.plugin))
|
package/package.json
CHANGED
|
@@ -105,7 +105,7 @@ After every page task is complete:
|
|
|
105
105
|
2. Run one managed command with all required `--test-list` values on the qualified device, using only refs actually asserted by the batch.
|
|
106
106
|
3. Require non-zero execution with no failures, errors, or ignored tests.
|
|
107
107
|
4. Append the managed batch evidence and timestamp to `batch_report.md`, then update and validate the migration report.
|
|
108
|
-
5.
|
|
108
|
+
5. Treat this managed Python batch as the primary application-wide regression for the page-spec workflow. Run ArkTS `--all` only as supplemental coverage when the project maintains relevant ArkTS ohosTest assets; it is not a fixed completion gate for this workflow.
|
|
109
109
|
|
|
110
110
|
## Final result
|
|
111
111
|
|
|
@@ -21,7 +21,7 @@ Resolve these paths before writing:
|
|
|
21
21
|
- `legacy_tasks_root`: optional `<migration_root>/.migration/tasks`; use existing briefs, core facts, source context, and acceptance files only as read-only evidence from an older flow.
|
|
22
22
|
- `output_root`: default `<migration_root>/.migration/page-specs`.
|
|
23
23
|
|
|
24
|
-
Facts and
|
|
24
|
+
Facts are the deterministic structured evidence baseline extracted from Android source. They support scope discovery, entity and interaction linkage, report initialization, and omission checks, but unresolved items and extraction gaps mean they are not substitutes for reading Android source and, where necessary, observing runtime behavior. Legacy Task artifacts are read-only indexes from the older flow. Existing HarmonyOS files and tests are implementation evidence, not proof that a behavior is complete.
|
|
25
25
|
|
|
26
26
|
## Output contract
|
|
27
27
|
|