repo-contract 0.1.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.
Files changed (145) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +967 -0
  4. package/dist/.dts/config/define-repo-contract.d.ts +36 -0
  5. package/dist/.dts/config/define-repo-contract.d.ts.map +1 -0
  6. package/dist/.dts/config/tokenize-command.d.ts +33 -0
  7. package/dist/.dts/config/tokenize-command.d.ts.map +1 -0
  8. package/dist/.dts/config/validate-config.d.ts +32 -0
  9. package/dist/.dts/config/validate-config.d.ts.map +1 -0
  10. package/dist/.dts/errors.d.ts +155 -0
  11. package/dist/.dts/errors.d.ts.map +1 -0
  12. package/dist/.dts/evidence/build-evidence.d.ts +26 -0
  13. package/dist/.dts/evidence/build-evidence.d.ts.map +1 -0
  14. package/dist/.dts/execution/abort-signals.d.ts +29 -0
  15. package/dist/.dts/execution/abort-signals.d.ts.map +1 -0
  16. package/dist/.dts/execution/concurrency-pool.d.ts +14 -0
  17. package/dist/.dts/execution/concurrency-pool.d.ts.map +1 -0
  18. package/dist/.dts/execution/dependency-scheduler.d.ts +30 -0
  19. package/dist/.dts/execution/dependency-scheduler.d.ts.map +1 -0
  20. package/dist/.dts/execution/process-tree.d.ts +48 -0
  21. package/dist/.dts/execution/process-tree.d.ts.map +1 -0
  22. package/dist/.dts/execution/run-checks.d.ts +29 -0
  23. package/dist/.dts/execution/run-checks.d.ts.map +1 -0
  24. package/dist/.dts/execution/spawn-check.d.ts +30 -0
  25. package/dist/.dts/execution/spawn-check.d.ts.map +1 -0
  26. package/dist/.dts/index.d.ts +13 -0
  27. package/dist/.dts/index.d.ts.map +1 -0
  28. package/dist/.dts/parsing/parse-json.d.ts +8 -0
  29. package/dist/.dts/parsing/parse-json.d.ts.map +1 -0
  30. package/dist/.dts/parsing/parse-output.d.ts +10 -0
  31. package/dist/.dts/parsing/parse-output.d.ts.map +1 -0
  32. package/dist/.dts/parsing/parse-text.d.ts +8 -0
  33. package/dist/.dts/parsing/parse-text.d.ts.map +1 -0
  34. package/dist/.dts/parsing/parse-yaml.d.ts +21 -0
  35. package/dist/.dts/parsing/parse-yaml.d.ts.map +1 -0
  36. package/dist/.dts/policy/run-policies.d.ts +38 -0
  37. package/dist/.dts/policy/run-policies.d.ts.map +1 -0
  38. package/dist/.dts/presets/arethetypeswrong.d.ts +39 -0
  39. package/dist/.dts/presets/arethetypeswrong.d.ts.map +1 -0
  40. package/dist/.dts/presets/broken-links.d.ts +16 -0
  41. package/dist/.dts/presets/broken-links.d.ts.map +1 -0
  42. package/dist/.dts/presets/commitlint.d.ts +22 -0
  43. package/dist/.dts/presets/commitlint.d.ts.map +1 -0
  44. package/dist/.dts/presets/dead-code.d.ts +23 -0
  45. package/dist/.dts/presets/dead-code.d.ts.map +1 -0
  46. package/dist/.dts/presets/duplication.d.ts +14 -0
  47. package/dist/.dts/presets/duplication.d.ts.map +1 -0
  48. package/dist/.dts/presets/e2e.d.ts +4 -0
  49. package/dist/.dts/presets/e2e.d.ts.map +1 -0
  50. package/dist/.dts/presets/format.d.ts +4 -0
  51. package/dist/.dts/presets/format.d.ts.map +1 -0
  52. package/dist/.dts/presets/index.d.ts +31 -0
  53. package/dist/.dts/presets/index.d.ts.map +1 -0
  54. package/dist/.dts/presets/license.d.ts +4 -0
  55. package/dist/.dts/presets/license.d.ts.map +1 -0
  56. package/dist/.dts/presets/lint.d.ts +20 -0
  57. package/dist/.dts/presets/lint.d.ts.map +1 -0
  58. package/dist/.dts/presets/markdownlint.d.ts +23 -0
  59. package/dist/.dts/presets/markdownlint.d.ts.map +1 -0
  60. package/dist/.dts/presets/publint.d.ts +13 -0
  61. package/dist/.dts/presets/publint.d.ts.map +1 -0
  62. package/dist/.dts/presets/security-deps.d.ts +4 -0
  63. package/dist/.dts/presets/security-deps.d.ts.map +1 -0
  64. package/dist/.dts/presets/security-secrets.d.ts +4 -0
  65. package/dist/.dts/presets/security-secrets.d.ts.map +1 -0
  66. package/dist/.dts/presets/shared/error-warning-pass-policy.d.ts +13 -0
  67. package/dist/.dts/presets/shared/error-warning-pass-policy.d.ts.map +1 -0
  68. package/dist/.dts/presets/shared/exit-code-fail-rationale.d.ts +23 -0
  69. package/dist/.dts/presets/shared/exit-code-fail-rationale.d.ts.map +1 -0
  70. package/dist/.dts/presets/shared/missing-dependency.d.ts +19 -0
  71. package/dist/.dts/presets/shared/missing-dependency.d.ts.map +1 -0
  72. package/dist/.dts/presets/shared/read-json-report.d.ts +33 -0
  73. package/dist/.dts/presets/shared/read-json-report.d.ts.map +1 -0
  74. package/dist/.dts/presets/shared/terminal-status.d.ts +25 -0
  75. package/dist/.dts/presets/shared/terminal-status.d.ts.map +1 -0
  76. package/dist/.dts/presets/shared/vitest-json-policy.d.ts +20 -0
  77. package/dist/.dts/presets/shared/vitest-json-policy.d.ts.map +1 -0
  78. package/dist/.dts/presets/stylelint.d.ts +17 -0
  79. package/dist/.dts/presets/stylelint.d.ts.map +1 -0
  80. package/dist/.dts/presets/test.d.ts +4 -0
  81. package/dist/.dts/presets/test.d.ts.map +1 -0
  82. package/dist/.dts/presets/typecheck.d.ts +4 -0
  83. package/dist/.dts/presets/typecheck.d.ts.map +1 -0
  84. package/dist/.dts/run-repo-contract.d.ts +38 -0
  85. package/dist/.dts/run-repo-contract.d.ts.map +1 -0
  86. package/dist/.dts/types.d.ts +324 -0
  87. package/dist/.dts/types.d.ts.map +1 -0
  88. package/dist/index.cjs +46 -0
  89. package/dist/index.cjs.map +1 -0
  90. package/dist/index.d.cts +1 -0
  91. package/dist/index.d.ts +1 -0
  92. package/dist/index.js +11 -0
  93. package/dist/index.js.map +1 -0
  94. package/dist/presets.cjs +30 -0
  95. package/dist/presets.cjs.map +1 -0
  96. package/dist/presets.d.cts +1 -0
  97. package/dist/presets.d.ts +1 -0
  98. package/dist/presets.js +13 -0
  99. package/dist/presets.js.map +1 -0
  100. package/package.json +192 -0
  101. package/presets/package.json +5 -0
  102. package/schemas/evidence.schema.json +253 -0
  103. package/schemas/verdict.schema.json +66 -0
  104. package/src/config/define-repo-contract.ts +38 -0
  105. package/src/config/tokenize-command.ts +214 -0
  106. package/src/config/validate-config.ts +368 -0
  107. package/src/errors.ts +229 -0
  108. package/src/evidence/build-evidence.ts +91 -0
  109. package/src/execution/abort-signals.ts +56 -0
  110. package/src/execution/concurrency-pool.ts +64 -0
  111. package/src/execution/dependency-scheduler.ts +216 -0
  112. package/src/execution/process-tree.ts +107 -0
  113. package/src/execution/run-checks.ts +348 -0
  114. package/src/execution/spawn-check.ts +494 -0
  115. package/src/index.ts +44 -0
  116. package/src/parsing/parse-json.ts +18 -0
  117. package/src/parsing/parse-output.ts +26 -0
  118. package/src/parsing/parse-text.ts +10 -0
  119. package/src/parsing/parse-yaml.ts +40 -0
  120. package/src/policy/run-policies.ts +261 -0
  121. package/src/presets/arethetypeswrong.ts +116 -0
  122. package/src/presets/broken-links.ts +95 -0
  123. package/src/presets/commitlint.ts +77 -0
  124. package/src/presets/dead-code.ts +223 -0
  125. package/src/presets/duplication.ts +137 -0
  126. package/src/presets/e2e.ts +144 -0
  127. package/src/presets/format.ts +25 -0
  128. package/src/presets/index.ts +30 -0
  129. package/src/presets/license.ts +90 -0
  130. package/src/presets/lint.ts +116 -0
  131. package/src/presets/markdownlint.ts +105 -0
  132. package/src/presets/publint.ts +38 -0
  133. package/src/presets/security-deps.ts +142 -0
  134. package/src/presets/security-secrets.ts +93 -0
  135. package/src/presets/shared/error-warning-pass-policy.ts +39 -0
  136. package/src/presets/shared/exit-code-fail-rationale.ts +34 -0
  137. package/src/presets/shared/missing-dependency.ts +31 -0
  138. package/src/presets/shared/read-json-report.ts +46 -0
  139. package/src/presets/shared/terminal-status.ts +70 -0
  140. package/src/presets/shared/vitest-json-policy.ts +95 -0
  141. package/src/presets/stylelint.ts +101 -0
  142. package/src/presets/test.ts +19 -0
  143. package/src/presets/typecheck.ts +25 -0
  144. package/src/run-repo-contract.ts +80 -0
  145. package/src/types.ts +340 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/presets/shared/missing-dependency.ts","../src/presets/shared/exit-code-fail-rationale.ts","../src/presets/shared/terminal-status.ts","../src/presets/arethetypeswrong.ts","../src/presets/broken-links.ts","../src/presets/commitlint.ts","../src/presets/dead-code.ts","../src/presets/shared/read-json-report.ts","../src/presets/duplication.ts","../src/presets/e2e.ts","../src/presets/format.ts","../src/presets/license.ts","../src/presets/shared/error-warning-pass-policy.ts","../src/presets/lint.ts","../src/presets/markdownlint.ts","../src/presets/publint.ts","../src/presets/security-deps.ts","../src/presets/security-secrets.ts","../src/presets/stylelint.ts","../src/presets/shared/vitest-json-policy.ts","../src/presets/test.ts","../src/presets/typecheck.ts"],"names":["readFile","REPORT_PATH","test"],"mappings":"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","file":"presets.cjs","sourcesContent":["import type { CheckEvidence, PolicyResult } from \"../../types.js\"\n\n/**\n * Every preset in `src/presets/*.ts` (except `securityDeps`, which shells out\n * to `npm` itself -- something that cannot be \"missing\" in any environment\n * capable of running `npm run <script>` at all) calls this first, before its\n * own pass/fail/warn logic. `CheckEvidence.status === \"spawn_error\"` already\n * distinguishes \"the OS couldn't even launch the executable\" from \"the tool\n * ran and exited non-zero\" -- but not every spawn failure means the package\n * is missing (a permission error or an invalid executable format lands here\n * too), so this checks the structured `spawnErrorCode` for `\"ENOENT\"`\n * specifically rather than treating every spawn error as \"not installed.\"\n * A non-ENOENT spawn error falls through to the preset's normal handling,\n * unchanged, rather than getting a misleading \"not installed\" message.\n * @param result - the check's raw execution evidence to inspect.\n * @param packageName - the npm package a consumer would install to fix this (may differ from the binary name, e.g. `tsc` comes from `typescript`).\n * @returns an actionable, package-manager-neutral `PolicyResult` if the tool appears to be missing, or `undefined` if the caller should proceed with its own interpretation.\n */\nexport function checkDependencyInstalled(\n result: CheckEvidence,\n packageName: string,\n): PolicyResult | undefined {\n if (result.status !== \"spawn_error\" || result.spawnErrorCode !== \"ENOENT\") {\n return undefined\n }\n\n return {\n outcome: \"fail\",\n rationale: `\\`${packageName}\\` is required by this preset but was not found. Install \\`${packageName}\\` as a development dependency and run the contract again.`,\n }\n}\n","import type { CheckEvidence } from \"../../types.js\"\n\n/**\n * A check's captured stdout and stderr, trimmed and joined into one block -- either stream may be\n * empty and is dropped rather than contributing a blank line. Shared by `exitCodeFailRationale`\n * below and by `publint` (which needs the combined text itself, not just a rendered failure\n * message, to detect its own \"Warnings:\"/\"Suggestions:\" section headers).\n * @param result - the check's execution evidence (only `stdout`/`stderr` are read).\n * @returns the combined, trimmed stdout+stderr text, or `\"\"` if the tool produced neither.\n */\nexport function combinedOutput(result: CheckEvidence): string {\n return [result.stdout.trim(), result.stderr.trim()]\n .filter((value): value is string => Boolean(value))\n .join(\"\\n\")\n}\n\n/**\n * Shared by every preset whose policy is a plain \"exitCode 0 = pass, else\n * render captured stdout/stderr (or fall back to an exit-code-only message\n * if the tool produced neither)\" -- `format`, `typecheck`, `commitlint`.\n * Each preset still owns its own pass rationale and its own description of\n * what failed; this only renders the shared \"here's what the tool printed\"\n * half.\n * @param result - the check's execution evidence (only `stdout`/`stderr`/`exitCode` are read).\n * @param description - a present-tense description of the failure, e.g. \"Prettier reported formatting failures\".\n * @returns `\"{description}:\\n{output}\"` when the tool produced output, or `\"{description} (exit code {N}).\"` otherwise.\n */\nexport function exitCodeFailRationale(result: CheckEvidence, description: string): string {\n const output = combinedOutput(result)\n\n return output.length > 0\n ? `${description}:\\n${output}`\n : `${description} (exit code ${String(result.exitCode)}).`\n}\n","import type { CheckEvidence, PolicyResult } from \"../../types.js\"\nimport { combinedOutput } from \"./exit-code-fail-rationale.js\"\n\n/**\n * The guard every preset needs immediately after `checkDependencyInstalled`\n * and before its own pass/fail logic: a check whose process did not run to a\n * normal exit on its own -- it timed out, was aborted via `options.signal`,\n * was killed by a host `SIGINT`/`SIGTERM`, received an external signal, or\n * failed to spawn for a reason other than a missing executable -- has a\n * `null` `exitCode` and only whatever partial output the tool managed before\n * termination. Interpreting that with an exit-code comparison or a JSON\n * parse would present an operational failure to the consumer as a fabricated\n * tool-specific verdict (\"TypeScript reported type errors (exit code null)\",\n * \"ESLint output could not be parsed as JSON\"). This reports the real\n * terminal cause instead.\n *\n * `\"completed\"` returns `undefined` -- the process reached its own exit and\n * the preset interprets the (possibly non-zero) exit code itself. The\n * ENOENT `\"spawn_error\"` case is already handled by `checkDependencyInstalled`;\n * this catches the remaining spawn failures (`EACCES`, `ENOEXEC`) that\n * `missing-dependency.ts` documents as falling through.\n * @param result - the check's raw execution evidence to inspect.\n * @param toolName - the tool's own display name for the rationale (e.g. \"ESLint\", \"TypeScript\").\n * @returns a fail `PolicyResult` describing the abnormal termination, or `undefined` if the process ran to its own exit and the caller should proceed.\n */\nexport function checkTerminatedAbnormally(\n result: CheckEvidence,\n toolName: string,\n): PolicyResult | undefined {\n if (result.status === \"completed\") {\n return undefined\n }\n\n const detail = combinedOutput(result)\n const suffix = detail.length > 0 ? `\\n${detail}` : \"\"\n\n switch (result.status) {\n case \"timed_out\":\n return {\n outcome: \"fail\",\n rationale: `${toolName} did not finish: its process exceeded the configured timeout and was terminated.${suffix}`,\n }\n case \"aborted\":\n return {\n outcome: \"fail\",\n rationale: `${toolName} did not finish: the run was aborted before its process completed.${suffix}`,\n }\n case \"host_terminated\":\n return {\n outcome: \"fail\",\n rationale: `${toolName} did not finish: the host process received a termination signal and killed it.${suffix}`,\n }\n case \"signaled\":\n return {\n outcome: \"fail\",\n rationale: `${toolName} was terminated by signal ${result.signal ?? \"unknown\"} before it completed.${suffix}`,\n }\n case \"spawn_error\":\n return {\n outcome: \"fail\",\n rationale: `${toolName} could not be started: ${result.spawnError ?? \"the process failed to spawn\"}.`,\n }\n default: {\n // A newly added `CheckStatus` must be classified here deliberately, not\n // silently fall through the switch and be read by callers as \"proceed\".\n const unhandled: never = result.status\n throw new Error(`checkTerminatedAbnormally: unhandled check status ${String(unhandled)}`)\n }\n }\n}\n","import type { CheckDefinitionConfig, PolicyResult } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\n/**\n * attw's own `--format json` contract -- not published as a TypeScript type\n * by the tool. `problems` is a flat record keyed by problem kind (e.g.\n * \"FalseCJS\", \"NoResolution\"), each entry carrying whichever context fields\n * that kind of problem produces.\n */\nexport interface AttwReport {\n readonly problems?: Record<string, readonly AttwProblem[]>\n}\n\nexport interface AttwProblem {\n readonly kind: string\n readonly entrypoint?: string\n readonly resolutionKind?: string\n readonly typesFileName?: string\n readonly implementationFileName?: string\n}\n\n/**\n * Renders one attw problem as a single human-readable line, appending whichever context fields (entrypoint, resolution kind, types/impl file names) that problem kind happens to carry.\n * @param problem - the attw problem to render.\n * @returns the rendered `kind: context...` line, or just the kind if it carries no context fields.\n */\nfunction formatProblem(problem: AttwProblem): string {\n const context = [\n problem.entrypoint ? `entrypoint=${problem.entrypoint}` : undefined,\n problem.resolutionKind ? `resolution=${problem.resolutionKind}` : undefined,\n problem.typesFileName ? `types=${problem.typesFileName}` : undefined,\n problem.implementationFileName ? `impl=${problem.implementationFileName}` : undefined,\n ].filter((value): value is string => value !== undefined)\n\n return context.length > 0 ? `${problem.kind}: ${context.join(\" \")}` : problem.kind\n}\n\n/**\n * Interprets an already-parsed attw JSON report -- exported (unlike this\n * package's other internal evaluators) because a repository whose package\n * has enough entrypoints to make attw's own `--format json` output exceed\n * ~64KB can hit a real, reproducible upstream bug: attw truncates its own\n * stdout when it's a pipe (confirmed independently of repo-contract, via\n * plain shell piping) rather than a TTY or regular file. Redirecting attw's\n * output to a file sidesteps that bug; a consumer doing so needs this same\n * interpretation logic without re-deriving it. repo-contract's own\n * `repo-contract.config.ts` does exactly this once it has more than one real\n * entrypoint (see that file's `arethetypeswrong` override).\n * Accepts `unknown` and validates the shape itself: its inputs are always\n * untrusted parsed JSON (a tool's stdout, a report file), and valid JSON of an\n * unexpected shape must produce a clean fail verdict here rather than a\n * `TypeError` in the caller.\n * @param report - the parsed attw JSON report to evaluate.\n * @returns the pass/fail outcome and its rationale.\n */\nexport function evaluateAttwReport(report: unknown): PolicyResult {\n if (typeof report !== \"object\" || report === null) {\n return {\n outcome: \"fail\",\n rationale: \"@arethetypeswrong/cli produced invalid JSON report data.\",\n }\n }\n\n const rawProblems = (report as { problems?: unknown }).problems\n const problemGroups =\n typeof rawProblems === \"object\" && rawProblems !== null ? Object.values(rawProblems) : []\n const problems = problemGroups\n .flat()\n .filter((problem): problem is AttwProblem => typeof problem === \"object\" && problem !== null)\n\n if (problems.length === 0) {\n return {\n outcome: \"pass\",\n rationale: \"@arethetypeswrong/cli found 0 packaged type-resolution problem(s).\",\n }\n }\n\n return {\n outcome: \"fail\",\n rationale: [\n `@arethetypeswrong/cli found ${String(problems.length)} packaged type-resolution problem(s):`,\n ...problems.map((problem) => `- ${formatProblem(problem)}`),\n ].join(\"\\n\"),\n }\n}\n\n// `--pack` runs `npm pack` against the current directory so this preset\n// evaluates exactly what `files`/`exports` in package.json would ship, not\n// the working tree directly. Relevant only to repositories that publish an\n// npm package. Unlike repo-contract's own internal `arethetypeswrong` check,\n// this preset does not exclude any entrypoint -- `--exclude-entrypoints` is\n// specific to whichever of a consumer's own `exports` subpaths are\n// non-code (e.g. a bare JSON schema export), so it's left as a `run`\n// override for the consumer to add, rather than guessed at generically here.\n/** Published-package type-resolution correctness via `@arethetypeswrong/cli`. */\nexport const arethetypeswrong: CheckDefinitionConfig = {\n run: [\"attw\", \"--pack\", \".\", \"--format\", \"json\"],\n output: { format: \"json\" },\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"@arethetypeswrong/cli\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"@arethetypeswrong/cli\")\n if (terminated) return terminated\n\n if (!result.output?.success) {\n return {\n outcome: \"fail\",\n rationale: \"@arethetypeswrong/cli output could not be parsed as JSON.\",\n }\n }\n\n return evaluateAttwReport(result.output.value)\n },\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\n/** linkinator's own `--format json` contract -- not published as a TypeScript type by the tool. */\ninterface LinkinatorLink {\n readonly url: string\n readonly status: number\n readonly state: \"OK\" | \"BROKEN\" | \"SKIPPED\"\n readonly parent?: string\n}\n\ninterface LinkinatorReport {\n readonly links: readonly LinkinatorLink[]\n}\n\n/** Options accepted by {@link brokenLinks}. */\ninterface BrokenLinksOptions {\n /** File or directory passed straight through to linkinator as its positional target. Defaults to `\".\"`. */\n readonly start?: string\n}\n\n/**\n * @param link One linkinator link result with `state === \"BROKEN\"`.\n * @returns A single-line `url -- HTTP status (linked from parent)` summary.\n */\nfunction formatBrokenLink(link: LinkinatorLink): string {\n const parent = link.parent ? ` (linked from ${link.parent})` : \"\"\n\n return `${link.url} -- HTTP ${String(link.status)}${parent}`\n}\n\n/**\n * Broken-link detection via linkinator, recursing through local files and\n * following both local and remote links. `--skip node_modules` avoids\n * wasting the crawl on vendored files that were never authored content.\n * @param options - configuration for this check; see {@link BrokenLinksOptions}.\n * @returns the configured check.\n */\nexport function brokenLinks(options: BrokenLinksOptions = {}): CheckDefinitionConfig {\n const { start = \".\" } = options\n\n return {\n run: [\"linkinator\", start, \"--recurse\", \"--format\", \"json\", \"--skip\", \"node_modules\"],\n output: { format: \"json\" },\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"linkinator\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"linkinator\")\n if (terminated) return terminated\n\n if (!result.output?.success) {\n return { outcome: \"fail\", rationale: \"linkinator output could not be parsed as JSON.\" }\n }\n\n // Valid JSON of an unexpected shape (a future linkinator reporter\n // change, `null`, a primitive, or any leading non-JSON line that still\n // parses to something without `.links`) must produce a clean fail, not\n // a TypeError that escapes the policy and crashes the whole run --\n // matching how dead-code.ts / duplication.ts guard their own reports.\n const value: unknown = result.output.value\n\n if (typeof value !== \"object\" || value === null) {\n return { outcome: \"fail\", rationale: \"linkinator produced invalid JSON report data.\" }\n }\n\n const report = value as LinkinatorReport\n\n if (!Array.isArray(report.links)) {\n return { outcome: \"fail\", rationale: \"linkinator produced invalid JSON report data.\" }\n }\n\n // Re-annotated rather than used directly: `Array.isArray` narrows to\n // `any[]` regardless of the checked value's declared type.\n const links: readonly LinkinatorLink[] = report.links\n const brokenLinkResults = links.filter((link) => link.state === \"BROKEN\")\n\n if (brokenLinkResults.length === 0) {\n return {\n outcome: \"pass\",\n rationale: `linkinator found 0 broken link(s) across ${String(links.length)} checked.`,\n }\n }\n\n return {\n outcome: \"fail\",\n rationale: [\n `linkinator found ${String(brokenLinkResults.length)} broken link(s):`,\n ...brokenLinkResults.map((link) => `- ${formatBrokenLink(link)}`),\n ].join(\"\\n\"),\n }\n },\n }\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\nimport { exitCodeFailRationale } from \"./shared/exit-code-fail-rationale.js\"\n\n/** Options accepted by {@link commitlint}. */\ninterface CommitlintOptions {\n /** The ref commitlint lints commits *from* (exclusive). Defaults to `\"origin/main\"`. */\n readonly from?: string\n /** The ref commitlint lints commits *to* (inclusive). Defaults to `\"HEAD\"`. */\n readonly to?: string\n}\n\n/**\n * The git commands a contributor runs to fix commit messages already on their branch. Appended\n * to every failure rationale so the fix is in the error itself, not a doc they have to go find.\n * @param from - the ref the rebase is based on (commitlint's own `--from`).\n * @returns the remediation block, leading with a blank line.\n */\nfunction remediation(from: string): string {\n return [\n \"\",\n \"Rewrite the offending commit message(s) already on this branch:\",\n \"\",\n ` git rebase -i ${from}`,\n \"\",\n \"In the editor, for each commit flagged above change `pick` to:\",\n \" - `reword` to keep the commit but fix its message (a valid Conventional Commit:\",\n \" `type(scope): subject`, lowercase type, no trailing period), or\",\n \" - `squash` / `fixup` to fold it into the commit before it, or\",\n \" - `drop` to remove the commit entirely.\",\n \"\",\n \"Then, if the branch is already pushed:\",\n \"\",\n \" git push --force-with-lease\",\n ].join(\"\\n\")\n}\n\n/**\n * Commit-message governance via commitlint, using whatever commitlint\n * config the consumer's own repository already has (commitlint ships no\n * rules of its own -- e.g. `@commitlint/config-conventional`). Exit-code\n * based rather than `--format json`: commitlint has no broadly-documented,\n * stable JSON CLI output, so this preset reads its plain-text report the\n * same way the `format`/`typecheck` presets already do for their tools,\n * rather than relying on an unconfirmed flag.\n * @param options - configuration for this check; see {@link CommitlintOptions}.\n * @returns the configured check.\n */\nexport function commitlint(options: CommitlintOptions = {}): CheckDefinitionConfig {\n const { from = \"origin/main\", to = \"HEAD\" } = options\n\n return {\n run: [\"commitlint\", \"--from\", from, \"--to\", to],\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"@commitlint/cli\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"commitlint\")\n if (terminated) return terminated\n\n if (result.exitCode === 0) {\n return {\n outcome: \"pass\",\n rationale: `commitlint found 0 commit message violations between ${from} and ${to}.`,\n }\n }\n\n return {\n outcome: \"fail\",\n rationale:\n exitCodeFailRationale(result, \"commitlint reported commit message violations\") +\n `\\n${remediation(from)}`,\n }\n },\n }\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\n/**\n * Knip does not expose the serialized JSON reporter result as a public\n * TypeScript type, so the local evidence type below intentionally models\n * that JSON contract. This targets knip's `json` reporter as of knip 6:\n * `{ issues: KnipIssue[] }`, one entry per file, each carrying an array per\n * issue category (`knip 5` additionally had a top-level `files: string[]` for\n * unused files; knip 6 folds those into `issues[].files`). The policy reports\n * the actual issue category and name instead of only returning a count.\n */\ninterface KnipIssueEntry {\n readonly name: string\n readonly line?: number\n readonly col?: number\n readonly pos?: number\n}\n\n/** `duplicates`/`cycles` group several symbols together; every other category is a flat entry. */\ntype KnipCategory = readonly (KnipIssueEntry | readonly KnipIssueEntry[])[]\n\ninterface KnipIssue {\n readonly file: string\n readonly dependencies?: KnipCategory\n readonly devDependencies?: KnipCategory\n readonly optionalPeerDependencies?: KnipCategory\n readonly unlisted?: KnipCategory\n readonly unresolved?: KnipCategory\n readonly exports?: KnipCategory\n readonly types?: KnipCategory\n readonly nsExports?: KnipCategory\n readonly nsTypes?: KnipCategory\n readonly namespaceMembers?: KnipCategory\n readonly enumMembers?: KnipCategory\n readonly binaries?: KnipCategory\n readonly duplicates?: KnipCategory\n readonly cycles?: KnipCategory\n readonly files?: KnipCategory\n}\n\ninterface KnipReport {\n readonly issues: readonly KnipIssue[]\n}\n\n/** Options accepted by {@link deadCode}. */\ninterface DeadCodeOptions {\n /**\n * devDependency names to exclude from the \"unused devDependency\" issue\n * category -- e.g. CLI tools knip has no way to see are used, because\n * nothing `import`s them. Round-tripped through knip's own\n * `--reporter-options` flag (see `readReporterOptions`) rather than kept in\n * a closure, so the exempt list this check actually ran with is visible on\n * the recorded command line and in persisted evidence, not just in this\n * file's source. Defaults to an empty list -- repo-contract ships no\n * built-in exemptions; add your own repository's here.\n */\n readonly exemptUnusedDevDependencies?: readonly string[]\n}\n\n/**\n * Recovers the JSON payload knip's own `--reporter-options` flag was invoked\n * with, if any. This is how `deadCode`'s exempt list gets from `run` back\n * into the policy purely via `result.args` -- see {@link DeadCodeOptions}.\n * @param args - the exact argv the check's command was spawned with (`CheckEvidence.args`).\n * @returns the parsed `--reporter-options` payload, or `undefined` if the flag is absent or its value isn't valid JSON.\n */\nfunction readReporterOptions(args: readonly string[]): DeadCodeOptions | undefined {\n const flagIndex = args.indexOf(\"--reporter-options\")\n const raw = flagIndex === -1 ? undefined : args[flagIndex + 1]\n\n // Provably equivalent, not a coverage gap: `JSON.parse(undefined)` (what\n // happens if this guard is removed or forced false) always throws\n // (\"undefined\" is not valid JSON, confirmed empirically), which the catch\n // block below already converts back to `undefined` -- the exact same\n // observable result this early return produces. Kept for clarity (avoids\n // relying on that throw-and-catch as the mechanism), not for behavior no\n // test can otherwise reach.\n // Stryker disable next-line ConditionalExpression,EqualityOperator,BlockStatement -- JSON.parse(undefined) always throws, and the catch block below already converts that back to undefined, the same result this early return produces\n if (raw === undefined) {\n return undefined\n }\n\n // Provably equivalent, not a coverage gap: the catch block below is the\n // last statement in the function, so an empty block there falls off the\n // end and implicitly returns `undefined` anyway -- identical to its\n // explicit `return undefined`. Kept for clarity, not for behavior no\n // test can otherwise reach.\n // Stryker disable BlockStatement -- an empty catch block falls off the end of the function and implicitly returns undefined, identical to its explicit return\n try {\n return JSON.parse(raw) as DeadCodeOptions\n } catch {\n return undefined\n }\n // Stryker restore all\n}\n\n/**\n * Renders one category entry as `{ name, location }`. `duplicates`/`cycles` entries are a\n * group of symbols (knip pushes `symbols.map(...)`); every other category is a flat entry.\n * @param entry - a single `KnipIssueEntry`, or a `duplicates`/`cycles` group of them.\n * @returns the joined symbol name(s) and a `:line:col` suffix (empty for a group or a\n * location-less entry).\n */\nfunction formatEntry(entry: KnipIssueEntry | readonly KnipIssueEntry[]): {\n readonly name: string\n readonly location: string\n} {\n if (Array.isArray(entry)) {\n const group = entry as readonly KnipIssueEntry[]\n return { name: group.map((member) => member.name).join(\", \"), location: \"\" }\n }\n\n const single = entry as KnipIssueEntry\n const location =\n typeof single.line === \"number\" ? `:${String(single.line)}:${String(single.col ?? 1)}` : \"\"\n return { name: single.name, location }\n}\n\n/**\n * Dead/unused-code detection via knip.\n * @param options - configuration for this check; see {@link DeadCodeOptions}.\n * @returns the configured check.\n */\nexport function deadCode(options: DeadCodeOptions = {}): CheckDefinitionConfig {\n const { exemptUnusedDevDependencies = [] } = options\n\n return {\n run: [\n \"knip\",\n \"--reporter\",\n \"json\",\n \"--reporter-options\",\n JSON.stringify({ exemptUnusedDevDependencies } satisfies DeadCodeOptions),\n ],\n output: { format: \"json\" },\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"knip\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"Knip\")\n if (terminated) return terminated\n\n if (!result.output?.success) {\n return { outcome: \"fail\", rationale: \"Knip output could not be parsed as JSON.\" }\n }\n\n // `output.success` only means `JSON.parse` didn't throw -- `value` is `unknown` at\n // runtime. Guard that it is a real object (not `null` / a primitive / an array) before\n // trusting the `KnipReport` cast, so a policy TypeError never escapes into the run.\n const value: unknown = result.output.value\n\n if (typeof value !== \"object\" || value === null) {\n return { outcome: \"fail\", rationale: \"Knip produced invalid JSON report data.\" }\n }\n\n const report = value as KnipReport\n\n if (!Array.isArray(report.issues)) {\n return { outcome: \"fail\", rationale: \"Knip produced invalid JSON report data.\" }\n }\n\n // Re-annotated rather than used directly: `Array.isArray` narrows its\n // argument to `any[]` regardless of the checked value's declared type (a\n // long-standing TypeScript limitation), so `report.issues` would\n // otherwise silently lose its element type below.\n const issues: readonly KnipIssue[] = report.issues\n\n const exemptDevDependencies = new Set(\n readReporterOptions(result.args)?.exemptUnusedDevDependencies ?? [],\n )\n\n const details: string[] = []\n\n for (const issue of issues) {\n const addEntries = (\n label: string,\n entries: KnipCategory | undefined,\n ignored: ReadonlySet<string> = new Set(),\n ): void => {\n for (const entry of entries ?? []) {\n const { name, location } = formatEntry(entry)\n\n if (ignored.has(name)) {\n continue\n }\n\n details.push(`${issue.file}${location} — ${label}: ${name}`)\n }\n }\n\n addEntries(\"unused dependency\", issue.dependencies)\n addEntries(\"unused devDependency\", issue.devDependencies, exemptDevDependencies)\n addEntries(\"unused optional peer dependency\", issue.optionalPeerDependencies)\n addEntries(\"unlisted dependency\", issue.unlisted)\n addEntries(\"unresolved import\", issue.unresolved)\n addEntries(\"unused export\", issue.exports)\n addEntries(\"unused export (namespace)\", issue.nsExports)\n addEntries(\"unused type\", issue.types)\n addEntries(\"unused type (namespace)\", issue.nsTypes)\n addEntries(\"unused namespace member\", issue.namespaceMembers)\n addEntries(\"unused enum member\", issue.enumMembers)\n addEntries(\"unlisted binary\", issue.binaries)\n addEntries(\"duplicate export\", issue.duplicates)\n addEntries(\"circular dependency\", issue.cycles)\n addEntries(\"unused file\", issue.files)\n }\n\n if (details.length === 0) {\n return { outcome: \"pass\", rationale: \"Knip reported 0 issues.\" }\n }\n\n return {\n outcome: \"fail\",\n rationale: [\n `Knip reported ${String(details.length)} issue(s):`,\n ...details.map((detail: string) => `- ${detail}`),\n ].join(\"\\n\"),\n }\n },\n }\n}\n","import type { PolicyResult } from \"../../types.js\"\n\n/** The report, already JSON-parsed and narrowed to `T`, or the fail `PolicyResult` to return verbatim when reading or parsing it failed. See `readJsonReport`. */\ntype ReadJsonReportResult<T> =\n { readonly ok: true; readonly value: T } | { readonly ok: false; readonly result: PolicyResult }\n\n/**\n * Reads and JSON-parses a report a tool wrote to disk rather than printing to stdout -- the \"read,\n * fail with one rationale if the read itself fails, fail with a different rationale if the JSON is\n * invalid\" shape shared by every preset whose tool has no stdout JSON mode (jscpd,\n * markdownlint-cli2, secretlint). Each failure takes its own caller-supplied rationale rather than a\n * generic shared message, since a missing report and invalid JSON usually point a consumer at a\n * different fix (a misconfigured reporter/output flag vs. a genuinely broken tool run), and each\n * tool's own advice differs (markdownlint's own read-failure rationale, for instance, names the\n * specific config field to check).\n *\n * Takes the read itself as a thunk (`readRaw`), rather than a `path` this function reads from\n * directly, so every call site's own `readFile(LITERAL_PATH, \"utf8\")` stays written as a literal\n * argument in the caller's own file -- required by this repo's `security/detect-non-literal-fs-filename`\n * policy, which forbids suppressing that rule outright (see policy-config.ts's `eslint.rules[\"security/*\"]`)\n * and would otherwise flag a `path: string` function parameter threaded into `readFile` here as\n * non-literal.\n * @param readRaw - reads the report's raw text (typically `() => readFile(REPORT_PATH, \"utf8\")`).\n * @param onReadFailed - the rationale to fail with if `readRaw` rejects.\n * @param onParseFailed - the rationale to fail with if the read text isn't valid JSON.\n * @returns `{ ok: true, value }` with the parsed JSON narrowed to `T`, or `{ ok: false, result }` with the fail `PolicyResult` to return verbatim.\n */\nexport async function readJsonReport<T>(\n readRaw: () => Promise<string>,\n onReadFailed: string,\n onParseFailed: string,\n): Promise<ReadJsonReportResult<T>> {\n let raw: string\n\n try {\n raw = await readRaw()\n } catch {\n return { ok: false, result: { outcome: \"fail\", rationale: onReadFailed } }\n }\n\n try {\n return { ok: true, value: JSON.parse(raw) as T }\n } catch {\n return { ok: false, result: { outcome: \"fail\", rationale: onParseFailed } }\n }\n}\n","import { readFile } from \"node:fs/promises\"\nimport type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { readJsonReport } from \"./shared/read-json-report.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\ninterface JscpdFileSpan {\n readonly name: string\n readonly start: number\n readonly end: number\n}\n\ninterface JscpdDuplicate {\n readonly format: string\n readonly lines: number\n readonly tokens: number\n readonly firstFile: JscpdFileSpan\n readonly secondFile: JscpdFileSpan\n}\n\ninterface JscpdStatisticsTotal {\n readonly clones: number\n readonly duplicatedLines: number\n readonly lines: number\n readonly percentage: number\n readonly sources: number\n}\n\ninterface JscpdReport {\n readonly duplicates?: readonly JscpdDuplicate[]\n readonly statistics?: {\n readonly total?: JscpdStatisticsTotal\n }\n}\n\n/** Options accepted by {@link duplication}. */\ninterface DuplicationOptions {\n /** Directory to scan for duplicated code, passed straight through to jscpd as its positional target. Defaults to `\".\"` -- narrow it (e.g. `\"src\"`) to scope the scan to your own source tree. */\n readonly path?: string\n}\n\n// Kept in lockstep with the `--output reports/jscpd` argument below. Both are\n// relative and resolve against the *host* process's cwd, not the check's own\n// `cwd` option: jscpd writes here and this policy's `readFile` reads from here,\n// so a check configured with a different `cwd` would look in the wrong place.\n// This preset does not expose an output-path option -- a consumer needing one\n// runs jscpd via a custom `run`/`policy` instead.\nconst REPORT_PATH = \"reports/jscpd/jscpd-report.json\"\n\n// jscpd's JSON reporter writes its report to disk -- it never prints JSON to\n// stdout, which instead carries decorative progress/summary text -- so the\n// report is read from disk directly. jscpd's own `--threshold`/`--exit-code`\n// flags are deliberately not used: this preset reads the raw clone count\n// from evidence and owns the pass/fail decision itself, exactly as the\n// deadCode/securityDeps presets already do for their own tools.\n/**\n * Duplicated-code detection via jscpd.\n * @param options - configuration for this check; see {@link DuplicationOptions}.\n * @returns the configured check.\n */\nexport function duplication(options: DuplicationOptions = {}): CheckDefinitionConfig {\n const { path = \".\" } = options\n\n return {\n run: [\"jscpd\", path, \"--reporters\", \"json\", \"--output\", \"reports/jscpd\", \"--silent\"],\n policy: async ({ result }) => {\n const missing = checkDependencyInstalled(result, \"jscpd\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"jscpd\")\n if (terminated) return terminated\n\n const parsed = await readJsonReport<JscpdReport>(\n // Provably equivalent, not a coverage gap: `JSON.parse` coerces\n // whatever `readFile` returns via that value's own `toString()`\n // (confirmed empirically for a Buffer, which is what a mutated/\n // unrecognized encoding argument produces here) -- and `Buffer`'s\n // default `toString()` encoding is itself utf8, so parsing succeeds\n // identically either way. No test can observe a difference through\n // this policy's output.\n // Stryker disable next-line StringLiteral -- JSON.parse coerces via toString(), which defaults to utf8 for a Buffer, so parsing succeeds identically either way\n () => readFile(REPORT_PATH, \"utf8\"),\n \"jscpd did not produce its expected JSON report.\",\n \"jscpd produced invalid JSON evidence.\",\n )\n if (!parsed.ok) return parsed.result\n // `readJsonReport<T>` narrows only at the type level -- the value is `unknown` at\n // runtime. Guard it is a real object before trusting the cast, so `.statistics` /\n // `.duplicates` never throw a TypeError out of the policy (matching markdownlint.ts).\n const value: unknown = parsed.value\n\n if (typeof value !== \"object\" || value === null) {\n return { outcome: \"fail\", rationale: \"jscpd produced invalid JSON report data.\" }\n }\n\n const report = value as JscpdReport\n const total = report.statistics?.total\n\n if (\n !Array.isArray(report.duplicates) ||\n !total ||\n typeof total.percentage !== \"number\" ||\n !Number.isFinite(total.percentage)\n ) {\n // `total.percentage` feeds `.toFixed(2)` below -- a missing or non-finite\n // value would throw or render \"NaN\" instead of failing cleanly.\n return { outcome: \"fail\", rationale: \"jscpd produced invalid JSON report data.\" }\n }\n\n // Re-annotated rather than used directly: `Array.isArray` narrows its\n // argument to `any[]` regardless of the checked value's declared type (a\n // long-standing TypeScript limitation), so `report.duplicates` would\n // otherwise silently lose its `JscpdDuplicate` element type below.\n const duplicates: readonly JscpdDuplicate[] = report.duplicates\n\n if (duplicates.length === 0) {\n return {\n outcome: \"pass\",\n rationale: `jscpd found 0 duplicated block(s) across ${String(total.sources)} file(s) (${String(total.lines)} lines).`,\n }\n }\n\n const details = duplicates.map(\n (duplicate) =>\n `${duplicate.firstFile.name}:${String(duplicate.firstFile.start)} duplicates ${duplicate.secondFile.name}:${String(duplicate.secondFile.start)} -- ${String(duplicate.lines)} lines / ${String(duplicate.tokens)} tokens`,\n )\n\n return {\n outcome: \"fail\",\n rationale: [\n `jscpd found ${String(duplicates.length)} duplicated block(s) (${total.percentage.toFixed(2)}% of ${String(total.lines)} lines across ${String(total.sources)} file(s)):`,\n ...details.map((detail) => `- ${detail}`),\n ].join(\"\\n\"),\n }\n },\n }\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\n/**\n * Playwright's own `--reporter=json` contract -- not published as a\n * TypeScript type by the tool. Suites nest (a project, then a file, then\n * `describe` blocks), so failing specs are collected recursively.\n */\ninterface PlaywrightTestResult {\n readonly status?: string\n readonly error?: { readonly message?: string }\n}\n\ninterface PlaywrightTest {\n readonly results?: readonly PlaywrightTestResult[]\n}\n\ninterface PlaywrightSpec {\n readonly title: string\n readonly file?: string\n readonly line?: number\n readonly ok: boolean\n readonly tests?: readonly PlaywrightTest[]\n}\n\ninterface PlaywrightSuite {\n readonly title: string\n readonly specs?: readonly PlaywrightSpec[]\n readonly suites?: readonly PlaywrightSuite[]\n}\n\ninterface PlaywrightStats {\n readonly expected: number\n readonly unexpected: number\n readonly flaky: number\n readonly skipped: number\n}\n\ninterface PlaywrightReport {\n readonly suites?: readonly PlaywrightSuite[]\n readonly stats?: PlaywrightStats\n}\n\n/**\n * Recursively collects one human-readable line per failing spec across a (possibly nested) suite tree.\n * @param suites - the suite tree to walk, as `PlaywrightReport.suites` or a suite's own nested `suites`.\n * @returns one rendered `file:line title -- message` line per failing spec, depth-first.\n */\nfunction collectFailingSpecs(suites: readonly PlaywrightSuite[]): string[] {\n const details: string[] = []\n\n for (const suite of suites) {\n for (const spec of suite.specs ?? []) {\n if (spec.ok) continue\n\n const location = spec.line !== undefined ? `:${String(spec.line)}` : \"\"\n // Provably equivalent, not a coverage gap: whatever non-array/non-test\n // garbage a mutated `?? []` fallback substitutes here, every field\n // access on it below (`.results`, `.error`, `.message`) resolves\n // safely to `undefined` via its own optional chaining -- confirmed by\n // hand-tracing both fallback sites -- converging on the exact same\n // `message: undefined` this line already produces for a genuinely\n // empty `spec.tests`/`t.results`. No test can observe a difference.\n // Stryker disable next-line ArrayDeclaration -- any fallback garbage here resolves safely to undefined via optional chaining below, same as a genuinely empty array\n const lastResult = (spec.tests ?? []).flatMap((t) => t.results ?? []).at(-1)\n const message = lastResult?.error?.message?.trim()\n\n details.push(\n `${spec.file ?? suite.title}${location} ${spec.title}${message ? ` — ${message}` : \"\"}`,\n )\n }\n\n if (suite.suites) details.push(...collectFailingSpecs(suite.suites))\n }\n\n return details\n}\n\n/** End-to-end test execution via Playwright, reading its JSON reporter output. */\nexport const e2e: CheckDefinitionConfig = {\n run: [\"playwright\", \"test\", \"--reporter=json\"],\n output: { format: \"json\" },\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"@playwright/test\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"Playwright\")\n if (terminated) return terminated\n\n if (!result.output?.success) {\n return { outcome: \"fail\", rationale: \"Playwright output could not be parsed as JSON.\" }\n }\n\n // `output.success` only means `JSON.parse` didn't throw -- `value` is `unknown` at\n // runtime. Guard it is a real object before trusting the cast, matching how\n // dead-code.ts / duplication.ts guard theirs, so `.stats` never throws out of the policy.\n const value: unknown = result.output.value\n\n if (typeof value !== \"object\" || value === null) {\n return { outcome: \"fail\", rationale: \"Playwright produced invalid JSON report data.\" }\n }\n\n const report = value as PlaywrightReport\n const stats = report.stats\n\n if (!stats || typeof stats.unexpected !== \"number\" || typeof stats.flaky !== \"number\") {\n // The outcome checks below compare `unexpected`/`flaky` numerically -- a\n // missing or non-numeric counter must fail cleanly, not slip through every\n // comparison as `false`.\n return { outcome: \"fail\", rationale: \"Playwright produced invalid JSON report data.\" }\n }\n\n if (stats.unexpected === 0 && stats.flaky === 0) {\n return {\n outcome: \"pass\",\n rationale: `Playwright completed ${String(stats.expected)} test(s) with 0 unexpected failures.`,\n }\n }\n\n if (stats.unexpected > 0) {\n // Provably equivalent, not a coverage gap: collectFailingSpecs itself\n // only ever reads `.specs`/`.suites` off each element via safe\n // optional chaining (see its own comment), so substituting any\n // non-suite garbage for a genuinely absent `report.suites` still\n // yields zero collected detail lines either way.\n // Stryker disable next-line ArrayDeclaration -- collectFailingSpecs only reads .specs/.suites via safe optional chaining, so fallback garbage yields zero details either way\n const details = collectFailingSpecs(report.suites ?? [])\n\n return {\n outcome: \"fail\",\n rationale: [\n `Playwright reported ${String(stats.unexpected)} unexpected failure(s):`,\n ...details.map((detail) => `- ${detail}`),\n ].join(\"\\n\"),\n }\n }\n\n return {\n outcome: \"warn\",\n rationale: `Playwright completed with ${String(stats.flaky)} flaky test(s) that eventually passed on retry.`,\n }\n },\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\nimport { exitCodeFailRationale } from \"./shared/exit-code-fail-rationale.js\"\n\n/** Code formatting via Prettier, applied in place. */\nexport const format: CheckDefinitionConfig = {\n run: [\"prettier\", \"--write\", \".\"],\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"prettier\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"Prettier\")\n if (terminated) return terminated\n\n if (result.exitCode === 0) {\n return { outcome: \"pass\", rationale: \"Prettier reported no formatting failures.\" }\n }\n\n return {\n outcome: \"fail\",\n rationale: exitCodeFailRationale(result, \"Prettier reported formatting failures\"),\n }\n },\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { exitCodeFailRationale } from \"./shared/exit-code-fail-rationale.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\ninterface LicenseeEntry {\n readonly name: string\n readonly version: string\n readonly license?: string\n}\n\n// `--production` scopes evaluation to the dependency graph actually shipped\n// to consumers -- devDependencies never end up in a consumer's install, so\n// their licenses carry no obligation onto this package's own license. Same\n// runtime-only rationale the securityDeps preset already applies to `npm\n// audit --omit=dev`. `--osi` treats Open Source Initiative approval as the\n// approval criterion rather than a repository-maintained SPDX allowlist --\n// the same \"policy is repository policy, not a repo-contract opinion\"\n// stance securityDeps documents, just resolved to the broadest\n// widely-recognized standard instead of a bespoke list. `--errors-only`\n// keeps the ndjson evidence limited to the packages actually driving the\n// verdict, matching the deadCode/duplication presets' report-issues-only\n// shape.\n/** Dependency license compliance via licensee. */\nexport const license: CheckDefinitionConfig = {\n run: [\"licensee\", \"--production\", \"--osi\", \"--errors-only\", \"--ndjson\"],\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"licensee\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"licensee\")\n if (terminated) return terminated\n\n const trimmed = result.stdout.trim()\n\n // `--errors-only` makes licensee exit non-zero *because* it found an\n // offending dependency -- so a non-zero exit with ndjson on stdout is the\n // expected failure path, handled below. But a non-zero exit with *empty*\n // stdout means licensee never evaluated anything (node_modules not\n // installed, an unreadable dependency tree, an internal `die()`): the\n // error is on stderr and there is nothing to parse. Treating that as\n // \"found 0 offending dependencies\" would let the compliance gate pass on\n // a run that never actually ran. Only an empty stdout from a process that\n // exited cleanly on its own is a genuine \"nothing offending\" pass.\n if (trimmed.length === 0) {\n if (result.status === \"completed\" && result.exitCode === 0) {\n return {\n outcome: \"pass\",\n rationale: \"licensee found 0 production dependencies with a non-OSI-approved license.\",\n }\n }\n\n return {\n outcome: \"fail\",\n rationale: exitCodeFailRationale(\n result,\n \"licensee did not evaluate any dependency licenses (it produced no output)\",\n ),\n }\n }\n\n let entries: readonly LicenseeEntry[]\n\n try {\n entries = trimmed\n .split(\"\\n\")\n // licensee emits one JSON object per line; a blank line between\n // records (some versions/locales do this, as can a leading\n // informational line) is not invalid evidence -- skip it rather than\n // feeding \"\" to JSON.parse and discarding the real violation list.\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .map((line) => JSON.parse(line) as LicenseeEntry)\n } catch {\n return { outcome: \"fail\", rationale: \"licensee produced invalid JSON evidence.\" }\n }\n\n const details = entries\n .map((entry) => `${entry.name}@${entry.version}: ${entry.license ?? \"unknown license\"}`)\n .sort()\n\n return {\n outcome: \"fail\",\n rationale: [\n `licensee found ${String(details.length)} production dependency(ies) without an OSI-approved license:`,\n ...details.map((detail) => `- ${detail}`),\n ].join(\"\\n\"),\n }\n },\n}\n","import type { PolicyResult } from \"../../types.js\"\n\n/**\n * The shared three-branch shape behind every lint-style preset's pass/warn/fail decision: fail,\n * listing every error, if there are any; else warn, listing every warning, if there are any; else\n * pass -- shared by `lint` (ESLint) and `stylelint`, whose only difference was the tool name\n * substituted into each rationale string.\n * @param toolName - the tool's own display name, substituted into every rationale (e.g. \"ESLint\", \"stylelint\").\n * @param errorDetails - one rendered line per error-severity finding.\n * @param warningDetails - one rendered line per warning-severity finding.\n * @returns the fail/warn/pass `PolicyResult`.\n */\nexport function errorWarningPassPolicy(\n toolName: string,\n errorDetails: readonly string[],\n warningDetails: readonly string[],\n): PolicyResult {\n if (errorDetails.length > 0) {\n return {\n outcome: \"fail\",\n rationale: [\n `${toolName} reported ${String(errorDetails.length)} error(s):`,\n ...errorDetails.map((detail) => `- ${detail}`),\n ].join(\"\\n\"),\n }\n }\n\n if (warningDetails.length > 0) {\n return {\n outcome: \"warn\",\n rationale: [\n `${toolName} reported 0 errors but ${String(warningDetails.length)} warning(s):`,\n ...warningDetails.map((detail) => `- ${detail}`),\n ].join(\"\\n\"),\n }\n }\n\n return { outcome: \"pass\", rationale: `${toolName} reported 0 errors and 0 warnings.` }\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { combinedOutput } from \"./shared/exit-code-fail-rationale.js\"\nimport { errorWarningPassPolicy } from \"./shared/error-warning-pass-policy.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\n/**\n * ESLint does not expose its JSON formatter result as a public LintResult\n * export -- these types describe the JSON formatter contract rather than\n * ESLint's internal Linter types.\n */\ninterface EslintMessage {\n readonly ruleId: string | null\n readonly severity: 0 | 1 | 2\n readonly message: string\n readonly line: number\n readonly column: number\n}\n\ninterface EslintResult {\n readonly filePath: string\n readonly messages: readonly EslintMessage[]\n readonly errorCount: number\n readonly warningCount: number\n}\n\n/** Options accepted by {@link lint}. */\ninterface LintOptions {\n /** Path (or glob) passed straight through to ESLint as its positional target. Defaults to `\".\"` -- narrow it (e.g. `\"src\"`) to scope linting to your own source tree. */\n readonly path?: string\n}\n\n/**\n * Renders every message at the given severity across all files as one `file:line:column [rule]: message` line each.\n * @param results - the full ESLint JSON formatter result to filter and render.\n * @param severity - which severity to render (`2` for errors, `1` for warnings).\n * @returns one rendered line per matching message, across every file.\n */\nfunction renderMessages(results: readonly EslintResult[], severity: 1 | 2): string[] {\n return results.flatMap((file: EslintResult): string[] =>\n file.messages\n .filter((message: EslintMessage) => message.severity === severity)\n .map((message: EslintMessage) => {\n const rule = message.ruleId ? ` [${message.ruleId}]` : \"\"\n\n return `${file.filePath}:${String(message.line)}:${String(message.column)}${rule}: ${message.message}`\n }),\n )\n}\n\n/**\n * Static analysis via ESLint, using whatever `eslint.config.js` the\n * consumer's own repository already has -- this preset makes no assumption\n * about rule configuration, only about how to run the tool and interpret\n * its JSON output. Severity `2` (error) blocks; severity `1` (warning) is\n * reported but never blocks -- ESLint's own severities already encode that\n * distinction, so this preset just respects it rather than treating every\n * finding as equally blocking.\n * @param options - configuration for this check; see {@link LintOptions}.\n * @returns the configured check.\n */\nexport function lint(options: LintOptions = {}): CheckDefinitionConfig {\n const { path = \".\" } = options\n\n return {\n run: [\"eslint\", path, \"--format\", \"json\"],\n output: { format: \"json\" },\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"eslint\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"ESLint\")\n if (terminated) return terminated\n\n if (!result.output?.success) {\n // ESLint exits non-zero with no JSON on stdout both for a flat-config\n // load error and for a glob that matched no lintable files. Surface\n // whatever it printed so the consumer sees the real cause instead of\n // only \"could not be parsed as JSON\".\n const printed = combinedOutput(result)\n\n return {\n outcome: \"fail\",\n rationale:\n printed.length > 0\n ? `ESLint output could not be parsed as JSON. ESLint printed:\\n${printed}`\n : \"ESLint output could not be parsed as JSON.\",\n }\n }\n\n // Valid JSON of an unexpected shape (an ESLint formatter change, a\n // primitive, an entry without a `messages` array) must fail cleanly, not\n // throw a TypeError out of `renderMessages` -- matching the other JSON\n // presets' guards.\n const value: unknown = result.output.value\n if (\n !Array.isArray(value) ||\n !value.every(\n (file): file is EslintResult =>\n typeof file === \"object\" &&\n file !== null &&\n Array.isArray((file as { messages?: unknown }).messages),\n )\n ) {\n return { outcome: \"fail\", rationale: \"ESLint output could not be parsed as JSON.\" }\n }\n\n const results: readonly EslintResult[] = value\n\n const errorDetails = renderMessages(results, 2)\n const warningDetails = renderMessages(results, 1)\n\n return errorWarningPassPolicy(\"ESLint\", errorDetails, warningDetails)\n },\n }\n}\n","import { readFile } from \"node:fs/promises\"\nimport type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { readJsonReport } from \"./shared/read-json-report.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\n/**\n * markdownlint-cli2 has no stdout JSON mode -- this describes its own JSON\n * output-formatter contract (markdownlint-cli2-formatter-json), read back\n * from disk. Not published as a TypeScript type by either package.\n */\ninterface MarkdownlintFinding {\n readonly fileName: string\n readonly lineNumber: number\n readonly ruleNames: readonly string[]\n readonly ruleDescription: string\n readonly errorDetail: string | null\n readonly severity: \"error\" | \"warning\"\n}\n\n/** Options accepted by {@link markdownlint}. */\ninterface MarkdownlintOptions {\n /** Glob passed straight through to markdownlint-cli2 as its positional target. Defaults to `\"**\\/*.md\"`. */\n readonly glob?: string\n}\n\nconst REPORT_PATH = \"reports/markdownlint.json\"\n\n/**\n * @param finding One markdownlint-cli2 finding.\n * @returns A single-line `file:line [rule]: description (detail)` summary.\n */\nfunction formatFinding(finding: MarkdownlintFinding): string {\n const rule = finding.ruleNames.join(\"/\")\n const detail = finding.errorDetail ? ` (${finding.errorDetail})` : \"\"\n\n return `${finding.fileName}:${String(finding.lineNumber)} [${rule}]: ${finding.ruleDescription}${detail}`\n}\n\n/**\n * Markdown structure/style lint via markdownlint-cli2. Unlike this\n * package's other file-based-report presets, the report path is\n * config-driven rather than a CLI flag -- markdownlint-cli2 only writes\n * JSON when its own config file requests it. This preset assumes the\n * consumer's `.markdownlint-cli2.jsonc` includes:\n * ```jsonc\n * \"outputFormatters\": [[\"markdownlint-cli2-formatter-json\", { \"name\": \"reports/markdownlint.json\" }]]\n * ```\n * which also requires the `markdownlint-cli2-formatter-json` package\n * alongside `markdownlint-cli2` itself.\n * @param options - configuration for this check; see {@link MarkdownlintOptions}.\n * @returns the configured check.\n */\nexport function markdownlint(options: MarkdownlintOptions = {}): CheckDefinitionConfig {\n const { glob = \"**/*.md\" } = options\n\n return {\n run: [\"markdownlint-cli2\", glob],\n policy: async ({ result }) => {\n const missing = checkDependencyInstalled(result, \"markdownlint-cli2\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"markdownlint-cli2\")\n if (terminated) return terminated\n\n const parsed = await readJsonReport<readonly MarkdownlintFinding[]>(\n // Provably equivalent, not a coverage gap -- see the identical\n // comment in src/presets/duplication.ts for why.\n // Stryker disable next-line StringLiteral -- JSON.parse coerces via toString(), which defaults to utf8 for a Buffer, so parsing succeeds identically either way\n () => readFile(REPORT_PATH, \"utf8\"),\n \"markdownlint-cli2 did not produce its expected JSON report -- confirm your \" +\n \".markdownlint-cli2.jsonc configures outputFormatters to write \" +\n `\"${REPORT_PATH}\" (requires the markdownlint-cli2-formatter-json package).`,\n \"markdownlint-cli2 produced invalid JSON evidence.\",\n )\n if (!parsed.ok) return parsed.result\n\n // `readJsonReport<T>` narrows only at the type level -- the parsed\n // value is `unknown` at runtime. Valid JSON that isn't an array (an\n // object from a different/older formatter, `null`) must fail cleanly\n // rather than throw `.length`/`.map` out of the policy and crash the\n // run, matching duplication.ts's `Array.isArray` guard.\n if (!Array.isArray(parsed.value)) {\n return {\n outcome: \"fail\",\n rationale: \"markdownlint-cli2 produced invalid JSON report data.\",\n }\n }\n\n const findings: readonly MarkdownlintFinding[] = parsed.value\n\n if (findings.length === 0) {\n return { outcome: \"pass\", rationale: \"markdownlint-cli2 reported 0 issues.\" }\n }\n\n return {\n outcome: \"fail\",\n rationale: [\n `markdownlint-cli2 reported ${String(findings.length)} issue(s):`,\n ...findings.map((finding) => `- ${formatFinding(finding)}`),\n ].join(\"\\n\"),\n }\n },\n }\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { combinedOutput, exitCodeFailRationale } from \"./shared/exit-code-fail-rationale.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\n/**\n * publint has no machine-readable output mode -- only a plain-text CLI\n * reporter (see its own `src/cli.js` `formatMessages`). Its process exit\n * code reflects only 'error'-level findings; 'warning'/'suggestion'-level\n * findings never affect it. This preset reads the same three section\n * headers publint's own CLI writes (\"Errors:\", \"Warnings:\", \"Suggestions:\")\n * to distinguish blocking findings from non-blocking ones, without\n * depending on any per-message structure publint doesn't expose. Relevant\n * only to repositories that publish an npm package.\n */\nexport const publint: CheckDefinitionConfig = {\n run: [\"publint\", \"run\"],\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"publint\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"publint\")\n if (terminated) return terminated\n\n const output = combinedOutput(result)\n\n if (result.exitCode === 0) {\n return output.includes(\"Warnings:\") || output.includes(\"Suggestions:\")\n ? { outcome: \"warn\", rationale: `publint reported non-blocking finding(s):\\n${output}` }\n : { outcome: \"pass\", rationale: \"publint reported no packaging errors.\" }\n }\n\n return {\n outcome: \"fail\",\n rationale: exitCodeFailRationale(result, \"publint reported packaging error(s)\"),\n }\n },\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\ninterface NpmAuditVulnerabilityCounts {\n readonly info: number\n readonly low: number\n readonly moderate: number\n readonly high: number\n readonly critical: number\n}\n\ninterface NpmAuditAdvisory {\n readonly severity?: string\n readonly range?: string\n readonly isDirect?: boolean\n readonly via?: readonly unknown[]\n readonly fixAvailable?:\n | boolean\n | {\n readonly name?: string\n readonly version?: string\n readonly isSemVerMajor?: boolean\n }\n}\n\ninterface NpmAuditReport {\n readonly auditReportVersion?: number\n readonly vulnerabilities?: Record<string, NpmAuditAdvisory>\n readonly metadata?: {\n readonly vulnerabilities?: NpmAuditVulnerabilityCounts\n }\n}\n\n// --omit=dev evaluates only the dependency graph shipped to consumers.\n// Development dependency vulnerabilities remain evidence but do not block\n// this runtime security contract. The blocking threshold is repository\n// policy rather than an opinion imposed by repo-contract.\n//\n// No missing-dependency check here (see shared/missing-dependency.ts's own\n// doc comment): this preset shells out to `npm` itself, which cannot be\n// \"missing\" in any environment capable of running `npm run <script>` at\n// all -- the exception is intentional, not an oversight.\n/** Dependency vulnerability scanning via `npm audit`. */\nexport const securityDeps: CheckDefinitionConfig = {\n run: [\"npm\", \"audit\", \"--omit=dev\", \"--json\"],\n output: { format: \"json\" },\n policy: ({ result }) => {\n const terminated = checkTerminatedAbnormally(result, \"npm audit\")\n if (terminated) return terminated\n\n if (!result.output?.success) {\n return { outcome: \"fail\", rationale: \"npm audit output could not be parsed as JSON.\" }\n }\n\n // `output.success` only means `JSON.parse` didn't throw -- valid JSON of an\n // unexpected shape (`null`, a primitive) must fail cleanly, not throw\n // `.metadata` out of the policy.\n const value: unknown = result.output.value\n if (typeof value !== \"object\" || value === null) {\n return { outcome: \"fail\", rationale: \"npm audit produced invalid JSON report data.\" }\n }\n\n const report = value as NpmAuditReport\n const vulnerabilities = report.metadata?.vulnerabilities\n\n if (!vulnerabilities) {\n return {\n outcome: \"fail\",\n rationale: \"npm audit produced no vulnerability summary.\",\n }\n }\n\n // Every count is cast from untrusted parsed JSON. A proxy registry, a\n // future npm format, or a truncated report can omit a severity field --\n // `undefined + n` is `NaN`, and both `NaN > 0` and `undefined > 0` are\n // false, which would silently turn real reported vulnerabilities into a\n // \"0 of everything\" pass. Require every severity count to be a finite\n // number before trusting the summary at all.\n const severities = [\"info\", \"low\", \"moderate\", \"high\", \"critical\"] as const\n const missingCount = severities.find((severity) => !Number.isFinite(vulnerabilities[severity]))\n\n if (missingCount !== undefined) {\n return {\n outcome: \"fail\",\n rationale: `npm audit's vulnerability summary is missing a numeric \"${missingCount}\" count -- the report could not be evaluated.`,\n }\n }\n\n const blocking =\n vulnerabilities.low +\n vulnerabilities.moderate +\n vulnerabilities.high +\n vulnerabilities.critical\n\n if (blocking > 0) {\n const details = Object.entries(report.vulnerabilities ?? {})\n .map(([name, vulnerability]: [string, NpmAuditAdvisory]) => {\n const severity = vulnerability.severity ?? \"unknown\"\n\n const dependencyType = vulnerability.isDirect === true ? \"direct\" : \"transitive\"\n\n const range = vulnerability.range ? ` range=${vulnerability.range}` : \"\"\n\n const fix =\n vulnerability.fixAvailable === true\n ? \" fix available\"\n : vulnerability.fixAvailable\n ? \" remediation available\"\n : \" no automatic fix available\"\n\n return `${name}: ${severity} (${dependencyType})${range};${fix}`\n })\n .sort()\n\n return {\n outcome: \"fail\",\n rationale: [\n `npm audit found ${String(blocking)} runtime vulnerability(ies):`,\n ...details.map((detail: string) => `- ${detail}`),\n ].join(\"\\n\"),\n }\n }\n\n // `info`-severity findings are excluded from the blocking count above\n // (they were never part of this policy's pass/fail contract), but a pass\n // built on top of some unresolved info-level findings is still worth\n // surfacing explicitly rather than silently folding into an unqualified\n // pass.\n if (vulnerabilities.info > 0) {\n return {\n outcome: \"warn\",\n rationale: `Runtime dependency policy passed. 0 critical, 0 high, 0 moderate, and 0 low vulnerabilities were found. ${String(vulnerabilities.info)} info-severity finding(s) remain and are non-blocking under repository policy.`,\n }\n }\n\n return {\n outcome: \"pass\",\n rationale:\n \"Runtime dependency policy passed. 0 critical, 0 high, 0 moderate, and 0 low vulnerabilities were found.\",\n }\n },\n}\n","import { readFile } from \"node:fs/promises\"\nimport type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { readJsonReport } from \"./shared/read-json-report.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\ninterface SecretlintMessage {\n readonly message: string\n readonly line: number\n readonly column: number\n readonly ruleId?: string\n readonly severity?: number\n}\n\ninterface SecretlintResult {\n readonly filePath: string\n readonly messages: readonly SecretlintMessage[]\n}\n\n// Secret values are deliberately excluded from the policy output. The\n// location and rule identify the remediation target without turning the\n// contract result itself into another secret-disclosure channel. Requires\n// the consumer's own secretlint config (secretlint has no built-in rules).\n/** Secret-leak scanning via secretlint. */\nexport const securitySecrets: CheckDefinitionConfig = {\n run: [\"secretlint\", \"--format\", \"json\", \"--output\", \"reports/secretlint.json\", \"**/*\"],\n policy: async ({ result }) => {\n const missing = checkDependencyInstalled(result, \"secretlint\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"Secretlint\")\n if (terminated) return terminated\n\n const parsed = await readJsonReport<readonly SecretlintResult[]>(\n // Provably equivalent, not a coverage gap -- see the identical\n // comment in src/presets/duplication.ts for why.\n // Stryker disable next-line StringLiteral -- JSON.parse coerces via toString(), which defaults to utf8 for a Buffer, so parsing succeeds identically either way\n () => readFile(\"reports/secretlint.json\", \"utf8\"),\n \"Secretlint did not produce its expected JSON report.\",\n \"Secretlint produced invalid JSON evidence.\",\n )\n if (!parsed.ok) return parsed.result\n\n // `readJsonReport<T>` narrows only at the type level; valid JSON that\n // isn't an array must fail cleanly rather than throw `.flatMap` out of\n // the policy and crash the run.\n if (!Array.isArray(parsed.value)) {\n return { outcome: \"fail\", rationale: \"Secretlint produced invalid JSON report data.\" }\n }\n\n const results: readonly SecretlintResult[] = parsed.value\n\n const findings = results.flatMap((file: unknown) => {\n // A single malformed array element (not an object, or missing its\n // `messages` array) must not throw `.map` out of the policy -- skip it,\n // exactly as the top-level non-array guard fails cleanly.\n if (\n typeof file !== \"object\" ||\n file === null ||\n !Array.isArray((file as { messages?: unknown }).messages)\n ) {\n return []\n }\n\n const typedFile = file as SecretlintResult\n return typedFile.messages.map((message: SecretlintMessage) => ({\n file: typedFile.filePath,\n line: message.line,\n column: message.column,\n ruleId: message.ruleId,\n }))\n })\n\n if (findings.length === 0) {\n return { outcome: \"pass\", rationale: \"Secretlint found 0 potential secrets.\" }\n }\n\n const details = findings.map((finding) => {\n const rule = finding.ruleId ? ` [${finding.ruleId}]` : \"\"\n\n return `${finding.file}:${String(finding.line)}:${String(finding.column)}${rule}`\n })\n\n return {\n outcome: \"fail\",\n rationale: [\n `Secretlint found ${String(findings.length)} potential secret(s):`,\n ...details.map((detail: string) => `- ${detail}`),\n \"Potential secret values are intentionally omitted. Remove the secret, replace it with an appropriate secret-management mechanism, and rotate any credential that may already have been exposed.\",\n ].join(\"\\n\"),\n }\n },\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { combinedOutput } from \"./shared/exit-code-fail-rationale.js\"\nimport { errorWarningPassPolicy } from \"./shared/error-warning-pass-policy.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\n\n/** Stylelint's own `--formatter json` contract -- not published as a TypeScript type by the tool. */\ninterface StylelintWarning {\n readonly line: number\n readonly column: number\n readonly rule: string\n readonly severity: \"error\" | \"warning\"\n readonly text: string\n}\n\ninterface StylelintResult {\n readonly source?: string\n readonly errored: boolean\n readonly warnings: readonly StylelintWarning[]\n}\n\n/** Options accepted by {@link stylelint}. */\ninterface StylelintOptions {\n /** Glob passed straight through to stylelint as its positional target. Defaults to `\"**\\/*.{css,scss}\"` -- adjust it for your own stylesheet file extensions (e.g. `.less`, `.vue`, `.svelte`). */\n readonly glob?: string\n}\n\n/**\n * CSS/SCSS lint via stylelint, using whatever stylelint config the\n * consumer's own repository already has. `severity: \"error\"` blocks;\n * `severity: \"warning\"` is reported but never blocks, matching how the\n * `lint` preset treats ESLint's own severities.\n * @param options - configuration for this check; see {@link StylelintOptions}.\n * @returns the configured check.\n */\nexport function stylelint(options: StylelintOptions = {}): CheckDefinitionConfig {\n const { glob = \"**/*.{css,scss}\" } = options\n\n return {\n run: [\"stylelint\", glob, \"--formatter\", \"json\"],\n output: { format: \"json\" },\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"stylelint\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"stylelint\")\n if (terminated) return terminated\n\n if (!result.output?.success) {\n // stylelint exits non-zero with no JSON on stdout when its glob\n // matched no stylesheets or its config failed to load. Surface what\n // it printed so a repo that legitimately has no CSS sees the real\n // cause rather than an opaque parse failure.\n const printed = combinedOutput(result)\n\n return {\n outcome: \"fail\",\n rationale:\n printed.length > 0\n ? `stylelint output could not be parsed as JSON. stylelint printed:\\n${printed}`\n : \"stylelint output could not be parsed as JSON.\",\n }\n }\n\n // Valid JSON of an unexpected shape (a stylelint formatter change, a\n // primitive, an entry without a `warnings` array) must fail cleanly, not\n // throw a TypeError out of the `flatMap` below.\n const value: unknown = result.output.value\n if (\n !Array.isArray(value) ||\n !value.every(\n (entry): entry is StylelintResult =>\n typeof entry === \"object\" &&\n entry !== null &&\n Array.isArray((entry as { warnings?: unknown }).warnings),\n )\n ) {\n return { outcome: \"fail\", rationale: \"stylelint output could not be parsed as JSON.\" }\n }\n\n const results: readonly StylelintResult[] = value\n\n const render = (file: StylelintResult, warning: StylelintWarning): string =>\n `${file.source ?? \"<unknown file>\"}:${String(warning.line)}:${String(warning.column)} [${warning.rule}]: ${warning.text}`\n\n const errorDetails = results.flatMap((file: StylelintResult): string[] =>\n file.warnings\n .filter((warning: StylelintWarning) => warning.severity === \"error\")\n .map((warning: StylelintWarning) => render(file, warning)),\n )\n\n const warningDetails = results.flatMap((file: StylelintResult): string[] =>\n file.warnings\n .filter((warning: StylelintWarning) => warning.severity === \"warning\")\n .map((warning: StylelintWarning) => render(file, warning)),\n )\n\n return errorWarningPassPolicy(\"stylelint\", errorDetails, warningDetails)\n },\n }\n}\n","import type { JsonAssertionResult, JsonTestResult, JsonTestResults } from \"vitest/reporters\"\nimport type { ParsedOutput, PolicyResult } from \"../../types.js\"\n\ntype VitestJsonReport = JsonTestResults\ntype VitestJsonTestSuite = JsonTestResult\ntype VitestJsonAssertion = JsonAssertionResult\n\n/**\n * Interprets Vitest's own `--reporter=json` output shape -- and nothing\n * else. Shared between the `test` preset (a single, un-categorized\n * `vitest run --reporter=json`) and this repository's own\n * `test-unit`/`test-integration`/`test-property`/`test-e2e` checks, whose\n * `run` splits tests into four mutually exclusive categories via\n * scripts/run-test-category.mjs -- a repository-specific concern this\n * function knows nothing about. Each of those four checks owns its own\n * category-specific semantics on top of this evaluator; this function must\n * stay narrowly scoped to \"parse Vitest's JSON reporter shape,\" never grow\n * into a general \"testing policy\" abstraction. A category's own\n * `output.success === false` (vitest crashed / produced unparseable output)\n * is kept distinct from a substantive test failure, exactly as every other\n * preset in this package already does via `ParsedOutput.success`.\n * @param output - the vitest check's parsed `--reporter=json` output to evaluate.\n * @returns the pass/fail outcome and its rationale.\n */\nexport function evaluateVitestJsonPolicy(output: ParsedOutput<unknown> | undefined): PolicyResult {\n if (!output?.success) {\n return { outcome: \"fail\", rationale: \"Vitest output could not be parsed as JSON.\" }\n }\n\n // `output.value` is `unknown` -- valid JSON that isn't Vitest's reporter\n // shape (`null`, a primitive, a wrapper that printed `{}`, a config dump, a\n // future schema change) must produce a fail verdict, not a TypeError out of\n // the policy that `runPolicies` rethrows as `PolicyThrewError` and rejects the\n // whole `runRepoContract()` promise with. `numFailedTests`/\n // `numFailedTestSuites` being `undefined` (not `0`) already falls through the\n // pass branch below, so `testResults` must be guarded before it is walked.\n const value: unknown = output.value\n if (typeof value !== \"object\" || value === null) {\n return { outcome: \"fail\", rationale: \"Vitest produced invalid JSON report data.\" }\n }\n\n const report = value as VitestJsonReport\n\n if (!Array.isArray(report.testResults)) {\n return { outcome: \"fail\", rationale: \"Vitest produced invalid JSON report data.\" }\n }\n\n if (report.numFailedTests === 0 && report.numFailedTestSuites === 0) {\n return {\n outcome: \"pass\",\n rationale: `Vitest completed ${String(report.numTotalTests)} test(s) with 0 failures across ${String(report.numTotalTestSuites)} suite(s).`,\n }\n }\n\n // `Partial<>` because the elements are untrusted parsed JSON, not a guaranteed\n // `JsonTestResult` -- a suite missing `assertionResults` entirely (a partial or\n // older reporter shape) must not throw out of the policy, just contribute no\n // failure detail lines.\n const failures = report.testResults.flatMap((suite: Partial<VitestJsonTestSuite>): string[] =>\n (suite.assertionResults ?? [])\n .filter((test: VitestJsonAssertion) => test.status === \"failed\")\n .map((test: VitestJsonAssertion) => {\n const location = test.location\n ? `:${String(test.location.line)}:${String(test.location.column)}`\n : \"\"\n\n const messages = (test.failureMessages ?? [])\n .map((message: string) => message.trim())\n .filter(Boolean)\n .join(\" | \")\n\n // This mutant (dropping .filter(Boolean).join(\" — \"), returning the bare array instead)\n // is proven killed under direct, unmocked `vitest run` of\n // test/unit/presets/shared/vitest-json-policy.test.ts -- applying this exact replacement\n // by hand and re-running fails 4 of that file's tests, including two that assert the\n // complete rationale string via `toBe` specifically to make this mutation observable --\n // but it survives every `npx stryker run` against this file (scoped or full, reproduced\n // three times, once with concurrency forced to 1): this mutant's own `coveredBy`/\n // `testsCompleted` show only 6 of the file's 11 tests ever ran against it, never the two\n // `toBe` tests that would kill it. See stryker.config.mjs's own comment for the identical\n // \"coverage-attribution quirk\" already found and worked around for `perTest` mode -- this\n // is the same class of bug surfacing under `\"all\"` mode too, for this one line.\n // Stryker disable next-line MethodExpression -- proven killed under direct vitest execution but Stryker's own coverage attribution never runs the two tests that would kill it; see the comment above.\n return [`${suite.name}${location}`, test.fullName, messages].filter(Boolean).join(\" — \")\n }),\n )\n\n return {\n outcome: \"fail\",\n rationale: [\n `Vitest reported ${String(report.numFailedTests)} failing test(s) across ${String(report.numFailedTestSuites)} failing suite(s):`,\n ...failures.map((failure: string) => `- ${failure}`),\n ].join(\"\\n\"),\n }\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\nimport { evaluateVitestJsonPolicy } from \"./shared/vitest-json-policy.js\"\n\n/** Unit/integration test execution via Vitest, reading its JSON reporter output. */\nexport const test: CheckDefinitionConfig = {\n run: [\"vitest\", \"run\", \"--reporter=json\"],\n output: { format: \"json\" },\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"vitest\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"Vitest\")\n if (terminated) return terminated\n\n return evaluateVitestJsonPolicy(result.output)\n },\n}\n","import type { CheckDefinitionConfig } from \"../types.js\"\nimport { checkDependencyInstalled } from \"./shared/missing-dependency.js\"\nimport { checkTerminatedAbnormally } from \"./shared/terminal-status.js\"\nimport { exitCodeFailRationale } from \"./shared/exit-code-fail-rationale.js\"\n\n/** Type checking via `tsc --noEmit`. */\nexport const typecheck: CheckDefinitionConfig = {\n run: [\"tsc\", \"--noEmit\", \"-p\", \"tsconfig.json\"],\n policy: ({ result }) => {\n const missing = checkDependencyInstalled(result, \"typescript\")\n if (missing) return missing\n\n const terminated = checkTerminatedAbnormally(result, \"TypeScript\")\n if (terminated) return terminated\n\n if (result.exitCode === 0) {\n return { outcome: \"pass\", rationale: \"tsc reported no type errors.\" }\n }\n\n return {\n outcome: \"fail\",\n rationale: exitCodeFailRationale(result, \"TypeScript reported type errors\"),\n }\n },\n}\n"]}
