ultra11y 5.43.0 → 5.43.1

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.
@@ -10,7 +10,7 @@
10
10
  "name": "ultra11y",
11
11
  "source": "./",
12
12
  "description": "Automatic accessibility review before commit, push and pull request, plus detailed evidenced Markdown, HTML and per-page WCAG 2.2 AA / RGAA reports in Claude Code.",
13
- "version": "5.43.0",
13
+ "version": "5.43.1",
14
14
  "author": { "name": "maxgfr" },
15
15
  "homepage": "https://github.com/SocialGouv/ultra11y",
16
16
  "repository": "https://github.com/SocialGouv/ultra11y",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ultra11y",
3
3
  "description": "Accessibility for WCAG 2.2 AA and country standards (RGAA…): automatic review before commit, push and pull request, plus detailed evidenced Markdown, HTML and per-page conformance reports in interactive agent sessions.",
4
- "version": "5.43.0",
4
+ "version": "5.43.1",
5
5
  "author": { "name": "maxgfr" },
6
6
  "homepage": "https://github.com/SocialGouv/ultra11y",
7
7
  "repository": "https://github.com/SocialGouv/ultra11y",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ultra11y",
3
3
  "description": "Accessibility for WCAG 2.2 AA and country standards (RGAA…): automatic review before commit, push and pull request, plus detailed evidenced Markdown, HTML and per-page conformance reports in interactive agent sessions.",
4
- "version": "5.43.0",
4
+ "version": "5.43.1",
5
5
  "author": { "name": "maxgfr", "url": "https://github.com/maxgfr" },
6
6
  "homepage": "https://github.com/SocialGouv/ultra11y",
7
7
  "repository": "https://github.com/SocialGouv/ultra11y",
@@ -27,7 +27,7 @@ import { fileURLToPath } from "node:url";
27
27
  // Ownership marker: `ultra11y install --opencode` refuses to overwrite a plugin file that
28
28
  // does not carry it, so a user's own ultra11y.js is never clobbered.
29
29
  const ULTRA11Y_OPENCODE_PLUGIN = "ULTRA11Y_OPENCODE_PLUGIN";
30
- const ULTRA11Y_PLUGIN_VERSION = "5.43.0";
30
+ const ULTRA11Y_PLUGIN_VERSION = "5.43.1";
31
31
 
32
32
  const here = dirname(fileURLToPath(import.meta.url));
33
33
 
