android2harmony 0.1.4 → 0.1.5

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.
Files changed (104) hide show
  1. package/README.md +1 -407
  2. package/agents/self-tester.md +376 -376
  3. package/dist/index.js +134 -116
  4. package/dist/index.js.map +3 -3
  5. package/package.json +36 -32
  6. package/skills/a2h-resource-convert/SKILL.md +902 -0
  7. package/skills/a2h-resource-convert/references/code-vector-icon-rules.md +335 -0
  8. package/skills/{hmos-resources-convert → a2h-resource-convert}/references/conversion-rules.md +15 -2
  9. package/skills/{hmos-resources-convert → a2h-resource-convert}/references/dependency-analysis-rules.md +24 -2
  10. package/skills/a2h-resource-convert/references/lottie-conversion-rules.md +219 -0
  11. package/skills/{hmos-resources-convert → a2h-resource-convert}/references/resource-mapping-rules.md +27 -2
  12. package/skills/{hmos-resources-convert → a2h-resource-convert}/references/xml-drawable-to-svg-rules.md +118 -1
  13. package/skills/a2h-resource-convert/scripts/a2h_resource_convert.js +2166 -0
  14. package/skills/a2h-resource-convert/scripts/code_vector_icons.js +607 -0
  15. package/skills/a2h-resource-convert/scripts/package.json +3 -0
  16. package/skills/a2h-resource-convert/scripts/svg_fidelity_check.js +632 -0
  17. package/skills/a2h-ui-transfer/SKILL.md +420 -0
  18. package/skills/a2h-ui-transfer/references/conversion-procedure.md +572 -0
  19. package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/_/350/214/203/345/274/217/351/200/211/346/213/251/350/257/264/346/230/216.md +1 -1
  20. package/skills/a2h-ui-transfer/references/mvvm-v2/_/350/243/205/351/245/260/345/231/250/351/200/237/346/237/245.md +133 -0
  21. package/skills/{hmos-batch-ui-align/scripts/android_parse_fast.ts → a2h-ui-transfer/scripts/android_parse_fast.js} +397 -283
  22. package/skills/a2h-ui-transfer/scripts/arkts_static_check.js +1624 -0
  23. package/skills/a2h-ui-transfer/scripts/measure_pack.js +1005 -0
  24. package/skills/a2h-ui-transfer/scripts/package.json +3 -0
  25. package/skills/hmos-incremental-ui-align/README.md +251 -251
  26. package/skills/hmos-incremental-ui-align/SKILL.md +364 -364
  27. package/skills/hmos-incremental-ui-align/references/State_Model_Template.md +2 -2
  28. package/skills/hmos-incremental-ui-align/scripts/app_feature_verify.js +790 -0
  29. package/skills/hmos-incremental-ui-align/scripts/extract_checklist.js +285 -0
  30. package/skills/hmos-incremental-ui-align/scripts/navigation-capure.md +76 -76
  31. package/skills/hmos-incremental-ui-align/scripts/page_capture.js +756 -0
  32. package/skills/hmos-incremental-ui-align/scripts/page_capture_burst.js +155 -0
  33. package/skills/hmos-batch-ui-align/SKILL.md +0 -141
  34. package/skills/hmos-batch-ui-align/references/conversion-procedure.md +0 -217
  35. package/skills/hmos-incremental-ui-align/scripts/app_feature_verify.ts +0 -999
  36. package/skills/hmos-incremental-ui-align/scripts/extract_checklist.ts +0 -343
  37. package/skills/hmos-incremental-ui-align/scripts/page_capture.ts +0 -977
  38. package/skills/hmos-incremental-ui-align/scripts/page_capture_burst.ts +0 -188
  39. package/skills/hmos-resources-convert/SKILL.md +0 -654
  40. package/skills/hmos-resources-convert/template/AppScope/app.json5 +0 -10
  41. package/skills/hmos-resources-convert/template/AppScope/resources/base/element/string.json +0 -8
  42. package/skills/hmos-resources-convert/template/AppScope/resources/base/media/background.png +0 -0
  43. package/skills/hmos-resources-convert/template/AppScope/resources/base/media/foreground.png +0 -0
  44. package/skills/hmos-resources-convert/template/AppScope/resources/base/media/layered_image.json +0 -7
  45. package/skills/hmos-resources-convert/template/build-profile.json5 +0 -42
  46. package/skills/hmos-resources-convert/template/code-linter.json5 +0 -32
  47. package/skills/hmos-resources-convert/template/entry/build-profile.json5 +0 -33
  48. package/skills/hmos-resources-convert/template/entry/hvigorfile.ts +0 -6
  49. package/skills/hmos-resources-convert/template/entry/obfuscation-rules.txt +0 -23
  50. package/skills/hmos-resources-convert/template/entry/oh-package.json5 +0 -10
  51. package/skills/hmos-resources-convert/template/entry/src/main/ets/entryability/EntryAbility.ets +0 -48
  52. package/skills/hmos-resources-convert/template/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets +0 -16
  53. package/skills/hmos-resources-convert/template/entry/src/main/ets/pages/Index.ets +0 -23
  54. package/skills/hmos-resources-convert/template/entry/src/main/module.json5 +0 -55
  55. package/skills/hmos-resources-convert/template/entry/src/main/resources/base/element/color.json +0 -8
  56. package/skills/hmos-resources-convert/template/entry/src/main/resources/base/element/float.json +0 -8
  57. package/skills/hmos-resources-convert/template/entry/src/main/resources/base/element/string.json +0 -16
  58. package/skills/hmos-resources-convert/template/entry/src/main/resources/base/media/background.png +0 -0
  59. package/skills/hmos-resources-convert/template/entry/src/main/resources/base/media/foreground.png +0 -0
  60. package/skills/hmos-resources-convert/template/entry/src/main/resources/base/media/layered_image.json +0 -7
  61. package/skills/hmos-resources-convert/template/entry/src/main/resources/base/media/startIcon.png +0 -0
  62. package/skills/hmos-resources-convert/template/entry/src/main/resources/base/profile/backup_config.json +0 -3
  63. package/skills/hmos-resources-convert/template/entry/src/main/resources/base/profile/main_pages.json +0 -5
  64. package/skills/hmos-resources-convert/template/entry/src/main/resources/dark/element/color.json +0 -8
  65. package/skills/hmos-resources-convert/template/entry/src/mock/mock-config.json5 +0 -2
  66. package/skills/hmos-resources-convert/template/entry/src/ohosTest/ets/test/Ability.test.ets +0 -35
  67. package/skills/hmos-resources-convert/template/entry/src/ohosTest/ets/test/List.test.ets +0 -5
  68. package/skills/hmos-resources-convert/template/entry/src/ohosTest/module.json5 +0 -16
  69. package/skills/hmos-resources-convert/template/entry/src/test/List.test.ets +0 -5
  70. package/skills/hmos-resources-convert/template/entry/src/test/LocalUnit.test.ets +0 -33
  71. package/skills/hmos-resources-convert/template/hvigor/hvigor-config.json5 +0 -23
  72. package/skills/hmos-resources-convert/template/hvigorfile.ts +0 -6
  73. package/skills/hmos-resources-convert/template/oh-package-lock.json5 +0 -28
  74. package/skills/hmos-resources-convert/template/oh-package.json5 +0 -10
  75. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mappings/android-to-harmonyOS-ui-atomic-component-mapping-reference.md +0 -0
  76. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mappings/android-to-harmonyOS-ui-interaction-mapping-reference.md +0 -0
  77. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mappings/android-to-harmonyOS-ui-layout-mapping-reference.md +0 -0
  78. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/@Link/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/217/214/345/220/221/345/220/214/346/255/245.md" +0 -0
  79. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/@Observed/350/243/205/351/245/260/345/231/250/345/222/214@ObjectLink/350/243/205/351/245/260/345/231/250/357/274/232/345/265/214/345/245/227/347/261/273/345/257/271/350/261/241/345/261/236/346/200/247/345/217/230/345/214/226.md" +0 -0
  80. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/@Prop/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/215/225/345/220/221/345/220/214/346/255/245.md" +0 -0
  81. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/@Provide/350/243/205/351/245/260/345/231/250/345/222/214@Consume/350/243/205/351/245/260/345/231/250/357/274/232/344/270/216/345/220/216/344/273/243/347/273/204/344/273/266/345/217/214/345/220/221/345/220/214/346/255/245.md" +0 -0
  82. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/@State/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/347/212/266/346/200/201.md" +0 -0
  83. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/@Track/350/243/205/351/245/260/345/231/250/357/274/232class/345/257/271/350/261/241/345/261/236/346/200/247/347/272/247/346/233/264/346/226/260.md" +0 -0
  84. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/@Watch/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/346/233/264/346/224/271/351/200/232/347/237/245.md" +0 -0
  85. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/AppStorage/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200/347/232/204UI/347/212/266/346/200/201/345/255/230/345/202/250.md" +0 -0
  86. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md" +0 -0
  87. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/LocalStorage/357/274/232/351/241/265/351/235/242/347/272/247UI/347/212/266/346/200/201/345/255/230/345/202/250.md" +0 -0
  88. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/MVVM/346/250/241/345/274/217/357/274/210V1/357/274/211.md" +0 -0
  89. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm/PersistentStorage/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md" +0 -0
  90. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm//347/256/241/347/220/206/345/272/224/347/224/250/346/213/245/346/234/211/347/232/204/347/212/266/346/200/201/346/246/202/350/277/260.md" +0 -0
  91. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/!!/350/257/255/346/263/225/357/274/232/345/217/214/345/220/221/347/273/221/345/256/232.md" +0 -0
  92. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/@Computed/350/243/205/351/245/260/345/231/250/357/274/232/350/256/241/347/256/227/345/261/236/346/200/247.md" +0 -0
  93. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/@Event/350/243/205/351/245/260/345/231/250/357/274/232/350/247/204/350/214/203/347/273/204/344/273/266/350/276/223/345/207/272.md" +0 -0
  94. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/@Local/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/351/203/250/347/212/266/346/200/201.md" +0 -0
  95. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/@Monitor/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/344/277/256/346/224/271/345/274/202/346/255/245/347/233/221/345/220/254.md" +0 -0
  96. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/@ObservedV2/350/243/205/351/245/260/345/231/250/345/222/214@Trace/350/243/205/351/245/260/345/231/250/357/274/232/347/261/273/345/261/236/346/200/247/345/217/230/345/214/226/350/247/202/346/265/213.md" +0 -0
  97. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/@Once/350/243/205/351/245/260/345/231/250/357/274/232/345/210/235/345/247/213/345/214/226/345/220/214/346/255/245/344/270/200/346/254/241.md" +0 -0
  98. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/@Param/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/244/226/351/203/250/350/276/223/345/205/245.md" +0 -0
  99. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/@Provider/350/243/205/351/245/260/345/231/250/345/222/214@Consumer/350/243/205/351/245/260/345/231/250/357/274/232/350/267/250/347/273/204/344/273/266/345/261/202/347/272/247/345/217/214/345/220/221/345/220/214/346/255/245.md" +0 -0
  100. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/@Type/350/243/205/351/245/260/345/231/250/357/274/232/346/240/207/350/256/260/347/261/273/345/261/236/346/200/247/347/232/204/347/261/273/345/236/213.md" +0 -0
  101. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/AppStorageV2/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200UI/347/212/266/346/200/201/345/255/230/345/202/250.md" +0 -0
  102. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/MVVM/346/250/241/345/274/217/357/274/210V2/357/274/211.md" +0 -0
  103. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2/PersistenceV2/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md" +0 -0
  104. /package/skills/{hmos-batch-ui-align → a2h-ui-transfer}/references/mvvm-v2//347/212/266/346/200/201/347/256/241/347/220/206V1/345/220/221V2/350/277/201/347/247/273/344/270/216/346/267/267/347/224/250/346/214/207/345/257/274.md" +0 -0
