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,267 @@
1
+ import { mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import {
4
+ mergeAreaReqMarkdown,
5
+ mergeAreaReqTxt,
6
+ mergeReqMarkdown,
7
+ mergeReqTxt,
8
+ } from "./merge.js";
9
+ import {
10
+ areaDirFor,
11
+ expandAreaRenderItems,
12
+ expandRenderItems,
13
+ renderDirFor,
14
+ } from "./orchestrate.js";
15
+ /** Read a finalized per-Feature output written by either Stage 2 dispatch
16
+ * mode. Exported for downstream handoff adapters so they can consume the
17
+ * structured result without reverse-parsing req text. */
18
+ export async function readAttempt(file) {
19
+ try {
20
+ const parsed = JSON.parse(await readFile(file, "utf8"));
21
+ // A partially-written or failed output.json counts as "not rendered" —
22
+ // and so does a not-yet-finalized one: in subagent mode (ADR-0005)
23
+ // outputPath is first written by the subagent's own raw judgment (which
24
+ // can legitimately carry status "ok" before it has passed self-check)
25
+ // and only overwritten in place once `finalize` runs, so `finalized`
26
+ // must hold too, not just `status`.
27
+ return parsed.finalized === true &&
28
+ parsed.status === "ok" &&
29
+ typeof parsed.body === "string"
30
+ ? parsed
31
+ : undefined;
32
+ } catch {
33
+ return undefined;
34
+ }
35
+ }
36
+ /** Read a finalized per-Area output written by Stage 2. */
37
+ export async function readAreaAttempt(file) {
38
+ try {
39
+ const parsed = JSON.parse(await readFile(file, "utf8"));
40
+ // A partially-written or failed output.json counts as "not rendered" —
41
+ // see readAttempt above for why `finalized` must hold too, not just
42
+ // `status`.
43
+ if (parsed.status !== "ok" || parsed.finalized !== true) return undefined;
44
+ const features = new Map();
45
+ for (const [id, featureResult] of Object.entries(parsed.features ?? {})) {
46
+ if (
47
+ featureResult.status === "ok" &&
48
+ typeof featureResult.body === "string"
49
+ ) {
50
+ features.set(id, featureResult);
51
+ }
52
+ }
53
+ return {
54
+ status: "ok",
55
+ areaId: parsed.areaId,
56
+ ...(parsed.areaDescription === undefined
57
+ ? {}
58
+ : { areaDescription: parsed.areaDescription }),
59
+ ...(parsed.accessPath === undefined
60
+ ? {}
61
+ : { accessPath: parsed.accessPath }),
62
+ ...(parsed.reachable === undefined
63
+ ? {}
64
+ : { reachable: parsed.reachable }),
65
+ features,
66
+ ...(parsed.addedFeatures === undefined
67
+ ? {}
68
+ : { addedFeatures: parsed.addedFeatures }),
69
+ ...(parsed.hasFeature === false ? { hasFeature: false } : {}),
70
+ attempt: parsed.attempt,
71
+ };
72
+ } catch {
73
+ return undefined;
74
+ }
75
+ }
76
+ /** Offline merge: reads rendering/ output.json files only, never touches a
77
+ * backend. Failed/missing entries fall back to the template body.
78
+ * `renderableReqModel` (post-filterRenderableAreas) decides which output.json
79
+ * files to look for; `fullReqModel` must be the same, unfiltered req-model
80
+ * templateText was rendered from, so the merge walk's Area/Feature positions
81
+ * line up with the template text — filtering only some Areas out of
82
+ * rendering must not desync it from the template it is walking. */
83
+ export async function snapshotReq(
84
+ renderableReqModel,
85
+ fullReqModel,
86
+ renderDir,
87
+ outputDirectory,
88
+ templateText,
89
+ mergeOptions = {},
90
+ clock = Date.now,
91
+ ) {
92
+ const items = expandRenderItems(renderableReqModel);
93
+ const results = new Map();
94
+ for (const item of items) {
95
+ const file = path.join(
96
+ renderDir,
97
+ renderDirFor(item.feature.id),
98
+ "output.json",
99
+ );
100
+ const attempt = await readAttempt(file);
101
+ if (attempt !== undefined) results.set(item.feature.id, attempt);
102
+ }
103
+ const timestamp = new Date(clock()).toISOString().replace(/[:.]/g, "-");
104
+ const snapshotFile = path.join(outputDirectory, `req-${timestamp}.md`);
105
+ await writeFile(
106
+ snapshotFile,
107
+ mergeReqMarkdown(
108
+ fullReqModel,
109
+ renderableReqModel,
110
+ results,
111
+ templateText,
112
+ mergeOptions,
113
+ ),
114
+ "utf8",
115
+ );
116
+ return {
117
+ snapshotFile,
118
+ total: items.length,
119
+ aiRendered: results.size,
120
+ fallback: items.length - results.size,
121
+ };
122
+ }
123
+ /** Offline merge for per-Area rendering: reads rendering/ output.json files.
124
+ * See snapshotReq for why both a renderable and a full req-model are needed. */
125
+ export async function snapshotAreaReq(
126
+ renderableReqModel,
127
+ fullReqModel,
128
+ renderDir,
129
+ outputDirectory,
130
+ templateText,
131
+ mergeOptions = {},
132
+ clock = Date.now,
133
+ ) {
134
+ const items = expandAreaRenderItems(renderableReqModel);
135
+ const areaResults = new Map();
136
+ let totalFeatures = 0;
137
+ let aiRendered = 0;
138
+ for (const item of items) {
139
+ totalFeatures += item.area.features.length;
140
+ const file = path.join(renderDir, areaDirFor(item.area.id), "output.json");
141
+ const attempt = await readAreaAttempt(file);
142
+ if (attempt !== undefined) {
143
+ areaResults.set(item.area.id, attempt);
144
+ aiRendered += attempt.features.size;
145
+ }
146
+ }
147
+ const timestamp = new Date(clock()).toISOString().replace(/[:.]/g, "-");
148
+ const snapshotFile = path.join(outputDirectory, `req-${timestamp}.md`);
149
+ await writeFile(
150
+ snapshotFile,
151
+ mergeAreaReqMarkdown(
152
+ fullReqModel,
153
+ renderableReqModel,
154
+ areaResults,
155
+ templateText,
156
+ mergeOptions,
157
+ ),
158
+ "utf8",
159
+ );
160
+ return {
161
+ snapshotFile,
162
+ totalAreas: items.length,
163
+ totalFeatures,
164
+ aiRendered,
165
+ fallback: totalFeatures - aiRendered,
166
+ };
167
+ }
168
+ /** Write this run's compact req-N.txt sequence and remove only obsolete files
169
+ * in the Stage 2-owned numbered naming scheme. This keeps reruns from
170
+ * retaining an empty/stale file whose Area no longer has a Feature. */
171
+ export async function writeReqTxtFiles(outputDirectory, txtAreas) {
172
+ await mkdir(outputDirectory, { recursive: true });
173
+ await Promise.all(
174
+ txtAreas.map((content, index) =>
175
+ writeFile(
176
+ path.join(outputDirectory, `req-${index + 1}.txt`),
177
+ content,
178
+ "utf8",
179
+ ),
180
+ ),
181
+ );
182
+ const currentNames = new Set(
183
+ txtAreas.map((_, index) => `req-${index + 1}.txt`),
184
+ );
185
+ const entries = await readdir(outputDirectory, { withFileTypes: true });
186
+ await Promise.all(
187
+ entries.flatMap((entry) =>
188
+ entry.isFile() &&
189
+ /^req-\d+\.txt$/u.test(entry.name) &&
190
+ !currentNames.has(entry.name)
191
+ ? [unlink(path.join(outputDirectory, entry.name))]
192
+ : [],
193
+ ),
194
+ );
195
+ }
196
+ /** Offline merge for per-Area rendering → per-area req-{idx}.txt files. */
197
+ export async function snapshotAreaReqTxt(
198
+ renderableReqModel,
199
+ fullReqModel,
200
+ graph,
201
+ renderDir,
202
+ outputDirectory,
203
+ mergeOptions = {},
204
+ ) {
205
+ const items = expandAreaRenderItems(renderableReqModel);
206
+ const areaResults = new Map();
207
+ let totalFeatures = 0;
208
+ let aiRendered = 0;
209
+ for (const item of items) {
210
+ totalFeatures += item.area.features.length;
211
+ const file = path.join(renderDir, areaDirFor(item.area.id), "output.json");
212
+ const attempt = await readAreaAttempt(file);
213
+ if (attempt !== undefined) {
214
+ areaResults.set(item.area.id, attempt);
215
+ aiRendered += attempt.features.size;
216
+ }
217
+ }
218
+ const txtAreas = mergeAreaReqTxt(
219
+ fullReqModel,
220
+ renderableReqModel,
221
+ areaResults,
222
+ graph,
223
+ mergeOptions,
224
+ );
225
+ await writeReqTxtFiles(outputDirectory, txtAreas);
226
+ return {
227
+ totalAreas: txtAreas.length,
228
+ totalFeatures,
229
+ aiRendered,
230
+ fallback: totalFeatures - aiRendered,
231
+ };
232
+ }
233
+ /** Offline merge for per-Feature rendering → per-area req-{idx}.txt files. */
234
+ export async function snapshotReqTxt(
235
+ renderableReqModel,
236
+ fullReqModel,
237
+ graph,
238
+ renderDir,
239
+ outputDirectory,
240
+ mergeOptions = {},
241
+ ) {
242
+ const items = expandRenderItems(renderableReqModel);
243
+ const results = new Map();
244
+ for (const item of items) {
245
+ const file = path.join(
246
+ renderDir,
247
+ renderDirFor(item.feature.id),
248
+ "output.json",
249
+ );
250
+ const attempt = await readAttempt(file);
251
+ if (attempt !== undefined) results.set(item.feature.id, attempt);
252
+ }
253
+ const txtAreas = mergeReqTxt(
254
+ fullReqModel,
255
+ renderableReqModel,
256
+ results,
257
+ graph,
258
+ mergeOptions,
259
+ );
260
+ await writeReqTxtFiles(outputDirectory, txtAreas);
261
+ return {
262
+ totalAreas: txtAreas.length,
263
+ totalFeatures: items.length,
264
+ aiRendered: results.size,
265
+ fallback: items.length - results.size,
266
+ };
267
+ }
@@ -0,0 +1,122 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ async function checkCitation(citation, resolvedRoot, readFileFn) {
4
+ // Agents often echo absolute paths from their own Read/Grep tools even
5
+ // though the prompt asks for project-relative paths — accept either, but
6
+ // still enforce the project.root boundary.
7
+ const resolvedFile = path.isAbsolute(citation.file)
8
+ ? path.resolve(citation.file)
9
+ : path.resolve(resolvedRoot, citation.file);
10
+ if (
11
+ resolvedFile !== resolvedRoot &&
12
+ !resolvedFile.startsWith(resolvedRoot + path.sep)
13
+ ) {
14
+ return { citation, reason: "outside-project-root" };
15
+ }
16
+ try {
17
+ await readFileFn(resolvedFile);
18
+ } catch {
19
+ return { citation, reason: "file-not-found" };
20
+ }
21
+ return undefined;
22
+ }
23
+ export async function validateCitations(
24
+ citations,
25
+ projectRoot,
26
+ readFileFn = (file) => readFile(file, "utf8"),
27
+ ) {
28
+ const resolvedRoot = path.resolve(projectRoot);
29
+ const invalid = [];
30
+ for (const citation of citations) {
31
+ const problem = await checkCitation(citation, resolvedRoot, readFileFn);
32
+ if (problem !== undefined) invalid.push(problem);
33
+ }
34
+ return { valid: invalid.length === 0, invalid };
35
+ }
36
+ function deepEqual(a, b) {
37
+ if (a === b) return true;
38
+ if (Array.isArray(a) && Array.isArray(b)) {
39
+ return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
40
+ }
41
+ if (
42
+ typeof a === "object" &&
43
+ typeof b === "object" &&
44
+ a !== null &&
45
+ b !== null
46
+ ) {
47
+ const ka = Object.keys(a);
48
+ const kb = Object.keys(b);
49
+ if (ka.length !== kb.length) return false;
50
+ return ka.every((k) => deepEqual(a[k], b[k]));
51
+ }
52
+ return false;
53
+ }
54
+ // controlType is deliberately skipped: the new model's `trigger` carries
55
+ // different semantics than the old control.type (SPEC-0001 open question,
56
+ //评审倾向跳过). Only default/options are compared.
57
+ export function validateRestatedFacts(restatedFacts, feature) {
58
+ const mismatches = [];
59
+ const expectedDefault =
60
+ feature.defaultValue?.status === "resolved"
61
+ ? feature.defaultValue.value
62
+ : undefined;
63
+ if (
64
+ expectedDefault !== undefined &&
65
+ !deepEqual(restatedFacts.default, expectedDefault)
66
+ ) {
67
+ mismatches.push("default");
68
+ }
69
+ const expectedOptions = new Set(
70
+ feature.options.map((option) => option.value),
71
+ );
72
+ const actualOptions = new Set(restatedFacts.options ?? []);
73
+ const optionsMatch =
74
+ expectedOptions.size === actualOptions.size &&
75
+ [...expectedOptions].every((label) => actualOptions.has(label));
76
+ if (!optionsMatch) mismatches.push("options");
77
+ return { valid: mismatches.length === 0, mismatches };
78
+ }
79
+ /** Placeholder "待确认" must never survive into the final title.
80
+ * Resolved UI-literal names (translatable=false) must appear verbatim —
81
+ * the Agent may rewrite a code-identifier name (translatable=true), but
82
+ * it must not alter a name Stage 1 already resolved from UI text.
83
+ * Quote consistency is deferred to a non-blocking audit (overview.ts). */
84
+ export function validateTitle(agentTitle, parts) {
85
+ const problems = [];
86
+ // Still-pending: placeholder must be replaced
87
+ if (!parts.areaResolved && agentTitle.includes("Area 名称待确认")) {
88
+ problems.push("area-segment-still-pending");
89
+ }
90
+ if (!parts.featureResolved && agentTitle.includes("控件名称待确认")) {
91
+ problems.push("feature-segment-still-pending");
92
+ }
93
+ // Resolved UI-literal name must survive verbatim
94
+ if (
95
+ parts.areaResolved &&
96
+ !parts.areaTranslatable &&
97
+ !agentTitle.includes(parts.areaName)
98
+ ) {
99
+ problems.push("resolved-area-segment-rewritten");
100
+ }
101
+ if (
102
+ parts.featureResolved &&
103
+ !parts.featureTranslatable &&
104
+ !agentTitle.includes(parts.featureName)
105
+ ) {
106
+ problems.push("resolved-feature-segment-rewritten");
107
+ }
108
+ return { valid: problems.length === 0, problems };
109
+ }
110
+ /** Same rules as validateTitle, applied to every member of a merged req item
111
+ * (see FeatureRenderResult.mergedRequirementIds) — the one shared title must
112
+ * satisfy each merged Control's own name-inclusion requirement. Degenerates
113
+ * to validateTitle's result for a single-member list (the ordinary,
114
+ * non-merged case). */
115
+ export function validateTitleForMembers(agentTitle, partsList) {
116
+ const problems = new Set();
117
+ for (const parts of partsList) {
118
+ for (const problem of validateTitle(agentTitle, parts).problems)
119
+ problems.add(problem);
120
+ }
121
+ return { valid: problems.size === 0, problems: [...problems] };
122
+ }
@@ -0,0 +1,62 @@
1
+ export function executionFlowsForward(flowKind) {
2
+ return (
3
+ flowKind === "listener-invocation" ||
4
+ flowKind === "direct-call" ||
5
+ flowKind === "event-channel"
6
+ );
7
+ }
8
+ /**
9
+ * True only for value-flow edges that represent an argument supplied to one
10
+ * concrete invocation. Declaration aliases intentionally have no call-site
11
+ * identity and keep their previous context-free behavior.
12
+ */
13
+ export function isCallSiteArgumentStep(step) {
14
+ return (
15
+ step.flowKind === "argument-to-parameter" ||
16
+ (step.flowKind === "method-reference" &&
17
+ (step.callSiteKey !== undefined || step.parameterName !== undefined))
18
+ );
19
+ }
20
+ /**
21
+ * Maintains the minimum call string needed to pair a formal callback slot
22
+ * with the actual callback supplied at the same invocation.
23
+ *
24
+ * A direct call pushes its raw call-site identity. Traversing a callback
25
+ * argument backwards (formal slot -> actual implementation) must match and
26
+ * pop that identity. If execution starts inside a reusable declaration there
27
+ * is no call-site frame; a unique actual is safe, while multiple actuals are
28
+ * deliberately rejected instead of being cross-wired.
29
+ */
30
+ export function advanceCallSiteStack(
31
+ current,
32
+ step,
33
+ reverseArgumentCandidateCount,
34
+ ) {
35
+ if (step.flowKind === "direct-call" && step.callSiteKey) {
36
+ return {
37
+ accepted: true,
38
+ callSiteStack: [...current, step.callSiteKey],
39
+ };
40
+ }
41
+ if (!isCallSiteArgumentStep(step)) {
42
+ return { accepted: true, callSiteStack: current };
43
+ }
44
+ const expected = current.at(-1);
45
+ if (expected !== undefined) {
46
+ if (step.callSiteKey !== undefined) {
47
+ if (step.callSiteKey !== expected) {
48
+ return { accepted: false, callSiteStack: current };
49
+ }
50
+ } else if (reverseArgumentCandidateCount !== 1) {
51
+ return { accepted: false, callSiteStack: current };
52
+ }
53
+ return {
54
+ accepted: true,
55
+ callSiteStack: current.slice(0, -1),
56
+ };
57
+ }
58
+ if (reverseArgumentCandidateCount !== 1) {
59
+ return { accepted: false, callSiteStack: current };
60
+ }
61
+ return { accepted: true, callSiteStack: current };
62
+ }