ultra11y 5.43.5 → 5.44.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.
@@ -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.5",
13
+ "version": "5.44.0",
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.5",
4
+ "version": "5.44.0",
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.5",
4
+ "version": "5.44.0",
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.5";
30
+ const ULTRA11Y_PLUGIN_VERSION = "5.44.0";
31
31
 
32
32
  const here = dirname(fileURLToPath(import.meta.url));
33
33
 
package/README.md CHANGED
@@ -160,7 +160,7 @@ ultra11y verify --report <md> [--conformities <ledger|adjudication.json> | --n
160
160
  ultra11y fix <globs… | -> [--write] [--iterate] [--changed | --since <ref> | --staged] [--safe] [--only <ids>] [--jsx] [--json]
161
161
  ultra11y init [--hook] [--ci] [--baseline] [--fail-on blocking|major|minor]
162
162
  ultra11y pack check <pack.json> [--guidance <g.json>] | scaffold # gate an (AI-)authored standards pack
163
- ultra11y scan <url|file…> [--runtime auto|local|docker] [--cwd <dir>] [--storage-state <file>] [--merge <audit.json>] [--out <dir>] [--json]
163
+ ultra11y scan <url|file…> [--runtime auto|local|docker] [--cwd <dir>] [--root <dir>] [--storage-state <file>] [--merge <audit.json>] [--out <dir>] [--json]
164
164
  ultra11y scan --sitemap <url> | --crawl <url> [--depth <n>] [--max <n>] [--runtime …] [--merge <audit.json>] [--json]
165
165
  ultra11y mcp [--transport stdio|http] [--cwd <dir>] [--allow-write] [--port <n>] [--bind <addr>] [--allow-remote]
166
166
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultra11y",
3
- "version": "5.43.5",
3
+ "version": "5.44.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",
@@ -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.5";
9
+ var VERSION = "5.44.0";
10
10
  var SCHEMA_VERSION = 2;
11
11
  var INAPPLICABLE_STATUS = "C";
12
12
 
@@ -74160,9 +74160,9 @@ Usage:
74160
74160
  ultra11y init [--hook] [--ci] [--baseline] [--fail-on blocking|major|minor]
74161
74161
  ultra11y judge --in <audit.json> [--standard <pack>] [--runner api|claude|codex] [--grain batch|criterion] [--max <n>] [--model <id>] [--effort <level>] [--max-budget-usd <n>] [--timeout <s>] [--out <dir>] [--apply] (adjudicate manual criteria \u2014 api needs ANTHROPIC_API_KEY; claude/codex reuse their CLI login; cli aliases claude)
74162
74162
  ultra11y pack check <pack.json> [--guidance <g.json>] [--json] | pack scaffold
74163
- ultra11y scan <url|file\u2026> [--runtime auto|local|docker] [--cwd <dir>] [--storage-state <file>] [--no-interact] [--interact-clicks] [--no-snapshot] [--merge <audit.json>] [--out <dir>] [--json]
74164
- ultra11y scan --sample [--runtime \u2026] [--cwd <dir>] [--storage-state <file>] [--merge <audit.json>] [--json] (scan the .ultra11yrc.json page sample)
74165
- ultra11y scan --sitemap <url> | --crawl <url> [--depth <n>] [--max <n>] [--runtime \u2026] [--cwd <dir>] [--merge <audit.json>] [--json]
74163
+ ultra11y scan <url|file\u2026> [--runtime auto|local|docker] [--cwd <dir>] [--root <dir>] [--storage-state <file>] [--no-interact] [--interact-clicks] [--no-snapshot] [--merge <audit.json>] [--out <dir>] [--json]
74164
+ ultra11y scan --sample [--runtime \u2026] [--cwd <dir>] [--root <dir>] [--storage-state <file>] [--merge <audit.json>] [--json] (scan the .ultra11yrc.json page sample)
74165
+ ultra11y scan --sitemap <url> | --crawl <url> [--depth <n>] [--max <n>] [--runtime \u2026] [--cwd <dir>] [--root <dir>] [--merge <audit.json>] [--json]
74166
74166
  ultra11y scan --clean (remove the dynamic-tier Docker image + temp contexts)
74167
74167
  ultra11y sample check [--standard <pack>] [--json] (lint the .ultra11yrc.json page sample vs the standard's required page kinds)
74168
74168
  ultra11y snapshot write [--root <dir>] [--fail-on blocking|major|minor] [--json] (payload on stdin \u2192 .ultra11y/pages/<id>/ + audit it)
@@ -74406,7 +74406,8 @@ Options:
74406
74406
  --no-captures audit: do NOT auto-detect/ingest .ultra11y/captures nor .ultra11y/pages
74407
74407
  --e2e render: write the Playwright/Cypress fixtures into .ultra11y/e2e/
74408
74408
  --runner <name> render --e2e: force playwright|cypress instead of auto-detecting
74409
- --root <dir> snapshot: project root holding .ultra11y/pages (default: .)
74409
+ --root <dir> snapshot, scan: project root holding .ultra11y/pages (default: . \u2014
74410
+ scan writes the snapshots it collects under it)
74410
74411
  --port <n> dev: port for the side-car (default: 4111); mcp: HTTP transport port
74411
74412
  --transport <k> mcp: stdio (default) or http
74412
74413
  --bind <addr> mcp --transport http: address to bind (default 127.0.0.1)
@@ -77031,6 +77032,10 @@ Iterated over ${rounds} round(s) to a fixpoint \u2014 ${totalWritten} file(s) wr
77031
77032
  }
77032
77033
  return 0;
77033
77034
  }
