ultra11y 5.3.1 → 5.3.2

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 of the code under change before every commit, push and pull request, plus full WCAG 2.2 AA / RGAA audits and conformance deliverables on demand.",
13
- "version": "5.3.1",
13
+ "version": "5.3.2",
14
14
  "author": { "name": "maxgfr" },
15
15
  "homepage": "https://github.com/maxgfr/ultra11y",
16
16
  "repository": "https://github.com/maxgfr/ultra11y",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ultra11y",
3
3
  "description": "Accessibility for WCAG 2.2 AA and country standards (RGAA…): an automatic review of the code under change before every commit, push and pull request, plus full audits and conformance deliverables on demand.",
4
- "version": "5.3.1",
4
+ "version": "5.3.2",
5
5
  "author": { "name": "maxgfr" },
6
6
  "homepage": "https://github.com/maxgfr/ultra11y",
7
7
  "repository": "https://github.com/maxgfr/ultra11y",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ultra11y",
3
3
  "description": "Accessibility for WCAG 2.2 AA and country standards (RGAA…): an automatic review of the code under change before every commit, push and pull request, plus full audits and conformance deliverables on demand.",
4
- "version": "5.3.1",
4
+ "version": "5.3.2",
5
5
  "author": { "name": "maxgfr", "url": "https://github.com/maxgfr" },
6
6
  "homepage": "https://github.com/maxgfr/ultra11y",
7
7
  "repository": "https://github.com/maxgfr/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.3.1";
30
+ const ULTRA11Y_PLUGIN_VERSION = "5.3.2";
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.3.1",
3
+ "version": "5.3.2",
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 join50, relative as relative5, resolve as resolve15, 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.3.1";
9
+ var VERSION = "5.3.2";
10
10
  var SCHEMA_VERSION = 2;
11
11
 
12
12
  // src/audit.ts
@@ -60223,14 +60223,16 @@ function perPageTable(result, standard = CORE2, lang = "en") {
60223
60223
  if (!scope.length) return "";
60224
60224
  attributePages(result, scope);
60225
60225
  const derived = derivePages(result, scope);
60226
- return [`### ${s.perPage}`, "", ...scoreboardTable(derived, s, lang), "", ...basisCaveats(result, derived, s, lang)].join("\n");
60226
+ return [`### ${s.perPage}`, "", ...scoreboardTable(result, derived, standard, s, lang), "", ...basisCaveats(result, derived, s, lang)].join("\n");
60227
60227
  }
