ultra11y 2.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +223 -0
  3. package/docker/Dockerfile +7 -0
  4. package/docker/package.json +9 -0
  5. package/docker/runner.mjs +23 -0
  6. package/package.json +73 -0
  7. package/scripts/bench.mjs +151 -0
  8. package/scripts/build-act-corpus.mjs +143 -0
  9. package/scripts/build-adjudication.mjs +503 -0
  10. package/scripts/build-pack-rgaa.mjs +397 -0
  11. package/scripts/build-standards.mjs +548 -0
  12. package/scripts/copy-bundle.mjs +39 -0
  13. package/scripts/import-pack.mjs +107 -0
  14. package/scripts/sync-engine.mjs +84 -0
  15. package/scripts/sync-version.mjs +43 -0
  16. package/scripts/ultra11y.mjs +52739 -0
  17. package/scripts/vendor/act-testcases.json +12297 -0
  18. package/scripts/vendor/rgaa/SOURCE.json +8 -0
  19. package/scripts/vendor/rgaa/criteres.json +4144 -0
  20. package/scripts/vendor/rgaa/glossaire.json +480 -0
  21. package/scripts/vendor/wcag-2.2-fr.json +82 -0
  22. package/scripts/vendor/wcag-2.2-sc-universe.json +950 -0
  23. package/scripts/vendor/wcag-2.2-sc.json +574 -0
  24. package/scripts/verify-rgaa-source.mjs +126 -0
  25. package/scripts/verify-skill-bundle.mjs +91 -0
  26. package/skills/review-a11y/SKILL.md +123 -0
  27. package/skills/review-a11y/scripts/ultra11y.mjs +52739 -0
  28. package/skills/ultra11y/SKILL.md +292 -0
  29. package/skills/ultra11y/references/act.md +163 -0
  30. package/skills/ultra11y/references/adjudication.md +599 -0
  31. package/skills/ultra11y/references/audit.md +100 -0
  32. package/skills/ultra11y/references/authoring.md +37 -0
  33. package/skills/ultra11y/references/automation.md +113 -0
  34. package/skills/ultra11y/references/correction.md +41 -0
  35. package/skills/ultra11y/references/criteria.md +129 -0
  36. package/skills/ultra11y/references/cross-file.md +82 -0
  37. package/skills/ultra11y/references/dynamic.md +152 -0
  38. package/skills/ultra11y/references/false-positives.md +81 -0
  39. package/skills/ultra11y/references/fix.md +46 -0
  40. package/skills/ultra11y/references/focus-and-logic.md +64 -0
  41. package/skills/ultra11y/references/forbidden-patterns.md +61 -0
  42. package/skills/ultra11y/references/forms-and-errors.md +147 -0
  43. package/skills/ultra11y/references/guidance.md +55 -0
  44. package/skills/ultra11y/references/judgment.md +90 -0
  45. package/skills/ultra11y/references/media-and-motion.md +116 -0
  46. package/skills/ultra11y/references/methodology.md +72 -0
  47. package/skills/ultra11y/references/naming.md +117 -0
  48. package/skills/ultra11y/references/orchestration.md +44 -0
  49. package/skills/ultra11y/references/packs.md +193 -0
  50. package/skills/ultra11y/references/prd.md +104 -0
  51. package/skills/ultra11y/references/rendered.md +110 -0
  52. package/skills/ultra11y/references/scale.md +49 -0
  53. package/skills/ultra11y/references/standards.md +97 -0
  54. package/skills/ultra11y/references/structure.md +138 -0
  55. package/skills/ultra11y/references/verify.md +88 -0
  56. package/skills/ultra11y/references/widgets.md +106 -0
  57. package/skills/ultra11y/scripts/ultra11y.mjs +52739 -0
  58. package/src/act.ts +441 -0
  59. package/src/adjudicate.ts +630 -0
  60. package/src/aria.ts +230 -0
  61. package/src/audit.ts +396 -0
  62. package/src/auditor.ts +399 -0
  63. package/src/autofill.ts +102 -0
  64. package/src/axe-map.ts +294 -0
  65. package/src/baseline.ts +75 -0
  66. package/src/capture.ts +182 -0
  67. package/src/check.ts +243 -0
  68. package/src/cli.ts +1927 -0
  69. package/src/color.ts +102 -0
  70. package/src/config.ts +182 -0
  71. package/src/crawl.ts +75 -0
  72. package/src/criteria.ts +183 -0
  73. package/src/data/adjudication.json +770 -0
  74. package/src/data/guidance/rgaa.json +2395 -0
  75. package/src/data/standards/rgaa.glossary.json +478 -0
  76. package/src/data/standards/rgaa.json +3454 -0
  77. package/src/data/wcag-universe.json +530 -0
  78. package/src/data/wcag.json +1178 -0
  79. package/src/discover.ts +203 -0
  80. package/src/fix/codemods.ts +76 -0
  81. package/src/fix/diff.ts +64 -0
  82. package/src/fix/edits.ts +126 -0
  83. package/src/fix.ts +215 -0
  84. package/src/gh.ts +214 -0
  85. package/src/glob.ts +206 -0
  86. package/src/graph/build.ts +114 -0
  87. package/src/graph/engine-resolve.ts +0 -0
  88. package/src/graph/graph.ts +126 -0
  89. package/src/graph/imports.ts +359 -0
  90. package/src/graph/resolve.ts +73 -0
  91. package/src/graph/tsconfig.ts +113 -0
  92. package/src/grounding.ts +119 -0
  93. package/src/guidance/index.ts +45 -0
  94. package/src/guidance/types.ts +36 -0
  95. package/src/init.ts +113 -0
  96. package/src/mcp/handlers.ts +388 -0
  97. package/src/mcp/http.ts +260 -0
  98. package/src/mcp/prompts.ts +183 -0
  99. package/src/mcp/protocol.ts +187 -0
  100. package/src/mcp/resources.ts +136 -0
  101. package/src/mcp/server.ts +228 -0
  102. package/src/mcp/stdio.ts +119 -0
  103. package/src/mcp/tools.ts +347 -0
  104. package/src/messages.ts +1011 -0
  105. package/src/name.ts +174 -0
  106. package/src/orchestrate-templates.ts +231 -0
  107. package/src/orchestrate.ts +186 -0
  108. package/src/output.ts +108 -0
  109. package/src/pack.ts +187 -0
  110. package/src/parse/html.ts +258 -0
  111. package/src/parse/jsx-ast.ts +67 -0
  112. package/src/parse/jsx-bridge.ts +247 -0
  113. package/src/parse/jsx.ts +19 -0
  114. package/src/parse/source.ts +75 -0
  115. package/src/prd.ts +406 -0
  116. package/src/project-lock.ts +42 -0
  117. package/src/render.ts +307 -0
  118. package/src/report.ts +399 -0
  119. package/src/rules/colors.ts +125 -0
  120. package/src/rules/cross-registry.ts +264 -0
  121. package/src/rules/cross-rule.ts +83 -0
  122. package/src/rules/forms.ts +590 -0
  123. package/src/rules/frames.ts +33 -0
  124. package/src/rules/headings.ts +227 -0
  125. package/src/rules/images.ts +200 -0
  126. package/src/rules/links.ts +193 -0
  127. package/src/rules/mandatory.ts +173 -0
  128. package/src/rules/multimedia.ts +77 -0
  129. package/src/rules/navigation.ts +190 -0
  130. package/src/rules/presentation.ts +75 -0
  131. package/src/rules/registry.ts +57 -0
  132. package/src/rules/rule.ts +122 -0
  133. package/src/rules/scripts-aria.ts +636 -0
  134. package/src/rules/tables.ts +264 -0
  135. package/src/rules/timing.ts +55 -0
  136. package/src/sample.ts +176 -0
  137. package/src/scan-local.ts +866 -0
  138. package/src/scan.ts +538 -0
  139. package/src/standards/derive.ts +195 -0
  140. package/src/standards/index.ts +31 -0
  141. package/src/standards/pack-rules.ts +111 -0
  142. package/src/standards/pack.ts +81 -0
  143. package/src/standards/registry.ts +100 -0
  144. package/src/standards/types.ts +202 -0
  145. package/src/standards/validate.ts +544 -0
  146. package/src/standards/vocabulary.ts +75 -0
  147. package/src/types.ts +355 -0
  148. package/src/util.ts +32 -0
  149. package/src/vendor/codeindex-engine.d.mts +1009 -0
  150. package/src/vendor/codeindex-engine.mjs +13701 -0
  151. package/src/vendor/engine.meta.json +9 -0
  152. package/src/verify.ts +275 -0
  153. package/src/wcag.ts +128 -0
