nfunc-mcp 0.4.0 → 0.5.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.
@@ -1,12 +1,68 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join, resolve } from "node:path";
1
4
  import { z } from "zod";
2
5
  import { runShell } from "../utils/shellRunner.js";
3
6
  import { parsePa11yJSON } from "../utils/outputParsers.js";
4
- import { shellErrorResponse, parseErrorResponse, } from "../utils/toolResponse.js";
5
7
  import { formatA11yFinding } from "../mappers/defectFormatter.js";
6
8
  import { dedupeA11yFindings } from "../mappers/a11yDedupe.js";
7
9
  import { sortFindingsByPriority } from "../mappers/priorityMapper.js";
10
+ import { resolveUrlInputs } from "../utils/urlInput.js";
11
+ import { compareRuns } from "../mappers/runComparator.js";
12
+ import { summariseConformance, } from "../mappers/wcagLevels.js";
13
+ import { DEFAULT_MAX_SECONDS_PER_CALL, decodeCursor, encodeCursor, elapsedSeconds, filterCompleted, hasBudget, mergeIndex, readIndex, slugForUrl, } from "../utils/batchState.js";
14
+ /** A pa11y run is faster than Lighthouse but still Chrome. Measured mid-range. */
15
+ const TYPICAL_RUN_MS = 15_000;
16
+ const DEFAULT_OUTPUT_DIR = "./a11y-reports";
17
+ /**
18
+ * pa11y has no --viewport flag, but its --config file is passed through to
19
+ * Puppeteer, so a mobile viewport goes in there. The numbers match Lighthouse's
20
+ * mobile emulation (412x823, 2x DPR, touch) so an a11y run and a perf run are
21
+ * describing the same rendered page rather than two different layouts.
22
+ *
23
+ * Desktop deliberately writes no config at all: pa11y's own default viewport is
24
+ * already desktop-shaped, and passing a config would override any pa11y.json a
25
+ * project has of its own.
26
+ */
27
+ const MOBILE_VIEWPORT = {
28
+ viewport: { width: 412, height: 823, deviceScaleFactor: 2, isMobile: true, hasTouch: true },
29
+ };
8
30
  const inputShape = {
9
- url: z.string().url(),
31
+ url: z
32
+ .string()
33
+ .min(1)
34
+ .describe("One URL, several comma- or newline-separated URLs, or a path to a CSV " +
35
+ "containing a URL column. More than one URL switches the tool into " +
36
+ "batch mode."),
37
+ urls: z.array(z.string()).optional(),
38
+ target_level: z
39
+ .enum(["A", "AA", "AAA"])
40
+ .optional()
41
+ .describe("WCAG conformance level the project has committed to. Default 'AA' — the " +
42
+ "legal and industry bar for essentially all commercial work. This drives " +
43
+ "priority: a Level A failure is P1 because it puts the target out of " +
44
+ "reach entirely, a Level AA failure is P2, and a criterion above the " +
45
+ "target is P3 (an enhancement, not a gap)."),
46
+ form_factor: z
47
+ .enum(["desktop", "mobile", "both"])
48
+ .optional()
49
+ .describe("Viewport to test at. 'desktop' (default) uses pa11y's own viewport. " +
50
+ "'mobile' emulates a 412x823 touch device, matching run_lighthouse's " +
51
+ "mobile profile — worth using when the mobile layout differs, since " +
52
+ "touch-target and reflow failures only appear there. 'both' runs each."),
53
+ output_dir: z.string().optional(),
54
+ cursor: z.string().optional().describe("Resume token from a previous batch call."),
55
+ max_seconds_per_call: z.number().int().min(30).max(900).optional(),
56
+ skip_completed: z.boolean().optional(),
57
+ baseline_dir: z
58
+ .string()
59
+ .optional()
60
+ .describe("Compare this run against a previous run's index and report what was " +
61
+ "fixed, what still fails, and what is newly introduced. Point it at an " +
62
+ "earlier output_dir. Answers 'did my fix work, and did I break " +
63
+ "anything?' — a violation count alone cannot, since a fix that also " +
64
+ "introduces a defect leaves the total unchanged. May be the same as " +
65
+ "output_dir; the baseline is read before anything is written."),
10
66
  standard: z.enum(["WCAG2A", "WCAG2AA", "WCAG2AAA"]).optional(),
11
67
  ignore: z.array(z.string()).optional(),
12
68
  runner: z
@@ -21,84 +77,453 @@ const inputShape = {
21
77
  "the two and merges the results, which is the most thorough option " +
22
78
  "and roughly doubles runtime."),
23
79
  };