package/README.md CHANGED
@@ -577,7 +577,7 @@ pnpm run build:icons # re-generate the browser extension's icons from their
577
577
  ```
578
578
 
579
579
  Releases are cut automatically by **semantic-release** on push to `main` (GitHub release +
580
- npm publish via OIDC trusted publishing, plus the moving `v2` major tag). The version bump is
580
+ npm publish via OIDC trusted publishing, plus the moving `v5` major tag). The version bump is
581
581
  decided by **Conventional Commits**: a commit whose subject carries no `feat:`/`fix:` prefix
582
582
  is analysed as *no release*, so a change that must ship needs at least one conventional commit
583
583
  in the range — otherwise the major alias and npm keep serving the previous version while `main`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultra11y",
3
- "version": "5.43.0",
3
+ "version": "5.43.1",
4
4
  "description": "Audit HTML/CSS/JSX against WCAG 2.2 AA and produce a dated compliance report, or author/review accessible markup (native-HTML-first). A skills.sh agent skill: an install-free static engine (bundled, no npm install) plus the agent's judgment, with check/verify gates against hallucinated non-conformities, and pluggable in-repo standards packs (RGAA France first; Section 508 & EN 301 549 next).",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.33.0",
@@ -6,7 +6,7 @@ import { join as join52, relative as relative6, resolve as resolve17, sep as sep
6
6
  import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL3 } from "url";
7
7
 
8
8
  // src/types.ts
9
- var VERSION = "5.43.0";
9
+ var VERSION = "5.43.1";
10
10
  var SCHEMA_VERSION = 2;
11
11
  var INAPPLICABLE_STATUS = "C";
12
12
 
@@ -2298,7 +2298,7 @@ var wcag_universe_default = {
2298
2298
  wcagVersion: "2.2",
2299
2299
  source: "https://www.w3.org/TR/WCAG22/",
2300
2300
  criteriaSource: "https://github.com/w3c/wcag",
2301
- provenance: "Full WCAG 2.x SC universe (all levels incl. AAA, and the removed 4.1.1 Parsing) fetched from raw.githubusercontent.com/w3c/wcag@main on 2026-10-13 via `node scripts/build-standards.mjs --refresh-universe`. Classification: core-AA = ships in src/data/wcag.json (the shipped WCAG 2.2 AA core); out-of-core = WCAG AAA; removed = obsolete (4.1.1).",
2301
+ provenance: "Full WCAG 2.x SC universe (all levels incl. AAA, and the removed 4.1.1 Parsing) fetched from raw.githubusercontent.com/w3c/wcag@main on 2026-10-19 via `node scripts/build-standards.mjs --refresh-universe`. Classification: core-AA = ships in src/data/wcag.json (the shipped WCAG 2.2 AA core); out-of-core = WCAG AAA; removed = obsolete (4.1.1).",
2302
2302
  criteria: [
2303
2303
  {
2304
2304
  id: "1.1.1",
@@ -62733,7 +62733,7 @@ import { existsSync as existsSync21, readFileSync as readFileSync18 } from "fs";
62733
62733
  import { resolve as resolve10 } from "path";
62734
62734
  var WINDOW = 10;
62735
62735
  var norm2 = (s) => s.normalize("NFKC").replace(/[‘’]/g, "'").replace(/[“”]/g, '"').replace(/\s+/g, " ").replace(/>\s+/g, ">").replace(/\s+</g, "<").trim();
62736
- var isUnresolvable = (file) => !file || file === "-" || file === "<stdin>" || file === "stdin";
62736
+ var isUnresolvable = (file) => !file || file === "-" || file === "<stdin>" || file === "stdin" || /^[a-z][a-z0-9+.-]*:\/\//.test(file);
62737
62737
  var SEMANTIC_SELECTORS = /* @__PURE__ */ new Set(["handler"]);
62738
62738
  function selectorProbes(selector) {
62739
62739
  if (SEMANTIC_SELECTORS.has(selector.trim().toLowerCase())) return [];
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "source": "https://www.w3.org/Translations/WCAG22-fr/",
3
- "fetchedAt": "2026-10-13",
3
+ "fetchedAt": "2026-10-19",
4
4
  "principles": {
5
5
  "1": "Perceptible",
6
6
  "2": "Utilisable",
@@ -2,7 +2,7 @@
2
2
  "wcagVersion": "2.2",
3
3
  "source": "https://www.w3.org/TR/WCAG22/",
4
4
  "criteriaSource": "https://github.com/w3c/wcag",
5
- "provenance": "Full WCAG 2.x SC universe (all levels incl. AAA, and the removed 4.1.1 Parsing) fetched from raw.githubusercontent.com/w3c/wcag@main on 2026-10-13 via `node scripts/build-standards.mjs --refresh-universe`. Classification: core-AA = ships in src/data/wcag.json (the shipped WCAG 2.2 AA core); out-of-core = WCAG AAA; removed = obsolete (4.1.1).",
5
+ "provenance": "Full WCAG 2.x SC universe (all levels incl. AAA, and the removed 4.1.1 Parsing) fetched from raw.githubusercontent.com/w3c/wcag@main on 2026-10-19 via `node scripts/build-standards.mjs --refresh-universe`. Classification: core-AA = ships in src/data/wcag.json (the shipped WCAG 2.2 AA core); out-of-core = WCAG AAA; removed = obsolete (4.1.1).",
6
6
  "principles": [
7
7
  {
8
8
  "number": 1,
@@ -2,7 +2,7 @@
2
2
  "source": "https://github.com/w3c/wcag",
3
3
  "understanding": "https://www.w3.org/WAI/WCAG22/Understanding/",
4
4
  "license": "W3C Document License (code samples: W3C Software License)",
5
- "fetchedAt": "2026-10-13",
5
+ "fetchedAt": "2026-10-19",
6
6
  "criteria": {
7
7
  "1.1.1": {
8
8
  "slug": "non-text-content",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "source": "https://github.com/w3c/wcag",
3
3
  "license": "W3C Document License",
4
- "fetchedAt": "2026-10-13",
4
+ "fetchedAt": "2026-10-19",
5
5
  "criteria": {
6
6
  "1.1.1": "All non-text content that is presented to the user has a text alternative that serves the equivalent purpose, except for the situations listed below.\nControls, Input:\nIf non-text content is a control or accepts user input, then it has a name that describes its purpose. (Refer to Success Criterion 4.1.2 Name, Role, Value for additional requirements for controls and content that accepts user input.)\nTime-Based Media:\nIf non-text content is time-based media, then text alternatives at least provide descriptive identification of the non-text content. (Refer to Guideline 1.2 for additional requirements for media.)\nTest:\nIf non-text content is a test or exercise that would be invalid if presented in text, then text alternatives at least provide descriptive identification of the non-text content.\nSensory:\nIf non-text content is primarily intended to create a specific sensory experience, then text alternatives at least provide descriptive identification of the non-text content.\nCAPTCHA:\nIf the purpose of non-text content is to confirm that content is being accessed by a person rather than a computer, then text alternatives that identify and describe the purpose of the non-text content are provided, and alternative forms of CAPTCHA using output modes for different types of sensory perception are provided to accommodate different disabilities.\nDecoration, Formatting, Invisible:\nIf non-text content is pure decoration, is used only for visual formatting, or is not presented to users, then it is implemented in a way that it can be ignored by assistive technology.",
7
7
  "1.2.1": "For prerecorded audio-only and prerecorded video-only media, the following are true, except when the audio or video is a media alternative for text and is clearly labeled as such:\nPrerecorded Audio-only:\nAn alternative for time-based media is provided that presents equivalent information for prerecorded audio-only content.\nPrerecorded Video-only:\nEither an alternative for time-based media or an audio track is provided that presents equivalent information for prerecorded video-only content.",
@@ -3,7 +3,7 @@ name: review-a11y
3
3
  description: "Use to REVIEW changed frontend code for accessibility: staged files, a working diff, branch, or PR; prompts such as 'review a11y', 'is this accessible?', or 'anything to fix before merge?'; and hook or CI findings on a change. Run the bundled install-free engine with cross-file JSX/TSX analysis, then adjudicate candidates and return a severity-ranked WCAG 2.2 AA review with file:line fixes, residual rendering risks, and a verdict. Use `ultra11y` instead for whole-repo audits, dated conformance reports, country standards, PRD backlogs, or authoring accessible markup."
4
4
  license: MIT
5
5
  metadata:
6
- version: 5.43.0
6
+ version: 5.43.1
7
7
  ---
8
8
 
9
9
  # review-a11y — accessibility review of changed code
@@ -6,7 +6,7 @@ import { join as join52, relative as relative6, resolve as resolve17, sep as sep
6
6
  import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL3 } from "url";
7
7
 
8
8
  // src/types.ts
9
- var VERSION = "5.43.0";
9
+ var VERSION = "5.43.1";
10
10
  var SCHEMA_VERSION = 2;
11
11
  var INAPPLICABLE_STATUS = "C";
12
12
 
@@ -2298,7 +2298,7 @@ var wcag_universe_default = {
2298
2298
  wcagVersion: "2.2",
2299
2299
  source: "https://www.w3.org/TR/WCAG22/",
2300
2300
  criteriaSource: "https://github.com/w3c/wcag",
2301
- provenance: "Full WCAG 2.x SC universe (all levels incl. AAA, and the removed 4.1.1 Parsing) fetched from raw.githubusercontent.com/w3c/wcag@main on 2026-10-13 via `node scripts/build-standards.mjs --refresh-universe`. Classification: core-AA = ships in src/data/wcag.json (the shipped WCAG 2.2 AA core); out-of-core = WCAG AAA; removed = obsolete (4.1.1).",
2301
+ provenance: "Full WCAG 2.x SC universe (all levels incl. AAA, and the removed 4.1.1 Parsing) fetched from raw.githubusercontent.com/w3c/wcag@main on 2026-10-19 via `node scripts/build-standards.mjs --refresh-universe`. Classification: core-AA = ships in src/data/wcag.json (the shipped WCAG 2.2 AA core); out-of-core = WCAG AAA; removed = obsolete (4.1.1).",
2302
2302
  criteria: [
2303
2303
  {
2304
2304
  id: "1.1.1",
@@ -62733,7 +62733,7 @@ import { existsSync as existsSync21, readFileSync as readFileSync18 } from "fs";
62733
62733
  import { resolve as resolve10 } from "path";
62734
62734
  var WINDOW = 10;
62735
62735
  var norm2 = (s) => s.normalize("NFKC").replace(/[‘’]/g, "'").replace(/[“”]/g, '"').replace(/\s+/g, " ").replace(/>\s+/g, ">").replace(/\s+</g, "<").trim();
62736
- var isUnresolvable = (file) => !file || file === "-" || file === "<stdin>" || file === "stdin";
62736
+ var isUnresolvable = (file) => !file || file === "-" || file === "<stdin>" || file === "stdin" || /^[a-z][a-z0-9+.-]*:\/\//.test(file);
62737
62737
  var SEMANTIC_SELECTORS = /* @__PURE__ */ new Set(["handler"]);
62738
62738
  function selectorProbes(selector) {
62739
62739
  if (SEMANTIC_SELECTORS.has(selector.trim().toLowerCase())) return [];
@@ -3,7 +3,7 @@ name: ultra11y
3
3
  description: "Use to AUDIT a repository, site, or page against WCAG 2.2 AA or a country standard such as RGAA; produce a dated conformance report, criterion grid, PRD backlog, or tickets; AUTHOR accessible markup; fix accessibility; or wire a repo gate and rendered-DOM capture pipeline. The bundled install-free engine runs 93 static checks tied to success criteria, while the agent adjudicates judgment criteria and routes rendering criteria to browser scans; check/verify reject invented non-conformities. Use `review-a11y` instead for a review scoped only to a diff, branch, or PR."
4
4
  license: MIT
5
5
  metadata:
6
- version: 5.43.0
6
+ version: 5.43.1
7
7
  ---
8
8
 
9
9
  # ultra11y — audit WCAG 2.2 AA and write accessible markup
@@ -15,16 +15,21 @@ Pin the version. `npx` resolves `latest` otherwise, so what runs can change with
15
15
  anywhere.
16
16
 
17
17
  ```sh
