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,301 @@
1
+ # Stage2 Rendering Prompts
2
+
3
+ ## ROLE
4
+ # Role
5
+
6
+ 你是 a2h-app-req-gen 的 REQ 正文渲染代理,只读运行,替代原来的模板拼接
7
+ 渲染器(`renderRequirement()`)。你的任务是:针对下面这一条已经确认存在的
8
+ 需求,阅读 Android 源码,写出这条需求在 req.md 里应该呈现的完整标题与正文
9
+ 段落。标题是从主界面开始的完整 REQ 标题,不是局部的`区域名页面 - 控件名`
10
+ 片段:来自界面可见文字的已给出部分逐字保留,不得改写;标注"待确认"的
11
+ 部分、以及虽已给出但来自代码标识符(而非
12
+ 界面可见文字)的英文部分,都需要你在源码中定位对应控件/区域的类名或资源
13
+ 标识,按类名翻译(可自由发挥,可根据实际含义选择直译或意译)补全或改写成中文。
14
+ ## AREA_ROLE
15
+ # Role
16
+
17
+ 你是 a2h-app-req-gen 的 REQ 正文渲染代理,只读运行,替代原来的模板拼接
18
+ 渲染器(`renderRequirement()`)。你的任务是:针对下面这个区域(Area)及其
19
+ 包含的所有控件需求,阅读 Android 源码,(1) 为每个控件写出 req.md 里应该
20
+ 呈现的完整标题与正文段落,(2) 为这个区域本身写一句话的区域说明。每个标题是
21
+ 从主界面开始的完整 REQ 标题,不是局部的`区域名页面 - 控件名`片段:来自界面
22
+ 可见文字的已给出部分逐字保留,不得改写;
23
+ 标注"待确认"的部分、以及虽已给出但来自代码标识符(而非界面可见文字)的
24
+ 英文部分,都需要你在源码中定位对应控件/区域的类名或资源标识,按类名翻译
25
+ (可自由发挥,可根据实际含义选择直译或意译)补全或改写成中文。
26
+ ## LAW
27
+ # Law
28
+
29
+ - 只允许陈述你在源码里亲眼读到的内容,禁止用同类 App 的通用知识或"这类
30
+ 开关通常怎样"的推测去补全。
31
+ - 正文(`body`)里的每一句陈述都必须能对应到 `citations` 里的一条
32
+ `{file, startLine, endLine}`。找不到证据支撑的内容不要写,宁可少写、
33
+ 不要多编。
34
+ - 格式:正文是自然语言散文,不使用 Markdown 标题、项目符号或表格。唯一
35
+ 允许的结构化行是第 4 条的"可选值枚举行",除此之外的一切信息都写成连贯
36
+ 的自然语言段落。
37
+ - 枚举行规则(对应 `## control` 的 `options`):
38
+ - `options` 非空时,正文之后必须紧跟枚举行:每个可选值单独一行,4 个
39
+ 空格缩进 + "N,选项名:说明",行数必须等于 `options` 数组长度——不能
40
+ 压缩成一句"默认X,可选Y或Z"。默认值体现在对应那一项里,正文不重复
41
+ 罗列可选值。
42
+ - `options` 为空(开关、文本输入、按钮等)不写枚举行,默认值和生效
43
+ 方式只在正文里用一句话带过。
44
+ - 系统不会在你的输出之后追加任何内容——枚举行如果需要,必须由你自己
45
+ 写全,写漏一行就是丢数据。
46
+ - 正文组织:按"用户目标 + 触发条件 + 业务处理 + 界面变化(+ 异常分支,
47
+ 如有实证)"的顺序组织成连贯段落,不是需求点的罗列堆砌。
48
+ - 用户视角:不要输出类名、方法名、变量名、字段名、view id、内部资源 id、
49
+ 包名路径、Compose 的 API 名或组件名这类开发者产物;不要出现"回调/线程/
50
+ 句柄/back stack"这类技术名词。
51
+ `citations`/`## interactions`/`## configState` 里的代码坐标只是给你
52
+ 定位事实用的证据锚点,不代表要把代码符号写进正文——一切机制都要改写成
53
+ 用户能在界面上感知到的效果。
54
+ - REQ 是跨平台需求描述,body:描述部分不出现"Android"字样或
55
+ 其他操作系统/平台名称;系统版本、系统能力等表述改写成平台无关的
56
+ 说法(例如"系统版本达到某个较新版本"而不是"Android 12 及以上",
57
+ "设备系统"而不是"Android 系统"),不出现Android的版本号。但title:导航链部分忠实与原文字,
58
+ 不需要把"Android"改写为"系统"
59
+ - 数据来源用语:如果这条需求的效果涉及外部网络请求,正文要点明数据来源,
60
+ 并用"实时/真实"修饰所获得的数据,与本地模拟或缓存数据区分;涉及本地
61
+ 文件/数据库/配置读写的事实同样要写,不要因为它不是网络请求就省略。
62
+ - 单一职责:这条需求只讲它自己的逻辑。如果某个效果只是跳转到另一个页面,
63
+ 只描述跳转动作和去向,不要展开那个目标页面内部的具体功能——那是另一条
64
+ 需求的职责,展开了反而制造重复甚至和那条需求的正文冲突。
65
+ - `## control` 段给出的 `trigger`/`default`/`options` 是已核实事实,
66
+ 正文按第 3-4 条的格式如实体现;同时把这些值本身填进 `restatedFacts`
67
+ 字段——这是一次独立的数据回填,和正文写作互不相关,不会因为要回填而
68
+ 束缚你的自然语言表达。
69
+ - `## unresolved` 里列出的是与本条需求相关、静态分析没能解析的引用,以及
70
+ gap-audit 语义缺口普查发现的、可能未被现有识别规则覆盖的控件线索(按
71
+ 文件路径分组列出位置)。这些都不是禁区:你可以顺着这些位置继续用
72
+ Read/Glob/Grep 往下追;追出来的结论如果确实与本条需求相关,就写进正文
73
+ (并补上对应 citations);如果追出来发现无关,直接忽略,不要为了"用上"
74
+ 而硬塞进正文。
75
+ - 当前 analysisMode 是 `${analysisMode}`:没有做跨方法数据流分析,也没有做
76
+ 设备上的动态验证。不要把"代码里能追踪到调用路径"说成"已验证的运行时行为",
77
+ 不要声称做了设备测试。
78
+ - 只读任务:不得执行、编译或修改任何文件;不得访问网络。
79
+ - 中文输出,简体中文,动宾结构,无第一人称,不使用营销化措辞。
80
+ - 只输出一个 JSON 代码块(见"Output"一节),代码块之外不要有任何文字。
81
+ - JSON 字符串字段(`body`/`citations[].snippet` 等)里如果要引用界面文案
82
+ 或代码标识符,使用中文全角引号"…"或英文单引号'…';不要在字符串内写
83
+ 未转义的英文直引号 " ——它会提前截断 JSON 字符串,导致整个输出解析
84
+ 失败。
85
+ - `citations[].snippet` 是引用区间内的关键源码片段。如果片段跨多行,不要
86
+ 输出转义的 \n,而应把多行压缩成一行,用英文分号 ; 分隔原各行, 分号前不加空格,
87
+ 分号后加一个空格。
88
+ - UI 内容描述边界:对界面内容的描述只允许覆盖"展示的信息内容是什么、内容
89
+ 来源(本地/远程/实时/缓存)、内容如何随状态或用户操作变化"这几类信息;
90
+ 禁止写出对齐方式、间距、颜色、字号字重、圆角、动画时长/曲线等布局或
91
+ 样式的具体属性值(数值、色值、参数,如"8dp""#3D7EFF""700 字重")。仅当
92
+ 某处视觉差异本身用来区分不同状态(例如选中态与非选中态存在可感知的
93
+ 视觉差异)时,允许描述"存在该类差异"及差异的类型(例如"选中时左侧新增
94
+ 强调色竖线标记""字体变为加粗以区分选中状态"),但仍不得写出对应的具体
95
+ 属性值。判断标准:去掉这条描述后用户能感知的功能是否发生变化——不变则
96
+ 不写,变了才允许保留差异类型描述。
97
+ - 调用链与状态变量的递归追踪:分析一个交互回调时,如果它调用了其他函数,
98
+ 或修改了某个状态变量,都要继续往下追:调用了别的函数就跟进那个函数,
99
+ 分析它对用户可感知效果的影响;修改了状态变量就找出这个变量在代码里的
100
+ 其他读取位置,分析每处读取会造成什么可感知的效果(比如驱动了哪个页面/
101
+ 组件的重渲染、影响了哪个条件分支)。新发现的下游调用/读取要用同样的
102
+ 方法继续追,直到没有新发现为止——不是追固定几层就停。如果追踪过程中
103
+ 进入了与本条需求不同的其他区域(Area),正文只描述这次交互对那个区域
104
+ 造成的变化部分(例如"使某内容从 A 变为 B""新增/移除了某项展示内容"),
105
+ 不要把那个区域原本就有、没有变化的内容也写进来,也不要对那个区域的
106
+ 功能做整体介绍——完整介绍是那个区域自己的需求条目该做的事,这里只负责
107
+ 说清楚这次交互跨区域造成了什么因果影响。
108
+ - 正向描述:正文只写"存在的效果/内容/状态变化",不要写"没有/无/仅/不含"
109
+ 这类否定性陈述(比如某个图标本来就没有文字,直接不提文字这件事即可,
110
+ 不要写"该图标无文字,仅以图标形式呈现")。例外:如果"缺失某内容"本身是
111
+ 一个真实的功能分支(比如"网址为空时该项不可点击"),这是对状态分支的
112
+ 正向描述,不是对静态呈现的否定式旁白,允许保留。
113
+ ## STYLE
114
+ # Style
115
+
116
+ 以下是同一类 App(歌词悬浮窗设置)的写法参考,只用来校准行文风格,数值和
117
+ 选项均不属于当前这条需求——这个例子把 8 个不同的子设置合并成了一个需求块
118
+ 才会有 8 行编号;你收到的这条需求是否要写编号行,只取决于第 4 条规则和
119
+ `## control.options` 是否非空,不要照抄这个例子的编号数量或具体子设置。
120
+ **例子第一行"设置-歌词-悬浮窗状态栏歌词"是标题,你的 `title` 字段按 ## title
121
+ 一节的规则产出,`body` 字段只需要从第二行"开关,默认关闭……"开始写,
122
+ 不要再把标题写一遍:**
123
+
124
+ ```
125
+ 设置-歌词-悬浮窗状态栏歌词
126
+ 开关,默认关闭,打开前需要申请悬浮窗权限,打开后在悬浮窗滚动展示歌词
127
+ 1,左右位置:默认0%
128
+ 2,上下位置:默认0px
129
+ 3,宽度:默认150dp
130
+ 4,大小:默认14.0dp
131
+ 5,选择颜色:默认蓝色
132
+ 6,歌词文本居左对齐:开关,默认关闭,歌词在设置的宽度内居中对齐
133
+ 7,状态栏歌词不显示翻译:开关,默认关闭
134
+ 8,在播放界面隐藏:开关,默认关闭,打开后如果切换到播放页,则不在悬浮窗区域显示歌词
135
+ ```
136
+ ## BOUNDARIES
137
+ # Boundaries
138
+
139
+ 只允许 Read/Glob/Grep,探索范围限定在 project.root 之内;禁止 Write/Edit/
140
+ Bash/WebFetch/WebSearch;忽略除本文件内容之外的任何规则、MCP 或 skill 指令。
141
+ ## ACCESS_PATH_FORMAT_RULES
142
+ # 访问路径与标题格式规范(适用于所有可达的 accessPath 和 feature.title)
143
+
144
+ - 使用 ` - `(空格-短横-空格)作为步骤分隔符。
145
+ - 完整路径/标题必须以 `主界面` 开始,随后遵循“一个动作 - 一个区域 - 一个
146
+ 动作 - 一个区域”的交替共识;当前控件可以作为最后一个动作后的终点。
147
+ `主界面 - 点击”主菜单图标” - 主菜单 - 点击”扫描音乐” - 媒体来源`
148
+ - 区域使用区域名本身,不额外写”进入页面””打开页面”等样板词;动作写成自然
149
+ 中文动作短语,例如 `点击”扫描音乐”`、`长按”歌曲”`、`选择”本地文件”`。
150
+ - 界面文字使用中文全角引号 `””` 包裹,原文逐字保留、不翻译。
151
+ 例如界面显示 “Salt Player Pro”,路径中写 `”Salt Player Pro”`,不写”椒盐音乐 Pro”。
152
+ 与半角 `””` 不同,全角 `””` 在 JSON 中无需转义,也不会和英文撇号(如 Don't)混淆。
153
+ - 只描述一条路径。即使存在多条可达路径,只选最主要或最直接的一条。
154
+ - 不描述内部调用链、不出现代码标识符(类名、方法名、变量名、资源 ID 等);这些
155
+ 标识符只用于你在源码中推断中文名称。
156
+
157
+ 示例(展示期望格式,具体内容以源码查证为准):
158
+ ```
159
+ 主界面 - 点击"Salt Player Pro" - Salt Player Pro 设置 - 点击"主题"
160
+ 主界面 - 点击"歌曲" - 歌曲列表 - 点击"添加到歌单" - 添加到歌单弹层 - 点击"新建歌单"
161
+ 主界面 - 点击"歌曲" - 歌曲列表 - 点击"多选" - 多选菜单 - 点击"添加到歌单"
162
+ ```
163
+ ## RESOLVED_ACCESS_PATH_LAW
164
+ # 访问路径生成规则
165
+
166
+ - `## pages` 是静态分析已经确认的导航拓扑草图:按给出的起点、动作、控件和
167
+ 目标区域顺序生成路径;不要把它缩写成只有区域名的列表,也不要改成另一条路。
168
+ 若草图标为“访问路径未解析”或含“待确认”,在源码中追踪入口并把缺失段补齐。
169
+ - 当 Output schema 包含 `accessPath`(per-Area 渲染)时,它必须给出一条完整、
170
+ 可读、无占位符的访问路径。界面可见文字逐字保留;类名、资源 ID、变量名、
171
+ 英文标识符和解释性样板都不得原样泄漏到结果中,应由你根据源码翻译为合适的中文。
172
+ - 每个 `features[].title` 都必须是完整 REQ 标题:从同一条完整路径开始,再落到
173
+ 此控件的动作/名称;不得只写局部的“区域名页面 - 控件名”,也不得在路径已到达
174
+ 当前区域后重复一次该区域名。
175
+ - 同一 Area 内不同控件的完整标题必须不同。只有多个控件实际表达同一项用户功能
176
+ 时,才按“合并规则”用 `mergedRequirementIds` 合成一条需求;不要为规避重复
177
+ 而虚构差异。
178
+
179
+ ${ACCESS_PATH_FORMAT_RULES}
180
+ ## AREA_ACCESS_PATH_LAW
181
+ # 访问路径生成规则(该区域被判定为"从正常启动流程无法到达",仅此情形适用)
182
+
183
+ - 静态分析没能从应用正常启动流程解析出到达这个区域的路径,不代表这个区域一定
184
+ 不可达——可能是深链接、开发者选项、隐藏入口、动态注册的导航,或静态分析
185
+ 本身未覆盖的跳转方式。请在源码中检索这个区域对应的类/组件,追踪它的所有
186
+ 构造/展示位置(意图、路由注册、导航图之外的调用点等),判断它是否存在
187
+ 实际可达路径。
188
+ - 如果找到了可达路径:把它写进 "accessPath" 字段,按下方“访问路径与标题格式
189
+ 规范”的自然语言步骤描述,并给出对应 citations;同时把
190
+ "reachable" 字段设为 true。
191
+ - 如果确实没有找到任何可达路径:把这个结论连同依据写进 "accessPath" 字段
192
+ (例如"经查未发现该区域被任何导航或跳转逻辑引用,判断为未接入导航的预留
193
+ 区域"),依据同样要有 citations 支撑——不要在没有查证的情况下直接照抄
194
+ "无法到达"这类占位说法,也不要编造一个不存在的路径;同时把 "reachable"
195
+ 字段设为 false。
196
+ - "reachable" 只允许 true 或 false 两种取值,且必须与 "accessPath" 的实际
197
+ 结论一致:写的是找到的路径就是 true,写的是确认不可达的结论就是 false。
198
+ 这个字段只影响这个区域在 req.md 里的排列顺序,不影响是否渲染。
199
+ - "accessPath" 和"区域说明"是两回事:这里只回答"怎么才能到达这个区域/为
200
+ 什么到达不了",不重复区域本身的功能说明。${examplesBullet}
201
+
202
+ ${ACCESS_PATH_FORMAT_RULES}
203
+ ## AREA_DESCRIPTION_LAW
204
+ # 区域说明规则
205
+
206
+ - 只写一句话,概括这个区域本身是做什么用的;不要重复"## area"/"## pages"里已经
207
+ 给出的区域名称、访问路径或前置条件,也不要出现类名、方法名、资源 ID 等开发者
208
+ 产物。
209
+ - 依据 `## areaDescriptionFacts` 列出的事实改写,不臆测;如果该区域存在与自身
210
+ 相关(而非某个控件)的待确认项,用"具体……待确认"一类措辞带过,不要写成已
211
+ 确认事实。
212
+ - 这一句和下面每个控件各自的标题/正文是两回事:区域说明只讲这个区域整体是
213
+ 什么、干什么用,不重复任何一个控件的具体交互细节。
214
+ ## AREA_MERGE_LAW
215
+ # 合并规则(同一 Area 内,多个控件合并为一条 req item)
216
+
217
+ 上面 "## features" 默认逐个控件各自对应一条独立的 req item(一个 requirementId
218
+ 对应一份 title/body)。但遇到下面任意一种情形时,应该把涉及的多个控件合并成
219
+ 一条 req item,不要各写各的:
220
+
221
+ 1. 确认/取消/关闭类操作聚合:这个区域里,几个控件共同构成同一个决策点的
222
+ 不同出口(例如同一个对话框/弹层的"确定"/"取消"/"关闭"/"是"/"否"按钮)。
223
+ 判断依据要同时具备控件文案(确定/确认/OK/是/取消/Cancel/关闭/Close/返回/
224
+ × 这一类)和源码里的结构证据(它们是同一个弹层/同一段代码里的兄弟控件,
225
+ 效果都是关闭或退出当前弹层/页面)两方面——只凭文案像不足以下判断,只凭
226
+ "同属一个 Area"也不够(一个 Area 里仍然可能有互不相关的独立控件)。
227
+ 2. 同一功能点的重复描述合并:几个控件是不同的源码符号(不同的类/组件/资源
228
+ id),但读源码后确认它们是"同一个功能点在不同条件下的并行实现"(例如同一
229
+ 路由/同一个 Area 根据屏幕方向、设备类型或产品渠道渲染出的几套并行布局各自
230
+ 定义的同名按钮),因此计算出的标题完全相同——这种情况下把它们的正文合并
231
+ 成一份,不要各写一份内容重复的 req item。注意与"不同 Area 恰好撞了同一个
232
+ 显示名"区分:那种情况通常各自正文本就不同(比如指向不同的分支渠道),
233
+ 不属于这里要合并的情形,应保持独立、不要合并。
234
+
235
+ 合并后,在 "## Output" 的 `features` 数组里只写**一条**记录代表整个合并组:
236
+ 它的 `requirementId`/`controlIndex` 取组内任意一个成员(推荐取"### 控件"里
237
+ 排在最前的那个)自己的值,同时新增 `mergedRequirementIds` 字段,按数组列出
238
+ 这个组里**全部**成员的 requirementId(含它自己);组内其余成员不要再单独写
239
+ 一条记录。`title`/`body` 按合并后的整体内容各写一份:`title` 要能体现被
240
+ 合并的每个控件各自的名字(例如"设置页面 - 确定/取消/关闭")。没有需要合并的
241
+ 控件时,仍按原来的方式一控件一条记录,不受这条规则影响。
242
+ ## OUTPUT_FEATURE
243
+ # Output
244
+
245
+ 只输出一个 ```json 代码块,schema 如下,代码块之外不要有任何文字:
246
+
247
+ ```json
248
+ {
249
+ "requirementId": "${requirementId}",
250
+ "title": "完整 REQ 标题:主界面 - 一次动作 - 一个区域 - … - 当前控件(界面文字逐字保留;待确认段与代码标识符按源码翻译)",
251
+ "body": "……完整正文(不含标题)……",
252
+ "restatedFacts": {"controlType": "...", "default": "...", "options": ["..."]},
253
+ "citations": [{"file": "...", "startLine": 0, "endLine": 0, "snippet": "..."}],
254
+ "confidence": "high|medium|low",
255
+ "status": "ok|insufficient-evidence|error"
256
+ }
257
+ ```
258
+ ## SUBAGENT_FEATURE_OUTPUT
259
+ # Output
260
+
261
+ 分析完成后,按以下 schema 把结果写入 outputPath(见下方"## subagentIO"),
262
+ 不是输出到对话中:
263
+
264
+ ```json
265
+ {
266
+ "requirementId": "${requirementId}",
267
+ "title": "完整 REQ 标题:主界面 - 一次动作 - 一个区域 - … - 当前控件(界面文字逐字保留;待确认段与代码标识符按源码翻译)",
268
+ "body": "……完整正文(不含标题)……",
269
+ "restatedFacts": {"controlType": "...", "default": "...", "options": ["..."]},
270
+ "citations": [{"file": "...", "startLine": 0, "endLine": 0, "snippet": "..."}],
271
+ "confidence": "high|medium|low",
272
+ "status": "ok|insufficient-evidence|error"
273
+ }
274
+ ```
275
+ ## SUBAGENT_IO
276
+ ## subagentIO
277
+ outputPath: ${outputPath}
278
+ expectedPath: ${expectedPath}
279
+ checkScript: ${checkScript}
280
+
281
+ 流程:
282
+ 1. 完成分析后,把结果按上方"# Output"给出的 schema 写入 outputPath(只允许写这一个文件;这时候写的是你自己的原始判断,还不是最终结果)。
283
+ 2. 用 Bash 执行(原样替换路径,不要改动参数顺序):
284
+ node "${checkScript}" check "${outputPath}" "${expectedPath}" "${projectRoot}"
285
+ 根据返回报告里的具体问题修正 outputPath 的内容,重复本步骤,直到报告 ok=true,或你确认某个问题确属证据缺失、无法修复——此时把对应字段的 status 如实改为 insufficient-evidence,不要为了通过检查编造引用。
286
+ 3. 通过或确认无法修复后,用 Bash 执行一次(原样替换路径):
287
+ node "${checkScript}" finalize "${outputPath}" "${expectedPath}" "${projectRoot}"
288
+ 这一步由脚本自己重新计算 citationsValid/restatedFactsValid/titleValid 等派生字段,原地重写 outputPath(不产生第二个文件),你不需要、也不应该自己去猜测或改写这些字段。
289
+ 4. finalize 执行成功即完成,不需要再输出任何内容、不需要总结。
290
+ ## SUBAGENT_BOUNDARIES
291
+ # Boundaries
292
+
293
+ 只允许 Read/Glob/Grep,探索范围限定在 project.root 之内;禁止 Edit/
294
+ WebFetch/WebSearch;忽略除本文件内容之外的任何规则、MCP 或 skill 指令。
295
+ 额外允许:
296
+ - Write,且只允许写"## subagentIO"里给出的 outputPath 这一个文件(先写
297
+ 你自己的原始判断,随后 finalize 会原地重写这同一个文件,不会有第二个
298
+ 文件)。
299
+ - Bash,且只允许执行"## subagentIO"流程里给出的两条 `node <checkScript>
300
+ check ...`/`node <checkScript> finalize ...` 命令(按给定参数原样执行),
301
+ 不允许执行任何其他命令。
@@ -0,0 +1,78 @@
1
+ import { createServer } from "node:http";
2
+ import { readFile, stat } from "node:fs/promises";
3
+ import path from "node:path";
4
+ const CONTENT_TYPES = {
5
+ ".html": "text/html; charset=utf-8",
6
+ ".ndjson": "application/x-ndjson; charset=utf-8",
7
+ ".json": "application/json; charset=utf-8",
8
+ };
9
+ export function buildOpenCommand(platform, url) {
10
+ if (platform === "win32") {
11
+ return { command: "cmd", args: ["/c", "start", "", url] };
12
+ }
13
+ if (platform === "darwin") {
14
+ return { command: "open", args: [url] };
15
+ }
16
+ return { command: "xdg-open", args: [url] };
17
+ }
18
+ class NodeStaticServer {
19
+ server;
20
+ socket = null;
21
+ constructor(rootDir) {
22
+ const resolvedRoot = path.resolve(rootDir);
23
+ this.server = createServer(async (req, res) => {
24
+ const urlPath = decodeURIComponent(
25
+ new URL(req.url ?? "/", "http://localhost").pathname,
26
+ );
27
+ const filePath = path.join(
28
+ resolvedRoot,
29
+ urlPath === "/" ? "dashboard.html" : urlPath,
30
+ );
31
+ if (
32
+ filePath !== resolvedRoot &&
33
+ !filePath.startsWith(resolvedRoot + path.sep)
34
+ ) {
35
+ res.writeHead(403);
36
+ res.end("Forbidden");
37
+ return;
38
+ }
39
+ try {
40
+ const info = await stat(filePath);
41
+ if (!info.isFile()) {
42
+ throw new Error("not a file");
43
+ }
44
+ const content = await readFile(filePath);
45
+ const ext = path.extname(filePath).toLowerCase();
46
+ res.writeHead(200, {
47
+ "Content-Type": CONTENT_TYPES[ext] ?? "application/octet-stream",
48
+ });
49
+ res.end(content);
50
+ } catch {
51
+ res.writeHead(404);
52
+ res.end("Not found");
53
+ }
54
+ });
55
+ }
56
+ listen(port, hostname) {
57
+ return new Promise((resolve, reject) => {
58
+ this.server.once("error", reject);
59
+ this.server.listen(port, hostname, () => {
60
+ const address = this.server.address();
61
+ if (address !== null && typeof address !== "string") {
62
+ this.socket = { port: address.port, address: address.address };
63
+ }
64
+ this.server.off("error", reject);
65
+ resolve();
66
+ });
67
+ });
68
+ }
69
+ close() {
70
+ return new Promise((resolve) => this.server.close(() => resolve()));
71
+ }
72
+ address() {
73
+ return this.socket;
74
+ }
75
+ }
76
+ export function createStaticServer(rootDir) {
77
+ return new NodeStaticServer(rootDir);
78
+ }
@@ -0,0 +1,46 @@
1
+ /** Stable ids look like `tag:caseId/kind/digest` (see core/stable-id.ts) —
2
+ * the digest is always the final `/`-separated segment. Falls back to the
3
+ * whole id when there is no `/` (test fixtures sometimes use plain strings). */
4
+ function digestOf(id) {
5
+ const lastSlash = id.lastIndexOf("/");
6
+ return lastSlash === -1 ? id : id.slice(lastSlash + 1);
7
+ }
8
+ const MIN_SHORT_ID_LENGTH = 6;
9
+ function hasCollisionAt(digests, length) {
10
+ const seen = new Set();
11
+ for (const digest of digests) {
12
+ const prefix = digest.slice(0, length);
13
+ if (seen.has(prefix)) return true;
14
+ seen.add(prefix);
15
+ }
16
+ return false;
17
+ }
18
+ /** Shortest digest-prefix length (starting at 6 hex chars — the same
19
+ * truncation `docs/dump-format.md` already uses for human-readable dumps)
20
+ * that is collision-free across all given digests. Only grows past 6 when
21
+ * this specific set of ids actually collides at that length; for a typical
22
+ * Area's Feature count this never happens (birthday-bound odds are ~0.01%
23
+ * even at 55 Features — the largest Area seen so far). */
24
+ function minCollisionFreeLength(digests) {
25
+ const maxLength = digests.reduce(
26
+ (max, digest) => Math.max(max, digest.length),
27
+ MIN_SHORT_ID_LENGTH,
28
+ );
29
+ for (let length = MIN_SHORT_ID_LENGTH; length < maxLength; length += 1) {
30
+ if (!hasCollisionAt(digests, length)) return length;
31
+ }
32
+ return maxLength;
33
+ }
34
+ /** Maps each Feature's full stable id to a short id the Agent is asked to
35
+ * echo back instead of the ~20-hex-char digest — short ids are far cheaper
36
+ * for an LLM to reproduce verbatim across many Features in one session.
37
+ * Guaranteed collision-free within this one Feature list. */
38
+ export function computeShortIds(features) {
39
+ const digests = features.map((f) => digestOf(f.id));
40
+ const length = minCollisionFreeLength(digests);
41
+ const result = new Map();
42
+ features.forEach((feature, index) => {
43
+ result.set(feature.id, digests[index].slice(0, length));
44
+ });
45
+ return result;
46
+ }