ultra11y 5.43.2 → 5.43.4
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.opencode/plugins/ultra11y.js +1 -1
- package/package.json +1 -1
- package/scripts/ultra11y.mjs +8 -4
- package/skills/review-a11y/SKILL.md +1 -1
- package/skills/review-a11y/scripts/ultra11y.mjs +8 -4
- package/skills/ultra11y/SKILL.md +1 -1
- package/skills/ultra11y/references/orchestrators.md +3 -1
- package/skills/ultra11y/references/verify.md +4 -1
- package/skills/ultra11y/scripts/ultra11y.mjs +8 -4
- package/skills/ultra11y/templates/gitlab-ci.yml +1 -1
- package/src/adjudicate.ts +21 -10
- package/src/types.ts +1 -1
|
@@ -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.
|
|
13
|
+
"version": "5.43.4",
|
|
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.
|
|
4
|
+
"version": "5.43.4",
|
|
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.
|
|
4
|
+
"version": "5.43.4",
|
|
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.
|
|
30
|
+
const ULTRA11Y_PLUGIN_VERSION = "5.43.4";
|
|
31
31
|
|
|
32
32
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
33
33
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultra11y",
|
|
3
|
-
"version": "5.43.
|
|
3
|
+
"version": "5.43.4",
|
|
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",
|
package/scripts/ultra11y.mjs
CHANGED
|
@@ -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.
|
|
9
|
+
var VERSION = "5.43.4";
|
|
10
10
|
var SCHEMA_VERSION = 2;
|
|
11
11
|
var INAPPLICABLE_STATUS = "C";
|
|
12
12
|
|
|
@@ -64455,7 +64455,10 @@ function applyAdjudication(audit2, adj, opts = {}) {
|
|
|
64455
64455
|
}
|
|
64456
64456
|
for (const it of adj.items) {
|
|
64457
64457
|
if (!open.has(it.criteriaId)) {
|
|
64458
|
-
blame(
|
|
64458
|
+
blame(
|
|
64459
|
+
it.criteriaId,
|
|
64460
|
+
`criterion ${it.criteriaId}: not open for adjudication \u2014 already decided (by the engine or a previous fold), or not part of ${adj.standard}`
|
|
64461
|
+
);
|
|
64459
64462
|
}
|
|
64460
64463
|
}
|
|
64461
64464
|
const groundInputs = /* @__PURE__ */ new Map();
|
|
@@ -64487,6 +64490,7 @@ function applyAdjudication(audit2, adj, opts = {}) {
|
|
|
64487
64490
|
else groundInputs.set(criteriaId, [entry]);
|
|
64488
64491
|
};
|
|
64489
64492
|
for (const it of adj.items) {
|
|
64493
|
+
if (!open.has(it.criteriaId)) continue;
|
|
64490
64494
|
const v = it.verdict;
|
|
64491
64495
|
if (v === null) {
|
|
64492
64496
|
blame(it.criteriaId, `criterion ${it.criteriaId}: unadjudicated (verdict is null)`);
|
|
@@ -64506,10 +64510,10 @@ function applyAdjudication(audit2, adj, opts = {}) {
|
|
|
64506
64510
|
`criterion ${it.criteriaId}: a C verdict needs evidence to cite, and none was harvested for this criterion \u2014 record "manual" (reason "undecidable"), or "NA" if nothing in scope is concerned`
|
|
64507
64511
|
);
|
|
64508
64512
|
}
|
|
64509
|
-
} else if (cites.length === 0 && v === "C") {
|
|
64513
|
+
} else if (cites.length === 0 && (v === "C" || v === "NA")) {
|
|
64510
64514
|
blame(
|
|
64511
64515
|
it.criteriaId,
|
|
64512
|
-
`criterion ${it.criteriaId}: a C verdict must cite at least one of the ${it.evidence.length} evidence item(s) it was shown (citations: [{file, line, \u2026}])`
|
|
64516
|
+
v === "C" ? `criterion ${it.criteriaId}: a C verdict must cite at least one of the ${it.evidence.length} evidence item(s) it was shown (citations: [{file, line, \u2026}])` : `criterion ${it.criteriaId}: a NA verdict on a criterion with evidence must cite it`
|
|
64513
64517
|
);
|
|
64514
64518
|
} else if (cites.length > 0) {
|
|
64515
64519
|
const anchors = it.evidence.flatMap((e) => [`${e.file}:${e.line}`, ...e.alsoAt ?? []]);
|
|
@@ -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.
|
|
6
|
+
version: 5.43.4
|
|
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.
|
|
9
|
+
var VERSION = "5.43.4";
|
|
10
10
|
var SCHEMA_VERSION = 2;
|
|
11
11
|
var INAPPLICABLE_STATUS = "C";
|
|
12
12
|
|
|
@@ -64455,7 +64455,10 @@ function applyAdjudication(audit2, adj, opts = {}) {
|
|
|
64455
64455
|
}
|
|
64456
64456
|
for (const it of adj.items) {
|
|
64457
64457
|
if (!open.has(it.criteriaId)) {
|
|
64458
|
-
blame(
|
|
64458
|
+
blame(
|
|
64459
|
+
it.criteriaId,
|
|
64460
|
+
`criterion ${it.criteriaId}: not open for adjudication \u2014 already decided (by the engine or a previous fold), or not part of ${adj.standard}`
|
|
64461
|
+
);
|
|
64459
64462
|
}
|
|
64460
64463
|
}
|
|
64461
64464
|
const groundInputs = /* @__PURE__ */ new Map();
|
|
@@ -64487,6 +64490,7 @@ function applyAdjudication(audit2, adj, opts = {}) {
|
|
|
64487
64490
|
else groundInputs.set(criteriaId, [entry]);
|
|
64488
64491
|
};
|
|
64489
64492
|
for (const it of adj.items) {
|
|
64493
|
+
if (!open.has(it.criteriaId)) continue;
|
|
64490
64494
|
const v = it.verdict;
|
|
64491
64495
|
if (v === null) {
|
|
64492
64496
|
blame(it.criteriaId, `criterion ${it.criteriaId}: unadjudicated (verdict is null)`);
|
|
@@ -64506,10 +64510,10 @@ function applyAdjudication(audit2, adj, opts = {}) {
|
|
|
64506
64510
|
`criterion ${it.criteriaId}: a C verdict needs evidence to cite, and none was harvested for this criterion \u2014 record "manual" (reason "undecidable"), or "NA" if nothing in scope is concerned`
|
|
64507
64511
|
);
|
|
64508
64512
|
}
|
|
64509
|
-
} else if (cites.length === 0 && v === "C") {
|
|
64513
|
+
} else if (cites.length === 0 && (v === "C" || v === "NA")) {
|
|
64510
64514
|
blame(
|
|
64511
64515
|
it.criteriaId,
|
|
64512
|
-
`criterion ${it.criteriaId}: a C verdict must cite at least one of the ${it.evidence.length} evidence item(s) it was shown (citations: [{file, line, \u2026}])`
|
|
64516
|
+
v === "C" ? `criterion ${it.criteriaId}: a C verdict must cite at least one of the ${it.evidence.length} evidence item(s) it was shown (citations: [{file, line, \u2026}])` : `criterion ${it.criteriaId}: a NA verdict on a criterion with evidence must cite it`
|
|
64513
64517
|
);
|
|
64514
64518
|
} else if (cites.length > 0) {
|
|
64515
64519
|
const anchors = it.evidence.flatMap((e) => [`${e.file}:${e.line}`, ...e.alsoAt ?? []]);
|
package/skills/ultra11y/SKILL.md
CHANGED
|
@@ -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.
|
|
6
|
+
version: 5.43.4
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# ultra11y — audit WCAG 2.2 AA and write accessible markup
|
|
@@ -59,7 +59,9 @@ $ENGINE verify --manual --in "$RUN/audit-latest.json" --out "$RUN" --json
|
|
|
59
59
|
|
|
60
60
|
# 4. FOLD — partial by default: every verdict the gate accepts lands, every refusal is named
|
|
61
61
|
# in `rejectedCriteria[]` / `issues[]`, and a criterion absent from the file is refused as a
|
|
62
|
-
# coverage gap.
|
|
62
|
+
# coverage gap. A verdict for a criterion a previous fold already decided is refused too
|
|
63
|
+
# (« not open for adjudication »), so re-applying a file on the written-back audit is safe.
|
|
64
|
+
# Exit 1 only when nothing landed. `--strict` makes it all-or-nothing (exit 1
|
|
63
65
|
# on any refusal, audit left untouched).
|
|
64
66
|
$ENGINE verify --apply "$RUN/ADJUDICATE.verdicts.json" --in "$RUN/audit-latest.json" --out "$RUN" --json
|
|
65
67
|
|
|
@@ -87,7 +87,10 @@ Fold the verdicts back FAIL-CLOSED:
|
|
|
87
87
|
node scripts/ultra11y.mjs verify --apply ADJUDICATE.todo.json --in audit.json --out .
|
|
88
88
|
```
|
|
89
89
|
It rejects a null verdict, a `C`/`NA` without a `justification`, an `NC` without a groundable
|
|
90
|
-
finding, a `manual` without a `reason`, or any uncovered residual criterion.
|
|
90
|
+
finding, a `manual` without a `reason`, or any uncovered residual criterion. A verdict for a
|
|
91
|
+
criterion that is no longer open — one a previous fold already decided — is likewise refused by
|
|
92
|
+
name (« not open for adjudication »), never re-applied: re-folding the same file on the
|
|
93
|
+
written-back audit answers `ok: false` with that criterion in `rejectedCriteria[]`. Agent `NC`s become
|
|
91
94
|
real `agent:<sc>` findings that re-render in the report's §2 and re-enter the verify worklist;
|
|
92
95
|
`report`/`prd` re-render with the adjudicated statuses; §5 shrinks to only still-`manual` items.
|
|
93
96
|
|
|
@@ -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.
|
|
9
|
+
var VERSION = "5.43.4";
|
|
10
10
|
var SCHEMA_VERSION = 2;
|
|
11
11
|
var INAPPLICABLE_STATUS = "C";
|
|
12
12
|
|
|
@@ -64455,7 +64455,10 @@ function applyAdjudication(audit2, adj, opts = {}) {
|
|
|
64455
64455
|
}
|
|
64456
64456
|
for (const it of adj.items) {
|
|
64457
64457
|
if (!open.has(it.criteriaId)) {
|
|
64458
|
-
blame(
|
|
64458
|
+
blame(
|
|
64459
|
+
it.criteriaId,
|
|
64460
|
+
`criterion ${it.criteriaId}: not open for adjudication \u2014 already decided (by the engine or a previous fold), or not part of ${adj.standard}`
|
|
64461
|
+
);
|
|
64459
64462
|
}
|
|
64460
64463
|
}
|
|
64461
64464
|
const groundInputs = /* @__PURE__ */ new Map();
|
|
@@ -64487,6 +64490,7 @@ function applyAdjudication(audit2, adj, opts = {}) {
|
|
|
64487
64490
|
else groundInputs.set(criteriaId, [entry]);
|
|
64488
64491
|
};
|
|
64489
64492
|
for (const it of adj.items) {
|
|
64493
|
+
if (!open.has(it.criteriaId)) continue;
|
|
64490
64494
|
const v = it.verdict;
|
|
64491
64495
|
if (v === null) {
|
|
64492
64496
|
blame(it.criteriaId, `criterion ${it.criteriaId}: unadjudicated (verdict is null)`);
|
|
@@ -64506,10 +64510,10 @@ function applyAdjudication(audit2, adj, opts = {}) {
|
|
|
64506
64510
|
`criterion ${it.criteriaId}: a C verdict needs evidence to cite, and none was harvested for this criterion \u2014 record "manual" (reason "undecidable"), or "NA" if nothing in scope is concerned`
|
|
64507
64511
|
);
|
|
64508
64512
|
}
|
|
64509
|
-
} else if (cites.length === 0 && v === "C") {
|
|
64513
|
+
} else if (cites.length === 0 && (v === "C" || v === "NA")) {
|
|
64510
64514
|
blame(
|
|
64511
64515
|
it.criteriaId,
|
|
64512
|
-
`criterion ${it.criteriaId}: a C verdict must cite at least one of the ${it.evidence.length} evidence item(s) it was shown (citations: [{file, line, \u2026}])`
|
|
64516
|
+
v === "C" ? `criterion ${it.criteriaId}: a C verdict must cite at least one of the ${it.evidence.length} evidence item(s) it was shown (citations: [{file, line, \u2026}])` : `criterion ${it.criteriaId}: a NA verdict on a criterion with evidence must cite it`
|
|
64513
64517
|
);
|
|
64514
64518
|
} else if (cites.length > 0) {
|
|
64515
64519
|
const anchors = it.evidence.flatMap((e) => [`${e.file}:${e.line}`, ...e.alsoAt ?? []]);
|
|
@@ -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.
|
|
30
|
+
ULTRA11Y_VERSION: '5.43.4'
|
|
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
|
package/src/adjudicate.ts
CHANGED
|
@@ -1016,7 +1016,10 @@ export function applyAdjudication(
|
|
|
1016
1016
|
// citation, no normativeRef. Adjudication may only ever decide what the engine left open.
|
|
1017
1017
|
for (const it of adj.items) {
|
|
1018
1018
|
if (!open.has(it.criteriaId)) {
|
|
1019
|
-
blame(
|
|
1019
|
+
blame(
|
|
1020
|
+
it.criteriaId,
|
|
1021
|
+
`criterion ${it.criteriaId}: not open for adjudication — already decided (by the engine or a previous fold), or not part of ${adj.standard}`,
|
|
1022
|
+
);
|
|
1020
1023
|
}
|
|
1021
1024
|
}
|
|
1022
1025
|
|
|
@@ -1064,6 +1067,12 @@ export function applyAdjudication(
|
|
|
1064
1067
|
else groundInputs.set(criteriaId, [entry]);
|
|
1065
1068
|
};
|
|
1066
1069
|
for (const it of adj.items) {
|
|
1070
|
+
// A surplus verdict is already blamed above (« not open for adjudication ») and the fold
|
|
1071
|
+
// below records nothing for it. Gating it further would read `it.evidence` — which
|
|
1072
|
+
// `hydrateAdjudication` deliberately did not restore, the criterion being decided is WHY the
|
|
1073
|
+
// item is surplus — so the gate crashed on `undefined.length` instead of refusing. The blame
|
|
1074
|
+
// above IS the refusal; there is nothing left to validate.
|
|
1075
|
+
if (!open.has(it.criteriaId)) continue;
|
|
1067
1076
|
const v = it.verdict;
|
|
1068
1077
|
if (v === null) {
|
|
1069
1078
|
blame(it.criteriaId, `criterion ${it.criteriaId}: unadjudicated (verdict is null)`);
|
|
@@ -1094,19 +1103,21 @@ export function applyAdjudication(
|
|
|
1094
1103
|
`criterion ${it.criteriaId}: a C verdict needs evidence to cite, and none was harvested for this criterion — record "manual" (reason "undecidable"), or "NA" if nothing in scope is concerned`,
|
|
1095
1104
|
);
|
|
1096
1105
|
}
|
|
1097
|
-
} else if (cites.length === 0 && v === "C") {
|
|
1098
|
-
//
|
|
1099
|
-
//
|
|
1100
|
-
//
|
|
1101
|
-
//
|
|
1102
|
-
//
|
|
1103
|
-
//
|
|
1104
|
-
//
|
|
1106
|
+
} else if (cites.length === 0 && (v === "C" || v === "NA")) {
|
|
1107
|
+
// Either clearing verdict must cite. A `C` says "everything here conforms" and a `NA`
|
|
1108
|
+
// says "none of this is what the criterion is about" — both rule on the harvested
|
|
1109
|
+
// evidence, and the contract the filler was given (adjudicationContract, echoed by the
|
|
1110
|
+
// judge schema and the brief) already requires citations[] whenever evidence was
|
|
1111
|
+
// presented: "to say which of those items fall outside the criterion's scope". The
|
|
1112
|
+
// fold used to enforce only the `C` half, so a bare NA cleared shown evidence without
|
|
1113
|
+
// naming it — an agent could wave what it had been shown out of scope with a sentence.
|
|
1105
1114
|
//
|
|
1106
1115
|
// The justification is what keeps an NA falsifiable, and it is still required above.
|
|
1107
1116
|
blame(
|
|
1108
1117
|
it.criteriaId,
|
|
1109
|
-
|
|
1118
|
+
v === "C"
|
|
1119
|
+
? `criterion ${it.criteriaId}: a C verdict must cite at least one of the ${it.evidence.length} evidence item(s) it was shown (citations: [{file, line, …}])`
|
|
1120
|
+
: `criterion ${it.criteriaId}: a NA verdict on a criterion with evidence must cite it`,
|
|
1110
1121
|
);
|
|
1111
1122
|
} else if (cites.length > 0) {
|
|
1112
1123
|
// Each citation must name evidence THIS item carried. Grounding alone would only
|
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.
|
|
3
|
+
export const VERSION = "5.43.4";
|
|
4
4
|
export const SCHEMA_VERSION = 2;
|
|
5
5
|
|
|
6
6
|
// Lang = the UI FRAME's language — the `L` localization tables each module (report,
|