18
- npm_config_update_notifier=false npx -y ultra11y@2.31.2 --version # → 2.31.2, exit 0
18
+ npm_config_update_notifier=false npx -y ultra11y@5.43.0 --version # → 5.43.0, exit 0
19
19
  ```
20
20
 
21
21
  - **`npm_config_update_notifier=false` is not optional.** Without it npm prints its
22
22
  "New major version available" notice into the output a step is about to parse.
23
23
  - **`ULTRA11Y_BIN`** points at an engine you already have (a vendored `ultra11y.mjs`, a
24
- container layer). The engine is one self-contained file with no runtime dependencies, so
25
- vendoring is a supported path — that is exactly what the skills and the Action do.
24
+ container layer). For every command but `scan` the engine is one self-contained file with
25
+ no runtime dependencies, so vendoring is a supported path — that is exactly what the skills
26
+ and the Action do. `scan` resolves `@playwright/test` and `@axe-core/playwright` from
27
+ `--cwd` first, then from the engine's own install, so a vendored file alone cannot scan.
26
28
  - **Node ≥ 22.18.** No other system dependency, no API key. (`judge` takes a key; nothing
27
29
  else does. `scan` needs a browser tier — see `references/dynamic.md`.)
30
+ - **Pin the file, not only the version.** An orchestrator that resolves the engine itself
31
+ should check the entry file's sha256 before running it: `--version` is a banner any file
32
+ can print.
28
33
  - **Verify what you resolved, and fail if it is not what you asked for.** A step that lets a
29
34
  missing engine fall through reports zero findings, which reads exactly like a clean audit.
30
35
  This is the one failure mode worth being loud about.
@@ -34,7 +39,7 @@ npm_config_update_notifier=false npx -y ultra11y@2.31.2 --version # → 2.31.2
34
39
  Six steps. Four are deterministic; only step 3 involves a model.
35
40
 
36
41
  ```sh