77035
+ function scanSnapshotRoot(flags2) {
77036
+ if (flags2["no-snapshot"] === true) return void 0;
77037
+ return typeof flags2.root === "string" && flags2.root ? resolve17(flags2.root) : process.cwd();
77038
+ }
77034
77039
  async function cmdScan(p) {
77035
77040
  const standard = stdOf(p, "scan");
77036
77041
  if (standard === null) return 2;
@@ -77083,7 +77088,7 @@ async function cmdScan(p) {
77083
77088
  const interactClicks = p.flags["interact-clicks"] === true;
77084
77089
  const sitemap = typeof p.flags.sitemap === "string" ? p.flags.sitemap : void 0;
77085
77090
  const crawl = typeof p.flags.crawl === "string" ? p.flags.crawl : void 0;
77086
- const snapshotRoot = p.flags["no-snapshot"] === true ? void 0 : process.cwd();
77091
+ const snapshotRoot = scanSnapshotRoot(p.flags);
77087
77092
  const useSample = p.flags.sample === true;
77088
77093
  let sampleConfig;
77089
77094
  if (useSample) {
@@ -77768,6 +77773,7 @@ export {
77768
77773
  COMMANDS,
77769
77774
  REMOVED_FLAGS,
77770
77775
  main,
77771
- parseArgs
77776
+ parseArgs,
77777
+ scanSnapshotRoot
77772
77778
  };
77773
77779
  // "Copyright" and "@license" are already caught by DIRECTIVE_RE.
@@ -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.5
6
+ version: 5.44.0
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.5";
9
+ var VERSION = "5.44.0";
10
10
  var SCHEMA_VERSION = 2;
11
11
  var INAPPLICABLE_STATUS = "C";
12
12
 
@@ -74160,9 +74160,9 @@ Usage:
74160
74160
  ultra11y init [--hook] [--ci] [--baseline] [--fail-on blocking|major|minor]
74161
74161
  ultra11y judge --in <audit.json> [--standard <pack>] [--runner api|claude|codex] [--grain batch|criterion] [--max <n>] [--model <id>] [--effort <level>] [--max-budget-usd <n>] [--timeout <s>] [--out <dir>] [--apply] (adjudicate manual criteria \u2014 api needs ANTHROPIC_API_KEY; claude/codex reuse their CLI login; cli aliases claude)
74162
74162
  ultra11y pack check <pack.json> [--guidance <g.json>] [--json] | pack scaffold
74163
- ultra11y scan <url|file\u2026> [--runtime auto|local|docker] [--cwd <dir>] [--storage-state <file>] [--no-interact] [--interact-clicks] [--no-snapshot] [--merge <audit.json>] [--out <dir>] [--json]
74164
- ultra11y scan --sample [--runtime \u2026] [--cwd <dir>] [--storage-state <file>] [--merge <audit.json>] [--json] (scan the .ultra11yrc.json page sample)
74165
- ultra11y scan --sitemap <url> | --crawl <url> [--depth <n>] [--max <n>] [--runtime \u2026] [--cwd <dir>] [--merge <audit.json>] [--json]
74163
+ ultra11y scan <url|file\u2026> [--runtime auto|local|docker] [--cwd <dir>] [--root <dir>] [--storage-state <file>] [--no-interact] [--interact-clicks] [--no-snapshot] [--merge <audit.json>] [--out <dir>] [--json]
74164
+ ultra11y scan --sample [--runtime \u2026] [--cwd <dir>] [--root <dir>] [--storage-state <file>] [--merge <audit.json>] [--json] (scan the .ultra11yrc.json page sample)
74165
+ ultra11y scan --sitemap <url> | --crawl <url> [--depth <n>] [--max <n>] [--runtime \u2026] [--cwd <dir>] [--root <dir>] [--merge <audit.json>] [--json]
74166
74166
  ultra11y scan --clean (remove the dynamic-tier Docker image + temp contexts)
74167
74167
  ultra11y sample check [--standard <pack>] [--json] (lint the .ultra11yrc.json page sample vs the standard's required page kinds)
74168
74168
  ultra11y snapshot write [--root <dir>] [--fail-on blocking|major|minor] [--json] (payload on stdin \u2192 .ultra11y/pages/<id>/ + audit it)
@@ -74406,7 +74406,8 @@ Options:
74406
74406
  --no-captures audit: do NOT auto-detect/ingest .ultra11y/captures nor .ultra11y/pages
74407
74407
  --e2e render: write the Playwright/Cypress fixtures into .ultra11y/e2e/
74408
74408
  --runner <name> render --e2e: force playwright|cypress instead of auto-detecting
74409
- --root <dir> snapshot: project root holding .ultra11y/pages (default: .)
74409
+ --root <dir> snapshot, scan: project root holding .ultra11y/pages (default: . \u2014
74410
+ scan writes the snapshots it collects under it)
74410
74411
  --port <n> dev: port for the side-car (default: 4111); mcp: HTTP transport port
74411
74412
  --transport <k> mcp: stdio (default) or http
74412
74413
  --bind <addr> mcp --transport http: address to bind (default 127.0.0.1)
@@ -77031,6 +77032,10 @@ Iterated over ${rounds} round(s) to a fixpoint \u2014 ${totalWritten} file(s) wr
77031
77032
  }
77032
77033
  return 0;
77033
77034
  }
77035
+ function scanSnapshotRoot(flags2) {
77036
+ if (flags2["no-snapshot"] === true) return void 0;
77037
+ return typeof flags2.root === "string" && flags2.root ? resolve17(flags2.root) : process.cwd();
77038
+ }
77034
77039
  async function cmdScan(p) {
77035
77040
  const standard = stdOf(p, "scan");
77036
77041
  if (standard === null) return 2;
@@ -77083,7 +77088,7 @@ async function cmdScan(p) {
77083
77088
  const interactClicks = p.flags["interact-clicks"] === true;
77084
77089
  const sitemap = typeof p.flags.sitemap === "string" ? p.flags.sitemap : void 0;
77085
77090
  const crawl = typeof p.flags.crawl === "string" ? p.flags.crawl : void 0;
77086
- const snapshotRoot = p.flags["no-snapshot"] === true ? void 0 : process.cwd();
77091
+ const snapshotRoot = scanSnapshotRoot(p.flags);
77087
77092
  const useSample = p.flags.sample === true;
77088
77093
  let sampleConfig;
77089
77094
  if (useSample) {
@@ -77768,6 +77773,7 @@ export {
77768
77773
  COMMANDS,
77769
77774
  REMOVED_FLAGS,
77770
77775
  main,
77771
- parseArgs
77776
+ parseArgs,
77777
+ scanSnapshotRoot
77772
77778
  };
77773
77779
  // "Copyright" and "@license" are already caught by DIRECTIVE_RE.
@@ -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.5
6
+ version: 5.44.0
7
7
  ---
8
8
 
9
9
  # ultra11y — audit WCAG 2.2 AA and write accessible markup
@@ -233,7 +233,8 @@ and the scan stops there. Point `--crawl` at a real entry page, or pass the URLs
233
233
  `scan` does not only keep findings: each page it visits is persisted to
234
234
  `.ultra11y/pages/<id>/` (DOM + computed styles + boxes + stylesheets + a viewport
235
235
  screenshot). The browser is already on the page, so this costs one `evaluate`. `--no-snapshot`
236
- opts out.
236
+ opts out; `--root <dir>` relocates the tree (default: the working directory — `--cwd` is
237
+ where Playwright resolves from, not where snapshots land).
237
238
 
238
239
  ### …and what it MEASURED, not only what it saw
239
240
 
@@ -166,9 +166,10 @@ repo it does not own — write the run's intermediates out-of-tree and let only
166
166
  dated report land in the project, if at all.
167
167
 
168
168
  `.ultra11y/pages/` is written only by the page-snapshot commands (`scan`, `snapshot`,
169
- `dev`). `snapshot`, `dev` and `pages discover` take `--root` to relocate it; `scan` does not —
170
- it writes under the current working directory, so run it from the directory that should
171
- hold the snapshots. `audit`, `report`, `prd`, `tickets`, `verify` and `check` never touch it.
169
+ `dev`). All of them take `--root` to relocate it — for `scan`, where the snapshots it
170
+ collects are written (`--cwd` stays where Playwright resolves from), so an orchestrator can
171
+ run from the audited checkout without dirtying it. `audit`, `report`, `prd`, `tickets`,
172
+ `verify` and `check` never touch it.
172
173
 
173
174
  ## Exit codes
174
175
 
@@ -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.5";
9
+ var VERSION = "5.44.0";
10
10
  var SCHEMA_VERSION = 2;
11
11
  var INAPPLICABLE_STATUS = "C";
12
12
 
@@ -74160,9 +74160,9 @@ Usage:
74160
74160
  ultra11y init [--hook] [--ci] [--baseline] [--fail-on blocking|major|minor]
74161
74161
  ultra11y judge --in <audit.json> [--standard <pack>] [--runner api|claude|codex] [--grain batch|criterion] [--max <n>] [--model <id>] [--effort <level>] [--max-budget-usd <n>] [--timeout <s>] [--out <dir>] [--apply] (adjudicate manual criteria \u2014 api needs ANTHROPIC_API_KEY; claude/codex reuse their CLI login; cli aliases claude)
74162
74162
  ultra11y pack check <pack.json> [--guidance <g.json>] [--json] | pack scaffold
74163
- ultra11y scan <url|file\u2026> [--runtime auto|local|docker] [--cwd <dir>] [--storage-state <file>] [--no-interact] [--interact-clicks] [--no-snapshot] [--merge <audit.json>] [--out <dir>] [--json]
74164
- ultra11y scan --sample [--runtime \u2026] [--cwd <dir>] [--storage-state <file>] [--merge <audit.json>] [--json] (scan the .ultra11yrc.json page sample)
74165
- ultra11y scan --sitemap <url> | --crawl <url> [--depth <n>] [--max <n>] [--runtime \u2026] [--cwd <dir>] [--merge <audit.json>] [--json]
74163
+ ultra11y scan <url|file\u2026> [--runtime auto|local|docker] [--cwd <dir>] [--root <dir>] [--storage-state <file>] [--no-interact] [--interact-clicks] [--no-snapshot] [--merge <audit.json>] [--out <dir>] [--json]
74164
+ ultra11y scan --sample [--runtime \u2026] [--cwd <dir>] [--root <dir>] [--storage-state <file>] [--merge <audit.json>] [--json] (scan the .ultra11yrc.json page sample)
74165
+ ultra11y scan --sitemap <url> | --crawl <url> [--depth <n>] [--max <n>] [--runtime \u2026] [--cwd <dir>] [--root <dir>] [--merge <audit.json>] [--json]
74166
74166
  ultra11y scan --clean (remove the dynamic-tier Docker image + temp contexts)
74167
74167
  ultra11y sample check [--standard <pack>] [--json] (lint the .ultra11yrc.json page sample vs the standard's required page kinds)
74168
74168
  ultra11y snapshot write [--root <dir>] [--fail-on blocking|major|minor] [--json] (payload on stdin \u2192 .ultra11y/pages/<id>/ + audit it)
@@ -74406,7 +74406,8 @@ Options:
74406
74406
  --no-captures audit: do NOT auto-detect/ingest .ultra11y/captures nor .ultra11y/pages
74407
74407
  --e2e render: write the Playwright/Cypress fixtures into .ultra11y/e2e/
74408
74408
  --runner <name> render --e2e: force playwright|cypress instead of auto-detecting
74409
- --root <dir> snapshot: project root holding .ultra11y/pages (default: .)
74409
+ --root <dir> snapshot, scan: project root holding .ultra11y/pages (default: . \u2014
74410
+ scan writes the snapshots it collects under it)
74410
74411
  --port <n> dev: port for the side-car (default: 4111); mcp: HTTP transport port
74411
74412
  --transport <k> mcp: stdio (default) or http
74412
74413
  --bind <addr> mcp --transport http: address to bind (default 127.0.0.1)
@@ -77031,6 +77032,10 @@ Iterated over ${rounds} round(s) to a fixpoint \u2014 ${totalWritten} file(s) wr
77031
77032
  }
77032
77033
  return 0;
77033
77034
  }
77035
+ function scanSnapshotRoot(flags2) {
77036
+ if (flags2["no-snapshot"] === true) return void 0;
77037
+ return typeof flags2.root === "string" && flags2.root ? resolve17(flags2.root) : process.cwd();
77038
+ }
77034
77039
  async function cmdScan(p) {
77035
77040
  const standard = stdOf(p, "scan");
77036
77041
  if (standard === null) return 2;
@@ -77083,7 +77088,7 @@ async function cmdScan(p) {
77083
77088
  const interactClicks = p.flags["interact-clicks"] === true;
77084
77089
  const sitemap = typeof p.flags.sitemap === "string" ? p.flags.sitemap : void 0;
77085
77090
  const crawl = typeof p.flags.crawl === "string" ? p.flags.crawl : void 0;
77086
- const snapshotRoot = p.flags["no-snapshot"] === true ? void 0 : process.cwd();
77091
+ const snapshotRoot = scanSnapshotRoot(p.flags);
77087
77092
  const useSample = p.flags.sample === true;
77088
77093
  let sampleConfig;
77089
77094
  if (useSample) {
@@ -77768,6 +77773,7 @@ export {
77768
77773
  COMMANDS,
77769
77774
  REMOVED_FLAGS,
77770
77775
  main,
77771
- parseArgs
77776
+ parseArgs,
77777
+ scanSnapshotRoot
77772
77778
  };
77773
77779
  // "Copyright" and "@license" are already caught by DIRECTIVE_RE.
@@ -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.5'
30
+ ULTRA11Y_VERSION: '5.44.0'
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/cli.ts CHANGED
@@ -160,9 +160,9 @@ Usage:
160
160
  ultra11y init [--hook] [--ci] [--baseline] [--fail-on blocking|major|minor]
161
161
  ultra11y judge --in <audit.json> [--standard <pack>] [--runner api|claude|codex] [--grain batch|criterion] [--max <n>] [--model <id>] [--effort <level>] [--max-budget-usd <n>] [--timeout <s>] [--out <dir>] [--apply] (adjudicate manual criteria — api needs ANTHROPIC_API_KEY; claude/codex reuse their CLI login; cli aliases claude)
162
162
  ultra11y pack check <pack.json> [--guidance <g.json>] [--json] | pack scaffold
163
- ultra11y scan <url|file…> [--runtime auto|local|docker] [--cwd <dir>] [--storage-state <file>] [--no-interact] [--interact-clicks] [--no-snapshot] [--merge <audit.json>] [--out <dir>] [--json]
164
- ultra11y scan --sample [--runtime …] [--cwd <dir>] [--storage-state <file>] [--merge <audit.json>] [--json] (scan the .ultra11yrc.json page sample)
165
- ultra11y scan --sitemap <url> | --crawl <url> [--depth <n>] [--max <n>] [--runtime …] [--cwd <dir>] [--merge <audit.json>] [--json]
163
+ ultra11y scan <url|file…> [--runtime auto|local|docker] [--cwd <dir>] [--root <dir>] [--storage-state <file>] [--no-interact] [--interact-clicks] [--no-snapshot] [--merge <audit.json>] [--out <dir>] [--json]
164
+ ultra11y scan --sample [--runtime …] [--cwd <dir>] [--root <dir>] [--storage-state <file>] [--merge <audit.json>] [--json] (scan the .ultra11yrc.json page sample)
165
+ ultra11y scan --sitemap <url> | --crawl <url> [--depth <n>] [--max <n>] [--runtime …] [--cwd <dir>] [--root <dir>] [--merge <audit.json>] [--json]
166
166
  ultra11y scan --clean (remove the dynamic-tier Docker image + temp contexts)
167
167
  ultra11y sample check [--standard <pack>] [--json] (lint the .ultra11yrc.json page sample vs the standard's required page kinds)
168
168
  ultra11y snapshot write [--root <dir>] [--fail-on blocking|major|minor] [--json] (payload on stdin → .ultra11y/pages/<id>/ + audit it)
@@ -406,7 +406,8 @@ Options:
406
406
  --no-captures audit: do NOT auto-detect/ingest .ultra11y/captures nor .ultra11y/pages
407
407
  --e2e render: write the Playwright/Cypress fixtures into .ultra11y/e2e/
408
408
  --runner <name> render --e2e: force playwright|cypress instead of auto-detecting
409
- --root <dir> snapshot: project root holding .ultra11y/pages (default: .)
409
+ --root <dir> snapshot, scan: project root holding .ultra11y/pages (default: . —
410
+ scan writes the snapshots it collects under it)
410
411
  --port <n> dev: port for the side-car (default: 4111); mcp: HTTP transport port
411
412
  --transport <k> mcp: stdio (default) or http
412
413
  --bind <addr> mcp --transport http: address to bind (default 127.0.0.1)
@@ -4028,6 +4029,16 @@ async function cmdFix(p: ParsedArgs): Promise<number> {
4028
4029
  return 0;
4029
4030
  }
4030
4031
 
4032
+ /** Where `scan` writes the page snapshots it collects: `--root <dir>` when given — the same
4033
+ * contract as `snapshot write`, `dev` and `pages discover --from-snapshots` — else the
4034
+ * working directory. Absolute either way, as it always was: the merge audits the snapshot
4035
+ * DOMs by this path. Undefined under `--no-snapshot`: nothing is persisted. `--cwd` plays
4036
+ * no part here: it keeps its own meaning, where Playwright resolves from. */
4037
+ export function scanSnapshotRoot(flags: ParsedArgs["flags"]): string | undefined {
4038
+ if (flags["no-snapshot"] === true) return undefined;
4039
+ return typeof flags.root === "string" && flags.root ? resolve(flags.root) : process.cwd();
4040
+ }
4041
+
4031
4042
  async function cmdScan(p: ParsedArgs): Promise<number> {
4032
4043
  // `scan` takes `--standard` for the same reason `audit` now does: it REWRITES
4033
4044
  // audit-latest.json mid-chain, and a merge that silently re-keyed an RGAA document back to
@@ -4135,7 +4146,7 @@ async function cmdScan(p: ParsedArgs): Promise<number> {
4135
4146
  // is already on the page, so this costs one `evaluate` — and it is what lets the page be
4136
4147
  // re-audited offline and earn a real per-page verdict instead of staying "to assess"
4137
4148
  // forever (src/pages.ts). `--no-snapshot` opts out.
4138
- const snapshotRoot = p.flags["no-snapshot"] === true ? undefined : process.cwd();
4149
+ const snapshotRoot = scanSnapshotRoot(p.flags);
4139
4150
 
4140
4151
  // --sample: iterate the NORMATIVE page sample from `.ultra11yrc.json` (per-page
4141
4152
  // storageState overrides --storage-state). Loaded + validated here (hard error on a
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.5";
3
+ export const VERSION = "5.44.0";
4
4
  export const SCHEMA_VERSION = 2;
5
5
 
6
6
  // Lang = the UI FRAME's language — the `L` localization tables each module (report,