ultra11y 3.0.0 → 4.0.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.
- 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/README.md +3 -2
- package/package.json +1 -1
- package/scripts/build-extension-icons.mjs +11 -43
- package/scripts/ultra11y.mjs +646 -62
- package/skills/review-a11y/SKILL.md +1 -1
- package/skills/review-a11y/scripts/ultra11y.mjs +646 -62
- package/skills/ultra11y/SKILL.md +1 -1
- package/skills/ultra11y/references/ci.md +11 -9
- package/skills/ultra11y/references/dynamic.md +24 -0
- package/skills/ultra11y/references/pages.md +82 -10
- package/skills/ultra11y/scripts/ultra11y.mjs +646 -62
- package/src/annotate.ts +8 -4
- package/src/audit.ts +35 -4
- package/src/auditor.ts +0 -0
- package/src/capture.ts +13 -0
- package/src/cli.ts +342 -20
- package/src/dev.ts +17 -3
- package/src/evidence.ts +499 -0
- package/src/external/adapters/ara.ts +164 -0
- package/src/external/diff.ts +143 -0
- package/src/external/registry.ts +22 -0
- package/src/external/types.ts +59 -0
- package/src/mcp/handlers.ts +45 -6
- package/src/pages-report.ts +41 -18
- package/src/pages.ts +83 -13
- package/src/pixel.ts +174 -2
- package/src/report.ts +15 -1
- package/src/rules/cross-rule.ts +7 -0
- package/src/sample.ts +46 -0
- package/src/scan.ts +5 -0
- package/src/snapshot.ts +38 -4
- package/src/standards/pack-rules.ts +6 -0
- package/src/tickets/grain.ts +14 -2
- package/src/tickets/types.ts +5 -3
- package/src/types.ts +27 -8
- package/src/verify.ts +6 -1
|
@@ -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": "
|
|
13
|
+
"version": "4.0.0",
|
|
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": "
|
|
4
|
+
"version": "4.0.0",
|
|
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": "
|
|
4
|
+
"version": "4.0.0",
|
|
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 = "
|
|
30
|
+
const ULTRA11Y_PLUGIN_VERSION = "4.0.0";
|
|
31
31
|
|
|
32
32
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
33
33
|
|
package/README.md
CHANGED
|
@@ -125,7 +125,7 @@ claude mcp add ultra11y -- npx -y ultra11y mcp
|
|
|
125
125
|
**As a GitHub Action** — audits the PR diff and, optionally, the served pages:
|
|
126
126
|
|
|
127
127
|
```yaml
|
|
128
|
-
- uses: maxgfr/ultra11y@
|
|
128
|
+
- uses: maxgfr/ultra11y@v3
|
|
129
129
|
with: { since: auto, standard: rgaa, fail-on: blocking }
|
|
130
130
|
```
|
|
131
131
|
|
|
@@ -429,7 +429,8 @@ Releases are cut automatically by **semantic-release** on push to `main` (GitHub
|
|
|
429
429
|
npm publish via OIDC trusted publishing, plus the moving `v2` major tag). The version bump is
|
|
430
430
|
decided by **Conventional Commits**: a commit whose subject carries no `feat:`/`fix:` prefix
|
|
431
431
|
is analysed as *no release*, so a change that must ship needs at least one conventional commit
|
|
432
|
-
in the range — otherwise
|
|
432
|
+
in the range — otherwise the major alias and npm keep serving the previous version while `main`
|
|
433
|
+
moves on.
|
|
433
434
|
|
|
434
435
|
## Data & licensing
|
|
435
436
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ultra11y",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
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",
|
|
@@ -7,15 +7,22 @@
|
|
|
7
7
|
// script produces — the same reproducibility contract the engine bundle is held to.
|
|
8
8
|
//
|
|
9
9
|
// The mark is an eye (the action's own branding icon), drawn as a filled lens with a pupil on
|
|
10
|
-
// the purple the action already declares.
|
|
11
|
-
//
|
|
10
|
+
// the purple the action already declares. The PNG encoder is the engine's own
|
|
11
|
+
// (`src/pixel.ts`), imported through Node's type-stripping — the repo has no image dependency
|
|
12
|
+
// and is not about to grow one for four small files.
|
|
13
|
+
//
|
|
14
|
+
// That import runs both ways: because these four icons are committed, `--check` re-encodes
|
|
15
|
+
// them and proves `encodePng` still emits the exact bytes it emitted when they were drawn.
|
|
16
|
+
// A decode/encode round-trip could only prove the pair is self-consistent; this proves the
|
|
17
|
+
// encoder is PNG-correct against files a browser accepts. Keep `src/pixel.ts` a leaf (one
|
|
18
|
+
// runtime import, `node:zlib`) or this import stops resolving.
|
|
12
19
|
//
|
|
13
20
|
// node scripts/build-extension-icons.mjs # write
|
|
14
21
|
// node scripts/build-extension-icons.mjs --check # fail if the committed files differ
|
|
15
|
-
import { deflateSync } from "node:zlib";
|
|
16
22
|
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
17
23
|
import { dirname, join } from "node:path";
|
|
18
24
|
import { fileURLToPath } from "node:url";
|
|
25
|
+
import { encodePng } from "../src/pixel.ts";
|
|
19
26
|
|
|
20
27
|
const OUT = join(dirname(fileURLToPath(import.meta.url)), "..", "extension", "icons");
|
|
21
28
|
const SIZES = [16, 32, 48, 128];
|
|
@@ -24,45 +31,6 @@ const SIZES = [16, 32, 48, 128];
|
|
|
24
31
|
const BG = [107, 70, 193]; // #6b46c1
|
|
25
32
|
const FG = [255, 255, 255];
|
|
26
33
|
|
|
27
|
-
function crc32(buf) {
|
|
28
|
-
let c = ~0;
|
|
29
|
-
for (const b of buf) {
|
|
30
|
-
c ^= b;
|
|
31
|
-
for (let i = 0; i < 8; i++) c = (c >>> 1) ^ (0xedb88320 & -(c & 1));
|
|
32
|
-
}
|
|
33
|
-
return ~c >>> 0;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function chunk(type, data) {
|
|
37
|
-
const len = Buffer.alloc(4);
|
|
38
|
-
len.writeUInt32BE(data.length);
|
|
39
|
-
const body = Buffer.concat([Buffer.from(type, "latin1"), data]);
|
|
40
|
-
const crc = Buffer.alloc(4);
|
|
41
|
-
crc.writeUInt32BE(crc32(body));
|
|
42
|
-
return Buffer.concat([len, body, crc]);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** An RGBA pixel buffer → a PNG. Colour type 6, 8-bit, one filter byte per row. */
|
|
46
|
-
function png(size, rgba) {
|
|
47
|
-
const raw = Buffer.alloc(size * (size * 4 + 1));
|
|
48
|
-
for (let y = 0; y < size; y++) {
|
|
49
|
-
raw[y * (size * 4 + 1)] = 0; // filter: none — the images are tiny, filtering buys nothing
|
|
50
|
-
rgba.copy(raw, y * (size * 4 + 1) + 1, y * size * 4, (y + 1) * size * 4);
|
|
51
|
-
}
|
|
52
|
-
const ihdr = Buffer.alloc(13);
|
|
53
|
-
ihdr.writeUInt32BE(size, 0);
|
|
54
|
-
ihdr.writeUInt32BE(size, 4);
|
|
55
|
-
ihdr[8] = 8; // bit depth
|
|
56
|
-
ihdr[9] = 6; // RGBA
|
|
57
|
-
return Buffer.concat([
|
|
58
|
-
Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
|
|
59
|
-
chunk("IHDR", ihdr),
|
|
60
|
-
// level 9 so the bytes are a function of the pixels alone, not of zlib's default tuning.
|
|
61
|
-
chunk("IDAT", deflateSync(raw, { level: 9 })),
|
|
62
|
-
chunk("IEND", Buffer.alloc(0)),
|
|
63
|
-
]);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
34
|
/** The eye mark, supersampled 4× so the curves do not alias at 16px. */
|
|
67
35
|
function draw(size) {
|
|
68
36
|
const S = 4;
|
|
@@ -118,7 +86,7 @@ mkdirSync(OUT, { recursive: true });
|
|
|
118
86
|
let stale = [];
|
|
119
87
|
for (const size of SIZES) {
|
|
120
88
|
const file = join(OUT, `icon-${size}.png`);
|
|
121
|
-
const bytes =
|
|
89
|
+
const bytes = encodePng({ width: size, height: size, data: draw(size) });
|
|
122
90
|
if (check) {
|
|
123
91
|
let current = null;
|
|
124
92
|
try {
|