37
- ENGINE="npx -y ultra11y@2.31.2" # or "node $ULTRA11Y_BIN"
42
+ ENGINE="npx -y ultra11y@5.43.0" # or "node $ULTRA11Y_BIN"
38
43
  RUN=/tmp/a11y-run # out-of-tree: see "Where output lands"
39
44
 
40
45
  # 1. FIND — the static engine. No model. This is the finding set.
@@ -42,15 +47,21 @@ $ENGINE audit "<globs>" --graph --out "$RUN" --json --lang en > /dev/null
42
47
  # …or, on a pull request, exactly what the branch introduced:
43
48
  $ENGINE audit --since "$BASE_REF" --graph --out "$RUN" --json --lang en > /dev/null
44
49
 
45
- # 2. WORKLIST — a draft report, then the criteria a static pass cannot decide.
46
- $ENGINE report --in "$RUN/audit-latest.json" --out "$RUN" --lang en > /dev/null
47
- $ENGINE verify --report "$RUN"/wcag-*.md --in "$RUN/audit-latest.json" --manual --out "$RUN" --json
50
+ # 2. WORKLIST — the criteria a static pass cannot decide, one brief per criterion.
51
+ $ENGINE verify --manual --in "$RUN/audit-latest.json" --out "$RUN" --json
52
+ # → { count, todoPath, verdictsPath, itemsDir, mdPath, items }. ADJUDICATE.todo.json carries
53
+ # the evidence (it can reach hundreds of KB); ADJUDICATE.verdicts.json is the same worklist
54
+ # without it — hand the agent that slim file plus the briefs in <itemsDir>/<criterion>.md.
48
55
 
