@casoon/astro-post-audit 0.2.5 → 0.2.7

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.
@@ -207,12 +207,58 @@ export interface RulesConfig {
207
207
  /** Skip links to these domains. */
208
208
  block_domains?: string[];
209
209
  };
210
+ /** I18n consistency audit across route locale, lang, hreflang, and canonical signals. */
211
+ i18n_audit?: {
212
+ /** Enable i18n consistency checks in dist output. @default false */
213
+ enabled?: boolean;
214
+ };
215
+ /** Crawl budget audit for URL variants, indexability mismatches, and duplicate clusters. */
216
+ crawl_budget?: {
217
+ /** Enable crawl budget checks in dist output. @default false */
218
+ enabled?: boolean;
219
+ };
220
+ /** Static render-blocking audit for critical resources and connection hints. */
221
+ render_blocking?: {
222
+ /** Enable render-blocking checks in dist output. @default false */
223
+ enabled?: boolean;
224
+ };
225
+ /** Static privacy and security posture audit (third-party, SRI, CSP readiness, consent indicators). */
226
+ privacy_security?: {
227
+ /** Enable privacy/security checks in dist output. @default false */
228
+ enabled?: boolean;
229
+ };
230
+ /** Cross-page structured-data graph consistency checks. */
231
+ structured_data_graph?: {
232
+ /** Enable cross-page JSON-LD consistency checks in dist output. @default false */
233
+ enabled?: boolean;
234
+ };
235
+ }
236
+ export type GroupValue = boolean | "warn";
237
+ export interface GroupsConfig {
238
+ /** Enable SEO-focused rules (canonical, meta description, OG tags, structured data). */
239
+ seo?: GroupValue;
240
+ /** Enable accessibility rules (a11y, headings, lang attribute). */
241
+ a11y?: GroupValue;
242
+ /** Enable link-integrity rules (broken links, fragments, orphan pages). */
243
+ links?: GroupValue;
244
+ /** Enable performance rules (image dimensions, hashed filenames, render blocking). */
245
+ performance?: GroupValue;
246
+ /** Enable privacy/security rules (third-party domains, SRI, inline scripts). */
247
+ privacy?: GroupValue;
248
+ }
249
+ export interface ReportsConfig {
250
+ /** Write a JSON report to this file path (relative to project root). */
251
+ json?: string;
252
+ /** Write a Markdown summary report to this file path (relative to project root). */
253
+ markdown?: string;
254
+ /** Write a SARIF 2.1.0 report to this file path (relative to project root). For use with GitHub Code Scanning. */
255
+ sarif?: string;
210
256
  }
