android2harmony 0.1.5 → 0.1.6
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 +33 -354
- package/dist/index.js +172 -76
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/skills/a2h-resource-convert/SKILL.md +36 -7
- package/skills/a2h-resource-convert/scripts/a2h_resource_convert.js +20 -0
- package/skills/a2h-resource-convert/scripts/app_identity.js +741 -0
- package/skills/a2h-ui-transfer/SKILL.md +14 -3
- package/skills/a2h-ui-transfer/references/conversion-procedure.md +5 -30
- package/skills/a2h-ui-transfer/scripts/android_parse_fast.js +137 -20
- package/skills/hmos-fix-build-errors/SKILL.md +1 -1
- package/skills/hmos-incremental-ui-align/README.md +251 -251
- package/skills/hmos-incremental-ui-align/SKILL.md +364 -364
- package/skills/hmos-integration-test/README.md +341 -0
- package/skills/hmos-integration-test/SKILL.md +446 -0
- package/skills/hmos-integration-test/scripts/report-tool.mjs +646 -0
- package/skills/hmos-integration-test/scripts/resolve-metadata-tool.mjs +147 -0
- package/skills/hmos-integration-test/scripts/self-test-runner.mjs +1006 -0
- package/skills/hmos-integration-test/scripts/testcases-tool.mjs +189 -0
- package/skills/hmos-spec-generate/SKILL.md +26 -24
- package/skills/hmos-spec-generate/scripts/parse_requirements.ts +515 -0
- package/skills/hmos-spec-generate/template/REQ.txt +22 -0
- package/skills/hmos-spec-generate/template/REQ.xlsx +0 -0
|
@@ -42,7 +42,20 @@ node ./scripts/a2h_resource_convert.js \
|
|
|
42
42
|
--ui-module <ui_module> \
|
|
43
43
|
--records <work_dir>/records.json
|
|
44
44
|
|
|
45
|
-
# 2.
|
|
45
|
+
# 2. App identity: launcher icon + app name → AppScope/app.json5 + abilities[0]
|
|
46
|
+
# Step 1 converts the icon *assets* and the app-name string, but writes them into
|
|
47
|
+
# <ui_module>/…/resources — while the desktop icon and app name are decided by
|
|
48
|
+
# AppScope/app.json5, whose $media:/$string: domain is AppScope/resources. Nothing
|
|
49
|
+
# else reads AndroidManifest's android:icon / android:label either, so without this
|
|
50
|
+
# step the DevEco template defaults survive: default icon and the name "label".
|
|
51
|
+
# Runs after step 1 because it reuses the layered-image JSON that step produces.
|
|
52
|
+
node ./scripts/app_identity.js \
|
|
53
|
+
--manifest <decoded_output_path>/AndroidManifest.xml \
|
|
54
|
+
--res <decoded_output_path>/res \
|
|
55
|
+
--harmony <harmony_project_dir> --ui-module <ui_module> \
|
|
56
|
+
--json <work_dir>/app_identity.json
|
|
57
|
+
|
|
58
|
+
# 3. Code-defined vector icons — REQUIRED for any Jetpack Compose app (see Step 4.1.3)
|
|
46
59
|
# --fetch pulls artwork from a pinned upstream commit, never a moving branch.
|
|
47
60
|
# Requires network access to raw.githubusercontent.com.
|
|
48
61
|
# Prefer a *minified* (release) APK's decoded dir. On a debug APK the icon library
|
|
@@ -54,23 +67,24 @@ node ./scripts/code_vector_icons.js \
|
|
|
54
67
|
--out <harmony_project_dir>/<ui_module>/src/main/resources/base/media \
|
|
55
68
|
--fetch --json <work_dir>/icons.json
|
|
56
69
|
|
|
57
|
-
#
|
|
70
|
+
# 4. Vector fidelity gate — any error blocks completion
|
|
58
71
|
node ./scripts/svg_fidelity_check.js \
|
|
59
72
|
--android-res <decoded_output_path>/res \
|
|
60
73
|
--harmony-media <harmony_project_dir>/<ui_module>/src/main/resources/base/media \
|
|
61
74
|
--json <work_dir>/fidelity.json
|
|
62
75
|
|
|
63
|
-
#
|
|
76
|
+
# 5. Documents, rebuilt from the records of step 1 plus the results of steps 3-4
|
|
64
77
|
node ./scripts/a2h_resource_convert.js --docs-only \
|
|
65
78
|
--records <work_dir>/records.json \
|
|
66
79
|
--icons-json <work_dir>/icons.json --fidelity-json <work_dir>/fidelity.json \
|
|
80
|
+
--app-identity-json <work_dir>/app_identity.json \
|
|
67
81
|
--report <work_dir>/resource_conversion_report.md \
|
|
68
82
|
--mapping <resource_mapping_path> \
|
|
69
83
|
--apk <apk_path> --android-commit <commit> --app-module <app_module> \
|
|
70
84
|
--harmony <harmony_project_dir>
|
|
71
85
|
```
|
|
72
86
|
|
|
73
|
-
Step
|
|
87
|
+
Step 5 is separate because the documents need the fidelity and icon results, which in turn need the artifacts step 1 produces. It re-reads `records.json` rather than re-running the conversion.
|
|
74
88
|
|
|
75
89
|
**What remains your job:**
|
|
76
90
|
|
|
@@ -606,7 +620,7 @@ After resolution, scan all converted resources for any remaining unresolved refe
|
|
|
606
620
|
|
|
607
621
|
### Step 6: Verify Completeness
|
|
608
622
|
|
|
609
|
-
Items 1-9 and 11 below are performed by `scripts/a2h_resource_convert.js` and reported in `records.json`; items 10 and
|
|
623
|
+
Items 1-9 and 11 below are performed by `scripts/a2h_resource_convert.js` and reported in `records.json`; items 10, 12 and 13 are the three separate gates (`svg_fidelity_check.js`, `code_vector_icons.js` and `app_identity.js`). Your job is to confirm each one actually ran and to act on what it found — a gate whose output nobody read is not a gate.
|
|
610
624
|
|
|
611
625
|
The checks are:
|
|
612
626
|
|
|
@@ -644,6 +658,15 @@ The checks are:
|
|
|
644
658
|
c. The pinned snapshot ref used for artwork is recorded in the report and in the mapping document metadata. A run whose artwork came from a moving branch is not reproducible and must be re-run against a pinned ref.
|
|
645
659
|
|
|
646
660
|
Unlike item 10, a failure here does not block completion — an unresolved icon is a recorded gap, not a corrupt asset. But an *unrecorded* icon does block: it reproduces exactly the defect this step exists to catch.
|
|
661
|
+
13. **App identity (launcher icon + app name), blocking**: items 1-12 all reason about the `<ui_module>` resource tree. The desktop icon and app name live somewhere else — `AppScope/app.json5`, whose `$media:`/`$string:` domain is `AppScope/resources` — and no other item touches them. Run Toolchain step 2's gate:
|
|
662
|
+
|
|
663
|
+
```
|
|
664
|
+
node ./scripts/app_identity.js --check --json <work_dir>/app_identity.json
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
It re-reads both `json5` files and requires that `AppScope/app.json5`'s `icon`/`label` and `abilities[0]`'s `icon`/`label`/`startWindowIcon` still hold the values resolved from `AndroidManifest.xml`, and that each reference resolves to a file that exists in the *right* resource root. **`GATE: FAIL` blocks completion** — this is a user-visible wrong product (default icon, app named "label"), not a recorded gap.
|
|
668
|
+
|
|
669
|
+
It compares against the recorded values rather than against "not equal to the template default" on purpose: template defaults change between DevEco versions, so a default-value check misses. Note this is the one item existing checks structurally cannot catch — the template's `$media:layered_image` points at a template-supplied file that really exists, so every existence and reference check upstream passes while the icon is still wrong.
|
|
647
670
|
|
|
648
671
|
**Placeholder SVG template** (for missing media resources):
|
|
649
672
|
```svg
|
|
@@ -656,7 +679,7 @@ Replace `RESOURCE_NAME` with the actual resource name (truncated if too long).
|
|
|
656
679
|
|
|
657
680
|
### Step 7: Generate Report
|
|
658
681
|
|
|
659
|
-
The report is written by Toolchain step
|
|
682
|
+
The report is written by Toolchain step 5 (`--docs-only --report`). It is deliberately **aggregated** so a human can read it end to end: counts by type, qualifier mappings, the full reference-resolution table, unmappable reasons grouped by cause, fidelity findings, code-defined icons, and warnings grouped by kind with a per-kind sample. The exhaustive per-resource listing belongs in the mapping document (Step 8), not here.
|
|
660
683
|
|
|
661
684
|
Your job is to read it and act on what it says — an unresolved reference, a fidelity error, or a target collision is a finding, not a formatting detail.
|
|
662
685
|
|
|
@@ -704,6 +727,12 @@ Libraries declared in the project's build.gradle that may provide resources:
|
|
|
704
727
|
- Code-defined icon media files written: <count>
|
|
705
728
|
- Code-defined icons screen-attributed / Unknown: <count> / <count>
|
|
706
729
|
- Material Icons snapshot ref: <pinned commit or vendored snapshot path>
|
|
730
|
+
- App icon: <AndroidManifest android:icon> → <AppScope/app.json5 icon value> | "未改写(原因)"
|
|
731
|
+
- App name: <AndroidManifest android:label> → <app.json5 label value> = "<resolved text>" | "未改写(原因)"
|
|
732
|
+
- App name locales written to AppScope: <qualifier dirs, e.g. base, zh_CN>
|
|
733
|
+
- App identity gate: <PASS | FAIL(n 项)>
|
|
734
|
+
|
|
735
|
+
Take these five lines from `app_identity.json` (Toolchain step 2). `a2h-ui-transfer` greps them as its App-identity gate, so keep the labels verbatim.
|
|
707
736
|
|
|
708
737
|
## Conversion Details
|
|
709
738
|
|
|
@@ -836,7 +865,7 @@ Media resources referenced in `.ets` UI code but not found in converted resource
|
|
|
836
865
|
|
|
837
866
|
### Step 8: Generate Resource Mapping Document
|
|
838
867
|
|
|
839
|
-
The second document, at `resource_mapping_path`, is written by the same Toolchain step
|
|
868
|
+
The second document, at `resource_mapping_path`, is written by the same Toolchain step 5 invocation (`--mapping`). It is the audit surface: **every** observed Android resource appears as its own row, `values` at entry granularity. It does not sample, summarise, or aggregate — those are the report's job. Expect it to be large (measured range: 4 MB to 22 MB); that size is the cost of the no-omission requirement, and the dataset tracks these files with Git LFS for exactly that reason.
|
|
840
869
|
|
|
841
870
|
Do not hand-write or hand-trim this document. If it looks too large, that is not a reason to sample it.
|
|
842
871
|
|
|
@@ -1832,6 +1832,25 @@ class DocWriter {
|
|
|
1832
1832
|
} else {
|
|
1833
1833
|
p('- Code-defined vector icons: not analysed (run scripts/code_vector_icons.js)');
|
|
1834
1834
|
}
|
|
1835
|
+
// 应用图标 / 应用名。这几行 a2h-ui-transfer 会 grep 作为 App-identity gate,
|
|
1836
|
+
// 标签文字不要改。
|
|
1837
|
+
const idn = this.ctx.appIdentity;
|
|
1838
|
+
if (idn) {
|
|
1839
|
+
const r = idn.resolved ?? {};
|
|
1840
|
+
// 原因要按字段挑,不能一律取 warnings[0]:图标的告警贴到应用名那行上,
|
|
1841
|
+
// 读者会照着错的原因去排查。
|
|
1842
|
+
const why = (re) => {
|
|
1843
|
+
const hit = (idn.warnings ?? []).find((w) => re.test(w));
|
|
1844
|
+
return hit ? `未改写(${hit})` : '未改写';
|
|
1845
|
+
};
|
|
1846
|
+
p(`- App icon: ${idn.android?.icon || '(none)'} → ${r.appIcon ?? why(/图标/)}`);
|
|
1847
|
+
p(`- App name: ${idn.android?.label || '(none)'} → ${r.appLabel ?? why(/应用名|label/)}`
|
|
1848
|
+
+ (r.labelValue != null ? ` = "${r.labelValue}"` : ''));
|
|
1849
|
+
p(`- App name locales written to AppScope: ${(r.labelQualifiers ?? []).join(', ') || '(none)'}`);
|
|
1850
|
+
p(`- App identity gate: ${r.appIcon && r.appLabel ? 'PASS' : 'FAIL(应用图标或应用名未落地)'}`);
|
|
1851
|
+
} else {
|
|
1852
|
+
p('- App identity (launcher icon + app name): not run (run scripts/app_identity.js)');
|
|
1853
|
+
}
|
|
1835
1854
|
p();
|
|
1836
1855
|
|
|
1837
1856
|
p('## Conversion Details');
|
|
@@ -2154,6 +2173,7 @@ function emitDocs(
|
|
|
2154
2173
|
buildResult: typeof args['build-result'] === 'string' ? args['build-result'] : '(not run by this script)',
|
|
2155
2174
|
icons: readJson('icons-json'),
|
|
2156
2175
|
fidelity: readJson('fidelity-json'),
|
|
2176
|
+
appIdentity: readJson('app-identity-json'),
|
|
2157
2177
|
});
|
|
2158
2178
|
if (typeof args.report === 'string') fs.writeFileSync(args.report, `${doc.report()}
|
|
2159
2179
|
`, 'utf8');
|