@@ -0,0 +1,202 @@
1
+ // Types for a STANDARDS PACK — a pluggable, in-repo country accessibility standard
2
+ // (RGAA, Section 508, EN 301 549, AODA…) that maps its localized criteria onto WCAG
3
+ // success criteria. The WCAG 2.2 core (src/types.ts `Sc` / src/wcag.ts) stays canonical;
4
+ // a pack is a derived view. See CONTRIBUTING.md for the authoring contract.
5
+ // A localized string, keyed by a BCP-47-ish locale tag ("fr", "en", "pt-BR", "de"…) — NOT
6
+ // the UI frame's `Lang` ("fr"|"en", see src/types.ts): a pack may legitimately be
7
+ // authored in any language (e.g. a hypothetical German-only standard), decoupled from
8
+ // the languages the CLI's own tables (`L`) render in. `defaultLocale` (declared on the
9
+ // pack) MUST be present; other locales are optional. English is recommended for
10
+ // worldwide readability but a French-only standard like RGAA legitimately ships fr-only.
11
+ export type LocaleString = Partial<Record<string, string>>;
12
+
13
+ export interface PackTheme {
14
+ number: number;
15
+ name: LocaleString;
16
+ count: number;
17
+ }
18
+
19
+ export interface PackCriterion {
20
+ id: string; // pack-local id, e.g. RGAA "1.1"
21
+ theme: number;
22
+ title: LocaleString;
23
+ titlePlain: LocaleString;
24
+ tests?: Record<string, string[]>;
25
+ techniques?: string[];
26
+ technicalNote?: string[];
27
+ particularCases?: string[];
28
+ wcag: string[]; // bare WCAG SC ids this criterion maps to, e.g. ["1.1.1", "4.1.2"]
29
+ // Per-criterion APPLICABILITY: the engine rule ids whose findings this criterion can
30
+ // actually be non-conformant on. A single WCAG SC maps to MANY pack criteria (RGAA
31
+ // 1.1.1 → 19 criteria: informative-image, CAPTCHA, detailed-description, layout
32
+ // tables, downloadable documents…), so an `img-alt-missing` failure must attach ONLY
33
+ // to the informative-image criterion, not fan out to CAPTCHA/description/etc. A finding
34
+ // collected via a mapped SC attaches iff its `ruleId` matches one of these (exact, or a
35
+ // "prefix:*" wildcard for `axe:*`/`dyn-*`/`agent:*`). An empty list means "no engine
36
+ // rule can evidence this criterion" (it stays manual/NA, never NC from a sibling's
37
+ // failure). Optional/additive: a pack WITHOUT `appliesTo` keeps the legacy fan-out
38
+ // (every mapped SC's findings attach) so third-party packs are unaffected.
39
+ appliesTo?: { ruleIds: string[] };
40
+ }
41
+
42
+ // The localized DISPLAY vocabulary a standard uses when its audit is rendered for an
43
+ // AUDITOR (the `prd` auditor block + GitHub issues): the NOUNS the standard gives to a
44
+ // theme, a criterion, a test, and its three conformance verdicts, plus an optional
45
+ // section heading and a bespoke normative note. Every field is optional and localized —
46
+ // missing terms fall back to a generic default and the WCAG core keeps its own set (see
47
+ // src/standards/vocabulary.ts), so a pack that omits `vocabulary` still renders. This is
48
+ // what lets the auditor output speak each country's language rather than hardcoding RGAA
49
+ // ("Thématique / Critère / Test / C-NC-NA") or WCAG ("Principle · Guideline / Success
50
+ // criterion / Technique / Pass-Fail").
51
+ export interface PackVocabulary {
52
+ theme?: LocaleString; // grouping noun, e.g. RGAA "Thématique"
53
+ criterion?: LocaleString; // item noun, e.g. "Critère"
54
+ test?: LocaleString; // sub-item noun, e.g. "Test"
55
+ conformant?: LocaleString; // verdict, e.g. "Conforme (C)"
56
+ nonConformant?: LocaleString; // verdict, e.g. "Non conforme (NC)"
57
+ notApplicable?: LocaleString; // verdict, e.g. "Non applicable (NA)"
58
+ auditorHeading?: LocaleString; // section/doc title, e.g. "Critère d'accessibilité"
59
+ normativeNote?: LocaleString; // overrides the composed "Lecture auditeur — …" blockquote
60
+ }
61
+
62
+ // The NORMATIVE page-sample methodology for a standard — the REQUIRED page KINDS a real
63
+ // audit of it must cover. Standard-agnostic sample MECHANICS live in the core
64
+ // (src/types.ts SampleConfig + src/sample.ts); this pack field carries only the standard's
65
+ // own required-kinds LIST (RGAA: accueil, contact, mentions légales, déclaration
66
+ // d'accessibilité, plan du site, aide, authentification, pages représentatives + éléments
67
+ // transverses). Advisory: `ultra11y sample check` / `scan --sample` report which kinds the
68
+ // configured sample lacks (fuzzy match on a page's name/notes/url) — never a hard gate.
69
+ export interface SampleRequiredKind {
70
+ id: string; // slug, e.g. "mentions-legales"
71
+ label: LocaleString; // display label, e.g. { fr: "Mentions légales" }
72
+ keywords: string[]; // fuzzy-match terms (accent-insensitive) against a page's name/notes/url
73
+ }
74
+ export interface SampleMethodology {
75
+ requiredKinds: SampleRequiredKind[];
76
+ }
77
+
78
+ // ---- Declarative pack RULES — a bounded, validatable matcher DSL (NO arbitrary code).
79
+ // A pack ships its OWN detection for genuinely pack-only semantics WITHOUT forking the
80
+ // engine: a rule matches source elements structurally and emits a namespaced finding
81
+ // (`pack:<packKey>:<id>`) that projects onto the pack criterion it reports under. The
82
+ // vocabulary is deliberately CAPPED at what the built-in RGAA pack needs today (tag +
83
+ // attribute predicates + a visible-text predicate + bounded descendant conditions);
84
+ // anything more expressive belongs in a core WCAG-keyed engine rule instead (see
85
+ // skills/ultra11y/references/packs.md). A runtime pack loaded via `--pack` stays FULLY
86
+ // validatable — every regex is ReDoS-guarded, nesting is depth-bounded, JS plugins are
87
+ // rejected by construction (there is nowhere to put code).
88
+
89
+ // The operators an attribute predicate may use. `equals`/`matches` require `value`;
90
+ // `present`/`absent` ignore it. `matches` compiles the (ReDoS-guarded) value as a
91
+ // case-insensitive regex against the attribute value.
92
+ export type MatchOp = "present" | "absent" | "equals" | "matches";
93
+
94
+ export interface MatchAttr {
95
+ name: string; // attribute name (case-insensitive), e.g. "href"
96
+ op: MatchOp;
97
+ value?: string; // required for equals/matches; a regex string for matches
98
+ }
99
+
100
+ // A predicate over an element's VISIBLE TEXT (whitespace-collapsed descendant text).
101
+ // `matches` fires when the text matches the (ReDoS-guarded, case-insensitive) regex;
102
+ // `lacks` fires when it does NOT — the negation the download-link rule needs to flag a
103
+ // link whose visible text omits the file format/weight.
104
+ export interface MatchText {
105
+ op: "matches" | "lacks";
106
+ value: string; // a regex string
107
+ }
108
+
109
+ // One structural condition node. All present sub-conditions must hold (AND). `has`
110
+ // requires that EACH listed node matches SOME descendant; `lacks` requires that NONE of
111
+ // its listed nodes matches ANY descendant. Nesting of has/lacks is depth-bounded by the
112
+ // validator (MAX_MATCH_DEPTH).
113
+ export interface MatchNode {
114
+ tag?: string; // intrinsic tag to match (case-insensitive), e.g. "a"
115
+ attrs?: MatchAttr[];
116
+ text?: MatchText;
117
+ has?: MatchNode[];
118
+ lacks?: MatchNode[];
119
+ }
120
+
121
+ // The top-level match of a rule: a MatchNode plus an optional applicability scope —
122
+ // `page` restricts the rule to a full document (has an <html> element), `fragment`
123
+ // (default) lets it fire on any parsed source.
124
+ export interface PackRuleMatch extends MatchNode {
125
+ scope?: "page" | "fragment";
126
+ }
127
+
128
+ export interface PackRule {
129
+ id: string; // slug (lower-kebab); the emitted finding's ruleId is `pack:<packKey>:<id>`
130
+ criterion: string; // the pack criterion id this rule reports under (must exist)
131
+ wcag: string[]; // WCAG SC(s) the finding keys on for the core projection (must exist)
132
+ severity: "bloquant" | "majeur" | "mineur";
133
+ advisory?: boolean; // non-normative recommendation — never flips a criterion to NC
134
+ match: PackRuleMatch;
135
+ message: LocaleString; // { en, fr } — both required by the validator
136
+ remediation: LocaleString; // { en, fr } — both required by the validator
137
+ }
138
+
139
+ // A per-pack normativity/severity OVERRIDE, keyed by a finding's ruleId (a core engine
140
+ // rule id, or a `pack:<key>:<id>` declarative rule). Applied in `derivePackResults`
141
+ // WITHIN THIS PACK'S PROJECTION ONLY — the core WCAG result is untouched. This is the
142
+ // precise "WCAG can differ from RGAA" mechanism: a pack can re-normativize a
143
+ // core-advisory finding (advisory→normative, or the reverse) and re-grade its severity
144
+ // inside its own view.
145
+ export interface PackOverride {
146
+ advisory?: boolean;
147
+ severity?: "bloquant" | "majeur" | "mineur";
148
+ }
149
+
150
+ // A GENERIC secondary crosswalk projection: it declares that a finding raised under
151
+ // `ruleId` ALSO projects onto an ADDITIONAL pack criterion whose official WCAG crosswalk
152
+ // does NOT contain the finding's SC. This is the explicit, opt-in DEVIATION from the
153
+ // SC-faithful projection — the standard-agnostic mechanism a country pack (or a
154
+ // `.ultra11yrc.json`) uses when its own body classifies a defect under a criterion the
155
+ // WCAG mapping alone would never reach. Shipped DISABLED (`enabled` absent/false) so the
156
+ // out-of-box projection stays WCAG-faithful; a config activates it (see src/config.ts +
157
+ // registry.enableSecondaryMapping). Matching is by EXACT `ruleId` in `derivePackResults`,
158
+ // bypassing BOTH the SC gate and the appliesTo/ruleMatches gate — so sibling rules on the
159
+ // same SC are never pulled in. A tagged secondary finding DRIVES status (NC), like any
160
+ // normative finding; there is no annotate-only variant.
161
+ export interface SecondaryMapping {
162
+ ruleId: string; // an engine rule id (or a `pack:<key>:<id>` declarative rule) — EXACT match
163
+ criterion: string; // the ADDITIONAL pack criterion id this ruleId also projects onto (must exist)
164
+ note?: LocaleString; // optional localized note explaining the deviation, rendered on the finding
165
+ enabled?: boolean; // opt-in switch; absent/false ⇒ inert (WCAG-faithful default)
166
+ }
167
+
168
+ export interface StandardPack {
169
+ key: string; // unique slug, e.g. "rgaa" (may not be the reserved core key "wcag")
170
+ name: string; // short display name, e.g. "RGAA"
171
+ fullName?: string;
172
+ org: string; // authoring body, e.g. "DINUM"
173
+ country: string; // ISO-ish code, e.g. "FR"
174
+ baseVersion: string; // standard version, e.g. "4.1.2"
175
+ wcagVersion: string; // the WCAG version the pack maps to, e.g. "2.1"
176
+ locales: string[]; // BCP-47-ish tags, e.g. ["fr"] or ["de"] — the pack's OWN locales,
177
+ // independent of the UI frame's `Lang` (see `LocaleString` above)
178
+ defaultLocale: string;
179
+ license: string;
180
+ source: string;
181
+ attribution: string;
182
+ idPattern: string; // regex (string) the pack's criterion ids match
183
+ vocabulary?: PackVocabulary; // localized auditor-display terms (optional; defaults apply)
184
+ sampleMethodology?: SampleMethodology; // normative required page kinds (optional; advisory lint)
185
+ // Declarative pack-only detection (optional). Each rule runs AFTER the core engine
186
+ // rules in the audit pipeline (src/audit.ts) and emits a `pack:<key>:<id>` finding that
187
+ // projects onto its criterion via the same appliesTo/ruleMatches machinery as engine
188
+ // findings. Pack findings NEVER contribute to the core WCAG verdict.
189
+ rules?: PackRule[];
190
+ // Per-pack normativity/severity overrides keyed by finding ruleId, applied only within
191
+ // this pack's projection (derivePackResults) — the core result is never mutated.
192
+ overrides?: Record<string, PackOverride>;
193
+ // Optional, opt-in secondary crosswalk projections (src/standards/types.ts
194
+ // SecondaryMapping). Each shipped DISABLED by default; a config flips one on. Applied in
195
+ // derivePackResults, keying by EXACT ruleId to project a finding onto an ADDITIONAL
196
+ // criterion whose WCAG mapping does not contain the finding's SC — the standard-agnostic
197
+ // "differs from the WCAG crosswalk on purpose" mechanism (RGAA 7.4 for live regions is
198
+ // the first consumer). The core WCAG result is never touched.
199
+ secondaryMappings?: SecondaryMapping[];
200
+ themes: PackTheme[];
201
+ criteria: PackCriterion[];
202
+ }