android2harmony 0.1.6 → 0.1.8

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 (227) hide show
  1. package/agents/api-analyzer.md +113 -0
  2. package/agents/app-action.md +122 -0
  3. package/agents/code-reviewer.md +191 -295
  4. package/agents/coder.md +377 -0
  5. package/agents/self-tester.md +8 -8
  6. package/agents/spec-designer.md +56 -0
  7. package/package.json +1 -1
  8. package/skills/a2h-app-req-gen/SKILL.md +174 -0
  9. package/skills/a2h-app-req-gen/references/spec-handoff.md +99 -0
  10. package/skills/a2h-app-req-gen/references/subagent-render.md +115 -0
  11. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/build.gradle.kts +41 -0
  12. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle/wrapper/gradle-wrapper.jar +0 -0
  13. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle/wrapper/gradle-wrapper.properties +8 -0
  14. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle.properties +3 -0
  15. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradlew +251 -0
  16. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradlew.bat +94 -0
  17. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/settings.gradle.kts +17 -0
  18. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawAnalysisDetector.java +1911 -0
  19. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawIssueRegistry.java +37 -0
  20. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawJson.java +146 -0
  21. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawLocation.java +96 -0
  22. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawRecordWriter.java +227 -0
  23. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry +1 -0
  24. package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/resources/dev/reqgen/analyzer/jvm/raw-record-v1.schema.json +93 -0
  25. package/skills/a2h-app-req-gen/scripts/reqgen/assets/dashboard.html +151 -0
  26. package/skills/a2h-app-req-gen/scripts/reqgen/gradle/reqgen-lint.init.gradle +60 -0
  27. package/skills/a2h-app-req-gen/scripts/reqgen/gradle/reqgen-model.init.gradle +204 -0
  28. package/skills/a2h-app-req-gen/scripts/reqgen/package.json +14 -0
  29. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/backend.js +323 -0
  30. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/cli.js +811 -0
  31. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/gap-audit-link.js +62 -0
  32. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/index.js +66 -0
  33. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/merge.js +605 -0
  34. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/name-trace.js +153 -0
  35. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/orchestrate.js +1324 -0
  36. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/output-parse.js +50 -0
  37. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/overview.js +10 -0
  38. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/pool.js +23 -0
  39. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/post-merge-fix.js +146 -0
  40. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompt-loader.js +51 -0
  41. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompt.js +967 -0
  42. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompts.md +301 -0
  43. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/serve.js +78 -0
  44. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/short-id.js +46 -0
  45. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/snapshot.js +267 -0
  46. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/types.js +1 -0
  47. package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/validate.js +122 -0
  48. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/callback-call-sites.js +62 -0
  49. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/gap-audit/build.js +1291 -0
  50. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/gap-audit/index.js +1 -0
  51. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/area-ownership.js +392 -0
  52. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/build.js +1995 -0
  53. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/callback-flow.js +277 -0
  54. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/component-variants.js +725 -0
  55. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/index.js +15 -0
  56. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/index.js +12 -0
  57. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/policy.js +469 -0
  58. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/traceability.js +468 -0
  59. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/req-model/build.js +1066 -0
  60. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/req-model/index.js +1 -0
  61. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/android-interaction-registry.js +174 -0
  62. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/android.js +1062 -0
  63. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/area-titles.js +678 -0
  64. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/builder.js +350 -0
  65. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose-api-registry.js +395 -0
  66. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose-call-sites.js +2008 -0
  67. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose.js +9059 -0
  68. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/dynamic-repeated-call-sites.js +529 -0
  69. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/index.js +1 -0
  70. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/interaction-effects.js +1149 -0
  71. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/jvm.js +6272 -0
  72. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/normalize.js +33 -0
  73. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/pending-intents.js +565 -0
  74. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/resource-id.js +42 -0
  75. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/route-state-variants.js +781 -0
  76. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/state.js +234 -0
  77. package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/types.js +1 -0
  78. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/extract.js +40 -0
  79. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/index.js +6 -0
  80. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/manifest.js +513 -0
  81. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/resources.js +398 -0
  82. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/types.js +1 -0
  83. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/views.js +447 -0
  84. package/skills/a2h-app-req-gen/scripts/reqgen/src/android/xml-parser.js +175 -0
  85. package/skills/a2h-app-req-gen/scripts/reqgen/src/cli.js +398 -0
  86. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/area-graph.js +1 -0
  87. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/artifact.js +1 -0
  88. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/common.js +16 -0
  89. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/diagnostic.js +10 -0
  90. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/gap-audit.js +14 -0
  91. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/index.js +11 -0
  92. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/name-traceability.js +26 -0
  93. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/raw-fact.js +40 -0
  94. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/req-model.js +1 -0
  95. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/run.js +19 -0
  96. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/semantic-completeness.js +11 -0
  97. package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/source-facts.js +1 -0
  98. package/skills/a2h-app-req-gen/scripts/reqgen/src/core/output-guard.js +41 -0
  99. package/skills/a2h-app-req-gen/scripts/reqgen/src/core/stable-id.js +92 -0
  100. package/skills/a2h-app-req-gen/scripts/reqgen/src/dashboard-cli.js +169 -0
  101. package/skills/a2h-app-req-gen/scripts/reqgen/src/diagnostics.js +104 -0
  102. package/skills/a2h-app-req-gen/scripts/reqgen/src/dump/dump.js +1028 -0
  103. package/skills/a2h-app-req-gen/scripts/reqgen/src/dump/index.js +1 -0
  104. package/skills/a2h-app-req-gen/scripts/reqgen/src/dump-cli.js +251 -0
  105. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/artifacts.js +49 -0
  106. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/index.js +18 -0
  107. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/quality-report.js +125 -0
  108. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/render.js +353 -0
  109. package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/types.js +2 -0
  110. package/skills/a2h-app-req-gen/scripts/reqgen/src/graph/paths.js +474 -0
  111. package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/index.js +15 -0
  112. package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/protocol.js +408 -0
  113. package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/runner.js +452 -0
  114. package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/index.js +8 -0
  115. package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/output.js +165 -0
  116. package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/run-stage1.js +891 -0
  117. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/discovery.js +299 -0
  118. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/gradle-model.js +358 -0
  119. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/gradle-runner.js +165 -0
  120. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/resource-profile.js +60 -0
  121. package/skills/a2h-app-req-gen/scripts/reqgen/src/project/types.js +1 -0
  122. package/skills/a2h-app-req-gen/scripts/reqgen/src/spec-handoff-cli.js +151 -0
  123. package/skills/a2h-app-req-gen/scripts/reqgen/src/spec-handoff.js +1004 -0
  124. package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-cli.js +109 -0
  125. package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-input.js +419 -0
  126. package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-name-trace-input.js +95 -0
  127. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/area-graph.js +444 -0
  128. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/index.js +7 -0
  129. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/req-model.js +580 -0
  130. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/req-text.js +195 -0
  131. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/semantic-area-graph.js +1431 -0
  132. package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/types.js +1 -0
  133. package/skills/a2h-app-req-gen/scripts/reqgen-audit.mjs +298 -0
  134. package/skills/a2h-app-req-gen/scripts/reqgen-selfcheck.mjs +555 -0
  135. package/skills/a2h-code-review/SKILL.md +379 -0
  136. package/skills/{hmos-integration-test → a2h-integration-test}/README.md +6 -6
  137. package/skills/{hmos-integration-test → a2h-integration-test}/SKILL.md +6 -6
  138. package/skills/{hmos-integration-test → a2h-integration-test}/scripts/report-tool.mjs +1 -1
  139. package/skills/a2h-spec-design/SKILL.md +330 -0
  140. package/skills/a2h-spec-design/scripts/inspect_spec_design_inputs.mjs +207 -0
  141. package/skills/a2h-spec-design/scripts/move_spec_technical_reference.mjs +198 -0
  142. package/skills/a2h-spec-design/scripts/validate_spec_design_output.mjs +256 -0
  143. package/skills/a2h-spec-generate/SKILL.md +696 -0
  144. package/skills/a2h-spec-generate/references/trace-template.md +115 -0
  145. package/skills/a2h-spec-generate/scripts/parse_requirements.mjs +537 -0
  146. package/skills/a2h-spec-generate/template/REQ.txt +22 -0
  147. package/skills/a2h-spec-generate/template/REQ.xlsx +0 -0
  148. package/skills/a2h-spec-implement/SKILL.md +548 -0
  149. package/skills/a2h-spec-implement/references/harmony-pitfalls.md +186 -0
  150. package/skills/a2h-spec-implement/references/l1-unit-test.md +185 -0
  151. package/skills/a2h-spec-implement/references/l3-e2e-uitest.md +167 -0
  152. package/skills/a2h-spec-implement/references/test-core.md +132 -0
  153. package/skills/a2h-spec-implement/rules/arkts/arkts-standards.md +184 -0
  154. package/skills/a2h-spec-implement/rules/arkts/conventions/coding-style.md +96 -0
  155. package/skills/a2h-spec-implement/rules/arkts/conventions/security.md +126 -0
  156. package/skills/a2h-spec-implement/rules/arkts/language/arkts-rules.md +650 -0
  157. package/skills/a2h-spec-implement/rules/arkts/language/arkui-structure-rules.md +173 -0
  158. package/skills/a2h-spec-implement/rules/arkts/language/ts-to-arkts-rewrites.md +58 -0
  159. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Link/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/217/214/345/220/221/345/220/214/346/255/245.md +648 -0
  160. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Observed/350/243/205/351/245/260/345/231/250/345/222/214@ObjectLink/350/243/205/351/245/260/345/231/250/357/274/232/345/265/214/345/245/227/347/261/273/345/257/271/350/261/241/345/261/236/346/200/247/345/217/230/345/214/226.md +2089 -0
  161. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Prop/350/243/205/351/245/260/345/231/250/357/274/232/347/210/266/345/255/220/345/215/225/345/220/221/345/220/214/346/255/245.md +1033 -0
  162. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Provide/350/243/205/351/245/260/345/231/250/345/222/214@Consume/350/243/205/351/245/260/345/231/250/357/274/232/344/270/216/345/220/216/344/273/243/347/273/204/344/273/266/345/217/214/345/220/221/345/220/214/346/255/245.md +1183 -0
  163. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@State/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/347/212/266/346/200/201.md +576 -0
  164. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Track/350/243/205/351/245/260/345/231/250/357/274/232class/345/257/271/350/261/241/345/261/236/346/200/247/347/272/247/346/233/264/346/226/260.md +297 -0
  165. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/@Watch/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/346/233/264/346/224/271/351/200/232/347/237/245.md +395 -0
  166. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/AppStorage/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200/347/232/204UI/347/212/266/346/200/201/345/255/230/345/202/250.md +903 -0
  167. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/Environment/357/274/232/350/256/276/345/244/207/347/216/257/345/242/203/346/237/245/350/257/242.md +106 -0
  168. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/LocalStorage/357/274/232/351/241/265/351/235/242/347/272/247UI/347/212/266/346/200/201/345/255/230/345/202/250.md +1178 -0
  169. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/MVVM/346/250/241/345/274/217/357/274/210V1/357/274/211.md +911 -0
  170. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1/PersistentStorage/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +355 -0
  171. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v1//347/256/241/347/220/206/345/272/224/347/224/250/346/213/245/346/234/211/347/232/204/347/212/266/346/200/201/346/246/202/350/277/260.md +11 -0
  172. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/!!/350/257/255/346/263/225/357/274/232/345/217/214/345/220/221/347/273/221/345/256/232.md +216 -0
  173. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Computed/350/243/205/351/245/260/345/231/250/357/274/232/350/256/241/347/256/227/345/261/236/346/200/247.md +442 -0
  174. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Event/350/243/205/351/245/260/345/231/250/357/274/232/350/247/204/350/214/203/347/273/204/344/273/266/350/276/223/345/207/272.md +169 -0
  175. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Local/350/243/205/351/245/260/345/231/250/357/274/232/347/273/204/344/273/266/345/206/205/351/203/250/347/212/266/346/200/201.md +763 -0
  176. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Monitor/350/243/205/351/245/260/345/231/250/357/274/232/347/212/266/346/200/201/345/217/230/351/207/217/344/277/256/346/224/271/345/274/202/346/255/245/347/233/221/345/220/254.md +2088 -0
  177. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@ObservedV2/350/243/205/351/245/260/345/231/250/345/222/214@Trace/350/243/205/351/245/260/345/231/250/357/274/232/347/261/273/345/261/236/346/200/247/345/217/230/345/214/226/350/247/202/346/265/213.md +1258 -0
  178. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Once/357/274/232/345/210/235/345/247/213/345/214/226/345/220/214/346/255/245/344/270/200/346/254/241.md +175 -0
  179. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Param/357/274/232/347/273/204/344/273/266/345/244/226/351/203/250/350/276/223/345/205/245.md +850 -0
  180. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Provider/350/243/205/351/245/260/345/231/250/345/222/214@Consumer/350/243/205/351/245/260/345/231/250/357/274/232/350/267/250/347/273/204/344/273/266/345/261/202/347/272/247/345/217/214/345/220/221/345/220/214/346/255/245.md +862 -0
  181. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/@Type/350/243/205/351/245/260/345/231/250/357/274/232/346/240/207/350/256/260/347/261/273/345/261/236/346/200/247/347/232/204/347/261/273/345/236/213.md +110 -0
  182. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/AppStorageV2/357/274/232/345/272/224/347/224/250/345/205/250/345/261/200UI/347/212/266/346/200/201/345/255/230/345/202/250.md +301 -0
  183. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/MVVM/346/250/241/345/274/217/357/274/210V2/357/274/211.md +1411 -0
  184. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/PersistenceV2/357/274/232/346/214/201/344/271/205/345/214/226/345/255/230/345/202/250UI/347/212/266/346/200/201.md +1392 -0
  185. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/getTarget/346/216/245/345/217/243/357/274/232/350/216/267/345/217/226/347/212/266/346/200/201/347/256/241/347/220/206/346/241/206/346/236/266/344/273/243/347/220/206/345/211/215/347/232/204/345/216/237/345/247/213/345/257/271/350/261/241.md +288 -0
  186. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2/makeObserved/346/216/245/345/217/243/357/274/232/345/260/206/351/235/236/350/247/202/345/257/237/346/225/260/346/215/256/345/217/230/344/270/272/345/217/257/350/247/202/345/257/237/346/225/260/346/215/256.md +768 -0
  187. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2//347/212/266/346/200/201/347/256/241/347/220/206V1/345/222/214V2/346/267/267/347/224/250/346/214/207/345/257/274/357/274/210API version 19/345/217/212/344/271/213/345/220/216/357/274/211.md" +829 -0
  188. package/skills/a2h-spec-implement/rules/arkts/official/mvvm-v2//347/212/266/346/200/201/347/256/241/347/220/206/346/246/202/350/277/260.md +184 -0
  189. package/skills/a2h-spec-implement/rules/arkts/ui/component-cookbook.md +431 -0
  190. package/skills/a2h-spec-implement/rules/arkts/ui/state-management.md +152 -0
  191. package/skills/a2h-spec-implement/rules/arkts/ui/ui-quality.md +67 -0
  192. package/skills/a2h-spec-implement/rules/arkts/ui/ui-runtime-diagnosis.md +32 -0
  193. package/skills/a2h-spec-implement/rules/pipeline/build/package-set-collection.md +43 -0
  194. package/skills/a2h-spec-implement/scripts/_lib/common.mjs +97 -0
  195. package/skills/a2h-spec-implement/scripts/_lib/config.mjs +70 -0
  196. package/skills/a2h-spec-implement/scripts/_lib/lessons_cli.mjs +48 -0
  197. package/skills/a2h-spec-implement/scripts/build_lessons.mjs +24 -0
  198. package/skills/a2h-spec-implement/scripts/code_pattern_lessons.mjs +26 -0
  199. package/skills/a2h-spec-implement/scripts/device_ui.mjs +433 -0
  200. package/skills/a2h-spec-implement/scripts/device_ui_core.mjs +895 -0
  201. package/skills/a2h-spec-implement/scripts/ledger/aggregate_run.mjs +207 -0
  202. package/skills/a2h-spec-implement/scripts/manifest/emit_summary_line.mjs +37 -0
  203. package/skills/a2h-spec-implement/scripts/manifest/finalize_run.mjs +115 -0
  204. package/skills/a2h-spec-implement/scripts/manifest/render_final_summary.mjs +78 -0
  205. package/skills/a2h-spec-implement/scripts/manifest/root_mirror.mjs +137 -0
  206. package/skills/a2h-spec-implement/scripts/package.json +12 -0
  207. package/skills/a2h-spec-implement/scripts/state_propagation_check.mjs +676 -0
  208. package/skills/a2h-spec-implement/scripts/test/l2_run.mjs +244 -0
  209. package/skills/a2h-spec-implement/scripts/test/tp_coverage.mjs +231 -0
  210. package/skills/a2h-spec-implement/scripts/ui_memory.mjs +161 -0
  211. package/skills/a2h-spec-implement/scripts/utils/ensure_app.mjs +134 -0
  212. package/skills/a2h-ui-transfer/SKILL.md +20 -9
  213. package/skills/a2h-ui-transfer/scripts/arkts_static_check.js +80 -0
  214. package/skills/hmos-convert-pipeline/SKILL.md +7 -5
  215. package/skills/hmos-incremental-ui-align/README.md +7 -7
  216. package/skills/hmos-incremental-ui-align/SKILL.md +1 -1
  217. package/skills/hmos-incremental-ui-align/page_align.md +1 -1
  218. package/skills/hmos-spec-generate/SKILL.md +2 -2
  219. package/skills/hmos-spec-generate/scripts/parse_requirements.mjs +537 -0
  220. package/skills/hmos-fix-build-errors/SKILL.md +0 -266
  221. package/skills/hmos-fix-build-errors/references/arkts-strict-patterns.md +0 -219
  222. package/skills/hmos-fix-build-errors/references/known-patterns.md +0 -157
  223. package/skills/hmos-fix-build-errors/references/rdb-entity-pattern.md +0 -131
  224. package/skills/hmos-spec-generate/scripts/parse_requirements.ts +0 -515
  225. /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/resolve-metadata-tool.mjs +0 -0
  226. /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/self-test-runner.mjs +0 -0
  227. /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/testcases-tool.mjs +0 -0
