@harmonyos-arkts/d2h 0.1.11 → 0.1.13

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 (126) hide show
  1. package/.claude-plugin/marketplace.json +15 -13
  2. package/.claude-plugin/plugin.json +13 -7
  3. package/AGENTS.md +5 -5
  4. package/README.md +212 -212
  5. package/agents/android-to-hmos-00-orchestrator.md +318 -318
  6. package/agents/d2h.md +157 -157
  7. package/dist/bin/install-opencode.js +30 -30
  8. package/docs/environment-check.md +86 -86
  9. package/install-opencode.sh +160 -160
  10. package/opencode/agents.json +16 -16
  11. package/opencode/vscode-d2h-package.json +7 -7
  12. package/opencode/vscode-d2h-plugin.mjs +29 -29
  13. package/package.json +54 -54
  14. package/schemas/android-source-manifest.schema.json +25 -25
  15. package/schemas/checkpoint-provenance.schema.json +67 -67
  16. package/schemas/final-acceptance.schema.json +29 -29
  17. package/schemas/managed-evidence-index.schema.json +15 -15
  18. package/schemas/managed-evidence.schema.json +114 -114
  19. package/schemas/migration-config.schema.json +51 -51
  20. package/schemas/migration-report-index.schema.json +39 -39
  21. package/schemas/migration-report-item.schema.json +51 -51
  22. package/schemas/migration-report-summary.schema.json +25 -25
  23. package/schemas/migration-status.schema.json +202 -202
  24. package/schemas/preflight.schema.json +60 -60
  25. package/schemas/source-order-audit.schema.json +16 -16
  26. package/schemas/source-provenance-event.schema.json +19 -19
  27. package/schemas/spec-app-shard.schema.json +45 -45
  28. package/schemas/spec-fact-corrections-shard.schema.json +13 -13
  29. package/schemas/spec-features-shard.schema.json +43 -43
  30. package/schemas/spec-index.schema.json +26 -26
  31. package/schemas/spec-interactions-shard.schema.json +40 -40
  32. package/schemas/spec-page.schema.json +98 -98
  33. package/schemas/spec-pages-index.schema.json +1 -1
  34. package/schemas/spec-unresolved-shard.schema.json +1 -1
  35. package/schemas/task-envelope.schema.json +109 -109
  36. package/schemas/task-plan.schema.json +341 -341
  37. package/scripts/check-environment.mjs +320 -320
  38. package/skills/android2hmos_resources_convert/SKILL.md +180 -180
  39. package/skills/android2hmos_resources_convert/references/image-conversion-rules.md +230 -230
  40. package/skills/android2hmos_resources_convert/references/svg-fix-patterns.md +175 -175
  41. package/skills/android2hmos_resources_convert/references/xml-drawable-to-svg-rules.md +513 -513
  42. package/skills/arkts-app-identity/SKILL.md +238 -238
  43. package/skills/arkts-i18n/SKILL.md +496 -496
  44. package/skills/arkts-i18n/evals/evals.json +84 -84
  45. package/skills/arkts-i18n/references/code-examples.md +302 -302
  46. package/skills/arkts-i18n/references/common-pitfalls.md +391 -391
  47. package/skills/arkts-i18n/references/dynamic-language-switch.md +604 -604
  48. package/skills/arkts-i18n/references/hardcoded-string-scanner.md +348 -348
  49. package/skills/arkts-i18n/references/language-codes.md +104 -104
  50. package/skills/arkts-i18n/references/resource-file-structure.md +775 -775
  51. package/skills/arkts-i18n/references/static-vs-dynamic.md +242 -242
  52. package/skills/arkts-i18n/references/v1-compat.md +244 -244
  53. package/skills/arkts-i18n/scripts/audit_i18n_completeness.sh +174 -174
  54. package/skills/arkts-icon-sizing/SKILL.md +211 -211
  55. package/skills/arkts-icon-sizing/scripts/icon_audit.py +131 -131
  56. package/skills/arkts-icon-sizing/scripts/icon_autofix.py +88 -88
  57. package/skills/arkts-icon-sizing/scripts/icon_dims.py +179 -179
  58. package/skills/arkts-icon-sizing/scripts/icon_fix.py +119 -119
  59. package/skills/arkts-mvvm-architecture/SKILL.md +613 -613
  60. package/skills/d2h-hypium-forge/SKILL.md +309 -309
  61. package/skills/d2h-hypium-forge/references/functional-spec-template.md +140 -140
  62. package/skills/d2h-hypium-forge/references/official-api.md +135 -135
  63. package/skills/d2h-hypium-forge/references/pitfalls.md +98 -98
  64. package/skills/d2h-hypium-forge/references/testability-template.md +71 -71
  65. package/skills/d2h-hypium-forge/scripts/_common_template.py +659 -659
  66. package/skills/d2h-hypium-forge/scripts/analyze_results.py +165 -165
  67. package/skills/d2h-hypium-forge/scripts/assert_audit.py +107 -107
  68. package/skills/d2h-hypium-forge/scripts/collect_runtime_pages.py +169 -169
  69. package/skills/d2h-hypium-forge/scripts/forge_report.py +325 -325
  70. package/skills/d2h-hypium-forge/scripts/inject_resource_ids.py +114 -114
  71. package/skills/d2h-hypium-forge/scripts/lint_asserts.py +80 -80
  72. package/skills/d2h-hypium-forge/scripts/lint_locate.py +60 -60
  73. package/skills/d2h-hypium-forge/scripts/merge_appgraph.py +249 -249
  74. package/skills/d2h-hypium-forge/scripts/precondition.py +140 -140
  75. package/skills/d2h-hypium-forge/scripts/preinject_ids.py +232 -232
  76. package/skills/d2h-hypium-forge/scripts/probe.py +197 -197
  77. package/skills/d2h-hypium-forge/scripts/run_direct.py +823 -823
  78. package/skills/d2h-hypium-forge/scripts/run_parallel.py +121 -121
  79. package/skills/d2h-hypium-forge/scripts/scan_features.py +255 -255
  80. package/skills/d2h-hypium-forge/scripts/upgrade_asserts.py +66 -66
  81. package/skills/d2h-hypium-forge/scripts/validate_scenarios.py +84 -84
  82. package/skills/d2h-page-develop/SKILL.md +112 -112
  83. package/skills/d2h-page-develop/agents/openai.yaml +7 -7
  84. package/skills/d2h-page-spec-generate/SKILL.md +206 -206
  85. package/skills/d2h-page-spec-generate/scripts/build_batch_report.py +227 -227
  86. package/skills/d2h-utg-ai-generate/SKILL.md +128 -128
  87. package/skills/d2h-utg-ai-generate/references/click-paths-schema.json +76 -76
  88. package/skills/d2h-utg-ai-generate/references/extraction-guide.md +34 -34
  89. package/skills/d2h-utg-ai-generate/references/facts-contract.md +96 -96
  90. package/skills/d2h-utg-ai-generate/references/page-schema.json +61 -61
  91. package/skills/d2h-utg-ai-generate/references/utg-schema.json +89 -89
  92. package/skills/d2h-utg-ai-generate/scripts/build_page_json.py +314 -314
  93. package/skills/d2h-utg-ai-generate/scripts/build_utg.py +123 -123
  94. package/skills/d2h-utg-ai-generate/scripts/capture_from_page_json.ts +280 -280
  95. package/skills/d2h-utg-ai-generate/scripts/utg_common.py +524 -524
  96. package/skills/d2h-utg-ai-generate/scripts/utg_html.py +489 -489
  97. package/skills/d2h-utg-ai-generate/scripts/validate_utg.py +69 -69
  98. package/skills/d2h-utg-ai-generate/scripts/vendor/D3-LICENSE +13 -13
  99. package/skills/d2h-utg-ai-generate/scripts/vendor/d3-7.9.0.min.js +2 -2
  100. package/skills/d2h-utg-ai-generate/tests/test_pipeline.py +369 -369
  101. package/skills/d2h-utg-static-generate/SKILL.md +73 -73
  102. package/skills/d2h-utg-static-generate/references/discoveries.md +38 -38
  103. package/skills/d2h-utg-static-generate/scripts/generate.py +499 -499
  104. package/skills/d2h-utg-static-generate/tests/test_static.py +335 -335
  105. package/skills/d2h-utg-static-generate/tests/verify-offline-html.py +60 -60
  106. package/skills/d2h-utg-static-generate/tests/verify-produced-fixture.py +131 -131
  107. package/skills/harmonyos-migration-playbook/SKILL.md +83 -83
  108. package/skills/harmonyos-migration-playbook/agents/openai.yaml +7 -7
  109. package/skills/harmonyos-migration-playbook/references/arkts-compile.md +24 -24
  110. package/skills/harmonyos-migration-playbook/references/harmony-runtime.md +53 -53
  111. package/skills/harmonyos-migration-playbook/references/lesson-lifecycle.md +45 -45
  112. package/skills/harmonyos-migration-playbook/references/protocol-e2e.md +23 -23
  113. package/skills/harmonyos-migration-playbook/references/ui-automation.md +53 -53
  114. package/skills/harmonyos-migration-playbook/references/windows-environment.md +38 -38
  115. package/skills/maintaining-migration-report/SKILL.md +144 -144
  116. package/skills/maintaining-migration-report/references/final-acceptance.md +48 -48
  117. package/skills/maintaining-migration-report/references/source-provenance.md +66 -66
  118. package/skills/managing-d2h-toolchain/SKILL.md +24 -24
  119. package/skills/managing-d2h-toolchain/environment-requirements.json +16 -16
  120. package/skills/managing-d2h-toolchain/scripts/manage-toolchain.mjs +98 -98
  121. package/skills/managing-d2h-toolchain/toolchain.json +16 -16
  122. package/skills/native-library-substitution/SKILL.md +384 -384
  123. package/skills/native-library-substitution/references/native-library-substitution.json +56905 -56905
  124. package/skills/native-library-substitution/references/native-library-substitution.md +163 -163
  125. package/skills/preparing-migration-workspace/SKILL.md +131 -131
  126. package/skills/reviewing-migration-process/SKILL.md +62 -62
