@harmonyos-arkts/d2h 0.1.19 → 0.1.21

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 (151) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +40 -0
  3. package/agents/android-to-hmos-00-orchestrator.md +3 -315
  4. package/agents/d2h.md +53 -38
  5. package/contracts/workflow/artifacts.md +22 -0
  6. package/contracts/workflow/delivery.md +54 -0
  7. package/contracts/workflow/dispatch.md +26 -0
  8. package/contracts/workflow/execution.md +125 -0
  9. package/contracts/workflow/generation.md +40 -0
  10. package/contracts/workflow/orchestration.md +49 -0
  11. package/contracts/workflow/overview.md +58 -0
  12. package/contracts/workflow/plan.md +119 -0
  13. package/contracts/workflow/scope.md +151 -0
  14. package/dist/bin/install-opencode.js +34 -15
  15. package/dist/src/install-codex.js +131 -0
  16. package/dist/src/install-opencode.js +5 -5
  17. package/dist/src/workflow.js +54 -0
  18. package/docs/architecture-plan-guide.zh-CN.md +70 -0
  19. package/docs/incremental-spec-evaluation-design.md +670 -0
  20. package/docs/spec-plan-guide.md +226 -0
  21. package/docs/workflow-decoupling.md +59 -0
  22. package/opencode/interactive-tools/advance-progress-demo.mjs +21 -0
  23. package/opencode/interactive-tools/browser-host.ts +110 -0
  24. package/opencode/interactive-tools/core.ts +242 -0
  25. package/opencode/interactive-tools/demo-workflow.ts +55 -0
  26. package/opencode/interactive-tools/demo.mjs +37 -0
  27. package/opencode/interactive-tools/package-lock.json +1876 -0
  28. package/opencode/interactive-tools/package.json +23 -0
  29. package/opencode/interactive-tools/panel.ts +40 -0
  30. package/opencode/interactive-tools/prepare-demo.mjs +17 -0
  31. package/opencode/interactive-tools/prepare-progress-demo.mjs +13 -0
  32. package/opencode/interactive-tools/progress.ts +118 -0
  33. package/opencode/interactive-tools/server-legacy.mjs +2 -0
  34. package/opencode/interactive-tools/server.mjs +40 -0
  35. package/opencode/interactive-tools/tui.tsx +230 -0
  36. package/package.json +9 -1
  37. package/schemas/native-libs-analysis-report.schema.json +695 -0
  38. package/schemas/native-libs-verify-report.schema.json +566 -0
  39. package/schemas/spec-native-libs-shard.schema.json +110 -0
  40. package/skills/arkts-icon-sizing/SKILL.md +0 -10
  41. package/skills/cpp/d2h-native-library-analyse/SKILL.md +91 -0
  42. package/skills/cpp/d2h-native-library-analyse/scripts/analyse-android-so.py +630 -0
  43. package/skills/cpp/d2h-native-library-build/SKILL.md +403 -0
  44. package/skills/cpp/d2h-native-library-build/references/build-config-mapping.md +180 -0
  45. package/skills/cpp/d2h-native-library-build/references/jni-to-napi-mapping.md +74 -0
  46. package/skills/cpp/d2h-native-library-build/scripts/check-android-so.py +580 -0
  47. package/skills/cpp/d2h-native-library-verify/SKILL.md +111 -0
  48. package/skills/cpp/d2h-native-library-verify/references/demo-build-sign-run.md +67 -0
  49. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/AppScope/app.json5 +1 -0
  50. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/AppScope/resources/base/element/string.json +1 -0
  51. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/README.md +25 -0
  52. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/build-profile.json5 +24 -0
  53. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/build-profile.json5 +1 -0
  54. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/hvigorfile.ts +2 -0
  55. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/oh-package.json5 +1 -0
  56. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/src/main/ets/entryability/EntryAbility.ets +5 -0
  57. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/src/main/ets/pages/Index.ets +3 -0
  58. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/src/main/ets/pages/NativeVerifyDemo.ets +276 -0
  59. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/src/main/module.json5 +1 -0
  60. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/src/main/resources/base/element/color.json +1 -0
  61. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/src/main/resources/base/element/string.json +1 -0
  62. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/src/main/resources/base/profile/main_pages.json +1 -0
  63. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/src/ohosTest/ets/test/FFmpegVerify.test.ets +176 -0
  64. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/src/ohosTest/ets/test/List.test.ets +2 -0
  65. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/entry/src/ohosTest/module.json5 +1 -0
  66. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/hvigor/hvigor-config.json5 +1 -0
  67. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/hvigorfile.ts +2 -0
  68. package/skills/cpp/d2h-native-library-verify/references/demo-project-template/oh-package.json5 +9 -0
  69. package/skills/cpp/d2h-native-library-verify/references/demo-template.md +176 -0
  70. package/skills/cpp/d2h-native-library-verify/references/hypium-test-template.md +163 -0
  71. package/skills/cpp/d2h-native-library-verify/scripts/__pycache__/native_common.cpython-313.pyc +0 -0
  72. package/skills/cpp/d2h-native-library-verify/scripts/device-verify.py +304 -0
  73. package/skills/cpp/d2h-native-library-verify/scripts/native_common.py +341 -0
  74. package/skills/cpp/d2h-native-library-verify/scripts/verify-ohos-native.py +1099 -0
  75. package/skills/d2h-app-solution/SKILL.md +198 -0
  76. package/skills/d2h-app-solution/agents/openai.yaml +4 -0
  77. package/skills/d2h-app-solution/references/framework-evidence.md +117 -0
  78. package/skills/d2h-app-solution/references/hierarchy-rules.md +88 -0
  79. package/skills/d2h-app-solution/references/inventory-schema.md +305 -0
  80. package/skills/d2h-app-solution/references/technical-analysis.md +101 -0
  81. package/skills/d2h-app-solution/scripts/scan_repositories.py +350 -0
  82. package/skills/d2h-app-solution/scripts/validate_inventory.py +337 -0
  83. package/skills/d2h-architecture-plan/SKILL.md +35 -0
  84. package/skills/d2h-architecture-plan/references/directory-creation.md +43 -0
  85. package/skills/d2h-architecture-plan/references/hybrid-design.md +84 -0
  86. package/skills/d2h-architecture-plan/references/layout-reference.md +83 -0
  87. package/skills/d2h-architecture-plan/references/plan-contract.md +51 -0
  88. package/skills/d2h-architecture-plan/references/source-review.md +50 -0
  89. package/skills/d2h-cloud-knowledge/SKILL.md +28 -7
  90. package/skills/d2h-cloud-knowledge/kb_query.mjs +8 -0
  91. package/skills/d2h-dashboard/SKILL.md +56 -0
  92. package/skills/d2h-product-family-migration/SKILL.md +103 -0
  93. package/skills/d2h-product-family-migration/agents/openai.yaml +3 -0
  94. package/skills/d2h-product-family-migration/assets/incremental-plan.template.md +55 -0
  95. package/skills/d2h-product-family-migration/references/advanced/behavioral-verification.md +59 -0
  96. package/skills/d2h-product-family-migration/references/advanced/existing-skill-integration.md +30 -0
  97. package/skills/d2h-product-family-migration/references/advanced/packaging-and-verification.md +43 -0
  98. package/skills/d2h-product-family-migration/references/advanced/platform-probes.md +26 -0
  99. package/skills/d2h-product-family-migration/references/advanced/product-line-design.md +40 -0
  100. package/skills/d2h-product-family-migration/references/baseline-and-delta.md +50 -0
  101. package/skills/d2h-product-family-migration/tests/markdown-cases.md +76 -0
  102. package/skills/{d2h-page-develop → d2h-spec-develop}/SKILL.md +143 -132
  103. package/skills/d2h-spec-develop/agents/openai.yaml +7 -0
  104. package/skills/d2h-spec-develop/references/worker-workflow.md +26 -0
  105. package/skills/{d2h-page-spec-generate → d2h-spec-generate}/SKILL.md +24 -13
  106. package/skills/d2h-spec-generate/assets/spec-template.md +109 -0
  107. package/skills/d2h-spec-generate/references/from-plan.md +19 -0
  108. package/skills/d2h-spec-generate/references/spec-content.md +34 -0
  109. package/skills/{d2h-page-spec-generate → d2h-spec-generate}/scripts/build_batch_report.py +35 -84
  110. package/skills/d2h-spec-plan/SKILL.md +38 -0
  111. package/skills/d2h-spec-plan/agents/openai.yaml +4 -0
  112. package/skills/d2h-spec-plan/references/architecture-handoff.md +9 -0
  113. package/skills/d2h-spec-plan/references/plan-contract.md +13 -0
  114. package/skills/d2h-spec-plan/references/planning-method.md +46 -0
  115. package/skills/d2h-spec-plan/references/round-scope-assessment.md +49 -0
  116. package/skills/d2h-spec-plan/references/work-packets.md +61 -0
  117. package/skills/d2h-utg-ai-generate/references/click-paths-schema.json +2 -2
  118. package/skills/d2h-utg-ai-generate/references/page-schema.json +2 -2
  119. package/skills/d2h-utg-ai-generate/references/utg-schema.json +2 -2
  120. package/skills/d2h-utg-static-generate/SKILL.md +2 -2
  121. package/skills/managing-d2h-toolchain/environment-requirements.json +1 -1
  122. package/skills/managing-d2h-toolchain/toolchain.json +1 -1
  123. package/skills/preparing-migration-workspace/SKILL.md +32 -2
  124. package/workflow/__pycache__/artifact_bindings.cpython-313.pyc +0 -0
  125. package/workflow/__pycache__/spec_runtime.cpython-313.pyc +0 -0
  126. package/workflow/artifact_bindings.py +224 -0
  127. package/workflow/assets/dashboard.html +88 -0
  128. package/workflow/build_batch_report.py +8 -0
  129. package/workflow/collect_code_metrics.py +75 -0
  130. package/workflow/dashboard_overview.py +109 -0
  131. package/workflow/delivery_view.py +82 -0
  132. package/workflow/feature_plan.py +234 -0
  133. package/workflow/page_batches.py +223 -0
  134. package/workflow/spec_generation.py +120 -0
  135. package/workflow/spec_runtime.py +890 -0
  136. package/workflow/work_packets.py +85 -0
  137. package/skills/d2h-page-develop/agents/openai.yaml +0 -7
  138. package/skills/harmonyos-migration-playbook/SKILL.md +0 -83
  139. package/skills/harmonyos-migration-playbook/agents/openai.yaml +0 -7
  140. package/skills/harmonyos-migration-playbook/references/arkts-compile.md +0 -24
  141. package/skills/harmonyos-migration-playbook/references/harmony-runtime.md +0 -53
  142. package/skills/harmonyos-migration-playbook/references/lesson-lifecycle.md +0 -45
  143. package/skills/harmonyos-migration-playbook/references/protocol-e2e.md +0 -23
  144. package/skills/harmonyos-migration-playbook/references/ui-automation.md +0 -53
  145. package/skills/harmonyos-migration-playbook/references/windows-environment.md +0 -38
  146. package/skills/native-library-substitution/SKILL.md +0 -385
  147. package/skills/native-library-substitution/references/native-library-substitution.json +0 -56906
  148. package/skills/native-library-substitution/references/native-library-substitution.md +0 -163
  149. package/skills/porting-cmake-native-libraries/SKILL.md +0 -57
  150. package/skills/porting-cmake-native-libraries/references/platform-adaptation.md +0 -49
  151. package/skills/porting-cmake-native-libraries/references/report-and-build.md +0 -60