@@ -1,365 +1,365 @@
1
- ---
2
- name: hmos-incremental-ui-align
3
- description: "Automated HarmonyOS-Android UI alignment pipeline. Takes a natural language task description, automatically navigates to the target pages on both Android and HarmonyOS devices, captures view trees and screenshots, then aligns HarmonyOS code to match Android. Use this skill whenever the user wants to align a HarmonyOS page with its Android counterpart, fix visual differences between Android and HarmonyOS, add missing HarmonyOS pages based on Android, or describes a page path like '首页-设置-关于' that needs UI alignment. Also trigger on phrases like 'UI对齐', '页面对齐', '和安卓对齐', '鸿蒙页面修复','UI增量开发','align HarmonyOS with Android', or any request involving comparing and fixing HarmonyOS UI to match Android."
4
- ---
5
-
6
- # HarmonyOS-Android UI Alignment
7
- You are a senior engineer proficient in Android and HarmonyOS app development, with expertise in HarmonyOS technologies such as ArkTS and ArkUI.
8
- You must follow the pipeline in this document, executing the steps one by one.
9
- You are writing ArkTS codes.
10
-
11
- # Rules
12
- - Use Mock Data unless the user tell you to implement/align the feature together**
13
- - you can not start Step 2 until Step 1 is completely finished
14
- - Do not proceed to Step 3 until every page pair has its `UI_comparison.md` written in Step 2
15
- - Step 2 MUST be executed by the main agent sequentially (not delegated to background agents). Each sub-step (2.1 → 2.2 → 2.3) must complete and be verified before the next begins.
16
- - If mock data is required, write them in `{harmony_project_dir}/entry/src/main/ets/model/` according to the hmos MVVM mode (V1 or V2, per the paradigm detected in Step 3.1).
17
- - Do not make any other changes unrelated to the user's requirements.
18
-
19
- **Skill scripts** (TypeScript, run directly with `node` — Node ≥ 22.18/23.6, no build step, no third-party deps; all paths relative to this skill's root):
20
- - `navigation_tool` = `./scripts/app_feature_verify.ts`
21
- - `capture_tool` = `./scripts/page_capture.ts`
22
- - `burst_capture_tool` = `./scripts/page_capture_burst.ts` — continuous view-tree+screenshot capture at ~1s intervals, for multi-state components (Step 1.5)
23
- - `checklist_tool` = `./scripts/extract_checklist.ts` — deterministically extracts all diffs from `UI_comparison.md` files into `fix_checklist.md` (used in Step 3)
24
-
25
- ## Step 0: Resolve Inputs
26
-
27
- This skill takes three path inputs from the invocation and resolves its other settings along the standard chain — **OS environment variable → `~/.hometrans/config.json` → ask the user** (see Step 0.0).
28
-
29
- ### Skill input arguments (provided by the user when invoking the skill)
30
-
31
- | Argument | Required | Description |
32
- |---|---|---|
33
- | `android_project_dir` | yes | Android source code root path |
34
- | `harmony_project_dir` | yes | HarmonyOS project root path (will be modified) |
35
- | `capture_output_dir` | no | Base dir for captured page data (screenshots / view trees / analysis). Default: `<harmony_project_dir>/.hometrans/capture_output` under the current working directory |
36
-
37
- The user may pass them as named args (e.g. `android_project_dir: D:\path\to\android`) or describe them in the request. If `android_project_dir` or `harmony_project_dir` cannot be determined from the invocation, **ask the user** before proceeding.
38
-
39
- ### Step 0.0: Environment Variables Check (run first)
40
-
41
- Resolve each value along the standard chain — **OS environment variable first, then `~/.hometrans/config.json`, then ask the user** (read env vars with `echo "$VAR"` on macOS/Linux; `$env:VAR` in PowerShell / `echo %VAR%` in cmd on Windows).
42
-
43
- | Variable | config.json fallback | Purpose | Valid when |
44
- |---|---|---|---|
45
- | `HOMETRANS_MODEL_*` (`HOMETRANS_MODEL_API_KEY` / `_NAME` / `_BASE_URL`) | `autotest.unified_model.{api_key,name,base_url}`(provider 默认 openai;再兜底 `GLM_API_KEY` → 智谱 GLM 端点) | 统一多模态模型(UI 对齐 + 自测共用) | 插件场景:由 `a2h_app_feature_verify` 工具经 stdin 注入(host 解析,无需手动设);直接 `node` 运行:`HOMETRANS_MODEL_API_KEY` 非空或 config.json 已配置或 `GLM_API_KEY` 已设置 |
46
- | `OHOS_SDK_PATH` | `env.OHOS_SDK_PATH` | HarmonyOS SDK ETS API reference (Step 3) | path exists on disk |
47
- | `HMS_SDK_PATH` | `env.HMS_SDK_PATH` | HMS SDK ETS API reference (Step 3) | path exists on disk |
48
-
49
- The model config is injected automatically: in the plugin context the `a2h_app_feature_verify` tool resolves the key from the host and pipes it to `scripts/app_feature_verify.ts` over stdin (`--model-stdin`), so the key never sits in an env var and is not visible to the spawned adb/hdc subprocesses — you do not read or pass the key by hand. For a direct `node scripts/app_feature_verify.ts` run (no tool, e.g. debugging), the script still resolves `--api-key` → `HOMETRANS_MODEL_*` env → `~/.hometrans/config.json` → `GLM_API_KEY`; ensure one of those is set. For `OHOS_SDK_PATH` / `HMS_SDK_PATH`, if both the env var and `~/.hometrans/config.json` are empty but `DEVECO_SDK_HOME` is set (env or `env.DEVECO_SDK_HOME` in config.json), derive them as `<DEVECO_SDK_HOME>/default/openharmony/ets` and `<DEVECO_SDK_HOME>/default/hms/ets`.
50
-
51
- For each value that is still missing/empty (or a path that does not exist) after both the env var and `~/.hometrans/config.json`, **stop and ask the user to provide a value**, then use what they give for this run. Suggest running `ht init` to persist them as machine environment variables for next time.
52
-
53
- ### Step 0.1: Auto-derive App Names & Package Names
54
-
55
- `android.app_name` / `android.package` / `harmony.app_name` / `harmony.package` are required for navigation (passed to the `a2h_app_feature_verify` tool as `--app` / `--package`). They are not provided as inputs — resolve them from the project dirs (`android_project_dir` / `harmony_project_dir`) as follows.
56
-
57
- **`app_name` matters because it is the launcher label the navigator taps to open the app** — when the resolved label is a localized resource and a Chinese (`zh`) variant exists, prefer the Chinese value (devices are typically zh-CN).
58
-
59
- #### Android (from `android_project_dir`)
60
- 1. **`android.package`** — locate the application module (the module whose Gradle file applies `com.android.application`, usually `app/`):
61
- - Read `applicationId` from `{module}/build.gradle` (Groovy: `applicationId "com.x"`) or `build.gradle.kts` (Kotlin DSL: `applicationId = "com.x"`). Use the default/base `applicationId`; ignore flavor-specific `applicationIdSuffix`.
62
- - Fallback: the `package="..."` attribute in `{module}/src/main/AndroidManifest.xml`.
63
- 2. **`android.app_name`** — in `{module}/src/main/AndroidManifest.xml`, read `android:label`. Prefer the launcher `<activity>` label (the activity whose `<intent-filter>` has `android.intent.action.MAIN` + `android.intent.category.LAUNCHER`); if it has none, use the `<application>` label.
64
- - If the label is a literal string, use it directly.
65
- - If it is `@string/<name>`, resolve `<name>` in the string resources: prefer a Chinese variant (`{module}/src/main/res/values-zh-rCN/strings.xml`, else `values-zh/strings.xml`), falling back to the default `values/strings.xml`. Use the matching `<string name="<name>">…</string>` value.
66
-
67
- #### HarmonyOS (from `harmony_project_dir`)
68
- 1. **`harmony.package`** — read `app.bundleName` from `{harmony_project_dir}/AppScope/app.json5`.
69
- 2. **`harmony.app_name`** — read `app.label` from `{harmony_project_dir}/AppScope/app.json5`.
70
- - If it is a literal string, use it directly.
71
- - If it is `$string:<name>`, resolve `<name>`: prefer a Chinese element dir (`{harmony_project_dir}/AppScope/resources/zh_CN/element/string.json`, else `zh/element/string.json`), falling back to `base/element/string.json`. Find the entry in `string[]` whose `name` equals `<name>` and use its `value`.
72
-
73
- After resolving all four, briefly echo them to the user (e.g. `android.app_name="…", android.package="…", harmony.app_name="…", harmony.package="…"`) before starting Step 1. If any value cannot be resolved from the project dir, ask the user to supply it.
74
-
75
- ## Step 1: Capture All Related Pages on Android & HarmonyOS Devices
76
-
77
- Read `scripts/navigation-capure.md` to learn the usage of `scripts/app_feature_verify.ts` (navigation) and `scripts/page_capture.ts` (capture).
78
-
79
- ### Step 1.1: Parse User Request and Build Capture Plan
80
- Analyze the user's description and build a list of **base pages** to capture.
81
- - **Specific path** (e.g., "首页 → 设置 → 关于"): add it directly as a base page with the given click path.
82
- - **Ambiguous scope** (e.g., "播放列表歌曲页的所有二级弹窗"): identify one determinable base page first — interactive sub-states (tabs, popups, etc.) will be discovered automatically in Step 1.3.
83
-
84
- For each base page, define:
85
- - `page_name`: short identifier (e.g., `enterprise_detail`)
86
- - `android_nav_path` / `hmos_nav_path`: the navigation prompt for each device
87
-
88
- Create the timestamped output directory and per-page sub-directories following the pattern in `scripts/navigation-capure.md`.
89
-
90
- ### Step 1.2: Capture Base Pages
91
- For each base page in the plan, on **both** Android and HarmonyOS devices:
92
- 1. Use the `a2h_app_feature_verify` tool to navigate to the page (it runs `scripts/app_feature_verify.ts` with the model key piped over stdin, so the key is not leaked into env/argv).
93
- 2. On success, use `scripts/page_capture.ts` to capture the view tree and screenshot.
94
- 3. For HarmonyOS pages that don't exist yet, navigation will fail — leave the directory empty (expected).
95
-
96
- ### Step 1.3: Discover and Capture Interactive States
97
- After capturing each base page, scan its view tree for **interactive elements that change the visible UI**, including but not limited to:
98
- - Tabs / Segmented controls (each tab shows different content)
99
- - Filter / Sort / Dropdown trigger buttons (clicking opens a popup, bottom sheet, or dropdown)
100
- - Expandable / Collapsible sections ("展开"/"收起", accordion)
101
- - Any other clickable element that reveals content not visible in the current capture (toggle, switch-mode button, etc.)
102
-
103
- **For each interactive element found:**
104
- 1. Create a separate capture directory: `{platform}_page_{i}_{base_name}_{state_type}_{state_name}` (e.g., `android_page_1_detail_tab_city`, `android_page_1_detail_popup_filter_identity`).
105
- 2. Navigate to the base page (reuse the same nav path), then append the click action to trigger the state change. Capture with `scripts/page_capture.ts`.
106
- 3. Repeat for **both** Android and HarmonyOS devices.
107
- 4. Each captured state is treated as a separate page pair in Step 2 and Step 3.
108
-
109
- **Skip condition**: Only skip this step for a specific page if the user explicitly says to ignore interactive states (e.g., "只对齐主页面,不管弹窗和tab").
110
-
111
- ### Step 1.4: Source Code Scan for Dynamic / Transient / Non-Touch UI
112
-
113
- Static screenshots and view trees cannot capture animations, transient UI (Toast, Snackbar), or UI triggered by voice/sensors. This step extracts those effects from source code.
114
-
115
- **Scan scope**: Only scan source files related to the pages captured in Step 1.2/1.3 (use Activity/Fragment names from navigation to locate relevant files).
116
-
117
- **Search patterns** (in `android_project_dir`):
118
-
119
- | Category | Grep patterns |
120
- |----------|--------------|
121
- | Animation | `ObjectAnimator`, `ValueAnimator`, `AnimatorSet`, `@anim/`, `animateLayoutChanges`, `MotionLayout`, `Transition`, `LottieAnimationView`, `setAnimation` |
122
- | Transient UI | `Toast.makeText`, `Snackbar.make`, `PopupWindow`, `ToolTip`, `postDelayed.*GONE\|VISIBLE`, `CountDownTimer` |
123
- | Voice/Sensor | `SpeechRecognizer`, `VoiceInteractionService`, `SensorManager`, `MediaRecorder` |
124
- | External event UI | `BroadcastReceiver`+UI updates, `onMessageReceived` (FCM/JPush) |
125
-
126
- **Output**: Write `{task_dir}/dynamic_ui_inventory.md` with this format:
127
- ```markdown
128
- # Dynamic UI Inventory
129
- | Type | Trigger | Source File:Line | Target UI Component | Effect Description | Duration/Timing |
130
- |------|---------|-----------------|--------------------|--------------------|-----------------|
131
- | animation | page enter | LoginActivity.kt:45 | logo_image | scale 0→1 + fade in | 400ms, overshoot |
132
- | Toast | login success | LoginActivity.kt:112 | — | "登录成功" | 2000ms auto-dismiss |
133
- | voice input | mic button click | SearchActivity.kt:78 | voice_wave_view | shows waveform animation | until recognition ends |
134
- ```
135
-
136
- **Skip condition**: If grep finds zero matches across all patterns for a page's related source files, note "No dynamic UI found" for that page and proceed.
137
-
138
- ### Step 1.5: Stateful Component Analysis (Multi-State UI)
139
-
140
- This step identifies components with multiple distinct UI states driven by user interaction (e.g., voice input: idle → recording → cancelling → recognized) and builds a state transition model from source code.
141
-
142
- #### Step 1.5.1: Identify Multi-State Components
143
-
144
- **Trigger conditions** (any one):
145
- - User description explicitly mentions state changes ("语音输入各状态", "按住说话的录音和取消", "各个弹窗状态")
146
- - Step 1.4 source scan discovers ≥3 distinct UI state values in the same component
147
-
148
- **Grep patterns (Android)**:
149
- - `enum.*State` / `sealed class.*State` / `companion object.*STATE`
150
- - `when.*state` / `switch.*state` / `if.*state ==`
151
- - `setVisibility.*GONE|VISIBLE` (multiple occurrences in same method)
152
- - `LiveData<.*State>` / `MutableStateFlow<.*State>`
153
-
154
- **Grep patterns (HarmonyOS)**:
155
- - `@State.*state` / `enum.*State`
156
- - `if.*this.state` / `switch.*this.state`
157
- - `.visibility(this.state ===`
158
- - `@Watch` decorators on state variables
159
-
160
- **Output**: List of multi-state components to analyze.
161
-
162
- #### Step 1.5.2: Build State Transition Model
163
-
164
- For each identified multi-state component, read the relevant source code and produce a state model following the template in `references/State_Model_Template.md`.
165
-
166
- The model MUST include:
167
- 1. **State enumeration** — all possible states with UI descriptions
168
- 2. **Transitions** — from/to/trigger/gesture type/threshold/duration, each with source file:line
169
- 3. **Per-state UI properties** — visibility, background, text, color, border, animation, all traced to source
170
- 4. **Animations between states** — property/from/to/duration/easing
171
-
172
- **Key constraint**: Every UI property and transition condition MUST reference a source code location. No estimation from screenshots.
173
-
174
- **Output**: Write `{task_dir}/state_model.md`
175
-
176
- #### Step 1.5.3: Capture State Snapshots
177
-
178
- **For auto-capturable states** (single tap, simple long-press then release):
179
- 1. Navigate to the component's page
180
- 2. Start `scripts/page_capture_burst.ts` (see `scripts/navigation-capure.md` for burst workflow)
181
- 3. Trigger the state via the `a2h_app_feature_verify` tool
182
- 4. Select representative frames from burst output
183
-
184
- **For non-auto-capturable states** (long-press hold, drag, pan, sensor, voice):
185
- Generate manual capture instructions and present them to the user. Wait for user confirmation before proceeding.
186
-
187
- **Auto-capture feasibility rules**:
188
- | Gesture | Auto? | Reason |
189
- |---------|-------|--------|
190
- | Single tap | Yes | phone-agent supports directly |
191
- | Long-press then release | Yes | decompose to press → wait → release |
192
- | Long-press and hold | **No** | must maintain pressure during burst |
193
- | Drag/Pan with threshold | **No** | requires precise coordinates + simultaneous capture |
194
- | Sensor/Voice input | **No** | requires physical input |
195
-
196
- #### Step 1.5.4: Expand States into Virtual Page Pairs
197
-
198
- Each captured state becomes a standalone page pair for Step 2:
199
- ```
200
- {platform}_page_{i}_{base_name}_state_{state_id}_{state_name}/
201
- screenshot_001.png (representative frame from burst or manual capture)
202
- view_001.xml
203
- state_context.md (state's entry from state_model.md)
204
- ```
205
-
206
- These virtual page pairs follow the same naming convention and enter Step 2 identically to base pages.
207
-
208
- #### Step 1.5.5: Skip Condition
209
- If no multi-state components are identified (neither from user description nor from Step 1.4 grep results), skip Step 1.5 entirely and proceed to Navigation Rules → Step 2.
210
-
211
- ### Navigation Rules (apply to all capture operations in Step 1)
212
-
213
- **Click path extraction**: do not replace or translate key operations of hdc/adb (such as drag, swipe).
214
- **When navigation fails**:
215
- Firstly, make sure whether the page exists, then:
216
- 1. Page does not exist → record the result and skip the capture.
217
- 2. Page exists but click path is wrong → force-stop and restart the app, retry with the corrected path.
218
- 3. Page exists, path is correct, but the tool reports failure → review the screenshot yourself and decide whether the target was actually reached.
219
- **Must Remember**: Do not skip any page on Android/HarmonyOS unless navigation fails more than twice.
220
-
221
- ## Step 2: UI Diff Analysis
222
-
223
- **CRITICAL RULES for Step 2**:
224
- - Android `UI_Analysis.md` MUST be generated for EVERY page, even if HarmonyOS capture is empty
225
- - HarmonyOS `UI_Analysis.md` (or `UI_Analysis_from_code.md`) MUST be generated for EVERY page
226
- - `UI_comparison.md` MUST contain a real markdown diff table (not just a status note)
227
-
228
- **Dimension rule (applies to Step 2.1, 2.2, and 2.3)**:
229
- All size/position values must include:
230
- - raw px value (from view tree bounds)
231
- - device density (read from the page's `meta.json` → `density_factor`; e.g. 3.0)
232
- - converted dp/vp value (px ÷ density_factor)
233
- Format: "126px (3.0x → 42vp)". Never write bare px or vp without the other.
234
- **Density source**: `scripts/page_capture.ts` records the real device density into each capture directory's `meta.json` (`dpi` and `density_factor`). Read `density_factor` from there per page — do NOT assume 3x. Android and HarmonyOS captures may have different densities, so convert each side using its own `meta.json`. If a page's `meta.json` is missing `density_factor`, fall back to 3.0 and note the assumption.
235
- **MANDATORY OUTPUT**: Write the result to `android_page_{i}_{name}/UI_Analysis.md`,写完后确认文件已创建。
236
- **This step is NEVER skippable** — even if the HarmonyOS counterpart is empty, the Android analysis must still be written.
237
-
238
- For each page <`android_page_{i}_{name}`,`hmos_page_{i}_{name}`> collected in {Step 1}, write UI Analysis using the Analysis Template in `references/UI_Analysis_Template.md`:
239
- ### Step 2.1 UI Analysis of `android_page_{i}_{name}`
240
- Read `android_page_{i}_{name}` 目录下的 screenshot(_n) 和 view tree(_n) 信息,以 table 形式列举出该页面所有组件,每个组件包含位置、颜色、icon、大小、形状、文字内容、alignment(居中、靠左、靠右等)等一切视觉要素。
241
- Additionally, check `{task_dir}/dynamic_ui_inventory.md` for any dynamic/transient effects related to this page and include them in the analysis under a "Dynamic / Transient UI Effects" section (see template).
242
- **MANDATORY OUTPUT**: following the template `references/UI_Analysis_Template.md` to write the result to `android_page_{i}_{name}/UI_Analysis.md`,写完后确认文件已创建。
243
-
244
- ### Step 2.2 UI Analysis of `hmos_page_{i}_{name}`
245
- if `hmos_page_{i}_{name}` has screenshots and view trees:
246
- Read `hmos_page_{i}_{name}` 目录下的 screenshot 和 view tree 信息,以 table 形式列举出该页面所有组件,每个组件包含位置、颜色、icon、大小、形状、文字内容、alignment(居中、靠左、靠右等)等一切视觉要素。
247
- Additionally, analyze the HarmonyOS source code for any dynamic/transient effects (e.g., `animateTo()`, `promptAction.showToast()`, `.transition()`) and include them in the "Dynamic / Transient UI Effects" section.
248
- **MANDATORY OUTPUT**: following the template `references/UI_Analysis_Template.md` to Write the result to `hmos_page_{i}_{name}/UI_Analysis.md`,写完后确认文件已创建。
249
- if `hmos_page_{i}_{name}` is empty (no screenshots/view trees captured):
250
- Read the HarmonyOS source code at `harmony_project_dir` to find the corresponding page implementation. Analyze the source code to extract all UI components, their properties, layout structure, colors, dimensions, and text content. Also extract any dynamic/transient effects from the code. Create a comprehensive component table from the code analysis.
251
- **MANDATORY OUTPUT**: following the template `references/UI_Analysis_Template.md` to Write the result to `hmos_page_{i}_{name}/UI_Analysis_from_code.md`,写完后确认文件已创建。
252
- **DO NOT** write a placeholder like "page not captured" — you must actually read the source code and produce a real analysis.
253
- ### Step 2.3 Make UI Diff Analysis and Write the Comparison Table
254
- **Input requirement**: You MUST Read the already-written `android_page_{i}_{name}/UI_Analysis.md` and `hmos_page_{i}_{name}/UI_Analysis.md` (or `UI_Analysis_from_code.md`) files using the Read tool before writing the comparison. Do NOT generate the comparison from raw view trees, screenshots, or source code directly — the comparison must be derived from the two Analysis documents.
255
-
256
- Using `android_page_{i}_{name}/UI_Analysis.md` as the ground truth, compare the detailed differences of each component between `android_page_{i}_{name}/UI_Analysis.md` and `hmos_page_{i}_{name}/UI_Analysis.md` (or `hmos_page_{i}_{name}/UI_Analysis_from_code.md` if hmos page was empty), and list them in a table like `references/Comparison_Template.md`
257
-
258
- **Quality requirement for UI_comparison.md**:
259
- - The file MUST contain a markdown table with `|` delimiters listing every component
260
- - If HarmonyOS page is missing entirely, each diff column must state the Android target value as the implementation spec, not just "缺失". Format: "HarmonyOS: 缺失 → 目标: {Android的具体值}". Example: Alignment Diff = "HarmonyOS: 缺失 → 目标: 左对齐". Example: Text Color Diff = "HarmonyOS: 缺失 → 目标: #333333". A column that only says "缺失" without a target value is INVALID.
261
- - A comparison that only says "page not captured" or "needs implementation" without a component-level table is INVALID
262
- - **Dynamic UI Diff**: After the static component table, include a separate "Dynamic / Transient UI Comparison" table comparing animation parameters (duration, easing, properties), transient UI (Toast text, duration, trigger condition), and non-touch input support (voice, sensor). Format same as static diff: "HarmonyOS: {current} → 目标: {Android value}".
263
- - **State Machine Diff** (for Step 1.5 components only): After the Dynamic UI table, include a "State Machine Comparison" section following `references/Comparison_Template.md`. This must cover: state count diff, per-transition trigger/threshold diff, and per-state visual property diff. Each diff must reference the source line from `state_model.md`.
264
-
265
- **MANDATORY OUTPUT**: Write the comparison table into `hmos_page_{i}_{name}/UI_comparison.md`
266
-
267
- ### Step 2.4 Output Verification (Main Agent)
268
- MUST verify:
269
- 1. Use Glob to list all `**/UI_Analysis*.md` files — confirm one exists for every `android_page_*` and every `hmos_page_*` directory
270
- 2. Use Glob to list all `**/UI_comparison.md` files — confirm one exists for every `hmos_page_*` directory
271
- 3. For each `UI_comparison.md`, Read the first 10 lines and confirm it contains a markdown table (has `|` characters)
272
- 4. If ANY file is missing or invalid, re-run Step 2 for that specific page pair before proceeding
273
-
274
- ## Step 3: Fix UI Diffs or Implement Missed Pages (MainAgent)
275
-
276
- **CHECKPOINT — before proceeding, you MUST**:
277
- 1. For every page pair, use the Read tool to open `hmos_page_{i}_{name}/UI_comparison.md` and confirm it exists and contains a markdown diff table (has `|` delimiters with component rows).
278
- 2. If any `UI_comparison.md` is missing or contains only a status note without a component table, go back to Step 2 and complete it. For pages where HarmonyOS was not captured, read the source code to generate `UI_Analysis_from_code.md` first, then regenerate the comparison with a proper component-level diff table.
279
- 3. Generate `{task_dir}/fix_checklist.md` **deterministically** by running the extraction script — do NOT hand-enumerate diffs from the comparison tables (manual enumeration is the main cause of missed items):
280
- ```bash
281
- node ./scripts/extract_checklist.ts --task-dir "{task_dir}"
282
- ```
283
- The script parses ALL five table types in every `UI_comparison.md` (main static component table, Dynamic / Transient UI, State Machine, Per-Transition, Per-State Visual), skips rows whose Diff cell is empty / "一致" / "-", splits a row carrying multiple diffs (separated by `;`, `;`, or `<br>`) into separate items, and tags items with `[DYNAMIC]` / `[STATE]` / `[TRANSITION]` prefixes. It prints a per-page reconciliation table (`diff_rows` vs `items`).
284
-
285
- 4. **Reconciliation gate** — read the script's stdout report and the generated `fix_checklist.md`:
286
- - For every page, confirm `items >= diff_rows`. Any row flagged `<-- CHECK` means a diff row produced no item → open that `UI_comparison.md` and find why (malformed Diff cell, missing Diff column). Fix the comparison file and re-run the script.
287
- - If the report shows `total diff rows: 0` or a page shows `tables=0` (only a status note, no real table), that page's Step 2 is incomplete → go back to Step 2, generate `UI_Analysis_from_code.md` from HarmonyOS source if the page was not captured, regenerate the comparison with a real component-level diff table, then re-run the script.
288
- - Only after the script output covers every page with no `<-- CHECK` flags is the checklist trustworthy.
289
-
290
- 5. **Review pass (human-readable refinement)** — the script output is a faithful but raw draft. Edit `fix_checklist.md` to: merge exact duplicates, make terse cells read as actionable instructions, and keep the auto-generated `<!-- source: ... -->` comment line under each page heading (it records the provenance and row/item counts for the final review in Step 3.4). Do NOT delete any item during this pass — only merge true duplicates.
291
-
292
- This checklist is your single source of truth for what needs to be fixed. The format is:
293
- ```
294
- # Fix Checklist
295
- ## hmos_page_{i}_{name}
296
- <!-- source: ... | tables=N | diff_rows=N | items=N -->
297
- - [ ] {diff description 1}
298
- - [ ] [DYNAMIC] {effect}: {diff}
299
- - [ ] [STATE] {state}: {diff}
300
- ...
301
- ```
302
-
303
- For **multi-state components** (from Step 1.5), use tagged prefixes in the checklist:
304
- ```
305
- ## Component: {name} (Stateful)
306
- - [ ] [STATE] 实现 {state_name} 状态 ({state_id}): {UI description}
307
- - [ ] [TRANSITION] {from}→{to}: {gesture type} {threshold/condition}
308
- - [ ] [ANIMATION] {state}: {animation description with params}
309
- ```
310
-
311
- ### Step 3.1: Analyze Project Architecture and load knowledge (Main Agent)
312
- 1. understand the existing HarmonyOS project's architecture, analyze existing patterns and identify {reusable components}.
313
- 2. **Detect the project's state-management paradigm (V1 vs V2)** before loading MVVM docs — decide once at project level and keep it for the whole task:
314
- - Scan existing `.ets` under `{harmony_project_dir}/entry/src/main/ets/` for decorators:
315
- - `@Component` + `@State`/`@Prop`/`@Link`/`@Provide`/`@Consume`/`@Observed`/`@ObjectLink`/`@Watch` → **V1**
316
- - `@ComponentV2` + `@Local`/`@Param`/`@Once`/`@Event`/`@ObservedV2`/`@Trace`/`@Monitor`/`@Provider`/`@Consumer` → **V2**
317
- - Empty project / 0→1 fresh conversion / no state decorators → **default V2**; only-V1 → V1; only-V2 → V2; both → follow the majority and match the target page's existing directory, note it in the report.
318
- - Do NOT mix V1 and V2 decorators in the same project/component. Detection rule detailed in `./references/MVVM开发文档V2/_范式选择说明.md`.
319
- 3. Load the matching MVVM docs:
320
- - **V1** → read `./references/MVVM开发文档/MVVM模式V1.md` (and other V1 decorator docs in that dir as needed)
321
- - **V2** → read `./references/MVVM开发文档V2/MVVM模式(V2).md` (and other V2 decorator docs in that dir as needed)
322
- **Note**: If mock data is required, add them in **Model Layer** according to the detected MVVM paradigm.
323
-
324
- ### Step 3.2: Learn typical transformation rules
325
- read `page_align.md` to learn typical transformation rules
326
-
327
- ### Step 3.3 Fix all Diffs
328
- Read `{task_dir}/fix_checklist.md` and **Fix Every Diffs (No Matter significant or minor)**,
329
- Use {reusable components} if it is available and has been aligned with Android
330
- Following the MVVM mode
331
-
332
- **Value tracing rule**: Before fixing any dimension/size/icon-size/alignment diff, you MUST trace the target value back to Android source code (layout XML `layout_width`/`layout_height`/`padding`/`src`, drawable intrinsic size, or style definition). Write the source reference (file:line or resource name) next to the checklist item. Estimating from screenshots or "looks about right" is NOT acceptable — if the Android source cannot be located, flag the item and ask the user.
333
- **Alignment rule**: When implementing a new component or fixing an existing one, explicitly set alignment/justification for EVERY text and container element. Copy the alignment value directly from the Android UI_Analysis.md (e.g., "左对齐" → `.textAlign(TextAlign.Start)` + `.width('100%')`). Never rely on default alignment — always set it explicitly.
334
- **Stateful component rule** (for [STATE]/[TRANSITION]/[ANIMATION] items):
335
- - State enumerations must map 1:1 with Android states (same count, same semantics)
336
- - Transition conditions (gesture type, threshold in vp, delay in ms) must be traced to Android source — copy values exactly
337
- - Animation parameters (duration, easing, property, from/to values) must match Android precisely — refer to `state_model.md` for source references
338
- - Implement state changes using HarmonyOS `@State` + conditional rendering or `.visibility()` per the MVVM pattern
339
- - For gesture-triggered transitions, use ArkUI gesture APIs: `LongPressGesture`, `PanGesture`, `TapGesture` per `references/android-to-harmonyOS-ui-interaction-mapping-reference.md`
340
- **After fixing each diff, update `fix_checklist.md`**: change `- [ ]` to `- [x]` for the completed item.
341
- **CRITICAL RULE**:
342
- - Do not skip any diff item in `fix_checklist.md`, regardless of the priority.
343
- - Fixing compile errors does NOT count as fixing UI diffs. After the build passes, you MUST return to `fix_checklist.md` and continue fixing any remaining unchecked items. The task is not complete until every item in the checklist is marked `[x]`.
344
-
345
- ### Step 3.4 Final Checklist Review
346
- Read `fix_checklist.md` and verify every item is marked `[x]`. If any items remain unchecked:
347
- 1. List the unchecked items
348
- 2. For each, explain why it was not fixed (blocked by missing API, requires backend, etc.) or fix it now
349
- 3. Items that genuinely cannot be fixed should be marked with `- [~]` and a reason
350
-
351
- **Coverage re-check**: For each page, the `<!-- source: ... | items=N -->` comment records how many items the script extracted. Confirm the number of `- [x]`/`- [~]` lines under each page heading still matches that `items=N` count — if fewer, items were silently dropped during the review pass; recover them from the page's `UI_comparison.md`.
352
-
353
- ## Step 4 validate and build (Main Agent)
354
- if available, use `hmos-fix-build-errors` skill to verify the project is compilable, do not deploy.
355
-
356
- ## Guidelines
357
- - **Preserve existing code**: When editing existing files, make targeted edits — never rewrite an entire file from scratch. Respect the existing code structure, variable names, and patterns.
358
- - **Follow existing conventions**: All new code must match the HarmonyOS project's established naming conventions, import patterns, state management approach, and component composition style.
359
- - **Reuse rather than creating**: Always check for existing shared components, viewmodels, and models before creating new ones.
360
- - **Resource references must match exactly**: every color, string, dimension, image, and other resource used in the Android source must have a corresponding HarmonyOS resource. Do not hardcode values.
361
- - Use `$r('app.type.name')` for all resource references available in the resource list.
362
- - Handle responsive layouts: prefer percentage widths and `Flex` over fixed dimensions where appropriate.
363
- - Maintain accessibility: convert `content-desc` to `.accessibilityText()`, convert meaningful `text` to proper labels.
364
- - Group related UI into `@Component` sub-components when the hierarchy is deep (> 5 nesting levels).
1
+ ---
2
+ name: hmos-incremental-ui-align
3
+ description: "Automated HarmonyOS-Android UI alignment pipeline. Takes a natural language task description, automatically navigates to the target pages on both Android and HarmonyOS devices, captures view trees and screenshots, then aligns HarmonyOS code to match Android. Use this skill whenever the user wants to align a HarmonyOS page with its Android counterpart, fix visual differences between Android and HarmonyOS, add missing HarmonyOS pages based on Android, or describes a page path like '首页-设置-关于' that needs UI alignment. Also trigger on phrases like 'UI对齐', '页面对齐', '和安卓对齐', '鸿蒙页面修复','UI增量开发','align HarmonyOS with Android', or any request involving comparing and fixing HarmonyOS UI to match Android."
4
+ ---
5
+
6
+ # HarmonyOS-Android UI Alignment
7
+ You are a senior engineer proficient in Android and HarmonyOS app development, with expertise in HarmonyOS technologies such as ArkTS and ArkUI.
8
+ You must follow the pipeline in this document, executing the steps one by one.
9
+ You are writing ArkTS codes.
10
+
11
+ # Rules
12
+ - Use Mock Data unless the user tell you to implement/align the feature together**
13
+ - you can not start Step 2 until Step 1 is completely finished
14
+ - Do not proceed to Step 3 until every page pair has its `UI_comparison.md` written in Step 2
15
+ - Step 2 MUST be executed by the main agent sequentially (not delegated to background agents). Each sub-step (2.1 → 2.2 → 2.3) must complete and be verified before the next begins.
16
+ - If mock data is required, write them in `{harmony_project_dir}/entry/src/main/ets/model/` according to the hmos MVVM mode (V1 or V2, per the paradigm detected in Step 3.1).
17
+ - Do not make any other changes unrelated to the user's requirements.
18
+
19
+ **Skill scripts** (`.js` sources, run with `node`; no build step, no third-party deps; all paths relative to this skill's root):
20
+ - `navigation_tool` = `./scripts/app_feature_verify.js`
21
+ - `capture_tool` = `./scripts/page_capture.js`
22
+ - `burst_capture_tool` = `./scripts/page_capture_burst.js` — continuous view-tree+screenshot capture at ~1s intervals, for multi-state components (Step 1.5)
23
+ - `checklist_tool` = `./scripts/extract_checklist.js` — deterministically extracts all diffs from `UI_comparison.md` files into `fix_checklist.md` (used in Step 3)
24
+
25
+ ## Step 0: Resolve Inputs
26
+
27
+ This skill takes three path inputs from the invocation and resolves its other settings along the standard chain — **OS environment variable → `~/.hometrans/config.json` → ask the user** (see Step 0.0).
28
+
29
+ ### Skill input arguments (provided by the user when invoking the skill)
30
+
31
+ | Argument | Required | Description |
32
+ |---|---|---|
33
+ | `android_project_dir` | yes | Android source code root path |
34
+ | `harmony_project_dir` | yes | HarmonyOS project root path (will be modified) |
35
+ | `capture_output_dir` | no | Base dir for captured page data (screenshots / view trees / analysis). Default: `<harmony_project_dir>/.hometrans/capture_output` under the current working directory |
36
+
37
+ The user may pass them as named args (e.g. `android_project_dir: D:\path\to\android`) or describe them in the request. If `android_project_dir` or `harmony_project_dir` cannot be determined from the invocation, **ask the user** before proceeding.
38
+
39
+ ### Step 0.0: Environment Variables Check (run first)
40
+
41
+ Resolve each value along the standard chain — **OS environment variable first, then `~/.hometrans/config.json`, then ask the user** (read env vars with `echo "$VAR"` on macOS/Linux; `$env:VAR` in PowerShell / `echo %VAR%` in cmd on Windows).
42
+
43
+ | Variable | config.json fallback | Purpose | Valid when |
44
+ |---|---|---|---|
45
+ | `HOMETRANS_MODEL_*` (`HOMETRANS_MODEL_API_KEY` / `_NAME` / `_BASE_URL`) | `autotest.unified_model.{api_key,name,base_url}`(provider 默认 openai;再兜底 `GLM_API_KEY` → 智谱 GLM 端点) | 统一多模态模型(UI 对齐 + 自测共用) | 插件场景:由 `a2h_run_model_script` 工具(`script="app_feature_verify"`)经 stdin 注入(host 解析,无需手动设);直接 `node` 运行:`HOMETRANS_MODEL_API_KEY` 非空或 config.json 已配置或 `GLM_API_KEY` 已设置 |
46
+ | `OHOS_SDK_PATH` | `env.OHOS_SDK_PATH` | HarmonyOS SDK ETS API reference (Step 3) | path exists on disk |
47
+ | `HMS_SDK_PATH` | `env.HMS_SDK_PATH` | HMS SDK ETS API reference (Step 3) | path exists on disk |
48
+
49
+ The model config is injected automatically: in the plugin context the `a2h_run_model_script` tool (called with `script="app_feature_verify"` and the navigation params as a `commandArgs` object — see `scripts/navigation-capure.md` for the field list) resolves the key from the host and pipes it to `scripts/app_feature_verify.js` over stdin, so the key never sits in an env var and is not visible to the spawned adb/hdc subprocesses — you do not read or pass the key by hand. For a direct `node scripts/app_feature_verify.js` run (no tool, e.g. debugging), the script still resolves `--api-key` → `HOMETRANS_MODEL_*` env → `~/.hometrans/config.json` → `GLM_API_KEY`; ensure one of those is set. For `OHOS_SDK_PATH` / `HMS_SDK_PATH`, if both the env var and `~/.hometrans/config.json` are empty but `DEVECO_SDK_HOME` is set (env or `env.DEVECO_SDK_HOME` in config.json), derive them as `<DEVECO_SDK_HOME>/default/openharmony/ets` and `<DEVECO_SDK_HOME>/default/hms/ets`.
50
+
51
+ For each value that is still missing/empty (or a path that does not exist) after both the env var and `~/.hometrans/config.json`, **stop and ask the user to provide a value**, then use what they give for this run. Suggest running `ht init` to persist them as machine environment variables for next time.
52
+
53
+ ### Step 0.1: Auto-derive App Names & Package Names
54
+
55
+ `android.app_name` / `android.package` / `harmony.app_name` / `harmony.package` are required for navigation (passed to the `a2h_run_model_script` tool as the `app` / `package` fields of its `commandArgs` object, with `script="app_feature_verify"`). They are not provided as inputs — resolve them from the project dirs (`android_project_dir` / `harmony_project_dir`) as follows.
56
+
57
+ **`app_name` matters because it is the launcher label the navigator taps to open the app** — when the resolved label is a localized resource and a Chinese (`zh`) variant exists, prefer the Chinese value (devices are typically zh-CN).
58
+
59
+ #### Android (from `android_project_dir`)
60
+ 1. **`android.package`** — locate the application module (the module whose Gradle file applies `com.android.application`, usually `app/`):
61
+ - Read `applicationId` from `{module}/build.gradle` (Groovy: `applicationId "com.x"`) or `build.gradle.kts` (Kotlin DSL: `applicationId = "com.x"`). Use the default/base `applicationId`; ignore flavor-specific `applicationIdSuffix`.
62
+ - Fallback: the `package="..."` attribute in `{module}/src/main/AndroidManifest.xml`.
63
+ 2. **`android.app_name`** — in `{module}/src/main/AndroidManifest.xml`, read `android:label`. Prefer the launcher `<activity>` label (the activity whose `<intent-filter>` has `android.intent.action.MAIN` + `android.intent.category.LAUNCHER`); if it has none, use the `<application>` label.
64
+ - If the label is a literal string, use it directly.
65
+ - If it is `@string/<name>`, resolve `<name>` in the string resources: prefer a Chinese variant (`{module}/src/main/res/values-zh-rCN/strings.xml`, else `values-zh/strings.xml`), falling back to the default `values/strings.xml`. Use the matching `<string name="<name>">…</string>` value.
66
+
67
+ #### HarmonyOS (from `harmony_project_dir`)
68
+ 1. **`harmony.package`** — read `app.bundleName` from `{harmony_project_dir}/AppScope/app.json5`.
69
+ 2. **`harmony.app_name`** — read `app.label` from `{harmony_project_dir}/AppScope/app.json5`.
70
+ - If it is a literal string, use it directly.
71
+ - If it is `$string:<name>`, resolve `<name>`: prefer a Chinese element dir (`{harmony_project_dir}/AppScope/resources/zh_CN/element/string.json`, else `zh/element/string.json`), falling back to `base/element/string.json`. Find the entry in `string[]` whose `name` equals `<name>` and use its `value`.
72
+
73
+ After resolving all four, briefly echo them to the user (e.g. `android.app_name="…", android.package="…", harmony.app_name="…", harmony.package="…"`) before starting Step 1. If any value cannot be resolved from the project dir, ask the user to supply it.
74
+
75
+ ## Step 1: Capture All Related Pages on Android & HarmonyOS Devices
76
+
77
+ Read `scripts/navigation-capure.md` to learn the usage of `scripts/app_feature_verify.js` (navigation) and `scripts/page_capture.js` (capture).
78
+
79
+ ### Step 1.1: Parse User Request and Build Capture Plan
80
+ Analyze the user's description and build a list of **base pages** to capture.
81
+ - **Specific path** (e.g., "首页 → 设置 → 关于"): add it directly as a base page with the given click path.
82
+ - **Ambiguous scope** (e.g., "播放列表歌曲页的所有二级弹窗"): identify one determinable base page first — interactive sub-states (tabs, popups, etc.) will be discovered automatically in Step 1.3.
83
+
84
+ For each base page, define:
85
+ - `page_name`: short identifier (e.g., `enterprise_detail`)
86
+ - `android_nav_path` / `hmos_nav_path`: the navigation prompt for each device
87
+
88
+ Create the timestamped output directory and per-page sub-directories following the pattern in `scripts/navigation-capure.md`.
89
+
90
+ ### Step 1.2: Capture Base Pages
91
+ For each base page in the plan, on **both** Android and HarmonyOS devices:
92
+ 1. Use the `a2h_run_model_script` tool to navigate to the page: set `script="app_feature_verify"` and pass the navigation params as a `commandArgs` object (the tool description lists the `commandArgs` fields). See `scripts/navigation-capure.md` for the navigation prompt rule and capture workflow.
93
+ 2. On success, use `scripts/page_capture.js` to capture the view tree and screenshot.
94
+ 3. For HarmonyOS pages that don't exist yet, navigation will fail — leave the directory empty (expected).
95
+
96
+ ### Step 1.3: Discover and Capture Interactive States
97
+ After capturing each base page, scan its view tree for **interactive elements that change the visible UI**, including but not limited to:
98
+ - Tabs / Segmented controls (each tab shows different content)
99
+ - Filter / Sort / Dropdown trigger buttons (clicking opens a popup, bottom sheet, or dropdown)
100
+ - Expandable / Collapsible sections ("展开"/"收起", accordion)
101
+ - Any other clickable element that reveals content not visible in the current capture (toggle, switch-mode button, etc.)
102
+
103
+ **For each interactive element found:**
104
+ 1. Create a separate capture directory: `{platform}_page_{i}_{base_name}_{state_type}_{state_name}` (e.g., `android_page_1_detail_tab_city`, `android_page_1_detail_popup_filter_identity`).
105
+ 2. Navigate to the base page (reuse the same nav path), then append the click action to trigger the state change. Capture with `scripts/page_capture.js`.
106
+ 3. Repeat for **both** Android and HarmonyOS devices.
107
+ 4. Each captured state is treated as a separate page pair in Step 2 and Step 3.
108
+
109
+ **Skip condition**: Only skip this step for a specific page if the user explicitly says to ignore interactive states (e.g., "只对齐主页面,不管弹窗和tab").
110
+
111
+ ### Step 1.4: Source Code Scan for Dynamic / Transient / Non-Touch UI
112
+
113
+ Static screenshots and view trees cannot capture animations, transient UI (Toast, Snackbar), or UI triggered by voice/sensors. This step extracts those effects from source code.
114
+
115
+ **Scan scope**: Only scan source files related to the pages captured in Step 1.2/1.3 (use Activity/Fragment names from navigation to locate relevant files).
116
+
117
+ **Search patterns** (in `android_project_dir`):
118
+
119
+ | Category | Grep patterns |
120
+ |----------|--------------|
121
+ | Animation | `ObjectAnimator`, `ValueAnimator`, `AnimatorSet`, `@anim/`, `animateLayoutChanges`, `MotionLayout`, `Transition`, `LottieAnimationView`, `setAnimation` |
122
+ | Transient UI | `Toast.makeText`, `Snackbar.make`, `PopupWindow`, `ToolTip`, `postDelayed.*GONE\|VISIBLE`, `CountDownTimer` |
123
+ | Voice/Sensor | `SpeechRecognizer`, `VoiceInteractionService`, `SensorManager`, `MediaRecorder` |
124
+ | External event UI | `BroadcastReceiver`+UI updates, `onMessageReceived` (FCM/JPush) |
125
+
126
+ **Output**: Write `{task_dir}/dynamic_ui_inventory.md` with this format:
127
+ ```markdown
128
+ # Dynamic UI Inventory
129
+ | Type | Trigger | Source File:Line | Target UI Component | Effect Description | Duration/Timing |
130
+ |------|---------|-----------------|--------------------|--------------------|-----------------|
131
+ | animation | page enter | LoginActivity.kt:45 | logo_image | scale 0→1 + fade in | 400ms, overshoot |
132
+ | Toast | login success | LoginActivity.kt:112 | — | "登录成功" | 2000ms auto-dismiss |
133
+ | voice input | mic button click | SearchActivity.kt:78 | voice_wave_view | shows waveform animation | until recognition ends |
134
+ ```
135
+
136
+ **Skip condition**: If grep finds zero matches across all patterns for a page's related source files, note "No dynamic UI found" for that page and proceed.
137
+
138
+ ### Step 1.5: Stateful Component Analysis (Multi-State UI)
139
+
140
+ This step identifies components with multiple distinct UI states driven by user interaction (e.g., voice input: idle → recording → cancelling → recognized) and builds a state transition model from source code.
141
+
142
+ #### Step 1.5.1: Identify Multi-State Components
143
+
144
+ **Trigger conditions** (any one):
145
+ - User description explicitly mentions state changes ("语音输入各状态", "按住说话的录音和取消", "各个弹窗状态")
146
+ - Step 1.4 source scan discovers ≥3 distinct UI state values in the same component
147
+
148
+ **Grep patterns (Android)**:
149
+ - `enum.*State` / `sealed class.*State` / `companion object.*STATE`
150
+ - `when.*state` / `switch.*state` / `if.*state ==`
151
+ - `setVisibility.*GONE|VISIBLE` (multiple occurrences in same method)
152
+ - `LiveData<.*State>` / `MutableStateFlow<.*State>`
153
+
154
+ **Grep patterns (HarmonyOS)**:
155
+ - `@State.*state` / `enum.*State`
156
+ - `if.*this.state` / `switch.*this.state`
157
+ - `.visibility(this.state ===`
158
+ - `@Watch` decorators on state variables
159
+
160
+ **Output**: List of multi-state components to analyze.
161
+
162
+ #### Step 1.5.2: Build State Transition Model
163
+
164
+ For each identified multi-state component, read the relevant source code and produce a state model following the template in `references/State_Model_Template.md`.
165
+
166
+ The model MUST include:
167
+ 1. **State enumeration** — all possible states with UI descriptions
168
+ 2. **Transitions** — from/to/trigger/gesture type/threshold/duration, each with source file:line
169
+ 3. **Per-state UI properties** — visibility, background, text, color, border, animation, all traced to source
170
+ 4. **Animations between states** — property/from/to/duration/easing
171
+
172
+ **Key constraint**: Every UI property and transition condition MUST reference a source code location. No estimation from screenshots.
173
+
174
+ **Output**: Write `{task_dir}/state_model.md`
175
+
176
+ #### Step 1.5.3: Capture State Snapshots
177
+
178
+ **For auto-capturable states** (single tap, simple long-press then release):
179
+ 1. Navigate to the component's page
180
+ 2. Start `scripts/page_capture_burst.js` (see `scripts/navigation-capure.md` for burst workflow)
181
+ 3. Trigger the state via the `a2h_run_model_script` tool (`script="app_feature_verify"`, navigation params in `commandArgs`)
182
+ 4. Select representative frames from burst output
183
+
184
+ **For non-auto-capturable states** (long-press hold, drag, pan, sensor, voice):
185
+ Generate manual capture instructions and present them to the user. Wait for user confirmation before proceeding.
186
+
187
+ **Auto-capture feasibility rules**:
188
+ | Gesture | Auto? | Reason |
189
+ |---------|-------|--------|
190
+ | Single tap | Yes | phone-agent supports directly |
191
+ | Long-press then release | Yes | decompose to press → wait → release |
192
+ | Long-press and hold | **No** | must maintain pressure during burst |
193
+ | Drag/Pan with threshold | **No** | requires precise coordinates + simultaneous capture |
194
+ | Sensor/Voice input | **No** | requires physical input |
195
+
196
+ #### Step 1.5.4: Expand States into Virtual Page Pairs
197
+
198
+ Each captured state becomes a standalone page pair for Step 2:
199
+ ```
200
+ {platform}_page_{i}_{base_name}_state_{state_id}_{state_name}/
201
+ screenshot_001.png (representative frame from burst or manual capture)
202
+ view_001.xml
203
+ state_context.md (state's entry from state_model.md)
204
+ ```
205
+
206
+ These virtual page pairs follow the same naming convention and enter Step 2 identically to base pages.
207
+
208
+ #### Step 1.5.5: Skip Condition
209
+ If no multi-state components are identified (neither from user description nor from Step 1.4 grep results), skip Step 1.5 entirely and proceed to Navigation Rules → Step 2.
210
+
211
+ ### Navigation Rules (apply to all capture operations in Step 1)
212
+
213
+ **Click path extraction**: do not replace or translate key operations of hdc/adb (such as drag, swipe).
214
+ **When navigation fails**:
215
+ Firstly, make sure whether the page exists, then:
216
+ 1. Page does not exist → record the result and skip the capture.
217
+ 2. Page exists but click path is wrong → force-stop and restart the app, retry with the corrected path.
218
+ 3. Page exists, path is correct, but the tool reports failure → review the screenshot yourself and decide whether the target was actually reached.
219
+ **Must Remember**: Do not skip any page on Android/HarmonyOS unless navigation fails more than twice.
220
+
221
+ ## Step 2: UI Diff Analysis
222
+
223
+ **CRITICAL RULES for Step 2**:
224
+ - Android `UI_Analysis.md` MUST be generated for EVERY page, even if HarmonyOS capture is empty
225
+ - HarmonyOS `UI_Analysis.md` (or `UI_Analysis_from_code.md`) MUST be generated for EVERY page
226
+ - `UI_comparison.md` MUST contain a real markdown diff table (not just a status note)
227
+
228
+ **Dimension rule (applies to Step 2.1, 2.2, and 2.3)**:
229
+ All size/position values must include:
230
+ - raw px value (from view tree bounds)
231
+ - device density (read from the page's `meta.json` → `density_factor`; e.g. 3.0)
232
+ - converted dp/vp value (px ÷ density_factor)
233
+ Format: "126px (3.0x → 42vp)". Never write bare px or vp without the other.
234
+ **Density source**: `scripts/page_capture.js` records the real device density into each capture directory's `meta.json` (`dpi` and `density_factor`). Read `density_factor` from there per page — do NOT assume 3x. Android and HarmonyOS captures may have different densities, so convert each side using its own `meta.json`. If a page's `meta.json` is missing `density_factor`, fall back to 3.0 and note the assumption.
235
+ **MANDATORY OUTPUT**: Write the result to `android_page_{i}_{name}/UI_Analysis.md`,写完后确认文件已创建。
236
+ **This step is NEVER skippable** — even if the HarmonyOS counterpart is empty, the Android analysis must still be written.
237
+
238
+ For each page <`android_page_{i}_{name}`,`hmos_page_{i}_{name}`> collected in {Step 1}, write UI Analysis using the Analysis Template in `references/UI_Analysis_Template.md`:
239
+ ### Step 2.1 UI Analysis of `android_page_{i}_{name}`
240
+ Read `android_page_{i}_{name}` 目录下的 screenshot(_n) 和 view tree(_n) 信息,以 table 形式列举出该页面所有组件,每个组件包含位置、颜色、icon、大小、形状、文字内容、alignment(居中、靠左、靠右等)等一切视觉要素。
241
+ Additionally, check `{task_dir}/dynamic_ui_inventory.md` for any dynamic/transient effects related to this page and include them in the analysis under a "Dynamic / Transient UI Effects" section (see template).
242
+ **MANDATORY OUTPUT**: following the template `references/UI_Analysis_Template.md` to write the result to `android_page_{i}_{name}/UI_Analysis.md`,写完后确认文件已创建。
243
+
244
+ ### Step 2.2 UI Analysis of `hmos_page_{i}_{name}`
245
+ if `hmos_page_{i}_{name}` has screenshots and view trees:
246
+ Read `hmos_page_{i}_{name}` 目录下的 screenshot 和 view tree 信息,以 table 形式列举出该页面所有组件,每个组件包含位置、颜色、icon、大小、形状、文字内容、alignment(居中、靠左、靠右等)等一切视觉要素。
247
+ Additionally, analyze the HarmonyOS source code for any dynamic/transient effects (e.g., `animateTo()`, `promptAction.showToast()`, `.transition()`) and include them in the "Dynamic / Transient UI Effects" section.
248
+ **MANDATORY OUTPUT**: following the template `references/UI_Analysis_Template.md` to Write the result to `hmos_page_{i}_{name}/UI_Analysis.md`,写完后确认文件已创建。
249
+ if `hmos_page_{i}_{name}` is empty (no screenshots/view trees captured):
250
+ Read the HarmonyOS source code at `harmony_project_dir` to find the corresponding page implementation. Analyze the source code to extract all UI components, their properties, layout structure, colors, dimensions, and text content. Also extract any dynamic/transient effects from the code. Create a comprehensive component table from the code analysis.
251
+ **MANDATORY OUTPUT**: following the template `references/UI_Analysis_Template.md` to Write the result to `hmos_page_{i}_{name}/UI_Analysis_from_code.md`,写完后确认文件已创建。
252
+ **DO NOT** write a placeholder like "page not captured" — you must actually read the source code and produce a real analysis.
253
+ ### Step 2.3 Make UI Diff Analysis and Write the Comparison Table
254
+ **Input requirement**: You MUST Read the already-written `android_page_{i}_{name}/UI_Analysis.md` and `hmos_page_{i}_{name}/UI_Analysis.md` (or `UI_Analysis_from_code.md`) files using the Read tool before writing the comparison. Do NOT generate the comparison from raw view trees, screenshots, or source code directly — the comparison must be derived from the two Analysis documents.
255
+
256
+ Using `android_page_{i}_{name}/UI_Analysis.md` as the ground truth, compare the detailed differences of each component between `android_page_{i}_{name}/UI_Analysis.md` and `hmos_page_{i}_{name}/UI_Analysis.md` (or `hmos_page_{i}_{name}/UI_Analysis_from_code.md` if hmos page was empty), and list them in a table like `references/Comparison_Template.md`
257
+
258
+ **Quality requirement for UI_comparison.md**:
259
+ - The file MUST contain a markdown table with `|` delimiters listing every component
260
+ - If HarmonyOS page is missing entirely, each diff column must state the Android target value as the implementation spec, not just "缺失". Format: "HarmonyOS: 缺失 → 目标: {Android的具体值}". Example: Alignment Diff = "HarmonyOS: 缺失 → 目标: 左对齐". Example: Text Color Diff = "HarmonyOS: 缺失 → 目标: #333333". A column that only says "缺失" without a target value is INVALID.
261
+ - A comparison that only says "page not captured" or "needs implementation" without a component-level table is INVALID
262
+ - **Dynamic UI Diff**: After the static component table, include a separate "Dynamic / Transient UI Comparison" table comparing animation parameters (duration, easing, properties), transient UI (Toast text, duration, trigger condition), and non-touch input support (voice, sensor). Format same as static diff: "HarmonyOS: {current} → 目标: {Android value}".
263
+ - **State Machine Diff** (for Step 1.5 components only): After the Dynamic UI table, include a "State Machine Comparison" section following `references/Comparison_Template.md`. This must cover: state count diff, per-transition trigger/threshold diff, and per-state visual property diff. Each diff must reference the source line from `state_model.md`.
264
+
265
+ **MANDATORY OUTPUT**: Write the comparison table into `hmos_page_{i}_{name}/UI_comparison.md`
266
+
267
+ ### Step 2.4 Output Verification (Main Agent)
268
+ MUST verify:
269
+ 1. Use Glob to list all `**/UI_Analysis*.md` files — confirm one exists for every `android_page_*` and every `hmos_page_*` directory
270
+ 2. Use Glob to list all `**/UI_comparison.md` files — confirm one exists for every `hmos_page_*` directory
271
+ 3. For each `UI_comparison.md`, Read the first 10 lines and confirm it contains a markdown table (has `|` characters)
272
+ 4. If ANY file is missing or invalid, re-run Step 2 for that specific page pair before proceeding
273
+
274
+ ## Step 3: Fix UI Diffs or Implement Missed Pages (MainAgent)
275
+
276
+ **CHECKPOINT — before proceeding, you MUST**:
277
+ 1. For every page pair, use the Read tool to open `hmos_page_{i}_{name}/UI_comparison.md` and confirm it exists and contains a markdown diff table (has `|` delimiters with component rows).
278
+ 2. If any `UI_comparison.md` is missing or contains only a status note without a component table, go back to Step 2 and complete it. For pages where HarmonyOS was not captured, read the source code to generate `UI_Analysis_from_code.md` first, then regenerate the comparison with a proper component-level diff table.
279
+ 3. Generate `{task_dir}/fix_checklist.md` **deterministically** by running the extraction script — do NOT hand-enumerate diffs from the comparison tables (manual enumeration is the main cause of missed items):
280
+ ```bash
281
+ node ./scripts/extract_checklist.js --task-dir "{task_dir}"
282
+ ```
283
+ The script parses ALL five table types in every `UI_comparison.md` (main static component table, Dynamic / Transient UI, State Machine, Per-Transition, Per-State Visual), skips rows whose Diff cell is empty / "一致" / "-", splits a row carrying multiple diffs (separated by `;`, `;`, or `<br>`) into separate items, and tags items with `[DYNAMIC]` / `[STATE]` / `[TRANSITION]` prefixes. It prints a per-page reconciliation table (`diff_rows` vs `items`).
284
+
285
+ 4. **Reconciliation gate** — read the script's stdout report and the generated `fix_checklist.md`:
286
+ - For every page, confirm `items >= diff_rows`. Any row flagged `<-- CHECK` means a diff row produced no item → open that `UI_comparison.md` and find why (malformed Diff cell, missing Diff column). Fix the comparison file and re-run the script.
287
+ - If the report shows `total diff rows: 0` or a page shows `tables=0` (only a status note, no real table), that page's Step 2 is incomplete → go back to Step 2, generate `UI_Analysis_from_code.md` from HarmonyOS source if the page was not captured, regenerate the comparison with a real component-level diff table, then re-run the script.
288
+ - Only after the script output covers every page with no `<-- CHECK` flags is the checklist trustworthy.
289
+
290
+ 5. **Review pass (human-readable refinement)** — the script output is a faithful but raw draft. Edit `fix_checklist.md` to: merge exact duplicates, make terse cells read as actionable instructions, and keep the auto-generated `<!-- source: ... -->` comment line under each page heading (it records the provenance and row/item counts for the final review in Step 3.4). Do NOT delete any item during this pass — only merge true duplicates.
291
+
292
+ This checklist is your single source of truth for what needs to be fixed. The format is:
293
+ ```
294
+ # Fix Checklist
295
+ ## hmos_page_{i}_{name}
296
+ <!-- source: ... | tables=N | diff_rows=N | items=N -->
297
+ - [ ] {diff description 1}
298
+ - [ ] [DYNAMIC] {effect}: {diff}
299
+ - [ ] [STATE] {state}: {diff}
300
+ ...
301
+ ```
302
+
303
+ For **multi-state components** (from Step 1.5), use tagged prefixes in the checklist:
304
+ ```
305
+ ## Component: {name} (Stateful)
306
+ - [ ] [STATE] 实现 {state_name} 状态 ({state_id}): {UI description}
307
+ - [ ] [TRANSITION] {from}→{to}: {gesture type} {threshold/condition}
308
+ - [ ] [ANIMATION] {state}: {animation description with params}
309
+ ```
310
+
311
+ ### Step 3.1: Analyze Project Architecture and load knowledge (Main Agent)
312
+ 1. understand the existing HarmonyOS project's architecture, analyze existing patterns and identify {reusable components}.
313
+ 2. **Detect the project's state-management paradigm (V1 vs V2)** before loading MVVM docs — decide once at project level and keep it for the whole task:
314
+ - Scan existing `.ets` under `{harmony_project_dir}/entry/src/main/ets/` for decorators:
315
+ - `@Component` + `@State`/`@Prop`/`@Link`/`@Provide`/`@Consume`/`@Observed`/`@ObjectLink`/`@Watch` → **V1**
316
+ - `@ComponentV2` + `@Local`/`@Param`/`@Once`/`@Event`/`@ObservedV2`/`@Trace`/`@Monitor`/`@Provider`/`@Consumer` → **V2**
317
+ - Empty project / 0→1 fresh conversion / no state decorators → **default V2**; only-V1 → V1; only-V2 → V2; both → follow the majority and match the target page's existing directory, note it in the report.
318
+ - Do NOT mix V1 and V2 decorators in the same project/component. Detection rule detailed in `./references/MVVM开发文档V2/_范式选择说明.md`.
319
+ 3. Load the matching MVVM docs:
320
+ - **V1** → read `./references/MVVM开发文档/MVVM模式V1.md` (and other V1 decorator docs in that dir as needed)
321
+ - **V2** → read `./references/MVVM开发文档V2/MVVM模式(V2).md` (and other V2 decorator docs in that dir as needed)
322
+ **Note**: If mock data is required, add them in **Model Layer** according to the detected MVVM paradigm.
323
+
324
+ ### Step 3.2: Learn typical transformation rules
325
+ read `page_align.md` to learn typical transformation rules
326
+
327
+ ### Step 3.3 Fix all Diffs
328
+ Read `{task_dir}/fix_checklist.md` and **Fix Every Diffs (No Matter significant or minor)**,
329
+ Use {reusable components} if it is available and has been aligned with Android
330
+ Following the MVVM mode
331
+
332
+ **Value tracing rule**: Before fixing any dimension/size/icon-size/alignment diff, you MUST trace the target value back to Android source code (layout XML `layout_width`/`layout_height`/`padding`/`src`, drawable intrinsic size, or style definition). Write the source reference (file:line or resource name) next to the checklist item. Estimating from screenshots or "looks about right" is NOT acceptable — if the Android source cannot be located, flag the item and ask the user.
333
+ **Alignment rule**: When implementing a new component or fixing an existing one, explicitly set alignment/justification for EVERY text and container element. Copy the alignment value directly from the Android UI_Analysis.md (e.g., "左对齐" → `.textAlign(TextAlign.Start)` + `.width('100%')`). Never rely on default alignment — always set it explicitly.
334
+ **Stateful component rule** (for [STATE]/[TRANSITION]/[ANIMATION] items):
335
+ - State enumerations must map 1:1 with Android states (same count, same semantics)
336
+ - Transition conditions (gesture type, threshold in vp, delay in ms) must be traced to Android source — copy values exactly
337
+ - Animation parameters (duration, easing, property, from/to values) must match Android precisely — refer to `state_model.md` for source references
338
+ - Implement state changes using HarmonyOS `@State` + conditional rendering or `.visibility()` per the MVVM pattern
339
+ - For gesture-triggered transitions, use ArkUI gesture APIs: `LongPressGesture`, `PanGesture`, `TapGesture` per `references/android-to-harmonyOS-ui-interaction-mapping-reference.md`
340
+ **After fixing each diff, update `fix_checklist.md`**: change `- [ ]` to `- [x]` for the completed item.
341
+ **CRITICAL RULE**:
342
+ - Do not skip any diff item in `fix_checklist.md`, regardless of the priority.
343
+ - Fixing compile errors does NOT count as fixing UI diffs. After the build passes, you MUST return to `fix_checklist.md` and continue fixing any remaining unchecked items. The task is not complete until every item in the checklist is marked `[x]`.
344
+
345
+ ### Step 3.4 Final Checklist Review
346
+ Read `fix_checklist.md` and verify every item is marked `[x]`. If any items remain unchecked:
347
+ 1. List the unchecked items
348
+ 2. For each, explain why it was not fixed (blocked by missing API, requires backend, etc.) or fix it now
349
+ 3. Items that genuinely cannot be fixed should be marked with `- [~]` and a reason
350
+
351
+ **Coverage re-check**: For each page, the `<!-- source: ... | items=N -->` comment records how many items the script extracted. Confirm the number of `- [x]`/`- [~]` lines under each page heading still matches that `items=N` count — if fewer, items were silently dropped during the review pass; recover them from the page's `UI_comparison.md`.
352
+
353
+ ## Step 4 validate and build (Main Agent)
354
+ if available, use `hmos-fix-build-errors` skill to verify the project is compilable, do not deploy.
355
+
356
+ ## Guidelines
357
+ - **Preserve existing code**: When editing existing files, make targeted edits — never rewrite an entire file from scratch. Respect the existing code structure, variable names, and patterns.
358
+ - **Follow existing conventions**: All new code must match the HarmonyOS project's established naming conventions, import patterns, state management approach, and component composition style.
359
+ - **Reuse rather than creating**: Always check for existing shared components, viewmodels, and models before creating new ones.
360
+ - **Resource references must match exactly**: every color, string, dimension, image, and other resource used in the Android source must have a corresponding HarmonyOS resource. Do not hardcode values.
361
+ - Use `$r('app.type.name')` for all resource references available in the resource list.
362
+ - Handle responsive layouts: prefer percentage widths and `Flex` over fixed dimensions where appropriate.
363
+ - Maintain accessibility: convert `content-desc` to `.accessibilityText()`, convert meaningful `text` to proper labels.
364
+ - Group related UI into `@Component` sub-components when the hierarchy is deep (> 5 nesting levels).
365
365
  - **鸿蒙 API 可参考 `OHOS_SDK_PATH` / `HMS_SDK_PATH`(HarmonyOS SDK 的 ETS 目录,取自 OS 环境变量);鸿蒙 MVVM 开发模式:V1 参考 `./references/MVVM开发文档/`,V2 参考 `./references/MVVM开发文档V2/`(按 Step 3.1 探测到的工程范式二选一,详见 `./references/MVVM开发文档V2/_范式选择说明.md`)**