49
- # 3. ADJUDICATE — hand $RUN/ADJUDICATE.todo.json to the agent; it fills every `verdict`.
50
- # The file carries its own `contract` (see below) — the agent needs nothing else.
56
+ # 3. ADJUDICATE — the agent fills every `verdict` (C/NC/NA/manual) in the verdicts file.
57
+ # The file carries its own `contract` (see below) — the agent needs nothing else. The fold
58
+ # re-hydrates the evidence from the audit, so a verdicts-only file is accepted.
51
59
 
52
- # 4. FOLD — fail-closed. Exit 1 with per-criterion reasons if a verdict is unsupported.
53
- $ENGINE verify --apply "$RUN/adjudication.json" --in "$RUN/audit-latest.json" --out "$RUN" --json
60
+ # 4. FOLD — partial by default: every verdict the gate accepts lands, every refusal is named
61
+ # in `rejectedCriteria[]` / `issues[]`, and a criterion absent from the file is refused as a
62
+ # coverage gap. Exit 1 only when nothing landed. `--strict` makes it all-or-nothing (exit 1
63
+ # on any refusal, audit left untouched).
64
+ $ENGINE verify --apply "$RUN/ADJUDICATE.verdicts.json" --in "$RUN/audit-latest.json" --out "$RUN" --json
54
65
 