80
+ /** Path to a pa11y config carrying a mobile viewport, written once per process. */
81
+ let mobileConfigPath = null;
82
+ async function mobileConfig() {
83
+ if (mobileConfigPath)
84
+ return mobileConfigPath;
85
+ const path = join(tmpdir(), `nfunc-pa11y-mobile-${process.pid}.json`);
86
+ await writeFile(path, JSON.stringify(MOBILE_VIEWPORT, null, 2), "utf8");
87
+ mobileConfigPath = path;
88
+ return path;
89
+ }
90
+ async function auditUrl(url, engines, standard, ignore, formFactor, target) {
91
+ const configPath = formFactor === "mobile" ? await mobileConfig() : null;
92
+ const buildArgs = (engine) => {
93
+ const args = [url, "--reporter", "json", "--standard", standard, "--runner", engine];
94
+ if (ignore && ignore.length > 0)
95
+ args.push("--ignore", ignore.join(";"));
96
+ if (configPath)
97
+ args.push("--config", configPath);
98
+ return args;
99
+ };
100
+ // Engines run concurrently: unlike Lighthouse, pa11y is not measuring time,
101
+ // so CPU contention costs nothing but wall clock.
102
+ const results = await Promise.all(engines.map((e) => runShell("pa11y", buildArgs(e), { timeoutMs: 120_000 })));
103
+ // pa11y exits 2 when issues are found — a successful run with data. Exit 1
104
+ // means pa11y itself failed (browser launch, bad URL).
105
+ const usable = results.filter((r) => (r.exitCode === 0 || r.exitCode === 2) && r.stdout);
106
+ if (usable.length === 0) {
107
+ return {
108
+ findings: [],
109
+ rawCount: 0,
110
+ runnersUsed: [],
111
+ error: results[0]?.stderr.slice(0, 300) || `exit ${results[0]?.exitCode}`,
112
+ };
113
+ }
114
+ const rawFindings = [];
115
+ for (const result of usable) {
116
+ let parsed;
117
+ try {
118
+ parsed = parsePa11yJSON(result.stdout);
119
+ }
120
+ catch (err) {
121
+ return { findings: [], rawCount: 0, runnersUsed: [], error: `unparseable pa11y JSON: ${err.message}` };
122
+ }
123
+ for (const violation of parsed.violations) {
124
+ const finding = formatA11yFinding(violation, target);
125
+ if (finding)
126
+ rawFindings.push(finding);
127
+ }
128
+ }
129
+ // Collapse repeats of the same defect before counting — see a11yDedupe for
130
+ // why pa11y produces them. Dedupes *within* an engine only: the key is
131
+ // (rule_code, selector) and the engines emit different code shapes for the
132
+ // same defect, so an element both flag appears twice. Deliberate — two
133
+ // independent engines agreeing is corroboration worth seeing.
134
+ const { findings, rawCount } = dedupeA11yFindings(rawFindings);
135
+ sortFindingsByPriority(findings);
136
+ return {
137
+ findings,
138
+ rawCount,
139
+ runnersUsed: engines.slice(0, usable.length),
140
+ ...(usable.length < engines.length
141
+ ? { partial: `Only ${usable.length} of ${engines.length} runners produced output.` }
142
+ : {}),
143
+ };
144
+ }
145
+ const ruleIdOf = (f) => String(f.evidence["rule_code"] ?? f.title);
146
+ function toDefects(findings) {
147
+ return findings.map((f) => ({ id: ruleIdOf(f), priority: f.priority, title: f.title }));
148
+ }
149
+ /** Index records → the flat defect list the comparator works on. */
150
+ function recordsToDefectRefs(records) {
151
+ const refs = [];
152
+ for (const record of records) {
153
+ // Older indexes predate `defects` and only carry rule ids; fall back so a
154
+ // stale baseline degrades to a comparison without priorities rather than
155
+ // silently comparing nothing.
156
+ const defects = record.defects ?? record.rules.map((id) => ({ id, priority: "P2", title: id }));
157
+ for (const d of defects) {
158
+ refs.push({ url: record.url, variant: record.variant, id: d.id, priority: d.priority, title: d.title });
159
+ }
160
+ }
161
+ return refs;
162
+ }
163
+ /**
164
+ * Cross-page rollup.
165
+ *
166
+ * The useful question over a set of pages is not "how many violations" but
167
+ * "which defects are in the shared layout". A rule failing on nearly every
168
+ * page is in the header, the footer or the base template — one fix clears all
169
+ * of them — while a rule failing on one page is that page's own bug. Volume
170
+ * alone cannot tell those apart, so the rollup counts pages per rule.
171
+ */
172
+ /**
173
+ * Cross-page conformance.
174
+ *
175
+ * A criterion failing on one page fails the site's conformance claim just as
176
+ * surely as one failing everywhere — conformance is per page, and a statement
177
+ * about a site is only as good as its worst page. So the rollup is a union of
178
+ * failing criteria, with the pages each affects.
179
+ */
180
+ function rollUpConformance(records, target) {
181
+ const byCriterion = new Map();
182
+ for (const record of records) {
183
+ for (const failed of record.conformance?.failed_criteria ?? []) {
184
+ const entry = byCriterion.get(failed.criterion) ?? {
185
+ criterion: failed.criterion,
186
+ name: failed.name,
187
+ level: failed.level,
188
+ pages: new Set(),
189
+ blocks_target: failed.blocks_target,
190
+ };
191
+ entry.pages.add(record.url);
192
+ byCriterion.set(failed.criterion, entry);
193
+ }
194
+ }
195
+ const pages = new Set(records.map((r) => r.url)).size;
196
+ const all = [...byCriterion.values()].sort((a, b) => a.level.length - b.level.length || a.criterion.localeCompare(b.criterion));
197
+ const blocking = all.filter((c) => c.blocks_target);
198
+ const conformantPages = records.filter((r) => r.conformance?.conformant).length;
199
+ return {
200
+ target_level: target,
201
+ pages_conformant: conformantPages,
202
+ pages_total: pages,
203
+ failing_criteria: {
204
+ A: blocking.filter((c) => c.level === "A").length,
205
+ AA: blocking.filter((c) => c.level === "AA").length,
206
+ AAA: blocking.filter((c) => c.level === "AAA").length,
207
+ },
208
+ beyond_target: all.length - blocking.length,
209
+ criteria: all.map((c) => ({
210
+ criterion: c.criterion,
211
+ name: c.name,
212
+ level: c.level,
213
+ pages_affected: c.pages.size,
214
+ of_pages: pages,
215
+ blocks_target: c.blocks_target,
216
+ })),
217
+ summary: blocking.length === 0
218
+ ? `No Level ${target} conformance failures across ${pages} page(s) by automated testing. Manual verification still required — automated tools reach roughly a third of WCAG criteria.`
219
+ : `${conformantPages} of ${pages} page(s) pass automated Level ${target} checks. ` +
220
+ `${blocking.length} distinct criteri${blocking.length === 1 ? "on" : "a"} fail across the set` +
221
+ (blocking.some((c) => c.level === "A")
222
+ ? `, including ${blocking.filter((c) => c.level === "A").length} at Level A — the floor, which must be cleared before Level ${target} is reachable.`
223
+ : "."),
224
+ };
225
+ }
226
+ function aggregateA11y(records, target) {
227
+ const pages = new Set(records.map((r) => r.url)).size;
228
+ const byRule = new Map();
229
+ for (const record of records) {
230
+ for (const rule of record.rules) {
231
+ const entry = byRule.get(rule) ?? { rule, pages: new Set(), runs: 0 };
232
+ entry.pages.add(record.url);
233
+ entry.runs++;
234
+ byRule.set(rule, entry);
235
+ }
236
+ }
237
+ const rules = [...byRule.values()]
238
+ .map((e) => ({
239
+ rule: e.rule,
240
+ pages_affected: e.pages.size,
241
+ of_pages: pages,
242
+ pct: Math.round((e.pages.size / pages) * 100),
243
+ // A rule on 80%+ of pages is shared-layout, not per-page. Same threshold
244
+ // as the PSI systemic collapse, for the same reason.
245
+ shared_layout: e.pages.size / pages >= 0.8 && pages >= 3,
246
+ }))
247
+ .sort((a, b) => b.pages_affected - a.pages_affected);
248
+ const worst = [...records]
249
+ .sort((a, b) => b.p1_count - a.p1_count || b.violation_count - a.violation_count)
250
+ .slice(0, 3)
251
+ .map((r) => ({ url: r.url, variant: r.variant, p1_count: r.p1_count, violation_count: r.violation_count }));
252
+ return {
253
+ pages,
254
+ run_count: records.length,
255
+ captured_at: new Date().toISOString(),
256
+ conformance: rollUpConformance(records, target),
257
+ totals: {
258
+ violations: records.reduce((n, r) => n + r.violation_count, 0),
259
+ p1: records.reduce((n, r) => n + r.p1_count, 0),
260
+ clean_runs: records.filter((r) => r.violation_count === 0).length,
261
+ },
262
+ by_variant: [...new Set(records.map((r) => r.variant))].map((variant) => {
263
+ const group = records.filter((r) => r.variant === variant);
264
+ return {
265
+ variant,
266
+ runs: group.length,
267
+ violations: group.reduce((n, r) => n + r.violation_count, 0),
268
+ p1: group.reduce((n, r) => n + r.p1_count, 0),
269
+ };
270
+ }),
271
+ rules,
272
+ shared_layout_rules: rules.filter((r) => r.shared_layout).map((r) => r.rule),
273
+ worst_pages: worst,
274
+ };
275
+ }
276
+ const text = (payload) => ({
277
+ content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
278
+ });
24
279
  export function registerAccessibilityTool(server) {
25
280
  server.registerTool("run_accessibility_check", {
26
- description: "Runs pa11y against a URL and returns a QA-style report of WCAG " +
27
- "violations prioritised P1/P2/P3 (notices are filtered out). " +
281
+ description: "Runs pa11y and returns a QA-style report of WCAG violations " +
282
+ "prioritised P1/P2/P3 (notices filtered out). " +
283
+ "\n\n" +
284
+ "**Accepts one URL, a comma- or newline-separated list, or a path to a " +
285
+ "CSV with a URL column.** Several URLs switch to batch mode: a running " +
286
+ "`_index.json` accumulates in `output_dir`, a `cursor` is returned to " +
287
+ "continue with, and the final call adds an `aggregate` block. That " +
288
+ "block answers the question a single-page run cannot — **which rules " +
289
+ "fail across most pages**, and are therefore in the shared header, " +
290
+ "footer or base template rather than being any one page's bug. " +
28
291
  "\n\n" +
29
- "Two engines are available via `runner`. htmlcs (default) checks WCAG " +
30
- "techniques and is strong on document structure, labels, and forms. " +
31
- "axe is Deque's engine and is materially stronger on ARIA — invalid " +
32
- "roles, missing required parent/child relationships, prohibited and " +
33
- "unsupported attributes — and on computed colour contrast. " +
34
- "**Prefer runner='axe' whenever the work under test involves ARIA, a " +
35
- "component library, or a design system**, and runner='both' for the " +
36
- "most thorough sweep. The two engines overlap only partly: on a real " +
37
- "commerce page htmlcs found unlabelled inputs and duplicate ids that " +
292
+ "Two engines via `runner`. htmlcs (default) is strong on WCAG " +
293
+ "techniques, document structure, labels and duplicate ids. axe is " +
294
+ "Deque's engine and is materially stronger on ARIA — roles, required " +
295
+ "parent/child relationships, prohibited and unsupported attributes — " +
296
+ "and on computed colour contrast. **Prefer runner='axe' whenever the " +
297
+ "work involves ARIA, a component library, or a design system**, and " +
298
+ "'both' for the most thorough sweep. The overlap is only partial: on a " +
299
+ "real commerce page htmlcs found unlabelled inputs and duplicate ids " +
38
300
  "axe did not, while axe found aria-allowed-attr, aria-required-parent " +
39
301
  "and image-alt failures htmlcs missed entirely. " +
40
302
  "\n\n" +
303
+ "`form_factor` defaults to desktop. Pass 'mobile' when the mobile " +
304
+ "layout differs — touch-target and reflow failures appear only there. " +
305
+ "\n\n" +
41
306
  "Requires the pa11y CLI on PATH (`npm install -g pa11y`).",
42
307
  inputSchema: inputShape,
43
- }, async ({ url, standard, ignore, runner }) => {
44
- const resolvedStandard = standard ?? "WCAG2AA";
308
+ }, async ({ url, urls, standard, ignore, runner, form_factor, target_level, output_dir, cursor, max_seconds_per_call, skip_completed, baseline_dir, }) => {
309
+ const target = target_level ?? "AA";
310
+ // Always test at AA or above, whatever the committed target.
311
+ //
312
+ // Testing only at Level A when the target is A would mean AA criteria are
313
+ // never checked, so they can neither fail nor be reported as
314
+ // enhancements — the run would silently hide information rather than
315
+ // classify it. Testing at AA and letting `target` decide what *blocks*
316
+ // keeps the classification honest: an AA finding under a Level A
317
+ // commitment is an enhancement, not a gap, and the report says so.
318
+ const resolvedStandard = standard ?? (target === "AAA" ? "WCAG2AAA" : "WCAG2AA");
45
319
  const resolvedRunner = runner ?? "htmlcs";
46
320
  const engines = resolvedRunner === "both" ? ["htmlcs", "axe"] : [resolvedRunner];
47
- const buildArgs = (engine) => {
48
- const args = [url, "--reporter", "json", "--standard", resolvedStandard,
49
- "--runner", engine];
50
- if (ignore && ignore.length > 0)
51
- args.push("--ignore", ignore.join(";"));
52
- return args;
321
+ const requestedFactor = form_factor ?? "desktop";
322
+ const factors = requestedFactor === "both" ? ["desktop", "mobile"] : [requestedFactor];
323
+ let resolved;
324
+ try {
325
+ resolved = resolveUrlInputs(url, urls);
326
+ }
327
+ catch (err) {
328
+ return {
329
+ ...text({ error: "unusable_url_input", message: err.message }),
330
+ isError: true,
331
+ };
332
+ }
333
+ const warnings = [...resolved.warnings];
334
+ // Read the baseline before anything is written, so baseline_dir and
335
+ // output_dir may be the same directory — "compare against the last run
336
+ // in here" is the natural way to use this.
337
+ const baselineRefs = baseline_dir
338
+ ? recordsToDefectRefs(await readIndex(resolve(baseline_dir)))
339
+ : null;
340
+ if (baseline_dir && baselineRefs && baselineRefs.length === 0) {
341
+ warnings.push(`No previous results found in ${resolve(baseline_dir)} — nothing to compare against. ` +
342
+ "Run once with output_dir set to create a baseline.");
343
+ }
344
+ const compareWith = async (records) => {
345
+ if (!baselineRefs)
346
+ return undefined;
347
+ const result = compareRuns(resolve(baseline_dir), baselineRefs, recordsToDefectRefs(records), {});
348
+ warnings.push(...result.warnings);
349
+ const { warnings: _dropped, ...rest } = result;
350
+ return rest;
53
351
  };
54
- // Engines run concurrently so "both" costs little more wall time than one.
55
- const results = await Promise.all(engines.map((e) => runShell("pa11y", buildArgs(e), { timeoutMs: 120_000 })));
56
- // pa11y exits 2 when issues are found — that's a successful run with data.
57
- // Exit 1 means pa11y itself failed (browser launch, bad URL, etc.).
58
- const usable = results.filter((r) => (r.exitCode === 0 || r.exitCode === 2) && r.stdout);
59
- if (usable.length === 0) {
60
- return shellErrorResponse("pa11y did not produce a usable report", results[0]);
61
- }
62
- const rawFindings = [];
63
- for (const result of usable) {
64
- let parsed;
65
- try {
66
- parsed = parsePa11yJSON(result.stdout);
352
+ // ---- Single URL, single viewport: unchanged contract --------------
353
+ if (resolved.urls.length === 1 && factors.length === 1) {
354
+ const target2 = resolved.urls[0];
355
+ const outcome = await auditUrl(target2, engines, resolvedStandard, ignore, factors[0], target);
356
+ if (outcome.error) {
357
+ return {
358
+ ...text({
359
+ error: "pa11y_failed",
360
+ url: target,
361
+ form_factor: factors[0],
362
+ message: outcome.error,
363
+ }),
364
+ isError: true,
365
+ };
67
366
  }
68
- catch (err) {
69
- return parseErrorResponse("Failed to parse pa11y JSON", err, result);
367
+ if (outcome.partial)
368
+ warnings.push(outcome.partial);
369
+ const record = {
370
+ url: target2,
371
+ variant: factors[0],
372
+ violation_count: outcome.findings.length,
373
+ raw_violation_count: outcome.rawCount,
374
+ p1_count: outcome.findings.filter((f) => f.priority === "P1").length,
375
+ rules: [...new Set(outcome.findings.map(ruleIdOf))],
376
+ defects: toDefects(outcome.findings),
377
+ conformance: summariseConformance(outcome.findings, target),
378
+ report_file: "",
379
+ };
380
+ // A single URL only touches disk when asked to. That keeps the
381
+ // original contract for a one-off check, while making the same call
382
+ // usable as a baseline for the next one.
383
+ let indexFile;
384
+ if (output_dir) {
385
+ const dir = resolve(output_dir);
386
+ await mkdir(dir, { recursive: true });
387
+ record.report_file = `${slugForUrl(target2)}_${factors[0]}.json`;
388
+ await writeFile(join(dir, record.report_file), JSON.stringify({ url: target2, form_factor: factors[0], standard: resolvedStandard,
389
+ runners: engines, violation_count: outcome.findings.length,
390
+ raw_violation_count: outcome.rawCount, findings: outcome.findings }, null, 2), "utf8");
391
+ indexFile = (await mergeIndex(dir, [record])).indexPath;
392
+ }
393
+ const comparison = await compareWith([record]);
394
+ return text({
395
+ url: target2,
396
+ standard: resolvedStandard,
397
+ runners: engines,
398
+ target_level: target,
399
+ conformance: summariseConformance(outcome.findings, target),
400
+ ...(factors[0] === "mobile" ? { form_factor: "mobile" } : {}),
401
+ violation_count: outcome.findings.length,
402
+ // Pre-dedup total, so a large drop between the two is explainable
403
+ // rather than looking like dropped findings.
404
+ raw_violation_count: outcome.rawCount,
405
+ findings: outcome.findings,
406
+ ...(indexFile ? { output_dir: resolve(output_dir), index_file: indexFile } : {}),
407
+ ...(comparison ? { comparison } : {}),
408
+ ...(warnings.length ? { warnings } : {}),
409
+ });
410
+ }
411
+ // ---- Batch --------------------------------------------------------
412
+ const dir = resolve(output_dir ?? DEFAULT_OUTPUT_DIR);
413
+ await mkdir(dir, { recursive: true });
414
+ const budgetMs = (max_seconds_per_call ?? DEFAULT_MAX_SECONDS_PER_CALL) * 1000;
415
+ const startedAt = Date.now();
416
+ const allUnits = resolved.urls.flatMap((u) => factors.map((factor) => ({ url: u, variant: factor })));
417
+ // When comparing, re-measuring is the whole point — skipping completed
418
+ // work would silently compare a run against itself.
419
+ const { units, skipped } = await filterCompleted(dir, allUnits, skip_completed ?? !baseline_dir, cursor);
420
+ if (skipped > 0) {
421
+ warnings.push(`Skipped ${skipped} URL/viewport pair(s) already in ${join(dir, "_index.json")}. ` +
422
+ "Pass skip_completed:false to re-test them.");
423
+ }
424
+ if (units.length === 0) {
425
+ return text({
426
+ complete: true,
427
+ progress: { done: 0, total: 0, failed: 0 },
428
+ message: "Every requested URL/viewport pair is already in the index.",
429
+ index_file: join(dir, "_index.json"),
430
+ warnings,
431
+ });
432
+ }
433
+ const start = decodeCursor(cursor);
434
+ const records = [];
435
+ const results = [];
436
+ const failures = [];
437
+ let index = start;
438
+ let budgetExhausted = false;
439
+ while (index < units.length) {
440
+ if (!hasBudget(startedAt, budgetMs, TYPICAL_RUN_MS * engines.length, index - start)) {
441
+ budgetExhausted = true;
442
+ break;
70
443
  }
71
- for (const violation of parsed.violations) {
72
- const finding = formatA11yFinding(violation);
73
- if (finding)
74
- rawFindings.push(finding);
444
+ const unit = units[index];
445
+ const factor = unit.variant;
446
+ const outcome = await auditUrl(unit.url, engines, resolvedStandard, ignore, factor, target);
447
+ if (outcome.error) {
448
+ failures.push({ url: unit.url, form_factor: factor, error: outcome.error });
449
+ index++;
450
+ continue;
75
451
  }
452
+ if (outcome.partial)
453
+ warnings.push(`${unit.url} (${factor}): ${outcome.partial}`);
454
+ const reportFile = `${slugForUrl(unit.url)}_${factor}.json`;
455
+ await writeFile(join(dir, reportFile), JSON.stringify({
456
+ url: unit.url,
457
+ form_factor: factor,
458
+ standard: resolvedStandard,
459
+ runners: engines,
460
+ violation_count: outcome.findings.length,
461
+ raw_violation_count: outcome.rawCount,
462
+ findings: outcome.findings,
463
+ }, null, 2), "utf8");
464
+ // Rule ids drive the cross-page rollup, so they are stored per run
465
+ // rather than recomputed from the findings later.
466
+ const rules = [
467
+ ...new Set(outcome.findings.map((f) => String(f.evidence["rule_code"] ?? f.title))),
468
+ ];
469
+ records.push({
470
+ url: unit.url,
471
+ variant: factor,
472
+ violation_count: outcome.findings.length,
473
+ raw_violation_count: outcome.rawCount,
474
+ p1_count: outcome.findings.filter((f) => f.priority === "P1").length,
475
+ rules,
476
+ defects: toDefects(outcome.findings),
477
+ conformance: summariseConformance(outcome.findings, target),
478
+ report_file: reportFile,
479
+ });
480
+ results.push({
481
+ url: unit.url,
482
+ form_factor: factor,
483
+ violation_count: outcome.findings.length,
484
+ raw_violation_count: outcome.rawCount,
485
+ conformance: summariseConformance(outcome.findings, target),
486
+ findings: outcome.findings,
487
+ report_file: reportFile,
488
+ });
489
+ index++;
490
+ }
491
+ const { indexPath } = await mergeIndex(dir, records);
492
+ const complete = index >= units.length;
493
+ if (budgetExhausted) {
494
+ warnings.push(`Stopped after ${elapsedSeconds(startedAt)}s to stay inside the per-call budget. ` +
495
+ "Call again with the cursor to continue.");
496
+ }
497
+ if (failures.length > 0) {
498
+ warnings.push(`${failures.length} run(s) failed. Call again with the same URLs and no cursor — ` +
499
+ "completed pairs are skipped, so only the gaps are retried.");
76
500
  }
77
- // Collapse repeats of the same defect before counting or sorting — see
78
- // a11yDedupe for why pa11y produces them. Note this dedupes *within* an
79
- // engine only: the key is (rule_code, selector), and the two engines emit
80
- // different code shapes for the same defect ("...1_1_1.H37" vs
81
- // "image-alt"), so an element both engines flag appears twice. That is
82
- // deliberate for now — two independent engines agreeing is corroboration
83
- // worth seeing, the same signal the Lighthouse/pa11y correlator promotes.
84
- const { findings, rawCount } = dedupeA11yFindings(rawFindings);
85
- sortFindingsByPriority(findings);
86
- const report = {
87
- url,
501
+ let aggregateBlock;
502
+ let comparison;
503
+ if (complete) {
504
+ const all = await readIndex(dir);
505
+ aggregateBlock = aggregateA11y(all, target);
506
+ comparison = await compareWith(all);
507
+ }
508
+ return text({
509
+ complete,
510
+ ...(complete ? {} : { cursor: encodeCursor(index) }),
511
+ progress: { done: index, total: units.length, failed: failures.length },
512
+ input_kind: resolved.kind,
513
+ ...(resolved.source ? { input_source: resolved.source } : {}),
88
514
  standard: resolvedStandard,
89
515
  runners: engines,
90
- ...(usable.length < engines.length
91
- ? { warnings: [`Only ${usable.length} of ${engines.length} runners produced output.`] }
92
- : {}),
93
- violation_count: findings.length,
94
- // Pre-dedup total, so a large drop between the two is explainable
95
- // rather than looking like dropped findings.
96
- raw_violation_count: rawCount,
97
- findings,
98
- };
99
- return {
100
- content: [{ type: "text", text: JSON.stringify(report, null, 2) }],
101
- };
516
+ target_level: target,
517
+ form_factor: requestedFactor,
518
+ output_dir: dir,
519
+ index_file: indexPath,
520
+ results,
521
+ ...(failures.length ? { failures } : {}),
522
+ ...(aggregateBlock ? { aggregate: aggregateBlock } : {}),
523
+ ...(comparison ? { comparison } : {}),
524
+ ...(complete ? {} : { next_step: "Call run_accessibility_check again with this cursor and the same input." }),
525
+ warnings,
526
+ });
102
527
  });
103
528
  }
104
529
  //# sourceMappingURL=accessibility.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"accessibility.js","sourceRoot":"","sources":["../../src/tools/accessibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,MAAM,UAAU,GAAG;IACjB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE;IAC9D,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtC,MAAM,EAAE,CAAC;SACN,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;SAC/B,QAAQ,EAAE;SACV,QAAQ,CACP,oEAAoE;QAClE,qEAAqE;QACrE,sEAAsE;QACtE,kEAAkE;QAClE,sEAAsE;QACtE,oEAAoE;QACpE,oEAAoE;QACpE,8BAA8B,CACjC;CACJ,CAAC;AAEF,MAAM,UAAU,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,WAAW,EACT,iEAAiE;YACjE,8DAA8D;YAC9D,MAAM;YACN,uEAAuE;YACvE,qEAAqE;YACrE,qEAAqE;YACrE,qEAAqE;YACrE,4DAA4D;YAC5D,sEAAsE;YACtE,qEAAqE;YACrE,sEAAsE;YACtE,sEAAsE;YACtE,uEAAuE;YACvE,iDAAiD;YACjD,MAAM;YACN,0DAA0D;QAC5D,WAAW,EAAE,UAAU;KACxB,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1C,MAAM,gBAAgB,GAAG,QAAQ,IAAI,SAAS,CAAC;QAC/C,MAAM,cAAc,GAAG,MAAM,IAAI,QAAQ,CAAC;QAC1C,MAAM,OAAO,GACX,cAAc,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QAEnE,MAAM,SAAS,GAAG,CAAC,MAAc,EAAE,EAAE;YACnC,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB;gBACrE,UAAU,EAAE,MAAM,CAAC,CAAC;YACtB,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YACzE,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,2EAA2E;QAC3E,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,CAC5E,CAAC;QAEF,2EAA2E;QAC3E,oEAAoE;QACpE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAC3B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAC1D,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,kBAAkB,CACvB,uCAAuC,EACvC,OAAO,CAAC,CAAC,CAAE,CACZ,CAAC;QACJ,CAAC;QAED,MAAM,WAAW,GAAc,EAAE,CAAC;QAClC,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;YAC5B,IAAI,MAAM,CAAC;YACX,IAAI,CAAC;gBACH,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,kBAAkB,CAAC,4BAA4B,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YACvE,CAAC;YACD,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBAC1C,MAAM,OAAO,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;gBAC7C,IAAI,OAAO;oBAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,uEAAuE;QACvE,wEAAwE;QACxE,0EAA0E;QAC1E,+DAA+D;QAC/D,uEAAuE;QACvE,yEAAyE;QACzE,0EAA0E;QAC1E,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAC/D,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QAEjC,MAAM,MAAM,GAAG;YACb,GAAG;YACH,QAAQ,EAAE,gBAAgB;YAC1B,OAAO,EAAE,OAAO;YAChB,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM;gBAChC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,OAAO,OAAO,CAAC,MAAM,2BAA2B,CAAC,EAAE;gBACvF,CAAC,CAAC,EAAE,CAAC;YACP,eAAe,EAAE,QAAQ,CAAC,MAAM;YAChC,kEAAkE;YAClE,6CAA6C;YAC7C,mBAAmB,EAAE,QAAQ;YAC7B,QAAQ;SACT,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"accessibility.js","sourceRoot":"","sources":["../../src/tools/accessibility.ts"],"names":[],"mappings":"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"}