@harmonyos-arkts/d2h 0.1.15 → 0.1.17

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "android-to-hmos-migration",
3
3
  "description": "基于确定性 facts、迁移报告与端到端验证的 Android 到 HarmonyOS 迁移插件",
4
- "version": "0.1.15",
4
+ "version": "0.1.17",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "android",
package/AGENTS.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Android to HarmonyOS Migration
2
2
 
3
- 处理迁移请求时,由当前正式主 Agent `agents/d2h_v2.md` 统一编排专项 Skill。`agents/android-to-hmos-00-orchestrator.md` 和 `agents/d2h.md` 仅保留旧名称兼容,不是规则真源。
3
+ 处理迁移请求时,由当前正式主 Agent `agents/d2h.md` 统一编排专项 Skill。`agents/android-to-hmos-00-orchestrator.md`仅保留旧名称兼容,不是规则真源。
4
4
 
5
5
  以真实 HarmonyOS 应用质量为目标,以 AppGraph facts 和迁移报告降低遗漏风险。不要恢复已废弃的旧 SPEC/PLAN/TASK 多 Agent 文档流程或静态转译器;当前使用的 Kernel Task Plan(`droid2hmos task plan/validate/next/show` 派生计划)属于 Migration Kernel 协议,不在此列。
@@ -72,6 +72,7 @@ description: Android 应用到 HarmonyOS 的结果驱动迁移主 Agent,以完
72
72
 
73
73
  - 图片/图形资源转换 skill:`android2hmos_resources_convert`(res/ 图片资产 → `media/`、XML drawable → SVG、自适应图标 → layered-image)。需要 Preflight 已创建或复用的 HarmonyOS 工程
74
74
  - 安卓/鸿蒙三方库映射关系 skill:`native-library-substitution`
75
+ - 云侧权威知识查询 skill:`d2h-cloud-knowledge`。当当前实现的功能涉及不确定的 @kit.* Kit / @ohos.* 模块 API、ArkUI 组件行为或平台能力(相机/定位/文件/通知/蓝牙/分享/Web/后台任务等)、构建或测试失败指向 API 签名与行为、或需核验已选型 ohpm 库用法时加载。先查 `.migration/knowledge/kb_cache.json` 缓存,命中不重查;结论以文档 `title`/`uri` 引用回 spec 与迁移报告。本地文档、`harmonyos-migration-playbook` 已验证经验或其他专项 skill 能解决时不加载。
75
76
 
76
77
  Skill 是当前工作的操作说明,不替代本 Agent 的目标、判断和持续执行责任。读取一个 Skill 后只使用与当前阶段直接相关的内容。
77
78
 
@@ -109,7 +110,8 @@ Skill 是当前工作的操作说明,不替代本 Agent 的目标、判断和
109
110
  - App 名称、图标、版本号、包名等身份信息迁移 → `arkts-app-identity`;
110
111
  - 用户可见文案与多语言资源迁移 → `arkts-i18n`;
111
112
  - 图标/图片尺寸失真校准 → `arkts-icon-sizing`;
112
- - Android 三方库依赖的鸿蒙替代映射 → `native-library-substitution`。
113
+ - Android 三方库依赖的鸿蒙替代映射 → `native-library-substitution`;
114
+ - 平台能力实现、不确定的 @kit.* Kit / @ohos.* 模块 API、ArkUI 组件行为,或构建/测试失败分诊需核对 API 权威签名、权限、错误码 → `d2h-cloud-knowledge`(先查 `.migration/knowledge/kb_cache.json`,结论回写缓存并在 spec/报告引用文档 uri)。
113
115
  7. 小步运行构建和应用验证,按以下分组规则建立与使用测试:
114
116
 
115
117
  **测试政策**
package/agents/d2h.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: d2h
3
- description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁移场景加载专项 Skill,完成页面规划、逐页开发、受管验证和最终交付闭环。
3
+ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁移场景加载专项 Skill,完成页面规划、逐页开发、Forge 测试验收和最终交付闭环。
4
4
  ---
5
5
 
6
6
  # Android to HarmonyOS Migration Agent
@@ -11,16 +11,16 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
11
11
 
12
12
  必须覆盖所有页面、可见控件和状态、导航与 Dialog 流程、业务功能,以及影响行为的资源和配置。Android 源码与真实运行行为决定“做什么”,HarmonyOS 原生机制决定“怎么做”。无法等价的差异必须明确记录,不能静默省略或伪装成完成。
13
13
 
14
- 迁移由 AI 读取 Facts、`.migration/utg/page.json`、Android 源码、HarmonyOS 代码、迁移报告和受管执行证据后作出决策。禁止使用 Migration Kernel 的任务规划子命令或静态任务脚本代替 AI 进行页面拆分、任务选择和开发调度。
14
+ 迁移由 AI 读取 Facts、`.migration/utg/page.json`、页面 Spec、`batch_report.md`、Android 源码、HarmonyOS 代码和实际测试结果后作出决策。禁止使用 Migration Kernel 的任务规划子命令或静态任务脚本代替 AI 进行页面拆分、任务选择和开发调度。
15
15
 
16
16
  ## 产物边界
17
17
 
