android2harmony 0.1.7 → 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 +2 -2
- 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 @@
|
|
|
1
|
+
export * from "./dump.js";
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import {
|
|
5
|
+
dumpAreaGraph,
|
|
6
|
+
dumpDiagnostics,
|
|
7
|
+
dumpGapAudit,
|
|
8
|
+
dumpReqModel,
|
|
9
|
+
} from "./dump/index.js";
|
|
10
|
+
import { sha256Text } from "./pipeline/output.js";
|
|
11
|
+
export const DUMP_USAGE = `Usage:
|
|
12
|
+
pnpm dump -- --input <stage1-output-directory>
|
|
13
|
+
|
|
14
|
+
Reads the Stage 1 JSON artifacts in <stage1-output-directory> (schema is a
|
|
15
|
+
stable Stage 1 -> Stage 2 contract, see ADR-0004) and writes a human-readable
|
|
16
|
+
recursive tree dump next to each one this tool knows how to render:
|
|
17
|
+
area-graph.json -> area-graph.dump.txt
|
|
18
|
+
req-model.json -> req-model.dump.txt
|
|
19
|
+
gap-audit.json -> gap-audit.dump.txt
|
|
20
|
+
diagnostics.json -> diagnostics.dump.txt
|
|
21
|
+
|
|
22
|
+
Every dumped JSON is verified against the sha256 recorded for it in
|
|
23
|
+
run-report.json before being rendered; a missing run-report.json or a hash
|
|
24
|
+
mismatch fails the run instead of dumping unverified data (ADR-0004). An
|
|
25
|
+
artifact run-report.json does not record (for example area-graph.json on a
|
|
26
|
+
run that failed before the graph stage) is silently skipped, not an error.
|
|
27
|
+
`;
|
|
28
|
+
export class DumpCliError extends Error {
|
|
29
|
+
constructor(message) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = "DumpCliError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const DUMPABLE_ARTIFACTS = [
|
|
35
|
+
{
|
|
36
|
+
kind: "area-graph",
|
|
37
|
+
filename: "area-graph.json",
|
|
38
|
+
dumpFilename: "area-graph.dump.txt",
|
|
39
|
+
dump: (text, _areaGraph, sourceFacts, nameTraceability) =>
|
|
40
|
+
dumpAreaGraph(JSON.parse(text), sourceFacts, nameTraceability),
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
kind: "req-model",
|
|
44
|
+
filename: "req-model.json",
|
|
45
|
+
dumpFilename: "req-model.dump.txt",
|
|
46
|
+
dump: (text, areaGraph, sourceFacts, nameTraceability) =>
|
|
47
|
+
dumpReqModel(JSON.parse(text), areaGraph, sourceFacts, nameTraceability),
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
kind: "gap-audit",
|
|
51
|
+
filename: "gap-audit.json",
|
|
52
|
+
dumpFilename: "gap-audit.dump.txt",
|
|
53
|
+
dump: (text, _areaGraph, sourceFacts) =>
|
|
54
|
+
dumpGapAudit(JSON.parse(text), sourceFacts),
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
kind: "diagnostics",
|
|
58
|
+
filename: "diagnostics.json",
|
|
59
|
+
dumpFilename: "diagnostics.dump.txt",
|
|
60
|
+
dump: (text) => dumpDiagnostics(JSON.parse(text)),
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
function isRecord(value) {
|
|
64
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
65
|
+
}
|
|
66
|
+
async function readRunReport(inputDirectory) {
|
|
67
|
+
let text;
|
|
68
|
+
try {
|
|
69
|
+
text = await readFile(join(inputDirectory, "run-report.json"), "utf8");
|
|
70
|
+
} catch (error) {
|
|
71
|
+
throw new DumpCliError(
|
|
72
|
+
`${inputDirectory} does not contain run-report.json; dump requires a ` +
|
|
73
|
+
"Stage 1 output directory so its JSON artifacts can be hash-verified " +
|
|
74
|
+
"(ADR-0004).",
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
let value;
|
|
78
|
+
try {
|
|
79
|
+
value = JSON.parse(text);
|
|
80
|
+
} catch {
|
|
81
|
+
throw new DumpCliError("run-report.json is not valid JSON");
|
|
82
|
+
}
|
|
83
|
+
if (!isRecord(value) || !Array.isArray(value.artifacts)) {
|
|
84
|
+
throw new DumpCliError("run-report.json has an unsupported envelope");
|
|
85
|
+
}
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
async function writeDumpFile(directory, filename, content) {
|
|
89
|
+
const root = resolve(directory);
|
|
90
|
+
await mkdir(root, { recursive: true });
|
|
91
|
+
const target = join(root, filename);
|
|
92
|
+
const normalized = content.endsWith("\n") ? content : `${content}\n`;
|
|
93
|
+
const temporary = join(root, `.${filename}.${process.pid}.${Date.now()}.tmp`);
|
|
94
|
+
try {
|
|
95
|
+
await writeFile(temporary, normalized, { encoding: "utf8", flag: "wx" });
|
|
96
|
+
await rename(temporary, target);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
await rm(temporary, { force: true });
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const defaultIo = {
|
|
103
|
+
stdout: (text) => process.stdout.write(text),
|
|
104
|
+
stderr: (text) => process.stderr.write(text),
|
|
105
|
+
};
|
|
106
|
+
function parseDumpArguments(argv) {
|
|
107
|
+
const args = argv[0] === "--" ? argv.slice(1) : argv;
|
|
108
|
+
const values = new Map();
|
|
109
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
110
|
+
const token = args[index];
|
|
111
|
+
if (!token.startsWith("--")) {
|
|
112
|
+
throw new DumpCliError(`Unexpected argument: ${token}`);
|
|
113
|
+
}
|
|
114
|
+
const name = token.slice(2);
|
|
115
|
+
if (name !== "input") {
|
|
116
|
+
throw new DumpCliError(`Unknown option: --${name}`);
|
|
117
|
+
}
|
|
118
|
+
const value = args[index + 1];
|
|
119
|
+
if (value === undefined || value.startsWith("--")) {
|
|
120
|
+
throw new DumpCliError(`Option requires a value: --${name}`);
|
|
121
|
+
}
|
|
122
|
+
values.set(name, value);
|
|
123
|
+
index += 1;
|
|
124
|
+
}
|
|
125
|
+
const input = values.get("input");
|
|
126
|
+
if (input === undefined) {
|
|
127
|
+
throw new DumpCliError("Missing required option: --input");
|
|
128
|
+
}
|
|
129
|
+
return { input: resolve(input) };
|
|
130
|
+
}
|
|
131
|
+
/** Reads+hash-verifies one artifact recorded in run-report.json; returns
|
|
132
|
+
* undefined only when that run never recorded it (ADR-0004 skip case). */
|
|
133
|
+
async function readVerifiedArtifact(inputDirectory, report, kind, filename) {
|
|
134
|
+
const recorded = report.artifacts.find(
|
|
135
|
+
(candidate) =>
|
|
136
|
+
candidate.kind === kind && candidate.relativePath === filename,
|
|
137
|
+
);
|
|
138
|
+
if (recorded === undefined) return undefined;
|
|
139
|
+
let text;
|
|
140
|
+
try {
|
|
141
|
+
text = await readFile(join(inputDirectory, filename), "utf8");
|
|
142
|
+
} catch (error) {
|
|
143
|
+
throw new DumpCliError(
|
|
144
|
+
`run-report.json records ${filename} but it is missing from ${inputDirectory}`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
if (recorded.sha256 !== sha256Text(text)) {
|
|
148
|
+
throw new DumpCliError(
|
|
149
|
+
`${filename} does not match the artifact hash recorded in ` +
|
|
150
|
+
"run-report.json; refusing to dump unverified data (ADR-0004).",
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
return text;
|
|
154
|
+
}
|
|
155
|
+
/** Dumps every Stage 1 JSON artifact this tool renders, trusting only what
|
|
156
|
+
* run-report.json's `artifacts[]` manifest actually recorded: an artifact it
|
|
157
|
+
* doesn't mention is skipped (that Stage 1 run never produced it), an
|
|
158
|
+
* artifact it mentions but whose file is missing or hash-mismatched fails
|
|
159
|
+
* the run (ADR-0004 forbids dumping an unverified same-named file). */
|
|
160
|
+
export async function runDump(inputDirectory) {
|
|
161
|
+
const report = await readRunReport(inputDirectory);
|
|
162
|
+
const dumped = [];
|
|
163
|
+
// area-graph.dump.txt and req-model.dump.txt additionally cross-reference
|
|
164
|
+
// area-graph.json, source-facts.json, and generation/name-traceability.json
|
|
165
|
+
// (same ADR-0004 hash verification) when that run recorded them, so they
|
|
166
|
+
// can render each entity's Symbol and @Anchor (DEVELOPER.md) — req-model
|
|
167
|
+
// resolves Area/Control/Action identity from the exact same graph objects
|
|
168
|
+
// area-graph's own dump uses (see dump/dump.ts); name-traceability's ranked
|
|
169
|
+
// identity decision is preferred over the source-facts heuristic for
|
|
170
|
+
// Area/Control when present.
|
|
171
|
+
const areaGraphText = await readVerifiedArtifact(
|
|
172
|
+
inputDirectory,
|
|
173
|
+
report,
|
|
174
|
+
"area-graph",
|
|
175
|
+
"area-graph.json",
|
|
176
|
+
);
|
|
177
|
+
const areaGraph =
|
|
178
|
+
areaGraphText !== undefined ? JSON.parse(areaGraphText) : undefined;
|
|
179
|
+
const sourceFactsText = await readVerifiedArtifact(
|
|
180
|
+
inputDirectory,
|
|
181
|
+
report,
|
|
182
|
+
"source-facts",
|
|
183
|
+
"source-facts.json",
|
|
184
|
+
);
|
|
185
|
+
const sourceFacts =
|
|
186
|
+
sourceFactsText !== undefined ? JSON.parse(sourceFactsText) : undefined;
|
|
187
|
+
const nameTraceabilityText = await readVerifiedArtifact(
|
|
188
|
+
inputDirectory,
|
|
189
|
+
report,
|
|
190
|
+
"name-traceability",
|
|
191
|
+
"generation/name-traceability.json",
|
|
192
|
+
);
|
|
193
|
+
const nameTraceability =
|
|
194
|
+
nameTraceabilityText !== undefined
|
|
195
|
+
? JSON.parse(nameTraceabilityText)
|
|
196
|
+
: undefined;
|
|
197
|
+
for (const artifact of DUMPABLE_ARTIFACTS) {
|
|
198
|
+
const text = await readVerifiedArtifact(
|
|
199
|
+
inputDirectory,
|
|
200
|
+
report,
|
|
201
|
+
artifact.kind,
|
|
202
|
+
artifact.filename,
|
|
203
|
+
);
|
|
204
|
+
if (text === undefined) continue;
|
|
205
|
+
await writeDumpFile(
|
|
206
|
+
inputDirectory,
|
|
207
|
+
artifact.dumpFilename,
|
|
208
|
+
artifact.dump(text, areaGraph, sourceFacts, nameTraceability),
|
|
209
|
+
);
|
|
210
|
+
dumped.push(artifact.dumpFilename);
|
|
211
|
+
}
|
|
212
|
+
return dumped;
|
|
213
|
+
}
|
|
214
|
+
export async function runDumpCli(argv, io = defaultIo) {
|
|
215
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
216
|
+
io.stdout(DUMP_USAGE);
|
|
217
|
+
return 0;
|
|
218
|
+
}
|
|
219
|
+
let options;
|
|
220
|
+
try {
|
|
221
|
+
options = parseDumpArguments(argv);
|
|
222
|
+
} catch (error) {
|
|
223
|
+
io.stderr(
|
|
224
|
+
`${error instanceof Error ? error.message : String(error)}\n\n${DUMP_USAGE}`,
|
|
225
|
+
);
|
|
226
|
+
return 2;
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
const dumped = await runDump(options.input);
|
|
230
|
+
if (dumped.length === 0) {
|
|
231
|
+
io.stderr(
|
|
232
|
+
"No dumpable Stage 1 JSON artifacts (area-graph.json, req-model.json, " +
|
|
233
|
+
`gap-audit.json, diagnostics.json) were recorded in ${options.input}\n`,
|
|
234
|
+
);
|
|
235
|
+
return 1;
|
|
236
|
+
}
|
|
237
|
+
for (const filename of dumped) {
|
|
238
|
+
io.stdout(`${join(options.input, filename)}\n`);
|
|
239
|
+
}
|
|
240
|
+
return 0;
|
|
241
|
+
} catch (error) {
|
|
242
|
+
io.stderr(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
243
|
+
return 1;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const isDirectExecution =
|
|
247
|
+
process.argv[1] !== undefined &&
|
|
248
|
+
resolve(process.argv[1]) === resolve(fileURLToPath(import.meta.url));
|
|
249
|
+
if (isDirectExecution) {
|
|
250
|
+
process.exitCode = await runDumpCli(process.argv.slice(2));
|
|
251
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NAME_TRACEABILITY_FILENAME,
|
|
3
|
+
buildNameTraceability,
|
|
4
|
+
} from "../analysis/names/index.js";
|
|
5
|
+
import { writeJsonArtifact, writeTextArtifact } from "../pipeline/output.js";
|
|
6
|
+
import { buildQualityReport } from "./quality-report.js";
|
|
7
|
+
import { renderReqDraft, renderReqMarkdown } from "./render.js";
|
|
8
|
+
export const REQ_FILENAME = "req.draft.md";
|
|
9
|
+
export const QUALITY_REPORT_FILENAME = "quality-report.json";
|
|
10
|
+
/**
|
|
11
|
+
* Write the deterministic generation directory (Stage 1 only).
|
|
12
|
+
* Writes req.draft.md (deterministic markdown draft for human review).
|
|
13
|
+
* Stage 2 does NOT read this file — it recomputes from req-model + area-graph. */
|
|
14
|
+
export async function writeDeterministicGenerationArtifacts(
|
|
15
|
+
outputDirectory,
|
|
16
|
+
input,
|
|
17
|
+
) {
|
|
18
|
+
const reqText = renderReqDraft(input.reqModel, input.graph);
|
|
19
|
+
const nameTraceability = buildNameTraceability({
|
|
20
|
+
...input,
|
|
21
|
+
reqText,
|
|
22
|
+
});
|
|
23
|
+
const artifacts = [];
|
|
24
|
+
artifacts.push(
|
|
25
|
+
await writeTextArtifact(
|
|
26
|
+
outputDirectory,
|
|
27
|
+
REQ_FILENAME,
|
|
28
|
+
"req-text",
|
|
29
|
+
renderReqMarkdown(input.reqModel, input.graph),
|
|
30
|
+
),
|
|
31
|
+
);
|
|
32
|
+
artifacts.push(
|
|
33
|
+
await writeJsonArtifact(
|
|
34
|
+
outputDirectory,
|
|
35
|
+
QUALITY_REPORT_FILENAME,
|
|
36
|
+
"quality-report",
|
|
37
|
+
buildQualityReport(input.reqModel),
|
|
38
|
+
),
|
|
39
|
+
);
|
|
40
|
+
artifacts.push(
|
|
41
|
+
await writeJsonArtifact(
|
|
42
|
+
outputDirectory,
|
|
43
|
+
NAME_TRACEABILITY_FILENAME,
|
|
44
|
+
"name-traceability",
|
|
45
|
+
nameTraceability,
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
return { reqText, nameTraceability, artifacts };
|
|
49
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export {
|
|
2
|
+
QUALITY_REPORT_FILENAME,
|
|
3
|
+
REQ_FILENAME,
|
|
4
|
+
writeDeterministicGenerationArtifacts,
|
|
5
|
+
} from "./artifacts.js";
|
|
6
|
+
export { buildQualityReport } from "./quality-report.js";
|
|
7
|
+
export {
|
|
8
|
+
buildAreaContentTxt,
|
|
9
|
+
renderReqDraft,
|
|
10
|
+
renderReqMarkdown,
|
|
11
|
+
renderAllReqTxt,
|
|
12
|
+
renderReqTxtArea,
|
|
13
|
+
renderedPath,
|
|
14
|
+
resolvedName,
|
|
15
|
+
serializeReqMarkdown,
|
|
16
|
+
serializeReqTxtAreaContent,
|
|
17
|
+
} from "./render.js";
|
|
18
|
+
export { GENERATION_CONTRACT_VERSION } from "./types.js";
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { GENERATION_CONTRACT_VERSION } from "./types.js";
|
|
2
|
+
function increment(target, key) {
|
|
3
|
+
target.set(key, (target.get(key) ?? 0) + 1);
|
|
4
|
+
}
|
|
5
|
+
function normalizedMessage(value) {
|
|
6
|
+
return value.trim().replace(/\s+/gu, " ");
|
|
7
|
+
}
|
|
8
|
+
function featureHasUnknownEffect(feature, unresolvedById) {
|
|
9
|
+
const interactionEffects =
|
|
10
|
+
feature.interactions && feature.interactions.length > 0
|
|
11
|
+
? feature.interactions.map((interaction) => interaction.effects)
|
|
12
|
+
: [feature.effects];
|
|
13
|
+
if (
|
|
14
|
+
interactionEffects.some(
|
|
15
|
+
(effects) =>
|
|
16
|
+
effects.length === 0 ||
|
|
17
|
+
effects.some((effect) => effect.kind === "unknown"),
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
return true;
|
|
21
|
+
return feature.unresolvedRefs.some((ref) => {
|
|
22
|
+
const unresolved = unresolvedById.get(ref);
|
|
23
|
+
return unresolved?.impact.includes("req-feature-effect") === true;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export function buildQualityReport(reqModel) {
|
|
27
|
+
const canonicalPathStatus = {
|
|
28
|
+
resolved: 0,
|
|
29
|
+
unreachable: 0,
|
|
30
|
+
unresolved: 0,
|
|
31
|
+
};
|
|
32
|
+
let unknownAreaNames = 0;
|
|
33
|
+
let areasWithUnresolved = 0;
|
|
34
|
+
let featureCount = 0;
|
|
35
|
+
let unknownFeatureNames = 0;
|
|
36
|
+
let unknownFeatureEffects = 0;
|
|
37
|
+
let featuresWithUnresolved = 0;
|
|
38
|
+
const unresolvedById = new Map(
|
|
39
|
+
reqModel.unresolved.map((item) => [item.id, item]),
|
|
40
|
+
);
|
|
41
|
+
for (const area of reqModel.areas) {
|
|
42
|
+
canonicalPathStatus[area.canonicalPath.status] += 1;
|
|
43
|
+
if (area.displayName.status === "unresolved") unknownAreaNames += 1;
|
|
44
|
+
if (area.unresolvedRefs.length > 0) areasWithUnresolved += 1;
|
|
45
|
+
for (const feature of area.features) {
|
|
46
|
+
featureCount += 1;
|
|
47
|
+
if (feature.displayName.status === "unresolved") {
|
|
48
|
+
unknownFeatureNames += 1;
|
|
49
|
+
}
|
|
50
|
+
if (featureHasUnknownEffect(feature, unresolvedById)) {
|
|
51
|
+
unknownFeatureEffects += 1;
|
|
52
|
+
}
|
|
53
|
+
if (feature.unresolvedRefs.length > 0) {
|
|
54
|
+
featuresWithUnresolved += 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const reasonCounts = new Map();
|
|
59
|
+
const impactCounts = new Map();
|
|
60
|
+
for (const unresolved of reqModel.unresolved) {
|
|
61
|
+
increment(reasonCounts, unresolved.reasonCode);
|
|
62
|
+
for (const impact of new Set(unresolved.impact)) {
|
|
63
|
+
increment(impactCounts, impact);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const limitationMessages = new Map();
|
|
67
|
+
let criticalLimitations = 0;
|
|
68
|
+
const limitations = reqModel.limitations ?? [];
|
|
69
|
+
for (const limitation of limitations) {
|
|
70
|
+
if (limitation.critical) criticalLimitations += 1;
|
|
71
|
+
const message = normalizedMessage(limitation.message);
|
|
72
|
+
const counts = limitationMessages.get(message) ?? {
|
|
73
|
+
count: 0,
|
|
74
|
+
criticalCount: 0,
|
|
75
|
+
nonCriticalCount: 0,
|
|
76
|
+
};
|
|
77
|
+
counts.count += 1;
|
|
78
|
+
if (limitation.critical) {
|
|
79
|
+
counts.criticalCount += 1;
|
|
80
|
+
} else {
|
|
81
|
+
counts.nonCriticalCount += 1;
|
|
82
|
+
}
|
|
83
|
+
limitationMessages.set(message, counts);
|
|
84
|
+
}
|
|
85
|
+
const messages = [...limitationMessages]
|
|
86
|
+
.sort(([left], [right]) => left.localeCompare(right, "en"))
|
|
87
|
+
.map(([message, counts]) => ({ message, ...counts }));
|
|
88
|
+
return {
|
|
89
|
+
contractVersion: GENERATION_CONTRACT_VERSION,
|
|
90
|
+
artifactKind: "quality-report",
|
|
91
|
+
caseId: reqModel.caseId,
|
|
92
|
+
reqModelSchemaVersion: reqModel.schemaVersion,
|
|
93
|
+
completeness: reqModel.semanticCompleteness ?? "unknown",
|
|
94
|
+
analysisContext: reqModel.analysisContext,
|
|
95
|
+
areas: {
|
|
96
|
+
total: reqModel.areas.length,
|
|
97
|
+
unknownNameCount: unknownAreaNames,
|
|
98
|
+
withUnresolvedCount: areasWithUnresolved,
|
|
99
|
+
canonicalPathStatus,
|
|
100
|
+
},
|
|
101
|
+
features: {
|
|
102
|
+
total: featureCount,
|
|
103
|
+
unknownNameCount: unknownFeatureNames,
|
|
104
|
+
unknownEffectCount: unknownFeatureEffects,
|
|
105
|
+
withUnresolvedCount: featuresWithUnresolved,
|
|
106
|
+
},
|
|
107
|
+
unresolved: {
|
|
108
|
+
total: reqModel.unresolved.length,
|
|
109
|
+
byReason: [...reasonCounts]
|
|
110
|
+
.sort(([left], [right]) => left.localeCompare(right, "en"))
|
|
111
|
+
.map(([reasonCode, count]) => ({ reasonCode, count })),
|
|
112
|
+
byImpact: [...impactCounts]
|
|
113
|
+
.sort(([left], [right]) => left.localeCompare(right, "en"))
|
|
114
|
+
.map(([impact, count]) => ({ impact, count })),
|
|
115
|
+
},
|
|
116
|
+
limitations: {
|
|
117
|
+
total: limitations.length,
|
|
118
|
+
criticalCount: criticalLimitations,
|
|
119
|
+
nonCriticalCount: limitations.length - criticalLimitations,
|
|
120
|
+
uniqueMessageCount: messages.length,
|
|
121
|
+
duplicateMessageCount: limitations.length - messages.length,
|
|
122
|
+
messages,
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|