@@ -0,0 +1,85 @@
1
+ """Explicit work-packet readiness and shared-state contracts; no source inference."""
2
+
3
+ POLICY = 'required-v1'
4
+ LAYERS = {'static', 'logic', 'integration', 'device'}
5
+
6
+
7
+ def enabled(plan):
8
+ return plan.get('work_packet_policy') == POLICY
9
+
10
+
11
+ def validate(plan, specs, require, strings):
12
+ require(plan.get('work_packet_policy') in (None, POLICY), 'unsupported work_packet_policy')
13
+ contracts = plan.get('shared_contracts', [])
14
+ require(isinstance(contracts, list), 'shared_contracts must be an array')
15
+ seen = set()
16
+ for contract in contracts:
17
+ require(isinstance(contract, dict), 'shared contract must be an object')
18
+ identity = contract.get('state_id')
19
+ require(isinstance(identity, str) and bool(identity.strip()) and identity not in seen, 'unique shared state_id required')
20
+ seen.add(identity)
21
+ producer = contract.get('producer_spec_id')
22
+ readers = strings(contract.get('consumer_spec_ids'), 'shared state consumers', True)
23
+ require(producer in specs and all(s in specs and s != producer for s in readers), 'unknown/self shared contract participant')
24
+ capability = contract.get('capability')
25
+ require(any(c['capability'] == capability for c in specs[producer]['provides']), 'shared state capability must be provided by producer')
26
+ require(all(capability in specs[s]['requires'] for s in readers), 'shared state consumers must require its capability')
27
+ checks = strings(contract.get('checks'), 'shared contract checks', True)
28
+ participants = [producer, *readers]
29
+ allowed = {c for sid in participants for c in specs[sid]['checks']}
30
+ require(set(checks) <= allowed and all(set(checks) & set(specs[s]['checks']) for s in participants), 'shared state needs checks from every participant')
31
+ for sid, spec in specs.items():
32
+ layers = spec.get('testing', {}).get('layers')
33
+ if layers is not None:
34
+ require(isinstance(layers, list), 'testing.layers must be an array')
35
+ checks = set()
36
+ for layer in layers:
37
+ require(isinstance(layer, dict) and layer.get('check_id') in spec['checks'], 'unknown layered check')
38
+ require(layer['check_id'] not in checks, 'duplicate layered check')
39
+ checks.add(layer['check_id'])
40
+ require(layer.get('layer') in LAYERS, 'unsupported validation layer')
41
+ require(isinstance(layer.get('reason'), str) and bool(layer['reason'].strip()), 'validation layer reason required')
42
+ brief = spec.get('implementation_brief')
43
+ if brief is not None:
44
+ require(isinstance(brief, dict), f'{sid}: implementation_brief must be an object')
45
+ for key in ('behavior_notes', 'invariants', 'known_pitfalls', 'open_questions'):
46
+ if key in brief:
47
+ strings(brief[key], f'{sid}.implementation_brief.{key}')
48
+
49
+
50
+ def readiness_gaps(plan, spec):
51
+ if not enabled(plan):
52
+ return []
53
+ gaps = []
54
+ brief = spec.get('implementation_brief') or {}
55
+ if not brief.get('behavior_notes'):
56
+ gaps.append('implementation_brief.behavior_notes missing')
57
+ for key in ('invariants', 'known_pitfalls', 'open_questions'):
58
+ if key not in brief:
59
+ gaps.append(f'implementation_brief.{key} missing (use [] when reviewed and empty)')
60
+ gaps.extend('unresolved: ' + q for q in brief.get('open_questions', []))
61
+ covered = {i['check_id'] for i in (spec['testing'].get('layers') or [])}
62
+ gaps.extend('validation layer missing: ' + c for c in sorted(set(spec['checks']) - covered))
63
+ for contract in plan.get('shared_contracts', []):
64
+ if spec['spec_id'] in [contract['producer_spec_id'], *contract['consumer_spec_ids']]:
65
+ for field in ('channel', 'payload', 'initialization', 'lifecycle'):
66
+ if not isinstance(contract.get(field), str) or not contract[field].strip():
67
+ gaps.append(f"shared state {contract['state_id']}: {field} missing")
68
+ return gaps
69
+
70
+
71
+ def interface_ready(plan, task, capability, candidate, file_hash):
72
+ if not enabled(plan):
73
+ return True
74
+ receipt = task.get('interfaces', {}).get(capability)
75
+ if not receipt or not candidate or receipt['candidate'] != candidate:
76
+ return False
77
+ try:
78
+ return bool(receipt['code_files']) and all(file_hash(ref['path']) == ref['sha256'] for ref in receipt['code_files'])
79
+ except (KeyError, OSError, TypeError):
80
+ return False
81
+
82
+
83
+ def packet(plan, spec, task, candidate, file_hash):
84
+ """Materialize only this Spec's planning fields; receipts remain runtime-owned."""
85
+ return {'goal': list(spec['scope']), 'source_refs': list(spec['evidence_refs']), 'target_paths': list(spec['allocation']['owned_paths']), 'implementation_brief': spec.get('implementation_brief'), 'validation_layers': (spec['testing'].get('layers') or []), 'shared_contracts': [c for c in plan.get('shared_contracts', []) if spec['spec_id'] in [c['producer_spec_id'], *c['consumer_spec_ids']]], 'confirmed_interfaces': {cap: receipt for cap, receipt in task.get('interfaces', {}).items() if interface_ready(plan, task, cap, candidate, file_hash)}}
@@ -1,7 +0,0 @@
1
- interface:
2
- display_name: "HarmonyOS Page Development Loop"
3
- short_description: "按 spec.md 完成单页面受管开发、测试与提交闭环"
4
- default_prompt: "Use $d2h-page-develop to serially implement ordered HarmonyOS page tasks from pages.json, batch_report.md, and spec.md in the current agent without delegating page work to subagents."
5
-
6
- policy:
7
- allow_implicit_invocation: true
@@ -1,83 +0,0 @@
1
- ---
2
- name: harmonyos-migration-playbook
3
- description: Diagnose Android-to-HarmonyOS migration failures, check whether verified lessons apply, and return the smallest scoped fix or recommendation for ArkTS compilation, HarmonyOS runtime, UI automation, protocol E2E, and Windows toolchains. Use during implementation, failure recovery, validation, or retrospectives; do not control checkpoints or outer workflow state.
4
- ---
5
-
6
- # HarmonyOS migration playbook
7
-
8
- Use verified experience to shorten diagnosis without replacing current-project evidence.
9
-
10
- ## Inputs and domain result
11
-
12
- Accept the current symptom, in-scope files, SDK/tool versions, relevant logs or managed evidence, and any project lesson candidates. Do not infer success from an earlier project.
13
-
14
- Return the same result shape whether called directly or from an orchestrator:
15
-
16
- ```json
17
- {
18
- "status": "completed | partial | failed",
19
- "changedFiles": [],
20
- "sourceFiles": [],
21
- "evidence": [],
22
- "domainChecks": [],
23
- "unresolved": [],
24
- "verificationRequests": [],
25
- "suggestedRemediation": [],
26
- "details": {
27
- "validatedRootCause": null,
28
- "applicability": {},
29
- "lessonCandidates": []
30
- }
31
- }
32
- ```
33
-
34
- `status` describes diagnosis and any in-scope fix only. `validatedRootCause` requires current-project evidence. Put repository-level build, test, device, or review needs in `verificationRequests`; do not choose the caller's checkpoint or workflow transition.
35
-
36
- ## Required operating loop
37
-
38
- 1. Identify the current symptom and task boundary.
39
- 2. Read only the relevant reference below.
40
- 3. Check that the recorded applicability conditions match the current SDK, UI stack, runtime and code path.
41
- 4. Reproduce or inspect evidence before applying a fix. Historical experience is a hypothesis until confirmed in the current project.
42
- 5. If the request authorizes a change, apply the smallest in-scope fix; otherwise return the smallest concrete recommendation.
43
- 6. Perform only domain-local checks available within scope. Return repository-level verification as `verificationRequests` and a reusable `lessonCandidates` entry only when the root cause and fix are supported by current-project evidence.
44
-
45
- ## Reference routing
46
-
47
- - ArkTS compiler errors or language restrictions: read [references/arkts-compile.md](references/arkts-compile.md).
48
- - Socket, TLS, IME, asynchronous execution, component state or theme problems: read [references/harmony-runtime.md](references/harmony-runtime.md).
49
- - Emulator interaction, screenshots, `dumpLayout`, input or scrolling failures: read [references/ui-automation.md](references/ui-automation.md).
50
- - IMAP/SMTP or other protocol-level end-to-end verification: read [references/protocol-e2e.md](references/protocol-e2e.md).
51
- - Windows, Gradle, SDK, proxy, encoding or background-service process hangs: read [references/windows-environment.md](references/windows-environment.md).
52
- - DevEco CLI login callback refused (`localhost 拒绝了连接`) or auth gate retries: read [references/windows-environment.md](references/windows-environment.md).
53
- - Recording or promoting migration experience: read [references/lesson-lifecycle.md](references/lesson-lifecycle.md).
54
-
55
- ## Evidence levels
56
-
57
- - **Platform rule**: supported by the active SDK/compiler behavior or repeatable minimal reproduction.
58
- - **Reusable pattern**: reproduced in more than one relevant project or independent environment.
59
- - **Project-validated**: fully proven in one project and useful beyond that project. It may enter the public playbook immediately, but every new project must revalidate it before relying on it.
60
- - **Candidate observation**: plausible but not yet proven; never use as a completion claim.
61
-
62
- Prefer narrower classifications. Public does not mean universal: a project-validated lesson is visible for reuse but remains a hypothesis outside its source project. Record SDK/tool versions when behavior could change.
63
-
64
- ## Non-negotiable boundaries
65
-
66
- - Android source and observable behavior remain authoritative.
67
- - Do not bypass AppGraph, compilation, tests or device validation merely because an earlier project was slow or unreliable. Diagnose the current failure; any explicit degradation must preserve a visible coverage gap.
68
- - Do not convert implementation defects into platform limitations or external blockers.
69
- - Do not claim a lesson is verified from a report, comment, code existence or compile success alone when runtime behavior is relevant.
70
- - Do not modify the public playbook from every task. First record the lesson in the current project; a reviewed, non-obvious and well-verified single-project lesson may be promoted as `project-validated` under `lesson-lifecycle.md` instead of waiting invisibly for another project.
71
- - Do not stage or commit files, create a checkpoint, update the migration report, call `complete`, schedule full regression, or decide an outer workflow state. The caller owns those actions.
72
-
73
- ## Quick triage
74
-
75
- ```text
76
- Compile failure -> ArkTS error code and exact source construct
77
- Button does nothing -> reachability, UI tree, callback log, async context
78
- Socket failure -> bind/connect/TLS stage and network logs
79
- Login callback refused-> login process lifecycle (windows-environment.md)
80
- Input corruption -> focus, IME state, input command and current value
81
- Visual mismatch -> element-by-element layout/style/content comparison
82
- Repeated task failure -> read project lessons, then verify applicability
83
- ```
@@ -1,7 +0,0 @@
1
- interface:
2
- display_name: "HarmonyOS Migration Playbook"
3
- short_description: "复用经验证的鸿蒙迁移诊断与测试经验"
4
- default_prompt: "Use $harmonyos-migration-playbook to diagnose this migration issue and verify that the historical lesson applies here."
5
-
6
- policy:
7
- allow_implicit_invocation: true
@@ -1,24 +0,0 @@
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 +0,0 @@
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 +0,0 @@
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 +0,0 @@
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 +0,0 @@
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 +0,0 @@
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).