android2harmony 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agents/self-tester.md +339 -0
- package/dist/index.js +625 -7
- package/dist/index.js.map +4 -4
- package/package.json +37 -29
- package/skills/hmos-incremental-ui-align/README.md +251 -0
- package/skills/hmos-incremental-ui-align/SKILL.md +365 -0
- package/skills/hmos-incremental-ui-align/diff_analysis.md +53 -0
- package/skills/hmos-incremental-ui-align/page_align.md +62 -0
- package/skills/hmos-incremental-ui-align/references/Comparison_Template.md +38 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@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 +648 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@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 +2089 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@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 +1033 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@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 +1183 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@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 +576 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@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 +297 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/@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 +395 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/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 +903 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md +106 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/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 +1178 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/MVVM/346/250/241/345/274/217V1.md +911 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243/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 +355 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243//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 +11 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/!!/350/257/255/346/263/225/357/274/232/345/217/214/345/220/221/347/273/221/345/256/232.md +206 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@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 +373 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@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 +158 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@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 +750 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@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 +1704 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@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 +1012 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@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 +164 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@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 +840 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@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 +856 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/@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 +83 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/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 +294 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/MVVM/346/250/241/345/274/217/357/274/210V2/357/274/211.md +1407 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/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 +1220 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2/_/350/214/203/345/274/217/351/200/211/346/213/251/350/257/264/346/230/216.md +47 -0
- package/skills/hmos-incremental-ui-align/references/MVVM/345/274/200/345/217/221/346/226/207/346/241/243V2//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 +840 -0
- package/skills/hmos-incremental-ui-align/references/State_Model_Template.md +74 -0
- package/skills/hmos-incremental-ui-align/references/UI_Analysis_Template.md +34 -0
- package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-atomic-component-mapping-reference.md +2533 -0
- package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-interaction-mapping-reference.md +555 -0
- package/skills/hmos-incremental-ui-align/references/android-to-harmonyOS-ui-layout-mapping-reference.md +117 -0
- package/skills/hmos-incremental-ui-align/scripts/app_feature_verify.ts +999 -0
- package/skills/hmos-incremental-ui-align/scripts/extract_checklist.ts +343 -0
- package/skills/hmos-incremental-ui-align/scripts/navigation-capure.md +76 -0
- package/skills/hmos-incremental-ui-align/scripts/page_capture.ts +977 -0
- package/skills/hmos-incremental-ui-align/scripts/page_capture_burst.ts +188 -0
- package/tools/autotest/deps/autotest-agent-0.1.1.tgz +0 -0
- package/tools/autotest/engine/batch-launcher.ts +326 -0
- package/tools/autotest/engine/report-tool.ts +773 -0
- package/tools/autotest/engine/self-test-runner.ts +1024 -0
- package/tools/autotest/engine/testcases-tool.ts +246 -0
- package/tools/autotest/resolve-metadata-tool.ts +143 -0
- package/tools/autotest/runner/logger.ts +45 -0
- package/tools/autotest/runner/process-utils.ts +41 -0
- package/tools/autotest/validate.ts +115 -0
|
@@ -0,0 +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).
|
|
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`)**
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
### Diff Analysis
|
|
2
|
+
use `{android_page_info}`, `{hmos_page_info}`,`{android_project_dir}`,`{harmony_project_dir}` to make a detailed comparison on visual effects
|
|
3
|
+
|
|
4
|
+
#### Step 1: Parse Android View Hierarchy
|
|
5
|
+
|
|
6
|
+
Read `{android_page_info}/view.xml` and build a structural understanding:
|
|
7
|
+
- Parse the XML node tree to understand the full view hierarchy
|
|
8
|
+
- Identify the key structural containers (root layouts, toolbar, content area, bottom navigation)
|
|
9
|
+
- Map each Android widget node to its attributes: `class`, `resource-id`, `text`, `content-desc`, `bounds`, `clickable`, `scrollable`, `checkable`, `checked`, `enabled`
|
|
10
|
+
- Calculate layout relationships from `bounds` (parent-child containment, sibling positioning)
|
|
11
|
+
- Identify recurring patterns (list items, grid items, card layouts)
|
|
12
|
+
|
|
13
|
+
If there exist `view_scroll_n.xml` files (n = 1, 2, 3, ...), read each one and merge their structural understanding with `view.xml` (the Android UI is longer than one screen).
|
|
14
|
+
|
|
15
|
+
Read the Android `screenshot.png` (and `screenshot_scroll_n.png` if they exist) to visually understand the target UI.
|
|
16
|
+
|
|
17
|
+
Additionally, find and read the static XML layout files and Kotlin/Java code files in `{android_project_dir}` that correspond to this page. Use atomic Android components to replace user-defined and third-party components, building a **final Android structural understanding**.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
#### Step 2: Parse HarmonyOS Current State
|
|
21
|
+
|
|
22
|
+
Read the HarmonyOS view tree XML and screenshot from `{hmos_page_info}/`:
|
|
23
|
+
- Parse the HarmonyOS view hierarchy to understand the current UI structure
|
|
24
|
+
- Read the screenshot to visually understand the current state
|
|
25
|
+
|
|
26
|
+
Also read the corresponding `.ets` source file(s) in `{harmony_project_dir}` for this page:
|
|
27
|
+
- Identify the existing component structure, state variables, child components
|
|
28
|
+
- Understand how the page is currently implemented
|
|
29
|
+
|
|
30
|
+
Build a **current HarmonyOS structural understanding**.
|
|
31
|
+
|
|
32
|
+
#### Step 3: Diff Analysis
|
|
33
|
+
|
|
34
|
+
Compare the Android final structural understanding (Step 4.1) against the HarmonyOS current structural understanding (Step 4.2):
|
|
35
|
+
Android pages and Harmony pages may be running on different devices, so be robust to the differences caused by devices (e.g., 组件间的间距、截图上显示的颜色等等)
|
|
36
|
+
|
|
37
|
+
1. **Structural diff**:
|
|
38
|
+
- Missing pages/components (in Android but not in HarmonyOS)
|
|
39
|
+
- Extra pages/components (in HarmonyOS but not in Android)
|
|
40
|
+
- Wrong nesting / layout structure differences
|
|
41
|
+
- Incorrect component type mappings
|
|
42
|
+
|
|
43
|
+
2. **Visual diff**:
|
|
44
|
+
- Color mismatches (background, foreground, fill)
|
|
45
|
+
- Size / spacing differences
|
|
46
|
+
- Position / alignment issues
|
|
47
|
+
- Shape mismatches (rounded corners, borders)
|
|
48
|
+
- Text content or font differences
|
|
49
|
+
- Icon / image mismatches
|
|
50
|
+
|
|
51
|
+
3. **Interaction diff** — compare clickable elements, navigation targets, gestures
|
|
52
|
+
|
|
53
|
+
Return a diff analysis report which lists all diffs
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Page Align Insruction
|
|
2
|
+
|
|
3
|
+
Based on the diff analysis, flexibly combine editing and creation as needed — a single page may require both aligning existing code and adding new components/files:
|
|
4
|
+
|
|
5
|
+
**For existing files that need alignment:**
|
|
6
|
+
- Read the existing `.ets` file(s) for this page
|
|
7
|
+
- For each discrepancy identified in the diff, make **targeted edits** using the Edit tool:
|
|
8
|
+
- Fix layout structure mismatches (wrong container type, missing nesting)
|
|
9
|
+
- Add missing components
|
|
10
|
+
- Remove extra components that don't exist in the Android UI
|
|
11
|
+
- Fix styling (colors, sizes, spacing, shapes)
|
|
12
|
+
- Fix resource references to use correct `$r('app.xxx.yyy')`
|
|
13
|
+
|
|
14
|
+
**For new files that need to be created** (new pages, new sub-components, new viewmodels/models):
|
|
15
|
+
- Generate new `.ets` files following the conventions discovered in Phase 1:
|
|
16
|
+
- Use the same import patterns as existing pages
|
|
17
|
+
- Use the same state management patterns
|
|
18
|
+
- Reuse existing shared components from `components/`
|
|
19
|
+
- Reuse or extend existing viewmodels/models
|
|
20
|
+
- Follow the same naming conventions
|
|
21
|
+
- Write page files to `{harmony_project_dir}/entry/src/main/ets/pages/`
|
|
22
|
+
- Write component files to `{harmony_project_dir}/entry/src/main/ets/components/`
|
|
23
|
+
- Write viewmodel files to `{harmony_project_dir}/entry/src/main/ets/viewmodel/`
|
|
24
|
+
- Write model files to `{harmony_project_dir}/entry/src/main/ets/model/`
|
|
25
|
+
- Register any new page in the router configuration
|
|
26
|
+
|
|
27
|
+
## For all changes, apply these conversion rules:
|
|
28
|
+
|
|
29
|
+
**Resource Conversion:**
|
|
30
|
+
- For each resource referenced by the Android UI, find the corresponding mapping in `{harmony_project_dir}/entry/src/main/resources`
|
|
31
|
+
- If a needed resource does not exist, use the **`hmos-resources-convert`** skill to convert it
|
|
32
|
+
|
|
33
|
+
**Layout Conversion:**
|
|
34
|
+
- Consult `./references/android-to-harmonyOS-ui-layout-mapping-reference.md` for all layout container mappings and layout attribute mappings
|
|
35
|
+
- Apply the layout property mappings (e.g., `layout_weight` → `.layoutWeight()`, `padding` → `.padding()`, visibility handling, etc.)
|
|
36
|
+
|
|
37
|
+
**Widget Conversion:**
|
|
38
|
+
- Consult `./references/android-to-harmonyOS-ui-atomic-component-mapping-reference.md` for all atomic widget mappings
|
|
39
|
+
- Apply the detailed attribute-level mappings for each component
|
|
40
|
+
|
|
41
|
+
**Interaction Conversion:**
|
|
42
|
+
- Consult `./references/android-to-harmonyOS-ui-interaction-mapping-reference.md` for all event and gesture mappings
|
|
43
|
+
- Apply touch event mappings, click event mappings, gesture mappings, and animation mappings
|
|
44
|
+
|
|
45
|
+
**Always consult the reference files first** — they contain project-specific and comprehensive mappings that take priority over built-in knowledge.
|
|
46
|
+
|
|
47
|
+
**Styling Conversion:**
|
|
48
|
+
- Android `dp` → HarmonyOS `vp`
|
|
49
|
+
- Android `sp` → HarmonyOS `fp`
|
|
50
|
+
- Calculate dimensions from `bounds` in the XML: `width = x2 - x1`, `height = y2 - y1`
|
|
51
|
+
- Convert absolute pixel values to `vp` using the **device density recorded in the page's `meta.json`** (`density_factor`): `vp = px ÷ density_factor`. Do NOT hardcode 3x — read `density_factor` from the Android capture's `meta.json` for Android values and from the HarmonyOS capture's `meta.json` for HarmonyOS values (they may differ). Only fall back to `3.0` if `meta.json` is missing.
|
|
52
|
+
- Use `$r('app.color.xxx')` for colors when available in the resource list
|
|
53
|
+
- Use `$r('app.string.xxx')` for text strings when available in the resource list
|
|
54
|
+
- Use `$r('app.media.xxx')` for images when available in the resource list
|
|
55
|
+
|
|
56
|
+
**Router Conversion:**
|
|
57
|
+
- Convert router relationships among UIs and components
|
|
58
|
+
- Register new page routes in the router configuration when new pages are created
|
|
59
|
+
- Fix any incorrect router targets in existing pages
|
|
60
|
+
|
|
61
|
+
**Interactive Elements:**
|
|
62
|
+
- **Prefer real implementation over mocking**: before mocking any click event, navigation jump, or interaction, first check whether the target component or page already exists in the HarmonyOS project. If the target is already implemented, wire up the real event handler (e.g., actual `router.pushUrl()` with the correct page path). **Only mock when the related component or page has not yet been implemented** — in that case, use placeholder implementations to ensure the program compiles (e.g., `console.info('TODO: navigate to SettingsActivity — target page not yet implemented')`)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
| UI Component | 文本内容 | 尺寸与布局 | 颜色与背景 | 边框与轮廓 | 文本样式 | 变换与效果 | 状态与交互反馈 | Diff |
|
|
2
|
+
|:-------------|:-----|:------|:------|:------|:-----|:------|:--------|:--------|
|
|
3
|
+
|
|
4
|
+
## Dynamic / Transient UI Comparison
|
|
5
|
+
|
|
6
|
+
| Effect | Android (Target) | HarmonyOS (Current) | Diff |
|
|
7
|
+
|:-------|:-----------------|:--------------------|:-----|
|
|
8
|
+
| e.g., page enter animation | alpha 0→1, 300ms ease-out (LoginActivity.kt:45) | 缺失 → 目标: animateTo alpha 0→1, 300ms ease-out | Missing |
|
|
9
|
+
| e.g., Toast on save | "保存成功", 2000ms, bottom (EditActivity.kt:88) | promptAction.showToast "已保存", 1500ms | Duration mismatch: 1500ms → 2000ms; Text: "已保存" → "保存成功" |
|
|
10
|
+
| e.g., voice input UI | mic click → waveform + overlay (SearchActivity.kt:78) | 缺失 → 目标: implement voice recognition with waveform | Missing |
|
|
11
|
+
|
|
12
|
+
Omit this section if `dynamic_ui_inventory.md` has no entries for this page.
|
|
13
|
+
|
|
14
|
+
## State Machine Comparison (Multi-State Components Only)
|
|
15
|
+
|
|
16
|
+
Include this section when the component was analyzed in Step 1.5 (has a `state_model.md` entry).
|
|
17
|
+
|
|
18
|
+
| Dimension | Android | HarmonyOS | Diff |
|
|
19
|
+
|:----------|:--------|:----------|:-----|
|
|
20
|
+
| 状态数量 | {N} ({state1}/{state2}/...) | {M} ({state1}/...) | {e.g., "缺少 cancelling, recognized"} |
|
|
21
|
+
| 状态变量类型 | {enum/sealed class/Int} | {enum/@State/未实现} | {diff or "一致"} |
|
|
22
|
+
|
|
23
|
+
### Per-Transition Comparison
|
|
24
|
+
|
|
25
|
+
| Transition | Android Trigger | Android Params | HarmonyOS Trigger | HarmonyOS Params | Diff |
|
|
26
|
+
|:-----------|:---------------|:---------------|:------------------|:-----------------|:-----|
|
|
27
|
+
| S0→S1 | {gesture type} | {threshold/duration} (Source:Line) | {gesture or "缺失"} | {params} | {diff description} |
|
|
28
|
+
| S1→S2 | {gesture type} | {threshold/duration} (Source:Line) | {gesture or "缺失"} | {params} | {HarmonyOS: 缺失 → 目标: {Android value}} |
|
|
29
|
+
|
|
30
|
+
### Per-State Visual Diff
|
|
31
|
+
|
|
32
|
+
| State | Property | Android Value | HarmonyOS Value | Diff |
|
|
33
|
+
|:------|:---------|:-------------|:----------------|:-----|
|
|
34
|
+
| S1 | background | #FFFFFF (Source:Line) | #F5F5F5 | HarmonyOS: #F5F5F5 → 目标: #FFFFFF |
|
|
35
|
+
| S1 | animation | waveform, realtime amplitude (Source:Line) | 静态 icon | HarmonyOS: 静态 → 目标: animateTo amplitude |
|
|
36
|
+
| S2 | border | 2vp dashed #FF4444 (Source:Line) | 缺失 | HarmonyOS: 缺失 → 目标: 2vp dashed #FF4444 |
|
|
37
|
+
|
|
38
|
+
Omit this section if no multi-state components were identified in Step 1.5.
|