@@ -1,24 +1,24 @@
1
- # ArkTS compilation diagnosis
2
-
3
- Use the compiler error and the smallest failing construct. These are migration patterns, not permission to mechanically rewrite unrelated code.
4
-
5
- | Error/pattern | Check | Typical repair |
6
- |---|---|---|
7
- | `arkts-no-any-unknown` | untyped catch/callback value | introduce an explicit supported type and narrow safely |
8
- | `arkts-no-untyped-obj-literals` | object literal crosses a typed boundary | define a class/interface and construct the declared value |
9
- | `arkts-no-obj-literals-as-types` | inline object type | introduce a named type |
10
- | `arkts-no-indexed-signatures` | string-key object access | use `Map` or a typed wrapper API |
11
- | `arkts-no-structural-typing` | shape-compatible literal assigned to class | use the class constructor |
12
- | `arkts-no-destruct-params` | destructured callback parameter | accept one typed parameter, then read fields |
13
- | `arkts-no-misplaced-imports` | import emitted below declarations | move imports to the file header |
14
- | implicit return failure | branch result cannot be inferred | declare a concrete return type |
15
-
16
- Also check compiler/SDK support before applying these previously observed repairs:
17
-
18
- - Enum strings usually need an explicit parser rather than a blind cast.
19
- - Unsupported Unicode escape syntax can be replaced with a supported literal or four-digit escape.
20
- - A `Button` label constructor and child content must follow the active ArkUI API signature.
21
- - Complex inline component callbacks may need a data-driven component API.
22
- - Expressions rejected inside `build()` can move to a typed helper method.
23
-
24
- Verification: rerun the exact ArkTS compile command and a focused test for behavior affected by the rewrite. A different compiler error is not success.
1
+ # ArkTS compilation diagnosis
2
+
3
+ Use the compiler error and the smallest failing construct. These are migration patterns, not permission to mechanically rewrite unrelated code.
4
+
5
+ | Error/pattern | Check | Typical repair |
6
+ |---|---|---|
7
+ | `arkts-no-any-unknown` | untyped catch/callback value | introduce an explicit supported type and narrow safely |
8
+ | `arkts-no-untyped-obj-literals` | object literal crosses a typed boundary | define a class/interface and construct the declared value |
9
+ | `arkts-no-obj-literals-as-types` | inline object type | introduce a named type |
10
+ | `arkts-no-indexed-signatures` | string-key object access | use `Map` or a typed wrapper API |
11
+ | `arkts-no-structural-typing` | shape-compatible literal assigned to class | use the class constructor |
12
+ | `arkts-no-destruct-params` | destructured callback parameter | accept one typed parameter, then read fields |
13
+ | `arkts-no-misplaced-imports` | import emitted below declarations | move imports to the file header |
14
+ | implicit return failure | branch result cannot be inferred | declare a concrete return type |
15
+
16
+ Also check compiler/SDK support before applying these previously observed repairs:
17
+
18
+ - Enum strings usually need an explicit parser rather than a blind cast.
19
+ - Unsupported Unicode escape syntax can be replaced with a supported literal or four-digit escape.
20
+ - A `Button` label constructor and child content must follow the active ArkUI API signature.
21
+ - Complex inline component callbacks may need a data-driven component API.
22
+ - Expressions rejected inside `build()` can move to a typed helper method.
23
+
24
+ Verification: rerun the exact ArkTS compile command and a focused test for behavior affected by the rewrite. A different compiler error is not success.
@@ -1,53 +1,53 @@
1
- # HarmonyOS runtime diagnosis
2
-
3
- The following are Thunderbird migration observations. Confirm them against the active SDK and current call path.
4
-
5
- ## TLS and networking
6
-
7
- - When TLS reports missing socket/bind state, instrument bind and connect separately. Some SDK paths require binding a local address before `connect` and explicit supported protocols.
8
- - Android STARTTLS flows do not automatically imply a one-to-one HarmonyOS socket upgrade API. Confirm current platform support; if behavior must change, preserve the user-visible security contract and document the adaptation.
9
- - A request that appears hung needs stage logs and a deterministic timeout path. Do not assume a timeout strategy works if the scheduling context itself is stalled.
10
-
11
- ### Real-device TLSSocket receive failure (proven platform defect, Mate system build)
12
-
13
- Symptom chain on a physical phone against any TLS endpoint (incl. `www.qq.com:443`):
14
- `bind ok → TLS handshake ok → send ok → 'message' callback never delivers any byte`, while the
15
- system `@ohos.net.http` stack fetches HTTPS fine at the same moment and the identical
16
- TLSSocket code passes on the emulator.
17
-
18
- Bisection procedure (ship a probe page, launch via want param, e.g. `--ps tlsProbe 1`):
19
-
20
- 1. control `http.request('https://...')` — if this also fails, the device network is the problem;
21
- 2. TLSSocket to a well-known HTTPS host with an HTTP GET — if handshake succeeds but zero bytes
22
- arrive, the TLSSocket receive path is broken on that system build;
23
- 3. confirm on the emulator with the same code before blaming the app.
24
-
25
- Related real bugs to fix BEFORE attributing to the platform (each bit us once):
26
-
27
- - `TLSSocket.send`/`TCPSocket.send` on real devices rejected ArrayBuffer slices copied from
28
- Uint8Array (`"data is not string"`); line protocols should send plain strings
29
- (`tls.send(str)`, `tcp.send({ data: str })`).
30
- - Servers that reject credentials (163/QQ IMAP with a login password) may half-close without
31
- firing `close`; treat `message` with 0 length as peer-closed to fail fast, and surface a
32
- provider-specific hint (authorization code / 授权码) instead of a raw timeout.
33
- - IPv6-preferred networks can blackhole the AAAA path: resolve with
34
- `connection.getAddressesByName` and prefer an A record; Coremail servers do not require SNI,
35
- so IP-direct connect still passes certificate validation.
36
-
37
- ## IME and asynchronous callbacks
38
-
39
- If work triggered from `TextInput.onSubmit` produces no logs or completion:
40
-
41
- 1. prove the synchronous callback ran;
42
- 2. log before and after the asynchronous boundary;
43
- 3. compare with the same operation triggered by a normal button;
44
- 4. keep IME handling synchronous if the current SDK reproduces the stall, and move business execution to a verified callback path.
45
-
46
- Do not universalize this behavior without a current reproduction.
47
-
48
- ## Component state
49
-
50
- - If an externally changed value is not rendered, verify whether the ArkUI component is controlled by that state or only initialized from it.
51
- - If a static theme lookup does not redraw, establish a real observed state dependency and verify the rendered color after switching.
52
-
53
- Verification must include the actual runtime path, not only compilation or a matching function name.
1
+ # HarmonyOS runtime diagnosis
2
+
3
+ The following are Thunderbird migration observations. Confirm them against the active SDK and current call path.
4
+
5
+ ## TLS and networking
6
+
7
+ - When TLS reports missing socket/bind state, instrument bind and connect separately. Some SDK paths require binding a local address before `connect` and explicit supported protocols.
8
+ - Android STARTTLS flows do not automatically imply a one-to-one HarmonyOS socket upgrade API. Confirm current platform support; if behavior must change, preserve the user-visible security contract and document the adaptation.
9
+ - A request that appears hung needs stage logs and a deterministic timeout path. Do not assume a timeout strategy works if the scheduling context itself is stalled.
10
+
11
+ ### Real-device TLSSocket receive failure (proven platform defect, Mate system build)
12
+
13
+ Symptom chain on a physical phone against any TLS endpoint (incl. `www.qq.com:443`):
14
+ `bind ok → TLS handshake ok → send ok → 'message' callback never delivers any byte`, while the
15
+ system `@ohos.net.http` stack fetches HTTPS fine at the same moment and the identical
16
+ TLSSocket code passes on the emulator.
17
+
18
+ Bisection procedure (ship a probe page, launch via want param, e.g. `--ps tlsProbe 1`):
19
+
20
+ 1. control `http.request('https://...')` — if this also fails, the device network is the problem;
21
+ 2. TLSSocket to a well-known HTTPS host with an HTTP GET — if handshake succeeds but zero bytes
22
+ arrive, the TLSSocket receive path is broken on that system build;
23
+ 3. confirm on the emulator with the same code before blaming the app.
24
+
25
+ Related real bugs to fix BEFORE attributing to the platform (each bit us once):
26
+
27
+ - `TLSSocket.send`/`TCPSocket.send` on real devices rejected ArrayBuffer slices copied from
28
+ Uint8Array (`"data is not string"`); line protocols should send plain strings
29
+ (`tls.send(str)`, `tcp.send({ data: str })`).
30
+ - Servers that reject credentials (163/QQ IMAP with a login password) may half-close without
31
+ firing `close`; treat `message` with 0 length as peer-closed to fail fast, and surface a
32
+ provider-specific hint (authorization code / 授权码) instead of a raw timeout.
33
+ - IPv6-preferred networks can blackhole the AAAA path: resolve with
34
+ `connection.getAddressesByName` and prefer an A record; Coremail servers do not require SNI,
35
+ so IP-direct connect still passes certificate validation.
36
+
37
+ ## IME and asynchronous callbacks
38
+
39
+ If work triggered from `TextInput.onSubmit` produces no logs or completion:
40
+
41
+ 1. prove the synchronous callback ran;
42
+ 2. log before and after the asynchronous boundary;
43
+ 3. compare with the same operation triggered by a normal button;
44
+ 4. keep IME handling synchronous if the current SDK reproduces the stall, and move business execution to a verified callback path.
45
+
46
+ Do not universalize this behavior without a current reproduction.
47
+
48
+ ## Component state
49
+
50
+ - If an externally changed value is not rendered, verify whether the ArkUI component is controlled by that state or only initialized from it.
51
+ - If a static theme lookup does not redraw, establish a real observed state dependency and verify the rendered color after switching.
52
+
53
+ Verification must include the actual runtime path, not only compilation or a matching function name.
@@ -1,45 +1,45 @@
1
- # Lesson lifecycle
2
-
3
- ## Read before a task
4
-
5
- Read `.migration/experience/lessons.md` when it exists. Select lessons by task type, symptom, subsystem and applicability. Do not load or repeat unrelated lessons.
6
-
7
- ## Record after validation and commit
8
-
9
- The playbook returns a lesson candidate only after the root cause and fix are supported by current-project evidence. The caller decides whether validation and checkpoint requirements are satisfied and whether to persist or promote the candidate. Use this structure:
10
-
11
- ```markdown
12
- ## <short title>
13
- - Task/commit: `<task>` / `<sha>`
14
- - Evidence level: project-validated | reusable-pattern | platform-rule
15
- - Applies when: <specific conditions and versions>
16
- - Symptom: <observable failure>
17
- - Root cause: <proven cause>
18
- - Fix: <minimal effective change>
19
- - Verification: <commands, tests, device evidence>
20
- - Does not apply when: <known boundary>
21
- ```
22
-
23
- Skip routine success, generic coding advice, speculative causes, duplicate lessons and details recoverable from the commit alone.
24
-
25
- If the project tracks `.migration/experience/lessons.md`, the caller may persist an accepted candidate there. The migration workspace `<android-project>-migration/` lives outside the Android Git repository, so the lesson remains workspace-local run memory unless that workspace is versioned independently.
26
-
27
- This reference does not inspect, create, or time checkpoints and never recommends broad staging merely to capture a lesson.
28
-
29
- ## Promote to the public playbook
30
-
31
- `.migration/experience/lessons.md` is the source-project evidence log, not the cross-project knowledge base. After the caller confirms acceptance, review whether a lesson is non-obvious, reproducible, useful beyond one task, bounded by explicit applicability conditions, and backed by real verification evidence. Only then may its generalized form enter the relevant public Playbook reference as `project-validated`.
32
-
33
- Public entries must contain:
34
-
35
- - evidence level;
36
- - symptom and proven root cause;
37
- - applicable SDK/tool versions and conditions;
38
- - recommended fix or workflow;
39
- - repeatable verification;
40
- - non-applicable cases;
41
- - source project and commits.
42
-
43
- Remove project-specific names and identifiers from the recommendation. Keep them only in source evidence. A public `project-validated` entry is discoverable by later projects but must be treated as a candidate solution there. After an independent project or environment reproduces it, upgrade it to `reusable-pattern` and add the new evidence. Upgrade to `platform-rule` only with active SDK/compiler evidence or a repeatable minimal reproduction.
44
-
45
- Do not promote routine success, generic advice, speculation, or a workaround whose root cause is unknown. Promotion is a reviewed change to the plugin Playbook; migration agents must not silently mutate an installed or cached plugin copy.
1
+ # Lesson lifecycle
2
+
3
+ ## Read before a task
4
+
5
+ Read `.migration/experience/lessons.md` when it exists. Select lessons by task type, symptom, subsystem and applicability. Do not load or repeat unrelated lessons.
6
+
7
+ ## Record after validation and commit
8
+
9
+ The playbook returns a lesson candidate only after the root cause and fix are supported by current-project evidence. The caller decides whether validation and checkpoint requirements are satisfied and whether to persist or promote the candidate. Use this structure:
10
+
11
+ ```markdown
12
+ ## <short title>
13
+ - Task/commit: `<task>` / `<sha>`
14
+ - Evidence level: project-validated | reusable-pattern | platform-rule
15
+ - Applies when: <specific conditions and versions>
16
+ - Symptom: <observable failure>
17
+ - Root cause: <proven cause>
18
+ - Fix: <minimal effective change>
19
+ - Verification: <commands, tests, device evidence>
20
+ - Does not apply when: <known boundary>
21
+ ```
22
+
23
+ Skip routine success, generic coding advice, speculative causes, duplicate lessons and details recoverable from the commit alone.
24
+
25
+ If the project tracks `.migration/experience/lessons.md`, the caller may persist an accepted candidate there. The migration workspace `<android-project>-migration/` lives outside the Android Git repository, so the lesson remains workspace-local run memory unless that workspace is versioned independently.
26
+
27
+ This reference does not inspect, create, or time checkpoints and never recommends broad staging merely to capture a lesson.
28
+
29
+ ## Promote to the public playbook
30
+
31
+ `.migration/experience/lessons.md` is the source-project evidence log, not the cross-project knowledge base. After the caller confirms acceptance, review whether a lesson is non-obvious, reproducible, useful beyond one task, bounded by explicit applicability conditions, and backed by real verification evidence. Only then may its generalized form enter the relevant public Playbook reference as `project-validated`.
32
+
33
+ Public entries must contain:
34
+
35
+ - evidence level;
36
+ - symptom and proven root cause;
37
+ - applicable SDK/tool versions and conditions;
38
+ - recommended fix or workflow;
39
+ - repeatable verification;
40
+ - non-applicable cases;
41
+ - source project and commits.
42
+
43
+ Remove project-specific names and identifiers from the recommendation. Keep them only in source evidence. A public `project-validated` entry is discoverable by later projects but must be treated as a candidate solution there. After an independent project or environment reproduces it, upgrade it to `reusable-pattern` and add the new evidence. Upgrade to `platform-rule` only with active SDK/compiler evidence or a repeatable minimal reproduction.
44
+
45
+ Do not promote routine success, generic advice, speculation, or a workaround whose root cause is unknown. Promotion is a reviewed change to the plugin Playbook; migration agents must not silently mutate an installed or cached plugin copy.
@@ -1,23 +1,23 @@
1
- # Protocol-level E2E
2
-
3
- For mail or other network protocols, use a deterministic local server when external infrastructure makes results unstable.
4
-
5
- Derive a version-1 protocol specification from Android source evidence. Every route must include non-empty `sourceEvidence` and the four scenarios `success`, `empty`, `business-failure`, and `boundary`; do not invent routes or payloads. Generate the server with:
6
-
7
- ```text
8
- droid2hmos mock init <android-project> --spec <protocol-spec.json>
9
- ```
10
-
11
- The generated `mock-server/scenarios.json` is the protocol fixture and `transcript.jsonl` is request evidence. Start the generated server through the managed service command shown in `mock-server/README.md`, then use `droid2hmos service status` and `droid2hmos service stop`; do not launch a detached Node process directly. Select scenarios with the `x-droid2hmos-scenario` header or `scenario` query parameter.
12
-
13
- ## Evidence layers
14
-
15
- 1. Protocol driver: real socket exchange and server transcript.
16
- 2. Application behavior: parsed data, persistence and error handling.
17
- 3. UI flow: real user action reaches the protocol path and renders the result.
18
-
19
- Keep each layer's evidence separate. A direct protocol driver does not prove the UI path is connected.
20
-
21
- For IMAP literals, preserve byte lengths and response framing exactly. Seed known messages and assert complete subjects/senders/content rather than only response success. A small host-side parser mimic can help isolate tokenizer differences, but the final assertion must run against the ArkTS implementation.
22
-
23
- Restart behavior must be deterministic when launch parameters are consumed only during application creation; verify the process lifecycle rather than assuming a foreground launch recreates it.
1
+ # Protocol-level E2E
2
+
3
+ For mail or other network protocols, use a deterministic local server when external infrastructure makes results unstable.
4
+
5
+ Derive a version-1 protocol specification from Android source evidence. Every route must include non-empty `sourceEvidence` and the four scenarios `success`, `empty`, `business-failure`, and `boundary`; do not invent routes or payloads. Generate the server with:
6
+
7
+ ```text
8
+ droid2hmos mock init <android-project> --spec <protocol-spec.json>
9
+ ```
10
+
11
+ The generated `mock-server/scenarios.json` is the protocol fixture and `transcript.jsonl` is request evidence. Start the generated server through the managed service command shown in `mock-server/README.md`, then use `droid2hmos service status` and `droid2hmos service stop`; do not launch a detached Node process directly. Select scenarios with the `x-droid2hmos-scenario` header or `scenario` query parameter.
12
+
13
+ ## Evidence layers
14
+
15
+ 1. Protocol driver: real socket exchange and server transcript.
16
+ 2. Application behavior: parsed data, persistence and error handling.
17
+ 3. UI flow: real user action reaches the protocol path and renders the result.
18
+
19
+ Keep each layer's evidence separate. A direct protocol driver does not prove the UI path is connected.
20
+
21
+ For IMAP literals, preserve byte lengths and response framing exactly. Seed known messages and assert complete subjects/senders/content rather than only response success. A small host-side parser mimic can help isolate tokenizer differences, but the final assertion must run against the ArkTS implementation.
22
+
23
+ Restart behavior must be deterministic when launch parameters are consumed only during application creation; verify the process lifecycle rather than assuming a foreground launch recreates it.
@@ -1,53 +1,53 @@
1
- # UI automation and visual verification
2
-
3
- Use device automation as evidence, not as a substitute for understanding the UI.
4
-
5
- ## Reliable workflow
6
-
7
- 1. Start from a known app state.
8
- 2. Capture a screenshot and `dumpLayout` before interaction.
9
- 3. Perform one interaction.
10
- 4. Capture the resulting screenshot, UI tree and relevant log.
11
- 5. Assert the expected visible, navigation or state result.
12
-
13
- Use the managed evidence commands for collection and packaging:
14
-
15
- ```text
16
- droid2hmos evidence capture harmony <android-project> --name <name> [--target <id>]
17
- droid2hmos evidence flow harmony <android-project> --name <name> (--class <class> [--case <case>] | --all)
18
- droid2hmos evidence compare <android-project> --name <name> --android <android-evidence-dir> --harmony <harmony-evidence-dir>
19
- ```
20
-
21
- `capture` collects the screenshot, UI tree/`dumpLayout`, and device logs. `flow` creates before/after captures around a HarmonyOS Hypium test (Android-side flow has been removed with the Android runtime dependency). `compare` creates a dual-platform evidence record from existing evidence directories; it supports human review but does not by itself prove semantic equivalence. Preserve command output paths as report evidence.
22
-
23
- For text input, verify focus and current value after each operation. A click can hit an input field or IME candidate and inject unintended text. Close the IME only with a method proven in the current environment.
24
-
25
- ## `dumpLayout` checks
26
-
27
- - control text/value and selected state;
28
- - element bounds and scroll viewport;
29
- - missing or zero-size controls;
30
- - duplicate windows or duplicated controls;
31
- - visibility and reachability of the intended action.
32
-
33
- ## Visual comparison dimensions
34
-
35
- Inspect every user-visible element for content, position, size, spacing, alignment, color, typography, icon, border, state and enabled/clickable behavior. When no visual model or Android device is available, use Android source/resources plus the HarmonyOS UI tree and screenshot; state the evidence limitation.
36
-
37
- White/non-white screenshot heuristics only detect gross rendering failures. They cannot prove Android parity.
38
-
39
- ## Prefer semantic Hypium UI tests over coordinate injection
40
-
41
- > Update (2026-10): migration-flow Hypium test case creation and execution are now standardized on the Python-based `d2h-hypium-forge` pipeline (`.hypium_forge/` assets; iteration via its `run_direct.py`, managed acceptance via `droid2hmos test harmony --runner python --test-list ...`). The ArkTS `entry_test` module workflow below remains valid only as a project-verified lesson for existing ArkTS assets; the principle "semantic location over coordinate injection" and the exception boundaries continue to apply.
42
-
43
- - **Evidence level:** project-validated
44
- - **Applies when:** HarmonyOS user flows need repeatable device-side verification and the relevant ArkUI controls can expose semantic nodes. Verified with DevEco SDK 6.0.2(22) and `@ohos/hypium` 1.0.25; recheck APIs on other versions.
45
- - **Symptom:** a migration relies on repeated coordinate-based device injection, requiring layout dumps and manual coordinate calculation at every step. Scrolling or layout changes cause misclicks, stale-frame dumps and evidence that cannot be replayed reliably.
46
- - **Root cause:** the command-line injection path was mistaken for the full UI-test capability. Empty IDs in a layout dump were also treated as proof that semantic selection was unavailable, without first checking whether the app had stable ArkUI `.id()` anchors or a test module.
47
- - **Required acceptance workflow:** development does not have to be test-first, but a runnable `entry_test` Hypium module must exist before the first interactive feature is accepted as complete. Add stable, unique semantic IDs to important interactive controls; locate them through `Driver` selectors such as `ON.id(...)`; execute only the affected class/case after an implementation change. Run the full suite only for broad shared-code changes, coherent batch acceptance and final regression. Dynamic-list IDs must derive from stable business identity, not the current visual position. A feature without a current successful Hypium result remains unverified.
48
- - **Verification:** rerun the same semantic test suite after layout movement or scrolling and assert the visible/navigation/state result, not merely a successful click. The source project ran five core flows twice: list rendering, detail navigation, timer start/stop, settings entry and editor entry.
49
- - **Does not apply when:** performing one-off exploratory probing or interacting with content proven to have no usable semantic node, such as Canvas or an external system surface. Coordinate injection may help explore these cases, but it is not acceptance evidence by itself; record why semantic selection is impossible and verify the resulting visible or business state through another repeatable assertion. An unconfirmed Hypium API or a test module not yet created is a setup problem to resolve, not a lasting exception.
50
- - **API investigation checks:** confirm the correct Hypium dependency/import, selector matching behavior, test delegator launch API, whether the clickable node is the text child or its parent, and ArkTS syntax accepted in the test module. Do not copy an API fix across SDK versions without compiling and running it.
51
- - **Source evidence:** Cofi migration; test assets commit `65472f1d`, lesson commit `09278323`; five device tests passed in two runs on emulator `127.0.0.1:5555`.
52
-
53
- Android `uiautomator` and HarmonyOS `dumpLayout` can expose different semantic trees. Missing Compose `AnimatedVisibility` text on the Android side is a comparison-tool limitation until corroborated by the visible app; do not report it directly as an application mismatch.
1
+ # UI automation and visual verification
2
+
3
+ Use device automation as evidence, not as a substitute for understanding the UI.
4
+
5
+ ## Reliable workflow
6
+
7
+ 1. Start from a known app state.
8
+ 2. Capture a screenshot and `dumpLayout` before interaction.
9
+ 3. Perform one interaction.
10
+ 4. Capture the resulting screenshot, UI tree and relevant log.
11
+ 5. Assert the expected visible, navigation or state result.
12
+
13
+ Use the managed evidence commands for collection and packaging:
14
+
15
+ ```text
16
+ droid2hmos evidence capture harmony <android-project> --name <name> [--target <id>]
17
+ droid2hmos evidence flow harmony <android-project> --name <name> (--class <class> [--case <case>] | --all)
18
+ droid2hmos evidence compare <android-project> --name <name> --android <android-evidence-dir> --harmony <harmony-evidence-dir>
19
+ ```
20
+
21
+ `capture` collects the screenshot, UI tree/`dumpLayout`, and device logs. `flow` creates before/after captures around a HarmonyOS Hypium test (Android-side flow has been removed with the Android runtime dependency). `compare` creates a dual-platform evidence record from existing evidence directories; it supports human review but does not by itself prove semantic equivalence. Preserve command output paths as report evidence.
22
+
23
+ For text input, verify focus and current value after each operation. A click can hit an input field or IME candidate and inject unintended text. Close the IME only with a method proven in the current environment.
24
+
25
+ ## `dumpLayout` checks
26
+
27
+ - control text/value and selected state;
28
+ - element bounds and scroll viewport;
29
+ - missing or zero-size controls;
30
+ - duplicate windows or duplicated controls;
31
+ - visibility and reachability of the intended action.
32
+
33
+ ## Visual comparison dimensions
34
+
35
+ Inspect every user-visible element for content, position, size, spacing, alignment, color, typography, icon, border, state and enabled/clickable behavior. When no visual model or Android device is available, use Android source/resources plus the HarmonyOS UI tree and screenshot; state the evidence limitation.
36
+
37
+ White/non-white screenshot heuristics only detect gross rendering failures. They cannot prove Android parity.
38
+
39
+ ## Prefer semantic Hypium UI tests over coordinate injection
40
+
41
+ > Update (2026-10): migration-flow Hypium test case creation and execution are now standardized on the Python-based `d2h-hypium-forge` pipeline (`.hypium_forge/` assets; iteration via its `run_direct.py`, managed acceptance via `droid2hmos test harmony --runner python --test-list ...`). The ArkTS `entry_test` module workflow below remains valid only as a project-verified lesson for existing ArkTS assets; the principle "semantic location over coordinate injection" and the exception boundaries continue to apply.
42
+
43
+ - **Evidence level:** project-validated
44
+ - **Applies when:** HarmonyOS user flows need repeatable device-side verification and the relevant ArkUI controls can expose semantic nodes. Verified with DevEco SDK 6.0.2(22) and `@ohos/hypium` 1.0.25; recheck APIs on other versions.
45
+ - **Symptom:** a migration relies on repeated coordinate-based device injection, requiring layout dumps and manual coordinate calculation at every step. Scrolling or layout changes cause misclicks, stale-frame dumps and evidence that cannot be replayed reliably.
46
+ - **Root cause:** the command-line injection path was mistaken for the full UI-test capability. Empty IDs in a layout dump were also treated as proof that semantic selection was unavailable, without first checking whether the app had stable ArkUI `.id()` anchors or a test module.
47
+ - **Required acceptance workflow:** development does not have to be test-first, but a runnable `entry_test` Hypium module must exist before the first interactive feature is accepted as complete. Add stable, unique semantic IDs to important interactive controls; locate them through `Driver` selectors such as `ON.id(...)`; execute only the affected class/case after an implementation change. Run the full suite only for broad shared-code changes, coherent batch acceptance and final regression. Dynamic-list IDs must derive from stable business identity, not the current visual position. A feature without a current successful Hypium result remains unverified.
48
+ - **Verification:** rerun the same semantic test suite after layout movement or scrolling and assert the visible/navigation/state result, not merely a successful click. The source project ran five core flows twice: list rendering, detail navigation, timer start/stop, settings entry and editor entry.
49
+ - **Does not apply when:** performing one-off exploratory probing or interacting with content proven to have no usable semantic node, such as Canvas or an external system surface. Coordinate injection may help explore these cases, but it is not acceptance evidence by itself; record why semantic selection is impossible and verify the resulting visible or business state through another repeatable assertion. An unconfirmed Hypium API or a test module not yet created is a setup problem to resolve, not a lasting exception.
50
+ - **API investigation checks:** confirm the correct Hypium dependency/import, selector matching behavior, test delegator launch API, whether the clickable node is the text child or its parent, and ArkTS syntax accepted in the test module. Do not copy an API fix across SDK versions without compiling and running it.
51
+ - **Source evidence:** Cofi migration; test assets commit `65472f1d`, lesson commit `09278323`; five device tests passed in two runs on emulator `127.0.0.1:5555`.
52
+
53
+ Android `uiautomator` and HarmonyOS `dumpLayout` can expose different semantic trees. Missing Compose `AnimatedVisibility` text on the Android side is a comparison-tool limitation until corroborated by the visible app; do not report it directly as an application mismatch.
@@ -1,38 +1,38 @@
1
- # Windows environment checks
2
-
3
- Check actual paths rather than trusting environment variables:
4
-
5
- - JDK/DevEco SDK directories exist and match the invoked tool.
6
- - Included Gradle builds have the local configuration they require.
7
- - Proxy settings apply to Gradle/Node and do not unexpectedly intercept device or mail ports.
8
- - Node/npm pairs come from compatible installations.
9
- - Commands preserve spaces and non-ASCII paths.
10
-
11
- Encoding is tool- and file-format-specific. Detect the existing encoding and the consuming compiler/schema requirements before changing it. Do not impose BOM rules globally, and do not rewrite source files merely to normalize encoding.
12
-
13
- For long tasks, emit progress and bounded diagnostics. Do not leave an unbounded process running when a smaller stage probe can identify the bottleneck.
14
-
15
- ## Long-lived background services under OpenCode on Windows
16
-
17
- **Evidence level: reusable pattern.** `Start-Process` and Node `detached + unref` can both leave a Mock Server or development server inside the process tree tracked by the Windows command runner. The launcher may print a successful result while the tool call still waits forever for the descendant service.
18
-
19
- Use the plugin-owned launcher instead:
20
-
21
- ```text
22
- droid2hmos service start mock-server <PROJECT> --health-url <URL> -- <command> [args...]
23
- ```
24
-
25
- On Windows it asks `Win32_Process.Create` to create a short-lived host outside the command runner's process tree. The host starts the service with closed stdin and file-backed stdout/stderr, records the actual service PID, then exits. The outer launcher performs only a bounded health check and exits immediately after success.
26
-
27
- Do not substitute `Start-Process`, a foreground server command, or a project-local `spawn(..., { detached: true }).unref()` launcher. If the system-level creation mechanism is unavailable, return a blocking external-service item in `unresolved`, put the manual start instruction in `suggestedRemediation`, and let the caller handle user coordination rather than risking an unbounded migration run.
28
-
29
- ## DevEco CLI login callback server lifecycle
30
-
31
- **Evidence level: project-validated.** `devecocli auth login` starts a local OAuth callback server on a random `127.0.0.1` port, and that server lives only as long as the login process. If the process is killed, reaped by a tool-call timeout, or launched as a short-lived child of a CLI invocation, the browser keeps the Huawei login page; completing authorization then redirects to the dead port and the browser shows "localhost refused to connect". The failure does not heal on re-run.
32
-
33
- - Symptom: browser shows `localhost 拒绝了我们的连接请求` after finishing Huawei account authorization during a DevEco CLI login.
34
- - Root cause: the login callback server died with its process (orphaned browser tab pointing at a stale port, often left by an earlier automated or timed-out login attempt).
35
- - Fix workflow: use the managed login `droid2hmos auth login <android-project>` — it kills orphan `devecocli auth login` processes first, relaunches the login process outside the command runner's process tree with stdin held open (auto-sends Enter to trigger the browser), prints the login URL for manual access, and polls `devecocli auth status` with a bounded timeout. Treat a failed `devecocli-auth` preflight gate as `retry.kind: external`; do not retry it with short-lived processes and do not start a second concurrent login while one is pending.
36
- - Verification: preflight `devecocli-auth` gate passes after `droid2hmos auth login`; `.migration/services/devecocli-auth.pid` is cleaned up after the login process exits.
37
- - Does not apply when: the CLI was never installed (`toolchain` gate fails first), or the browser cannot reach `127.0.0.1` at all (proxy/VPN intercepting loopback — see the proxy checks above).
38
- - Source: Android2Harmony droid2hmos CLI, DevEco CLI login callback incident (2026-09).
1
+ # Windows environment checks
2
+
3
+ Check actual paths rather than trusting environment variables:
4
+
5
+ - JDK/DevEco SDK directories exist and match the invoked tool.
6
+ - Included Gradle builds have the local configuration they require.
7
+ - Proxy settings apply to Gradle/Node and do not unexpectedly intercept device or mail ports.
8
+ - Node/npm pairs come from compatible installations.
9
+ - Commands preserve spaces and non-ASCII paths.
10
+
11
+ Encoding is tool- and file-format-specific. Detect the existing encoding and the consuming compiler/schema requirements before changing it. Do not impose BOM rules globally, and do not rewrite source files merely to normalize encoding.
12
+
13
+ For long tasks, emit progress and bounded diagnostics. Do not leave an unbounded process running when a smaller stage probe can identify the bottleneck.
14
+
15
+ ## Long-lived background services under OpenCode on Windows
16
+
17
+ **Evidence level: reusable pattern.** `Start-Process` and Node `detached + unref` can both leave a Mock Server or development server inside the process tree tracked by the Windows command runner. The launcher may print a successful result while the tool call still waits forever for the descendant service.
18
+
19
+ Use the plugin-owned launcher instead:
20
+
21
+ ```text
22
+ droid2hmos service start mock-server <PROJECT> --health-url <URL> -- <command> [args...]
23
+ ```
24
+
25
+ On Windows it asks `Win32_Process.Create` to create a short-lived host outside the command runner's process tree. The host starts the service with closed stdin and file-backed stdout/stderr, records the actual service PID, then exits. The outer launcher performs only a bounded health check and exits immediately after success.
26
+
27
+ Do not substitute `Start-Process`, a foreground server command, or a project-local `spawn(..., { detached: true }).unref()` launcher. If the system-level creation mechanism is unavailable, return a blocking external-service item in `unresolved`, put the manual start instruction in `suggestedRemediation`, and let the caller handle user coordination rather than risking an unbounded migration run.
28
+
29
+ ## DevEco CLI login callback server lifecycle
30
+
31
+ **Evidence level: project-validated.** `devecocli auth login` starts a local OAuth callback server on a random `127.0.0.1` port, and that server lives only as long as the login process. If the process is killed, reaped by a tool-call timeout, or launched as a short-lived child of a CLI invocation, the browser keeps the Huawei login page; completing authorization then redirects to the dead port and the browser shows "localhost refused to connect". The failure does not heal on re-run.
32
+
33
+ - Symptom: browser shows `localhost 拒绝了我们的连接请求` after finishing Huawei account authorization during a DevEco CLI login.
34
+ - Root cause: the login callback server died with its process (orphaned browser tab pointing at a stale port, often left by an earlier automated or timed-out login attempt).
35
+ - Fix workflow: use the managed login `droid2hmos auth login <android-project>` — it kills orphan `devecocli auth login` processes first, relaunches the login process outside the command runner's process tree with stdin held open (auto-sends Enter to trigger the browser), prints the login URL for manual access, and polls `devecocli auth status` with a bounded timeout. Treat a failed `devecocli-auth` preflight gate as `retry.kind: external`; do not retry it with short-lived processes and do not start a second concurrent login while one is pending.
36
+ - Verification: preflight `devecocli-auth` gate passes after `droid2hmos auth login`; `.migration/services/devecocli-auth.pid` is cleaned up after the login process exits.
37
+ - Does not apply when: the CLI was never installed (`toolchain` gate fails first), or the browser cannot reach `127.0.0.1` at all (proxy/VPN intercepting loopback — see the proxy checks above).
38
+ - Source: Android2Harmony droid2hmos CLI, DevEco CLI login callback incident (2026-09).