@@ -0,0 +1,513 @@
1
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
2
+ import { basename, dirname, join, relative, sep } from "node:path";
3
+ import { hardFailure } from "../diagnostics.js";
4
+ import { descendantElements, localName, parseXml } from "./xml-parser.js";
5
+ function attribute(element, name) {
6
+ return element.attributes[`android:${name}`] ?? element.attributes[name];
7
+ }
8
+ function relativePath(root, path) {
9
+ return relative(root, path).split(sep).join("/");
10
+ }
11
+ function evidence(selected, path, element, anchor) {
12
+ return {
13
+ sourceKind: "manifest",
14
+ path: relativePath(selected.model.projectRoot, path),
15
+ anchor,
16
+ range: {
17
+ startLine: element.startLine,
18
+ endLine: element.endLine,
19
+ },
20
+ };
21
+ }
22
+ function resolveClassName(name, packageName) {
23
+ if (!packageName) return name;
24
+ if (name.startsWith(".")) return `${packageName}${name}`;
25
+ if (!name.includes(".")) return `${packageName}.${name}`;
26
+ return name;
27
+ }
28
+ function comparablePath(path) {
29
+ const slashes = path.trim().replaceAll("\\", "/");
30
+ const wslDrive = /^\/mnt\/([A-Za-z])\/(.*)$/u.exec(slashes);
31
+ return (wslDrive ? `${wslDrive[1]}:/${wslDrive[2]}` : slashes)
32
+ .replace(/\/{2,}/gu, "/")
33
+ .toLowerCase();
34
+ }
35
+ function walkFiles(root) {
36
+ if (!existsSync(root) || !statSync(root).isDirectory()) return [];
37
+ return readdirSync(root, { withFileTypes: true }).flatMap((entry) => {
38
+ const path = join(root, entry.name);
39
+ return entry.isDirectory() ? walkFiles(path) : entry.isFile() ? [path] : [];
40
+ });
41
+ }
42
+ /** Locate the AGP sidecar whose numbered lines correspond to the merge. */
43
+ function manifestMergerBlamePath(selected, manifestPath) {
44
+ const root = join(
45
+ selected.applicationModule.directory,
46
+ "build",
47
+ "intermediates",
48
+ "manifest_merge_blame_file",
49
+ selected.variant.name,
50
+ );
51
+ const candidates = walkFiles(root)
52
+ .filter((path) => /manifest-merger-blame-.*-report\.txt$/u.test(path))
53
+ .sort();
54
+ if (candidates.length === 0) return undefined;
55
+ const taskDirectory = basename(dirname(manifestPath));
56
+ return (
57
+ candidates.find((path) => path.split(/[\\/]/u).includes(taskDirectory)) ??
58
+ (candidates.length === 1 ? candidates[0] : undefined)
59
+ );
60
+ }
61
+ function readBlameOrigins(path) {
62
+ if (!path || !existsSync(path)) return new Map();
63
+ const origins = new Map();
64
+ for (const line of readFileSync(path, "utf8").split(/\r?\n/u)) {
65
+ /*
66
+ * Columns are mandatory in AGP blame coordinates. Requiring the final
67
+ * `:line:column` pair makes the greedy path safe for both `C:\\...` and
68
+ * `[group:artifact:version] C:\\...` origins.
69
+ */
70
+ const match = /^(\d+)-->(.+):(\d+):(\d+)(?:-(?:(\d+):)?(\d+))?\s*$/u.exec(
71
+ line,
72
+ );
73
+ if (!match) continue;
74
+ const mergedLine = Number(match[1]);
75
+ const values = origins.get(mergedLine) ?? [];
76
+ values.push({ path: match[2].trim(), sourceLine: Number(match[3]) });
77
+ origins.set(mergedLine, values);
78
+ }
79
+ return origins;
80
+ }
81
+ function localManifestSources(selected) {
82
+ const sources = [];
83
+ for (const module of selected.reachableModules) {
84
+ for (const sourceSet of selected.activeSourceSets.get(module.gradlePath) ??
85
+ []) {
86
+ if (!existsSync(sourceSet.manifest)) continue;
87
+ sources.push({
88
+ ownership:
89
+ module.gradlePath === selected.applicationModule.gradlePath
90
+ ? "app"
91
+ : "local-module",
92
+ modulePath: module.gradlePath,
93
+ manifestPath: relativePath(
94
+ selected.model.projectRoot,
95
+ sourceSet.manifest,
96
+ ),
97
+ absolutePath: sourceSet.manifest,
98
+ });
99
+ }
100
+ }
101
+ return sources.sort((left, right) =>
102
+ `${left.ownership}:${left.modulePath}:${left.manifestPath}`.localeCompare(
103
+ `${right.ownership}:${right.modulePath}:${right.manifestPath}`,
104
+ "en",
105
+ ),
106
+ );
107
+ }
108
+ function sourceForBlameOrigin(origin, sources) {
109
+ const reported = comparablePath(origin.path);
110
+ const match = sources.find((source) => {
111
+ const absolute = comparablePath(source.absolutePath);
112
+ const projectRelative = comparablePath(source.manifestPath);
113
+ return (
114
+ reported === absolute ||
115
+ reported.endsWith(`/${projectRelative}`) ||
116
+ absolute.endsWith(`/${reported}`)
117
+ );
118
+ });
119
+ return match
120
+ ? {
121
+ ownership: match.ownership,
122
+ modulePath: match.modulePath,
123
+ manifestPath: match.manifestPath,
124
+ sourceLine: origin.sourceLine,
125
+ }
126
+ : undefined;
127
+ }
128
+ function sourceComponentNames(selected, module, manifestPath) {
129
+ try {
130
+ const root = parseXml(readFileSync(manifestPath, "utf8"));
131
+ const packageName =
132
+ root.attributes.package ??
133
+ module.namespace ??
134
+ (module.gradlePath === selected.applicationModule.gradlePath
135
+ ? selected.variant.applicationId
136
+ : undefined);
137
+ const application = root.children.find(
138
+ (child) => localName(child.name) === "application",
139
+ );
140
+ if (!application) return [];
141
+ return descendantElements(application).flatMap((element) => {
142
+ const kind = localName(element.name);
143
+ if (
144
+ kind !== "activity" &&
145
+ kind !== "activity-alias" &&
146
+ kind !== "fragment" &&
147
+ kind !== "receiver"
148
+ )
149
+ return [];
150
+ const rawName = attribute(element, "name")?.replaceAll(
151
+ "${applicationId}",
152
+ selected.variant.applicationId ?? packageName ?? "",
153
+ );
154
+ return rawName
155
+ ? [
156
+ {
157
+ name: resolveClassName(rawName, packageName),
158
+ sourceLine: element.startLine,
159
+ },
160
+ ]
161
+ : [];
162
+ });
163
+ } catch {
164
+ // The merged Manifest remains the authoritative parse. A missing fallback
165
+ // declaration must never fabricate local ownership.
166
+ return [];
167
+ }
168
+ }
169
+ function declarationsByComponent(selected, sources) {
170
+ const moduleByPath = new Map(
171
+ selected.reachableModules.map((module) => [module.gradlePath, module]),
172
+ );
173
+ const result = new Map();
174
+ for (const source of sources) {
175
+ const module = moduleByPath.get(source.modulePath);
176
+ if (!module) continue;
177
+ for (const component of sourceComponentNames(
178
+ selected,
179
+ module,
180
+ source.absolutePath,
181
+ )) {
182
+ const values = result.get(component.name) ?? [];
183
+ values.push({
184
+ ownership: source.ownership,
185
+ modulePath: source.modulePath,
186
+ manifestPath: source.manifestPath,
187
+ sourceLine: component.sourceLine,
188
+ });
189
+ result.set(component.name, values);
190
+ }
191
+ }
192
+ return result;
193
+ }
194
+ function uniqueSources(sources) {
195
+ return [
196
+ ...new Map(
197
+ sources.map((source) => [
198
+ `${source.ownership}:${source.modulePath}:${source.manifestPath}:` +
199
+ `${source.sourceLine ?? ""}`,
200
+ source,
201
+ ]),
202
+ ).values(),
203
+ ].sort((left, right) => {
204
+ const leftKey =
205
+ `${left.ownership}:${left.modulePath}:` +
206
+ `${left.manifestPath}:${left.sourceLine ?? ""}`;
207
+ const rightKey =
208
+ `${right.ownership}:${right.modulePath}:` +
209
+ `${right.manifestPath}:${right.sourceLine ?? ""}`;
210
+ return leftKey.localeCompare(rightKey, "en");
211
+ });
212
+ }
213
+ function componentProvenance(
214
+ name,
215
+ element,
216
+ blameOrigins,
217
+ localSources,
218
+ fallbackDeclarations,
219
+ ) {
220
+ const firstChildLine = element.children.reduce(
221
+ (earliest, child) => Math.min(earliest, child.startLine),
222
+ Number.POSITIVE_INFINITY,
223
+ );
224
+ const declarationEndLine = Number.isFinite(firstChildLine)
225
+ ? Math.max(element.startLine, firstChildLine - 1)
226
+ : element.endLine;
227
+ const declarationOrigins = Array.from(
228
+ { length: declarationEndLine - element.startLine + 1 },
229
+ (_, index) => element.startLine + index,
230
+ ).flatMap((line) => blameOrigins.get(line) ?? []);
231
+ const origins = blameOrigins.get(element.startLine)?.length
232
+ ? [...(blameOrigins.get(element.startLine) ?? [])]
233
+ : declarationOrigins;
234
+ const blamedLocal = origins.flatMap((origin) => {
235
+ const source = sourceForBlameOrigin(origin, localSources);
236
+ return source ? [source] : [];
237
+ });
238
+ const sources = uniqueSources(
239
+ origins.length > 0 ? blamedLocal : (fallbackDeclarations.get(name) ?? []),
240
+ );
241
+ return {
242
+ ownership: sources.some((source) => source.ownership === "app")
243
+ ? "app"
244
+ : sources.length > 0
245
+ ? "local-module"
246
+ : "external-dependency",
247
+ attribution:
248
+ origins.length > 0
249
+ ? "manifest-merger-blame"
250
+ : sources.length > 0
251
+ ? "active-source-manifest"
252
+ : "merged-manifest-only",
253
+ sources,
254
+ };
255
+ }
256
+ function dataAttributes(element) {
257
+ return Object.fromEntries(
258
+ Object.entries(element.attributes)
259
+ .map(([name, value]) => [localName(name), value])
260
+ .sort(([left], [right]) => left.localeCompare(right, "en")),
261
+ );
262
+ }
263
+ function deepLinkUri(data) {
264
+ if (!data.scheme) return undefined;
265
+ let uri = data.host
266
+ ? `${data.scheme}://${data.host}${data.port ? `:${data.port}` : ""}`
267
+ : `${data.scheme}:`;
268
+ uri += data.path ?? data.pathPrefix ?? data.pathPattern ?? "";
269
+ return uri;
270
+ }
271
+ function resourceName(value, expectedType) {
272
+ if (!value) return undefined;
273
+ const match = /^@(?:(?:[^:/]+):)?([^/]+)\/(.+)$/u.exec(value);
274
+ return match?.[1] === expectedType ? match[2] : undefined;
275
+ }
276
+ function metadataResource(component, metadataName) {
277
+ for (const child of component.children) {
278
+ if (
279
+ localName(child.name) !== "meta-data" ||
280
+ attribute(child, "name") !== metadataName
281
+ )
282
+ continue;
283
+ const name = resourceName(attribute(child, "resource"), "xml");
284
+ if (name) return { name, element: child };
285
+ }
286
+ return undefined;
287
+ }
288
+ function intentFilterActions(component) {
289
+ return component.children
290
+ .filter((child) => localName(child.name) === "intent-filter")
291
+ .flatMap((filter) =>
292
+ filter.children
293
+ .filter((child) => localName(child.name) === "action")
294
+ .map((child) => attribute(child, "name"))
295
+ .filter((value) => value !== undefined),
296
+ );
297
+ }
298
+ function intentEntries(selected, manifestPath, componentName, component) {
299
+ return component.children
300
+ .filter((child) => localName(child.name) === "intent-filter")
301
+ .flatMap((filter) => {
302
+ const actions = filter.children
303
+ .filter((child) => localName(child.name) === "action")
304
+ .map((child) => attribute(child, "name"))
305
+ .filter((value) => value !== undefined);
306
+ const categories = filter.children
307
+ .filter((child) => localName(child.name) === "category")
308
+ .map((child) => attribute(child, "name"))
309
+ .filter((value) => value !== undefined)
310
+ .sort((left, right) => left.localeCompare(right, "en"));
311
+ const results = [];
312
+ if (
313
+ actions.includes("android.intent.action.MAIN") &&
314
+ categories.includes("android.intent.category.LAUNCHER")
315
+ ) {
316
+ results.push({
317
+ kind: "launcher",
318
+ category: "normal",
319
+ componentName,
320
+ action: "android.intent.action.MAIN",
321
+ categories,
322
+ data: {},
323
+ evidence: evidence(
324
+ selected,
325
+ manifestPath,
326
+ filter,
327
+ `launcher:${componentName}`,
328
+ ),
329
+ });
330
+ }
331
+ if (
332
+ actions.includes("android.intent.action.VIEW") &&
333
+ categories.includes("android.intent.category.BROWSABLE")
334
+ ) {
335
+ const dataElements = filter.children.filter(
336
+ (child) => localName(child.name) === "data",
337
+ );
338
+ const alternatives = dataElements.length > 0 ? dataElements : [filter];
339
+ for (const dataElement of alternatives) {
340
+ const data =
341
+ dataElement === filter ? {} : dataAttributes(dataElement);
342
+ const uri = deepLinkUri(data);
343
+ results.push({
344
+ kind: "deep-link",
345
+ category: "alternate",
346
+ componentName,
347
+ action: "android.intent.action.VIEW",
348
+ categories,
349
+ ...(uri ? { uri } : {}),
350
+ data,
351
+ evidence: evidence(
352
+ selected,
353
+ manifestPath,
354
+ dataElement,
355
+ `deep-link:${componentName}${uri ? `:${uri}` : ""}`,
356
+ ),
357
+ });
358
+ }
359
+ }
360
+ return results;
361
+ });
362
+ }
363
+ export function extractMergedManifest(selected, manifestPath) {
364
+ try {
365
+ const root = parseXml(readFileSync(manifestPath, "utf8"));
366
+ if (localName(root.name) !== "manifest") {
367
+ throw new Error(`root element is ${root.name}, expected manifest`);
368
+ }
369
+ const packageName =
370
+ root.attributes.package ??
371
+ selected.variant.applicationId ??
372
+ selected.applicationModule.namespace;
373
+ const componentPackage =
374
+ root.attributes.package ??
375
+ selected.applicationModule.namespace ??
376
+ selected.variant.applicationId;
377
+ const application = root.children.find(
378
+ (child) => localName(child.name) === "application",
379
+ );
380
+ if (!application) {
381
+ throw new Error("manifest has no application element");
382
+ }
383
+ const componentElements = descendantElements(application).filter(
384
+ (element) => {
385
+ const name = localName(element.name);
386
+ return (
387
+ name === "activity" ||
388
+ name === "activity-alias" ||
389
+ name === "fragment" ||
390
+ name === "receiver"
391
+ );
392
+ },
393
+ );
394
+ const localSources = localManifestSources(selected);
395
+ const blameOrigins = readBlameOrigins(
396
+ manifestMergerBlamePath(selected, manifestPath),
397
+ );
398
+ const fallbackDeclarations = declarationsByComponent(
399
+ selected,
400
+ localSources,
401
+ );
402
+ const components = [];
403
+ const entries = [];
404
+ for (const element of componentElements) {
405
+ const rawName = attribute(element, "name");
406
+ if (!rawName) continue;
407
+ const name = resolveClassName(rawName, componentPackage);
408
+ const elementKind = localName(element.name);
409
+ const appWidgetMetadata =
410
+ elementKind === "receiver"
411
+ ? metadataResource(element, "android.appwidget.provider")
412
+ : undefined;
413
+ const widgetAction = intentFilterActions(element).includes(
414
+ "android.appwidget.action.APPWIDGET_UPDATE",
415
+ );
416
+ const kind =
417
+ elementKind === "receiver" && (appWidgetMetadata || widgetAction)
418
+ ? "app-widget"
419
+ : elementKind;
420
+ const exported = attribute(element, "exported");
421
+ const targetActivity = attribute(element, "targetActivity");
422
+ const shortcuts =
423
+ elementKind === "activity" || elementKind === "activity-alias"
424
+ ? metadataResource(element, "android.app.shortcuts")
425
+ : undefined;
426
+ components.push({
427
+ kind,
428
+ name,
429
+ ...(targetActivity
430
+ ? {
431
+ targetActivity: resolveClassName(
432
+ targetActivity,
433
+ componentPackage,
434
+ ),
435
+ }
436
+ : {}),
437
+ ...(exported === "true" || exported === "false"
438
+ ? { exported: exported === "true" }
439
+ : {}),
440
+ ...(appWidgetMetadata
441
+ ? { appWidgetInfoResource: appWidgetMetadata.name }
442
+ : {}),
443
+ ...(shortcuts ? { shortcutResources: [shortcuts.name] } : {}),
444
+ provenance: componentProvenance(
445
+ name,
446
+ element,
447
+ blameOrigins,
448
+ localSources,
449
+ fallbackDeclarations,
450
+ ),
451
+ evidence: evidence(selected, manifestPath, element, `${kind}:${name}`),
452
+ });
453
+ entries.push(...intentEntries(selected, manifestPath, name, element));
454
+ if (kind === "app-widget") {
455
+ const entryElement =
456
+ element.children.find(
457
+ (child) =>
458
+ localName(child.name) === "intent-filter" &&
459
+ child.children.some(
460
+ (grandchild) =>
461
+ localName(grandchild.name) === "action" &&
462
+ attribute(grandchild, "name") ===
463
+ "android.appwidget.action.APPWIDGET_UPDATE",
464
+ ),
465
+ ) ??
466
+ appWidgetMetadata?.element ??
467
+ element;
468
+ entries.push({
469
+ kind: "widget",
470
+ category: "alternate",
471
+ componentName: name,
472
+ action: "android.appwidget.action.APPWIDGET_UPDATE",
473
+ categories: [],
474
+ data: appWidgetMetadata
475
+ ? { providerInfo: `@xml/${appWidgetMetadata.name}` }
476
+ : {},
477
+ evidence: evidence(
478
+ selected,
479
+ manifestPath,
480
+ entryElement,
481
+ `widget:${name}`,
482
+ ),
483
+ });
484
+ }
485
+ }
486
+ components.sort((left, right) =>
487
+ `${left.kind}:${left.name}`.localeCompare(
488
+ `${right.kind}:${right.name}`,
489
+ "en",
490
+ ),
491
+ );
492
+ entries.sort((left, right) =>
493
+ `${left.kind}:${left.componentName}:${left.uri ?? ""}`.localeCompare(
494
+ `${right.kind}:${right.componentName}:${right.uri ?? ""}`,
495
+ "en",
496
+ ),
497
+ );
498
+ return {
499
+ ...(packageName ? { packageName } : {}),
500
+ components,
501
+ entries,
502
+ };
503
+ } catch (error) {
504
+ if (error instanceof Error && error.name === "AnalysisFailure") throw error;
505
+ throw hardFailure(
506
+ "MERGED_MANIFEST_PARSE_FAILED",
507
+ "manifest",
508
+ `Could not parse merged Android Manifest: ${error instanceof Error ? error.message : String(error)}`,
509
+ undefined,
510
+ { path: relativePath(selected.model.projectRoot, manifestPath) },
511
+ );
512
+ }
513
+ }