18
- - `.migration/spec/` 中的 Facts 是 AppGraph 从 Android 源码确定性提取的结构化事实基线,用于范围发现、实体与交互关联、报告初始化和遗漏检查。Facts 可能包含 unresolved 项或存在抽取遗漏,不能替代对 Android 源码及必要运行行为的阅读核验。
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` 到页面包。
22
- - `.migration/page-specs/batch_report.md` 是可变执行账本。初始账本由 `d2h-page-spec-generate` 使用 `build_batch_report.py` 从 `pages.json` 生成;开发开始后由 AI 原位维护,不得重新生成并覆盖历史。
23
- - 报告、Spec、测试文件和状态字段都是辅助证据,不是应用实现本身。只存在于文档、注释、桩代码或不可达文件中的能力均视为未完成。
22
+ - `.migration/page-specs/batch_report.md` 是页面进度、实现与证据引用、差异和最终回归结论的统一账本。初始账本由 `d2h-page-spec-generate` 使用 `build_batch_report.py` 从 `pages.json` 生成;开发开始后由 AI 原位维护,不得重新生成并覆盖历史。
23
+ - Spec、账本、测试文件和状态字段都是辅助证据,不是应用实现本身。只存在于文档、注释、桩代码或不可达文件中的能力均视为未完成。
24
24
 
25
25
  ## 场景与 Skill 路由
26
26
 
@@ -31,7 +31,6 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
31
31
  | 开始或恢复迁移,定位工程、准备工具链、读取状态、执行 Preflight、检查设备 | `preparing-migration-workspace` |
32
32
  | 从 Android 源码生成或刷新 Facts、UTG、点击路径和 `.migration/utg/page.json` | `d2h-utg-static-generate` |
33
33
  | 需要 AI 修复源码派生 UTG,或在 Android 设备上按已有计划采集运行时证据 | `d2h-utg-ai-generate` |
34
- | 初始化、更新或校验迁移报告 | `maintaining-migration-report` |
35
34
  | 根据 Facts、`.migration/utg/page.json` 和源码生成 `pages.json`、逐页 `spec.md` 与初始 `batch_report.md` | `d2h-page-spec-generate` |
36
35
  | 按 `batch_report.md` 串行完成单页面实现、构建、测试、提交和账本更新 | `d2h-page-develop` |
37
36
  | 规划或编写 ArkTS 架构、状态、导航和页面代码 | `arkts-mvvm-architecture` |
@@ -41,10 +40,15 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
41
40
  | 转换 Android 图片、XML drawable 和自适应图标 | `android2hmos_resources_convert` |
42
41
  | 修复 HarmonyOS 图片或图标尺寸、比例失真 | `arkts-icon-sizing` |
43
42
  | 诊断 ArkTS 构建、运行时、UI 自动化或迁移验证故障 | `harmonyos-migration-playbook` |
43
+ | 实现涉及不确定的 @kit.* Kit / @ohos.* 模块 API、ArkUI 组件行为或平台能力(相机/定位/文件/通知/蓝牙/分享/Web/后台任务等),构建/测试失败需核对 API 签名、权限、错误码,或核验已选型 ohpm 库用法 | `d2h-cloud-knowledge` |
44
44
  | 迁移完整结束或本次运行明确中止后复盘流程 | `reviewing-migration-process` |
45
45
  | 首次安装、工具缺失、版本/能力不符或主动升级 | `managing-d2h-toolchain` |
46
46
 
47
- 若一个步骤同时命中多个场景,加载最小必要 Skill 组合。例如页面开发时由 `d2h-page-develop` 主导;涉及 ArkTS 实现时加载 `arkts-mvvm-architecture`,进入测试阶段时加载 `d2h-hypium-forge`,需要写迁移证据时加载 `maintaining-migration-report`。专项 Skill 的领域结果不能单独证明页面或整次迁移完成。
47
+ 若一个步骤同时命中多个场景,加载最小必要 Skill 组合。例如页面开发时由 `d2h-page-develop` 主导;涉及 ArkTS 实现时加载 `arkts-mvvm-architecture`,进入测试阶段时加载 `d2h-hypium-forge`。实现和测试证据由主 Agent 直接记录到 `batch_report.md`。专项 Skill 的领域结果不能单独证明页面或整次迁移完成。
48
+
49
+ 本流程的测试执行统一由 `d2h-hypium-forge` 负责,`batch_report.md` 记录其实际结果和证据路径,主 Agent 对照 Spec 和设备行为决定验收。
50
+
51
+ 加载 `d2h-cloud-knowledge` 时先查 `.migration/knowledge/kb_cache.json` 缓存,命中不重查;结论以文档 `title`/`uri` 引用回页面 Spec 与 `batch_report.md`。本地文档、`harmonyos-migration-playbook` 已验证经验或其他专项 Skill 能解决时不加载该 Skill。
48
52
 
49
53
  ## 迁移流程
50
54
 
@@ -56,12 +60,11 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
56
60
 
57
61
  设备暂不可用时可以继续静态分析、页面规划和不依赖设备的实现,但交互页面不能标记为验证通过,也不能进入最终完成门禁。
58
62
 
59
- ### 二、Android 分析与报告初始化
63
+ ### 二、Android 分析与范围核对
60
64
 
61
65
  1. 加载 `d2h-utg-static-generate`,生成或刷新 Facts、UTG、点击路径和 `.migration/utg/page.json`,并对照真实 Android 源码核验页面、入口、交互、数据流和 unresolved 项。
62
66
  2. 需要修复 UTG 或有 Android 设备可用于运行时采集时,加载 `d2h-utg-ai-generate`。运行时证据留在该 Skill 定义的位置,不复制进页面 Spec 包。
63
- 3. 加载 `maintaining-migration-report` 初始化或安全更新迁移报告。
64
- 4. Facts 或 UTG 未覆盖、但源码中真实存在的行为仍须纳入迁移范围。
67
+ 3. Facts 或 UTG 未覆盖、但源码中真实存在的行为仍须纳入页面 Spec,并在 `batch_report.md` 中记录发现与处理情况。
65
68
 
66
69
  ### 三、HarmonyOS 工程与公共能力
67
70
 
@@ -85,22 +88,24 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
85
88
 
86
89
  ### 五、逐页代码串行开发
87
90
 
88
- 加载 `d2h-page-develop`,由当前主 Agent 以严格串行方式执行页面开发。任意时刻最多只能有一个页面处于开发或修复状态,页面实现、构建、测试、报告、提交和账本更新不得委派给独立 worker 或其他子 Agent:
91
+ 加载 `d2h-page-develop`,以严格串行方式执行页面开发。任意时刻最多只能有一个页面处于开发或修复状态,禁止并行开发多个页面,也禁止一次向 worker 派发多个页面:
89
92
 
90
93
  1. 主 Agent 按 `batch_report.md` 选择顺序最前且未达到 `implemented/passed/passed` 的页面。
91
- 2. 主 Agent 只处理当前一个页面,不得领取、预研或修改后续页面,并负责执行 `d2h-page-develop` 定义的完整单页闭环。
92
- 3. 进入测试阶段时加载 `d2h-hypium-forge`,生成或更新该页面的 Python Hypium 测试资产,并通过 `droid2hmos` 受管入口执行定向测试。
93
- 4. 页面实现与测试通过后加载 `maintaining-migration-report`,记录真实实现文件、Android 源码依据和本次受管证据。
94
+ 2. 只派发一个独立 page-worker,且该 worker 只负责当前一个页面。worker 必须加载 `d2h-page-develop`,不得领取、预研或修改后续页面。
95
+ 3. 进入测试阶段时加载 `d2h-hypium-forge`,生成或更新该页面的 Python Hypium 测试资产。先确认本次构建的 HAP 已安装到目标设备,再按该 Skill 执行当前页面及受影响功能的定向测试,保留实际结果、日志和必要截图。主 Agent 核对执行用例及其断言是否覆盖 Spec 功能项,不能仅凭进程退出码或汇总文案判定通过。
96
+ 4. 页面实现与测试通过后,在 `batch_report.md` 当前页面明细中记录真实实现文件、Android 源码依据、本次构建与 Forge 测试的实际结果及证据路径,以及差异或阻塞。未产出或未保存的结果、日志如实记录为缺失,不得填写假定存在的路径或据此标记通过。
94
97
  5. 主 Agent 完成当前页面的实现提交,原位更新 `batch_report.md`,并按 Skill 的页面完成清单复核实现、构建、测试、证据、提交和工作区状态。
95
- 6. 当前页面未闭环、仍有页面所属未提交修改或复核失败时,只能继续修复当前页面。当前页面完整闭环并通过复核后,才能按顺序选择下一页。
98
+ 6. 前页面未闭环、仍有页面所属未提交修改或复核失败时,只能继续修复当前页面。当前页面完整闭环并通过主 Agent 复核后,才能按顺序选择并派发下一页。
99
+
100
+ 若当前环境不支持独立 page-worker,必须明确报告该开发模式无法执行,不能静默改成主 Agent 批量开发。
96
101
 
97
102
  ### 六、批次回归与最终门禁
98
103
 
99
104
  全部页面达到 `implemented/passed/passed` 后:
100
105
 
101
- 1. 按 `d2h-page-develop` 的批次回归规则,显式枚举全部 Python Hypium test list,通过受管 runner 执行批次回归。Python runner 不使用 `--all`。
106
+ 1. 加载 `d2h-hypium-forge`,在已安装当前 HAP 的目标设备上执行覆盖全部迁移范围内功能场景的完整 Python Hypium 回归,保留本次实际执行结果和日志。核对用例范围、执行数和各项状态;零执行、失败、错误或必测场景被跳过、未执行时均不能通过,历史 PASS 不能替代本次完整回归。
102
107
  2. 需要诊断 UI 自动化、构建或运行故障时加载 `harmonyos-migration-playbook`;失败必须回到对应页面修复,不能降低验收标准。
103
- 3. 更新并校验迁移报告及 final acceptance。
108
+ 3. 主 Agent 对照各页 Spec、源码、实际实现和设备结果完成行为审查,将结论、被测 HAP 与设备、完整回归结果和实际证据路径、差异及未解决问题记录到 `batch_report.md` 的批次回归部分。直接核对账本队列、页面明细、汇总和引用证据的一致性,满足完成条件后才能宣布迁移完成。
104
109
  4. 完整结束或明确中止后加载 `reviewing-migration-process` 生成流程复盘;复盘不是完成条件。
105
110
 
106
111
  ## 持续执行与人工介入
@@ -119,14 +124,14 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
119
124
 
120
125
  以下任一情况都视为未完成:
121
126
 
122
- - 报告、Spec 或账本写着完成,但实现只有注释、空函数、固定值或桩数据。
127
+ - Spec 或账本写着完成,但实现只有注释、空函数、固定值或桩数据。
123
128
  - 页面文件存在,但不能从真实 Ability、导航或 Android 对应控件到达。
124
129
  - 为通过测试新增替代控件,而 Android 对应控件仍无正确行为。
125
130
  - 只证明编译、安装、启动、不白屏或截图相似,没有验证交互与业务结果。
126
131
  - 只覆盖 Facts 或 UTG,忽略源码或运行时中真实存在的页面、入口和业务逻辑。
127
132
  - 测试只写未跑,或使用旧证据、无关 refs、空执行结果冒充通过。
128
133
  - 使用坐标点击替代可语义定位控件的正式 Hypium 验收。
129
- - 把实现缺陷包装成外部 blocker,或用报告说明代替修复。
134
+ - 把实现缺陷包装成外部 blocker,或用账本说明代替修复。
130
135
  - 静态脚本、清单或状态字段宣称通过,但 AI 尚未核对真实源码、代码路径和设备结果。
131
136
 
132
137
  判断原则始终是:用户在 HarmonyOS 应用中实际看到、操作和获得的结果是否与 Android 一致。
@@ -135,15 +140,16 @@ description: Android 应用到 HarmonyOS 的 AI 驱动迁移主 Agent;按迁
135
140
 
136
141
  只有同时满足以下条件,才允许宣布迁移完成:
137
142
 
138
- - Preflight、Facts、UTG、迁移报告和证据对应当前源码。
143
+ - Preflight、Facts、UTG、页面 Spec、`batch_report.md` 和证据对应当前源码。
139
144
  - `pages.json` 覆盖全部已知页面或明确记录排除原因。
140
145
  - 每个已知页面、Dialog、Sheet 和关键模式都有唯一 `spec.md`,页面包中没有额外产物。
141
146
  - `batch_report.md` 覆盖全部页面,且所有任务均为 `implemented/passed/passed`,没有未解决阻塞。
142
- - 所有 Spec 功能项都有真实、可达的 HarmonyOS 实现和当前受管测试证据。
143
- - HarmonyOS 工程构建、安装、启动成功;全部 Python Hypium test list 的批次回归通过。
147
+ - 所有 Spec 功能项都有真实、可达的 HarmonyOS 实现。
148
+ - HarmonyOS 工程构建、安装、启动成功;当前 HAP 的 Forge 完整回归通过,没有失败、错误或必测场景未执行。
149
+ - `batch_report.md` 已记录最终行为审查、完整回归结论及实际证据路径,队列、页面明细和汇总一致。
144
150
  - 所有页面、可见控件、状态、导航、Dialog、业务功能、数据效果和错误路径均真实实现。
145
151
  - Facts 或 UTG 遗漏、但经源码或运行时发现的行为也已实现并验证。
146
152
  - 无法等价的差异已经明确呈现,没有被静默标记为完成。
147
153
  - 每个页面实现都有可恢复提交,用户已有和无关改动未被覆盖。
148
154
 
149
- 完成报告不等于完成迁移;机器门禁成功也不能替代对真实用户可观察结果的 AI 审查。
155
+ 账本状态、编译成功或测试汇总都不能替代对真实用户可观察结果的 AI 审查。
@@ -20,21 +20,38 @@ node scripts/check-environment.mjs --output-dir ~/reports/hmos-environment
20
20
 
21
21
  ## 当前检查项
22
22
 
23
+ 检查结果分为运行环境、鸿蒙工具链和迁移场景依赖三组。JSON 中保留原有检查 ID,并为每项增加 `category`;DevEco 项还记录安装类型、安装根目录和识别来源。
24
+
25
+ ### 运行环境
26
+
23
27
  | 项目 | 条件 |
24
28
  | --- | --- |
25
- | Node.js | 当前运行时为 24.x |
29
+ | Node.js | 当前运行时满足配置的版本范围 |
26
30
  | Git | git --version 成功 |
27
31
  | npm | npm --version 成功 |
28
- | Java/JDK | java -version 成功,不固定 JDK 主版本 |
29
32
  | Python | 找到 Python 3.10+,优先 PYTHON_BINARY |
30
- | AppGraph | appgraph --version 成功且匹配 D2H 锁定的 0.0.11 |
31
- | droid2hmos | droid2hmos --version 成功且匹配 D2H 锁定的 0.0.12 |
32
- | DevEco 工具链目录 | 安装目录存在 |
33
+
34
+ ### 鸿蒙工具链
35
+
36
+ DevEco Studio 或 HarmonyOS Command Line Tools 任一存在,即认为 DevEco 父项已安装。报告会区分 `studio`、`command-line-tools`、`studio-and-command-line-tools` 和 `missing`,并继续显示可用子工具的版本。
37
+
38
+ | 项目 | 条件 |
39
+ | --- | --- |
40
+ | DevEco 工具链 | DevEco Studio 或 HarmonyOS Command Line Tools 安装目录存在 |
41
+ | Java/JDK | 优先 JAVA_HOME 和 PATH,再检查 DevEco 内置 JBR/JDK;java -version 成功 |
33
42
  | Hvigor | 版本命令成功 |
34
43
  | ohpm | 版本命令成功 |
35
- | DevEco CLI | devecocli --version 成功 |
36
- | 开发者账号 | DevEco CLI 登录状态成功,报告不保留账号输出 |
37
44
  | HarmonyOS SDK 目录 | 辅助诊断,不作为必需门禁 |
45
+ | DevEco CLI | devecocli --version 成功 |
46
+ | 开发者账号 | DevEco CLI 登录状态成功;CLI 缺失时跳过,报告不保留账号输出 |
47
+
48
+ ### 迁移场景依赖
49
+
50
+ | 项目 | 条件 |
51
+ | --- | --- |
52
+ | AppGraph | appgraph --version 成功且匹配 D2H 锁定的 0.0.11 |
53
+ | droid2hmos | droid2hmos --version 成功且匹配 D2H 锁定的 0.0.12 |
54
+ | Android 源码根目录 | 传入 --android-project 时包含 Gradle 配置标记 |
38
55
 
39
56
  按需检查:指定插件生产脚本导入 json5 时检查相同 Python 的 json5 模块;传入 --android-project 时检查源码 Gradle 配置标记;传入 --harmony-project 时枚举工程可用 SDK 版本。
40
57
 
@@ -65,11 +82,11 @@ npx --yes @harmonyos-arkts/d2h@0.1.5 --check-env --requirements ./environment-re
65
82
 
66
83
  不再提供 --host、--host-binary、--skip-devices 参数。
67
84
 
68
- 工具环境变量:DEVECO_STUDIO_HOME、DEVECO_HOME、DROID2HMOS_HVIGOR、DROID2HMOS_OHPM、DEVECO_CLI_BINARY、PYTHON_BINARY、HARMONYOS_SDK_HOME、OHOS_SDK_HOME、DEVECO_SDK_HOME。macOS 包含 DevEco 默认 Contents 目录和常见 Python 安装路径。
85
+ 工具环境变量:DEVECO_STUDIO_HOME、DEVECO_HOME、JAVA_HOME、DROID2HMOS_HVIGOR、DROID2HMOS_OHPM、DEVECO_CLI_BINARY、PYTHON_BINARY、HARMONYOS_SDK_HOME、OHOS_SDK_HOME、DEVECO_SDK_HOME。macOS 包含 DevEco 默认 Contents 目录和常见 Python 安装路径。
69
86
 
70
87
  ## 输出
71
88
 
72
- 命令行先显示总体结果,然后逐项显示 `[通过]`、`[未通过]`、`[提醒]` 或 `[未检查]` 及版本/原因。未通过、提醒和未检查项下方直接显示修复指导,最后显示报告路径。完整明细、证据和修复指导保存在 environment.md/environment.json,重复执行覆盖。脚本只提供指导,不自动安装或修改环境。
89
+ 命令行先显示总体结果,再按“运行环境”“鸿蒙工具链”“迁移场景依赖”分组显示 `[通过]`、`[未通过]`、`[提醒]` 或 `[未检查]` 及版本/原因。未通过、提醒和未检查项下方直接显示修复指导,最后显示报告路径。完整明细、证据、分类、DevEco 安装信息和修复指导保存在 environment.md/environment.json,重复执行覆盖。脚本只提供指导,不自动安装或修改环境。
73
90
 
74
91
  退出码:0=必需检查通过;1=必需失败或执行错误;2=必需项未检查或参数错误。SDK 辅助诊断 warning 不阻断通过。
75
92
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harmonyos-arkts/d2h",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Install Android-to-HarmonyOS migration agents and skills into OpenCode or DevEco Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,6 +8,18 @@ import { parseArgs } from 'node:util';
8
8
 
9
9
  const DEFAULT_REQUIREMENTS = fileURLToPath(new URL('../skills/managing-d2h-toolchain/environment-requirements.json', import.meta.url));
10
10
  const VERSION_TOOLS = ['node', 'python', 'git', 'npm', 'java', 'python-json5', 'appgraph', 'droid2hmos', 'hvigor', 'ohpm', 'devecocli'];
11
+ const CATEGORY_LABELS = {
12
+ runtime: '运行环境',
13
+ 'harmony-toolchain': '鸿蒙工具链',
14
+ 'migration-capabilities': '迁移场景依赖',
15
+ };
16
+ const CHECK_CATEGORIES = {
17
+ node: 'runtime', npm: 'runtime', git: 'runtime', python: 'runtime', 'python-json5': 'runtime',
18
+ deveco: 'harmony-toolchain', java: 'harmony-toolchain', hvigor: 'harmony-toolchain', ohpm: 'harmony-toolchain',
19
+ 'harmony-sdk-location': 'harmony-toolchain', 'harmony-sdk-compatibility': 'harmony-toolchain',
20
+ devecocli: 'harmony-toolchain', 'devecocli-auth': 'harmony-toolchain',
21
+ appgraph: 'migration-capabilities', droid2hmos: 'migration-capabilities', 'android-source-root': 'migration-capabilities',
22
+ };
11
23
 
12
24
  function versionParts(value) {
13
25
  if (typeof value !== 'string' || !/^\d+(?:\.\d+){0,3}$/.test(value)) throw new Error(`无效版本:${value}`);
@@ -169,9 +181,27 @@ export function pythonJson5Required(source) {
169
181
  }
170
182
 
171
183
  export function parseDevEcoJson(output) {
172
- // DevEco CLI 1.3.3 appends its updater notice to stdout even with --format json.
173
- // Strip only that known trailing line; unrelated malformed output still fails.
174
- return JSON.parse(output.replace(/\r?\n\s*New version [\w.+-]+ available, run `devecocli update` to upgrade\s*$/, '').trim());
184
+ // DevEco CLI 会在 --format json 输出前后追加非 JSON 文本(如升级提示
185
+ // "New version 1.3.5 available, run `devecocli update` to upgrade",措辞随版本变化)。
186
+ // 整体解析失败时回退提取最外层 JSON 值再解析;完全不含 JSON 才失败。
187
+ // 与 droid2hmos src/commands/deveco-cli.ts parseJson 保持同一策略。
188
+ const trimmed = String(output).trim();
189
+ try {
190
+ return JSON.parse(trimmed);
191
+ } catch (error) {
192
+ const start = trimmed.search(/[[{]/);
193
+ if (start >= 0) {
194
+ const close = trimmed[start] === '[' ? ']' : '}';
195
+ const end = trimmed.lastIndexOf(close);
196
+ if (end > start) {
197
+ try {
198
+ return JSON.parse(trimmed.slice(start, end + 1));
199
+ } catch { /* fall through */
200
+ }
201
+ }
202
+ }
203
+ throw error;
204
+ }
175
205
  }
176
206
 
177
207
  export async function collect(options, { runner = probe, env = process.env, platform = process.platform, home = os.homedir(), directoryFinder = firstDirectory, nodeVersion = process.version } = {}) {
@@ -179,24 +209,27 @@ export async function collect(options, { runner = probe, env = process.env, plat
179
209
  const requirements = loadRequirements(requirementsFile);
180
210
  const ruleFor = id => requirements.tools[id];
181
211
  const checks = [];
182
- const add = (id, required, passed, summary, remediation = '', evidence = [], skipped = false) => {
183
- checks.push({ id, required, status: skipped ? 'skipped' : passed ? 'passed' : required ? 'failed' : 'warning', summary,
184
- remediation: passed ? '' : remediation, evidence });
212
+ const add = (id, required, passed, summary, remediation = '', evidence = [], skipped = false, details = {}) => {
213
+ checks.push({ id, category: CHECK_CATEGORIES[id] || 'migration-capabilities', required,
214
+ status: skipped ? 'skipped' : passed ? 'passed' : required ? 'failed' : 'warning', summary,
215
+ remediation: passed ? '' : remediation, evidence, ...details });
185
216
  };
186
217
  const tool = async (id, executable, params, remediation, predicate = () => true) => {
187
218
  const result = await runner(executable, params, options.timeout);
188
219
  const rule = ruleFor(id);
189
220
  const passed = result.ok && predicate(result.output) && meetsVersionRule(result.output, rule, id);
190
- const summary = result.output.split(/\r?\n/)[0] || result.error || '命令未成功';
221
+ const missing = /(?:ENOENT|not found|无法找到|找不到)/i.test(`${result.error || ''}\n${result.output || ''}`);
222
+ const summary = missing ? `未找到 ${id}` : result.output.split(/\r?\n/)[0] || result.error || '命令未成功';
223
+ const version = result.output.match(/\d+\.\d+(?:\.\d+){0,2}/)?.[0];
191
224
  add(id, true, passed, `${summary}${rule ? `(要求 ${constraintLabel(rule)})` : ''}`,
192
- `${remediation}${rule ? ` 版本须满足 ${constraintLabel(rule)}。` : ''}`, [result]);
225
+ `${remediation}${rule ? ` 版本须满足 ${constraintLabel(rule)}。` : ''}`, [result], false,
226
+ { executable, ...(version ? { version } : {}) });
193
227
  return result;
194
228
  };
195
229
  add('node', true, meetsVersionRule(nodeVersion, ruleFor('node')), `${nodeVersion} (${process.execPath})(要求 ${constraintLabel(ruleFor('node'))})`,
196
230
  `请安装满足 ${constraintLabel(ruleFor('node'))} 的 Node.js,然后重新运行脚本。`);
197
231
  await tool('git', 'git', ['--version'], '安装 Git 并将 git 加入 PATH。');
198
232
  await tool('npm', 'npm', ['--version'], '使用 Node.js 自带的 npm,检查 PATH。');
199
- await tool('java', 'java', ['-version'], '安装项目 Gradle/DevEco 所需 JDK,设置 JAVA_HOME 和 PATH;本检查不限定 JDK 主版本。');
200
233
  // Python is a migration dependency, no longer a prerequisite to run this doctor.
201
234
  const candidates = [...new Set([env.PYTHON_BINARY, platform === 'win32' ? 'python' : 'python3', 'python',
202
235
  platform === 'darwin' ? '/opt/homebrew/bin/python3' : null, platform === 'darwin' ? '/usr/local/bin/python3' : null,
@@ -221,26 +254,66 @@ export async function collect(options, { runner = probe, env = process.env, plat
221
254
  for (const name of ['appgraph', 'droid2hmos']) {
222
255
  await tool(name, name, ['--version'], '运行 managing-d2h-toolchain Skill 中的 node scripts/manage-toolchain.mjs install 安装精确版本;本地 npm link 需由开发者显式管理。');
223
256
  }
224
- const deveco = directoryFinder([env.DEVECO_STUDIO_HOME, env.DEVECO_HOME,
257
+ const studio = directoryFinder([env.DEVECO_STUDIO_HOME,
225
258
  platform === 'darwin' ? '/Applications/DevEco-Studio.app/Contents' : null,
226
259
  ...(platform === 'win32' ? ['C:/Program Files/Huawei/DevEco Studio', 'D:/Program Files/Huawei/DevEco Studio'] : [])]);
227
- add('deveco', true, Boolean(deveco), deveco || '未找到 DevEco Studio', '安装 DevEco Studio,设置 DEVECO_STUDIO_HOME 为安装根目录(macOS 为 Contents)。');
228
- for (const [id, variable, relative, fallback] of [
229
- ['hvigor', 'DROID2HMOS_HVIGOR', 'tools/hvigor/bin/hvigorw.js', 'hvigorw'],
230
- ['ohpm', 'DROID2HMOS_OHPM', 'tools/ohpm/bin/pm-cli.js', 'ohpm'],
231
- ]) {
232
- const bundled = deveco && path.join(deveco, relative);
233
- await tool(id, env[variable] || (isFile(bundled) ? bundled : fallback), ['--version'], `安装 DevEco 配套工具;设置 ${variable} 为可执行文件或 JS 入口路径。`);
260
+ const commandLineTools = directoryFinder([env.DEVECO_HOME,
261
+ ...(platform === 'win32' ? ['C:/Huawei/command-line-tools', 'D:/HarmonyOS/command-line-tools'] : [])]);
262
+ const deveco = studio || commandLineTools;
263
+ const installationType = studio && commandLineTools ? 'studio-and-command-line-tools' : studio ? 'studio' : commandLineTools ? 'command-line-tools' : 'missing';
264
+ const installationLabel = { studio: 'DevEco Studio', 'command-line-tools': 'HarmonyOS Command Line Tools',
265
+ 'studio-and-command-line-tools': 'DevEco Studio 和 HarmonyOS Command Line Tools' }[installationType];
266
+ add('deveco', true, Boolean(deveco), deveco ? `${installationLabel}:${[studio, commandLineTools].filter(Boolean).join(';')}` : '未找到 DevEco Studio 或 HarmonyOS Command Line Tools',
267
+ '安装 DevEco Studio 或 HarmonyOS Command Line Tools,并设置 DEVECO_STUDIO_HOME 或 DEVECO_HOME(macOS 的 DevEco Studio 根目录为 Contents)。',
268
+ [], false, { installation: { type: installationType, studioRoot: studio, commandLineToolsRoot: commandLineTools,
269
+ detectedBy: studio === env.DEVECO_STUDIO_HOME ? 'DEVECO_STUDIO_HOME' : commandLineTools === env.DEVECO_HOME ? 'DEVECO_HOME' : deveco ? 'default-location' : null } });
270
+ if (deveco) {
271
+ const javaCandidates = [...new Set([
272
+ env.JAVA_HOME && path.join(env.JAVA_HOME, 'bin', platform === 'win32' ? 'java.exe' : 'java'),
273
+ 'java',
274
+ ...[studio, commandLineTools].filter(Boolean).flatMap(root => [
275
+ path.join(root, 'jbr', 'bin', platform === 'win32' ? 'java.exe' : 'java'),
276
+ path.join(root, 'jbr', 'Contents', 'Home', 'bin', 'java'),
277
+ ]).filter(isFile),
278
+ ].filter(Boolean))];
279
+ let javaResult = null;
280
+ let javaExecutable = null;
281
+ for (const candidate of javaCandidates) {
282
+ const result = await runner(candidate, ['-version'], options.timeout);
283
+ if (result.ok && meetsVersionRule(result.output, ruleFor('java'), 'java')) { javaResult = result; javaExecutable = candidate; break; }
284
+ javaResult ??= result;
285
+ }
286
+ const javaRule = ruleFor('java');
287
+ const javaVersion = javaResult?.output.match(/\d+\.\d+(?:\.\d+){0,2}/)?.[0];
288
+ add('java', true, Boolean(javaExecutable), javaExecutable ? `${javaResult.output.split(/\r?\n/)[0]} (${javaExecutable})` : '未找到可用的 Java/JDK',
289
+ `配置 JAVA_HOME,或检查 DevEco 内置 JBR/JDK${javaRule ? `;版本须满足 ${constraintLabel(javaRule)}` : ''}。`, javaResult ? [javaResult] : [], false,
290
+ { relatedTo: ['deveco', 'hvigor'], ...(javaExecutable ? { executable: javaExecutable } : {}), ...(javaVersion ? { version: javaVersion } : {}) });
291
+ for (const [id, variable, relative, fallback] of [
292
+ ['hvigor', 'DROID2HMOS_HVIGOR', 'tools/hvigor/bin/hvigorw.js', 'hvigorw'],
293
+ ['ohpm', 'DROID2HMOS_OHPM', 'tools/ohpm/bin/pm-cli.js', 'ohpm'],
294
+ ]) {
295
+ const bundled = [studio, commandLineTools].filter(Boolean).map(root => path.join(root, relative)).find(isFile);
296
+ await tool(id, env[variable] || bundled || fallback, ['--version'], `安装 DevEco 配套工具;设置 ${variable} 为可执行文件或 JS 入口路径。`);
297
+ }
298
+ const sdk = directoryFinder([options.sdkPath, env.HARMONYOS_SDK_HOME, env.OHOS_SDK_HOME, env.DEVECO_SDK_HOME, path.join(deveco, 'sdk')]);
299
+ add('harmony-sdk-location', false, Boolean(sdk), sdk || '未发现声明 SDK 根目录', '设置 HARMONYOS_SDK_HOME 或 --sdk-path;实际声明有效性由 droid2hmos preflight 检查。');
300
+ } else {
301
+ for (const id of ['java', 'hvigor', 'ohpm', 'harmony-sdk-location']) {
302
+ add(id, id !== 'harmony-sdk-location', false, '等待鸿蒙基础工具链配置', '', [], true,
303
+ id === 'java' ? { relatedTo: ['deveco', 'hvigor'] } : {});
304
+ }
234
305
  }
235
- const sdk = directoryFinder([options.sdkPath, env.HARMONYOS_SDK_HOME, env.OHOS_SDK_HOME, env.DEVECO_SDK_HOME, deveco && path.join(deveco, 'sdk')]);
236
- add('harmony-sdk-location', false, Boolean(sdk), sdk || '未发现声明 SDK 根目录', '设置 HARMONYOS_SDK_HOME 或 --sdk-path;实际声明有效性由 droid2hmos preflight 检查。');
237
306
  const cli = env.DEVECO_CLI_BINARY || 'devecocli';
238
- await tool('devecocli', cli, ['--version'], '安装 npm install -g @deveco/deveco-cli。');
239
- const auth = await runner(cli, ['auth', 'status'], options.timeout);
240
- const loggedIn = auth.ok && /Current user:\s*[^\r\n]+/i.test(auth.output) && !/Not logged in/i.test(auth.output);
241
- add('devecocli-auth', true, loggedIn, loggedIn ? '已登录' : '未登录或无法确认登录状态',
242
- '运行 droid2hmos auth login <android-project>,在浏览器完成授权;不要并发登录。',
243
- [{ command: auth.command, exitCode: auth.exitCode, error: auth.error }]);
307
+ const cliProbe = await tool('devecocli', cli, ['--version'], '安装 npm install -g @deveco/deveco-cli。');
308
+ if (cliProbe.ok) {
309
+ const auth = await runner(cli, ['auth', 'status'], options.timeout);
310
+ const loggedIn = auth.ok && /Current user:\s*[^\r\n]+/i.test(auth.output) && !/Not logged in/i.test(auth.output);
311
+ add('devecocli-auth', true, loggedIn, loggedIn ? '已登录' : '未登录或无法确认登录状态',
312
+ '运行 droid2hmos auth login <android-project>,在浏览器完成授权;不要并发登录。',
313
+ [{ command: auth.command, exitCode: auth.exitCode, error: auth.error }]);
314
+ } else {
315
+ add('devecocli-auth', true, false, '未检查:devecocli 不可用', '先安装 devecocli,再重新运行环境检查。', [], true);
316
+ }
244
317
  if (options.harmonyProject) {
245
318
  const project = path.resolve(options.harmonyProject);
246
319
  const versions = await runner(cli, ['check', 'compat', 'versions', '--format', 'json'], options.timeout, { cwd: project });
@@ -264,9 +337,11 @@ export async function collect(options, { runner = probe, env = process.env, plat
264
337
 
265
338
  export function markdown(report) {
266
339
  const escape = (value) => String(value).replaceAll('|', '\\|').replaceAll('\r', '').replaceAll('\n', '<br>');
267
- return ['# Android → HarmonyOS 环境检查', '', `结果:**${report.result}**`, '', report.scope, '', `版本配置:${report.requirementsFile || ''}`, '',
340
+ const sections = Object.entries(CATEGORY_LABELS).flatMap(([category, label]) => ['', `## ${label}`, '',
268
341
  '| 检查 | 必需 | 状态 | 说明 |', '| --- | --- | --- | --- |',