60228
- function scoreboardTable(derived, s, lang) {
60228
+ function scoreboardTable(result, derived, standard, s, lang) {
60229
60229
  const out2 = [`| ${s.page} | ${s.basis} | ${s.pageRate} | \u{1F534} | \u{1F7E0} | \u{1F7E1} |`, "| --- | --- | ---: | ---: | ---: | ---: |"];
60230
60230
  for (const pg of derived) {
60231
60231
  const n = (sev) => severityCount(pg, sev);
60232
+ const rows = pageCriterionRows(result, pg, standard, lang);
60233
+ const cov = pageCoverage(rows);
60232
60234
  out2.push(
60233
- `| ${pg.name}${pg.auth ? " \u{1F512}" : ""} \u2014 \`${pg.url}\` | ${basisLabel(pg.basis, lang)} | ${formatRate(pg.conformancePct, pg.decided, pg.total)} | ${n("bloquant")} | ${n("majeur")} | ${n("mineur")} |`
60235
+ `| ${pg.name}${pg.auth ? " \u{1F512}" : ""} \u2014 \`${pg.url}\` | ${basisLabel(pg.basis, lang)} | ${formatRate(pageRatePct(rows), cov.decided, cov.total)} | ${n("bloquant")} | ${n("majeur")} | ${n("mineur")} |`
60234
60236
  );
60235
60237
  }
60236
60238
  return out2;
@@ -60304,7 +60306,7 @@ function pagesComment(result, opts = {}) {
60304
60306
  (a, b) => severityCount(b, "bloquant") - severityCount(a, "bloquant") || severityCount(b, "majeur") - severityCount(a, "majeur") || severityCount(b, "mineur") - severityCount(a, "mineur")
60305
60307
  ).map((p) => pageBlock(result, p, standard, lang)).filter((b) => b !== void 0);
60306
60308
  const assemble = (nBlocks2, nRows2) => {
60307
- const body3 = [...scoreboardTable(derived.slice(0, nRows2), s, lang), ""];
60309
+ const body3 = [...scoreboardTable(result, derived.slice(0, nRows2), standard, s, lang), ""];
60308
60310
  if (nRows2 < derived.length) body3.push(s.scoreboardClamped(derived.length - nRows2), "");
60309
60311
  body3.push(...basisCaveats(result, derived, s, lang));
60310
60312
  if (redirected.length) body3.push(...renderRedirected(redirected, lang), "");
@@ -5,7 +5,7 @@ when_to_use: "Invoke WITHOUT being asked whenever changed front-end code should
5
5
  allowed-tools: Bash(node ${CLAUDE_SKILL_DIR}/scripts/ultra11y.mjs *), Read, Grep, Glob
6
6
  license: MIT
7
7
  metadata:
8
- version: 5.3.1
8
+ version: 5.3.2
9
9
  ---
10
10
 
11
11
  # review-a11y — accessibility review of changed code
@@ -6,7 +6,7 @@ import { join as join50, relative as relative5, resolve as resolve15, 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.3.1";
9
+ var VERSION = "5.3.2";
10
10
  var SCHEMA_VERSION = 2;
11
11
 
12
12
  // src/audit.ts
@@ -60223,14 +60223,16 @@ function perPageTable(result, standard = CORE2, lang = "en") {
60223
60223
  if (!scope.length) return "";
60224
60224
  attributePages(result, scope);
60225
60225
  const derived = derivePages(result, scope);
60226
- return [`### ${s.perPage}`, "", ...scoreboardTable(derived, s, lang), "", ...basisCaveats(result, derived, s, lang)].join("\n");
60226
+ return [`### ${s.perPage}`, "", ...scoreboardTable(result, derived, standard, s, lang), "", ...basisCaveats(result, derived, s, lang)].join("\n");
60227
60227
  }
60228
- function scoreboardTable(derived, s, lang) {
60228
+ function scoreboardTable(result, derived, standard, s, lang) {
60229
60229
  const out2 = [`| ${s.page} | ${s.basis} | ${s.pageRate} | \u{1F534} | \u{1F7E0} | \u{1F7E1} |`, "| --- | --- | ---: | ---: | ---: | ---: |"];
60230
60230
  for (const pg of derived) {
60231
60231
  const n = (sev) => severityCount(pg, sev);
60232
+ const rows = pageCriterionRows(result, pg, standard, lang);
60233
+ const cov = pageCoverage(rows);
60232
60234
  out2.push(
60233
- `| ${pg.name}${pg.auth ? " \u{1F512}" : ""} \u2014 \`${pg.url}\` | ${basisLabel(pg.basis, lang)} | ${formatRate(pg.conformancePct, pg.decided, pg.total)} | ${n("bloquant")} | ${n("majeur")} | ${n("mineur")} |`
60235
+ `| ${pg.name}${pg.auth ? " \u{1F512}" : ""} \u2014 \`${pg.url}\` | ${basisLabel(pg.basis, lang)} | ${formatRate(pageRatePct(rows), cov.decided, cov.total)} | ${n("bloquant")} | ${n("majeur")} | ${n("mineur")} |`
60234
60236
  );
60235
60237
  }
60236
60238
  return out2;
@@ -60304,7 +60306,7 @@ function pagesComment(result, opts = {}) {
60304
60306
  (a, b) => severityCount(b, "bloquant") - severityCount(a, "bloquant") || severityCount(b, "majeur") - severityCount(a, "majeur") || severityCount(b, "mineur") - severityCount(a, "mineur")
60305
60307
  ).map((p) => pageBlock(result, p, standard, lang)).filter((b) => b !== void 0);
60306
60308
  const assemble = (nBlocks2, nRows2) => {
60307
- const body3 = [...scoreboardTable(derived.slice(0, nRows2), s, lang), ""];
60309
+ const body3 = [...scoreboardTable(result, derived.slice(0, nRows2), standard, s, lang), ""];
60308
60310
  if (nRows2 < derived.length) body3.push(s.scoreboardClamped(derived.length - nRows2), "");
60309
60311
  body3.push(...basisCaveats(result, derived, s, lang));
60310
60312
  if (redirected.length) body3.push(...renderRedirected(redirected, lang), "");
@@ -4,7 +4,7 @@ description: "Use to AUDIT existing HTML/CSS/JSX against WCAG 2.2 AA accessibili
4
4
  when_to_use: "Invoke when the user asks for an accessibility AUDIT or a formal deliverable: audit a repo, site or page against WCAG 2.2 AA or a country standard (RGAA, Section 508, EN 301 549); produce a dated conformance report, a criterion grid, a PRD backlog, or tickets (GitHub/GitLab/Jira); author accessible markup from scratch; wire the repo gate (init --hook/--ci) or a rendered-DOM capture pipeline. For a review of the code UNDER CHANGE (diff, branch, PR), use the `review-a11y` skill instead."
5
5
  license: MIT
6
6
  metadata:
7
- version: 5.3.1
7
+ version: 5.3.2
8
8
  ---
9
9
 
10
10
  # ultra11y — audit WCAG 2.2 AA and write accessible markup
@@ -6,7 +6,7 @@ import { join as join50, relative as relative5, resolve as resolve15, 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.3.1";
9
+ var VERSION = "5.3.2";
10
10
  var SCHEMA_VERSION = 2;
11
11
 
12
12
  // src/audit.ts
@@ -60223,14 +60223,16 @@ function perPageTable(result, standard = CORE2, lang = "en") {
60223
60223
  if (!scope.length) return "";
60224
60224
  attributePages(result, scope);
60225
60225
  const derived = derivePages(result, scope);
60226
- return [`### ${s.perPage}`, "", ...scoreboardTable(derived, s, lang), "", ...basisCaveats(result, derived, s, lang)].join("\n");
60226
+ return [`### ${s.perPage}`, "", ...scoreboardTable(result, derived, standard, s, lang), "", ...basisCaveats(result, derived, s, lang)].join("\n");
60227
60227
  }
60228
- function scoreboardTable(derived, s, lang) {
60228
+ function scoreboardTable(result, derived, standard, s, lang) {
60229
60229
  const out2 = [`| ${s.page} | ${s.basis} | ${s.pageRate} | \u{1F534} | \u{1F7E0} | \u{1F7E1} |`, "| --- | --- | ---: | ---: | ---: | ---: |"];
60230
60230
  for (const pg of derived) {
60231
60231
  const n = (sev) => severityCount(pg, sev);
60232
+ const rows = pageCriterionRows(result, pg, standard, lang);
60233
+ const cov = pageCoverage(rows);
60232
60234
  out2.push(
60233
- `| ${pg.name}${pg.auth ? " \u{1F512}" : ""} \u2014 \`${pg.url}\` | ${basisLabel(pg.basis, lang)} | ${formatRate(pg.conformancePct, pg.decided, pg.total)} | ${n("bloquant")} | ${n("majeur")} | ${n("mineur")} |`
60235
+ `| ${pg.name}${pg.auth ? " \u{1F512}" : ""} \u2014 \`${pg.url}\` | ${basisLabel(pg.basis, lang)} | ${formatRate(pageRatePct(rows), cov.decided, cov.total)} | ${n("bloquant")} | ${n("majeur")} | ${n("mineur")} |`
60234
60236
  );
60235
60237
  }
60236
60238
  return out2;
@@ -60304,7 +60306,7 @@ function pagesComment(result, opts = {}) {
60304
60306
  (a, b) => severityCount(b, "bloquant") - severityCount(a, "bloquant") || severityCount(b, "majeur") - severityCount(a, "majeur") || severityCount(b, "mineur") - severityCount(a, "mineur")
60305
60307
  ).map((p) => pageBlock(result, p, standard, lang)).filter((b) => b !== void 0);
60306
60308
  const assemble = (nBlocks2, nRows2) => {
60307
- const body3 = [...scoreboardTable(derived.slice(0, nRows2), s, lang), ""];
60309
+ const body3 = [...scoreboardTable(result, derived.slice(0, nRows2), standard, s, lang), ""];
60308
60310
  if (nRows2 < derived.length) body3.push(s.scoreboardClamped(derived.length - nRows2), "");
60309
60311
  body3.push(...basisCaveats(result, derived, s, lang));
60310
60312
  if (redirected.length) body3.push(...renderRedirected(redirected, lang), "");
package/src/annotate.ts CHANGED
@@ -36,7 +36,7 @@ import {
36
36
  renderRedirected,
37
37
  unattributedFindings,
38
38
  } from "./pages.js";
39
- import { pageCriterionRows, pageTally, pageTallyNote } from "./pages-report.js";
39
+ import { pageCoverage, pageCriterionRows, pageRatePct, pageTally, pageTallyNote } from "./pages-report.js";
40
40
 
41
41
  export interface AnnotateOptions {
42
42
  standard?: StandardId;
@@ -384,18 +384,27 @@ export function perPageTable(result: AuditResult, standard: StandardId = CORE, l
384
384
  attributePages(result, scope);
385
385
  const derived = derivePages(result, scope);
386
386
  // The summary has a 1 MiB budget: it never clamps, and passes every page.
387
- return [`### ${s.perPage}`, "", ...scoreboardTable(derived, s, lang), "", ...basisCaveats(result, derived, s, lang)].join("\n");
387
+ return [`### ${s.perPage}`, "", ...scoreboardTable(result, derived, standard, s, lang), "", ...basisCaveats(result, derived, s, lang)].join("\n");
388
388
  }
389
389
 
390
390
  /** The scoreboard's rows. Extracted so the job summary and the page-by-page pull-request
391
391
  * comment draw ONE table from one projection — a second copy of this loop is a second chance
392
- * to disagree about what a page's rate is. */
393
- function scoreboardTable(derived: PageResult[], s: (typeof S)[Lang], lang: Lang): string[] {
392
+ * to disagree about what a page's rate is.
393
+ *
394
+ * The rate comes from `pageCriterionRows`, in the ACTIVE standard's vocabulary — NOT from
395
+ * `PageResult.conformancePct`, which is always WCAG-keyed. Under a pack the two count
396
+ * different things, and the gap is visible in one glance: a page rendered « 50 % (4/55) »
397
+ * here while its own sheet in the artifact counted those 4 against RGAA's 106, and the run
398
+ * headline right above said `(9/106)`. One document, one standard, two denominators —
399
+ * exactly the drift `formatRate` exists to prevent. */
400
+ function scoreboardTable(result: AuditResult, derived: PageResult[], standard: StandardId, s: (typeof S)[Lang], lang: Lang): string[] {
394
401
  const out: string[] = [`| ${s.page} | ${s.basis} | ${s.pageRate} | 🔴 | 🟠 | 🟡 |`, "| --- | --- | ---: | ---: | ---: | ---: |"];
395
402
  for (const pg of derived) {
396
403
  const n = (sev: Severity): number => severityCount(pg, sev);
404
+ const rows = pageCriterionRows(result, pg, standard, lang);
405
+ const cov = pageCoverage(rows);
397
406
  out.push(
398
- `| ${pg.name}${pg.auth ? " 🔒" : ""} — \`${pg.url}\` | ${basisLabel(pg.basis, lang)} | ${formatRate(pg.conformancePct, pg.decided, pg.total)} | ${n("bloquant")} | ${n("majeur")} | ${n("mineur")} |`,
407
+ `| ${pg.name}${pg.auth ? " 🔒" : ""} — \`${pg.url}\` | ${basisLabel(pg.basis, lang)} | ${formatRate(pageRatePct(rows), cov.decided, cov.total)} | ${n("bloquant")} | ${n("majeur")} | ${n("mineur")} |`,
399
408
  );
400
409
  }
401
410
  return out;
@@ -520,7 +529,7 @@ export function pagesComment(result: AuditResult, opts: AnnotateOptions & { runU
520
529
  // goes first because the scoreboard is the half that cannot be reconstructed from the
521
530
  // artifact link alone.
522
531
  const assemble = (nBlocks: number, nRows: number): string => {
523
- const body: string[] = [...scoreboardTable(derived.slice(0, nRows), s, lang), ""];
532
+ const body: string[] = [...scoreboardTable(result, derived.slice(0, nRows), standard, s, lang), ""];
524
533
  if (nRows < derived.length) body.push(s.scoreboardClamped(derived.length - nRows), "");
525
534
  body.push(...basisCaveats(result, derived, s, lang));
526
535
  if (redirected.length) body.push(...renderRedirected(redirected, lang), "");
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.3.1";
3
+ export const VERSION = "5.3.2";
4
4
  export const SCHEMA_VERSION = 2;
5
5
 
6
6
  // Lang = the UI FRAME's language — the `L` localization tables each module (report,