55
66
  # 5. REPORT — deterministic rendering of the adjudicated audit.
56
67
  $ENGINE report --in "$RUN/audit-latest.json" --out audits --standard rgaa --lang fr
@@ -153,15 +164,16 @@ repo it does not own — write the run's intermediates out-of-tree and let only
153
164
  dated report land in the project, if at all.
154
165
 
155
166
  `.ultra11y/pages/` is written only by the page-snapshot commands (`scan`, `snapshot`,
156
- `dev`); `--root` relocates it. `audit`, `report`, `prd`, `tickets`, `verify` and `check`
157
- never touch it.
167
+ `dev`). `snapshot`, `dev` and `pages discover` take `--root` to relocate it; `scan` does not —
168
+ it writes under the current working directory, so run it from the directory that should
169
+ hold the snapshots. `audit`, `report`, `prd`, `tickets`, `verify` and `check` never touch it.
158
170
 
159
171
  ## Exit codes
160
172
 
161
173
  | | 0 | 1 | 2 |
162
174
  |---|---|---|---|
163
175
  | `audit` | reported (no `--fail-on`), or clean | findings ≥ `--fail-on` | usage / bad input |
164
- | `verify --apply` | folded | the adjudication was refused (see `issues[]`) | usage / bad input |
176
+ | `verify --apply` | at least one verdict landed (refusals, if any, in `rejectedCriteria[]` / `issues[]`) | nothing landed, or `--strict` and a refusal | usage / bad input |
165
177
  | `check` | report is sound | integrity failure | report not found / bad input |
166
178
  | `prd` | written | — (it writes markdown and files nothing) | usage / bad input |
167
179
  | `tickets` | filed, skipped, or nothing to file | a creation failed, the provider is unusable, or no page in scope | usage / bad input / past `--max-tickets` |
@@ -174,8 +186,24 @@ Read exit codes from the process, **not** from a pipeline — `cmd --json | head
174
186
  - `audit --json` → the `AuditResult` (also at `<out>/audit-latest.json`): `findings[]` with
175
187
  stable `findingId`, `criteriaId`, `severity`, `file`, `line`; `residualRisks[]`;
176
188
  `conformancePct` — the **automatic static pass rate**, not a conformance rate.
177
- - `verify --apply --json` → `{ ok, auditPath, applied, stillManual, conformancePct, findings, grounding }`
178
- on success; `{ ok: false, issues[], audit }` when refused.
189
+ - `verify --apply --json` → `{ ok, auditPath, applied, stillManual, rejected, rejectedCriteria[], issues[],
190
+ conformancePct, findings, grounding }`; `ok: false` when nothing landed. Count on
191
+ `applied + stillManual + rejected`, never on the exit code alone.
192
+ - With `--prune`, **`ok: false` does not mean "nothing was applied"**. The CLI computes the
193
+ coverage and grounding verdicts first, but `applyPrune` writes the pruned
194
+ `audit-latest.json` and repairs the `--ledger` file BEFORE `ok` is derived — so a trial that
195
+ fails on grounding still applied every refutation it decided. Read `pruned` in the JSON
196
+ (or the audit document itself) to know what the audit now says; never report `ok: false` as
197
+ "trial not applied".
198
+ - `grounding` re-opens every cited file of a retained verdict. A `file` that is a served URL
199
+ (`^[a-z][a-z0-9+.-]*://` — a rendered finding whose page has no `.ultra11y/pages` capture
200
+ mapped back to source) has no on-disk source to re-open and is skipped like `stdin`, not
201
+ counted as `failed`.
202
+ - Under a pack standard (`--standard rgaa`), `audit-latest.json` is a `pack-audit` document:
203
+ its root `conformancePct` is the automatic pass rate for that standard, `core` is the WCAG
204
+ audit, and `report --json` and `verify --apply --json` echo the **core** rate. The
205
+ standard's own conformance rate (validated ÷ validated + NC + à évaluer, NA excluded) is
206
+ printed by the report; derive it from `criteria[]` if a number is needed in a pipeline.
179
207
  - `check --json` → `{ ok, issues[] }`.
