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,725 @@
1
+ import {
2
+ codeNameCandidate,
3
+ literalNameCandidate,
4
+ resolveNameCandidates,
5
+ semanticIdentifierName,
6
+ } from "../names/policy.js";
7
+ function uniqueSorted(values) {
8
+ return [...new Set(values)].sort((left, right) =>
9
+ left.localeCompare(right, "en"),
10
+ );
11
+ }
12
+ function leafStateName(stateKey) {
13
+ return stateKey.slice(
14
+ Math.max(
15
+ stateKey.lastIndexOf("#"),
16
+ stateKey.lastIndexOf("."),
17
+ stateKey.lastIndexOf("/"),
18
+ ) + 1,
19
+ );
20
+ }
21
+ function compactExpression(value) {
22
+ return value.replace(/\s+/gu, "").replace(/^\((.*)\)$/u, "$1");
23
+ }
24
+ /** Returns false only for a condition that provably contradicts the variant. */
25
+ function expressionCompatible(expression, stateName, value) {
26
+ if (typeof value !== "boolean") return true;
27
+ const normalized = compactExpression(expression);
28
+ const state = compactExpression(stateName);
29
+ if (normalized === state) return value;
30
+ if (normalized === `!${state}` || normalized === `!(${state})`) return !value;
31
+ const equality = new RegExp(
32
+ `^${state.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")}(?:==|=)(true|false)$`,
33
+ "u",
34
+ ).exec(normalized);
35
+ if (equality) return (equality[1] === "true") === value;
36
+ return true;
37
+ }
38
+ function refsCompatible(refs, stateName, value, conditionById) {
39
+ return refs.every((ref) => {
40
+ const expression = conditionById.get(ref)?.data.expressionAnchor;
41
+ return !expression || expressionCompatible(expression, stateName, value);
42
+ });
43
+ }
44
+ function alternativesCompatible(alternatives, stateName, value, conditionById) {
45
+ return (
46
+ !alternatives ||
47
+ alternatives.length === 0 ||
48
+ compatibleAlternatives(alternatives, stateName, value, conditionById)
49
+ .length > 0
50
+ );
51
+ }
52
+ function compatibleAlternatives(alternatives, stateName, value, conditionById) {
53
+ return alternatives.filter((alternative) =>
54
+ refsCompatible(alternative.conditionRefs, stateName, value, conditionById),
55
+ );
56
+ }
57
+ function conditionsOutsideAlternatives(refs, alternatives) {
58
+ const alternativeRefs = new Set(
59
+ alternatives?.flatMap((alternative) => alternative.conditionRefs) ?? [],
60
+ );
61
+ return refs.filter((ref) => !alternativeRefs.has(ref));
62
+ }
63
+ function commonAlternativeConditions(alternatives) {
64
+ if (alternatives.length === 0) return [];
65
+ return uniqueSorted(
66
+ alternatives[0].conditionRefs.filter((conditionRef) =>
67
+ alternatives.every((alternative) =>
68
+ alternative.conditionRefs.includes(conditionRef),
69
+ ),
70
+ ),
71
+ );
72
+ }
73
+ function actionCompatible(
74
+ action,
75
+ effectById,
76
+ edgesByAction,
77
+ stateName,
78
+ value,
79
+ conditionById,
80
+ replacedAreaConditionRefs,
81
+ ) {
82
+ if (!refsCompatible(action.preconditionRefs, stateName, value, conditionById))
83
+ return false;
84
+ if (
85
+ !alternativesCompatible(
86
+ action.preconditionAlternatives,
87
+ stateName,
88
+ value,
89
+ conditionById,
90
+ )
91
+ )
92
+ return false;
93
+ const effectCompatible = action.effectRefs.some((effectRef) => {
94
+ const effect = effectById.get(effectRef);
95
+ return (
96
+ !effect ||
97
+ alternativesCompatible(
98
+ effect.conditionAlternatives,
99
+ stateName,
100
+ value,
101
+ conditionById,
102
+ )
103
+ );
104
+ });
105
+ if (action.effectRefs.length > 0 && !effectCompatible) return false;
106
+ const edges = edgesByAction.get(action.id) ?? [];
107
+ return (
108
+ edges.length === 0 ||
109
+ edges.some(
110
+ (edge) =>
111
+ refsCompatible(
112
+ conditionsOutsideAlternatives(
113
+ edge.conditions,
114
+ edge.conditionAlternatives,
115
+ ).filter(
116
+ (conditionRef) => !replacedAreaConditionRefs.has(conditionRef),
117
+ ),
118
+ stateName,
119
+ value,
120
+ conditionById,
121
+ ) &&
122
+ alternativesCompatible(
123
+ edge.conditionAlternatives,
124
+ stateName,
125
+ value,
126
+ conditionById,
127
+ ),
128
+ )
129
+ );
130
+ }
131
+ function fallbackVariantName(base, variant) {
132
+ const stateName = semanticIdentifierName(
133
+ leafStateName(variant.data.stateKey),
134
+ );
135
+ const value = String(variant.data.value);
136
+ if (base.name.status === "resolved") {
137
+ return stateName
138
+ ? `${base.name.value} (${stateName} = ${value})`
139
+ : `${base.name.value} (${value})`;
140
+ }
141
+ return stateName ? `${stateName} = ${value}` : value;
142
+ }
143
+ function targetVariantForAction(action, variants, bindingById) {
144
+ const callbacks = new Set(
145
+ action.sourceFactRefs.flatMap((sourceRef) => {
146
+ const binding = bindingById.get(sourceRef);
147
+ return binding ? [binding.data.callbackKey] : [];
148
+ }),
149
+ );
150
+ const matches = variants.filter((variant) =>
151
+ variant.data.entryCallbackKeys.some((callbackRef) =>
152
+ callbacks.has(callbackRef),
153
+ ),
154
+ );
155
+ return matches.length === 1 ? matches[0] : undefined;
156
+ }
157
+ /**
158
+ * Expands explicit component-variant facts into Area graph entities. The
159
+ * source normalizer has already proved the scalar values and entry callbacks;
160
+ * this pass only rewrites graph ownership and references.
161
+ */
162
+ export function applyComponentVariants(input) {
163
+ if (input.variants.length === 0) return;
164
+ const unresolvedById = new Map(
165
+ input.unresolved.map((item) => [item.id, item]),
166
+ );
167
+ const bindingById = new Map(input.bindings.map((fact) => [fact.id, fact]));
168
+ const conditionById = new Map(
169
+ input.conditions.map((fact) => [fact.id, fact]),
170
+ );
171
+ const variantsByBaseArea = new Map();
172
+ for (const variant of input.variants) {
173
+ const baseAreaRef = input.areaByComponent.get(variant.data.componentKey);
174
+ if (!baseAreaRef) continue;
175
+ const facts = variantsByBaseArea.get(baseAreaRef) ?? [];
176
+ facts.push(variant);
177
+ variantsByBaseArea.set(baseAreaRef, facts);
178
+ }
179
+ for (const [baseAreaRef, unsortedVariants] of variantsByBaseArea) {
180
+ const baseArea = input.areasById.get(baseAreaRef);
181
+ if (!baseArea || unsortedVariants.length < 2) continue;
182
+ const variants = [...unsortedVariants].sort((left, right) =>
183
+ left.id.localeCompare(right.id, "en"),
184
+ );
185
+ const allVariantConditionRefs = new Set(
186
+ variants.flatMap((variant) => variant.data.conditionKeys),
187
+ );
188
+ const variantAreaByFact = new Map();
189
+ for (const variant of variants) {
190
+ const areaId = input.id(
191
+ "area",
192
+ input.caseId,
193
+ "component-variant",
194
+ variant.id,
195
+ );
196
+ const nameDecision = resolveNameCandidates([
197
+ literalNameCandidate(
198
+ "variant-display-name",
199
+ variant.data.displayName,
200
+ [variant.id],
201
+ variant.confidence,
202
+ ),
203
+ codeNameCandidate(
204
+ "variant-state",
205
+ variant.data.stateKey,
206
+ [
207
+ variant.id,
208
+ ...(baseArea.name.status === "resolved"
209
+ ? baseArea.name.supportRefs
210
+ : []),
211
+ ],
212
+ () => fallbackVariantName(baseArea, variant),
213
+ ),
214
+ ]);
215
+ const area = {
216
+ ...baseArea,
217
+ id: areaId,
218
+ identityAnchors: uniqueSorted([
219
+ ...baseArea.identityAnchors,
220
+ variant.id,
221
+ `${variant.data.stateKey}=${JSON.stringify(variant.data.value)}`,
222
+ ]),
223
+ name:
224
+ nameDecision.value !== undefined &&
225
+ nameDecision.confidence !== undefined
226
+ ? {
227
+ status: "resolved",
228
+ value: nameDecision.value,
229
+ confidence: nameDecision.confidence,
230
+ supportRefs: nameDecision.supportRefs,
231
+ }
232
+ : baseArea.name,
233
+ controlRefs: [],
234
+ conditions: uniqueSorted([
235
+ ...baseArea.conditions.filter(
236
+ (conditionRef) => !allVariantConditionRefs.has(conditionRef),
237
+ ),
238
+ ...variant.data.conditionKeys,
239
+ ]),
240
+ sourceFactRefs: uniqueSorted([
241
+ ...baseArea.sourceFactRefs,
242
+ variant.id,
243
+ ...variant.data.conditionKeys,
244
+ ...variant.data.entryCallbackKeys,
245
+ ]),
246
+ };
247
+ variantAreaByFact.set(variant.id, area);
248
+ input.areasById.set(area.id, area);
249
+ }
250
+ const baseControls = input.controls.filter(
251
+ (control) => control.areaRef === baseAreaRef,
252
+ );
253
+ const baseControlIds = new Set(baseControls.map((control) => control.id));
254
+ const baseActions = input.actions.filter((action) =>
255
+ baseControlIds.has(action.controlRef),
256
+ );
257
+ const baseActionIds = new Set(baseActions.map((action) => action.id));
258
+ const baseEffects = input.effects.filter((effect) =>
259
+ baseActionIds.has(effect.actionRef),
260
+ );
261
+ const baseEffectById = new Map(
262
+ baseEffects.map((effect) => [effect.id, effect]),
263
+ );
264
+ const baseEdges = input.edges.filter(
265
+ (edge) =>
266
+ baseActionIds.has(edge.actionRef) && edge.sourceAreaRef === baseAreaRef,
267
+ );
268
+ const removedOwnerIds = new Set([
269
+ baseAreaRef,
270
+ ...baseControlIds,
271
+ ...baseActionIds,
272
+ ...baseEffects.map((effect) => effect.id),
273
+ ...baseEdges.map((edge) => edge.id),
274
+ ]);
275
+ const mutableEdgesByAction = new Map();
276
+ for (const edge of baseEdges) {
277
+ const values = mutableEdgesByAction.get(edge.actionRef) ?? [];
278
+ values.push(edge);
279
+ mutableEdgesByAction.set(edge.actionRef, values);
280
+ }
281
+ for (const variant of variants) {
282
+ const area = variantAreaByFact.get(variant.id);
283
+ const stateName = leafStateName(variant.data.stateKey);
284
+ const cloneRefByBase = new Map([[baseAreaRef, area.id]]);
285
+ const controlPlans = [];
286
+ for (const control of baseControls) {
287
+ if (
288
+ variant.data.visibleElementKeys &&
289
+ !variant.data.visibleElementKeys.some((sourceRef) =>
290
+ control.sourceFactRefs.includes(sourceRef),
291
+ )
292
+ )
293
+ continue;
294
+ if (
295
+ !refsCompatible(
296
+ control.visibilityConditions,
297
+ stateName,
298
+ variant.data.value,
299
+ conditionById,
300
+ )
301
+ )
302
+ continue;
303
+ const actions = baseActions.filter(
304
+ (action) =>
305
+ action.controlRef === control.id &&
306
+ actionCompatible(
307
+ action,
308
+ baseEffectById,
309
+ mutableEdgesByAction,
310
+ stateName,
311
+ variant.data.value,
312
+ conditionById,
313
+ allVariantConditionRefs,
314
+ ),
315
+ );
316
+ if (control.actionRefs.length > 0 && actions.length === 0) continue;
317
+ const controlId = input.id(
318
+ "control",
319
+ input.caseId,
320
+ control.kind,
321
+ `${control.id}:${variant.id}`,
322
+ );
323
+ cloneRefByBase.set(control.id, controlId);
324
+ const actionPlans = [];
325
+ for (const action of actions) {
326
+ const actionId = input.id(
327
+ "action",
328
+ input.caseId,
329
+ action.trigger,
330
+ `${action.id}:${variant.id}`,
331
+ );
332
+ cloneRefByBase.set(action.id, actionId);
333
+ const effectPlans = [];
334
+ for (const effectRef of action.effectRefs) {
335
+ const effect = baseEffectById.get(effectRef);
336
+ if (
337
+ !effect ||
338
+ !alternativesCompatible(
339
+ effect.conditionAlternatives,
340
+ stateName,
341
+ variant.data.value,
342
+ conditionById,
343
+ )
344
+ )
345
+ continue;
346
+ const effectId = input.id(
347
+ "effect",
348
+ input.caseId,
349
+ effect.kind,
350
+ `${effect.id}:${variant.id}`,
351
+ );
352
+ cloneRefByBase.set(effect.id, effectId);
353
+ effectPlans.push({
354
+ effect,
355
+ id: effectId,
356
+ conditionAlternatives: effect.conditionAlternatives
357
+ ? compatibleAlternatives(
358
+ effect.conditionAlternatives,
359
+ stateName,
360
+ variant.data.value,
361
+ conditionById,
362
+ )
363
+ : undefined,
364
+ });
365
+ }
366
+ const edgePlans = [];
367
+ for (const edge of mutableEdgesByAction.get(action.id) ?? []) {
368
+ const conditionAlternatives = edge.conditionAlternatives
369
+ ? compatibleAlternatives(
370
+ edge.conditionAlternatives,
371
+ stateName,
372
+ variant.data.value,
373
+ conditionById,
374
+ )
375
+ : undefined;
376
+ const retainedConditions = conditionsOutsideAlternatives(
377
+ edge.conditions,
378
+ edge.conditionAlternatives,
379
+ ).filter(
380
+ (conditionRef) => !allVariantConditionRefs.has(conditionRef),
381
+ );
382
+ if (
383
+ !refsCompatible(
384
+ retainedConditions,
385
+ stateName,
386
+ variant.data.value,
387
+ conditionById,
388
+ ) ||
389
+ !alternativesCompatible(
390
+ edge.conditionAlternatives,
391
+ stateName,
392
+ variant.data.value,
393
+ conditionById,
394
+ )
395
+ )
396
+ continue;
397
+ const edgeId = input.id(
398
+ "edge",
399
+ input.caseId,
400
+ "component-variant",
401
+ `${edge.id}:${variant.id}`,
402
+ );
403
+ cloneRefByBase.set(edge.id, edgeId);
404
+ edgePlans.push({
405
+ edge,
406
+ id: edgeId,
407
+ conditions: uniqueSorted([
408
+ ...retainedConditions,
409
+ ...(conditionAlternatives?.flatMap(
410
+ (alternative) => alternative.conditionRefs,
411
+ ) ?? []),
412
+ ...variant.data.conditionKeys,
413
+ ]),
414
+ conditionAlternatives,
415
+ });
416
+ }
417
+ const preconditionAlternatives = action.preconditionAlternatives
418
+ ? compatibleAlternatives(
419
+ action.preconditionAlternatives,
420
+ stateName,
421
+ variant.data.value,
422
+ conditionById,
423
+ )
424
+ : undefined;
425
+ actionPlans.push({
426
+ action,
427
+ id: actionId,
428
+ preconditionRefs: preconditionAlternatives
429
+ ? commonAlternativeConditions(preconditionAlternatives)
430
+ : action.preconditionRefs,
431
+ preconditionAlternatives,
432
+ effects: effectPlans,
433
+ edges: edgePlans,
434
+ });
435
+ }
436
+ controlPlans.push({ control, id: controlId, actions: actionPlans });
437
+ }
438
+ /*
439
+ * A graph-owned unresolved item is part of the entity being cloned, not
440
+ * immutable source evidence. Give every variant its own stable item and
441
+ * move ownership to the corresponding cloned graph entity. Source-fact
442
+ * owned unresolved items remain shared because their owner survives this
443
+ * rewrite and they still describe the same source uncertainty.
444
+ */
445
+ const clonedUnresolvedByOwner = new Map();
446
+ const cloneUnresolvedRef = (ref, fallbackOwnerRef) => {
447
+ const item = unresolvedById.get(ref);
448
+ if (!item || !removedOwnerIds.has(item.ownerRef)) return ref;
449
+ const ownerRef = cloneRefByBase.get(item.ownerRef) ?? fallbackOwnerRef;
450
+ if (!ownerRef) return undefined;
451
+ const key = `${ref}\u0000${ownerRef}`;
452
+ const existing = clonedUnresolvedByOwner.get(key);
453
+ if (existing) return existing;
454
+ const id = input.id(
455
+ "unresolved",
456
+ input.caseId,
457
+ "component-variant-clone",
458
+ JSON.stringify([ref, ownerRef]),
459
+ );
460
+ const clone = {
461
+ ...item,
462
+ id,
463
+ ownerRef,
464
+ candidates: item.candidates.map((candidate) => ({
465
+ ...candidate,
466
+ value:
467
+ typeof candidate.value === "string"
468
+ ? (cloneRefByBase.get(candidate.value) ?? candidate.value)
469
+ : candidate.value,
470
+ })),
471
+ ...(item.originRef
472
+ ? {
473
+ originRef: cloneRefByBase.get(item.originRef) ?? item.originRef,
474
+ }
475
+ : {}),
476
+ };
477
+ input.unresolved.push(clone);
478
+ unresolvedById.set(id, clone);
479
+ clonedUnresolvedByOwner.set(key, id);
480
+ return id;
481
+ };
482
+ const cloneUnresolvedRefs = (refs) =>
483
+ uniqueSorted(
484
+ refs.flatMap((ref) => {
485
+ const cloned = cloneUnresolvedRef(ref);
486
+ return cloned ? [cloned] : [];
487
+ }),
488
+ );
489
+ const cloneSupportedValue = (value, fallbackOwnerRef) => {
490
+ if (value.status === "resolved") return value;
491
+ const unresolvedRef = cloneUnresolvedRef(
492
+ value.unresolvedRef,
493
+ fallbackOwnerRef,
494
+ );
495
+ return unresolvedRef ? { ...value, unresolvedRef } : value;
496
+ };
497
+ const cloneUnresolvedValue = (value, fallbackOwnerRef) => {
498
+ const unresolvedRef = cloneUnresolvedRef(
499
+ value.unresolvedRef,
500
+ fallbackOwnerRef,
501
+ );
502
+ return unresolvedRef ? { ...value, unresolvedRef } : value;
503
+ };
504
+ for (const plan of controlPlans) {
505
+ const clonedActionRefs = [];
506
+ for (const actionPlan of plan.actions) {
507
+ const clonedEffectRefs = actionPlan.effects.map(
508
+ (effectPlan) => effectPlan.id,
509
+ );
510
+ for (const effectPlan of actionPlan.effects) {
511
+ const { effect, id: effectId } = effectPlan;
512
+ input.effects.push({
513
+ ...effect,
514
+ id: effectId,
515
+ actionRef: actionPlan.id,
516
+ conditionAlternatives: effectPlan.conditionAlternatives,
517
+ description: cloneSupportedValue(effect.description, effectId),
518
+ ...(effect.stateKey
519
+ ? {
520
+ stateKey: cloneSupportedValue(effect.stateKey, effectId),
521
+ }
522
+ : {}),
523
+ ...(effect.value
524
+ ? { value: cloneSupportedValue(effect.value, effectId) }
525
+ : {}),
526
+ sourceFactRefs: uniqueSorted([
527
+ ...effect.sourceFactRefs,
528
+ variant.id,
529
+ ]),
530
+ ...(effect.unresolvedRefs
531
+ ? {
532
+ unresolvedRefs: cloneUnresolvedRefs(effect.unresolvedRefs),
533
+ }
534
+ : {}),
535
+ });
536
+ }
537
+ input.actions.push({
538
+ ...actionPlan.action,
539
+ id: actionPlan.id,
540
+ controlRef: plan.id,
541
+ effectRefs: clonedEffectRefs,
542
+ preconditionRefs: actionPlan.preconditionRefs,
543
+ preconditionAlternatives: actionPlan.preconditionAlternatives,
544
+ sourceFactRefs: uniqueSorted([
545
+ ...actionPlan.action.sourceFactRefs,
546
+ variant.id,
547
+ ]),
548
+ });
549
+ clonedActionRefs.push(actionPlan.id);
550
+ for (const edgePlan of actionPlan.edges) {
551
+ const { edge, id: edgeId } = edgePlan;
552
+ const effectRef = actionPlan.action.effectRefs.find((candidate) =>
553
+ baseEffectById.has(candidate),
554
+ );
555
+ const clonedEffectRef = effectRef
556
+ ? cloneRefByBase.get(effectRef)
557
+ : undefined;
558
+ input.edges.push({
559
+ ...edge,
560
+ id: edgeId,
561
+ sourceAreaRef: area.id,
562
+ controlRef: plan.id,
563
+ actionRef: actionPlan.id,
564
+ target:
565
+ "status" in edge.target
566
+ ? cloneUnresolvedValue(edge.target, edgeId)
567
+ : edge.target.kind === "area" &&
568
+ edge.target.ref === baseAreaRef
569
+ ? { kind: "area", ref: area.id }
570
+ : edge.target,
571
+ conditions: edgePlan.conditions,
572
+ conditionAlternatives: edgePlan.conditionAlternatives,
573
+ sourceFactRefs: uniqueSorted([
574
+ ...edge.sourceFactRefs,
575
+ variant.id,
576
+ ...(clonedEffectRef ? [clonedEffectRef] : []),
577
+ ]),
578
+ });
579
+ }
580
+ }
581
+ input.controls.push({
582
+ ...plan.control,
583
+ id: plan.id,
584
+ areaRef: area.id,
585
+ name: cloneSupportedValue(plan.control.name, plan.id),
586
+ ...(plan.control.enabled
587
+ ? {
588
+ enabled: cloneSupportedValue(plan.control.enabled, plan.id),
589
+ }
590
+ : {}),
591
+ actionRefs: uniqueSorted(clonedActionRefs),
592
+ visibilityConditions: uniqueSorted([
593
+ ...plan.control.visibilityConditions,
594
+ ...variant.data.conditionKeys,
595
+ ]),
596
+ sourceFactRefs: uniqueSorted([
597
+ ...plan.control.sourceFactRefs,
598
+ variant.id,
599
+ ]),
600
+ unresolvedRefs: cloneUnresolvedRefs(plan.control.unresolvedRefs),
601
+ });
602
+ const currentArea = input.areasById.get(area.id);
603
+ input.areasById.set(area.id, {
604
+ ...currentArea,
605
+ controlRefs: uniqueSorted([...currentArea.controlRefs, plan.id]),
606
+ });
607
+ }
608
+ const currentArea = input.areasById.get(area.id);
609
+ input.areasById.set(area.id, {
610
+ ...currentArea,
611
+ name: cloneSupportedValue(currentArea.name, area.id),
612
+ descriptionFacts: currentArea.descriptionFacts.map((description) => ({
613
+ ...description,
614
+ value: cloneSupportedValue(description.value, area.id),
615
+ })),
616
+ unresolvedRefs: cloneUnresolvedRefs(currentArea.unresolvedRefs),
617
+ });
618
+ }
619
+ const incoming = input.edges.filter(
620
+ (edge) =>
621
+ !baseActionIds.has(edge.actionRef) &&
622
+ !("status" in edge.target) &&
623
+ edge.target.kind === "area" &&
624
+ edge.target.ref === baseAreaRef,
625
+ );
626
+ const actionById = new Map(
627
+ input.actions.map((action) => [action.id, action]),
628
+ );
629
+ const effectById = new Map(
630
+ input.effects.map((effect) => [effect.id, effect]),
631
+ );
632
+ for (const edge of incoming) {
633
+ const action = actionById.get(edge.actionRef);
634
+ const variant = action
635
+ ? targetVariantForAction(action, variants, bindingById)
636
+ : undefined;
637
+ const targetArea = variant
638
+ ? variantAreaByFact.get(variant.id)
639
+ : undefined;
640
+ if (!action || !variant || !targetArea) {
641
+ const unresolvedId = input.id(
642
+ "unresolved",
643
+ input.caseId,
644
+ "component-variant-target",
645
+ edge.id,
646
+ );
647
+ input.unresolved.push({
648
+ id: unresolvedId,
649
+ ownerRef: edge.id,
650
+ fieldPath: "target",
651
+ reasonCode: "INTRINSIC_COMPONENT_VARIANT_TARGET_UNKNOWN",
652
+ message:
653
+ "导航进入具有多个静态页面变体的组件,但入口回调不能唯一确定状态值。",
654
+ evidenceRefs: [],
655
+ candidates: variants.map((candidate) => ({
656
+ value: variantAreaByFact.get(candidate.id).id,
657
+ supportRefs: candidate.support.map((item) => item.evidenceRef),
658
+ })),
659
+ impact: ["area-path"],
660
+ originRef: edge.id,
661
+ });
662
+ const index = input.edges.findIndex(
663
+ (candidate) => candidate.id === edge.id,
664
+ );
665
+ input.edges[index] = {
666
+ ...edge,
667
+ target: { status: "unresolved", unresolvedRef: unresolvedId },
668
+ };
669
+ continue;
670
+ }
671
+ const edgeIndex = input.edges.findIndex(
672
+ (candidate) => candidate.id === edge.id,
673
+ );
674
+ input.edges[edgeIndex] = {
675
+ ...edge,
676
+ target: { kind: "area", ref: targetArea.id },
677
+ sourceFactRefs: uniqueSorted([...edge.sourceFactRefs, variant.id]),
678
+ };
679
+ for (const effectRef of action.effectRefs) {
680
+ const effect = effectById.get(effectRef);
681
+ if (!effect || effect.kind !== "navigate-area") continue;
682
+ const effectIndex = input.effects.findIndex(
683
+ (candidate) => candidate.id === effect.id,
684
+ );
685
+ input.effects[effectIndex] = {
686
+ ...effect,
687
+ description: {
688
+ status: "resolved",
689
+ value: `进入 ${
690
+ targetArea.name.status === "resolved"
691
+ ? targetArea.name.value
692
+ : "目标区域"
693
+ }`,
694
+ confidence:
695
+ effect.description.status === "resolved"
696
+ ? effect.description.confidence
697
+ : variant.confidence,
698
+ supportRefs: uniqueSorted([
699
+ ...(effect.description.status === "resolved"
700
+ ? effect.description.supportRefs
701
+ : []),
702
+ variant.id,
703
+ ]),
704
+ },
705
+ sourceFactRefs: uniqueSorted([...effect.sourceFactRefs, variant.id]),
706
+ };
707
+ }
708
+ }
709
+ input.areasById.delete(baseAreaRef);
710
+ const removeById = (values, ids) => {
711
+ for (let index = values.length - 1; index >= 0; index -= 1) {
712
+ if (ids.has(values[index].id)) values.splice(index, 1);
713
+ }
714
+ };
715
+ removeById(input.controls, baseControlIds);
716
+ removeById(input.actions, baseActionIds);
717
+ removeById(input.effects, new Set(baseEffects.map((effect) => effect.id)));
718
+ removeById(input.edges, new Set(baseEdges.map((edge) => edge.id)));
719
+ for (let index = input.unresolved.length - 1; index >= 0; index -= 1) {
720
+ if (!removedOwnerIds.has(input.unresolved[index].ownerRef)) continue;
721
+ unresolvedById.delete(input.unresolved[index].id);
722
+ input.unresolved.splice(index, 1);
723
+ }
724
+ }
725
+ }