269
- ...report.checks.map((c) => `| ${c.id} | ${c.required ? '是' : '否'} | ${c.status} | ${escape(c.summary)} |`),
342
+ ...report.checks.filter(c => c.category === category).map((c) => `| ${c.id} | ${c.required ? '是' : '否'} | ${c.status} | ${escape(c.summary)} |`)]);
343
+ return ['# Android → HarmonyOS 环境检查', '', `结果:**${report.result}**`, '', report.scope, '', `版本配置:${report.requirementsFile || ''}`,
344
+ ...sections,
270
345
  '', '## 修复指导', '', ...report.checks.filter((c) => c.remediation).map((c) => `- **${c.id}**:${c.remediation}`), '',
271
346
  '修复后重新运行本脚本。主机检查通过后,运行 `droid2hmos preflight <android-project>` 验证真实项目门禁;该命令可能初始化工程并执行构建。', ''].join('\n');
272
347
  }
@@ -305,10 +380,13 @@ export async function main(argv = process.argv.slice(2)) {
305
380
  const resultLabel = { passed: '通过', failed: '未通过', incomplete: '未完成' }[report.result];
306
381
  console.log(`环境检查:${resultLabel}(通过 ${passed},失败 ${failures.length}${warnings ? `,提醒 ${warnings}` : ''}${skipped ? `,未检查 ${skipped}` : ''})`);
307
382
  const statusLabels = { passed: '通过', failed: '未通过', warning: '提醒', skipped: '未检查' };
308
- for (const check of report.checks) {
309
- console.log(`[${statusLabels[check.status] || check.status}] ${check.id}:${check.summary}`);
310
- if (check.status !== 'passed' && check.remediation) {
311
- console.log(` 修复:${check.remediation}`);
383
+ for (const [category, label] of Object.entries(CATEGORY_LABELS)) {
384
+ console.log(`\n${label}`);
385
+ for (const check of report.checks.filter(item => item.category === category)) {
386
+ console.log(`[${statusLabels[check.status] || check.status}] ${check.id}:${check.summary}`);
387
+ if (check.status !== 'passed' && check.remediation) {
388
+ console.log(` 修复:${check.remediation}`);
389
+ }
312
390
  }
313
391
  }
314
392
  console.log(`详细报告:${path.join(options.outputDir, 'environment.md')}`);
@@ -0,0 +1,129 @@
1
+ ---
2
+ name: d2h-cloud-knowledge
3
+ description: >-
4
+ D2h 迁移过程中的华为开发者云侧知识库查询技能。在 Android 转 HarmonyOS 迁移的各环节,
5
+ 根据当前正在实现的功能(平台能力、HarmonyOS API(@kit.* Kit 导入或 @ohos.* 模块)、ArkUI 组件行为、
6
+ 三方库用法)主动查询权威依据,
7
+ 提升转换质量与效率。适用于:页面 spec 生成时的能力可行性核对、页面实现前的 API 签名/参数/权限/
8
+ 错误码核对、构建与测试失败分诊中涉及的 API 行为确认、三方库(ohpm)用法与注意事项核验、
9
+ 系统能力支持范围确认。查询词从当前 Android 功能语义(类名/能力/行为)构造。
10
+ 无需注册 MCP 服务或初始化握手;先查本地缓存,未命中先搜索摘要,信息不足再取全文;
11
+ 结论以文档 title/uri 引用回 spec 与迁移报告。本地文档或其他专项 skill 能解决时不使用本技能。
12
+ version: 1.3.0
13
+ ---
14
+ # 云侧知识库查询(HarmonyOS Developer Knowledge)
15
+
16
+ 在 D2h 迁移过程中,当当前实现的功能涉及不确定的 HarmonyOS API、平台能力或三方库用法时,通过 Shell 用 Node.js `fetch` 直接发送 HTTP POST 查询华为开发者知识库,**无需注册 MCP 服务或执行初始化握手**。
17
+
18
+ ## 目标
19
+
20
+ 1. 把云侧查询绑定到**当前正在迁移的功能**:从 Android 源码证据(类名、权限、行为)构造查询词,获取权威实现依据,而不是凭印象写 API。
21
+ 2. 控制成本:先查本地缓存(`kb_cache.json`),未命中先搜摘要(`content`),确实相关再取全文;单功能点预算 ≤2 次 search、≤3 篇全文。
22
+ 3. 结论可追溯:以文档 `title`/`uri` 引用回页面 spec、迁移报告或失败分诊记录;同一主题查询一次、跨页面复用。
23
+
24
+ ## 迁移流程中的触发时机
25
+
26
+ 在 D2h 主流程的以下环节,命中即按需加载本技能(同一功能不重复查询):
27
+
28
+ | 环节 | 触发条件 | 查什么 |
29
+ |------|----------|--------|
30
+ | 页面 spec 生成(`d2h-page-spec-generate`) | spec 标记了平台能力项(相机/定位/文件/通知/蓝牙/分享/Web/后台任务等) | 该能力对应 Kit/API 是否可用、是否受系统能力限制,写入 spec 依据 |
31
+ | 页面实现前(`d2h-page-develop` 步骤 1-2) | 功能清单(F-xxx)中存在平台能力或不确定的 @kit.* Kit / @ohos.* 模块 API | API 签名、参数/返回值、所需权限、错误码、推荐用法与指南 |
32
+ | 页面实现中 | 不确定 ArkUI 组件/属性行为(如 Tabs、Swiper、手势、懒加载) | 开发指南与 FAQ 中的权威行为描述 |
33
+ | 构建失败分诊 | 编译错误指向 @kit.* / @ohos.* API 签名、类型、import 模块名 | 核对该 API 的真实签名与起始版本,避免臆造签名反复试错 |
34
+ | 测试失败分诊(`d2h-hypium-forge`) | 运行时行为与预期不符、错误码/权限弹窗原因不明 | API 行为约束、错误码含义、权限申请时序 |
35
+ | 三方库替换后核验(`native-library-substitution` 已选型) | 已确定替代库,需要确认用法 | 所选 ohpm 库的开发指南、已知限制、实践样例 |
36
+
37
+ 优先级与边界(先走更合适的通道,本技能兜底权威依据):
38
+
39
+ - 本地工程文档能确定答案 → `deveco-cli docs`,不发起云侧查询。
40
+ - 已验证的迁移失败教训 → `harmonyos-migration-playbook` 命中即用,不重查云侧。
41
+ - 三方库**选型**(Android 库 → 鸿蒙库映射)→ `native-library-substitution`;本技能只负责所选库的**用法核验**。
42
+
43
+ ## 从当前功能构造查询词
44
+
45
+ 查询词 = **Android 侧证据 + 期望行为 + HarmonyOS 术语**,两步走:
46
+
47
+ 1. 探索(尚不知对应 API):用「开发场景 + 想实现的行为」,可带 Android 类名提高召回,例如 `选择文件并读取内容 ContentResolver`、`后台下载续传 WorkManager`。
48
+ 2. 精查(已知 Kit/模块/API/权限/错误码):把它直接放进 query;Kit 名与 @ohos 模块名均可作精查词,官方文档两种写法都会出现,组合使用召回更好,例如 `FilePicker DocumentViewPicker`、`CameraKit @ohos.multimedia.camera photoAccessHelper 拍照`。
49
+
50
+ 常用 Android → HarmonyOS 术语对照(用于构造查询词和对照检索结果,**不作为实现结论,结论以检索到的文档为准**):
51
+
52
+ | Android 侧 | HarmonyOS 检索词 |
53
+ |------------|------------------|
54
+ | Activity / Fragment | UIAbility / Navigation |
55
+ | SharedPreferences | @ohos.data.preferences |
56
+ | ContentProvider / ContentResolver | DataShare / FilePicker |
57
+ | CameraX / Camera2 | CameraKit @ohos.multimedia.camera |
58
+ | FusedLocationProvider | LocationKit geoLocationManager |
59
+ | Notification / NotificationChannel | NotificationKit @ohos.notification |
60
+ | WebView | Web 组件 @ohos.web.webview |
61
+ | Bitmap / Canvas | PixelMap / Canvas @ohos.graphics.drawing |
62
+ | OkHttp / Retrofit | @ohos.net.http / Remote Communication Kit rcp |
63
+ | Glide / Coil | ImageKnife(ohpm) |
64
+ | WorkManager / JobScheduler | BackgroundTasksKit 后台任务 |
65
+ | RecyclerView / DiffUtil | List / Grid / LazyForEach |
66
+
67
+ ## 知识缓存(跨页面复用)
68
+
69
+ 维护 `.migration/knowledge/kb_cache.json`(工作缓存,非受管证据;建议随页面 ledger 一并提交以便跨会话复用)。顶层为 `topics` 对象,按功能 slug 作 key(如 `file-picker`、`camera-capture`),每个条目包含字段:
70
+
71
+ - `query`:产生该结论的查询词;`date`:查询日期。
72
+ - `conclusion`:结论摘要(API/Kit、支持范围、权限、关键约束)。
73
+ - `docs[]`:引用文档列表,每项含 `parent`、`title`、`uri`。
74
+ - `usedBy[]`:使用该结论的页面/任务 ID 列表。
75
+
76
+ 规则:
77
+
78
+ - 实现前先按主题查缓存(key 用功能 slug,如 `file-picker`、`camera-capture`);命中直接复用结论与文档引用,不重查。
79
+ - 未命中才发起云侧查询;拿到结论后立即写入缓存,并在 `usedBy` 登记当前页面/任务。
80
+ - 缓存中的结论仅是摘要;实现时仍以 `docs` 里的全文为准,摘要与全文冲突时更新缓存。
81
+
82
+ ## 请求基础
83
+
84
+ - 请求地址:`https://connect-api.cloud.huawei.com/api/developerknowledge/mcp`(本技能唯一域名)
85
+ - 每次请求超时:**30 秒**。
86
+ - 固定请求头:`x-gray-flag: 1`、`Content-Type: application/json`、`Accept: application/json, text/event-stream`、`sceneName: app2harmony`(D2h 应用转换场景专用标识,脚本内已内置)。
87
+
88
+ ## 通用请求脚本
89
+
90
+ 脚本已随本技能打包为 `skills/d2h-cloud-knowledge/kb_query.mjs`(OpenCode 安装后位于 `~/.config/opencode/skills/d2h-cloud-knowledge/kb_query.mjs`)。首次使用时复制到 `<MIGRATION_ROOT>/.migration/knowledge/` 后一直复用,不要手抄重写,也不要绕过脚本手写 curl/JSON-RPC:
91
+
92
+ - `node kb_query.mjs search "<query>"`:摘要检索(searchDocuments),输出每条结果的 `parent`(文档标识)与 `content`(摘要)。
93
+ - `node kb_query.mjs doc "<parent1,parent2>"`:读取全文(getDocumentsById),输出全文条目的 `name`/`title`/`uri`/`content`,多个 `parent` 用英文逗号分隔。
94
+ - 脚本固定 30 秒超时,自动完成请求、SSE 处理、JSON-RPC 解析、业务码校验与结构化输出;失败时输出错误摘要并以非零码退出(判定标准见「失败判定」)。
95
+
96
+ ## 搜索文档 searchDocuments
97
+
98
+ 通过脚本 `search` 模式调用,query 按「从当前功能构造查询词」组织。单个功能点最多 2 次 search(探索 1 次 + 精查 1 次);两次仍无相关结果视为「知识库未覆盖」,改用本地文档或指南链接,不要继续换词重试。
99
+
100
+ ## 读取全文 getDocumentsById
101
+
102
+ 根据摘要筛选真正相关的结果,按 `parent` 去重后通过脚本 `doc` 模式获取全文(单次 ≤3 篇)。全文条目包含 `name`、`title`、`uri`、`content`,返回顺序可能与传入顺序不同,**必须按 `name` 识别对应文档,不能依赖数组下标**。
103
+
104
+ ## 解析响应与回流
105
+
106
+ 响应解析(SSE 提取、JSON-RPC 解包、业务码校验)已封装在 `kb_query.mjs` 中,脚本输出即结构化结果,直接使用即可,无需再手动解析。拿到结果后按以下方式回流(让查询真正改善转换效果):
107
+
108
+ - 实现依据:按文档核对 API 签名、权限、版本后落地 ArkTS 代码。
109
+ - spec / 迁移报告:在依据、差异(differences)或发现(discoveries)处引用文档 `title` + `uri`,让结论可复核。
110
+ - 失败分诊:在分诊记录中注明「依据 <uri>」,避免同一 API 问题反复查询。
111
+ - 更新 `kb_cache.json`(见「知识缓存」)。
112
+
113
+ ## 失败判定
114
+
115
+ 以下任一情况均视为调用失败,不得当作空结果继续:
116
+
117
+ - HTTP 状态非成功(非 2xx)。
118
+ - 外层 JSON-RPC 带顶层 `error` 字段。
119
+ - `result.isError: true`。
120
+ - 业务结果 `code` 非 `0` / `"0"`。
121
+
122
+ 失败时输出原始错误摘要与 HTTP 状态,检查 query / names 是否合法后最多重试一次;不要循环重试同一请求。知识库持续不可用时,退回本地文档通道并在分诊/报告记录「云侧知识库不可用」,不得阻塞页面主流程。
123
+
124
+ ## 注意事项
125
+
126
+ - 只查询**当前功能点**所需资料,不批量拉取无关文档。
127
+ - 全文请求按 `parent` 去重,避免重复请求同一文档;缓存命中时不发起请求。
128
+ - 响应中的 `content` 为 Markdown 正文,直接引用时保留关键代码与注意事项,不要臆造摘要之外的内容。
129
+ - 本技能是只读查询,不修改任何工程文件(`.migration/knowledge/` 下的查询脚本与缓存除外)。
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ // 云侧知识库查询脚本(d2h-cloud-knowledge 技能配套)。
3
+ // 用法:
4
+ // node kb_query.mjs search "FilePicker DocumentViewPicker"
5
+ // node kb_query.mjs doc "alliance/document/cn/harmonyos-guides/select-user-file,alliance/document/cn/other"
6
+ // sceneName 固定为 app2harmony(D2h 应用转换场景)
7
+ const KB_URL = 'https://connect-api.cloud.huawei.com/api/developerknowledge/mcp';
8
+ const HEADERS = {
9
+ 'x-gray-flag': '1',
10
+ 'Content-Type': 'application/json',
11
+ 'Accept': 'application/json, text/event-stream',
12
+ 'sceneName': 'app2harmony',
13
+ };
14
+
15
+ async function callKb(name, args) {
16
+ const resp = await fetch(KB_URL, {
17
+ method: 'POST',
18
+ headers: HEADERS,
19
+ body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/call', params: { name, arguments: args } }),
20
+ signal: AbortSignal.timeout(30000),
21
+ });
22
+ if (!resp.ok) throw new Error(`HTTP ${resp.status} ${resp.statusText}`);
23
+ const raw = await resp.text();
24
+ // 若返回 SSE,提取 data: 内容;否则按 JSON 解析
25
+ const dataLines = raw.split('\n').map((l) => l.trim()).filter((l) => l.startsWith('data:'));
26
+ const payloads = dataLines.length ? dataLines.map((l) => JSON.parse(l.slice(5).trim())) : [JSON.parse(raw)];
27
+ const outer = payloads.find((p) => p && (p.result || p.error)) || payloads[0];
28
+ if (outer.error) throw new Error(`JSON-RPC error: ${JSON.stringify(outer.error)}`);
29
+ if (outer.result && outer.result.isError) throw new Error(`result.isError: ${JSON.stringify(outer.result)}`);
30
+ const text = (outer.result && outer.result.content || []).find((c) => c.type === 'text');
31
+ if (!text || !text.text) throw new Error('响应中缺少 type=text 内容');
32
+ const biz = JSON.parse(text.text);
33
+ if (biz.code !== 0 && String(biz.code) !== '0') throw new Error(`业务错误 code=${biz.code} message=${biz.message}`);
34
+ return biz.resultList || [];
35
+ }
36
+
37
+ const [mode, arg] = process.argv.slice(2);
38
+ (async () => {
39
+ if (mode === 'search') {
40
+ const list = await callKb('searchDocuments', { SearchDocumentsReq: { query: arg } });
41
+ for (const item of list) {
42
+ console.log(JSON.stringify({ parent: item.parent, content: item.content }, null, 2));
43
+ console.log('---');
44
+ }
45
+ } else if (mode === 'doc') {
46
+ const names = arg.split(',').map((s) => s.trim()).filter(Boolean);
47
+ const list = await callKb('getDocumentsById', { GetDocumentsByIdRequest: { names } });
48
+ for (const doc of list) {
49
+ console.log(JSON.stringify({ name: doc.name, title: doc.title, uri: doc.uri, content: doc.content }, null, 2));
50
+ console.log('---');
51
+ }
52
+ } else {
53
+ throw new Error('用法: node kb_query.mjs search "<query>" | doc "<parent1,parent2>"');
54
+ }
55
+ })().catch((e) => { console.error('调用失败:', e.message); process.exit(1); });
@@ -1,112 +1,132 @@
1
- ---
2
- name: d2h-page-develop
3
- description: Implement ordered Android-to-HarmonyOS page tasks from pages.json, batch_report.md, and page-scoped spec.md files. Use during page development when the current agent must complete each page serially through ArkTS implementation, managed build, Python Hypium tests, scoped commits, migration-report evidence, and in-place ledger updates before starting the next page. Do not delegate page work to subagents.
4
- ---
5
-
6
- # Page development loop
7
-
8
- Implement and verify one ordered page task at a time in the current agent. Own each page's complete loop and do not delegate page implementation, build, testing, reporting, commits, or ledger updates to subagents.
9
-
10
- ## Inputs and boundaries
11
-
12
- - Use `.migration/page-specs/pages.json` as the immutable page order and `batch_report.md` as the mutable execution ledger.
13
- - Use the selected page package's `spec.md` as the authority for page scope, behavior, acceptance sequences, Android evidence, and expected HarmonyOS files.
14
- - Read `.migration/utg/page.json` when the Spec references a UTG node or the arrival path needs clarification. Read cited Android source before implementing behavior.
15
- - Do not require or generate `ui-design.md`, copied screenshots, copied `view.xml`, or any other page-package artifact. Each `page_NNNN_<name>-<id>/` directory continues to contain only `spec.md`.
16
- - Do not regenerate `pages.json`, page Specs, or `batch_report.md` during ordinary development. Correct an owning artifact only when current source proves it wrong, record the reason, and preserve execution history.
17
- - Use `droid2hmos` managed build and test entry points. Do not use task-planning commands or static scripts to choose or execute page work.
18
- - Preserve unrelated user changes. Never reset, discard, or include them in a page commit.
19
-
20
- ## Single-agent mode
21
-
22
- 1. Read `pages.json` and `batch_report.md`; use AI judgment to verify their task IDs, order, links, counts, and current states agree.
23
- 2. Select the earliest ordered page whose development/build/validation states are not `implemented/passed/passed` and whose declared dependencies are satisfied.
24
- 3. Resolve the page package, Android root, HarmonyOS root, repository root, current `HEAD`, Git status, device target, and task evidence directory.
25
- 4. Record the current `HEAD` and Git status as the task baseline, then execute the selected page through the complete per-page loop below.
26
- 5. Verify the resulting implementation, current managed build/test evidence, migration report, commits, batch ledger, and Git status.
27
- 6. If the page is incomplete or fails verification, repair the same page; do not select another page.
28
- 7. Only after the selected task is genuinely `implemented/passed/passed` may the current agent select the next task.
29
- 8. After all tasks are complete, explicitly enumerate every Python Hypium test list and run one managed batch regression. Append the batch evidence to `batch_report.md` and the migration report.
30
-
31
- ## Per-page execution
32
-
33
- ### 1. Claim and understand the page
34
-
35
- - Confirm the task is the earliest incomplete eligible row and no other task is `in_progress`.
36
- - Compare the checkout with the recorded task baseline. Preserve and avoid unrelated dirty files; if ownership conflicts with a build-affecting file, return the exact conflict instead of overwriting it.
37
- - Mark only the selected task `in_progress` in the working copy of `batch_report.md`.
38
- - Read the complete `spec.md`, the referenced `.migration/utg/page.json` node, every cited Fact, and every cited Android source file. Follow handlers, state transitions, repositories, navigation, persistence, error paths, and platform side effects far enough to establish the observable result.
39
- - Inspect the HarmonyOS architecture, routes, resources, shared components, tests, and current implementation. Load `arkts-mvvm-architecture` before planning or writing ArkTS.
40
- - Build a private checklist mapping every `F-xxx` to reachable code, a stable semantic locator, an executed test assertion, and an observable result. Do not create another planning file.
41
- - Resume valid existing work for this same task instead of duplicating it.
42
-
43
- ### 2. Implement
44
-
45
- - Implement all page-scoped UI, navigation, overlays, state transitions, persistence/data effects, error paths, resources, and required shared integration.
46
- - Use the Android source and observable behavior for functional truth. Use HarmonyOS-native architecture and components for the target implementation.
47
- - Give tested interactive elements stable, unique semantic locators. Do not add controls solely to make testing easier.
48
- - Load the applicable domain Skill for identity, i18n, drawable conversion, icon sizing, or third-party substitution when the page touches that domain.
49
- - Keep shared changes limited to capabilities this page actually needs and record downstream consumers.
50
- - Do not leave stubs, fixed success values, swallowed errors, unreachable pages, placeholder controls, or TODO implementations.
51
-
52
- ### 3. Managed build
53
-
54
- - Run a fresh, non-interactive, bounded build through `droid2hmos build harmony <ANDROID_PROJECT>` using the resolved project configuration.
55
- - Save the exact command, exit status, timestamps, relevant log, produced HAP path, and HAP SHA-256 in the task evidence directory.
56
- - Treat compilation errors caused or exposed by the implementation as work to fix. Repeat edit/build until the managed build passes.
57
- - An older HAP, static analysis result, direct Hvigor run, or previous log is not current build evidence.
58
-
59
- ### 4. Managed page tests
60
-
61
- - Load `d2h-hypium-forge`. Add or update executable Python Hypium tests for every `F-xxx`, with paired `.py` and `.json` test-list assets and stable semantic locators.
62
- - Cover navigation or overlay lifecycle, state changes, data effects, and error behavior required by the Spec. Assertions must prove the declared result, not merely that a page or button exists.
63
- - Run the affected lists through the managed entry point:
64
-
65
- ```text
66
- droid2hmos test harmony <ANDROID_PROJECT> \
67
- --runner python --hypium-project <HARMONY_PROJECT>/.hypium_forge \
68
- --test-list <AFFECTED_LIST> --target <DEVICE> \
69
- --ref <ACTUALLY_ASSERTED_REF>...
70
- ```
71
-
72
- - Save the exact command, result, native report/log, device target, timestamps, hashes, and returned `managedEvidence` in the task evidence directory.
73
- - A written-but-unexecuted test, screenshot-only check, coordinate-only replay, direct local runner, old log, or zero-test result is not a pass.
74
- - Fix implementation or test defects and repeat managed build/test until both pass. Only a persistent external environment, signing, or device failure may become `blocked`, after bounded retries with diagnostics recorded.
75
-
76
- ### 5. Report and commit
77
-
78
- - Load `maintaining-migration-report` while evidence is fresh. Record real HarmonyOS files, Android source provenance, current managed evidence, differences, and source-proven discoveries; run report validation.
79
- - Inspect Git status and diff. Stage only the selected page's implementation, resources, tests, necessary shared files, and a source-proven correction to this page's `spec.md` when required. Do not include unrelated changes.
80
- - Create a scoped implementation commit only after the managed build and page tests pass. Record its commit ID.
81
- - If build-affecting page changes remain after the commit, correct the commit and rerun build/test so the evidence proves the committed tree.
82
- - Update the existing `batch_report.md` queue row, detail section, counts, evidence, files, implementation commit, timestamp, blocker, and chronological notes in place. Do not rerun `build_batch_report.py`.
83
- - Set `implemented/passed/passed` only when all three states are supported by current evidence. Use AI inspection to confirm queue/detail/count consistency and preserve all prior history.
84
- - Commit the ledger and immutable task evidence separately from the implementation commit. Do not create a self-referential commit field.
85
-
86
- ## Page completion verification
87
-
88
- Before marking the page complete, confirm:
89
-
90
- - every `F-xxx` has reachable implementation, a stable locator, and an actually executed assertion;
91
- - the page is reachable from the real app entry without a test-only route or replacement control;
92
- - build logs, HAP hash, test reports, managed evidence, and migration-report refs correspond to the implementation commit;
93
- - `batch_report.md` is internally consistent and the selected row is `implemented/passed/passed`;
94
- - both scoped commits exist and no uncommitted change owned by the page remains;
95
- - user changes and other pages were not reset or included;
96
- - no implementation defect was reclassified as a platform difference or external blocker.
97
-
98
- If verification fails, repair the same task before selecting or starting the next task.
99
-
100
- ## Batch regression
101
-
102
- After every page task is complete:
103
-
104
- 1. Enumerate every current Python Hypium test list explicitly; the Python runner does not use `--all`.
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
- 3. Require non-zero execution with no failures, errors, or ignored tests.
107
- 4. Append the managed batch evidence and timestamp to `batch_report.md`, then update and validate the migration report.
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
-
110
- ## Final result
111
-
112
- Return each task ID and page, final states, implementation and test files, managed build command/HAP/evidence, managed test command/evidence, implementation and ledger commit IDs, batch regression evidence, unrelated Git changes left untouched, and any genuine blocker or unresolved item.
1
+ ---
2
+ name: d2h-page-develop
3
+ description: Implement ordered Android-to-HarmonyOS page tasks from pages.json, batch_report.md, and page-scoped spec.md files. Use during page development when a dedicated page-worker must complete one page through ArkTS implementation, managed build, Python Hypium tests, scoped commits, migration-report evidence, and in-place ledger updates before the next page starts.
4
+ ---
5
+
6
+ # Page development loop
7
+
8
+ Implement and verify one ordered page task at a time. The parent agent selects and reviews the task; a dedicated page-worker owns exactly one page's complete loop.
9
+
10
+ ## Inputs and boundaries
11
+
12
+ - Use `.migration/page-specs/pages.json` as the immutable page order and `batch_report.md` as the mutable execution ledger.
13
+ - Use the selected page package's `spec.md` as the authority for page scope, behavior, acceptance sequences, Android evidence, and expected HarmonyOS files.
14
+ - Read `.migration/utg/page.json` when the Spec references a UTG node or the arrival path needs clarification. Read cited Android source before implementing behavior.
15
+ - Do not require or generate `ui-design.md`, copied screenshots, copied `view.xml`, or any other page-package artifact. Each `page_NNNN_<name>-<id>/` directory continues to contain only `spec.md`.
16
+ - Do not regenerate `pages.json`, page Specs, or `batch_report.md` during ordinary development. Correct an owning artifact only when current source proves it wrong, record the reason, and preserve execution history.
17
+ - Use `droid2hmos` managed build and test entry points. Do not use task-planning commands or static scripts to choose or execute page work.
18
+ - Preserve unrelated user changes. Never reset, discard, or include them in a page commit.
19
+
20
+ ## Parent-agent mode
21
+
22
+ 1. Read `pages.json` and `batch_report.md`; use AI judgment to verify their task IDs, order, links, counts, and current states agree.
23
+ 2. Select the earliest ordered page whose development/build/validation states are not `implemented/passed/passed` and whose declared dependencies are satisfied.
24
+ 3. Resolve the page package, Android root, HarmonyOS root, repository root, current `HEAD`, Git status, device target, and task evidence directory.
25
+ 4. Dispatch exactly one page-worker with absolute paths, selected task ID, dispatch baseline, device target, and evidence directory. Do not run page-workers in parallel or give one worker multiple pages.
26
+ 5. Wait for the worker to complete the selected page. If it is incomplete or fails review, send the same page back for repair; do not select another page.
27
+ 6. Independently verify the resulting implementation, current managed build/test evidence, migration report, commits, batch ledger, and Git status.
28
+ 7. Only after the selected task is genuinely `implemented/passed/passed` may the parent select the next task.
29
+ 8. After all tasks are complete, explicitly enumerate every Python Hypium test list and run one managed batch regression. Append the batch evidence to `batch_report.md` and the migration report.
30
+
31
+ Use this worker prompt contract:
32
+
33
+ ```text
34
+ Use $d2h-page-develop in page-worker mode. Complete exactly <TASK_ID>.
35
+ Migration root: <absolute path>
36
+ Page package: <absolute path>
37
+ Android root: <absolute path>
38
+ HarmonyOS root: <absolute path>
39
+ Repository root: <absolute path>
40
+ Dispatch baseline: <HEAD and recorded Git status>
41
+ Device target: <target>
42
+ Evidence directory: <absolute task/run directory>
43
+
44
+ Own the complete page loop: read spec.md, UTG evidence and cited Android source;
45
+ implement the page; run managed build; load $d2h-hypium-forge and execute the
46
+ page tests through the managed Python runner; update the migration report;
47
+ create scoped commits; and update batch_report.md in place. Do not start another page.
48
+ ```
49
+
50
+ If independent page-worker execution is unavailable, return that the required mode cannot run. Do not silently implement multiple pages in the parent agent.
51
+
52
+ ## Page-worker mode
53
+
54
+ ### 1. Claim and understand the page
55
+
56
+ - Confirm the task is the earliest incomplete eligible row and no other task is `in_progress`.
57
+ - Compare the checkout with the dispatch baseline. Preserve and avoid unrelated dirty files; if ownership conflicts with a build-affecting file, return the exact conflict instead of overwriting it.
58
+ - Mark only the selected task `in_progress` in the working copy of `batch_report.md`.
59
+ - Read the complete `spec.md`, the referenced `.migration/utg/page.json` node, every cited Fact, and every cited Android source file. Follow handlers, state transitions, repositories, navigation, persistence, error paths, and platform side effects far enough to establish the observable result.
60
+ - Inspect the HarmonyOS architecture, routes, resources, shared components, tests, and current implementation. Load `arkts-mvvm-architecture` before planning or writing ArkTS.
61
+ - Build a private checklist mapping every `F-xxx` to reachable code, a stable semantic locator, an executed test assertion, and an observable result. Do not create another planning file.
62
+ - Resume valid existing work for this same task instead of duplicating it.
63
+
64
+ ### 2. Implement
65
+
66
+ - Implement all page-scoped UI, navigation, overlays, state transitions, persistence/data effects, error paths, resources, and required shared integration.
67
+ - Use the Android source and observable behavior for functional truth. Use HarmonyOS-native architecture and components for the target implementation.
68
+ - Give tested interactive elements stable, unique semantic locators. Do not add controls solely to make testing easier.
69
+ - Load the applicable domain Skill for identity, i18n, drawable conversion, icon sizing, or third-party substitution when the page touches that domain. Before implementing platform capabilities or uncertain HarmonyOS APIs (`@kit.*` Kit imports or `@ohos.*` modules), and when build or test failures point to API signatures or behavior, load `d2h-cloud-knowledge`: check `.migration/knowledge/kb_cache.json` first, query only on cache miss, and record conclusions with doc `title`/`uri` back into the cache, the page spec evidence, and the migration report.
70
+ - Keep shared changes limited to capabilities this page actually needs and record downstream consumers.
71
+ - Do not leave stubs, fixed success values, swallowed errors, unreachable pages, placeholder controls, or TODO implementations.
72
+
73
+ ### 3. Managed build
74
+
75
+ - Run a fresh, non-interactive, bounded build through `droid2hmos build harmony <ANDROID_PROJECT>` using the resolved project configuration.
76
+ - Save the exact command, exit status, timestamps, relevant log, produced HAP path, and HAP SHA-256 in the task evidence directory.
77
+ - Treat compilation errors caused or exposed by the implementation as work to fix. Repeat edit/build until the managed build passes.
78
+ - An older HAP, static analysis result, direct Hvigor run, or previous log is not current build evidence.
79
+
80
+ ### 4. Managed page tests
81
+
82
+ - Load `d2h-hypium-forge`. Add or update executable Python Hypium tests for every `F-xxx`, with paired `.py` and `.json` test-list assets and stable semantic locators.
83
+ - Cover navigation or overlay lifecycle, state changes, data effects, and error behavior required by the Spec. Assertions must prove the declared result, not merely that a page or button exists.
84
+ - Run the affected lists through the managed entry point:
85
+
86
+ ```text
87
+ droid2hmos test harmony <ANDROID_PROJECT> \
88
+ --runner python --hypium-project <HARMONY_PROJECT>/.hypium_forge \
89
+ --test-list <AFFECTED_LIST> --target <DEVICE> \
90
+ --ref <ACTUALLY_ASSERTED_REF>...
91
+ ```
92
+
93
+ - Save the exact command, result, native report/log, device target, timestamps, hashes, and returned `managedEvidence` in the task evidence directory.
94
+ - A written-but-unexecuted test, screenshot-only check, coordinate-only replay, direct local runner, old log, or zero-test result is not a pass.
95
+ - Fix implementation or test defects and repeat managed build/test until both pass. Only a persistent external environment, signing, or device failure may become `blocked`, after bounded retries with diagnostics recorded.
96
+
97
+ ### 5. Report and commit
98
+
99
+ - Load `maintaining-migration-report` while evidence is fresh. Record real HarmonyOS files, Android source provenance, current managed evidence, differences, and source-proven discoveries; run report validation.
100
+ - Inspect Git status and diff. Stage only the selected page's implementation, resources, tests, necessary shared files, and a source-proven correction to this page's `spec.md` when required. Do not include unrelated changes.
101
+ - Create a scoped implementation commit only after the managed build and page tests pass. Record its commit ID.
102
+ - If build-affecting page changes remain after the commit, correct the commit and rerun build/test so the evidence proves the committed tree.
103
+ - Update the existing `batch_report.md` queue row, detail section, counts, evidence, files, implementation commit, timestamp, blocker, and chronological notes in place. Do not rerun `build_batch_report.py`.
104
+ - Set `implemented/passed/passed` only when all three states are supported by current evidence. Use AI inspection to confirm queue/detail/count consistency and preserve all prior history.
105
+ - Commit the ledger and immutable task evidence separately from the implementation commit. Do not create a self-referential commit field.
106
+
107
+ ## Parent verification
108
+
109
+ Before accepting the worker result, independently confirm:
110
+
111
+ - every `F-xxx` has reachable implementation, a stable locator, and an actually executed assertion;
112
+ - the page is reachable from the real app entry without a test-only route or replacement control;
113
+ - build logs, HAP hash, test reports, managed evidence, and migration-report refs correspond to the implementation commit;
114
+ - `batch_report.md` is internally consistent and the selected row is `implemented/passed/passed`;
115
+ - both scoped commits exist and no uncommitted change owned by the page remains;
116
+ - user changes and other pages were not reset or included;
117
+ - no implementation defect was reclassified as a platform difference or external blocker.
118
+
119
+ Review failure returns the same task for repair. The worker never selects or starts the next task.
120
+
121
+ ## Batch regression
122
+
123
+ After every page task is complete:
124
+
125
+ 1. Enumerate every current Python Hypium test list explicitly; the Python runner does not use `--all`.
126
+ 2. Run one managed command with all required `--test-list` values on the qualified device, using only refs actually asserted by the batch.
127
+ 3. Require non-zero execution with no failures, errors, or ignored tests.
128
+ 4. Append the managed batch evidence and timestamp to `batch_report.md`, then update and validate the migration report.
129
+ 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.
130
+
131
+ ## Worker result
132
+ Return the task ID and page, final states, implementation and test files, managed build command/HAP/evidence, managed test command/evidence, implementation and ledger commit IDs, unrelated Git changes left untouched, and any genuine blocker or unresolved item.
@@ -92,6 +92,7 @@ Use schema `d2h-page-plan/v1`. Every `pages[]` item must contain:
92
92
  3. Use `page.json` navigation steps, selectors, guards, expected-arrival rules, required state, and depth to reconstruct the semantic arrival path. Source-derived reachability is planning evidence, not runtime confirmation.
93
93
  4. Translate selectors into semantic control names only when Facts, resources, or Android source support the mapping. Keep missing or ambiguous selectors explicitly unresolved.
94
94
  5. Verify every listed Android path exists under `android_root`. Verify every HarmonyOS path marked `existing` exists under `harmony_root`; otherwise mark it `planned`.
95
+ 6. When page features touch platform capabilities (camera, location, files, notifications, Bluetooth, share, Web, background tasks, etc.) or uncertain HarmonyOS APIs (`@kit.*` Kit imports or `@ohos.*` modules), load `d2h-cloud-knowledge` to confirm the corresponding Kit/API availability and system-capability limits before writing: check `.migration/knowledge/kb_cache.json` first, query only on cache miss, cite the doc `title`/`uri` in「未决项与平台差异」or the supporting feature item, and record the topic in the cache with this page as `usedBy`.
95
96
 
96
97
  ### 5. Write only `spec.md`
97
98