@@ -0,0 +1 @@
1
+ export * from "./.dts/presets/index.js";
@@ -0,0 +1 @@
1
+ export * from "./.dts/presets/index.js";
@@ -0,0 +1,13 @@
1
+ import { readFile } from 'fs/promises';
2
+
3
+ function checkDependencyInstalled(result,packageName){if(result.status!=="spawn_error"||result.spawnErrorCode!=="ENOENT"){return void 0}return {outcome:"fail",rationale:`\`${packageName}\` is required by this preset but was not found. Install \`${packageName}\` as a development dependency and run the contract again.`}}function combinedOutput(result){return [result.stdout.trim(),result.stderr.trim()].filter(value=>Boolean(value)).join("\n")}function exitCodeFailRationale(result,description){const output=combinedOutput(result);return output.length>0?`${description}:
4
+ ${output}`:`${description} (exit code ${String(result.exitCode)}).`}function checkTerminatedAbnormally(result,toolName){if(result.status==="completed"){return void 0}const detail=combinedOutput(result);const suffix=detail.length>0?`
5
+ ${detail}`:"";switch(result.status){case "timed_out":return {outcome:"fail",rationale:`${toolName} did not finish: its process exceeded the configured timeout and was terminated.${suffix}`};case "aborted":return {outcome:"fail",rationale:`${toolName} did not finish: the run was aborted before its process completed.${suffix}`};case "host_terminated":return {outcome:"fail",rationale:`${toolName} did not finish: the host process received a termination signal and killed it.${suffix}`};case "signaled":return {outcome:"fail",rationale:`${toolName} was terminated by signal ${result.signal??"unknown"} before it completed.${suffix}`};case "spawn_error":return {outcome:"fail",rationale:`${toolName} could not be started: ${result.spawnError??"the process failed to spawn"}.`};default:{const unhandled=result.status;throw new Error(`checkTerminatedAbnormally: unhandled check status ${String(unhandled)}`)}}}function formatProblem(problem){const context=[problem.entrypoint?`entrypoint=${problem.entrypoint}`:void 0,problem.resolutionKind?`resolution=${problem.resolutionKind}`:void 0,problem.typesFileName?`types=${problem.typesFileName}`:void 0,problem.implementationFileName?`impl=${problem.implementationFileName}`:void 0].filter(value=>value!==void 0);return context.length>0?`${problem.kind}: ${context.join(" ")}`:problem.kind}function evaluateAttwReport(report){if(typeof report!=="object"||report===null){return {outcome:"fail",rationale:"@arethetypeswrong/cli produced invalid JSON report data."}}const rawProblems=report.problems;const problemGroups=typeof rawProblems==="object"&&rawProblems!==null?Object.values(rawProblems):[];const problems=problemGroups.flat().filter(problem=>typeof problem==="object"&&problem!==null);if(problems.length===0){return {outcome:"pass",rationale:"@arethetypeswrong/cli found 0 packaged type-resolution problem(s)."}}return {outcome:"fail",rationale:[`@arethetypeswrong/cli found ${String(problems.length)} packaged type-resolution problem(s):`,...problems.map(problem=>`- ${formatProblem(problem)}`)].join("\n")}}var arethetypeswrong={run:["attw","--pack",".","--format","json"],output:{format:"json"},policy:({result})=>{const missing=checkDependencyInstalled(result,"@arethetypeswrong/cli");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"@arethetypeswrong/cli");if(terminated)return terminated;if(!result.output?.success){return {outcome:"fail",rationale:"@arethetypeswrong/cli output could not be parsed as JSON."}}return evaluateAttwReport(result.output.value)}};function formatBrokenLink(link){const parent=link.parent?` (linked from ${link.parent})`:"";return `${link.url} -- HTTP ${String(link.status)}${parent}`}function brokenLinks(options={}){const{start="."}=options;return {run:["linkinator",start,"--recurse","--format","json","--skip","node_modules"],output:{format:"json"},policy:({result})=>{const missing=checkDependencyInstalled(result,"linkinator");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"linkinator");if(terminated)return terminated;if(!result.output?.success){return {outcome:"fail",rationale:"linkinator output could not be parsed as JSON."}}const value=result.output.value;if(typeof value!=="object"||value===null){return {outcome:"fail",rationale:"linkinator produced invalid JSON report data."}}const report=value;if(!Array.isArray(report.links)){return {outcome:"fail",rationale:"linkinator produced invalid JSON report data."}}const links=report.links;const brokenLinkResults=links.filter(link=>link.state==="BROKEN");if(brokenLinkResults.length===0){return {outcome:"pass",rationale:`linkinator found 0 broken link(s) across ${String(links.length)} checked.`}}return {outcome:"fail",rationale:[`linkinator found ${String(brokenLinkResults.length)} broken link(s):`,...brokenLinkResults.map(link=>`- ${formatBrokenLink(link)}`)].join("\n")}}}}function remediation(from){return ["","Rewrite the offending commit message(s) already on this branch:","",` git rebase -i ${from}`,"","In the editor, for each commit flagged above change `pick` to:"," - `reword` to keep the commit but fix its message (a valid Conventional Commit:"," `type(scope): subject`, lowercase type, no trailing period), or"," - `squash` / `fixup` to fold it into the commit before it, or"," - `drop` to remove the commit entirely.","","Then, if the branch is already pushed:",""," git push --force-with-lease"].join("\n")}function commitlint(options={}){const{from="origin/main",to="HEAD"}=options;return {run:["commitlint","--from",from,"--to",to],policy:({result})=>{const missing=checkDependencyInstalled(result,"@commitlint/cli");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"commitlint");if(terminated)return terminated;if(result.exitCode===0){return {outcome:"pass",rationale:`commitlint found 0 commit message violations between ${from} and ${to}.`}}return {outcome:"fail",rationale:exitCodeFailRationale(result,"commitlint reported commit message violations")+`
6
+ ${remediation(from)}`}}}}function readReporterOptions(args){const flagIndex=args.indexOf("--reporter-options");const raw=flagIndex===-1?void 0:args[flagIndex+1];if(raw===void 0){return void 0}try{return JSON.parse(raw)}catch{return void 0}}function formatEntry(entry){if(Array.isArray(entry)){const group=entry;return {name:group.map(member=>member.name).join(", "),location:""}}const single=entry;const location=typeof single.line==="number"?`:${String(single.line)}:${String(single.col??1)}`:"";return {name:single.name,location}}function deadCode(options={}){const{exemptUnusedDevDependencies=[]}=options;return {run:["knip","--reporter","json","--reporter-options",JSON.stringify({exemptUnusedDevDependencies})],output:{format:"json"},policy:({result})=>{const missing=checkDependencyInstalled(result,"knip");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"Knip");if(terminated)return terminated;if(!result.output?.success){return {outcome:"fail",rationale:"Knip output could not be parsed as JSON."}}const value=result.output.value;if(typeof value!=="object"||value===null){return {outcome:"fail",rationale:"Knip produced invalid JSON report data."}}const report=value;if(!Array.isArray(report.issues)){return {outcome:"fail",rationale:"Knip produced invalid JSON report data."}}const issues=report.issues;const exemptDevDependencies=new Set(readReporterOptions(result.args)?.exemptUnusedDevDependencies??[]);const details=[];for(const issue of issues){const addEntries=(label,entries,ignored=new Set)=>{for(const entry of entries??[]){const{name,location}=formatEntry(entry);if(ignored.has(name)){continue}details.push(`${issue.file}${location} \u2014 ${label}: ${name}`);}};addEntries("unused dependency",issue.dependencies);addEntries("unused devDependency",issue.devDependencies,exemptDevDependencies);addEntries("unused optional peer dependency",issue.optionalPeerDependencies);addEntries("unlisted dependency",issue.unlisted);addEntries("unresolved import",issue.unresolved);addEntries("unused export",issue.exports);addEntries("unused export (namespace)",issue.nsExports);addEntries("unused type",issue.types);addEntries("unused type (namespace)",issue.nsTypes);addEntries("unused namespace member",issue.namespaceMembers);addEntries("unused enum member",issue.enumMembers);addEntries("unlisted binary",issue.binaries);addEntries("duplicate export",issue.duplicates);addEntries("circular dependency",issue.cycles);addEntries("unused file",issue.files);}if(details.length===0){return {outcome:"pass",rationale:"Knip reported 0 issues."}}return {outcome:"fail",rationale:[`Knip reported ${String(details.length)} issue(s):`,...details.map(detail=>`- ${detail}`)].join("\n")}}}}async function readJsonReport(readRaw,onReadFailed,onParseFailed){let raw;try{raw=await readRaw();}catch{return {ok:false,result:{outcome:"fail",rationale:onReadFailed}}}try{return {ok:true,value:JSON.parse(raw)}}catch{return {ok:false,result:{outcome:"fail",rationale:onParseFailed}}}}var REPORT_PATH="reports/jscpd/jscpd-report.json";function duplication(options={}){const{path="."}=options;return {run:["jscpd",path,"--reporters","json","--output","reports/jscpd","--silent"],policy:async({result})=>{const missing=checkDependencyInstalled(result,"jscpd");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"jscpd");if(terminated)return terminated;const parsed=await readJsonReport(()=>readFile(REPORT_PATH,"utf8"),"jscpd did not produce its expected JSON report.","jscpd produced invalid JSON evidence.");if(!parsed.ok)return parsed.result;const value=parsed.value;if(typeof value!=="object"||value===null){return {outcome:"fail",rationale:"jscpd produced invalid JSON report data."}}const report=value;const total=report.statistics?.total;if(!Array.isArray(report.duplicates)||!total||typeof total.percentage!=="number"||!Number.isFinite(total.percentage)){return {outcome:"fail",rationale:"jscpd produced invalid JSON report data."}}const duplicates=report.duplicates;if(duplicates.length===0){return {outcome:"pass",rationale:`jscpd found 0 duplicated block(s) across ${String(total.sources)} file(s) (${String(total.lines)} lines).`}}const details=duplicates.map(duplicate=>`${duplicate.firstFile.name}:${String(duplicate.firstFile.start)} duplicates ${duplicate.secondFile.name}:${String(duplicate.secondFile.start)} -- ${String(duplicate.lines)} lines / ${String(duplicate.tokens)} tokens`);return {outcome:"fail",rationale:[`jscpd found ${String(duplicates.length)} duplicated block(s) (${total.percentage.toFixed(2)}% of ${String(total.lines)} lines across ${String(total.sources)} file(s)):`,...details.map(detail=>`- ${detail}`)].join("\n")}}}}function collectFailingSpecs(suites){const details=[];for(const suite of suites){for(const spec of suite.specs??[]){if(spec.ok)continue;const location=spec.line!==void 0?`:${String(spec.line)}`:"";const lastResult=(spec.tests??[]).flatMap(t=>t.results??[]).at(-1);const message=lastResult?.error?.message?.trim();details.push(`${spec.file??suite.title}${location} ${spec.title}${message?` \u2014 ${message}`:""}`);}if(suite.suites)details.push(...collectFailingSpecs(suite.suites));}return details}var e2e={run:["playwright","test","--reporter=json"],output:{format:"json"},policy:({result})=>{const missing=checkDependencyInstalled(result,"@playwright/test");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"Playwright");if(terminated)return terminated;if(!result.output?.success){return {outcome:"fail",rationale:"Playwright output could not be parsed as JSON."}}const value=result.output.value;if(typeof value!=="object"||value===null){return {outcome:"fail",rationale:"Playwright produced invalid JSON report data."}}const report=value;const stats=report.stats;if(!stats||typeof stats.unexpected!=="number"||typeof stats.flaky!=="number"){return {outcome:"fail",rationale:"Playwright produced invalid JSON report data."}}if(stats.unexpected===0&&stats.flaky===0){return {outcome:"pass",rationale:`Playwright completed ${String(stats.expected)} test(s) with 0 unexpected failures.`}}if(stats.unexpected>0){const details=collectFailingSpecs(report.suites??[]);return {outcome:"fail",rationale:[`Playwright reported ${String(stats.unexpected)} unexpected failure(s):`,...details.map(detail=>`- ${detail}`)].join("\n")}}return {outcome:"warn",rationale:`Playwright completed with ${String(stats.flaky)} flaky test(s) that eventually passed on retry.`}}};var format={run:["prettier","--write","."],policy:({result})=>{const missing=checkDependencyInstalled(result,"prettier");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"Prettier");if(terminated)return terminated;if(result.exitCode===0){return {outcome:"pass",rationale:"Prettier reported no formatting failures."}}return {outcome:"fail",rationale:exitCodeFailRationale(result,"Prettier reported formatting failures")}}};var license={run:["licensee","--production","--osi","--errors-only","--ndjson"],policy:({result})=>{const missing=checkDependencyInstalled(result,"licensee");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"licensee");if(terminated)return terminated;const trimmed=result.stdout.trim();if(trimmed.length===0){if(result.status==="completed"&&result.exitCode===0){return {outcome:"pass",rationale:"licensee found 0 production dependencies with a non-OSI-approved license."}}return {outcome:"fail",rationale:exitCodeFailRationale(result,"licensee did not evaluate any dependency licenses (it produced no output)")}}let entries;try{entries=trimmed.split("\n").map(line=>line.trim()).filter(line=>line.length>0).map(line=>JSON.parse(line));}catch{return {outcome:"fail",rationale:"licensee produced invalid JSON evidence."}}const details=entries.map(entry=>`${entry.name}@${entry.version}: ${entry.license??"unknown license"}`).sort();return {outcome:"fail",rationale:[`licensee found ${String(details.length)} production dependency(ies) without an OSI-approved license:`,...details.map(detail=>`- ${detail}`)].join("\n")}}};function errorWarningPassPolicy(toolName,errorDetails,warningDetails){if(errorDetails.length>0){return {outcome:"fail",rationale:[`${toolName} reported ${String(errorDetails.length)} error(s):`,...errorDetails.map(detail=>`- ${detail}`)].join("\n")}}if(warningDetails.length>0){return {outcome:"warn",rationale:[`${toolName} reported 0 errors but ${String(warningDetails.length)} warning(s):`,...warningDetails.map(detail=>`- ${detail}`)].join("\n")}}return {outcome:"pass",rationale:`${toolName} reported 0 errors and 0 warnings.`}}function renderMessages(results,severity){return results.flatMap(file=>file.messages.filter(message=>message.severity===severity).map(message=>{const rule=message.ruleId?` [${message.ruleId}]`:"";return `${file.filePath}:${String(message.line)}:${String(message.column)}${rule}: ${message.message}`}))}function lint(options={}){const{path="."}=options;return {run:["eslint",path,"--format","json"],output:{format:"json"},policy:({result})=>{const missing=checkDependencyInstalled(result,"eslint");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"ESLint");if(terminated)return terminated;if(!result.output?.success){const printed=combinedOutput(result);return {outcome:"fail",rationale:printed.length>0?`ESLint output could not be parsed as JSON. ESLint printed:
7
+ ${printed}`:"ESLint output could not be parsed as JSON."}}const value=result.output.value;if(!Array.isArray(value)||!value.every(file=>typeof file==="object"&&file!==null&&Array.isArray(file.messages))){return {outcome:"fail",rationale:"ESLint output could not be parsed as JSON."}}const results=value;const errorDetails=renderMessages(results,2);const warningDetails=renderMessages(results,1);return errorWarningPassPolicy("ESLint",errorDetails,warningDetails)}}}var REPORT_PATH2="reports/markdownlint.json";function formatFinding(finding){const rule=finding.ruleNames.join("/");const detail=finding.errorDetail?` (${finding.errorDetail})`:"";return `${finding.fileName}:${String(finding.lineNumber)} [${rule}]: ${finding.ruleDescription}${detail}`}function markdownlint(options={}){const{glob="**/*.md"}=options;return {run:["markdownlint-cli2",glob],policy:async({result})=>{const missing=checkDependencyInstalled(result,"markdownlint-cli2");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"markdownlint-cli2");if(terminated)return terminated;const parsed=await readJsonReport(()=>readFile(REPORT_PATH2,"utf8"),`markdownlint-cli2 did not produce its expected JSON report -- confirm your .markdownlint-cli2.jsonc configures outputFormatters to write "${REPORT_PATH2}" (requires the markdownlint-cli2-formatter-json package).`,"markdownlint-cli2 produced invalid JSON evidence.");if(!parsed.ok)return parsed.result;if(!Array.isArray(parsed.value)){return {outcome:"fail",rationale:"markdownlint-cli2 produced invalid JSON report data."}}const findings=parsed.value;if(findings.length===0){return {outcome:"pass",rationale:"markdownlint-cli2 reported 0 issues."}}return {outcome:"fail",rationale:[`markdownlint-cli2 reported ${String(findings.length)} issue(s):`,...findings.map(finding=>`- ${formatFinding(finding)}`)].join("\n")}}}}var publint={run:["publint","run"],policy:({result})=>{const missing=checkDependencyInstalled(result,"publint");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"publint");if(terminated)return terminated;const output=combinedOutput(result);if(result.exitCode===0){return output.includes("Warnings:")||output.includes("Suggestions:")?{outcome:"warn",rationale:`publint reported non-blocking finding(s):
8
+ ${output}`}:{outcome:"pass",rationale:"publint reported no packaging errors."}}return {outcome:"fail",rationale:exitCodeFailRationale(result,"publint reported packaging error(s)")}}};var securityDeps={run:["npm","audit","--omit=dev","--json"],output:{format:"json"},policy:({result})=>{const terminated=checkTerminatedAbnormally(result,"npm audit");if(terminated)return terminated;if(!result.output?.success){return {outcome:"fail",rationale:"npm audit output could not be parsed as JSON."}}const value=result.output.value;if(typeof value!=="object"||value===null){return {outcome:"fail",rationale:"npm audit produced invalid JSON report data."}}const report=value;const vulnerabilities=report.metadata?.vulnerabilities;if(!vulnerabilities){return {outcome:"fail",rationale:"npm audit produced no vulnerability summary."}}const severities=["info","low","moderate","high","critical"];const missingCount=severities.find(severity=>!Number.isFinite(vulnerabilities[severity]));if(missingCount!==void 0){return {outcome:"fail",rationale:`npm audit's vulnerability summary is missing a numeric "${missingCount}" count -- the report could not be evaluated.`}}const blocking=vulnerabilities.low+vulnerabilities.moderate+vulnerabilities.high+vulnerabilities.critical;if(blocking>0){const details=Object.entries(report.vulnerabilities??{}).map(([name,vulnerability])=>{const severity=vulnerability.severity??"unknown";const dependencyType=vulnerability.isDirect===true?"direct":"transitive";const range=vulnerability.range?` range=${vulnerability.range}`:"";const fix=vulnerability.fixAvailable===true?" fix available":vulnerability.fixAvailable?" remediation available":" no automatic fix available";return `${name}: ${severity} (${dependencyType})${range};${fix}`}).sort();return {outcome:"fail",rationale:[`npm audit found ${String(blocking)} runtime vulnerability(ies):`,...details.map(detail=>`- ${detail}`)].join("\n")}}if(vulnerabilities.info>0){return {outcome:"warn",rationale:`Runtime dependency policy passed. 0 critical, 0 high, 0 moderate, and 0 low vulnerabilities were found. ${String(vulnerabilities.info)} info-severity finding(s) remain and are non-blocking under repository policy.`}}return {outcome:"pass",rationale:"Runtime dependency policy passed. 0 critical, 0 high, 0 moderate, and 0 low vulnerabilities were found."}}};var securitySecrets={run:["secretlint","--format","json","--output","reports/secretlint.json","**/*"],policy:async({result})=>{const missing=checkDependencyInstalled(result,"secretlint");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"Secretlint");if(terminated)return terminated;const parsed=await readJsonReport(()=>readFile("reports/secretlint.json","utf8"),"Secretlint did not produce its expected JSON report.","Secretlint produced invalid JSON evidence.");if(!parsed.ok)return parsed.result;if(!Array.isArray(parsed.value)){return {outcome:"fail",rationale:"Secretlint produced invalid JSON report data."}}const results=parsed.value;const findings=results.flatMap(file=>{if(typeof file!=="object"||file===null||!Array.isArray(file.messages)){return []}const typedFile=file;return typedFile.messages.map(message=>({file:typedFile.filePath,line:message.line,column:message.column,ruleId:message.ruleId}))});if(findings.length===0){return {outcome:"pass",rationale:"Secretlint found 0 potential secrets."}}const details=findings.map(finding=>{const rule=finding.ruleId?` [${finding.ruleId}]`:"";return `${finding.file}:${String(finding.line)}:${String(finding.column)}${rule}`});return {outcome:"fail",rationale:[`Secretlint found ${String(findings.length)} potential secret(s):`,...details.map(detail=>`- ${detail}`),"Potential secret values are intentionally omitted. Remove the secret, replace it with an appropriate secret-management mechanism, and rotate any credential that may already have been exposed."].join("\n")}}};function stylelint(options={}){const{glob="**/*.{css,scss}"}=options;return {run:["stylelint",glob,"--formatter","json"],output:{format:"json"},policy:({result})=>{const missing=checkDependencyInstalled(result,"stylelint");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"stylelint");if(terminated)return terminated;if(!result.output?.success){const printed=combinedOutput(result);return {outcome:"fail",rationale:printed.length>0?`stylelint output could not be parsed as JSON. stylelint printed:
9
+ ${printed}`:"stylelint output could not be parsed as JSON."}}const value=result.output.value;if(!Array.isArray(value)||!value.every(entry=>typeof entry==="object"&&entry!==null&&Array.isArray(entry.warnings))){return {outcome:"fail",rationale:"stylelint output could not be parsed as JSON."}}const results=value;const render=(file,warning)=>`${file.source??"<unknown file>"}:${String(warning.line)}:${String(warning.column)} [${warning.rule}]: ${warning.text}`;const errorDetails=results.flatMap(file=>file.warnings.filter(warning=>warning.severity==="error").map(warning=>render(file,warning)));const warningDetails=results.flatMap(file=>file.warnings.filter(warning=>warning.severity==="warning").map(warning=>render(file,warning)));return errorWarningPassPolicy("stylelint",errorDetails,warningDetails)}}}function evaluateVitestJsonPolicy(output){if(!output?.success){return {outcome:"fail",rationale:"Vitest output could not be parsed as JSON."}}const value=output.value;if(typeof value!=="object"||value===null){return {outcome:"fail",rationale:"Vitest produced invalid JSON report data."}}const report=value;if(!Array.isArray(report.testResults)){return {outcome:"fail",rationale:"Vitest produced invalid JSON report data."}}if(report.numFailedTests===0&&report.numFailedTestSuites===0){return {outcome:"pass",rationale:`Vitest completed ${String(report.numTotalTests)} test(s) with 0 failures across ${String(report.numTotalTestSuites)} suite(s).`}}const failures=report.testResults.flatMap(suite=>(suite.assertionResults??[]).filter(test2=>test2.status==="failed").map(test2=>{const location=test2.location?`:${String(test2.location.line)}:${String(test2.location.column)}`:"";const messages=(test2.failureMessages??[]).map(message=>message.trim()).filter(Boolean).join(" | ");return [`${suite.name}${location}`,test2.fullName,messages].filter(Boolean).join(" \u2014 ")}));return {outcome:"fail",rationale:[`Vitest reported ${String(report.numFailedTests)} failing test(s) across ${String(report.numFailedTestSuites)} failing suite(s):`,...failures.map(failure=>`- ${failure}`)].join("\n")}}var test={run:["vitest","run","--reporter=json"],output:{format:"json"},policy:({result})=>{const missing=checkDependencyInstalled(result,"vitest");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"Vitest");if(terminated)return terminated;return evaluateVitestJsonPolicy(result.output)}};var typecheck={run:["tsc","--noEmit","-p","tsconfig.json"],policy:({result})=>{const missing=checkDependencyInstalled(result,"typescript");if(missing)return missing;const terminated=checkTerminatedAbnormally(result,"TypeScript");if(terminated)return terminated;if(result.exitCode===0){return {outcome:"pass",rationale:"tsc reported no type errors."}}return {outcome:"fail",rationale:exitCodeFailRationale(result,"TypeScript reported type errors")}}};
10
+
11
+ export { arethetypeswrong, brokenLinks, commitlint, deadCode, duplication, e2e, format, license, lint, markdownlint, publint, securityDeps, securitySecrets, stylelint, test, typecheck };
12
+ //# sourceMappingURL=presets.js.map
13
+ //# sourceMappingURL=presets.js.map