180
208
 
181
209
  ## Honesty rules an orchestrator has to carry
@@ -23,6 +23,9 @@ node scripts/ultra11y.mjs check --report audits/wcag-YYYY-MM-DD.md --semantic [-
23
23
  Fails **closed** if there is no adjudicated verdicts artifact (never green-but-inactive),
24
24
  re-runs the **uncapped** coverage check, and re-grounds every passing verdict against the cited
25
25
  source. `--verdicts` points at the artifact (default `VERIFY.todo.json` next to the report).
26
+ A `file` that is a served URL (a rendered finding whose page has no `.ultra11y/pages` capture
27
+ mapped back to source) is not a path to re-open: it is skipped like `stdin`, never reported as
28
+ « cited file not found ».
26
29
 
27
30
  ### Applicability gate — `check --report … --standard rgaa --in audit.json`
28
31
 
@@ -6,7 +6,7 @@ import { join as join52, relative as relative6, resolve as resolve17, sep as sep
6
6
  import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL3 } from "url";
7
7
 
8
8
  // src/types.ts
9
- var VERSION = "5.43.0";
9
+ var VERSION = "5.43.1";
10
10
  var SCHEMA_VERSION = 2;
11
11
  var INAPPLICABLE_STATUS = "C";
12
12
 
@@ -2298,7 +2298,7 @@ var wcag_universe_default = {
2298
2298
  wcagVersion: "2.2",
2299
2299
  source: "https://www.w3.org/TR/WCAG22/",
2300
2300
  criteriaSource: "https://github.com/w3c/wcag",
2301
- provenance: "Full WCAG 2.x SC universe (all levels incl. AAA, and the removed 4.1.1 Parsing) fetched from raw.githubusercontent.com/w3c/wcag@main on 2026-10-13 via `node scripts/build-standards.mjs --refresh-universe`. Classification: core-AA = ships in src/data/wcag.json (the shipped WCAG 2.2 AA core); out-of-core = WCAG AAA; removed = obsolete (4.1.1).",
2301
+ provenance: "Full WCAG 2.x SC universe (all levels incl. AAA, and the removed 4.1.1 Parsing) fetched from raw.githubusercontent.com/w3c/wcag@main on 2026-10-19 via `node scripts/build-standards.mjs --refresh-universe`. Classification: core-AA = ships in src/data/wcag.json (the shipped WCAG 2.2 AA core); out-of-core = WCAG AAA; removed = obsolete (4.1.1).",
2302
2302
  criteria: [
2303
2303
  {
2304
2304
  id: "1.1.1",
@@ -62733,7 +62733,7 @@ import { existsSync as existsSync21, readFileSync as readFileSync18 } from "fs";
62733
62733
  import { resolve as resolve10 } from "path";
62734
62734
  var WINDOW = 10;
62735
62735
  var norm2 = (s) => s.normalize("NFKC").replace(/[‘’]/g, "'").replace(/[“”]/g, '"').replace(/\s+/g, " ").replace(/>\s+/g, ">").replace(/\s+</g, "<").trim();
62736
- var isUnresolvable = (file) => !file || file === "-" || file === "<stdin>" || file === "stdin";
62736
+ var isUnresolvable = (file) => !file || file === "-" || file === "<stdin>" || file === "stdin" || /^[a-z][a-z0-9+.-]*:\/\//.test(file);
62737
62737
  var SEMANTIC_SELECTORS = /* @__PURE__ */ new Set(["handler"]);
62738
62738
  function selectorProbes(selector) {
62739
62739
  if (SEMANTIC_SELECTORS.has(selector.trim().toLowerCase())) return [];
@@ -27,7 +27,7 @@ variables:
27
27
  ULTRA11Y_LANG: en
28
28
  # Exact by default: a CI report must say which engine produced it. The release script keeps
29
29
  # this pin aligned with the package version; override only for a deliberate upgrade test.
30
- ULTRA11Y_VERSION: '5.43.0'
30
+ ULTRA11Y_VERSION: '5.43.1'
31
31
  # Batches of 8 amortise the prompt; each accepted verdict is checkpointed before the next
32
32
  # batch, and later passes receive only the residue.
33
33
  ULTRA11Y_GRAIN: batch
@@ -2,7 +2,7 @@
2
2
  "wcagVersion": "2.2",
3
3
  "source": "https://www.w3.org/TR/WCAG22/",
4
4
  "criteriaSource": "https://github.com/w3c/wcag",
5
- "provenance": "Full WCAG 2.x SC universe (all levels incl. AAA, and the removed 4.1.1 Parsing) fetched from raw.githubusercontent.com/w3c/wcag@main on 2026-10-13 via `node scripts/build-standards.mjs --refresh-universe`. Classification: core-AA = ships in src/data/wcag.json (the shipped WCAG 2.2 AA core); out-of-core = WCAG AAA; removed = obsolete (4.1.1).",
5
+ "provenance": "Full WCAG 2.x SC universe (all levels incl. AAA, and the removed 4.1.1 Parsing) fetched from raw.githubusercontent.com/w3c/wcag@main on 2026-10-19 via `node scripts/build-standards.mjs --refresh-universe`. Classification: core-AA = ships in src/data/wcag.json (the shipped WCAG 2.2 AA core); out-of-core = WCAG AAA; removed = obsolete (4.1.1).",
6
6
  "criteria": [
7
7
  {
8
8
  "id": "1.1.1",
package/src/grounding.ts CHANGED
@@ -39,8 +39,11 @@ const WINDOW = 10;
39
39
  const norm = (s: string) =>
40
40
  s.normalize("NFKC").replace(/[‘’]/g, "'").replace(/[“”]/g, '"').replace(/\s+/g, " ").replace(/>\s+/g, ">").replace(/\s+</g, "<").trim();
41
41
 
42
- /** Streams/aggregates have no on-disk source to re-open. */
43
- const isUnresolvable = (file: string) => !file || file === "-" || file === "<stdin>" || file === "stdin";
42
+ /** Streams/aggregates have no on-disk source to re-open. Neither has a served URL: a rendered
43
+ * finding whose page has no `.ultra11y/pages` capture keeps the page URL as its `file`, and
44
+ * resolving that against the cwd can only report it missing. The `://` keeps a Windows drive
45
+ * letter (`C:\…`) out — only a scheme + authority is a URL. */
46
+ const isUnresolvable = (file: string) => !file || file === "-" || file === "<stdin>" || file === "stdin" || /^[a-z][a-z0-9+.-]*:\/\//.test(file);
44
47
 
45
48
  /** A markup token a selector implies. `ci` = case-INSENSITIVE (HTML tag & attribute
46
49
  * names, which the HTML spec treats case-insensitively — `<IMG>` ≡ `<img>`); `cs` =
package/src/types.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Single source of truth for shared types + the embedded version. sync-version.mjs
2
2
  // rewrites VERSION at release time (kept in lockstep with package.json + SKILL.md).
3
- export const VERSION = "5.43.0";
3
+ export const VERSION = "5.43.1";
4
4
  export const SCHEMA_VERSION = 2;
5
5
 
6
6
  // Lang = the UI FRAME's language — the `L` localization tables each module (report,