211
257
  export interface PostAuditOptions {
212
258
  /** Inline rules config — all check settings go here. */
213
259
  rules?: RulesConfig;
214
260
  /** Preset to apply before user overrides. `"strict"` enables all checks, `"relaxed"` is lenient. */
215
- preset?: "strict" | "relaxed";
261
+ preset?: "strict" | "relaxed" | "seo" | "accessibility" | "performance" | "production";
216
262
  /** Base URL (auto-detected from Astro's `site` config if not set). */
217
263
  site?: string;
218
264
  /** Treat warnings as errors. */
@@ -223,12 +269,44 @@ export interface PostAuditOptions {
223
269
  pageOverview?: boolean;
224
270
  /** Write the JSON report to this file path (relative to project root). */
225
271
  output?: string;
272
+ /** Write a Markdown summary report to this file path (relative to project root). */
273
+ outputMarkdown?: string;
274
+ /**
275
+ * Write one or more report files. Supports `json`, `markdown`, and `sarif` (SARIF 2.1.0) formats.
276
+ * Multiple formats can be active simultaneously. Takes precedence over `output`/`outputMarkdown` when both are set.
277
+ */
278
+ reports?: ReportsConfig;
279
+ /** Heuristic hints for source file locations in Content Collections / MDX projects. */
280
+ hints?: {
281
+ /** Show likely source file paths next to dist/ findings. Heuristic — may not always match. @default false */
282
+ sourceFiles?: boolean;
283
+ };
226
284
  /** Print per-check timing benchmarks in the output. */
227
285
  benchmark?: boolean;
228
286
  /** Disable the integration (useful for dev mode). */
229
287
  disable?: boolean;
230
288
  /** Throw an error when the audit finds issues (fails the build). Default: false */
231
289
  throwOnError?: boolean;
290
+ /**
291
+ * Path to a baseline file (relative to project root). When set, only findings that are
292
+ * *new* since the baseline was written will be reported. If the file does not exist,
293
+ * a warning is logged and the audit runs normally.
294
+ */
295
+ baseline?: string;
296
+ /**
297
+ * Write current findings as the new baseline and exit with code 0.
298
+ * Use this once to adopt the plugin on a site with existing issues.
299
+ */
300
+ writeBaseline?: boolean;
301
+ /**
302
+ * Build fail strategy. `'errors'`: fail on errors only (default when `throwOnError` is true).
303
+ * `'warnings'`: fail on any finding (implies `strict`). `'never'`: never fail the build.
304
+ */
305
+ failOn?: "never" | "errors" | "warnings";
306
+ /** Fail the build if the warning count exceeds this number. */
307
+ maxWarnings?: number;
308
+ /** Shorthand rule groups. `true` enables the group, `"warn"` enables but downgrades all findings to warnings. */
309
+ groups?: GroupsConfig;
232
310
  }
233
311
  interface RuntimeDeps {
234
312
  execFileSync: typeof execFileSync;
@@ -1 +1 @@
1
- {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"integration.d.ts","sourceRoot":"","sources":["../src/integration.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { execFileSync } from "node:child_process";
2
2
  import { existsSync, writeFileSync } from "node:fs";
3
- import { dirname, join } from "node:path";
3
+ import { dirname, join, resolve } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  const defaultDeps = {
6
6
  execFileSync,
@@ -25,14 +25,147 @@ function supportsConfigStdin(binaryPath, run) {
25
25
  return false;
26
26
  }
27
27
  }
28
+ function logJsonSummary(json, logger) {
29
+ try {
30
+ const report = JSON.parse(json);
31
+ const s = report.summary;
32
+ if (!s)
33
+ return;
34
+ const parts = [];
35
+ if (s.errors)
36
+ parts.push(`${s.errors} error${s.errors === 1 ? "" : "s"}`);
37
+ if (s.warnings)
38
+ parts.push(`${s.warnings} warning${s.warnings === 1 ? "" : "s"}`);
39
+ if (s.info)
40
+ parts.push(`${s.info} info`);
41
+ const filesMsg = s.files_checked !== undefined ? ` (${s.files_checked} files checked)` : "";
42
+ if (parts.length === 0) {
43
+ logger.info(`Audit passed${filesMsg}.`);
44
+ }
45
+ else {
46
+ logger.warn(`Audit: ${parts.join(", ")}${filesMsg}.`);
47
+ }
48
+ }
49
+ catch {
50
+ // non-JSON output, skip summary
51
+ }
52
+ }
53
+ const GROUP_DEFS = {
54
+ seo: {
55
+ rules: {
56
+ html_basics: { meta_description_required: true },
57
+ opengraph: {
58
+ require_og_title: true,
59
+ require_og_description: true,
60
+ require_og_image: true,
61
+ },
62
+ structured_data: { check_json_ld: true },
63
+ },
64
+ ruleIds: [
65
+ "canonical/missing", "canonical/multiple", "canonical/empty",
66
+ "canonical/not-absolute", "canonical/cross-origin", "canonical/not-self",
67
+ "canonical/target-missing", "canonical/cluster", "robots/noindex",
68
+ "sitemap/missing", "sitemap/canonical-missing", "sitemap/entry-not-in-dist",
69
+ "sitemap/non-canonical-entry", "opengraph/title-missing",
70
+ "opengraph/description-missing", "opengraph/image-missing",
71
+ "html/title-missing", "html/meta-description-missing",
72
+ "html/meta-description-too-long", "structured-data/missing",
73
+ "structured-data/invalid-json",
74
+ ],
75
+ },
76
+ a11y: {
77
+ rules: {
78
+ a11y: { require_skip_link: true },
79
+ headings: { no_skip: true },
80
+ },
81
+ ruleIds: [
82
+ "a11y/img-alt", "a11y/link-name", "a11y/generic-link-text",
83
+ "a11y/button-name", "a11y/form-label", "a11y/skip-link",
84
+ "a11y/aria-hidden-focusable", "headings/no-h1", "headings/multiple-h1",
85
+ "headings/skip-level", "html/lang-missing",
86
+ ],
87
+ },
88
+ links: {
89
+ rules: {
90
+ links: { detect_orphan_pages: true, check_fragments: true },
91
+ },
92
+ ruleIds: [
93
+ "links/broken", "links/broken-fragment", "links/query-params",
94
+ "links/mixed-content", "links/orphan-page", "external-links/broken",
95
+ ],
96
+ },
97
+ performance: {
98
+ rules: {
99
+ assets: { check_image_dimensions: true, require_hashed_filenames: true },
100
+ render_blocking: { enabled: true },
101
+ },
102
+ ruleIds: [
103
+ "assets/img-dimensions", "assets/unhashed-filename", "assets/large-image",
104
+ "assets/large-js", "assets/large-css", "render-blocking/sync-head-scripts",
105
+ "render-blocking/missing-style-preload", "render-blocking/missing-preconnect",
106
+ ],
107
+ },
108
+ privacy: {
109
+ rules: {
110
+ privacy_security: { enabled: true },
111
+ security: { warn_inline_scripts: true },
112
+ },
113
+ ruleIds: [
114
+ "privacy-security/third-party-domains", "privacy-security/missing-sri-script",
115
+ "privacy-security/missing-sri-stylesheet",
116
+ "privacy-security/csp-readiness-inline-script",
117
+ "privacy-security/missing-consent-indicator",
118
+ "security/target-blank-noopener", "security/inline-scripts",
119
+ "security/mixed-content",
120
+ ],
121
+ },
122
+ };
123
+ function deepMerge(base, override) {
124
+ const result = { ...base };
125
+ for (const [key, val] of Object.entries(override)) {
126
+ if (val !== null &&
127
+ typeof val === "object" &&
128
+ !Array.isArray(val) &&
129
+ typeof result[key] === "object" &&
130
+ result[key] !== null) {
131
+ result[key] = deepMerge(result[key], val);
132
+ }
133
+ else {
134
+ result[key] = val;
135
+ }
136
+ }
137
+ return result;
138
+ }
139
+ function expandGroups(groups, userRules) {
140
+ let accumulated = {};
141
+ const warnOverrides = {};
142
+ for (const [name, value] of Object.entries(groups)) {
143
+ if (!value)
144
+ continue;
145
+ const def = GROUP_DEFS[name];
146
+ accumulated = deepMerge(accumulated, def.rules);
147
+ if (value === "warn") {
148
+ for (const id of def.ruleIds) {
149
+ warnOverrides[id] = "warning";
150
+ }
151
+ }
152
+ }
153
+ const merged = deepMerge(accumulated, userRules);
154
+ if (Object.keys(warnOverrides).length > 0) {
155
+ merged.severity = { ...warnOverrides, ...userRules.severity };
156
+ }
157
+ return merged;
158
+ }
28
159
  export default function postAudit(options = {}, deps = defaultDeps) {
29
160
  let siteUrl;
161
+ let rootDir;
30
162
  let astroTrailingSlash;
31
163
  return {
32
164
  name: "astro-post-audit",
33
165
  hooks: {
34
166
  "astro:config:done": ({ config }) => {
35
167
  siteUrl = config.site?.toString();
168
+ rootDir = fileURLToPath(config.root);
36
169
  // Bridge Astro's trailingSlash config automatically
37
170
  if (config.trailingSlash) {
38
171
  astroTrailingSlash = config.trailingSlash;
@@ -47,27 +180,55 @@ export default function postAudit(options = {}, deps = defaultDeps) {
47
180
  }
48
181
  return;
49
182
  }
183
+ const shouldFail = options.throwOnError === true ||
184
+ (options.failOn !== undefined && options.failOn !== "never");
185
+ const resolvedRules = options.groups
186
+ ? expandGroups(options.groups, options.rules ?? {})
187
+ : (options.rules ?? {});
50
188
  // Validate that rules is a non-empty object if provided
51
189
  if (options.rules &&
52
190
  typeof options.rules === "object" &&
53
191
  Object.keys(options.rules).length === 0) {
54
192
  logger.warn('astro-post-audit: "rules" is an empty object — using default config.');
55
193
  }
194
+ // Warn: `site` missing but canonical/sitemap checks active
195
+ const effectiveSite = options.site ?? siteUrl;
196
+ if (!effectiveSite) {
197
+ const canonicalActive = resolvedRules.canonical?.require !== false;
198
+ const sitemapActive = resolvedRules.sitemap?.canonical_must_be_in_sitemap !== false;
199
+ if (canonicalActive || sitemapActive) {
200
+ logger.warn("`site` is not set in astro.config.mjs. Canonical and sitemap URL checks will be limited — set `site` to enable full URL verification.");
201
+ }
202
+ }
56
203
  const binaryPath = resolveBinaryPath(deps.existsSync);
57
204
  if (!binaryPath) {
58
- logger.warn('astro-post-audit binary not found. Run "npm rebuild @casoon/astro-post-audit".');
205
+ const msg = 'astro-post-audit binary not found. Run "npm rebuild @casoon/astro-post-audit".';
206
+ if (shouldFail)
207
+ throw new Error(msg);
208
+ logger.warn(msg);
59
209
  return;
60
210
  }
61
211
  if (!supportsConfigStdin(binaryPath, deps.execFileSync)) {
62
- logger.error('astro-post-audit binary is outdated and does not support --config-stdin. Run "npm rebuild @casoon/astro-post-audit".');
212
+ const msg = 'astro-post-audit binary is outdated and does not support --config-stdin. Run "npm rebuild @casoon/astro-post-audit".';
213
+ if (shouldFail)
214
+ throw new Error(msg);
215
+ logger.error(msg);
63
216
  return;
64
217
  }
65
218
  const distPath = fileURLToPath(dir);
66
219
  const args = [distPath, "--config-stdin"];
220
+ // Info: sitemap checks active but no sitemap.xml in dist
221
+ const sitemapChecksActive = resolvedRules.sitemap?.canonical_must_be_in_sitemap !== false ||
222
+ resolvedRules.sitemap?.entries_must_exist_in_dist !== false;
223
+ if (sitemapChecksActive &&
224
+ !deps.existsSync(join(distPath, "sitemap.xml")) &&
225
+ !deps.existsSync(join(distPath, "sitemap-index.xml"))) {
226
+ logger.info("No sitemap.xml found in dist/. Sitemap checks are limited. Add @astrojs/sitemap or @casoon/astro-sitemap to generate a sitemap.");
227
+ }
67
228
  // Build the full JSON config for the Rust binary
68
- const site = options.site ?? siteUrl;
229
+ const site = effectiveSite;
69
230
  const stdinConfig = {
70
- ...options.rules,
231
+ ...resolvedRules,
71
232
  };
72
233
  if (site)
73
234
  stdinConfig.site = { base_url: site };
@@ -82,19 +243,95 @@ export default function postAudit(options = {}, deps = defaultDeps) {
82
243
  trailing_slash: astroTrailingSlash,
83
244
  };
84
245
  }
85
- if (options.strict)
246
+ if (options.failOn === "warnings" && options.strict !== false) {
86
247
  stdinConfig.strict = true;
87
- if (options.benchmark)
88
- stdinConfig.benchmark = true;
248
+ }
249
+ else if (options.strict !== undefined) {
250
+ stdinConfig.strict = options.strict;
251
+ }
252
+ if (options.benchmark !== undefined)
253
+ stdinConfig.benchmark = options.benchmark;
254
+ if (options.maxWarnings != null)
255
+ stdinConfig.max_warnings = options.maxWarnings;
256
+ if (options.baseline)
257
+ stdinConfig.baseline = resolve(rootDir ?? process.cwd(), options.baseline);
258
+ if (options.writeBaseline)
259
+ stdinConfig.write_baseline = true;
260
+ if (options.hints?.sourceFiles && rootDir) {
261
+ stdinConfig.hints = { source_files: true };
262
+ stdinConfig.project_root = rootDir;
263
+ }
89
264
  if (options.maxErrors != null)
90
265
  stdinConfig.max_errors = options.maxErrors;
91
- if (options.pageOverview)
92
- stdinConfig.page_overview = true;
93
- if (options.output)
266
+ if (options.pageOverview !== undefined)
267
+ stdinConfig.page_overview = options.pageOverview;
268
+ const root = rootDir ?? process.cwd();
269
+ const outputPath = options.reports?.json
270
+ ? resolve(root, options.reports.json)
271
+ : options.output
272
+ ? resolve(root, options.output)
273
+ : undefined;
274
+ if (outputPath)
94
275
  stdinConfig.format = "json";
276
+ const outputMarkdownPath = options.reports?.markdown
277
+ ? resolve(root, options.reports.markdown)
278
+ : options.outputMarkdown
279
+ ? resolve(root, options.outputMarkdown)
280
+ : undefined;
281
+ const outputSarifPath = options.reports?.sarif
282
+ ? resolve(root, options.reports.sarif)
283
+ : undefined;
95
284
  const stdinInput = JSON.stringify(stdinConfig);
285
+ // Run Markdown report if requested (separate invocation, captures stdout)
286
+ if (outputMarkdownPath) {
287
+ const mdConfig = { ...stdinConfig, format: "markdown" };
288
+ try {
289
+ const mdResult = deps.execFileSync(binaryPath, args, {
290
+ stdio: ["pipe", "pipe", "inherit"],
291
+ input: JSON.stringify(mdConfig),
292
+ encoding: "utf-8",
293
+ });
294
+ if (mdResult) {
295
+ deps.writeFileSync(outputMarkdownPath, mdResult);
296
+ logger.info(`Markdown report written to ${outputMarkdownPath}`);
297
+ }
298
+ }
299
+ catch (mdErr) {
300
+ if (mdErr &&
301
+ typeof mdErr === "object" &&
302
+ "stdout" in mdErr &&
303
+ mdErr.stdout) {
304
+ deps.writeFileSync(outputMarkdownPath, mdErr.stdout);
305
+ logger.info(`Markdown report written to ${outputMarkdownPath}`);
306
+ }
307
+ }
308
+ }
309
+ // Run SARIF report if requested (separate invocation, captures stdout)
310
+ if (outputSarifPath) {
311
+ const sarifConfig = { ...stdinConfig, format: "sarif" };
312
+ try {
313
+ const sarifResult = deps.execFileSync(binaryPath, args, {
314
+ stdio: ["pipe", "pipe", "inherit"],
315
+ input: JSON.stringify(sarifConfig),
316
+ encoding: "utf-8",
317
+ });
318
+ if (sarifResult) {
319
+ deps.writeFileSync(outputSarifPath, sarifResult);
320
+ logger.info(`SARIF report written to ${outputSarifPath}`);
321
+ }
322
+ }
323
+ catch (sarifErr) {
324
+ if (sarifErr &&
325
+ typeof sarifErr === "object" &&
326
+ "stdout" in sarifErr &&
327
+ sarifErr.stdout) {
328
+ deps.writeFileSync(outputSarifPath, sarifErr.stdout);
329
+ logger.info(`SARIF report written to ${outputSarifPath}`);
330
+ }
331
+ }
332
+ }
96
333
  logger.info("Running post-build audit...");
97
- const captureOutput = !!options.output;
334
+ const captureOutput = !!outputPath;
98
335
  try {
99
336
  const result = deps.execFileSync(binaryPath, args, {
100
337
  stdio: ["pipe", captureOutput ? "pipe" : "inherit", "inherit"],
@@ -102,8 +339,9 @@ export default function postAudit(options = {}, deps = defaultDeps) {
102
339
  encoding: captureOutput ? "utf-8" : undefined,
103
340
  });
104
341
  if (captureOutput && result) {
105
- deps.writeFileSync(options.output, result);
106
- logger.info(`Report written to ${options.output}`);
342
+ deps.writeFileSync(outputPath, result);
343
+ logger.info(`Report written to ${outputPath}`);
344
+ logJsonSummary(result, logger);
107
345
  }
108
346
  logger.info("All checks passed!");
109
347
  }
@@ -119,12 +357,14 @@ export default function postAudit(options = {}, deps = defaultDeps) {
119
357
  "stdout" in err) {
120
358
  const stdout = err.stdout;
121
359
  if (stdout) {
122
- deps.writeFileSync(options.output, stdout);
123
- logger.info(`Report written to ${options.output}`);
360
+ const stdoutStr = typeof stdout === "string" ? stdout : stdout.toString("utf-8");
361
+ deps.writeFileSync(outputPath, stdoutStr);
362
+ logger.info(`Report written to ${outputPath}`);
363
+ logJsonSummary(stdoutStr, logger);
124
364
  }
125
365
  }
126
366
  if (exitCode === 1) {
127
- if (options.throwOnError) {
367
+ if (shouldFail) {
128
368
  throw new Error("astro-post-audit found issues. See output above.");
129
369
  }
130
370
  logger.warn("Audit found issues. See output above.");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@casoon/astro-post-audit",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Astro integration for post-build auditing: SEO, links, and lightweight WCAG checks",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -13,9 +13,6 @@
13
13
  },
14
14
  "./schema": "./schema.json"
15
15
  },
16
- "bin": {
17
- "astro-post-audit": "bin/run.cjs"
18
- },
19
16
  "scripts": {
20
17
  "build": "tsc && npm run generate-schema",
21
18
  "generate-schema": "typescript-json-schema tsconfig.json PostAuditOptions --noExtraProps -o schema.json",
@@ -25,7 +22,8 @@
25
22
  "postinstall": "node bin/install.cjs"
26
23
  },
27
24
  "files": [
28
- "bin/",
25
+ "bin/install.cjs",
26
+ "bin/run.cjs",
29
27
  "dist/",
30
28
  "schema.json"
31
29
  ],
package/schema.json CHANGED
@@ -2,12 +2,72 @@
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "additionalProperties": false,
4
4
  "definitions": {
5
- "SeverityOverrides": {
6
- "additionalProperties": {
7
- "enum": ["error", "warning", "info", "off"],
8
- "type": "string"
5
+ "GroupsConfig": {
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "a11y": {
9
+ "description": "Enable accessibility rules (a11y, headings, lang attribute).",
10
+ "enum": [
11
+ false,
12
+ true,
13
+ "warn"
14
+ ]
15
+ },
16
+ "links": {
17
+ "description": "Enable link-integrity rules (broken links, fragments, orphan pages).",
18
+ "enum": [
19
+ false,
20
+ true,
21
+ "warn"
22
+ ]
23
+ },
24
+ "performance": {
25
+ "description": "Enable performance rules (image dimensions, hashed filenames, render blocking).",
26
+ "enum": [
27
+ false,
28
+ true,
29
+ "warn"
30
+ ]
31
+ },
32
+ "privacy": {
33
+ "description": "Enable privacy/security rules (third-party domains, SRI, inline scripts).",
34
+ "enum": [
35
+ false,
36
+ true,
37
+ "warn"
38
+ ]
39
+ },
40
+ "seo": {
41
+ "description": "Enable SEO-focused rules (canonical, meta description, OG tags, structured data).",
42
+ "enum": [
43
+ false,
44
+ true,
45
+ "warn"
46
+ ]
47
+ }
48
+ },
49
+ "type": "object"
50
+ },
51
+ "Record<string,\"error\"|\"warning\"|\"info\"|\"off\">": {
52
+ "additionalProperties": false,
53
+ "type": "object"
54
+ },
55
+ "ReportsConfig": {
56
+ "additionalProperties": false,
57
+ "properties": {
58
+ "json": {
59
+ "description": "Write a JSON report to this file path (relative to project root).",
60
+ "type": "string"
61
+ },
62
+ "markdown": {
63
+ "description": "Write a Markdown summary report to this file path (relative to project root).",
64
+ "type": "string"
65
+ },
66
+ "sarif": {
67
+ "description": "Write a SARIF 2.1.0 report to this file path (relative to project root). For use with GitHub Code Scanning.",
68
+ "type": "string"
69
+ }
9
70
  },
10
- "description": "Map of rule IDs to severity levels.",
11
71
  "type": "object"
12
72
  },
13
73
  "RulesConfig": {
@@ -154,6 +214,18 @@
154
214
  },
155
215
  "type": "object"
156
216
  },
217
+ "crawl_budget": {
218
+ "additionalProperties": false,
219
+ "description": "Crawl budget audit for URL variants, indexability mismatches, and duplicate clusters.",
220
+ "properties": {
221
+ "enabled": {
222
+ "default": false,
223
+ "description": "Enable crawl budget checks in dist output.",
224
+ "type": "boolean"
225
+ }
226
+ },
227
+ "type": "object"
228
+ },
157
229
  "external_links": {
158
230
  "additionalProperties": false,
159
231
  "description": "External link checking (HEAD requests to verify URLs return 2xx).",
@@ -302,6 +374,18 @@
302
374
  },
303
375
  "type": "object"
304
376
  },
377
+ "i18n_audit": {
378
+ "additionalProperties": false,
379
+ "description": "I18n consistency audit across route locale, lang, hreflang, and canonical signals.",
380
+ "properties": {
381
+ "enabled": {
382
+ "default": false,
383
+ "description": "Enable i18n consistency checks in dist output.",
384
+ "type": "boolean"
385
+ }
386
+ },
387
+ "type": "object"
388
+ },
305
389
  "links": {
306
390
  "additionalProperties": false,
307
391
  "description": "Internal link consistency checks.",
@@ -366,6 +450,30 @@
366
450
  },
367
451
  "type": "object"
368
452
  },
453
+ "privacy_security": {
454
+ "additionalProperties": false,
455
+ "description": "Static privacy and security posture audit (third-party, SRI, CSP readiness, consent indicators).",
456
+ "properties": {
457
+ "enabled": {
458
+ "default": false,
459
+ "description": "Enable privacy/security checks in dist output.",
460
+ "type": "boolean"
461
+ }
462
+ },
463
+ "type": "object"
464
+ },
465
+ "render_blocking": {
466
+ "additionalProperties": false,
467
+ "description": "Static render-blocking audit for critical resources and connection hints.",
468
+ "properties": {
469
+ "enabled": {
470
+ "default": false,
471
+ "description": "Enable render-blocking checks in dist output.",
472
+ "type": "boolean"
473
+ }
474
+ },
475
+ "type": "object"
476
+ },
369
477
  "robots_meta": {
370
478
  "additionalProperties": false,
371
479
  "description": "Robots meta tag checks.",
@@ -423,7 +531,7 @@
423
531
  "type": "object"
424
532
  },
425
533
  "severity": {
426
- "$ref": "#/definitions/SeverityOverrides",
534
+ "$ref": "#/definitions/Record%3Cstring%2C%22error%22%7C%22warning%22%7C%22info%22%7C%22off%22%3E",
427
535
  "description": "Override severity per rule ID."
428
536
  },
429
537
  "site": {
@@ -486,6 +594,18 @@
486
594
  },
487
595
  "type": "object"
488
596
  },
597
+ "structured_data_graph": {
598
+ "additionalProperties": false,
599
+ "description": "Cross-page structured-data graph consistency checks.",
600
+ "properties": {
601
+ "enabled": {
602
+ "default": false,
603
+ "description": "Enable cross-page JSON-LD consistency checks in dist output.",
604
+ "type": "boolean"
605
+ }
606
+ },
607
+ "type": "object"
608
+ },
489
609
  "url_normalization": {
490
610
  "additionalProperties": false,
491
611
  "description": "URL normalization rules for internal link and canonical consistency.",
@@ -517,6 +637,10 @@
517
637
  }
518
638
  },
519
639
  "properties": {
640
+ "baseline": {
641
+ "description": "Path to a baseline file (relative to project root). When set, only findings that are\n*new* since the baseline was written will be reported. If the file does not exist,\na warning is logged and the audit runs normally.",
642
+ "type": "string"
643
+ },
520
644
  "benchmark": {
521
645
  "description": "Print per-check timing benchmarks in the output.",
522
646
  "type": "boolean"
@@ -525,14 +649,47 @@
525
649
  "description": "Disable the integration (useful for dev mode).",
526
650
  "type": "boolean"
527
651
  },
652
+ "failOn": {
653
+ "description": "Build fail strategy. `'errors'`: fail on errors only (default when `throwOnError` is true).\n`'warnings'`: fail on any finding (implies `strict`). `'never'`: never fail the build.",
654
+ "enum": [
655
+ "errors",
656
+ "never",
657
+ "warnings"
658
+ ],
659
+ "type": "string"
660
+ },
661
+ "groups": {
662
+ "$ref": "#/definitions/GroupsConfig",
663
+ "description": "Shorthand rule groups. `true` enables the group, `\"warn\"` enables but downgrades all findings to warnings."
664
+ },
665
+ "hints": {
666
+ "additionalProperties": false,
667
+ "description": "Heuristic hints for source file locations in Content Collections / MDX projects.",
668
+ "properties": {
669
+ "sourceFiles": {
670
+ "default": false,
671
+ "description": "Show likely source file paths next to dist/ findings. Heuristic — may not always match.",
672
+ "type": "boolean"
673
+ }
674
+ },
675
+ "type": "object"
676
+ },
528
677
  "maxErrors": {
529
678
  "description": "Maximum number of errors before aborting.",
530
679
  "type": "number"
531
680
  },
681
+ "maxWarnings": {
682
+ "description": "Fail the build if the warning count exceeds this number.",
683
+ "type": "number"
684
+ },
532
685
  "output": {
533
686
  "description": "Write the JSON report to this file path (relative to project root).",
534
687
  "type": "string"
535
688
  },
689
+ "outputMarkdown": {
690
+ "description": "Write a Markdown summary report to this file path (relative to project root).",
691
+ "type": "string"
692
+ },
536
693
  "pageOverview": {
537
694
  "description": "Show page properties overview instead of running checks.",
538
695
  "type": "boolean"
@@ -540,11 +697,19 @@
540
697
  "preset": {
541
698
  "description": "Preset to apply before user overrides. `\"strict\"` enables all checks, `\"relaxed\"` is lenient.",
542
699
  "enum": [
700
+ "accessibility",
701
+ "performance",
702
+ "production",
543
703
  "relaxed",
704
+ "seo",
544
705
  "strict"
545
706
  ],
546
707
  "type": "string"
547
708
  },
709
+ "reports": {
710
+ "$ref": "#/definitions/ReportsConfig",
711
+ "description": "Write one or more report files. Supports `json`, `markdown`, and `sarif` (SARIF 2.1.0) formats.\nMultiple formats can be active simultaneously. Takes precedence over `output`/`outputMarkdown` when both are set."
712
+ },
548
713
  "rules": {
549
714
  "$ref": "#/definitions/RulesConfig",
550
715
  "description": "Inline rules config — all check settings go here."
@@ -560,6 +725,10 @@
560
725
  "throwOnError": {
561
726
  "description": "Throw an error when the audit finds issues (fails the build). Default: false",
562
727
  "type": "boolean"
728
+ },
729
+ "writeBaseline": {
730
+ "description": "Write current findings as the new baseline and exit with code 0.\nUse this once to adopt the plugin on a site with existing issues.",
731
+ "type": "boolean"
563
732
  }
564
733
  },
565
734
  "type": "object"
Binary file