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.
- package/agents/api-analyzer.md +113 -0
- package/agents/app-action.md +122 -0
- package/agents/code-reviewer.md +191 -295
- package/agents/coder.md +377 -0
- package/agents/self-tester.md +8 -8
- package/agents/spec-designer.md +56 -0
- package/package.json +1 -1
- package/skills/a2h-app-req-gen/SKILL.md +174 -0
- package/skills/a2h-app-req-gen/references/spec-handoff.md +99 -0
- package/skills/a2h-app-req-gen/references/subagent-render.md +115 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/build.gradle.kts +41 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle/wrapper/gradle-wrapper.properties +8 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradle.properties +3 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradlew +251 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/gradlew.bat +94 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/settings.gradle.kts +17 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawAnalysisDetector.java +1911 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawIssueRegistry.java +37 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawJson.java +146 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawLocation.java +96 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/java/dev/reqgen/analyzer/jvm/RawRecordWriter.java +227 -0
- 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
- package/skills/a2h-app-req-gen/scripts/reqgen/analyzer-jvm/src/main/resources/dev/reqgen/analyzer/jvm/raw-record-v1.schema.json +93 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/assets/dashboard.html +151 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/gradle/reqgen-lint.init.gradle +60 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/gradle/reqgen-model.init.gradle +204 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/package.json +14 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/backend.js +323 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/cli.js +811 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/gap-audit-link.js +62 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/index.js +66 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/merge.js +605 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/name-trace.js +153 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/orchestrate.js +1324 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/output-parse.js +50 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/overview.js +10 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/pool.js +23 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/post-merge-fix.js +146 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompt-loader.js +51 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompt.js +967 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/prompts.md +301 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/serve.js +78 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/short-id.js +46 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/snapshot.js +267 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/types.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/agent-render/validate.js +122 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/callback-call-sites.js +62 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/gap-audit/build.js +1291 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/gap-audit/index.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/area-ownership.js +392 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/build.js +1995 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/callback-flow.js +277 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/component-variants.js +725 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/graph/index.js +15 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/index.js +12 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/policy.js +469 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/names/traceability.js +468 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/req-model/build.js +1066 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/req-model/index.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/android-interaction-registry.js +174 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/android.js +1062 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/area-titles.js +678 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/builder.js +350 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose-api-registry.js +395 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose-call-sites.js +2008 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/compose.js +9059 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/dynamic-repeated-call-sites.js +529 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/index.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/interaction-effects.js +1149 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/jvm.js +6272 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/normalize.js +33 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/pending-intents.js +565 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/resource-id.js +42 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/route-state-variants.js +781 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/state.js +234 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/analysis/source-facts/types.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/android/extract.js +40 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/android/index.js +6 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/android/manifest.js +513 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/android/resources.js +398 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/android/types.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/android/views.js +447 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/android/xml-parser.js +175 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/cli.js +398 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/area-graph.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/artifact.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/common.js +16 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/diagnostic.js +10 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/gap-audit.js +14 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/index.js +11 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/name-traceability.js +26 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/raw-fact.js +40 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/req-model.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/run.js +19 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/semantic-completeness.js +11 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/contracts/source-facts.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/core/output-guard.js +41 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/core/stable-id.js +92 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/dashboard-cli.js +169 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/diagnostics.js +104 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/dump/dump.js +1028 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/dump/index.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/dump-cli.js +251 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/artifacts.js +49 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/index.js +18 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/quality-report.js +125 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/render.js +353 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/generation/types.js +2 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/graph/paths.js +474 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/index.js +15 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/protocol.js +408 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/jvm/runner.js +452 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/index.js +8 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/output.js +165 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/pipeline/run-stage1.js +891 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/project/discovery.js +299 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/project/gradle-model.js +358 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/project/gradle-runner.js +165 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/project/resource-profile.js +60 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/project/types.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/spec-handoff-cli.js +151 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/spec-handoff.js +1004 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-cli.js +109 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-input.js +419 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/stage2-name-trace-input.js +95 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/area-graph.js +444 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/index.js +7 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/req-model.js +580 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/req-text.js +195 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/semantic-area-graph.js +1431 -0
- package/skills/a2h-app-req-gen/scripts/reqgen/src/validation/types.js +1 -0
- package/skills/a2h-app-req-gen/scripts/reqgen-audit.mjs +298 -0
- package/skills/a2h-app-req-gen/scripts/reqgen-selfcheck.mjs +555 -0
- package/skills/a2h-code-review/SKILL.md +379 -0
- package/skills/{hmos-integration-test → a2h-integration-test}/README.md +6 -6
- package/skills/{hmos-integration-test → a2h-integration-test}/SKILL.md +6 -6
- package/skills/{hmos-integration-test → a2h-integration-test}/scripts/report-tool.mjs +1 -1
- package/skills/a2h-spec-design/SKILL.md +330 -0
- package/skills/a2h-spec-design/scripts/inspect_spec_design_inputs.mjs +207 -0
- package/skills/a2h-spec-design/scripts/move_spec_technical_reference.mjs +198 -0
- package/skills/a2h-spec-design/scripts/validate_spec_design_output.mjs +256 -0
- package/skills/a2h-spec-generate/SKILL.md +696 -0
- package/skills/a2h-spec-generate/references/trace-template.md +115 -0
- package/skills/a2h-spec-generate/scripts/parse_requirements.mjs +537 -0
- package/skills/a2h-spec-generate/template/REQ.txt +22 -0
- package/skills/a2h-spec-generate/template/REQ.xlsx +0 -0
- package/skills/a2h-spec-implement/SKILL.md +548 -0
- package/skills/a2h-spec-implement/references/harmony-pitfalls.md +186 -0
- package/skills/a2h-spec-implement/references/l1-unit-test.md +185 -0
- package/skills/a2h-spec-implement/references/l3-e2e-uitest.md +167 -0
- package/skills/a2h-spec-implement/references/test-core.md +132 -0
- package/skills/a2h-spec-implement/rules/arkts/arkts-standards.md +184 -0
- package/skills/a2h-spec-implement/rules/arkts/conventions/coding-style.md +96 -0
- package/skills/a2h-spec-implement/rules/arkts/conventions/security.md +126 -0
- package/skills/a2h-spec-implement/rules/arkts/language/arkts-rules.md +650 -0
- package/skills/a2h-spec-implement/rules/arkts/language/arkui-structure-rules.md +173 -0
- package/skills/a2h-spec-implement/rules/arkts/language/ts-to-arkts-rewrites.md +58 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/skills/a2h-spec-implement/rules/arkts/ui/component-cookbook.md +431 -0
- package/skills/a2h-spec-implement/rules/arkts/ui/state-management.md +152 -0
- package/skills/a2h-spec-implement/rules/arkts/ui/ui-quality.md +67 -0
- package/skills/a2h-spec-implement/rules/arkts/ui/ui-runtime-diagnosis.md +32 -0
- package/skills/a2h-spec-implement/rules/pipeline/build/package-set-collection.md +43 -0
- package/skills/a2h-spec-implement/scripts/_lib/common.mjs +97 -0
- package/skills/a2h-spec-implement/scripts/_lib/config.mjs +70 -0
- package/skills/a2h-spec-implement/scripts/_lib/lessons_cli.mjs +48 -0
- package/skills/a2h-spec-implement/scripts/build_lessons.mjs +24 -0
- package/skills/a2h-spec-implement/scripts/code_pattern_lessons.mjs +26 -0
- package/skills/a2h-spec-implement/scripts/device_ui.mjs +433 -0
- package/skills/a2h-spec-implement/scripts/device_ui_core.mjs +895 -0
- package/skills/a2h-spec-implement/scripts/ledger/aggregate_run.mjs +207 -0
- package/skills/a2h-spec-implement/scripts/manifest/emit_summary_line.mjs +37 -0
- package/skills/a2h-spec-implement/scripts/manifest/finalize_run.mjs +115 -0
- package/skills/a2h-spec-implement/scripts/manifest/render_final_summary.mjs +78 -0
- package/skills/a2h-spec-implement/scripts/manifest/root_mirror.mjs +137 -0
- package/skills/a2h-spec-implement/scripts/package.json +12 -0
- package/skills/a2h-spec-implement/scripts/state_propagation_check.mjs +676 -0
- package/skills/a2h-spec-implement/scripts/test/l2_run.mjs +244 -0
- package/skills/a2h-spec-implement/scripts/test/tp_coverage.mjs +231 -0
- package/skills/a2h-spec-implement/scripts/ui_memory.mjs +161 -0
- package/skills/a2h-spec-implement/scripts/utils/ensure_app.mjs +134 -0
- package/skills/a2h-ui-transfer/SKILL.md +20 -9
- package/skills/a2h-ui-transfer/scripts/arkts_static_check.js +80 -0
- package/skills/hmos-convert-pipeline/SKILL.md +7 -5
- package/skills/hmos-incremental-ui-align/README.md +7 -7
- package/skills/hmos-incremental-ui-align/SKILL.md +1 -1
- package/skills/hmos-incremental-ui-align/page_align.md +1 -1
- package/skills/hmos-spec-generate/SKILL.md +2 -2
- package/skills/hmos-spec-generate/scripts/parse_requirements.mjs +537 -0
- package/skills/hmos-fix-build-errors/SKILL.md +0 -266
- package/skills/hmos-fix-build-errors/references/arkts-strict-patterns.md +0 -219
- package/skills/hmos-fix-build-errors/references/known-patterns.md +0 -157
- package/skills/hmos-fix-build-errors/references/rdb-entity-pattern.md +0 -131
- package/skills/hmos-spec-generate/scripts/parse_requirements.ts +0 -515
- /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/resolve-metadata-tool.mjs +0 -0
- /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/self-test-runner.mjs +0 -0
- /package/skills/{hmos-integration-test → a2h-integration-test}/scripts/testcases-tool.mjs +0 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: a2h-code-review
|
|
3
|
+
description: "Reviews the code quality of a HarmonyOS app: performs code-change analysis through program analysis, outputs the affected code context, checks each scenario described in the SPEC document to determine whether it has been implemented, and fixes the scenarios that have not been implemented"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Expected Input
|
|
7
|
+
|
|
8
|
+
- `harmony_project_dir`: Path to the HarmonyOS project directory to review.
|
|
9
|
+
- `spec_path`: Path to the requirement specification document, which declares all scenarios.
|
|
10
|
+
- `scenarios`: The set of scenarios to verify this time, given either as an array of scenario ids or as a textual description of the scenarios; a subset of the scenarios declared in `spec_path`. If empty, all scenarios in `spec_path` are to be reviewed.
|
|
11
|
+
- `commit_info`: Path to the file recording the code-change information, containing the commit hash.
|
|
12
|
+
- `output_path`: Path where this skill's artifacts are stored.
|
|
13
|
+
|
|
14
|
+
## Expected Output
|
|
15
|
+
|
|
16
|
+
- Fixed source files in the HarmonyOS project
|
|
17
|
+
- `code-review-report.md` in `output_path` (merged review + fix report; the commit id is recorded in its `## Commit Info` section, or `none`)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Step 1 — Obtain Code-Change Information via git
|
|
22
|
+
|
|
23
|
+
In `harmony_project_dir`:
|
|
24
|
+
1. `git show --stat <commit_id>` — list the affected files.
|
|
25
|
+
2. `git diff <commit_id>^..<commit_id>` — get the raw diff.
|
|
26
|
+
Then classify and analyze the change:
|
|
27
|
+
- If the affected file types are code files, e.g. ArkTS/TS/C/CPP/H/HPP, extract from the diff the **changed symbol names** (functions, methods, `struct`/`class`/component names) and the changed files, and continue with Step 2.
|
|
28
|
+
- If the affected file types are non-code files, e.g. images (`.png`, `.jpg`), JSON/resource files (`.json`, `.json5`, resources under `entry/src/main/resources/`), or config files (`build-profile.json5`, `oh-package.json5`, `module.json5`, `.gitignore`, etc.), then **skip homegraph entirely**.
|
|
29
|
+
Analyze the change content directly from the diff above; for binary/image assets, record the add/modify/delete and the size change. Treat this diff as the **code context** and go straight to Step 3.
|
|
30
|
+
|
|
31
|
+
## Step 2 — Use homegraph to Expand the Code Context from the Raw Diff
|
|
32
|
+
|
|
33
|
+
homegraph provides program-analysis capability by building an index of the target repository, and exposes two kinds of interfaces:
|
|
34
|
+
|
|
35
|
+
- **Index management**.
|
|
36
|
+
|
|
37
|
+
| Interface | Description |
|
|
38
|
+
|--------------------|------------------------------------------|
|
|
39
|
+
| homegraph init -i [path] | Initialize and index the project. |
|
|
40
|
+
| homegraph index [path] | Full indexing (`--force` forces a rebuild). |
|
|
41
|
+
| homegraph sync [path] | Incrementally sync changes. |
|
|
42
|
+
| homegraph status [path] | Check index status. |
|
|
43
|
+
|
|
44
|
+
- **Code queries**.
|
|
45
|
+
|
|
46
|
+
| Interface | Description |
|
|
47
|
+
|--------------------|------------------------------------------|
|
|
48
|
+
| homegraph query <keyword> | Search for symbol locations. |
|
|
49
|
+
| homegraph explore <keyword> | Explore detailed information about the target. |
|
|
50
|
+
| homegraph node <symbol or file> | Get node information. |
|
|
51
|
+
| homegraph callers <symbol> | Who calls it. |
|
|
52
|
+
| homegraph callees <symbol> | What it calls. |
|
|
53
|
+
| homegraph impact <symbol> | The blast radius of modifying this symbol. |
|
|
54
|
+
| homegraph files | The tree of indexed files. |
|
|
55
|
+
|
|
56
|
+
### Ensure the index homegraph uses, built from the target repository, is up to date
|
|
57
|
+
|
|
58
|
+
1. Run `npx -y homegraph status <harmony_project_dir>` to check the index status.
|
|
59
|
+
2. Decide based on the command output:
|
|
60
|
+
- **Not indexed** (no `.homegraph/`) → run `npx -y homegraph init -i <harmony_project_dir>`, wait for completion.
|
|
61
|
+
- **Stale index** (output does NOT contain `[OK] Index is up to date`) → run `npx -y homegraph sync <harmony_project_dir>` (incremental) or `npx -y homegraph index <harmony_project_dir> --force` (full rebuild).
|
|
62
|
+
- **Index up to date** → proceed to the next step.
|
|
63
|
+
**Timeout (required).** Indexing a large project can run long — when invoking `init` / `sync` / `index` via the Bash tool, pass an explicit `timeout` of **600000** ms (10 minutes); do not rely on the tool's implicit default.
|
|
64
|
+
If the command is killed for exceeding it, treat it as a failure and take the fallback.
|
|
65
|
+
|
|
66
|
+
### Expand the changed symbols into the code context
|
|
67
|
+
|
|
68
|
+
For the symbols and files collected in the previous step, using the changed line ranges from the diff as anchors:
|
|
69
|
+
|
|
70
|
+
- Call `npx -y homegraph explore` with the concrete changed symbol / file basenames (**several names in one explore — one explore beats a chain of search → node → grep**).
|
|
71
|
+
It returns the line-numbered source of those symbols plus the call paths between them.
|
|
72
|
+
- Only when explore does not give enough information, supplement with the following commands:
|
|
73
|
+
- `npx -y homegraph callers` / `npx -y homegraph callees` — who invokes a changed function and what it invokes (which pages/components a change reaches).
|
|
74
|
+
- `npx -y homegraph impact` — the blast radius of a changed symbol, i.e. which other scenarios the commit may affect.
|
|
75
|
+
- `npx -y homegraph node` — one specific symbol body, or a bounded `offset`/`limit` read of one indexed file.
|
|
76
|
+
- For non-code literals that live outside the graph (resource names in `string.json`, routes in `main_pages.json`, permissions in `module.json5`), use `Grep` on the exact literal.
|
|
77
|
+
|
|
78
|
+
**Read only what the analysis points at — do not read whole files.** When you need extra surrounding context (an import, a type declaration a changed range depends on), read just that span with the Read tool's `offset`/`limit`.
|
|
79
|
+
First determine whether **the project** involves multiple programming languages such as ArkTS and CPP (not just the diff). If it does, then while analyzing the changed code, use `Grep` and similar means to work out the ArkTS-CPP and CPP-ArkTS call traces. Once a cross-language hop is identified, keep going with homegraph on the symbols at the **other** end (e.g. `npx -y homegraph explore` on the ArkTS entry when the change is in CPP, and vice versa) to expand that side as well. Add both the call traces and the expanded other-side symbols to the code context.
|
|
80
|
+
|
|
81
|
+
### Fallback
|
|
82
|
+
|
|
83
|
+
If homegraph is unavailable (commands error out and cannot be resolved, or a command was killed for exceeding 600000 ms), fall back to analyzing the diff directly: based on the raw diff information, read the changed files directly from the project, assemble the code context by hand, and continue the review with this manually assembled context.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Step 3 — Read the User Scenario Design Document
|
|
88
|
+
|
|
89
|
+
- Extract every user scenario / user story / use case described in it
|
|
90
|
+
- For each scenario, identify:
|
|
91
|
+
- **Scenario name**: A short descriptive title
|
|
92
|
+
- **Scenario description**: What the user does and expects
|
|
93
|
+
- **Involved pages/components**: Which UI pages or components participate
|
|
94
|
+
- **Involved data flows**: What data is read, written, or transmitted
|
|
95
|
+
- **Expected behavior**: The outcome the user should see
|
|
96
|
+
- **Related APIs/Kits**: Which HarmonyOS APIs or Kits are needed
|
|
97
|
+
If the scenario document uses a different structure (e.g. navigation flows, module descriptions, component hierarchies), derive the implicit user scenarios from it. Every navigable page, every data operation, and every user-facing feature implies at least one scenario.
|
|
98
|
+
**Build a scenario checklist** — a numbered list of all extracted scenarios. This list drives the rest of the review.
|
|
99
|
+
|
|
100
|
+
## Step 4 — Per-Scenario Validation
|
|
101
|
+
|
|
102
|
+
For **each scenario** in the checklist from Step 3, perform a detailed review:
|
|
103
|
+
|
|
104
|
+
### Trace the scenario through the code
|
|
105
|
+
|
|
106
|
+
Walk through the code path that the scenario would exercise, focusing on the changes in the code context (you can use `npx -y homegraph explore` to analyze both endpoints — e.g. the page and the data API — and get the path between them in one call):
|
|
107
|
+
- **Launch path (start here, not at the page under review)**: Resolve the app's *actual* launch page before tracing anything else — read `module.json5` `mainElement` → that ability's `srcEntry` → the page it loads (typically the first entry of `resources/base/profile/main_pages.json`). Then trace, hop by hop, how a user reaches the scenario's page **from that launch page**. For every hop, name the concrete control the user taps and confirm its handler actually navigates (`router.pushUrl` / `pushPath` / a `Navigation` destination). A page carrying `@Entry` is **not** evidence it is the launch page — `@Entry` only makes a page routable. Route registration in `main_pages.json` is **not** evidence the hop works; it only proves the target is addressable.
|
|
108
|
+
If any hop's control cannot be found, or its handler only logs (`hilog.*`) / is a TODO / is otherwise a no-op, the scenario is **FAIL** regardless of how complete the target page is — the user can never get there. Record the broken hop as the defect.
|
|
109
|
+
- **Entry point**: Which page or ability handles this scenario? Does it exist? Was it modified in this commit?
|
|
110
|
+
- **UI layer**: Are the required UI components implemented? Do they accept user input correctly?
|
|
111
|
+
- **Logic layer**: Is the business logic implemented? Does it handle the scenario's data flow?
|
|
112
|
+
- **Data layer**: Are data reads/writes/network calls present? Do they target the right sources?
|
|
113
|
+
- **API usage**: Are the required HarmonyOS APIs imported and called correctly?
|
|
114
|
+
- **Error handling**: Are failure paths handled (network errors, permission denials, empty data)?
|
|
115
|
+
- **Commit relevance**: Does this commit's changes contribute to or break this scenario?
|
|
116
|
+
|
|
117
|
+
### Determine the verdict
|
|
118
|
+
|
|
119
|
+
Assign one of these verdicts to each scenario:
|
|
120
|
+
|
|
121
|
+
| Verdict | Meaning |
|
|
122
|
+
|---------|---------|
|
|
123
|
+
| **PASS** | For **every** observable the scenario's steps assert, you can name the code that *produces* that observable, and the launch path to it is unbroken. |
|
|
124
|
+
| **PARTIAL** | The code partially implements this scenario. Some parts are present but key pieces are missing or incomplete. |
|
|
125
|
+
| **FAIL** | The code does not implement this scenario, or the implementation has critical errors that would prevent it from working. |
|
|
126
|
+
| **UNABLE TO VERIFY** | The scenario's observable cannot be settled by reading code — it depends on framework runtime behavior, device state, or timing. Use this instead of PASS whenever you are reasoning about *what the framework will do*, not *what the code says*. |
|
|
127
|
+
|
|
128
|
+
**UNABLE TO VERIFY vs. PARTIAL — judge by what's missing, not by what you call it.** These two get confused for a reason worth naming directly: a scenario can have every line of code correct and complete — the fetch, the parse, the persistence, the read-back — and still be unable to earn PASS, because the final observable (a real downloaded duration, a value surviving restart, a live network response) only exists once that code actually runs. That gap is UNABLE TO VERIFY, `class=environment` downstream — it is evidence debt, not a code defect, and a later round cannot close it by writing more code. PARTIAL means something different: the code itself is incomplete or wrong, and writing more code *would* close the gap. If you find yourself reaching for a description like "code path traced and correct, but the terminal value is a runtime/device observable" — that description **is** UNABLE TO VERIFY, however you phrase it in your own notes (e.g. "runtime debt"). Recording that situation as PARTIAL mislabels an evidence gap as a code defect, and a caller mapping verdicts to ledger `class` will file it under `class=code` instead of `class=environment` — which feeds it into defect counts and stuck-signature checks it was never meant to be part of, and a scenario that is actually done just gets stuck re-appearing as unfinished, round after round.
|
|
129
|
+
|
|
130
|
+
**The PASS bar — "the code exists" is not the bar.** Each of the scenario's numbered steps names an observable (a literal string on screen, a control appearing or disappearing, a value changing, a visual change, state surviving restart). For each one, ask: *which line makes this observable happen, and does anything downstream actually consume it?* These do **not** earn PASS on their own:
|
|
131
|
+
|
|
132
|
+
- A literal exists in the source, but you have not traced the branch that renders it.
|
|
133
|
+
- A state field is assigned, but you have not traced the assignment through to a rendered difference.
|
|
134
|
+
- A handler is wired, but the framework precondition that makes it fire is absent (see Step 5 item 4).
|
|
135
|
+
- A value is persisted, but the read path that restores it was not traced.
|
|
136
|
+
- The spec says a state "updates" / "applies" / "takes effect" *visually*, and the code only records the selection.
|
|
137
|
+
|
|
138
|
+
When the scenario's own wording is too vague to name an observable (e.g. "the theme updates accordingly"), do not invent a strict one and do not wave it through. Derive the narrowest observable the wording can bear, state in the evidence which observable you settled on, and if the code cannot even produce that, the verdict is PARTIAL — with the ambiguity recorded as a gap against the spec.
|
|
139
|
+
|
|
140
|
+
### Record findings for each scenario
|
|
141
|
+
|
|
142
|
+
For each scenario, record:
|
|
143
|
+
- **Scenario name and ID** (from the checklist)
|
|
144
|
+
- **Verdict**: PASS / PARTIAL / FAIL / UNABLE TO VERIFY
|
|
145
|
+
- **Evidence**: Specific files and line numbers that implement (or should implement) this scenario
|
|
146
|
+
- **Gaps** (if PARTIAL or FAIL): What is missing or broken, with specific details — these become the **actionable defects** in Step 5.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Step 5 — Cross-Cutting Checks
|
|
151
|
+
|
|
152
|
+
After the per-scenario review, check these cross-cutting concerns that affect multiple scenarios:
|
|
153
|
+
|
|
154
|
+
1. **Permission coverage**: Are all permissions required by the scenarios declared in `module.json5`?
|
|
155
|
+
2. **Navigation completeness**: Resolve the real launch page once (`module.json5` `mainElement` → ability `srcEntry` → loaded page / `main_pages.json` first entry) and record it explicitly in the report. Then, for each scenario page, confirm an unbroken tap-by-tap path from that launch page, and that Back returns along it. State the launch page you resolved and each hop's control — a bare "all pages registered in `main_pages.json`" is not an acceptable finding for this item, because registration proves addressability, not reachability.
|
|
156
|
+
3. **Stub traversal**: Scaffold projects ship placeholder handlers that are tappable but inert (body is only `hilog.*`, a TODO comment, or empty). Grep the handlers along every scenario's path for these, and flag any that the path must cross. A stub on the path fails the scenario even when the destination page is complete.
|
|
157
|
+
4. **Framework precondition pairing**: Some ArkUI capabilities are inert unless a partner attribute or decorator is also present. Wiring the handler alone is not implementation. Check every such pair the scenarios rely on, for example:
|
|
158
|
+
- `List` `.onItemMove()` — fires only when the `List` also has `.editMode(true)`.
|
|
159
|
+
- `@ObjectLink` — inert unless the linked class is declared `@Observed`.
|
|
160
|
+
- `@Observed` class fields read in UI — may need `@Track` to trigger re-render.
|
|
161
|
+
- `@Prop` / `@Link` — need the parent to pass the binding in the matching form (`$var` for `@Link`).
|
|
162
|
+
- Persisted state — needs a read path invoked from a lifecycle hook (`aboutToAppear` / `onPageShow`), not just a write path.
|
|
163
|
+
For each pair the scenario depends on, name both halves in the evidence. If the partner half is missing, that is a defect and the scenario is FAIL, not PASS.
|
|
164
|
+
5. **Precondition vs. seeded fixture conflict**: When a scenario asserts values for a stated starting condition (an empty list, no downloads, a fresh install), check the project's seed data (`resources/rawfile/*.json` and any in-code defaults) for entries that contradict it. A seeded row that survives a data reset will make the scenario's baseline assertions unreachable. Flag the conflict and say which fixture entry causes it.
|
|
165
|
+
6. **State management correctness**: Is state shared correctly between the components involved in scenarios, using the project's own paradigm consistently? V1 project → `@State`/`@Prop`/`@Link`/`@Provide`/`@Consume` (plus `@Observed`/`@Track`); V2 project → `@Local`/`@Param`/`@Event`/`@Provider`/`@Consumer` (plus `@ObservedV2`/`@Trace`). Flag any V1/V2 decorator mixing within a component.
|
|
166
|
+
Additionally, for any scenario whose observable is *a re-render after a state change*, check the propagation path end to end: the mutation must reach the rendering expression. In V1, watch for a `ForEach` whose `keyGenerator` returns a key that does not change when the item's rendered content changes — the child may keep stale `@Prop` values. Name the mutation site, the propagation mechanism, and the rendering expression. If you cannot establish that the re-render follows from reading the code, the verdict is UNABLE TO VERIFY, not PASS.
|
|
167
|
+
7. **API version compatibility**: Are all used APIs available in the project's target API version?
|
|
168
|
+
8. **Resource completeness**: Are all UI strings, images, and other resources referenced by scenarios present?
|
|
169
|
+
9. **Theming support (only when a scenario asserts a visual theme change)**: A scenario that requires a visible light/dark or color-scheme change needs a mechanism capable of producing it — a `dark` resource qualifier directory (`resources/dark/element/color.json`) or a runtime color-token indirection that every affected view reads from. Check whether that mechanism exists. If the affected pages hardcode literal hex colors and no `dark` qualifier set is present, recording the user's selection cannot produce the asserted visual change; report this as an architectural gap and say which of the two mechanisms is missing, rather than marking the scenario PASS because the selection persists.
|
|
170
|
+
|
|
171
|
+
Each cross-cutting defect becomes an actionable fix item in Step 6.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Step 6 — Fix the Defects
|
|
176
|
+
|
|
177
|
+
You just found the defects yourself in Steps before, go straight to fixing.
|
|
178
|
+
|
|
179
|
+
### Prioritize
|
|
180
|
+
|
|
181
|
+
Sort all defects into this fix order:
|
|
182
|
+
|
|
183
|
+
1. **Cross-cutting: Permissions** — blocking prerequisite for many features
|
|
184
|
+
2. **Cross-cutting: Navigation and stub traversal** — an unreachable page makes every scenario on it fail, so a broken hop outranks any defect on the destination page
|
|
185
|
+
3. **Cross-cutting: Framework precondition pairing** — a one-attribute fix that turns already-written code from inert to working; cheapest fix per scenario recovered
|
|
186
|
+
4. **Cross-cutting: Resources** — UI depends on strings/images
|
|
187
|
+
5. **Cross-cutting: Seeded fixture conflicts** — a baseline the scenario cannot reach invalidates its assertions
|
|
188
|
+
6. **FAIL scenarios** — in report order (earlier scenarios are typically more fundamental)
|
|
189
|
+
7. **PARTIAL scenarios** — in report order
|
|
190
|
+
8. **Cross-cutting: State management** and other quality issues — lowest priority
|
|
191
|
+
|
|
192
|
+
**Maximum 2 effective attempts** per defect (an effective attempt = code was modified AND compiles successfully; compile-fix retries inside `a2h-fix-build-errors` do NOT count as an attempt).
|
|
193
|
+
|
|
194
|
+
### Fix strategies
|
|
195
|
+
|
|
196
|
+
Apply the strategy that matches the defect category.
|
|
197
|
+
|
|
198
|
+
#### Permission Fixes
|
|
199
|
+
|
|
200
|
+
**When**: `module.json5` is missing a required permission.
|
|
201
|
+
|
|
202
|
+
1. **Verify the permission name is valid** — first use `node -yes devecocli docs search` / `node -yes devecocli docs read` to confirm the permission exists in the HarmonyOS docs; fall back to WebSearch only if the local docs flow does not surface the needed reference.
|
|
203
|
+
2. Read `module.json5` and locate the `requestPermissions` array (create it if absent).
|
|
204
|
+
3. Add the missing permission entry:
|
|
205
|
+
```json
|
|
206
|
+
{ "name": "ohos.permission.XXX" }
|
|
207
|
+
```
|
|
208
|
+
4. If the feature requires **runtime permission** (e.g., camera, location, media), also add the runtime request code:
|
|
209
|
+
- Search the Android source (if available) to see how the permission is requested.
|
|
210
|
+
- Add `abilityAccessCtrl.createAtManager().requestPermissionsFromUser()` in the appropriate lifecycle (`onWindowStageCreate` or `aboutToAppear`).
|
|
211
|
+
- Prefer `node -yes devecocli docs search` / `node -yes devecocli docs read` for the HarmonyOS API reference, then fall back to WebSearch if the local docs are insufficient.
|
|
212
|
+
|
|
213
|
+
#### Page/Component Creation
|
|
214
|
+
|
|
215
|
+
**When**: A page or component referenced by a scenario does not exist.
|
|
216
|
+
|
|
217
|
+
1. **Use `node -yes devecocli docs search` / `node -yes devecocli docs read` first** to look up the HarmonyOS equivalent UI components (e.g., `Grid` for `RecyclerView`, `List` for `ListView`). Fall back to WebSearch only when the local docs flow is insufficient.
|
|
218
|
+
2. **Create the page file** under `entry/src/main/ets/pages/`:
|
|
219
|
+
- Implement a **minimal viable page**: basic UI structure + essential state variables + placeholder data.
|
|
220
|
+
- Do NOT attempt to implement all business logic — focus on making the scenario's happy path work.
|
|
221
|
+
3. **Register the route** in `resources/base/profile/main_pages.json`.
|
|
222
|
+
4. **Add navigation** from the calling page (if the scenario specifies a navigation flow).
|
|
223
|
+
|
|
224
|
+
#### Broken Launch-Path Hop / Stub on the Path
|
|
225
|
+
|
|
226
|
+
**When**: A hop from the launch page to the scenario's page has no control, or its handler only logs / is a TODO / is empty.
|
|
227
|
+
|
|
228
|
+
1. Locate the control the user is meant to tap on the *source* page of the broken hop. If the scenario or the Android source names its label, match that label exactly.
|
|
229
|
+
2. Replace the inert body with a real navigation call, following the project's existing navigation idiom — copy the form used by a hop that already works in this project (`router.pushUrl({ url: 'pages/XxxPage' })` or the project's `Navigation`/`NavPathStack` push), rather than introducing a second idiom.
|
|
230
|
+
3. If the control does not exist at all, add it to the source page in the position the scenario describes, matching the labels and styling of its sibling controls.
|
|
231
|
+
4. Verify the destination route is registered in `main_pages.json`, and that Back returns to the source page.
|
|
232
|
+
5. **Do not** work around a broken hop by making the destination page the launch page, by adding `@Entry` to it, or by deep-linking past the hop — the user-visible path is what the scenario asserts.
|
|
233
|
+
|
|
234
|
+
#### Framework Precondition Pairing
|
|
235
|
+
|
|
236
|
+
**When**: A handler or decorator is present but its required partner is missing (the Step 5 item 4 list).
|
|
237
|
+
|
|
238
|
+
1. Confirm the pairing requirement from the docs before editing — `npx -y devecocli docs search` / `npx -y devecocli docs read` on the component or decorator.
|
|
239
|
+
2. Add the missing half at the site that already has the other half (e.g. add `.editMode(true)` to the `List` that already declares `.onItemMove()`; add `@Observed` to the class an `@ObjectLink` already points at).
|
|
240
|
+
3. Prefer adding the partner attribute over rewriting the working half — the existing logic is usually correct and only inert.
|
|
241
|
+
4. Check whether the added attribute changes unrelated behavior on the same component (e.g. `editMode` affecting item interaction), and adjust only if it breaks another scenario.
|
|
242
|
+
|
|
243
|
+
#### Seeded Fixture Conflicts
|
|
244
|
+
|
|
245
|
+
**When**: Seed data contradicts a starting condition a scenario asserts.
|
|
246
|
+
|
|
247
|
+
1. Identify the exact fixture entry (file plus the entry's identifying field) that violates the stated starting condition.
|
|
248
|
+
2. Prefer changing the seed data over changing the logic: remove or empty the offending entry so the declared starting condition is actually reachable. Aggregation/derivation logic that reads the fixture is usually correct and should be left alone.
|
|
249
|
+
3. If other scenarios depend on that seeded entry, do not delete it — record the conflict as a residual gap naming both scenarios, since the two starting conditions cannot coexist in one fixture.
|
|
250
|
+
4. Never hardcode the asserted value to satisfy the assertion; that removes the derivation the scenario is checking.
|
|
251
|
+
|
|
252
|
+
#### API Import and Call Fixes
|
|
253
|
+
|
|
254
|
+
**When**: A required HarmonyOS API is not imported or called.
|
|
255
|
+
|
|
256
|
+
1. **Identify the correct API**:
|
|
257
|
+
- If Android source is available, find the corresponding Android API call and determine the HarmonyOS equivalent.
|
|
258
|
+
- Prefer `node -yes devecocli docs search` / `node -yes devecocli docs read` for HarmonyOS API documentation.
|
|
259
|
+
- Use WebSearch as fallback when the local docs flow does not provide enough detail.
|
|
260
|
+
2. **Do NOT guess API signatures** — always verify import path, function name, parameter types, and return type from documentation.
|
|
261
|
+
3. Add the import statement and the API call in the correct location.
|
|
262
|
+
|
|
263
|
+
#### Event Handling / Business Logic Fixes
|
|
264
|
+
|
|
265
|
+
**When**: A user interaction or data flow is missing.
|
|
266
|
+
|
|
267
|
+
1. **Read the Android implementation** (if available):
|
|
268
|
+
- Find the event listener (e.g., `setOnClickListener`, `addTextChangedListener`).
|
|
269
|
+
- Trace what happens when the event fires: state changes, API calls, UI updates, navigation.
|
|
270
|
+
2. **Translate to ArkTS**:
|
|
271
|
+
- Android `setOnClickListener` → ArkUI `.onClick(() => { ... })`
|
|
272
|
+
- Android `TextWatcher` → ArkUI `.onChange((value: string) => { ... })`
|
|
273
|
+
- Android `onItemClick` → ArkUI `.onClick()` on `ListItem` / `GridItem`
|
|
274
|
+
- Android `LongClickListener` → ArkUI `.gesture(LongPressGesture().onAction(() => { ... }))`
|
|
275
|
+
3. **Implement the business logic**:
|
|
276
|
+
- Mirror the Android logic flow as closely as possible.
|
|
277
|
+
- Use appropriate HarmonyOS APIs for persistence (`preferences`), networking (`http`), file operations (`fileIo`).
|
|
278
|
+
4. **Bind to UI**: Ensure the reactive state variables are updated so the UI reflects changes — `@State`/`@Link` etc. in a V1 project, `@Local`/`@Param` etc. in a V2 project (see State Management Fixes below for paradigm detection).
|
|
279
|
+
|
|
280
|
+
#### Resource Fixes
|
|
281
|
+
|
|
282
|
+
**When**: String resources, media files, or layout parameters are missing.
|
|
283
|
+
|
|
284
|
+
1. **String resources**:
|
|
285
|
+
- Read `resources/base/element/string.json`.
|
|
286
|
+
- Add missing string entries with appropriate keys and values.
|
|
287
|
+
- If Android source is available, reference `res/values/strings.xml` for the original text.
|
|
288
|
+
2. **Media resources (images/icons)**:
|
|
289
|
+
- If the original image exists in the Android project's `res/drawable*` or `res/mipmap*`, note it for manual copy (do not auto-copy binary files).
|
|
290
|
+
- For missing icons, record as "media resource needed" in the fix report — do not create placeholder images.
|
|
291
|
+
3. **Layout parameters**:
|
|
292
|
+
- Add missing dimension/color values to `float.json` or `color.json` as needed.
|
|
293
|
+
|
|
294
|
+
#### State Management Fixes
|
|
295
|
+
|
|
296
|
+
**When**: Components have incorrect or missing state decorators.
|
|
297
|
+
|
|
298
|
+
0. **Detect the project's state-management paradigm first** (project-level, decided once). ArkTS has two paradigms and they must NOT be mixed within a project/component:
|
|
299
|
+
- `@Component` + `@State`/`@Prop`/`@Link`/`@Provide`/`@Consume`/`@Observed`/`@ObjectLink`/`@Watch` → **V1**
|
|
300
|
+
- `@ComponentV2` + `@Local`/`@Param`/`@Once`/`@Event`/`@ObservedV2`/`@Trace`/`@Monitor`/`@Provider`/`@Consumer` → **V2**
|
|
301
|
+
- Empty project / no state decorators → default **V2**. When both exist, follow the majority and match the file's surrounding code. Fix decorators to fit the detected paradigm — never introduce the other one.
|
|
302
|
+
1. **Analyze the component hierarchy** (use the matching paradigm's decorators):
|
|
303
|
+
- **V1**: Parent → Child: `@State` in parent + `@Prop` (one-way) or `@Link` (two-way) in child. Ancestor → deep descendant: `@Provide` + `@Consume`. Global: `AppStorage` / `LocalStorage`.
|
|
304
|
+
- **V2**: Component-internal: `@Local`. Parent → Child input: `@Param` (+ `@Once` if sync-once). Child → parent: `@Event` callback (with `!!` two-way binding when appropriate). Ancestor → descendant: `@Provider` / `@Consumer`. Global: `AppStorageV2` / `PersistenceV2`.
|
|
305
|
+
2. **Check for common mistakes**:
|
|
306
|
+
- **V1**: `@State` on a non-primitive without `@Observed` on the class; `@Link` without a `$variable` binding from the parent; missing `@Watch` when a side-effect is needed on state change; `@Observed` class property used in UI but missing `@Track`.
|
|
307
|
+
- **V2**: `@ObservedV2` class property observed in UI but missing `@Trace` (both must be used together — either alone is inert); `@Param` mutated inside the child (it is input-only — emit changes via `@Event`); `@Local` expected to receive external input (use `@Param` instead).
|
|
308
|
+
- **Mixing**: V1 and V2 decorators in the same component (e.g. `@Local` inside `@Component`, or `@State` inside `@ComponentV2`) — align to the detected paradigm.
|
|
309
|
+
3. Use `node -yes devecocli docs search` / `node -yes devecocli docs read` first to verify the correct decorator combination if unsure. Fall back to WebSearch only when the local docs are insufficient.
|
|
310
|
+
|
|
311
|
+
After every single defect fix, invoke the `a2h-fix-build-errors` skill (if available in this edition) to compile and build the project, and try to fix any compile errors. If that skill is not available, stop and report it rather than guessing a build command — do not silently skip the compile gate, since every "effective attempt" is defined by a successful compile. If compilation fails and cannot be fixed, roll back this defect fix and record the fix result for this defect as "failed to fix — compilation error".
|
|
312
|
+
|
|
313
|
+
After all defects have been fixed, if source files were ultimately modified, commit the changes and record the commit_id.
|
|
314
|
+
```bash
|
|
315
|
+
cd "<harmony_project_dir>"
|
|
316
|
+
git add -A
|
|
317
|
+
git commit -m "fix(review): code review defects Total defects: {total defects}, Fixed: {successfully fixed number}, Failed: {failed to fix number}"
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## Step 7 — Generate the Report `code-review-report.md`
|
|
323
|
+
|
|
324
|
+
Write the merged review + fix report to `<output_path>/code-review-report.md` with the following structure:
|
|
325
|
+
|
|
326
|
+
```markdown
|
|
327
|
+
# Code Review Report
|
|
328
|
+
|
|
329
|
+
## Overview
|
|
330
|
+
- **Total Scenarios**: <N>
|
|
331
|
+
- **Scenario Results**: <X> PASS | <Y> PARTIAL | <Z> FAIL | <W> UNABLE TO VERIFY
|
|
332
|
+
- **Total Defects Found**: <T> (FAIL + PARTIAL scenarios + cross-cutting defects)
|
|
333
|
+
- **Successfully Fixed**: <A>
|
|
334
|
+
- **Failed to Fix**: <B>
|
|
335
|
+
|
|
336
|
+
## Launch Path
|
|
337
|
+
|
|
338
|
+
- **Resolved launch page**: <page> (from `module.json5` mainElement=<ability> → srcEntry=<path> → <page>)
|
|
339
|
+
- **Path to each scenario page**: <launch page> --tap "<control label>"--> <page> --tap "<control label>"--> <target>
|
|
340
|
+
- **Hop status**: <OK / broken at hop N: control "<label>" handler is a no-op>
|
|
341
|
+
|
|
342
|
+
## Scenario Coverage Summary
|
|
343
|
+
|
|
344
|
+
| # | Scenario | Verdict | Observables checked (produced-by evidence) | Key Gaps | Fix Status |
|
|
345
|
+
|---|----------|---------|--------------------------------------------|----------|-----------|
|
|
346
|
+
| 1 | ... | PASS | "<asserted literal>" ← <file>:<line> <the builder/branch that renders it> | — | — |
|
|
347
|
+
| 2 | ... | PARTIAL | <asserted value change> ← <file>:<line>; re-render path not established | ... | ✅ Fixed |
|
|
348
|
+
| 3 | ... | FAIL | — (unreachable: hop <N> inert) | ... | ⚠️ Partially Fixed |
|
|
349
|
+
| ...| ... | ... | ... | ... | ... |
|
|
350
|
+
|
|
351
|
+
Every PASS row must cite, for each asserted observable, the file:line that produces it. A row that cites only "the literal exists" or "the field is assigned" does not qualify as PASS — downgrade it.
|
|
352
|
+
|
|
353
|
+
## Residual Gaps (not closed by this pass)
|
|
354
|
+
|
|
355
|
+
List anything you could not settle statically, each with the reason it could not be closed and what would settle it (device run, spec clarification, fixture change). Scenarios marked UNABLE TO VERIFY must appear here.
|
|
356
|
+
|
|
357
|
+
## Commit Info
|
|
358
|
+
|
|
359
|
+
commit_id: <commit_id>
|
|
360
|
+
```
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Guidelines
|
|
364
|
+
|
|
365
|
+
- **Scenario-first**: Every finding must be tied to a specific user scenario. Do not report generic code style issues unless they impact a scenario.
|
|
366
|
+
- **Be specific**: Always include file paths and line numbers as evidence.
|
|
367
|
+
- **Be fair, in both directions**: If the code genuinely produces every observable the scenario asserts, give it PASS — don't nitpick style in a scenario review. Equally, don't award PASS for code that merely looks complete: the presence of a literal, a field assignment, or a wired handler is not the observable. When you find yourself writing evidence of the form "X exists", stop and trace what consumes X.
|
|
368
|
+
- **Distinguish "the code says" from "the framework will"**: Static review can settle the first and not always the second. Reserve PASS for observables you settled by reading code; when the outcome hinges on framework behavior you cannot confirm from the source (re-render timing, gesture recognition, focus and selection lifecycle, IME interaction), that is UNABLE TO VERIFY and belongs in Residual Gaps. Silent optimism here is what lets a scenario ship broken.
|
|
369
|
+
- **Derive implicit scenarios**: If the scenario document describes architecture (pages, modules, data flows) rather than explicit user stories, derive the scenarios yourself.
|
|
370
|
+
- **No re-verification**: You found the defects; do not run another verification pass before fixing. Trust your own findings. This is about not re-litigating a *defect you already confirmed* — it does not license awarding PASS without having traced the observable in the first place.
|
|
371
|
+
- **Look up before you guess**: For HarmonyOS API usage, parameter types, and patterns, prefer `npx -y devecocli docs search` / `npx -y devecocli docs read`.
|
|
372
|
+
- **Use device logs for runtime-only clues**: When a scenario failure appears device-specific or cannot be closed statically, first use `npx -y devecocli log --level E` and `npx -y devecocli log --crash --bundle-name <bundle>` to obtain the runtime information.
|
|
373
|
+
- **Re-sync after fixing**: If later steps depend on graph queries after you have edited source, run `npx -y homegraph sync <harmony_project_dir>` first.
|
|
374
|
+
- **Minimal changes**: Only fix identified defects. Do not refactor, add comments to unrelated code, or "improve" working code.
|
|
375
|
+
- **Fix the root cause**: Address the underlying issue, not just the symptom.
|
|
376
|
+
- **Compile before moving on**: After every defect fix, compilation must pass before the fix counts as truly complete.
|
|
377
|
+
- **Don't introduce new issues**: Verify that fixes don't break other features by checking for shared state, shared components, or shared resources — running `npx -y homegraph impact` on the symbol you changed is the fastest way to see what else it reaches.
|
|
378
|
+
- **Preserve intent**: Keep the original code's structure and patterns where possible. Match the existing naming conventions, file organization, and code style.
|
|
379
|
+
- **Prioritize gaps**: In the final assessment, rank residual gaps by user impact — which gaps would users notice first?
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
- 首轮:解析 `test_case.md` → 写出 `output-path/testcases.json` 与 `app-metadata.json` → 连接真机或模拟器、安装 HAP、跑 AutoTest → 产出 `output-path/self-test-report.md`
|
|
31
31
|
- 测试完成后,SKILL 把当轮的 `self-test-report.md`、`task/`、`_extracted.json`(若有)快照到 `output-path/round-{n}/`
|
|
32
32
|
- Fix:白盒审查代码 → 修改源码 → 产出 `round-{n}/self-test-fix-report.md`
|
|
33
|
-
- Build
|
|
33
|
+
- Build:编译项目并修复 → 从构建输出重新收集包集合并更新下一轮使用的 HAP/HSP
|
|
34
34
|
- 后续轮:跳过解析阶段,直接读首轮已生成的 `testcases.json` + `app-metadata.json`,用新 HAP 跑测试 → 同样快照到对应轮 `round-{n}/`
|
|
35
35
|
2. **HAP 镜像** — 循环结束后,最后一轮的 HAP 复制到 `output-path/entry-default.hap`,方便直接取用
|
|
36
36
|
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
│ 否(退出循环) 是(进入编译) │
|
|
125
125
|
│ │ │
|
|
126
126
|
│ ┌── Build ────────────────────────────────────────────┐ │
|
|
127
|
-
│ │
|
|
127
|
+
│ │ 编译项目并修复 → 从构建输出重新收集 entry/HSP │ │
|
|
128
128
|
│ │ → 组装到 round-{n}/package-set/ 供下一轮安装 │ │
|
|
129
129
|
│ └──────────────────────┬──────────────────────────────┘ │
|
|
130
130
|
│ │ │
|
|
@@ -193,7 +193,7 @@
|
|
|
193
193
|
- **修复计划**:按依赖关系排序的修复列表
|
|
194
194
|
- **修复详情**:每条修复的 Android 参考、根因、具体修改、有效尝试次数、结果
|
|
195
195
|
- **误报说明**:为什么判定为误报,测试 agent 出了什么问题
|
|
196
|
-
-
|
|
196
|
+
- **编译验证**:编译结果及编译修复情况(如有)
|
|
197
197
|
- **所有修改文件汇总**:文件路径、修改类型、关联 Scenario 的汇总表
|
|
198
198
|
|
|
199
199
|
### 编译阶段
|
|
@@ -204,9 +204,9 @@
|
|
|
204
204
|
|
|
205
205
|
## test_case.md 怎么写
|
|
206
206
|
|
|
207
|
-
完整格式定义见 `
|
|
207
|
+
完整格式定义见 `a2h-test-case-generation/references/contract.md`(`a2h-test-case-generation` skill 产出的就是该完整格式)。集成测试的解析器只从中提取 `### Scenario` 的 `动作`/`预期结果`,其余字段(`- 前置条件:`、`## 编号映射表`、`- 测试点:` 等)会被忽略——所以你既可以手写完整格式,也可以手写下面的最小子集。
|
|
208
208
|
|
|
209
|
-
完整格式(`
|
|
209
|
+
完整格式(`a2h-test-case-generation` 产出,contract.md 节选):
|
|
210
210
|
|
|
211
211
|
```markdown
|
|
212
212
|
# 测试套件名
|
|
@@ -338,4 +338,4 @@ A: 不必须。提供了 fixer 会参考 Android 实现来修 bug,质量更高
|
|
|
338
338
|
|
|
339
339
|
**Q: 报 "Build did not produce a HAP"?**
|
|
340
340
|
|
|
341
|
-
A:
|
|
341
|
+
A: 通常是编译失败或构建配置有误。检查编译输出,确认项目能正常构建后继续循环。
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: a2h-integration-test
|
|
3
3
|
description: "Run on-device self-test for a HarmonyOS app. Parse test_case.md, install the HAP, execute AutoTest, and produce a verification report. Optionally enters a test-and-fix loop. Triggers on phrases like '跑自测', '运行自测', '执行自测', '自动测试', '设备测试', '跑用例', '跑自动化测试', 'self test', 'run autotest'."
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- Read
|
|
@@ -119,7 +119,7 @@ Substitute `<MAX_ROUNDS>` in the question text with the parsed value (default `3
|
|
|
119
119
|
|
|
120
120
|
### 2A — Test (per round)
|
|
121
121
|
|
|
122
|
-
The helper scripts (`resolve-metadata-tool.mjs`, `testcases-tool.mjs`, `report-tool.mjs`) are bundled in this skill's own `scripts/` directory (NOT the legacy `$HOMETRANS_TOOL_PATH` copy). Before running any `node` command below, resolve `SKILL_SCRIPTS` to the absolute path of this skill's `scripts/` directory — for opencode that is `~/.config/opencode/skills/
|
|
122
|
+
The helper scripts (`resolve-metadata-tool.mjs`, `testcases-tool.mjs`, `report-tool.mjs`) are bundled in this skill's own `scripts/` directory (NOT the legacy `$HOMETRANS_TOOL_PATH` copy). Before running any `node` command below, resolve `SKILL_SCRIPTS` to the absolute path of this skill's `scripts/` directory — for opencode that is `~/.config/opencode/skills/a2h-integration-test/scripts`. `self-test-runner.mjs` itself is spawned by the `a2h_self_test` / `a2h_self_test_status` tools (the plugin resolves its path internally), so you do **not** invoke it via `node` yourself. The scripts locate `@autotest/agent`'s `batch_runner.js` by walking up from their own location and falling back to the global npm root, so they run correctly whether invoked from the repo, the skill dir, or a project.
|
|
123
123
|
|
|
124
124
|
`self-test-runner.mjs` orchestrates HAP install/uninstall + batch execution; polling is driven by you via `a2h_self_test_status`. The agent mode (`single` vs `layered` Planner+Executor dual-agent) is set by the `mode` field of the `a2h_self_test` tool call — default `single`; pass `mode: "layered"` when the app is complex enough to benefit from a planning step. There is no `autotest.yaml` to edit on this path — the tool writes a temporary one (0o600) inside `task_subdir` from the stdin-injected key and deletes it on terminal state.
|
|
125
125
|
|
|
@@ -270,11 +270,11 @@ If `round_no_confirmed_defects`:
|
|
|
270
270
|
|
|
271
271
|
If `confirmed > 0`:
|
|
272
272
|
|
|
273
|
-
**Capture `BUILD_START`** immediately before
|
|
273
|
+
**Capture `BUILD_START`** immediately before the rebuild — e.g. `touch "<ROUND_DIR>/.build_start_marker"` (or record a timestamp). This marks the moment the rebuild begins, so the re-collection step below can tell freshly-rebuilt module outputs from stale ones left by a prior build.
|
|
274
274
|
|
|
275
|
-
**Determine signing mode**: Check `ORIGINAL_HAP_PATH` (the user's original input). If it contains `*-signed.hap` or `*-signed.hsp` entries → the original packages were signed (real device path) →
|
|
275
|
+
**Determine signing mode**: Check `ORIGINAL_HAP_PATH` (the user's original input). If it contains `*-signed.hap` or `*-signed.hsp` entries → the original packages were signed (real device path) → produce signed output. If not (emulator path, unsigned packages) → produce unsigned output. This prevents the rebuilt HAP from failing `hdc install -r` on a real device while allowing unsigned testing on emulators.
|
|
276
276
|
|
|
277
|
-
Then
|
|
277
|
+
Then build the project and fix errors at `<PROJECT_ROOT>` (producing signed output if determined above) for a rebuild.
|
|
278
278
|
|
|
279
279
|
After completion, locate the authoritative entry directly from `<PROJECT_ROOT>/entry/build/default/outputs/default/`. Identify `ENTRY_HAP` in this priority order:
|
|
280
280
|
|
|
@@ -426,7 +426,7 @@ If failures remain (for `max_rounds_reached`), list them briefly (scenario names
|
|
|
426
426
|
| `<output-path>/testcases.json` is empty (`total == 0` in 2A) | Report: "testcases.json contains 0 cases — nothing to run." Exit loop with `stop_reason = no_testcases`. Do NOT enter the fix loop. |
|
|
427
427
|
| The skill writes a sentinel FAIL report (first line `status: FAIL`), or no `self-test-report.md` was written (skill failed before producing a report) | Capture the `reason:` line. Exit loop with `stop_reason = agent_early_exit` and surface the captured reason. Do NOT enter the fix loop — these failures (config / device / autotest-dir / crash / timeout / precondition failures / report not produced) are not application defects. |
|
|
428
428
|
| Fixer returns `confirmed == 0` (all false positives) | Exit loop with `stop_reason = no_confirmed_defects`. Surface the fix report summary. |
|
|
429
|
-
|
|
|
429
|
+
| The rebuild produces no HAP in build output | Report: "Build did not produce a HAP — cannot re-test." Exit loop with `stop_reason = no_hap`. |
|
|
430
430
|
| Loop reaches `MAX_ROUNDS` (default 3) with failures remaining | Report `stop_reason = max_rounds_reached`. Surface final pass rate and remaining failures. |
|
|
431
431
|
| `app-metadata.json` missing after round 1 (PROJECT_ROOT unknown) | Surface agent error; PROJECT_ROOT cannot be resolved. Do NOT enter 2B. |
|
|
432
432
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Exit 0 = PASSED, exit 1 = FAILED.
|
|
13
13
|
*
|
|
14
14
|
* The emitted markdown is a FROZEN contract parsed by the
|
|
15
|
-
*
|
|
15
|
+
* a2h-integration-test skill and validateReport below — template strings are
|
|
16
16
|
* verbatim and must not drift.
|
|
17
17
|
*/
|
|
18
18
|
import fs from 'node:fs';
|