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,398 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { DEFAULT_ANALYSIS_LIMITS, runStage1 } from "./pipeline/index.js";
|
|
5
|
+
import { deriveCaseId, isValidCaseId } from "./core/stable-id.js";
|
|
6
|
+
import {
|
|
7
|
+
ensureOutputDirectoryEmpty,
|
|
8
|
+
OutputDirectoryNotEmptyError,
|
|
9
|
+
} from "./core/output-guard.js";
|
|
10
|
+
import { parseResourceConfiguration } from "./project/resource-profile.js";
|
|
11
|
+
export const CLI_USAGE = `Usage:
|
|
12
|
+
pnpm stage1 -- --project <android-project> \\
|
|
13
|
+
[--module <:application-module>] [--variant <build-variant>]
|
|
14
|
+
|
|
15
|
+
Module and variant may be omitted only when the Gradle model has one choice.
|
|
16
|
+
Stage 1 performs static analysis and deterministically writes req.md;
|
|
17
|
+
it never accepts model or API options. Every run extracts the current project
|
|
18
|
+
with the current analyzer; cached Raw JVM input and replay are intentionally
|
|
19
|
+
unsupported.
|
|
20
|
+
By default, output is written below .build/runs/<case-id>/<run-id>/.
|
|
21
|
+
|
|
22
|
+
Optional:
|
|
23
|
+
--output <new-run-directory> (must be empty or non-existent)
|
|
24
|
+
--locale <locale> (default: zh-CN)
|
|
25
|
+
--orientation <portrait|landscape> (default: portrait)
|
|
26
|
+
--ui-mode <notnight|night> (default: notnight)
|
|
27
|
+
--api-level <positive-integer> (default: 36)
|
|
28
|
+
--density <density> (default: xhdpi)
|
|
29
|
+
--smallest-width-dp <positive-integer> (default: 360)
|
|
30
|
+
--case-id <stable-case-id>
|
|
31
|
+
--run-id <run-id>
|
|
32
|
+
--init-script <path>
|
|
33
|
+
--analyzer-project <path>
|
|
34
|
+
--analyzer-artifact <path-relative-to-analyzer-project>
|
|
35
|
+
--gradle-timeout-ms <positive-integer> per Gradle invocation (default: 600000)
|
|
36
|
+
--max-call-depth <positive-integer>
|
|
37
|
+
--max-callback-iterations <positive-integer>
|
|
38
|
+
--max-graph-states <positive-integer>
|
|
39
|
+
|
|
40
|
+
Toolchain environment (optional):
|
|
41
|
+
REQGEN_PROJECT_GRADLE_EXECUTABLE Target-project Gradle executor
|
|
42
|
+
REQGEN_PROJECT_JAVA_HOME Target-project JDK
|
|
43
|
+
REQGEN_ANALYZER_GRADLE_EXECUTABLE Reqgen analyzer Gradle executor
|
|
44
|
+
REQGEN_ANALYZER_JAVA_HOME Reqgen analyzer JDK
|
|
45
|
+
|
|
46
|
+
REQGEN_GRADLE_EXECUTABLE and JAVA_HOME remain shared fallbacks when a
|
|
47
|
+
scope-specific value is not set.
|
|
48
|
+
`;
|
|
49
|
+
const PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
50
|
+
export class CliUsageError extends Error {
|
|
51
|
+
constructor(message) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.name = "CliUsageError";
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const allowedOptions = new Set([
|
|
57
|
+
"project",
|
|
58
|
+
"output",
|
|
59
|
+
"module",
|
|
60
|
+
"variant",
|
|
61
|
+
"locale",
|
|
62
|
+
"orientation",
|
|
63
|
+
"ui-mode",
|
|
64
|
+
"api-level",
|
|
65
|
+
"density",
|
|
66
|
+
"smallest-width-dp",
|
|
67
|
+
"case-id",
|
|
68
|
+
"run-id",
|
|
69
|
+
"init-script",
|
|
70
|
+
"analyzer-project",
|
|
71
|
+
"analyzer-artifact",
|
|
72
|
+
"gradle-timeout-ms",
|
|
73
|
+
"max-call-depth",
|
|
74
|
+
"max-callback-iterations",
|
|
75
|
+
"max-graph-states",
|
|
76
|
+
]);
|
|
77
|
+
function parseOptions(args) {
|
|
78
|
+
const values = new Map();
|
|
79
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
80
|
+
const token = args[index];
|
|
81
|
+
if (!token.startsWith("--")) {
|
|
82
|
+
throw new CliUsageError(`Unexpected argument: ${token}`);
|
|
83
|
+
}
|
|
84
|
+
const separator = token.indexOf("=");
|
|
85
|
+
const name = token.slice(2, separator === -1 ? undefined : separator);
|
|
86
|
+
if (!allowedOptions.has(name)) {
|
|
87
|
+
throw new CliUsageError(`Unknown option: --${name}`);
|
|
88
|
+
}
|
|
89
|
+
if (values.has(name)) {
|
|
90
|
+
throw new CliUsageError(`Option may be provided once: --${name}`);
|
|
91
|
+
}
|
|
92
|
+
const inline = separator === -1 ? undefined : token.slice(separator + 1);
|
|
93
|
+
const value = inline ?? args[index + 1];
|
|
94
|
+
if (
|
|
95
|
+
value === undefined ||
|
|
96
|
+
value.trim().length === 0 ||
|
|
97
|
+
(inline === undefined && value.startsWith("--"))
|
|
98
|
+
) {
|
|
99
|
+
throw new CliUsageError(`Option requires a value: --${name}`);
|
|
100
|
+
}
|
|
101
|
+
values.set(name, value);
|
|
102
|
+
if (inline === undefined) {
|
|
103
|
+
index += 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return values;
|
|
107
|
+
}
|
|
108
|
+
function generatedRunId() {
|
|
109
|
+
const timestamp = new Date()
|
|
110
|
+
.toISOString()
|
|
111
|
+
.replace(/[-:]/gu, "")
|
|
112
|
+
.replace(/\.\d{3}Z$/u, "Z");
|
|
113
|
+
return `${timestamp}-${randomUUID().slice(0, 8)}`;
|
|
114
|
+
}
|
|
115
|
+
function safePathSegment(value, fallback) {
|
|
116
|
+
const sanitized = value
|
|
117
|
+
.trim()
|
|
118
|
+
.normalize("NFC")
|
|
119
|
+
.replace(/[^\p{Letter}\p{Number}._-]+/gu, "-")
|
|
120
|
+
.replace(/^-+|-+$/gu, "");
|
|
121
|
+
return sanitized.length === 0 || sanitized === "." || sanitized === ".."
|
|
122
|
+
? fallback
|
|
123
|
+
: sanitized;
|
|
124
|
+
}
|
|
125
|
+
function required(values, name) {
|
|
126
|
+
const value = values.get(name);
|
|
127
|
+
if (value === undefined) {
|
|
128
|
+
throw new CliUsageError(`Missing required option: --${name}`);
|
|
129
|
+
}
|
|
130
|
+
return value;
|
|
131
|
+
}
|
|
132
|
+
function positiveInteger(value, option) {
|
|
133
|
+
const result = Number(value);
|
|
134
|
+
if (!Number.isSafeInteger(result) || result <= 0) {
|
|
135
|
+
throw new CliUsageError(
|
|
136
|
+
`--${option} must be a positive integer, got ${value}`,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
export function parseStage1Arguments(args) {
|
|
142
|
+
const values = parseOptions(args);
|
|
143
|
+
const projectRoot = resolve(required(values, "project"));
|
|
144
|
+
let resourceConfiguration;
|
|
145
|
+
try {
|
|
146
|
+
resourceConfiguration = parseResourceConfiguration({
|
|
147
|
+
...(values.has("locale") ? { locale: required(values, "locale") } : {}),
|
|
148
|
+
...(values.has("orientation")
|
|
149
|
+
? { orientation: required(values, "orientation") }
|
|
150
|
+
: {}),
|
|
151
|
+
...(values.has("ui-mode") ? { uiMode: required(values, "ui-mode") } : {}),
|
|
152
|
+
...(values.has("api-level")
|
|
153
|
+
? { apiLevel: required(values, "api-level") }
|
|
154
|
+
: {}),
|
|
155
|
+
...(values.has("density")
|
|
156
|
+
? { density: required(values, "density") }
|
|
157
|
+
: {}),
|
|
158
|
+
...(values.has("smallest-width-dp")
|
|
159
|
+
? {
|
|
160
|
+
smallestWidthDp: required(values, "smallest-width-dp"),
|
|
161
|
+
}
|
|
162
|
+
: {}),
|
|
163
|
+
});
|
|
164
|
+
} catch (error) {
|
|
165
|
+
throw new CliUsageError(
|
|
166
|
+
error instanceof Error ? error.message : String(error),
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
const limits = {
|
|
170
|
+
maxCallDepth: values.has("max-call-depth")
|
|
171
|
+
? positiveInteger(required(values, "max-call-depth"), "max-call-depth")
|
|
172
|
+
: DEFAULT_ANALYSIS_LIMITS.maxCallDepth,
|
|
173
|
+
maxCallbackIterations: values.has("max-callback-iterations")
|
|
174
|
+
? positiveInteger(
|
|
175
|
+
required(values, "max-callback-iterations"),
|
|
176
|
+
"max-callback-iterations",
|
|
177
|
+
)
|
|
178
|
+
: DEFAULT_ANALYSIS_LIMITS.maxCallbackIterations,
|
|
179
|
+
maxGraphStates: values.has("max-graph-states")
|
|
180
|
+
? positiveInteger(
|
|
181
|
+
required(values, "max-graph-states"),
|
|
182
|
+
"max-graph-states",
|
|
183
|
+
)
|
|
184
|
+
: DEFAULT_ANALYSIS_LIMITS.maxGraphStates,
|
|
185
|
+
};
|
|
186
|
+
const explicitCaseId = values.has("case-id")
|
|
187
|
+
? required(values, "case-id")
|
|
188
|
+
: undefined;
|
|
189
|
+
if (explicitCaseId !== undefined && !isValidCaseId(explicitCaseId)) {
|
|
190
|
+
throw new CliUsageError(
|
|
191
|
+
"--case-id must start with a lowercase ASCII letter or digit and " +
|
|
192
|
+
"contain only lowercase ASCII letters, digits, '.', '_', or '-'",
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
const caseId = explicitCaseId ?? deriveCaseId(basename(projectRoot));
|
|
196
|
+
const needsGeneratedRunId = !values.has("output") && !values.has("run-id");
|
|
197
|
+
const runId = values.has("run-id")
|
|
198
|
+
? required(values, "run-id")
|
|
199
|
+
: needsGeneratedRunId
|
|
200
|
+
? generatedRunId()
|
|
201
|
+
: undefined;
|
|
202
|
+
const outputExplicit = values.has("output");
|
|
203
|
+
const outputDirectory = outputExplicit
|
|
204
|
+
? resolve(required(values, "output"))
|
|
205
|
+
: join(
|
|
206
|
+
PACKAGE_ROOT,
|
|
207
|
+
".build",
|
|
208
|
+
"runs",
|
|
209
|
+
safePathSegment(caseId, "case"),
|
|
210
|
+
safePathSegment(runId ?? generatedRunId(), "run"),
|
|
211
|
+
);
|
|
212
|
+
const gradleTimeoutMs = values.has("gradle-timeout-ms")
|
|
213
|
+
? positiveInteger(
|
|
214
|
+
required(values, "gradle-timeout-ms"),
|
|
215
|
+
"gradle-timeout-ms",
|
|
216
|
+
)
|
|
217
|
+
: undefined;
|
|
218
|
+
return {
|
|
219
|
+
options: {
|
|
220
|
+
projectRoot,
|
|
221
|
+
outputDirectory,
|
|
222
|
+
resourceConfiguration,
|
|
223
|
+
limits,
|
|
224
|
+
...(values.has("module")
|
|
225
|
+
? { applicationModulePath: required(values, "module") }
|
|
226
|
+
: {}),
|
|
227
|
+
...(values.has("variant")
|
|
228
|
+
? { variantName: required(values, "variant") }
|
|
229
|
+
: {}),
|
|
230
|
+
caseId,
|
|
231
|
+
...(runId === undefined ? {} : { runId }),
|
|
232
|
+
...(values.has("init-script")
|
|
233
|
+
? { initScriptPath: resolve(required(values, "init-script")) }
|
|
234
|
+
: {}),
|
|
235
|
+
...(values.has("analyzer-project")
|
|
236
|
+
? {
|
|
237
|
+
analyzerProjectRoot: resolve(required(values, "analyzer-project")),
|
|
238
|
+
}
|
|
239
|
+
: {}),
|
|
240
|
+
...(values.has("analyzer-artifact")
|
|
241
|
+
? { analyzerArtifactPath: required(values, "analyzer-artifact") }
|
|
242
|
+
: {}),
|
|
243
|
+
...(gradleTimeoutMs === undefined
|
|
244
|
+
? {}
|
|
245
|
+
: {
|
|
246
|
+
projectGradle: { timeoutMs: gradleTimeoutMs },
|
|
247
|
+
analyzerGradle: { timeoutMs: gradleTimeoutMs },
|
|
248
|
+
}),
|
|
249
|
+
},
|
|
250
|
+
outputExplicit,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const defaultIo = {
|
|
254
|
+
stdout: (text) => process.stdout.write(text),
|
|
255
|
+
stderr: (text) => process.stderr.write(text),
|
|
256
|
+
};
|
|
257
|
+
const defaultRuntime = {
|
|
258
|
+
environment: process.env,
|
|
259
|
+
};
|
|
260
|
+
function durationText(elapsedMs) {
|
|
261
|
+
return elapsedMs < 1_000
|
|
262
|
+
? `${elapsedMs} ms`
|
|
263
|
+
: `${(elapsedMs / 1_000).toFixed(1)} s`;
|
|
264
|
+
}
|
|
265
|
+
function progressLine(event) {
|
|
266
|
+
const prefix = `[Stage ${event.index}/${event.total}] ${event.label}`;
|
|
267
|
+
if (event.status === "started") {
|
|
268
|
+
return `${prefix}...\n`;
|
|
269
|
+
}
|
|
270
|
+
return `${prefix} ${event.status} in ${durationText(event.elapsedMs ?? 0)}.\n`;
|
|
271
|
+
}
|
|
272
|
+
function streamedGradleOptions(scope, options, io, runtimeEnvironment) {
|
|
273
|
+
const environment = {
|
|
274
|
+
...runtimeEnvironment,
|
|
275
|
+
...options?.environment,
|
|
276
|
+
};
|
|
277
|
+
const prefix = scope === "project" ? "REQGEN_PROJECT" : "REQGEN_ANALYZER";
|
|
278
|
+
const scopedExecutable = environment[`${prefix}_GRADLE_EXECUTABLE`];
|
|
279
|
+
const scopedJavaHome = environment[`${prefix}_JAVA_HOME`];
|
|
280
|
+
const executable =
|
|
281
|
+
options?.executable ??
|
|
282
|
+
scopedExecutable ??
|
|
283
|
+
environment.REQGEN_GRADLE_EXECUTABLE;
|
|
284
|
+
environment.REQGEN_GRADLE_SCOPE = scope;
|
|
285
|
+
if (scopedJavaHome !== undefined && scopedJavaHome.trim().length > 0) {
|
|
286
|
+
environment.JAVA_HOME = scopedJavaHome;
|
|
287
|
+
}
|
|
288
|
+
const existingStdout = options?.onStdout;
|
|
289
|
+
const existingStderr = options?.onStderr;
|
|
290
|
+
return {
|
|
291
|
+
...options,
|
|
292
|
+
...(executable === undefined ? {} : { executable }),
|
|
293
|
+
environment,
|
|
294
|
+
onStdout: (chunk) => {
|
|
295
|
+
existingStdout?.(chunk);
|
|
296
|
+
io.stdout(chunk);
|
|
297
|
+
},
|
|
298
|
+
onStderr: (chunk) => {
|
|
299
|
+
existingStderr?.(chunk);
|
|
300
|
+
io.stderr(chunk);
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
export async function runCli(
|
|
305
|
+
argv,
|
|
306
|
+
dependencies = { runStage1 },
|
|
307
|
+
io = defaultIo,
|
|
308
|
+
runtime = defaultRuntime,
|
|
309
|
+
) {
|
|
310
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
311
|
+
io.stdout(CLI_USAGE);
|
|
312
|
+
return 0;
|
|
313
|
+
}
|
|
314
|
+
const [command, ...rawArgs] = argv;
|
|
315
|
+
if (command !== "stage1") {
|
|
316
|
+
io.stderr(
|
|
317
|
+
`${command ? `Unknown command: ${command}\n\n` : ""}${CLI_USAGE}`,
|
|
318
|
+
);
|
|
319
|
+
return 2;
|
|
320
|
+
}
|
|
321
|
+
const args = rawArgs[0] === "--" ? rawArgs.slice(1) : rawArgs;
|
|
322
|
+
let parsed;
|
|
323
|
+
try {
|
|
324
|
+
parsed = parseStage1Arguments(args);
|
|
325
|
+
} catch (error) {
|
|
326
|
+
io.stderr(
|
|
327
|
+
`${error instanceof Error ? error.message : String(error)}\n\n${CLI_USAGE}`,
|
|
328
|
+
);
|
|
329
|
+
return 2;
|
|
330
|
+
}
|
|
331
|
+
const { options } = parsed;
|
|
332
|
+
// Guard: refuse to overwrite an existing output directory when the user
|
|
333
|
+
// explicitly set --output. Auto-generated default paths already embed a
|
|
334
|
+
// unique timestamp-based run-id and are never guarded.
|
|
335
|
+
if (parsed.outputExplicit) {
|
|
336
|
+
try {
|
|
337
|
+
await ensureOutputDirectoryEmpty(options.outputDirectory);
|
|
338
|
+
} catch (error) {
|
|
339
|
+
if (error instanceof OutputDirectoryNotEmptyError) {
|
|
340
|
+
io.stderr(error.message + "\n");
|
|
341
|
+
return 2;
|
|
342
|
+
}
|
|
343
|
+
throw error;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
try {
|
|
347
|
+
const existingProgress = options.onProgress;
|
|
348
|
+
const result = await dependencies.runStage1({
|
|
349
|
+
...options,
|
|
350
|
+
projectGradle: streamedGradleOptions(
|
|
351
|
+
"project",
|
|
352
|
+
options.projectGradle,
|
|
353
|
+
io,
|
|
354
|
+
runtime.environment,
|
|
355
|
+
),
|
|
356
|
+
analyzerGradle: streamedGradleOptions(
|
|
357
|
+
"analyzer",
|
|
358
|
+
options.analyzerGradle,
|
|
359
|
+
io,
|
|
360
|
+
runtime.environment,
|
|
361
|
+
),
|
|
362
|
+
onProgress: (event) => {
|
|
363
|
+
existingProgress?.(event);
|
|
364
|
+
io.stderr(progressLine(event));
|
|
365
|
+
},
|
|
366
|
+
});
|
|
367
|
+
if (result.report.status === "succeeded") {
|
|
368
|
+
const publication = result.report.publishable
|
|
369
|
+
? "publishable; deterministic REQ draft generated"
|
|
370
|
+
: "semantic quality incomplete; deterministic REQ draft generated for review";
|
|
371
|
+
io.stdout(
|
|
372
|
+
`Stage 1 succeeded (${publication}): ${result.outputDirectory}\n` +
|
|
373
|
+
`Target: ${result.report.target.applicationModule}/` +
|
|
374
|
+
`${result.report.target.buildVariant}\n` +
|
|
375
|
+
`Unresolved: ${result.coverage.counts.unresolved}\n` +
|
|
376
|
+
`Draft: ${join(result.outputDirectory, "generation", "req.draft.md")}\n`,
|
|
377
|
+
);
|
|
378
|
+
return 0;
|
|
379
|
+
}
|
|
380
|
+
io.stderr(
|
|
381
|
+
`Stage 1 failed; partial facts are not publishable: ${result.outputDirectory}\n${result.report.diagnostics
|
|
382
|
+
.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`)
|
|
383
|
+
.join("\n")}\n`,
|
|
384
|
+
);
|
|
385
|
+
return 1;
|
|
386
|
+
} catch (error) {
|
|
387
|
+
io.stderr(
|
|
388
|
+
`Unable to write the Stage 1 failure report: ${error instanceof Error ? error.message : String(error)}\n`,
|
|
389
|
+
);
|
|
390
|
+
return 1;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
const isDirectExecution =
|
|
394
|
+
process.argv[1] !== undefined &&
|
|
395
|
+
resolve(process.argv[1]) === resolve(fileURLToPath(import.meta.url));
|
|
396
|
+
if (isDirectExecution) {
|
|
397
|
+
process.exitCode = await runCli(process.argv.slice(2));
|
|
398
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const semanticIdentityKinds = [
|
|
2
|
+
"application",
|
|
3
|
+
"variant",
|
|
4
|
+
"component",
|
|
5
|
+
"symbol",
|
|
6
|
+
"resource",
|
|
7
|
+
"route",
|
|
8
|
+
"container",
|
|
9
|
+
"control",
|
|
10
|
+
"callback",
|
|
11
|
+
"state",
|
|
12
|
+
"entry",
|
|
13
|
+
"external-target",
|
|
14
|
+
"semantic-position",
|
|
15
|
+
"semantic-key",
|
|
16
|
+
];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const DIAGNOSTIC_CONTRACT_VERSION = "1.0.0";
|
|
2
|
+
export function defineDiagnostic(input) {
|
|
3
|
+
return {
|
|
4
|
+
...input,
|
|
5
|
+
contractVersion: DIAGNOSTIC_CONTRACT_VERSION,
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function diagnosticFailsRun(diagnostic) {
|
|
9
|
+
return diagnostic.disposition === "fail-run";
|
|
10
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const GAP_AUDIT_CONTRACT_VERSION = "1.0.0";
|
|
2
|
+
export const gapAuditCategoryIds = [
|
|
3
|
+
"manifest-components",
|
|
4
|
+
"manifest-entries",
|
|
5
|
+
"actionable-xml-controls",
|
|
6
|
+
"resolved-listener-interactions",
|
|
7
|
+
"resolved-compose-controls",
|
|
8
|
+
"resolved-compose-surfaces",
|
|
9
|
+
"resolved-compose-ui",
|
|
10
|
+
"resolved-navigation-calls",
|
|
11
|
+
"resolved-pager-tab-calls",
|
|
12
|
+
"resolved-async-calls",
|
|
13
|
+
"other-resolved-calls",
|
|
14
|
+
];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./artifact.js";
|
|
2
|
+
export * from "./area-graph.js";
|
|
3
|
+
export * from "./common.js";
|
|
4
|
+
export * from "./diagnostic.js";
|
|
5
|
+
export * from "./gap-audit.js";
|
|
6
|
+
export * from "./name-traceability.js";
|
|
7
|
+
export * from "./raw-fact.js";
|
|
8
|
+
export * from "./req-model.js";
|
|
9
|
+
export * from "./run.js";
|
|
10
|
+
export * from "./semantic-completeness.js";
|
|
11
|
+
export * from "./source-facts.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const NAME_TRACEABILITY_CONTRACT_VERSION = "1.0.0";
|
|
2
|
+
export function nameTraceKey(kind, ref) {
|
|
3
|
+
return `${kind}:${ref}`;
|
|
4
|
+
}
|
|
5
|
+
export function buildNameTraceLookup(entries) {
|
|
6
|
+
return new Map(
|
|
7
|
+
entries.map((entry) => [
|
|
8
|
+
nameTraceKey(entry.entityKind, entry.entityRef),
|
|
9
|
+
entry,
|
|
10
|
+
]),
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Strategies that read real, user-visible UI text — never a translation
|
|
15
|
+
* candidate (agent-render) and never a code Symbol (dump). Anything else
|
|
16
|
+
* (component-identifier, resource-id, symbol, icon-resource,
|
|
17
|
+
* dynamic-list-item) is code/structural in origin and may happen to be
|
|
18
|
+
* English purely because the identifier is.
|
|
19
|
+
*/
|
|
20
|
+
export const LITERAL_NAME_STRATEGIES = new Set([
|
|
21
|
+
"visible-title",
|
|
22
|
+
"visible-text",
|
|
23
|
+
"content-description",
|
|
24
|
+
"associated-label",
|
|
25
|
+
"variant-display-name",
|
|
26
|
+
]);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const RAW_FACT_CONTRACT_VERSION = "1.0.0";
|
|
2
|
+
export const rawFactKinds = [
|
|
3
|
+
"component",
|
|
4
|
+
"component-variant",
|
|
5
|
+
"entry-point",
|
|
6
|
+
"resource-value",
|
|
7
|
+
"ui-element",
|
|
8
|
+
"ui-property",
|
|
9
|
+
"container-binding",
|
|
10
|
+
"callback",
|
|
11
|
+
"interaction-binding",
|
|
12
|
+
"callback-flow",
|
|
13
|
+
"condition",
|
|
14
|
+
"behavior-effect",
|
|
15
|
+
"navigation-target",
|
|
16
|
+
];
|
|
17
|
+
function assertNonBlank(value, field) {
|
|
18
|
+
if (value.trim().length === 0) {
|
|
19
|
+
throw new Error(`${field} must not be blank`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function defineRawFact(input) {
|
|
23
|
+
input.identity.forEach((part, index) =>
|
|
24
|
+
assertNonBlank(part.value, `identity[${index}].value`),
|
|
25
|
+
);
|
|
26
|
+
input.evidence.forEach((location, index) => {
|
|
27
|
+
assertNonBlank(location.path, `evidence[${index}].path`);
|
|
28
|
+
assertNonBlank(location.anchor, `evidence[${index}].anchor`);
|
|
29
|
+
if (
|
|
30
|
+
location.range.startLine < 1 ||
|
|
31
|
+
location.range.endLine < location.range.startLine
|
|
32
|
+
) {
|
|
33
|
+
throw new Error(`evidence[${index}].range is invalid`);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
...input,
|
|
38
|
+
contractVersion: RAW_FACT_CONTRACT_VERSION,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const RUN_CONTRACT_VERSION = "1.0.0";
|
|
2
|
+
export const STAGE1_COVERAGE_VERSION = "1.0.0";
|
|
3
|
+
export const stage1CoverageStageNames = [
|
|
4
|
+
"projectModel",
|
|
5
|
+
"androidXml",
|
|
6
|
+
"jvm",
|
|
7
|
+
"normalize",
|
|
8
|
+
"graph",
|
|
9
|
+
"reqModel",
|
|
10
|
+
];
|
|
11
|
+
export function defineRunRequest(input) {
|
|
12
|
+
return {
|
|
13
|
+
...input,
|
|
14
|
+
contractVersion: RUN_CONTRACT_VERSION,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function runCanPublish(report) {
|
|
18
|
+
return report.status === "succeeded" && report.publishable;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
2
|
+
/**
|
|
3
|
+
* Fail-fast guard: when --output is explicitly provided, refuse to write into
|
|
4
|
+
* a directory that already contains results — this prevents accidentally
|
|
5
|
+
* overwriting a previous run's output. The check only applies when the user
|
|
6
|
+
* explicitly sets --output; auto-generated default paths are never guarded
|
|
7
|
+
* because they already include a unique run-id timestamp.
|
|
8
|
+
*
|
|
9
|
+
* Snapshot mode (stage2 --snapshot) is exempt: it must be able to read
|
|
10
|
+
* existing output.json files from a prior rendering pass.
|
|
11
|
+
*/
|
|
12
|
+
export class OutputDirectoryNotEmptyError extends Error {
|
|
13
|
+
constructor(outputDir) {
|
|
14
|
+
super(
|
|
15
|
+
`Output directory is not empty: ${outputDir}\n` +
|
|
16
|
+
`Refusing to overwrite existing results. Either:\n` +
|
|
17
|
+
` - Choose a different --output path, or\n` +
|
|
18
|
+
` - Delete / clear the directory first, then re-run.`,
|
|
19
|
+
);
|
|
20
|
+
this.name = "OutputDirectoryNotEmptyError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Throws {@link OutputDirectoryNotEmptyError} if `outputDir` exists and
|
|
25
|
+
* contains at least one entry (file or subdirectory). Does nothing when the
|
|
26
|
+
* directory does not exist yet or is empty.
|
|
27
|
+
*/
|
|
28
|
+
export async function ensureOutputDirectoryEmpty(outputDir) {
|
|
29
|
+
let entries;
|
|
30
|
+
try {
|
|
31
|
+
entries = await readdir(outputDir);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
// Directory doesn't exist — that's fine, it'll be created downstream.
|
|
34
|
+
const code = error?.code;
|
|
35
|
+
if (code === "ENOENT" || code === "ENOTDIR") return;
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
if (entries.length > 0) {
|
|
39
|
+
throw new OutputDirectoryNotEmptyError(outputDir);
|
|
40
|
+
}
|
|
41
|
+
}
|