@standards-kit/conform 0.2.0 → 0.3.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 (35) hide show
  1. package/dist/{chunk-YGDEM6K5.js → chunk-FJZMUGYW.js} +13 -10
  2. package/dist/chunk-FJZMUGYW.js.map +1 -0
  3. package/dist/{chunk-NADY2H35.js → chunk-YKKWXHYS.js} +2 -2
  4. package/dist/{chunk-NADY2H35.js.map → chunk-YKKWXHYS.js.map} +1 -1
  5. package/dist/cli/index.d.ts +3 -0
  6. package/dist/cli/process.d.ts +2 -0
  7. package/dist/cli/utils.d.ts +19 -0
  8. package/dist/cli/validate.d.ts +2 -0
  9. package/dist/cli.js +3892 -3873
  10. package/dist/cli.js.map +1 -1
  11. package/dist/core/schema.d.ts +167 -1709
  12. package/dist/{core-QRFGIQ42.js → core-LFX2BFLG.js} +2 -2
  13. package/dist/index.js +3 -5
  14. package/dist/index.js.map +1 -1
  15. package/dist/infra/schemas.d.ts +41 -533
  16. package/dist/{infra-TO54IUSC.js → infra-RFEWGWPW.js} +2 -2
  17. package/dist/mcp/standards/parser.d.ts +2 -14
  18. package/dist/{mcp-73FZXT3P.js → mcp-T2JFU4E2.js} +3 -3
  19. package/dist/{registry-JRCQAIHR.js → registry-J2LVW3M2.js} +2 -2
  20. package/dist/{scan-RHQWHASY.js → scan-BZH5IR3Z.js} +3 -3
  21. package/dist/scan-BZH5IR3Z.js.map +1 -0
  22. package/dist/{standards-XAZKTKYJ.js → standards-ALMA4VIU.js} +2 -2
  23. package/dist/{sync-P3UZECLW.js → sync-EGJ2CSYK.js} +2 -2
  24. package/dist/sync-EGJ2CSYK.js.map +1 -0
  25. package/dist/{validate-J5E336GX.js → validate-X4K2SHYT.js} +4 -4
  26. package/dist/{validate-J5E336GX.js.map → validate-X4K2SHYT.js.map} +1 -1
  27. package/package.json +10 -6
  28. package/dist/chunk-YGDEM6K5.js.map +0 -1
  29. package/dist/scan-RHQWHASY.js.map +0 -1
  30. package/dist/sync-P3UZECLW.js.map +0 -1
  31. /package/dist/{core-QRFGIQ42.js.map → core-LFX2BFLG.js.map} +0 -0
  32. /package/dist/{infra-TO54IUSC.js.map → infra-RFEWGWPW.js.map} +0 -0
  33. /package/dist/{mcp-73FZXT3P.js.map → mcp-T2JFU4E2.js.map} +0 -0
  34. /package/dist/{registry-JRCQAIHR.js.map → registry-J2LVW3M2.js.map} +0 -0
  35. /package/dist/{standards-XAZKTKYJ.js.map → standards-ALMA4VIU.js.map} +0 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/code/tools/base.ts","../src/code/tools/coverage-run.ts","../src/code/tools/disable-comments.ts","../src/code/tools/comment-utils.ts","../src/code/tools/eslint.ts","../src/code/tools/gitleaks.ts","../src/code/tools/knip.ts","../src/code/tools/naming.ts","../src/code/tools/pipaudit.ts","../src/code/tools/pnpmaudit.ts","../src/code/tools/ruff.ts","../src/code/tools/tsc.ts","../src/code/tools/ty.ts","../src/code/tools/vulture.ts","../src/code/index.ts","../src/process/tools/backups.ts","../src/process/tools/base.ts","../src/process/tools/branches.ts","../src/process/tools/changesets.ts","../src/process/tools/ci.ts","../src/process/tools/codeowners.ts","../src/process/tools/commits.ts","../src/process/tools/coverage.ts","../src/process/tools/docs.ts","../src/process/tools/docs-helpers.ts","../src/process/tools/forbidden-files.ts","../src/process/tools/hooks.ts","../src/process/tools/pr.ts","../src/process/tools/repo.ts","../src/process/tools/tickets.ts","../src/process/index.ts","../src/process/scan/index.ts","../src/process/scan/scanner.ts","../src/process/scan/remote-fetcher.ts","../src/process/scan/validators.ts","../src/output/index.ts","../src/dependencies/index.ts","../src/dependencies/mappings.ts","../src/validate/guidelines.ts","../src/mcp/standards/fetcher.ts","../src/mcp/standards/parser.ts","../src/mcp/standards/matcher.ts","../src/validate/tier.ts","../src/validate/types.ts","../src/mcp/server.ts","../src/mcp/tools/get-guideline.ts","../src/mcp/tools/get-ruleset.ts","../src/mcp/tools/get-standards.ts","../src/mcp/tools/list-guidelines.ts","../src/infra/index.ts","../src/infra/output.ts","../src/infra/checkers/index.ts","../src/infra/checkers/gcp/index.ts","../src/infra/scan.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { CheckResultBuilder, type CheckResult, type IToolRunner, type Violation } from \"../../core/index.js\";\n\n/**\n * Abstract base class for tool runners.\n * Provides common functionality for checking configs and handling errors.\n */\nexport abstract class BaseToolRunner implements IToolRunner {\n abstract readonly name: string;\n abstract readonly rule: string;\n abstract readonly toolId: string;\n abstract readonly configFiles: string[];\n\n /**\n * Check if any of the config files exist\n */\n protected hasConfig(projectRoot: string): boolean {\n return this.configFiles.some((config) => fs.existsSync(path.join(projectRoot, config)));\n }\n\n /**\n * Find which config file exists (if any)\n */\n protected findConfig(projectRoot: string): string | null {\n for (const config of this.configFiles) {\n if (fs.existsSync(path.join(projectRoot, config))) {\n return config;\n }\n }\n return null;\n }\n\n /**\n * Check if an error indicates the tool is not installed\n */\n protected isNotInstalledError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n const message = error.message.toLowerCase();\n return message.includes(\"enoent\") || message.includes(\"not found\");\n }\n\n /**\n * Create a fail result for when config is missing\n */\n protected failNoConfig(duration: number): CheckResult {\n const expected = this.configFiles.join(\" or \");\n return CheckResultBuilder.fail(\n this.name,\n this.rule,\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message: `Config not found. Expected one of: ${expected}`,\n severity: \"error\",\n },\n ],\n duration\n );\n }\n\n /**\n * Create a skip result for when tool is not installed\n */\n protected skipNotInstalled(duration: number): CheckResult {\n return CheckResultBuilder.skip(this.name, this.rule, `${this.name} not installed`, duration);\n }\n\n /**\n * Create a pass result\n */\n protected pass(duration: number): CheckResult {\n return CheckResultBuilder.pass(this.name, this.rule, duration);\n }\n\n /**\n * Create a fail result from violations\n */\n protected fail(violations: Violation[], duration: number): CheckResult {\n return CheckResultBuilder.fail(this.name, this.rule, violations, duration);\n }\n\n /**\n * Create a result from violations (pass if empty, fail otherwise)\n */\n protected fromViolations(violations: Violation[], duration: number): CheckResult {\n return CheckResultBuilder.fromViolations(this.name, this.rule, violations, duration);\n }\n\n /**\n * Run the tool - must be implemented by subclasses\n */\n abstract run(projectRoot: string): Promise<CheckResult>;\n\n /**\n * Default audit implementation - checks if config exists\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (this.hasConfig(projectRoot)) {\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, Date.now() - startTime);\n }\n\n return CheckResultBuilder.fail(\n `${this.name} Config`,\n this.rule,\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: `${this.name} config not found. Expected one of: ${this.configFiles.join(\", \")}`,\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { CheckResultBuilder, type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Coverage run configuration from standards.toml */\ninterface CoverageRunConfig {\n enabled?: boolean;\n min_threshold?: number;\n runner?: \"vitest\" | \"jest\" | \"pytest\" | \"auto\";\n command?: string;\n}\n\n/** Parsed coverage data */\ninterface CoverageData {\n lines?: number;\n statements?: number;\n branches?: number;\n functions?: number;\n}\n\n/** File coverage data from coverage-final.json */\ninterface FileCoverageData {\n s?: Record<string, number>;\n f?: Record<string, number>;\n b?: Record<string, number[]>;\n}\n\n/** Check if a config file exists */\nfunction configExists(projectRoot: string, configFile: string): boolean {\n return fs.existsSync(path.join(projectRoot, configFile));\n}\n\n/** Check if any config from a list exists */\nfunction findConfig(projectRoot: string, configs: string[]): boolean {\n return configs.some((config) => configExists(projectRoot, config));\n}\n\n/** Check for jest config in package.json */\nfunction hasJestInPackageJson(projectRoot: string): boolean {\n const packageJsonPath = path.join(projectRoot, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) {\n return false;\n }\n try {\n const pkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\")) as Record<string, unknown>;\n return Boolean(pkg.jest);\n } catch {\n return false;\n }\n}\n\n/** Safely extract pct from a coverage entry */\nfunction getPct(entry: { pct?: number } | undefined): number | undefined {\n return entry?.pct;\n}\n\n/** Parse coverage-summary.json format */\nfunction parseSummaryFormat(data: Record<string, unknown>): CoverageData | null {\n if (!data.total || typeof data.total !== \"object\") {\n return null;\n }\n const total = data.total as Record<string, { pct?: number } | undefined>;\n return {\n lines: getPct(total.lines),\n statements: getPct(total.statements),\n branches: getPct(total.branches),\n functions: getPct(total.functions),\n };\n}\n\n/** Parse pytest-cov format */\nfunction parsePytestFormat(data: Record<string, unknown>): CoverageData | null {\n if (!data.totals || typeof data.totals !== \"object\") {\n return null;\n }\n const totals = data.totals as { percent_covered?: number };\n if (totals.percent_covered === undefined) {\n return null;\n }\n return { lines: totals.percent_covered };\n}\n\n/** Count covered items in a record */\nfunction countCovered(items: Record<string, number>): { total: number; covered: number } {\n let total = 0;\n let covered = 0;\n for (const count of Object.values(items)) {\n total++;\n if (count > 0) {\n covered++;\n }\n }\n return { total, covered };\n}\n\n/** Count covered branches */\nfunction countCoveredBranches(branches: Record<string, number[]>): {\n total: number;\n covered: number;\n} {\n let total = 0;\n let covered = 0;\n for (const counts of Object.values(branches)) {\n for (const count of counts) {\n total++;\n if (count > 0) {\n covered++;\n }\n }\n }\n return { total, covered };\n}\n\n/** Compute percentage from totals */\nfunction computePercentage(total: number, covered: number): number {\n return total > 0 ? (covered / total) * 100 : 100;\n}\n\n/** Default coverage counts */\nconst zeroCounts = { total: 0, covered: 0 };\n\n/** Process a single file's coverage data */\nfunction processFileCoverage(fileData: FileCoverageData): {\n statements: { total: number; covered: number };\n functions: { total: number; covered: number };\n branches: { total: number; covered: number };\n} {\n return {\n statements: fileData.s ? countCovered(fileData.s) : zeroCounts,\n functions: fileData.f ? countCovered(fileData.f) : zeroCounts,\n branches: fileData.b ? countCoveredBranches(fileData.b) : zeroCounts,\n };\n}\n\n/** Accumulate coverage totals from multiple files */\ninterface CoverageTotals {\n statements: { total: number; covered: number };\n functions: { total: number; covered: number };\n branches: { total: number; covered: number };\n}\n\n/** Create empty coverage totals */\nfunction createEmptyTotals(): CoverageTotals {\n return {\n statements: { total: 0, covered: 0 },\n functions: { total: 0, covered: 0 },\n branches: { total: 0, covered: 0 },\n };\n}\n\n/** Add file coverage to totals */\nfunction addFileCoverage(\n totals: CoverageTotals,\n fileCov: ReturnType<typeof processFileCoverage>\n): void {\n totals.statements.total += fileCov.statements.total;\n totals.statements.covered += fileCov.statements.covered;\n totals.functions.total += fileCov.functions.total;\n totals.functions.covered += fileCov.functions.covered;\n totals.branches.total += fileCov.branches.total;\n totals.branches.covered += fileCov.branches.covered;\n}\n\n/** Convert totals to coverage data */\nfunction totalsToPercentages(totals: CoverageTotals): CoverageData {\n return {\n statements: computePercentage(totals.statements.total, totals.statements.covered),\n functions: computePercentage(totals.functions.total, totals.functions.covered),\n branches: computePercentage(totals.branches.total, totals.branches.covered),\n };\n}\n\n/** Check if data looks like coverage-final format */\nfunction isCoverageFinalFormat(data: Record<string, unknown>): boolean {\n const files = Object.keys(data).filter((key) => key !== \"total\");\n if (files.length === 0) {\n return false;\n }\n const firstFile = data[files[0]];\n if (!firstFile || typeof firstFile !== \"object\") {\n return false;\n }\n const fileData = firstFile as FileCoverageData;\n return Boolean(fileData.s ?? fileData.f ?? fileData.b);\n}\n\n/**\n * Coverage verification runner.\n * Runs tests with coverage and verifies the result meets a minimum threshold.\n */\nexport class CoverageRunRunner extends BaseToolRunner {\n readonly name = \"Coverage Run\";\n readonly rule = \"code.coverage\";\n readonly toolId = \"coverage-run\";\n readonly configFiles: string[] = [];\n\n private config: CoverageRunConfig = {\n enabled: false,\n min_threshold: 80,\n runner: \"auto\",\n };\n\n setConfig(config: CoverageRunConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n private detectRunner(projectRoot: string): \"vitest\" | \"jest\" | \"pytest\" | null {\n const vitestConfigs = [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"vitest.config.mts\",\n \"vitest.config.mjs\",\n ];\n if (findConfig(projectRoot, vitestConfigs)) {\n return \"vitest\";\n }\n\n const jestConfigs = [\"jest.config.js\", \"jest.config.ts\", \"jest.config.mjs\", \"jest.config.cjs\"];\n if (findConfig(projectRoot, jestConfigs) || hasJestInPackageJson(projectRoot)) {\n return \"jest\";\n }\n\n const pytestConfigs = [\"pytest.ini\", \"pyproject.toml\", \"setup.cfg\", \"conftest.py\"];\n if (findConfig(projectRoot, pytestConfigs)) {\n return \"pytest\";\n }\n\n return null;\n }\n\n private getRunnerCommand(runner: \"vitest\" | \"jest\" | \"pytest\"): { cmd: string; args: string[] } {\n const commands: Record<\"vitest\" | \"jest\" | \"pytest\", { cmd: string; args: string[] }> = {\n vitest: { cmd: \"npx\", args: [\"vitest\", \"run\", \"--coverage\", \"--coverage.reporter=json\"] },\n jest: { cmd: \"npx\", args: [\"jest\", \"--coverage\", \"--coverageReporters=json\"] },\n pytest: { cmd: \"pytest\", args: [\"--cov\", \"--cov-report=json\"] },\n };\n return commands[runner];\n }\n\n private getTestCommand(projectRoot: string): { cmd: string; args: string[] } | null {\n if (this.config.command) {\n const parts = this.config.command.split(\" \");\n return { cmd: parts[0], args: parts.slice(1) };\n }\n\n const runner =\n this.config.runner === \"auto\" ? this.detectRunner(projectRoot) : this.config.runner;\n if (!runner) {\n return null;\n }\n\n return this.getRunnerCommand(runner);\n }\n\n private parseCoverageReport(projectRoot: string): CoverageData | null {\n const possiblePaths = [\n \"coverage/coverage-final.json\",\n \"coverage/coverage-summary.json\",\n \".coverage.json\",\n \"coverage.json\",\n ];\n\n for (const relativePath of possiblePaths) {\n const fullPath = path.join(projectRoot, relativePath);\n if (!fs.existsSync(fullPath)) {\n continue;\n }\n\n try {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n const data = JSON.parse(content) as Record<string, unknown>;\n const result = this.extractCoverageData(data);\n if (result) {\n return result;\n }\n } catch {\n // Try next path\n }\n }\n\n return null;\n }\n\n private extractCoverageData(data: Record<string, unknown>): CoverageData | null {\n // Try summary format first\n const summaryResult = parseSummaryFormat(data);\n if (summaryResult) {\n return summaryResult;\n }\n\n // Try pytest format\n const pytestResult = parsePytestFormat(data);\n if (pytestResult) {\n return pytestResult;\n }\n\n // Try coverage-final.json format\n return this.computeCoverageFromFinal(data);\n }\n\n private computeCoverageFromFinal(data: Record<string, unknown>): CoverageData | null {\n if (!isCoverageFinalFormat(data)) {\n return null;\n }\n\n const totals = createEmptyTotals();\n for (const [filePath, fd] of Object.entries(data)) {\n if (filePath !== \"total\" && fd && typeof fd === \"object\") {\n addFileCoverage(totals, processFileCoverage(fd as FileCoverageData));\n }\n }\n\n return totalsToPercentages(totals);\n }\n\n private getOverallCoverage(data: CoverageData): number {\n if (data.lines !== undefined) {\n return data.lines;\n }\n if (data.statements !== undefined) {\n return data.statements;\n }\n\n const values = [data.branches, data.functions].filter((v): v is number => v !== undefined);\n if (values.length > 0) {\n return values.reduce((a, b) => a + b, 0) / values.length;\n }\n\n return 0;\n }\n\n private async executeTests(\n testCommand: { cmd: string; args: string[] },\n projectRoot: string\n ): Promise<{ exitCode: number | undefined; stderr: string; stdout: string }> {\n const result = await execa(testCommand.cmd, testCommand.args, {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeToolExtended,\n env: { ...process.env, CI: \"true\" },\n });\n return { exitCode: result.exitCode, stderr: result.stderr, stdout: result.stdout };\n }\n\n private checkCoverageThreshold(projectRoot: string): CheckResult | null {\n const coverageData = this.parseCoverageReport(projectRoot);\n if (!coverageData) {\n return this.fail(\n [\n this.createViolation(\n \"Could not find or parse coverage report. Ensure coverage reporter outputs JSON.\"\n ),\n ],\n 0\n );\n }\n\n const coverage = this.getOverallCoverage(coverageData);\n const threshold = this.config.min_threshold ?? 80;\n\n if (coverage < threshold) {\n return this.fail(\n [\n this.createViolation(\n `Coverage ${coverage.toFixed(1)}% is below minimum threshold ${threshold}%`\n ),\n ],\n 0\n );\n }\n\n return null;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const testCommand = this.getTestCommand(projectRoot);\n if (!testCommand) {\n return this.fail(\n [this.createViolation(\"Could not detect test runner. Set runner or command in config.\")],\n elapsed()\n );\n }\n\n try {\n const result = await this.executeTests(testCommand, projectRoot);\n const exitError = this.validateExitCode(result, elapsed);\n if (exitError) {\n return exitError;\n }\n\n const thresholdResult = this.checkCoverageThreshold(projectRoot);\n if (thresholdResult) {\n return { ...thresholdResult, duration: elapsed() };\n }\n\n return this.pass(elapsed());\n } catch (error) {\n return this.handleRunError(error, elapsed);\n }\n }\n\n /** Validate test command exit code and return error result if invalid */\n private validateExitCode(\n result: { exitCode?: number; stdout: string; stderr: string },\n elapsed: () => number\n ): CheckResult | null {\n if (result.exitCode === undefined) {\n const errorMsg = result.stderr || result.stdout || \"Command not found or failed to execute\";\n return this.fail(\n [this.createViolation(`Test command failed to execute: ${errorMsg}`)],\n elapsed()\n );\n }\n\n if (result.exitCode !== 0 && result.exitCode !== 1) {\n const errorMsg = result.stderr || result.stdout;\n return this.fail(\n [\n this.createViolation(\n `Test command failed with exit code ${result.exitCode}: ${errorMsg}`\n ),\n ],\n elapsed()\n );\n }\n\n return null;\n }\n\n private handleRunError(error: unknown, elapsed: () => number): CheckResult {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createViolation(`Coverage run error: ${message}`)], elapsed());\n }\n\n override async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n const testCommand = this.getTestCommand(projectRoot);\n if (!testCommand) {\n return CheckResultBuilder.fail(\n `${this.name} Config`,\n this.rule,\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"Could not detect test runner. Configure runner or command in standards.toml.\",\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, Date.now() - startTime);\n }\n\n private createViolation(message: string): Violation {\n return { rule: `${this.rule}.${this.toolId}`, tool: this.toolId, message, severity: \"error\" };\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { glob } from \"glob\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\nimport {\n findBlockEnd,\n findCommentInLine,\n findFirstPattern,\n KNOWN_EXTENSIONS,\n} from \"./comment-utils.js\";\n\n/** Default patterns to detect disable comments */\nconst DEFAULT_PATTERNS = [\n // ESLint\n \"eslint-disable\",\n \"eslint-disable-line\",\n \"eslint-disable-next-line\",\n // TypeScript\n \"@ts-ignore\",\n \"@ts-expect-error\",\n \"@ts-nocheck\",\n // Python\n \"# noqa\",\n \"# type: ignore\",\n \"# pylint: disable\",\n \"# pragma: no cover\",\n];\n\n/** Default file extensions to scan */\nconst DEFAULT_EXTENSIONS = [\"ts\", \"tsx\", \"js\", \"jsx\", \"py\"];\n\n/** Default directories to exclude */\nconst DEFAULT_EXCLUDE = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/__pycache__/**\",\n \"**/.venv/**\",\n \"**/venv/**\",\n \"**/coverage/**\",\n];\n\n/** Configuration for disable-comments validation */\ninterface DisableCommentsConfig {\n enabled?: boolean;\n patterns?: string[];\n extensions?: string[];\n exclude?: string[];\n}\n\n/** Context for scanning a file */\ninterface ScanContext {\n file: string;\n patterns: string[];\n inBlockComment: boolean;\n}\n\n/** Violation data */\ninterface ViolationData {\n line: number;\n pattern: string;\n content: string;\n}\n\n/** Line scan result */\ninterface LineScanResult {\n violation: ViolationData | null;\n inBlockComment: boolean;\n}\n\n/** Line scan parameters */\ninterface LineScanParams {\n line: string;\n lineNum: number;\n ext: string;\n patterns: string[];\n}\n\n/**\n * Disable comments runner for detecting linter/type-checker disable comments\n */\nexport class DisableCommentsRunner extends BaseToolRunner {\n readonly name = \"Disable Comments\";\n readonly rule = \"code.quality\";\n readonly toolId = \"disable-comments\";\n readonly configFiles: string[] = []; // No config file needed\n\n private config: DisableCommentsConfig = {};\n\n setConfig(config: DisableCommentsConfig): void {\n this.config = config;\n }\n\n private getPatterns(): string[] {\n return this.config.patterns ?? DEFAULT_PATTERNS;\n }\n\n private getExtensions(): string[] {\n return this.config.extensions ?? DEFAULT_EXTENSIONS;\n }\n\n private getExcludePatterns(): string[] {\n return [...DEFAULT_EXCLUDE, ...(this.config.exclude ?? [])];\n }\n\n private buildGlobPattern(): string {\n const extensions = this.getExtensions();\n const unique = [...new Set(extensions)];\n if (unique.length === 1) {\n return `**/*.${unique[0]}`;\n }\n return `**/*.{${unique.join(\",\")}}`;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n try {\n const files = await glob(this.buildGlobPattern(), {\n cwd: projectRoot,\n ignore: this.getExcludePatterns(),\n nodir: true,\n });\n\n if (files.length === 0) {\n return this.pass(Date.now() - startTime);\n }\n\n const violations = this.scanAllFiles(projectRoot, files);\n return this.fromViolations(violations, Date.now() - startTime);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`Disable comments check error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n\n private scanAllFiles(projectRoot: string, files: string[]): Violation[] {\n const violations: Violation[] = [];\n const patterns = this.getPatterns();\n\n for (const file of files) {\n const filePath = path.join(projectRoot, file);\n violations.push(...this.scanFile(filePath, { file, patterns, inBlockComment: false }));\n }\n\n return violations;\n }\n\n private scanFile(absolutePath: string, ctx: ScanContext): Violation[] {\n try {\n const content = fs.readFileSync(absolutePath, \"utf-8\");\n return this.scanContent(content, ctx);\n } catch {\n return []; // Skip unreadable files\n }\n }\n\n private scanContent(content: string, ctx: ScanContext): Violation[] {\n const lines = content.split(\"\\n\");\n const ext = path.extname(ctx.file).slice(1).toLowerCase();\n const violations: Violation[] = [];\n let inBlock = ctx.inBlockComment;\n\n for (let i = 0; i < lines.length; i++) {\n const params: LineScanParams = {\n line: lines[i],\n lineNum: i + 1,\n ext,\n patterns: ctx.patterns,\n };\n const result = this.scanLine(params, inBlock);\n if (result.violation) {\n violations.push(this.createViolation(ctx.file, result.violation));\n }\n inBlock = result.inBlockComment;\n }\n\n return violations;\n }\n\n private scanLine(params: LineScanParams, inBlock: boolean): LineScanResult {\n const { ext } = params;\n if (ext === \"py\" || !KNOWN_EXTENSIONS.has(ext)) {\n return { violation: this.scanSimpleLine(params), inBlockComment: false };\n }\n return this.scanJsLine(params, inBlock);\n }\n\n private scanSimpleLine(params: LineScanParams): ViolationData | null {\n const { line, lineNum, ext, patterns } = params;\n for (const pattern of patterns) {\n if (this.isPatternInComment(line, pattern, ext)) {\n return { line: lineNum, pattern, content: line };\n }\n }\n return null;\n }\n\n private scanJsLine(params: LineScanParams, inBlock: boolean): LineScanResult {\n const { line, lineNum, patterns } = params;\n return this.processJsLineComments(line, lineNum, patterns, inBlock);\n }\n\n private processJsLineComments(\n line: string,\n lineNum: number,\n patterns: string[],\n inBlock: boolean\n ): LineScanResult {\n let state = { pos: 0, inBlock };\n\n while (state.pos < line.length) {\n const r = state.inBlock\n ? this.handleInsideBlock(line, lineNum, patterns, state.pos)\n : this.handleOutsideBlock(line, lineNum, patterns, state.pos);\n\n if (r.done) {\n return r.result;\n }\n state = { pos: r.nextPos, inBlock: r.enterBlock ?? false };\n if (r.enterBlock) {\n break;\n }\n }\n\n return { violation: null, inBlockComment: state.inBlock };\n }\n\n private handleInsideBlock(\n line: string,\n lineNum: number,\n patterns: string[],\n pos: number\n ): { done: boolean; result: LineScanResult; nextPos: number; enterBlock?: boolean } {\n const blockEnd = findBlockEnd(line, pos);\n const text = line.slice(pos, blockEnd === -1 ? line.length : blockEnd);\n const pattern = findFirstPattern(text, patterns);\n\n if (pattern) {\n return {\n done: true,\n result: {\n violation: { line: lineNum, pattern, content: line },\n inBlockComment: blockEnd === -1,\n },\n nextPos: 0,\n };\n }\n if (blockEnd === -1) {\n return { done: true, result: { violation: null, inBlockComment: true }, nextPos: 0 };\n }\n return { done: false, result: { violation: null, inBlockComment: false }, nextPos: blockEnd };\n }\n\n private handleOutsideBlock(\n line: string,\n lineNum: number,\n patterns: string[],\n pos: number\n ): { done: boolean; result: LineScanResult; nextPos: number; enterBlock: boolean } {\n const comment = findCommentInLine(line, pos, false);\n if (!comment) {\n return {\n done: true,\n result: { violation: null, inBlockComment: false },\n nextPos: 0,\n enterBlock: false,\n };\n }\n if (!comment.isBlock) {\n return this.handleLineComment(line, lineNum, patterns, comment.index);\n }\n return this.handleBlockCommentStart(line, lineNum, patterns, comment.index);\n }\n\n private handleLineComment(\n line: string,\n lineNum: number,\n patterns: string[],\n index: number\n ): { done: boolean; result: LineScanResult; nextPos: number; enterBlock: boolean } {\n const pattern = findFirstPattern(line.slice(index), patterns);\n const result: LineScanResult = pattern\n ? { violation: { line: lineNum, pattern, content: line }, inBlockComment: false }\n : { violation: null, inBlockComment: false };\n return { done: true, result, nextPos: 0, enterBlock: false };\n }\n\n private handleBlockCommentStart(\n line: string,\n lineNum: number,\n patterns: string[],\n index: number\n ): { done: boolean; result: LineScanResult; nextPos: number; enterBlock: boolean } {\n const blockEnd = findBlockEnd(line, index + 2);\n const text = line.slice(index + 2, blockEnd === -1 ? line.length : blockEnd);\n const pattern = findFirstPattern(text, patterns);\n\n if (pattern) {\n return {\n done: true,\n result: {\n violation: { line: lineNum, pattern, content: line },\n inBlockComment: blockEnd === -1,\n },\n nextPos: 0,\n enterBlock: false,\n };\n }\n if (blockEnd === -1) {\n return {\n done: false,\n result: { violation: null, inBlockComment: true },\n nextPos: 0,\n enterBlock: true,\n };\n }\n return {\n done: false,\n result: { violation: null, inBlockComment: false },\n nextPos: blockEnd,\n enterBlock: false,\n };\n }\n\n /** Check if a pattern appears in a comment (not in a string) - for simple line detection */\n private isPatternInComment(line: string, pattern: string, extension: string): boolean {\n if (!line.includes(pattern)) {\n return false;\n }\n if (!KNOWN_EXTENSIONS.has(extension)) {\n return true;\n }\n\n const comment = findCommentInLine(line, 0, extension === \"py\");\n if (!comment) {\n return false;\n }\n\n const patternIndex = line.indexOf(pattern);\n return comment.index <= patternIndex;\n }\n\n private createViolation(file: string, data: ViolationData): Violation {\n const trimmed = data.content.trim();\n const display = trimmed.length > 60 ? `${trimmed.substring(0, 60)}...` : trimmed;\n\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file,\n line: data.line,\n message: `Found \"${data.pattern}\" comment: ${display}`,\n code: data.pattern,\n severity: \"error\",\n };\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n override async audit(_projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n const patterns = this.getPatterns();\n if (patterns.length === 0) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"At least one pattern must be configured\",\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return this.pass(Date.now() - startTime);\n }\n}\n","/** Quote state for tracking string contexts */\ninterface QuoteState {\n single: boolean;\n double: boolean;\n template: boolean;\n}\n\n/** File extensions with known comment syntax */\nexport const KNOWN_EXTENSIONS = new Set([\"py\", \"ts\", \"tsx\", \"js\", \"jsx\"]);\n\n/**\n * Check if a character at the given index starts a block comment.\n */\nfunction isBlockCommentStart(line: string, index: number): boolean {\n return line[index] === \"/\" && line[index + 1] === \"*\";\n}\n\n/**\n * Check if a character at the given index starts a line comment.\n */\nfunction isLineCommentStart(line: string, index: number): boolean {\n return line[index] === \"/\" && line[index + 1] === \"/\";\n}\n\n/**\n * Find the first pattern that appears in the given text range.\n */\nexport function findFirstPattern(text: string, patterns: string[]): string | null {\n for (const pattern of patterns) {\n if (text.includes(pattern)) {\n return pattern;\n }\n }\n return null;\n}\n\n/**\n * Find where a block comment ends in a line. Returns -1 if not found.\n */\nexport function findBlockEnd(line: string, startIndex: number): number {\n const idx = line.indexOf(\"*/\", startIndex);\n return idx === -1 ? -1 : idx + 2;\n}\n\n/**\n * Check if a quote character can be toggled given current state.\n */\nfunction canToggle(char: string, target: string, state: QuoteState, isPython: boolean): boolean {\n if (char !== target) {\n return false;\n }\n if (target === \"'\") {\n return !state.double && !state.template;\n }\n if (target === '\"') {\n return !state.single && !state.template;\n }\n return !isPython && !state.single && !state.double; // backtick\n}\n\n/**\n * Update quote state based on current character.\n */\nfunction updateQuotes(char: string, prev: string, state: QuoteState, isPython: boolean): void {\n if (prev === \"\\\\\") {\n return;\n }\n if (canToggle(char, \"'\", state, isPython)) {\n state.single = !state.single;\n } else if (canToggle(char, '\"', state, isPython)) {\n state.double = !state.double;\n } else if (canToggle(char, \"`\", state, isPython)) {\n state.template = !state.template;\n }\n}\n\n/**\n * Check if currently inside a string based on quote state.\n */\nfunction inString(state: QuoteState): boolean {\n return state.single || state.double || state.template;\n}\n\n/**\n * Check for comment marker at position, return type or null.\n */\nfunction getCommentAt(line: string, i: number, isPython: boolean): { isBlock: boolean } | null {\n if (isPython) {\n return line[i] === \"#\" ? { isBlock: false } : null;\n }\n if (isLineCommentStart(line, i)) {\n return { isBlock: false };\n }\n if (isBlockCommentStart(line, i)) {\n return { isBlock: true };\n }\n return null;\n}\n\n/**\n * Build quote state for a line up to the given position.\n */\nfunction buildQuoteState(line: string, endPos: number, isPython: boolean): QuoteState {\n const quotes: QuoteState = { single: false, double: false, template: false };\n for (let i = 0; i < endPos; i++) {\n updateQuotes(line[i], line[i - 1] || \"\", quotes, isPython);\n }\n return quotes;\n}\n\n/**\n * Find comment start in a line, respecting string boundaries.\n */\nexport function findCommentInLine(\n line: string,\n startPos: number,\n isPython: boolean\n): { index: number; isBlock: boolean } | null {\n const quotes = buildQuoteState(line, startPos, isPython);\n\n for (let i = startPos; i < line.length; i++) {\n updateQuotes(line[i], line[i - 1] || \"\", quotes, isPython);\n if (inString(quotes)) {\n continue;\n }\n\n const comment = getCommentAt(line, i, isPython);\n if (comment) {\n return { index: i, isBlock: comment.isBlock };\n }\n }\n\n return null;\n}\n","import * as path from \"node:path\";\n\nimport { execa } from \"execa\";\nimport { globSync } from \"glob\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { CheckResultBuilder, type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** ESLint JSON output message format */\ninterface ESLintMessage {\n ruleId: string | null;\n severity: 1 | 2;\n message: string;\n line: number;\n column: number;\n}\n\n/** ESLint JSON output file result format */\ninterface ESLintFileResult {\n filePath: string;\n messages: ESLintMessage[];\n}\n\n/**\n * ESLint rule with options in TOML-friendly object format.\n * Example: { severity: \"error\", max: 10 }\n */\ninterface ESLintRuleWithOptions {\n severity: \"off\" | \"warn\" | \"error\";\n [key: string]: unknown;\n}\n\n/** ESLint rule value - severity string or object with options */\ntype ESLintRuleValue = \"off\" | \"warn\" | \"error\" | ESLintRuleWithOptions;\n\n/** ESLint configuration options */\ninterface ESLintConfig {\n enabled?: boolean;\n files?: string[];\n ignore?: string[];\n \"max-warnings\"?: number;\n rules?: Record<string, ESLintRuleValue>;\n}\n\n/** ESLint --print-config output format */\ninterface ESLintPrintConfig {\n rules?: Record<string, unknown[]>;\n}\n\n/**\n * ESLint tool runner\n */\nexport class ESLintRunner extends BaseToolRunner {\n readonly name = \"ESLint\";\n readonly rule = \"code.linting\";\n readonly toolId = \"eslint\";\n readonly configFiles = [\n \"eslint.config.js\",\n \"eslint.config.mjs\",\n \"eslint.config.cjs\",\n \".eslintrc.js\",\n \".eslintrc.json\",\n \".eslintrc.yml\",\n \".eslintrc.yaml\",\n ];\n\n private config: ESLintConfig = {};\n\n /**\n * Set ESLint configuration options\n */\n setConfig(config: ESLintConfig): void {\n this.config = config;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (!this.hasConfig(projectRoot)) {\n return this.failNoConfig(Date.now() - startTime);\n }\n\n try {\n const args = this.buildArgs();\n const result = await execa(\"npx\", [\"eslint\", ...args], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n const violations = this.parseOutput(result.stdout, projectRoot);\n\n // Handle parse failure with non-zero exit\n if (violations === null && result.exitCode !== 0 && result.stderr) {\n return this.fail(\n [this.createErrorViolation(`ESLint error: ${result.stderr}`)],\n Date.now() - startTime\n );\n }\n\n return this.fromViolations(violations ?? [], Date.now() - startTime);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`ESLint error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n\n /**\n * Audit ESLint config - verify config exists and required rules are present\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n // First check if config exists\n if (!this.hasConfig(projectRoot)) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: `${this.name} config not found. Expected one of: ${this.configFiles.join(\", \")}`,\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n\n // If no rules defined, just pass\n if (!this.config.rules || Object.keys(this.config.rules).length === 0) {\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, elapsed());\n }\n\n // Get effective ESLint config and verify rules\n const violations = await this.auditRules(projectRoot);\n if (violations.length === 0) {\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, elapsed());\n }\n\n return CheckResultBuilder.fail(`${this.name} Config`, this.rule, violations, elapsed());\n }\n\n /**\n * Audit that required rules are present in ESLint config\n */\n private async auditRules(projectRoot: string): Promise<Violation[]> {\n // Check if files pattern is configured\n if (!this.config.files || this.config.files.length === 0) {\n return [\n this.createAuditViolation(\n 'Rules audit requires \"files\" to be configured in standards.toml (e.g., files = [\"src/**/*.ts\"])',\n \"error\"\n ),\n ];\n }\n\n const sampleFile = this.findSampleFile(projectRoot);\n if (!sampleFile) {\n return [\n this.createAuditViolation(\n `No files found matching patterns: ${this.config.files.join(\", \")}`,\n \"error\"\n ),\n ];\n }\n\n const effectiveRules = await this.getEffectiveRules(projectRoot, sampleFile);\n if (\"error\" in effectiveRules) {\n return [this.createAuditViolation(effectiveRules.error, \"error\")];\n }\n\n return this.compareRules(projectRoot, this.config.rules ?? {}, effectiveRules.rules);\n }\n\n /**\n * Get effective ESLint rules for a file\n */\n private async getEffectiveRules(\n projectRoot: string,\n sampleFile: string\n ): Promise<{ rules: Record<string, unknown[]> } | { error: string }> {\n try {\n const result = await execa(\"npx\", [\"eslint\", \"--print-config\", sampleFile], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.quick,\n });\n\n if (result.exitCode !== 0) {\n return { error: `Failed to read ESLint config: ${result.stderr || \"Unknown error\"}` };\n }\n\n const config = JSON.parse(result.stdout) as ESLintPrintConfig;\n return { rules: config.rules ?? {} };\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n return { error: `Failed to audit ESLint config: ${msg}` };\n }\n }\n\n /**\n * Extract options from a rule value (excludes severity)\n */\n private extractRuleOptions(value: ESLintRuleValue): unknown[] | null {\n if (typeof value === \"string\") {\n return null; // No options for severity-only rules\n }\n if (this.isRuleWithOptions(value)) {\n // For object format, convert to array format for comparison\n const { severity: _, ...options } = value;\n return Object.keys(options).length > 0 ? [options] : null;\n }\n return null;\n }\n\n /**\n * Get effective option value, handling both object and primitive formats.\n * ESLint normalizes some rules like max-depth from [\"error\", { max: 4 }] to [2, 4].\n */\n private getEffectiveOptionValue(effectiveOptions: unknown, optionName: string): unknown {\n // If effectiveOptions is an object, look up the key\n if (typeof effectiveOptions === \"object\" && effectiveOptions !== null) {\n return (effectiveOptions as Record<string, unknown>)[optionName];\n }\n // If effectiveOptions is a primitive and we're looking for \"max\", return the primitive\n // This handles rules like max-depth, max-params, complexity where ESLint uses [severity, number]\n if (\n optionName === \"max\" &&\n (typeof effectiveOptions === \"number\" || typeof effectiveOptions === \"string\")\n ) {\n return effectiveOptions;\n }\n return undefined;\n }\n\n /**\n * Compare rule options between required and effective config.\n */\n private compareRuleOptions(\n ruleName: string,\n requiredOptions: unknown[],\n effectiveRule: unknown[],\n configFile: string | undefined\n ): Violation[] {\n const effectiveOptions = effectiveRule.slice(1);\n if (this.deepEqual(requiredOptions, effectiveOptions)) {\n return [];\n }\n // For single-object rules, try detailed comparison\n if (requiredOptions.length === 1 && typeof requiredOptions[0] === \"object\") {\n return this.compareObjectOptions(ruleName, requiredOptions[0], effectiveOptions, configFile);\n }\n // For complex rules, show full mismatch\n const msg = `Rule \"${ruleName}\": options mismatch`;\n return [this.createAuditViolation(msg, \"error\", configFile)];\n }\n\n /** Compare single-object rule options for detailed error messages */\n private compareObjectOptions(\n ruleName: string,\n reqObj: unknown,\n effectiveOptions: unknown[],\n configFile: string | undefined\n ): Violation[] {\n const violations: Violation[] = [];\n const required = reqObj as Record<string, unknown>;\n const effective = typeof effectiveOptions[0] === \"object\" ? effectiveOptions[0] : {};\n for (const [key, reqVal] of Object.entries(required)) {\n const effVal = this.getEffectiveOptionValue(effective, key);\n if (effVal === undefined) {\n violations.push(\n this.createAuditViolation(`Rule \"${ruleName}\": \"${key}\" required`, \"error\", configFile)\n );\n } else if (!this.deepEqual(reqVal, effVal)) {\n violations.push(\n this.createAuditViolation(`Rule \"${ruleName}\": \"${key}\" mismatch`, \"error\", configFile)\n );\n }\n }\n return violations;\n }\n\n /**\n * Deep equality check for comparing option values\n */\n private deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) {\n return true;\n }\n if (typeof a !== typeof b) {\n return false;\n }\n if (typeof a !== \"object\" || a === null || b === null) {\n return false;\n }\n const keysA = Object.keys(a as object);\n const keysB = Object.keys(b as object);\n if (keysA.length !== keysB.length) {\n return false;\n }\n for (const key of keysA) {\n if (\n !this.deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])\n ) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Compare a single rule against effective config\n */\n private compareSingleRule(\n ruleName: string,\n requiredValue: ESLintRuleValue,\n effectiveRule: unknown[] | undefined,\n configFile: string | undefined\n ): Violation[] {\n if (!effectiveRule) {\n return [\n this.createAuditViolation(\n `Rule \"${ruleName}\" is required but not configured`,\n \"error\",\n configFile\n ),\n ];\n }\n\n const violations: Violation[] = [];\n const requiredSeverity = this.normalizeSeverity(requiredValue);\n const effectiveSeverity = this.normalizeSeverity(effectiveRule[0]);\n\n if (requiredSeverity !== effectiveSeverity) {\n const msg = `Rule \"${ruleName}\": expected \"${this.severityToString(requiredSeverity)}\", got \"${this.severityToString(effectiveSeverity)}\"`;\n violations.push(this.createAuditViolation(msg, \"error\", configFile));\n }\n\n const requiredOptions = this.extractRuleOptions(requiredValue);\n if (requiredOptions) {\n violations.push(\n ...this.compareRuleOptions(ruleName, requiredOptions, effectiveRule, configFile)\n );\n }\n\n return violations;\n }\n\n /**\n * Compare required rules against effective rules\n */\n private compareRules(\n projectRoot: string,\n requiredRules: Record<string, ESLintRuleValue>,\n effectiveRules: Record<string, unknown[]>\n ): Violation[] {\n const configFile = this.findConfig(projectRoot) ?? undefined;\n\n return Object.entries(requiredRules).flatMap(([ruleName, requiredValue]) =>\n this.compareSingleRule(ruleName, requiredValue, effectiveRules[ruleName], configFile)\n );\n }\n\n /**\n * Create an audit violation\n */\n private createAuditViolation(\n message: string,\n severity: \"error\" | \"warning\",\n file?: string\n ): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message,\n severity,\n file,\n };\n }\n\n /**\n * Find a sample source file to check ESLint config against.\n * Requires 'files' to be configured in standards.toml.\n */\n private findSampleFile(projectRoot: string): string | null {\n const filePatterns = this.config.files;\n if (!filePatterns || filePatterns.length === 0) {\n return null;\n }\n\n // Use glob to find a file matching the configured patterns\n const matches = globSync(filePatterns, {\n cwd: projectRoot,\n nodir: true,\n ignore: this.config.ignore ?? [],\n });\n\n return matches.length > 0 ? matches[0] : null;\n }\n\n /**\n * Check if a value is an ESLint rule with options object\n */\n private isRuleWithOptions(value: unknown): value is ESLintRuleWithOptions {\n return typeof value === \"object\" && value !== null && \"severity\" in value;\n }\n\n /**\n * Normalize rule severity to number (0, 1, 2)\n */\n private normalizeSeverity(value: unknown): number {\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\") {\n switch (value) {\n case \"off\":\n return 0;\n case \"warn\":\n return 1;\n case \"error\":\n return 2;\n default:\n return parseInt(value, 10) || 0;\n }\n }\n if (Array.isArray(value)) {\n return this.normalizeSeverity(value[0]);\n }\n if (this.isRuleWithOptions(value)) {\n return this.normalizeSeverity(value.severity);\n }\n return 0;\n }\n\n /**\n * Convert severity number to string\n */\n private severityToString(severity: number): string {\n switch (severity) {\n case 0:\n return \"off\";\n case 1:\n return \"warn\";\n case 2:\n return \"error\";\n default:\n return String(severity);\n }\n }\n\n private buildArgs(): string[] {\n const args: string[] = [];\n\n // Files to lint (default to \".\")\n if (this.config.files && this.config.files.length > 0) {\n args.push(...this.config.files);\n } else {\n args.push(\".\");\n }\n\n // Output format\n args.push(\"--format\", \"json\");\n\n // Ignore patterns\n if (this.config.ignore) {\n for (const pattern of this.config.ignore) {\n args.push(\"--ignore-pattern\", pattern);\n }\n }\n\n // Max warnings\n if (this.config[\"max-warnings\"] !== undefined) {\n args.push(\"--max-warnings\", String(this.config[\"max-warnings\"]));\n }\n\n return args;\n }\n\n private parseOutput(stdout: string, projectRoot: string): Violation[] | null {\n try {\n const results = JSON.parse(stdout) as ESLintFileResult[];\n const violations: Violation[] = [];\n\n for (const fileResult of results) {\n for (const msg of fileResult.messages) {\n violations.push({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: path.relative(projectRoot, fileResult.filePath),\n line: msg.line,\n column: msg.column,\n message: msg.message,\n code: msg.ruleId ?? undefined,\n severity: msg.severity === 2 ? \"error\" : \"warning\",\n });\n }\n }\n\n return violations;\n } catch {\n return null;\n }\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Gitleaks finding entry from JSON output */\ninterface GitleaksFinding {\n Description: string;\n StartLine: number;\n EndLine: number;\n StartColumn: number;\n EndColumn: number;\n Match: string;\n Secret: string;\n File: string;\n Commit: string;\n Entropy: number;\n Author: string;\n Email: string;\n Date: string;\n Message: string;\n Tags: string[];\n RuleID: string;\n Fingerprint: string;\n}\n\n/** Scan mode options */\ntype ScanMode = \"branch\" | \"files\" | \"staged\" | \"full\";\n\n/** Gitleaks configuration */\ninterface GitleaksConfig {\n enabled?: boolean;\n scan_mode?: ScanMode;\n base_branch?: string;\n}\n\n/**\n * Gitleaks tool runner for detecting hardcoded secrets\n */\nexport class GitleaksRunner extends BaseToolRunner {\n readonly name = \"gitleaks\";\n readonly rule = \"code.security\";\n readonly toolId = \"secrets\";\n readonly configFiles = [\".gitleaks.toml\", \"gitleaks.toml\"];\n\n private config: GitleaksConfig = {\n scan_mode: \"branch\",\n base_branch: \"main\",\n };\n\n setConfig(config: GitleaksConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Find gitleaks config file if it exists\n * Returns just the filename (relative to projectRoot) since gitleaks runs with cwd=projectRoot\n */\n private findGitleaksConfig(projectRoot: string): string | null {\n for (const configFile of this.configFiles) {\n const configPath = path.join(projectRoot, configFile);\n if (fs.existsSync(configPath)) {\n return configFile; // Return just the filename, not the full path\n }\n }\n return null;\n }\n\n /**\n * Build gitleaks arguments based on scan mode\n */\n private buildArgs(projectRoot: string): string[] {\n const scanMode = this.config.scan_mode ?? \"branch\";\n const baseBranch = this.config.base_branch ?? \"main\";\n\n const args = [\"detect\", \"--report-format\", \"json\", \"--report-path\", \"/dev/stdout\"];\n\n switch (scanMode) {\n case \"branch\":\n // Scan only commits on current branch since diverging from base branch\n args.push(\"--log-opts\", `${baseBranch}..HEAD`);\n break;\n case \"files\":\n // Scan filesystem only (no git history)\n args.push(\"--source\", \".\", \"--no-git\");\n break;\n case \"staged\":\n // Scan only staged files\n args.push(\"--staged\");\n break;\n case \"full\":\n // Scan entire git history (no special flags needed)\n break;\n }\n\n // Use custom config if it exists - use absolute path for reliability\n const configPath = this.findGitleaksConfig(projectRoot);\n if (configPath) {\n const absoluteConfigPath = path.join(projectRoot, configPath);\n args.push(\"--config\", absoluteConfigPath);\n }\n\n return args;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n try {\n const args = this.buildArgs(projectRoot);\n\n const result = await execa(\"gitleaks\", args, {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n return this.processResult(result, elapsed);\n } catch (error) {\n return this.handleRunError(error, elapsed);\n }\n }\n\n private isBinaryNotFound(result: Awaited<ReturnType<typeof execa>>): boolean {\n const execaResult = result as Awaited<ReturnType<typeof execa>> & {\n code?: string;\n message?: string;\n };\n return (\n execaResult.code === \"ENOENT\" ||\n (execaResult.failed && String(execaResult.message ?? \"\").includes(\"ENOENT\"))\n );\n }\n\n private processResult(\n result: Awaited<ReturnType<typeof execa>>,\n elapsed: () => number\n ): CheckResult {\n if (this.isBinaryNotFound(result)) {\n return this.skipNotInstalled(elapsed());\n }\n\n // Exit code 0 = no leaks found, exit code 1 = leaks found\n if (result.exitCode === 0) {\n return this.pass(elapsed());\n }\n\n if (result.exitCode === 1) {\n return this.processLeaksFound(result, elapsed);\n }\n\n // Other exit codes are errors\n const errorMsg = result.stderr ?? result.stdout ?? \"Unknown error\";\n return this.fail([this.createErrorViolation(`gitleaks error: ${errorMsg}`)], elapsed());\n }\n\n private processLeaksFound(\n result: Awaited<ReturnType<typeof execa>>,\n elapsed: () => number\n ): CheckResult {\n const output = String(result.stdout ?? \"\");\n const violations = this.parseOutput(output);\n\n if (violations === null) {\n return this.fail([this.createErrorViolation(`Failed to parse gitleaks output`)], elapsed());\n }\n\n return this.fromViolations(violations, elapsed());\n }\n\n private handleRunError(error: unknown, elapsed: () => number): CheckResult {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createErrorViolation(`gitleaks error: ${message}`)], elapsed());\n }\n\n private parseOutput(output: string): Violation[] | null {\n if (!output.trim()) {\n return [];\n }\n\n try {\n const findings = JSON.parse(output) as GitleaksFinding[];\n const violations: Violation[] = [];\n\n for (const finding of findings) {\n violations.push({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: finding.File,\n line: finding.StartLine,\n column: finding.StartColumn,\n message: `${finding.RuleID}: ${finding.Description}`,\n code: finding.RuleID,\n severity: \"error\",\n });\n }\n\n return violations;\n } catch {\n return null;\n }\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - gitleaks doesn't require config, just check if installed\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n try {\n await execa(\"gitleaks\", [\"version\"], {\n cwd: projectRoot,\n reject: true,\n timeout: TIMEOUTS.versionCheck,\n });\n\n return this.pass(Date.now() - startTime);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`gitleaks audit error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n}\n","import * as fs from \"node:fs\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Knip JSON output format for a dependency issue */\ninterface KnipDependencyIssue {\n name: string;\n line?: number;\n col?: number;\n pos?: number;\n}\n\n/** Knip JSON output format for an export issue */\ninterface KnipExportIssue {\n name: string;\n line?: number;\n col?: number;\n pos?: number;\n type?: string;\n}\n\n/** Knip JSON output format for issues per file */\ninterface KnipFileIssue {\n file: string;\n dependencies?: KnipDependencyIssue[];\n devDependencies?: KnipDependencyIssue[];\n optionalPeerDependencies?: KnipDependencyIssue[];\n unlisted?: KnipDependencyIssue[];\n binaries?: KnipDependencyIssue[];\n unresolved?: KnipDependencyIssue[];\n exports?: KnipExportIssue[];\n types?: KnipExportIssue[];\n enumMembers?: Record<string, KnipExportIssue[]>;\n duplicates?: KnipExportIssue[];\n}\n\n/** Knip JSON output format */\ninterface KnipOutput {\n files: string[];\n issues: KnipFileIssue[];\n}\n\n/**\n * Knip tool runner for detecting unused code\n */\nexport class KnipRunner extends BaseToolRunner {\n readonly name = \"Knip\";\n readonly rule = \"code.unused\";\n readonly toolId = \"knip\";\n readonly configFiles = [\n \"knip.json\",\n \"knip.jsonc\",\n \"knip.js\",\n \"knip.ts\",\n \"knip.config.js\",\n \"knip.config.ts\",\n ];\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Knip works without a config file (uses defaults), so we don't skip if no config\n // It just needs package.json to exist\n try {\n const result = await execa(\"npx\", [\"knip\", \"--reporter\", \"json\"], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n // Knip outputs JSON to stdout\n const output = result.stdout || result.stderr;\n const violations = this.parseOutput(output, projectRoot);\n\n if (violations === null && result.exitCode !== 0) {\n return this.fail(\n [this.createErrorViolation(`Knip error: ${result.stderr}`)],\n Date.now() - startTime\n );\n }\n\n return this.fromViolations(violations ?? [], Date.now() - startTime);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`Knip error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n\n private parseOutput(output: string, _projectRoot: string): Violation[] | null {\n try {\n const result = JSON.parse(output) as KnipOutput;\n const violations: Violation[] = [];\n\n // Unused files\n for (const file of result.files) {\n violations.push({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file,\n message: \"Unused file\",\n code: \"unused-file\",\n severity: \"warning\",\n });\n }\n\n // Issues per file\n for (const issue of result.issues) {\n violations.push(...this.parseFileIssues(issue));\n }\n\n return violations;\n } catch {\n return null;\n }\n }\n\n private parseFileIssues(issue: KnipFileIssue): Violation[] {\n const file = issue.file;\n return [\n ...this.mapToViolations(file, issue.dependencies, {\n prefix: \"Unused dependency\",\n code: \"unused-dependency\",\n severity: \"warning\",\n }),\n ...this.mapToViolations(file, issue.devDependencies, {\n prefix: \"Unused devDependency\",\n code: \"unused-devDependency\",\n severity: \"warning\",\n }),\n ...this.mapToViolations(file, issue.unlisted, {\n prefix: \"Unlisted dependency\",\n code: \"unlisted-dependency\",\n severity: \"error\",\n }),\n ...this.mapToViolations(file, issue.unresolved, {\n prefix: \"Unresolved import\",\n code: \"unresolved-import\",\n severity: \"error\",\n }),\n ...this.mapToViolations(file, issue.exports, {\n prefix: \"Unused export\",\n code: \"unused-export\",\n severity: \"warning\",\n }),\n ...this.mapToViolations(file, issue.types, {\n prefix: \"Unused type\",\n code: \"unused-type\",\n severity: \"warning\",\n }),\n ...this.mapToViolations(file, issue.duplicates, {\n prefix: \"Duplicate export\",\n code: \"duplicate-export\",\n severity: \"warning\",\n }),\n ];\n }\n\n private mapToViolations(\n file: string,\n items: { name: string; line?: number; col?: number }[] | undefined,\n opts: { prefix: string; code: string; severity: \"error\" | \"warning\" }\n ): Violation[] {\n return (items ?? []).map((item) => ({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file,\n line: item.line,\n column: item.col,\n message: `${opts.prefix}: ${item.name}`,\n code: opts.code,\n severity: opts.severity,\n }));\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - Knip doesn't require a config file, so just check if it can run\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Check if package.json exists (required for Knip)\n const hasPackageJson = fs.existsSync(`${projectRoot}/package.json`);\n\n if (!hasPackageJson) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"package.json not found (required for Knip)\",\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return this.pass(Date.now() - startTime);\n }\n}\n","import * as path from \"node:path\";\n\nimport { glob } from \"glob\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Supported case types */\ntype CaseType = \"kebab-case\" | \"snake_case\" | \"camelCase\" | \"PascalCase\";\n\n/** Single naming rule configuration */\ninterface NamingRule {\n extensions: string[];\n file_case: CaseType;\n folder_case: CaseType;\n exclude?: string[];\n allow_dynamic_routes?: boolean;\n}\n\n/** Configuration for naming validation */\ninterface NamingConfig {\n enabled?: boolean;\n rules?: NamingRule[];\n}\n\n/** Default directories to exclude */\nconst DEFAULT_EXCLUDE = [\n \"node_modules\",\n \".git\",\n \"dist\",\n \"build\",\n \"__pycache__\",\n \".venv\",\n \"venv\",\n \".next\",\n \".nuxt\",\n \"coverage\",\n];\n\n/**\n * Check if a string matches kebab-case (lowercase with hyphens)\n * Also allows pure numeric names like \"404\" for Next.js pages\n */\nfunction isKebabCase(str: string): boolean {\n // Allow pure numeric names (e.g., 404, 500)\n if (/^\\d+$/.test(str)) {\n return true;\n }\n return /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(str);\n}\n\n/**\n * Check if a string matches snake_case (lowercase with underscores)\n * Also allows pure numeric names like \"404\" for Next.js pages\n */\nfunction isSnakeCase(str: string): boolean {\n // Allow pure numeric names (e.g., 404, 500)\n if (/^\\d+$/.test(str)) {\n return true;\n }\n return /^[a-z][a-z0-9]*(_[a-z0-9]+)*$/.test(str);\n}\n\n/**\n * Check if a string matches camelCase (starts lowercase, no separators)\n * Also allows pure numeric names like \"404\" for Next.js pages\n */\nfunction isCamelCase(str: string): boolean {\n // Allow pure numeric names (e.g., 404, 500)\n if (/^\\d+$/.test(str)) {\n return true;\n }\n return /^[a-z][a-zA-Z0-9]*$/.test(str);\n}\n\n/**\n * Check if a string matches PascalCase (starts uppercase, no separators)\n * Also allows pure numeric names like \"404\" for Next.js pages\n */\nfunction isPascalCase(str: string): boolean {\n // Allow pure numeric names (e.g., 404, 500)\n if (/^\\d+$/.test(str)) {\n return true;\n }\n return /^[A-Z][a-zA-Z0-9]*$/.test(str);\n}\n\n/**\n * Check if a string matches the specified case type\n */\nfunction matchesCase(str: string, caseType: CaseType): boolean {\n switch (caseType) {\n case \"kebab-case\":\n return isKebabCase(str);\n case \"snake_case\":\n return isSnakeCase(str);\n case \"camelCase\":\n return isCamelCase(str);\n case \"PascalCase\":\n return isPascalCase(str);\n default: {\n const exhaustiveCheck: never = caseType;\n throw new Error(`Unknown case type: ${exhaustiveCheck}`);\n }\n }\n}\n\n/**\n * Get the base name of a file without extension\n * Handles multiple extensions like .test.ts, .spec.js\n */\nfunction getBaseName(filePath: string): string {\n const fileName = path.basename(filePath);\n // Remove all extensions (e.g., foo.test.ts -> foo)\n const parts = fileName.split(\".\");\n return parts[0];\n}\n\n/**\n * Check if a file should be skipped (special files like __init__.py)\n */\nfunction isSpecialFile(baseName: string): boolean {\n // Skip files that start with underscore (Python special files like __init__, __main__)\n if (baseName.startsWith(\"_\")) {\n return true;\n }\n return false;\n}\n\n/**\n * Dynamic route patterns for Next.js/Remix folder names.\n * Order matters: more specific patterns must come first.\n */\nconst DYNAMIC_ROUTE_PATTERNS = [\n /^\\[\\[\\.\\.\\.([^\\]]+)\\]\\]$/, // [[...slug]] - optional catch-all\n /^\\[\\.\\.\\.([^\\]]+)\\]$/, // [...slug] - catch-all\n /^\\[([^\\]]+)\\]$/, // [id] - dynamic segment\n /^\\(([^)]+)\\)$/, // (group) - route group\n];\n\n/**\n * Extract the inner content from a dynamic route folder pattern.\n * Handles Next.js/Remix patterns:\n * - [id] → \"id\"\n * - [...slug] → \"slug\"\n * - [[...slug]] → \"slug\"\n * - (group) → \"group\"\n * - @parallel → \"parallel\"\n *\n * Returns null if the folder is not a dynamic route pattern.\n */\nfunction extractDynamicRouteContent(folderName: string): string | null {\n // @parallel - parallel route (prefix pattern, not regex)\n if (folderName.startsWith(\"@\")) {\n return folderName.slice(1);\n }\n\n // Try each pattern in order\n for (const pattern of DYNAMIC_ROUTE_PATTERNS) {\n const match = pattern.exec(folderName);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n}\n\n/**\n * Naming conventions runner for checking file and folder names\n */\nexport class NamingRunner extends BaseToolRunner {\n readonly name = \"Naming\";\n readonly rule = \"code.naming\";\n readonly toolId = \"naming\";\n readonly configFiles: string[] = []; // No config file needed\n\n private config: NamingConfig = {};\n\n /**\n * Set the configuration for this runner\n */\n setConfig(config: NamingConfig): void {\n this.config = config;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n const rules = this.config.rules ?? [];\n if (rules.length === 0) {\n return this.pass(Date.now() - startTime);\n }\n\n try {\n const ruleResults = await Promise.all(rules.map((rule) => this.checkRule(projectRoot, rule)));\n const violations = ruleResults.flat();\n\n if (violations.length === 0) {\n return this.pass(Date.now() - startTime);\n }\n\n return this.fail(violations, Date.now() - startTime);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`Naming validation error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n\n /**\n * Check a single naming rule against the project\n */\n private async checkRule(projectRoot: string, rule: NamingRule): Promise<Violation[]> {\n const pattern = this.buildGlobPattern(rule.extensions);\n\n // Combine default excludes with rule-specific excludes\n const ignorePatterns = DEFAULT_EXCLUDE.map((dir) => `**/${dir}/**`);\n if (rule.exclude) {\n ignorePatterns.push(...rule.exclude);\n }\n\n const files = await glob(pattern, {\n cwd: projectRoot,\n ignore: ignorePatterns,\n nodir: true,\n });\n\n const { violations: fileViolations, folders } = this.checkFiles(files, rule);\n const folderViolations = this.checkFolders(\n folders,\n rule.folder_case,\n rule.allow_dynamic_routes\n );\n\n return [...fileViolations, ...folderViolations];\n }\n\n /**\n * Check file names and collect folders containing matching files\n */\n private checkFiles(\n files: string[],\n rule: NamingRule\n ): { violations: Violation[]; folders: Set<string> } {\n const violations: Violation[] = [];\n const folders = new Set<string>();\n\n for (const file of files) {\n const baseName = getBaseName(file);\n\n if (!baseName || isSpecialFile(baseName)) {\n continue;\n }\n\n if (!matchesCase(baseName, rule.file_case)) {\n violations.push(this.createFileViolation(file, baseName, rule.file_case));\n }\n\n const folderPath = path.dirname(file);\n if (folderPath && folderPath !== \".\") {\n folders.add(folderPath);\n }\n }\n\n return { violations, folders };\n }\n\n /**\n * Check folder names for all folders containing matching files\n */\n private checkFolders(\n foldersWithMatchingFiles: Set<string>,\n expectedCase: CaseType,\n allowDynamicRoutes?: boolean\n ): Violation[] {\n const violations: Violation[] = [];\n const checkedFolders = new Set<string>();\n\n for (const folderPath of foldersWithMatchingFiles) {\n const folderViolations = this.checkFolderPath(\n folderPath,\n expectedCase,\n checkedFolders,\n allowDynamicRoutes\n );\n violations.push(...folderViolations);\n }\n\n return violations;\n }\n\n /**\n * Get the name to validate from a folder segment, handling dynamic routes\n */\n private getNameToValidate(segment: string, allowDynamicRoutes?: boolean): string {\n if (!allowDynamicRoutes) {\n return segment;\n }\n const innerContent = extractDynamicRouteContent(segment);\n return innerContent ?? segment;\n }\n\n /**\n * Check all segments of a folder path\n */\n private checkFolderPath(\n folderPath: string,\n expectedCase: CaseType,\n checkedFolders: Set<string>,\n allowDynamicRoutes?: boolean\n ): Violation[] {\n const violations: Violation[] = [];\n const segments = folderPath.split(path.sep);\n let currentPath = \"\";\n\n for (const segment of segments) {\n currentPath = currentPath ? path.join(currentPath, segment) : segment;\n\n if (checkedFolders.has(currentPath) || DEFAULT_EXCLUDE.includes(segment)) {\n continue;\n }\n checkedFolders.add(currentPath);\n\n const nameToValidate = this.getNameToValidate(segment, allowDynamicRoutes);\n if (!matchesCase(nameToValidate, expectedCase)) {\n violations.push(this.createFolderViolation(currentPath, segment, expectedCase));\n }\n }\n\n return violations;\n }\n\n /**\n * Build a glob pattern for the given extensions\n */\n private buildGlobPattern(extensions: string[]): string {\n // Deduplicate extensions to avoid glob pattern issues\n const unique = [...new Set(extensions)];\n if (unique.length === 1) {\n return `**/*.${unique[0]}`;\n }\n return `**/*.{${unique.join(\",\")}}`;\n }\n\n private createFileViolation(file: string, baseName: string, expectedCase: CaseType): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file,\n message: `File \"${baseName}\" should be ${expectedCase}`,\n code: \"file-case\",\n severity: \"error\",\n };\n }\n\n private createFolderViolation(\n folderPath: string,\n folderName: string,\n expectedCase: CaseType\n ): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: folderPath,\n message: `Folder \"${folderName}\" should be ${expectedCase}`,\n code: \"folder-case\",\n severity: \"error\",\n };\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - for naming, we just verify the config is valid\n */\n override async audit(_projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Naming validation doesn't require external config files\n // Just verify the rules are valid\n const rules = this.config.rules ?? [];\n\n for (const rule of rules) {\n if (rule.extensions.length === 0) {\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: false,\n violations: [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"Naming rule must have at least one extension\",\n severity: \"error\",\n },\n ],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n }\n\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: true,\n violations: [],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n}\n","import * as fs from \"node:fs\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** pip-audit vulnerability entry */\ninterface PipAuditVulnerability {\n id: string;\n fix_versions: string[];\n aliases: string[];\n description: string;\n}\n\n/** pip-audit package entry */\ninterface PipAuditPackage {\n name: string;\n version: string;\n vulns: PipAuditVulnerability[];\n}\n\n/** pip-audit JSON output format */\ntype PipAuditOutput = PipAuditPackage[];\n\n/**\n * pip-audit tool runner for detecting Python dependency vulnerabilities\n */\nexport class PipAuditRunner extends BaseToolRunner {\n readonly name = \"pipaudit\";\n readonly rule = \"code.security\";\n readonly toolId = \"pipaudit\";\n readonly configFiles = [\"requirements.txt\", \"pyproject.toml\", \"setup.py\"];\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n this.projectRoot = projectRoot;\n\n if (!this.hasConfig(projectRoot)) {\n return this.failNoConfig(elapsed());\n }\n\n try {\n const result = await this.runPipAudit(projectRoot);\n return this.processResult(result, elapsed);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createErrorViolation(`pip-audit error: ${message}`)], elapsed());\n }\n }\n\n private processResult(\n result: Awaited<ReturnType<typeof execa>>,\n elapsed: () => number\n ): CheckResult {\n const output = String(result.stdout ?? result.stderr ?? \"\");\n const violations = this.parseOutput(output);\n\n if (violations === null) {\n if (result.exitCode !== 0 && result.exitCode !== 1) {\n return this.fail(\n [this.createErrorViolation(`pip-audit error: ${result.stderr ?? \"Unknown error\"}`)],\n elapsed()\n );\n }\n return this.pass(elapsed());\n }\n\n return this.fromViolations(violations, elapsed());\n }\n\n private async runPipAudit(projectRoot: string): Promise<Awaited<ReturnType<typeof execa>>> {\n // Build args - use -r requirements.txt if it exists to audit project deps, not environment\n const args = [\"pip-audit\", \"--format\", \"json\"];\n if (fs.existsSync(`${projectRoot}/requirements.txt`)) {\n args.push(\"-r\", \"requirements.txt\");\n }\n\n // Try uvx first\n try {\n return await execa(\"uvx\", args, {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n } catch {\n // Fall back to pip-audit directly (remove \"pip-audit\" from args for direct call)\n return await execa(\"pip-audit\", args.slice(1), {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n }\n }\n\n private parseOutput(output: string): Violation[] | null {\n try {\n const result = JSON.parse(output) as PipAuditOutput;\n const violations: Violation[] = [];\n\n for (const pkg of result) {\n for (const vuln of pkg.vulns) {\n const severity = this.mapSeverity(vuln);\n const fixInfo = this.getFixInfo(vuln);\n const vulnId = vuln.aliases.length > 0 ? vuln.aliases[0] : vuln.id;\n\n violations.push({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: this.findDependencyFile(pkg.name),\n message: `${pkg.name}@${pkg.version}: ${vulnId}${fixInfo}`,\n code: vuln.id,\n severity,\n });\n }\n }\n\n return violations;\n } catch {\n return null;\n }\n }\n\n private mapSeverity(vuln: PipAuditVulnerability): \"error\" | \"warning\" {\n // If a fix is available, it's an error (should be fixed)\n // If no fix available, it's a warning (awareness only)\n return vuln.fix_versions.length > 0 ? \"error\" : \"warning\";\n }\n\n private getFixInfo(vuln: PipAuditVulnerability): string {\n if (vuln.fix_versions.length === 0) {\n return \" (no fix available)\";\n }\n return ` (fix: ${vuln.fix_versions[0]})`;\n }\n\n private projectRoot = \"\";\n\n private findDependencyFile(_pkgName: string): string | undefined {\n // Check which dependency files actually exist and return the first one found\n // We can't determine which exact file contains the package without parsing,\n // so return the first existing file or undefined if none found\n const possibleFiles = [\"requirements.txt\", \"pyproject.toml\", \"setup.py\"];\n for (const file of possibleFiles) {\n if (this.projectRoot && fs.existsSync(`${this.projectRoot}/${file}`)) {\n return file;\n }\n }\n return undefined;\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - check if Python dependency files exist\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Check for any Python project file\n const hasPythonDeps =\n fs.existsSync(`${projectRoot}/requirements.txt`) ||\n fs.existsSync(`${projectRoot}/pyproject.toml`) ||\n fs.existsSync(`${projectRoot}/setup.py`);\n\n if (!hasPythonDeps) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message:\n \"No Python dependency file found (requirements.txt, pyproject.toml, or setup.py)\",\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return this.pass(Date.now() - startTime);\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** pnpm audit advisory entry */\ninterface PnpmAdvisory {\n module_name: string;\n severity: \"info\" | \"low\" | \"moderate\" | \"high\" | \"critical\";\n title: string;\n url: string;\n findings: { version: string; paths: string[] }[];\n}\n\n/** pnpm audit JSON output format */\ninterface PnpmAuditOutput {\n advisories?: Record<string, PnpmAdvisory>;\n metadata: {\n vulnerabilities: {\n info: number;\n low: number;\n moderate: number;\n high: number;\n critical: number;\n };\n };\n}\n\n/** pnpm audit configuration */\nexport interface PnpmAuditConfig {\n enabled?: boolean;\n exclude_dev?: boolean;\n}\n\n/**\n * pnpm dependency audit tool runner for detecting vulnerabilities.\n * Only checks production dependencies by default (exclude_dev: true).\n */\nexport class PnpmAuditRunner extends BaseToolRunner {\n readonly name = \"pnpmaudit\";\n readonly rule = \"code.security\";\n readonly toolId = \"pnpmaudit\";\n readonly configFiles = [\"pnpm-lock.yaml\"];\n\n private config: PnpmAuditConfig = {\n enabled: false,\n exclude_dev: true,\n };\n\n /**\n * Set configuration for the runner\n */\n setConfig(config: PnpmAuditConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Check if pnpm-lock.yaml exists\n */\n private hasLockFile(projectRoot: string): boolean {\n return fs.existsSync(path.join(projectRoot, \"pnpm-lock.yaml\"));\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!this.hasLockFile(projectRoot)) {\n return this.fail([this.createErrorViolation(\"No pnpm-lock.yaml found\")], elapsed());\n }\n\n try {\n const args = [\"audit\", \"--json\"];\n\n // Add --prod flag to exclude dev dependencies\n if (this.config.exclude_dev !== false) {\n args.push(\"--prod\");\n }\n\n const result = await execa(\"pnpm\", args, {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n return this.processAuditResult(result, elapsed);\n } catch (error) {\n return this.handleRunError(error, elapsed);\n }\n }\n\n private processAuditResult(\n result: Awaited<ReturnType<typeof execa>>,\n elapsed: () => number\n ): CheckResult {\n const output = String(result.stdout ?? result.stderr ?? \"\");\n const violations = this.parseOutput(output);\n\n if (violations === null) {\n if (result.exitCode !== 0) {\n return this.fail(\n [this.createErrorViolation(`pnpm audit error: ${result.stderr ?? \"Unknown error\"}`)],\n elapsed()\n );\n }\n return this.pass(elapsed());\n }\n\n return this.fromViolations(violations, elapsed());\n }\n\n private handleRunError(error: unknown, elapsed: () => number): CheckResult {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createErrorViolation(`pnpm audit error: ${message}`)], elapsed());\n }\n\n private parseOutput(output: string): Violation[] | null {\n try {\n const result = JSON.parse(output) as PnpmAuditOutput;\n const violations: Violation[] = [];\n\n if (!result.advisories) {\n return violations;\n }\n\n for (const [, advisory] of Object.entries(result.advisories)) {\n const severity = this.mapSeverity(advisory.severity);\n\n violations.push({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: \"pnpm-lock.yaml\",\n message: `${advisory.module_name}: ${advisory.title}`,\n code: advisory.severity,\n severity,\n });\n }\n\n return violations;\n } catch {\n return null;\n }\n }\n\n private mapSeverity(auditSeverity: string): \"error\" | \"warning\" {\n switch (auditSeverity) {\n case \"critical\":\n case \"high\":\n return \"error\";\n case \"moderate\":\n case \"low\":\n case \"info\":\n default:\n return \"warning\";\n }\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - check if pnpm-lock.yaml exists\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (!this.hasLockFile(projectRoot)) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"No pnpm-lock.yaml found\",\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return this.pass(Date.now() - startTime);\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Check if a file is a symlink */\nfunction isSymlink(filePath: string): boolean {\n try {\n const stats = fs.lstatSync(filePath);\n return stats.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\n/** Ruff JSON output message format */\ninterface RuffMessage {\n code: string;\n message: string;\n filename: string;\n location: {\n row: number;\n column: number;\n };\n}\n\n/** Ruff configuration options from standards.toml */\ninterface RuffConfig {\n enabled?: boolean;\n format?: boolean;\n \"line-length\"?: number;\n lint?: {\n select?: string[];\n ignore?: string[];\n };\n}\n\n/**\n * Ruff (Python linter) tool runner\n */\nexport class RuffRunner extends BaseToolRunner {\n readonly name = \"Ruff\";\n readonly rule = \"code.linting\";\n readonly toolId = \"ruff\";\n readonly configFiles = [\"ruff.toml\", \".ruff.toml\"];\n\n private ruffConfig: RuffConfig = {};\n\n /**\n * Set the Ruff configuration from standards.toml\n */\n setConfig(config: RuffConfig): void {\n this.ruffConfig = config;\n }\n\n /**\n * Build CLI arguments from config\n */\n private buildCliArgs(): string[] {\n const args = [\"check\", \".\", \"--output-format\", \"json\"];\n\n if (this.ruffConfig[\"line-length\"]) {\n args.push(\"--line-length\", String(this.ruffConfig[\"line-length\"]));\n }\n\n if (this.ruffConfig.lint?.select?.length) {\n args.push(\"--select\", this.ruffConfig.lint.select.join(\",\"));\n }\n\n if (this.ruffConfig.lint?.ignore?.length) {\n args.push(\"--ignore\", this.ruffConfig.lint.ignore.join(\",\"));\n }\n\n return args;\n }\n\n /**\n * Override hasConfig to also check for [tool.ruff] in pyproject.toml\n */\n protected override hasConfig(projectRoot: string): boolean {\n // Check dedicated config files\n if (super.hasConfig(projectRoot)) {\n return true;\n }\n\n // Check pyproject.toml for [tool.ruff] section\n return this.hasPyprojectConfig(projectRoot);\n }\n\n private hasPyprojectConfig(projectRoot: string): boolean {\n const pyprojectPath = path.join(projectRoot, \"pyproject.toml\");\n if (!fs.existsSync(pyprojectPath)) {\n return false;\n }\n\n try {\n const content = fs.readFileSync(pyprojectPath, \"utf-8\");\n return content.includes(\"[tool.ruff]\");\n } catch {\n return false;\n }\n }\n\n private async hasPythonFiles(projectRoot: string): Promise<boolean> {\n try {\n const result = await execa(\"find\", [\".\", \"-name\", \"*.py\", \"-type\", \"f\"], {\n cwd: projectRoot,\n reject: false,\n });\n return Boolean(result.stdout.trim());\n } catch {\n return false;\n }\n }\n\n private isBinaryNotFound(result: Awaited<ReturnType<typeof execa>>): boolean {\n const execaResult = result as Awaited<ReturnType<typeof execa>> & {\n code?: string;\n message?: string;\n };\n return (\n execaResult.code === \"ENOENT\" ||\n (execaResult.failed && String(execaResult.message ?? \"\").includes(\"ENOENT\"))\n );\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Skip if no Python files\n if (!(await this.hasPythonFiles(projectRoot))) {\n return this.skip(\"No Python files found\", Date.now() - startTime);\n }\n\n try {\n const result = await execa(\"ruff\", this.buildCliArgs(), {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n // Check if ruff binary was not found\n if (this.isBinaryNotFound(result)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n const violations = this.parseOutput(result.stdout, projectRoot);\n\n // Handle parse failure with non-zero exit\n if (violations === null && result.exitCode !== 0 && result.stderr) {\n return this.fail(\n [this.createErrorViolation(`Ruff error: ${result.stderr}`)],\n Date.now() - startTime\n );\n }\n\n return this.fromViolations(violations ?? [], Date.now() - startTime);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`Ruff error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n\n private skip(reason: string, duration: number): CheckResult {\n return {\n name: this.name,\n rule: this.rule,\n passed: true,\n violations: [],\n skipped: true,\n skipReason: reason,\n duration,\n };\n }\n\n private parseOutput(stdout: string, projectRoot: string): Violation[] | null {\n if (!stdout.trim()) {\n return [];\n }\n\n try {\n const results = JSON.parse(stdout) as RuffMessage[];\n return results\n .filter((msg) => {\n // Skip parse errors (E999) for symlinks - they may point to non-Python files\n if (msg.code === \"E999\") {\n const fullPath = path.isAbsolute(msg.filename)\n ? msg.filename\n : path.join(projectRoot, msg.filename);\n if (isSymlink(fullPath)) {\n return false;\n }\n }\n return true;\n })\n .map((msg) => ({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: path.relative(projectRoot, msg.filename),\n line: msg.location.row,\n column: msg.location.column,\n message: msg.message,\n code: msg.code,\n severity: \"error\" as const,\n }));\n } catch {\n return null;\n }\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Override audit to include pyproject.toml check\n */\n override async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (this.hasConfig(projectRoot)) {\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: true,\n violations: [],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n\n const allConfigs = [...this.configFiles, \"pyproject.toml [tool.ruff]\"];\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: false,\n violations: [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: `Ruff config not found. Expected one of: ${allConfigs.join(\", \")}`,\n severity: \"error\",\n },\n ],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { CheckResultBuilder, type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** TypeScript compiler options that can be audited */\ninterface TscRequiredOptions {\n strict?: boolean;\n noImplicitAny?: boolean;\n strictNullChecks?: boolean;\n noUnusedLocals?: boolean;\n noUnusedParameters?: boolean;\n noImplicitReturns?: boolean;\n noFallthroughCasesInSwitch?: boolean;\n esModuleInterop?: boolean;\n skipLibCheck?: boolean;\n forceConsistentCasingInFileNames?: boolean;\n}\n\n/**\n * Strip comments from JSONC content (JSON with Comments).\n * Uses regex replacement to handle single-line and multi-line comments.\n * Note: This is a simplified approach that works for typical tsconfig.json files.\n */\nfunction stripJsonComments(content: string): string {\n // Remove single-line comments (// ...) not inside strings\n // Remove multi-line comments (/* ... */)\n // This regex-based approach handles most tsconfig.json cases\n return content\n .replace(/\\\\\"|\"(?:\\\\\"|[^\"])*\"|\\/\\/[^\\n]*/g, (match) => {\n // Keep strings, remove single-line comments\n return match.startsWith(\"//\") ? \"\" : match;\n })\n .replace(/\\\\\"|\"(?:\\\\\"|[^\"])*\"|\\/\\*[\\s\\S]*?\\*\\//g, (match) => {\n // Keep strings, remove multi-line comments\n return match.startsWith(\"/*\") ? \"\" : match;\n });\n}\n\n/** Parsed tsc diagnostic */\ninterface TscDiagnostic {\n file: string;\n line: number;\n column: number;\n code: number;\n message: string;\n}\n\n/**\n * TypeScript type checker tool runner\n */\nexport class TscRunner extends BaseToolRunner {\n readonly name = \"TypeScript\";\n readonly rule = \"code.types\";\n readonly toolId = \"tsc\";\n readonly configFiles = [\"tsconfig.json\"];\n\n private requiredOptions: TscRequiredOptions = {};\n\n /**\n * Set required compiler options for audit\n */\n setRequiredOptions(options: TscRequiredOptions): void {\n this.requiredOptions = options;\n }\n\n /**\n * Strip ANSI escape codes from a string\n */\n private stripAnsi(str: string): string {\n // Use String.fromCharCode to avoid control character in regex literal\n const ESC = String.fromCharCode(27);\n const pattern = new RegExp(`${ESC}(?:[@-Z\\\\\\\\-_]|\\\\[[0-?]*[ -/]*[@-~])`, \"g\");\n return str.replace(pattern, \"\");\n }\n\n /**\n * Check if the output indicates tsc is not installed\n */\n private isTscNotFoundOutput(output: string): boolean {\n const stripped = this.stripAnsi(output);\n return (\n stripped.includes(\"This is not the tsc command you are looking for\") ||\n stripped.includes(\"command not found\") ||\n stripped.includes(\"ENOENT\")\n );\n }\n\n private handleTscFailure(\n result: Awaited<ReturnType<typeof execa>>,\n projectRoot: string\n ): Violation[] | \"not-installed\" {\n const stdout = String(result.stdout ?? \"\");\n const stderr = String(result.stderr ?? \"\");\n const combinedOutput = stdout || stderr;\n\n // Check if tsc is not installed (npx shows an error message)\n if (this.isTscNotFoundOutput(combinedOutput)) {\n return \"not-installed\";\n }\n\n const violations = this.parseOutput(stdout, projectRoot);\n if (violations.length === 0) {\n if (combinedOutput) {\n return [\n this.createErrorViolation(\n `TypeScript error: ${this.stripAnsi(combinedOutput).slice(0, 500)}`\n ),\n ];\n }\n }\n return violations;\n }\n\n private async runTsc(projectRoot: string): Promise<Awaited<ReturnType<typeof execa>>> {\n return execa(\"npx\", [\"tsc\", \"--noEmit\"], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n }\n\n private processRunResult(\n result: Awaited<ReturnType<typeof execa>>,\n projectRoot: string,\n elapsed: () => number\n ): CheckResult {\n if (result.exitCode === 0) {\n return this.pass(elapsed());\n }\n const violations = this.handleTscFailure(result, projectRoot);\n if (violations === \"not-installed\") {\n return this.skipNotInstalled(elapsed());\n }\n return this.fromViolations(violations, elapsed());\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!this.hasConfig(projectRoot)) {\n return this.failNoConfig(elapsed());\n }\n\n try {\n const result = await this.runTsc(projectRoot);\n return this.processRunResult(result, projectRoot, elapsed);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createErrorViolation(`TypeScript error: ${message}`)], elapsed());\n }\n }\n\n /**\n * Parse tsc output into diagnostics\n * Format: file(line,col): error TSxxxx: message\n */\n private parseOutput(stdout: string, projectRoot: string): Violation[] {\n const diagnostics = this.parseDiagnostics(stdout, projectRoot);\n return diagnostics.map((diag) => ({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: diag.file,\n line: diag.line,\n column: diag.column,\n message: diag.message,\n code: `TS${diag.code}`,\n severity: \"error\" as const,\n }));\n }\n\n private parseDiagnostics(output: string, projectRoot: string): TscDiagnostic[] {\n const diagnostics: TscDiagnostic[] = [];\n const lines = output.split(\"\\n\");\n const errorRegex = /^(.+?)\\((\\d+),(\\d+)\\):\\s*error\\s+TS(\\d+):\\s*(.+)$/;\n\n for (const line of lines) {\n const match = errorRegex.exec(line);\n if (match) {\n const [, filePath, lineNum, colNum, code, message] = match;\n diagnostics.push({\n file: path.relative(projectRoot, filePath),\n line: parseInt(lineNum, 10),\n column: parseInt(colNum, 10),\n code: parseInt(code, 10),\n message: message.trim(),\n });\n }\n }\n\n return diagnostics;\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit tsconfig.json - check existence and required compiler options\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n // First check if config exists\n if (!this.hasConfig(projectRoot)) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: `${this.name} config not found. Expected: ${this.configFiles.join(\", \")}`,\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n\n // If no required options, just pass\n if (Object.keys(this.requiredOptions).length === 0) {\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, elapsed());\n }\n\n // Read and parse tsconfig.json\n const configPath = path.join(projectRoot, \"tsconfig.json\");\n const violations = this.auditCompilerOptions(configPath);\n\n if (violations.length === 0) {\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, elapsed());\n }\n\n return CheckResultBuilder.fail(`${this.name} Config`, this.rule, violations, elapsed());\n }\n\n private parseConfigFile(\n configPath: string\n ): { compilerOptions?: Record<string, unknown> } | null {\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n const jsonContent = stripJsonComments(content);\n return JSON.parse(jsonContent) as { compilerOptions?: Record<string, unknown> };\n } catch {\n return null;\n }\n }\n\n private auditCompilerOptions(configPath: string): Violation[] {\n const tsconfig = this.parseConfigFile(configPath);\n if (tsconfig === null) {\n return [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n file: \"tsconfig.json\",\n message: \"Failed to parse tsconfig.json\",\n severity: \"error\",\n },\n ];\n }\n\n const compilerOptions = tsconfig.compilerOptions ?? {};\n return this.validateCompilerOptions(compilerOptions);\n }\n\n private validateCompilerOptions(compilerOptions: Record<string, unknown>): Violation[] {\n const violations: Violation[] = [];\n for (const [option, expectedValue] of Object.entries(this.requiredOptions)) {\n if (expectedValue === undefined) {\n continue;\n }\n\n const actualValue = compilerOptions[option];\n if (actualValue === undefined) {\n violations.push(this.createAuditViolation(option, expectedValue, \"missing\"));\n } else if (actualValue !== expectedValue) {\n violations.push(this.createAuditViolation(option, expectedValue, actualValue));\n }\n }\n return violations;\n }\n\n private createAuditViolation(option: string, expected: unknown, actual: unknown): Violation {\n const actualStr = actual === \"missing\" ? \"missing\" : String(actual);\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n file: \"tsconfig.json\",\n message: `${option}: expected ${String(expected)}, got ${actualStr}`,\n severity: \"error\",\n };\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Check if a file is a symlink */\nfunction isSymlink(filePath: string): boolean {\n try {\n const stats = fs.lstatSync(filePath);\n return stats.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\n/** Parsed ty diagnostic */\ninterface TyDiagnostic {\n file: string;\n line: number;\n column: number;\n code: string;\n message: string;\n severity: \"error\" | \"warning\";\n}\n\n/**\n * ty Python type checker tool runner\n * ty is Astral's extremely fast Python type checker\n */\nexport class TyRunner extends BaseToolRunner {\n readonly name = \"ty\";\n readonly rule = \"code.types\";\n readonly toolId = \"ty\";\n readonly configFiles = [\"ty.toml\"];\n\n /**\n * Override hasConfig to also check for [tool.ty] in pyproject.toml\n */\n protected override hasConfig(projectRoot: string): boolean {\n // Check for dedicated ty.toml config file\n if (super.hasConfig(projectRoot)) {\n return true;\n }\n\n // Check pyproject.toml for [tool.ty] section\n return this.hasPyprojectConfig(projectRoot);\n }\n\n private hasPyprojectConfig(projectRoot: string): boolean {\n const pyprojectPath = path.join(projectRoot, \"pyproject.toml\");\n if (!fs.existsSync(pyprojectPath)) {\n return false;\n }\n\n try {\n const content = fs.readFileSync(pyprojectPath, \"utf-8\");\n return content.includes(\"[tool.ty]\");\n } catch {\n return false;\n }\n }\n\n /**\n * Override audit to check for ty.toml or [tool.ty] in pyproject.toml\n */\n override async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (this.hasConfig(projectRoot)) {\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: true,\n violations: [],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: false,\n violations: [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"ty config not found. Expected ty.toml or [tool.ty] in pyproject.toml\",\n severity: \"error\",\n },\n ],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n try {\n const result = await execa(\"uvx\", [\"ty\", \"check\", \"--output-format\", \"concise\", \".\"], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n return this.handleExitCode(result, projectRoot, elapsed);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createErrorViolation(`ty error: ${message}`)], elapsed());\n }\n }\n\n private isBinaryNotFound(result: Awaited<ReturnType<typeof execa>>): boolean {\n const execaResult = result as Awaited<ReturnType<typeof execa>> & {\n code?: string;\n message?: string;\n };\n return (\n execaResult.code === \"ENOENT\" ||\n (execaResult.failed && String(execaResult.message ?? \"\").includes(\"ENOENT\"))\n );\n }\n\n private handleExitCode(\n result: Awaited<ReturnType<typeof execa>>,\n projectRoot: string,\n elapsed: () => number\n ): CheckResult {\n // Check if uvx/ty binary was not found\n if (this.isBinaryNotFound(result)) {\n return this.skipNotInstalled(elapsed());\n }\n\n if (result.exitCode === 0) {\n return this.pass(elapsed());\n }\n\n if (result.exitCode === 1) {\n return this.handleTypeErrors(result, projectRoot, elapsed);\n }\n\n if (result.exitCode === 2) {\n // Use trimmed string values so empty strings are falsy with ||\n const stderr = String(result.stderr ?? \"\").trim();\n const stdout = String(result.stdout ?? \"\").trim();\n const errorMessage = stderr || stdout || \"Configuration error\";\n return this.fail(\n [this.createErrorViolation(`ty configuration error: ${errorMessage.slice(0, 500)}`)],\n elapsed()\n );\n }\n\n const violations = this.handleUnexpectedFailure(result, projectRoot);\n return this.fromViolations(violations, elapsed());\n }\n\n private handleTypeErrors(\n result: Awaited<ReturnType<typeof execa>>,\n projectRoot: string,\n elapsed: () => number\n ): CheckResult {\n const violations = this.parseOutput(String(result.stdout ?? \"\"), projectRoot);\n if (violations.length === 0) {\n const errorOutput = String(result.stdout ?? result.stderr ?? \"Type check failed\");\n return this.fail(\n [this.createErrorViolation(`ty error: ${errorOutput.slice(0, 500)}`)],\n elapsed()\n );\n }\n return this.fail(violations, elapsed());\n }\n\n private handleUnexpectedFailure(\n result: Awaited<ReturnType<typeof execa>>,\n projectRoot: string\n ): Violation[] {\n const stdout = String(result.stdout ?? \"\");\n const violations = this.parseOutput(stdout, projectRoot);\n if (violations.length === 0) {\n const errorOutput = stdout || String(result.stderr ?? \"\");\n if (errorOutput) {\n return [this.createErrorViolation(`ty error: ${errorOutput.slice(0, 500)}`)];\n }\n }\n return violations;\n }\n\n /**\n * Parse ty concise output into violations\n * Format: file:line:column: severity[rule-code] message\n * Example: test.py:4:15: error[invalid-assignment] Object of type `int` is not assignable to `str`\n */\n private parseOutput(stdout: string, projectRoot: string): Violation[] {\n const diagnostics = this.parseDiagnostics(stdout, projectRoot);\n return diagnostics.map((diag) => ({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: diag.file,\n line: diag.line,\n column: diag.column,\n message: diag.message,\n code: diag.code,\n severity: diag.severity,\n }));\n }\n\n private parseDiagnostics(output: string, projectRoot: string): TyDiagnostic[] {\n const diagnostics: TyDiagnostic[] = [];\n const lines = output.split(\"\\n\");\n // Format: file:line:column: severity[rule-code] message\n const diagnosticRegex = /^(.+?):(\\d+):(\\d+):\\s*(error|warning)\\[([^\\]]+)\\]\\s*(.+)$/;\n\n for (const line of lines) {\n const match = diagnosticRegex.exec(line);\n if (match) {\n const [, filePath, lineNum, colNum, severity, code, message] = match;\n\n // Skip syntax/parse errors for symlinks - they may point to non-Python files\n if (code.includes(\"syntax\") || code.includes(\"parse\")) {\n const fullPath = path.isAbsolute(filePath) ? filePath : path.join(projectRoot, filePath);\n if (isSymlink(fullPath)) {\n continue;\n }\n }\n\n // Only apply path.relative if the path is absolute\n const normalizedPath = path.isAbsolute(filePath)\n ? path.relative(projectRoot, filePath)\n : filePath;\n diagnostics.push({\n file: normalizedPath,\n line: parseInt(lineNum, 10),\n column: parseInt(colNum, 10),\n code,\n message: message.trim(),\n severity: severity as \"error\" | \"warning\",\n });\n }\n }\n\n return diagnostics;\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/**\n * Vulture tool runner for detecting dead Python code\n */\nexport class VultureRunner extends BaseToolRunner {\n readonly name = \"Vulture\";\n readonly rule = \"code.unused\";\n readonly toolId = \"vulture\";\n readonly configFiles: string[] = []; // Vulture doesn't use config files\n\n private async hasPythonFiles(projectRoot: string): Promise<boolean> {\n try {\n const result = await execa(\"find\", [\".\", \"-name\", \"*.py\", \"-type\", \"f\"], {\n cwd: projectRoot,\n reject: false,\n });\n return Boolean(result.stdout.trim());\n } catch {\n return false;\n }\n }\n\n private isBinaryNotFound(result: Awaited<ReturnType<typeof execa>>): boolean {\n const execaResult = result as typeof result & { code?: string; message?: string };\n return (\n execaResult.code === \"ENOENT\" ||\n (execaResult.failed && String(execaResult.message ?? \"\").includes(\"ENOENT\"))\n );\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (!(await this.hasPythonFiles(projectRoot))) {\n return this.skip(\"No Python files found\", Date.now() - startTime);\n }\n\n try {\n // Exclude common virtual environment and build directories\n const excludePatterns = \".venv,venv,.git,node_modules,__pycache__,dist,build,.tox,.nox,.eggs\";\n const result = await execa(\"vulture\", [\".\", \"--exclude\", excludePatterns], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n if (this.isBinaryNotFound(result)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n // Vulture exit codes: 0=clean, 1=invalid input, 2=invalid args, 3=dead code\n if (result.exitCode === 1 || result.exitCode === 2) {\n return this.fail(\n [this.createErrorViolation(`Vulture error: ${result.stderr || result.stdout}`)],\n Date.now() - startTime\n );\n }\n\n return this.fromViolations(\n this.parseOutput(result.stdout, projectRoot),\n Date.now() - startTime\n );\n } catch (error) {\n return this.handleRunError(error, startTime);\n }\n }\n\n private handleRunError(error: unknown, startTime: number): CheckResult {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`Vulture error: ${message}`)],\n Date.now() - startTime\n );\n }\n\n private skip(reason: string, duration: number): CheckResult {\n return {\n name: this.name,\n rule: this.rule,\n passed: true,\n violations: [],\n skipped: true,\n skipReason: reason,\n duration,\n };\n }\n\n private parseOutput(stdout: string, projectRoot: string): Violation[] {\n if (!stdout.trim()) {\n return [];\n }\n\n const violations: Violation[] = [];\n const lines = stdout.trim().split(\"\\n\");\n\n for (const line of lines) {\n const violation = this.parseLine(line, projectRoot);\n if (violation) {\n violations.push(violation);\n }\n }\n\n return violations;\n }\n\n /**\n * Parse a single Vulture output line\n * Format: \"path/to/file.py:10: unused function 'my_func' (60% confidence)\"\n */\n private parseLine(line: string, projectRoot: string): Violation | null {\n // Match: file.py:line: message (confidence% confidence)\n const regex = /^(.+?):(\\d+):\\s*(.+?)\\s*\\((\\d+)%\\s*confidence\\)$/;\n const match = regex.exec(line);\n if (!match) {\n return null;\n }\n\n const [, filePath, lineNum, message, confidence] = match;\n const relPath = path.relative(projectRoot, path.resolve(projectRoot, filePath));\n\n // Determine code from message\n const code = this.getCodeFromMessage(message);\n\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: relPath,\n line: parseInt(lineNum, 10),\n message: `${message} (${confidence}% confidence)`,\n code,\n severity: \"warning\",\n };\n }\n\n private static readonly CODE_PATTERNS: [string, string][] = [\n [\"unused function\", \"unused-function\"],\n [\"unused class\", \"unused-class\"],\n [\"unused method\", \"unused-method\"],\n [\"unused variable\", \"unused-variable\"],\n [\"unused import\", \"unused-import\"],\n [\"unused attribute\", \"unused-attribute\"],\n [\"unused property\", \"unused-property\"],\n [\"unreachable code\", \"unreachable-code\"],\n ];\n\n /**\n * Extract a code identifier from the vulture message\n */\n private getCodeFromMessage(message: string): string {\n for (const [pattern, code] of VultureRunner.CODE_PATTERNS) {\n if (message.includes(pattern)) {\n return code;\n }\n }\n return \"unused-code\";\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - Vulture doesn't require a config file, so just check if Python files exist\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Check if any Python files exist\n if (!(await this.hasPythonFiles(projectRoot))) {\n return this.skip(\"No Python files found\", Date.now() - startTime);\n }\n\n // Check if pyproject.toml or setup.py exists (typical Python project)\n const hasPyproject = fs.existsSync(path.join(projectRoot, \"pyproject.toml\"));\n const hasSetupPy = fs.existsSync(path.join(projectRoot, \"setup.py\"));\n const hasRequirements = fs.existsSync(path.join(projectRoot, \"requirements.txt\"));\n\n if (!hasPyproject && !hasSetupPy && !hasRequirements) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"No Python project file found (pyproject.toml, setup.py, or requirements.txt)\",\n severity: \"warning\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return this.pass(Date.now() - startTime);\n }\n}\n","import { type Config } from \"../core/index.js\";\nimport { type CheckResult, type DomainResult, DomainResultBuilder, type IToolRunner } from \"../core/index.js\";\nimport {\n CoverageRunRunner,\n DisableCommentsRunner,\n ESLintRunner,\n GitleaksRunner,\n KnipRunner,\n NamingRunner,\n PipAuditRunner,\n PnpmAuditRunner,\n RuffRunner,\n TscRunner,\n TyRunner,\n VultureRunner,\n} from \"./tools/index.js\";\n\n// Tool runner instances (singletons for tools that don't need per-run config)\nconst knip = new KnipRunner();\nconst pipaudit = new PipAuditRunner();\nconst ty = new TyRunner();\nconst vulture = new VultureRunner();\n\n// Note: RuffRunner and TscRunner are created per-run to support config from standards.toml\n\n// Export tool runners for direct access\nexport {\n BaseToolRunner,\n ESLintRunner,\n KnipRunner,\n NamingRunner,\n RuffRunner,\n TscRunner,\n TyRunner,\n VultureRunner,\n} from \"./tools/index.js\";\n\n/** Tool configuration entry mapping config getter to runner or runner factory */\ninterface ToolEntry {\n isEnabled: (config: Config) => boolean;\n runner: IToolRunner | ((config: Config) => IToolRunner);\n}\n\n/** Check if a tool is enabled in config */\nfunction isEnabled(toolConfig: { enabled?: boolean } | undefined): boolean {\n return toolConfig?.enabled === true;\n}\n\n/** Create a configured ESLintRunner */\nfunction createEslintRunner(config: Config): ESLintRunner {\n const runner = new ESLintRunner();\n const eslintConfig = config.code?.linting?.eslint;\n if (eslintConfig) {\n runner.setConfig({\n enabled: eslintConfig.enabled,\n files: eslintConfig.files,\n ignore: eslintConfig.ignore,\n \"max-warnings\": eslintConfig[\"max-warnings\"],\n rules: eslintConfig.rules,\n });\n }\n return runner;\n}\n\n/** Create a configured CoverageRunRunner */\nfunction createCoverageRunRunner(config: Config): CoverageRunRunner {\n const runner = new CoverageRunRunner();\n const coverageConfig = config.code?.coverage_run;\n if (coverageConfig) {\n runner.setConfig({\n enabled: coverageConfig.enabled,\n min_threshold: coverageConfig.min_threshold,\n runner: coverageConfig.runner,\n command: coverageConfig.command,\n });\n }\n return runner;\n}\n\n/** Create a configured RuffRunner */\nfunction createRuffRunner(config: Config): RuffRunner {\n const runner = new RuffRunner();\n const ruffConfig = config.code?.linting?.ruff;\n if (ruffConfig) {\n runner.setConfig({\n enabled: ruffConfig.enabled,\n \"line-length\": ruffConfig[\"line-length\"],\n lint: ruffConfig.lint,\n });\n }\n return runner;\n}\n\n/** Create a configured TscRunner */\nfunction createTscRunner(config: Config): TscRunner {\n const runner = new TscRunner();\n const tscConfig = config.code?.types?.tsc;\n if (tscConfig?.require) {\n runner.setRequiredOptions(tscConfig.require);\n }\n return runner;\n}\n\n/** Create a configured NamingRunner */\nfunction createNamingRunner(config: Config): NamingRunner {\n const runner = new NamingRunner();\n const namingConfig = config.code?.naming;\n if (namingConfig) {\n runner.setConfig({\n enabled: namingConfig.enabled,\n rules: namingConfig.rules,\n });\n }\n return runner;\n}\n\n/** Create a configured DisableCommentsRunner */\nfunction createDisableCommentsRunner(config: Config): DisableCommentsRunner {\n const runner = new DisableCommentsRunner();\n const disableCommentsConfig = config.code?.quality?.[\"disable-comments\"];\n if (disableCommentsConfig) {\n runner.setConfig({\n enabled: disableCommentsConfig.enabled,\n patterns: disableCommentsConfig.patterns,\n extensions: disableCommentsConfig.extensions,\n exclude: disableCommentsConfig.exclude,\n });\n }\n return runner;\n}\n\n/** Create a configured PnpmAuditRunner */\nfunction createPnpmAuditRunner(config: Config): PnpmAuditRunner {\n const runner = new PnpmAuditRunner();\n const pnpmauditConfig = config.code?.security?.pnpmaudit;\n if (pnpmauditConfig) {\n runner.setConfig({\n enabled: pnpmauditConfig.enabled,\n exclude_dev: pnpmauditConfig.exclude_dev,\n });\n }\n return runner;\n}\n\n/** Create a configured GitleaksRunner */\nfunction createGitleaksRunner(config: Config): GitleaksRunner {\n const runner = new GitleaksRunner();\n const secretsConfig = config.code?.security?.secrets;\n if (secretsConfig) {\n runner.setConfig({\n enabled: secretsConfig.enabled,\n scan_mode: secretsConfig.scan_mode,\n base_branch: secretsConfig.base_branch,\n });\n }\n return runner;\n}\n\n/** All available tools with their config predicates */\nconst toolRegistry: ToolEntry[] = [\n { isEnabled: (c) => isEnabled(c.code?.linting?.eslint), runner: createEslintRunner },\n { isEnabled: (c) => isEnabled(c.code?.linting?.ruff), runner: createRuffRunner },\n { isEnabled: (c) => isEnabled(c.code?.types?.tsc), runner: createTscRunner },\n { isEnabled: (c) => isEnabled(c.code?.types?.ty), runner: ty },\n { isEnabled: (c) => isEnabled(c.code?.unused?.knip), runner: knip },\n { isEnabled: (c) => isEnabled(c.code?.unused?.vulture), runner: vulture },\n { isEnabled: (c) => isEnabled(c.code?.security?.secrets), runner: createGitleaksRunner },\n { isEnabled: (c) => isEnabled(c.code?.security?.pnpmaudit), runner: createPnpmAuditRunner },\n { isEnabled: (c) => isEnabled(c.code?.security?.pipaudit), runner: pipaudit },\n { isEnabled: (c) => isEnabled(c.code?.coverage_run), runner: createCoverageRunRunner },\n { isEnabled: (c) => isEnabled(c.code?.naming), runner: createNamingRunner },\n {\n isEnabled: (c) => isEnabled(c.code?.quality?.[\"disable-comments\"]),\n runner: createDisableCommentsRunner,\n },\n];\n\n/**\n * Get enabled tools based on configuration\n */\nfunction getEnabledTools(config: Config): IToolRunner[] {\n return toolRegistry\n .filter((entry) => entry.isEnabled(config))\n .map((entry) => (typeof entry.runner === \"function\" ? entry.runner(config) : entry.runner));\n}\n\n/**\n * Run all code checks based on configuration\n */\nexport async function runCodeChecks(projectRoot: string, config: Config): Promise<DomainResult> {\n const tools = getEnabledTools(config);\n const checks = await runTools(tools, projectRoot, \"run\");\n return DomainResultBuilder.fromChecks(\"code\", checks);\n}\n\n/**\n * Audit code configuration (check that configs exist without running tools)\n */\nexport async function auditCodeConfig(projectRoot: string, config: Config): Promise<DomainResult> {\n const tools = getEnabledTools(config);\n const checks = await runTools(tools, projectRoot, \"audit\");\n return DomainResultBuilder.fromChecks(\"code\", checks);\n}\n\n/**\n * Run tools in parallel with error isolation\n * Uses Promise.allSettled to ensure one failing tool doesn't lose all results\n */\nasync function runTools(\n tools: IToolRunner[],\n projectRoot: string,\n mode: \"run\" | \"audit\"\n): Promise<CheckResult[]> {\n const promises = tools.map((tool) =>\n mode === \"run\" ? tool.run(projectRoot) : tool.audit(projectRoot)\n );\n\n const results = await Promise.allSettled(promises);\n\n return results.map((result, index) => {\n if (result.status === \"fulfilled\") {\n return result.value;\n }\n\n // Handle rejected promise - create error result for the tool\n const tool = tools[index];\n const errorMessage = result.reason instanceof Error ? result.reason.message : \"Unknown error\";\n\n return {\n name: tool.name,\n rule: tool.rule,\n passed: false,\n violations: [\n {\n rule: tool.rule,\n tool: tool.toolId,\n message: `Tool error: ${errorMessage}`,\n severity: \"error\" as const,\n },\n ],\n skipped: false,\n duration: 0,\n };\n });\n}\n","import { type _Object, ListObjectsV2Command, S3Client } from \"@aws-sdk/client-s3\";\n\nimport { AWS_DEFAULTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Backups configuration */\ninterface BackupsConfig {\n enabled?: boolean;\n bucket?: string;\n prefix?: string;\n max_age_hours?: number;\n region?: string;\n}\n\n/**\n * Runner for S3 backup verification.\n * Checks that backups exist in S3 and are recent.\n */\nexport class BackupsRunner extends BaseProcessToolRunner {\n readonly name = \"Backups\";\n readonly rule = \"process.backups\";\n readonly toolId = \"backups\";\n\n private config: BackupsConfig = { enabled: false };\n private s3Client: S3Client | null = null;\n\n setConfig(config: BackupsConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Allow injecting S3 client for testing */\n setS3Client(client: S3Client): void {\n this.s3Client = client;\n }\n\n async run(_projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!this.config.bucket) {\n return this.skip(\"No bucket configured\", elapsed());\n }\n\n try {\n const violations = await this.checkBackups();\n return this.fromViolations(violations, elapsed());\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return this.skip(`S3 error: ${message}`, elapsed());\n }\n }\n\n private async checkBackups(): Promise<Violation[]> {\n const client = this.getS3Client();\n const response = await client.send(\n new ListObjectsV2Command({\n Bucket: this.config.bucket,\n Prefix: this.config.prefix,\n })\n );\n\n if (!response.Contents || response.Contents.length === 0) {\n return [this.createExistsViolation()];\n }\n\n return this.checkBackupRecency(response.Contents);\n }\n\n private getS3Client(): S3Client {\n return (\n this.s3Client ??\n new S3Client({\n region: this.config.region ?? process.env.AWS_REGION ?? AWS_DEFAULTS.globalRegion,\n })\n );\n }\n\n private createExistsViolation(): Violation {\n return {\n rule: `${this.rule}.exists`,\n tool: this.toolId,\n message: `No backups found at s3://${this.config.bucket}/${this.config.prefix ?? \"\"}`,\n severity: \"error\",\n };\n }\n\n private checkBackupRecency(contents: _Object[]): Violation[] {\n const mostRecent = this.findMostRecentBackup(contents);\n\n if (!mostRecent?.LastModified) {\n return [\n {\n rule: `${this.rule}.recency`,\n tool: this.toolId,\n message: \"Could not determine backup age\",\n severity: \"error\",\n },\n ];\n }\n\n const maxAgeHours = this.config.max_age_hours ?? 24;\n const ageHours = (Date.now() - mostRecent.LastModified.getTime()) / (1000 * 60 * 60);\n\n if (ageHours > maxAgeHours) {\n return [\n {\n rule: `${this.rule}.recency`,\n tool: this.toolId,\n message: `Backup is ${Math.round(ageHours)} hours old (max: ${maxAgeHours} hours)`,\n severity: \"error\",\n file: mostRecent.Key,\n },\n ];\n }\n\n return [];\n }\n\n private findMostRecentBackup(contents: _Object[]): _Object | undefined {\n const withDates = contents.filter(\n (obj): obj is _Object & { LastModified: Date } => obj.LastModified !== undefined\n );\n return withDates.sort((a, b) => b.LastModified.getTime() - a.LastModified.getTime())[0];\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { CheckResultBuilder, type CheckResult, type IToolRunner, type Violation } from \"../../core/index.js\";\n\n/**\n * Abstract base class for process tool runners.\n * Provides common functionality for checking files and directories.\n */\nexport abstract class BaseProcessToolRunner implements IToolRunner {\n abstract readonly name: string;\n abstract readonly rule: string;\n abstract readonly toolId: string;\n /** Process tools don't have config files in the same way code tools do */\n readonly configFiles: string[] = [];\n\n /**\n * Check if a directory exists\n */\n protected directoryExists(projectRoot: string, dirPath: string): boolean {\n const fullPath = path.join(projectRoot, dirPath);\n return fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory();\n }\n\n /**\n * Check if a file exists\n */\n protected fileExists(projectRoot: string, filePath: string): boolean {\n const fullPath = path.join(projectRoot, filePath);\n return fs.existsSync(fullPath) && fs.statSync(fullPath).isFile();\n }\n\n /**\n * Read file contents\n */\n protected readFile(projectRoot: string, filePath: string): string | null {\n const fullPath = path.join(projectRoot, filePath);\n try {\n return fs.readFileSync(fullPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n /**\n * Check if a file contains a specific string/pattern\n */\n protected fileContains(projectRoot: string, filePath: string, pattern: string): boolean {\n const content = this.readFile(projectRoot, filePath);\n if (content === null) {\n return false;\n }\n return content.includes(pattern);\n }\n\n /**\n * Create a pass result\n */\n protected pass(duration: number): CheckResult {\n return CheckResultBuilder.pass(this.name, this.rule, duration);\n }\n\n /**\n * Create a fail result from violations\n */\n protected fail(violations: Violation[], duration: number): CheckResult {\n return CheckResultBuilder.fail(this.name, this.rule, violations, duration);\n }\n\n /**\n * Create a result from violations (pass if empty, fail otherwise)\n */\n protected fromViolations(violations: Violation[], duration: number): CheckResult {\n return CheckResultBuilder.fromViolations(this.name, this.rule, violations, duration);\n }\n\n /**\n * Create a skip result\n */\n protected skip(reason: string, duration: number): CheckResult {\n return CheckResultBuilder.skip(this.name, this.rule, reason, duration);\n }\n\n /**\n * Run the tool - must be implemented by subclasses\n */\n abstract run(projectRoot: string): Promise<CheckResult>;\n\n /**\n * Audit the tool - by default same as run for process tools\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n return this.run(projectRoot);\n }\n}\n","import { execa } from \"execa\";\n\nimport { type CheckResult } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Branches configuration from standards.toml */\ninterface BranchesConfig {\n enabled?: boolean;\n pattern?: string;\n exclude?: string[];\n require_issue?: boolean;\n issue_pattern?: string;\n}\n\n/** Default pattern to extract issue number from branch name */\nconst DEFAULT_ISSUE_PATTERN = \"^(?:feature|fix|hotfix|docs)/([0-9]+)/.*$\";\n\n/**\n * Branch naming validation runner.\n * Checks that the current git branch name matches a required pattern.\n */\nexport class BranchesRunner extends BaseProcessToolRunner {\n readonly name = \"Branches\";\n readonly rule = \"process.branches\";\n readonly toolId = \"branches\";\n\n private config: BranchesConfig = {\n enabled: false,\n require_issue: false,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: BranchesConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Get the current git branch name */\n private async getCurrentBranch(projectRoot: string): Promise<string | null> {\n try {\n const result = await execa(\"git\", [\"branch\", \"--show-current\"], {\n cwd: projectRoot,\n });\n return result.stdout.trim() || null;\n } catch {\n return null;\n }\n }\n\n /** Check if branch is excluded from validation */\n private isExcluded(branch: string): boolean {\n const excludeList = this.config.exclude ?? [];\n return excludeList.includes(branch);\n }\n\n /** Validate branch name against pattern */\n private validateBranchPattern(branch: string): { passed: boolean; error?: string } {\n const pattern = this.config.pattern;\n if (!pattern) {\n return { passed: true }; // No pattern = no validation\n }\n\n try {\n const regex = new RegExp(pattern);\n if (regex.test(branch)) {\n return { passed: true };\n }\n return {\n passed: false,\n error: `Branch '${branch}' does not match pattern: ${pattern}`,\n };\n } catch {\n return {\n passed: false,\n error: `Invalid regex pattern: ${pattern}`,\n };\n }\n }\n\n /** Extract issue number from branch name */\n private extractIssueNumber(branch: string): string | null {\n const pattern = this.config.issue_pattern ?? DEFAULT_ISSUE_PATTERN;\n try {\n const regex = new RegExp(pattern);\n const match = branch.match(regex);\n return match?.[1] ?? null;\n } catch {\n return null;\n }\n }\n\n /** Validate that branch contains issue reference */\n private validateIssueReference(branch: string): { passed: boolean; error?: string } {\n if (!this.config.require_issue) {\n return { passed: true };\n }\n\n const issueNumber = this.extractIssueNumber(branch);\n if (issueNumber) {\n return { passed: true };\n }\n\n const pattern = this.config.issue_pattern ?? DEFAULT_ISSUE_PATTERN;\n return {\n passed: false,\n error: `Branch '${branch}' does not contain issue number. Expected format matching: ${pattern} (e.g., feature/123/description)`,\n };\n }\n\n /** Check if any validation is configured */\n private hasValidationConfigured(): boolean {\n return this.config.pattern !== undefined || this.config.require_issue === true;\n }\n\n /** Collect violations from all validations */\n private collectViolations(\n branch: string\n ): { rule: string; tool: string; message: string; severity: \"error\" | \"warning\" }[] {\n const violations: {\n rule: string;\n tool: string;\n message: string;\n severity: \"error\" | \"warning\";\n }[] = [];\n\n const patternResult = this.validateBranchPattern(branch);\n if (!patternResult.passed && patternResult.error) {\n violations.push({\n rule: `${this.rule}.pattern`,\n tool: this.toolId,\n message: patternResult.error,\n severity: \"error\",\n });\n }\n\n const issueResult = this.validateIssueReference(branch);\n if (!issueResult.passed && issueResult.error) {\n violations.push({\n rule: `${this.rule}.require_issue`,\n tool: this.toolId,\n message: issueResult.error,\n severity: \"error\",\n });\n }\n\n return violations;\n }\n\n /** Run branch naming validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!this.hasValidationConfigured()) {\n return this.skip(\"No branch pattern or issue requirement configured\", elapsed());\n }\n\n const branch = await this.getCurrentBranch(projectRoot);\n if (!branch) {\n return this.skip(\"Not in a git repository or no branch checked out\", elapsed());\n }\n\n if (this.isExcluded(branch)) {\n return this.pass(elapsed());\n }\n\n const violations = this.collectViolations(branch);\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\nimport { minimatch } from \"minimatch\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Valid changeset bump types */\ntype BumpType = \"patch\" | \"minor\" | \"major\";\n\n/** Changesets configuration from standards.toml */\ninterface ChangesetsConfig {\n enabled?: boolean;\n require_for_paths?: string[];\n exclude_paths?: string[];\n validate_format?: boolean;\n allowed_bump_types?: BumpType[];\n require_description?: boolean;\n min_description_length?: number;\n}\n\n/** Parsed changeset file */\ninterface ParsedChangeset {\n filePath: string;\n packages: Map<string, BumpType>;\n description: string;\n parseError?: string;\n}\n\n/** Find frontmatter boundaries in content lines */\nfunction findFrontmatterBounds(lines: string[]): { start: number; end: number } {\n let start = -1;\n let end = -1;\n\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].trim() === \"---\") {\n if (start === -1) {\n start = i;\n } else {\n end = i;\n break;\n }\n }\n }\n\n return { start, end };\n}\n\n/** Parse frontmatter lines to extract packages and bump types */\nfunction parseFrontmatterPackages(\n lines: string[],\n start: number,\n end: number\n): Map<string, BumpType> {\n const packages = new Map<string, BumpType>();\n\n for (let i = start + 1; i < end; i++) {\n const line = lines[i].trim();\n if (!line) {\n continue;\n }\n\n // Match: \"package-name\": bump-type\n const match = /^[\"']([^\"']+)[\"']:\\s*(patch|minor|major)\\s*$/.exec(line);\n if (match) {\n packages.set(match[1], match[2] as BumpType);\n }\n }\n\n return packages;\n}\n\n/** Check if a git branch exists */\nasync function branchExists(projectRoot: string, branch: string): Promise<boolean> {\n try {\n await execa(\"git\", [\"rev-parse\", \"--verify\", branch], { cwd: projectRoot });\n return true;\n } catch {\n return false;\n }\n}\n\n/** Try to find the base branch (main or master) */\nasync function findBaseBranch(projectRoot: string): Promise<string | null> {\n const branches = [\"origin/main\", \"origin/master\", \"main\", \"master\"];\n\n // Check branches in parallel to avoid await-in-loop\n const results = await Promise.all(branches.map((b) => branchExists(projectRoot, b)));\n const index = results.findIndex(Boolean);\n\n if (index === -1) {\n return null;\n }\n\n return branches[index].replace(\"origin/\", \"\");\n}\n\n/**\n * Changeset validation runner.\n * Validates that changeset files exist and are properly formatted.\n */\nexport class ChangesetsRunner extends BaseProcessToolRunner {\n readonly name = \"Changesets\";\n readonly rule = \"process.changesets\";\n readonly toolId = \"changesets\";\n\n private config: ChangesetsConfig = {\n enabled: false,\n validate_format: true,\n require_description: true,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: ChangesetsConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Get list of changeset files (excluding config.json) */\n private getChangesetFiles(projectRoot: string): string[] {\n const changesetDir = path.join(projectRoot, \".changeset\");\n\n if (!fs.existsSync(changesetDir)) {\n return [];\n }\n\n try {\n const files = fs.readdirSync(changesetDir);\n return files\n .filter((f) => f.endsWith(\".md\") && f !== \"README.md\")\n .map((f) => path.join(\".changeset\", f));\n } catch {\n return [];\n }\n }\n\n /** Parse a changeset file and extract frontmatter and description */\n private parseChangesetFile(projectRoot: string, filePath: string): ParsedChangeset {\n const fullPath = path.join(projectRoot, filePath);\n const result: ParsedChangeset = { filePath, packages: new Map(), description: \"\" };\n\n try {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n return this.parseChangesetContent(content, result);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n result.parseError = `Failed to read file: ${msg}`;\n return result;\n }\n }\n\n /** Parse changeset content and populate result */\n private parseChangesetContent(content: string, result: ParsedChangeset): ParsedChangeset {\n const lines = content.split(\"\\n\");\n const { start, end } = findFrontmatterBounds(lines);\n\n if (start === -1) {\n result.parseError = \"Missing frontmatter: no opening '---' delimiter found\";\n return result;\n }\n if (end === -1) {\n result.parseError =\n \"Invalid frontmatter: opening '---' found but missing closing '---' delimiter\";\n return result;\n }\n\n result.packages = parseFrontmatterPackages(lines, start, end);\n result.description = lines\n .slice(end + 1)\n .join(\"\\n\")\n .trim();\n return result;\n }\n\n /** Get files changed in current branch vs main/master */\n private async getChangedFiles(projectRoot: string): Promise<string[] | null> {\n const baseBranch = await findBaseBranch(projectRoot);\n if (!baseBranch) {\n return null;\n }\n\n try {\n const result = await execa(\"git\", [\"diff\", \"--name-only\", `${baseBranch}...HEAD`], {\n cwd: projectRoot,\n });\n return result.stdout.trim().split(\"\\n\").filter(Boolean);\n } catch {\n return null;\n }\n }\n\n /** Check if any changed files match the require_for_paths patterns */\n private hasChangesRequiringChangeset(changedFiles: string[]): boolean {\n const requirePaths = this.config.require_for_paths;\n const excludePaths = this.config.exclude_paths ?? [];\n\n if (!requirePaths || requirePaths.length === 0) {\n return false;\n }\n\n return changedFiles.some((file) => {\n const isExcluded = excludePaths.some((pattern) => minimatch(file, pattern));\n if (isExcluded) {\n return false;\n }\n return requirePaths.some((pattern) => minimatch(file, pattern));\n });\n }\n\n /** Validate changeset format (packages in frontmatter) */\n private validateFormat(changeset: ParsedChangeset): Violation[] {\n const violations: Violation[] = [];\n\n if (changeset.packages.size === 0) {\n violations.push({\n rule: `${this.rule}.format`,\n tool: this.toolId,\n message: \"Changeset has no package entries in frontmatter\",\n severity: \"error\",\n file: changeset.filePath,\n });\n }\n\n return violations;\n }\n\n /** Validate bump types against allowed list */\n private validateBumpTypes(changeset: ParsedChangeset): Violation[] {\n const violations: Violation[] = [];\n const allowed = this.config.allowed_bump_types;\n\n if (!allowed || allowed.length === 0) {\n return violations;\n }\n\n for (const [pkg, bumpType] of changeset.packages) {\n if (!allowed.includes(bumpType)) {\n violations.push({\n rule: `${this.rule}.bump_type`,\n tool: this.toolId,\n message: `Package \"${pkg}\" has bump type \"${bumpType}\" but only ${allowed.join(\", \")} are allowed`,\n severity: \"error\",\n file: changeset.filePath,\n });\n }\n }\n\n return violations;\n }\n\n /** Validate description requirements */\n private validateDescription(changeset: ParsedChangeset): Violation[] {\n const violations: Violation[] = [];\n\n if (this.config.require_description === false) {\n return violations;\n }\n\n if (!changeset.description) {\n violations.push({\n rule: `${this.rule}.description`,\n tool: this.toolId,\n message: \"Changeset has no description\",\n severity: \"error\",\n file: changeset.filePath,\n });\n return violations;\n }\n\n const minLen = this.config.min_description_length;\n if (minLen && changeset.description.length < minLen) {\n violations.push({\n rule: `${this.rule}.description`,\n tool: this.toolId,\n message: `Changeset description is ${changeset.description.length} characters, minimum is ${minLen}`,\n severity: \"error\",\n file: changeset.filePath,\n });\n }\n\n return violations;\n }\n\n /** Validate a single changeset file */\n private validateChangeset(changeset: ParsedChangeset): Violation[] {\n if (changeset.parseError) {\n return [\n {\n rule: `${this.rule}.format`,\n tool: this.toolId,\n message: `Invalid changeset format: ${changeset.parseError}`,\n severity: \"error\",\n file: changeset.filePath,\n },\n ];\n }\n\n const violations: Violation[] = [];\n\n if (this.config.validate_format !== false) {\n violations.push(...this.validateFormat(changeset));\n violations.push(...this.validateBumpTypes(changeset));\n }\n\n violations.push(...this.validateDescription(changeset));\n\n return violations;\n }\n\n /** Check if changeset directory exists */\n private checkDirectoryExists(projectRoot: string, elapsed: () => number): CheckResult | null {\n if (!this.directoryExists(projectRoot, \".changeset\")) {\n return this.fromViolations(\n [\n {\n rule: `${this.rule}.directory`,\n tool: this.toolId,\n message: \"No .changeset directory found. Run 'pnpm exec changeset init' to initialize.\",\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n return null;\n }\n\n /** Check if changes require a changeset */\n private async checkChangesRequireChangeset(\n projectRoot: string,\n changesetFiles: string[],\n _elapsed: () => number\n ): Promise<{ skip?: string; violations: Violation[] }> {\n const requirePaths = this.config.require_for_paths;\n\n if (!requirePaths || requirePaths.length === 0) {\n return { violations: [] };\n }\n\n const changedFiles = await this.getChangedFiles(projectRoot);\n\n if (changedFiles === null) {\n return {\n skip: \"Could not determine changed files (not on a branch or no base branch found)\",\n violations: [],\n };\n }\n\n const violations: Violation[] = [];\n\n if (this.hasChangesRequiringChangeset(changedFiles) && changesetFiles.length === 0) {\n violations.push({\n rule: `${this.rule}.required`,\n tool: this.toolId,\n message: `Changes to files matching ${requirePaths.join(\", \")} require a changeset. Run 'pnpm exec changeset' to create one.`,\n severity: \"error\",\n });\n }\n\n return { violations };\n }\n\n /** Run changeset validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n // Check directory exists\n const dirCheck = this.checkDirectoryExists(projectRoot, elapsed);\n if (dirCheck) {\n return dirCheck;\n }\n\n // Get changeset files\n const changesetFiles = this.getChangesetFiles(projectRoot);\n\n // Check if changes require changeset\n const { skip, violations } = await this.checkChangesRequireChangeset(\n projectRoot,\n changesetFiles,\n elapsed\n );\n if (skip) {\n return this.skip(skip, elapsed());\n }\n\n // Validate each changeset file\n for (const file of changesetFiles) {\n const parsed = this.parseChangesetFile(projectRoot, file);\n violations.push(...this.validateChangeset(parsed));\n }\n\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n}\n","/* eslint-disable max-lines -- CI workflow validation requires comprehensive coverage of jobs, actions, and commands */\nimport * as yaml from \"js-yaml\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Commands configuration value - workflow-level or job-level */\ntype CommandsValue = string[] | Record<string, string[]>;\n\n/** CI configuration from standards.toml */\ninterface CiConfig {\n enabled?: boolean;\n require_workflows?: string[];\n jobs?: Record<string, string[]>;\n actions?: Record<string, string[]>;\n commands?: Record<string, CommandsValue>;\n}\n\n/** Parsed GitHub Actions workflow structure */\ninterface WorkflowFile {\n on?: WorkflowTriggers;\n jobs?: Record<string, WorkflowJob>;\n}\n\n/** Workflow triggers - can be string, array, or object */\ntype WorkflowTriggers =\n | string\n | string[]\n | {\n pull_request?: TriggerConfig;\n pull_request_target?: TriggerConfig;\n push?: TriggerConfig;\n [key: string]: unknown;\n };\n\ninterface TriggerConfig {\n branches?: string[];\n}\n\ninterface WorkflowJob {\n if?: string | boolean; // GitHub Actions allows boolean literals\n steps?: WorkflowStep[];\n uses?: string; // Reusable workflow reference\n}\n\ninterface WorkflowStep {\n if?: string | boolean; // GitHub Actions allows boolean literals\n run?: string;\n uses?: string;\n}\n\n/** Result of searching for a command in a workflow */\ninterface CommandSearchResult {\n found: boolean;\n conditional: boolean;\n conditionExpression?: string | boolean;\n commentedOut: boolean;\n}\n\n/**\n * CI/CD workflow validation runner.\n * Checks that GitHub Actions workflows exist and contain required jobs/actions/commands.\n */\nexport class CiRunner extends BaseProcessToolRunner {\n readonly name = \"CI\";\n readonly rule = \"process.ci\";\n readonly toolId = \"ci\";\n\n private config: CiConfig = {\n enabled: false,\n };\n\n setConfig(config: CiConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n private checkWorkflowsDirectory(projectRoot: string): Violation | null {\n if (this.directoryExists(projectRoot, \".github/workflows\")) {\n return null;\n }\n return {\n rule: `${this.rule}.directory`,\n tool: this.toolId,\n message: \"GitHub workflows directory not found (.github/workflows/)\",\n severity: \"error\",\n };\n }\n\n private checkRequiredWorkflows(projectRoot: string): Violation[] {\n const workflows = this.config.require_workflows ?? [];\n return workflows\n .filter((workflow) => !this.fileExists(projectRoot, `.github/workflows/${workflow}`))\n .map((workflow) => ({\n rule: `${this.rule}.workflow`,\n tool: this.toolId,\n file: `.github/workflows/${workflow}`,\n message: `Required workflow '${workflow}' not found`,\n severity: \"error\" as const,\n }));\n }\n\n private parseWorkflow(\n projectRoot: string,\n workflowFile: string\n ): { workflow: WorkflowFile | null; parseError?: string } {\n const content = this.readFile(projectRoot, `.github/workflows/${workflowFile}`);\n if (content === null) {\n return { workflow: null };\n }\n try {\n return { workflow: yaml.load(content) as WorkflowFile };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown YAML parse error\";\n return { workflow: null, parseError: message };\n }\n }\n\n private triggersPRToMain(workflow: WorkflowFile): boolean {\n const triggers = workflow.on;\n if (!triggers) {\n return false;\n }\n\n if (typeof triggers === \"string\") {\n return [\"pull_request\", \"pull_request_target\", \"push\"].includes(triggers);\n }\n\n if (Array.isArray(triggers)) {\n return triggers.some((t) => [\"pull_request\", \"pull_request_target\", \"push\"].includes(t));\n }\n\n const checkBranches = (config: TriggerConfig | undefined): boolean => {\n if (!config) {\n return false;\n }\n const branches = config.branches;\n if (!branches || branches.length === 0) {\n return true;\n }\n return branches.some((b) => [\"main\", \"master\", \"*\"].includes(b));\n };\n\n return (\n checkBranches(triggers.pull_request as TriggerConfig) ||\n checkBranches(triggers.pull_request_target as TriggerConfig) ||\n checkBranches(triggers.push as TriggerConfig)\n );\n }\n\n private isUnconditionalExpression(expression: string | boolean | undefined): boolean {\n if (expression === undefined) {\n return true;\n }\n // Handle boolean values (YAML parses `if: true` as boolean)\n if (typeof expression === \"boolean\") {\n return expression;\n }\n const expr = String(expression).trim().toLowerCase();\n return [\"true\", \"success()\", \"always()\"].includes(expr);\n }\n\n private extractRunCommands(runContent: string): string[] {\n return runContent\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line && !line.startsWith(\"#\"));\n }\n\n private commandMatches(actual: string, required: string): boolean {\n return actual.includes(required);\n }\n\n /** Check if run content has a commented version of the command */\n private hasCommentedCommand(runContent: string, command: string): boolean {\n return runContent\n .split(\"\\n\")\n .some((line) => line.trim().startsWith(\"#\") && this.commandMatches(line, command));\n }\n\n /** Search for a command in a single step */\n private searchCommandInStep(\n step: WorkflowStep,\n requiredCommand: string,\n jobConditional: boolean,\n jobCondition: string | boolean | undefined\n ): CommandSearchResult | null {\n if (!step.run) {\n return null;\n }\n\n const commentedOut = this.hasCommentedCommand(step.run, requiredCommand);\n const commands = this.extractRunCommands(step.run);\n const found = commands.some((cmd) => this.commandMatches(cmd, requiredCommand));\n\n if (!found) {\n return commentedOut ? { found: false, conditional: false, commentedOut: true } : null;\n }\n\n const stepConditional = !this.isUnconditionalExpression(step.if);\n const conditional = jobConditional || stepConditional;\n const conditionExpression = jobConditional ? jobCondition : step.if;\n\n return { found: true, conditional, conditionExpression, commentedOut };\n }\n\n private searchCommandInJob(job: WorkflowJob, requiredCommand: string): CommandSearchResult {\n const jobConditional = !this.isUnconditionalExpression(job.if);\n let commentedOut = false;\n\n for (const step of job.steps ?? []) {\n const result = this.searchCommandInStep(step, requiredCommand, jobConditional, job.if);\n if (result?.commentedOut) {\n commentedOut = true;\n }\n if (result?.found) {\n return result;\n }\n }\n\n return { found: false, conditional: false, commentedOut };\n }\n\n private searchCommandInWorkflow(\n workflow: WorkflowFile,\n requiredCommand: string\n ): CommandSearchResult {\n let commentedOut = false;\n let conditionalResult: CommandSearchResult | null = null;\n\n for (const job of Object.values(workflow.jobs ?? {})) {\n if (job.uses) {\n continue;\n }\n const result = this.searchCommandInJob(job, requiredCommand);\n if (result.commentedOut) {\n commentedOut = true;\n }\n if (result.found && !result.conditional) {\n return result;\n }\n if (result.found && !conditionalResult) {\n conditionalResult = result;\n }\n }\n return conditionalResult ?? { found: false, conditional: false, commentedOut };\n }\n\n private cmdViolation(workflowFile: string, msg: string): Violation {\n return {\n rule: `${this.rule}.commands`,\n tool: this.toolId,\n file: `.github/workflows/${workflowFile}`,\n message: msg,\n severity: \"error\",\n };\n }\n\n private workflowCmdViolation(wf: string, cmd: string, r: CommandSearchResult): Violation | null {\n if (!r.found && r.commentedOut) {\n return this.cmdViolation(wf, `Command '${cmd}' appears commented out in workflow '${wf}'`);\n }\n if (!r.found) {\n return this.cmdViolation(wf, `Required command '${cmd}' not found in workflow '${wf}'`);\n }\n if (r.conditional) {\n return this.cmdViolation(\n wf,\n `Command '${cmd}' in workflow '${wf}' may not execute on PRs (has condition: ${r.conditionExpression})`\n );\n }\n return null;\n }\n\n private jobCmdViolation(\n wf: string,\n jobId: string,\n cmd: string,\n r: CommandSearchResult\n ): Violation | null {\n if (!r.found && r.commentedOut) {\n return this.cmdViolation(\n wf,\n `Command '${cmd}' appears commented out in job '${jobId}' of workflow '${wf}'`\n );\n }\n if (!r.found) {\n return this.cmdViolation(\n wf,\n `Required command '${cmd}' not found in job '${jobId}' of workflow '${wf}'`\n );\n }\n if (r.conditional) {\n return this.cmdViolation(\n wf,\n `Command '${cmd}' in job '${jobId}' of workflow '${wf}' may not execute on PRs (has condition: ${r.conditionExpression})`\n );\n }\n return null;\n }\n\n private checkWorkflowLevelCommands(\n workflow: WorkflowFile,\n wf: string,\n commands: string[]\n ): Violation[] {\n return commands\n .map((cmd) => this.workflowCmdViolation(wf, cmd, this.searchCommandInWorkflow(workflow, cmd)))\n .filter((v): v is Violation => v !== null);\n }\n\n private checkJobLevelCommands(\n workflow: WorkflowFile,\n wf: string,\n jobCommands: Record<string, string[]>\n ): Violation[] {\n const violations: Violation[] = [];\n for (const [jobId, commands] of Object.entries(jobCommands)) {\n const job = workflow.jobs?.[jobId];\n if (!job) {\n violations.push(this.cmdViolation(wf, `Job '${jobId}' not found in workflow '${wf}'`));\n continue;\n }\n if (job.uses) {\n violations.push(\n this.cmdViolation(\n wf,\n `Job '${jobId}' in workflow '${wf}' uses a reusable workflow - command validation not supported`\n )\n );\n continue;\n }\n for (const cmd of commands) {\n const v = this.jobCmdViolation(wf, jobId, cmd, this.searchCommandInJob(job, cmd));\n if (v) {\n violations.push(v);\n }\n }\n }\n return violations;\n }\n\n private yamlErrorViolation(wf: string, parseError: string): Violation {\n return {\n rule: `${this.rule}.yaml`,\n tool: this.toolId,\n file: `.github/workflows/${wf}`,\n message: `Invalid YAML in workflow '${wf}': ${parseError}`,\n severity: \"error\",\n };\n }\n\n private checkWorkflowCommands(projectRoot: string): Violation[] {\n const violations: Violation[] = [];\n for (const [wf, commandsValue] of Object.entries(this.config.commands ?? {})) {\n const { workflow, parseError } = this.parseWorkflow(projectRoot, wf);\n if (parseError) {\n violations.push(this.yamlErrorViolation(wf, parseError));\n continue;\n }\n if (!workflow) {\n violations.push({\n rule: `${this.rule}.commands`,\n tool: this.toolId,\n file: `.github/workflows/${wf}`,\n message: `Workflow file '${wf}' not found`,\n severity: \"error\",\n });\n continue;\n }\n if (!this.triggersPRToMain(workflow)) {\n violations.push(\n this.cmdViolation(wf, `Workflow '${wf}' does not trigger on pull_request to main/master`)\n );\n continue;\n }\n violations.push(\n ...(Array.isArray(commandsValue)\n ? this.checkWorkflowLevelCommands(workflow, wf, commandsValue)\n : this.checkJobLevelCommands(workflow, wf, commandsValue))\n );\n }\n return violations;\n }\n\n private checkRequiredJobs(projectRoot: string): Violation[] {\n const violations: Violation[] = [];\n for (const [workflowFile, requiredJobs] of Object.entries(this.config.jobs ?? {})) {\n const { workflow, parseError } = this.parseWorkflow(projectRoot, workflowFile);\n if (parseError) {\n violations.push(this.yamlErrorViolation(workflowFile, parseError));\n continue;\n }\n if (!workflow) {\n continue;\n }\n const existingJobs = Object.keys(workflow.jobs ?? {});\n for (const job of requiredJobs.filter((j) => !existingJobs.includes(j))) {\n violations.push({\n rule: `${this.rule}.jobs`,\n tool: this.toolId,\n file: `.github/workflows/${workflowFile}`,\n message: `Workflow '${workflowFile}' missing required job: ${job}`,\n severity: \"error\",\n });\n }\n }\n return violations;\n }\n\n /**\n * Parse a GitHub Actions reference to extract the action name.\n * Handles:\n * - Standard refs: \"actions/checkout@v4\" -> \"actions/checkout\"\n * - SHA refs: \"actions/checkout@abc123\" -> \"actions/checkout\"\n * - Local actions: \"./path/to/action\" -> \"./path/to/action\"\n * - Docker actions: \"docker://image:tag\" -> null (excluded)\n */\n private parseActionReference(uses: string): string | null {\n // Skip Docker actions - they're container images, not GitHub Actions\n if (uses.startsWith(\"docker://\")) {\n return null;\n }\n\n // Local actions don't have version tags\n if (uses.startsWith(\"./\") || uses.startsWith(\"../\")) {\n return uses;\n }\n\n // Standard GitHub Actions: extract name before @ version tag\n const atIndex = uses.indexOf(\"@\");\n return atIndex > 0 ? uses.slice(0, atIndex) : uses;\n }\n\n private extractUsedActions(workflow: WorkflowFile): string[] {\n return Object.values(workflow.jobs ?? {}).flatMap((job) =>\n (job.steps ?? [])\n .map((s) => (s.uses ? this.parseActionReference(s.uses) : null))\n .filter((u): u is string => u !== null)\n );\n }\n\n private checkRequiredActions(projectRoot: string): Violation[] {\n const violations: Violation[] = [];\n for (const [workflowFile, requiredActions] of Object.entries(this.config.actions ?? {})) {\n const { workflow, parseError } = this.parseWorkflow(projectRoot, workflowFile);\n if (parseError) {\n violations.push(this.yamlErrorViolation(workflowFile, parseError));\n continue;\n }\n if (!workflow) {\n continue;\n }\n const usedActions = this.extractUsedActions(workflow);\n for (const action of requiredActions.filter((a) => !usedActions.includes(a))) {\n violations.push({\n rule: `${this.rule}.actions`,\n tool: this.toolId,\n file: `.github/workflows/${workflowFile}`,\n message: `Workflow '${workflowFile}' missing required action: ${action}`,\n severity: \"error\",\n });\n }\n }\n return violations;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const directoryViolation = this.checkWorkflowsDirectory(projectRoot);\n if (directoryViolation) {\n return this.fromViolations([directoryViolation], elapsed());\n }\n\n const violations = [\n ...this.checkRequiredWorkflows(projectRoot),\n ...this.checkRequiredJobs(projectRoot),\n ...this.checkRequiredActions(projectRoot),\n ...this.checkWorkflowCommands(projectRoot),\n ];\n\n return this.fromViolations(violations, elapsed());\n }\n}\n","import { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Single CODEOWNERS rule from config */\ninterface CodeownersRule {\n pattern: string;\n owners: string[];\n}\n\n/** CODEOWNERS configuration */\ninterface CodeownersConfig {\n enabled?: boolean;\n rules?: CodeownersRule[];\n}\n\n/** Parsed rule from CODEOWNERS file */\ninterface ParsedRule {\n pattern: string;\n owners: string[];\n line: number;\n}\n\n/** Common CODEOWNERS file locations */\nconst CODEOWNERS_LOCATIONS = [\".github/CODEOWNERS\", \"CODEOWNERS\", \"docs/CODEOWNERS\"];\n\n/**\n * Runner for CODEOWNERS file validation.\n * Validates that CODEOWNERS file exists and contains all required rules.\n */\nexport class CodeownersRunner extends BaseProcessToolRunner {\n readonly name = \"CODEOWNERS\";\n readonly rule = \"process.codeowners\";\n readonly toolId = \"codeowners\";\n\n private config: CodeownersConfig = { enabled: false };\n\n setConfig(config: CodeownersConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Run check - validates CODEOWNERS content matches config\n */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n // Find CODEOWNERS file\n const codeownersPath = this.findCodeownersFile(projectRoot);\n if (!codeownersPath) {\n return this.fail(\n [\n {\n rule: `${this.rule}.file`,\n tool: this.toolId,\n message:\n \"CODEOWNERS file not found (checked .github/CODEOWNERS, CODEOWNERS, docs/CODEOWNERS)\",\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n\n // Read and parse CODEOWNERS file\n const content = this.readFile(projectRoot, codeownersPath);\n if (content === null) {\n return this.fail(\n [\n {\n rule: `${this.rule}.file`,\n tool: this.toolId,\n message: `Could not read CODEOWNERS file: ${codeownersPath}`,\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n\n const { rules: parsedRules, malformedViolations } = this.parseCodeowners(\n content,\n codeownersPath\n );\n const validationViolations = this.validateRules(parsedRules, codeownersPath);\n\n // Combine malformed line violations with validation violations\n const violations = [...malformedViolations, ...validationViolations];\n return this.fromViolations(violations, elapsed());\n }\n\n /**\n * Audit - just checks that CODEOWNERS file exists\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const codeownersPath = this.findCodeownersFile(projectRoot);\n if (!codeownersPath) {\n return this.fail(\n [\n {\n rule: `${this.rule}.file`,\n tool: this.toolId,\n message:\n \"CODEOWNERS file not found (checked .github/CODEOWNERS, CODEOWNERS, docs/CODEOWNERS)\",\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n\n return this.pass(elapsed());\n }\n\n /**\n * Find CODEOWNERS file in one of the standard locations\n */\n private findCodeownersFile(projectRoot: string): string | null {\n for (const location of CODEOWNERS_LOCATIONS) {\n if (this.fileExists(projectRoot, location)) {\n return location;\n }\n }\n return null;\n }\n\n /**\n * Parse result including both valid rules and malformed line violations\n */\n private parseCodeowners(\n content: string,\n filePath: string\n ): { rules: ParsedRule[]; malformedViolations: Violation[] } {\n const rules: ParsedRule[] = [];\n const malformedViolations: Violation[] = [];\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n const lineNumber = i + 1;\n\n // Skip empty lines and comments\n if (!line || line.startsWith(\"#\")) {\n continue;\n }\n\n const parsed = this.parseCodeownersLine(line, lineNumber);\n if (parsed) {\n rules.push(parsed);\n } else {\n // Report malformed line as violation\n malformedViolations.push({\n rule: `${this.rule}.malformed`,\n tool: this.toolId,\n file: filePath,\n line: lineNumber,\n message: `Malformed CODEOWNERS line: pattern \"${line}\" has no owners`,\n severity: \"error\",\n });\n }\n }\n\n return { rules, malformedViolations };\n }\n\n /**\n * Parse a single CODEOWNERS line into pattern and owners\n */\n private parseCodeownersLine(line: string, lineNumber: number): ParsedRule | null {\n // Split on whitespace - first token is pattern, rest are owners\n const tokens = line.split(/\\s+/).filter(Boolean);\n\n if (tokens.length < 2) {\n // Invalid line - pattern without owners\n return null;\n }\n\n const [pattern, ...owners] = tokens;\n return { pattern, owners, line: lineNumber };\n }\n\n /**\n * Validate rules against config\n */\n private validateRules(parsedRules: ParsedRule[], filePath: string): Violation[] {\n const configRules = this.config.rules ?? [];\n const parsedRuleMap = this.buildParsedRuleMap(parsedRules);\n\n const missingViolations = this.checkMissingRules(configRules, parsedRuleMap, filePath);\n const extraViolations = this.checkExtraRules(parsedRules, configRules, filePath);\n\n return [...missingViolations, ...extraViolations];\n }\n\n /**\n * Build a map of parsed rules for quick lookup\n */\n private buildParsedRuleMap(parsedRules: ParsedRule[]): Map<string, ParsedRule> {\n const map = new Map<string, ParsedRule>();\n for (const rule of parsedRules) {\n map.set(rule.pattern, rule);\n }\n return map;\n }\n\n /**\n * Check that all configured rules exist with correct owners\n */\n private checkMissingRules(\n configRules: CodeownersRule[],\n parsedRuleMap: Map<string, ParsedRule>,\n filePath: string\n ): Violation[] {\n const violations: Violation[] = [];\n\n for (const configRule of configRules) {\n const parsedRule = parsedRuleMap.get(configRule.pattern);\n const violation = this.validateConfigRule(configRule, parsedRule, filePath);\n if (violation) {\n violations.push(violation);\n }\n }\n\n return violations;\n }\n\n /**\n * Validate a single config rule against parsed rule\n */\n private validateConfigRule(\n configRule: CodeownersRule,\n parsedRule: ParsedRule | undefined,\n filePath: string\n ): Violation | null {\n if (!parsedRule) {\n return {\n rule: `${this.rule}.missing`,\n tool: this.toolId,\n file: filePath,\n message: `Missing required rule: ${configRule.pattern} ${configRule.owners.join(\" \")}`,\n severity: \"error\",\n };\n }\n\n if (!this.ownersMatch(configRule.owners, parsedRule.owners)) {\n return {\n rule: `${this.rule}.owners`,\n tool: this.toolId,\n file: filePath,\n line: parsedRule.line,\n message: `Owner mismatch for ${configRule.pattern}: expected [${configRule.owners.join(\", \")}], got [${parsedRule.owners.join(\", \")}]`,\n severity: \"error\",\n };\n }\n\n return null;\n }\n\n /**\n * Check for rules in CODEOWNERS that aren't in config\n */\n private checkExtraRules(\n parsedRules: ParsedRule[],\n configRules: CodeownersRule[],\n filePath: string\n ): Violation[] {\n const configPatterns = new Set(configRules.map((r) => r.pattern));\n const violations: Violation[] = [];\n\n for (const parsedRule of parsedRules) {\n if (!configPatterns.has(parsedRule.pattern)) {\n violations.push({\n rule: `${this.rule}.extra`,\n tool: this.toolId,\n file: filePath,\n line: parsedRule.line,\n message: `Unexpected rule not in config: ${parsedRule.pattern} ${parsedRule.owners.join(\" \")}`,\n severity: \"error\",\n });\n }\n }\n\n return violations;\n }\n\n /**\n * Check if two owner arrays match exactly (order-sensitive)\n */\n private ownersMatch(expected: string[], actual: string[]): boolean {\n if (expected.length !== actual.length) {\n return false;\n }\n return expected.every((owner, index) => owner === actual[index]);\n }\n}\n","import { execa } from \"execa\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Commits configuration from standards.toml */\ninterface CommitsConfig {\n enabled?: boolean;\n pattern?: string;\n types?: string[];\n require_scope?: boolean;\n max_subject_length?: number;\n}\n\n/**\n * Commit message format validation runner.\n * Validates that commit messages follow conventional commit format or custom patterns.\n */\nexport class CommitsRunner extends BaseProcessToolRunner {\n readonly name = \"Commits\";\n readonly rule = \"process.commits\";\n readonly toolId = \"commits\";\n\n private config: CommitsConfig = {\n enabled: false,\n require_scope: false,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: CommitsConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Get the HEAD commit message (subject line only) */\n private async getHeadCommitSubject(projectRoot: string): Promise<string | null> {\n try {\n const result = await execa(\"git\", [\"log\", \"-1\", \"--format=%s\"], {\n cwd: projectRoot,\n });\n return result.stdout.trim() || null;\n } catch {\n return null;\n }\n }\n\n /** Build conventional commits pattern from config */\n private buildConventionalPattern(): string {\n const types = this.config.types;\n if (!types || types.length === 0) {\n return \"\";\n }\n\n const typePattern = types.join(\"|\");\n // Use [^)]+ instead of .+ to avoid greedy matching through multiple parentheses\n const scopePattern = this.config.require_scope ? \"\\\\([^)]+\\\\)\" : \"(\\\\([^)]+\\\\))?\";\n\n // Pattern: type(scope)?: description\n // e.g., feat(api): add new endpoint\n return `^(${typePattern})${scopePattern}: .+`;\n }\n\n /** Check if text matches a pattern */\n private matchesPattern(text: string, pattern: string): boolean {\n try {\n const regex = new RegExp(pattern);\n return regex.test(text);\n } catch {\n return false;\n }\n }\n\n /** Validate the regex pattern is valid */\n private isValidPattern(pattern: string): boolean {\n try {\n new RegExp(pattern);\n return true;\n } catch {\n return false;\n }\n }\n\n /** Check configuration validity */\n private hasValidConfig(): { valid: boolean; reason?: string; pattern?: string } {\n // If explicit pattern is provided, use it\n if (this.config.pattern) {\n if (!this.isValidPattern(this.config.pattern)) {\n return { valid: false, reason: `Invalid regex pattern: ${this.config.pattern}` };\n }\n return { valid: true, pattern: this.config.pattern };\n }\n\n // If types are provided, build conventional commits pattern\n if (this.config.types && this.config.types.length > 0) {\n const pattern = this.buildConventionalPattern();\n return { valid: true, pattern };\n }\n\n // No pattern and no types - need at least one\n return { valid: false, reason: \"No pattern or types configured for commit validation\" };\n }\n\n /** Validate commit message format */\n private validateCommitFormat(\n subject: string,\n pattern: string,\n elapsed: () => number\n ): CheckResult {\n const violations: Violation[] = [];\n\n // Check pattern match\n if (!this.matchesPattern(subject, pattern)) {\n const typesHint = this.config.types\n ? ` Expected format: ${this.config.types.join(\"|\")}${this.config.require_scope ? \"(scope)\" : \"(scope)?\"}: description`\n : \"\";\n violations.push({\n rule: `${this.rule}.pattern`,\n tool: this.toolId,\n message: `Commit message does not match required format.${typesHint}`,\n severity: \"error\",\n });\n }\n\n // Check max subject length\n if (this.config.max_subject_length && subject.length > this.config.max_subject_length) {\n violations.push({\n rule: `${this.rule}.max_subject_length`,\n tool: this.toolId,\n message: `Commit subject is ${subject.length} characters, exceeds max of ${this.config.max_subject_length}`,\n severity: \"error\",\n });\n }\n\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n\n /** Run commit message validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const configCheck = this.hasValidConfig();\n if (!configCheck.valid) {\n return this.skip(configCheck.reason ?? \"Invalid configuration\", elapsed());\n }\n\n const subject = await this.getHeadCommitSubject(projectRoot);\n if (!subject) {\n return this.skip(\"Not in a git repository or no commits\", elapsed());\n }\n\n return this.validateCommitFormat(subject, configCheck.pattern as string, elapsed);\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport * as yaml from \"js-yaml\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Coverage configuration from standards.toml */\ninterface CoverageConfig {\n enabled?: boolean;\n min_threshold?: number;\n enforce_in?: \"ci\" | \"config\" | \"both\";\n ci_workflow?: string;\n ci_job?: string;\n}\n\n/** Coverage config file detection result */\ninterface CoverageConfigResult {\n found: boolean;\n file?: string;\n threshold?: number;\n error?: string;\n}\n\n/** Helper to safely read and parse JSON */\nfunction parseJsonFile(filePath: string): Record<string, unknown> | null {\n try {\n const content = fs.readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n/** Helper to read file content */\nfunction readFileContent(filePath: string): string | null {\n try {\n return fs.readFileSync(filePath, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/** Extract threshold from vitest/jest style config */\nfunction extractThresholdFromContent(content: string): number | undefined {\n const match = /(?:lines|statements|branches|functions)\\s*:\\s*(\\d+)/.exec(content);\n return match ? parseInt(match[1], 10) : undefined;\n}\n\n/** Parse nyc config file content (JSON or YAML) */\nfunction parseNycConfigContent(\n content: string,\n configFile: string\n): { config: Record<string, unknown> } | { error: string } {\n try {\n const config =\n configFile.endsWith(\".yaml\") || configFile.endsWith(\".yml\")\n ? (yaml.load(content) as Record<string, unknown>)\n : (JSON.parse(content) as Record<string, unknown>);\n return { config };\n } catch {\n return { error: \"Failed to parse config file\" };\n }\n}\n\n/** Extract threshold from nyc config object */\nfunction extractNycThreshold(config: Record<string, unknown>): number | undefined {\n return (\n (config.lines as number | undefined) ??\n (config.statements as number | undefined) ??\n (config.branches as number | undefined) ??\n (config.functions as number | undefined)\n );\n}\n\n/**\n * Coverage enforcement runner.\n * Checks that coverage thresholds are configured in CI workflows and/or config files.\n */\nexport class CoverageRunner extends BaseProcessToolRunner {\n readonly name = \"Coverage\";\n readonly rule = \"process.coverage\";\n readonly toolId = \"coverage\";\n\n private config: CoverageConfig = {\n enabled: false,\n enforce_in: \"config\",\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: CoverageConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Check for vitest coverage config */\n private checkVitestConfig(projectRoot: string): CoverageConfigResult {\n const configFiles = [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"vitest.config.mts\",\n \"vitest.config.mjs\",\n ];\n\n for (const configFile of configFiles) {\n const configPath = path.join(projectRoot, configFile);\n const content = readFileContent(configPath);\n if (!content) {\n continue;\n }\n\n const hasThreshold =\n /coverage\\s*:\\s*\\{[^}]*thresholds?\\s*:/s.test(content) ||\n /thresholds?\\s*:\\s*\\{[^}]*(?:lines|statements|branches|functions)\\s*:/s.test(content);\n\n if (hasThreshold) {\n return { found: true, file: configFile, threshold: extractThresholdFromContent(content) };\n }\n return { found: false, file: configFile, error: \"No coverage thresholds configured\" };\n }\n return { found: false };\n }\n\n /** Check jest config file */\n private checkJestConfigFile(projectRoot: string): CoverageConfigResult {\n const configFiles = [\"jest.config.js\", \"jest.config.ts\", \"jest.config.mjs\", \"jest.config.cjs\"];\n\n for (const configFile of configFiles) {\n const configPath = path.join(projectRoot, configFile);\n const content = readFileContent(configPath);\n if (!content) {\n continue;\n }\n\n if (/coverageThreshold\\s*:/s.test(content)) {\n return { found: true, file: configFile, threshold: extractThresholdFromContent(content) };\n }\n return { found: false, file: configFile, error: \"No coverageThreshold configured\" };\n }\n return { found: false };\n }\n\n /** Check jest config in package.json */\n private checkJestPackageJson(projectRoot: string): CoverageConfigResult {\n const pkg = parseJsonFile(path.join(projectRoot, \"package.json\"));\n if (!pkg) {\n return { found: false };\n }\n\n const jestConfig = pkg.jest as Record<string, unknown> | undefined;\n if (!jestConfig?.coverageThreshold) {\n return { found: false };\n }\n\n const globalThreshold = (jestConfig.coverageThreshold as Record<string, unknown>).global as\n | { lines?: number; statements?: number; branches?: number; functions?: number }\n | undefined;\n if (!globalThreshold) {\n return { found: false };\n }\n\n const threshold =\n globalThreshold.lines ??\n globalThreshold.statements ??\n globalThreshold.branches ??\n globalThreshold.functions;\n return { found: true, file: \"package.json (jest)\", threshold };\n }\n\n /** Check for jest coverage config */\n private checkJestConfig(projectRoot: string): CoverageConfigResult {\n const fileResult = this.checkJestConfigFile(projectRoot);\n if (fileResult.found || fileResult.file) {\n return fileResult;\n }\n return this.checkJestPackageJson(projectRoot);\n }\n\n /** Check a single nyc config file and return result */\n private checkSingleNycConfig(configFile: string, content: string): CoverageConfigResult {\n const parseResult = parseNycConfigContent(content, configFile);\n if (\"error\" in parseResult) {\n return { found: false, file: configFile, error: parseResult.error };\n }\n\n if (!parseResult.config[\"check-coverage\"]) {\n return { found: false, file: configFile, error: \"check-coverage not enabled\" };\n }\n\n return { found: true, file: configFile, threshold: extractNycThreshold(parseResult.config) };\n }\n\n /** Check nyc config file */\n private checkNycConfigFile(projectRoot: string): CoverageConfigResult {\n const nycrcFiles = [\".nycrc\", \".nycrc.json\", \".nycrc.yaml\", \".nycrc.yml\"];\n\n for (const configFile of nycrcFiles) {\n const configPath = path.join(projectRoot, configFile);\n if (!fs.existsSync(configPath)) {\n continue;\n }\n\n const content = readFileContent(configPath);\n if (!content) {\n return { found: false, file: configFile, error: \"Failed to read config file\" };\n }\n\n return this.checkSingleNycConfig(configFile, content);\n }\n return { found: false };\n }\n\n /** Check nyc config in package.json */\n private checkNycPackageJson(projectRoot: string): CoverageConfigResult {\n const pkg = parseJsonFile(path.join(projectRoot, \"package.json\"));\n if (!pkg) {\n return { found: false };\n }\n\n const nycConfig = pkg.nyc as Record<string, unknown> | undefined;\n if (!nycConfig?.[\"check-coverage\"]) {\n return { found: false };\n }\n\n const threshold =\n (nycConfig.lines as number | undefined) ??\n (nycConfig.statements as number | undefined) ??\n (nycConfig.branches as number | undefined) ??\n (nycConfig.functions as number | undefined);\n return { found: true, file: \"package.json (nyc)\", threshold };\n }\n\n /** Check for nyc coverage config */\n private checkNycConfig(projectRoot: string): CoverageConfigResult {\n const fileResult = this.checkNycConfigFile(projectRoot);\n if (fileResult.found || fileResult.file) {\n return fileResult;\n }\n return this.checkNycPackageJson(projectRoot);\n }\n\n /** Check for coverage config in any supported tool */\n private checkConfigCoverage(projectRoot: string): CoverageConfigResult {\n const vitestResult = this.checkVitestConfig(projectRoot);\n if (vitestResult.found) {\n return vitestResult;\n }\n\n const jestResult = this.checkJestConfig(projectRoot);\n if (jestResult.found) {\n return jestResult;\n }\n\n const nycResult = this.checkNycConfig(projectRoot);\n if (nycResult.found) {\n return nycResult;\n }\n\n return {\n found: false,\n error: \"No coverage threshold config found (checked vitest, jest, nyc)\",\n };\n }\n\n /** Check if a step has coverage enforcement */\n private stepHasCoverage(run: string): boolean {\n if (\n !run.includes(\"--coverage\") &&\n !run.includes(\"test:coverage\") &&\n !run.includes(\"coverage:check\")\n ) {\n return false;\n }\n return (\n run.includes(\"threshold\") ||\n run.includes(\"check-coverage\") ||\n run.includes(\"--coverage.\") ||\n run.includes(\"test:coverage\") ||\n run.includes(\"coverage:check\")\n );\n }\n\n /** Check a single job for coverage enforcement */\n private checkJobForCoverage(\n job: Record<string, unknown>,\n jobName: string,\n workflowFile: string\n ): CoverageConfigResult | null {\n const steps = job.steps as { run?: string }[] | undefined;\n if (!steps) {\n return null;\n }\n\n for (const step of steps) {\n if (step.run && this.stepHasCoverage(step.run)) {\n return { found: true, file: `${workflowFile} (job: ${jobName})` };\n }\n }\n return null;\n }\n\n /** Check workflow jobs for coverage */\n private checkWorkflowJobs(\n jobs: Record<string, Record<string, unknown>>,\n targetJob: string | undefined,\n workflowFile: string\n ): CoverageConfigResult {\n if (targetJob && targetJob in jobs) {\n const result = this.checkJobForCoverage(jobs[targetJob], targetJob, workflowFile);\n if (result) {\n return result;\n }\n } else if (!targetJob) {\n for (const [jobName, job] of Object.entries(jobs)) {\n const result = this.checkJobForCoverage(job, jobName, workflowFile);\n if (result) {\n return result;\n }\n }\n }\n\n return { found: false, file: workflowFile, error: \"No coverage enforcement found in workflow\" };\n }\n\n /** Check for coverage enforcement in CI workflow */\n private checkCiCoverage(projectRoot: string): CoverageConfigResult {\n const workflowFile = this.config.ci_workflow ?? \"ci.yml\";\n const workflowPath = path.join(projectRoot, \".github\", \"workflows\", workflowFile);\n\n const content = readFileContent(workflowPath);\n if (!content) {\n return { found: false, error: `Workflow file not found: ${workflowFile}` };\n }\n\n let workflow: Record<string, unknown>;\n try {\n workflow = yaml.load(content) as Record<string, unknown>;\n } catch {\n return { found: false, file: workflowFile, error: \"Failed to parse workflow file\" };\n }\n\n const jobs = workflow.jobs as Record<string, Record<string, unknown>> | undefined;\n if (!jobs) {\n return { found: false, file: workflowFile, error: \"No jobs found in workflow\" };\n }\n\n return this.checkWorkflowJobs(jobs, this.config.ci_job, workflowFile);\n }\n\n /** Validate config coverage and add violations if needed */\n private validateConfigCoverage(projectRoot: string, violations: Violation[]): void {\n const configResult = this.checkConfigCoverage(projectRoot);\n\n // If min_threshold is set in standards.toml, that's a valid coverage config\n // (no need for tool-specific config like vitest.config.ts or jest.config.js)\n const hasCheckTomlThreshold = this.config.min_threshold !== undefined;\n\n if (!configResult.found && !hasCheckTomlThreshold) {\n violations.push({\n rule: `${this.rule}.config`,\n tool: this.toolId,\n message: configResult.error ?? \"No coverage threshold configuration found\",\n severity: \"error\",\n });\n return;\n }\n\n // If tool config exists, validate its threshold meets the minimum\n if (\n configResult.found &&\n this.config.min_threshold !== undefined &&\n configResult.threshold !== undefined\n ) {\n if (configResult.threshold < this.config.min_threshold) {\n violations.push({\n rule: `${this.rule}.threshold`,\n tool: this.toolId,\n message: `Coverage threshold ${configResult.threshold}% is below minimum ${this.config.min_threshold}% (in ${configResult.file})`,\n severity: \"error\",\n });\n }\n }\n }\n\n /** Validate CI coverage and add violations if needed */\n private validateCiCoverage(projectRoot: string, violations: Violation[]): void {\n const ciResult = this.checkCiCoverage(projectRoot);\n\n if (!ciResult.found) {\n violations.push({\n rule: `${this.rule}.ci`,\n tool: this.toolId,\n message: ciResult.error ?? \"No coverage enforcement found in CI workflow\",\n severity: \"error\",\n });\n }\n }\n\n /** Run coverage validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const violations: Violation[] = [];\n const enforceIn = this.config.enforce_in ?? \"config\";\n\n if (enforceIn === \"config\" || enforceIn === \"both\") {\n this.validateConfigCoverage(projectRoot, violations);\n }\n\n if (enforceIn === \"ci\" || enforceIn === \"both\") {\n this.validateCiCoverage(projectRoot, violations);\n }\n\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\nimport { glob } from \"glob\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\nimport {\n type DocsConfig,\n type DocTypeConfig,\n escapeRegex,\n type ExportInfo,\n extractFileExports,\n getTrackedPath,\n type ParsedDoc,\n parseMarkdownFile,\n} from \"./docs-helpers.js\";\n\n/**\n * Documentation governance runner.\n * Validates documentation structure, content, freshness, and API coverage.\n */\nexport class DocsRunner extends BaseProcessToolRunner {\n readonly name = \"Documentation\";\n readonly rule = \"process.docs\";\n readonly toolId = \"docs\";\n\n private config: DocsConfig = {\n enabled: false,\n path: \"docs/\",\n enforcement: \"warn\",\n staleness_days: 30,\n };\n\n setConfig(config: DocsConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n private getSeverity(): \"error\" | \"warning\" {\n return this.config.enforcement === \"block\" ? \"error\" : \"warning\";\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const violations: Violation[] = [];\n violations.push(...(await this.checkStructure(projectRoot)));\n violations.push(...(await this.checkContent(projectRoot)));\n violations.push(...(await this.checkFreshness(projectRoot)));\n violations.push(...(await this.checkApiCoverage(projectRoot)));\n\n return this.fromViolations(violations, elapsed());\n }\n\n // ===========================================================================\n // Structure Enforcement\n // ===========================================================================\n\n private async checkStructure(projectRoot: string): Promise<Violation[]> {\n const docsPath = this.config.path ?? \"docs/\";\n const allowlist = new Set(this.config.allowlist ?? []);\n\n const allMdFiles = await glob(\"**/*.md\", {\n cwd: projectRoot,\n ignore: [\"node_modules/**\", \".git/**\", \"dist/**\", \".changeset/**\"],\n nodir: true,\n });\n\n const violations = this.checkAllowlist(allMdFiles, docsPath, allowlist);\n const docsFiles = allMdFiles.filter((f) => f.startsWith(docsPath));\n\n violations.push(...this.checkFileLimits(projectRoot, docsFiles));\n\n return violations;\n }\n\n private checkAllowlist(files: string[], docsPath: string, allowlist: Set<string>): Violation[] {\n const violations: Violation[] = [];\n for (const file of files) {\n const isInDocs = file.startsWith(docsPath);\n const isAllowlisted = allowlist.has(file) || allowlist.has(path.basename(file));\n if (!isInDocs && !isAllowlisted) {\n violations.push({\n rule: `${this.rule}.structure`,\n tool: this.toolId,\n file,\n message: `Markdown file outside ${docsPath} is not allowlisted`,\n severity: this.getSeverity(),\n });\n }\n }\n return violations;\n }\n\n private checkFileLimits(projectRoot: string, docsFiles: string[]): Violation[] {\n const violations: Violation[] = [];\n\n if (this.config.max_files !== undefined && docsFiles.length > this.config.max_files) {\n violations.push({\n rule: `${this.rule}.structure`,\n tool: this.toolId,\n message: `Documentation has ${docsFiles.length} files, max allowed is ${this.config.max_files}`,\n severity: this.getSeverity(),\n });\n }\n\n let totalKb = 0;\n for (const file of docsFiles) {\n const result = this.checkSingleFileLimit(projectRoot, file);\n totalKb += result.sizeKb;\n violations.push(...result.violations);\n }\n\n if (this.config.max_total_kb !== undefined && totalKb > this.config.max_total_kb) {\n violations.push({\n rule: `${this.rule}.structure`,\n tool: this.toolId,\n message: `Total docs size is ${totalKb.toFixed(1)}KB, max allowed is ${this.config.max_total_kb}KB`,\n severity: this.getSeverity(),\n });\n }\n\n return violations;\n }\n\n private checkSingleFileLimit(\n projectRoot: string,\n file: string\n ): { sizeKb: number; violations: Violation[] } {\n const violations: Violation[] = [];\n const fullPath = path.join(projectRoot, file);\n\n try {\n const stats = fs.statSync(fullPath);\n const sizeKb = stats.size / 1024;\n\n if (this.config.max_file_lines !== undefined) {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n const lineCount = content.split(\"\\n\").length;\n if (lineCount > this.config.max_file_lines) {\n violations.push({\n rule: `${this.rule}.structure`,\n tool: this.toolId,\n file,\n message: `File has ${lineCount} lines, max allowed is ${this.config.max_file_lines}`,\n severity: this.getSeverity(),\n });\n }\n }\n\n return { sizeKb, violations };\n } catch {\n return { sizeKb: 0, violations };\n }\n }\n\n // ===========================================================================\n // Content Validation\n // ===========================================================================\n\n private async checkContent(projectRoot: string): Promise<Violation[]> {\n const types = this.config.types ?? {};\n if (Object.keys(types).length === 0) {\n return [];\n }\n\n const docsPath = this.config.path ?? \"docs/\";\n const docsFiles = await glob(`${docsPath}**/*.md`, { cwd: projectRoot, nodir: true });\n const violations: Violation[] = [];\n\n for (const file of docsFiles) {\n violations.push(...this.validateDocFile(projectRoot, file, types));\n }\n\n return violations;\n }\n\n private validateDocFile(\n projectRoot: string,\n file: string,\n types: Record<string, DocTypeConfig>\n ): Violation[] {\n const parsed = this.parseDocFile(projectRoot, file);\n if (!parsed) {\n return [];\n }\n\n const violations: Violation[] = [];\n const docType = parsed.frontmatter.type as string | undefined;\n const typeConfig = docType ? types[docType] : undefined;\n\n if (typeConfig) {\n violations.push(\n ...this.validateFrontmatter(file, parsed.frontmatter, typeConfig.frontmatter ?? [])\n );\n violations.push(\n ...this.validateSections(file, parsed.headings, typeConfig.required_sections ?? [])\n );\n }\n\n violations.push(...this.validateInternalLinks(projectRoot, file, parsed.content));\n\n return violations;\n }\n\n private parseDocFile(projectRoot: string, filePath: string): ParsedDoc | null {\n const fullPath = path.join(projectRoot, filePath);\n try {\n const raw = fs.readFileSync(fullPath, \"utf-8\");\n return parseMarkdownFile(raw, filePath);\n } catch {\n return null;\n }\n }\n\n private validateFrontmatter(\n file: string,\n frontmatter: Record<string, unknown>,\n required: string[]\n ): Violation[] {\n return required\n .filter((field) => !(field in frontmatter))\n .map((field) => ({\n rule: `${this.rule}.content`,\n tool: this.toolId,\n file,\n message: `Missing required frontmatter field: ${field}`,\n severity: this.getSeverity(),\n }));\n }\n\n private validateSections(file: string, headings: string[], required: string[]): Violation[] {\n const headingSet = new Set(headings.map((h) => h.toLowerCase()));\n return required\n .filter((section) => !headingSet.has(section.toLowerCase()))\n .map((section) => ({\n rule: `${this.rule}.content`,\n tool: this.toolId,\n file,\n message: `Missing required section: ${section}`,\n severity: this.getSeverity(),\n }));\n }\n\n private validateInternalLinks(projectRoot: string, file: string, content: string): Violation[] {\n const violations: Violation[] = [];\n const linkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n let match;\n\n while ((match = linkRegex.exec(content)) !== null) {\n const violation = this.checkSingleLink(projectRoot, file, match[2]);\n if (violation) {\n violations.push(violation);\n }\n }\n\n return violations;\n }\n\n private checkSingleLink(projectRoot: string, file: string, linkTarget: string): Violation | null {\n if (\n linkTarget.startsWith(\"http\") ||\n linkTarget.startsWith(\"#\") ||\n linkTarget.startsWith(\"mailto:\")\n ) {\n return null;\n }\n\n const targetPath = linkTarget.split(\"#\")[0];\n if (!targetPath) {\n return null;\n }\n\n const resolvedPath = path.join(projectRoot, path.dirname(file), targetPath);\n if (!fs.existsSync(resolvedPath)) {\n return {\n rule: `${this.rule}.links`,\n tool: this.toolId,\n file,\n message: `Broken internal link: ${linkTarget}`,\n severity: \"warning\",\n };\n }\n\n return null;\n }\n\n // ===========================================================================\n // Freshness Tracking\n // ===========================================================================\n\n private async checkFreshness(projectRoot: string): Promise<Violation[]> {\n const docsPath = this.config.path ?? \"docs/\";\n const docsFiles = await glob(`${docsPath}**/*.md`, { cwd: projectRoot, nodir: true });\n\n const results = await Promise.all(\n docsFiles.map((file) => this.checkFileFreshness(projectRoot, file, docsPath))\n );\n\n return results.filter((v): v is Violation => v !== null);\n }\n\n private async getTimestamps(\n projectRoot: string,\n file: string,\n trackedPath: string\n ): Promise<{ docTime: number; sourceTime: number } | null> {\n const docTime = await this.getGitLastModified(projectRoot, file);\n const sourceTime = await this.getGitLastModified(projectRoot, trackedPath);\n if (docTime === null || sourceTime === null) {\n return null;\n }\n return { docTime, sourceTime };\n }\n\n private createStalenessViolation(file: string, daysDiff: number, trackedPath: string): Violation {\n return {\n rule: `${this.rule}.freshness`,\n tool: this.toolId,\n file,\n message: `Doc is ${Math.round(daysDiff)} days behind tracked source: ${trackedPath}`,\n severity: this.getSeverity(),\n };\n }\n\n private async checkFileFreshness(\n projectRoot: string,\n file: string,\n docsPath: string\n ): Promise<Violation | null> {\n const parsed = this.parseDocFile(projectRoot, file);\n if (!parsed) {\n return null;\n }\n\n const staleMappings = this.config.stale_mappings ?? {};\n const trackedPath = getTrackedPath(file, parsed.frontmatter, staleMappings, docsPath);\n if (!trackedPath || !fs.existsSync(path.join(projectRoot, trackedPath))) {\n return null;\n }\n\n const timestamps = await this.getTimestamps(projectRoot, file, trackedPath);\n if (!timestamps) {\n return null;\n }\n\n const stalenessDays = this.config.staleness_days ?? 30;\n const daysDiff = (timestamps.sourceTime - timestamps.docTime) / (1000 * 60 * 60 * 24);\n\n return daysDiff > stalenessDays\n ? this.createStalenessViolation(file, daysDiff, trackedPath)\n : null;\n }\n\n private async getGitLastModified(projectRoot: string, filePath: string): Promise<number | null> {\n try {\n const result = await execa(\"git\", [\"log\", \"-1\", \"--format=%ct\", \"--\", filePath], {\n cwd: projectRoot,\n });\n const timestamp = parseInt(result.stdout.trim(), 10);\n return isNaN(timestamp) ? null : timestamp * 1000;\n } catch {\n return null;\n }\n }\n\n // ===========================================================================\n // API Coverage\n // ===========================================================================\n\n private async checkApiCoverage(projectRoot: string): Promise<Violation[]> {\n const minCoverage = this.config.min_coverage;\n if (minCoverage === undefined) {\n return [];\n }\n\n const sourceFiles = await this.getSourceFiles(projectRoot);\n const exports = this.extractExports(projectRoot, sourceFiles);\n if (exports.length === 0) {\n return [];\n }\n\n const allDocsContent = await this.getAllDocsContent(projectRoot);\n const undocumented = exports.filter(\n (exp) => !this.isExportDocumented(exp.name, allDocsContent)\n );\n\n return this.buildCoverageViolations(exports.length, undocumented, minCoverage);\n }\n\n private async getSourceFiles(projectRoot: string): Promise<string[]> {\n const coveragePaths = this.config.coverage_paths ?? [\"src/**/*.ts\"];\n const excludePatterns = this.config.exclude_patterns ?? [\"**/*.test.ts\", \"**/*.spec.ts\"];\n\n const fileArrays = await Promise.all(\n coveragePaths.map((pattern) =>\n glob(pattern, {\n cwd: projectRoot,\n ignore: [\"node_modules/**\", ...excludePatterns],\n nodir: true,\n })\n )\n );\n\n return fileArrays.flat();\n }\n\n private async getAllDocsContent(projectRoot: string): Promise<string> {\n const docsPath = this.config.path ?? \"docs/\";\n const docsFiles = await glob(`${docsPath}**/*.md`, { cwd: projectRoot, nodir: true });\n\n return docsFiles.map((f) => this.readFile(projectRoot, f) ?? \"\").join(\"\\n\");\n }\n\n private isExportDocumented(exportName: string, docsContent: string): boolean {\n const regex = new RegExp(`\\\\b${escapeRegex(exportName)}\\\\b`);\n return regex.test(docsContent);\n }\n\n private buildCoverageViolations(\n totalExports: number,\n undocumented: ExportInfo[],\n minCoverage: number\n ): Violation[] {\n const documented = totalExports - undocumented.length;\n const coverage = (documented / totalExports) * 100;\n\n if (coverage >= minCoverage) {\n return [];\n }\n\n const violations: Violation[] = [\n {\n rule: `${this.rule}.coverage`,\n tool: this.toolId,\n message: `API documentation coverage is ${coverage.toFixed(1)}% (min: ${minCoverage}%). ${undocumented.length} undocumented exports.`,\n severity: this.getSeverity(),\n },\n ];\n\n const limit = 10;\n for (const exp of undocumented.slice(0, limit)) {\n violations.push({\n rule: `${this.rule}.coverage`,\n tool: this.toolId,\n file: exp.file,\n line: exp.line,\n message: `Export \"${exp.name}\" is not documented`,\n severity: \"warning\",\n });\n }\n\n if (undocumented.length > limit) {\n violations.push({\n rule: `${this.rule}.coverage`,\n tool: this.toolId,\n message: `...and ${undocumented.length - limit} more undocumented exports`,\n severity: \"warning\",\n });\n }\n\n return violations;\n }\n\n private extractExports(projectRoot: string, files: string[]): ExportInfo[] {\n const exports: ExportInfo[] = [];\n\n for (const file of files) {\n const content = this.readFile(projectRoot, file);\n if (!content) {\n continue;\n }\n exports.push(...extractFileExports(file, content));\n }\n\n return exports;\n }\n}\n","import matter from \"gray-matter\";\n\n/** Enforcement mode for documentation checks */\nexport type EnforcementMode = \"block\" | \"warn\";\n\n/** Doc type configuration */\nexport interface DocTypeConfig {\n required_sections?: string[];\n frontmatter?: string[];\n}\n\n/** Documentation configuration from standards.toml */\nexport interface DocsConfig {\n enabled?: boolean;\n path?: string;\n enforcement?: EnforcementMode;\n allowlist?: string[];\n max_files?: number;\n max_file_lines?: number;\n max_total_kb?: number;\n staleness_days?: number;\n stale_mappings?: Record<string, string>;\n min_coverage?: number;\n coverage_paths?: string[];\n exclude_patterns?: string[];\n types?: Record<string, DocTypeConfig>;\n}\n\n/** Parsed frontmatter from a markdown file */\nexport interface ParsedDoc {\n filePath: string;\n frontmatter: Record<string, unknown>;\n content: string;\n headings: string[];\n}\n\n/** Export info from TypeScript file */\nexport interface ExportInfo {\n name: string;\n file: string;\n line: number;\n}\n\n/** Escape special regex characters in a string */\nexport function escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/** Extract heading text from markdown content */\nfunction extractHeadings(content: string): string[] {\n const headingRegex = /^#{1,6}\\s+(.+)$/gm;\n const headings: string[] = [];\n let match;\n while ((match = headingRegex.exec(content)) !== null) {\n headings.push(match[1].trim());\n }\n return headings;\n}\n\n/** Parse named export from a line */\nfunction parseNamedExport(line: string): string | null {\n const match = /^export\\s+(?:const|let|var|function|class|interface|type|enum)\\s+(\\w+)/.exec(line);\n return match ? match[1] : null;\n}\n\n/** Parse default export from a line */\nfunction parseDefaultExport(line: string): string | null {\n const match = /^export\\s+default\\s+(\\w+)/.exec(line);\n if (match && ![\"function\", \"class\", \"async\"].includes(match[1])) {\n return match[1];\n }\n return null;\n}\n\n/** Parse re-exports from a line */\nfunction parseReExports(line: string): string[] {\n const match = /^export\\s*\\{\\s*([^}]+)\\s*\\}/.exec(line);\n if (!match) {\n return [];\n }\n return match[1]\n .split(\",\")\n .map((n) => {\n const parts = n.trim().split(/\\s+as\\s+/);\n return parts[parts.length - 1].trim();\n })\n .filter((name) => name && !/^(type|interface)$/.test(name));\n}\n\n/** Parse a markdown file and extract frontmatter, content, headings */\nexport function parseMarkdownFile(content: string, filePath: string): ParsedDoc {\n const { data, content: mdContent } = matter(content);\n return {\n filePath,\n frontmatter: data,\n content: mdContent,\n headings: extractHeadings(mdContent),\n };\n}\n\n/** Process a single line and extract any exports */\nfunction processLine(line: string, file: string, lineNumber: number): ExportInfo[] {\n const named = parseNamedExport(line);\n if (named) {\n return [{ name: named, file, line: lineNumber }];\n }\n\n const defaultExp = parseDefaultExport(line);\n if (defaultExp) {\n return [{ name: defaultExp, file, line: lineNumber }];\n }\n\n return parseReExports(line).map((name) => ({ name, file, line: lineNumber }));\n}\n\n/** Extract exports from file content */\nexport function extractFileExports(file: string, content: string): ExportInfo[] {\n return content.split(\"\\n\").flatMap((line, i) => processLine(line, file, i + 1));\n}\n\n/** Get the source path that a doc file tracks */\nexport function getTrackedPath(\n docFile: string,\n frontmatter: Record<string, unknown>,\n staleMappings: Record<string, string>,\n docsPath: string\n): string | null {\n if (typeof frontmatter.tracks === \"string\") {\n return frontmatter.tracks;\n }\n if (Array.isArray(frontmatter.tracks) && frontmatter.tracks.length > 0) {\n return frontmatter.tracks[0] as string;\n }\n if (staleMappings[docFile]) {\n return staleMappings[docFile];\n }\n if (docFile.startsWith(docsPath)) {\n const baseName = docFile.slice(docsPath.length).replace(/\\.md$/, \"\");\n return `src/${baseName}/`;\n }\n return null;\n}\n","import { glob } from \"glob\";\n\nimport { DEFAULT_FORBIDDEN_FILES_IGNORE } from \"../../core/index.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Forbidden files configuration */\ninterface ForbiddenFilesConfig {\n enabled?: boolean;\n files?: string[];\n ignore?: string[];\n message?: string;\n}\n\n/**\n * Runner for forbidden files validation.\n * Validates that certain files do NOT exist anywhere in the repository.\n */\nexport class ForbiddenFilesRunner extends BaseProcessToolRunner {\n readonly name = \"Forbidden Files\";\n readonly rule = \"process.forbidden_files\";\n readonly toolId = \"forbidden-files\";\n\n private config: ForbiddenFilesConfig = { enabled: false };\n\n setConfig(config: ForbiddenFilesConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Run check - scans for forbidden files using glob patterns\n */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const patterns = this.config.files ?? [];\n if (patterns.length === 0) {\n return this.pass(elapsed());\n }\n\n // Process all patterns in parallel for better performance\n const results = await Promise.all(\n patterns.map(async (pattern) => {\n const foundFiles = await this.findForbiddenFiles(projectRoot, pattern);\n return foundFiles.map((file) => this.createViolation(file, pattern));\n })\n );\n\n // Deduplicate violations by file path (fix #181)\n // Keep only the first violation for each file\n const allViolations = results.flat();\n const seenFiles = new Set<string>();\n const violations: Violation[] = [];\n for (const violation of allViolations) {\n if (violation.file && !seenFiles.has(violation.file)) {\n seenFiles.add(violation.file);\n violations.push(violation);\n }\n }\n\n return this.fromViolations(violations, elapsed());\n }\n\n /**\n * Find files matching a forbidden pattern\n */\n private async findForbiddenFiles(projectRoot: string, pattern: string): Promise<string[]> {\n // Determine ignore patterns:\n // - If ignore is explicitly set (including empty array), use it (fix #185)\n // - If ignore is undefined (not set), use defaults\n const ignorePatterns = this.getIgnorePatterns();\n\n try {\n const matches = await glob(pattern, {\n cwd: projectRoot,\n dot: true,\n nodir: true,\n ignore: ignorePatterns,\n });\n return matches;\n } catch {\n return [];\n }\n }\n\n /**\n * Get ignore patterns, respecting explicit empty array override\n * - undefined: use defaults (node_modules, .git)\n * - []: no ignores (scan everything)\n * - [...]: use custom ignores\n */\n private getIgnorePatterns(): string[] {\n // Check if ignore was explicitly set (including empty array)\n // Object.hasOwn checks if the property exists, even if value is []\n if (Object.hasOwn(this.config, \"ignore\") && this.config.ignore !== undefined) {\n return this.config.ignore;\n }\n return DEFAULT_FORBIDDEN_FILES_IGNORE;\n }\n\n /**\n * Create a violation for a forbidden file\n */\n private createViolation(file: string, pattern: string): Violation {\n const customMessage = this.config.message;\n const baseMessage = `Forbidden file exists: ${file} (matched pattern: ${pattern})`;\n const message = customMessage ? `${baseMessage}. ${customMessage}` : baseMessage;\n\n return {\n rule: `${this.rule}.exists`,\n tool: this.toolId,\n file,\n message,\n severity: \"error\",\n };\n }\n}\n","import { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Hooks configuration from standards.toml */\ninterface HooksConfig {\n enabled?: boolean;\n require_husky?: boolean;\n require_hooks?: string[];\n commands?: Record<string, string[]>;\n protected_branches?: string[];\n}\n\n/**\n * Git hooks validation runner.\n * Checks that husky is installed and required hooks are configured.\n */\nexport class HooksRunner extends BaseProcessToolRunner {\n readonly name = \"Hooks\";\n readonly rule = \"process.hooks\";\n readonly toolId = \"hooks\";\n\n private config: HooksConfig = {\n enabled: false,\n require_husky: true,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: HooksConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Check if husky is installed */\n private checkHuskyInstalled(projectRoot: string): Violation | null {\n if (this.config.require_husky === false) {\n return null;\n }\n if (this.directoryExists(projectRoot, \".husky\")) {\n return null;\n }\n return {\n rule: `${this.rule}.husky`,\n tool: this.toolId,\n message: \"Husky not installed (.husky/ directory not found)\",\n severity: \"error\",\n };\n }\n\n /** Check that required hooks exist */\n private checkRequiredHooks(projectRoot: string): Violation[] {\n const hooks = this.config.require_hooks ?? [];\n return hooks\n .filter((hook) => !this.fileExists(projectRoot, `.husky/${hook}`))\n .map((hook) => ({\n rule: `${this.rule}.${hook}`,\n tool: this.toolId,\n file: `.husky/${hook}`,\n message: `Required hook '${hook}' not found`,\n severity: \"error\" as const,\n }));\n }\n\n /** Check that hooks contain required commands */\n private checkHookCommands(projectRoot: string): Violation[] {\n const commands = this.config.commands ?? {};\n const violations: Violation[] = [];\n\n for (const [hook, requiredCommands] of Object.entries(commands)) {\n const hookPath = `.husky/${hook}`;\n if (!this.fileExists(projectRoot, hookPath)) {\n continue;\n }\n for (const command of requiredCommands) {\n if (!this.fileContains(projectRoot, hookPath, command)) {\n violations.push({\n rule: `${this.rule}.${hook}.commands`,\n tool: this.toolId,\n file: hookPath,\n message: `Hook '${hook}' does not contain required command: ${command}`,\n severity: \"error\",\n });\n }\n }\n }\n return violations;\n }\n\n /** Create a pre-push hook violation */\n private createPrePushViolation(ruleId: string, message: string): Violation {\n return {\n rule: `${this.rule}.${ruleId}`,\n tool: this.toolId,\n file: \".husky/pre-push\",\n message,\n severity: \"error\",\n };\n }\n\n /** Check if pre-push hook has branch detection */\n private hasBranchDetection(projectRoot: string): boolean {\n const branchDetectionPatterns = [\n \"git rev-parse --abbrev-ref HEAD\",\n \"git branch --show-current\",\n \"git symbolic-ref --short HEAD\",\n ];\n const hookPath = \".husky/pre-push\";\n return branchDetectionPatterns.some((pattern) =>\n this.fileContains(projectRoot, hookPath, pattern)\n );\n }\n\n /** Check that pre-push hook prevents direct pushes to protected branches */\n private checkProtectedBranches(projectRoot: string): Violation[] {\n const protectedBranches = this.config.protected_branches ?? [];\n if (protectedBranches.length === 0) {\n return [];\n }\n\n const hookPath = \".husky/pre-push\";\n\n // First check if pre-push hook exists\n if (!this.fileExists(projectRoot, hookPath)) {\n return [\n this.createPrePushViolation(\n \"pre-push\",\n \"Pre-push hook not found. Required for protected branch enforcement.\"\n ),\n ];\n }\n\n // Check for branch detection pattern\n if (!this.hasBranchDetection(projectRoot)) {\n return [\n this.createPrePushViolation(\n \"pre-push.branch-detection\",\n \"Pre-push hook does not detect current branch. Expected one of: git rev-parse --abbrev-ref HEAD, git branch --show-current\"\n ),\n ];\n }\n\n // Check that each protected branch is referenced in the hook\n return protectedBranches\n .filter((branch) => !this.fileContains(projectRoot, hookPath, branch))\n .map((branch) =>\n this.createPrePushViolation(\n \"pre-push.protected-branch\",\n `Pre-push hook does not check for protected branch \"${branch}\"`\n )\n );\n }\n\n /** Run hooks validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n // Check husky first - if not installed, can't check hooks\n const huskyViolation = this.checkHuskyInstalled(projectRoot);\n if (huskyViolation) {\n return this.fromViolations([huskyViolation], elapsed());\n }\n\n const violations = [\n ...this.checkRequiredHooks(projectRoot),\n ...this.checkHookCommands(projectRoot),\n ...this.checkProtectedBranches(projectRoot),\n ];\n\n return this.fromViolations(violations, elapsed());\n }\n}\n","import * as fs from \"node:fs\";\n\nimport { minimatch } from \"minimatch\";\n\nimport { GITHUB_API } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** PR configuration from standards.toml */\ninterface PrConfig {\n enabled?: boolean;\n max_files?: number;\n max_lines?: number;\n require_issue?: boolean;\n issue_keywords?: string[];\n exclude?: string[];\n}\n\n/** Default keywords that link PRs to issues */\nconst DEFAULT_ISSUE_KEYWORDS = [\"Closes\", \"Fixes\", \"Resolves\"];\n\n/** GitHub PR event payload structure (partial) */\ninterface GitHubPrEventPayload {\n pull_request?: {\n number?: number;\n changed_files?: number;\n additions?: number;\n deletions?: number;\n title?: string;\n body?: string;\n };\n repository?: {\n full_name?: string;\n };\n}\n\n/** GitHub PR file from API response */\ninterface GitHubPrFile {\n filename: string;\n additions: number;\n deletions: number;\n}\n\n/**\n * PR size validation runner.\n * Checks that the PR does not exceed configured size limits.\n * Reads PR data from GITHUB_EVENT_PATH environment variable (GitHub Actions context).\n */\nexport class PrRunner extends BaseProcessToolRunner {\n readonly name = \"PR\";\n readonly rule = \"process.pr\";\n readonly toolId = \"pr\";\n\n private config: PrConfig = {\n enabled: false,\n require_issue: false,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: PrConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Read PR data from GitHub event payload */\n private readPrEventPayload(): GitHubPrEventPayload | null {\n const eventPath = process.env.GITHUB_EVENT_PATH;\n if (!eventPath) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(eventPath, \"utf-8\");\n return JSON.parse(content) as GitHubPrEventPayload;\n } catch {\n return null;\n }\n }\n\n /** Get PR data from payload, returns null if not available */\n private getPrData(\n payload: GitHubPrEventPayload | null\n ): GitHubPrEventPayload[\"pull_request\"] | null {\n return payload?.pull_request ?? null;\n }\n\n /** Fetch a single page of PR files from GitHub API */\n private async fetchPrFilesPage(\n repo: string,\n prNumber: number,\n page: number,\n token: string\n ): Promise<GitHubPrFile[] | null> {\n const response = await fetch(\n `${GITHUB_API.baseUrl}/repos/${repo}/pulls/${prNumber}/files?per_page=${GITHUB_API.perPage}&page=${page}`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"application/vnd.github.v3+json\",\n },\n }\n );\n return response.ok ? ((await response.json()) as GitHubPrFile[]) : null;\n }\n\n /**\n * Fetch PR files from GitHub API with pagination support.\n * Returns empty array if GITHUB_TOKEN is not available or API fails.\n */\n private async fetchPrFiles(repo: string, prNumber: number): Promise<GitHubPrFile[]> {\n const token = process.env.GITHUB_TOKEN;\n if (!token) {\n return [];\n }\n\n const fetchPage = async (\n page: number,\n accumulated: GitHubPrFile[]\n ): Promise<GitHubPrFile[]> => {\n const pageFiles = await this.fetchPrFilesPage(repo, prNumber, page, token);\n if (!pageFiles) {\n return [];\n }\n const allFiles = [...accumulated, ...pageFiles];\n return pageFiles.length < 100 ? allFiles : fetchPage(page + 1, allFiles);\n };\n\n try {\n return await fetchPage(1, []);\n } catch {\n return [];\n }\n }\n\n /**\n * Filter files that match exclude patterns.\n * Returns only files that do NOT match any exclude pattern.\n */\n private filterExcludedFiles(files: GitHubPrFile[], excludePatterns: string[]): GitHubPrFile[] {\n if (excludePatterns.length === 0) {\n return files;\n }\n\n return files.filter(\n (file) => !excludePatterns.some((pattern) => minimatch(file.filename, pattern))\n );\n }\n\n /** Check if any validation is configured */\n private hasValidationConfigured(): boolean {\n return (\n this.config.max_files !== undefined ||\n this.config.max_lines !== undefined ||\n this.config.require_issue === true\n );\n }\n\n /** Check if PR body contains issue reference with keyword */\n private findIssueReference(text: string | undefined): string | null {\n if (!text) {\n return null;\n }\n\n const keywords = this.config.issue_keywords ?? DEFAULT_ISSUE_KEYWORDS;\n // Build pattern: \\b(Closes|Fixes|Resolves)\\s+#(\\d+)\n // Word boundary \\b prevents matching \"Closes\" in \"ClosesFile\"\n const keywordPattern = keywords.map((k) => k.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")).join(\"|\");\n const regex = new RegExp(`\\\\b(?:${keywordPattern})\\\\s+#(\\\\d+)`, \"i\");\n const match = text.match(regex);\n return match ? match[1] : null;\n }\n\n /** Validate that PR contains issue reference */\n private validateIssueReference(pr: NonNullable<GitHubPrEventPayload[\"pull_request\"]>): {\n passed: boolean;\n error?: string;\n } {\n if (!this.config.require_issue) {\n return { passed: true };\n }\n\n // Check body first (primary location for issue links)\n const bodyIssue = this.findIssueReference(pr.body);\n if (bodyIssue) {\n return { passed: true };\n }\n\n // Also check title as fallback\n const titleIssue = this.findIssueReference(pr.title);\n if (titleIssue) {\n return { passed: true };\n }\n\n const keywords = this.config.issue_keywords ?? DEFAULT_ISSUE_KEYWORDS;\n return {\n passed: false,\n error: `PR does not contain issue reference. Include \"${keywords[0]} #<issue-number>\" in the PR description.`,\n };\n }\n\n /** Get PR counts, applying exclusions if configured */\n private async getPrCounts(\n pr: NonNullable<GitHubPrEventPayload[\"pull_request\"]>,\n repo: string | undefined\n ): Promise<{ fileCount: number; lineCount: number }> {\n const defaultCounts = {\n fileCount: pr.changed_files ?? 0,\n lineCount: (pr.additions ?? 0) + (pr.deletions ?? 0),\n };\n\n if (!this.config.exclude?.length || !repo || !pr.number) {\n return defaultCounts;\n }\n\n const files = await this.fetchPrFiles(repo, pr.number);\n if (files.length === 0) {\n return defaultCounts; // API failed, fall back\n }\n\n const filtered = this.filterExcludedFiles(files, this.config.exclude);\n return {\n fileCount: filtered.length,\n lineCount: filtered.reduce((sum, f) => sum + f.additions + f.deletions, 0),\n };\n }\n\n /** Check size limits and return violations */\n private checkSizeLimits(fileCount: number, lineCount: number): Violation[] {\n const violations: Violation[] = [];\n\n if (this.config.max_files !== undefined && fileCount > this.config.max_files) {\n violations.push({\n rule: `${this.rule}.max_files`,\n tool: this.toolId,\n message: `PR has ${fileCount} files changed (max: ${this.config.max_files})`,\n severity: \"error\",\n });\n }\n\n if (this.config.max_lines !== undefined && lineCount > this.config.max_lines) {\n violations.push({\n rule: `${this.rule}.max_lines`,\n tool: this.toolId,\n message: `PR has ${lineCount} lines changed (max: ${this.config.max_lines})`,\n severity: \"error\",\n });\n }\n\n return violations;\n }\n\n /** Validate PR size against configured limits */\n private async validatePrSize(\n pr: NonNullable<GitHubPrEventPayload[\"pull_request\"]>,\n repo: string | undefined,\n elapsed: () => number\n ): Promise<CheckResult> {\n const { fileCount, lineCount } = await this.getPrCounts(pr, repo);\n const violations = this.checkSizeLimits(fileCount, lineCount);\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n\n /** Collect all violations from PR validations */\n private async collectViolations(\n prData: NonNullable<GitHubPrEventPayload[\"pull_request\"]>,\n repo: string | undefined,\n elapsed: () => number\n ): Promise<Violation[]> {\n const violations: Violation[] = [];\n\n const sizeResult = await this.validatePrSize(prData, repo, elapsed);\n if (!sizeResult.passed) {\n violations.push(...sizeResult.violations);\n }\n\n const issueResult = this.validateIssueReference(prData);\n if (!issueResult.passed && issueResult.error) {\n violations.push({\n rule: `${this.rule}.require_issue`,\n tool: this.toolId,\n message: issueResult.error,\n severity: \"error\",\n });\n }\n\n return violations;\n }\n\n /** Run PR validation */\n async run(_projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!this.hasValidationConfigured()) {\n return this.skip(\"No PR validation configured\", elapsed());\n }\n\n const payload = this.readPrEventPayload();\n const prData = this.getPrData(payload);\n if (!prData) {\n return this.skip(\"Not in a PR context (GITHUB_EVENT_PATH not set or no PR data)\", elapsed());\n }\n\n const repo = payload?.repository?.full_name;\n const violations = await this.collectViolations(prData, repo, elapsed);\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n}\n","/* eslint-disable max-lines */\nimport { execa } from \"execa\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Bypass actor configuration */\ninterface BypassActorConfig {\n actor_type: \"Integration\" | \"OrganizationAdmin\" | \"RepositoryRole\" | \"Team\" | \"DeployKey\";\n actor_id?: number;\n bypass_mode?: \"always\" | \"pull_request\";\n}\n\n/** Ruleset configuration (uses GitHub Rulesets API) */\ninterface RulesetConfig {\n name?: string;\n branch?: string;\n enforcement?: \"active\" | \"evaluate\" | \"disabled\";\n required_reviews?: number;\n dismiss_stale_reviews?: boolean;\n require_code_owner_reviews?: boolean;\n require_status_checks?: string[];\n require_branches_up_to_date?: boolean;\n require_signed_commits?: boolean;\n enforce_admins?: boolean;\n bypass_actors?: BypassActorConfig[];\n}\n\n/** Tag protection configuration */\ninterface TagProtectionConfig {\n patterns?: string[];\n prevent_deletion?: boolean;\n prevent_update?: boolean;\n}\n\n/** Repository configuration */\ninterface RepoConfig {\n enabled?: boolean;\n require_branch_protection?: boolean;\n require_codeowners?: boolean;\n ruleset?: RulesetConfig;\n tag_protection?: TagProtectionConfig;\n}\n\n/** GitHub Ruleset bypass actor */\ninterface RulesetBypassActor {\n actor_id: number | null;\n actor_type: string;\n bypass_mode: string;\n}\n\n/** GitHub Ruleset rule */\ninterface RulesetRule {\n type: string;\n parameters?: {\n required_approving_review_count?: number;\n dismiss_stale_reviews_on_push?: boolean;\n require_code_owner_review?: boolean;\n required_status_checks?: { context: string }[];\n strict_required_status_checks_policy?: boolean;\n };\n}\n\n/** GitHub Ruleset response */\ninterface RulesetResponse {\n id: number;\n name: string;\n target: string;\n enforcement: string;\n conditions?: { ref_name?: { include?: string[]; exclude?: string[] } };\n bypass_actors?: RulesetBypassActor[];\n rules?: RulesetRule[];\n}\n\n/** Runner for repository settings validation */\nexport class RepoRunner extends BaseProcessToolRunner {\n readonly name = \"Repository\";\n readonly rule = \"process.repo\";\n readonly toolId = \"repo\";\n private config: RepoConfig = {\n enabled: false,\n require_branch_protection: false,\n require_codeowners: false,\n };\n\n setConfig(config: RepoConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!(await this.isGhCliAvailable())) {\n return this.skip(\"GitHub CLI (gh) not available\", elapsed());\n }\n const repoInfo = await this.getRepoInfo(projectRoot);\n if (!repoInfo) {\n return this.skip(\"Could not determine GitHub repository from git remote\", elapsed());\n }\n\n const violations = await this.collectViolations(projectRoot, repoInfo);\n return this.fromViolations(violations, elapsed());\n }\n\n private async collectViolations(\n projectRoot: string,\n repoInfo: { owner: string; repo: string }\n ): Promise<Violation[]> {\n const violations: Violation[] = [];\n if (this.config.require_codeowners) {\n violations.push(...this.checkCodeowners(projectRoot));\n }\n if (this.config.require_branch_protection || this.config.ruleset) {\n violations.push(...(await this.checkBranchProtection(repoInfo)));\n }\n if (this.config.tag_protection?.patterns?.length) {\n violations.push(...(await this.checkTagProtection(repoInfo)));\n }\n return violations;\n }\n\n private async isGhCliAvailable(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n }\n\n private async getRepoInfo(projectRoot: string): Promise<{ owner: string; repo: string } | null> {\n try {\n // Use gh to get the current repo\n const result = await execa(\"gh\", [\"repo\", \"view\", \"--json\", \"owner,name\"], {\n cwd: projectRoot,\n });\n const data = JSON.parse(result.stdout) as { owner: { login: string }; name: string };\n return { owner: data.owner.login, repo: data.name };\n } catch {\n return null;\n }\n }\n\n private checkCodeowners(projectRoot: string): Violation[] {\n const locations = [\"CODEOWNERS\", \".github/CODEOWNERS\", \"docs/CODEOWNERS\"];\n if (locations.some((loc) => this.fileExists(projectRoot, loc))) {\n return [];\n }\n return [\n {\n rule: `${this.rule}.codeowners`,\n tool: this.toolId,\n severity: \"error\",\n message:\n \"CODEOWNERS file not found (checked CODEOWNERS, .github/CODEOWNERS, docs/CODEOWNERS)\",\n },\n ];\n }\n\n private async checkBranchProtection(repoInfo: {\n owner: string;\n repo: string;\n }): Promise<Violation[]> {\n const rulesetConfig = this.config.ruleset;\n const branch = rulesetConfig?.branch ?? \"main\";\n\n try {\n const result = await execa(\"gh\", [\n \"api\",\n `repos/${repoInfo.owner}/${repoInfo.repo}/rulesets`,\n ]);\n\n const rulesets = JSON.parse(result.stdout) as RulesetResponse[];\n const branchRuleset = this.findBranchRuleset(rulesets, branch);\n\n if (!branchRuleset) {\n return this.handleNoBranchRuleset(branch);\n }\n\n return this.validateBranchRulesetSettings(branchRuleset, branch);\n } catch (error) {\n return this.handleBranchProtectionError(error, branch);\n }\n }\n\n private findBranchRuleset(\n rulesets: RulesetResponse[],\n branch: string\n ): RulesetResponse | undefined {\n return rulesets.find(\n (r) =>\n r.target === \"branch\" &&\n r.enforcement === \"active\" &&\n this.matchesBranch(r.conditions?.ref_name?.include ?? [], branch)\n );\n }\n\n private matchesBranch(patterns: string[], branch: string): boolean {\n for (const pattern of patterns) {\n const cleanPattern = pattern.replace(/^refs\\/heads\\//, \"\");\n if (cleanPattern === branch) {\n return true;\n }\n if (cleanPattern === \"~DEFAULT_BRANCH\" && branch === \"main\") {\n return true;\n }\n if (cleanPattern === \"~ALL\") {\n return true;\n }\n if (cleanPattern.includes(\"*\")) {\n const regex = new RegExp(`^${cleanPattern.replace(/\\*/g, \".*\")}$`);\n if (regex.test(branch)) {\n return true;\n }\n }\n }\n return false;\n }\n\n private handleNoBranchRuleset(branch: string): Violation[] {\n if (this.config.require_branch_protection) {\n return [\n {\n rule: `${this.rule}.branch_protection`,\n tool: this.toolId,\n message: `Branch '${branch}' does not have a branch protection ruleset`,\n severity: \"error\",\n },\n ];\n }\n return [];\n }\n\n private handleBranchProtectionError(error: unknown, branch: string): Violation[] {\n const msg = error instanceof Error ? error.message : String(error);\n const v = (message: string, severity: \"error\" | \"warning\" = \"error\"): Violation[] => [\n { rule: `${this.rule}.branch_protection`, tool: this.toolId, message, severity },\n ];\n if (msg.includes(\"404\")) {\n return this.config.require_branch_protection\n ? v(`Branch '${branch}' does not have branch protection enabled`)\n : [];\n }\n if (msg.includes(\"403\") || msg.includes(\"Must have admin rights\")) {\n return v(\n \"Cannot check branch protection: insufficient permissions (requires admin access)\",\n \"warning\"\n );\n }\n return v(`Failed to check branch protection: ${msg}`);\n }\n\n private validateBranchRulesetSettings(ruleset: RulesetResponse, branch: string): Violation[] {\n const bpConfig = this.config.ruleset;\n if (!bpConfig) {\n return [];\n }\n\n const violations: Violation[] = [];\n const rules = ruleset.rules ?? [];\n\n const prRule = rules.find((r) => r.type === \"pull_request\");\n violations.push(...this.checkPullRequestRuleSettings(prRule, bpConfig, branch));\n\n const statusRule = rules.find((r) => r.type === \"required_status_checks\");\n violations.push(...this.checkStatusChecksRuleSettings(statusRule, bpConfig, branch));\n\n if (bpConfig.require_signed_commits === true) {\n if (!rules.some((r) => r.type === \"required_signatures\")) {\n violations.push({\n rule: `${this.rule}.branch_protection.require_signed_commits`,\n tool: this.toolId,\n message: `Branch '${branch}' does not require signed commits`,\n severity: \"error\",\n });\n }\n }\n\n violations.push(...this.checkBypassActorsSettings(ruleset, bpConfig, branch));\n\n return violations;\n }\n\n // eslint-disable-next-line complexity\n private checkPullRequestRuleSettings(\n prRule: RulesetRule | undefined,\n bpConfig: RulesetConfig,\n branch: string\n ): Violation[] {\n const violations: Violation[] = [];\n const params = prRule?.parameters;\n\n if (bpConfig.required_reviews !== undefined) {\n const actualReviews = params?.required_approving_review_count ?? 0;\n if (actualReviews < bpConfig.required_reviews) {\n violations.push({\n rule: `${this.rule}.branch_protection.required_reviews`,\n tool: this.toolId,\n message: `Branch '${branch}' requires ${actualReviews} reviews, expected at least ${bpConfig.required_reviews}`,\n severity: \"error\",\n });\n }\n }\n\n if (bpConfig.dismiss_stale_reviews === true) {\n if (!(params?.dismiss_stale_reviews_on_push ?? false)) {\n violations.push({\n rule: `${this.rule}.branch_protection.dismiss_stale_reviews`,\n tool: this.toolId,\n message: `Branch '${branch}' does not dismiss stale reviews on new commits`,\n severity: \"error\",\n });\n }\n }\n\n if (bpConfig.require_code_owner_reviews === true) {\n if (!(params?.require_code_owner_review ?? false)) {\n violations.push({\n rule: `${this.rule}.branch_protection.require_code_owner_reviews`,\n tool: this.toolId,\n message: `Branch '${branch}' does not require code owner reviews`,\n severity: \"error\",\n });\n }\n }\n\n return violations;\n }\n\n // eslint-disable-next-line complexity\n private checkStatusChecksRuleSettings(\n statusRule: RulesetRule | undefined,\n bpConfig: RulesetConfig,\n branch: string\n ): Violation[] {\n const violations: Violation[] = [];\n const params = statusRule?.parameters;\n\n if (bpConfig.require_status_checks && bpConfig.require_status_checks.length > 0) {\n const actualChecks = params?.required_status_checks?.map((c) => c.context) ?? [];\n const missingChecks = bpConfig.require_status_checks.filter(\n (check) => !actualChecks.includes(check)\n );\n if (missingChecks.length > 0) {\n violations.push({\n rule: `${this.rule}.branch_protection.require_status_checks`,\n tool: this.toolId,\n message: `Branch '${branch}' missing required status checks: ${missingChecks.join(\", \")}`,\n severity: \"error\",\n });\n }\n }\n\n if (bpConfig.require_branches_up_to_date === true) {\n if (!(params?.strict_required_status_checks_policy ?? false)) {\n violations.push({\n rule: `${this.rule}.branch_protection.require_branches_up_to_date`,\n tool: this.toolId,\n message: `Branch '${branch}' does not require branches to be up to date before merging`,\n severity: \"error\",\n });\n }\n }\n\n return violations;\n }\n\n private checkBypassActorsSettings(\n ruleset: RulesetResponse,\n bpConfig: RulesetConfig,\n branch: string\n ): Violation[] {\n const violations: Violation[] = [];\n const actualBypass = ruleset.bypass_actors ?? [];\n\n // enforce_admins means no bypass actors should be configured\n if (bpConfig.enforce_admins === true && actualBypass.length > 0) {\n violations.push({\n rule: `${this.rule}.branch_protection.enforce_admins`,\n tool: this.toolId,\n message: `Branch '${branch}' has bypass actors configured but enforce_admins requires no bypasses`,\n severity: \"error\",\n });\n }\n\n // Check if configured bypass actors are present\n if (bpConfig.bypass_actors && bpConfig.bypass_actors.length > 0) {\n for (const expected of bpConfig.bypass_actors) {\n const found = actualBypass.some(\n (a) =>\n a.actor_type === expected.actor_type &&\n (expected.actor_id === undefined || a.actor_id === expected.actor_id)\n );\n if (!found) {\n violations.push({\n rule: `${this.rule}.branch_protection.bypass_actors`,\n tool: this.toolId,\n message: `Branch '${branch}' missing bypass actor: ${expected.actor_type}${expected.actor_id ? ` (id: ${expected.actor_id})` : \"\"}`,\n severity: \"error\",\n });\n }\n }\n }\n\n return violations;\n }\n\n // ===========================================================================\n // Tag Protection\n // ===========================================================================\n\n private async checkTagProtection(repoInfo: {\n owner: string;\n repo: string;\n }): Promise<Violation[]> {\n try {\n const result = await execa(\"gh\", [\n \"api\",\n `repos/${repoInfo.owner}/${repoInfo.repo}/rulesets`,\n ]);\n\n const rulesets = JSON.parse(result.stdout) as RulesetResponse[];\n return this.validateTagProtection(rulesets);\n } catch (error) {\n return this.handleTagProtectionError(error);\n }\n }\n\n private validateTagProtection(rulesets: RulesetResponse[]): Violation[] {\n const cfg = this.config.tag_protection;\n if (!cfg?.patterns?.length) {\n return [];\n }\n const ruleset = rulesets.find((r) => r.target === \"tag\" && r.enforcement === \"active\");\n if (!ruleset) {\n return [this.tagViolation(\"tag_protection\", \"No active tag protection ruleset found\")];\n }\n return [\n ...this.checkTagPatterns(cfg.patterns, ruleset.conditions?.ref_name?.include ?? []),\n ...this.checkTagRules(cfg, ruleset.rules ?? []),\n ];\n }\n\n private checkTagPatterns(expected: string[], actual: string[]): Violation[] {\n const exp = expected.map((p) => `refs/tags/${p}`).sort();\n const act = [...actual].sort();\n if (exp.length === act.length && exp.every((v, i) => v === act[i])) {\n return [];\n }\n const found = act.map((p) => p.replace(/^refs\\/tags\\//, \"\")).join(\", \");\n return [\n this.tagViolation(\n \"tag_protection.patterns\",\n `Tag protection patterns mismatch: expected [${expected.join(\", \")}], found [${found}]`\n ),\n ];\n }\n\n private checkTagRules(cfg: TagProtectionConfig, rules: { type: string }[]): Violation[] {\n const v: Violation[] = [];\n if (cfg.prevent_deletion !== false && !rules.some((r) => r.type === \"deletion\")) {\n v.push(\n this.tagViolation(\n \"tag_protection.prevent_deletion\",\n \"Tag protection does not prevent deletion\"\n )\n );\n }\n if (cfg.prevent_update !== false && !rules.some((r) => r.type === \"update\")) {\n v.push(\n this.tagViolation(\n \"tag_protection.prevent_update\",\n \"Tag protection does not prevent updates (force-push)\"\n )\n );\n }\n return v;\n }\n\n private tagViolation(\n rule: string,\n message: string,\n severity: \"error\" | \"warning\" = \"error\"\n ): Violation {\n return { rule: `${this.rule}.${rule}`, tool: this.toolId, message, severity };\n }\n\n private handleTagProtectionError(error: unknown): Violation[] {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes(\"403\") || msg.includes(\"Must have admin rights\")) {\n return [\n this.tagViolation(\n \"tag_protection\",\n \"Cannot check tag protection: insufficient permissions (requires admin access)\",\n \"warning\"\n ),\n ];\n }\n return [this.tagViolation(\"tag_protection\", `Failed to check tag protection: ${msg}`)];\n }\n}\n","import { execa } from \"execa\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Tickets configuration from standards.toml */\ninterface TicketsConfig {\n enabled?: boolean;\n pattern?: string;\n require_in_commits?: boolean;\n require_in_branch?: boolean;\n}\n\n/**\n * Ticket reference validation runner.\n * Checks that commit messages and/or branch names contain ticket references.\n */\nexport class TicketsRunner extends BaseProcessToolRunner {\n readonly name = \"Tickets\";\n readonly rule = \"process.tickets\";\n readonly toolId = \"tickets\";\n\n private config: TicketsConfig = {\n enabled: false,\n require_in_commits: true,\n require_in_branch: false,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: TicketsConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Get the current git branch name */\n private async getCurrentBranch(projectRoot: string): Promise<string | null> {\n try {\n const result = await execa(\"git\", [\"branch\", \"--show-current\"], {\n cwd: projectRoot,\n });\n return result.stdout.trim() || null;\n } catch {\n return null;\n }\n }\n\n /** Get the HEAD commit message */\n private async getHeadCommitMessage(projectRoot: string): Promise<string | null> {\n try {\n const result = await execa(\"git\", [\"log\", \"-1\", \"--format=%s\"], {\n cwd: projectRoot,\n });\n return result.stdout.trim() || null;\n } catch {\n return null;\n }\n }\n\n /** Check if text contains a match for the ticket pattern */\n private matchesPattern(text: string, pattern: string): boolean {\n try {\n const regex = new RegExp(pattern);\n return regex.test(text);\n } catch {\n return false;\n }\n }\n\n /** Validate the regex pattern is valid */\n private isValidPattern(pattern: string): boolean {\n try {\n new RegExp(pattern);\n return true;\n } catch {\n return false;\n }\n }\n\n /** Check configuration validity */\n private hasValidConfig(): { valid: boolean; reason?: string } {\n if (!this.config.pattern) {\n return { valid: false, reason: \"No ticket pattern configured\" };\n }\n if (!this.isValidPattern(this.config.pattern)) {\n return { valid: false, reason: `Invalid regex pattern: ${this.config.pattern}` };\n }\n if (!this.config.require_in_commits && !this.config.require_in_branch) {\n return {\n valid: false,\n reason: \"Neither require_in_commits nor require_in_branch is enabled\",\n };\n }\n return { valid: true };\n }\n\n /** Validate branch name contains ticket reference */\n private async validateBranch(\n projectRoot: string,\n pattern: string\n ): Promise<{ skip?: string; violation?: Violation }> {\n const branch = await this.getCurrentBranch(projectRoot);\n if (!branch) {\n return { skip: \"Not in a git repository or no branch checked out\" };\n }\n if (!this.matchesPattern(branch, pattern)) {\n return {\n violation: {\n rule: `${this.rule}.branch`,\n tool: this.toolId,\n message: `Branch '${branch}' does not contain ticket reference matching: ${pattern}`,\n severity: \"error\",\n },\n };\n }\n return {};\n }\n\n /** Validate commit message contains ticket reference */\n private async validateCommit(\n projectRoot: string,\n pattern: string\n ): Promise<{ skip?: string; violation?: Violation }> {\n const commitMessage = await this.getHeadCommitMessage(projectRoot);\n if (!commitMessage) {\n return { skip: \"Not in a git repository or no commits\" };\n }\n if (!this.matchesPattern(commitMessage, pattern)) {\n return {\n violation: {\n rule: `${this.rule}.commits`,\n tool: this.toolId,\n message: `Commit message does not contain ticket reference matching: ${pattern}`,\n severity: \"error\",\n },\n };\n }\n return {};\n }\n\n /** Perform all validations and collect results */\n private async runValidations(\n projectRoot: string,\n pattern: string\n ): Promise<{ skip?: string; violations: Violation[] }> {\n const violations: Violation[] = [];\n\n if (this.config.require_in_branch) {\n const result = await this.validateBranch(projectRoot, pattern);\n if (result.skip) {\n return { skip: result.skip, violations: [] };\n }\n if (result.violation) {\n violations.push(result.violation);\n }\n }\n\n if (this.config.require_in_commits) {\n const result = await this.validateCommit(projectRoot, pattern);\n if (result.skip) {\n return { skip: result.skip, violations: [] };\n }\n if (result.violation) {\n violations.push(result.violation);\n }\n }\n\n return { violations };\n }\n\n /** Run ticket validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const configCheck = this.hasValidConfig();\n if (!configCheck.valid) {\n return this.skip(configCheck.reason ?? \"Invalid configuration\", elapsed());\n }\n\n const pattern = this.config.pattern as string;\n const { skip, violations } = await this.runValidations(projectRoot, pattern);\n\n if (skip) {\n return this.skip(skip, elapsed());\n }\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n}\n","import { type Config } from \"../core/index.js\";\nimport { type CheckResult, type DomainResult, DomainResultBuilder, type IToolRunner } from \"../core/index.js\";\nimport {\n BackupsRunner,\n BranchesRunner,\n ChangesetsRunner,\n CiRunner,\n CodeownersRunner,\n CommitsRunner,\n CoverageRunner,\n DocsRunner,\n ForbiddenFilesRunner,\n HooksRunner,\n PrRunner,\n RepoRunner,\n TicketsRunner,\n} from \"./tools/index.js\";\n\n// Export tool runners for direct access\nexport {\n BackupsRunner,\n BaseProcessToolRunner,\n BranchesRunner,\n ChangesetsRunner,\n CiRunner,\n CodeownersRunner,\n CommitsRunner,\n CoverageRunner,\n DocsRunner,\n ForbiddenFilesRunner,\n HooksRunner,\n PrRunner,\n RepoRunner,\n TicketsRunner,\n} from \"./tools/index.js\";\n\n/** Tool configuration entry mapping config getter to runner or runner factory */\ninterface ToolEntry {\n isEnabled: (config: Config) => boolean;\n runner: IToolRunner | ((config: Config) => IToolRunner);\n}\n\n/** Check if a tool is enabled in config */\nfunction isEnabled(toolConfig: { enabled?: boolean } | undefined): boolean {\n return toolConfig?.enabled === true;\n}\n\n/** Create a configured HooksRunner */\nfunction createHooksRunner(config: Config): HooksRunner {\n const runner = new HooksRunner();\n const hooksConfig = config.process?.hooks;\n if (hooksConfig) {\n runner.setConfig({\n enabled: hooksConfig.enabled,\n require_husky: hooksConfig.require_husky,\n require_hooks: hooksConfig.require_hooks,\n commands: hooksConfig.commands,\n protected_branches: hooksConfig.protected_branches,\n });\n }\n return runner;\n}\n\n/** Create a configured CiRunner */\nfunction createCiRunner(config: Config): CiRunner {\n const runner = new CiRunner();\n const ciConfig = config.process?.ci;\n if (ciConfig) {\n runner.setConfig({\n enabled: ciConfig.enabled,\n require_workflows: ciConfig.require_workflows,\n jobs: ciConfig.jobs,\n actions: ciConfig.actions,\n commands: ciConfig.commands,\n });\n }\n return runner;\n}\n\n/** Create a configured BranchesRunner */\nfunction createBranchesRunner(config: Config): BranchesRunner {\n const runner = new BranchesRunner();\n const branchesConfig = config.process?.branches;\n if (branchesConfig) {\n runner.setConfig({\n enabled: branchesConfig.enabled,\n pattern: branchesConfig.pattern,\n exclude: branchesConfig.exclude,\n require_issue: branchesConfig.require_issue,\n issue_pattern: branchesConfig.issue_pattern,\n });\n }\n return runner;\n}\n\n/** Create a configured CommitsRunner */\nfunction createCommitsRunner(config: Config): CommitsRunner {\n const runner = new CommitsRunner();\n const commitsConfig = config.process?.commits;\n if (commitsConfig) {\n runner.setConfig({\n enabled: commitsConfig.enabled,\n pattern: commitsConfig.pattern,\n types: commitsConfig.types,\n require_scope: commitsConfig.require_scope,\n max_subject_length: commitsConfig.max_subject_length,\n });\n }\n return runner;\n}\n\n/** Create a configured ChangesetsRunner */\nfunction createChangesetsRunner(config: Config): ChangesetsRunner {\n const runner = new ChangesetsRunner();\n const changesetsConfig = config.process?.changesets;\n if (changesetsConfig) {\n runner.setConfig({\n enabled: changesetsConfig.enabled,\n require_for_paths: changesetsConfig.require_for_paths,\n exclude_paths: changesetsConfig.exclude_paths,\n validate_format: changesetsConfig.validate_format,\n allowed_bump_types: changesetsConfig.allowed_bump_types,\n require_description: changesetsConfig.require_description,\n min_description_length: changesetsConfig.min_description_length,\n });\n }\n return runner;\n}\n\n/** Create a configured PrRunner */\nfunction createPrRunner(config: Config): PrRunner {\n const runner = new PrRunner();\n const prConfig = config.process?.pr;\n if (prConfig) {\n runner.setConfig({\n enabled: prConfig.enabled,\n max_files: prConfig.max_files,\n max_lines: prConfig.max_lines,\n require_issue: prConfig.require_issue,\n issue_keywords: prConfig.issue_keywords,\n });\n }\n return runner;\n}\n\n/** Create a configured TicketsRunner */\nfunction createTicketsRunner(config: Config): TicketsRunner {\n const runner = new TicketsRunner();\n const ticketsConfig = config.process?.tickets;\n if (ticketsConfig) {\n runner.setConfig({\n enabled: ticketsConfig.enabled,\n pattern: ticketsConfig.pattern,\n require_in_commits: ticketsConfig.require_in_commits,\n require_in_branch: ticketsConfig.require_in_branch,\n });\n }\n return runner;\n}\n\n/** Create a configured CoverageRunner */\nfunction createCoverageRunner(config: Config): CoverageRunner {\n const runner = new CoverageRunner();\n const coverageConfig = config.process?.coverage;\n if (coverageConfig) {\n runner.setConfig({\n enabled: coverageConfig.enabled,\n min_threshold: coverageConfig.min_threshold,\n enforce_in: coverageConfig.enforce_in,\n ci_workflow: coverageConfig.ci_workflow,\n ci_job: coverageConfig.ci_job,\n });\n }\n return runner;\n}\n\n/** Create a configured RepoRunner */\nfunction createRepoRunner(config: Config): RepoRunner {\n const runner = new RepoRunner();\n const repoConfig = config.process?.repo;\n if (repoConfig) {\n runner.setConfig({\n enabled: repoConfig.enabled,\n require_branch_protection: repoConfig.require_branch_protection,\n require_codeowners: repoConfig.require_codeowners,\n ruleset: repoConfig.ruleset,\n tag_protection: repoConfig.tag_protection,\n });\n }\n return runner;\n}\n\n/** Create a configured BackupsRunner */\nfunction createBackupsRunner(config: Config): BackupsRunner {\n const runner = new BackupsRunner();\n const backupsConfig = config.process?.backups;\n if (backupsConfig) {\n runner.setConfig({\n enabled: backupsConfig.enabled,\n bucket: backupsConfig.bucket,\n prefix: backupsConfig.prefix,\n max_age_hours: backupsConfig.max_age_hours,\n region: backupsConfig.region,\n });\n }\n return runner;\n}\n\n/** Create a configured CodeownersRunner */\nfunction createCodeownersRunner(config: Config): CodeownersRunner {\n const runner = new CodeownersRunner();\n const codeownersConfig = config.process?.codeowners;\n if (codeownersConfig) {\n runner.setConfig({\n enabled: codeownersConfig.enabled,\n rules: codeownersConfig.rules,\n });\n }\n return runner;\n}\n\n/** Create a configured DocsRunner */\nfunction createDocsRunner(config: Config): DocsRunner {\n const runner = new DocsRunner();\n const docsConfig = config.process?.docs;\n if (docsConfig) {\n runner.setConfig({\n enabled: docsConfig.enabled,\n path: docsConfig.path,\n enforcement: docsConfig.enforcement,\n allowlist: docsConfig.allowlist,\n max_files: docsConfig.max_files,\n max_file_lines: docsConfig.max_file_lines,\n max_total_kb: docsConfig.max_total_kb,\n staleness_days: docsConfig.staleness_days,\n stale_mappings: docsConfig.stale_mappings,\n min_coverage: docsConfig.min_coverage,\n coverage_paths: docsConfig.coverage_paths,\n exclude_patterns: docsConfig.exclude_patterns,\n types: docsConfig.types,\n });\n }\n return runner;\n}\n\n/** Create a configured ForbiddenFilesRunner */\nfunction createForbiddenFilesRunner(config: Config): ForbiddenFilesRunner {\n const runner = new ForbiddenFilesRunner();\n const forbiddenFilesConfig = config.process?.forbidden_files;\n if (forbiddenFilesConfig) {\n runner.setConfig({\n enabled: forbiddenFilesConfig.enabled,\n files: forbiddenFilesConfig.files,\n ignore: forbiddenFilesConfig.ignore,\n message: forbiddenFilesConfig.message,\n });\n }\n return runner;\n}\n\n/** All available process tools with their config predicates */\nconst toolRegistry: ToolEntry[] = [\n { isEnabled: (c) => isEnabled(c.process?.hooks), runner: createHooksRunner },\n { isEnabled: (c) => isEnabled(c.process?.ci), runner: createCiRunner },\n { isEnabled: (c) => isEnabled(c.process?.branches), runner: createBranchesRunner },\n { isEnabled: (c) => isEnabled(c.process?.commits), runner: createCommitsRunner },\n { isEnabled: (c) => isEnabled(c.process?.changesets), runner: createChangesetsRunner },\n { isEnabled: (c) => isEnabled(c.process?.pr), runner: createPrRunner },\n { isEnabled: (c) => isEnabled(c.process?.tickets), runner: createTicketsRunner },\n { isEnabled: (c) => isEnabled(c.process?.coverage), runner: createCoverageRunner },\n { isEnabled: (c) => isEnabled(c.process?.repo), runner: createRepoRunner },\n { isEnabled: (c) => isEnabled(c.process?.backups), runner: createBackupsRunner },\n { isEnabled: (c) => isEnabled(c.process?.codeowners), runner: createCodeownersRunner },\n { isEnabled: (c) => isEnabled(c.process?.docs), runner: createDocsRunner },\n { isEnabled: (c) => isEnabled(c.process?.forbidden_files), runner: createForbiddenFilesRunner },\n];\n\n/**\n * Get enabled tools based on configuration\n */\nfunction getEnabledTools(config: Config): IToolRunner[] {\n return toolRegistry\n .filter((entry) => entry.isEnabled(config))\n .map((entry) => (typeof entry.runner === \"function\" ? entry.runner(config) : entry.runner));\n}\n\n/**\n * Run all process checks based on configuration\n */\nexport async function runProcessChecks(projectRoot: string, config: Config): Promise<DomainResult> {\n const tools = getEnabledTools(config);\n const checks = await runTools(tools, projectRoot, \"run\");\n return DomainResultBuilder.fromChecks(\"process\", checks);\n}\n\n/**\n * Audit process configuration (check that configs exist without running tools)\n */\nexport async function auditProcessConfig(\n projectRoot: string,\n config: Config\n): Promise<DomainResult> {\n const tools = getEnabledTools(config);\n const checks = await runTools(tools, projectRoot, \"audit\");\n return DomainResultBuilder.fromChecks(\"process\", checks);\n}\n\n/**\n * Run tools in parallel with error isolation\n * Uses Promise.allSettled to ensure one failing tool doesn't lose all results\n */\nasync function runTools(\n tools: IToolRunner[],\n projectRoot: string,\n mode: \"run\" | \"audit\"\n): Promise<CheckResult[]> {\n const promises = tools.map((tool) =>\n mode === \"run\" ? tool.run(projectRoot) : tool.audit(projectRoot)\n );\n\n const results = await Promise.allSettled(promises);\n\n return results.map((result, index) => {\n if (result.status === \"fulfilled\") {\n return result.value;\n }\n\n // Handle rejected promise - create error result for the tool\n const tool = tools[index];\n const errorMessage = result.reason instanceof Error ? result.reason.message : \"Unknown error\";\n\n return {\n name: tool.name,\n rule: tool.rule,\n passed: false,\n violations: [\n {\n rule: tool.rule,\n tool: tool.toolId,\n message: `Tool error: ${errorMessage}`,\n severity: \"error\" as const,\n },\n ],\n skipped: false,\n duration: 0,\n };\n });\n}\n","import chalk from \"chalk\";\n\nimport { loadConfigAsync } from \"../../core/index.js\";\nimport { ExitCode } from \"../../core/index.js\";\nimport { scanRepository } from \"./scanner.js\";\nimport { type ScanOptions, type ScanResult } from \"./types.js\";\n\n// Re-export public API types\nexport {\n type RemoteRepoInfo,\n type ScanOptions,\n type ScanResult,\n type ValidateProcessOptions,\n type ValidateProcessResult,\n} from \"./types.js\";\n\n// Re-export scanner\nexport { scanRepository, validateProcess } from \"./scanner.js\";\n\n/** Format scan result as text */\nfunction formatScanText(result: ScanResult): string {\n const lines: string[] = [];\n\n lines.push(`Repository: ${result.repoInfo.owner}/${result.repoInfo.repo}`);\n lines.push(\"\");\n\n for (const check of result.checks) {\n if (check.skipped) {\n lines.push(chalk.yellow(`⊘ ${check.name} (skipped: ${check.skipReason})`));\n } else if (check.passed) {\n lines.push(chalk.green(`✓ ${check.name}`));\n } else {\n lines.push(chalk.red(`✗ ${check.name}`));\n for (const violation of check.violations) {\n lines.push(chalk.red(` • ${violation.message}`));\n }\n }\n }\n\n lines.push(\"\");\n lines.push(\n `Summary: ${result.summary.passedChecks} passed, ` +\n `${result.summary.failedChecks} failed, ` +\n `${result.summary.skippedChecks} skipped`\n );\n\n return lines.join(\"\\n\");\n}\n\n/** Format scan result as JSON */\nfunction formatScanJson(result: ScanResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n/** Run the scan command */\nexport async function runScan(options: ScanOptions): Promise<void> {\n try {\n const { config } = await loadConfigAsync(options.config);\n const result = await scanRepository(options.repo, config);\n\n const output = options.format === \"json\" ? formatScanJson(result) : formatScanText(result);\n\n process.stdout.write(`${output}\\n`);\n process.exit(result.passed ? ExitCode.SUCCESS : ExitCode.VIOLATIONS_FOUND);\n } catch (error) {\n if (options.format === \"json\") {\n const errorObj = {\n error: true,\n message: error instanceof Error ? error.message : String(error),\n code: (error as { code?: string }).code ?? \"UNKNOWN\",\n };\n process.stdout.write(`${JSON.stringify(errorObj, null, 2)}\\n`);\n } else {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));\n }\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n}\n","import { execa } from \"execa\";\n\nimport { type Config } from \"../../core/index.js\";\nimport { type CheckResult, ExitCode, type Violation } from \"../../core/index.js\";\nimport {\n checkRemoteFiles,\n isGhAvailable,\n parseRepoString,\n RemoteFetcherError,\n standardFileChecks,\n verifyRepoAccess,\n} from \"./remote-fetcher.js\";\nimport {\n type FileCheckConfig,\n type RemoteRepoInfo,\n type ScanResult,\n type ValidateProcessOptions,\n type ValidateProcessResult,\n} from \"./types.js\";\nimport { type RulesetResponse, validateRulesets } from \"./validators.js\";\n\n/** Fetch rulesets from GitHub API */\nasync function fetchRulesets(repoInfo: RemoteRepoInfo): Promise<RulesetResponse[]> {\n const result = await execa(\"gh\", [\"api\", `repos/${repoInfo.owner}/${repoInfo.repo}/rulesets`]);\n return JSON.parse(result.stdout) as RulesetResponse[];\n}\n\n/** Create a skipped check result */\nfunction createSkippedResult(\n name: string,\n rule: string,\n reason: string,\n duration: number\n): CheckResult {\n return { name, rule, passed: true, violations: [], skipped: true, skipReason: reason, duration };\n}\n\n/** Create an error check result */\nfunction createErrorResult(\n name: string,\n rule: string,\n message: string,\n duration: number\n): CheckResult {\n return {\n name,\n rule,\n passed: false,\n violations: [{ rule, tool: \"scan\", message, severity: \"error\" }],\n skipped: false,\n duration,\n };\n}\n\n/** Handle API errors for ruleset fetching */\nfunction handleRulesetError(\n error: unknown,\n repoConfig: NonNullable<Config[\"process\"]>[\"repo\"],\n elapsed: () => number\n): CheckResult {\n const msg = error instanceof Error ? error.message : String(error);\n\n if (msg.includes(\"403\") || msg.includes(\"Must have admin rights\")) {\n return createSkippedResult(\n \"Repository Settings\",\n \"process.repo\",\n \"Cannot check rulesets: insufficient permissions (requires admin access)\",\n elapsed()\n );\n }\n\n if (msg.includes(\"404\")) {\n const violations: Violation[] = [];\n if (repoConfig?.require_branch_protection) {\n violations.push({\n rule: \"process.repo.branch_protection\",\n tool: \"scan\",\n message: \"No branch protection rulesets configured\",\n severity: \"error\",\n });\n }\n return {\n name: \"Repository Settings\",\n rule: \"process.repo\",\n passed: violations.length === 0,\n violations,\n skipped: false,\n duration: elapsed(),\n };\n }\n\n return createErrorResult(\n \"Repository Settings\",\n \"process.repo\",\n `Failed to check rulesets: ${msg}`,\n elapsed()\n );\n}\n\n/** Check repository rulesets and branch protection */\nasync function checkRulesets(repoInfo: RemoteRepoInfo, config: Config): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n const repoConfig = config.process?.repo;\n\n if (!repoConfig?.enabled) {\n return createSkippedResult(\n \"Repository Settings\",\n \"process.repo\",\n \"Repository settings check not enabled in config\",\n elapsed()\n );\n }\n\n try {\n const rulesets = await fetchRulesets(repoInfo);\n const violations = validateRulesets(rulesets, repoConfig);\n\n return {\n name: \"Repository Settings\",\n rule: \"process.repo\",\n passed: violations.length === 0,\n violations,\n skipped: false,\n duration: elapsed(),\n };\n } catch (error) {\n return handleRulesetError(error, repoConfig, elapsed);\n }\n}\n\n/** Build file checks configuration from config */\nfunction buildFileChecks(config: Config): FileCheckConfig[] {\n const fileChecks: FileCheckConfig[] = [];\n\n if (config.process?.repo?.require_codeowners) {\n fileChecks.push({\n path: \"CODEOWNERS\",\n alternativePaths: [\".github/CODEOWNERS\", \"docs/CODEOWNERS\"],\n required: true,\n description: \"CODEOWNERS file for code review assignment\",\n });\n }\n\n fileChecks.push(\n ...standardFileChecks.filter((check) => !fileChecks.some((fc) => fc.path === check.path))\n );\n\n return fileChecks;\n}\n\n/** Convert file check results to violations */\nfunction fileResultsToViolations(\n results: { path: string; exists: boolean; checkedPaths: string[] }[],\n fileChecks: FileCheckConfig[]\n): Violation[] {\n const violations: Violation[] = [];\n\n for (const result of results) {\n const checkConfig = fileChecks.find((fc) => fc.path === result.path);\n if (!result.exists && checkConfig?.required) {\n violations.push({\n rule: `process.scan.files.${result.path.replace(/[./]/g, \"_\")}`,\n tool: \"scan\",\n message: `Required file not found: ${result.path} (checked: ${result.checkedPaths.join(\", \")})`,\n severity: \"error\",\n });\n }\n }\n\n return violations;\n}\n\n/** Check remote files for existence */\nasync function checkFiles(repoInfo: RemoteRepoInfo, config: Config): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n const fileChecks = buildFileChecks(config);\n\n if (fileChecks.length === 0) {\n return createSkippedResult(\n \"Repository Files\",\n \"process.scan.files\",\n \"No file checks configured\",\n elapsed()\n );\n }\n\n try {\n const results = await checkRemoteFiles(repoInfo, fileChecks);\n const violations = fileResultsToViolations(results, fileChecks);\n\n return {\n name: \"Repository Files\",\n rule: \"process.scan.files\",\n passed: violations.length === 0,\n violations,\n skipped: false,\n duration: elapsed(),\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return createErrorResult(\n \"Repository Files\",\n \"process.scan.files\",\n `Failed to check files: ${msg}`,\n elapsed()\n );\n }\n}\n\n/** Aggregate check results into scan result */\nfunction aggregateResults(repoInfo: RemoteRepoInfo, checks: CheckResult[]): ScanResult {\n const violations = checks.flatMap((c) => c.violations);\n const passedChecks = checks.filter((c) => c.passed && !c.skipped).length;\n const failedChecks = checks.filter((c) => !c.passed && !c.skipped).length;\n const skippedChecks = checks.filter((c) => c.skipped).length;\n\n return {\n repoInfo,\n checks,\n violations,\n passed: failedChecks === 0,\n summary: { totalChecks: checks.length, passedChecks, failedChecks, skippedChecks },\n };\n}\n\n/** Run all remote scans for a repository */\nexport async function scanRepository(repo: string, config: Config): Promise<ScanResult> {\n const repoInfo = parseRepoString(repo);\n\n if (!(await isGhAvailable())) {\n throw new RemoteFetcherError(\n \"GitHub CLI (gh) not available. Install it from https://cli.github.com/\",\n \"NO_GH\"\n );\n }\n\n await verifyRepoAccess(repoInfo);\n\n const [rulesetsResult, filesResult] = await Promise.all([\n checkRulesets(repoInfo, config),\n checkFiles(repoInfo, config),\n ]);\n\n return aggregateResults(repoInfo, [rulesetsResult, filesResult]);\n}\n\n/** Programmatic API for validating remote process checks */\nexport async function validateProcess(\n options: ValidateProcessOptions\n): Promise<ValidateProcessResult> {\n const { loadConfigAsync } = await import(\"../../core/index.js\");\n const { config } = await loadConfigAsync(options.config);\n const result = await scanRepository(options.repo, config);\n\n const fs = await import(\"node:fs\");\n const path = await import(\"node:path\");\n const { fileURLToPath } = await import(\"node:url\");\n\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const packageJsonPath = path.resolve(__dirname, \"..\", \"..\", \"..\", \"package.json\");\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\")) as { version: string };\n\n return {\n version: packageJson.version,\n repoInfo: result.repoInfo,\n domain: \"process\",\n checks: result.checks,\n summary: {\n totalChecks: result.summary.totalChecks,\n passedChecks: result.summary.passedChecks,\n failedChecks: result.summary.failedChecks,\n totalViolations: result.violations.length,\n exitCode: result.passed ? ExitCode.SUCCESS : ExitCode.VIOLATIONS_FOUND,\n },\n };\n}\n","import { execa } from \"execa\";\n\nimport { type FileCheckConfig, type FileCheckResult, type RemoteRepoInfo } from \"./types.js\";\n\n/** Error thrown when remote fetcher encounters an issue */\nexport class RemoteFetcherError extends Error {\n constructor(\n message: string,\n public readonly code: \"NO_GH\" | \"NO_REPO\" | \"NO_PERMISSION\" | \"API_ERROR\" | \"INVALID_REPO\"\n ) {\n super(message);\n this.name = \"RemoteFetcherError\";\n }\n}\n\n/** Parse owner/repo string into RemoteRepoInfo */\nexport function parseRepoString(repo: string): RemoteRepoInfo {\n const parts = repo.split(\"/\");\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new RemoteFetcherError(\n `Invalid repository format: \"${repo}\". Expected \"owner/repo\" format.`,\n \"INVALID_REPO\"\n );\n }\n return { owner: parts[0], repo: parts[1] };\n}\n\n/** Check if gh CLI is available */\nexport async function isGhAvailable(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Verify the repository exists and user has access */\nexport async function verifyRepoAccess(repoInfo: RemoteRepoInfo): Promise<boolean> {\n try {\n await execa(\"gh\", [\"api\", `repos/${repoInfo.owner}/${repoInfo.repo}`]);\n return true;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (errorMessage.includes(\"404\") || errorMessage.includes(\"Not Found\")) {\n throw new RemoteFetcherError(\n `Repository not found: ${repoInfo.owner}/${repoInfo.repo}`,\n \"NO_REPO\"\n );\n }\n\n if (errorMessage.includes(\"403\") || errorMessage.includes(\"401\")) {\n throw new RemoteFetcherError(\n `Cannot access repository: ${repoInfo.owner}/${repoInfo.repo}. Check your GITHUB_TOKEN permissions.`,\n \"NO_PERMISSION\"\n );\n }\n\n throw new RemoteFetcherError(\n `Failed to verify repository access: ${errorMessage}`,\n \"API_ERROR\"\n );\n }\n}\n\n/** Check if a file exists in the remote repository via GitHub Contents API */\nexport async function checkRemoteFileExists(\n repoInfo: RemoteRepoInfo,\n filePath: string\n): Promise<boolean> {\n try {\n await execa(\"gh\", [\n \"api\",\n `repos/${repoInfo.owner}/${repoInfo.repo}/contents/${filePath}`,\n \"--silent\",\n ]);\n return true;\n } catch {\n // File doesn't exist or no access - both return false\n return false;\n }\n}\n\n/** Check multiple alternative paths for a file */\nasync function checkRemoteFileWithAlternatives(\n repoInfo: RemoteRepoInfo,\n config: FileCheckConfig\n): Promise<FileCheckResult> {\n const allPaths = [config.path, ...(config.alternativePaths ?? [])];\n\n for (const path of allPaths) {\n // Sequential check needed - stop on first match\n const exists = await checkRemoteFileExists(repoInfo, path);\n if (exists) {\n return { path: config.path, exists: true, checkedPaths: allPaths };\n }\n }\n\n return { path: config.path, exists: false, checkedPaths: allPaths };\n}\n\n/** Batch check multiple files in a repository */\nexport async function checkRemoteFiles(\n repoInfo: RemoteRepoInfo,\n configs: FileCheckConfig[]\n): Promise<FileCheckResult[]> {\n // Run checks in parallel for efficiency\n const results = await Promise.all(\n configs.map((config) => checkRemoteFileWithAlternatives(repoInfo, config))\n );\n return results;\n}\n\n/** Standard file checks for remote validation */\nexport const standardFileChecks: FileCheckConfig[] = [\n {\n path: \"CODEOWNERS\",\n alternativePaths: [\".github/CODEOWNERS\", \"docs/CODEOWNERS\"],\n required: false,\n description: \"CODEOWNERS file for code review assignment\",\n },\n {\n path: \".github/PULL_REQUEST_TEMPLATE.md\",\n alternativePaths: [\n \".github/pull_request_template.md\",\n \"PULL_REQUEST_TEMPLATE.md\",\n \"pull_request_template.md\",\n ],\n required: false,\n description: \"Pull request template\",\n },\n {\n path: \"README.md\",\n alternativePaths: [\"readme.md\", \"README\"],\n required: false,\n description: \"Repository README\",\n },\n {\n path: \".github/workflows\",\n required: false,\n description: \"GitHub Actions workflows directory\",\n },\n];\n","import { type Config } from \"../../core/index.js\";\nimport { type Violation } from \"../../core/index.js\";\n\n/** GitHub Ruleset response types */\ninterface RulesetBypassActor {\n actor_id: number | null;\n actor_type: string;\n bypass_mode: string;\n}\n\ninterface RulesetRule {\n type: string;\n parameters?: {\n required_approving_review_count?: number;\n dismiss_stale_reviews_on_push?: boolean;\n require_code_owner_review?: boolean;\n required_status_checks?: { context: string }[];\n strict_required_status_checks_policy?: boolean;\n };\n}\n\nexport interface RulesetResponse {\n id: number;\n name: string;\n target: string;\n enforcement: string;\n conditions?: { ref_name?: { include?: string[]; exclude?: string[] } };\n bypass_actors?: RulesetBypassActor[];\n rules?: RulesetRule[];\n}\n\ntype RulesetConfig = NonNullable<NonNullable<Config[\"process\"]>[\"repo\"]>[\"ruleset\"];\ntype TagProtectionConfig = NonNullable<NonNullable<Config[\"process\"]>[\"repo\"]>[\"tag_protection\"];\n\n/** Check if branch matches any of the include patterns */\nfunction matchesBranch(patterns: string[], branch: string): boolean {\n for (const pattern of patterns) {\n const cleanPattern = pattern.replace(/^refs\\/heads\\//, \"\");\n if (cleanPattern === branch) {\n return true;\n }\n if (cleanPattern === \"~DEFAULT_BRANCH\" && branch === \"main\") {\n return true;\n }\n if (cleanPattern === \"~ALL\") {\n return true;\n }\n if (cleanPattern.includes(\"*\")) {\n const regex = new RegExp(`^${cleanPattern.replace(/\\*/g, \".*\")}$`);\n if (regex.test(branch)) {\n return true;\n }\n }\n }\n return false;\n}\n\n/** Find branch ruleset matching the target branch */\nfunction findBranchRuleset(\n rulesets: RulesetResponse[],\n branch: string\n): RulesetResponse | undefined {\n return rulesets.find(\n (r) =>\n r.target === \"branch\" &&\n r.enforcement === \"active\" &&\n matchesBranch(r.conditions?.ref_name?.include ?? [], branch)\n );\n}\n\n/** Validate rulesets against config */\n// eslint-disable-next-line complexity\nexport function validateRulesets(\n rulesets: RulesetResponse[],\n repoConfig: NonNullable<Config[\"process\"]>[\"repo\"]\n): Violation[] {\n if (!repoConfig) {\n return [];\n }\n\n const violations: Violation[] = [];\n const rulesetConfig = repoConfig.ruleset;\n const branch = rulesetConfig?.branch ?? \"main\";\n const branchRuleset = findBranchRuleset(rulesets, branch);\n\n if (repoConfig.require_branch_protection && !branchRuleset) {\n violations.push({\n rule: \"process.repo.branch_protection\",\n tool: \"scan\",\n message: `Branch '${branch}' does not have a branch protection ruleset`,\n severity: \"error\",\n });\n }\n\n if (branchRuleset && rulesetConfig) {\n violations.push(...validateBranchRuleset(branchRuleset, rulesetConfig, branch));\n }\n\n if (repoConfig.tag_protection?.patterns?.length) {\n violations.push(...validateTagProtection(rulesets, repoConfig.tag_protection));\n }\n\n return violations;\n}\n\n/** Validate branch ruleset settings against config */\nfunction validateBranchRuleset(\n ruleset: RulesetResponse,\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (!config) {\n return [];\n }\n\n const violations: Violation[] = [];\n const rules = ruleset.rules ?? [];\n const prRule = rules.find((r) => r.type === \"pull_request\");\n const statusRule = rules.find((r) => r.type === \"required_status_checks\");\n\n violations.push(...validatePullRequestRule(prRule, config, branch));\n violations.push(...validateStatusChecksRule(statusRule, config, branch));\n violations.push(...validateSignedCommits(rules, config, branch));\n violations.push(...validateBypassActors(ruleset.bypass_actors ?? [], config, branch));\n\n return violations;\n}\n\n/** Validate pull request rule settings */\n// eslint-disable-next-line complexity\nfunction validatePullRequestRule(\n prRule: RulesetRule | undefined,\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (!config) {\n return [];\n }\n\n const violations: Violation[] = [];\n const params = prRule?.parameters;\n\n if (config.required_reviews !== undefined) {\n const actualReviews = params?.required_approving_review_count ?? 0;\n if (actualReviews < config.required_reviews) {\n violations.push({\n rule: \"process.repo.branch_protection.required_reviews\",\n tool: \"scan\",\n message: `Branch '${branch}' requires ${actualReviews} reviews, expected at least ${config.required_reviews}`,\n severity: \"error\",\n });\n }\n }\n\n if (config.dismiss_stale_reviews === true && !(params?.dismiss_stale_reviews_on_push ?? false)) {\n violations.push({\n rule: \"process.repo.branch_protection.dismiss_stale_reviews\",\n tool: \"scan\",\n message: `Branch '${branch}' does not dismiss stale reviews on new commits`,\n severity: \"error\",\n });\n }\n\n if (config.require_code_owner_reviews === true && !(params?.require_code_owner_review ?? false)) {\n violations.push({\n rule: \"process.repo.branch_protection.require_code_owner_reviews\",\n tool: \"scan\",\n message: `Branch '${branch}' does not require code owner reviews`,\n severity: \"error\",\n });\n }\n\n return violations;\n}\n\n/** Validate status checks rule settings */\n// eslint-disable-next-line complexity\nfunction validateStatusChecksRule(\n statusRule: RulesetRule | undefined,\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (!config) {\n return [];\n }\n\n const violations: Violation[] = [];\n const params = statusRule?.parameters;\n\n if (config.require_status_checks && config.require_status_checks.length > 0) {\n const actualChecks = params?.required_status_checks?.map((c) => c.context) ?? [];\n const missingChecks = config.require_status_checks.filter(\n (check) => !actualChecks.includes(check)\n );\n if (missingChecks.length > 0) {\n violations.push({\n rule: \"process.repo.branch_protection.require_status_checks\",\n tool: \"scan\",\n message: `Branch '${branch}' missing required status checks: ${missingChecks.join(\", \")}`,\n severity: \"error\",\n });\n }\n }\n\n if (\n config.require_branches_up_to_date === true &&\n !(params?.strict_required_status_checks_policy ?? false)\n ) {\n violations.push({\n rule: \"process.repo.branch_protection.require_branches_up_to_date\",\n tool: \"scan\",\n message: `Branch '${branch}' does not require branches to be up to date before merging`,\n severity: \"error\",\n });\n }\n\n return violations;\n}\n\n/** Validate signed commits requirement */\nfunction validateSignedCommits(\n rules: RulesetRule[],\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (config?.require_signed_commits !== true) {\n return [];\n }\n\n if (!rules.some((r) => r.type === \"required_signatures\")) {\n return [\n {\n rule: \"process.repo.branch_protection.require_signed_commits\",\n tool: \"scan\",\n message: `Branch '${branch}' does not require signed commits`,\n severity: \"error\",\n },\n ];\n }\n\n return [];\n}\n\n/** Validate bypass actors configuration */\nfunction validateBypassActors(\n actualBypass: RulesetBypassActor[],\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (config?.enforce_admins !== true || actualBypass.length === 0) {\n return [];\n }\n\n return [\n {\n rule: \"process.repo.branch_protection.enforce_admins\",\n tool: \"scan\",\n message: `Branch '${branch}' has bypass actors configured but enforce_admins requires no bypasses`,\n severity: \"error\",\n },\n ];\n}\n\n/** Validate tag protection rulesets */\nfunction validateTagProtection(\n rulesets: RulesetResponse[],\n tagConfig: TagProtectionConfig\n): Violation[] {\n if (!tagConfig?.patterns?.length) {\n return [];\n }\n\n const violations: Violation[] = [];\n const tagRuleset = rulesets.find((r) => r.target === \"tag\" && r.enforcement === \"active\");\n\n if (!tagRuleset) {\n return [\n {\n rule: \"process.repo.tag_protection\",\n tool: \"scan\",\n message: \"No active tag protection ruleset found\",\n severity: \"error\",\n },\n ];\n }\n\n violations.push(...validateTagPatterns(tagConfig.patterns, tagRuleset));\n violations.push(...validateTagRules(tagConfig, tagRuleset.rules ?? []));\n\n return violations;\n}\n\n/** Validate tag patterns match */\nfunction validateTagPatterns(expectedPatterns: string[], tagRuleset: RulesetResponse): Violation[] {\n const expected = expectedPatterns.map((p) => `refs/tags/${p}`).sort();\n const actual = [...(tagRuleset.conditions?.ref_name?.include ?? [])].sort();\n\n if (expected.length === actual.length && expected.every((v, i) => v === actual[i])) {\n return [];\n }\n\n const found = actual.map((p) => p.replace(/^refs\\/tags\\//, \"\")).join(\", \");\n return [\n {\n rule: \"process.repo.tag_protection.patterns\",\n tool: \"scan\",\n message: `Tag protection patterns mismatch: expected [${expectedPatterns.join(\", \")}], found [${found}]`,\n severity: \"error\",\n },\n ];\n}\n\n/** Validate tag protection rules */\nfunction validateTagRules(tagConfig: TagProtectionConfig, rules: RulesetRule[]): Violation[] {\n if (!tagConfig) {\n return [];\n }\n\n const violations: Violation[] = [];\n\n if (tagConfig.prevent_deletion !== false && !rules.some((r) => r.type === \"deletion\")) {\n violations.push({\n rule: \"process.repo.tag_protection.prevent_deletion\",\n tool: \"scan\",\n message: \"Tag protection does not prevent deletion\",\n severity: \"error\",\n });\n }\n\n if (tagConfig.prevent_update !== false && !rules.some((r) => r.type === \"update\")) {\n violations.push({\n rule: \"process.repo.tag_protection.prevent_update\",\n tool: \"scan\",\n message: \"Tag protection does not prevent updates (force-push)\",\n severity: \"error\",\n });\n }\n\n return violations;\n}\n","import chalk from \"chalk\";\n\nimport {\n type DomainResult,\n type DomainStatus,\n type FullResult,\n type Violation,\n} from \"../core/index.js\";\n\nexport type OutputFormat = \"text\" | \"json\";\n\n/** Icon mapping for domain/check status with colors */\nconst STATUS_ICONS: Record<DomainStatus, string> = {\n pass: chalk.green(\"✓\"),\n fail: chalk.red(\"✗\"),\n skip: chalk.gray(\"○\"),\n};\n\n/**\n * Format output as JSON\n */\nexport function formatJson(result: FullResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Format output as human-readable text\n */\nexport function formatText(result: FullResult): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`conform v${result.version}`);\n lines.push(`Config: ${result.configPath}`);\n lines.push(\"\");\n\n // Domain results\n for (const [domainName, domain] of Object.entries(result.domains)) {\n lines.push(formatDomainText(domainName, domain));\n lines.push(\"\");\n }\n\n // Summary\n lines.push(chalk.dim(\"─\".repeat(50)));\n if (result.summary.totalViolations === 0) {\n lines.push(chalk.green(\"✓ All checks passed\"));\n } else {\n lines.push(chalk.red(`✗ ${result.summary.totalViolations} violation(s) found`));\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction getStatusIcon(status: DomainStatus): string {\n return STATUS_ICONS[status];\n}\n\nfunction getCheckIcon(passed: boolean, skipped: boolean): string {\n if (passed) {\n return chalk.green(\"✓\");\n }\n if (skipped) {\n return chalk.gray(\"○\");\n }\n return chalk.red(\"✗\");\n}\n\nfunction formatCheckLine(check: DomainResult[\"checks\"][number]): string[] {\n const checkIcon = getCheckIcon(check.passed, check.skipped);\n const duration = check.duration ? chalk.dim(` (${check.duration}ms)`) : \"\";\n\n if (check.skipped) {\n return [\n ` ${checkIcon} ${chalk.bold(check.name)}: ${chalk.gray(\"skipped\")} - ${chalk.gray(check.skipReason)}${duration}`,\n ];\n }\n if (check.passed) {\n return [` ${checkIcon} ${chalk.bold(check.name)}: ${chalk.green(\"passed\")}${duration}`];\n }\n\n const lines = [\n ` ${checkIcon} ${chalk.bold(check.name)}: ${chalk.red(`${check.violations.length} violation(s)`)}${duration}`,\n ];\n const violationsToShow = check.violations.slice(0, 10);\n lines.push(...violationsToShow.map(formatViolationText));\n if (check.violations.length > 10) {\n lines.push(chalk.dim(` ... and ${check.violations.length - 10} more`));\n }\n return lines;\n}\n\nfunction formatDomainText(name: string, domain: DomainResult): string {\n const statusIcon = getStatusIcon(domain.status);\n const lines = [`${statusIcon} ${chalk.bold(name.toUpperCase())}`];\n for (const check of domain.checks) {\n lines.push(...formatCheckLine(check));\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Format a single violation as text\n */\nfunction formatLocation(file: string, line?: number, column?: number): string {\n if (line !== undefined && column !== undefined) {\n return `${file}:${line}:${column}`;\n }\n if (line !== undefined) {\n return `${file}:${line}`;\n }\n return file;\n}\n\nfunction formatViolationText(v: Violation): string {\n const location = v.file ? chalk.cyan(formatLocation(v.file, v.line, v.column)) : \"\";\n const code = v.code ? chalk.dim(`[${v.code}]`) : \"\";\n const severity = v.severity === \"error\" ? chalk.red(\"error\") : chalk.yellow(\"warn\");\n\n if (location) {\n return ` ${location} ${severity} ${code} ${v.message}`;\n }\n return ` ${severity} ${code} ${v.message}`;\n}\n\n/**\n * Format result based on output format\n */\nexport function formatOutput(result: FullResult, format: OutputFormat): string {\n switch (format) {\n case \"json\":\n return formatJson(result);\n case \"text\":\n default:\n return formatText(result);\n }\n}\n","/**\n * Core implementation of the conform dependencies command\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { globSync } from \"glob\";\n\nimport { type Config, getProjectRoot, loadConfigAsync } from \"../core/index.js\";\nimport { ALWAYS_TRACKED, BUILTIN_MAPPINGS } from \"./mappings.js\";\nimport { formatDependenciesJson, formatDependenciesText } from \"./output.js\";\nimport type { DependenciesOptions, DependenciesResult } from \"./types.js\";\n\n// Re-export types for library consumers\nexport type { DependenciesOptions, DependenciesResult } from \"./types.js\";\n\n/**\n * Tool configuration with optional dependencies field\n */\ninterface ToolConfig {\n enabled?: boolean;\n dependencies?: string[];\n}\n\n/** Map of tool IDs to config accessor functions */\nconst TOOL_CONFIG_ACCESSORS: Record<string, (c: Config) => ToolConfig | undefined> = {\n eslint: (c) => c.code?.linting?.eslint,\n ruff: (c) => c.code?.linting?.ruff,\n tsc: (c) => c.code?.types?.tsc,\n ty: (c) => c.code?.types?.ty,\n knip: (c) => c.code?.unused?.knip,\n vulture: (c) => c.code?.unused?.vulture,\n secrets: (c) => c.code?.security?.secrets,\n pnpmaudit: (c) => c.code?.security?.pnpmaudit,\n pipaudit: (c) => c.code?.security?.pipaudit,\n};\n\n/** Coverage runner tool IDs */\nconst COVERAGE_RUNNERS = [\"vitest\", \"jest\", \"pytest\"];\n\n/**\n * Get tool configuration from standards.toml config by tool ID\n */\nfunction getToolConfig(config: Config, toolId: string): ToolConfig | undefined {\n // Handle coverage runners specially\n if (COVERAGE_RUNNERS.includes(toolId)) {\n const coverageConfig = config.code?.coverage_run;\n if (!coverageConfig?.enabled) {\n return undefined;\n }\n const runner = coverageConfig.runner;\n if (runner === \"auto\" || runner === toolId) {\n return coverageConfig;\n }\n return undefined;\n }\n // Use lookup table for other tools\n if (!(toolId in TOOL_CONFIG_ACCESSORS)) {\n return undefined;\n }\n return TOOL_CONFIG_ACCESSORS[toolId](config);\n}\n\n/**\n * Check if a pattern contains glob characters\n */\nfunction isGlobPattern(pattern: string): boolean {\n return pattern.includes(\"*\") || pattern.includes(\"?\") || pattern.includes(\"[\");\n}\n\n/**\n * Expand glob patterns and filter to only existing files\n */\nfunction expandAndFilter(patterns: string[], projectRoot: string): string[] {\n const results: string[] = [];\n\n for (const pattern of patterns) {\n if (isGlobPattern(pattern)) {\n const matches = globSync(pattern, { cwd: projectRoot, nodir: true, dot: true });\n results.push(...matches);\n } else {\n const fullPath = path.join(projectRoot, pattern);\n if (fs.existsSync(fullPath)) {\n results.push(pattern);\n }\n }\n }\n\n return [...new Set(results)].sort();\n}\n\n/**\n * Collect dependencies for a single tool\n */\nfunction collectToolDependencies(\n toolId: string,\n config: Config,\n projectRoot: string\n): string[] | null {\n const toolConfig = getToolConfig(config, toolId);\n if (!toolConfig?.enabled) {\n return null;\n }\n\n const mapping = BUILTIN_MAPPINGS[toolId];\n const builtinFiles = expandAndFilter(mapping.configFiles, projectRoot);\n const customFiles = toolConfig.dependencies\n ? expandAndFilter(toolConfig.dependencies, projectRoot)\n : [];\n\n const allFiles = [...new Set([...builtinFiles, ...customFiles])].sort();\n return allFiles.length > 0 ? allFiles : null;\n}\n\n/**\n * Get all dependencies for a project\n */\nexport async function getDependencies(\n options: Partial<DependenciesOptions> = {}\n): Promise<DependenciesResult> {\n const { config, configPath } = await loadConfigAsync(options.config);\n const projectRoot = options.project\n ? path.resolve(process.cwd(), options.project)\n : getProjectRoot(configPath);\n\n const dependencies: Record<string, string[]> = {};\n\n for (const toolId of Object.keys(BUILTIN_MAPPINGS)) {\n if (options.check && options.check !== toolId) {\n continue;\n }\n const files = collectToolDependencies(toolId, config, projectRoot);\n if (files) {\n dependencies[toolId] = files;\n }\n }\n\n const alwaysTracked = expandAndFilter(ALWAYS_TRACKED, projectRoot);\n const allFiles = [...new Set([...Object.values(dependencies).flat(), ...alwaysTracked])].sort();\n\n return {\n project: options.project ?? \".\",\n checkTomlPath: path.relative(projectRoot, configPath) || \"standards.toml\",\n dependencies,\n alwaysTracked,\n allFiles,\n };\n}\n\n/**\n * Run the dependencies command (CLI entry point)\n */\nexport async function runDependencies(options: DependenciesOptions): Promise<void> {\n const result = await getDependencies(options);\n const output =\n options.format === \"json\" ? formatDependenciesJson(result) : formatDependenciesText(result);\n process.stdout.write(`${output}\\n`);\n}\n","/**\n * Built-in dependency mappings for tools\n *\n * Maps tool IDs to their known configuration file patterns.\n * These patterns may include globs that need to be expanded.\n */\n\nimport type { ToolDependencyMapping } from \"./types.js\";\n\n/**\n * Built-in dependency mappings for all supported tools.\n * Keys match the toolId used in standards.toml config paths.\n */\nexport const BUILTIN_MAPPINGS: Record<string, ToolDependencyMapping> = {\n // Linting tools\n eslint: {\n toolId: \"eslint\",\n configFiles: [\n \"eslint.config.js\",\n \"eslint.config.mjs\",\n \"eslint.config.cjs\",\n \".eslintrc.js\",\n \".eslintrc.json\",\n \".eslintrc.yml\",\n \".eslintrc.yaml\",\n \".eslintignore\",\n ],\n },\n ruff: {\n toolId: \"ruff\",\n configFiles: [\"ruff.toml\", \".ruff.toml\", \"pyproject.toml\"],\n },\n\n // Type checking tools\n tsc: {\n toolId: \"tsc\",\n configFiles: [\"tsconfig.json\", \"tsconfig.*.json\"],\n },\n ty: {\n toolId: \"ty\",\n configFiles: [\"ty.toml\", \"pyproject.toml\"],\n },\n\n // Unused code detection\n knip: {\n toolId: \"knip\",\n configFiles: [\n \"knip.json\",\n \"knip.jsonc\",\n \"knip.js\",\n \"knip.ts\",\n \"knip.config.js\",\n \"knip.config.ts\",\n ],\n },\n vulture: {\n toolId: \"vulture\",\n configFiles: [\"pyproject.toml\"],\n },\n\n // Test coverage / test runners\n vitest: {\n toolId: \"vitest\",\n configFiles: [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"vitest.config.mts\",\n \"vitest.config.mjs\",\n \"vite.config.ts\",\n \"vite.config.js\",\n ],\n },\n jest: {\n toolId: \"jest\",\n configFiles: [\n \"jest.config.js\",\n \"jest.config.ts\",\n \"jest.config.mjs\",\n \"jest.config.cjs\",\n \"jest.config.json\",\n ],\n },\n pytest: {\n toolId: \"pytest\",\n configFiles: [\"pytest.ini\", \"pyproject.toml\", \"setup.cfg\", \"conftest.py\"],\n },\n\n // Security tools\n secrets: {\n toolId: \"secrets\",\n configFiles: [\".gitleaks.toml\", \"gitleaks.toml\"],\n },\n pnpmaudit: {\n toolId: \"pnpmaudit\",\n configFiles: [\"pnpm-lock.yaml\"],\n },\n pipaudit: {\n toolId: \"pipaudit\",\n configFiles: [\"requirements.txt\", \"pyproject.toml\", \"setup.py\"],\n },\n};\n\n/**\n * Files that are always tracked regardless of which tools are enabled.\n * These patterns may include globs.\n */\nexport const ALWAYS_TRACKED: string[] = [\n \"standards.toml\",\n \".github/workflows/*.yml\",\n \".github/workflows/*.yaml\",\n \"repo-metadata.yaml\",\n];\n","/**\n * Validate guideline markdown files against the frontmatter schema\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport chalk from \"chalk\";\nimport matter from \"gray-matter\";\n\nimport { frontmatterSchema } from \"../mcp/standards/index.js\";\nimport { ExitCode } from \"../core/index.js\";\n\n/** Single file validation error */\nexport interface GuidelineValidationError {\n file: string;\n errors: string[];\n}\n\n/** Overall validation result */\nexport interface GuidelineValidationResult {\n valid: boolean;\n validCount: number;\n invalidCount: number;\n errors: GuidelineValidationError[];\n}\n\n/** Format text output for validation result */\nfunction formatTextOutput(result: GuidelineValidationResult): string {\n if (result.valid) {\n return chalk.green(`✓ All ${result.validCount} guideline(s) valid`);\n }\n const lines = [chalk.red(`✗ Found ${result.invalidCount} invalid guideline(s)`), \"\"];\n for (const err of result.errors) {\n lines.push(chalk.red(` ${err.file}:`));\n for (const e of err.errors) {\n lines.push(chalk.red(` - ${e}`));\n }\n }\n return lines.join(\"\\n\");\n}\n\n/** Validate a directory of guideline files */\nexport function validateGuidelinesDir(dirPath: string): GuidelineValidationResult {\n const files = fs.readdirSync(dirPath).filter((f) => f.endsWith(\".md\"));\n const result: GuidelineValidationResult = {\n valid: true,\n validCount: 0,\n invalidCount: 0,\n errors: [],\n };\n\n for (const file of files) {\n const filePath = path.join(dirPath, file);\n const content = fs.readFileSync(filePath, \"utf-8\");\n const { data } = matter(content);\n\n const parseResult = frontmatterSchema.safeParse(data);\n if (parseResult.success) {\n result.validCount++;\n } else {\n result.valid = false;\n result.invalidCount++;\n result.errors.push({\n file,\n errors: parseResult.error.errors.map((e) => `${e.path.join(\".\")}: ${e.message}`),\n });\n }\n }\n\n return result;\n}\n\n/** Output error and exit */\nfunction exitWithError(error: string, format: string): never {\n if (format === \"json\") {\n process.stdout.write(`${JSON.stringify({ valid: false, error }, null, 2)}\\n`);\n } else {\n console.error(chalk.red(`✗ ${error}`));\n }\n process.exit(ExitCode.CONFIG_ERROR);\n}\n\n/** Resolve and validate directory path */\nfunction resolveAndValidatePath(dirPath: string, format: string): string {\n const resolvedPath = path.isAbsolute(dirPath) ? dirPath : path.resolve(process.cwd(), dirPath);\n\n if (!fs.existsSync(resolvedPath)) {\n exitWithError(`Path does not exist: ${resolvedPath}`, format);\n }\n\n const stats = fs.statSync(resolvedPath);\n if (!stats.isDirectory()) {\n exitWithError(`Path is not a directory: ${resolvedPath}`, format);\n }\n\n return resolvedPath;\n}\n\n/** Run the validate guidelines command */\nexport async function runValidateGuidelines(\n dirPath: string,\n options: { format: string }\n): Promise<void> {\n const resolvedPath = resolveAndValidatePath(dirPath, options.format);\n const result = validateGuidelinesDir(resolvedPath);\n\n if (options.format === \"json\") {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n } else {\n process.stdout.write(`${formatTextOutput(result)}\\n`);\n }\n\n process.exit(result.valid ? ExitCode.SUCCESS : ExitCode.CONFIG_ERROR);\n}\n","/**\n * Fetches the standards repository from GitHub or local filesystem\n */\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { CACHE, STANDARDS_REPO, TIMEOUTS } from \"../../constants.js\";\n\nconst CACHE_DIR = path.join(os.tmpdir(), CACHE.standardsCacheDir);\n\n/** Parsed GitHub source */\ninterface GitHubSource {\n type: \"github\";\n owner: string;\n repo: string;\n ref?: string;\n}\n\n/** Parsed local source */\ninterface LocalSource {\n type: \"local\";\n path: string;\n}\n\n/** Parsed source type */\ntype ParsedSource = GitHubSource | LocalSource;\n\n/** Parse github:owner/repo[@ref] format */\nfunction parseGitHubSource(source: string): GitHubSource {\n const remainder = source.slice(7); // Remove \"github:\"\n const atIndex = remainder.indexOf(\"@\");\n const ownerRepo = atIndex !== -1 ? remainder.slice(0, atIndex) : remainder;\n const ref = atIndex !== -1 ? remainder.slice(atIndex + 1) : undefined;\n const slashIndex = ownerRepo.indexOf(\"/\");\n\n if (slashIndex === -1) {\n throw new StandardsError(`Invalid GitHub source format: ${source}. Expected github:owner/repo`);\n }\n\n const owner = ownerRepo.slice(0, slashIndex);\n const repo = ownerRepo.slice(slashIndex + 1);\n\n if (!owner || !repo) {\n throw new StandardsError(`Invalid GitHub source format: ${source}. Expected github:owner/repo`);\n }\n\n return { type: \"github\", owner, repo, ref };\n}\n\n/**\n * Parse a source string into owner/repo/ref or local path.\n * Formats:\n * - \"github:owner/repo\" - GitHub repository\n * - \"github:owner/repo@ref\" - GitHub with branch/tag\n * - Local filesystem path (absolute or relative)\n */\nfunction parseSource(source: string): ParsedSource {\n if (source.startsWith(\"github:\")) {\n return parseGitHubSource(source);\n }\n return { type: \"local\", path: source };\n}\n\n/** Error class for standards fetching failures */\nexport class StandardsError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"StandardsError\";\n }\n}\n\n/** Authentication method for GitHub */\ntype AuthMethod = \"token\" | \"ssh\" | \"none\";\n\n/**\n * Detect authentication method based on environment variables.\n * Priority: CM_REGISTRY_TOKEN > GITHUB_TOKEN > SSH key detection > none\n */\nfunction detectAuthMethod(): AuthMethod {\n if (process.env.CM_REGISTRY_TOKEN || process.env.GITHUB_TOKEN) {\n return \"token\";\n }\n if (process.env.SSH_AUTH_SOCK) {\n return \"ssh\";\n }\n return \"none\";\n}\n\n/**\n * Get the authentication token from environment variables.\n */\nfunction getAuthToken(): string | undefined {\n return process.env.CM_REGISTRY_TOKEN ?? process.env.GITHUB_TOKEN;\n}\n\n/**\n * Build the git URL for a repository based on auth method.\n */\nfunction buildGitHubUrl(auth: AuthMethod, owner: string, repo: string): string {\n switch (auth) {\n case \"ssh\":\n return `git@github.com:${owner}/${repo}.git`;\n case \"token\": {\n const token = getAuthToken();\n if (token) {\n return `https://x-access-token:${token}@github.com/${owner}/${repo}.git`;\n }\n return `https://github.com/${owner}/${repo}.git`;\n }\n case \"none\":\n default:\n return `https://github.com/${owner}/${repo}.git`;\n }\n}\n\n/**\n * Update an existing cloned repository.\n */\nasync function updateExistingRepo(repoDir: string): Promise<boolean> {\n try {\n await execa(\"git\", [\"pull\", \"--ff-only\"], { cwd: repoDir, timeout: TIMEOUTS.git });\n return true;\n } catch {\n // If update fails, remove the directory so it will be re-cloned\n fs.rmSync(repoDir, { recursive: true, force: true });\n return false;\n }\n}\n\n/**\n * Clone a repository from GitHub.\n */\nasync function cloneRepo(repoDir: string, owner: string, repo: string, ref?: string): Promise<void> {\n fs.mkdirSync(CACHE_DIR, { recursive: true });\n\n const auth = detectAuthMethod();\n const url = buildGitHubUrl(auth, owner, repo);\n\n try {\n const args = [\"clone\", \"--depth\", \"1\"];\n if (ref) {\n args.push(\"--branch\", ref);\n }\n args.push(url, repoDir);\n\n await execa(\"git\", args, {\n timeout: TIMEOUTS.git,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.includes(\"timed out\")) {\n throw new StandardsError(`Standards repo clone timed out after ${TIMEOUTS.git / 1000} seconds`);\n }\n throw new StandardsError(`Failed to clone standards repo: ${message}`);\n }\n}\n\n/**\n * Fetch a GitHub repository, caching it locally.\n * Returns the path to the cached repository.\n */\nasync function fetchGitHubRepo(owner: string, repo: string, ref?: string): Promise<string> {\n const cacheKey = ref ? `${owner}-${repo}-${ref}` : `${owner}-${repo}`;\n const repoDir = path.join(CACHE_DIR, cacheKey);\n\n // If repo exists, try to update it\n if (fs.existsSync(repoDir)) {\n await updateExistingRepo(repoDir);\n }\n\n // Clone if it doesn't exist (either first time or after failed update)\n if (!fs.existsSync(repoDir)) {\n await cloneRepo(repoDir, owner, repo, ref);\n }\n\n return repoDir;\n}\n\n/**\n * Resolve a local source path to an absolute path.\n */\nfunction resolveLocalPath(localPath: string, basePath?: string): string {\n if (path.isAbsolute(localPath)) {\n return localPath;\n }\n const base = basePath ?? process.cwd();\n return path.resolve(base, localPath);\n}\n\n/**\n * Fetch the standards repository from a source string.\n * Supports:\n * - \"github:owner/repo\" - GitHub repository\n * - \"github:owner/repo@ref\" - GitHub with branch/tag\n * - Local filesystem path (absolute or relative)\n *\n * @param source - Source string to fetch from\n * @param basePath - Base path for resolving relative local paths (defaults to cwd)\n * @returns Path to the standards repository\n */\nexport async function fetchStandardsRepoFromSource(\n source: string,\n basePath?: string\n): Promise<string> {\n const parsed = parseSource(source);\n\n if (parsed.type === \"local\") {\n const resolvedPath = resolveLocalPath(parsed.path, basePath);\n if (!fs.existsSync(resolvedPath)) {\n throw new StandardsError(`Local standards path does not exist: ${resolvedPath}`);\n }\n return resolvedPath;\n }\n\n return fetchGitHubRepo(parsed.owner, parsed.repo, parsed.ref);\n}\n\n/**\n * Fetch the default standards repository, caching it locally.\n * Returns the path to the cached repository.\n */\nexport async function fetchStandardsRepo(): Promise<string> {\n return fetchGitHubRepo(STANDARDS_REPO.owner, STANDARDS_REPO.repo);\n}\n\n/**\n * Get the path to the guidelines directory.\n */\nexport function getGuidelinesDir(repoPath: string): string {\n return path.join(repoPath, \"guidelines\");\n}\n\n/**\n * Get the path to the rulesets directory.\n */\nexport function getRulesetsDir(repoPath: string): string {\n return path.join(repoPath, \"rulesets\");\n}\n","/**\n * Parser for guideline markdown files with YAML frontmatter\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport matter from \"gray-matter\";\nimport { z } from \"zod\";\n\nimport { type Guideline, type GuidelineListItem, type Ruleset } from \"./types.js\";\nimport { StandardsError } from \"./fetcher.js\";\n\n/** Zod schema for validating guideline frontmatter */\nexport const frontmatterSchema = z.object({\n id: z.string(),\n title: z.string(),\n category: z.string(),\n priority: z.number(),\n tags: z.array(z.string()),\n});\n\n/**\n * Parse a guideline markdown file content into a Guideline object.\n */\nexport function parseGuideline(fileContent: string, filename: string): Guideline {\n const { data, content } = matter(fileContent);\n\n const result = frontmatterSchema.safeParse(data);\n if (!result.success) {\n const errors = result.error.errors.map((e) => `${e.path.join(\".\")}: ${e.message}`).join(\", \");\n throw new StandardsError(`Invalid frontmatter in ${filename}: ${errors}`);\n }\n\n return {\n ...result.data,\n content: content.trim(),\n };\n}\n\n/**\n * Load all guidelines from a directory.\n */\nexport function loadAllGuidelines(guidelinesDir: string): Guideline[] {\n if (!fs.existsSync(guidelinesDir)) {\n throw new StandardsError(`Guidelines directory not found: ${guidelinesDir}`);\n }\n\n const files = fs.readdirSync(guidelinesDir).filter((f) => f.endsWith(\".md\"));\n const guidelines: Guideline[] = [];\n\n for (const file of files) {\n const filePath = path.join(guidelinesDir, file);\n const content = fs.readFileSync(filePath, \"utf-8\");\n\n try {\n guidelines.push(parseGuideline(content, file));\n } catch (error) {\n // Skip files that fail to parse, log warning\n console.warn(`Warning: Failed to parse guideline ${file}: ${error}`);\n }\n }\n\n return guidelines;\n}\n\n/**\n * Load a single guideline by ID.\n */\nexport function loadGuideline(guidelinesDir: string, id: string): Guideline | null {\n const filePath = path.join(guidelinesDir, `${id}.md`);\n\n if (!fs.existsSync(filePath)) {\n return null;\n }\n\n const content = fs.readFileSync(filePath, \"utf-8\");\n return parseGuideline(content, `${id}.md`);\n}\n\n/**\n * Convert guidelines to list items (summary format).\n */\nexport function toListItems(guidelines: Guideline[]): GuidelineListItem[] {\n return guidelines.map((g) => ({\n id: g.id,\n title: g.title,\n tags: g.tags,\n category: g.category,\n }));\n}\n\n/**\n * Load a ruleset file by ID.\n */\nexport function loadRuleset(rulesetsDir: string, id: string): Ruleset | null {\n const filePath = path.join(rulesetsDir, `${id}.toml`);\n\n if (!fs.existsSync(filePath)) {\n return null;\n }\n\n const content = fs.readFileSync(filePath, \"utf-8\");\n return { id, content };\n}\n\n/**\n * List all available ruleset IDs.\n */\nexport function listRulesets(rulesetsDir: string): string[] {\n if (!fs.existsSync(rulesetsDir)) {\n return [];\n }\n\n return fs\n .readdirSync(rulesetsDir)\n .filter((f) => f.endsWith(\".toml\"))\n .map((f) => f.replace(\".toml\", \"\"));\n}\n","/**\n * Smart keyword matching logic for guidelines\n */\nimport { type Guideline, type MatchedGuideline } from \"./types.js\";\n\n/**\n * Parse a context string into keywords.\n * Extracts words, lowercases them, and removes duplicates.\n */\nexport function parseContext(context: string): string[] {\n const words = context\n .toLowerCase()\n .split(/[\\s,.\\-_/]+/)\n .filter((word) => word.length > 1);\n\n return [...new Set(words)];\n}\n\n/**\n * Score a guideline based on how many keywords match its tags.\n */\nexport function scoreGuideline(guideline: Guideline, keywords: string[]): number {\n const tags = new Set(guideline.tags.map((t) => t.toLowerCase()));\n let score = 0;\n\n for (const keyword of keywords) {\n if (tags.has(keyword)) {\n score++;\n }\n }\n\n // Also check if keyword appears in category or id\n const category = guideline.category.toLowerCase();\n const id = guideline.id.toLowerCase();\n\n for (const keyword of keywords) {\n if (category.includes(keyword) || id.includes(keyword)) {\n score += 0.5; // Partial match bonus\n }\n }\n\n return score;\n}\n\n/**\n * Match guidelines against a context string.\n * Returns guidelines sorted by score (descending) then priority (ascending).\n */\nexport function matchGuidelines(\n guidelines: Guideline[],\n context: string,\n limit?: number\n): MatchedGuideline[] {\n const keywords = parseContext(context);\n\n if (keywords.length === 0) {\n return [];\n }\n\n const scored = guidelines\n .map((guideline) => ({\n guideline,\n score: scoreGuideline(guideline, keywords),\n }))\n .filter((m) => m.score > 0);\n\n // Sort by score descending, then by priority ascending\n scored.sort((a, b) => {\n if (b.score !== a.score) {\n return b.score - a.score;\n }\n return a.guideline.priority - b.guideline.priority;\n });\n\n return limit ? scored.slice(0, limit) : scored;\n}\n\n/**\n * Compose matched guidelines into a single markdown document.\n */\nexport function composeGuidelines(matches: MatchedGuideline[]): string {\n if (matches.length === 0) {\n return \"No matching guidelines found for the given context.\";\n }\n\n const sections = matches.map((m) => {\n const { guideline } = m;\n return `# ${guideline.title}\\n\\n**Category:** ${guideline.category} | **Priority:** ${guideline.priority}\\n**Tags:** ${guideline.tags.join(\", \")}\\n\\n${guideline.content}`;\n });\n\n return sections.join(\"\\n\\n---\\n\\n\");\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport TOML from \"@iarna/toml\";\nimport chalk from \"chalk\";\n\nimport { findConfigFile } from \"../core/index.js\";\nimport {\n type Tier,\n type TierSourceDetail,\n VALID_TIERS,\n type ValidateTierOptions,\n type ValidateTierResult,\n} from \"./types.js\";\n\n/** Default tier when not specified */\nconst DEFAULT_TIER: Tier = \"internal\";\n\n/** Extends section from standards.toml */\ninterface ExtendsConfig {\n registry?: string;\n rulesets?: string[];\n}\n\n/** Metadata section from standards.toml */\ninterface MetadataConfig {\n tier?: Tier;\n project?: string;\n organisation?: string;\n status?: string;\n}\n\n/** Raw standards.toml structure (just what we need) */\ninterface RawConfig {\n metadata?: MetadataConfig;\n extends?: ExtendsConfig;\n}\n\n/** Result of getTier with detailed info */\ninterface GetTierResult {\n tier: Tier;\n source: \"standards.toml\" | \"default\";\n sourceDetail: TierSourceDetail;\n invalidValue?: string;\n}\n\n/**\n * Load and parse standards.toml to get extends section\n */\nfunction loadExtendsConfig(configPath: string): ExtendsConfig | null {\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n const parsed = TOML.parse(content) as RawConfig;\n return parsed.extends ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Load tier from standards.toml [metadata] section\n */\nfunction loadTierFromStandardsToml(configPath: string): GetTierResult {\n if (!fs.existsSync(configPath)) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (file not found)\",\n };\n }\n\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n const parsed = TOML.parse(content) as RawConfig;\n\n if (!parsed.metadata) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (no metadata)\",\n };\n }\n\n if (parsed.metadata.tier === undefined) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (tier not specified)\",\n };\n }\n\n const tier = parsed.metadata.tier;\n\n // Check if tier value is valid\n if (!VALID_TIERS.includes(tier)) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (invalid value)\",\n invalidValue: String(tier),\n };\n }\n\n return { tier, source: \"standards.toml\", sourceDetail: \"standards.toml\" };\n } catch {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (file not found)\",\n };\n }\n}\n\n/**\n * Check if rulesets include a tier-matching ruleset\n */\nfunction findMatchingRulesets(rulesets: string[], tier: Tier): string[] {\n const suffix = `-${tier}`;\n return rulesets.filter((ruleset) => ruleset.endsWith(suffix));\n}\n\n/**\n * Resolve the config path from options\n */\nfunction resolveConfigPath(options: ValidateTierOptions): string | null {\n if (options.config) {\n const absolutePath = path.resolve(options.config);\n return fs.existsSync(absolutePath) ? absolutePath : null;\n }\n return findConfigFile();\n}\n\n/**\n * Create result for missing config\n */\nfunction createNotFoundResult(): ValidateTierResult {\n return {\n valid: false,\n tier: DEFAULT_TIER,\n tierSource: \"default\",\n tierSourceDetail: \"default (file not found)\",\n rulesets: [],\n expectedPattern: `*-${DEFAULT_TIER}`,\n matchedRulesets: [],\n error: \"No standards.toml found\",\n };\n}\n\n/** Options for building the result */\ninterface BuildResultOptions {\n tier: Tier;\n source: \"standards.toml\" | \"default\";\n sourceDetail: TierSourceDetail;\n rulesets: string[];\n matchedRulesets: string[];\n invalidTierValue?: string;\n hasEmptyRulesets?: boolean;\n registryUrl?: string;\n warnings?: string[];\n}\n\n/**\n * Build the validation result\n */\nfunction buildResult(options: BuildResultOptions): ValidateTierResult {\n const {\n tier,\n source,\n sourceDetail,\n rulesets,\n matchedRulesets,\n invalidTierValue,\n hasEmptyRulesets,\n registryUrl,\n } = options;\n const warnings: string[] = options.warnings ?? [];\n\n const expectedPattern = `*-${tier}`;\n const valid = rulesets.length === 0 || matchedRulesets.length > 0;\n\n // Add warning for invalid tier value\n if (invalidTierValue) {\n warnings.push(\n `Invalid tier '${invalidTierValue}' in standards.toml [metadata]. Valid values are: ${VALID_TIERS.join(\", \")}`\n );\n }\n\n // Add warning for empty rulesets with registry configured\n if (hasEmptyRulesets && registryUrl) {\n warnings.push(\n `[extends] is configured with registry '${registryUrl}' but rulesets is empty - no standards will be inherited`\n );\n }\n\n return {\n valid,\n tier,\n tierSource: source,\n tierSourceDetail: sourceDetail,\n rulesets,\n expectedPattern,\n matchedRulesets,\n error: valid\n ? undefined\n : `No ruleset matching pattern '${expectedPattern}' found. Rulesets: [${rulesets.join(\", \")}]`,\n invalidTierValue,\n hasEmptyRulesets,\n registryUrl,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\n/**\n * Validate that project tier matches its rulesets.\n * This is the programmatic API exported for library consumers.\n *\n * Tier is loaded from standards.toml [metadata].tier\n * Defaults to \"internal\" if not specified\n */\nexport function validateTierRuleset(options: ValidateTierOptions = {}): ValidateTierResult {\n const configPath = resolveConfigPath(options);\n if (!configPath) {\n return createNotFoundResult();\n }\n\n const tierResult = loadTierFromStandardsToml(configPath);\n\n const extendsConfig = loadExtendsConfig(configPath);\n const rulesets = extendsConfig?.rulesets ?? [];\n const matchedRulesets = rulesets.length > 0 ? findMatchingRulesets(rulesets, tierResult.tier) : [];\n\n // Detect empty rulesets with registry configured\n const hasEmptyRulesets = extendsConfig !== null && rulesets.length === 0;\n const registryUrl = extendsConfig?.registry;\n\n return buildResult({\n tier: tierResult.tier,\n source: tierResult.source,\n sourceDetail: tierResult.sourceDetail,\n rulesets,\n matchedRulesets,\n invalidTierValue: tierResult.invalidValue,\n hasEmptyRulesets,\n registryUrl,\n });\n}\n\n/** Format warnings section */\nfunction formatWarnings(warnings: string[] | undefined): string[] {\n if (!warnings || warnings.length === 0) {\n return [];\n }\n const lines = warnings.map((w) => chalk.yellow(`⚠ Warning: ${w}`));\n lines.push(\"\"); // Empty line after warnings\n return lines;\n}\n\n/** Format the rulesets message based on configuration */\nfunction formatRulesetsMessage(result: ValidateTierResult): string {\n if (result.matchedRulesets.length > 0) {\n return ` Matching rulesets: ${result.matchedRulesets.join(\", \")}`;\n }\n if (result.hasEmptyRulesets) {\n return \" No rulesets specified (no tier constraint)\";\n }\n return \" No extends configured (no tier constraint)\";\n}\n\n/** Format the failed validation section */\nfunction formatFailedValidation(result: ValidateTierResult, sourceDisplay: string): string[] {\n const lines = [\n chalk.red(\"✗ Tier validation failed\"),\n ` Tier: ${result.tier} (source: ${sourceDisplay})`,\n ` Expected pattern: ${result.expectedPattern}`,\n ` Rulesets: [${result.rulesets.join(\", \")}]`,\n ];\n if (result.error) {\n lines.push(chalk.red(` Error: ${result.error}`));\n }\n if (result.invalidTierValue) {\n lines.push(\"\");\n lines.push(\n chalk.cyan(\n ` Hint: Update standards.toml [metadata].tier to use a valid value: ${VALID_TIERS.join(\", \")}`\n )\n );\n }\n return lines;\n}\n\n/**\n * Format tier validation result as text\n */\nexport function formatTierResultText(result: ValidateTierResult): string {\n const lines: string[] = formatWarnings(result.warnings);\n const sourceDisplay = result.tierSourceDetail ?? result.tierSource;\n\n if (result.valid) {\n lines.push(chalk.green(\"✓ Tier validation passed\"));\n lines.push(` Tier: ${result.tier} (source: ${sourceDisplay})`);\n lines.push(formatRulesetsMessage(result));\n } else {\n lines.push(...formatFailedValidation(result, sourceDisplay));\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format tier validation result as JSON\n */\nexport function formatTierResultJson(result: ValidateTierResult): string {\n return JSON.stringify(result, null, 2);\n}\n","/**\n * Valid project tiers\n */\nexport type Tier = \"production\" | \"internal\" | \"prototype\";\n\n/**\n * Valid tier values as a constant array for validation and export\n */\nexport const VALID_TIERS: readonly Tier[] = [\"production\", \"internal\", \"prototype\"];\n\n/**\n * Detailed tier source indicating why a default was used\n */\nexport type TierSourceDetail =\n | \"standards.toml\" // Tier was read from [metadata] section\n | \"default\" // Generic default (for backwards compatibility)\n | \"default (file not found)\" // standards.toml doesn't exist\n | \"default (no metadata)\" // standards.toml exists but no [metadata] section\n | \"default (tier not specified)\" // [metadata] exists but no tier key\n | \"default (invalid value)\"; // [metadata] has tier but value is invalid\n\n/**\n * Options for the tier validation command\n */\nexport interface ValidateTierOptions {\n /** Path to standards.toml config file */\n config?: string;\n /** Output format */\n format?: \"text\" | \"json\";\n}\n\n/**\n * Result of tier validation\n */\nexport interface ValidateTierResult {\n /** Whether validation passed */\n valid: boolean;\n /** Project tier from standards.toml [metadata] (defaults to \"internal\") */\n tier: Tier;\n /** Source of tier value */\n tierSource: \"standards.toml\" | \"default\";\n /** Detailed source of tier value with reason for default */\n tierSourceDetail?: TierSourceDetail;\n /** Rulesets from standards.toml extends section */\n rulesets: string[];\n /** Expected ruleset suffix pattern */\n expectedPattern: string;\n /** Matched rulesets (those that satisfy the tier requirement) */\n matchedRulesets: string[];\n /** Error message if invalid */\n error?: string;\n /** Invalid tier value that was rejected (for error messages) */\n invalidTierValue?: string;\n /** Whether extends is configured but has empty rulesets */\n hasEmptyRulesets?: boolean;\n /** Registry URL if extends is configured */\n registryUrl?: string;\n /** Warnings about configuration */\n warnings?: string[];\n}\n","/**\n * MCP Server for coding standards\n */\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n\nimport { loadConfigAsync } from \"../core/index.js\";\nimport {\n createGetGuidelineHandler,\n getGuidelineInputSchema,\n createGetRulesetHandler,\n getRulesetInputSchema,\n createGetStandardsHandler,\n getStandardsInputSchema,\n createListGuidelinesHandler,\n listGuidelinesInputSchema,\n} from \"./tools/index.js\";\n\n/** Options for creating the MCP server */\nexport interface CreateServerOptions {\n /** Standards repository source (e.g., \"github:owner/repo\" or local path) */\n standardsSource?: string;\n}\n\n/**\n * Create and configure the MCP server with all tools registered.\n */\nexport function createServer(options: CreateServerOptions = {}): McpServer {\n const server = new McpServer({\n name: \"cm-standards\",\n version: \"1.0.0\",\n });\n\n const { standardsSource } = options;\n\n // Register get_standards tool - smart context matching\n server.registerTool(\"get_standards\", {\n description:\n \"Get composed coding standards matching a context string. Use this to fetch relevant guidelines for a specific technology stack or task.\",\n inputSchema: getStandardsInputSchema,\n }, createGetStandardsHandler(standardsSource));\n\n // Register list_guidelines tool\n server.registerTool(\"list_guidelines\", {\n description: \"List all available coding guidelines with optional category filter.\",\n inputSchema: listGuidelinesInputSchema,\n }, createListGuidelinesHandler(standardsSource));\n\n // Register get_guideline tool\n server.registerTool(\"get_guideline\", {\n description: \"Get a single coding guideline by its ID.\",\n inputSchema: getGuidelineInputSchema,\n }, createGetGuidelineHandler(standardsSource));\n\n // Register get_ruleset tool\n server.registerTool(\"get_ruleset\", {\n description:\n \"Get a tool configuration ruleset by ID (e.g., typescript-production, python-internal).\",\n inputSchema: getRulesetInputSchema,\n }, createGetRulesetHandler(standardsSource));\n\n return server;\n}\n\n/**\n * Start the MCP server with stdio transport.\n * Loads configuration from standards.toml to get the standards source.\n */\nexport async function startServer(): Promise<void> {\n let standardsSource: string | undefined;\n\n // Try to load config to get standards source\n try {\n const { config } = await loadConfigAsync();\n standardsSource = config.mcp?.standards?.source;\n } catch {\n // Config not found or invalid, use defaults\n }\n\n const server = createServer({ standardsSource });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","/**\n * MCP tool: get_guideline\n * Gets a single coding guideline by ID\n */\nimport { z } from \"zod\";\n\nimport {\n fetchStandardsRepo,\n fetchStandardsRepoFromSource,\n getGuidelinesDir,\n loadGuideline,\n} from \"../standards/index.js\";\n\n/** Input schema for get_guideline tool */\nexport const getGuidelineInputSchema = {\n id: z.string().describe('Guideline ID (e.g., \"auth\", \"database\", \"typescript\")'),\n};\n\n/** Handler result type - must have index signature for MCP SDK */\ninterface HandlerResult {\n [x: string]: unknown;\n content: { type: \"text\"; text: string }[];\n isError?: boolean;\n}\n\n/**\n * Create a get_guideline handler with optional custom source.\n * @param source - Optional standards source (e.g., \"github:owner/repo\" or local path)\n */\nexport function createGetGuidelineHandler(\n source?: string\n): (args: { id: string }) => Promise<HandlerResult> {\n return async (args) => {\n const repoPath = source\n ? await fetchStandardsRepoFromSource(source)\n : await fetchStandardsRepo();\n const guidelinesDir = getGuidelinesDir(repoPath);\n const guideline = loadGuideline(guidelinesDir, args.id);\n\n if (!guideline) {\n return {\n content: [\n {\n type: \"text\",\n text: `Guideline not found: ${args.id}`,\n },\n ],\n isError: true,\n };\n }\n\n // Return full markdown content with frontmatter info\n const header = `# ${guideline.title}\\n\\n**Category:** ${guideline.category} | **Priority:** ${guideline.priority}\\n**Tags:** ${guideline.tags.join(\", \")}\\n\\n---\\n\\n`;\n\n return {\n content: [\n {\n type: \"text\",\n text: header + guideline.content,\n },\n ],\n };\n };\n}\n","/**\n * MCP tool: get_ruleset\n * Gets a tool configuration ruleset by ID\n */\nimport { z } from \"zod\";\n\nimport {\n fetchStandardsRepo,\n fetchStandardsRepoFromSource,\n getRulesetsDir,\n loadRuleset,\n listRulesets,\n} from \"../standards/index.js\";\n\n/** Input schema for get_ruleset tool */\nexport const getRulesetInputSchema = {\n id: z.string().describe('Ruleset ID (e.g., \"typescript-production\", \"python-internal\")'),\n};\n\n/** Handler result type - must have index signature for MCP SDK */\ninterface HandlerResult {\n [x: string]: unknown;\n content: { type: \"text\"; text: string }[];\n isError?: boolean;\n}\n\n/**\n * Create a get_ruleset handler with optional custom source.\n * @param source - Optional standards source (e.g., \"github:owner/repo\" or local path)\n */\nexport function createGetRulesetHandler(\n source?: string\n): (args: { id: string }) => Promise<HandlerResult> {\n return async (args) => {\n const repoPath = source\n ? await fetchStandardsRepoFromSource(source)\n : await fetchStandardsRepo();\n const rulesetsDir = getRulesetsDir(repoPath);\n const ruleset = loadRuleset(rulesetsDir, args.id);\n\n if (!ruleset) {\n const available = listRulesets(rulesetsDir);\n return {\n content: [\n {\n type: \"text\",\n text: `Ruleset not found: ${args.id}\\n\\nAvailable rulesets:\\n${available.map((r) => `- ${r}`).join(\"\\n\")}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Ruleset: ${ruleset.id}\\n\\n\\`\\`\\`toml\\n${ruleset.content}\\n\\`\\`\\``,\n },\n ],\n };\n };\n}\n","/**\n * MCP tool: get_standards\n * Gets composed coding standards matching a context string\n */\nimport { z } from \"zod\";\n\nimport {\n fetchStandardsRepo,\n fetchStandardsRepoFromSource,\n getGuidelinesDir,\n loadAllGuidelines,\n matchGuidelines,\n composeGuidelines,\n} from \"../standards/index.js\";\n\n/** Input schema for get_standards tool */\nexport const getStandardsInputSchema = {\n context: z\n .string()\n .describe(\n 'Context string describing the task or technology stack (e.g., \"python fastapi llm postgresql\")'\n ),\n limit: z.number().optional().describe(\"Maximum number of guidelines to return (default: 5)\"),\n};\n\n/** Handler result type - must have index signature for MCP SDK */\ninterface HandlerResult {\n [x: string]: unknown;\n content: { type: \"text\"; text: string }[];\n}\n\n/**\n * Create a get_standards handler with optional custom source.\n * @param source - Optional standards source (e.g., \"github:owner/repo\" or local path)\n */\nexport function createGetStandardsHandler(\n source?: string\n): (args: { context: string; limit?: number }) => Promise<HandlerResult> {\n return async (args) => {\n const repoPath = source\n ? await fetchStandardsRepoFromSource(source)\n : await fetchStandardsRepo();\n const guidelinesDir = getGuidelinesDir(repoPath);\n const guidelines = loadAllGuidelines(guidelinesDir);\n\n const limit = args.limit ?? 5;\n const matches = matchGuidelines(guidelines, args.context, limit);\n\n const composed = composeGuidelines(matches);\n\n // Add summary header\n const summary =\n matches.length > 0\n ? `Found ${matches.length} matching guideline(s) for context: \"${args.context}\"\\n\\nMatched guidelines (by relevance):\\n${matches.map((m) => `- ${m.guideline.title} (score: ${m.score.toFixed(1)})`).join(\"\\n\")}\\n\\n---\\n\\n`\n : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: summary + composed,\n },\n ],\n };\n };\n}\n","/**\n * MCP tool: list_guidelines\n * Lists all available coding guidelines with optional category filter\n */\nimport { z } from \"zod\";\n\nimport {\n fetchStandardsRepo,\n fetchStandardsRepoFromSource,\n getGuidelinesDir,\n loadAllGuidelines,\n toListItems,\n} from \"../standards/index.js\";\n\n/** Input schema for list_guidelines tool */\nexport const listGuidelinesInputSchema = {\n category: z.string().optional().describe(\"Optional category filter (e.g., 'security', 'infrastructure')\"),\n};\n\n/** Handler result type - must have index signature for MCP SDK */\ninterface HandlerResult {\n [x: string]: unknown;\n content: { type: \"text\"; text: string }[];\n}\n\n/**\n * Create a list_guidelines handler with optional custom source.\n * @param source - Optional standards source (e.g., \"github:owner/repo\" or local path)\n */\nexport function createListGuidelinesHandler(\n source?: string\n): (args: { category?: string }) => Promise<HandlerResult> {\n return async (args) => {\n const repoPath = source\n ? await fetchStandardsRepoFromSource(source)\n : await fetchStandardsRepo();\n const guidelinesDir = getGuidelinesDir(repoPath);\n let guidelines = loadAllGuidelines(guidelinesDir);\n\n // Filter by category if provided\n if (args.category) {\n const categoryLower = args.category.toLowerCase();\n guidelines = guidelines.filter((g) => g.category.toLowerCase() === categoryLower);\n }\n\n const items = toListItems(guidelines);\n\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(items, null, 2),\n },\n ],\n };\n };\n}\n","/**\n * Infra scan module - Public API\n *\n * Provides functionality to verify AWS resources declared in a manifest actually exist.\n */\n\nimport * as path from \"node:path\";\n\nimport chalk from \"chalk\";\n\nimport { getProjectRoot, loadConfigAsync } from \"../core/index.js\";\nimport { ExitCode } from \"../core/index.js\";\n\nimport { ManifestError, readManifest } from \"./manifest.js\";\nimport { formatScan } from \"./output.js\";\nimport { scanManifest } from \"./scan.js\";\nimport type { InfraScanResult, RunInfraScanOptions, ScanInfraOptions } from \"./types.js\";\n\n// Re-export types\nexport type {\n AccountId,\n AccountScanResult,\n Arn,\n CloudProvider,\n GcpResourcePath,\n InfraScanResult,\n InfraScanSummary,\n LegacyManifest,\n Manifest,\n ManifestAccount,\n MultiAccountManifest,\n ParsedArn,\n ParsedGcpResource,\n PulumiResource,\n PulumiStackExport,\n ResourceCheckResult,\n ResourceIdentifier,\n ScanInfraOptions,\n} from \"./types.js\";\n\n// Re-export Zod schemas and validation functions for public API\nexport {\n // Schemas - for external consumers to validate manifests\n ArnSchema,\n AccountIdSchema,\n AccountKeySchema,\n CloudProviderSchema,\n GcpResourcePathSchema,\n InfraScanResultSchema,\n InfraScanSummarySchema,\n LegacyManifestSchema,\n ManifestAccountSchema,\n ManifestSchema,\n MultiAccountManifestSchema,\n ParsedArnSchema,\n ParsedGcpResourceSchema,\n PulumiResourceSchema,\n PulumiStackExportSchema,\n ResourceCheckResultSchema,\n ResourceIdentifierSchema,\n // Validation functions\n isValidArnFormat,\n isValidGcpResourcePath,\n isValidAccountKey,\n isMultiAccountManifestSchema,\n isLegacyManifestSchema,\n validateArn,\n validateGcpResourcePath,\n validateAccountKey,\n validateManifest,\n validateMultiAccountManifest,\n validateLegacyManifest,\n validateStackExport,\n} from \"./types.js\";\nexport {\n ManifestError,\n isMultiAccountManifest,\n isLegacyManifest,\n parseAccountKey,\n formatAccountKey,\n normalizeManifest,\n detectAccountFromResource,\n getAllResources,\n} from \"./manifest.js\";\nexport { parseArn, isValidArn } from \"./arn.js\";\nexport { parseGcpResource, isValidGcpResource } from \"./gcp.js\";\nexport { SUPPORTED_SERVICES, isSupportedService } from \"./checkers/index.js\";\nexport { SUPPORTED_GCP_SERVICES, isSupportedGcpService } from \"./checkers/gcp/index.js\";\n\n// Re-export generate functionality\nexport {\n DEFAULT_MANIFEST_NAME,\n generateManifestFromStdin,\n generateManifestFromFile,\n generateMultiAccountFromStdin,\n generateMultiAccountFromFile,\n generateWithMerge,\n mergeIntoManifest,\n parseStackExport,\n parseStackExportMultiAccount,\n readExistingManifest,\n writeManifest,\n type GenerateManifestOptions,\n} from \"./generate.js\";\n\n/**\n * Scan infrastructure resources declared in a manifest.\n *\n * This is the programmatic API for @standards-kit/drift integration.\n *\n * @param options - Options for the scan\n * @returns Scan result with all resource check results and summary\n *\n * @example\n * ```typescript\n * import { scanInfra } from \"@standards-kit/conform\";\n *\n * const result = await scanInfra({ manifestPath: \"./infra-manifest.json\" });\n * console.log(result.summary);\n * // { total: 5, found: 4, missing: 1, errors: 0 }\n * ```\n */\nexport async function scanInfra(options: ScanInfraOptions = {}): Promise<InfraScanResult> {\n const resolvedManifestPath = await resolveManifestPath(options);\n const manifest = readManifest(resolvedManifestPath);\n return scanManifest(manifest, resolvedManifestPath, { account: options.account });\n}\n\nasync function resolveManifestPath(options: ScanInfraOptions): Promise<string> {\n const { manifestPath, configPath } = options;\n\n if (manifestPath) {\n return path.isAbsolute(manifestPath)\n ? manifestPath\n : path.resolve(process.cwd(), manifestPath);\n }\n\n const { config, configPath: loadedConfigPath } = await loadConfigAsync(configPath);\n const projectRoot = getProjectRoot(loadedConfigPath);\n\n const infraConfig = config.infra;\n if (!infraConfig?.enabled) {\n throw new ManifestError(\"Infra scanning is not enabled in standards.toml\");\n }\n\n const manifestName = infraConfig.manifest;\n return path.resolve(projectRoot, manifestName);\n}\n\n/**\n * Run infra scan from CLI\n */\nexport async function runInfraScan(options: RunInfraScanOptions = {}): Promise<void> {\n const { format = \"text\", manifestPath, configPath, account } = options;\n\n try {\n const result = await scanInfra({ manifestPath, configPath, account });\n outputResult(result, format);\n } catch (error) {\n handleError(error, format);\n }\n}\n\nfunction outputResult(result: InfraScanResult, format: \"text\" | \"json\"): never {\n process.stdout.write(`${formatScan(result, format)}\\n`);\n\n if (result.summary.errors > 0) {\n process.exit(ExitCode.RUNTIME_ERROR);\n } else if (result.summary.missing > 0) {\n process.exit(ExitCode.VIOLATIONS_FOUND);\n } else {\n process.exit(ExitCode.SUCCESS);\n }\n}\n\nfunction handleError(error: unknown, format: \"text\" | \"json\"): never {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n const isConfigError = error instanceof ManifestError;\n\n if (format === \"json\") {\n process.stdout.write(`${JSON.stringify({ error: message }, null, 2)}\\n`);\n } else {\n console.error(chalk.red(`Error: ${message}`));\n }\n\n process.exit(isConfigError ? ExitCode.CONFIG_ERROR : ExitCode.RUNTIME_ERROR);\n}\n\n/**\n * Options for CLI generate command\n */\nexport interface RunInfraGenerateOptions {\n /** Input file path (if not provided, reads from stdin) */\n input?: string;\n /** Output file path (defaults to infra-manifest.json) */\n output?: string;\n /** Project name override */\n project?: string;\n /** Output to stdout instead of file */\n stdout?: boolean;\n /** Account alias (e.g., \"prod-aws\") for multi-account manifests */\n account?: string;\n /** Explicit account ID (e.g., \"aws:111111111111\") */\n accountId?: string;\n /** Merge into existing manifest instead of overwriting */\n merge?: boolean;\n}\n\n/**\n * Run infra generate from CLI\n */\nexport async function runInfraGenerate(options: RunInfraGenerateOptions = {}): Promise<void> {\n const {\n generateWithMerge,\n writeManifest,\n DEFAULT_MANIFEST_NAME,\n } = await import(\"./generate.js\");\n const { getAllResources, isMultiAccountManifest } = await import(\"./manifest.js\");\n\n try {\n const manifest = await generateWithMerge(options.input, {\n project: options.project,\n output: options.output,\n account: options.account,\n accountId: options.accountId,\n merge: options.merge,\n });\n\n writeManifest(manifest, { output: options.output, stdout: options.stdout });\n\n if (!options.stdout) {\n const outputPath = options.output ?? DEFAULT_MANIFEST_NAME;\n const resourceCount = getAllResources(manifest).length;\n const accountCount = isMultiAccountManifest(manifest)\n ? Object.keys(manifest.accounts).length\n : 1;\n const accountLabel = accountCount === 1 ? \"account\" : \"accounts\";\n\n console.error(\n chalk.green(`✓ Generated ${outputPath} with ${resourceCount} resources across ${accountCount} ${accountLabel}`)\n );\n }\n\n process.exit(ExitCode.SUCCESS);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.error(chalk.red(`Error: ${message}`));\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n}\n","/**\n * Output formatters for infra scan results\n */\n\nimport chalk from \"chalk\";\n\nimport type { AccountScanResult, InfraScanResult, ResourceCheckResult } from \"./types.js\";\n\n/**\n * Format scan result as text output\n */\nfunction formatScanText(result: InfraScanResult): string {\n const lines: string[] = [];\n\n formatHeader(lines, result);\n\n // If we have account results, format by account\n if (result.accountResults && Object.keys(result.accountResults).length > 0) {\n formatAccountResults(lines, result.accountResults);\n formatOverallSummary(lines, result.summary);\n } else {\n // Legacy format - flat results\n formatResultsByStatus(lines, result.results);\n formatSummary(lines, result.summary);\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction formatHeader(lines: string[], result: InfraScanResult): void {\n lines.push(chalk.bold(\"Infrastructure Scan Results\"));\n lines.push(`Manifest: ${result.manifest}`);\n if (result.project) {\n lines.push(`Project: ${result.project}`);\n }\n lines.push(\"\");\n}\n\nfunction formatResultsByStatus(lines: string[], results: ResourceCheckResult[]): void {\n const found = results.filter((r) => r.exists && !r.error);\n const missing = results.filter((r) => !r.exists && !r.error);\n const errors = results.filter((r) => r.error);\n\n formatResultSection(lines, found, {\n colorFn: chalk.green.bold,\n label: \"Found\",\n formatLine: formatFoundLine,\n });\n formatResultSection(lines, missing, {\n colorFn: chalk.red.bold,\n label: \"Missing\",\n formatLine: formatMissingLine,\n });\n formatResultSection(lines, errors, {\n colorFn: chalk.yellow.bold,\n label: \"Errors\",\n formatLine: formatErrorLine,\n });\n}\n\ninterface SectionConfig {\n colorFn: (s: string) => string;\n label: string;\n formatLine: (r: ResourceCheckResult) => string;\n}\n\nfunction formatResultSection(\n lines: string[],\n results: ResourceCheckResult[],\n config: SectionConfig\n): void {\n if (results.length === 0) {\n return;\n }\n lines.push(config.colorFn(`${config.label} (${results.length}):`));\n for (const r of results) {\n lines.push(config.formatLine(r));\n }\n lines.push(\"\");\n}\n\nfunction formatFoundLine(r: ResourceCheckResult): string {\n const icon = chalk.green(\"✓\");\n const resourceInfo = `${r.service}/${r.resourceType}/${r.resourceId}`;\n return ` ${icon} ${resourceInfo}`;\n}\n\nfunction formatMissingLine(r: ResourceCheckResult): string {\n const icon = chalk.red(\"✗\");\n const resourceInfo = `${r.service}/${r.resourceType}/${r.resourceId}`;\n return ` ${icon} ${resourceInfo}`;\n}\n\nfunction formatErrorLine(r: ResourceCheckResult): string {\n const icon = chalk.yellow(\"!\");\n const resourceInfo = `${r.service}/${r.resourceType}/${r.resourceId}`;\n const errorText = r.error ?? \"Unknown error\";\n return ` ${icon} ${resourceInfo} - ${chalk.yellow(errorText)}`;\n}\n\nfunction formatSummary(\n lines: string[],\n summary: { total: number; found: number; missing: number; errors: number }\n): void {\n lines.push(chalk.bold(\"Summary:\"));\n lines.push(` Total: ${summary.total}`);\n lines.push(chalk.green(` Found: ${summary.found}`));\n lines.push(chalk.red(` Missing: ${summary.missing}`));\n if (summary.errors > 0) {\n lines.push(chalk.yellow(` Errors: ${summary.errors}`));\n }\n}\n\n/**\n * Format overall summary for multi-account manifests\n */\nfunction formatOverallSummary(\n lines: string[],\n summary: { total: number; found: number; missing: number; errors: number }\n): void {\n lines.push(chalk.bold(\"Overall Summary:\"));\n lines.push(` Total: ${summary.total}`);\n lines.push(chalk.green(` Found: ${summary.found}`));\n lines.push(chalk.red(` Missing: ${summary.missing}`));\n if (summary.errors > 0) {\n lines.push(chalk.yellow(` Errors: ${summary.errors}`));\n }\n}\n\n/**\n * Format results grouped by account\n */\nfunction formatAccountResults(\n lines: string[],\n accountResults: Record<string, AccountScanResult>\n): void {\n for (const [accountKey, account] of Object.entries(accountResults)) {\n const accountLabel = account.alias\n ? `${account.alias} (${accountKey})`\n : accountKey;\n\n lines.push(chalk.bold.cyan(`\\nAccount: ${accountLabel}`));\n lines.push(chalk.gray(\"─\".repeat(40)));\n\n // Format results for this account\n formatAccountResourceResults(lines, account.results);\n\n // Account-level summary\n const { summary } = account;\n const summaryParts: string[] = [];\n if (summary.found > 0) {\n summaryParts.push(chalk.green(`${summary.found} found`));\n }\n if (summary.missing > 0) {\n summaryParts.push(chalk.red(`${summary.missing} missing`));\n }\n if (summary.errors > 0) {\n summaryParts.push(chalk.yellow(`${summary.errors} errors`));\n }\n lines.push(` ${chalk.dim(\"Summary:\")} ${summaryParts.join(\", \")}`);\n }\n lines.push(\"\");\n}\n\n/**\n * Format resource results for a single account (inline style)\n */\nfunction formatAccountResourceResults(lines: string[], results: ResourceCheckResult[]): void {\n for (const r of results) {\n if (r.error) {\n const icon = chalk.yellow(\"!\");\n lines.push(` ${icon} ${r.arn} - ${chalk.yellow(r.error)}`);\n } else if (r.exists) {\n const icon = chalk.green(\"✓\");\n lines.push(` ${icon} ${r.arn}`);\n } else {\n const icon = chalk.red(\"✗\");\n lines.push(` ${icon} ${r.arn}`);\n }\n }\n}\n\n/**\n * Format scan result as JSON output\n */\nfunction formatScanJson(result: InfraScanResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Format scan result based on output format\n */\nexport function formatScan(result: InfraScanResult, format: \"text\" | \"json\"): string {\n return format === \"json\" ? formatScanJson(result) : formatScanText(result);\n}\n","/**\n * Checker registry with lazy loading\n *\n * Checkers are loaded on-demand to avoid loading all AWS SDK clients upfront.\n */\n\nimport type { ResourceChecker } from \"./types.js\";\n\n/**\n * Supported AWS services for resource checking\n */\nexport const SUPPORTED_SERVICES = [\n \"s3\",\n \"lambda\",\n \"dynamodb\",\n \"sqs\",\n \"sns\",\n \"iam\",\n \"secretsmanager\",\n \"logs\",\n \"ecs\",\n \"rds\",\n \"ec2\",\n \"elasticache\",\n \"elasticloadbalancing\",\n] as const;\n\nexport type SupportedService = (typeof SUPPORTED_SERVICES)[number];\n\n/**\n * Check if a service is supported\n */\nexport function isSupportedService(service: string): service is SupportedService {\n return SUPPORTED_SERVICES.includes(service as SupportedService);\n}\n\n/**\n * Factory functions for checkers (lazy-loaded)\n */\nconst checkerFactories: Record<SupportedService, () => Promise<ResourceChecker>> = {\n s3: async () => (await import(\"./s3.js\")).S3Checker,\n lambda: async () => (await import(\"./lambda.js\")).LambdaChecker,\n dynamodb: async () => (await import(\"./dynamodb.js\")).DynamoDBChecker,\n sqs: async () => (await import(\"./sqs.js\")).SQSChecker,\n sns: async () => (await import(\"./sns.js\")).SNSChecker,\n iam: async () => (await import(\"./iam.js\")).IAMChecker,\n secretsmanager: async () => (await import(\"./secretsmanager.js\")).SecretsManagerChecker,\n logs: async () => (await import(\"./cloudwatch.js\")).CloudWatchLogsChecker,\n ecs: async () => (await import(\"./ecs.js\")).ECSChecker,\n rds: async () => (await import(\"./rds.js\")).RDSChecker,\n ec2: async () => (await import(\"./ec2.js\")).EC2Checker,\n elasticache: async () => (await import(\"./elasticache.js\")).ElastiCacheChecker,\n elasticloadbalancing: async () => (await import(\"./elb.js\")).ELBChecker,\n};\n\n/**\n * Cache of loaded checkers\n */\nconst checkerCache = new Map<SupportedService, ResourceChecker>();\n\n/**\n * Get a checker for a service, loading it if necessary\n *\n * @param service - The AWS service name\n * @returns The checker instance, or undefined if the service is not supported\n */\nexport async function getChecker(service: string): Promise<ResourceChecker | undefined> {\n if (!isSupportedService(service)) {\n return undefined;\n }\n\n // Return cached checker if available\n const cached = checkerCache.get(service);\n if (cached) {\n return cached;\n }\n\n // Load and cache the checker\n const factory = checkerFactories[service];\n const checker = await factory();\n checkerCache.set(service, checker);\n\n return checker;\n}\n\n/**\n * Clear the checker cache (useful for testing)\n */\nexport function clearCheckerCache(): void {\n checkerCache.clear();\n}\n","/**\n * GCP checker registry with lazy loading\n */\n\nimport type { GcpResourceChecker } from \"../types.js\";\n\n/**\n * Supported GCP services for resource checking\n */\nexport const SUPPORTED_GCP_SERVICES = [\"run\", \"secretmanager\", \"artifactregistry\", \"iam\"] as const;\n\nexport type SupportedGcpService = (typeof SUPPORTED_GCP_SERVICES)[number];\n\n/**\n * Check if a GCP service is supported\n */\nexport function isSupportedGcpService(service: string): service is SupportedGcpService {\n return SUPPORTED_GCP_SERVICES.includes(service as SupportedGcpService);\n}\n\n/**\n * Factory functions for GCP checkers (lazy-loaded)\n */\nconst checkerFactories: Record<SupportedGcpService, () => Promise<GcpResourceChecker>> = {\n run: async () => (await import(\"./cloudrun.js\")).CloudRunChecker,\n secretmanager: async () => (await import(\"./secretmanager.js\")).SecretManagerChecker,\n artifactregistry: async () => (await import(\"./artifactregistry.js\")).ArtifactRegistryChecker,\n iam: async () => (await import(\"./iam.js\")).ServiceAccountChecker,\n};\n\n/**\n * Cache of loaded GCP checkers\n */\nconst checkerCache = new Map<SupportedGcpService, GcpResourceChecker>();\n\n/**\n * Get a GCP checker for a service, loading it if necessary\n */\nexport async function getGcpChecker(service: string): Promise<GcpResourceChecker | undefined> {\n if (!isSupportedGcpService(service)) {\n return undefined;\n }\n\n const cached = checkerCache.get(service);\n if (cached) {\n return cached;\n }\n\n const factory = checkerFactories[service];\n const checker = await factory();\n checkerCache.set(service, checker);\n\n return checker;\n}\n","/**\n * Scan logic for infra scan\n *\n * Orchestrates checking all resources in a manifest (AWS and GCP)\n */\n\nimport { CONCURRENCY } from \"../constants.js\";\nimport { isValidArn, parseArn } from \"./arn.js\";\nimport { getChecker, isSupportedService, SUPPORTED_SERVICES } from \"./checkers/index.js\";\nimport {\n getGcpChecker,\n isSupportedGcpService,\n SUPPORTED_GCP_SERVICES,\n} from \"./checkers/gcp/index.js\";\nimport { isValidGcpResource, parseGcpResource } from \"./gcp.js\";\nimport { getAllResources, isMultiAccountManifest } from \"./manifest.js\";\nimport type {\n AccountScanResult,\n InfraScanResult,\n InfraScanSummary,\n Manifest,\n MultiAccountManifest,\n ResourceCheckResult,\n} from \"./types.js\";\n\n/**\n * Options for scanning\n */\ninterface ScanOptions {\n /** Max number of parallel checks */\n concurrency?: number;\n /** Filter to specific account (by alias or account key) */\n account?: string;\n}\n\n/**\n * Scan all resources in a manifest\n *\n * @param manifest - The manifest containing resources to check\n * @param manifestPath - Path to the manifest file (for result metadata)\n * @param options - Scan options\n * @returns Scan result with all resource check results and summary\n */\nexport async function scanManifest(\n manifest: Manifest,\n manifestPath: string,\n options: ScanOptions = {}\n): Promise<InfraScanResult> {\n const concurrency = options.concurrency ?? CONCURRENCY.infraScan;\n\n // For multi-account manifests, scan by account\n if (isMultiAccountManifest(manifest)) {\n return scanMultiAccountManifest(manifest, manifestPath, options);\n }\n\n // Legacy manifest - simple flat scan\n const resources = getAllResources(manifest);\n const results = await checkResourcesWithConcurrency(resources, concurrency);\n const summary = calculateSummary(results);\n\n return {\n manifest: manifestPath,\n project: manifest.project,\n results,\n summary,\n };\n}\n\n/**\n * Scan a multi-account manifest\n */\nasync function scanMultiAccountManifest(\n manifest: MultiAccountManifest,\n manifestPath: string,\n options: ScanOptions = {}\n): Promise<InfraScanResult> {\n const concurrency = options.concurrency ?? CONCURRENCY.infraScan;\n const accountResults: Record<string, AccountScanResult> = {};\n const allResults: ResourceCheckResult[] = [];\n\n // Get accounts to scan (filter by account if specified)\n const accountsToScan = filterAccounts(manifest, options.account);\n\n for (const [accountKey, account] of Object.entries(accountsToScan)) {\n const results = await checkResourcesWithConcurrency(account.resources, concurrency);\n const summary = calculateSummary(results);\n\n accountResults[accountKey] = {\n alias: account.alias,\n results,\n summary,\n };\n\n allResults.push(...results);\n }\n\n // Calculate overall summary\n const overallSummary = calculateSummary(allResults);\n\n return {\n manifest: manifestPath,\n project: manifest.project,\n results: allResults,\n summary: overallSummary,\n accountResults,\n };\n}\n\n/**\n * Filter accounts based on account filter\n * Returns matching accounts or all accounts if no filter\n */\nfunction filterAccounts(\n manifest: MultiAccountManifest,\n accountFilter?: string\n): Record<string, { alias?: string; resources: string[] }> {\n if (!accountFilter) {\n return manifest.accounts;\n }\n\n // Check if filter is an account key (e.g., \"aws:123456\")\n if (accountFilter in manifest.accounts) {\n return { [accountFilter]: manifest.accounts[accountFilter] };\n }\n\n // Check if filter matches an alias\n for (const [key, account] of Object.entries(manifest.accounts)) {\n if (account.alias === accountFilter) {\n return { [key]: account };\n }\n }\n\n // No match found - return empty\n return {};\n}\n\n/**\n * Check resources with controlled concurrency using a simple batching approach\n */\nasync function checkResourcesWithConcurrency(\n arns: string[],\n concurrency: number\n): Promise<ResourceCheckResult[]> {\n const results: ResourceCheckResult[] = [];\n\n // Process in batches\n for (let i = 0; i < arns.length; i += concurrency) {\n const batch = arns.slice(i, i + concurrency);\n const batchResults = await Promise.all(batch.map((arn) => checkResource(arn)));\n results.push(...batchResults);\n }\n\n // Sort results to maintain consistent order (by ARN)\n results.sort((a, b) => a.arn.localeCompare(b.arn));\n\n return results;\n}\n\n/**\n * Check a single resource (AWS or GCP)\n */\nasync function checkResource(resource: string): Promise<ResourceCheckResult> {\n // Detect cloud provider and route to appropriate checker\n if (isValidArn(resource)) {\n return checkAwsResource(resource);\n }\n if (isValidGcpResource(resource)) {\n return checkGcpResource(resource);\n }\n\n return {\n arn: resource,\n exists: false,\n error: \"Invalid resource format (not a valid AWS ARN or GCP resource path)\",\n service: \"unknown\",\n resourceType: \"unknown\",\n resourceId: resource,\n };\n}\n\n/**\n * Check an AWS resource\n */\nasync function checkAwsResource(arn: string): Promise<ResourceCheckResult> {\n const parsed = parseArn(arn);\n if (!parsed) {\n return errorResult({ arn, error: \"Invalid ARN format\" });\n }\n\n if (!isSupportedService(parsed.service)) {\n const msg = `Unsupported AWS service: ${parsed.service}. Supported: ${SUPPORTED_SERVICES.join(\", \")}`;\n return errorResult({\n arn,\n error: msg,\n service: parsed.service,\n resourceType: parsed.resourceType,\n resourceId: parsed.resourceId,\n });\n }\n\n const checker = await getChecker(parsed.service);\n if (!checker) {\n return errorResult({ arn, error: `No checker for AWS service: ${parsed.service}`, service: parsed.service });\n }\n\n return checker.check(parsed);\n}\n\n/**\n * Check a GCP resource\n */\nasync function checkGcpResource(resource: string): Promise<ResourceCheckResult> {\n const parsed = parseGcpResource(resource);\n if (!parsed) {\n return errorResult({ arn: resource, error: \"Invalid GCP resource path format\" });\n }\n\n if (!isSupportedGcpService(parsed.service)) {\n const msg = `Unsupported GCP service: ${parsed.service}. Supported: ${SUPPORTED_GCP_SERVICES.join(\", \")}`;\n return errorResult({\n arn: resource,\n error: msg,\n service: parsed.service,\n resourceType: parsed.resourceType,\n resourceId: parsed.resourceId,\n });\n }\n\n const checker = await getGcpChecker(parsed.service);\n if (!checker) {\n return errorResult({ arn: resource, error: `No checker for GCP service: ${parsed.service}`, service: parsed.service });\n }\n\n return checker.check(parsed);\n}\n\ninterface ErrorResultParams {\n arn: string;\n error: string;\n service?: string;\n resourceType?: string;\n resourceId?: string;\n}\n\n/**\n * Create an error result\n */\nfunction errorResult(params: ErrorResultParams): ResourceCheckResult {\n const { arn, error, service = \"unknown\", resourceType = \"unknown\", resourceId = arn } = params;\n return { arn, exists: false, error, service, resourceType, resourceId };\n}\n\n/**\n * Calculate summary statistics from check results\n */\nfunction calculateSummary(results: ResourceCheckResult[]): InfraScanSummary {\n let found = 0;\n let missing = 0;\n let errors = 0;\n\n for (const result of results) {\n if (result.error) {\n errors++;\n } else if (result.exists) {\n found++;\n } else {\n missing++;\n }\n }\n\n return {\n total: results.length,\n found,\n missing,\n errors,\n };\n}\n"],"mappings":"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","names":["fs","path","fs","path","path","execa","execa","fs","path","execa","execa","fs","execa","execa","path","glob","DEFAULT_EXCLUDE","glob","fs","execa","execa","fs","path","execa","execa","fs","path","execa","execa","fs","path","execa","execa","fs","path","execa","isSymlink","execa","fs","path","execa","execa","fs","path","execa","execa","fs","path","execa","execa","execa","execa","fs","path","yaml","fs","path","execa","glob","glob","execa","glob","glob","fs","minimatch","minimatch","execa","execa","execa","execa","isEnabled","toolRegistry","getEnabledTools","runTools","execa","execa","path","execa","loadConfigAsync","fs","path","chalk","fs","path","globSync","globSync","fs","path","chalk","matter","fs","path","execa","execa","fs","path","matter","matter","fs","path","chalk","chalk","z","z","z","z","z","z","z","z","path","chalk","chalk","checkerFactories","checkerCache"]}
1
+ {"version":3,"sources":["../src/code/tools/base.ts","../src/code/tools/coverage-run.ts","../src/code/tools/disable-comments.ts","../src/code/tools/comment-utils.ts","../src/code/tools/eslint.ts","../src/code/tools/gitleaks.ts","../src/code/tools/knip.ts","../src/code/tools/naming.ts","../src/code/tools/pipaudit.ts","../src/code/tools/pnpmaudit.ts","../src/code/tools/ruff.ts","../src/code/tools/tsc.ts","../src/code/tools/ty.ts","../src/code/tools/vulture.ts","../src/code/index.ts","../src/process/tools/backups.ts","../src/process/tools/base.ts","../src/process/tools/branches.ts","../src/process/tools/changesets.ts","../src/process/tools/ci.ts","../src/process/tools/codeowners.ts","../src/process/tools/commits.ts","../src/process/tools/coverage.ts","../src/process/tools/docs.ts","../src/process/tools/docs-helpers.ts","../src/process/tools/forbidden-files.ts","../src/process/tools/hooks.ts","../src/process/tools/pr.ts","../src/process/tools/repo.ts","../src/process/tools/tickets.ts","../src/process/index.ts","../src/process/scan/index.ts","../src/process/scan/scanner.ts","../src/process/scan/remote-fetcher.ts","../src/process/scan/validators.ts","../src/output/index.ts","../src/dependencies/index.ts","../src/dependencies/mappings.ts","../src/validate/guidelines.ts","../src/mcp/standards/fetcher.ts","../src/mcp/standards/parser.ts","../src/mcp/standards/matcher.ts","../src/validate/tier.ts","../src/validate/types.ts","../src/mcp/server.ts","../src/mcp/tools/get-guideline.ts","../src/mcp/tools/get-ruleset.ts","../src/mcp/tools/get-standards.ts","../src/mcp/tools/list-guidelines.ts","../src/infra/index.ts","../src/infra/output.ts","../src/infra/checkers/index.ts","../src/infra/checkers/gcp/index.ts","../src/infra/scan.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { CheckResultBuilder, type CheckResult, type IToolRunner, type Violation } from \"../../core/index.js\";\n\n/**\n * Abstract base class for tool runners.\n * Provides common functionality for checking configs and handling errors.\n */\nexport abstract class BaseToolRunner implements IToolRunner {\n abstract readonly name: string;\n abstract readonly rule: string;\n abstract readonly toolId: string;\n abstract readonly configFiles: string[];\n\n /**\n * Check if any of the config files exist\n */\n protected hasConfig(projectRoot: string): boolean {\n return this.configFiles.some((config) => fs.existsSync(path.join(projectRoot, config)));\n }\n\n /**\n * Find which config file exists (if any)\n */\n protected findConfig(projectRoot: string): string | null {\n for (const config of this.configFiles) {\n if (fs.existsSync(path.join(projectRoot, config))) {\n return config;\n }\n }\n return null;\n }\n\n /**\n * Check if an error indicates the tool is not installed\n */\n protected isNotInstalledError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n const message = error.message.toLowerCase();\n return message.includes(\"enoent\") || message.includes(\"not found\");\n }\n\n /**\n * Create a fail result for when config is missing\n */\n protected failNoConfig(duration: number): CheckResult {\n const expected = this.configFiles.join(\" or \");\n return CheckResultBuilder.fail(\n this.name,\n this.rule,\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message: `Config not found. Expected one of: ${expected}`,\n severity: \"error\",\n },\n ],\n duration\n );\n }\n\n /**\n * Create a skip result for when tool is not installed\n */\n protected skipNotInstalled(duration: number): CheckResult {\n return CheckResultBuilder.skip(this.name, this.rule, `${this.name} not installed`, duration);\n }\n\n /**\n * Create a pass result\n */\n protected pass(duration: number): CheckResult {\n return CheckResultBuilder.pass(this.name, this.rule, duration);\n }\n\n /**\n * Create a fail result from violations\n */\n protected fail(violations: Violation[], duration: number): CheckResult {\n return CheckResultBuilder.fail(this.name, this.rule, violations, duration);\n }\n\n /**\n * Create a result from violations (pass if empty, fail otherwise)\n */\n protected fromViolations(violations: Violation[], duration: number): CheckResult {\n return CheckResultBuilder.fromViolations(this.name, this.rule, violations, duration);\n }\n\n /**\n * Run the tool - must be implemented by subclasses\n */\n abstract run(projectRoot: string): Promise<CheckResult>;\n\n /**\n * Default audit implementation - checks if config exists\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (this.hasConfig(projectRoot)) {\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, Date.now() - startTime);\n }\n\n return CheckResultBuilder.fail(\n `${this.name} Config`,\n this.rule,\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: `${this.name} config not found. Expected one of: ${this.configFiles.join(\", \")}`,\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { CheckResultBuilder, type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Coverage run configuration from standards.toml */\ninterface CoverageRunConfig {\n enabled?: boolean;\n min_threshold?: number;\n runner?: \"vitest\" | \"jest\" | \"pytest\" | \"auto\";\n command?: string;\n}\n\n/** Parsed coverage data */\ninterface CoverageData {\n lines?: number;\n statements?: number;\n branches?: number;\n functions?: number;\n}\n\n/** File coverage data from coverage-final.json */\ninterface FileCoverageData {\n s?: Record<string, number>;\n f?: Record<string, number>;\n b?: Record<string, number[]>;\n}\n\n/** Check if a config file exists */\nfunction configExists(projectRoot: string, configFile: string): boolean {\n return fs.existsSync(path.join(projectRoot, configFile));\n}\n\n/** Check if any config from a list exists */\nfunction findConfig(projectRoot: string, configs: string[]): boolean {\n return configs.some((config) => configExists(projectRoot, config));\n}\n\n/** Check for jest config in package.json */\nfunction hasJestInPackageJson(projectRoot: string): boolean {\n const packageJsonPath = path.join(projectRoot, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) {\n return false;\n }\n try {\n const pkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\")) as Record<string, unknown>;\n return Boolean(pkg.jest);\n } catch {\n return false;\n }\n}\n\n/** Safely extract pct from a coverage entry */\nfunction getPct(entry: { pct?: number } | undefined): number | undefined {\n return entry?.pct;\n}\n\n/** Parse coverage-summary.json format */\nfunction parseSummaryFormat(data: Record<string, unknown>): CoverageData | null {\n if (!data.total || typeof data.total !== \"object\") {\n return null;\n }\n const total = data.total as Record<string, { pct?: number } | undefined>;\n return {\n lines: getPct(total.lines),\n statements: getPct(total.statements),\n branches: getPct(total.branches),\n functions: getPct(total.functions),\n };\n}\n\n/** Parse pytest-cov format */\nfunction parsePytestFormat(data: Record<string, unknown>): CoverageData | null {\n if (!data.totals || typeof data.totals !== \"object\") {\n return null;\n }\n const totals = data.totals as { percent_covered?: number };\n if (totals.percent_covered === undefined) {\n return null;\n }\n return { lines: totals.percent_covered };\n}\n\n/** Count covered items in a record */\nfunction countCovered(items: Record<string, number>): { total: number; covered: number } {\n let total = 0;\n let covered = 0;\n for (const count of Object.values(items)) {\n total++;\n if (count > 0) {\n covered++;\n }\n }\n return { total, covered };\n}\n\n/** Count covered branches */\nfunction countCoveredBranches(branches: Record<string, number[]>): {\n total: number;\n covered: number;\n} {\n let total = 0;\n let covered = 0;\n for (const counts of Object.values(branches)) {\n for (const count of counts) {\n total++;\n if (count > 0) {\n covered++;\n }\n }\n }\n return { total, covered };\n}\n\n/** Compute percentage from totals */\nfunction computePercentage(total: number, covered: number): number {\n return total > 0 ? (covered / total) * 100 : 100;\n}\n\n/** Default coverage counts */\nconst zeroCounts = { total: 0, covered: 0 };\n\n/** Process a single file's coverage data */\nfunction processFileCoverage(fileData: FileCoverageData): {\n statements: { total: number; covered: number };\n functions: { total: number; covered: number };\n branches: { total: number; covered: number };\n} {\n return {\n statements: fileData.s ? countCovered(fileData.s) : zeroCounts,\n functions: fileData.f ? countCovered(fileData.f) : zeroCounts,\n branches: fileData.b ? countCoveredBranches(fileData.b) : zeroCounts,\n };\n}\n\n/** Accumulate coverage totals from multiple files */\ninterface CoverageTotals {\n statements: { total: number; covered: number };\n functions: { total: number; covered: number };\n branches: { total: number; covered: number };\n}\n\n/** Create empty coverage totals */\nfunction createEmptyTotals(): CoverageTotals {\n return {\n statements: { total: 0, covered: 0 },\n functions: { total: 0, covered: 0 },\n branches: { total: 0, covered: 0 },\n };\n}\n\n/** Add file coverage to totals */\nfunction addFileCoverage(\n totals: CoverageTotals,\n fileCov: ReturnType<typeof processFileCoverage>\n): void {\n totals.statements.total += fileCov.statements.total;\n totals.statements.covered += fileCov.statements.covered;\n totals.functions.total += fileCov.functions.total;\n totals.functions.covered += fileCov.functions.covered;\n totals.branches.total += fileCov.branches.total;\n totals.branches.covered += fileCov.branches.covered;\n}\n\n/** Convert totals to coverage data */\nfunction totalsToPercentages(totals: CoverageTotals): CoverageData {\n return {\n statements: computePercentage(totals.statements.total, totals.statements.covered),\n functions: computePercentage(totals.functions.total, totals.functions.covered),\n branches: computePercentage(totals.branches.total, totals.branches.covered),\n };\n}\n\n/** Check if data looks like coverage-final format */\nfunction isCoverageFinalFormat(data: Record<string, unknown>): boolean {\n const files = Object.keys(data).filter((key) => key !== \"total\");\n if (files.length === 0) {\n return false;\n }\n const firstFile = data[files[0]];\n if (!firstFile || typeof firstFile !== \"object\") {\n return false;\n }\n const fileData = firstFile as FileCoverageData;\n return Boolean(fileData.s ?? fileData.f ?? fileData.b);\n}\n\n/**\n * Coverage verification runner.\n * Runs tests with coverage and verifies the result meets a minimum threshold.\n */\nexport class CoverageRunRunner extends BaseToolRunner {\n readonly name = \"Coverage Run\";\n readonly rule = \"code.coverage\";\n readonly toolId = \"coverage-run\";\n readonly configFiles: string[] = [];\n\n private config: CoverageRunConfig = {\n enabled: false,\n min_threshold: 80,\n runner: \"auto\",\n };\n\n setConfig(config: CoverageRunConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n private detectRunner(projectRoot: string): \"vitest\" | \"jest\" | \"pytest\" | null {\n const vitestConfigs = [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"vitest.config.mts\",\n \"vitest.config.mjs\",\n ];\n if (findConfig(projectRoot, vitestConfigs)) {\n return \"vitest\";\n }\n\n const jestConfigs = [\"jest.config.js\", \"jest.config.ts\", \"jest.config.mjs\", \"jest.config.cjs\"];\n if (findConfig(projectRoot, jestConfigs) || hasJestInPackageJson(projectRoot)) {\n return \"jest\";\n }\n\n const pytestConfigs = [\"pytest.ini\", \"pyproject.toml\", \"setup.cfg\", \"conftest.py\"];\n if (findConfig(projectRoot, pytestConfigs)) {\n return \"pytest\";\n }\n\n return null;\n }\n\n private getRunnerCommand(runner: \"vitest\" | \"jest\" | \"pytest\"): { cmd: string; args: string[] } {\n const commands: Record<\"vitest\" | \"jest\" | \"pytest\", { cmd: string; args: string[] }> = {\n vitest: { cmd: \"npx\", args: [\"vitest\", \"run\", \"--coverage\", \"--coverage.reporter=json\"] },\n jest: { cmd: \"npx\", args: [\"jest\", \"--coverage\", \"--coverageReporters=json\"] },\n pytest: { cmd: \"pytest\", args: [\"--cov\", \"--cov-report=json\"] },\n };\n return commands[runner];\n }\n\n private getTestCommand(projectRoot: string): { cmd: string; args: string[] } | null {\n if (this.config.command) {\n const parts = this.config.command.split(\" \");\n return { cmd: parts[0], args: parts.slice(1) };\n }\n\n const runner =\n this.config.runner === \"auto\" ? this.detectRunner(projectRoot) : this.config.runner;\n if (!runner) {\n return null;\n }\n\n return this.getRunnerCommand(runner);\n }\n\n private parseCoverageReport(projectRoot: string): CoverageData | null {\n const possiblePaths = [\n \"coverage/coverage-final.json\",\n \"coverage/coverage-summary.json\",\n \".coverage.json\",\n \"coverage.json\",\n ];\n\n for (const relativePath of possiblePaths) {\n const fullPath = path.join(projectRoot, relativePath);\n if (!fs.existsSync(fullPath)) {\n continue;\n }\n\n try {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n const data = JSON.parse(content) as Record<string, unknown>;\n const result = this.extractCoverageData(data);\n if (result) {\n return result;\n }\n } catch {\n // Try next path\n }\n }\n\n return null;\n }\n\n private extractCoverageData(data: Record<string, unknown>): CoverageData | null {\n // Try summary format first\n const summaryResult = parseSummaryFormat(data);\n if (summaryResult) {\n return summaryResult;\n }\n\n // Try pytest format\n const pytestResult = parsePytestFormat(data);\n if (pytestResult) {\n return pytestResult;\n }\n\n // Try coverage-final.json format\n return this.computeCoverageFromFinal(data);\n }\n\n private computeCoverageFromFinal(data: Record<string, unknown>): CoverageData | null {\n if (!isCoverageFinalFormat(data)) {\n return null;\n }\n\n const totals = createEmptyTotals();\n for (const [filePath, fd] of Object.entries(data)) {\n if (filePath !== \"total\" && fd && typeof fd === \"object\") {\n addFileCoverage(totals, processFileCoverage(fd as FileCoverageData));\n }\n }\n\n return totalsToPercentages(totals);\n }\n\n private getOverallCoverage(data: CoverageData): number {\n if (data.lines !== undefined) {\n return data.lines;\n }\n if (data.statements !== undefined) {\n return data.statements;\n }\n\n const values = [data.branches, data.functions].filter((v): v is number => v !== undefined);\n if (values.length > 0) {\n return values.reduce((a, b) => a + b, 0) / values.length;\n }\n\n return 0;\n }\n\n private async executeTests(\n testCommand: { cmd: string; args: string[] },\n projectRoot: string\n ): Promise<{ exitCode: number | undefined; stderr: string; stdout: string }> {\n const result = await execa(testCommand.cmd, testCommand.args, {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeToolExtended,\n env: { ...process.env, CI: \"true\" },\n });\n return { exitCode: result.exitCode, stderr: result.stderr, stdout: result.stdout };\n }\n\n private checkCoverageThreshold(projectRoot: string): CheckResult | null {\n const coverageData = this.parseCoverageReport(projectRoot);\n if (!coverageData) {\n return this.fail(\n [\n this.createViolation(\n \"Could not find or parse coverage report. Ensure coverage reporter outputs JSON.\"\n ),\n ],\n 0\n );\n }\n\n const coverage = this.getOverallCoverage(coverageData);\n const threshold = this.config.min_threshold ?? 80;\n\n if (coverage < threshold) {\n return this.fail(\n [\n this.createViolation(\n `Coverage ${coverage.toFixed(1)}% is below minimum threshold ${threshold}%`\n ),\n ],\n 0\n );\n }\n\n return null;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const testCommand = this.getTestCommand(projectRoot);\n if (!testCommand) {\n return this.fail(\n [this.createViolation(\"Could not detect test runner. Set runner or command in config.\")],\n elapsed()\n );\n }\n\n try {\n const result = await this.executeTests(testCommand, projectRoot);\n const exitError = this.validateExitCode(result, elapsed);\n if (exitError) {\n return exitError;\n }\n\n const thresholdResult = this.checkCoverageThreshold(projectRoot);\n if (thresholdResult) {\n return { ...thresholdResult, duration: elapsed() };\n }\n\n return this.pass(elapsed());\n } catch (error) {\n return this.handleRunError(error, elapsed);\n }\n }\n\n /** Validate test command exit code and return error result if invalid */\n private validateExitCode(\n result: { exitCode?: number; stdout: string; stderr: string },\n elapsed: () => number\n ): CheckResult | null {\n if (result.exitCode === undefined) {\n const errorMsg = result.stderr || result.stdout || \"Command not found or failed to execute\";\n return this.fail(\n [this.createViolation(`Test command failed to execute: ${errorMsg}`)],\n elapsed()\n );\n }\n\n if (result.exitCode !== 0 && result.exitCode !== 1) {\n const errorMsg = result.stderr || result.stdout;\n return this.fail(\n [\n this.createViolation(\n `Test command failed with exit code ${result.exitCode}: ${errorMsg}`\n ),\n ],\n elapsed()\n );\n }\n\n return null;\n }\n\n private handleRunError(error: unknown, elapsed: () => number): CheckResult {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createViolation(`Coverage run error: ${message}`)], elapsed());\n }\n\n override async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n const testCommand = this.getTestCommand(projectRoot);\n if (!testCommand) {\n return CheckResultBuilder.fail(\n `${this.name} Config`,\n this.rule,\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"Could not detect test runner. Configure runner or command in standards.toml.\",\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, Date.now() - startTime);\n }\n\n private createViolation(message: string): Violation {\n return { rule: `${this.rule}.${this.toolId}`, tool: this.toolId, message, severity: \"error\" };\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { glob } from \"glob\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\nimport {\n findBlockEnd,\n findCommentInLine,\n findFirstPattern,\n KNOWN_EXTENSIONS,\n} from \"./comment-utils.js\";\n\n/** Default patterns to detect disable comments */\nconst DEFAULT_PATTERNS = [\n // ESLint\n \"eslint-disable\",\n \"eslint-disable-line\",\n \"eslint-disable-next-line\",\n // TypeScript\n \"@ts-ignore\",\n \"@ts-expect-error\",\n \"@ts-nocheck\",\n // Python\n \"# noqa\",\n \"# type: ignore\",\n \"# pylint: disable\",\n \"# pragma: no cover\",\n];\n\n/** Default file extensions to scan */\nconst DEFAULT_EXTENSIONS = [\"ts\", \"tsx\", \"js\", \"jsx\", \"py\"];\n\n/** Default directories to exclude */\nconst DEFAULT_EXCLUDE = [\n \"**/node_modules/**\",\n \"**/.git/**\",\n \"**/dist/**\",\n \"**/build/**\",\n \"**/__pycache__/**\",\n \"**/.venv/**\",\n \"**/venv/**\",\n \"**/coverage/**\",\n];\n\n/** Configuration for disable-comments validation */\ninterface DisableCommentsConfig {\n enabled?: boolean;\n patterns?: string[];\n extensions?: string[];\n exclude?: string[];\n}\n\n/** Context for scanning a file */\ninterface ScanContext {\n file: string;\n patterns: string[];\n inBlockComment: boolean;\n}\n\n/** Violation data */\ninterface ViolationData {\n line: number;\n pattern: string;\n content: string;\n}\n\n/** Line scan result */\ninterface LineScanResult {\n violation: ViolationData | null;\n inBlockComment: boolean;\n}\n\n/** Line scan parameters */\ninterface LineScanParams {\n line: string;\n lineNum: number;\n ext: string;\n patterns: string[];\n}\n\n/**\n * Disable comments runner for detecting linter/type-checker disable comments\n */\nexport class DisableCommentsRunner extends BaseToolRunner {\n readonly name = \"Disable Comments\";\n readonly rule = \"code.quality\";\n readonly toolId = \"disable-comments\";\n readonly configFiles: string[] = []; // No config file needed\n\n private config: DisableCommentsConfig = {};\n\n setConfig(config: DisableCommentsConfig): void {\n this.config = config;\n }\n\n private getPatterns(): string[] {\n return this.config.patterns ?? DEFAULT_PATTERNS;\n }\n\n private getExtensions(): string[] {\n return this.config.extensions ?? DEFAULT_EXTENSIONS;\n }\n\n private getExcludePatterns(): string[] {\n return [...DEFAULT_EXCLUDE, ...(this.config.exclude ?? [])];\n }\n\n private buildGlobPattern(): string {\n const extensions = this.getExtensions();\n const unique = [...new Set(extensions)];\n if (unique.length === 1) {\n return `**/*.${unique[0]}`;\n }\n return `**/*.{${unique.join(\",\")}}`;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n try {\n const files = await glob(this.buildGlobPattern(), {\n cwd: projectRoot,\n ignore: this.getExcludePatterns(),\n nodir: true,\n });\n\n if (files.length === 0) {\n return this.pass(Date.now() - startTime);\n }\n\n const violations = this.scanAllFiles(projectRoot, files);\n return this.fromViolations(violations, Date.now() - startTime);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`Disable comments check error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n\n private scanAllFiles(projectRoot: string, files: string[]): Violation[] {\n const violations: Violation[] = [];\n const patterns = this.getPatterns();\n\n for (const file of files) {\n const filePath = path.join(projectRoot, file);\n violations.push(...this.scanFile(filePath, { file, patterns, inBlockComment: false }));\n }\n\n return violations;\n }\n\n private scanFile(absolutePath: string, ctx: ScanContext): Violation[] {\n try {\n const content = fs.readFileSync(absolutePath, \"utf-8\");\n return this.scanContent(content, ctx);\n } catch {\n return []; // Skip unreadable files\n }\n }\n\n private scanContent(content: string, ctx: ScanContext): Violation[] {\n const lines = content.split(\"\\n\");\n const ext = path.extname(ctx.file).slice(1).toLowerCase();\n const violations: Violation[] = [];\n let inBlock = ctx.inBlockComment;\n\n for (let i = 0; i < lines.length; i++) {\n const params: LineScanParams = {\n line: lines[i],\n lineNum: i + 1,\n ext,\n patterns: ctx.patterns,\n };\n const result = this.scanLine(params, inBlock);\n if (result.violation) {\n violations.push(this.createViolation(ctx.file, result.violation));\n }\n inBlock = result.inBlockComment;\n }\n\n return violations;\n }\n\n private scanLine(params: LineScanParams, inBlock: boolean): LineScanResult {\n const { ext } = params;\n if (ext === \"py\" || !KNOWN_EXTENSIONS.has(ext)) {\n return { violation: this.scanSimpleLine(params), inBlockComment: false };\n }\n return this.scanJsLine(params, inBlock);\n }\n\n private scanSimpleLine(params: LineScanParams): ViolationData | null {\n const { line, lineNum, ext, patterns } = params;\n for (const pattern of patterns) {\n if (this.isPatternInComment(line, pattern, ext)) {\n return { line: lineNum, pattern, content: line };\n }\n }\n return null;\n }\n\n private scanJsLine(params: LineScanParams, inBlock: boolean): LineScanResult {\n const { line, lineNum, patterns } = params;\n return this.processJsLineComments(line, lineNum, patterns, inBlock);\n }\n\n private processJsLineComments(\n line: string,\n lineNum: number,\n patterns: string[],\n inBlock: boolean\n ): LineScanResult {\n let state = { pos: 0, inBlock };\n\n while (state.pos < line.length) {\n const r = state.inBlock\n ? this.handleInsideBlock(line, lineNum, patterns, state.pos)\n : this.handleOutsideBlock(line, lineNum, patterns, state.pos);\n\n if (r.done) {\n return r.result;\n }\n state = { pos: r.nextPos, inBlock: r.enterBlock ?? false };\n if (r.enterBlock) {\n break;\n }\n }\n\n return { violation: null, inBlockComment: state.inBlock };\n }\n\n private handleInsideBlock(\n line: string,\n lineNum: number,\n patterns: string[],\n pos: number\n ): { done: boolean; result: LineScanResult; nextPos: number; enterBlock?: boolean } {\n const blockEnd = findBlockEnd(line, pos);\n const text = line.slice(pos, blockEnd === -1 ? line.length : blockEnd);\n const pattern = findFirstPattern(text, patterns);\n\n if (pattern) {\n return {\n done: true,\n result: {\n violation: { line: lineNum, pattern, content: line },\n inBlockComment: blockEnd === -1,\n },\n nextPos: 0,\n };\n }\n if (blockEnd === -1) {\n return { done: true, result: { violation: null, inBlockComment: true }, nextPos: 0 };\n }\n return { done: false, result: { violation: null, inBlockComment: false }, nextPos: blockEnd };\n }\n\n private handleOutsideBlock(\n line: string,\n lineNum: number,\n patterns: string[],\n pos: number\n ): { done: boolean; result: LineScanResult; nextPos: number; enterBlock: boolean } {\n const comment = findCommentInLine(line, pos, false);\n if (!comment) {\n return {\n done: true,\n result: { violation: null, inBlockComment: false },\n nextPos: 0,\n enterBlock: false,\n };\n }\n if (!comment.isBlock) {\n return this.handleLineComment(line, lineNum, patterns, comment.index);\n }\n return this.handleBlockCommentStart(line, lineNum, patterns, comment.index);\n }\n\n private handleLineComment(\n line: string,\n lineNum: number,\n patterns: string[],\n index: number\n ): { done: boolean; result: LineScanResult; nextPos: number; enterBlock: boolean } {\n const pattern = findFirstPattern(line.slice(index), patterns);\n const result: LineScanResult = pattern\n ? { violation: { line: lineNum, pattern, content: line }, inBlockComment: false }\n : { violation: null, inBlockComment: false };\n return { done: true, result, nextPos: 0, enterBlock: false };\n }\n\n private handleBlockCommentStart(\n line: string,\n lineNum: number,\n patterns: string[],\n index: number\n ): { done: boolean; result: LineScanResult; nextPos: number; enterBlock: boolean } {\n const blockEnd = findBlockEnd(line, index + 2);\n const text = line.slice(index + 2, blockEnd === -1 ? line.length : blockEnd);\n const pattern = findFirstPattern(text, patterns);\n\n if (pattern) {\n return {\n done: true,\n result: {\n violation: { line: lineNum, pattern, content: line },\n inBlockComment: blockEnd === -1,\n },\n nextPos: 0,\n enterBlock: false,\n };\n }\n if (blockEnd === -1) {\n return {\n done: false,\n result: { violation: null, inBlockComment: true },\n nextPos: 0,\n enterBlock: true,\n };\n }\n return {\n done: false,\n result: { violation: null, inBlockComment: false },\n nextPos: blockEnd,\n enterBlock: false,\n };\n }\n\n /** Check if a pattern appears in a comment (not in a string) - for simple line detection */\n private isPatternInComment(line: string, pattern: string, extension: string): boolean {\n if (!line.includes(pattern)) {\n return false;\n }\n if (!KNOWN_EXTENSIONS.has(extension)) {\n return true;\n }\n\n const comment = findCommentInLine(line, 0, extension === \"py\");\n if (!comment) {\n return false;\n }\n\n const patternIndex = line.indexOf(pattern);\n return comment.index <= patternIndex;\n }\n\n private createViolation(file: string, data: ViolationData): Violation {\n const trimmed = data.content.trim();\n const display = trimmed.length > 60 ? `${trimmed.substring(0, 60)}...` : trimmed;\n\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file,\n line: data.line,\n message: `Found \"${data.pattern}\" comment: ${display}`,\n code: data.pattern,\n severity: \"error\",\n };\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n override async audit(_projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n const patterns = this.getPatterns();\n if (patterns.length === 0) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"At least one pattern must be configured\",\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return this.pass(Date.now() - startTime);\n }\n}\n","/** Quote state for tracking string contexts */\ninterface QuoteState {\n single: boolean;\n double: boolean;\n template: boolean;\n}\n\n/** File extensions with known comment syntax */\nexport const KNOWN_EXTENSIONS = new Set([\"py\", \"ts\", \"tsx\", \"js\", \"jsx\"]);\n\n/**\n * Check if a character at the given index starts a block comment.\n */\nfunction isBlockCommentStart(line: string, index: number): boolean {\n return line[index] === \"/\" && line[index + 1] === \"*\";\n}\n\n/**\n * Check if a character at the given index starts a line comment.\n */\nfunction isLineCommentStart(line: string, index: number): boolean {\n return line[index] === \"/\" && line[index + 1] === \"/\";\n}\n\n/**\n * Find the first pattern that appears in the given text range.\n */\nexport function findFirstPattern(text: string, patterns: string[]): string | null {\n for (const pattern of patterns) {\n if (text.includes(pattern)) {\n return pattern;\n }\n }\n return null;\n}\n\n/**\n * Find where a block comment ends in a line. Returns -1 if not found.\n */\nexport function findBlockEnd(line: string, startIndex: number): number {\n const idx = line.indexOf(\"*/\", startIndex);\n return idx === -1 ? -1 : idx + 2;\n}\n\n/**\n * Check if a quote character can be toggled given current state.\n */\nfunction canToggle(char: string, target: string, state: QuoteState, isPython: boolean): boolean {\n if (char !== target) {\n return false;\n }\n if (target === \"'\") {\n return !state.double && !state.template;\n }\n if (target === '\"') {\n return !state.single && !state.template;\n }\n return !isPython && !state.single && !state.double; // backtick\n}\n\n/**\n * Update quote state based on current character.\n */\nfunction updateQuotes(char: string, prev: string, state: QuoteState, isPython: boolean): void {\n if (prev === \"\\\\\") {\n return;\n }\n if (canToggle(char, \"'\", state, isPython)) {\n state.single = !state.single;\n } else if (canToggle(char, '\"', state, isPython)) {\n state.double = !state.double;\n } else if (canToggle(char, \"`\", state, isPython)) {\n state.template = !state.template;\n }\n}\n\n/**\n * Check if currently inside a string based on quote state.\n */\nfunction inString(state: QuoteState): boolean {\n return state.single || state.double || state.template;\n}\n\n/**\n * Check for comment marker at position, return type or null.\n */\nfunction getCommentAt(line: string, i: number, isPython: boolean): { isBlock: boolean } | null {\n if (isPython) {\n return line[i] === \"#\" ? { isBlock: false } : null;\n }\n if (isLineCommentStart(line, i)) {\n return { isBlock: false };\n }\n if (isBlockCommentStart(line, i)) {\n return { isBlock: true };\n }\n return null;\n}\n\n/**\n * Build quote state for a line up to the given position.\n */\nfunction buildQuoteState(line: string, endPos: number, isPython: boolean): QuoteState {\n const quotes: QuoteState = { single: false, double: false, template: false };\n for (let i = 0; i < endPos; i++) {\n updateQuotes(line[i], line[i - 1] || \"\", quotes, isPython);\n }\n return quotes;\n}\n\n/**\n * Find comment start in a line, respecting string boundaries.\n */\nexport function findCommentInLine(\n line: string,\n startPos: number,\n isPython: boolean\n): { index: number; isBlock: boolean } | null {\n const quotes = buildQuoteState(line, startPos, isPython);\n\n for (let i = startPos; i < line.length; i++) {\n updateQuotes(line[i], line[i - 1] || \"\", quotes, isPython);\n if (inString(quotes)) {\n continue;\n }\n\n const comment = getCommentAt(line, i, isPython);\n if (comment) {\n return { index: i, isBlock: comment.isBlock };\n }\n }\n\n return null;\n}\n","import * as path from \"node:path\";\n\nimport { execa } from \"execa\";\nimport { globSync } from \"glob\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { CheckResultBuilder, type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** ESLint JSON output message format */\ninterface ESLintMessage {\n ruleId: string | null;\n severity: 1 | 2;\n message: string;\n line: number;\n column: number;\n}\n\n/** ESLint JSON output file result format */\ninterface ESLintFileResult {\n filePath: string;\n messages: ESLintMessage[];\n}\n\n/**\n * ESLint rule with options in TOML-friendly object format.\n * Example: { severity: \"error\", max: 10 }\n */\ninterface ESLintRuleWithOptions {\n severity: \"off\" | \"warn\" | \"error\";\n [key: string]: unknown;\n}\n\n/** ESLint rule value - severity string or object with options */\ntype ESLintRuleValue = \"off\" | \"warn\" | \"error\" | ESLintRuleWithOptions;\n\n/** ESLint configuration options */\ninterface ESLintConfig {\n enabled?: boolean;\n files?: string[];\n ignore?: string[];\n \"max-warnings\"?: number;\n rules?: Record<string, ESLintRuleValue>;\n}\n\n/** ESLint --print-config output format */\ninterface ESLintPrintConfig {\n rules?: Record<string, unknown[]>;\n}\n\n/**\n * ESLint tool runner\n */\nexport class ESLintRunner extends BaseToolRunner {\n readonly name = \"ESLint\";\n readonly rule = \"code.linting\";\n readonly toolId = \"eslint\";\n readonly configFiles = [\n \"eslint.config.js\",\n \"eslint.config.mjs\",\n \"eslint.config.cjs\",\n \".eslintrc.js\",\n \".eslintrc.json\",\n \".eslintrc.yml\",\n \".eslintrc.yaml\",\n ];\n\n private config: ESLintConfig = {};\n\n /**\n * Set ESLint configuration options\n */\n setConfig(config: ESLintConfig): void {\n this.config = config;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (!this.hasConfig(projectRoot)) {\n return this.failNoConfig(Date.now() - startTime);\n }\n\n try {\n const args = this.buildArgs();\n const result = await execa(\"npx\", [\"eslint\", ...args], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n const violations = this.parseOutput(result.stdout, projectRoot);\n\n // Handle parse failure with non-zero exit\n if (violations === null && result.exitCode !== 0 && result.stderr) {\n return this.fail(\n [this.createErrorViolation(`ESLint error: ${result.stderr}`)],\n Date.now() - startTime\n );\n }\n\n return this.fromViolations(violations ?? [], Date.now() - startTime);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`ESLint error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n\n /**\n * Audit ESLint config - verify config exists and required rules are present\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n // First check if config exists\n if (!this.hasConfig(projectRoot)) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: `${this.name} config not found. Expected one of: ${this.configFiles.join(\", \")}`,\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n\n // If no rules defined, just pass\n if (!this.config.rules || Object.keys(this.config.rules).length === 0) {\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, elapsed());\n }\n\n // Get effective ESLint config and verify rules\n const violations = await this.auditRules(projectRoot);\n if (violations.length === 0) {\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, elapsed());\n }\n\n return CheckResultBuilder.fail(`${this.name} Config`, this.rule, violations, elapsed());\n }\n\n /**\n * Audit that required rules are present in ESLint config\n */\n private async auditRules(projectRoot: string): Promise<Violation[]> {\n // Check if files pattern is configured\n if (!this.config.files || this.config.files.length === 0) {\n return [\n this.createAuditViolation(\n 'Rules audit requires \"files\" to be configured in standards.toml (e.g., files = [\"src/**/*.ts\"])',\n \"error\"\n ),\n ];\n }\n\n const sampleFile = this.findSampleFile(projectRoot);\n if (!sampleFile) {\n return [\n this.createAuditViolation(\n `No files found matching patterns: ${this.config.files.join(\", \")}`,\n \"error\"\n ),\n ];\n }\n\n const effectiveRules = await this.getEffectiveRules(projectRoot, sampleFile);\n if (\"error\" in effectiveRules) {\n return [this.createAuditViolation(effectiveRules.error, \"error\")];\n }\n\n return this.compareRules(projectRoot, this.config.rules ?? {}, effectiveRules.rules);\n }\n\n /**\n * Get effective ESLint rules for a file\n */\n private async getEffectiveRules(\n projectRoot: string,\n sampleFile: string\n ): Promise<{ rules: Record<string, unknown[]> } | { error: string }> {\n try {\n const result = await execa(\"npx\", [\"eslint\", \"--print-config\", sampleFile], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.quick,\n });\n\n if (result.exitCode !== 0) {\n return { error: `Failed to read ESLint config: ${result.stderr || \"Unknown error\"}` };\n }\n\n const config = JSON.parse(result.stdout) as ESLintPrintConfig;\n return { rules: config.rules ?? {} };\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n return { error: `Failed to audit ESLint config: ${msg}` };\n }\n }\n\n /**\n * Extract options from a rule value (excludes severity)\n */\n private extractRuleOptions(value: ESLintRuleValue): unknown[] | null {\n if (typeof value === \"string\") {\n return null; // No options for severity-only rules\n }\n if (this.isRuleWithOptions(value)) {\n // For object format, convert to array format for comparison\n const { severity: _, ...options } = value;\n return Object.keys(options).length > 0 ? [options] : null;\n }\n return null;\n }\n\n /**\n * Get effective option value, handling both object and primitive formats.\n * ESLint normalizes some rules like max-depth from [\"error\", { max: 4 }] to [2, 4].\n */\n private getEffectiveOptionValue(effectiveOptions: unknown, optionName: string): unknown {\n // If effectiveOptions is an object, look up the key\n if (typeof effectiveOptions === \"object\" && effectiveOptions !== null) {\n return (effectiveOptions as Record<string, unknown>)[optionName];\n }\n // If effectiveOptions is a primitive and we're looking for \"max\", return the primitive\n // This handles rules like max-depth, max-params, complexity where ESLint uses [severity, number]\n if (\n optionName === \"max\" &&\n (typeof effectiveOptions === \"number\" || typeof effectiveOptions === \"string\")\n ) {\n return effectiveOptions;\n }\n return undefined;\n }\n\n /**\n * Compare rule options between required and effective config.\n */\n private compareRuleOptions(\n ruleName: string,\n requiredOptions: unknown[],\n effectiveRule: unknown[],\n configFile: string | undefined\n ): Violation[] {\n const effectiveOptions = effectiveRule.slice(1);\n if (this.deepEqual(requiredOptions, effectiveOptions)) {\n return [];\n }\n // For single-object rules, try detailed comparison\n if (requiredOptions.length === 1 && typeof requiredOptions[0] === \"object\") {\n return this.compareObjectOptions(ruleName, requiredOptions[0], effectiveOptions, configFile);\n }\n // For complex rules, show full mismatch\n const msg = `Rule \"${ruleName}\": options mismatch`;\n return [this.createAuditViolation(msg, \"error\", configFile)];\n }\n\n /** Compare single-object rule options for detailed error messages */\n private compareObjectOptions(\n ruleName: string,\n reqObj: unknown,\n effectiveOptions: unknown[],\n configFile: string | undefined\n ): Violation[] {\n const violations: Violation[] = [];\n const required = reqObj as Record<string, unknown>;\n const effective = typeof effectiveOptions[0] === \"object\" ? effectiveOptions[0] : {};\n for (const [key, reqVal] of Object.entries(required)) {\n const effVal = this.getEffectiveOptionValue(effective, key);\n if (effVal === undefined) {\n violations.push(\n this.createAuditViolation(`Rule \"${ruleName}\": \"${key}\" required`, \"error\", configFile)\n );\n } else if (!this.deepEqual(reqVal, effVal)) {\n violations.push(\n this.createAuditViolation(`Rule \"${ruleName}\": \"${key}\" mismatch`, \"error\", configFile)\n );\n }\n }\n return violations;\n }\n\n /**\n * Deep equality check for comparing option values\n */\n private deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) {\n return true;\n }\n if (typeof a !== typeof b) {\n return false;\n }\n if (typeof a !== \"object\" || a === null || b === null) {\n return false;\n }\n const keysA = Object.keys(a as object);\n const keysB = Object.keys(b as object);\n if (keysA.length !== keysB.length) {\n return false;\n }\n for (const key of keysA) {\n if (\n !this.deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])\n ) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Compare a single rule against effective config\n */\n private compareSingleRule(\n ruleName: string,\n requiredValue: ESLintRuleValue,\n effectiveRule: unknown[] | undefined,\n configFile: string | undefined\n ): Violation[] {\n if (!effectiveRule) {\n return [\n this.createAuditViolation(\n `Rule \"${ruleName}\" is required but not configured`,\n \"error\",\n configFile\n ),\n ];\n }\n\n const violations: Violation[] = [];\n const requiredSeverity = this.normalizeSeverity(requiredValue);\n const effectiveSeverity = this.normalizeSeverity(effectiveRule[0]);\n\n if (requiredSeverity !== effectiveSeverity) {\n const msg = `Rule \"${ruleName}\": expected \"${this.severityToString(requiredSeverity)}\", got \"${this.severityToString(effectiveSeverity)}\"`;\n violations.push(this.createAuditViolation(msg, \"error\", configFile));\n }\n\n const requiredOptions = this.extractRuleOptions(requiredValue);\n if (requiredOptions) {\n violations.push(\n ...this.compareRuleOptions(ruleName, requiredOptions, effectiveRule, configFile)\n );\n }\n\n return violations;\n }\n\n /**\n * Compare required rules against effective rules\n */\n private compareRules(\n projectRoot: string,\n requiredRules: Record<string, ESLintRuleValue>,\n effectiveRules: Record<string, unknown[]>\n ): Violation[] {\n const configFile = this.findConfig(projectRoot) ?? undefined;\n\n return Object.entries(requiredRules).flatMap(([ruleName, requiredValue]) =>\n this.compareSingleRule(ruleName, requiredValue, effectiveRules[ruleName], configFile)\n );\n }\n\n /**\n * Create an audit violation\n */\n private createAuditViolation(\n message: string,\n severity: \"error\" | \"warning\",\n file?: string\n ): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message,\n severity,\n file,\n };\n }\n\n /**\n * Find a sample source file to check ESLint config against.\n * Requires 'files' to be configured in standards.toml.\n */\n private findSampleFile(projectRoot: string): string | null {\n const filePatterns = this.config.files;\n if (!filePatterns || filePatterns.length === 0) {\n return null;\n }\n\n // Use glob to find a file matching the configured patterns\n const matches = globSync(filePatterns, {\n cwd: projectRoot,\n nodir: true,\n ignore: this.config.ignore ?? [],\n });\n\n return matches.length > 0 ? matches[0] : null;\n }\n\n /**\n * Check if a value is an ESLint rule with options object\n */\n private isRuleWithOptions(value: unknown): value is ESLintRuleWithOptions {\n return typeof value === \"object\" && value !== null && \"severity\" in value;\n }\n\n /**\n * Normalize rule severity to number (0, 1, 2)\n */\n private normalizeSeverity(value: unknown): number {\n if (typeof value === \"number\") {\n return value;\n }\n if (typeof value === \"string\") {\n switch (value) {\n case \"off\":\n return 0;\n case \"warn\":\n return 1;\n case \"error\":\n return 2;\n default:\n return parseInt(value, 10) || 0;\n }\n }\n if (Array.isArray(value)) {\n return this.normalizeSeverity(value[0]);\n }\n if (this.isRuleWithOptions(value)) {\n return this.normalizeSeverity(value.severity);\n }\n return 0;\n }\n\n /**\n * Convert severity number to string\n */\n private severityToString(severity: number): string {\n switch (severity) {\n case 0:\n return \"off\";\n case 1:\n return \"warn\";\n case 2:\n return \"error\";\n default:\n return String(severity);\n }\n }\n\n private buildArgs(): string[] {\n const args: string[] = [];\n\n // Files to lint (default to \".\")\n if (this.config.files && this.config.files.length > 0) {\n args.push(...this.config.files);\n } else {\n args.push(\".\");\n }\n\n // Output format\n args.push(\"--format\", \"json\");\n\n // Ignore patterns\n if (this.config.ignore) {\n for (const pattern of this.config.ignore) {\n args.push(\"--ignore-pattern\", pattern);\n }\n }\n\n // Max warnings\n if (this.config[\"max-warnings\"] !== undefined) {\n args.push(\"--max-warnings\", String(this.config[\"max-warnings\"]));\n }\n\n return args;\n }\n\n private parseOutput(stdout: string, projectRoot: string): Violation[] | null {\n try {\n const results = JSON.parse(stdout) as ESLintFileResult[];\n const violations: Violation[] = [];\n\n for (const fileResult of results) {\n for (const msg of fileResult.messages) {\n violations.push({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: path.relative(projectRoot, fileResult.filePath),\n line: msg.line,\n column: msg.column,\n message: msg.message,\n code: msg.ruleId ?? undefined,\n severity: msg.severity === 2 ? \"error\" : \"warning\",\n });\n }\n }\n\n return violations;\n } catch {\n return null;\n }\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Gitleaks finding entry from JSON output */\ninterface GitleaksFinding {\n Description: string;\n StartLine: number;\n EndLine: number;\n StartColumn: number;\n EndColumn: number;\n Match: string;\n Secret: string;\n File: string;\n Commit: string;\n Entropy: number;\n Author: string;\n Email: string;\n Date: string;\n Message: string;\n Tags: string[];\n RuleID: string;\n Fingerprint: string;\n}\n\n/** Scan mode options */\ntype ScanMode = \"branch\" | \"files\" | \"staged\" | \"full\";\n\n/** Gitleaks configuration */\ninterface GitleaksConfig {\n enabled?: boolean;\n scan_mode?: ScanMode;\n base_branch?: string;\n}\n\n/**\n * Gitleaks tool runner for detecting hardcoded secrets\n */\nexport class GitleaksRunner extends BaseToolRunner {\n readonly name = \"gitleaks\";\n readonly rule = \"code.security\";\n readonly toolId = \"secrets\";\n readonly configFiles = [\".gitleaks.toml\", \"gitleaks.toml\"];\n\n private config: GitleaksConfig = {\n scan_mode: \"branch\",\n base_branch: \"main\",\n };\n\n setConfig(config: GitleaksConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Find gitleaks config file if it exists\n * Returns just the filename (relative to projectRoot) since gitleaks runs with cwd=projectRoot\n */\n private findGitleaksConfig(projectRoot: string): string | null {\n for (const configFile of this.configFiles) {\n const configPath = path.join(projectRoot, configFile);\n if (fs.existsSync(configPath)) {\n return configFile; // Return just the filename, not the full path\n }\n }\n return null;\n }\n\n /**\n * Build gitleaks arguments based on scan mode\n */\n private buildArgs(projectRoot: string): string[] {\n const scanMode = this.config.scan_mode ?? \"branch\";\n const baseBranch = this.config.base_branch ?? \"main\";\n\n const args = [\"detect\", \"--report-format\", \"json\", \"--report-path\", \"/dev/stdout\"];\n\n switch (scanMode) {\n case \"branch\":\n // Scan only commits on current branch since diverging from base branch\n args.push(\"--log-opts\", `${baseBranch}..HEAD`);\n break;\n case \"files\":\n // Scan filesystem only (no git history)\n args.push(\"--source\", \".\", \"--no-git\");\n break;\n case \"staged\":\n // Scan only staged files\n args.push(\"--staged\");\n break;\n case \"full\":\n // Scan entire git history (no special flags needed)\n break;\n }\n\n // Use custom config if it exists - use absolute path for reliability\n const configPath = this.findGitleaksConfig(projectRoot);\n if (configPath) {\n const absoluteConfigPath = path.join(projectRoot, configPath);\n args.push(\"--config\", absoluteConfigPath);\n }\n\n return args;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n try {\n const args = this.buildArgs(projectRoot);\n\n const result = await execa(\"gitleaks\", args, {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n return this.processResult(result, elapsed);\n } catch (error) {\n return this.handleRunError(error, elapsed);\n }\n }\n\n private isBinaryNotFound(result: Awaited<ReturnType<typeof execa>>): boolean {\n const execaResult = result as Awaited<ReturnType<typeof execa>> & {\n code?: string;\n message?: string;\n };\n return (\n execaResult.code === \"ENOENT\" ||\n (execaResult.failed && String(execaResult.message ?? \"\").includes(\"ENOENT\"))\n );\n }\n\n private processResult(\n result: Awaited<ReturnType<typeof execa>>,\n elapsed: () => number\n ): CheckResult {\n if (this.isBinaryNotFound(result)) {\n return this.skipNotInstalled(elapsed());\n }\n\n // Exit code 0 = no leaks found, exit code 1 = leaks found\n if (result.exitCode === 0) {\n return this.pass(elapsed());\n }\n\n if (result.exitCode === 1) {\n return this.processLeaksFound(result, elapsed);\n }\n\n // Other exit codes are errors\n const errorMsg = result.stderr ?? result.stdout ?? \"Unknown error\";\n return this.fail([this.createErrorViolation(`gitleaks error: ${errorMsg}`)], elapsed());\n }\n\n private processLeaksFound(\n result: Awaited<ReturnType<typeof execa>>,\n elapsed: () => number\n ): CheckResult {\n const output = String(result.stdout ?? \"\");\n const violations = this.parseOutput(output);\n\n if (violations === null) {\n return this.fail([this.createErrorViolation(`Failed to parse gitleaks output`)], elapsed());\n }\n\n return this.fromViolations(violations, elapsed());\n }\n\n private handleRunError(error: unknown, elapsed: () => number): CheckResult {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createErrorViolation(`gitleaks error: ${message}`)], elapsed());\n }\n\n private parseOutput(output: string): Violation[] | null {\n if (!output.trim()) {\n return [];\n }\n\n try {\n const findings = JSON.parse(output) as GitleaksFinding[];\n const violations: Violation[] = [];\n\n for (const finding of findings) {\n violations.push({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: finding.File,\n line: finding.StartLine,\n column: finding.StartColumn,\n message: `${finding.RuleID}: ${finding.Description}`,\n code: finding.RuleID,\n severity: \"error\",\n });\n }\n\n return violations;\n } catch {\n return null;\n }\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - gitleaks doesn't require config, just check if installed\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n try {\n await execa(\"gitleaks\", [\"version\"], {\n cwd: projectRoot,\n reject: true,\n timeout: TIMEOUTS.versionCheck,\n });\n\n return this.pass(Date.now() - startTime);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`gitleaks audit error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n}\n","import * as fs from \"node:fs\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Knip JSON output format for a dependency issue */\ninterface KnipDependencyIssue {\n name: string;\n line?: number;\n col?: number;\n pos?: number;\n}\n\n/** Knip JSON output format for an export issue */\ninterface KnipExportIssue {\n name: string;\n line?: number;\n col?: number;\n pos?: number;\n type?: string;\n}\n\n/** Knip JSON output format for issues per file */\ninterface KnipFileIssue {\n file: string;\n dependencies?: KnipDependencyIssue[];\n devDependencies?: KnipDependencyIssue[];\n optionalPeerDependencies?: KnipDependencyIssue[];\n unlisted?: KnipDependencyIssue[];\n binaries?: KnipDependencyIssue[];\n unresolved?: KnipDependencyIssue[];\n exports?: KnipExportIssue[];\n types?: KnipExportIssue[];\n enumMembers?: Record<string, KnipExportIssue[]>;\n duplicates?: KnipExportIssue[];\n}\n\n/** Knip JSON output format */\ninterface KnipOutput {\n files: string[];\n issues: KnipFileIssue[];\n}\n\n/**\n * Knip tool runner for detecting unused code\n */\nexport class KnipRunner extends BaseToolRunner {\n readonly name = \"Knip\";\n readonly rule = \"code.unused\";\n readonly toolId = \"knip\";\n readonly configFiles = [\n \"knip.json\",\n \"knip.jsonc\",\n \"knip.js\",\n \"knip.ts\",\n \"knip.config.js\",\n \"knip.config.ts\",\n ];\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Knip works without a config file (uses defaults), so we don't skip if no config\n // It just needs package.json to exist\n try {\n const result = await execa(\"npx\", [\"knip\", \"--reporter\", \"json\"], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n // Knip outputs JSON to stdout\n const output = result.stdout || result.stderr;\n const violations = this.parseOutput(output, projectRoot);\n\n if (violations === null && result.exitCode !== 0) {\n return this.fail(\n [this.createErrorViolation(`Knip error: ${result.stderr}`)],\n Date.now() - startTime\n );\n }\n\n return this.fromViolations(violations ?? [], Date.now() - startTime);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`Knip error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n\n private parseOutput(output: string, _projectRoot: string): Violation[] | null {\n try {\n const result = JSON.parse(output) as KnipOutput;\n const violations: Violation[] = [];\n\n // Unused files\n for (const file of result.files) {\n violations.push({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file,\n message: \"Unused file\",\n code: \"unused-file\",\n severity: \"warning\",\n });\n }\n\n // Issues per file\n for (const issue of result.issues) {\n violations.push(...this.parseFileIssues(issue));\n }\n\n return violations;\n } catch {\n return null;\n }\n }\n\n private parseFileIssues(issue: KnipFileIssue): Violation[] {\n const file = issue.file;\n return [\n ...this.mapToViolations(file, issue.dependencies, {\n prefix: \"Unused dependency\",\n code: \"unused-dependency\",\n severity: \"warning\",\n }),\n ...this.mapToViolations(file, issue.devDependencies, {\n prefix: \"Unused devDependency\",\n code: \"unused-devDependency\",\n severity: \"warning\",\n }),\n ...this.mapToViolations(file, issue.unlisted, {\n prefix: \"Unlisted dependency\",\n code: \"unlisted-dependency\",\n severity: \"error\",\n }),\n ...this.mapToViolations(file, issue.unresolved, {\n prefix: \"Unresolved import\",\n code: \"unresolved-import\",\n severity: \"error\",\n }),\n ...this.mapToViolations(file, issue.exports, {\n prefix: \"Unused export\",\n code: \"unused-export\",\n severity: \"warning\",\n }),\n ...this.mapToViolations(file, issue.types, {\n prefix: \"Unused type\",\n code: \"unused-type\",\n severity: \"warning\",\n }),\n ...this.mapToViolations(file, issue.duplicates, {\n prefix: \"Duplicate export\",\n code: \"duplicate-export\",\n severity: \"warning\",\n }),\n ];\n }\n\n private mapToViolations(\n file: string,\n items: { name: string; line?: number; col?: number }[] | undefined,\n opts: { prefix: string; code: string; severity: \"error\" | \"warning\" }\n ): Violation[] {\n return (items ?? []).map((item) => ({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file,\n line: item.line,\n column: item.col,\n message: `${opts.prefix}: ${item.name}`,\n code: opts.code,\n severity: opts.severity,\n }));\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - Knip doesn't require a config file, so just check if it can run\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Check if package.json exists (required for Knip)\n const hasPackageJson = fs.existsSync(`${projectRoot}/package.json`);\n\n if (!hasPackageJson) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"package.json not found (required for Knip)\",\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return this.pass(Date.now() - startTime);\n }\n}\n","import * as path from \"node:path\";\n\nimport { glob } from \"glob\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Supported case types */\ntype CaseType = \"kebab-case\" | \"snake_case\" | \"camelCase\" | \"PascalCase\";\n\n/** Single naming rule configuration */\ninterface NamingRule {\n extensions: string[];\n file_case: CaseType;\n folder_case: CaseType;\n exclude?: string[];\n allow_dynamic_routes?: boolean;\n}\n\n/** Configuration for naming validation */\ninterface NamingConfig {\n enabled?: boolean;\n rules?: NamingRule[];\n}\n\n/** Default directories to exclude */\nconst DEFAULT_EXCLUDE = [\n \"node_modules\",\n \".git\",\n \"dist\",\n \"build\",\n \"__pycache__\",\n \".venv\",\n \"venv\",\n \".next\",\n \".nuxt\",\n \"coverage\",\n];\n\n/**\n * Check if a string matches kebab-case (lowercase with hyphens)\n * Also allows pure numeric names like \"404\" for Next.js pages\n */\nfunction isKebabCase(str: string): boolean {\n // Allow pure numeric names (e.g., 404, 500)\n if (/^\\d+$/.test(str)) {\n return true;\n }\n return /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/.test(str);\n}\n\n/**\n * Check if a string matches snake_case (lowercase with underscores)\n * Also allows pure numeric names like \"404\" for Next.js pages\n */\nfunction isSnakeCase(str: string): boolean {\n // Allow pure numeric names (e.g., 404, 500)\n if (/^\\d+$/.test(str)) {\n return true;\n }\n return /^[a-z][a-z0-9]*(_[a-z0-9]+)*$/.test(str);\n}\n\n/**\n * Check if a string matches camelCase (starts lowercase, no separators)\n * Also allows pure numeric names like \"404\" for Next.js pages\n */\nfunction isCamelCase(str: string): boolean {\n // Allow pure numeric names (e.g., 404, 500)\n if (/^\\d+$/.test(str)) {\n return true;\n }\n return /^[a-z][a-zA-Z0-9]*$/.test(str);\n}\n\n/**\n * Check if a string matches PascalCase (starts uppercase, no separators)\n * Also allows pure numeric names like \"404\" for Next.js pages\n */\nfunction isPascalCase(str: string): boolean {\n // Allow pure numeric names (e.g., 404, 500)\n if (/^\\d+$/.test(str)) {\n return true;\n }\n return /^[A-Z][a-zA-Z0-9]*$/.test(str);\n}\n\n/**\n * Check if a string matches the specified case type\n */\nfunction matchesCase(str: string, caseType: CaseType): boolean {\n switch (caseType) {\n case \"kebab-case\":\n return isKebabCase(str);\n case \"snake_case\":\n return isSnakeCase(str);\n case \"camelCase\":\n return isCamelCase(str);\n case \"PascalCase\":\n return isPascalCase(str);\n default: {\n const exhaustiveCheck: never = caseType;\n throw new Error(`Unknown case type: ${exhaustiveCheck}`);\n }\n }\n}\n\n/**\n * Get the base name of a file without extension\n * Handles multiple extensions like .test.ts, .spec.js\n */\nfunction getBaseName(filePath: string): string {\n const fileName = path.basename(filePath);\n // Remove all extensions (e.g., foo.test.ts -> foo)\n const parts = fileName.split(\".\");\n return parts[0];\n}\n\n/**\n * Check if a file should be skipped (special files like __init__.py)\n */\nfunction isSpecialFile(baseName: string): boolean {\n // Skip files that start with underscore (Python special files like __init__, __main__)\n if (baseName.startsWith(\"_\")) {\n return true;\n }\n return false;\n}\n\n/**\n * Dynamic route patterns for Next.js/Remix folder names.\n * Order matters: more specific patterns must come first.\n */\nconst DYNAMIC_ROUTE_PATTERNS = [\n /^\\[\\[\\.\\.\\.([^\\]]+)\\]\\]$/, // [[...slug]] - optional catch-all\n /^\\[\\.\\.\\.([^\\]]+)\\]$/, // [...slug] - catch-all\n /^\\[([^\\]]+)\\]$/, // [id] - dynamic segment\n /^\\(([^)]+)\\)$/, // (group) - route group\n];\n\n/**\n * Extract the inner content from a dynamic route folder pattern.\n * Handles Next.js/Remix patterns:\n * - [id] → \"id\"\n * - [...slug] → \"slug\"\n * - [[...slug]] → \"slug\"\n * - (group) → \"group\"\n * - @parallel → \"parallel\"\n *\n * Returns null if the folder is not a dynamic route pattern.\n */\nfunction extractDynamicRouteContent(folderName: string): string | null {\n // @parallel - parallel route (prefix pattern, not regex)\n if (folderName.startsWith(\"@\")) {\n return folderName.slice(1);\n }\n\n // Try each pattern in order\n for (const pattern of DYNAMIC_ROUTE_PATTERNS) {\n const match = pattern.exec(folderName);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n}\n\n/**\n * Naming conventions runner for checking file and folder names\n */\nexport class NamingRunner extends BaseToolRunner {\n readonly name = \"Naming\";\n readonly rule = \"code.naming\";\n readonly toolId = \"naming\";\n readonly configFiles: string[] = []; // No config file needed\n\n private config: NamingConfig = {};\n\n /**\n * Set the configuration for this runner\n */\n setConfig(config: NamingConfig): void {\n this.config = config;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n const rules = this.config.rules ?? [];\n if (rules.length === 0) {\n return this.pass(Date.now() - startTime);\n }\n\n try {\n const ruleResults = await Promise.all(rules.map((rule) => this.checkRule(projectRoot, rule)));\n const violations = ruleResults.flat();\n\n if (violations.length === 0) {\n return this.pass(Date.now() - startTime);\n }\n\n return this.fail(violations, Date.now() - startTime);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`Naming validation error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n\n /**\n * Check a single naming rule against the project\n */\n private async checkRule(projectRoot: string, rule: NamingRule): Promise<Violation[]> {\n const pattern = this.buildGlobPattern(rule.extensions);\n\n // Combine default excludes with rule-specific excludes\n const ignorePatterns = DEFAULT_EXCLUDE.map((dir) => `**/${dir}/**`);\n if (rule.exclude) {\n ignorePatterns.push(...rule.exclude);\n }\n\n const files = await glob(pattern, {\n cwd: projectRoot,\n ignore: ignorePatterns,\n nodir: true,\n });\n\n const { violations: fileViolations, folders } = this.checkFiles(files, rule);\n const folderViolations = this.checkFolders(\n folders,\n rule.folder_case,\n rule.allow_dynamic_routes\n );\n\n return [...fileViolations, ...folderViolations];\n }\n\n /**\n * Check file names and collect folders containing matching files\n */\n private checkFiles(\n files: string[],\n rule: NamingRule\n ): { violations: Violation[]; folders: Set<string> } {\n const violations: Violation[] = [];\n const folders = new Set<string>();\n\n for (const file of files) {\n const baseName = getBaseName(file);\n\n if (!baseName || isSpecialFile(baseName)) {\n continue;\n }\n\n if (!matchesCase(baseName, rule.file_case)) {\n violations.push(this.createFileViolation(file, baseName, rule.file_case));\n }\n\n const folderPath = path.dirname(file);\n if (folderPath && folderPath !== \".\") {\n folders.add(folderPath);\n }\n }\n\n return { violations, folders };\n }\n\n /**\n * Check folder names for all folders containing matching files\n */\n private checkFolders(\n foldersWithMatchingFiles: Set<string>,\n expectedCase: CaseType,\n allowDynamicRoutes?: boolean\n ): Violation[] {\n const violations: Violation[] = [];\n const checkedFolders = new Set<string>();\n\n for (const folderPath of foldersWithMatchingFiles) {\n const folderViolations = this.checkFolderPath(\n folderPath,\n expectedCase,\n checkedFolders,\n allowDynamicRoutes\n );\n violations.push(...folderViolations);\n }\n\n return violations;\n }\n\n /**\n * Get the name to validate from a folder segment, handling dynamic routes\n */\n private getNameToValidate(segment: string, allowDynamicRoutes?: boolean): string {\n if (!allowDynamicRoutes) {\n return segment;\n }\n const innerContent = extractDynamicRouteContent(segment);\n return innerContent ?? segment;\n }\n\n /**\n * Check all segments of a folder path\n */\n private checkFolderPath(\n folderPath: string,\n expectedCase: CaseType,\n checkedFolders: Set<string>,\n allowDynamicRoutes?: boolean\n ): Violation[] {\n const violations: Violation[] = [];\n const segments = folderPath.split(path.sep);\n let currentPath = \"\";\n\n for (const segment of segments) {\n currentPath = currentPath ? path.join(currentPath, segment) : segment;\n\n if (checkedFolders.has(currentPath) || DEFAULT_EXCLUDE.includes(segment)) {\n continue;\n }\n checkedFolders.add(currentPath);\n\n const nameToValidate = this.getNameToValidate(segment, allowDynamicRoutes);\n if (!matchesCase(nameToValidate, expectedCase)) {\n violations.push(this.createFolderViolation(currentPath, segment, expectedCase));\n }\n }\n\n return violations;\n }\n\n /**\n * Build a glob pattern for the given extensions\n */\n private buildGlobPattern(extensions: string[]): string {\n // Deduplicate extensions to avoid glob pattern issues\n const unique = [...new Set(extensions)];\n if (unique.length === 1) {\n return `**/*.${unique[0]}`;\n }\n return `**/*.{${unique.join(\",\")}}`;\n }\n\n private createFileViolation(file: string, baseName: string, expectedCase: CaseType): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file,\n message: `File \"${baseName}\" should be ${expectedCase}`,\n code: \"file-case\",\n severity: \"error\",\n };\n }\n\n private createFolderViolation(\n folderPath: string,\n folderName: string,\n expectedCase: CaseType\n ): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: folderPath,\n message: `Folder \"${folderName}\" should be ${expectedCase}`,\n code: \"folder-case\",\n severity: \"error\",\n };\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - for naming, we just verify the config is valid\n */\n override async audit(_projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Naming validation doesn't require external config files\n // Just verify the rules are valid\n const rules = this.config.rules ?? [];\n\n for (const rule of rules) {\n if (rule.extensions.length === 0) {\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: false,\n violations: [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"Naming rule must have at least one extension\",\n severity: \"error\",\n },\n ],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n }\n\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: true,\n violations: [],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n}\n","import * as fs from \"node:fs\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** pip-audit vulnerability entry */\ninterface PipAuditVulnerability {\n id: string;\n fix_versions: string[];\n aliases: string[];\n description: string;\n}\n\n/** pip-audit package entry */\ninterface PipAuditPackage {\n name: string;\n version: string;\n vulns: PipAuditVulnerability[];\n}\n\n/** pip-audit JSON output format */\ntype PipAuditOutput = PipAuditPackage[];\n\n/**\n * pip-audit tool runner for detecting Python dependency vulnerabilities\n */\nexport class PipAuditRunner extends BaseToolRunner {\n readonly name = \"pipaudit\";\n readonly rule = \"code.security\";\n readonly toolId = \"pipaudit\";\n readonly configFiles = [\"requirements.txt\", \"pyproject.toml\", \"setup.py\"];\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n this.projectRoot = projectRoot;\n\n if (!this.hasConfig(projectRoot)) {\n return this.failNoConfig(elapsed());\n }\n\n try {\n const result = await this.runPipAudit(projectRoot);\n return this.processResult(result, elapsed);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createErrorViolation(`pip-audit error: ${message}`)], elapsed());\n }\n }\n\n private processResult(\n result: Awaited<ReturnType<typeof execa>>,\n elapsed: () => number\n ): CheckResult {\n const output = String(result.stdout ?? result.stderr ?? \"\");\n const violations = this.parseOutput(output);\n\n if (violations === null) {\n if (result.exitCode !== 0 && result.exitCode !== 1) {\n return this.fail(\n [this.createErrorViolation(`pip-audit error: ${result.stderr ?? \"Unknown error\"}`)],\n elapsed()\n );\n }\n return this.pass(elapsed());\n }\n\n return this.fromViolations(violations, elapsed());\n }\n\n private async runPipAudit(projectRoot: string): Promise<Awaited<ReturnType<typeof execa>>> {\n // Build args - use -r requirements.txt if it exists to audit project deps, not environment\n const args = [\"pip-audit\", \"--format\", \"json\"];\n if (fs.existsSync(`${projectRoot}/requirements.txt`)) {\n args.push(\"-r\", \"requirements.txt\");\n }\n\n // Try uvx first\n try {\n return await execa(\"uvx\", args, {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n } catch {\n // Fall back to pip-audit directly (remove \"pip-audit\" from args for direct call)\n return await execa(\"pip-audit\", args.slice(1), {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n }\n }\n\n private parseOutput(output: string): Violation[] | null {\n try {\n const result = JSON.parse(output) as PipAuditOutput;\n const violations: Violation[] = [];\n\n for (const pkg of result) {\n for (const vuln of pkg.vulns) {\n const severity = this.mapSeverity(vuln);\n const fixInfo = this.getFixInfo(vuln);\n const vulnId = vuln.aliases.length > 0 ? vuln.aliases[0] : vuln.id;\n\n violations.push({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: this.findDependencyFile(pkg.name),\n message: `${pkg.name}@${pkg.version}: ${vulnId}${fixInfo}`,\n code: vuln.id,\n severity,\n });\n }\n }\n\n return violations;\n } catch {\n return null;\n }\n }\n\n private mapSeverity(vuln: PipAuditVulnerability): \"error\" | \"warning\" {\n // If a fix is available, it's an error (should be fixed)\n // If no fix available, it's a warning (awareness only)\n return vuln.fix_versions.length > 0 ? \"error\" : \"warning\";\n }\n\n private getFixInfo(vuln: PipAuditVulnerability): string {\n if (vuln.fix_versions.length === 0) {\n return \" (no fix available)\";\n }\n return ` (fix: ${vuln.fix_versions[0]})`;\n }\n\n private projectRoot = \"\";\n\n private findDependencyFile(_pkgName: string): string | undefined {\n // Check which dependency files actually exist and return the first one found\n // We can't determine which exact file contains the package without parsing,\n // so return the first existing file or undefined if none found\n const possibleFiles = [\"requirements.txt\", \"pyproject.toml\", \"setup.py\"];\n for (const file of possibleFiles) {\n if (this.projectRoot && fs.existsSync(`${this.projectRoot}/${file}`)) {\n return file;\n }\n }\n return undefined;\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - check if Python dependency files exist\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Check for any Python project file\n const hasPythonDeps =\n fs.existsSync(`${projectRoot}/requirements.txt`) ||\n fs.existsSync(`${projectRoot}/pyproject.toml`) ||\n fs.existsSync(`${projectRoot}/setup.py`);\n\n if (!hasPythonDeps) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message:\n \"No Python dependency file found (requirements.txt, pyproject.toml, or setup.py)\",\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return this.pass(Date.now() - startTime);\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** pnpm audit advisory entry */\ninterface PnpmAdvisory {\n module_name: string;\n severity: \"info\" | \"low\" | \"moderate\" | \"high\" | \"critical\";\n title: string;\n url: string;\n findings: { version: string; paths: string[] }[];\n}\n\n/** pnpm audit JSON output format */\ninterface PnpmAuditOutput {\n advisories?: Record<string, PnpmAdvisory>;\n metadata: {\n vulnerabilities: {\n info: number;\n low: number;\n moderate: number;\n high: number;\n critical: number;\n };\n };\n}\n\n/** pnpm audit configuration */\nexport interface PnpmAuditConfig {\n enabled?: boolean;\n exclude_dev?: boolean;\n}\n\n/**\n * pnpm dependency audit tool runner for detecting vulnerabilities.\n * Only checks production dependencies by default (exclude_dev: true).\n */\nexport class PnpmAuditRunner extends BaseToolRunner {\n readonly name = \"pnpmaudit\";\n readonly rule = \"code.security\";\n readonly toolId = \"pnpmaudit\";\n readonly configFiles = [\"pnpm-lock.yaml\"];\n\n private config: PnpmAuditConfig = {\n enabled: false,\n exclude_dev: true,\n };\n\n /**\n * Set configuration for the runner\n */\n setConfig(config: PnpmAuditConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Check if pnpm-lock.yaml exists\n */\n private hasLockFile(projectRoot: string): boolean {\n return fs.existsSync(path.join(projectRoot, \"pnpm-lock.yaml\"));\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!this.hasLockFile(projectRoot)) {\n return this.fail([this.createErrorViolation(\"No pnpm-lock.yaml found\")], elapsed());\n }\n\n try {\n const args = [\"audit\", \"--json\"];\n\n // Add --prod flag to exclude dev dependencies\n if (this.config.exclude_dev !== false) {\n args.push(\"--prod\");\n }\n\n const result = await execa(\"pnpm\", args, {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n return this.processAuditResult(result, elapsed);\n } catch (error) {\n return this.handleRunError(error, elapsed);\n }\n }\n\n private processAuditResult(\n result: Awaited<ReturnType<typeof execa>>,\n elapsed: () => number\n ): CheckResult {\n const output = String(result.stdout ?? result.stderr ?? \"\");\n const violations = this.parseOutput(output);\n\n if (violations === null) {\n if (result.exitCode !== 0) {\n return this.fail(\n [this.createErrorViolation(`pnpm audit error: ${result.stderr ?? \"Unknown error\"}`)],\n elapsed()\n );\n }\n return this.pass(elapsed());\n }\n\n return this.fromViolations(violations, elapsed());\n }\n\n private handleRunError(error: unknown, elapsed: () => number): CheckResult {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createErrorViolation(`pnpm audit error: ${message}`)], elapsed());\n }\n\n private parseOutput(output: string): Violation[] | null {\n try {\n const result = JSON.parse(output) as PnpmAuditOutput;\n const violations: Violation[] = [];\n\n if (!result.advisories) {\n return violations;\n }\n\n for (const [, advisory] of Object.entries(result.advisories)) {\n const severity = this.mapSeverity(advisory.severity);\n\n violations.push({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: \"pnpm-lock.yaml\",\n message: `${advisory.module_name}: ${advisory.title}`,\n code: advisory.severity,\n severity,\n });\n }\n\n return violations;\n } catch {\n return null;\n }\n }\n\n private mapSeverity(auditSeverity: string): \"error\" | \"warning\" {\n switch (auditSeverity) {\n case \"critical\":\n case \"high\":\n return \"error\";\n case \"moderate\":\n case \"low\":\n case \"info\":\n default:\n return \"warning\";\n }\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - check if pnpm-lock.yaml exists\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (!this.hasLockFile(projectRoot)) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"No pnpm-lock.yaml found\",\n severity: \"error\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return this.pass(Date.now() - startTime);\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Check if a file is a symlink */\nfunction isSymlink(filePath: string): boolean {\n try {\n const stats = fs.lstatSync(filePath);\n return stats.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\n/** Ruff JSON output message format */\ninterface RuffMessage {\n code: string;\n message: string;\n filename: string;\n location: {\n row: number;\n column: number;\n };\n}\n\n/** Ruff configuration options from standards.toml */\ninterface RuffConfig {\n enabled?: boolean;\n format?: boolean;\n \"line-length\"?: number;\n lint?: {\n select?: string[];\n ignore?: string[];\n };\n}\n\n/**\n * Ruff (Python linter) tool runner\n */\nexport class RuffRunner extends BaseToolRunner {\n readonly name = \"Ruff\";\n readonly rule = \"code.linting\";\n readonly toolId = \"ruff\";\n readonly configFiles = [\"ruff.toml\", \".ruff.toml\"];\n\n private ruffConfig: RuffConfig = {};\n\n /**\n * Set the Ruff configuration from standards.toml\n */\n setConfig(config: RuffConfig): void {\n this.ruffConfig = config;\n }\n\n /**\n * Build CLI arguments from config\n */\n private buildCliArgs(): string[] {\n const args = [\"check\", \".\", \"--output-format\", \"json\"];\n\n if (this.ruffConfig[\"line-length\"]) {\n args.push(\"--line-length\", String(this.ruffConfig[\"line-length\"]));\n }\n\n if (this.ruffConfig.lint?.select?.length) {\n args.push(\"--select\", this.ruffConfig.lint.select.join(\",\"));\n }\n\n if (this.ruffConfig.lint?.ignore?.length) {\n args.push(\"--ignore\", this.ruffConfig.lint.ignore.join(\",\"));\n }\n\n return args;\n }\n\n /**\n * Override hasConfig to also check for [tool.ruff] in pyproject.toml\n */\n protected override hasConfig(projectRoot: string): boolean {\n // Check dedicated config files\n if (super.hasConfig(projectRoot)) {\n return true;\n }\n\n // Check pyproject.toml for [tool.ruff] section\n return this.hasPyprojectConfig(projectRoot);\n }\n\n private hasPyprojectConfig(projectRoot: string): boolean {\n const pyprojectPath = path.join(projectRoot, \"pyproject.toml\");\n if (!fs.existsSync(pyprojectPath)) {\n return false;\n }\n\n try {\n const content = fs.readFileSync(pyprojectPath, \"utf-8\");\n return content.includes(\"[tool.ruff]\");\n } catch {\n return false;\n }\n }\n\n private async hasPythonFiles(projectRoot: string): Promise<boolean> {\n try {\n const result = await execa(\"find\", [\".\", \"-name\", \"*.py\", \"-type\", \"f\"], {\n cwd: projectRoot,\n reject: false,\n });\n return Boolean(result.stdout.trim());\n } catch {\n return false;\n }\n }\n\n private isBinaryNotFound(result: Awaited<ReturnType<typeof execa>>): boolean {\n const execaResult = result as Awaited<ReturnType<typeof execa>> & {\n code?: string;\n message?: string;\n };\n return (\n execaResult.code === \"ENOENT\" ||\n (execaResult.failed && String(execaResult.message ?? \"\").includes(\"ENOENT\"))\n );\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Skip if no Python files\n if (!(await this.hasPythonFiles(projectRoot))) {\n return this.skip(\"No Python files found\", Date.now() - startTime);\n }\n\n try {\n const result = await execa(\"ruff\", this.buildCliArgs(), {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n // Check if ruff binary was not found\n if (this.isBinaryNotFound(result)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n const violations = this.parseOutput(result.stdout, projectRoot);\n\n // Handle parse failure with non-zero exit\n if (violations === null && result.exitCode !== 0 && result.stderr) {\n return this.fail(\n [this.createErrorViolation(`Ruff error: ${result.stderr}`)],\n Date.now() - startTime\n );\n }\n\n return this.fromViolations(violations ?? [], Date.now() - startTime);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`Ruff error: ${message}`)],\n Date.now() - startTime\n );\n }\n }\n\n private skip(reason: string, duration: number): CheckResult {\n return {\n name: this.name,\n rule: this.rule,\n passed: true,\n violations: [],\n skipped: true,\n skipReason: reason,\n duration,\n };\n }\n\n private parseOutput(stdout: string, projectRoot: string): Violation[] | null {\n if (!stdout.trim()) {\n return [];\n }\n\n try {\n const results = JSON.parse(stdout) as RuffMessage[];\n return results\n .filter((msg) => {\n // Skip parse errors (E999) for symlinks - they may point to non-Python files\n if (msg.code === \"E999\") {\n const fullPath = path.isAbsolute(msg.filename)\n ? msg.filename\n : path.join(projectRoot, msg.filename);\n if (isSymlink(fullPath)) {\n return false;\n }\n }\n return true;\n })\n .map((msg) => ({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: path.relative(projectRoot, msg.filename),\n line: msg.location.row,\n column: msg.location.column,\n message: msg.message,\n code: msg.code,\n severity: \"error\" as const,\n }));\n } catch {\n return null;\n }\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Override audit to include pyproject.toml check\n */\n override async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (this.hasConfig(projectRoot)) {\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: true,\n violations: [],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n\n const allConfigs = [...this.configFiles, \"pyproject.toml [tool.ruff]\"];\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: false,\n violations: [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: `Ruff config not found. Expected one of: ${allConfigs.join(\", \")}`,\n severity: \"error\",\n },\n ],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { CheckResultBuilder, type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** TypeScript compiler options that can be audited */\ninterface TscRequiredOptions {\n strict?: boolean;\n noImplicitAny?: boolean;\n strictNullChecks?: boolean;\n noUnusedLocals?: boolean;\n noUnusedParameters?: boolean;\n noImplicitReturns?: boolean;\n noFallthroughCasesInSwitch?: boolean;\n esModuleInterop?: boolean;\n skipLibCheck?: boolean;\n forceConsistentCasingInFileNames?: boolean;\n}\n\n/**\n * Strip comments from JSONC content (JSON with Comments).\n * Uses regex replacement to handle single-line and multi-line comments.\n * Note: This is a simplified approach that works for typical tsconfig.json files.\n */\nfunction stripJsonComments(content: string): string {\n // Remove single-line comments (// ...) not inside strings\n // Remove multi-line comments (/* ... */)\n // This regex-based approach handles most tsconfig.json cases\n return content\n .replace(/\\\\\"|\"(?:\\\\\"|[^\"])*\"|\\/\\/[^\\n]*/g, (match) => {\n // Keep strings, remove single-line comments\n return match.startsWith(\"//\") ? \"\" : match;\n })\n .replace(/\\\\\"|\"(?:\\\\\"|[^\"])*\"|\\/\\*[\\s\\S]*?\\*\\//g, (match) => {\n // Keep strings, remove multi-line comments\n return match.startsWith(\"/*\") ? \"\" : match;\n });\n}\n\n/** Parsed tsc diagnostic */\ninterface TscDiagnostic {\n file: string;\n line: number;\n column: number;\n code: number;\n message: string;\n}\n\n/**\n * TypeScript type checker tool runner\n */\nexport class TscRunner extends BaseToolRunner {\n readonly name = \"TypeScript\";\n readonly rule = \"code.types\";\n readonly toolId = \"tsc\";\n readonly configFiles = [\"tsconfig.json\"];\n\n private requiredOptions: TscRequiredOptions = {};\n\n /**\n * Set required compiler options for audit\n */\n setRequiredOptions(options: TscRequiredOptions): void {\n this.requiredOptions = options;\n }\n\n /**\n * Strip ANSI escape codes from a string\n */\n private stripAnsi(str: string): string {\n // Use String.fromCharCode to avoid control character in regex literal\n const ESC = String.fromCharCode(27);\n const pattern = new RegExp(`${ESC}(?:[@-Z\\\\\\\\-_]|\\\\[[0-?]*[ -/]*[@-~])`, \"g\");\n return str.replace(pattern, \"\");\n }\n\n /**\n * Check if the output indicates tsc is not installed\n */\n private isTscNotFoundOutput(output: string): boolean {\n const stripped = this.stripAnsi(output);\n return (\n stripped.includes(\"This is not the tsc command you are looking for\") ||\n stripped.includes(\"command not found\") ||\n stripped.includes(\"ENOENT\")\n );\n }\n\n private handleTscFailure(\n result: Awaited<ReturnType<typeof execa>>,\n projectRoot: string\n ): Violation[] | \"not-installed\" {\n const stdout = String(result.stdout ?? \"\");\n const stderr = String(result.stderr ?? \"\");\n const combinedOutput = stdout || stderr;\n\n // Check if tsc is not installed (npx shows an error message)\n if (this.isTscNotFoundOutput(combinedOutput)) {\n return \"not-installed\";\n }\n\n const violations = this.parseOutput(stdout, projectRoot);\n if (violations.length === 0) {\n if (combinedOutput) {\n return [\n this.createErrorViolation(\n `TypeScript error: ${this.stripAnsi(combinedOutput).slice(0, 500)}`\n ),\n ];\n }\n }\n return violations;\n }\n\n private async runTsc(projectRoot: string): Promise<Awaited<ReturnType<typeof execa>>> {\n return execa(\"npx\", [\"tsc\", \"--noEmit\"], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n }\n\n private processRunResult(\n result: Awaited<ReturnType<typeof execa>>,\n projectRoot: string,\n elapsed: () => number\n ): CheckResult {\n if (result.exitCode === 0) {\n return this.pass(elapsed());\n }\n const violations = this.handleTscFailure(result, projectRoot);\n if (violations === \"not-installed\") {\n return this.skipNotInstalled(elapsed());\n }\n return this.fromViolations(violations, elapsed());\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!this.hasConfig(projectRoot)) {\n return this.failNoConfig(elapsed());\n }\n\n try {\n const result = await this.runTsc(projectRoot);\n return this.processRunResult(result, projectRoot, elapsed);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createErrorViolation(`TypeScript error: ${message}`)], elapsed());\n }\n }\n\n /**\n * Parse tsc output into diagnostics\n * Format: file(line,col): error TSxxxx: message\n */\n private parseOutput(stdout: string, projectRoot: string): Violation[] {\n const diagnostics = this.parseDiagnostics(stdout, projectRoot);\n return diagnostics.map((diag) => ({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: diag.file,\n line: diag.line,\n column: diag.column,\n message: diag.message,\n code: `TS${diag.code}`,\n severity: \"error\" as const,\n }));\n }\n\n private parseDiagnostics(output: string, projectRoot: string): TscDiagnostic[] {\n const diagnostics: TscDiagnostic[] = [];\n const lines = output.split(\"\\n\");\n const errorRegex = /^(.+?)\\((\\d+),(\\d+)\\):\\s*error\\s+TS(\\d+):\\s*(.+)$/;\n\n for (const line of lines) {\n const match = errorRegex.exec(line);\n if (match) {\n const [, filePath, lineNum, colNum, code, message] = match;\n diagnostics.push({\n file: path.relative(projectRoot, filePath),\n line: parseInt(lineNum, 10),\n column: parseInt(colNum, 10),\n code: parseInt(code, 10),\n message: message.trim(),\n });\n }\n }\n\n return diagnostics;\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit tsconfig.json - check existence and required compiler options\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n // First check if config exists\n if (!this.hasConfig(projectRoot)) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: `${this.name} config not found. Expected: ${this.configFiles.join(\", \")}`,\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n\n // If no required options, just pass\n if (Object.keys(this.requiredOptions).length === 0) {\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, elapsed());\n }\n\n // Read and parse tsconfig.json\n const configPath = path.join(projectRoot, \"tsconfig.json\");\n const violations = this.auditCompilerOptions(configPath);\n\n if (violations.length === 0) {\n return CheckResultBuilder.pass(`${this.name} Config`, this.rule, elapsed());\n }\n\n return CheckResultBuilder.fail(`${this.name} Config`, this.rule, violations, elapsed());\n }\n\n private parseConfigFile(\n configPath: string\n ): { compilerOptions?: Record<string, unknown> } | null {\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n const jsonContent = stripJsonComments(content);\n return JSON.parse(jsonContent) as { compilerOptions?: Record<string, unknown> };\n } catch {\n return null;\n }\n }\n\n private auditCompilerOptions(configPath: string): Violation[] {\n const tsconfig = this.parseConfigFile(configPath);\n if (tsconfig === null) {\n return [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n file: \"tsconfig.json\",\n message: \"Failed to parse tsconfig.json\",\n severity: \"error\",\n },\n ];\n }\n\n const compilerOptions = tsconfig.compilerOptions ?? {};\n return this.validateCompilerOptions(compilerOptions);\n }\n\n private validateCompilerOptions(compilerOptions: Record<string, unknown>): Violation[] {\n const violations: Violation[] = [];\n for (const [option, expectedValue] of Object.entries(this.requiredOptions)) {\n if (expectedValue === undefined) {\n continue;\n }\n\n const actualValue = compilerOptions[option];\n if (actualValue === undefined) {\n violations.push(this.createAuditViolation(option, expectedValue, \"missing\"));\n } else if (actualValue !== expectedValue) {\n violations.push(this.createAuditViolation(option, expectedValue, actualValue));\n }\n }\n return violations;\n }\n\n private createAuditViolation(option: string, expected: unknown, actual: unknown): Violation {\n const actualStr = actual === \"missing\" ? \"missing\" : String(actual);\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n file: \"tsconfig.json\",\n message: `${option}: expected ${String(expected)}, got ${actualStr}`,\n severity: \"error\",\n };\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/** Check if a file is a symlink */\nfunction isSymlink(filePath: string): boolean {\n try {\n const stats = fs.lstatSync(filePath);\n return stats.isSymbolicLink();\n } catch {\n return false;\n }\n}\n\n/** Parsed ty diagnostic */\ninterface TyDiagnostic {\n file: string;\n line: number;\n column: number;\n code: string;\n message: string;\n severity: \"error\" | \"warning\";\n}\n\n/**\n * ty Python type checker tool runner\n * ty is Astral's extremely fast Python type checker\n */\nexport class TyRunner extends BaseToolRunner {\n readonly name = \"ty\";\n readonly rule = \"code.types\";\n readonly toolId = \"ty\";\n readonly configFiles = [\"ty.toml\"];\n\n /**\n * Override hasConfig to also check for [tool.ty] in pyproject.toml\n */\n protected override hasConfig(projectRoot: string): boolean {\n // Check for dedicated ty.toml config file\n if (super.hasConfig(projectRoot)) {\n return true;\n }\n\n // Check pyproject.toml for [tool.ty] section\n return this.hasPyprojectConfig(projectRoot);\n }\n\n private hasPyprojectConfig(projectRoot: string): boolean {\n const pyprojectPath = path.join(projectRoot, \"pyproject.toml\");\n if (!fs.existsSync(pyprojectPath)) {\n return false;\n }\n\n try {\n const content = fs.readFileSync(pyprojectPath, \"utf-8\");\n return content.includes(\"[tool.ty]\");\n } catch {\n return false;\n }\n }\n\n /**\n * Override audit to check for ty.toml or [tool.ty] in pyproject.toml\n */\n override async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (this.hasConfig(projectRoot)) {\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: true,\n violations: [],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n\n return {\n name: `${this.name} Config`,\n rule: this.rule,\n passed: false,\n violations: [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"ty config not found. Expected ty.toml or [tool.ty] in pyproject.toml\",\n severity: \"error\",\n },\n ],\n skipped: false,\n duration: Date.now() - startTime,\n };\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n try {\n const result = await execa(\"uvx\", [\"ty\", \"check\", \"--output-format\", \"concise\", \".\"], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n return this.handleExitCode(result, projectRoot, elapsed);\n } catch (error) {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(elapsed());\n }\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail([this.createErrorViolation(`ty error: ${message}`)], elapsed());\n }\n }\n\n private isBinaryNotFound(result: Awaited<ReturnType<typeof execa>>): boolean {\n const execaResult = result as Awaited<ReturnType<typeof execa>> & {\n code?: string;\n message?: string;\n };\n return (\n execaResult.code === \"ENOENT\" ||\n (execaResult.failed && String(execaResult.message ?? \"\").includes(\"ENOENT\"))\n );\n }\n\n private handleExitCode(\n result: Awaited<ReturnType<typeof execa>>,\n projectRoot: string,\n elapsed: () => number\n ): CheckResult {\n // Check if uvx/ty binary was not found\n if (this.isBinaryNotFound(result)) {\n return this.skipNotInstalled(elapsed());\n }\n\n if (result.exitCode === 0) {\n return this.pass(elapsed());\n }\n\n if (result.exitCode === 1) {\n return this.handleTypeErrors(result, projectRoot, elapsed);\n }\n\n if (result.exitCode === 2) {\n // Use trimmed string values so empty strings are falsy with ||\n const stderr = String(result.stderr ?? \"\").trim();\n const stdout = String(result.stdout ?? \"\").trim();\n const errorMessage = stderr || stdout || \"Configuration error\";\n return this.fail(\n [this.createErrorViolation(`ty configuration error: ${errorMessage.slice(0, 500)}`)],\n elapsed()\n );\n }\n\n const violations = this.handleUnexpectedFailure(result, projectRoot);\n return this.fromViolations(violations, elapsed());\n }\n\n private handleTypeErrors(\n result: Awaited<ReturnType<typeof execa>>,\n projectRoot: string,\n elapsed: () => number\n ): CheckResult {\n const violations = this.parseOutput(String(result.stdout ?? \"\"), projectRoot);\n if (violations.length === 0) {\n const errorOutput = String(result.stdout ?? result.stderr ?? \"Type check failed\");\n return this.fail(\n [this.createErrorViolation(`ty error: ${errorOutput.slice(0, 500)}`)],\n elapsed()\n );\n }\n return this.fail(violations, elapsed());\n }\n\n private handleUnexpectedFailure(\n result: Awaited<ReturnType<typeof execa>>,\n projectRoot: string\n ): Violation[] {\n const stdout = String(result.stdout ?? \"\");\n const violations = this.parseOutput(stdout, projectRoot);\n if (violations.length === 0) {\n const errorOutput = stdout || String(result.stderr ?? \"\");\n if (errorOutput) {\n return [this.createErrorViolation(`ty error: ${errorOutput.slice(0, 500)}`)];\n }\n }\n return violations;\n }\n\n /**\n * Parse ty concise output into violations\n * Format: file:line:column: severity[rule-code] message\n * Example: test.py:4:15: error[invalid-assignment] Object of type `int` is not assignable to `str`\n */\n private parseOutput(stdout: string, projectRoot: string): Violation[] {\n const diagnostics = this.parseDiagnostics(stdout, projectRoot);\n return diagnostics.map((diag) => ({\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: diag.file,\n line: diag.line,\n column: diag.column,\n message: diag.message,\n code: diag.code,\n severity: diag.severity,\n }));\n }\n\n private parseDiagnostics(output: string, projectRoot: string): TyDiagnostic[] {\n const diagnostics: TyDiagnostic[] = [];\n const lines = output.split(\"\\n\");\n // Format: file:line:column: severity[rule-code] message\n const diagnosticRegex = /^(.+?):(\\d+):(\\d+):\\s*(error|warning)\\[([^\\]]+)\\]\\s*(.+)$/;\n\n for (const line of lines) {\n const match = diagnosticRegex.exec(line);\n if (match) {\n const [, filePath, lineNum, colNum, severity, code, message] = match;\n\n // Skip syntax/parse errors for symlinks - they may point to non-Python files\n if (code.includes(\"syntax\") || code.includes(\"parse\")) {\n const fullPath = path.isAbsolute(filePath) ? filePath : path.join(projectRoot, filePath);\n if (isSymlink(fullPath)) {\n continue;\n }\n }\n\n // Only apply path.relative if the path is absolute\n const normalizedPath = path.isAbsolute(filePath)\n ? path.relative(projectRoot, filePath)\n : filePath;\n diagnostics.push({\n file: normalizedPath,\n line: parseInt(lineNum, 10),\n column: parseInt(colNum, 10),\n code,\n message: message.trim(),\n severity: severity as \"error\" | \"warning\",\n });\n }\n }\n\n return diagnostics;\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { TIMEOUTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseToolRunner } from \"./base.js\";\n\n/**\n * Vulture tool runner for detecting dead Python code\n */\nexport class VultureRunner extends BaseToolRunner {\n readonly name = \"Vulture\";\n readonly rule = \"code.unused\";\n readonly toolId = \"vulture\";\n readonly configFiles: string[] = []; // Vulture doesn't use config files\n\n private async hasPythonFiles(projectRoot: string): Promise<boolean> {\n try {\n const result = await execa(\"find\", [\".\", \"-name\", \"*.py\", \"-type\", \"f\"], {\n cwd: projectRoot,\n reject: false,\n });\n return Boolean(result.stdout.trim());\n } catch {\n return false;\n }\n }\n\n private isBinaryNotFound(result: Awaited<ReturnType<typeof execa>>): boolean {\n const execaResult = result as typeof result & { code?: string; message?: string };\n return (\n execaResult.code === \"ENOENT\" ||\n (execaResult.failed && String(execaResult.message ?? \"\").includes(\"ENOENT\"))\n );\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n if (!(await this.hasPythonFiles(projectRoot))) {\n return this.skip(\"No Python files found\", Date.now() - startTime);\n }\n\n try {\n // Exclude common virtual environment and build directories\n const excludePatterns = \".venv,venv,.git,node_modules,__pycache__,dist,build,.tox,.nox,.eggs\";\n const result = await execa(\"vulture\", [\".\", \"--exclude\", excludePatterns], {\n cwd: projectRoot,\n reject: false,\n timeout: TIMEOUTS.codeTool,\n });\n\n if (this.isBinaryNotFound(result)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n\n // Vulture exit codes: 0=clean, 1=invalid input, 2=invalid args, 3=dead code\n if (result.exitCode === 1 || result.exitCode === 2) {\n return this.fail(\n [this.createErrorViolation(`Vulture error: ${result.stderr || result.stdout}`)],\n Date.now() - startTime\n );\n }\n\n return this.fromViolations(\n this.parseOutput(result.stdout, projectRoot),\n Date.now() - startTime\n );\n } catch (error) {\n return this.handleRunError(error, startTime);\n }\n }\n\n private handleRunError(error: unknown, startTime: number): CheckResult {\n if (this.isNotInstalledError(error)) {\n return this.skipNotInstalled(Date.now() - startTime);\n }\n const message = error instanceof Error ? error.message : \"Unknown error\";\n return this.fail(\n [this.createErrorViolation(`Vulture error: ${message}`)],\n Date.now() - startTime\n );\n }\n\n private skip(reason: string, duration: number): CheckResult {\n return {\n name: this.name,\n rule: this.rule,\n passed: true,\n violations: [],\n skipped: true,\n skipReason: reason,\n duration,\n };\n }\n\n private parseOutput(stdout: string, projectRoot: string): Violation[] {\n if (!stdout.trim()) {\n return [];\n }\n\n const violations: Violation[] = [];\n const lines = stdout.trim().split(\"\\n\");\n\n for (const line of lines) {\n const violation = this.parseLine(line, projectRoot);\n if (violation) {\n violations.push(violation);\n }\n }\n\n return violations;\n }\n\n /**\n * Parse a single Vulture output line\n * Format: \"path/to/file.py:10: unused function 'my_func' (60% confidence)\"\n */\n private parseLine(line: string, projectRoot: string): Violation | null {\n // Match: file.py:line: message (confidence% confidence)\n const regex = /^(.+?):(\\d+):\\s*(.+?)\\s*\\((\\d+)%\\s*confidence\\)$/;\n const match = regex.exec(line);\n if (!match) {\n return null;\n }\n\n const [, filePath, lineNum, message, confidence] = match;\n const relPath = path.relative(projectRoot, path.resolve(projectRoot, filePath));\n\n // Determine code from message\n const code = this.getCodeFromMessage(message);\n\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n file: relPath,\n line: parseInt(lineNum, 10),\n message: `${message} (${confidence}% confidence)`,\n code,\n severity: \"warning\",\n };\n }\n\n private static readonly CODE_PATTERNS: [string, string][] = [\n [\"unused function\", \"unused-function\"],\n [\"unused class\", \"unused-class\"],\n [\"unused method\", \"unused-method\"],\n [\"unused variable\", \"unused-variable\"],\n [\"unused import\", \"unused-import\"],\n [\"unused attribute\", \"unused-attribute\"],\n [\"unused property\", \"unused-property\"],\n [\"unreachable code\", \"unreachable-code\"],\n ];\n\n /**\n * Extract a code identifier from the vulture message\n */\n private getCodeFromMessage(message: string): string {\n for (const [pattern, code] of VultureRunner.CODE_PATTERNS) {\n if (message.includes(pattern)) {\n return code;\n }\n }\n return \"unused-code\";\n }\n\n private createErrorViolation(message: string): Violation {\n return {\n rule: `${this.rule}.${this.toolId}`,\n tool: this.toolId,\n message,\n severity: \"error\",\n };\n }\n\n /**\n * Audit - Vulture doesn't require a config file, so just check if Python files exist\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n\n // Check if any Python files exist\n if (!(await this.hasPythonFiles(projectRoot))) {\n return this.skip(\"No Python files found\", Date.now() - startTime);\n }\n\n // Check if pyproject.toml or setup.py exists (typical Python project)\n const hasPyproject = fs.existsSync(path.join(projectRoot, \"pyproject.toml\"));\n const hasSetupPy = fs.existsSync(path.join(projectRoot, \"setup.py\"));\n const hasRequirements = fs.existsSync(path.join(projectRoot, \"requirements.txt\"));\n\n if (!hasPyproject && !hasSetupPy && !hasRequirements) {\n return this.fail(\n [\n {\n rule: `${this.rule}.${this.toolId}`,\n tool: \"audit\",\n message: \"No Python project file found (pyproject.toml, setup.py, or requirements.txt)\",\n severity: \"warning\",\n },\n ],\n Date.now() - startTime\n );\n }\n\n return this.pass(Date.now() - startTime);\n }\n}\n","import { type Config } from \"../core/index.js\";\nimport { type CheckResult, type DomainResult, DomainResultBuilder, type IToolRunner } from \"../core/index.js\";\nimport {\n CoverageRunRunner,\n DisableCommentsRunner,\n ESLintRunner,\n GitleaksRunner,\n KnipRunner,\n NamingRunner,\n PipAuditRunner,\n PnpmAuditRunner,\n RuffRunner,\n TscRunner,\n TyRunner,\n VultureRunner,\n} from \"./tools/index.js\";\n\n// Tool runner instances (singletons for tools that don't need per-run config)\nconst knip = new KnipRunner();\nconst pipaudit = new PipAuditRunner();\nconst ty = new TyRunner();\nconst vulture = new VultureRunner();\n\n// Note: RuffRunner and TscRunner are created per-run to support config from standards.toml\n\n// Export tool runners for direct access\nexport {\n BaseToolRunner,\n ESLintRunner,\n KnipRunner,\n NamingRunner,\n RuffRunner,\n TscRunner,\n TyRunner,\n VultureRunner,\n} from \"./tools/index.js\";\n\n/** Tool configuration entry mapping config getter to runner or runner factory */\ninterface ToolEntry {\n isEnabled: (config: Config) => boolean;\n runner: IToolRunner | ((config: Config) => IToolRunner);\n}\n\n/** Check if a tool is enabled in config */\nfunction isEnabled(toolConfig: { enabled?: boolean } | undefined): boolean {\n return toolConfig?.enabled === true;\n}\n\n/** Create a configured ESLintRunner */\nfunction createEslintRunner(config: Config): ESLintRunner {\n const runner = new ESLintRunner();\n const eslintConfig = config.code?.linting?.eslint;\n if (eslintConfig) {\n runner.setConfig({\n enabled: eslintConfig.enabled,\n files: eslintConfig.files,\n ignore: eslintConfig.ignore,\n \"max-warnings\": eslintConfig[\"max-warnings\"],\n rules: eslintConfig.rules,\n });\n }\n return runner;\n}\n\n/** Create a configured CoverageRunRunner */\nfunction createCoverageRunRunner(config: Config): CoverageRunRunner {\n const runner = new CoverageRunRunner();\n const coverageConfig = config.code?.coverage_run;\n if (coverageConfig) {\n runner.setConfig({\n enabled: coverageConfig.enabled,\n min_threshold: coverageConfig.min_threshold,\n runner: coverageConfig.runner,\n command: coverageConfig.command,\n });\n }\n return runner;\n}\n\n/** Create a configured RuffRunner */\nfunction createRuffRunner(config: Config): RuffRunner {\n const runner = new RuffRunner();\n const ruffConfig = config.code?.linting?.ruff;\n if (ruffConfig) {\n runner.setConfig({\n enabled: ruffConfig.enabled,\n \"line-length\": ruffConfig[\"line-length\"],\n lint: ruffConfig.lint,\n });\n }\n return runner;\n}\n\n/** Create a configured TscRunner */\nfunction createTscRunner(config: Config): TscRunner {\n const runner = new TscRunner();\n const tscConfig = config.code?.types?.tsc;\n if (tscConfig?.require) {\n runner.setRequiredOptions(tscConfig.require);\n }\n return runner;\n}\n\n/** Create a configured NamingRunner */\nfunction createNamingRunner(config: Config): NamingRunner {\n const runner = new NamingRunner();\n const namingConfig = config.code?.naming;\n if (namingConfig) {\n runner.setConfig({\n enabled: namingConfig.enabled,\n rules: namingConfig.rules,\n });\n }\n return runner;\n}\n\n/** Create a configured DisableCommentsRunner */\nfunction createDisableCommentsRunner(config: Config): DisableCommentsRunner {\n const runner = new DisableCommentsRunner();\n const disableCommentsConfig = config.code?.quality?.[\"disable-comments\"];\n if (disableCommentsConfig) {\n runner.setConfig({\n enabled: disableCommentsConfig.enabled,\n patterns: disableCommentsConfig.patterns,\n extensions: disableCommentsConfig.extensions,\n exclude: disableCommentsConfig.exclude,\n });\n }\n return runner;\n}\n\n/** Create a configured PnpmAuditRunner */\nfunction createPnpmAuditRunner(config: Config): PnpmAuditRunner {\n const runner = new PnpmAuditRunner();\n const pnpmauditConfig = config.code?.security?.pnpmaudit;\n if (pnpmauditConfig) {\n runner.setConfig({\n enabled: pnpmauditConfig.enabled,\n exclude_dev: pnpmauditConfig.exclude_dev,\n });\n }\n return runner;\n}\n\n/** Create a configured GitleaksRunner */\nfunction createGitleaksRunner(config: Config): GitleaksRunner {\n const runner = new GitleaksRunner();\n const secretsConfig = config.code?.security?.secrets;\n if (secretsConfig) {\n runner.setConfig({\n enabled: secretsConfig.enabled,\n scan_mode: secretsConfig.scan_mode,\n base_branch: secretsConfig.base_branch,\n });\n }\n return runner;\n}\n\n/** All available tools with their config predicates */\nconst toolRegistry: ToolEntry[] = [\n { isEnabled: (c) => isEnabled(c.code?.linting?.eslint), runner: createEslintRunner },\n { isEnabled: (c) => isEnabled(c.code?.linting?.ruff), runner: createRuffRunner },\n { isEnabled: (c) => isEnabled(c.code?.types?.tsc), runner: createTscRunner },\n { isEnabled: (c) => isEnabled(c.code?.types?.ty), runner: ty },\n { isEnabled: (c) => isEnabled(c.code?.unused?.knip), runner: knip },\n { isEnabled: (c) => isEnabled(c.code?.unused?.vulture), runner: vulture },\n { isEnabled: (c) => isEnabled(c.code?.security?.secrets), runner: createGitleaksRunner },\n { isEnabled: (c) => isEnabled(c.code?.security?.pnpmaudit), runner: createPnpmAuditRunner },\n { isEnabled: (c) => isEnabled(c.code?.security?.pipaudit), runner: pipaudit },\n { isEnabled: (c) => isEnabled(c.code?.coverage_run), runner: createCoverageRunRunner },\n { isEnabled: (c) => isEnabled(c.code?.naming), runner: createNamingRunner },\n {\n isEnabled: (c) => isEnabled(c.code?.quality?.[\"disable-comments\"]),\n runner: createDisableCommentsRunner,\n },\n];\n\n/**\n * Get enabled tools based on configuration\n */\nfunction getEnabledTools(config: Config): IToolRunner[] {\n return toolRegistry\n .filter((entry) => entry.isEnabled(config))\n .map((entry) => (typeof entry.runner === \"function\" ? entry.runner(config) : entry.runner));\n}\n\n/**\n * Run all code checks based on configuration\n */\nexport async function runCodeChecks(projectRoot: string, config: Config): Promise<DomainResult> {\n const tools = getEnabledTools(config);\n const checks = await runTools(tools, projectRoot, \"run\");\n return DomainResultBuilder.fromChecks(\"code\", checks);\n}\n\n/**\n * Audit code configuration (check that configs exist without running tools)\n */\nexport async function auditCodeConfig(projectRoot: string, config: Config): Promise<DomainResult> {\n const tools = getEnabledTools(config);\n const checks = await runTools(tools, projectRoot, \"audit\");\n return DomainResultBuilder.fromChecks(\"code\", checks);\n}\n\n/**\n * Run tools in parallel with error isolation\n * Uses Promise.allSettled to ensure one failing tool doesn't lose all results\n */\nasync function runTools(\n tools: IToolRunner[],\n projectRoot: string,\n mode: \"run\" | \"audit\"\n): Promise<CheckResult[]> {\n const promises = tools.map((tool) =>\n mode === \"run\" ? tool.run(projectRoot) : tool.audit(projectRoot)\n );\n\n const results = await Promise.allSettled(promises);\n\n return results.map((result, index) => {\n if (result.status === \"fulfilled\") {\n return result.value;\n }\n\n // Handle rejected promise - create error result for the tool\n const tool = tools[index];\n const errorMessage = result.reason instanceof Error ? result.reason.message : \"Unknown error\";\n\n return {\n name: tool.name,\n rule: tool.rule,\n passed: false,\n violations: [\n {\n rule: tool.rule,\n tool: tool.toolId,\n message: `Tool error: ${errorMessage}`,\n severity: \"error\" as const,\n },\n ],\n skipped: false,\n duration: 0,\n };\n });\n}\n","import { type _Object, ListObjectsV2Command, S3Client } from \"@aws-sdk/client-s3\";\n\nimport { AWS_DEFAULTS } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Backups configuration */\ninterface BackupsConfig {\n enabled?: boolean;\n bucket?: string;\n prefix?: string;\n max_age_hours?: number;\n region?: string;\n}\n\n/**\n * Runner for S3 backup verification.\n * Checks that backups exist in S3 and are recent.\n */\nexport class BackupsRunner extends BaseProcessToolRunner {\n readonly name = \"Backups\";\n readonly rule = \"process.backups\";\n readonly toolId = \"backups\";\n\n private config: BackupsConfig = { enabled: false };\n private s3Client: S3Client | null = null;\n\n setConfig(config: BackupsConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Allow injecting S3 client for testing */\n setS3Client(client: S3Client): void {\n this.s3Client = client;\n }\n\n async run(_projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!this.config.bucket) {\n return this.skip(\"No bucket configured\", elapsed());\n }\n\n try {\n const violations = await this.checkBackups();\n return this.fromViolations(violations, elapsed());\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return this.skip(`S3 error: ${message}`, elapsed());\n }\n }\n\n private async checkBackups(): Promise<Violation[]> {\n const client = this.getS3Client();\n const response = await client.send(\n new ListObjectsV2Command({\n Bucket: this.config.bucket,\n Prefix: this.config.prefix,\n })\n );\n\n if (!response.Contents || response.Contents.length === 0) {\n return [this.createExistsViolation()];\n }\n\n return this.checkBackupRecency(response.Contents);\n }\n\n private getS3Client(): S3Client {\n return (\n this.s3Client ??\n new S3Client({\n region: this.config.region ?? process.env.AWS_REGION ?? AWS_DEFAULTS.globalRegion,\n })\n );\n }\n\n private createExistsViolation(): Violation {\n return {\n rule: `${this.rule}.exists`,\n tool: this.toolId,\n message: `No backups found at s3://${this.config.bucket}/${this.config.prefix ?? \"\"}`,\n severity: \"error\",\n };\n }\n\n private checkBackupRecency(contents: _Object[]): Violation[] {\n const mostRecent = this.findMostRecentBackup(contents);\n\n if (!mostRecent?.LastModified) {\n return [\n {\n rule: `${this.rule}.recency`,\n tool: this.toolId,\n message: \"Could not determine backup age\",\n severity: \"error\",\n },\n ];\n }\n\n const maxAgeHours = this.config.max_age_hours ?? 24;\n const ageHours = (Date.now() - mostRecent.LastModified.getTime()) / (1000 * 60 * 60);\n\n if (ageHours > maxAgeHours) {\n return [\n {\n rule: `${this.rule}.recency`,\n tool: this.toolId,\n message: `Backup is ${Math.round(ageHours)} hours old (max: ${maxAgeHours} hours)`,\n severity: \"error\",\n file: mostRecent.Key,\n },\n ];\n }\n\n return [];\n }\n\n private findMostRecentBackup(contents: _Object[]): _Object | undefined {\n const withDates = contents.filter(\n (obj): obj is _Object & { LastModified: Date } => obj.LastModified !== undefined\n );\n return withDates.sort((a, b) => b.LastModified.getTime() - a.LastModified.getTime())[0];\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { CheckResultBuilder, type CheckResult, type IToolRunner, type Violation } from \"../../core/index.js\";\n\n/**\n * Abstract base class for process tool runners.\n * Provides common functionality for checking files and directories.\n */\nexport abstract class BaseProcessToolRunner implements IToolRunner {\n abstract readonly name: string;\n abstract readonly rule: string;\n abstract readonly toolId: string;\n /** Process tools don't have config files in the same way code tools do */\n readonly configFiles: string[] = [];\n\n /**\n * Check if a directory exists\n */\n protected directoryExists(projectRoot: string, dirPath: string): boolean {\n const fullPath = path.join(projectRoot, dirPath);\n return fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory();\n }\n\n /**\n * Check if a file exists\n */\n protected fileExists(projectRoot: string, filePath: string): boolean {\n const fullPath = path.join(projectRoot, filePath);\n return fs.existsSync(fullPath) && fs.statSync(fullPath).isFile();\n }\n\n /**\n * Read file contents\n */\n protected readFile(projectRoot: string, filePath: string): string | null {\n const fullPath = path.join(projectRoot, filePath);\n try {\n return fs.readFileSync(fullPath, \"utf-8\");\n } catch {\n return null;\n }\n }\n\n /**\n * Check if a file contains a specific string/pattern\n */\n protected fileContains(projectRoot: string, filePath: string, pattern: string): boolean {\n const content = this.readFile(projectRoot, filePath);\n if (content === null) {\n return false;\n }\n return content.includes(pattern);\n }\n\n /**\n * Create a pass result\n */\n protected pass(duration: number): CheckResult {\n return CheckResultBuilder.pass(this.name, this.rule, duration);\n }\n\n /**\n * Create a fail result from violations\n */\n protected fail(violations: Violation[], duration: number): CheckResult {\n return CheckResultBuilder.fail(this.name, this.rule, violations, duration);\n }\n\n /**\n * Create a result from violations (pass if empty, fail otherwise)\n */\n protected fromViolations(violations: Violation[], duration: number): CheckResult {\n return CheckResultBuilder.fromViolations(this.name, this.rule, violations, duration);\n }\n\n /**\n * Create a skip result\n */\n protected skip(reason: string, duration: number): CheckResult {\n return CheckResultBuilder.skip(this.name, this.rule, reason, duration);\n }\n\n /**\n * Run the tool - must be implemented by subclasses\n */\n abstract run(projectRoot: string): Promise<CheckResult>;\n\n /**\n * Audit the tool - by default same as run for process tools\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n return this.run(projectRoot);\n }\n}\n","import { execa } from \"execa\";\n\nimport { type CheckResult } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Branches configuration from standards.toml */\ninterface BranchesConfig {\n enabled?: boolean;\n pattern?: string;\n exclude?: string[];\n require_issue?: boolean;\n issue_pattern?: string;\n}\n\n/** Default pattern to extract issue number from branch name */\nconst DEFAULT_ISSUE_PATTERN = \"^(?:feature|fix|hotfix|docs)/([0-9]+)/.*$\";\n\n/**\n * Branch naming validation runner.\n * Checks that the current git branch name matches a required pattern.\n */\nexport class BranchesRunner extends BaseProcessToolRunner {\n readonly name = \"Branches\";\n readonly rule = \"process.branches\";\n readonly toolId = \"branches\";\n\n private config: BranchesConfig = {\n enabled: false,\n require_issue: false,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: BranchesConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Get the current git branch name */\n private async getCurrentBranch(projectRoot: string): Promise<string | null> {\n try {\n const result = await execa(\"git\", [\"branch\", \"--show-current\"], {\n cwd: projectRoot,\n });\n return result.stdout.trim() || null;\n } catch {\n return null;\n }\n }\n\n /** Check if branch is excluded from validation */\n private isExcluded(branch: string): boolean {\n const excludeList = this.config.exclude ?? [];\n return excludeList.includes(branch);\n }\n\n /** Validate branch name against pattern */\n private validateBranchPattern(branch: string): { passed: boolean; error?: string } {\n const pattern = this.config.pattern;\n if (!pattern) {\n return { passed: true }; // No pattern = no validation\n }\n\n try {\n const regex = new RegExp(pattern);\n if (regex.test(branch)) {\n return { passed: true };\n }\n return {\n passed: false,\n error: `Branch '${branch}' does not match pattern: ${pattern}`,\n };\n } catch {\n return {\n passed: false,\n error: `Invalid regex pattern: ${pattern}`,\n };\n }\n }\n\n /** Extract issue number from branch name */\n private extractIssueNumber(branch: string): string | null {\n const pattern = this.config.issue_pattern ?? DEFAULT_ISSUE_PATTERN;\n try {\n const regex = new RegExp(pattern);\n const match = branch.match(regex);\n return match?.[1] ?? null;\n } catch {\n return null;\n }\n }\n\n /** Validate that branch contains issue reference */\n private validateIssueReference(branch: string): { passed: boolean; error?: string } {\n if (!this.config.require_issue) {\n return { passed: true };\n }\n\n const issueNumber = this.extractIssueNumber(branch);\n if (issueNumber) {\n return { passed: true };\n }\n\n const pattern = this.config.issue_pattern ?? DEFAULT_ISSUE_PATTERN;\n return {\n passed: false,\n error: `Branch '${branch}' does not contain issue number. Expected format matching: ${pattern} (e.g., feature/123/description)`,\n };\n }\n\n /** Check if any validation is configured */\n private hasValidationConfigured(): boolean {\n return this.config.pattern !== undefined || this.config.require_issue === true;\n }\n\n /** Collect violations from all validations */\n private collectViolations(\n branch: string\n ): { rule: string; tool: string; message: string; severity: \"error\" | \"warning\" }[] {\n const violations: {\n rule: string;\n tool: string;\n message: string;\n severity: \"error\" | \"warning\";\n }[] = [];\n\n const patternResult = this.validateBranchPattern(branch);\n if (!patternResult.passed && patternResult.error) {\n violations.push({\n rule: `${this.rule}.pattern`,\n tool: this.toolId,\n message: patternResult.error,\n severity: \"error\",\n });\n }\n\n const issueResult = this.validateIssueReference(branch);\n if (!issueResult.passed && issueResult.error) {\n violations.push({\n rule: `${this.rule}.require_issue`,\n tool: this.toolId,\n message: issueResult.error,\n severity: \"error\",\n });\n }\n\n return violations;\n }\n\n /** Run branch naming validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!this.hasValidationConfigured()) {\n return this.skip(\"No branch pattern or issue requirement configured\", elapsed());\n }\n\n const branch = await this.getCurrentBranch(projectRoot);\n if (!branch) {\n return this.skip(\"Not in a git repository or no branch checked out\", elapsed());\n }\n\n if (this.isExcluded(branch)) {\n return this.pass(elapsed());\n }\n\n const violations = this.collectViolations(branch);\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\nimport { minimatch } from \"minimatch\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Valid changeset bump types */\ntype BumpType = \"patch\" | \"minor\" | \"major\";\n\n/** Changesets configuration from standards.toml */\ninterface ChangesetsConfig {\n enabled?: boolean;\n require_for_paths?: string[];\n exclude_paths?: string[];\n validate_format?: boolean;\n allowed_bump_types?: BumpType[];\n require_description?: boolean;\n min_description_length?: number;\n}\n\n/** Parsed changeset file */\ninterface ParsedChangeset {\n filePath: string;\n packages: Map<string, BumpType>;\n description: string;\n parseError?: string;\n}\n\n/** Find frontmatter boundaries in content lines */\nfunction findFrontmatterBounds(lines: string[]): { start: number; end: number } {\n let start = -1;\n let end = -1;\n\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].trim() === \"---\") {\n if (start === -1) {\n start = i;\n } else {\n end = i;\n break;\n }\n }\n }\n\n return { start, end };\n}\n\n/** Parse frontmatter lines to extract packages and bump types */\nfunction parseFrontmatterPackages(\n lines: string[],\n start: number,\n end: number\n): Map<string, BumpType> {\n const packages = new Map<string, BumpType>();\n\n for (let i = start + 1; i < end; i++) {\n const line = lines[i].trim();\n if (!line) {\n continue;\n }\n\n // Match: \"package-name\": bump-type\n const match = /^[\"']([^\"']+)[\"']:\\s*(patch|minor|major)\\s*$/.exec(line);\n if (match) {\n packages.set(match[1], match[2] as BumpType);\n }\n }\n\n return packages;\n}\n\n/** Check if a git branch exists */\nasync function branchExists(projectRoot: string, branch: string): Promise<boolean> {\n try {\n await execa(\"git\", [\"rev-parse\", \"--verify\", branch], { cwd: projectRoot });\n return true;\n } catch {\n return false;\n }\n}\n\n/** Try to find the base branch (main or master) */\nasync function findBaseBranch(projectRoot: string): Promise<string | null> {\n const branches = [\"origin/main\", \"origin/master\", \"main\", \"master\"];\n\n // Check branches in parallel to avoid await-in-loop\n const results = await Promise.all(branches.map((b) => branchExists(projectRoot, b)));\n const index = results.findIndex(Boolean);\n\n if (index === -1) {\n return null;\n }\n\n return branches[index].replace(\"origin/\", \"\");\n}\n\n/**\n * Changeset validation runner.\n * Validates that changeset files exist and are properly formatted.\n */\nexport class ChangesetsRunner extends BaseProcessToolRunner {\n readonly name = \"Changesets\";\n readonly rule = \"process.changesets\";\n readonly toolId = \"changesets\";\n\n private config: ChangesetsConfig = {\n enabled: false,\n validate_format: true,\n require_description: true,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: ChangesetsConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Get list of changeset files (excluding config.json) */\n private getChangesetFiles(projectRoot: string): string[] {\n const changesetDir = path.join(projectRoot, \".changeset\");\n\n if (!fs.existsSync(changesetDir)) {\n return [];\n }\n\n try {\n const files = fs.readdirSync(changesetDir);\n return files\n .filter((f) => f.endsWith(\".md\") && f !== \"README.md\")\n .map((f) => path.join(\".changeset\", f));\n } catch {\n return [];\n }\n }\n\n /** Parse a changeset file and extract frontmatter and description */\n private parseChangesetFile(projectRoot: string, filePath: string): ParsedChangeset {\n const fullPath = path.join(projectRoot, filePath);\n const result: ParsedChangeset = { filePath, packages: new Map(), description: \"\" };\n\n try {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n return this.parseChangesetContent(content, result);\n } catch (error) {\n const msg = error instanceof Error ? error.message : \"Unknown error\";\n result.parseError = `Failed to read file: ${msg}`;\n return result;\n }\n }\n\n /** Parse changeset content and populate result */\n private parseChangesetContent(content: string, result: ParsedChangeset): ParsedChangeset {\n const lines = content.split(\"\\n\");\n const { start, end } = findFrontmatterBounds(lines);\n\n if (start === -1) {\n result.parseError = \"Missing frontmatter: no opening '---' delimiter found\";\n return result;\n }\n if (end === -1) {\n result.parseError =\n \"Invalid frontmatter: opening '---' found but missing closing '---' delimiter\";\n return result;\n }\n\n result.packages = parseFrontmatterPackages(lines, start, end);\n result.description = lines\n .slice(end + 1)\n .join(\"\\n\")\n .trim();\n return result;\n }\n\n /** Get files changed in current branch vs main/master */\n private async getChangedFiles(projectRoot: string): Promise<string[] | null> {\n const baseBranch = await findBaseBranch(projectRoot);\n if (!baseBranch) {\n return null;\n }\n\n try {\n const result = await execa(\"git\", [\"diff\", \"--name-only\", `${baseBranch}...HEAD`], {\n cwd: projectRoot,\n });\n return result.stdout.trim().split(\"\\n\").filter(Boolean);\n } catch {\n return null;\n }\n }\n\n /** Check if any changed files match the require_for_paths patterns */\n private hasChangesRequiringChangeset(changedFiles: string[]): boolean {\n const requirePaths = this.config.require_for_paths;\n const excludePaths = this.config.exclude_paths ?? [];\n\n if (!requirePaths || requirePaths.length === 0) {\n return false;\n }\n\n return changedFiles.some((file) => {\n const isExcluded = excludePaths.some((pattern) => minimatch(file, pattern));\n if (isExcluded) {\n return false;\n }\n return requirePaths.some((pattern) => minimatch(file, pattern));\n });\n }\n\n /** Validate changeset format (packages in frontmatter) */\n private validateFormat(changeset: ParsedChangeset): Violation[] {\n const violations: Violation[] = [];\n\n if (changeset.packages.size === 0) {\n violations.push({\n rule: `${this.rule}.format`,\n tool: this.toolId,\n message: \"Changeset has no package entries in frontmatter\",\n severity: \"error\",\n file: changeset.filePath,\n });\n }\n\n return violations;\n }\n\n /** Validate bump types against allowed list */\n private validateBumpTypes(changeset: ParsedChangeset): Violation[] {\n const violations: Violation[] = [];\n const allowed = this.config.allowed_bump_types;\n\n if (!allowed || allowed.length === 0) {\n return violations;\n }\n\n for (const [pkg, bumpType] of changeset.packages) {\n if (!allowed.includes(bumpType)) {\n violations.push({\n rule: `${this.rule}.bump_type`,\n tool: this.toolId,\n message: `Package \"${pkg}\" has bump type \"${bumpType}\" but only ${allowed.join(\", \")} are allowed`,\n severity: \"error\",\n file: changeset.filePath,\n });\n }\n }\n\n return violations;\n }\n\n /** Validate description requirements */\n private validateDescription(changeset: ParsedChangeset): Violation[] {\n const violations: Violation[] = [];\n\n if (this.config.require_description === false) {\n return violations;\n }\n\n if (!changeset.description) {\n violations.push({\n rule: `${this.rule}.description`,\n tool: this.toolId,\n message: \"Changeset has no description\",\n severity: \"error\",\n file: changeset.filePath,\n });\n return violations;\n }\n\n const minLen = this.config.min_description_length;\n if (minLen && changeset.description.length < minLen) {\n violations.push({\n rule: `${this.rule}.description`,\n tool: this.toolId,\n message: `Changeset description is ${changeset.description.length} characters, minimum is ${minLen}`,\n severity: \"error\",\n file: changeset.filePath,\n });\n }\n\n return violations;\n }\n\n /** Validate a single changeset file */\n private validateChangeset(changeset: ParsedChangeset): Violation[] {\n if (changeset.parseError) {\n return [\n {\n rule: `${this.rule}.format`,\n tool: this.toolId,\n message: `Invalid changeset format: ${changeset.parseError}`,\n severity: \"error\",\n file: changeset.filePath,\n },\n ];\n }\n\n const violations: Violation[] = [];\n\n if (this.config.validate_format !== false) {\n violations.push(...this.validateFormat(changeset));\n violations.push(...this.validateBumpTypes(changeset));\n }\n\n violations.push(...this.validateDescription(changeset));\n\n return violations;\n }\n\n /** Check if changeset directory exists */\n private checkDirectoryExists(projectRoot: string, elapsed: () => number): CheckResult | null {\n if (!this.directoryExists(projectRoot, \".changeset\")) {\n return this.fromViolations(\n [\n {\n rule: `${this.rule}.directory`,\n tool: this.toolId,\n message: \"No .changeset directory found. Run 'pnpm exec changeset init' to initialize.\",\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n return null;\n }\n\n /** Check if changes require a changeset */\n private async checkChangesRequireChangeset(\n projectRoot: string,\n changesetFiles: string[],\n _elapsed: () => number\n ): Promise<{ skip?: string; violations: Violation[] }> {\n const requirePaths = this.config.require_for_paths;\n\n if (!requirePaths || requirePaths.length === 0) {\n return { violations: [] };\n }\n\n const changedFiles = await this.getChangedFiles(projectRoot);\n\n if (changedFiles === null) {\n return {\n skip: \"Could not determine changed files (not on a branch or no base branch found)\",\n violations: [],\n };\n }\n\n const violations: Violation[] = [];\n\n if (this.hasChangesRequiringChangeset(changedFiles) && changesetFiles.length === 0) {\n violations.push({\n rule: `${this.rule}.required`,\n tool: this.toolId,\n message: `Changes to files matching ${requirePaths.join(\", \")} require a changeset. Run 'pnpm exec changeset' to create one.`,\n severity: \"error\",\n });\n }\n\n return { violations };\n }\n\n /** Run changeset validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n // Check directory exists\n const dirCheck = this.checkDirectoryExists(projectRoot, elapsed);\n if (dirCheck) {\n return dirCheck;\n }\n\n // Get changeset files\n const changesetFiles = this.getChangesetFiles(projectRoot);\n\n // Check if changes require changeset\n const { skip, violations } = await this.checkChangesRequireChangeset(\n projectRoot,\n changesetFiles,\n elapsed\n );\n if (skip) {\n return this.skip(skip, elapsed());\n }\n\n // Validate each changeset file\n for (const file of changesetFiles) {\n const parsed = this.parseChangesetFile(projectRoot, file);\n violations.push(...this.validateChangeset(parsed));\n }\n\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n}\n"," \nimport * as yaml from \"js-yaml\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Commands configuration value - workflow-level or job-level */\ntype CommandsValue = string[] | Record<string, string[]>;\n\n/** CI configuration from standards.toml */\ninterface CiConfig {\n enabled?: boolean;\n require_workflows?: string[];\n jobs?: Record<string, string[]>;\n actions?: Record<string, string[]>;\n commands?: Record<string, CommandsValue>;\n}\n\n/** Parsed GitHub Actions workflow structure */\ninterface WorkflowFile {\n on?: WorkflowTriggers;\n jobs?: Record<string, WorkflowJob>;\n}\n\n/** Workflow triggers - can be string, array, or object */\ntype WorkflowTriggers =\n | string\n | string[]\n | {\n pull_request?: TriggerConfig;\n pull_request_target?: TriggerConfig;\n push?: TriggerConfig;\n [key: string]: unknown;\n };\n\ninterface TriggerConfig {\n branches?: string[];\n}\n\ninterface WorkflowJob {\n if?: string | boolean; // GitHub Actions allows boolean literals\n steps?: WorkflowStep[];\n uses?: string; // Reusable workflow reference\n}\n\ninterface WorkflowStep {\n if?: string | boolean; // GitHub Actions allows boolean literals\n run?: string;\n uses?: string;\n}\n\n/** Result of searching for a command in a workflow */\ninterface CommandSearchResult {\n found: boolean;\n conditional: boolean;\n conditionExpression?: string | boolean;\n commentedOut: boolean;\n}\n\n/**\n * CI/CD workflow validation runner.\n * Checks that GitHub Actions workflows exist and contain required jobs/actions/commands.\n */\nexport class CiRunner extends BaseProcessToolRunner {\n readonly name = \"CI\";\n readonly rule = \"process.ci\";\n readonly toolId = \"ci\";\n\n private config: CiConfig = {\n enabled: false,\n };\n\n setConfig(config: CiConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n private checkWorkflowsDirectory(projectRoot: string): Violation | null {\n if (this.directoryExists(projectRoot, \".github/workflows\")) {\n return null;\n }\n return {\n rule: `${this.rule}.directory`,\n tool: this.toolId,\n message: \"GitHub workflows directory not found (.github/workflows/)\",\n severity: \"error\",\n };\n }\n\n private checkRequiredWorkflows(projectRoot: string): Violation[] {\n const workflows = this.config.require_workflows ?? [];\n return workflows\n .filter((workflow) => !this.fileExists(projectRoot, `.github/workflows/${workflow}`))\n .map((workflow) => ({\n rule: `${this.rule}.workflow`,\n tool: this.toolId,\n file: `.github/workflows/${workflow}`,\n message: `Required workflow '${workflow}' not found`,\n severity: \"error\" as const,\n }));\n }\n\n private parseWorkflow(\n projectRoot: string,\n workflowFile: string\n ): { workflow: WorkflowFile | null; parseError?: string } {\n const content = this.readFile(projectRoot, `.github/workflows/${workflowFile}`);\n if (content === null) {\n return { workflow: null };\n }\n try {\n return { workflow: yaml.load(content) as WorkflowFile };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown YAML parse error\";\n return { workflow: null, parseError: message };\n }\n }\n\n private triggersPRToMain(workflow: WorkflowFile): boolean {\n const triggers = workflow.on;\n if (!triggers) {\n return false;\n }\n\n if (typeof triggers === \"string\") {\n return [\"pull_request\", \"pull_request_target\", \"push\"].includes(triggers);\n }\n\n if (Array.isArray(triggers)) {\n return triggers.some((t) => [\"pull_request\", \"pull_request_target\", \"push\"].includes(t));\n }\n\n const checkBranches = (config: TriggerConfig | undefined): boolean => {\n if (!config) {\n return false;\n }\n const branches = config.branches;\n if (!branches || branches.length === 0) {\n return true;\n }\n return branches.some((b) => [\"main\", \"master\", \"*\"].includes(b));\n };\n\n return (\n checkBranches(triggers.pull_request as TriggerConfig) ||\n checkBranches(triggers.pull_request_target as TriggerConfig) ||\n checkBranches(triggers.push as TriggerConfig)\n );\n }\n\n private isUnconditionalExpression(expression: string | boolean | undefined): boolean {\n if (expression === undefined) {\n return true;\n }\n // Handle boolean values (YAML parses `if: true` as boolean)\n if (typeof expression === \"boolean\") {\n return expression;\n }\n const expr = String(expression).trim().toLowerCase();\n return [\"true\", \"success()\", \"always()\"].includes(expr);\n }\n\n private extractRunCommands(runContent: string): string[] {\n return runContent\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line && !line.startsWith(\"#\"));\n }\n\n private commandMatches(actual: string, required: string): boolean {\n return actual.includes(required);\n }\n\n /** Check if run content has a commented version of the command */\n private hasCommentedCommand(runContent: string, command: string): boolean {\n return runContent\n .split(\"\\n\")\n .some((line) => line.trim().startsWith(\"#\") && this.commandMatches(line, command));\n }\n\n /** Search for a command in a single step */\n private searchCommandInStep(\n step: WorkflowStep,\n requiredCommand: string,\n jobConditional: boolean,\n jobCondition: string | boolean | undefined\n ): CommandSearchResult | null {\n if (!step.run) {\n return null;\n }\n\n const commentedOut = this.hasCommentedCommand(step.run, requiredCommand);\n const commands = this.extractRunCommands(step.run);\n const found = commands.some((cmd) => this.commandMatches(cmd, requiredCommand));\n\n if (!found) {\n return commentedOut ? { found: false, conditional: false, commentedOut: true } : null;\n }\n\n const stepConditional = !this.isUnconditionalExpression(step.if);\n const conditional = jobConditional || stepConditional;\n const conditionExpression = jobConditional ? jobCondition : step.if;\n\n return { found: true, conditional, conditionExpression, commentedOut };\n }\n\n private searchCommandInJob(job: WorkflowJob, requiredCommand: string): CommandSearchResult {\n const jobConditional = !this.isUnconditionalExpression(job.if);\n let commentedOut = false;\n\n for (const step of job.steps ?? []) {\n const result = this.searchCommandInStep(step, requiredCommand, jobConditional, job.if);\n if (result?.commentedOut) {\n commentedOut = true;\n }\n if (result?.found) {\n return result;\n }\n }\n\n return { found: false, conditional: false, commentedOut };\n }\n\n private searchCommandInWorkflow(\n workflow: WorkflowFile,\n requiredCommand: string\n ): CommandSearchResult {\n let commentedOut = false;\n let conditionalResult: CommandSearchResult | null = null;\n\n for (const job of Object.values(workflow.jobs ?? {})) {\n if (job.uses) {\n continue;\n }\n const result = this.searchCommandInJob(job, requiredCommand);\n if (result.commentedOut) {\n commentedOut = true;\n }\n if (result.found && !result.conditional) {\n return result;\n }\n if (result.found && !conditionalResult) {\n conditionalResult = result;\n }\n }\n return conditionalResult ?? { found: false, conditional: false, commentedOut };\n }\n\n private cmdViolation(workflowFile: string, msg: string): Violation {\n return {\n rule: `${this.rule}.commands`,\n tool: this.toolId,\n file: `.github/workflows/${workflowFile}`,\n message: msg,\n severity: \"error\",\n };\n }\n\n private workflowCmdViolation(wf: string, cmd: string, r: CommandSearchResult): Violation | null {\n if (!r.found && r.commentedOut) {\n return this.cmdViolation(wf, `Command '${cmd}' appears commented out in workflow '${wf}'`);\n }\n if (!r.found) {\n return this.cmdViolation(wf, `Required command '${cmd}' not found in workflow '${wf}'`);\n }\n if (r.conditional) {\n return this.cmdViolation(\n wf,\n `Command '${cmd}' in workflow '${wf}' may not execute on PRs (has condition: ${r.conditionExpression})`\n );\n }\n return null;\n }\n\n private jobCmdViolation(\n wf: string,\n jobId: string,\n cmd: string,\n r: CommandSearchResult\n ): Violation | null {\n if (!r.found && r.commentedOut) {\n return this.cmdViolation(\n wf,\n `Command '${cmd}' appears commented out in job '${jobId}' of workflow '${wf}'`\n );\n }\n if (!r.found) {\n return this.cmdViolation(\n wf,\n `Required command '${cmd}' not found in job '${jobId}' of workflow '${wf}'`\n );\n }\n if (r.conditional) {\n return this.cmdViolation(\n wf,\n `Command '${cmd}' in job '${jobId}' of workflow '${wf}' may not execute on PRs (has condition: ${r.conditionExpression})`\n );\n }\n return null;\n }\n\n private checkWorkflowLevelCommands(\n workflow: WorkflowFile,\n wf: string,\n commands: string[]\n ): Violation[] {\n return commands\n .map((cmd) => this.workflowCmdViolation(wf, cmd, this.searchCommandInWorkflow(workflow, cmd)))\n .filter((v): v is Violation => v !== null);\n }\n\n private checkJobLevelCommands(\n workflow: WorkflowFile,\n wf: string,\n jobCommands: Record<string, string[]>\n ): Violation[] {\n const violations: Violation[] = [];\n for (const [jobId, commands] of Object.entries(jobCommands)) {\n const job = workflow.jobs?.[jobId];\n if (!job) {\n violations.push(this.cmdViolation(wf, `Job '${jobId}' not found in workflow '${wf}'`));\n continue;\n }\n if (job.uses) {\n violations.push(\n this.cmdViolation(\n wf,\n `Job '${jobId}' in workflow '${wf}' uses a reusable workflow - command validation not supported`\n )\n );\n continue;\n }\n for (const cmd of commands) {\n const v = this.jobCmdViolation(wf, jobId, cmd, this.searchCommandInJob(job, cmd));\n if (v) {\n violations.push(v);\n }\n }\n }\n return violations;\n }\n\n private yamlErrorViolation(wf: string, parseError: string): Violation {\n return {\n rule: `${this.rule}.yaml`,\n tool: this.toolId,\n file: `.github/workflows/${wf}`,\n message: `Invalid YAML in workflow '${wf}': ${parseError}`,\n severity: \"error\",\n };\n }\n\n private checkWorkflowCommands(projectRoot: string): Violation[] {\n const violations: Violation[] = [];\n for (const [wf, commandsValue] of Object.entries(this.config.commands ?? {})) {\n const { workflow, parseError } = this.parseWorkflow(projectRoot, wf);\n if (parseError) {\n violations.push(this.yamlErrorViolation(wf, parseError));\n continue;\n }\n if (!workflow) {\n violations.push({\n rule: `${this.rule}.commands`,\n tool: this.toolId,\n file: `.github/workflows/${wf}`,\n message: `Workflow file '${wf}' not found`,\n severity: \"error\",\n });\n continue;\n }\n if (!this.triggersPRToMain(workflow)) {\n violations.push(\n this.cmdViolation(wf, `Workflow '${wf}' does not trigger on pull_request to main/master`)\n );\n continue;\n }\n violations.push(\n ...(Array.isArray(commandsValue)\n ? this.checkWorkflowLevelCommands(workflow, wf, commandsValue)\n : this.checkJobLevelCommands(workflow, wf, commandsValue))\n );\n }\n return violations;\n }\n\n private checkRequiredJobs(projectRoot: string): Violation[] {\n const violations: Violation[] = [];\n for (const [workflowFile, requiredJobs] of Object.entries(this.config.jobs ?? {})) {\n const { workflow, parseError } = this.parseWorkflow(projectRoot, workflowFile);\n if (parseError) {\n violations.push(this.yamlErrorViolation(workflowFile, parseError));\n continue;\n }\n if (!workflow) {\n continue;\n }\n const existingJobs = Object.keys(workflow.jobs ?? {});\n for (const job of requiredJobs.filter((j) => !existingJobs.includes(j))) {\n violations.push({\n rule: `${this.rule}.jobs`,\n tool: this.toolId,\n file: `.github/workflows/${workflowFile}`,\n message: `Workflow '${workflowFile}' missing required job: ${job}`,\n severity: \"error\",\n });\n }\n }\n return violations;\n }\n\n /**\n * Parse a GitHub Actions reference to extract the action name.\n * Handles:\n * - Standard refs: \"actions/checkout@v4\" -> \"actions/checkout\"\n * - SHA refs: \"actions/checkout@abc123\" -> \"actions/checkout\"\n * - Local actions: \"./path/to/action\" -> \"./path/to/action\"\n * - Docker actions: \"docker://image:tag\" -> null (excluded)\n */\n private parseActionReference(uses: string): string | null {\n // Skip Docker actions - they're container images, not GitHub Actions\n if (uses.startsWith(\"docker://\")) {\n return null;\n }\n\n // Local actions don't have version tags\n if (uses.startsWith(\"./\") || uses.startsWith(\"../\")) {\n return uses;\n }\n\n // Standard GitHub Actions: extract name before @ version tag\n const atIndex = uses.indexOf(\"@\");\n return atIndex > 0 ? uses.slice(0, atIndex) : uses;\n }\n\n private extractUsedActions(workflow: WorkflowFile): string[] {\n return Object.values(workflow.jobs ?? {}).flatMap((job) =>\n (job.steps ?? [])\n .map((s) => (s.uses ? this.parseActionReference(s.uses) : null))\n .filter((u): u is string => u !== null)\n );\n }\n\n private checkRequiredActions(projectRoot: string): Violation[] {\n const violations: Violation[] = [];\n for (const [workflowFile, requiredActions] of Object.entries(this.config.actions ?? {})) {\n const { workflow, parseError } = this.parseWorkflow(projectRoot, workflowFile);\n if (parseError) {\n violations.push(this.yamlErrorViolation(workflowFile, parseError));\n continue;\n }\n if (!workflow) {\n continue;\n }\n const usedActions = this.extractUsedActions(workflow);\n for (const action of requiredActions.filter((a) => !usedActions.includes(a))) {\n violations.push({\n rule: `${this.rule}.actions`,\n tool: this.toolId,\n file: `.github/workflows/${workflowFile}`,\n message: `Workflow '${workflowFile}' missing required action: ${action}`,\n severity: \"error\",\n });\n }\n }\n return violations;\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const directoryViolation = this.checkWorkflowsDirectory(projectRoot);\n if (directoryViolation) {\n return this.fromViolations([directoryViolation], elapsed());\n }\n\n const violations = [\n ...this.checkRequiredWorkflows(projectRoot),\n ...this.checkRequiredJobs(projectRoot),\n ...this.checkRequiredActions(projectRoot),\n ...this.checkWorkflowCommands(projectRoot),\n ];\n\n return this.fromViolations(violations, elapsed());\n }\n}\n","import { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Single CODEOWNERS rule from config */\ninterface CodeownersRule {\n pattern: string;\n owners: string[];\n}\n\n/** CODEOWNERS configuration */\ninterface CodeownersConfig {\n enabled?: boolean;\n rules?: CodeownersRule[];\n}\n\n/** Parsed rule from CODEOWNERS file */\ninterface ParsedRule {\n pattern: string;\n owners: string[];\n line: number;\n}\n\n/** Common CODEOWNERS file locations */\nconst CODEOWNERS_LOCATIONS = [\".github/CODEOWNERS\", \"CODEOWNERS\", \"docs/CODEOWNERS\"];\n\n/**\n * Runner for CODEOWNERS file validation.\n * Validates that CODEOWNERS file exists and contains all required rules.\n */\nexport class CodeownersRunner extends BaseProcessToolRunner {\n readonly name = \"CODEOWNERS\";\n readonly rule = \"process.codeowners\";\n readonly toolId = \"codeowners\";\n\n private config: CodeownersConfig = { enabled: false };\n\n setConfig(config: CodeownersConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Run check - validates CODEOWNERS content matches config\n */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n // Find CODEOWNERS file\n const codeownersPath = this.findCodeownersFile(projectRoot);\n if (!codeownersPath) {\n return this.fail(\n [\n {\n rule: `${this.rule}.file`,\n tool: this.toolId,\n message:\n \"CODEOWNERS file not found (checked .github/CODEOWNERS, CODEOWNERS, docs/CODEOWNERS)\",\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n\n // Read and parse CODEOWNERS file\n const content = this.readFile(projectRoot, codeownersPath);\n if (content === null) {\n return this.fail(\n [\n {\n rule: `${this.rule}.file`,\n tool: this.toolId,\n message: `Could not read CODEOWNERS file: ${codeownersPath}`,\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n\n const { rules: parsedRules, malformedViolations } = this.parseCodeowners(\n content,\n codeownersPath\n );\n const validationViolations = this.validateRules(parsedRules, codeownersPath);\n\n // Combine malformed line violations with validation violations\n const violations = [...malformedViolations, ...validationViolations];\n return this.fromViolations(violations, elapsed());\n }\n\n /**\n * Audit - just checks that CODEOWNERS file exists\n */\n async audit(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const codeownersPath = this.findCodeownersFile(projectRoot);\n if (!codeownersPath) {\n return this.fail(\n [\n {\n rule: `${this.rule}.file`,\n tool: this.toolId,\n message:\n \"CODEOWNERS file not found (checked .github/CODEOWNERS, CODEOWNERS, docs/CODEOWNERS)\",\n severity: \"error\",\n },\n ],\n elapsed()\n );\n }\n\n return this.pass(elapsed());\n }\n\n /**\n * Find CODEOWNERS file in one of the standard locations\n */\n private findCodeownersFile(projectRoot: string): string | null {\n for (const location of CODEOWNERS_LOCATIONS) {\n if (this.fileExists(projectRoot, location)) {\n return location;\n }\n }\n return null;\n }\n\n /**\n * Parse result including both valid rules and malformed line violations\n */\n private parseCodeowners(\n content: string,\n filePath: string\n ): { rules: ParsedRule[]; malformedViolations: Violation[] } {\n const rules: ParsedRule[] = [];\n const malformedViolations: Violation[] = [];\n const lines = content.split(\"\\n\");\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n const lineNumber = i + 1;\n\n // Skip empty lines and comments\n if (!line || line.startsWith(\"#\")) {\n continue;\n }\n\n const parsed = this.parseCodeownersLine(line, lineNumber);\n if (parsed) {\n rules.push(parsed);\n } else {\n // Report malformed line as violation\n malformedViolations.push({\n rule: `${this.rule}.malformed`,\n tool: this.toolId,\n file: filePath,\n line: lineNumber,\n message: `Malformed CODEOWNERS line: pattern \"${line}\" has no owners`,\n severity: \"error\",\n });\n }\n }\n\n return { rules, malformedViolations };\n }\n\n /**\n * Parse a single CODEOWNERS line into pattern and owners\n */\n private parseCodeownersLine(line: string, lineNumber: number): ParsedRule | null {\n // Split on whitespace - first token is pattern, rest are owners\n const tokens = line.split(/\\s+/).filter(Boolean);\n\n if (tokens.length < 2) {\n // Invalid line - pattern without owners\n return null;\n }\n\n const [pattern, ...owners] = tokens;\n return { pattern, owners, line: lineNumber };\n }\n\n /**\n * Validate rules against config\n */\n private validateRules(parsedRules: ParsedRule[], filePath: string): Violation[] {\n const configRules = this.config.rules ?? [];\n const parsedRuleMap = this.buildParsedRuleMap(parsedRules);\n\n const missingViolations = this.checkMissingRules(configRules, parsedRuleMap, filePath);\n const extraViolations = this.checkExtraRules(parsedRules, configRules, filePath);\n\n return [...missingViolations, ...extraViolations];\n }\n\n /**\n * Build a map of parsed rules for quick lookup\n */\n private buildParsedRuleMap(parsedRules: ParsedRule[]): Map<string, ParsedRule> {\n const map = new Map<string, ParsedRule>();\n for (const rule of parsedRules) {\n map.set(rule.pattern, rule);\n }\n return map;\n }\n\n /**\n * Check that all configured rules exist with correct owners\n */\n private checkMissingRules(\n configRules: CodeownersRule[],\n parsedRuleMap: Map<string, ParsedRule>,\n filePath: string\n ): Violation[] {\n const violations: Violation[] = [];\n\n for (const configRule of configRules) {\n const parsedRule = parsedRuleMap.get(configRule.pattern);\n const violation = this.validateConfigRule(configRule, parsedRule, filePath);\n if (violation) {\n violations.push(violation);\n }\n }\n\n return violations;\n }\n\n /**\n * Validate a single config rule against parsed rule\n */\n private validateConfigRule(\n configRule: CodeownersRule,\n parsedRule: ParsedRule | undefined,\n filePath: string\n ): Violation | null {\n if (!parsedRule) {\n return {\n rule: `${this.rule}.missing`,\n tool: this.toolId,\n file: filePath,\n message: `Missing required rule: ${configRule.pattern} ${configRule.owners.join(\" \")}`,\n severity: \"error\",\n };\n }\n\n if (!this.ownersMatch(configRule.owners, parsedRule.owners)) {\n return {\n rule: `${this.rule}.owners`,\n tool: this.toolId,\n file: filePath,\n line: parsedRule.line,\n message: `Owner mismatch for ${configRule.pattern}: expected [${configRule.owners.join(\", \")}], got [${parsedRule.owners.join(\", \")}]`,\n severity: \"error\",\n };\n }\n\n return null;\n }\n\n /**\n * Check for rules in CODEOWNERS that aren't in config\n */\n private checkExtraRules(\n parsedRules: ParsedRule[],\n configRules: CodeownersRule[],\n filePath: string\n ): Violation[] {\n const configPatterns = new Set(configRules.map((r) => r.pattern));\n const violations: Violation[] = [];\n\n for (const parsedRule of parsedRules) {\n if (!configPatterns.has(parsedRule.pattern)) {\n violations.push({\n rule: `${this.rule}.extra`,\n tool: this.toolId,\n file: filePath,\n line: parsedRule.line,\n message: `Unexpected rule not in config: ${parsedRule.pattern} ${parsedRule.owners.join(\" \")}`,\n severity: \"error\",\n });\n }\n }\n\n return violations;\n }\n\n /**\n * Check if two owner arrays match exactly (order-sensitive)\n */\n private ownersMatch(expected: string[], actual: string[]): boolean {\n if (expected.length !== actual.length) {\n return false;\n }\n return expected.every((owner, index) => owner === actual[index]);\n }\n}\n","import { execa } from \"execa\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Commits configuration from standards.toml */\ninterface CommitsConfig {\n enabled?: boolean;\n pattern?: string;\n types?: string[];\n require_scope?: boolean;\n max_subject_length?: number;\n}\n\n/**\n * Commit message format validation runner.\n * Validates that commit messages follow conventional commit format or custom patterns.\n */\nexport class CommitsRunner extends BaseProcessToolRunner {\n readonly name = \"Commits\";\n readonly rule = \"process.commits\";\n readonly toolId = \"commits\";\n\n private config: CommitsConfig = {\n enabled: false,\n require_scope: false,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: CommitsConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Get the HEAD commit message (subject line only) */\n private async getHeadCommitSubject(projectRoot: string): Promise<string | null> {\n try {\n const result = await execa(\"git\", [\"log\", \"-1\", \"--format=%s\"], {\n cwd: projectRoot,\n });\n return result.stdout.trim() || null;\n } catch {\n return null;\n }\n }\n\n /** Build conventional commits pattern from config */\n private buildConventionalPattern(): string {\n const types = this.config.types;\n if (!types || types.length === 0) {\n return \"\";\n }\n\n const typePattern = types.join(\"|\");\n // Use [^)]+ instead of .+ to avoid greedy matching through multiple parentheses\n const scopePattern = this.config.require_scope ? \"\\\\([^)]+\\\\)\" : \"(\\\\([^)]+\\\\))?\";\n\n // Pattern: type(scope)?: description\n // e.g., feat(api): add new endpoint\n return `^(${typePattern})${scopePattern}: .+`;\n }\n\n /** Check if text matches a pattern */\n private matchesPattern(text: string, pattern: string): boolean {\n try {\n const regex = new RegExp(pattern);\n return regex.test(text);\n } catch {\n return false;\n }\n }\n\n /** Validate the regex pattern is valid */\n private isValidPattern(pattern: string): boolean {\n try {\n new RegExp(pattern);\n return true;\n } catch {\n return false;\n }\n }\n\n /** Check configuration validity */\n private hasValidConfig(): { valid: boolean; reason?: string; pattern?: string } {\n // If explicit pattern is provided, use it\n if (this.config.pattern) {\n if (!this.isValidPattern(this.config.pattern)) {\n return { valid: false, reason: `Invalid regex pattern: ${this.config.pattern}` };\n }\n return { valid: true, pattern: this.config.pattern };\n }\n\n // If types are provided, build conventional commits pattern\n if (this.config.types && this.config.types.length > 0) {\n const pattern = this.buildConventionalPattern();\n return { valid: true, pattern };\n }\n\n // No pattern and no types - need at least one\n return { valid: false, reason: \"No pattern or types configured for commit validation\" };\n }\n\n /** Validate commit message format */\n private validateCommitFormat(\n subject: string,\n pattern: string,\n elapsed: () => number\n ): CheckResult {\n const violations: Violation[] = [];\n\n // Check pattern match\n if (!this.matchesPattern(subject, pattern)) {\n const typesHint = this.config.types\n ? ` Expected format: ${this.config.types.join(\"|\")}${this.config.require_scope ? \"(scope)\" : \"(scope)?\"}: description`\n : \"\";\n violations.push({\n rule: `${this.rule}.pattern`,\n tool: this.toolId,\n message: `Commit message does not match required format.${typesHint}`,\n severity: \"error\",\n });\n }\n\n // Check max subject length\n if (this.config.max_subject_length && subject.length > this.config.max_subject_length) {\n violations.push({\n rule: `${this.rule}.max_subject_length`,\n tool: this.toolId,\n message: `Commit subject is ${subject.length} characters, exceeds max of ${this.config.max_subject_length}`,\n severity: \"error\",\n });\n }\n\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n\n /** Run commit message validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const configCheck = this.hasValidConfig();\n if (!configCheck.valid) {\n return this.skip(configCheck.reason ?? \"Invalid configuration\", elapsed());\n }\n\n const subject = await this.getHeadCommitSubject(projectRoot);\n if (!subject) {\n return this.skip(\"Not in a git repository or no commits\", elapsed());\n }\n\n return this.validateCommitFormat(subject, configCheck.pattern as string, elapsed);\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport * as yaml from \"js-yaml\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Coverage configuration from standards.toml */\ninterface CoverageConfig {\n enabled?: boolean;\n min_threshold?: number;\n enforce_in?: \"ci\" | \"config\" | \"both\";\n ci_workflow?: string;\n ci_job?: string;\n}\n\n/** Coverage config file detection result */\ninterface CoverageConfigResult {\n found: boolean;\n file?: string;\n threshold?: number;\n error?: string;\n}\n\n/** Helper to safely read and parse JSON */\nfunction parseJsonFile(filePath: string): Record<string, unknown> | null {\n try {\n const content = fs.readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n/** Helper to read file content */\nfunction readFileContent(filePath: string): string | null {\n try {\n return fs.readFileSync(filePath, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/** Extract threshold from vitest/jest style config */\nfunction extractThresholdFromContent(content: string): number | undefined {\n const match = /(?:lines|statements|branches|functions)\\s*:\\s*(\\d+)/.exec(content);\n return match ? parseInt(match[1], 10) : undefined;\n}\n\n/** Parse nyc config file content (JSON or YAML) */\nfunction parseNycConfigContent(\n content: string,\n configFile: string\n): { config: Record<string, unknown> } | { error: string } {\n try {\n const config =\n configFile.endsWith(\".yaml\") || configFile.endsWith(\".yml\")\n ? (yaml.load(content) as Record<string, unknown>)\n : (JSON.parse(content) as Record<string, unknown>);\n return { config };\n } catch {\n return { error: \"Failed to parse config file\" };\n }\n}\n\n/** Extract threshold from nyc config object */\nfunction extractNycThreshold(config: Record<string, unknown>): number | undefined {\n return (\n (config.lines as number | undefined) ??\n (config.statements as number | undefined) ??\n (config.branches as number | undefined) ??\n (config.functions as number | undefined)\n );\n}\n\n/**\n * Coverage enforcement runner.\n * Checks that coverage thresholds are configured in CI workflows and/or config files.\n */\nexport class CoverageRunner extends BaseProcessToolRunner {\n readonly name = \"Coverage\";\n readonly rule = \"process.coverage\";\n readonly toolId = \"coverage\";\n\n private config: CoverageConfig = {\n enabled: false,\n enforce_in: \"config\",\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: CoverageConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Check for vitest coverage config */\n private checkVitestConfig(projectRoot: string): CoverageConfigResult {\n const configFiles = [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"vitest.config.mts\",\n \"vitest.config.mjs\",\n ];\n\n for (const configFile of configFiles) {\n const configPath = path.join(projectRoot, configFile);\n const content = readFileContent(configPath);\n if (!content) {\n continue;\n }\n\n const hasThreshold =\n /coverage\\s*:\\s*\\{[^}]*thresholds?\\s*:/s.test(content) ||\n /thresholds?\\s*:\\s*\\{[^}]*(?:lines|statements|branches|functions)\\s*:/s.test(content);\n\n if (hasThreshold) {\n return { found: true, file: configFile, threshold: extractThresholdFromContent(content) };\n }\n return { found: false, file: configFile, error: \"No coverage thresholds configured\" };\n }\n return { found: false };\n }\n\n /** Check jest config file */\n private checkJestConfigFile(projectRoot: string): CoverageConfigResult {\n const configFiles = [\"jest.config.js\", \"jest.config.ts\", \"jest.config.mjs\", \"jest.config.cjs\"];\n\n for (const configFile of configFiles) {\n const configPath = path.join(projectRoot, configFile);\n const content = readFileContent(configPath);\n if (!content) {\n continue;\n }\n\n if (/coverageThreshold\\s*:/s.test(content)) {\n return { found: true, file: configFile, threshold: extractThresholdFromContent(content) };\n }\n return { found: false, file: configFile, error: \"No coverageThreshold configured\" };\n }\n return { found: false };\n }\n\n /** Check jest config in package.json */\n private checkJestPackageJson(projectRoot: string): CoverageConfigResult {\n const pkg = parseJsonFile(path.join(projectRoot, \"package.json\"));\n if (!pkg) {\n return { found: false };\n }\n\n const jestConfig = pkg.jest as Record<string, unknown> | undefined;\n if (!jestConfig?.coverageThreshold) {\n return { found: false };\n }\n\n const globalThreshold = (jestConfig.coverageThreshold as Record<string, unknown>).global as\n | { lines?: number; statements?: number; branches?: number; functions?: number }\n | undefined;\n if (!globalThreshold) {\n return { found: false };\n }\n\n const threshold =\n globalThreshold.lines ??\n globalThreshold.statements ??\n globalThreshold.branches ??\n globalThreshold.functions;\n return { found: true, file: \"package.json (jest)\", threshold };\n }\n\n /** Check for jest coverage config */\n private checkJestConfig(projectRoot: string): CoverageConfigResult {\n const fileResult = this.checkJestConfigFile(projectRoot);\n if (fileResult.found || fileResult.file) {\n return fileResult;\n }\n return this.checkJestPackageJson(projectRoot);\n }\n\n /** Check a single nyc config file and return result */\n private checkSingleNycConfig(configFile: string, content: string): CoverageConfigResult {\n const parseResult = parseNycConfigContent(content, configFile);\n if (\"error\" in parseResult) {\n return { found: false, file: configFile, error: parseResult.error };\n }\n\n if (!parseResult.config[\"check-coverage\"]) {\n return { found: false, file: configFile, error: \"check-coverage not enabled\" };\n }\n\n return { found: true, file: configFile, threshold: extractNycThreshold(parseResult.config) };\n }\n\n /** Check nyc config file */\n private checkNycConfigFile(projectRoot: string): CoverageConfigResult {\n const nycrcFiles = [\".nycrc\", \".nycrc.json\", \".nycrc.yaml\", \".nycrc.yml\"];\n\n for (const configFile of nycrcFiles) {\n const configPath = path.join(projectRoot, configFile);\n if (!fs.existsSync(configPath)) {\n continue;\n }\n\n const content = readFileContent(configPath);\n if (!content) {\n return { found: false, file: configFile, error: \"Failed to read config file\" };\n }\n\n return this.checkSingleNycConfig(configFile, content);\n }\n return { found: false };\n }\n\n /** Check nyc config in package.json */\n private checkNycPackageJson(projectRoot: string): CoverageConfigResult {\n const pkg = parseJsonFile(path.join(projectRoot, \"package.json\"));\n if (!pkg) {\n return { found: false };\n }\n\n const nycConfig = pkg.nyc as Record<string, unknown> | undefined;\n if (!nycConfig?.[\"check-coverage\"]) {\n return { found: false };\n }\n\n const threshold =\n (nycConfig.lines as number | undefined) ??\n (nycConfig.statements as number | undefined) ??\n (nycConfig.branches as number | undefined) ??\n (nycConfig.functions as number | undefined);\n return { found: true, file: \"package.json (nyc)\", threshold };\n }\n\n /** Check for nyc coverage config */\n private checkNycConfig(projectRoot: string): CoverageConfigResult {\n const fileResult = this.checkNycConfigFile(projectRoot);\n if (fileResult.found || fileResult.file) {\n return fileResult;\n }\n return this.checkNycPackageJson(projectRoot);\n }\n\n /** Check for coverage config in any supported tool */\n private checkConfigCoverage(projectRoot: string): CoverageConfigResult {\n const vitestResult = this.checkVitestConfig(projectRoot);\n if (vitestResult.found) {\n return vitestResult;\n }\n\n const jestResult = this.checkJestConfig(projectRoot);\n if (jestResult.found) {\n return jestResult;\n }\n\n const nycResult = this.checkNycConfig(projectRoot);\n if (nycResult.found) {\n return nycResult;\n }\n\n return {\n found: false,\n error: \"No coverage threshold config found (checked vitest, jest, nyc)\",\n };\n }\n\n /** Check if a step has coverage enforcement */\n private stepHasCoverage(run: string): boolean {\n if (\n !run.includes(\"--coverage\") &&\n !run.includes(\"test:coverage\") &&\n !run.includes(\"coverage:check\")\n ) {\n return false;\n }\n return (\n run.includes(\"threshold\") ||\n run.includes(\"check-coverage\") ||\n run.includes(\"--coverage.\") ||\n run.includes(\"test:coverage\") ||\n run.includes(\"coverage:check\")\n );\n }\n\n /** Check a single job for coverage enforcement */\n private checkJobForCoverage(\n job: Record<string, unknown>,\n jobName: string,\n workflowFile: string\n ): CoverageConfigResult | null {\n const steps = job.steps as { run?: string }[] | undefined;\n if (!steps) {\n return null;\n }\n\n for (const step of steps) {\n if (step.run && this.stepHasCoverage(step.run)) {\n return { found: true, file: `${workflowFile} (job: ${jobName})` };\n }\n }\n return null;\n }\n\n /** Check workflow jobs for coverage */\n private checkWorkflowJobs(\n jobs: Record<string, Record<string, unknown>>,\n targetJob: string | undefined,\n workflowFile: string\n ): CoverageConfigResult {\n if (targetJob && targetJob in jobs) {\n const result = this.checkJobForCoverage(jobs[targetJob], targetJob, workflowFile);\n if (result) {\n return result;\n }\n } else if (!targetJob) {\n for (const [jobName, job] of Object.entries(jobs)) {\n const result = this.checkJobForCoverage(job, jobName, workflowFile);\n if (result) {\n return result;\n }\n }\n }\n\n return { found: false, file: workflowFile, error: \"No coverage enforcement found in workflow\" };\n }\n\n /** Check for coverage enforcement in CI workflow */\n private checkCiCoverage(projectRoot: string): CoverageConfigResult {\n const workflowFile = this.config.ci_workflow ?? \"ci.yml\";\n const workflowPath = path.join(projectRoot, \".github\", \"workflows\", workflowFile);\n\n const content = readFileContent(workflowPath);\n if (!content) {\n return { found: false, error: `Workflow file not found: ${workflowFile}` };\n }\n\n let workflow: Record<string, unknown>;\n try {\n workflow = yaml.load(content) as Record<string, unknown>;\n } catch {\n return { found: false, file: workflowFile, error: \"Failed to parse workflow file\" };\n }\n\n const jobs = workflow.jobs as Record<string, Record<string, unknown>> | undefined;\n if (!jobs) {\n return { found: false, file: workflowFile, error: \"No jobs found in workflow\" };\n }\n\n return this.checkWorkflowJobs(jobs, this.config.ci_job, workflowFile);\n }\n\n /** Validate config coverage and add violations if needed */\n private validateConfigCoverage(projectRoot: string, violations: Violation[]): void {\n const configResult = this.checkConfigCoverage(projectRoot);\n\n // If min_threshold is set in standards.toml, that's a valid coverage config\n // (no need for tool-specific config like vitest.config.ts or jest.config.js)\n const hasCheckTomlThreshold = this.config.min_threshold !== undefined;\n\n if (!configResult.found && !hasCheckTomlThreshold) {\n violations.push({\n rule: `${this.rule}.config`,\n tool: this.toolId,\n message: configResult.error ?? \"No coverage threshold configuration found\",\n severity: \"error\",\n });\n return;\n }\n\n // If tool config exists, validate its threshold meets the minimum\n if (\n configResult.found &&\n this.config.min_threshold !== undefined &&\n configResult.threshold !== undefined\n ) {\n if (configResult.threshold < this.config.min_threshold) {\n violations.push({\n rule: `${this.rule}.threshold`,\n tool: this.toolId,\n message: `Coverage threshold ${configResult.threshold}% is below minimum ${this.config.min_threshold}% (in ${configResult.file})`,\n severity: \"error\",\n });\n }\n }\n }\n\n /** Validate CI coverage and add violations if needed */\n private validateCiCoverage(projectRoot: string, violations: Violation[]): void {\n const ciResult = this.checkCiCoverage(projectRoot);\n\n if (!ciResult.found) {\n violations.push({\n rule: `${this.rule}.ci`,\n tool: this.toolId,\n message: ciResult.error ?? \"No coverage enforcement found in CI workflow\",\n severity: \"error\",\n });\n }\n }\n\n /** Run coverage validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const violations: Violation[] = [];\n const enforceIn = this.config.enforce_in ?? \"config\";\n\n if (enforceIn === \"config\" || enforceIn === \"both\") {\n this.validateConfigCoverage(projectRoot, violations);\n }\n\n if (enforceIn === \"ci\" || enforceIn === \"both\") {\n this.validateCiCoverage(projectRoot, violations);\n }\n\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\nimport { glob } from \"glob\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\nimport {\n type DocsConfig,\n type DocTypeConfig,\n escapeRegex,\n type ExportInfo,\n extractFileExports,\n getTrackedPath,\n type ParsedDoc,\n parseMarkdownFile,\n} from \"./docs-helpers.js\";\n\n/**\n * Documentation governance runner.\n * Validates documentation structure, content, freshness, and API coverage.\n */\nexport class DocsRunner extends BaseProcessToolRunner {\n readonly name = \"Documentation\";\n readonly rule = \"process.docs\";\n readonly toolId = \"docs\";\n\n private config: DocsConfig = {\n enabled: false,\n path: \"docs/\",\n enforcement: \"warn\",\n staleness_days: 30,\n };\n\n setConfig(config: DocsConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n private getSeverity(): \"error\" | \"warning\" {\n return this.config.enforcement === \"block\" ? \"error\" : \"warning\";\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const violations: Violation[] = [];\n violations.push(...(await this.checkStructure(projectRoot)));\n violations.push(...(await this.checkContent(projectRoot)));\n violations.push(...(await this.checkFreshness(projectRoot)));\n violations.push(...(await this.checkApiCoverage(projectRoot)));\n\n return this.fromViolations(violations, elapsed());\n }\n\n // ===========================================================================\n // Structure Enforcement\n // ===========================================================================\n\n private async checkStructure(projectRoot: string): Promise<Violation[]> {\n const docsPath = this.config.path ?? \"docs/\";\n const allowlist = new Set(this.config.allowlist ?? []);\n\n const allMdFiles = await glob(\"**/*.md\", {\n cwd: projectRoot,\n ignore: [\"node_modules/**\", \".git/**\", \"dist/**\", \".changeset/**\"],\n nodir: true,\n });\n\n const violations = this.checkAllowlist(allMdFiles, docsPath, allowlist);\n const docsFiles = allMdFiles.filter((f) => f.startsWith(docsPath));\n\n violations.push(...this.checkFileLimits(projectRoot, docsFiles));\n\n return violations;\n }\n\n private checkAllowlist(files: string[], docsPath: string, allowlist: Set<string>): Violation[] {\n const violations: Violation[] = [];\n for (const file of files) {\n const isInDocs = file.startsWith(docsPath);\n const isAllowlisted = allowlist.has(file) || allowlist.has(path.basename(file));\n if (!isInDocs && !isAllowlisted) {\n violations.push({\n rule: `${this.rule}.structure`,\n tool: this.toolId,\n file,\n message: `Markdown file outside ${docsPath} is not allowlisted`,\n severity: this.getSeverity(),\n });\n }\n }\n return violations;\n }\n\n private checkFileLimits(projectRoot: string, docsFiles: string[]): Violation[] {\n const violations: Violation[] = [];\n\n if (this.config.max_files !== undefined && docsFiles.length > this.config.max_files) {\n violations.push({\n rule: `${this.rule}.structure`,\n tool: this.toolId,\n message: `Documentation has ${docsFiles.length} files, max allowed is ${this.config.max_files}`,\n severity: this.getSeverity(),\n });\n }\n\n let totalKb = 0;\n for (const file of docsFiles) {\n const result = this.checkSingleFileLimit(projectRoot, file);\n totalKb += result.sizeKb;\n violations.push(...result.violations);\n }\n\n if (this.config.max_total_kb !== undefined && totalKb > this.config.max_total_kb) {\n violations.push({\n rule: `${this.rule}.structure`,\n tool: this.toolId,\n message: `Total docs size is ${totalKb.toFixed(1)}KB, max allowed is ${this.config.max_total_kb}KB`,\n severity: this.getSeverity(),\n });\n }\n\n return violations;\n }\n\n private checkSingleFileLimit(\n projectRoot: string,\n file: string\n ): { sizeKb: number; violations: Violation[] } {\n const violations: Violation[] = [];\n const fullPath = path.join(projectRoot, file);\n\n try {\n const stats = fs.statSync(fullPath);\n const sizeKb = stats.size / 1024;\n\n if (this.config.max_file_lines !== undefined) {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n const lineCount = content.split(\"\\n\").length;\n if (lineCount > this.config.max_file_lines) {\n violations.push({\n rule: `${this.rule}.structure`,\n tool: this.toolId,\n file,\n message: `File has ${lineCount} lines, max allowed is ${this.config.max_file_lines}`,\n severity: this.getSeverity(),\n });\n }\n }\n\n return { sizeKb, violations };\n } catch {\n return { sizeKb: 0, violations };\n }\n }\n\n // ===========================================================================\n // Content Validation\n // ===========================================================================\n\n private async checkContent(projectRoot: string): Promise<Violation[]> {\n const types = this.config.types ?? {};\n if (Object.keys(types).length === 0) {\n return [];\n }\n\n const docsPath = this.config.path ?? \"docs/\";\n const docsFiles = await glob(`${docsPath}**/*.md`, { cwd: projectRoot, nodir: true });\n const violations: Violation[] = [];\n\n for (const file of docsFiles) {\n violations.push(...this.validateDocFile(projectRoot, file, types));\n }\n\n return violations;\n }\n\n private validateDocFile(\n projectRoot: string,\n file: string,\n types: Record<string, DocTypeConfig>\n ): Violation[] {\n const parsed = this.parseDocFile(projectRoot, file);\n if (!parsed) {\n return [];\n }\n\n const violations: Violation[] = [];\n const docType = parsed.frontmatter.type as string | undefined;\n const typeConfig = docType ? types[docType] : undefined;\n\n if (typeConfig) {\n violations.push(\n ...this.validateFrontmatter(file, parsed.frontmatter, typeConfig.frontmatter ?? [])\n );\n violations.push(\n ...this.validateSections(file, parsed.headings, typeConfig.required_sections ?? [])\n );\n }\n\n violations.push(...this.validateInternalLinks(projectRoot, file, parsed.content));\n\n return violations;\n }\n\n private parseDocFile(projectRoot: string, filePath: string): ParsedDoc | null {\n const fullPath = path.join(projectRoot, filePath);\n try {\n const raw = fs.readFileSync(fullPath, \"utf-8\");\n return parseMarkdownFile(raw, filePath);\n } catch {\n return null;\n }\n }\n\n private validateFrontmatter(\n file: string,\n frontmatter: Record<string, unknown>,\n required: string[]\n ): Violation[] {\n return required\n .filter((field) => !(field in frontmatter))\n .map((field) => ({\n rule: `${this.rule}.content`,\n tool: this.toolId,\n file,\n message: `Missing required frontmatter field: ${field}`,\n severity: this.getSeverity(),\n }));\n }\n\n private validateSections(file: string, headings: string[], required: string[]): Violation[] {\n const headingSet = new Set(headings.map((h) => h.toLowerCase()));\n return required\n .filter((section) => !headingSet.has(section.toLowerCase()))\n .map((section) => ({\n rule: `${this.rule}.content`,\n tool: this.toolId,\n file,\n message: `Missing required section: ${section}`,\n severity: this.getSeverity(),\n }));\n }\n\n private validateInternalLinks(projectRoot: string, file: string, content: string): Violation[] {\n const violations: Violation[] = [];\n const linkRegex = /\\[([^\\]]+)\\]\\(([^)]+)\\)/g;\n let match;\n\n while ((match = linkRegex.exec(content)) !== null) {\n const violation = this.checkSingleLink(projectRoot, file, match[2]);\n if (violation) {\n violations.push(violation);\n }\n }\n\n return violations;\n }\n\n private checkSingleLink(projectRoot: string, file: string, linkTarget: string): Violation | null {\n if (\n linkTarget.startsWith(\"http\") ||\n linkTarget.startsWith(\"#\") ||\n linkTarget.startsWith(\"mailto:\")\n ) {\n return null;\n }\n\n const targetPath = linkTarget.split(\"#\")[0];\n if (!targetPath) {\n return null;\n }\n\n const resolvedPath = path.join(projectRoot, path.dirname(file), targetPath);\n if (!fs.existsSync(resolvedPath)) {\n return {\n rule: `${this.rule}.links`,\n tool: this.toolId,\n file,\n message: `Broken internal link: ${linkTarget}`,\n severity: \"warning\",\n };\n }\n\n return null;\n }\n\n // ===========================================================================\n // Freshness Tracking\n // ===========================================================================\n\n private async checkFreshness(projectRoot: string): Promise<Violation[]> {\n const docsPath = this.config.path ?? \"docs/\";\n const docsFiles = await glob(`${docsPath}**/*.md`, { cwd: projectRoot, nodir: true });\n\n const results = await Promise.all(\n docsFiles.map((file) => this.checkFileFreshness(projectRoot, file, docsPath))\n );\n\n return results.filter((v): v is Violation => v !== null);\n }\n\n private async getTimestamps(\n projectRoot: string,\n file: string,\n trackedPath: string\n ): Promise<{ docTime: number; sourceTime: number } | null> {\n const docTime = await this.getGitLastModified(projectRoot, file);\n const sourceTime = await this.getGitLastModified(projectRoot, trackedPath);\n if (docTime === null || sourceTime === null) {\n return null;\n }\n return { docTime, sourceTime };\n }\n\n private createStalenessViolation(file: string, daysDiff: number, trackedPath: string): Violation {\n return {\n rule: `${this.rule}.freshness`,\n tool: this.toolId,\n file,\n message: `Doc is ${Math.round(daysDiff)} days behind tracked source: ${trackedPath}`,\n severity: this.getSeverity(),\n };\n }\n\n private async checkFileFreshness(\n projectRoot: string,\n file: string,\n docsPath: string\n ): Promise<Violation | null> {\n const parsed = this.parseDocFile(projectRoot, file);\n if (!parsed) {\n return null;\n }\n\n const staleMappings = this.config.stale_mappings ?? {};\n const trackedPath = getTrackedPath(file, parsed.frontmatter, staleMappings, docsPath);\n if (!trackedPath || !fs.existsSync(path.join(projectRoot, trackedPath))) {\n return null;\n }\n\n const timestamps = await this.getTimestamps(projectRoot, file, trackedPath);\n if (!timestamps) {\n return null;\n }\n\n const stalenessDays = this.config.staleness_days ?? 30;\n const daysDiff = (timestamps.sourceTime - timestamps.docTime) / (1000 * 60 * 60 * 24);\n\n return daysDiff > stalenessDays\n ? this.createStalenessViolation(file, daysDiff, trackedPath)\n : null;\n }\n\n private async getGitLastModified(projectRoot: string, filePath: string): Promise<number | null> {\n try {\n const result = await execa(\"git\", [\"log\", \"-1\", \"--format=%ct\", \"--\", filePath], {\n cwd: projectRoot,\n });\n const timestamp = parseInt(result.stdout.trim(), 10);\n return isNaN(timestamp) ? null : timestamp * 1000;\n } catch {\n return null;\n }\n }\n\n // ===========================================================================\n // API Coverage\n // ===========================================================================\n\n private async checkApiCoverage(projectRoot: string): Promise<Violation[]> {\n const minCoverage = this.config.min_coverage;\n if (minCoverage === undefined) {\n return [];\n }\n\n const sourceFiles = await this.getSourceFiles(projectRoot);\n const exports = this.extractExports(projectRoot, sourceFiles);\n if (exports.length === 0) {\n return [];\n }\n\n const allDocsContent = await this.getAllDocsContent(projectRoot);\n const undocumented = exports.filter(\n (exp) => !this.isExportDocumented(exp.name, allDocsContent)\n );\n\n return this.buildCoverageViolations(exports.length, undocumented, minCoverage);\n }\n\n private async getSourceFiles(projectRoot: string): Promise<string[]> {\n const coveragePaths = this.config.coverage_paths ?? [\"src/**/*.ts\"];\n const excludePatterns = this.config.exclude_patterns ?? [\"**/*.test.ts\", \"**/*.spec.ts\"];\n\n const fileArrays = await Promise.all(\n coveragePaths.map((pattern) =>\n glob(pattern, {\n cwd: projectRoot,\n ignore: [\"node_modules/**\", ...excludePatterns],\n nodir: true,\n })\n )\n );\n\n return fileArrays.flat();\n }\n\n private async getAllDocsContent(projectRoot: string): Promise<string> {\n const docsPath = this.config.path ?? \"docs/\";\n const docsFiles = await glob(`${docsPath}**/*.md`, { cwd: projectRoot, nodir: true });\n\n return docsFiles.map((f) => this.readFile(projectRoot, f) ?? \"\").join(\"\\n\");\n }\n\n private isExportDocumented(exportName: string, docsContent: string): boolean {\n const regex = new RegExp(`\\\\b${escapeRegex(exportName)}\\\\b`);\n return regex.test(docsContent);\n }\n\n private buildCoverageViolations(\n totalExports: number,\n undocumented: ExportInfo[],\n minCoverage: number\n ): Violation[] {\n const documented = totalExports - undocumented.length;\n const coverage = (documented / totalExports) * 100;\n\n if (coverage >= minCoverage) {\n return [];\n }\n\n const violations: Violation[] = [\n {\n rule: `${this.rule}.coverage`,\n tool: this.toolId,\n message: `API documentation coverage is ${coverage.toFixed(1)}% (min: ${minCoverage}%). ${undocumented.length} undocumented exports.`,\n severity: this.getSeverity(),\n },\n ];\n\n const limit = 10;\n for (const exp of undocumented.slice(0, limit)) {\n violations.push({\n rule: `${this.rule}.coverage`,\n tool: this.toolId,\n file: exp.file,\n line: exp.line,\n message: `Export \"${exp.name}\" is not documented`,\n severity: \"warning\",\n });\n }\n\n if (undocumented.length > limit) {\n violations.push({\n rule: `${this.rule}.coverage`,\n tool: this.toolId,\n message: `...and ${undocumented.length - limit} more undocumented exports`,\n severity: \"warning\",\n });\n }\n\n return violations;\n }\n\n private extractExports(projectRoot: string, files: string[]): ExportInfo[] {\n const exports: ExportInfo[] = [];\n\n for (const file of files) {\n const content = this.readFile(projectRoot, file);\n if (!content) {\n continue;\n }\n exports.push(...extractFileExports(file, content));\n }\n\n return exports;\n }\n}\n","import matter from \"gray-matter\";\n\n/** Enforcement mode for documentation checks */\nexport type EnforcementMode = \"block\" | \"warn\";\n\n/** Doc type configuration */\nexport interface DocTypeConfig {\n required_sections?: string[];\n frontmatter?: string[];\n}\n\n/** Documentation configuration from standards.toml */\nexport interface DocsConfig {\n enabled?: boolean;\n path?: string;\n enforcement?: EnforcementMode;\n allowlist?: string[];\n max_files?: number;\n max_file_lines?: number;\n max_total_kb?: number;\n staleness_days?: number;\n stale_mappings?: Record<string, string>;\n min_coverage?: number;\n coverage_paths?: string[];\n exclude_patterns?: string[];\n types?: Record<string, DocTypeConfig>;\n}\n\n/** Parsed frontmatter from a markdown file */\nexport interface ParsedDoc {\n filePath: string;\n frontmatter: Record<string, unknown>;\n content: string;\n headings: string[];\n}\n\n/** Export info from TypeScript file */\nexport interface ExportInfo {\n name: string;\n file: string;\n line: number;\n}\n\n/** Escape special regex characters in a string */\nexport function escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/** Extract heading text from markdown content */\nfunction extractHeadings(content: string): string[] {\n const headingRegex = /^#{1,6}\\s+(.+)$/gm;\n const headings: string[] = [];\n let match;\n while ((match = headingRegex.exec(content)) !== null) {\n headings.push(match[1].trim());\n }\n return headings;\n}\n\n/** Parse named export from a line */\nfunction parseNamedExport(line: string): string | null {\n const match = /^export\\s+(?:const|let|var|function|class|interface|type|enum)\\s+(\\w+)/.exec(line);\n return match ? match[1] : null;\n}\n\n/** Parse default export from a line */\nfunction parseDefaultExport(line: string): string | null {\n const match = /^export\\s+default\\s+(\\w+)/.exec(line);\n if (match && ![\"function\", \"class\", \"async\"].includes(match[1])) {\n return match[1];\n }\n return null;\n}\n\n/** Parse re-exports from a line */\nfunction parseReExports(line: string): string[] {\n const match = /^export\\s*\\{\\s*([^}]+)\\s*\\}/.exec(line);\n if (!match) {\n return [];\n }\n return match[1]\n .split(\",\")\n .map((n) => {\n const parts = n.trim().split(/\\s+as\\s+/);\n return parts[parts.length - 1].trim();\n })\n .filter((name) => name && !/^(type|interface)$/.test(name));\n}\n\n/** Parse a markdown file and extract frontmatter, content, headings */\nexport function parseMarkdownFile(content: string, filePath: string): ParsedDoc {\n const { data, content: mdContent } = matter(content);\n return {\n filePath,\n frontmatter: data,\n content: mdContent,\n headings: extractHeadings(mdContent),\n };\n}\n\n/** Process a single line and extract any exports */\nfunction processLine(line: string, file: string, lineNumber: number): ExportInfo[] {\n const named = parseNamedExport(line);\n if (named) {\n return [{ name: named, file, line: lineNumber }];\n }\n\n const defaultExp = parseDefaultExport(line);\n if (defaultExp) {\n return [{ name: defaultExp, file, line: lineNumber }];\n }\n\n return parseReExports(line).map((name) => ({ name, file, line: lineNumber }));\n}\n\n/** Extract exports from file content */\nexport function extractFileExports(file: string, content: string): ExportInfo[] {\n return content.split(\"\\n\").flatMap((line, i) => processLine(line, file, i + 1));\n}\n\n/** Get the source path that a doc file tracks */\nexport function getTrackedPath(\n docFile: string,\n frontmatter: Record<string, unknown>,\n staleMappings: Record<string, string>,\n docsPath: string\n): string | null {\n if (typeof frontmatter.tracks === \"string\") {\n return frontmatter.tracks;\n }\n if (Array.isArray(frontmatter.tracks) && frontmatter.tracks.length > 0) {\n return frontmatter.tracks[0] as string;\n }\n if (staleMappings[docFile]) {\n return staleMappings[docFile];\n }\n if (docFile.startsWith(docsPath)) {\n const baseName = docFile.slice(docsPath.length).replace(/\\.md$/, \"\");\n return `src/${baseName}/`;\n }\n return null;\n}\n","import { glob } from \"glob\";\n\nimport { DEFAULT_FORBIDDEN_FILES_IGNORE } from \"../../core/index.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Forbidden files configuration */\ninterface ForbiddenFilesConfig {\n enabled?: boolean;\n files?: string[];\n ignore?: string[];\n message?: string;\n}\n\n/**\n * Runner for forbidden files validation.\n * Validates that certain files do NOT exist anywhere in the repository.\n */\nexport class ForbiddenFilesRunner extends BaseProcessToolRunner {\n readonly name = \"Forbidden Files\";\n readonly rule = \"process.forbidden_files\";\n readonly toolId = \"forbidden-files\";\n\n private config: ForbiddenFilesConfig = { enabled: false };\n\n setConfig(config: ForbiddenFilesConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Run check - scans for forbidden files using glob patterns\n */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const patterns = this.config.files ?? [];\n if (patterns.length === 0) {\n return this.pass(elapsed());\n }\n\n // Process all patterns in parallel for better performance\n const results = await Promise.all(\n patterns.map(async (pattern) => {\n const foundFiles = await this.findForbiddenFiles(projectRoot, pattern);\n return foundFiles.map((file) => this.createViolation(file, pattern));\n })\n );\n\n // Deduplicate violations by file path (fix #181)\n // Keep only the first violation for each file\n const allViolations = results.flat();\n const seenFiles = new Set<string>();\n const violations: Violation[] = [];\n for (const violation of allViolations) {\n if (violation.file && !seenFiles.has(violation.file)) {\n seenFiles.add(violation.file);\n violations.push(violation);\n }\n }\n\n return this.fromViolations(violations, elapsed());\n }\n\n /**\n * Find files matching a forbidden pattern\n */\n private async findForbiddenFiles(projectRoot: string, pattern: string): Promise<string[]> {\n // Determine ignore patterns:\n // - If ignore is explicitly set (including empty array), use it (fix #185)\n // - If ignore is undefined (not set), use defaults\n const ignorePatterns = this.getIgnorePatterns();\n\n try {\n const matches = await glob(pattern, {\n cwd: projectRoot,\n dot: true,\n nodir: true,\n ignore: ignorePatterns,\n });\n return matches;\n } catch {\n return [];\n }\n }\n\n /**\n * Get ignore patterns, respecting explicit empty array override\n * - undefined: use defaults (node_modules, .git)\n * - []: no ignores (scan everything)\n * - [...]: use custom ignores\n */\n private getIgnorePatterns(): string[] {\n // Check if ignore was explicitly set (including empty array)\n // Object.hasOwn checks if the property exists, even if value is []\n if (Object.hasOwn(this.config, \"ignore\") && this.config.ignore !== undefined) {\n return this.config.ignore;\n }\n return DEFAULT_FORBIDDEN_FILES_IGNORE;\n }\n\n /**\n * Create a violation for a forbidden file\n */\n private createViolation(file: string, pattern: string): Violation {\n const customMessage = this.config.message;\n const baseMessage = `Forbidden file exists: ${file} (matched pattern: ${pattern})`;\n const message = customMessage ? `${baseMessage}. ${customMessage}` : baseMessage;\n\n return {\n rule: `${this.rule}.exists`,\n tool: this.toolId,\n file,\n message,\n severity: \"error\",\n };\n }\n}\n","import { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Hooks configuration from standards.toml */\ninterface HooksConfig {\n enabled?: boolean;\n require_husky?: boolean;\n require_hooks?: string[];\n commands?: Record<string, string[]>;\n protected_branches?: string[];\n}\n\n/**\n * Git hooks validation runner.\n * Checks that husky is installed and required hooks are configured.\n */\nexport class HooksRunner extends BaseProcessToolRunner {\n readonly name = \"Hooks\";\n readonly rule = \"process.hooks\";\n readonly toolId = \"hooks\";\n\n private config: HooksConfig = {\n enabled: false,\n require_husky: true,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: HooksConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Check if husky is installed */\n private checkHuskyInstalled(projectRoot: string): Violation | null {\n if (this.config.require_husky === false) {\n return null;\n }\n if (this.directoryExists(projectRoot, \".husky\")) {\n return null;\n }\n return {\n rule: `${this.rule}.husky`,\n tool: this.toolId,\n message: \"Husky not installed (.husky/ directory not found)\",\n severity: \"error\",\n };\n }\n\n /** Check that required hooks exist */\n private checkRequiredHooks(projectRoot: string): Violation[] {\n const hooks = this.config.require_hooks ?? [];\n return hooks\n .filter((hook) => !this.fileExists(projectRoot, `.husky/${hook}`))\n .map((hook) => ({\n rule: `${this.rule}.${hook}`,\n tool: this.toolId,\n file: `.husky/${hook}`,\n message: `Required hook '${hook}' not found`,\n severity: \"error\" as const,\n }));\n }\n\n /** Check that hooks contain required commands */\n private checkHookCommands(projectRoot: string): Violation[] {\n const commands = this.config.commands ?? {};\n const violations: Violation[] = [];\n\n for (const [hook, requiredCommands] of Object.entries(commands)) {\n const hookPath = `.husky/${hook}`;\n if (!this.fileExists(projectRoot, hookPath)) {\n continue;\n }\n for (const command of requiredCommands) {\n if (!this.fileContains(projectRoot, hookPath, command)) {\n violations.push({\n rule: `${this.rule}.${hook}.commands`,\n tool: this.toolId,\n file: hookPath,\n message: `Hook '${hook}' does not contain required command: ${command}`,\n severity: \"error\",\n });\n }\n }\n }\n return violations;\n }\n\n /** Create a pre-push hook violation */\n private createPrePushViolation(ruleId: string, message: string): Violation {\n return {\n rule: `${this.rule}.${ruleId}`,\n tool: this.toolId,\n file: \".husky/pre-push\",\n message,\n severity: \"error\",\n };\n }\n\n /** Check if pre-push hook has branch detection */\n private hasBranchDetection(projectRoot: string): boolean {\n const branchDetectionPatterns = [\n \"git rev-parse --abbrev-ref HEAD\",\n \"git branch --show-current\",\n \"git symbolic-ref --short HEAD\",\n ];\n const hookPath = \".husky/pre-push\";\n return branchDetectionPatterns.some((pattern) =>\n this.fileContains(projectRoot, hookPath, pattern)\n );\n }\n\n /** Check that pre-push hook prevents direct pushes to protected branches */\n private checkProtectedBranches(projectRoot: string): Violation[] {\n const protectedBranches = this.config.protected_branches ?? [];\n if (protectedBranches.length === 0) {\n return [];\n }\n\n const hookPath = \".husky/pre-push\";\n\n // First check if pre-push hook exists\n if (!this.fileExists(projectRoot, hookPath)) {\n return [\n this.createPrePushViolation(\n \"pre-push\",\n \"Pre-push hook not found. Required for protected branch enforcement.\"\n ),\n ];\n }\n\n // Check for branch detection pattern\n if (!this.hasBranchDetection(projectRoot)) {\n return [\n this.createPrePushViolation(\n \"pre-push.branch-detection\",\n \"Pre-push hook does not detect current branch. Expected one of: git rev-parse --abbrev-ref HEAD, git branch --show-current\"\n ),\n ];\n }\n\n // Check that each protected branch is referenced in the hook\n return protectedBranches\n .filter((branch) => !this.fileContains(projectRoot, hookPath, branch))\n .map((branch) =>\n this.createPrePushViolation(\n \"pre-push.protected-branch\",\n `Pre-push hook does not check for protected branch \"${branch}\"`\n )\n );\n }\n\n /** Run hooks validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n // Check husky first - if not installed, can't check hooks\n const huskyViolation = this.checkHuskyInstalled(projectRoot);\n if (huskyViolation) {\n return this.fromViolations([huskyViolation], elapsed());\n }\n\n const violations = [\n ...this.checkRequiredHooks(projectRoot),\n ...this.checkHookCommands(projectRoot),\n ...this.checkProtectedBranches(projectRoot),\n ];\n\n return this.fromViolations(violations, elapsed());\n }\n}\n","import * as fs from \"node:fs\";\n\nimport { minimatch } from \"minimatch\";\n\nimport { GITHUB_API } from \"../../constants.js\";\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** PR configuration from standards.toml */\ninterface PrConfig {\n enabled?: boolean;\n max_files?: number;\n max_lines?: number;\n require_issue?: boolean;\n issue_keywords?: string[];\n exclude?: string[];\n}\n\n/** Default keywords that link PRs to issues */\nconst DEFAULT_ISSUE_KEYWORDS = [\"Closes\", \"Fixes\", \"Resolves\"];\n\n/** GitHub PR event payload structure (partial) */\ninterface GitHubPrEventPayload {\n pull_request?: {\n number?: number;\n changed_files?: number;\n additions?: number;\n deletions?: number;\n title?: string;\n body?: string;\n };\n repository?: {\n full_name?: string;\n };\n}\n\n/** GitHub PR file from API response */\ninterface GitHubPrFile {\n filename: string;\n additions: number;\n deletions: number;\n}\n\n/**\n * PR size validation runner.\n * Checks that the PR does not exceed configured size limits.\n * Reads PR data from GITHUB_EVENT_PATH environment variable (GitHub Actions context).\n */\nexport class PrRunner extends BaseProcessToolRunner {\n readonly name = \"PR\";\n readonly rule = \"process.pr\";\n readonly toolId = \"pr\";\n\n private config: PrConfig = {\n enabled: false,\n require_issue: false,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: PrConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Read PR data from GitHub event payload */\n private readPrEventPayload(): GitHubPrEventPayload | null {\n const eventPath = process.env.GITHUB_EVENT_PATH;\n if (!eventPath) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(eventPath, \"utf-8\");\n return JSON.parse(content) as GitHubPrEventPayload;\n } catch {\n return null;\n }\n }\n\n /** Get PR data from payload, returns null if not available */\n private getPrData(\n payload: GitHubPrEventPayload | null\n ): GitHubPrEventPayload[\"pull_request\"] | null {\n return payload?.pull_request ?? null;\n }\n\n /** Fetch a single page of PR files from GitHub API */\n private async fetchPrFilesPage(\n repo: string,\n prNumber: number,\n page: number,\n token: string\n ): Promise<GitHubPrFile[] | null> {\n const response = await fetch(\n `${GITHUB_API.baseUrl}/repos/${repo}/pulls/${prNumber}/files?per_page=${GITHUB_API.perPage}&page=${page}`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: \"application/vnd.github.v3+json\",\n },\n }\n );\n return response.ok ? ((await response.json()) as GitHubPrFile[]) : null;\n }\n\n /**\n * Fetch PR files from GitHub API with pagination support.\n * Returns empty array if GITHUB_TOKEN is not available or API fails.\n */\n private async fetchPrFiles(repo: string, prNumber: number): Promise<GitHubPrFile[]> {\n const token = process.env.GITHUB_TOKEN;\n if (!token) {\n return [];\n }\n\n const fetchPage = async (\n page: number,\n accumulated: GitHubPrFile[]\n ): Promise<GitHubPrFile[]> => {\n const pageFiles = await this.fetchPrFilesPage(repo, prNumber, page, token);\n if (!pageFiles) {\n return [];\n }\n const allFiles = [...accumulated, ...pageFiles];\n return pageFiles.length < 100 ? allFiles : fetchPage(page + 1, allFiles);\n };\n\n try {\n return await fetchPage(1, []);\n } catch {\n return [];\n }\n }\n\n /**\n * Filter files that match exclude patterns.\n * Returns only files that do NOT match any exclude pattern.\n */\n private filterExcludedFiles(files: GitHubPrFile[], excludePatterns: string[]): GitHubPrFile[] {\n if (excludePatterns.length === 0) {\n return files;\n }\n\n return files.filter(\n (file) => !excludePatterns.some((pattern) => minimatch(file.filename, pattern))\n );\n }\n\n /** Check if any validation is configured */\n private hasValidationConfigured(): boolean {\n return (\n this.config.max_files !== undefined ||\n this.config.max_lines !== undefined ||\n this.config.require_issue === true\n );\n }\n\n /** Check if PR body contains issue reference with keyword */\n private findIssueReference(text: string | undefined): string | null {\n if (!text) {\n return null;\n }\n\n const keywords = this.config.issue_keywords ?? DEFAULT_ISSUE_KEYWORDS;\n // Build pattern: \\b(Closes|Fixes|Resolves)\\s+#(\\d+)\n // Word boundary \\b prevents matching \"Closes\" in \"ClosesFile\"\n const keywordPattern = keywords.map((k) => k.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")).join(\"|\");\n const regex = new RegExp(`\\\\b(?:${keywordPattern})\\\\s+#(\\\\d+)`, \"i\");\n const match = text.match(regex);\n return match ? match[1] : null;\n }\n\n /** Validate that PR contains issue reference */\n private validateIssueReference(pr: NonNullable<GitHubPrEventPayload[\"pull_request\"]>): {\n passed: boolean;\n error?: string;\n } {\n if (!this.config.require_issue) {\n return { passed: true };\n }\n\n // Check body first (primary location for issue links)\n const bodyIssue = this.findIssueReference(pr.body);\n if (bodyIssue) {\n return { passed: true };\n }\n\n // Also check title as fallback\n const titleIssue = this.findIssueReference(pr.title);\n if (titleIssue) {\n return { passed: true };\n }\n\n const keywords = this.config.issue_keywords ?? DEFAULT_ISSUE_KEYWORDS;\n return {\n passed: false,\n error: `PR does not contain issue reference. Include \"${keywords[0]} #<issue-number>\" in the PR description.`,\n };\n }\n\n /** Get PR counts, applying exclusions if configured */\n private async getPrCounts(\n pr: NonNullable<GitHubPrEventPayload[\"pull_request\"]>,\n repo: string | undefined\n ): Promise<{ fileCount: number; lineCount: number }> {\n const defaultCounts = {\n fileCount: pr.changed_files ?? 0,\n lineCount: (pr.additions ?? 0) + (pr.deletions ?? 0),\n };\n\n if (!this.config.exclude?.length || !repo || !pr.number) {\n return defaultCounts;\n }\n\n const files = await this.fetchPrFiles(repo, pr.number);\n if (files.length === 0) {\n return defaultCounts; // API failed, fall back\n }\n\n const filtered = this.filterExcludedFiles(files, this.config.exclude);\n return {\n fileCount: filtered.length,\n lineCount: filtered.reduce((sum, f) => sum + f.additions + f.deletions, 0),\n };\n }\n\n /** Check size limits and return violations */\n private checkSizeLimits(fileCount: number, lineCount: number): Violation[] {\n const violations: Violation[] = [];\n\n if (this.config.max_files !== undefined && fileCount > this.config.max_files) {\n violations.push({\n rule: `${this.rule}.max_files`,\n tool: this.toolId,\n message: `PR has ${fileCount} files changed (max: ${this.config.max_files})`,\n severity: \"error\",\n });\n }\n\n if (this.config.max_lines !== undefined && lineCount > this.config.max_lines) {\n violations.push({\n rule: `${this.rule}.max_lines`,\n tool: this.toolId,\n message: `PR has ${lineCount} lines changed (max: ${this.config.max_lines})`,\n severity: \"error\",\n });\n }\n\n return violations;\n }\n\n /** Validate PR size against configured limits */\n private async validatePrSize(\n pr: NonNullable<GitHubPrEventPayload[\"pull_request\"]>,\n repo: string | undefined,\n elapsed: () => number\n ): Promise<CheckResult> {\n const { fileCount, lineCount } = await this.getPrCounts(pr, repo);\n const violations = this.checkSizeLimits(fileCount, lineCount);\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n\n /** Collect all violations from PR validations */\n private async collectViolations(\n prData: NonNullable<GitHubPrEventPayload[\"pull_request\"]>,\n repo: string | undefined,\n elapsed: () => number\n ): Promise<Violation[]> {\n const violations: Violation[] = [];\n\n const sizeResult = await this.validatePrSize(prData, repo, elapsed);\n if (!sizeResult.passed) {\n violations.push(...sizeResult.violations);\n }\n\n const issueResult = this.validateIssueReference(prData);\n if (!issueResult.passed && issueResult.error) {\n violations.push({\n rule: `${this.rule}.require_issue`,\n tool: this.toolId,\n message: issueResult.error,\n severity: \"error\",\n });\n }\n\n return violations;\n }\n\n /** Run PR validation */\n async run(_projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!this.hasValidationConfigured()) {\n return this.skip(\"No PR validation configured\", elapsed());\n }\n\n const payload = this.readPrEventPayload();\n const prData = this.getPrData(payload);\n if (!prData) {\n return this.skip(\"Not in a PR context (GITHUB_EVENT_PATH not set or no PR data)\", elapsed());\n }\n\n const repo = payload?.repository?.full_name;\n const violations = await this.collectViolations(prData, repo, elapsed);\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n}\n"," \nimport { execa } from \"execa\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Bypass actor configuration */\ninterface BypassActorConfig {\n actor_type: \"Integration\" | \"OrganizationAdmin\" | \"RepositoryRole\" | \"Team\" | \"DeployKey\";\n actor_id?: number;\n bypass_mode?: \"always\" | \"pull_request\";\n}\n\n/** Ruleset configuration (uses GitHub Rulesets API) */\ninterface RulesetConfig {\n name?: string;\n branch?: string;\n enforcement?: \"active\" | \"evaluate\" | \"disabled\";\n required_reviews?: number;\n dismiss_stale_reviews?: boolean;\n require_code_owner_reviews?: boolean;\n require_status_checks?: string[];\n require_branches_up_to_date?: boolean;\n require_signed_commits?: boolean;\n enforce_admins?: boolean;\n bypass_actors?: BypassActorConfig[];\n}\n\n/** Tag protection configuration */\ninterface TagProtectionConfig {\n patterns?: string[];\n prevent_deletion?: boolean;\n prevent_update?: boolean;\n}\n\n/** Repository configuration */\ninterface RepoConfig {\n enabled?: boolean;\n require_branch_protection?: boolean;\n require_codeowners?: boolean;\n ruleset?: RulesetConfig;\n tag_protection?: TagProtectionConfig;\n}\n\n/** GitHub Ruleset bypass actor */\ninterface RulesetBypassActor {\n actor_id: number | null;\n actor_type: string;\n bypass_mode: string;\n}\n\n/** GitHub Ruleset rule */\ninterface RulesetRule {\n type: string;\n parameters?: {\n required_approving_review_count?: number;\n dismiss_stale_reviews_on_push?: boolean;\n require_code_owner_review?: boolean;\n required_status_checks?: { context: string }[];\n strict_required_status_checks_policy?: boolean;\n };\n}\n\n/** GitHub Ruleset response */\ninterface RulesetResponse {\n id: number;\n name: string;\n target: string;\n enforcement: string;\n conditions?: { ref_name?: { include?: string[]; exclude?: string[] } };\n bypass_actors?: RulesetBypassActor[];\n rules?: RulesetRule[];\n}\n\n/** Runner for repository settings validation */\nexport class RepoRunner extends BaseProcessToolRunner {\n readonly name = \"Repository\";\n readonly rule = \"process.repo\";\n readonly toolId = \"repo\";\n private config: RepoConfig = {\n enabled: false,\n require_branch_protection: false,\n require_codeowners: false,\n };\n\n setConfig(config: RepoConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n if (!(await this.isGhCliAvailable())) {\n return this.skip(\"GitHub CLI (gh) not available\", elapsed());\n }\n const repoInfo = await this.getRepoInfo(projectRoot);\n if (!repoInfo) {\n return this.skip(\"Could not determine GitHub repository from git remote\", elapsed());\n }\n\n const violations = await this.collectViolations(projectRoot, repoInfo);\n return this.fromViolations(violations, elapsed());\n }\n\n private async collectViolations(\n projectRoot: string,\n repoInfo: { owner: string; repo: string }\n ): Promise<Violation[]> {\n const violations: Violation[] = [];\n if (this.config.require_codeowners) {\n violations.push(...this.checkCodeowners(projectRoot));\n }\n if (this.config.require_branch_protection || this.config.ruleset) {\n violations.push(...(await this.checkBranchProtection(repoInfo)));\n }\n if (this.config.tag_protection?.patterns?.length) {\n violations.push(...(await this.checkTagProtection(repoInfo)));\n }\n return violations;\n }\n\n private async isGhCliAvailable(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n }\n\n private async getRepoInfo(projectRoot: string): Promise<{ owner: string; repo: string } | null> {\n try {\n // Use gh to get the current repo\n const result = await execa(\"gh\", [\"repo\", \"view\", \"--json\", \"owner,name\"], {\n cwd: projectRoot,\n });\n const data = JSON.parse(result.stdout) as { owner: { login: string }; name: string };\n return { owner: data.owner.login, repo: data.name };\n } catch {\n return null;\n }\n }\n\n private checkCodeowners(projectRoot: string): Violation[] {\n const locations = [\"CODEOWNERS\", \".github/CODEOWNERS\", \"docs/CODEOWNERS\"];\n if (locations.some((loc) => this.fileExists(projectRoot, loc))) {\n return [];\n }\n return [\n {\n rule: `${this.rule}.codeowners`,\n tool: this.toolId,\n severity: \"error\",\n message:\n \"CODEOWNERS file not found (checked CODEOWNERS, .github/CODEOWNERS, docs/CODEOWNERS)\",\n },\n ];\n }\n\n private async checkBranchProtection(repoInfo: {\n owner: string;\n repo: string;\n }): Promise<Violation[]> {\n const rulesetConfig = this.config.ruleset;\n const branch = rulesetConfig?.branch ?? \"main\";\n\n try {\n const result = await execa(\"gh\", [\n \"api\",\n `repos/${repoInfo.owner}/${repoInfo.repo}/rulesets`,\n ]);\n\n const rulesets = JSON.parse(result.stdout) as RulesetResponse[];\n const branchRuleset = this.findBranchRuleset(rulesets, branch);\n\n if (!branchRuleset) {\n return this.handleNoBranchRuleset(branch);\n }\n\n return this.validateBranchRulesetSettings(branchRuleset, branch);\n } catch (error) {\n return this.handleBranchProtectionError(error, branch);\n }\n }\n\n private findBranchRuleset(\n rulesets: RulesetResponse[],\n branch: string\n ): RulesetResponse | undefined {\n return rulesets.find(\n (r) =>\n r.target === \"branch\" &&\n r.enforcement === \"active\" &&\n this.matchesBranch(r.conditions?.ref_name?.include ?? [], branch)\n );\n }\n\n private matchesBranch(patterns: string[], branch: string): boolean {\n for (const pattern of patterns) {\n const cleanPattern = pattern.replace(/^refs\\/heads\\//, \"\");\n if (cleanPattern === branch) {\n return true;\n }\n if (cleanPattern === \"~DEFAULT_BRANCH\" && branch === \"main\") {\n return true;\n }\n if (cleanPattern === \"~ALL\") {\n return true;\n }\n if (cleanPattern.includes(\"*\")) {\n const regex = new RegExp(`^${cleanPattern.replace(/\\*/g, \".*\")}$`);\n if (regex.test(branch)) {\n return true;\n }\n }\n }\n return false;\n }\n\n private handleNoBranchRuleset(branch: string): Violation[] {\n if (this.config.require_branch_protection) {\n return [\n {\n rule: `${this.rule}.branch_protection`,\n tool: this.toolId,\n message: `Branch '${branch}' does not have a branch protection ruleset`,\n severity: \"error\",\n },\n ];\n }\n return [];\n }\n\n private handleBranchProtectionError(error: unknown, branch: string): Violation[] {\n const msg = error instanceof Error ? error.message : String(error);\n const v = (message: string, severity: \"error\" | \"warning\" = \"error\"): Violation[] => [\n { rule: `${this.rule}.branch_protection`, tool: this.toolId, message, severity },\n ];\n if (msg.includes(\"404\")) {\n return this.config.require_branch_protection\n ? v(`Branch '${branch}' does not have branch protection enabled`)\n : [];\n }\n if (msg.includes(\"403\") || msg.includes(\"Must have admin rights\")) {\n return v(\n \"Cannot check branch protection: insufficient permissions (requires admin access)\",\n \"warning\"\n );\n }\n return v(`Failed to check branch protection: ${msg}`);\n }\n\n private validateBranchRulesetSettings(ruleset: RulesetResponse, branch: string): Violation[] {\n const bpConfig = this.config.ruleset;\n if (!bpConfig) {\n return [];\n }\n\n const violations: Violation[] = [];\n const rules = ruleset.rules ?? [];\n\n const prRule = rules.find((r) => r.type === \"pull_request\");\n violations.push(...this.checkPullRequestRuleSettings(prRule, bpConfig, branch));\n\n const statusRule = rules.find((r) => r.type === \"required_status_checks\");\n violations.push(...this.checkStatusChecksRuleSettings(statusRule, bpConfig, branch));\n\n if (bpConfig.require_signed_commits === true) {\n if (!rules.some((r) => r.type === \"required_signatures\")) {\n violations.push({\n rule: `${this.rule}.branch_protection.require_signed_commits`,\n tool: this.toolId,\n message: `Branch '${branch}' does not require signed commits`,\n severity: \"error\",\n });\n }\n }\n\n violations.push(...this.checkBypassActorsSettings(ruleset, bpConfig, branch));\n\n return violations;\n }\n\n \n private checkPullRequestRuleSettings(\n prRule: RulesetRule | undefined,\n bpConfig: RulesetConfig,\n branch: string\n ): Violation[] {\n const violations: Violation[] = [];\n const params = prRule?.parameters;\n\n if (bpConfig.required_reviews !== undefined) {\n const actualReviews = params?.required_approving_review_count ?? 0;\n if (actualReviews < bpConfig.required_reviews) {\n violations.push({\n rule: `${this.rule}.branch_protection.required_reviews`,\n tool: this.toolId,\n message: `Branch '${branch}' requires ${actualReviews} reviews, expected at least ${bpConfig.required_reviews}`,\n severity: \"error\",\n });\n }\n }\n\n if (bpConfig.dismiss_stale_reviews === true) {\n if (!(params?.dismiss_stale_reviews_on_push ?? false)) {\n violations.push({\n rule: `${this.rule}.branch_protection.dismiss_stale_reviews`,\n tool: this.toolId,\n message: `Branch '${branch}' does not dismiss stale reviews on new commits`,\n severity: \"error\",\n });\n }\n }\n\n if (bpConfig.require_code_owner_reviews === true) {\n if (!(params?.require_code_owner_review ?? false)) {\n violations.push({\n rule: `${this.rule}.branch_protection.require_code_owner_reviews`,\n tool: this.toolId,\n message: `Branch '${branch}' does not require code owner reviews`,\n severity: \"error\",\n });\n }\n }\n\n return violations;\n }\n\n \n private checkStatusChecksRuleSettings(\n statusRule: RulesetRule | undefined,\n bpConfig: RulesetConfig,\n branch: string\n ): Violation[] {\n const violations: Violation[] = [];\n const params = statusRule?.parameters;\n\n if (bpConfig.require_status_checks && bpConfig.require_status_checks.length > 0) {\n const actualChecks = params?.required_status_checks?.map((c) => c.context) ?? [];\n const missingChecks = bpConfig.require_status_checks.filter(\n (check) => !actualChecks.includes(check)\n );\n if (missingChecks.length > 0) {\n violations.push({\n rule: `${this.rule}.branch_protection.require_status_checks`,\n tool: this.toolId,\n message: `Branch '${branch}' missing required status checks: ${missingChecks.join(\", \")}`,\n severity: \"error\",\n });\n }\n }\n\n if (bpConfig.require_branches_up_to_date === true) {\n if (!(params?.strict_required_status_checks_policy ?? false)) {\n violations.push({\n rule: `${this.rule}.branch_protection.require_branches_up_to_date`,\n tool: this.toolId,\n message: `Branch '${branch}' does not require branches to be up to date before merging`,\n severity: \"error\",\n });\n }\n }\n\n return violations;\n }\n\n private checkBypassActorsSettings(\n ruleset: RulesetResponse,\n bpConfig: RulesetConfig,\n branch: string\n ): Violation[] {\n const violations: Violation[] = [];\n const actualBypass = ruleset.bypass_actors ?? [];\n\n // enforce_admins means no bypass actors should be configured\n if (bpConfig.enforce_admins === true && actualBypass.length > 0) {\n violations.push({\n rule: `${this.rule}.branch_protection.enforce_admins`,\n tool: this.toolId,\n message: `Branch '${branch}' has bypass actors configured but enforce_admins requires no bypasses`,\n severity: \"error\",\n });\n }\n\n // Check if configured bypass actors are present\n if (bpConfig.bypass_actors && bpConfig.bypass_actors.length > 0) {\n for (const expected of bpConfig.bypass_actors) {\n const found = actualBypass.some(\n (a) =>\n a.actor_type === expected.actor_type &&\n (expected.actor_id === undefined || a.actor_id === expected.actor_id)\n );\n if (!found) {\n violations.push({\n rule: `${this.rule}.branch_protection.bypass_actors`,\n tool: this.toolId,\n message: `Branch '${branch}' missing bypass actor: ${expected.actor_type}${expected.actor_id ? ` (id: ${expected.actor_id})` : \"\"}`,\n severity: \"error\",\n });\n }\n }\n }\n\n return violations;\n }\n\n // ===========================================================================\n // Tag Protection\n // ===========================================================================\n\n private async checkTagProtection(repoInfo: {\n owner: string;\n repo: string;\n }): Promise<Violation[]> {\n try {\n const result = await execa(\"gh\", [\n \"api\",\n `repos/${repoInfo.owner}/${repoInfo.repo}/rulesets`,\n ]);\n\n const rulesets = JSON.parse(result.stdout) as RulesetResponse[];\n return this.validateTagProtection(rulesets);\n } catch (error) {\n return this.handleTagProtectionError(error);\n }\n }\n\n private validateTagProtection(rulesets: RulesetResponse[]): Violation[] {\n const cfg = this.config.tag_protection;\n if (!cfg?.patterns?.length) {\n return [];\n }\n const ruleset = rulesets.find((r) => r.target === \"tag\" && r.enforcement === \"active\");\n if (!ruleset) {\n return [this.tagViolation(\"tag_protection\", \"No active tag protection ruleset found\")];\n }\n return [\n ...this.checkTagPatterns(cfg.patterns, ruleset.conditions?.ref_name?.include ?? []),\n ...this.checkTagRules(cfg, ruleset.rules ?? []),\n ];\n }\n\n private checkTagPatterns(expected: string[], actual: string[]): Violation[] {\n const exp = expected.map((p) => `refs/tags/${p}`).sort();\n const act = [...actual].sort();\n if (exp.length === act.length && exp.every((v, i) => v === act[i])) {\n return [];\n }\n const found = act.map((p) => p.replace(/^refs\\/tags\\//, \"\")).join(\", \");\n return [\n this.tagViolation(\n \"tag_protection.patterns\",\n `Tag protection patterns mismatch: expected [${expected.join(\", \")}], found [${found}]`\n ),\n ];\n }\n\n private checkTagRules(cfg: TagProtectionConfig, rules: { type: string }[]): Violation[] {\n const v: Violation[] = [];\n if (cfg.prevent_deletion !== false && !rules.some((r) => r.type === \"deletion\")) {\n v.push(\n this.tagViolation(\n \"tag_protection.prevent_deletion\",\n \"Tag protection does not prevent deletion\"\n )\n );\n }\n if (cfg.prevent_update !== false && !rules.some((r) => r.type === \"update\")) {\n v.push(\n this.tagViolation(\n \"tag_protection.prevent_update\",\n \"Tag protection does not prevent updates (force-push)\"\n )\n );\n }\n return v;\n }\n\n private tagViolation(\n rule: string,\n message: string,\n severity: \"error\" | \"warning\" = \"error\"\n ): Violation {\n return { rule: `${this.rule}.${rule}`, tool: this.toolId, message, severity };\n }\n\n private handleTagProtectionError(error: unknown): Violation[] {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes(\"403\") || msg.includes(\"Must have admin rights\")) {\n return [\n this.tagViolation(\n \"tag_protection\",\n \"Cannot check tag protection: insufficient permissions (requires admin access)\",\n \"warning\"\n ),\n ];\n }\n return [this.tagViolation(\"tag_protection\", `Failed to check tag protection: ${msg}`)];\n }\n}\n","import { execa } from \"execa\";\n\nimport { type CheckResult, type Violation } from \"../../core/index.js\";\nimport { BaseProcessToolRunner } from \"./base.js\";\n\n/** Tickets configuration from standards.toml */\ninterface TicketsConfig {\n enabled?: boolean;\n pattern?: string;\n require_in_commits?: boolean;\n require_in_branch?: boolean;\n}\n\n/**\n * Ticket reference validation runner.\n * Checks that commit messages and/or branch names contain ticket references.\n */\nexport class TicketsRunner extends BaseProcessToolRunner {\n readonly name = \"Tickets\";\n readonly rule = \"process.tickets\";\n readonly toolId = \"tickets\";\n\n private config: TicketsConfig = {\n enabled: false,\n require_in_commits: true,\n require_in_branch: false,\n };\n\n /**\n * Set configuration from standards.toml\n */\n setConfig(config: TicketsConfig): void {\n this.config = { ...this.config, ...config };\n }\n\n /** Get the current git branch name */\n private async getCurrentBranch(projectRoot: string): Promise<string | null> {\n try {\n const result = await execa(\"git\", [\"branch\", \"--show-current\"], {\n cwd: projectRoot,\n });\n return result.stdout.trim() || null;\n } catch {\n return null;\n }\n }\n\n /** Get the HEAD commit message */\n private async getHeadCommitMessage(projectRoot: string): Promise<string | null> {\n try {\n const result = await execa(\"git\", [\"log\", \"-1\", \"--format=%s\"], {\n cwd: projectRoot,\n });\n return result.stdout.trim() || null;\n } catch {\n return null;\n }\n }\n\n /** Check if text contains a match for the ticket pattern */\n private matchesPattern(text: string, pattern: string): boolean {\n try {\n const regex = new RegExp(pattern);\n return regex.test(text);\n } catch {\n return false;\n }\n }\n\n /** Validate the regex pattern is valid */\n private isValidPattern(pattern: string): boolean {\n try {\n new RegExp(pattern);\n return true;\n } catch {\n return false;\n }\n }\n\n /** Check configuration validity */\n private hasValidConfig(): { valid: boolean; reason?: string } {\n if (!this.config.pattern) {\n return { valid: false, reason: \"No ticket pattern configured\" };\n }\n if (!this.isValidPattern(this.config.pattern)) {\n return { valid: false, reason: `Invalid regex pattern: ${this.config.pattern}` };\n }\n if (!this.config.require_in_commits && !this.config.require_in_branch) {\n return {\n valid: false,\n reason: \"Neither require_in_commits nor require_in_branch is enabled\",\n };\n }\n return { valid: true };\n }\n\n /** Validate branch name contains ticket reference */\n private async validateBranch(\n projectRoot: string,\n pattern: string\n ): Promise<{ skip?: string; violation?: Violation }> {\n const branch = await this.getCurrentBranch(projectRoot);\n if (!branch) {\n return { skip: \"Not in a git repository or no branch checked out\" };\n }\n if (!this.matchesPattern(branch, pattern)) {\n return {\n violation: {\n rule: `${this.rule}.branch`,\n tool: this.toolId,\n message: `Branch '${branch}' does not contain ticket reference matching: ${pattern}`,\n severity: \"error\",\n },\n };\n }\n return {};\n }\n\n /** Validate commit message contains ticket reference */\n private async validateCommit(\n projectRoot: string,\n pattern: string\n ): Promise<{ skip?: string; violation?: Violation }> {\n const commitMessage = await this.getHeadCommitMessage(projectRoot);\n if (!commitMessage) {\n return { skip: \"Not in a git repository or no commits\" };\n }\n if (!this.matchesPattern(commitMessage, pattern)) {\n return {\n violation: {\n rule: `${this.rule}.commits`,\n tool: this.toolId,\n message: `Commit message does not contain ticket reference matching: ${pattern}`,\n severity: \"error\",\n },\n };\n }\n return {};\n }\n\n /** Perform all validations and collect results */\n private async runValidations(\n projectRoot: string,\n pattern: string\n ): Promise<{ skip?: string; violations: Violation[] }> {\n const violations: Violation[] = [];\n\n if (this.config.require_in_branch) {\n const result = await this.validateBranch(projectRoot, pattern);\n if (result.skip) {\n return { skip: result.skip, violations: [] };\n }\n if (result.violation) {\n violations.push(result.violation);\n }\n }\n\n if (this.config.require_in_commits) {\n const result = await this.validateCommit(projectRoot, pattern);\n if (result.skip) {\n return { skip: result.skip, violations: [] };\n }\n if (result.violation) {\n violations.push(result.violation);\n }\n }\n\n return { violations };\n }\n\n /** Run ticket validation */\n async run(projectRoot: string): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n\n const configCheck = this.hasValidConfig();\n if (!configCheck.valid) {\n return this.skip(configCheck.reason ?? \"Invalid configuration\", elapsed());\n }\n\n const pattern = this.config.pattern as string;\n const { skip, violations } = await this.runValidations(projectRoot, pattern);\n\n if (skip) {\n return this.skip(skip, elapsed());\n }\n return violations.length > 0\n ? this.fromViolations(violations, elapsed())\n : this.pass(elapsed());\n }\n}\n","import { type Config } from \"../core/index.js\";\nimport { type CheckResult, type DomainResult, DomainResultBuilder, type IToolRunner } from \"../core/index.js\";\nimport {\n BackupsRunner,\n BranchesRunner,\n ChangesetsRunner,\n CiRunner,\n CodeownersRunner,\n CommitsRunner,\n CoverageRunner,\n DocsRunner,\n ForbiddenFilesRunner,\n HooksRunner,\n PrRunner,\n RepoRunner,\n TicketsRunner,\n} from \"./tools/index.js\";\n\n// Export tool runners for direct access\nexport {\n BackupsRunner,\n BaseProcessToolRunner,\n BranchesRunner,\n ChangesetsRunner,\n CiRunner,\n CodeownersRunner,\n CommitsRunner,\n CoverageRunner,\n DocsRunner,\n ForbiddenFilesRunner,\n HooksRunner,\n PrRunner,\n RepoRunner,\n TicketsRunner,\n} from \"./tools/index.js\";\n\n/** Tool configuration entry mapping config getter to runner or runner factory */\ninterface ToolEntry {\n isEnabled: (config: Config) => boolean;\n runner: IToolRunner | ((config: Config) => IToolRunner);\n}\n\n/** Check if a tool is enabled in config */\nfunction isEnabled(toolConfig: { enabled?: boolean } | undefined): boolean {\n return toolConfig?.enabled === true;\n}\n\n/** Create a configured HooksRunner */\nfunction createHooksRunner(config: Config): HooksRunner {\n const runner = new HooksRunner();\n const hooksConfig = config.process?.hooks;\n if (hooksConfig) {\n runner.setConfig({\n enabled: hooksConfig.enabled,\n require_husky: hooksConfig.require_husky,\n require_hooks: hooksConfig.require_hooks,\n commands: hooksConfig.commands,\n protected_branches: hooksConfig.protected_branches,\n });\n }\n return runner;\n}\n\n/** Create a configured CiRunner */\nfunction createCiRunner(config: Config): CiRunner {\n const runner = new CiRunner();\n const ciConfig = config.process?.ci;\n if (ciConfig) {\n runner.setConfig({\n enabled: ciConfig.enabled,\n require_workflows: ciConfig.require_workflows,\n jobs: ciConfig.jobs,\n actions: ciConfig.actions,\n commands: ciConfig.commands,\n });\n }\n return runner;\n}\n\n/** Create a configured BranchesRunner */\nfunction createBranchesRunner(config: Config): BranchesRunner {\n const runner = new BranchesRunner();\n const branchesConfig = config.process?.branches;\n if (branchesConfig) {\n runner.setConfig({\n enabled: branchesConfig.enabled,\n pattern: branchesConfig.pattern,\n exclude: branchesConfig.exclude,\n require_issue: branchesConfig.require_issue,\n issue_pattern: branchesConfig.issue_pattern,\n });\n }\n return runner;\n}\n\n/** Create a configured CommitsRunner */\nfunction createCommitsRunner(config: Config): CommitsRunner {\n const runner = new CommitsRunner();\n const commitsConfig = config.process?.commits;\n if (commitsConfig) {\n runner.setConfig({\n enabled: commitsConfig.enabled,\n pattern: commitsConfig.pattern,\n types: commitsConfig.types,\n require_scope: commitsConfig.require_scope,\n max_subject_length: commitsConfig.max_subject_length,\n });\n }\n return runner;\n}\n\n/** Create a configured ChangesetsRunner */\nfunction createChangesetsRunner(config: Config): ChangesetsRunner {\n const runner = new ChangesetsRunner();\n const changesetsConfig = config.process?.changesets;\n if (changesetsConfig) {\n runner.setConfig({\n enabled: changesetsConfig.enabled,\n require_for_paths: changesetsConfig.require_for_paths,\n exclude_paths: changesetsConfig.exclude_paths,\n validate_format: changesetsConfig.validate_format,\n allowed_bump_types: changesetsConfig.allowed_bump_types,\n require_description: changesetsConfig.require_description,\n min_description_length: changesetsConfig.min_description_length,\n });\n }\n return runner;\n}\n\n/** Create a configured PrRunner */\nfunction createPrRunner(config: Config): PrRunner {\n const runner = new PrRunner();\n const prConfig = config.process?.pr;\n if (prConfig) {\n runner.setConfig({\n enabled: prConfig.enabled,\n max_files: prConfig.max_files,\n max_lines: prConfig.max_lines,\n require_issue: prConfig.require_issue,\n issue_keywords: prConfig.issue_keywords,\n });\n }\n return runner;\n}\n\n/** Create a configured TicketsRunner */\nfunction createTicketsRunner(config: Config): TicketsRunner {\n const runner = new TicketsRunner();\n const ticketsConfig = config.process?.tickets;\n if (ticketsConfig) {\n runner.setConfig({\n enabled: ticketsConfig.enabled,\n pattern: ticketsConfig.pattern,\n require_in_commits: ticketsConfig.require_in_commits,\n require_in_branch: ticketsConfig.require_in_branch,\n });\n }\n return runner;\n}\n\n/** Create a configured CoverageRunner */\nfunction createCoverageRunner(config: Config): CoverageRunner {\n const runner = new CoverageRunner();\n const coverageConfig = config.process?.coverage;\n if (coverageConfig) {\n runner.setConfig({\n enabled: coverageConfig.enabled,\n min_threshold: coverageConfig.min_threshold,\n enforce_in: coverageConfig.enforce_in,\n ci_workflow: coverageConfig.ci_workflow,\n ci_job: coverageConfig.ci_job,\n });\n }\n return runner;\n}\n\n/** Create a configured RepoRunner */\nfunction createRepoRunner(config: Config): RepoRunner {\n const runner = new RepoRunner();\n const repoConfig = config.process?.repo;\n if (repoConfig) {\n runner.setConfig({\n enabled: repoConfig.enabled,\n require_branch_protection: repoConfig.require_branch_protection,\n require_codeowners: repoConfig.require_codeowners,\n ruleset: repoConfig.ruleset,\n tag_protection: repoConfig.tag_protection,\n });\n }\n return runner;\n}\n\n/** Create a configured BackupsRunner */\nfunction createBackupsRunner(config: Config): BackupsRunner {\n const runner = new BackupsRunner();\n const backupsConfig = config.process?.backups;\n if (backupsConfig) {\n runner.setConfig({\n enabled: backupsConfig.enabled,\n bucket: backupsConfig.bucket,\n prefix: backupsConfig.prefix,\n max_age_hours: backupsConfig.max_age_hours,\n region: backupsConfig.region,\n });\n }\n return runner;\n}\n\n/** Create a configured CodeownersRunner */\nfunction createCodeownersRunner(config: Config): CodeownersRunner {\n const runner = new CodeownersRunner();\n const codeownersConfig = config.process?.codeowners;\n if (codeownersConfig) {\n runner.setConfig({\n enabled: codeownersConfig.enabled,\n rules: codeownersConfig.rules,\n });\n }\n return runner;\n}\n\n/** Create a configured DocsRunner */\nfunction createDocsRunner(config: Config): DocsRunner {\n const runner = new DocsRunner();\n const docsConfig = config.process?.docs;\n if (docsConfig) {\n runner.setConfig({\n enabled: docsConfig.enabled,\n path: docsConfig.path,\n enforcement: docsConfig.enforcement,\n allowlist: docsConfig.allowlist,\n max_files: docsConfig.max_files,\n max_file_lines: docsConfig.max_file_lines,\n max_total_kb: docsConfig.max_total_kb,\n staleness_days: docsConfig.staleness_days,\n stale_mappings: docsConfig.stale_mappings,\n min_coverage: docsConfig.min_coverage,\n coverage_paths: docsConfig.coverage_paths,\n exclude_patterns: docsConfig.exclude_patterns,\n types: docsConfig.types,\n });\n }\n return runner;\n}\n\n/** Create a configured ForbiddenFilesRunner */\nfunction createForbiddenFilesRunner(config: Config): ForbiddenFilesRunner {\n const runner = new ForbiddenFilesRunner();\n const forbiddenFilesConfig = config.process?.forbidden_files;\n if (forbiddenFilesConfig) {\n runner.setConfig({\n enabled: forbiddenFilesConfig.enabled,\n files: forbiddenFilesConfig.files,\n ignore: forbiddenFilesConfig.ignore,\n message: forbiddenFilesConfig.message,\n });\n }\n return runner;\n}\n\n/** All available process tools with their config predicates */\nconst toolRegistry: ToolEntry[] = [\n { isEnabled: (c) => isEnabled(c.process?.hooks), runner: createHooksRunner },\n { isEnabled: (c) => isEnabled(c.process?.ci), runner: createCiRunner },\n { isEnabled: (c) => isEnabled(c.process?.branches), runner: createBranchesRunner },\n { isEnabled: (c) => isEnabled(c.process?.commits), runner: createCommitsRunner },\n { isEnabled: (c) => isEnabled(c.process?.changesets), runner: createChangesetsRunner },\n { isEnabled: (c) => isEnabled(c.process?.pr), runner: createPrRunner },\n { isEnabled: (c) => isEnabled(c.process?.tickets), runner: createTicketsRunner },\n { isEnabled: (c) => isEnabled(c.process?.coverage), runner: createCoverageRunner },\n { isEnabled: (c) => isEnabled(c.process?.repo), runner: createRepoRunner },\n { isEnabled: (c) => isEnabled(c.process?.backups), runner: createBackupsRunner },\n { isEnabled: (c) => isEnabled(c.process?.codeowners), runner: createCodeownersRunner },\n { isEnabled: (c) => isEnabled(c.process?.docs), runner: createDocsRunner },\n { isEnabled: (c) => isEnabled(c.process?.forbidden_files), runner: createForbiddenFilesRunner },\n];\n\n/**\n * Get enabled tools based on configuration\n */\nfunction getEnabledTools(config: Config): IToolRunner[] {\n return toolRegistry\n .filter((entry) => entry.isEnabled(config))\n .map((entry) => (typeof entry.runner === \"function\" ? entry.runner(config) : entry.runner));\n}\n\n/**\n * Run all process checks based on configuration\n */\nexport async function runProcessChecks(projectRoot: string, config: Config): Promise<DomainResult> {\n const tools = getEnabledTools(config);\n const checks = await runTools(tools, projectRoot, \"run\");\n return DomainResultBuilder.fromChecks(\"process\", checks);\n}\n\n/**\n * Audit process configuration (check that configs exist without running tools)\n */\nexport async function auditProcessConfig(\n projectRoot: string,\n config: Config\n): Promise<DomainResult> {\n const tools = getEnabledTools(config);\n const checks = await runTools(tools, projectRoot, \"audit\");\n return DomainResultBuilder.fromChecks(\"process\", checks);\n}\n\n/**\n * Run tools in parallel with error isolation\n * Uses Promise.allSettled to ensure one failing tool doesn't lose all results\n */\nasync function runTools(\n tools: IToolRunner[],\n projectRoot: string,\n mode: \"run\" | \"audit\"\n): Promise<CheckResult[]> {\n const promises = tools.map((tool) =>\n mode === \"run\" ? tool.run(projectRoot) : tool.audit(projectRoot)\n );\n\n const results = await Promise.allSettled(promises);\n\n return results.map((result, index) => {\n if (result.status === \"fulfilled\") {\n return result.value;\n }\n\n // Handle rejected promise - create error result for the tool\n const tool = tools[index];\n const errorMessage = result.reason instanceof Error ? result.reason.message : \"Unknown error\";\n\n return {\n name: tool.name,\n rule: tool.rule,\n passed: false,\n violations: [\n {\n rule: tool.rule,\n tool: tool.toolId,\n message: `Tool error: ${errorMessage}`,\n severity: \"error\" as const,\n },\n ],\n skipped: false,\n duration: 0,\n };\n });\n}\n","import chalk from \"chalk\";\n\nimport { loadConfigAsync } from \"../../core/index.js\";\nimport { ExitCode } from \"../../core/index.js\";\nimport { scanRepository } from \"./scanner.js\";\nimport { type ScanOptions, type ScanResult } from \"./types.js\";\n\n// Re-export public API types\nexport {\n type RemoteRepoInfo,\n type ScanOptions,\n type ScanResult,\n type ValidateProcessOptions,\n type ValidateProcessResult,\n} from \"./types.js\";\n\n// Re-export scanner\nexport { scanRepository, validateProcess } from \"./scanner.js\";\n\n/** Format scan result as text */\nfunction formatScanText(result: ScanResult): string {\n const lines: string[] = [];\n\n lines.push(`Repository: ${result.repoInfo.owner}/${result.repoInfo.repo}`);\n lines.push(\"\");\n\n for (const check of result.checks) {\n if (check.skipped) {\n lines.push(chalk.yellow(`⊘ ${check.name} (skipped: ${check.skipReason})`));\n } else if (check.passed) {\n lines.push(chalk.green(`✓ ${check.name}`));\n } else {\n lines.push(chalk.red(`✗ ${check.name}`));\n for (const violation of check.violations) {\n lines.push(chalk.red(` • ${violation.message}`));\n }\n }\n }\n\n lines.push(\"\");\n lines.push(\n `Summary: ${result.summary.passedChecks} passed, ` +\n `${result.summary.failedChecks} failed, ` +\n `${result.summary.skippedChecks} skipped`\n );\n\n return lines.join(\"\\n\");\n}\n\n/** Format scan result as JSON */\nfunction formatScanJson(result: ScanResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n/** Run the scan command */\nexport async function runScan(options: ScanOptions): Promise<void> {\n try {\n const { config } = await loadConfigAsync(options.config);\n const result = await scanRepository(options.repo, config);\n\n const output = options.format === \"json\" ? formatScanJson(result) : formatScanText(result);\n\n process.stdout.write(`${output}\\n`);\n process.exit(result.passed ? ExitCode.SUCCESS : ExitCode.VIOLATIONS_FOUND);\n } catch (error) {\n if (options.format === \"json\") {\n const errorObj = {\n error: true,\n message: error instanceof Error ? error.message : String(error),\n code: (error as { code?: string }).code ?? \"UNKNOWN\",\n };\n process.stdout.write(`${JSON.stringify(errorObj, null, 2)}\\n`);\n } else {\n console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));\n }\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n}\n","import { execa } from \"execa\";\n\nimport { type Config } from \"../../core/index.js\";\nimport { type CheckResult, ExitCode, type Violation } from \"../../core/index.js\";\nimport {\n checkRemoteFiles,\n isGhAvailable,\n parseRepoString,\n RemoteFetcherError,\n standardFileChecks,\n verifyRepoAccess,\n} from \"./remote-fetcher.js\";\nimport {\n type FileCheckConfig,\n type RemoteRepoInfo,\n type ScanResult,\n type ValidateProcessOptions,\n type ValidateProcessResult,\n} from \"./types.js\";\nimport { type RulesetResponse, validateRulesets } from \"./validators.js\";\n\n/** Fetch rulesets from GitHub API */\nasync function fetchRulesets(repoInfo: RemoteRepoInfo): Promise<RulesetResponse[]> {\n const result = await execa(\"gh\", [\"api\", `repos/${repoInfo.owner}/${repoInfo.repo}/rulesets`]);\n return JSON.parse(result.stdout) as RulesetResponse[];\n}\n\n/** Create a skipped check result */\nfunction createSkippedResult(\n name: string,\n rule: string,\n reason: string,\n duration: number\n): CheckResult {\n return { name, rule, passed: true, violations: [], skipped: true, skipReason: reason, duration };\n}\n\n/** Create an error check result */\nfunction createErrorResult(\n name: string,\n rule: string,\n message: string,\n duration: number\n): CheckResult {\n return {\n name,\n rule,\n passed: false,\n violations: [{ rule, tool: \"scan\", message, severity: \"error\" }],\n skipped: false,\n duration,\n };\n}\n\n/** Handle API errors for ruleset fetching */\nfunction handleRulesetError(\n error: unknown,\n repoConfig: NonNullable<Config[\"process\"]>[\"repo\"],\n elapsed: () => number\n): CheckResult {\n const msg = error instanceof Error ? error.message : String(error);\n\n if (msg.includes(\"403\") || msg.includes(\"Must have admin rights\")) {\n return createSkippedResult(\n \"Repository Settings\",\n \"process.repo\",\n \"Cannot check rulesets: insufficient permissions (requires admin access)\",\n elapsed()\n );\n }\n\n if (msg.includes(\"404\")) {\n const violations: Violation[] = [];\n if (repoConfig?.require_branch_protection) {\n violations.push({\n rule: \"process.repo.branch_protection\",\n tool: \"scan\",\n message: \"No branch protection rulesets configured\",\n severity: \"error\",\n });\n }\n return {\n name: \"Repository Settings\",\n rule: \"process.repo\",\n passed: violations.length === 0,\n violations,\n skipped: false,\n duration: elapsed(),\n };\n }\n\n return createErrorResult(\n \"Repository Settings\",\n \"process.repo\",\n `Failed to check rulesets: ${msg}`,\n elapsed()\n );\n}\n\n/** Check repository rulesets and branch protection */\nasync function checkRulesets(repoInfo: RemoteRepoInfo, config: Config): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n const repoConfig = config.process?.repo;\n\n if (!repoConfig?.enabled) {\n return createSkippedResult(\n \"Repository Settings\",\n \"process.repo\",\n \"Repository settings check not enabled in config\",\n elapsed()\n );\n }\n\n try {\n const rulesets = await fetchRulesets(repoInfo);\n const violations = validateRulesets(rulesets, repoConfig);\n\n return {\n name: \"Repository Settings\",\n rule: \"process.repo\",\n passed: violations.length === 0,\n violations,\n skipped: false,\n duration: elapsed(),\n };\n } catch (error) {\n return handleRulesetError(error, repoConfig, elapsed);\n }\n}\n\n/** Build file checks configuration from config */\nfunction buildFileChecks(config: Config): FileCheckConfig[] {\n const fileChecks: FileCheckConfig[] = [];\n\n if (config.process?.repo?.require_codeowners) {\n fileChecks.push({\n path: \"CODEOWNERS\",\n alternativePaths: [\".github/CODEOWNERS\", \"docs/CODEOWNERS\"],\n required: true,\n description: \"CODEOWNERS file for code review assignment\",\n });\n }\n\n fileChecks.push(\n ...standardFileChecks.filter((check) => !fileChecks.some((fc) => fc.path === check.path))\n );\n\n return fileChecks;\n}\n\n/** Convert file check results to violations */\nfunction fileResultsToViolations(\n results: { path: string; exists: boolean; checkedPaths: string[] }[],\n fileChecks: FileCheckConfig[]\n): Violation[] {\n const violations: Violation[] = [];\n\n for (const result of results) {\n const checkConfig = fileChecks.find((fc) => fc.path === result.path);\n if (!result.exists && checkConfig?.required) {\n violations.push({\n rule: `process.scan.files.${result.path.replace(/[./]/g, \"_\")}`,\n tool: \"scan\",\n message: `Required file not found: ${result.path} (checked: ${result.checkedPaths.join(\", \")})`,\n severity: \"error\",\n });\n }\n }\n\n return violations;\n}\n\n/** Check remote files for existence */\nasync function checkFiles(repoInfo: RemoteRepoInfo, config: Config): Promise<CheckResult> {\n const startTime = Date.now();\n const elapsed = (): number => Date.now() - startTime;\n const fileChecks = buildFileChecks(config);\n\n if (fileChecks.length === 0) {\n return createSkippedResult(\n \"Repository Files\",\n \"process.scan.files\",\n \"No file checks configured\",\n elapsed()\n );\n }\n\n try {\n const results = await checkRemoteFiles(repoInfo, fileChecks);\n const violations = fileResultsToViolations(results, fileChecks);\n\n return {\n name: \"Repository Files\",\n rule: \"process.scan.files\",\n passed: violations.length === 0,\n violations,\n skipped: false,\n duration: elapsed(),\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n return createErrorResult(\n \"Repository Files\",\n \"process.scan.files\",\n `Failed to check files: ${msg}`,\n elapsed()\n );\n }\n}\n\n/** Aggregate check results into scan result */\nfunction aggregateResults(repoInfo: RemoteRepoInfo, checks: CheckResult[]): ScanResult {\n const violations = checks.flatMap((c) => c.violations);\n const passedChecks = checks.filter((c) => c.passed && !c.skipped).length;\n const failedChecks = checks.filter((c) => !c.passed && !c.skipped).length;\n const skippedChecks = checks.filter((c) => c.skipped).length;\n\n return {\n repoInfo,\n checks,\n violations,\n passed: failedChecks === 0,\n summary: { totalChecks: checks.length, passedChecks, failedChecks, skippedChecks },\n };\n}\n\n/** Run all remote scans for a repository */\nexport async function scanRepository(repo: string, config: Config): Promise<ScanResult> {\n const repoInfo = parseRepoString(repo);\n\n if (!(await isGhAvailable())) {\n throw new RemoteFetcherError(\n \"GitHub CLI (gh) not available. Install it from https://cli.github.com/\",\n \"NO_GH\"\n );\n }\n\n await verifyRepoAccess(repoInfo);\n\n const [rulesetsResult, filesResult] = await Promise.all([\n checkRulesets(repoInfo, config),\n checkFiles(repoInfo, config),\n ]);\n\n return aggregateResults(repoInfo, [rulesetsResult, filesResult]);\n}\n\n/** Programmatic API for validating remote process checks */\nexport async function validateProcess(\n options: ValidateProcessOptions\n): Promise<ValidateProcessResult> {\n const { loadConfigAsync } = await import(\"../../core/index.js\");\n const { config } = await loadConfigAsync(options.config);\n const result = await scanRepository(options.repo, config);\n\n const fs = await import(\"node:fs\");\n const path = await import(\"node:path\");\n const { fileURLToPath } = await import(\"node:url\");\n\n const __dirname = path.dirname(fileURLToPath(import.meta.url));\n const packageJsonPath = path.resolve(__dirname, \"..\", \"..\", \"..\", \"package.json\");\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\")) as { version: string };\n\n return {\n version: packageJson.version,\n repoInfo: result.repoInfo,\n domain: \"process\",\n checks: result.checks,\n summary: {\n totalChecks: result.summary.totalChecks,\n passedChecks: result.summary.passedChecks,\n failedChecks: result.summary.failedChecks,\n totalViolations: result.violations.length,\n exitCode: result.passed ? ExitCode.SUCCESS : ExitCode.VIOLATIONS_FOUND,\n },\n };\n}\n","import { execa } from \"execa\";\n\nimport { type FileCheckConfig, type FileCheckResult, type RemoteRepoInfo } from \"./types.js\";\n\n/** Error thrown when remote fetcher encounters an issue */\nexport class RemoteFetcherError extends Error {\n constructor(\n message: string,\n public readonly code: \"NO_GH\" | \"NO_REPO\" | \"NO_PERMISSION\" | \"API_ERROR\" | \"INVALID_REPO\"\n ) {\n super(message);\n this.name = \"RemoteFetcherError\";\n }\n}\n\n/** Parse owner/repo string into RemoteRepoInfo */\nexport function parseRepoString(repo: string): RemoteRepoInfo {\n const parts = repo.split(\"/\");\n if (parts.length !== 2 || !parts[0] || !parts[1]) {\n throw new RemoteFetcherError(\n `Invalid repository format: \"${repo}\". Expected \"owner/repo\" format.`,\n \"INVALID_REPO\"\n );\n }\n return { owner: parts[0], repo: parts[1] };\n}\n\n/** Check if gh CLI is available */\nexport async function isGhAvailable(): Promise<boolean> {\n try {\n await execa(\"gh\", [\"--version\"]);\n return true;\n } catch {\n return false;\n }\n}\n\n/** Verify the repository exists and user has access */\nexport async function verifyRepoAccess(repoInfo: RemoteRepoInfo): Promise<boolean> {\n try {\n await execa(\"gh\", [\"api\", `repos/${repoInfo.owner}/${repoInfo.repo}`]);\n return true;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n if (errorMessage.includes(\"404\") || errorMessage.includes(\"Not Found\")) {\n throw new RemoteFetcherError(\n `Repository not found: ${repoInfo.owner}/${repoInfo.repo}`,\n \"NO_REPO\"\n );\n }\n\n if (errorMessage.includes(\"403\") || errorMessage.includes(\"401\")) {\n throw new RemoteFetcherError(\n `Cannot access repository: ${repoInfo.owner}/${repoInfo.repo}. Check your GITHUB_TOKEN permissions.`,\n \"NO_PERMISSION\"\n );\n }\n\n throw new RemoteFetcherError(\n `Failed to verify repository access: ${errorMessage}`,\n \"API_ERROR\"\n );\n }\n}\n\n/** Check if a file exists in the remote repository via GitHub Contents API */\nexport async function checkRemoteFileExists(\n repoInfo: RemoteRepoInfo,\n filePath: string\n): Promise<boolean> {\n try {\n await execa(\"gh\", [\n \"api\",\n `repos/${repoInfo.owner}/${repoInfo.repo}/contents/${filePath}`,\n \"--silent\",\n ]);\n return true;\n } catch {\n // File doesn't exist or no access - both return false\n return false;\n }\n}\n\n/** Check multiple alternative paths for a file */\nasync function checkRemoteFileWithAlternatives(\n repoInfo: RemoteRepoInfo,\n config: FileCheckConfig\n): Promise<FileCheckResult> {\n const allPaths = [config.path, ...(config.alternativePaths ?? [])];\n\n for (const path of allPaths) {\n // Sequential check needed - stop on first match\n const exists = await checkRemoteFileExists(repoInfo, path);\n if (exists) {\n return { path: config.path, exists: true, checkedPaths: allPaths };\n }\n }\n\n return { path: config.path, exists: false, checkedPaths: allPaths };\n}\n\n/** Batch check multiple files in a repository */\nexport async function checkRemoteFiles(\n repoInfo: RemoteRepoInfo,\n configs: FileCheckConfig[]\n): Promise<FileCheckResult[]> {\n // Run checks in parallel for efficiency\n const results = await Promise.all(\n configs.map((config) => checkRemoteFileWithAlternatives(repoInfo, config))\n );\n return results;\n}\n\n/** Standard file checks for remote validation */\nexport const standardFileChecks: FileCheckConfig[] = [\n {\n path: \"CODEOWNERS\",\n alternativePaths: [\".github/CODEOWNERS\", \"docs/CODEOWNERS\"],\n required: false,\n description: \"CODEOWNERS file for code review assignment\",\n },\n {\n path: \".github/PULL_REQUEST_TEMPLATE.md\",\n alternativePaths: [\n \".github/pull_request_template.md\",\n \"PULL_REQUEST_TEMPLATE.md\",\n \"pull_request_template.md\",\n ],\n required: false,\n description: \"Pull request template\",\n },\n {\n path: \"README.md\",\n alternativePaths: [\"readme.md\", \"README\"],\n required: false,\n description: \"Repository README\",\n },\n {\n path: \".github/workflows\",\n required: false,\n description: \"GitHub Actions workflows directory\",\n },\n];\n","import { type Config } from \"../../core/index.js\";\nimport { type Violation } from \"../../core/index.js\";\n\n/** GitHub Ruleset response types */\ninterface RulesetBypassActor {\n actor_id: number | null;\n actor_type: string;\n bypass_mode: string;\n}\n\ninterface RulesetRule {\n type: string;\n parameters?: {\n required_approving_review_count?: number;\n dismiss_stale_reviews_on_push?: boolean;\n require_code_owner_review?: boolean;\n required_status_checks?: { context: string }[];\n strict_required_status_checks_policy?: boolean;\n };\n}\n\nexport interface RulesetResponse {\n id: number;\n name: string;\n target: string;\n enforcement: string;\n conditions?: { ref_name?: { include?: string[]; exclude?: string[] } };\n bypass_actors?: RulesetBypassActor[];\n rules?: RulesetRule[];\n}\n\ntype RulesetConfig = NonNullable<NonNullable<Config[\"process\"]>[\"repo\"]>[\"ruleset\"];\ntype TagProtectionConfig = NonNullable<NonNullable<Config[\"process\"]>[\"repo\"]>[\"tag_protection\"];\n\n/** Check if branch matches any of the include patterns */\nfunction matchesBranch(patterns: string[], branch: string): boolean {\n for (const pattern of patterns) {\n const cleanPattern = pattern.replace(/^refs\\/heads\\//, \"\");\n if (cleanPattern === branch) {\n return true;\n }\n if (cleanPattern === \"~DEFAULT_BRANCH\" && branch === \"main\") {\n return true;\n }\n if (cleanPattern === \"~ALL\") {\n return true;\n }\n if (cleanPattern.includes(\"*\")) {\n const regex = new RegExp(`^${cleanPattern.replace(/\\*/g, \".*\")}$`);\n if (regex.test(branch)) {\n return true;\n }\n }\n }\n return false;\n}\n\n/** Find branch ruleset matching the target branch */\nfunction findBranchRuleset(\n rulesets: RulesetResponse[],\n branch: string\n): RulesetResponse | undefined {\n return rulesets.find(\n (r) =>\n r.target === \"branch\" &&\n r.enforcement === \"active\" &&\n matchesBranch(r.conditions?.ref_name?.include ?? [], branch)\n );\n}\n\n/** Validate rulesets against config */\n \nexport function validateRulesets(\n rulesets: RulesetResponse[],\n repoConfig: NonNullable<Config[\"process\"]>[\"repo\"]\n): Violation[] {\n if (!repoConfig) {\n return [];\n }\n\n const violations: Violation[] = [];\n const rulesetConfig = repoConfig.ruleset;\n const branch = rulesetConfig?.branch ?? \"main\";\n const branchRuleset = findBranchRuleset(rulesets, branch);\n\n if (repoConfig.require_branch_protection && !branchRuleset) {\n violations.push({\n rule: \"process.repo.branch_protection\",\n tool: \"scan\",\n message: `Branch '${branch}' does not have a branch protection ruleset`,\n severity: \"error\",\n });\n }\n\n if (branchRuleset && rulesetConfig) {\n violations.push(...validateBranchRuleset(branchRuleset, rulesetConfig, branch));\n }\n\n if (repoConfig.tag_protection?.patterns?.length) {\n violations.push(...validateTagProtection(rulesets, repoConfig.tag_protection));\n }\n\n return violations;\n}\n\n/** Validate branch ruleset settings against config */\nfunction validateBranchRuleset(\n ruleset: RulesetResponse,\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (!config) {\n return [];\n }\n\n const violations: Violation[] = [];\n const rules = ruleset.rules ?? [];\n const prRule = rules.find((r) => r.type === \"pull_request\");\n const statusRule = rules.find((r) => r.type === \"required_status_checks\");\n\n violations.push(...validatePullRequestRule(prRule, config, branch));\n violations.push(...validateStatusChecksRule(statusRule, config, branch));\n violations.push(...validateSignedCommits(rules, config, branch));\n violations.push(...validateBypassActors(ruleset.bypass_actors ?? [], config, branch));\n\n return violations;\n}\n\n/** Validate pull request rule settings */\n \nfunction validatePullRequestRule(\n prRule: RulesetRule | undefined,\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (!config) {\n return [];\n }\n\n const violations: Violation[] = [];\n const params = prRule?.parameters;\n\n if (config.required_reviews !== undefined) {\n const actualReviews = params?.required_approving_review_count ?? 0;\n if (actualReviews < config.required_reviews) {\n violations.push({\n rule: \"process.repo.branch_protection.required_reviews\",\n tool: \"scan\",\n message: `Branch '${branch}' requires ${actualReviews} reviews, expected at least ${config.required_reviews}`,\n severity: \"error\",\n });\n }\n }\n\n if (config.dismiss_stale_reviews === true && !(params?.dismiss_stale_reviews_on_push ?? false)) {\n violations.push({\n rule: \"process.repo.branch_protection.dismiss_stale_reviews\",\n tool: \"scan\",\n message: `Branch '${branch}' does not dismiss stale reviews on new commits`,\n severity: \"error\",\n });\n }\n\n if (config.require_code_owner_reviews === true && !(params?.require_code_owner_review ?? false)) {\n violations.push({\n rule: \"process.repo.branch_protection.require_code_owner_reviews\",\n tool: \"scan\",\n message: `Branch '${branch}' does not require code owner reviews`,\n severity: \"error\",\n });\n }\n\n return violations;\n}\n\n/** Validate status checks rule settings */\n \nfunction validateStatusChecksRule(\n statusRule: RulesetRule | undefined,\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (!config) {\n return [];\n }\n\n const violations: Violation[] = [];\n const params = statusRule?.parameters;\n\n if (config.require_status_checks && config.require_status_checks.length > 0) {\n const actualChecks = params?.required_status_checks?.map((c) => c.context) ?? [];\n const missingChecks = config.require_status_checks.filter(\n (check) => !actualChecks.includes(check)\n );\n if (missingChecks.length > 0) {\n violations.push({\n rule: \"process.repo.branch_protection.require_status_checks\",\n tool: \"scan\",\n message: `Branch '${branch}' missing required status checks: ${missingChecks.join(\", \")}`,\n severity: \"error\",\n });\n }\n }\n\n if (\n config.require_branches_up_to_date === true &&\n !(params?.strict_required_status_checks_policy ?? false)\n ) {\n violations.push({\n rule: \"process.repo.branch_protection.require_branches_up_to_date\",\n tool: \"scan\",\n message: `Branch '${branch}' does not require branches to be up to date before merging`,\n severity: \"error\",\n });\n }\n\n return violations;\n}\n\n/** Validate signed commits requirement */\nfunction validateSignedCommits(\n rules: RulesetRule[],\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (config?.require_signed_commits !== true) {\n return [];\n }\n\n if (!rules.some((r) => r.type === \"required_signatures\")) {\n return [\n {\n rule: \"process.repo.branch_protection.require_signed_commits\",\n tool: \"scan\",\n message: `Branch '${branch}' does not require signed commits`,\n severity: \"error\",\n },\n ];\n }\n\n return [];\n}\n\n/** Validate bypass actors configuration */\nfunction validateBypassActors(\n actualBypass: RulesetBypassActor[],\n config: RulesetConfig,\n branch: string\n): Violation[] {\n if (config?.enforce_admins !== true || actualBypass.length === 0) {\n return [];\n }\n\n return [\n {\n rule: \"process.repo.branch_protection.enforce_admins\",\n tool: \"scan\",\n message: `Branch '${branch}' has bypass actors configured but enforce_admins requires no bypasses`,\n severity: \"error\",\n },\n ];\n}\n\n/** Validate tag protection rulesets */\nfunction validateTagProtection(\n rulesets: RulesetResponse[],\n tagConfig: TagProtectionConfig\n): Violation[] {\n if (!tagConfig?.patterns?.length) {\n return [];\n }\n\n const violations: Violation[] = [];\n const tagRuleset = rulesets.find((r) => r.target === \"tag\" && r.enforcement === \"active\");\n\n if (!tagRuleset) {\n return [\n {\n rule: \"process.repo.tag_protection\",\n tool: \"scan\",\n message: \"No active tag protection ruleset found\",\n severity: \"error\",\n },\n ];\n }\n\n violations.push(...validateTagPatterns(tagConfig.patterns, tagRuleset));\n violations.push(...validateTagRules(tagConfig, tagRuleset.rules ?? []));\n\n return violations;\n}\n\n/** Validate tag patterns match */\nfunction validateTagPatterns(expectedPatterns: string[], tagRuleset: RulesetResponse): Violation[] {\n const expected = expectedPatterns.map((p) => `refs/tags/${p}`).sort();\n const actual = [...(tagRuleset.conditions?.ref_name?.include ?? [])].sort();\n\n if (expected.length === actual.length && expected.every((v, i) => v === actual[i])) {\n return [];\n }\n\n const found = actual.map((p) => p.replace(/^refs\\/tags\\//, \"\")).join(\", \");\n return [\n {\n rule: \"process.repo.tag_protection.patterns\",\n tool: \"scan\",\n message: `Tag protection patterns mismatch: expected [${expectedPatterns.join(\", \")}], found [${found}]`,\n severity: \"error\",\n },\n ];\n}\n\n/** Validate tag protection rules */\nfunction validateTagRules(tagConfig: TagProtectionConfig, rules: RulesetRule[]): Violation[] {\n if (!tagConfig) {\n return [];\n }\n\n const violations: Violation[] = [];\n\n if (tagConfig.prevent_deletion !== false && !rules.some((r) => r.type === \"deletion\")) {\n violations.push({\n rule: \"process.repo.tag_protection.prevent_deletion\",\n tool: \"scan\",\n message: \"Tag protection does not prevent deletion\",\n severity: \"error\",\n });\n }\n\n if (tagConfig.prevent_update !== false && !rules.some((r) => r.type === \"update\")) {\n violations.push({\n rule: \"process.repo.tag_protection.prevent_update\",\n tool: \"scan\",\n message: \"Tag protection does not prevent updates (force-push)\",\n severity: \"error\",\n });\n }\n\n return violations;\n}\n","import chalk from \"chalk\";\n\nimport {\n type DomainResult,\n type DomainStatus,\n type FullResult,\n type Violation,\n} from \"../core/index.js\";\n\nexport type OutputFormat = \"text\" | \"json\";\n\n/** Icon mapping for domain/check status with colors */\nconst STATUS_ICONS: Record<DomainStatus, string> = {\n pass: chalk.green(\"✓\"),\n fail: chalk.red(\"✗\"),\n skip: chalk.gray(\"○\"),\n};\n\n/**\n * Format output as JSON\n */\nexport function formatJson(result: FullResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Format output as human-readable text\n */\nexport function formatText(result: FullResult): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`conform v${result.version}`);\n lines.push(`Config: ${result.configPath}`);\n lines.push(\"\");\n\n // Domain results\n for (const [domainName, domain] of Object.entries(result.domains)) {\n lines.push(formatDomainText(domainName, domain));\n lines.push(\"\");\n }\n\n // Summary\n lines.push(chalk.dim(\"─\".repeat(50)));\n if (result.summary.totalViolations === 0) {\n lines.push(chalk.green(\"✓ All checks passed\"));\n } else {\n lines.push(chalk.red(`✗ ${result.summary.totalViolations} violation(s) found`));\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction getStatusIcon(status: DomainStatus): string {\n return STATUS_ICONS[status];\n}\n\nfunction getCheckIcon(passed: boolean, skipped: boolean): string {\n if (passed) {\n return chalk.green(\"✓\");\n }\n if (skipped) {\n return chalk.gray(\"○\");\n }\n return chalk.red(\"✗\");\n}\n\nfunction formatCheckLine(check: DomainResult[\"checks\"][number]): string[] {\n const checkIcon = getCheckIcon(check.passed, check.skipped);\n const duration = check.duration ? chalk.dim(` (${check.duration}ms)`) : \"\";\n\n if (check.skipped) {\n return [\n ` ${checkIcon} ${chalk.bold(check.name)}: ${chalk.gray(\"skipped\")} - ${chalk.gray(check.skipReason)}${duration}`,\n ];\n }\n if (check.passed) {\n return [` ${checkIcon} ${chalk.bold(check.name)}: ${chalk.green(\"passed\")}${duration}`];\n }\n\n const lines = [\n ` ${checkIcon} ${chalk.bold(check.name)}: ${chalk.red(`${check.violations.length} violation(s)`)}${duration}`,\n ];\n const violationsToShow = check.violations.slice(0, 10);\n lines.push(...violationsToShow.map(formatViolationText));\n if (check.violations.length > 10) {\n lines.push(chalk.dim(` ... and ${check.violations.length - 10} more`));\n }\n return lines;\n}\n\nfunction formatDomainText(name: string, domain: DomainResult): string {\n const statusIcon = getStatusIcon(domain.status);\n const lines = [`${statusIcon} ${chalk.bold(name.toUpperCase())}`];\n for (const check of domain.checks) {\n lines.push(...formatCheckLine(check));\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Format a single violation as text\n */\nfunction formatLocation(file: string, line?: number, column?: number): string {\n if (line !== undefined && column !== undefined) {\n return `${file}:${line}:${column}`;\n }\n if (line !== undefined) {\n return `${file}:${line}`;\n }\n return file;\n}\n\nfunction formatViolationText(v: Violation): string {\n const location = v.file ? chalk.cyan(formatLocation(v.file, v.line, v.column)) : \"\";\n const code = v.code ? chalk.dim(`[${v.code}]`) : \"\";\n const severity = v.severity === \"error\" ? chalk.red(\"error\") : chalk.yellow(\"warn\");\n\n if (location) {\n return ` ${location} ${severity} ${code} ${v.message}`;\n }\n return ` ${severity} ${code} ${v.message}`;\n}\n\n/**\n * Format result based on output format\n */\nexport function formatOutput(result: FullResult, format: OutputFormat): string {\n switch (format) {\n case \"json\":\n return formatJson(result);\n case \"text\":\n default:\n return formatText(result);\n }\n}\n","/**\n * Core implementation of the conform dependencies command\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { globSync } from \"glob\";\n\nimport { type Config, getProjectRoot, loadConfigAsync } from \"../core/index.js\";\nimport { ALWAYS_TRACKED, BUILTIN_MAPPINGS } from \"./mappings.js\";\nimport { formatDependenciesJson, formatDependenciesText } from \"./output.js\";\nimport type { DependenciesOptions, DependenciesResult } from \"./types.js\";\n\n// Re-export types for library consumers\nexport type { DependenciesOptions, DependenciesResult } from \"./types.js\";\n\n/**\n * Tool configuration with optional dependencies field\n */\ninterface ToolConfig {\n enabled?: boolean;\n dependencies?: string[];\n}\n\n/** Map of tool IDs to config accessor functions */\nconst TOOL_CONFIG_ACCESSORS: Record<string, (c: Config) => ToolConfig | undefined> = {\n eslint: (c) => c.code?.linting?.eslint,\n ruff: (c) => c.code?.linting?.ruff,\n tsc: (c) => c.code?.types?.tsc,\n ty: (c) => c.code?.types?.ty,\n knip: (c) => c.code?.unused?.knip,\n vulture: (c) => c.code?.unused?.vulture,\n secrets: (c) => c.code?.security?.secrets,\n pnpmaudit: (c) => c.code?.security?.pnpmaudit,\n pipaudit: (c) => c.code?.security?.pipaudit,\n};\n\n/** Coverage runner tool IDs */\nconst COVERAGE_RUNNERS = [\"vitest\", \"jest\", \"pytest\"];\n\n/**\n * Get tool configuration from standards.toml config by tool ID\n */\nfunction getToolConfig(config: Config, toolId: string): ToolConfig | undefined {\n // Handle coverage runners specially\n if (COVERAGE_RUNNERS.includes(toolId)) {\n const coverageConfig = config.code?.coverage_run;\n if (!coverageConfig?.enabled) {\n return undefined;\n }\n const runner = coverageConfig.runner;\n if (runner === \"auto\" || runner === toolId) {\n return coverageConfig;\n }\n return undefined;\n }\n // Use lookup table for other tools\n if (!(toolId in TOOL_CONFIG_ACCESSORS)) {\n return undefined;\n }\n return TOOL_CONFIG_ACCESSORS[toolId](config);\n}\n\n/**\n * Check if a pattern contains glob characters\n */\nfunction isGlobPattern(pattern: string): boolean {\n return pattern.includes(\"*\") || pattern.includes(\"?\") || pattern.includes(\"[\");\n}\n\n/**\n * Expand glob patterns and filter to only existing files\n */\nfunction expandAndFilter(patterns: string[], projectRoot: string): string[] {\n const results: string[] = [];\n\n for (const pattern of patterns) {\n if (isGlobPattern(pattern)) {\n const matches = globSync(pattern, { cwd: projectRoot, nodir: true, dot: true });\n results.push(...matches);\n } else {\n const fullPath = path.join(projectRoot, pattern);\n if (fs.existsSync(fullPath)) {\n results.push(pattern);\n }\n }\n }\n\n return [...new Set(results)].sort();\n}\n\n/**\n * Collect dependencies for a single tool\n */\nfunction collectToolDependencies(\n toolId: string,\n config: Config,\n projectRoot: string\n): string[] | null {\n const toolConfig = getToolConfig(config, toolId);\n if (!toolConfig?.enabled) {\n return null;\n }\n\n const mapping = BUILTIN_MAPPINGS[toolId];\n const builtinFiles = expandAndFilter(mapping.configFiles, projectRoot);\n const customFiles = toolConfig.dependencies\n ? expandAndFilter(toolConfig.dependencies, projectRoot)\n : [];\n\n const allFiles = [...new Set([...builtinFiles, ...customFiles])].sort();\n return allFiles.length > 0 ? allFiles : null;\n}\n\n/**\n * Get all dependencies for a project\n */\nexport async function getDependencies(\n options: Partial<DependenciesOptions> = {}\n): Promise<DependenciesResult> {\n const { config, configPath } = await loadConfigAsync(options.config);\n const projectRoot = options.project\n ? path.resolve(process.cwd(), options.project)\n : getProjectRoot(configPath);\n\n const dependencies: Record<string, string[]> = {};\n\n for (const toolId of Object.keys(BUILTIN_MAPPINGS)) {\n if (options.check && options.check !== toolId) {\n continue;\n }\n const files = collectToolDependencies(toolId, config, projectRoot);\n if (files) {\n dependencies[toolId] = files;\n }\n }\n\n const alwaysTracked = expandAndFilter(ALWAYS_TRACKED, projectRoot);\n const allFiles = [...new Set([...Object.values(dependencies).flat(), ...alwaysTracked])].sort();\n\n return {\n project: options.project ?? \".\",\n checkTomlPath: path.relative(projectRoot, configPath) || \"standards.toml\",\n dependencies,\n alwaysTracked,\n allFiles,\n };\n}\n\n/**\n * Run the dependencies command (CLI entry point)\n */\nexport async function runDependencies(options: DependenciesOptions): Promise<void> {\n const result = await getDependencies(options);\n const output =\n options.format === \"json\" ? formatDependenciesJson(result) : formatDependenciesText(result);\n process.stdout.write(`${output}\\n`);\n}\n","/**\n * Built-in dependency mappings for tools\n *\n * Maps tool IDs to their known configuration file patterns.\n * These patterns may include globs that need to be expanded.\n */\n\nimport type { ToolDependencyMapping } from \"./types.js\";\n\n/**\n * Built-in dependency mappings for all supported tools.\n * Keys match the toolId used in standards.toml config paths.\n */\nexport const BUILTIN_MAPPINGS: Record<string, ToolDependencyMapping> = {\n // Linting tools\n eslint: {\n toolId: \"eslint\",\n configFiles: [\n \"eslint.config.js\",\n \"eslint.config.mjs\",\n \"eslint.config.cjs\",\n \".eslintrc.js\",\n \".eslintrc.json\",\n \".eslintrc.yml\",\n \".eslintrc.yaml\",\n \".eslintignore\",\n ],\n },\n ruff: {\n toolId: \"ruff\",\n configFiles: [\"ruff.toml\", \".ruff.toml\", \"pyproject.toml\"],\n },\n\n // Type checking tools\n tsc: {\n toolId: \"tsc\",\n configFiles: [\"tsconfig.json\", \"tsconfig.*.json\"],\n },\n ty: {\n toolId: \"ty\",\n configFiles: [\"ty.toml\", \"pyproject.toml\"],\n },\n\n // Unused code detection\n knip: {\n toolId: \"knip\",\n configFiles: [\n \"knip.json\",\n \"knip.jsonc\",\n \"knip.js\",\n \"knip.ts\",\n \"knip.config.js\",\n \"knip.config.ts\",\n ],\n },\n vulture: {\n toolId: \"vulture\",\n configFiles: [\"pyproject.toml\"],\n },\n\n // Test coverage / test runners\n vitest: {\n toolId: \"vitest\",\n configFiles: [\n \"vitest.config.ts\",\n \"vitest.config.js\",\n \"vitest.config.mts\",\n \"vitest.config.mjs\",\n \"vite.config.ts\",\n \"vite.config.js\",\n ],\n },\n jest: {\n toolId: \"jest\",\n configFiles: [\n \"jest.config.js\",\n \"jest.config.ts\",\n \"jest.config.mjs\",\n \"jest.config.cjs\",\n \"jest.config.json\",\n ],\n },\n pytest: {\n toolId: \"pytest\",\n configFiles: [\"pytest.ini\", \"pyproject.toml\", \"setup.cfg\", \"conftest.py\"],\n },\n\n // Security tools\n secrets: {\n toolId: \"secrets\",\n configFiles: [\".gitleaks.toml\", \"gitleaks.toml\"],\n },\n pnpmaudit: {\n toolId: \"pnpmaudit\",\n configFiles: [\"pnpm-lock.yaml\"],\n },\n pipaudit: {\n toolId: \"pipaudit\",\n configFiles: [\"requirements.txt\", \"pyproject.toml\", \"setup.py\"],\n },\n};\n\n/**\n * Files that are always tracked regardless of which tools are enabled.\n * These patterns may include globs.\n */\nexport const ALWAYS_TRACKED: string[] = [\n \"standards.toml\",\n \".github/workflows/*.yml\",\n \".github/workflows/*.yaml\",\n \"repo-metadata.yaml\",\n];\n","/**\n * Validate guideline markdown files against the frontmatter schema\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport chalk from \"chalk\";\nimport matter from \"gray-matter\";\n\nimport { frontmatterSchema } from \"../mcp/standards/index.js\";\nimport { ExitCode } from \"../core/index.js\";\n\n/** Single file validation error */\nexport interface GuidelineValidationError {\n file: string;\n errors: string[];\n}\n\n/** Overall validation result */\nexport interface GuidelineValidationResult {\n valid: boolean;\n validCount: number;\n invalidCount: number;\n errors: GuidelineValidationError[];\n}\n\n/** Format text output for validation result */\nfunction formatTextOutput(result: GuidelineValidationResult): string {\n if (result.valid) {\n return chalk.green(`✓ All ${result.validCount} guideline(s) valid`);\n }\n const lines = [chalk.red(`✗ Found ${result.invalidCount} invalid guideline(s)`), \"\"];\n for (const err of result.errors) {\n lines.push(chalk.red(` ${err.file}:`));\n for (const e of err.errors) {\n lines.push(chalk.red(` - ${e}`));\n }\n }\n return lines.join(\"\\n\");\n}\n\n/** Validate a directory of guideline files */\nexport function validateGuidelinesDir(dirPath: string): GuidelineValidationResult {\n const files = fs.readdirSync(dirPath).filter((f) => f.endsWith(\".md\"));\n const result: GuidelineValidationResult = {\n valid: true,\n validCount: 0,\n invalidCount: 0,\n errors: [],\n };\n\n for (const file of files) {\n const filePath = path.join(dirPath, file);\n const content = fs.readFileSync(filePath, \"utf-8\");\n const { data } = matter(content);\n\n const parseResult = frontmatterSchema.safeParse(data);\n if (parseResult.success) {\n result.validCount++;\n } else {\n result.valid = false;\n result.invalidCount++;\n result.errors.push({\n file,\n errors: parseResult.error.issues.map((e) => `${e.path.join(\".\")}: ${e.message}`),\n });\n }\n }\n\n return result;\n}\n\n/** Output error and exit */\nfunction exitWithError(error: string, format: string): never {\n if (format === \"json\") {\n process.stdout.write(`${JSON.stringify({ valid: false, error }, null, 2)}\\n`);\n } else {\n console.error(chalk.red(`✗ ${error}`));\n }\n process.exit(ExitCode.CONFIG_ERROR);\n}\n\n/** Resolve and validate directory path */\nfunction resolveAndValidatePath(dirPath: string, format: string): string {\n const resolvedPath = path.isAbsolute(dirPath) ? dirPath : path.resolve(process.cwd(), dirPath);\n\n if (!fs.existsSync(resolvedPath)) {\n exitWithError(`Path does not exist: ${resolvedPath}`, format);\n }\n\n const stats = fs.statSync(resolvedPath);\n if (!stats.isDirectory()) {\n exitWithError(`Path is not a directory: ${resolvedPath}`, format);\n }\n\n return resolvedPath;\n}\n\n/** Run the validate guidelines command */\nexport async function runValidateGuidelines(\n dirPath: string,\n options: { format: string }\n): Promise<void> {\n const resolvedPath = resolveAndValidatePath(dirPath, options.format);\n const result = validateGuidelinesDir(resolvedPath);\n\n if (options.format === \"json\") {\n process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n } else {\n process.stdout.write(`${formatTextOutput(result)}\\n`);\n }\n\n process.exit(result.valid ? ExitCode.SUCCESS : ExitCode.CONFIG_ERROR);\n}\n","/**\n * Fetches the standards repository from GitHub or local filesystem\n */\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { CACHE, STANDARDS_REPO, TIMEOUTS } from \"../../constants.js\";\n\nconst CACHE_DIR = path.join(os.tmpdir(), CACHE.standardsCacheDir);\n\n/** Parsed GitHub source */\ninterface GitHubSource {\n type: \"github\";\n owner: string;\n repo: string;\n ref?: string;\n}\n\n/** Parsed local source */\ninterface LocalSource {\n type: \"local\";\n path: string;\n}\n\n/** Parsed source type */\ntype ParsedSource = GitHubSource | LocalSource;\n\n/** Parse github:owner/repo[@ref] format */\nfunction parseGitHubSource(source: string): GitHubSource {\n const remainder = source.slice(7); // Remove \"github:\"\n const atIndex = remainder.indexOf(\"@\");\n const ownerRepo = atIndex !== -1 ? remainder.slice(0, atIndex) : remainder;\n const ref = atIndex !== -1 ? remainder.slice(atIndex + 1) : undefined;\n const slashIndex = ownerRepo.indexOf(\"/\");\n\n if (slashIndex === -1) {\n throw new StandardsError(`Invalid GitHub source format: ${source}. Expected github:owner/repo`);\n }\n\n const owner = ownerRepo.slice(0, slashIndex);\n const repo = ownerRepo.slice(slashIndex + 1);\n\n if (!owner || !repo) {\n throw new StandardsError(`Invalid GitHub source format: ${source}. Expected github:owner/repo`);\n }\n\n return { type: \"github\", owner, repo, ref };\n}\n\n/**\n * Parse a source string into owner/repo/ref or local path.\n * Formats:\n * - \"github:owner/repo\" - GitHub repository\n * - \"github:owner/repo@ref\" - GitHub with branch/tag\n * - Local filesystem path (absolute or relative)\n */\nfunction parseSource(source: string): ParsedSource {\n if (source.startsWith(\"github:\")) {\n return parseGitHubSource(source);\n }\n return { type: \"local\", path: source };\n}\n\n/** Error class for standards fetching failures */\nexport class StandardsError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"StandardsError\";\n }\n}\n\n/** Authentication method for GitHub */\ntype AuthMethod = \"token\" | \"ssh\" | \"none\";\n\n/**\n * Detect authentication method based on environment variables.\n * Priority: CM_REGISTRY_TOKEN > GITHUB_TOKEN > SSH key detection > none\n */\nfunction detectAuthMethod(): AuthMethod {\n if (process.env.CM_REGISTRY_TOKEN || process.env.GITHUB_TOKEN) {\n return \"token\";\n }\n if (process.env.SSH_AUTH_SOCK) {\n return \"ssh\";\n }\n return \"none\";\n}\n\n/**\n * Get the authentication token from environment variables.\n */\nfunction getAuthToken(): string | undefined {\n return process.env.CM_REGISTRY_TOKEN ?? process.env.GITHUB_TOKEN;\n}\n\n/**\n * Build the git URL for a repository based on auth method.\n */\nfunction buildGitHubUrl(auth: AuthMethod, owner: string, repo: string): string {\n switch (auth) {\n case \"ssh\":\n return `git@github.com:${owner}/${repo}.git`;\n case \"token\": {\n const token = getAuthToken();\n if (token) {\n return `https://x-access-token:${token}@github.com/${owner}/${repo}.git`;\n }\n return `https://github.com/${owner}/${repo}.git`;\n }\n case \"none\":\n default:\n return `https://github.com/${owner}/${repo}.git`;\n }\n}\n\n/**\n * Update an existing cloned repository.\n */\nasync function updateExistingRepo(repoDir: string): Promise<boolean> {\n try {\n await execa(\"git\", [\"pull\", \"--ff-only\"], { cwd: repoDir, timeout: TIMEOUTS.git });\n return true;\n } catch {\n // If update fails, remove the directory so it will be re-cloned\n fs.rmSync(repoDir, { recursive: true, force: true });\n return false;\n }\n}\n\n/**\n * Clone a repository from GitHub.\n */\nasync function cloneRepo(repoDir: string, owner: string, repo: string, ref?: string): Promise<void> {\n fs.mkdirSync(CACHE_DIR, { recursive: true });\n\n const auth = detectAuthMethod();\n const url = buildGitHubUrl(auth, owner, repo);\n\n try {\n const args = [\"clone\", \"--depth\", \"1\"];\n if (ref) {\n args.push(\"--branch\", ref);\n }\n args.push(url, repoDir);\n\n await execa(\"git\", args, {\n timeout: TIMEOUTS.git,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (message.includes(\"timed out\")) {\n throw new StandardsError(`Standards repo clone timed out after ${TIMEOUTS.git / 1000} seconds`);\n }\n throw new StandardsError(`Failed to clone standards repo: ${message}`);\n }\n}\n\n/**\n * Fetch a GitHub repository, caching it locally.\n * Returns the path to the cached repository.\n */\nasync function fetchGitHubRepo(owner: string, repo: string, ref?: string): Promise<string> {\n const cacheKey = ref ? `${owner}-${repo}-${ref}` : `${owner}-${repo}`;\n const repoDir = path.join(CACHE_DIR, cacheKey);\n\n // If repo exists, try to update it\n if (fs.existsSync(repoDir)) {\n await updateExistingRepo(repoDir);\n }\n\n // Clone if it doesn't exist (either first time or after failed update)\n if (!fs.existsSync(repoDir)) {\n await cloneRepo(repoDir, owner, repo, ref);\n }\n\n return repoDir;\n}\n\n/**\n * Resolve a local source path to an absolute path.\n */\nfunction resolveLocalPath(localPath: string, basePath?: string): string {\n if (path.isAbsolute(localPath)) {\n return localPath;\n }\n const base = basePath ?? process.cwd();\n return path.resolve(base, localPath);\n}\n\n/**\n * Fetch the standards repository from a source string.\n * Supports:\n * - \"github:owner/repo\" - GitHub repository\n * - \"github:owner/repo@ref\" - GitHub with branch/tag\n * - Local filesystem path (absolute or relative)\n *\n * @param source - Source string to fetch from\n * @param basePath - Base path for resolving relative local paths (defaults to cwd)\n * @returns Path to the standards repository\n */\nexport async function fetchStandardsRepoFromSource(\n source: string,\n basePath?: string\n): Promise<string> {\n const parsed = parseSource(source);\n\n if (parsed.type === \"local\") {\n const resolvedPath = resolveLocalPath(parsed.path, basePath);\n if (!fs.existsSync(resolvedPath)) {\n throw new StandardsError(`Local standards path does not exist: ${resolvedPath}`);\n }\n return resolvedPath;\n }\n\n return fetchGitHubRepo(parsed.owner, parsed.repo, parsed.ref);\n}\n\n/**\n * Fetch the default standards repository, caching it locally.\n * Returns the path to the cached repository.\n */\nexport async function fetchStandardsRepo(): Promise<string> {\n return fetchGitHubRepo(STANDARDS_REPO.owner, STANDARDS_REPO.repo);\n}\n\n/**\n * Get the path to the guidelines directory.\n */\nexport function getGuidelinesDir(repoPath: string): string {\n return path.join(repoPath, \"guidelines\");\n}\n\n/**\n * Get the path to the rulesets directory.\n */\nexport function getRulesetsDir(repoPath: string): string {\n return path.join(repoPath, \"rulesets\");\n}\n","/**\n * Parser for guideline markdown files with YAML frontmatter\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport matter from \"gray-matter\";\nimport { z } from \"zod\";\n\nimport { type Guideline, type GuidelineListItem, type Ruleset } from \"./types.js\";\nimport { StandardsError } from \"./fetcher.js\";\n\n/** Zod schema for validating guideline frontmatter */\nexport const frontmatterSchema = z.object({\n id: z.string(),\n title: z.string(),\n category: z.string(),\n priority: z.number(),\n tags: z.array(z.string()),\n});\n\n/**\n * Parse a guideline markdown file content into a Guideline object.\n */\nexport function parseGuideline(fileContent: string, filename: string): Guideline {\n const { data, content } = matter(fileContent);\n\n const result = frontmatterSchema.safeParse(data);\n if (!result.success) {\n const errors = result.error.issues.map((e) => `${e.path.join(\".\")}: ${e.message}`).join(\", \");\n throw new StandardsError(`Invalid frontmatter in ${filename}: ${errors}`);\n }\n\n return {\n ...result.data,\n content: content.trim(),\n };\n}\n\n/**\n * Load all guidelines from a directory.\n */\nexport function loadAllGuidelines(guidelinesDir: string): Guideline[] {\n if (!fs.existsSync(guidelinesDir)) {\n throw new StandardsError(`Guidelines directory not found: ${guidelinesDir}`);\n }\n\n const files = fs.readdirSync(guidelinesDir).filter((f) => f.endsWith(\".md\"));\n const guidelines: Guideline[] = [];\n\n for (const file of files) {\n const filePath = path.join(guidelinesDir, file);\n const content = fs.readFileSync(filePath, \"utf-8\");\n\n try {\n guidelines.push(parseGuideline(content, file));\n } catch (error) {\n // Skip files that fail to parse, log warning\n console.warn(`Warning: Failed to parse guideline ${file}: ${error}`);\n }\n }\n\n return guidelines;\n}\n\n/**\n * Load a single guideline by ID.\n */\nexport function loadGuideline(guidelinesDir: string, id: string): Guideline | null {\n const filePath = path.join(guidelinesDir, `${id}.md`);\n\n if (!fs.existsSync(filePath)) {\n return null;\n }\n\n const content = fs.readFileSync(filePath, \"utf-8\");\n return parseGuideline(content, `${id}.md`);\n}\n\n/**\n * Convert guidelines to list items (summary format).\n */\nexport function toListItems(guidelines: Guideline[]): GuidelineListItem[] {\n return guidelines.map((g) => ({\n id: g.id,\n title: g.title,\n tags: g.tags,\n category: g.category,\n }));\n}\n\n/**\n * Load a ruleset file by ID.\n */\nexport function loadRuleset(rulesetsDir: string, id: string): Ruleset | null {\n const filePath = path.join(rulesetsDir, `${id}.toml`);\n\n if (!fs.existsSync(filePath)) {\n return null;\n }\n\n const content = fs.readFileSync(filePath, \"utf-8\");\n return { id, content };\n}\n\n/**\n * List all available ruleset IDs.\n */\nexport function listRulesets(rulesetsDir: string): string[] {\n if (!fs.existsSync(rulesetsDir)) {\n return [];\n }\n\n return fs\n .readdirSync(rulesetsDir)\n .filter((f) => f.endsWith(\".toml\"))\n .map((f) => f.replace(\".toml\", \"\"));\n}\n","/**\n * Smart keyword matching logic for guidelines\n */\nimport { type Guideline, type MatchedGuideline } from \"./types.js\";\n\n/**\n * Parse a context string into keywords.\n * Extracts words, lowercases them, and removes duplicates.\n */\nexport function parseContext(context: string): string[] {\n const words = context\n .toLowerCase()\n .split(/[\\s,.\\-_/]+/)\n .filter((word) => word.length > 1);\n\n return [...new Set(words)];\n}\n\n/**\n * Score a guideline based on how many keywords match its tags.\n */\nexport function scoreGuideline(guideline: Guideline, keywords: string[]): number {\n const tags = new Set(guideline.tags.map((t) => t.toLowerCase()));\n let score = 0;\n\n for (const keyword of keywords) {\n if (tags.has(keyword)) {\n score++;\n }\n }\n\n // Also check if keyword appears in category or id\n const category = guideline.category.toLowerCase();\n const id = guideline.id.toLowerCase();\n\n for (const keyword of keywords) {\n if (category.includes(keyword) || id.includes(keyword)) {\n score += 0.5; // Partial match bonus\n }\n }\n\n return score;\n}\n\n/**\n * Match guidelines against a context string.\n * Returns guidelines sorted by score (descending) then priority (ascending).\n */\nexport function matchGuidelines(\n guidelines: Guideline[],\n context: string,\n limit?: number\n): MatchedGuideline[] {\n const keywords = parseContext(context);\n\n if (keywords.length === 0) {\n return [];\n }\n\n const scored = guidelines\n .map((guideline) => ({\n guideline,\n score: scoreGuideline(guideline, keywords),\n }))\n .filter((m) => m.score > 0);\n\n // Sort by score descending, then by priority ascending\n scored.sort((a, b) => {\n if (b.score !== a.score) {\n return b.score - a.score;\n }\n return a.guideline.priority - b.guideline.priority;\n });\n\n return limit ? scored.slice(0, limit) : scored;\n}\n\n/**\n * Compose matched guidelines into a single markdown document.\n */\nexport function composeGuidelines(matches: MatchedGuideline[]): string {\n if (matches.length === 0) {\n return \"No matching guidelines found for the given context.\";\n }\n\n const sections = matches.map((m) => {\n const { guideline } = m;\n return `# ${guideline.title}\\n\\n**Category:** ${guideline.category} | **Priority:** ${guideline.priority}\\n**Tags:** ${guideline.tags.join(\", \")}\\n\\n${guideline.content}`;\n });\n\n return sections.join(\"\\n\\n---\\n\\n\");\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport TOML from \"@iarna/toml\";\nimport chalk from \"chalk\";\n\nimport { findConfigFile } from \"../core/index.js\";\nimport {\n type Tier,\n type TierSourceDetail,\n VALID_TIERS,\n type ValidateTierOptions,\n type ValidateTierResult,\n} from \"./types.js\";\n\n/** Default tier when not specified */\nconst DEFAULT_TIER: Tier = \"internal\";\n\n/** Extends section from standards.toml */\ninterface ExtendsConfig {\n registry?: string;\n rulesets?: string[];\n}\n\n/** Metadata section from standards.toml */\ninterface MetadataConfig {\n tier?: Tier;\n project?: string;\n organisation?: string;\n status?: string;\n}\n\n/** Raw standards.toml structure (just what we need) */\ninterface RawConfig {\n metadata?: MetadataConfig;\n extends?: ExtendsConfig;\n}\n\n/** Result of getTier with detailed info */\ninterface GetTierResult {\n tier: Tier;\n source: \"standards.toml\" | \"default\";\n sourceDetail: TierSourceDetail;\n invalidValue?: string;\n}\n\n/**\n * Load and parse standards.toml to get extends section\n */\nfunction loadExtendsConfig(configPath: string): ExtendsConfig | null {\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n const parsed = TOML.parse(content) as RawConfig;\n return parsed.extends ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Load tier from standards.toml [metadata] section\n */\nfunction loadTierFromStandardsToml(configPath: string): GetTierResult {\n if (!fs.existsSync(configPath)) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (file not found)\",\n };\n }\n\n try {\n const content = fs.readFileSync(configPath, \"utf-8\");\n const parsed = TOML.parse(content) as RawConfig;\n\n if (!parsed.metadata) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (no metadata)\",\n };\n }\n\n if (parsed.metadata.tier === undefined) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (tier not specified)\",\n };\n }\n\n const tier = parsed.metadata.tier;\n\n // Check if tier value is valid\n if (!VALID_TIERS.includes(tier)) {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (invalid value)\",\n invalidValue: String(tier),\n };\n }\n\n return { tier, source: \"standards.toml\", sourceDetail: \"standards.toml\" };\n } catch {\n return {\n tier: DEFAULT_TIER,\n source: \"default\",\n sourceDetail: \"default (file not found)\",\n };\n }\n}\n\n/**\n * Check if rulesets include a tier-matching ruleset\n */\nfunction findMatchingRulesets(rulesets: string[], tier: Tier): string[] {\n const suffix = `-${tier}`;\n return rulesets.filter((ruleset) => ruleset.endsWith(suffix));\n}\n\n/**\n * Resolve the config path from options\n */\nfunction resolveConfigPath(options: ValidateTierOptions): string | null {\n if (options.config) {\n const absolutePath = path.resolve(options.config);\n return fs.existsSync(absolutePath) ? absolutePath : null;\n }\n return findConfigFile();\n}\n\n/**\n * Create result for missing config\n */\nfunction createNotFoundResult(): ValidateTierResult {\n return {\n valid: false,\n tier: DEFAULT_TIER,\n tierSource: \"default\",\n tierSourceDetail: \"default (file not found)\",\n rulesets: [],\n expectedPattern: `*-${DEFAULT_TIER}`,\n matchedRulesets: [],\n error: \"No standards.toml found\",\n };\n}\n\n/** Options for building the result */\ninterface BuildResultOptions {\n tier: Tier;\n source: \"standards.toml\" | \"default\";\n sourceDetail: TierSourceDetail;\n rulesets: string[];\n matchedRulesets: string[];\n invalidTierValue?: string;\n hasEmptyRulesets?: boolean;\n registryUrl?: string;\n warnings?: string[];\n}\n\n/**\n * Build the validation result\n */\nfunction buildResult(options: BuildResultOptions): ValidateTierResult {\n const {\n tier,\n source,\n sourceDetail,\n rulesets,\n matchedRulesets,\n invalidTierValue,\n hasEmptyRulesets,\n registryUrl,\n } = options;\n const warnings: string[] = options.warnings ?? [];\n\n const expectedPattern = `*-${tier}`;\n const valid = rulesets.length === 0 || matchedRulesets.length > 0;\n\n // Add warning for invalid tier value\n if (invalidTierValue) {\n warnings.push(\n `Invalid tier '${invalidTierValue}' in standards.toml [metadata]. Valid values are: ${VALID_TIERS.join(\", \")}`\n );\n }\n\n // Add warning for empty rulesets with registry configured\n if (hasEmptyRulesets && registryUrl) {\n warnings.push(\n `[extends] is configured with registry '${registryUrl}' but rulesets is empty - no standards will be inherited`\n );\n }\n\n return {\n valid,\n tier,\n tierSource: source,\n tierSourceDetail: sourceDetail,\n rulesets,\n expectedPattern,\n matchedRulesets,\n error: valid\n ? undefined\n : `No ruleset matching pattern '${expectedPattern}' found. Rulesets: [${rulesets.join(\", \")}]`,\n invalidTierValue,\n hasEmptyRulesets,\n registryUrl,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\n/**\n * Validate that project tier matches its rulesets.\n * This is the programmatic API exported for library consumers.\n *\n * Tier is loaded from standards.toml [metadata].tier\n * Defaults to \"internal\" if not specified\n */\nexport function validateTierRuleset(options: ValidateTierOptions = {}): ValidateTierResult {\n const configPath = resolveConfigPath(options);\n if (!configPath) {\n return createNotFoundResult();\n }\n\n const tierResult = loadTierFromStandardsToml(configPath);\n\n const extendsConfig = loadExtendsConfig(configPath);\n const rulesets = extendsConfig?.rulesets ?? [];\n const matchedRulesets = rulesets.length > 0 ? findMatchingRulesets(rulesets, tierResult.tier) : [];\n\n // Detect empty rulesets with registry configured\n const hasEmptyRulesets = extendsConfig !== null && rulesets.length === 0;\n const registryUrl = extendsConfig?.registry;\n\n return buildResult({\n tier: tierResult.tier,\n source: tierResult.source,\n sourceDetail: tierResult.sourceDetail,\n rulesets,\n matchedRulesets,\n invalidTierValue: tierResult.invalidValue,\n hasEmptyRulesets,\n registryUrl,\n });\n}\n\n/** Format warnings section */\nfunction formatWarnings(warnings: string[] | undefined): string[] {\n if (!warnings || warnings.length === 0) {\n return [];\n }\n const lines = warnings.map((w) => chalk.yellow(`⚠ Warning: ${w}`));\n lines.push(\"\"); // Empty line after warnings\n return lines;\n}\n\n/** Format the rulesets message based on configuration */\nfunction formatRulesetsMessage(result: ValidateTierResult): string {\n if (result.matchedRulesets.length > 0) {\n return ` Matching rulesets: ${result.matchedRulesets.join(\", \")}`;\n }\n if (result.hasEmptyRulesets) {\n return \" No rulesets specified (no tier constraint)\";\n }\n return \" No extends configured (no tier constraint)\";\n}\n\n/** Format the failed validation section */\nfunction formatFailedValidation(result: ValidateTierResult, sourceDisplay: string): string[] {\n const lines = [\n chalk.red(\"✗ Tier validation failed\"),\n ` Tier: ${result.tier} (source: ${sourceDisplay})`,\n ` Expected pattern: ${result.expectedPattern}`,\n ` Rulesets: [${result.rulesets.join(\", \")}]`,\n ];\n if (result.error) {\n lines.push(chalk.red(` Error: ${result.error}`));\n }\n if (result.invalidTierValue) {\n lines.push(\"\");\n lines.push(\n chalk.cyan(\n ` Hint: Update standards.toml [metadata].tier to use a valid value: ${VALID_TIERS.join(\", \")}`\n )\n );\n }\n return lines;\n}\n\n/**\n * Format tier validation result as text\n */\nexport function formatTierResultText(result: ValidateTierResult): string {\n const lines: string[] = formatWarnings(result.warnings);\n const sourceDisplay = result.tierSourceDetail ?? result.tierSource;\n\n if (result.valid) {\n lines.push(chalk.green(\"✓ Tier validation passed\"));\n lines.push(` Tier: ${result.tier} (source: ${sourceDisplay})`);\n lines.push(formatRulesetsMessage(result));\n } else {\n lines.push(...formatFailedValidation(result, sourceDisplay));\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Format tier validation result as JSON\n */\nexport function formatTierResultJson(result: ValidateTierResult): string {\n return JSON.stringify(result, null, 2);\n}\n","/**\n * Valid project tiers\n */\nexport type Tier = \"production\" | \"internal\" | \"prototype\";\n\n/**\n * Valid tier values as a constant array for validation and export\n */\nexport const VALID_TIERS: readonly Tier[] = [\"production\", \"internal\", \"prototype\"];\n\n/**\n * Detailed tier source indicating why a default was used\n */\nexport type TierSourceDetail =\n | \"standards.toml\" // Tier was read from [metadata] section\n | \"default\" // Generic default (for backwards compatibility)\n | \"default (file not found)\" // standards.toml doesn't exist\n | \"default (no metadata)\" // standards.toml exists but no [metadata] section\n | \"default (tier not specified)\" // [metadata] exists but no tier key\n | \"default (invalid value)\"; // [metadata] has tier but value is invalid\n\n/**\n * Options for the tier validation command\n */\nexport interface ValidateTierOptions {\n /** Path to standards.toml config file */\n config?: string;\n /** Output format */\n format?: \"text\" | \"json\";\n}\n\n/**\n * Result of tier validation\n */\nexport interface ValidateTierResult {\n /** Whether validation passed */\n valid: boolean;\n /** Project tier from standards.toml [metadata] (defaults to \"internal\") */\n tier: Tier;\n /** Source of tier value */\n tierSource: \"standards.toml\" | \"default\";\n /** Detailed source of tier value with reason for default */\n tierSourceDetail?: TierSourceDetail;\n /** Rulesets from standards.toml extends section */\n rulesets: string[];\n /** Expected ruleset suffix pattern */\n expectedPattern: string;\n /** Matched rulesets (those that satisfy the tier requirement) */\n matchedRulesets: string[];\n /** Error message if invalid */\n error?: string;\n /** Invalid tier value that was rejected (for error messages) */\n invalidTierValue?: string;\n /** Whether extends is configured but has empty rulesets */\n hasEmptyRulesets?: boolean;\n /** Registry URL if extends is configured */\n registryUrl?: string;\n /** Warnings about configuration */\n warnings?: string[];\n}\n","/**\n * MCP Server for coding standards\n */\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n\nimport { loadConfigAsync } from \"../core/index.js\";\nimport {\n createGetGuidelineHandler,\n getGuidelineInputSchema,\n createGetRulesetHandler,\n getRulesetInputSchema,\n createGetStandardsHandler,\n getStandardsInputSchema,\n createListGuidelinesHandler,\n listGuidelinesInputSchema,\n} from \"./tools/index.js\";\n\n/** Options for creating the MCP server */\nexport interface CreateServerOptions {\n /** Standards repository source (e.g., \"github:owner/repo\" or local path) */\n standardsSource?: string;\n}\n\n/**\n * Create and configure the MCP server with all tools registered.\n */\nexport function createServer(options: CreateServerOptions = {}): McpServer {\n const server = new McpServer({\n name: \"cm-standards\",\n version: \"1.0.0\",\n });\n\n const { standardsSource } = options;\n\n // Register get_standards tool - smart context matching\n server.registerTool(\"get_standards\", {\n description:\n \"Get composed coding standards matching a context string. Use this to fetch relevant guidelines for a specific technology stack or task.\",\n inputSchema: getStandardsInputSchema,\n }, createGetStandardsHandler(standardsSource));\n\n // Register list_guidelines tool\n server.registerTool(\"list_guidelines\", {\n description: \"List all available coding guidelines with optional category filter.\",\n inputSchema: listGuidelinesInputSchema,\n }, createListGuidelinesHandler(standardsSource));\n\n // Register get_guideline tool\n server.registerTool(\"get_guideline\", {\n description: \"Get a single coding guideline by its ID.\",\n inputSchema: getGuidelineInputSchema,\n }, createGetGuidelineHandler(standardsSource));\n\n // Register get_ruleset tool\n server.registerTool(\"get_ruleset\", {\n description:\n \"Get a tool configuration ruleset by ID (e.g., typescript-production, python-internal).\",\n inputSchema: getRulesetInputSchema,\n }, createGetRulesetHandler(standardsSource));\n\n return server;\n}\n\n/**\n * Start the MCP server with stdio transport.\n * Loads configuration from standards.toml to get the standards source.\n */\nexport async function startServer(): Promise<void> {\n let standardsSource: string | undefined;\n\n // Try to load config to get standards source\n try {\n const { config } = await loadConfigAsync();\n standardsSource = config.mcp?.standards?.source;\n } catch {\n // Config not found or invalid, use defaults\n }\n\n const server = createServer({ standardsSource });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n","/**\n * MCP tool: get_guideline\n * Gets a single coding guideline by ID\n */\nimport { z } from \"zod\";\n\nimport {\n fetchStandardsRepo,\n fetchStandardsRepoFromSource,\n getGuidelinesDir,\n loadGuideline,\n} from \"../standards/index.js\";\n\n/** Input schema for get_guideline tool */\nexport const getGuidelineInputSchema = {\n id: z.string().describe('Guideline ID (e.g., \"auth\", \"database\", \"typescript\")'),\n};\n\n/** Handler result type - must have index signature for MCP SDK */\ninterface HandlerResult {\n [x: string]: unknown;\n content: { type: \"text\"; text: string }[];\n isError?: boolean;\n}\n\n/**\n * Create a get_guideline handler with optional custom source.\n * @param source - Optional standards source (e.g., \"github:owner/repo\" or local path)\n */\nexport function createGetGuidelineHandler(\n source?: string\n): (args: { id: string }) => Promise<HandlerResult> {\n return async (args) => {\n const repoPath = source\n ? await fetchStandardsRepoFromSource(source)\n : await fetchStandardsRepo();\n const guidelinesDir = getGuidelinesDir(repoPath);\n const guideline = loadGuideline(guidelinesDir, args.id);\n\n if (!guideline) {\n return {\n content: [\n {\n type: \"text\",\n text: `Guideline not found: ${args.id}`,\n },\n ],\n isError: true,\n };\n }\n\n // Return full markdown content with frontmatter info\n const header = `# ${guideline.title}\\n\\n**Category:** ${guideline.category} | **Priority:** ${guideline.priority}\\n**Tags:** ${guideline.tags.join(\", \")}\\n\\n---\\n\\n`;\n\n return {\n content: [\n {\n type: \"text\",\n text: header + guideline.content,\n },\n ],\n };\n };\n}\n","/**\n * MCP tool: get_ruleset\n * Gets a tool configuration ruleset by ID\n */\nimport { z } from \"zod\";\n\nimport {\n fetchStandardsRepo,\n fetchStandardsRepoFromSource,\n getRulesetsDir,\n loadRuleset,\n listRulesets,\n} from \"../standards/index.js\";\n\n/** Input schema for get_ruleset tool */\nexport const getRulesetInputSchema = {\n id: z.string().describe('Ruleset ID (e.g., \"typescript-production\", \"python-internal\")'),\n};\n\n/** Handler result type - must have index signature for MCP SDK */\ninterface HandlerResult {\n [x: string]: unknown;\n content: { type: \"text\"; text: string }[];\n isError?: boolean;\n}\n\n/**\n * Create a get_ruleset handler with optional custom source.\n * @param source - Optional standards source (e.g., \"github:owner/repo\" or local path)\n */\nexport function createGetRulesetHandler(\n source?: string\n): (args: { id: string }) => Promise<HandlerResult> {\n return async (args) => {\n const repoPath = source\n ? await fetchStandardsRepoFromSource(source)\n : await fetchStandardsRepo();\n const rulesetsDir = getRulesetsDir(repoPath);\n const ruleset = loadRuleset(rulesetsDir, args.id);\n\n if (!ruleset) {\n const available = listRulesets(rulesetsDir);\n return {\n content: [\n {\n type: \"text\",\n text: `Ruleset not found: ${args.id}\\n\\nAvailable rulesets:\\n${available.map((r) => `- ${r}`).join(\"\\n\")}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: \"text\",\n text: `# Ruleset: ${ruleset.id}\\n\\n\\`\\`\\`toml\\n${ruleset.content}\\n\\`\\`\\``,\n },\n ],\n };\n };\n}\n","/**\n * MCP tool: get_standards\n * Gets composed coding standards matching a context string\n */\nimport { z } from \"zod\";\n\nimport {\n fetchStandardsRepo,\n fetchStandardsRepoFromSource,\n getGuidelinesDir,\n loadAllGuidelines,\n matchGuidelines,\n composeGuidelines,\n} from \"../standards/index.js\";\n\n/** Input schema for get_standards tool */\nexport const getStandardsInputSchema = {\n context: z\n .string()\n .describe(\n 'Context string describing the task or technology stack (e.g., \"python fastapi llm postgresql\")'\n ),\n limit: z.number().optional().describe(\"Maximum number of guidelines to return (default: 5)\"),\n};\n\n/** Handler result type - must have index signature for MCP SDK */\ninterface HandlerResult {\n [x: string]: unknown;\n content: { type: \"text\"; text: string }[];\n}\n\n/**\n * Create a get_standards handler with optional custom source.\n * @param source - Optional standards source (e.g., \"github:owner/repo\" or local path)\n */\nexport function createGetStandardsHandler(\n source?: string\n): (args: { context: string; limit?: number }) => Promise<HandlerResult> {\n return async (args) => {\n const repoPath = source\n ? await fetchStandardsRepoFromSource(source)\n : await fetchStandardsRepo();\n const guidelinesDir = getGuidelinesDir(repoPath);\n const guidelines = loadAllGuidelines(guidelinesDir);\n\n const limit = args.limit ?? 5;\n const matches = matchGuidelines(guidelines, args.context, limit);\n\n const composed = composeGuidelines(matches);\n\n // Add summary header\n const summary =\n matches.length > 0\n ? `Found ${matches.length} matching guideline(s) for context: \"${args.context}\"\\n\\nMatched guidelines (by relevance):\\n${matches.map((m) => `- ${m.guideline.title} (score: ${m.score.toFixed(1)})`).join(\"\\n\")}\\n\\n---\\n\\n`\n : \"\";\n\n return {\n content: [\n {\n type: \"text\",\n text: summary + composed,\n },\n ],\n };\n };\n}\n","/**\n * MCP tool: list_guidelines\n * Lists all available coding guidelines with optional category filter\n */\nimport { z } from \"zod\";\n\nimport {\n fetchStandardsRepo,\n fetchStandardsRepoFromSource,\n getGuidelinesDir,\n loadAllGuidelines,\n toListItems,\n} from \"../standards/index.js\";\n\n/** Input schema for list_guidelines tool */\nexport const listGuidelinesInputSchema = {\n category: z.string().optional().describe(\"Optional category filter (e.g., 'security', 'infrastructure')\"),\n};\n\n/** Handler result type - must have index signature for MCP SDK */\ninterface HandlerResult {\n [x: string]: unknown;\n content: { type: \"text\"; text: string }[];\n}\n\n/**\n * Create a list_guidelines handler with optional custom source.\n * @param source - Optional standards source (e.g., \"github:owner/repo\" or local path)\n */\nexport function createListGuidelinesHandler(\n source?: string\n): (args: { category?: string }) => Promise<HandlerResult> {\n return async (args) => {\n const repoPath = source\n ? await fetchStandardsRepoFromSource(source)\n : await fetchStandardsRepo();\n const guidelinesDir = getGuidelinesDir(repoPath);\n let guidelines = loadAllGuidelines(guidelinesDir);\n\n // Filter by category if provided\n if (args.category) {\n const categoryLower = args.category.toLowerCase();\n guidelines = guidelines.filter((g) => g.category.toLowerCase() === categoryLower);\n }\n\n const items = toListItems(guidelines);\n\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(items, null, 2),\n },\n ],\n };\n };\n}\n","/**\n * Infra scan module - Public API\n *\n * Provides functionality to verify AWS resources declared in a manifest actually exist.\n */\n\nimport * as path from \"node:path\";\n\nimport chalk from \"chalk\";\n\nimport { getProjectRoot, loadConfigAsync } from \"../core/index.js\";\nimport { ExitCode } from \"../core/index.js\";\n\nimport { ManifestError, readManifest } from \"./manifest.js\";\nimport { formatScan } from \"./output.js\";\nimport { scanManifest } from \"./scan.js\";\nimport type { InfraScanResult, RunInfraScanOptions, ScanInfraOptions } from \"./types.js\";\n\n// Re-export types\nexport type {\n AccountId,\n AccountScanResult,\n Arn,\n CloudProvider,\n GcpResourcePath,\n InfraScanResult,\n InfraScanSummary,\n LegacyManifest,\n Manifest,\n ManifestAccount,\n MultiAccountManifest,\n ParsedArn,\n ParsedGcpResource,\n PulumiResource,\n PulumiStackExport,\n ResourceCheckResult,\n ResourceIdentifier,\n ScanInfraOptions,\n} from \"./types.js\";\n\n// Re-export Zod schemas and validation functions for public API\nexport {\n // Schemas - for external consumers to validate manifests\n ArnSchema,\n AccountIdSchema,\n AccountKeySchema,\n CloudProviderSchema,\n GcpResourcePathSchema,\n InfraScanResultSchema,\n InfraScanSummarySchema,\n LegacyManifestSchema,\n ManifestAccountSchema,\n ManifestSchema,\n MultiAccountManifestSchema,\n ParsedArnSchema,\n ParsedGcpResourceSchema,\n PulumiResourceSchema,\n PulumiStackExportSchema,\n ResourceCheckResultSchema,\n ResourceIdentifierSchema,\n // Validation functions\n isValidArnFormat,\n isValidGcpResourcePath,\n isValidAccountKey,\n isMultiAccountManifestSchema,\n isLegacyManifestSchema,\n validateArn,\n validateGcpResourcePath,\n validateAccountKey,\n validateManifest,\n validateMultiAccountManifest,\n validateLegacyManifest,\n validateStackExport,\n} from \"./types.js\";\nexport {\n ManifestError,\n isMultiAccountManifest,\n isLegacyManifest,\n parseAccountKey,\n formatAccountKey,\n normalizeManifest,\n detectAccountFromResource,\n getAllResources,\n} from \"./manifest.js\";\nexport { parseArn, isValidArn } from \"./arn.js\";\nexport { parseGcpResource, isValidGcpResource } from \"./gcp.js\";\nexport { SUPPORTED_SERVICES, isSupportedService } from \"./checkers/index.js\";\nexport { SUPPORTED_GCP_SERVICES, isSupportedGcpService } from \"./checkers/gcp/index.js\";\n\n// Re-export generate functionality\nexport {\n DEFAULT_MANIFEST_NAME,\n generateManifestFromStdin,\n generateManifestFromFile,\n generateMultiAccountFromStdin,\n generateMultiAccountFromFile,\n generateWithMerge,\n mergeIntoManifest,\n parseStackExport,\n parseStackExportMultiAccount,\n readExistingManifest,\n writeManifest,\n type GenerateManifestOptions,\n} from \"./generate.js\";\n\n/**\n * Scan infrastructure resources declared in a manifest.\n *\n * This is the programmatic API for @standards-kit/drift integration.\n *\n * @param options - Options for the scan\n * @returns Scan result with all resource check results and summary\n *\n * @example\n * ```typescript\n * import { scanInfra } from \"@standards-kit/conform\";\n *\n * const result = await scanInfra({ manifestPath: \"./infra-manifest.json\" });\n * console.log(result.summary);\n * // { total: 5, found: 4, missing: 1, errors: 0 }\n * ```\n */\nexport async function scanInfra(options: ScanInfraOptions = {}): Promise<InfraScanResult> {\n const resolvedManifestPath = await resolveManifestPath(options);\n const manifest = readManifest(resolvedManifestPath);\n return scanManifest(manifest, resolvedManifestPath, { account: options.account });\n}\n\nasync function resolveManifestPath(options: ScanInfraOptions): Promise<string> {\n const { manifestPath, configPath } = options;\n\n if (manifestPath) {\n return path.isAbsolute(manifestPath)\n ? manifestPath\n : path.resolve(process.cwd(), manifestPath);\n }\n\n const { config, configPath: loadedConfigPath } = await loadConfigAsync(configPath);\n const projectRoot = getProjectRoot(loadedConfigPath);\n\n const infraConfig = config.infra;\n if (!infraConfig?.enabled) {\n throw new ManifestError(\"Infra scanning is not enabled in standards.toml\");\n }\n\n const manifestName = infraConfig.manifest;\n return path.resolve(projectRoot, manifestName);\n}\n\n/**\n * Run infra scan from CLI\n */\nexport async function runInfraScan(options: RunInfraScanOptions = {}): Promise<void> {\n const { format = \"text\", manifestPath, configPath, account } = options;\n\n try {\n const result = await scanInfra({ manifestPath, configPath, account });\n outputResult(result, format);\n } catch (error) {\n handleError(error, format);\n }\n}\n\nfunction outputResult(result: InfraScanResult, format: \"text\" | \"json\"): never {\n process.stdout.write(`${formatScan(result, format)}\\n`);\n\n if (result.summary.errors > 0) {\n process.exit(ExitCode.RUNTIME_ERROR);\n } else if (result.summary.missing > 0) {\n process.exit(ExitCode.VIOLATIONS_FOUND);\n } else {\n process.exit(ExitCode.SUCCESS);\n }\n}\n\nfunction handleError(error: unknown, format: \"text\" | \"json\"): never {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n const isConfigError = error instanceof ManifestError;\n\n if (format === \"json\") {\n process.stdout.write(`${JSON.stringify({ error: message }, null, 2)}\\n`);\n } else {\n console.error(chalk.red(`Error: ${message}`));\n }\n\n process.exit(isConfigError ? ExitCode.CONFIG_ERROR : ExitCode.RUNTIME_ERROR);\n}\n\n/**\n * Options for CLI generate command\n */\nexport interface RunInfraGenerateOptions {\n /** Input file path (if not provided, reads from stdin) */\n input?: string;\n /** Output file path (defaults to infra-manifest.json) */\n output?: string;\n /** Project name override */\n project?: string;\n /** Output to stdout instead of file */\n stdout?: boolean;\n /** Account alias (e.g., \"prod-aws\") for multi-account manifests */\n account?: string;\n /** Explicit account ID (e.g., \"aws:111111111111\") */\n accountId?: string;\n /** Merge into existing manifest instead of overwriting */\n merge?: boolean;\n}\n\n/**\n * Run infra generate from CLI\n */\nexport async function runInfraGenerate(options: RunInfraGenerateOptions = {}): Promise<void> {\n const {\n generateWithMerge,\n writeManifest,\n DEFAULT_MANIFEST_NAME,\n } = await import(\"./generate.js\");\n const { getAllResources, isMultiAccountManifest } = await import(\"./manifest.js\");\n\n try {\n const manifest = await generateWithMerge(options.input, {\n project: options.project,\n output: options.output,\n account: options.account,\n accountId: options.accountId,\n merge: options.merge,\n });\n\n writeManifest(manifest, { output: options.output, stdout: options.stdout });\n\n if (!options.stdout) {\n const outputPath = options.output ?? DEFAULT_MANIFEST_NAME;\n const resourceCount = getAllResources(manifest).length;\n const accountCount = isMultiAccountManifest(manifest)\n ? Object.keys(manifest.accounts).length\n : 1;\n const accountLabel = accountCount === 1 ? \"account\" : \"accounts\";\n\n console.error(\n chalk.green(`✓ Generated ${outputPath} with ${resourceCount} resources across ${accountCount} ${accountLabel}`)\n );\n }\n\n process.exit(ExitCode.SUCCESS);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n console.error(chalk.red(`Error: ${message}`));\n process.exit(ExitCode.RUNTIME_ERROR);\n }\n}\n","/**\n * Output formatters for infra scan results\n */\n\nimport chalk from \"chalk\";\n\nimport type { AccountScanResult, InfraScanResult, ResourceCheckResult } from \"./types.js\";\n\n/**\n * Format scan result as text output\n */\nfunction formatScanText(result: InfraScanResult): string {\n const lines: string[] = [];\n\n formatHeader(lines, result);\n\n // If we have account results, format by account\n if (result.accountResults && Object.keys(result.accountResults).length > 0) {\n formatAccountResults(lines, result.accountResults);\n formatOverallSummary(lines, result.summary);\n } else {\n // Legacy format - flat results\n formatResultsByStatus(lines, result.results);\n formatSummary(lines, result.summary);\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction formatHeader(lines: string[], result: InfraScanResult): void {\n lines.push(chalk.bold(\"Infrastructure Scan Results\"));\n lines.push(`Manifest: ${result.manifest}`);\n if (result.project) {\n lines.push(`Project: ${result.project}`);\n }\n lines.push(\"\");\n}\n\nfunction formatResultsByStatus(lines: string[], results: ResourceCheckResult[]): void {\n const found = results.filter((r) => r.exists && !r.error);\n const missing = results.filter((r) => !r.exists && !r.error);\n const errors = results.filter((r) => r.error);\n\n formatResultSection(lines, found, {\n colorFn: chalk.green.bold,\n label: \"Found\",\n formatLine: formatFoundLine,\n });\n formatResultSection(lines, missing, {\n colorFn: chalk.red.bold,\n label: \"Missing\",\n formatLine: formatMissingLine,\n });\n formatResultSection(lines, errors, {\n colorFn: chalk.yellow.bold,\n label: \"Errors\",\n formatLine: formatErrorLine,\n });\n}\n\ninterface SectionConfig {\n colorFn: (s: string) => string;\n label: string;\n formatLine: (r: ResourceCheckResult) => string;\n}\n\nfunction formatResultSection(\n lines: string[],\n results: ResourceCheckResult[],\n config: SectionConfig\n): void {\n if (results.length === 0) {\n return;\n }\n lines.push(config.colorFn(`${config.label} (${results.length}):`));\n for (const r of results) {\n lines.push(config.formatLine(r));\n }\n lines.push(\"\");\n}\n\nfunction formatFoundLine(r: ResourceCheckResult): string {\n const icon = chalk.green(\"✓\");\n const resourceInfo = `${r.service}/${r.resourceType}/${r.resourceId}`;\n return ` ${icon} ${resourceInfo}`;\n}\n\nfunction formatMissingLine(r: ResourceCheckResult): string {\n const icon = chalk.red(\"✗\");\n const resourceInfo = `${r.service}/${r.resourceType}/${r.resourceId}`;\n return ` ${icon} ${resourceInfo}`;\n}\n\nfunction formatErrorLine(r: ResourceCheckResult): string {\n const icon = chalk.yellow(\"!\");\n const resourceInfo = `${r.service}/${r.resourceType}/${r.resourceId}`;\n const errorText = r.error ?? \"Unknown error\";\n return ` ${icon} ${resourceInfo} - ${chalk.yellow(errorText)}`;\n}\n\nfunction formatSummary(\n lines: string[],\n summary: { total: number; found: number; missing: number; errors: number }\n): void {\n lines.push(chalk.bold(\"Summary:\"));\n lines.push(` Total: ${summary.total}`);\n lines.push(chalk.green(` Found: ${summary.found}`));\n lines.push(chalk.red(` Missing: ${summary.missing}`));\n if (summary.errors > 0) {\n lines.push(chalk.yellow(` Errors: ${summary.errors}`));\n }\n}\n\n/**\n * Format overall summary for multi-account manifests\n */\nfunction formatOverallSummary(\n lines: string[],\n summary: { total: number; found: number; missing: number; errors: number }\n): void {\n lines.push(chalk.bold(\"Overall Summary:\"));\n lines.push(` Total: ${summary.total}`);\n lines.push(chalk.green(` Found: ${summary.found}`));\n lines.push(chalk.red(` Missing: ${summary.missing}`));\n if (summary.errors > 0) {\n lines.push(chalk.yellow(` Errors: ${summary.errors}`));\n }\n}\n\n/**\n * Format results grouped by account\n */\nfunction formatAccountResults(\n lines: string[],\n accountResults: Record<string, AccountScanResult>\n): void {\n for (const [accountKey, account] of Object.entries(accountResults)) {\n const accountLabel = account.alias\n ? `${account.alias} (${accountKey})`\n : accountKey;\n\n lines.push(chalk.bold.cyan(`\\nAccount: ${accountLabel}`));\n lines.push(chalk.gray(\"─\".repeat(40)));\n\n // Format results for this account\n formatAccountResourceResults(lines, account.results);\n\n // Account-level summary\n const { summary } = account;\n const summaryParts: string[] = [];\n if (summary.found > 0) {\n summaryParts.push(chalk.green(`${summary.found} found`));\n }\n if (summary.missing > 0) {\n summaryParts.push(chalk.red(`${summary.missing} missing`));\n }\n if (summary.errors > 0) {\n summaryParts.push(chalk.yellow(`${summary.errors} errors`));\n }\n lines.push(` ${chalk.dim(\"Summary:\")} ${summaryParts.join(\", \")}`);\n }\n lines.push(\"\");\n}\n\n/**\n * Format resource results for a single account (inline style)\n */\nfunction formatAccountResourceResults(lines: string[], results: ResourceCheckResult[]): void {\n for (const r of results) {\n if (r.error) {\n const icon = chalk.yellow(\"!\");\n lines.push(` ${icon} ${r.arn} - ${chalk.yellow(r.error)}`);\n } else if (r.exists) {\n const icon = chalk.green(\"✓\");\n lines.push(` ${icon} ${r.arn}`);\n } else {\n const icon = chalk.red(\"✗\");\n lines.push(` ${icon} ${r.arn}`);\n }\n }\n}\n\n/**\n * Format scan result as JSON output\n */\nfunction formatScanJson(result: InfraScanResult): string {\n return JSON.stringify(result, null, 2);\n}\n\n/**\n * Format scan result based on output format\n */\nexport function formatScan(result: InfraScanResult, format: \"text\" | \"json\"): string {\n return format === \"json\" ? formatScanJson(result) : formatScanText(result);\n}\n","/**\n * Checker registry with lazy loading\n *\n * Checkers are loaded on-demand to avoid loading all AWS SDK clients upfront.\n */\n\nimport type { ResourceChecker } from \"./types.js\";\n\n/**\n * Supported AWS services for resource checking\n */\nexport const SUPPORTED_SERVICES = [\n \"s3\",\n \"lambda\",\n \"dynamodb\",\n \"sqs\",\n \"sns\",\n \"iam\",\n \"secretsmanager\",\n \"logs\",\n \"ecs\",\n \"rds\",\n \"ec2\",\n \"elasticache\",\n \"elasticloadbalancing\",\n] as const;\n\nexport type SupportedService = (typeof SUPPORTED_SERVICES)[number];\n\n/**\n * Check if a service is supported\n */\nexport function isSupportedService(service: string): service is SupportedService {\n return SUPPORTED_SERVICES.includes(service as SupportedService);\n}\n\n/**\n * Factory functions for checkers (lazy-loaded)\n */\nconst checkerFactories: Record<SupportedService, () => Promise<ResourceChecker>> = {\n s3: async () => (await import(\"./s3.js\")).S3Checker,\n lambda: async () => (await import(\"./lambda.js\")).LambdaChecker,\n dynamodb: async () => (await import(\"./dynamodb.js\")).DynamoDBChecker,\n sqs: async () => (await import(\"./sqs.js\")).SQSChecker,\n sns: async () => (await import(\"./sns.js\")).SNSChecker,\n iam: async () => (await import(\"./iam.js\")).IAMChecker,\n secretsmanager: async () => (await import(\"./secretsmanager.js\")).SecretsManagerChecker,\n logs: async () => (await import(\"./cloudwatch.js\")).CloudWatchLogsChecker,\n ecs: async () => (await import(\"./ecs.js\")).ECSChecker,\n rds: async () => (await import(\"./rds.js\")).RDSChecker,\n ec2: async () => (await import(\"./ec2.js\")).EC2Checker,\n elasticache: async () => (await import(\"./elasticache.js\")).ElastiCacheChecker,\n elasticloadbalancing: async () => (await import(\"./elb.js\")).ELBChecker,\n};\n\n/**\n * Cache of loaded checkers\n */\nconst checkerCache = new Map<SupportedService, ResourceChecker>();\n\n/**\n * Get a checker for a service, loading it if necessary\n *\n * @param service - The AWS service name\n * @returns The checker instance, or undefined if the service is not supported\n */\nexport async function getChecker(service: string): Promise<ResourceChecker | undefined> {\n if (!isSupportedService(service)) {\n return undefined;\n }\n\n // Return cached checker if available\n const cached = checkerCache.get(service);\n if (cached) {\n return cached;\n }\n\n // Load and cache the checker\n const factory = checkerFactories[service];\n const checker = await factory();\n checkerCache.set(service, checker);\n\n return checker;\n}\n\n/**\n * Clear the checker cache (useful for testing)\n */\nexport function clearCheckerCache(): void {\n checkerCache.clear();\n}\n","/**\n * GCP checker registry with lazy loading\n */\n\nimport type { GcpResourceChecker } from \"../types.js\";\n\n/**\n * Supported GCP services for resource checking\n */\nexport const SUPPORTED_GCP_SERVICES = [\"run\", \"secretmanager\", \"artifactregistry\", \"iam\"] as const;\n\nexport type SupportedGcpService = (typeof SUPPORTED_GCP_SERVICES)[number];\n\n/**\n * Check if a GCP service is supported\n */\nexport function isSupportedGcpService(service: string): service is SupportedGcpService {\n return SUPPORTED_GCP_SERVICES.includes(service as SupportedGcpService);\n}\n\n/**\n * Factory functions for GCP checkers (lazy-loaded)\n */\nconst checkerFactories: Record<SupportedGcpService, () => Promise<GcpResourceChecker>> = {\n run: async () => (await import(\"./cloudrun.js\")).CloudRunChecker,\n secretmanager: async () => (await import(\"./secretmanager.js\")).SecretManagerChecker,\n artifactregistry: async () => (await import(\"./artifactregistry.js\")).ArtifactRegistryChecker,\n iam: async () => (await import(\"./iam.js\")).ServiceAccountChecker,\n};\n\n/**\n * Cache of loaded GCP checkers\n */\nconst checkerCache = new Map<SupportedGcpService, GcpResourceChecker>();\n\n/**\n * Get a GCP checker for a service, loading it if necessary\n */\nexport async function getGcpChecker(service: string): Promise<GcpResourceChecker | undefined> {\n if (!isSupportedGcpService(service)) {\n return undefined;\n }\n\n const cached = checkerCache.get(service);\n if (cached) {\n return cached;\n }\n\n const factory = checkerFactories[service];\n const checker = await factory();\n checkerCache.set(service, checker);\n\n return checker;\n}\n","/**\n * Scan logic for infra scan\n *\n * Orchestrates checking all resources in a manifest (AWS and GCP)\n */\n\nimport { CONCURRENCY } from \"../constants.js\";\nimport { isValidArn, parseArn } from \"./arn.js\";\nimport { getChecker, isSupportedService, SUPPORTED_SERVICES } from \"./checkers/index.js\";\nimport {\n getGcpChecker,\n isSupportedGcpService,\n SUPPORTED_GCP_SERVICES,\n} from \"./checkers/gcp/index.js\";\nimport { isValidGcpResource, parseGcpResource } from \"./gcp.js\";\nimport { getAllResources, isMultiAccountManifest } from \"./manifest.js\";\nimport type {\n AccountScanResult,\n InfraScanResult,\n InfraScanSummary,\n Manifest,\n MultiAccountManifest,\n ResourceCheckResult,\n} from \"./types.js\";\n\n/**\n * Options for scanning\n */\ninterface ScanOptions {\n /** Max number of parallel checks */\n concurrency?: number;\n /** Filter to specific account (by alias or account key) */\n account?: string;\n}\n\n/**\n * Scan all resources in a manifest\n *\n * @param manifest - The manifest containing resources to check\n * @param manifestPath - Path to the manifest file (for result metadata)\n * @param options - Scan options\n * @returns Scan result with all resource check results and summary\n */\nexport async function scanManifest(\n manifest: Manifest,\n manifestPath: string,\n options: ScanOptions = {}\n): Promise<InfraScanResult> {\n const concurrency = options.concurrency ?? CONCURRENCY.infraScan;\n\n // For multi-account manifests, scan by account\n if (isMultiAccountManifest(manifest)) {\n return scanMultiAccountManifest(manifest, manifestPath, options);\n }\n\n // Legacy manifest - simple flat scan\n const resources = getAllResources(manifest);\n const results = await checkResourcesWithConcurrency(resources, concurrency);\n const summary = calculateSummary(results);\n\n return {\n manifest: manifestPath,\n project: manifest.project,\n results,\n summary,\n };\n}\n\n/**\n * Scan a multi-account manifest\n */\nasync function scanMultiAccountManifest(\n manifest: MultiAccountManifest,\n manifestPath: string,\n options: ScanOptions = {}\n): Promise<InfraScanResult> {\n const concurrency = options.concurrency ?? CONCURRENCY.infraScan;\n const accountResults: Record<string, AccountScanResult> = {};\n const allResults: ResourceCheckResult[] = [];\n\n // Get accounts to scan (filter by account if specified)\n const accountsToScan = filterAccounts(manifest, options.account);\n\n for (const [accountKey, account] of Object.entries(accountsToScan)) {\n const results = await checkResourcesWithConcurrency(account.resources, concurrency);\n const summary = calculateSummary(results);\n\n accountResults[accountKey] = {\n alias: account.alias,\n results,\n summary,\n };\n\n allResults.push(...results);\n }\n\n // Calculate overall summary\n const overallSummary = calculateSummary(allResults);\n\n return {\n manifest: manifestPath,\n project: manifest.project,\n results: allResults,\n summary: overallSummary,\n accountResults,\n };\n}\n\n/**\n * Filter accounts based on account filter\n * Returns matching accounts or all accounts if no filter\n */\nfunction filterAccounts(\n manifest: MultiAccountManifest,\n accountFilter?: string\n): Record<string, { alias?: string; resources: string[] }> {\n if (!accountFilter) {\n return manifest.accounts;\n }\n\n // Check if filter is an account key (e.g., \"aws:123456\")\n if (accountFilter in manifest.accounts) {\n return { [accountFilter]: manifest.accounts[accountFilter] };\n }\n\n // Check if filter matches an alias\n for (const [key, account] of Object.entries(manifest.accounts)) {\n if (account.alias === accountFilter) {\n return { [key]: account };\n }\n }\n\n // No match found - return empty\n return {};\n}\n\n/**\n * Check resources with controlled concurrency using a simple batching approach\n */\nasync function checkResourcesWithConcurrency(\n arns: string[],\n concurrency: number\n): Promise<ResourceCheckResult[]> {\n const results: ResourceCheckResult[] = [];\n\n // Process in batches\n for (let i = 0; i < arns.length; i += concurrency) {\n const batch = arns.slice(i, i + concurrency);\n const batchResults = await Promise.all(batch.map((arn) => checkResource(arn)));\n results.push(...batchResults);\n }\n\n // Sort results to maintain consistent order (by ARN)\n results.sort((a, b) => a.arn.localeCompare(b.arn));\n\n return results;\n}\n\n/**\n * Check a single resource (AWS or GCP)\n */\nasync function checkResource(resource: string): Promise<ResourceCheckResult> {\n // Detect cloud provider and route to appropriate checker\n if (isValidArn(resource)) {\n return checkAwsResource(resource);\n }\n if (isValidGcpResource(resource)) {\n return checkGcpResource(resource);\n }\n\n return {\n arn: resource,\n exists: false,\n error: \"Invalid resource format (not a valid AWS ARN or GCP resource path)\",\n service: \"unknown\",\n resourceType: \"unknown\",\n resourceId: resource,\n };\n}\n\n/**\n * Check an AWS resource\n */\nasync function checkAwsResource(arn: string): Promise<ResourceCheckResult> {\n const parsed = parseArn(arn);\n if (!parsed) {\n return errorResult({ arn, error: \"Invalid ARN format\" });\n }\n\n if (!isSupportedService(parsed.service)) {\n const msg = `Unsupported AWS service: ${parsed.service}. Supported: ${SUPPORTED_SERVICES.join(\", \")}`;\n return errorResult({\n arn,\n error: msg,\n service: parsed.service,\n resourceType: parsed.resourceType,\n resourceId: parsed.resourceId,\n });\n }\n\n const checker = await getChecker(parsed.service);\n if (!checker) {\n return errorResult({ arn, error: `No checker for AWS service: ${parsed.service}`, service: parsed.service });\n }\n\n return checker.check(parsed);\n}\n\n/**\n * Check a GCP resource\n */\nasync function checkGcpResource(resource: string): Promise<ResourceCheckResult> {\n const parsed = parseGcpResource(resource);\n if (!parsed) {\n return errorResult({ arn: resource, error: \"Invalid GCP resource path format\" });\n }\n\n if (!isSupportedGcpService(parsed.service)) {\n const msg = `Unsupported GCP service: ${parsed.service}. Supported: ${SUPPORTED_GCP_SERVICES.join(\", \")}`;\n return errorResult({\n arn: resource,\n error: msg,\n service: parsed.service,\n resourceType: parsed.resourceType,\n resourceId: parsed.resourceId,\n });\n }\n\n const checker = await getGcpChecker(parsed.service);\n if (!checker) {\n return errorResult({ arn: resource, error: `No checker for GCP service: ${parsed.service}`, service: parsed.service });\n }\n\n return checker.check(parsed);\n}\n\ninterface ErrorResultParams {\n arn: string;\n error: string;\n service?: string;\n resourceType?: string;\n resourceId?: string;\n}\n\n/**\n * Create an error result\n */\nfunction errorResult(params: ErrorResultParams): ResourceCheckResult {\n const { arn, error, service = \"unknown\", resourceType = \"unknown\", resourceId = arn } = params;\n return { arn, exists: false, error, service, resourceType, resourceId };\n}\n\n/**\n * Calculate summary statistics from check results\n */\nfunction calculateSummary(results: ResourceCheckResult[]): InfraScanSummary {\n let found = 0;\n let missing = 0;\n let errors = 0;\n\n for (const result of results) {\n if (result.error) {\n errors++;\n } else if (result.exists) {\n found++;\n } else {\n missing++;\n }\n }\n\n return {\n total: results.length,\n found,\n missing,\n errors,\n };\n}\n"],"mappings":"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","names":["fs","path","fs","path","path","execa","execa","fs","path","execa","execa","fs","execa","execa","path","glob","DEFAULT_EXCLUDE","glob","fs","execa","execa","fs","path","execa","execa","fs","path","execa","execa","fs","path","execa","execa","fs","path","execa","isSymlink","execa","fs","path","execa","execa","fs","path","execa","execa","fs","path","execa","execa","execa","execa","fs","path","yaml","fs","path","execa","glob","glob","execa","glob","glob","fs","minimatch","minimatch","execa","execa","execa","execa","isEnabled","toolRegistry","getEnabledTools","runTools","execa","execa","path","execa","loadConfigAsync","fs","path","chalk","fs","path","globSync","globSync","fs","path","chalk","matter","fs","path","execa","execa","fs","path","matter","matter","fs","path","chalk","chalk","z","z","z","z","z","z","z","z","path","chalk","chalk","checkerFactories","checkerCache"]}