@nolans01/agent-validator 0.1.0 → 0.2.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.
- package/README.md +117 -2
- package/dist/cli.js +596 -134
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.js +545 -110
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/resolver.ts","../src/detector.ts","../src/adapters/tsc.ts","../src/adapters/base.ts","../src/adapters/mypy.ts","../src/scorer.ts","../src/config/defaults.ts","../src/gates/shared.ts","../src/gates/type-safety.ts","../src/adapters/lizard.ts","../src/utils.ts","../src/gates/complexity.ts","../src/adapters/semgrep.ts","../src/adapters/gitleaks.ts","../src/gates/security.ts","../src/adapters/madge.ts","../src/adapters/jscpd.ts","../src/adapters/knip.ts","../src/gates/architecture.ts","../src/adapters/stryker.ts","../src/adapters/mutation-shared.ts","../src/adapters/mutmut.ts","../src/adapters/mutant.ts","../src/gates/test-quality.ts","../src/gates/index.ts","../src/runner.ts","../src/config/profiles.ts","../src/reporter.ts","../src/index.ts"],"sourcesContent":["import path from 'node:path';\nimport fs from 'node:fs';\nimport { glob } from 'glob';\nimport { execa } from 'execa';\nimport { detectLanguage, SOURCE_EXTENSIONS } from './detector.js';\nimport type { FileEntry, ResolveMode } from './types/index.js';\n\nexport interface ResolveOptions {\n mode: ResolveMode;\n targets?: string[];\n base?: string;\n head?: string;\n staged?: boolean;\n exclude?: string[];\n workdir: string;\n}\n\nexport async function resolveFiles(options: ResolveOptions): Promise<FileEntry[]> {\n let rawPaths: string[];\n\n switch (options.mode) {\n case 'diff':\n rawPaths = await resolveDiff(options);\n break;\n case 'files':\n rawPaths = await resolveFileList(options);\n break;\n case 'dir':\n rawPaths = await resolveDirectory(options);\n break;\n case 'scan':\n rawPaths = await resolveDirectory({ ...options, targets: ['.'] });\n break;\n default:\n throw new Error(`Unknown mode: ${options.mode}`);\n }\n\n const sourceFiles = rawPaths.filter((p) => {\n const ext = path.extname(p).toLowerCase();\n return SOURCE_EXTENSIONS.includes(ext);\n });\n\n return sourceFiles.map((p) => ({\n path: path.resolve(options.workdir, p),\n relativePath: p,\n language: detectLanguage(p),\n }));\n}\n\nasync function resolveDiff(options: ResolveOptions): Promise<string[]> {\n const args = ['diff', '--name-only', '--diff-filter=ACMR'];\n\n if (options.staged) {\n args.push('--staged');\n } else {\n const base = options.base ?? 'main';\n const head = options.head ?? 'HEAD';\n args.push(`${base}...${head}`);\n }\n\n const result = await execa('git', args, { cwd: options.workdir });\n return result.stdout.trim().split('\\n').filter(Boolean);\n}\n\nasync function resolveFileList(options: ResolveOptions): Promise<string[]> {\n const targets = options.targets ?? [];\n const resolved: string[] = [];\n\n for (const target of targets) {\n if (target.includes('*') || target.includes('?')) {\n const matches = await glob(target, { cwd: options.workdir });\n resolved.push(...matches);\n } else {\n const fullPath = path.resolve(options.workdir, target);\n if (fs.existsSync(fullPath)) {\n resolved.push(target);\n }\n }\n }\n\n return resolved;\n}\n\nasync function resolveDirectory(options: ResolveOptions): Promise<string[]> {\n const dirs = options.targets ?? ['.'];\n const patterns = dirs.map((d) => `${d}/**/*`);\n const defaultExclude = ['**/node_modules/**', '**/dist/**', '**/.git/**'];\n const ignore = [...defaultExclude, ...(options.exclude ?? [])];\n\n return glob(patterns, {\n cwd: options.workdir,\n nodir: true,\n ignore,\n });\n}\n","import path from 'node:path';\nimport type { Language, FileEntry } from './types/index.js';\n\nconst EXTENSION_MAP: Record<string, Language> = {\n '.ts': 'typescript',\n '.tsx': 'typescript',\n '.js': 'javascript',\n '.jsx': 'javascript',\n '.mjs': 'javascript',\n '.cjs': 'javascript',\n '.py': 'python',\n '.rb': 'ruby',\n '.go': 'go',\n '.rs': 'rust',\n};\n\nexport const SOURCE_EXTENSIONS = Object.keys(EXTENSION_MAP);\n\nexport function detectLanguage(filePath: string): Language {\n const ext = path.extname(filePath).toLowerCase();\n return EXTENSION_MAP[ext] ?? 'unknown';\n}\n\nexport function detectPrimaryLanguage(files: FileEntry[]): Language {\n const counts = new Map<Language, number>();\n\n for (const file of files) {\n if (file.language === 'unknown') continue;\n counts.set(file.language, (counts.get(file.language) ?? 0) + 1);\n }\n\n let maxLang: Language = 'unknown';\n let maxCount = 0;\n for (const [lang, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n maxLang = lang;\n }\n }\n\n return maxLang;\n}\n","import { execa } from 'execa';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { Finding, Language } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nexport interface TscAdapterConfig extends AdapterConfig {\n strict?: boolean;\n tsconfigPath?: string;\n}\n\nconst TSC_LINE_RE = /^(.+)\\((\\d+),(\\d+)\\): (error|warning) (TS\\d+): (.+)$/;\n\nfunction resolveLocalBinary(name: string, workdir: string): string | undefined {\n const localPath = path.join(workdir, 'node_modules', '.bin', name);\n return fs.existsSync(localPath) ? localPath : undefined;\n}\n\nfunction buildTscArgs(config: TscAdapterConfig, tsconfigPath: string, hasTsconfig: boolean, files: string[]): string[] {\n const args = ['--noEmit', '--pretty', 'false'];\n if (hasTsconfig) {\n args.push('--project', tsconfigPath);\n } else {\n if (config.strict) args.push('--strict');\n args.push(...files);\n }\n return args;\n}\n\nfunction parseTscOutput(stdout: string, workdir: string, fileSet: Set<string>, hasTsconfig: boolean): Finding[] {\n const findings: Finding[] = [];\n\n for (const line of stdout.split('\\n')) {\n const match = line.match(TSC_LINE_RE);\n if (!match) continue;\n\n const [, filePath, lineNum, , severity, code, message] = match;\n const relativePath = filePath.startsWith('/')\n ? path.relative(workdir, filePath)\n : filePath;\n\n if (hasTsconfig && !fileSet.has(relativePath)) continue;\n\n findings.push({\n file: relativePath,\n line: parseInt(lineNum, 10),\n severity: severity === 'error' ? 'blocker' : 'warning',\n metric: 'type_error',\n message,\n why: `TypeScript compiler error ${code}: the code will not compile.`,\n suggestion: 'Fix the type error to ensure type safety.',\n metadata: { code, source: 'tsc' },\n });\n }\n\n return findings;\n}\n\nexport class TscAdapter implements ToolAdapter {\n name = 'tsc';\n supportedLanguages: Language[] = ['typescript'];\n\n async isAvailable(workdir?: string): Promise<boolean> {\n if (workdir && resolveLocalBinary('tsc', workdir)) return true;\n return isBinaryAvailable('tsc');\n }\n\n async run(files: string[], config: TscAdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) return { findings: [] };\n\n const tsconfigPath = config.tsconfigPath\n ? path.resolve(config.workdir, config.tsconfigPath)\n : path.join(config.workdir, 'tsconfig.json');\n\n const hasTsconfig = fs.existsSync(tsconfigPath);\n const args = buildTscArgs(config, tsconfigPath, hasTsconfig, files);\n const binary = resolveLocalBinary('tsc', config.workdir) ?? 'tsc';\n\n const result = await execa(binary, args, {\n cwd: config.workdir,\n reject: false,\n });\n\n const stdout = result.stdout || '';\n if (!stdout.trim()) return { findings: [] };\n\n const fileSet = new Set(files);\n return { findings: parseTscOutput(stdout, config.workdir, fileSet, hasTsconfig) };\n }\n}\n","import { execa } from 'execa';\nimport type { Language } from '../types/index.js';\nimport type { Finding } from '../types/index.js';\n\nexport interface AdapterConfig {\n workdir: string;\n thresholds: Record<string, number>;\n}\n\nexport interface AdapterResult {\n findings: Finding[];\n totalFunctions?: number;\n}\n\nexport interface ToolAdapter {\n name: string;\n supportedLanguages: Language[];\n isAvailable(): Promise<boolean>;\n run(files: string[], config: AdapterConfig): Promise<AdapterResult>;\n}\n\nexport async function isBinaryAvailable(command: string): Promise<boolean> {\n try {\n await execa(command, ['--version']);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function getBinaryVersion(command: string): Promise<string | undefined> {\n try {\n const { stdout } = await execa(command, ['--version']);\n const match = stdout.match(/(\\d+\\.\\d+\\.\\d+)/);\n return match?.[1];\n } catch {\n return undefined;\n }\n}\n","import { execa } from 'execa';\nimport type { Finding, Language } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nexport interface MypyAdapterConfig extends AdapterConfig {\n strict?: boolean;\n}\n\nconst MYPY_LINE_RE = /^(.+):(\\d+): (error|warning|note): (.+?)(?:\\s+\\[(.+)\\])?$/;\n\nexport class MypyAdapter implements ToolAdapter {\n name = 'mypy';\n supportedLanguages: Language[] = ['python'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('mypy');\n }\n\n async run(files: string[], config: MypyAdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) return { findings: [] };\n\n const args = ['--no-color-output', '--no-error-summary'];\n if (config.strict) args.push('--strict');\n args.push(...files);\n\n const result = await execa('mypy', args, {\n cwd: config.workdir,\n reject: false,\n });\n\n const stdout = result.stdout || '';\n if (!stdout.trim()) return { findings: [] };\n\n const findings: Finding[] = [];\n\n for (const line of stdout.split('\\n')) {\n const match = line.match(MYPY_LINE_RE);\n if (!match) continue;\n\n const [, filePath, lineNum, severity, message, code] = match;\n\n findings.push({\n file: filePath,\n line: parseInt(lineNum, 10),\n severity: mapMypySeverity(severity),\n metric: 'type_error',\n message,\n why: buildMypyWhy(severity, code),\n suggestion: 'Fix the type annotation or value to satisfy the type checker.',\n metadata: { code: code ?? undefined, source: 'mypy' },\n });\n }\n\n return { findings };\n }\n}\n\nfunction mapMypySeverity(level: string): Finding['severity'] {\n switch (level) {\n case 'error':\n return 'blocker';\n case 'warning':\n return 'warning';\n default:\n return 'info';\n }\n}\n\nfunction buildMypyWhy(severity: string, code: string | undefined): string {\n const parts: string[] = [];\n if (severity === 'error') {\n parts.push('mypy type error: the code has an incorrect type annotation or usage');\n } else if (severity === 'warning') {\n parts.push('mypy warning: potential type issue detected');\n } else {\n parts.push('mypy note: additional type information');\n }\n if (code) parts.push(`[${code}]`);\n return parts.join(' ');\n}\n","import type { Finding, GateResult } from './types/index.js';\n\nexport interface ScoreInput {\n totalFunctions: number;\n findings: Finding[];\n}\n\nexport function calculateComplexityScore(input: ScoreInput): number {\n if (input.totalFunctions === 0) return 100;\n const violationCount = input.findings.length;\n const cleanCount = Math.max(0, input.totalFunctions - violationCount);\n return Math.round((cleanCount / input.totalFunctions) * 100);\n}\n\nexport function deriveStatus(score: number, findings: Finding[]): GateResult['status'] {\n const hasBlockers = findings.some((f) => f.severity === 'blocker');\n if (hasBlockers) return 'fail';\n if (score < 70) return 'fail';\n if (score < 85) return 'warn';\n return 'pass';\n}\n\nexport function calculateSecurityScore(input: { findings: Finding[] }): number {\n let score = 100;\n\n for (const finding of input.findings) {\n switch (finding.severity) {\n case 'blocker':\n score -= 25;\n break;\n case 'warning':\n score -= 10;\n break;\n case 'info':\n score -= 3;\n break;\n }\n }\n\n return Math.max(0, score);\n}\n\nexport function calculateTypeSafetyScore(input: { findings: Finding[] }): number {\n let score = 100;\n\n for (const finding of input.findings) {\n switch (finding.severity) {\n case 'blocker':\n score -= 10;\n break;\n case 'warning':\n score -= 5;\n break;\n case 'info':\n score -= 2;\n break;\n }\n }\n\n return Math.max(0, score);\n}\n\nexport function calculateArchitectureScore(input: { findings: Finding[] }): number {\n let score = 100;\n\n for (const finding of input.findings) {\n switch (finding.severity) {\n case 'blocker':\n score -= 15;\n break;\n case 'warning':\n score -= 7;\n break;\n case 'info':\n score -= 3;\n break;\n }\n }\n\n return Math.max(0, score);\n}\n\nexport function calculateTestQualityScore(input: { mutationScore: number }): number {\n return Math.round(Math.max(0, Math.min(100, input.mutationScore)));\n}\n\nexport function overallStatus(results: GateResult[]): 'pass' | 'fail' | 'warn' {\n if (results.some((r) => r.status === 'fail')) return 'fail';\n if (results.some((r) => r.status === 'warn')) return 'warn';\n return 'pass';\n}\n","import type { ComplexityThresholds, SecurityConfig, TypeSafetyConfig, ArchitectureConfig, TestQualityConfig } from '../types/index.js';\n\nexport const DEFAULT_COMPLEXITY: ComplexityThresholds = {\n cyclomatic: 10,\n length: 40,\n arguments: 4,\n nesting: 3,\n};\n\nexport const DEFAULT_SECURITY: SecurityConfig = {\n semgrepRules: ['p/security-audit', 'p/secrets'],\n gitleaksEnabled: true,\n};\n\nexport const DEFAULT_TYPE_SAFETY: TypeSafetyConfig = {\n strict: false,\n mypyEnabled: true,\n};\n\nexport const DEFAULT_JSCPD_EXCLUDE: string[] = [\n '**/test/**',\n '**/tests/**',\n '**/__tests__/**',\n '**/*.test.*',\n '**/*.spec.*',\n '**/docs/**',\n '**/*.md',\n '**/fixtures/**',\n '**/mocks/**',\n '**/node_modules/**',\n '**/dist/**',\n '**/vendor/**',\n];\n\nexport const DEFAULT_ARCHITECTURE: ArchitectureConfig = {\n madgeEnabled: true,\n jscpdEnabled: true,\n knipEnabled: true,\n};\n\nexport const DEFAULT_TEST_QUALITY: TestQualityConfig = {\n strykerEnabled: true,\n mutmutEnabled: true,\n mutantEnabled: true,\n mutationScoreThreshold: 80,\n timeout: 300000,\n maxSurvivorFindings: 5,\n};\n","import type { GateResult } from '../types/index.js';\n\nexport function toolMissingResult(gate: string, start: number, message: string, suggestion: string): GateResult {\n return {\n gate,\n score: 0,\n status: 'skip',\n duration_ms: Date.now() - start,\n findings: [\n {\n file: '',\n line: 0,\n severity: 'info',\n metric: 'tool_missing',\n message,\n why: `The ${gate} gate requires at least one tool to function.`,\n suggestion,\n },\n ],\n };\n}\n","import type { Gate, GateContext, GateResult, Finding, TypeSafetyConfig } from '../types/index.js';\nimport { TscAdapter, type TscAdapterConfig } from '../adapters/tsc.js';\nimport { MypyAdapter, type MypyAdapterConfig } from '../adapters/mypy.js';\nimport { calculateTypeSafetyScore, deriveStatus } from '../scorer.js';\nimport { DEFAULT_TYPE_SAFETY } from '../config/defaults.js';\nimport { toolMissingResult } from './shared.js';\n\nexport class TypeSafetyGate implements Gate {\n name = 'type_safety';\n private tsc = new TscAdapter();\n private mypy = new MypyAdapter();\n\n async run(ctx: GateContext): Promise<GateResult> {\n const start = Date.now();\n const config: TypeSafetyConfig = ctx.config.typeSafety ?? DEFAULT_TYPE_SAFETY;\n\n if (ctx.language === 'typescript') {\n return this.runTsc(ctx, config, start);\n }\n\n if (ctx.language === 'python' && config.mypyEnabled) {\n return this.runMypy(ctx, config, start);\n }\n\n const suggestion = ctx.language === 'python'\n ? 'Enable mypyEnabled in profile or install mypy: pip install mypy'\n : 'No type checker supported for this language yet.';\n return toolMissingResult(this.name, start, `No type checker available for language: ${ctx.language}`, suggestion);\n }\n\n private getFiles(ctx: GateContext, adapter: { supportedLanguages: readonly string[] }): string[] {\n return ctx.files\n .filter((f) => adapter.supportedLanguages.includes(f.language))\n .map((f) => f.relativePath);\n }\n\n private emptyResult(start: number): GateResult {\n return { gate: this.name, score: 100, status: 'pass', duration_ms: Date.now() - start, findings: [] };\n }\n\n private async runTsc(ctx: GateContext, config: TypeSafetyConfig, start: number): Promise<GateResult> {\n const available = await this.tsc.isAvailable(ctx.workdir);\n if (!available) {\n return toolMissingResult(this.name, start, 'tsc is not installed', 'Install with: npm install -g typescript');\n }\n\n const files = this.getFiles(ctx, this.tsc);\n if (files.length === 0) return this.emptyResult(start);\n\n const adapterConfig: TscAdapterConfig = {\n workdir: ctx.workdir,\n thresholds: {},\n strict: config.strict,\n tsconfigPath: config.tsconfigPath,\n };\n\n const result = await this.tsc.run(files, adapterConfig);\n return this.buildResult(result.findings, start);\n }\n\n private async runMypy(ctx: GateContext, config: TypeSafetyConfig, start: number): Promise<GateResult> {\n const available = await this.mypy.isAvailable();\n if (!available) {\n return toolMissingResult(this.name, start, 'mypy is not installed', 'Install with: pip install mypy');\n }\n\n const files = this.getFiles(ctx, this.mypy);\n if (files.length === 0) return this.emptyResult(start);\n\n const adapterConfig: MypyAdapterConfig = {\n workdir: ctx.workdir,\n thresholds: {},\n strict: config.strict,\n };\n\n const result = await this.mypy.run(files, adapterConfig);\n return this.buildResult(result.findings, start);\n }\n\n private buildResult(findings: Finding[], start: number): GateResult {\n const score = calculateTypeSafetyScore({ findings });\n const status = deriveStatus(score, findings);\n return { gate: this.name, score, status, duration_ms: Date.now() - start, findings };\n }\n\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { chunk } from '../utils.js';\n\nexport class LizardAdapter implements ToolAdapter {\n name = 'lizard';\n supportedLanguages: Language[] = [\n 'typescript',\n 'javascript',\n 'python',\n 'ruby',\n 'go',\n 'rust',\n ];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('lizard');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) {\n return { findings: [], totalFunctions: 0 };\n }\n\n const allFindings: Finding[] = [];\n let totalFunctions = 0;\n\n for (const batch of chunk(files, 50)) {\n const result = await execa('lizard', [...batch, '--csv'], {\n cwd: config.workdir,\n reject: false,\n });\n\n const parsed = parseLizardCsv(result.stdout, config.thresholds);\n allFindings.push(...parsed.findings);\n totalFunctions += parsed.totalFunctions;\n }\n\n return { findings: allFindings, totalFunctions };\n }\n}\n\ninterface ParseResult {\n findings: Finding[];\n totalFunctions: number;\n}\n\ninterface FunctionMetrics {\n nloc: number;\n ccn: number;\n params: number;\n file: string;\n func: string;\n start: number;\n end: number;\n}\n\nfunction parseCsvRow(fields: string[]): FunctionMetrics | null {\n if (fields.length < 11) return null;\n const ccn = parseInt(fields[1], 10);\n if (isNaN(ccn)) return null;\n return {\n nloc: parseInt(fields[0], 10),\n ccn,\n params: parseInt(fields[3], 10),\n file: fields[6],\n func: fields[7],\n start: parseInt(fields[9], 10),\n end: parseInt(fields[10], 10),\n };\n}\n\nfunction detectViolations(m: FunctionMetrics, thresholds: Record<string, number>): string[] {\n const violations: string[] = [];\n if (m.ccn > (thresholds.cyclomatic ?? 10)) violations.push('cyclomatic');\n if (m.nloc > (thresholds.length ?? 40)) violations.push('length');\n if (m.params > (thresholds.arguments ?? 4)) violations.push('arguments');\n return violations;\n}\n\nfunction metricsToFinding(m: FunctionMetrics, violations: string[], thresholds: Record<string, number>): Finding {\n return {\n file: m.file,\n line: m.start,\n end_line: m.end,\n function: m.func,\n severity: determineSeverity(m, thresholds),\n metric: 'complexity',\n value: m.ccn,\n threshold: thresholds.cyclomatic ?? 10,\n message: buildMessage(m, violations, thresholds),\n why: buildWhy(m, violations),\n suggestion: buildSuggestion(violations),\n metadata: { nloc: m.nloc, ccn: m.ccn, params: m.params, violations },\n };\n}\n\nfunction parseLizardCsv(csv: string, thresholds: Record<string, number>): ParseResult {\n const lines = csv.trim().split('\\n');\n if (lines.length <= 1) return { findings: [], totalFunctions: 0 };\n\n const findings: Finding[] = [];\n let totalFunctions = 0;\n\n for (const line of lines.slice(1)) {\n const m = parseCsvRow(parseCSVLine(line));\n if (!m) continue;\n totalFunctions++;\n\n const violations = detectViolations(m, thresholds);\n if (violations.length === 0) continue;\n\n findings.push(metricsToFinding(m, violations, thresholds));\n }\n\n return { findings, totalFunctions };\n}\n\nfunction determineSeverity(m: FunctionMetrics, thresholds: Record<string, number>): Finding['severity'] {\n const ccnRatio = m.ccn / (thresholds.cyclomatic ?? 10);\n const nlocRatio = m.nloc / (thresholds.length ?? 40);\n if (ccnRatio > 1.5 || nlocRatio > 1.5) return 'blocker';\n return 'warning';\n}\n\nfunction buildMessage(m: FunctionMetrics, violations: string[], thresholds: Record<string, number>): string {\n const parts: string[] = [];\n if (violations.includes('cyclomatic')) {\n parts.push(`Cyclomatic: ${m.ccn} (max: ${thresholds.cyclomatic ?? 10})`);\n }\n if (violations.includes('length')) {\n parts.push(`NLOC: ${m.nloc} (max: ${thresholds.length ?? 40})`);\n }\n if (violations.includes('arguments')) {\n parts.push(`Params: ${m.params} (max: ${thresholds.arguments ?? 4})`);\n }\n return parts.join(' | ');\n}\n\nfunction buildWhy(m: FunctionMetrics, violations: string[]): string {\n if (violations.includes('cyclomatic') && violations.includes('length')) {\n return `${m.ccn} execution paths in ${m.nloc} lines. Difficult to test exhaustively and high risk of bugs on change.`;\n }\n if (violations.includes('cyclomatic')) {\n return `${m.ccn} execution paths make this function hard to test and maintain.`;\n }\n if (violations.includes('length')) {\n return `${m.nloc} lines suggests this function does more than one thing.`;\n }\n if (violations.includes('arguments')) {\n return 'Too many parameters indicates this function has too many responsibilities or needs a config object.';\n }\n return 'Function exceeds complexity thresholds.';\n}\n\nfunction buildSuggestion(violations: string[]): string {\n if (violations.includes('cyclomatic') || violations.includes('length')) {\n return 'Extract into smaller, focused functions with single responsibility.';\n }\n if (violations.includes('arguments')) {\n return 'Group related parameters into an options/config object.';\n }\n return 'Simplify this function.';\n}\n\nfunction parseCSVLine(line: string): string[] {\n const fields: string[] = [];\n let current = '';\n let inQuotes = false;\n for (const char of line) {\n if (char === '\"') {\n inQuotes = !inQuotes;\n } else if (char === ',' && !inQuotes) {\n fields.push(current.trim());\n current = '';\n } else {\n current += char;\n }\n }\n fields.push(current.trim());\n return fields;\n}\n\n","export function chunk<T>(arr: T[], size: number): T[][] {\n if (size <= 0) return [arr];\n const chunks: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size));\n }\n return chunks;\n}\n","import type { Gate, GateContext, GateResult } from '../types/index.js';\nimport { LizardAdapter } from '../adapters/lizard.js';\nimport { calculateComplexityScore, deriveStatus } from '../scorer.js';\nimport { toolMissingResult } from './shared.js';\n\nexport class ComplexityGate implements Gate {\n name = 'complexity';\n private adapter = new LizardAdapter();\n\n async run(ctx: GateContext): Promise<GateResult> {\n const start = Date.now();\n\n const available = await this.adapter.isAvailable();\n if (!available) {\n return toolMissingResult(this.name, start, 'lizard is not installed', 'Install with: pip install lizard');\n }\n\n const supportedFiles = ctx.files\n .filter((f) => this.adapter.supportedLanguages.includes(f.language))\n .map((f) => f.relativePath);\n\n if (supportedFiles.length === 0) {\n return {\n gate: this.name,\n score: 100,\n status: 'pass',\n duration_ms: Date.now() - start,\n findings: [],\n };\n }\n\n const { findings, totalFunctions = 0 } = await this.adapter.run(supportedFiles, {\n workdir: ctx.workdir,\n thresholds: {\n cyclomatic: ctx.config.complexity.cyclomatic,\n length: ctx.config.complexity.length,\n arguments: ctx.config.complexity.arguments,\n },\n });\n\n const score = calculateComplexityScore({ totalFunctions, findings });\n const status = deriveStatus(score, findings);\n const duration_ms = Date.now() - start;\n\n return { gate: this.name, score, status, duration_ms, findings };\n }\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { chunk } from '../utils.js';\n\nexport interface SemgrepAdapterConfig extends AdapterConfig {\n rules?: string[];\n}\n\nexport class SemgrepAdapter implements ToolAdapter {\n name = 'semgrep';\n supportedLanguages: Language[] = [\n 'typescript',\n 'javascript',\n 'python',\n 'ruby',\n 'go',\n 'rust',\n ];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('semgrep');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) {\n return { findings: [] };\n }\n\n const rules = (config as SemgrepAdapterConfig).rules ?? ['p/security-audit', 'p/secrets'];\n const allFindings: Finding[] = [];\n\n for (const batch of chunk(files, 50)) {\n const configArgs = rules.flatMap((r) => ['--config', r]);\n const result = await execa(\n 'semgrep',\n [...configArgs, '--json', ...batch],\n { cwd: config.workdir, reject: false },\n );\n\n if (result.stdout) {\n const parsed = parseSemgrepJson(result.stdout);\n allFindings.push(...parsed);\n }\n }\n\n return { findings: allFindings };\n }\n}\n\ninterface SemgrepOutput {\n results: SemgrepResult[];\n errors: unknown[];\n paths: { scanned: string[]; skipped: string[] };\n}\n\ninterface SemgrepResult {\n check_id: string;\n path: string;\n start: { line: number; col: number };\n end: { line: number; col: number };\n extra: {\n message: string;\n severity: string;\n metadata?: {\n cwe?: string[];\n owasp?: string[];\n confidence?: string;\n };\n fix?: string;\n lines?: string;\n };\n}\n\nfunction parseSemgrepJson(json: string): Finding[] {\n let output: SemgrepOutput;\n try {\n output = JSON.parse(json) as SemgrepOutput;\n } catch {\n return [];\n }\n\n if (!output.results || !Array.isArray(output.results)) {\n return [];\n }\n\n return output.results.map((r) => ({\n file: r.path,\n line: r.start.line,\n end_line: r.end.line,\n severity: mapSeverity(r.extra.severity),\n metric: 'security',\n message: r.extra.message,\n why: buildWhy(r),\n suggestion: r.extra.fix ?? undefined,\n metadata: {\n ruleId: r.check_id,\n cwe: r.extra.metadata?.cwe,\n owasp: r.extra.metadata?.owasp,\n confidence: r.extra.metadata?.confidence,\n source: 'semgrep',\n },\n }));\n}\n\nfunction mapSeverity(severity: string): Finding['severity'] {\n switch (severity) {\n case 'ERROR':\n return 'blocker';\n case 'WARNING':\n return 'warning';\n case 'INFO':\n return 'info';\n default:\n return 'warning';\n }\n}\n\nfunction buildWhy(result: SemgrepResult): string {\n const parts: string[] = [];\n if (result.extra.metadata?.cwe?.length) {\n parts.push(result.extra.metadata.cwe.join(', '));\n }\n if (result.extra.metadata?.owasp?.length) {\n parts.push(result.extra.metadata.owasp.join(', '));\n }\n if (parts.length === 0) {\n return `Security issue detected by rule ${result.check_id}.`;\n }\n return `${parts.join(' | ')}. Detected by rule ${result.check_id}.`;\n}\n\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nexport class GitleaksAdapter implements ToolAdapter {\n name = 'gitleaks';\n supportedLanguages: Language[] = [\n 'typescript',\n 'javascript',\n 'python',\n 'ruby',\n 'go',\n 'rust',\n 'unknown',\n ];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('gitleaks');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n const result = await execa(\n 'gitleaks',\n ['detect', '--source', config.workdir, '--no-git', '-f', 'json', '--report-path', '/dev/stdout'],\n { cwd: config.workdir, reject: false },\n );\n\n if (!result.stdout || result.stdout.trim() === '') {\n return { findings: [] };\n }\n\n const allLeaks = parseGitleaksJson(result.stdout);\n\n const fileSet = new Set(files);\n const filtered = allLeaks.filter((f) => fileSet.has(f.file));\n\n return { findings: filtered };\n }\n}\n\ninterface GitleaksLeak {\n Description: string;\n StartLine: number;\n EndLine: number;\n File: string;\n RuleID: string;\n Entropy: number;\n Fingerprint: string;\n}\n\nfunction parseGitleaksJson(json: string): Finding[] {\n let leaks: GitleaksLeak[];\n try {\n leaks = JSON.parse(json) as GitleaksLeak[];\n } catch {\n return [];\n }\n\n if (!Array.isArray(leaks)) {\n return [];\n }\n\n return leaks.map((leak) => ({\n file: leak.File,\n line: leak.StartLine,\n end_line: leak.EndLine,\n severity: 'blocker' as const,\n metric: 'security',\n message: `Secret detected: ${leak.Description}`,\n why: `Exposed secrets can lead to unauthorized access. Rule: ${leak.RuleID}.`,\n suggestion: 'Remove the secret and rotate the credential. Use environment variables or a secrets manager.',\n metadata: {\n ruleId: leak.RuleID,\n entropy: leak.Entropy,\n fingerprint: leak.Fingerprint,\n source: 'gitleaks',\n },\n }));\n}\n","import type { Gate, GateContext, GateResult, Finding, SecurityConfig } from '../types/index.js';\nimport { SemgrepAdapter, type SemgrepAdapterConfig } from '../adapters/semgrep.js';\nimport { GitleaksAdapter } from '../adapters/gitleaks.js';\nimport { calculateSecurityScore, deriveStatus } from '../scorer.js';\nimport { DEFAULT_SECURITY } from '../config/defaults.js';\nimport { toolMissingResult } from './shared.js';\n\nexport class SecurityGate implements Gate {\n name = 'security';\n private semgrep = new SemgrepAdapter();\n private gitleaks = new GitleaksAdapter();\n\n async run(ctx: GateContext): Promise<GateResult> {\n const start = Date.now();\n const securityConfig: SecurityConfig = ctx.config.security ?? DEFAULT_SECURITY;\n\n const semgrepAvailable = await this.semgrep.isAvailable();\n const gitleaksAvailable = securityConfig.gitleaksEnabled\n ? await this.gitleaks.isAvailable()\n : false;\n\n if (!semgrepAvailable && !gitleaksAvailable) {\n return toolMissingResult(this.name, start, 'Neither semgrep nor gitleaks is installed', 'Install with: pip install semgrep OR brew install gitleaks');\n }\n\n const allFindings: Finding[] = [];\n\n if (semgrepAvailable) {\n const supportedFiles = ctx.files\n .filter((f) => this.semgrep.supportedLanguages.includes(f.language))\n .map((f) => f.relativePath);\n\n if (supportedFiles.length > 0) {\n const semgrepConfig: SemgrepAdapterConfig = {\n workdir: ctx.workdir,\n thresholds: {},\n rules: securityConfig.semgrepRules,\n };\n const result = await this.semgrep.run(supportedFiles, semgrepConfig);\n allFindings.push(...result.findings);\n }\n }\n\n if (gitleaksAvailable) {\n const allFiles = ctx.files.map((f) => f.relativePath);\n const result = await this.gitleaks.run(allFiles, {\n workdir: ctx.workdir,\n thresholds: {},\n });\n allFindings.push(...result.findings);\n }\n\n const score = calculateSecurityScore({ findings: allFindings });\n const status = deriveStatus(score, allFindings);\n const duration_ms = Date.now() - start;\n\n return { gate: this.name, score, status, duration_ms, findings: allFindings };\n }\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nfunction parseCycles(stdout: string): string[][] | null {\n if (!stdout.trim()) return null;\n try {\n const cycles = JSON.parse(stdout) as string[][];\n if (!Array.isArray(cycles) || cycles.length === 0) return null;\n return cycles;\n } catch {\n return null;\n }\n}\n\nfunction cycleToFinding(cycle: string[]): Finding {\n const cycleDesc = cycle.join(' → ') + ' → ' + cycle[0];\n return {\n file: cycle[0],\n line: 0,\n severity: 'blocker',\n metric: 'circular_dependency',\n message: `Circular dependency: ${cycleDesc}`,\n why: 'Circular dependencies make the code harder to test, refactor, and reason about.',\n suggestion: 'Break the cycle by extracting shared code into a separate module.',\n metadata: { cycle, source: 'madge' },\n };\n}\n\nexport class MadgeAdapter implements ToolAdapter {\n name = 'madge';\n supportedLanguages: Language[] = ['typescript', 'javascript'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('madge');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) return { findings: [] };\n\n const result = await execa('madge', ['--circular', '--json', config.workdir], {\n cwd: config.workdir,\n reject: false,\n });\n\n const cycles = parseCycles(result.stdout || '');\n if (!cycles) return { findings: [] };\n\n const fileSet = new Set(files);\n const findings = cycles\n .filter((cycle) => Array.isArray(cycle) && cycle.length > 0)\n .filter((cycle) => cycle.some((f) => fileSet.has(f)))\n .map(cycleToFinding);\n\n return { findings };\n }\n}\n","import { execa } from 'execa';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nexport interface JscpdAdapterConfig extends AdapterConfig {\n minLines?: number;\n minTokens?: number;\n exclude?: string[];\n}\n\ninterface JscpdClone {\n format: string;\n lines: number;\n tokens: number;\n firstFile: { name: string; startLoc: { line: number; column: number }; endLoc: { line: number; column: number } };\n secondFile: { name: string; startLoc: { line: number; column: number }; endLoc: { line: number; column: number } };\n}\n\ninterface JscpdReport {\n duplicates: JscpdClone[];\n statistics: unknown;\n}\n\nfunction buildArgs(config: JscpdAdapterConfig, tmpDir: string): string[] {\n const minLines = config.minLines ?? 5;\n const minTokens = config.minTokens ?? 50;\n const exclude = config.exclude ?? [];\n\n const args = [\n '--min-lines', String(minLines),\n '--min-tokens', String(minTokens),\n '--reporters', 'json',\n '--silent',\n '--output', tmpDir,\n ];\n\n for (const pattern of exclude) {\n args.push('--ignore', pattern);\n }\n\n args.push(config.workdir);\n return args;\n}\n\nfunction parseReport(reportPath: string): JscpdReport | null {\n if (!fs.existsSync(reportPath)) return null;\n\n const raw = fs.readFileSync(reportPath, 'utf-8');\n try {\n const report = JSON.parse(raw) as JscpdReport;\n if (!report.duplicates || !Array.isArray(report.duplicates)) return null;\n return report;\n } catch {\n return null;\n }\n}\n\nfunction cloneToFinding(clone: JscpdClone, workdir: string): Finding {\n const firstRel = path.relative(workdir, clone.firstFile.name);\n const secondRel = path.relative(workdir, clone.secondFile.name);\n\n return {\n file: firstRel,\n line: clone.firstFile.startLoc.line,\n end_line: clone.firstFile.endLoc.line,\n severity: 'warning',\n metric: 'code_duplication',\n message: `${clone.lines} lines duplicated with ${secondRel}:${clone.secondFile.startLoc.line}`,\n why: 'Duplicated code increases maintenance burden and risk of inconsistent changes.',\n suggestion: 'Extract the duplicated logic into a shared function or module.',\n metadata: {\n lines: clone.lines,\n tokens: clone.tokens,\n secondFile: secondRel,\n secondLine: clone.secondFile.startLoc.line,\n source: 'jscpd',\n },\n };\n}\n\nexport class JscpdAdapter implements ToolAdapter {\n name = 'jscpd';\n supportedLanguages: Language[] = ['typescript', 'javascript', 'python', 'ruby'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('jscpd');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) return { findings: [] };\n\n const jscpdConfig = config as JscpdAdapterConfig;\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jscpd-'));\n\n try {\n const args = buildArgs(jscpdConfig, tmpDir);\n await execa('jscpd', args, { cwd: config.workdir, reject: false });\n\n const report = parseReport(path.join(tmpDir, 'jscpd-report.json'));\n if (!report) return { findings: [] };\n\n const fileSet = new Set(files);\n\n return {\n findings: report.duplicates\n .filter((clone) => {\n const firstRel = path.relative(config.workdir, clone.firstFile.name);\n const secondRel = path.relative(config.workdir, clone.secondFile.name);\n return fileSet.has(firstRel) || fileSet.has(secondRel);\n })\n .map((clone) => cloneToFinding(clone, config.workdir)),\n };\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n }\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\ninterface KnipIssue {\n name: string;\n line?: number;\n col?: number;\n pos?: number;\n}\n\ninterface KnipFileIssue {\n file: string;\n dependencies?: KnipIssue[];\n devDependencies?: KnipIssue[];\n exports?: KnipIssue[];\n types?: KnipIssue[];\n duplicates?: KnipIssue[][];\n}\n\ninterface KnipReport {\n files: string[];\n issues: KnipFileIssue[];\n}\n\nfunction collectUnusedFiles(report: KnipReport, fileSet: Set<string>): Finding[] {\n if (!report.files || !Array.isArray(report.files)) return [];\n\n return report.files\n .filter((file) => fileSet.has(file))\n .map((file) => ({\n file,\n line: 0,\n severity: 'info' as const,\n metric: 'dead_code',\n message: `Unused file: ${file}`,\n why: 'Unused files add confusion and increase bundle/maintenance cost.',\n suggestion: 'Remove the file if it is no longer needed.',\n metadata: { type: 'file', source: 'knip' },\n }));\n}\n\nfunction exportToFinding(file: string, exp: KnipIssue): Finding {\n return {\n file,\n line: exp.line ?? 0,\n severity: 'info',\n metric: 'unused_export',\n message: `Unused export: ${exp.name}`,\n why: 'Unused exports indicate dead code that may confuse consumers.',\n suggestion: `Remove the export or make '${exp.name}' internal.`,\n metadata: { type: 'export', exportName: exp.name, source: 'knip' },\n };\n}\n\nfunction typeToFinding(file: string, typ: KnipIssue): Finding {\n return {\n file,\n line: typ.line ?? 0,\n severity: 'info',\n metric: 'unused_export',\n message: `Unused exported type: ${typ.name}`,\n why: 'Unused type exports indicate dead code.',\n suggestion: `Remove the type export '${typ.name}' if no longer needed.`,\n metadata: { type: 'type', exportName: typ.name, source: 'knip' },\n };\n}\n\nfunction collectUnusedExports(report: KnipReport, fileSet: Set<string>): Finding[] {\n if (!report.issues || !Array.isArray(report.issues)) return [];\n\n const findings: Finding[] = [];\n\n for (const issue of report.issues) {\n if (!fileSet.has(issue.file)) continue;\n if (issue.exports) findings.push(...issue.exports.map((e) => exportToFinding(issue.file, e)));\n if (issue.types) findings.push(...issue.types.map((t) => typeToFinding(issue.file, t)));\n }\n\n return findings;\n}\n\nexport class KnipAdapter implements ToolAdapter {\n name = 'knip';\n supportedLanguages: Language[] = ['typescript'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('knip');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) return { findings: [] };\n\n const result = await execa('knip', ['--reporter', 'json'], {\n cwd: config.workdir,\n reject: false,\n });\n\n const stdout = result.stdout || '';\n if (!stdout.trim()) return { findings: [] };\n\n let report: KnipReport;\n try {\n report = JSON.parse(stdout) as KnipReport;\n } catch {\n return { findings: [] };\n }\n\n const fileSet = new Set(files);\n\n return {\n findings: [\n ...collectUnusedFiles(report, fileSet),\n ...collectUnusedExports(report, fileSet),\n ],\n };\n }\n}\n","import type { Gate, GateContext, GateResult, Finding, ArchitectureConfig } from '../types/index.js';\nimport { MadgeAdapter } from '../adapters/madge.js';\nimport { JscpdAdapter, type JscpdAdapterConfig } from '../adapters/jscpd.js';\nimport { KnipAdapter } from '../adapters/knip.js';\nimport { calculateArchitectureScore, deriveStatus } from '../scorer.js';\nimport { DEFAULT_ARCHITECTURE, DEFAULT_JSCPD_EXCLUDE } from '../config/defaults.js';\nimport type { ToolAdapter, AdapterConfig } from '../adapters/base.js';\nimport { toolMissingResult } from './shared.js';\n\ninterface ToolAvailability {\n madge: boolean;\n jscpd: boolean;\n knip: boolean;\n}\n\nexport class ArchitectureGate implements Gate {\n name = 'architecture';\n private madge = new MadgeAdapter();\n private jscpd = new JscpdAdapter();\n private knip = new KnipAdapter();\n\n async run(ctx: GateContext): Promise<GateResult> {\n const start = Date.now();\n const config: ArchitectureConfig = ctx.config.architecture ?? DEFAULT_ARCHITECTURE;\n const available = await this.checkAvailability(config, ctx);\n\n if (!available.madge && !available.jscpd && !available.knip) {\n return toolMissingResult(this.name, start, 'No architecture tools available', 'Install with: npm install -g madge jscpd knip');\n }\n\n const allFindings = await this.collectFindings(available, config, ctx);\n const score = calculateArchitectureScore({ findings: allFindings });\n const status = deriveStatus(score, allFindings);\n\n return { gate: this.name, score, status, duration_ms: Date.now() - start, findings: allFindings };\n }\n\n private async checkAvailability(config: ArchitectureConfig, ctx: GateContext): Promise<ToolAvailability> {\n const madgeApplicable = config.madgeEnabled && this.madge.supportedLanguages.includes(ctx.language);\n const jscpdApplicable = config.jscpdEnabled;\n const knipApplicable = config.knipEnabled && this.knip.supportedLanguages.includes(ctx.language);\n\n return {\n madge: madgeApplicable ? await this.madge.isAvailable() : false,\n jscpd: jscpdApplicable ? await this.jscpd.isAvailable() : false,\n knip: knipApplicable ? await this.knip.isAvailable() : false,\n };\n }\n\n private async collectFindings(available: ToolAvailability, config: ArchitectureConfig, ctx: GateContext): Promise<Finding[]> {\n const allFindings: Finding[] = [];\n\n if (available.madge) {\n const findings = await this.runAdapter(this.madge, ctx, { workdir: ctx.workdir, thresholds: {} });\n allFindings.push(...findings);\n }\n\n if (available.jscpd) {\n const jscpdConfig: JscpdAdapterConfig = {\n workdir: ctx.workdir,\n thresholds: {},\n minLines: config.jscpdMinLines,\n minTokens: config.jscpdMinTokens,\n exclude: config.jscpdExclude ?? DEFAULT_JSCPD_EXCLUDE,\n };\n const findings = await this.runAdapter(this.jscpd, ctx, jscpdConfig);\n allFindings.push(...findings);\n }\n\n if (available.knip) {\n const findings = await this.runAdapter(this.knip, ctx, { workdir: ctx.workdir, thresholds: {} });\n allFindings.push(...findings);\n }\n\n return allFindings;\n }\n\n private async runAdapter(adapter: ToolAdapter, ctx: GateContext, config: AdapterConfig): Promise<Finding[]> {\n const files = ctx.files\n .filter((f) => adapter.supportedLanguages.includes(f.language))\n .map((f) => f.relativePath);\n\n if (files.length === 0) return [];\n const result = await adapter.run(files, config);\n return result.findings;\n }\n\n}\n","import { execa } from 'execa';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { timeoutResult } from './mutation-shared.js';\n\nexport interface StrykerAdapterConfig extends AdapterConfig {\n timeout?: number;\n mutationScoreThreshold?: number;\n maxSurvivorFindings?: number;\n}\n\ninterface StrykerMutant {\n id: string;\n mutatorName: string;\n replacement?: string;\n status: string;\n location: { start: { line: number; column: number }; end: { line: number; column: number } };\n}\n\ninterface StrykerFileResult {\n language?: string;\n source?: string;\n mutants: StrykerMutant[];\n}\n\ninterface StrykerReport {\n schemaVersion?: string;\n files: Record<string, StrykerFileResult>;\n}\n\ninterface FileMutationScore {\n file: string;\n killed: number;\n survived: number;\n noCoverage: number;\n timeout: number;\n total: number;\n score: number;\n}\n\nfunction calculateFileScore(mutants: StrykerMutant[]): { killed: number; survived: number; noCoverage: number; timeout: number; total: number; score: number } {\n let killed = 0;\n let survived = 0;\n let noCoverage = 0;\n let timeout = 0;\n let invalid = 0;\n\n for (const m of mutants) {\n switch (m.status) {\n case 'Killed': killed++; break;\n case 'Survived': survived++; break;\n case 'NoCoverage': noCoverage++; break;\n case 'Timeout': timeout++; break;\n case 'CompileError':\n case 'RuntimeError': invalid++; break;\n }\n }\n\n const total = mutants.length - invalid;\n const score = total > 0 ? ((killed + timeout) / total) * 100 : 100;\n\n return { killed, survived, noCoverage, timeout, total, score };\n}\n\nfunction scoreSeverity(score: number): 'blocker' | 'warning' | 'info' {\n if (score < 40) return 'blocker';\n if (score < 70) return 'warning';\n return 'info';\n}\n\nfunction buildScoreMessage(score: number, threshold: number, survived: number, noCoverage: number): string {\n return 'Mutation score ' + Math.round(score) + '% is below threshold ' + threshold + '% (' + survived + ' survived, ' + noCoverage + ' no coverage)';\n}\n\nfunction fileScoreToFinding(fileScore: FileMutationScore, threshold: number): Finding {\n const severity = scoreSeverity(fileScore.score);\n return {\n file: fileScore.file,\n line: 0,\n severity,\n metric: 'mutation_score',\n value: Math.round(fileScore.score),\n threshold,\n message: buildScoreMessage(fileScore.score, threshold, fileScore.survived, fileScore.noCoverage),\n why: 'A low mutation score means tests do not detect code changes, indicating weak or missing test coverage.',\n suggestion: 'Add or improve tests for this file to kill surviving mutants.',\n metadata: { killed: fileScore.killed, survived: fileScore.survived, noCoverage: fileScore.noCoverage, source: 'stryker' },\n };\n}\n\nfunction formatMutantMessage(mutant: StrykerMutant): string {\n const base = 'Surviving mutant: ' + mutant.mutatorName;\n return mutant.replacement ? base + ' → ' + mutant.replacement : base;\n}\n\nfunction survivorToFinding(file: string, mutant: StrykerMutant): Finding {\n return {\n file,\n line: mutant.location.start.line,\n end_line: mutant.location.end.line,\n severity: 'info',\n metric: 'surviving_mutant',\n message: formatMutantMessage(mutant),\n why: 'No test detects this code change, meaning this logic path is not properly verified.',\n suggestion: 'Add a test that would fail if this mutation were applied.',\n metadata: { mutatorName: mutant.mutatorName, status: mutant.status, source: 'stryker' },\n };\n}\n\nfunction findReportPath(workdir: string): string | undefined {\n const candidates = [\n path.join(workdir, 'reports', 'mutation', 'mutation.json'),\n path.join(workdir, 'reports', 'mutation.json'),\n ];\n return candidates.find((p) => fs.existsSync(p));\n}\n\nfunction readReport(workdir: string): StrykerReport | null {\n const reportPath = findReportPath(workdir);\n if (!reportPath) return null;\n\n try {\n const raw = fs.readFileSync(reportPath, 'utf-8');\n return JSON.parse(raw) as StrykerReport;\n } catch {\n return null;\n }\n}\n\nfunction processReport(report: StrykerReport, files: string[], threshold: number, maxSurvivorFindings: number): AdapterResult & { mutationScore: number } {\n const fileSet = new Set(files);\n const findings: Finding[] = [];\n let totalKilled = 0;\n let totalValid = 0;\n\n for (const [filePath, fileResult] of Object.entries(report.files)) {\n if (!fileSet.has(filePath)) continue;\n\n const stats = calculateFileScore(fileResult.mutants);\n totalKilled += stats.killed + stats.timeout;\n totalValid += stats.total;\n\n if (stats.score < threshold) {\n const fileScore: FileMutationScore = { file: filePath, ...stats };\n findings.push(fileScoreToFinding(fileScore, threshold));\n\n const survivors = fileResult.mutants\n .filter((m) => m.status === 'Survived' || m.status === 'NoCoverage')\n .slice(0, maxSurvivorFindings);\n findings.push(...survivors.map((m) => survivorToFinding(filePath, m)));\n }\n }\n\n const mutationScore = totalValid > 0 ? (totalKilled / totalValid) * 100 : 100;\n return { findings, mutationScore };\n}\n\nexport class StrykerAdapter implements ToolAdapter {\n name = 'stryker';\n supportedLanguages: Language[] = ['typescript', 'javascript'];\n\n async isAvailable(workdir?: string): Promise<boolean> {\n if (workdir) {\n const localBin = path.join(workdir, 'node_modules', '.bin', 'stryker');\n if (fs.existsSync(localBin)) return true;\n }\n return await isBinaryAvailable('stryker');\n }\n\n async run(files: string[], config: StrykerAdapterConfig): Promise<AdapterResult & { mutationScore: number }> {\n if (files.length === 0) return { findings: [], mutationScore: 100 };\n\n const timeout = config.timeout ?? 300000;\n const timedOut = await this.executeStryker(files, config, timeout);\n if (timedOut) return timeoutResult('Stryker', timeout);\n\n const report = readReport(config.workdir);\n if (!report) return { findings: [], mutationScore: 100 };\n\n return processReport(report, files, config.mutationScoreThreshold ?? 80, config.maxSurvivorFindings ?? 5);\n }\n\n private async executeStryker(files: string[], config: StrykerAdapterConfig, timeout: number): Promise<boolean> {\n const mutatePattern = files.join(',');\n const args = ['run', '--reporters', 'json', '--mutate', mutatePattern];\n\n const useNpx = fs.existsSync(path.join(config.workdir, 'node_modules', '.bin', 'stryker'));\n const command = useNpx ? 'npx' : 'stryker';\n const execArgs = useNpx ? ['stryker', ...args] : args;\n\n const result = await execa(command, execArgs, {\n cwd: config.workdir,\n reject: false,\n timeout,\n });\n\n return !!result.timedOut;\n }\n}\n","import type { Finding } from '../types/index.js';\nimport type { AdapterResult } from './base.js';\n\nfunction scoreSeverity(score: number): 'blocker' | 'warning' | 'info' {\n if (score < 40) return 'blocker';\n if (score < 70) return 'warning';\n return 'info';\n}\n\nfunction buildScoreMessage(score: number, threshold: number, survived: number, total: number): string {\n return 'Mutation score ' + Math.round(score) + '% is below threshold ' + threshold + '% (' + survived + ' survived of ' + total + ')';\n}\n\nexport function timeoutResult(tool: string, timeout: number): AdapterResult & { mutationScore: number; timedOut: boolean } {\n return {\n findings: [{\n file: '', line: 0, severity: 'info', metric: 'mutation_timeout',\n message: tool + ' timed out after ' + timeout + 'ms',\n why: 'Mutation testing exceeded the configured timeout.',\n suggestion: 'Increase the timeout or reduce the number of files to mutate.',\n }],\n mutationScore: 0,\n timedOut: true,\n };\n}\n\nexport interface FileScoreInput {\n file: string;\n score: number;\n threshold: number;\n survived: number;\n total: number;\n killed: number;\n source: string;\n}\n\nexport function fileScoreFinding(input: FileScoreInput): Finding {\n return {\n file: input.file,\n line: 0,\n severity: scoreSeverity(input.score),\n metric: 'mutation_score',\n value: Math.round(input.score),\n threshold: input.threshold,\n message: buildScoreMessage(input.score, input.threshold, input.survived, input.total),\n why: 'A low mutation score means tests do not detect code changes, indicating weak or missing test coverage.',\n suggestion: 'Add or improve tests for this file to kill surviving mutants.',\n metadata: { killed: input.killed, survived: input.survived, source: input.source },\n };\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { timeoutResult, fileScoreFinding } from './mutation-shared.js';\n\nexport interface MutmutAdapterConfig extends AdapterConfig {\n timeout?: number;\n mutationScoreThreshold?: number;\n maxSurvivorFindings?: number;\n}\n\ninterface MutantResult {\n file: string;\n name: string;\n status: 'killed' | 'survived';\n line?: number;\n}\n\nfunction matchToResult(match: RegExpExecArray): MutantResult {\n const classname = match[1];\n const name = match[2];\n const closingType = match[3];\n const body = match[4] ?? '';\n\n const isSelfClosing = closingType.trim().startsWith('/');\n const survived = !isSelfClosing && body.includes('<failure');\n const file = classname.replace(/\\./g, '/') + '.py';\n const lineMatch = name.match(/line\\s+(\\d+)/i) ?? name.match(/mutant\\s+(\\d+)/i);\n const line = lineMatch ? parseInt(lineMatch[1], 10) : undefined;\n\n return { file, name, status: survived ? 'survived' : 'killed', line };\n}\n\nfunction parseJunitXml(xml: string): MutantResult[] {\n const results: MutantResult[] = [];\n const testcaseRe = /<testcase\\s+classname=\"([^\"]*)\"[^>]*?name=\"([^\"]*)\"[^>]*?(\\/\\s*>|>([\\s\\S]*?)<\\/testcase>)/g;\n let match: RegExpExecArray | null;\n\n while ((match = testcaseRe.exec(xml)) !== null) {\n results.push(matchToResult(match));\n }\n\n return results;\n}\n\ninterface FileStats {\n killed: number;\n survived: number;\n total: number;\n score: number;\n survivors: MutantResult[];\n}\n\nfunction groupByFile(results: MutantResult[]): Map<string, FileStats> {\n const groups = new Map<string, { killed: number; survived: number; survivors: MutantResult[] }>();\n\n for (const r of results) {\n const group = groups.get(r.file) ?? { killed: 0, survived: 0, survivors: [] };\n if (r.status === 'killed') {\n group.killed++;\n } else {\n group.survived++;\n group.survivors.push(r);\n }\n groups.set(r.file, group);\n }\n\n const fileStats = new Map<string, FileStats>();\n for (const [file, g] of groups) {\n const total = g.killed + g.survived;\n const score = total > 0 ? (g.killed / total) * 100 : 100;\n fileStats.set(file, { killed: g.killed, survived: g.survived, total, score, survivors: g.survivors });\n }\n\n return fileStats;\n}\n\nfunction fileStatsToFindings(file: string, stats: FileStats, threshold: number, maxSurvivorFindings: number): Finding[] {\n const findings: Finding[] = [fileScoreFinding({ file, score: stats.score, threshold, survived: stats.survived, total: stats.total, killed: stats.killed, source: 'mutmut' })];\n\n for (const survivor of stats.survivors.slice(0, maxSurvivorFindings)) {\n findings.push({\n file,\n line: survivor.line ?? 0,\n severity: 'info',\n metric: 'surviving_mutant',\n message: 'Surviving mutant: ' + survivor.name,\n why: 'No test detects this code change, meaning this logic path is not properly verified.',\n suggestion: 'Add a test that would fail if this mutation were applied.',\n metadata: { mutantName: survivor.name, source: 'mutmut' },\n });\n }\n\n return findings;\n}\n\nexport class MutmutAdapter implements ToolAdapter {\n name = 'mutmut';\n supportedLanguages: Language[] = ['python'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('mutmut');\n }\n\n async run(files: string[], config: MutmutAdapterConfig): Promise<AdapterResult & { mutationScore: number }> {\n if (files.length === 0) return { findings: [], mutationScore: 100 };\n\n const timeout = config.timeout ?? 300000;\n const xml = await this.executeMutmut(files, config, timeout);\n if (xml === null) return timeoutResult('mutmut', timeout);\n if (!xml.trim()) return { findings: [], mutationScore: 100 };\n\n return this.processXml(xml, files, config.mutationScoreThreshold ?? 80, config.maxSurvivorFindings ?? 5);\n }\n\n private async executeMutmut(files: string[], config: MutmutAdapterConfig, timeout: number): Promise<string | null> {\n const pathsToMutate = files.join(',');\n\n const runResult = await execa('mutmut', ['run', `--paths-to-mutate=${pathsToMutate}`, '--CI', '--no-progress'], {\n cwd: config.workdir,\n reject: false,\n timeout,\n });\n\n if (runResult.timedOut) return null;\n\n const xmlResult = await execa('mutmut', ['junitxml'], {\n cwd: config.workdir,\n reject: false,\n });\n\n return xmlResult.stdout || '';\n }\n\n private processXml(xml: string, files: string[], threshold: number, maxSurvivorFindings: number): AdapterResult & { mutationScore: number } {\n const mutantResults = parseJunitXml(xml);\n if (mutantResults.length === 0) return { findings: [], mutationScore: 100 };\n\n const fileStatsMap = groupByFile(mutantResults);\n const fileSet = new Set(files);\n const findings: Finding[] = [];\n let totalKilled = 0;\n let totalMutants = 0;\n\n for (const [file, stats] of fileStatsMap) {\n if (!fileSet.has(file)) continue;\n\n totalKilled += stats.killed;\n totalMutants += stats.total;\n\n if (stats.score < threshold) {\n findings.push(...fileStatsToFindings(file, stats, threshold, maxSurvivorFindings));\n }\n }\n\n const mutationScore = totalMutants > 0 ? (totalKilled / totalMutants) * 100 : 100;\n return { findings, mutationScore };\n }\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { timeoutResult, fileScoreFinding } from './mutation-shared.js';\n\nexport interface MutantAdapterConfig extends AdapterConfig {\n timeout?: number;\n mutationScoreThreshold?: number;\n maxSurvivorFindings?: number;\n}\n\ninterface MutantResultEntry {\n status: 'alive' | 'killed' | 'timeout';\n subject: string;\n file: string;\n line: number;\n}\n\ninterface FileStats {\n killed: number;\n survived: number;\n timeout: number;\n total: number;\n score: number;\n survivors: MutantResultEntry[];\n}\n\nconst RESULT_LINE_RE = /^(alive|killed|timeout):(.+):(.+):(\\d+)/;\nconst COVERAGE_RE = /Coverage:\\s+([\\d.]+)%/;\n\nfunction parseOutput(stdout: string): { entries: MutantResultEntry[]; overallScore: number | null } {\n const entries: MutantResultEntry[] = [];\n let overallScore: number | null = null;\n\n for (const line of stdout.split('\\n')) {\n const resultMatch = RESULT_LINE_RE.exec(line);\n if (resultMatch) {\n entries.push({\n status: resultMatch[1] as 'alive' | 'killed' | 'timeout',\n subject: resultMatch[2],\n file: resultMatch[3],\n line: parseInt(resultMatch[4], 10),\n });\n continue;\n }\n\n const coverageMatch = COVERAGE_RE.exec(line);\n if (coverageMatch) {\n overallScore = parseFloat(coverageMatch[1]);\n }\n }\n\n return { entries, overallScore };\n}\n\nfunction groupByFile(entries: MutantResultEntry[]): Map<string, FileStats> {\n const groups = new Map<string, { killed: number; survived: number; timeout: number; survivors: MutantResultEntry[] }>();\n\n for (const entry of entries) {\n const group = groups.get(entry.file) ?? { killed: 0, survived: 0, timeout: 0, survivors: [] };\n switch (entry.status) {\n case 'killed': group.killed++; break;\n case 'alive': group.survived++; group.survivors.push(entry); break;\n case 'timeout': group.timeout++; break;\n }\n groups.set(entry.file, group);\n }\n\n const fileStats = new Map<string, FileStats>();\n for (const [file, g] of groups) {\n const total = g.killed + g.survived + g.timeout;\n const score = total > 0 ? ((g.killed + g.timeout) / total) * 100 : 100;\n fileStats.set(file, { killed: g.killed, survived: g.survived, timeout: g.timeout, total, score, survivors: g.survivors });\n }\n\n return fileStats;\n}\n\nfunction fileStatsToFinding(file: string, stats: FileStats, threshold: number): Finding {\n return fileScoreFinding({ file, score: stats.score, threshold, survived: stats.survived, total: stats.total, killed: stats.killed, source: 'mutant' });\n}\n\nfunction survivorToFinding(entry: MutantResultEntry): Finding {\n return {\n file: entry.file,\n line: entry.line,\n severity: 'info',\n metric: 'surviving_mutant',\n message: 'Surviving mutant in ' + entry.subject,\n why: 'No test detects this code change, meaning this logic path is not properly verified.',\n suggestion: 'Add a test that would fail if this mutation were applied.',\n metadata: { subject: entry.subject, source: 'mutant' },\n };\n}\n\ninterface ProcessOptions {\n entries: MutantResultEntry[];\n overallScore: number | null;\n files: string[];\n threshold: number;\n maxSurvivorFindings: number;\n}\n\nfunction processEntries(opts: ProcessOptions): AdapterResult & { mutationScore: number } {\n const fileStatsMap = groupByFile(opts.entries);\n const fileSet = new Set(opts.files);\n const findings: Finding[] = [];\n let totalKilled = 0;\n let totalMutants = 0;\n\n for (const [file, stats] of fileStatsMap) {\n if (!fileSet.has(file)) continue;\n\n totalKilled += stats.killed + stats.timeout;\n totalMutants += stats.total;\n\n if (stats.score < opts.threshold) {\n findings.push(fileStatsToFinding(file, stats, opts.threshold));\n findings.push(...stats.survivors.slice(0, opts.maxSurvivorFindings).map(survivorToFinding));\n }\n }\n\n const mutationScore = opts.overallScore ?? (totalMutants > 0 ? (totalKilled / totalMutants) * 100 : 100);\n return { findings, mutationScore };\n}\n\nexport class MutantAdapter implements ToolAdapter {\n name = 'mutant';\n supportedLanguages: Language[] = ['ruby'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('mutant');\n }\n\n async run(files: string[], config: MutantAdapterConfig): Promise<AdapterResult & { mutationScore: number }> {\n if (files.length === 0) return { findings: [], mutationScore: 100 };\n\n const timeout = config.timeout ?? 300000;\n const threshold = config.mutationScoreThreshold ?? 80;\n const maxSurvivorFindings = config.maxSurvivorFindings ?? 5;\n\n const stdout = await this.executeMutant(config.workdir, timeout);\n if (stdout === null) return timeoutResult('mutant', timeout);\n if (!stdout.trim()) return { findings: [], mutationScore: 100 };\n\n const { entries, overallScore } = parseOutput(stdout);\n if (entries.length === 0 && overallScore === null) return { findings: [], mutationScore: 100 };\n\n return processEntries({ entries, overallScore, files, threshold, maxSurvivorFindings });\n }\n\n private async executeMutant(workdir: string, timeout: number): Promise<string | null> {\n const result = await execa('mutant', ['run', '--include', 'lib', '--use', 'rspec'], {\n cwd: workdir,\n reject: false,\n timeout,\n });\n\n if (result.timedOut) return null;\n return result.stdout || '';\n }\n}\n","import type { Gate, GateContext, GateResult, Finding, TestQualityConfig } from '../types/index.js';\nimport { StrykerAdapter, type StrykerAdapterConfig } from '../adapters/stryker.js';\nimport { MutmutAdapter, type MutmutAdapterConfig } from '../adapters/mutmut.js';\nimport { MutantAdapter, type MutantAdapterConfig } from '../adapters/mutant.js';\nimport { calculateTestQualityScore, deriveStatus } from '../scorer.js';\nimport { DEFAULT_TEST_QUALITY } from '../config/defaults.js';\nimport { toolMissingResult } from './shared.js';\n\ninterface ToolAvailability {\n stryker: boolean;\n mutmut: boolean;\n mutant: boolean;\n}\n\nexport class TestQualityGate implements Gate {\n name = 'test_quality';\n private stryker = new StrykerAdapter();\n private mutmut = new MutmutAdapter();\n private mutant = new MutantAdapter();\n\n async run(ctx: GateContext): Promise<GateResult> {\n const start = Date.now();\n const config: TestQualityConfig = ctx.config.testQuality ?? DEFAULT_TEST_QUALITY;\n const available = await this.checkAvailability(config, ctx);\n\n if (!available.stryker && !available.mutmut && !available.mutant) {\n return toolMissingResult(this.name, start, 'No mutation testing tools available', 'Install: npm i -D @stryker-mutator/core | pip install mutmut | gem install mutant');\n }\n\n const { findings, mutationScore } = await this.collectFindings(available, config, ctx);\n const score = calculateTestQualityScore({ mutationScore });\n const status = deriveStatus(score, findings);\n\n return { gate: this.name, score, status, duration_ms: Date.now() - start, findings };\n }\n\n private async checkAvailability(config: TestQualityConfig, ctx: GateContext): Promise<ToolAvailability> {\n const tsOrJs = ctx.language === 'typescript' || ctx.language === 'javascript';\n const isPython = ctx.language === 'python';\n const isRuby = ctx.language === 'ruby';\n\n return {\n stryker: config.strykerEnabled && tsOrJs ? await this.stryker.isAvailable(ctx.workdir) : false,\n mutmut: config.mutmutEnabled && isPython ? await this.mutmut.isAvailable() : false,\n mutant: config.mutantEnabled && isRuby ? await this.mutant.isAvailable() : false,\n };\n }\n\n private async collectFindings(available: ToolAvailability, config: TestQualityConfig, ctx: GateContext): Promise<{ findings: Finding[]; mutationScore: number }> {\n const allFindings: Finding[] = [];\n let totalScore = 0;\n let adapterCount = 0;\n\n const adapters: { available: boolean; adapter: { supportedLanguages: readonly string[]; run: (files: string[], config: any) => Promise<{ findings: Finding[]; mutationScore: number; timedOut?: boolean }> } }[] = [\n { available: available.stryker, adapter: this.stryker },\n { available: available.mutmut, adapter: this.mutmut },\n { available: available.mutant, adapter: this.mutant },\n ];\n\n for (const { available: isAvail, adapter } of adapters) {\n if (!isAvail) continue;\n const result = await this.runAdapter(adapter, ctx, config);\n if (result) {\n allFindings.push(...result.findings);\n if (!result.timedOut) {\n totalScore += result.mutationScore;\n adapterCount++;\n }\n }\n }\n\n const mutationScore = adapterCount > 0 ? totalScore / adapterCount : 100;\n return { findings: allFindings, mutationScore };\n }\n\n private async runAdapter(adapter: { supportedLanguages: readonly string[]; run: (files: string[], config: any) => Promise<{ findings: Finding[]; mutationScore: number; timedOut?: boolean }> }, ctx: GateContext, config: TestQualityConfig): Promise<{ findings: Finding[]; mutationScore: number; timedOut?: boolean } | null> {\n const files = ctx.files\n .filter((f) => adapter.supportedLanguages.includes(f.language))\n .map((f) => f.relativePath);\n\n if (files.length === 0) return null;\n\n return adapter.run(files, {\n workdir: ctx.workdir,\n thresholds: {},\n timeout: config.timeout,\n mutationScoreThreshold: config.mutationScoreThreshold,\n maxSurvivorFindings: config.maxSurvivorFindings,\n });\n }\n}\n","import type { Gate } from '../types/index.js';\nimport { TypeSafetyGate } from './type-safety.js';\nimport { ComplexityGate } from './complexity.js';\nimport { SecurityGate } from './security.js';\nimport { ArchitectureGate } from './architecture.js';\nimport { TestQualityGate } from './test-quality.js';\n\nconst GATE_REGISTRY = new Map<string, Gate>();\n\nfunction registerGate(gate: Gate): void {\n GATE_REGISTRY.set(gate.name, gate);\n}\n\nexport function getGate(name: string): Gate | undefined {\n return GATE_REGISTRY.get(name);\n}\n\nexport function getAllGateNames(): string[] {\n return Array.from(GATE_REGISTRY.keys());\n}\n\nregisterGate(new TypeSafetyGate());\nregisterGate(new ComplexityGate());\nregisterGate(new SecurityGate());\nregisterGate(new ArchitectureGate());\nregisterGate(new TestQualityGate());\n","import type { GateContext, GateResult } from './types/index.js';\nimport { getGate } from './gates/index.js';\n\nexport async function runGates(ctx: GateContext, gateNames: string[]): Promise<GateResult[]> {\n const results: GateResult[] = [];\n\n for (const name of gateNames) {\n const gate = getGate(name);\n if (!gate) {\n results.push({\n gate: name,\n score: 0,\n status: 'skip',\n duration_ms: 0,\n findings: [\n {\n file: '',\n line: 0,\n severity: 'info',\n metric: 'gate_not_found',\n message: `Gate \"${name}\" is not implemented yet.`,\n why: 'This gate has not been registered.',\n },\n ],\n });\n continue;\n }\n\n const result = await gate.run(ctx);\n results.push(result);\n\n if (result.status === 'fail') break;\n }\n\n return results;\n}\n","import type { ProfileConfig } from '../types/index.js';\nimport { DEFAULT_COMPLEXITY, DEFAULT_SECURITY, DEFAULT_TYPE_SAFETY, DEFAULT_ARCHITECTURE, DEFAULT_TEST_QUALITY } from './defaults.js';\n\nconst PROFILES: Record<string, ProfileConfig> = {\n default: {\n name: 'default',\n complexity: DEFAULT_COMPLEXITY,\n security: DEFAULT_SECURITY,\n typeSafety: DEFAULT_TYPE_SAFETY,\n architecture: DEFAULT_ARCHITECTURE,\n testQuality: DEFAULT_TEST_QUALITY,\n },\n critical: {\n name: 'critical',\n complexity: {\n cyclomatic: 6,\n length: 30,\n arguments: 3,\n nesting: 2,\n },\n security: {\n semgrepRules: ['p/security-audit', 'p/secrets', 'p/owasp-top-ten'],\n gitleaksEnabled: true,\n },\n typeSafety: {\n strict: true,\n mypyEnabled: true,\n },\n architecture: {\n madgeEnabled: true,\n jscpdEnabled: true,\n knipEnabled: true,\n jscpdMinLines: 3,\n jscpdMinTokens: 30,\n },\n testQuality: {\n strykerEnabled: true,\n mutmutEnabled: true,\n mutantEnabled: true,\n mutationScoreThreshold: 90,\n timeout: 600000,\n maxSurvivorFindings: 10,\n },\n },\n prototype: {\n name: 'prototype',\n complexity: {\n cyclomatic: 15,\n length: 60,\n arguments: 6,\n nesting: 4,\n },\n security: {\n semgrepRules: ['p/security-audit'],\n gitleaksEnabled: false,\n },\n typeSafety: {\n strict: false,\n mypyEnabled: false,\n },\n architecture: {\n madgeEnabled: false,\n jscpdEnabled: false,\n knipEnabled: false,\n },\n testQuality: {\n strykerEnabled: false,\n mutmutEnabled: false,\n mutantEnabled: false,\n mutationScoreThreshold: 60,\n timeout: 120000,\n maxSurvivorFindings: 3,\n },\n },\n};\n\nexport function getProfile(name: string): ProfileConfig {\n const profile = PROFILES[name];\n if (!profile) {\n throw new Error(`Unknown profile: ${name}. Available: ${Object.keys(PROFILES).join(', ')}`);\n }\n return profile;\n}\n","import chalk from 'chalk';\nimport type { GateResult } from './types/index.js';\nimport { overallStatus } from './scorer.js';\n\nexport interface ReportMeta {\n mode: string;\n filesAnalyzed: number;\n}\n\nexport function reportText(results: GateResult[], meta: ReportMeta): string {\n const lines: string[] = [];\n\n lines.push(chalk.bold('=== VALIDATOR REPORT ==='));\n lines.push(`Files analyzed: ${meta.filesAnalyzed} (mode: ${meta.mode})`);\n lines.push('');\n\n for (const result of results) {\n const icon = statusIcon(result.status);\n const score = `${result.score}%`.padStart(4);\n const duration = `(${(result.duration_ms / 1000).toFixed(1)}s)`;\n lines.push(`${icon} ${result.gate.padEnd(20)} ${score} ${duration}`);\n }\n\n const allFindings = results.flatMap((r) => r.findings);\n if (allFindings.length > 0) {\n lines.push('');\n lines.push(chalk.bold('--- FINDINGS ---'));\n lines.push('');\n\n for (const f of allFindings) {\n const sev =\n f.severity === 'blocker'\n ? chalk.red('[BLOCKER]')\n : f.severity === 'warning'\n ? chalk.yellow('[WARNING]')\n : chalk.blue('[INFO]');\n const loc = f.function ? `${f.file}:${f.line} — ${f.function}` : `${f.file}:${f.line}`;\n lines.push(`${sev} ${loc}`);\n lines.push(` ${f.message}`);\n if (f.why) lines.push(` ${chalk.dim('Why:')} ${f.why}`);\n if (f.suggestion) lines.push(` ${chalk.dim('Fix:')} ${f.suggestion}`);\n lines.push('');\n }\n }\n\n const overall = overallStatus(results);\n const blockerCount = allFindings.filter((f) => f.severity === 'blocker').length;\n const warnCount = allFindings.filter((f) => f.severity === 'warning').length;\n lines.push(\n `RESULT: ${overall.toUpperCase()} (${blockerCount} blockers, ${warnCount} warnings)`,\n );\n\n return lines.join('\\n');\n}\n\nexport function reportJson(results: GateResult[], meta: ReportMeta): string {\n const allFindings = results.flatMap((r) => r.findings);\n const report = {\n version: '0.1.0',\n timestamp: new Date().toISOString(),\n mode: meta.mode,\n files_analyzed: meta.filesAnalyzed,\n overall: {\n status: overallStatus(results),\n blocked_by: results.filter((r) => r.status === 'fail').map((r) => r.gate),\n total_findings: allFindings.length,\n blockers: allFindings.filter((f) => f.severity === 'blocker').length,\n warnings: allFindings.filter((f) => f.severity === 'warning').length,\n },\n gates: Object.fromEntries(results.map((r) => [r.gate, r])),\n };\n return JSON.stringify(report, null, 2);\n}\n\nfunction statusIcon(status: string): string {\n switch (status) {\n case 'pass':\n return chalk.green('[PASS]');\n case 'fail':\n return chalk.red('[FAIL]');\n case 'warn':\n return chalk.yellow('[WARN]');\n case 'skip':\n return chalk.gray('[SKIP]');\n default:\n return '[????]';\n }\n}\n","import { resolveFiles } from './resolver.js';\nimport { runGates } from './runner.js';\nimport { detectPrimaryLanguage } from './detector.js';\nimport { getProfile } from './config/profiles.js';\nimport { getAllGateNames } from './gates/index.js';\nimport type { GateResult, OutputFormat, ResolveMode } from './types/index.js';\nimport { reportJson, reportText } from './reporter.js';\nimport { overallStatus } from './scorer.js';\n\nexport type { Gate, GateContext, GateResult, Finding } from './types/index.js';\nexport type { ProfileConfig, ComplexityThresholds, SecurityConfig, TypeSafetyConfig, ArchitectureConfig, TestQualityConfig, ValidatorConfig } from './types/index.js';\nexport type { Language, FileEntry } from './types/index.js';\n\nexport interface ValidateOptions {\n mode: ResolveMode;\n targets?: string[];\n base?: string;\n head?: string;\n staged?: boolean;\n profile?: string;\n gates?: string[];\n workdir?: string;\n}\n\nexport interface ValidationReport {\n status: 'pass' | 'fail' | 'warn';\n gates: GateResult[];\n filesAnalyzed: number;\n blockers: number;\n warnings: number;\n}\n\nexport async function validate(options: ValidateOptions): Promise<ValidationReport> {\n const workdir = options.workdir ?? process.cwd();\n const profile = getProfile(options.profile ?? 'default');\n const gateNames = options.gates ?? getAllGateNames();\n\n const files = await resolveFiles({\n mode: options.mode,\n targets: options.targets,\n base: options.base,\n head: options.head,\n staged: options.staged,\n workdir,\n });\n\n const language = detectPrimaryLanguage(files);\n const results = await runGates({ files, config: profile, workdir, language }, gateNames);\n\n const allFindings = results.flatMap((r) => r.findings);\n\n return {\n status: overallStatus(results),\n gates: results,\n filesAnalyzed: files.length,\n blockers: allFindings.filter((f) => f.severity === 'blocker').length,\n warnings: allFindings.filter((f) => f.severity === 'warning').length,\n };\n}\n\nexport function formatReport(\n report: ValidationReport,\n format: OutputFormat = 'text',\n mode = 'scan',\n): string {\n const meta = { mode, filesAnalyzed: report.filesAnalyzed };\n return format === 'json'\n ? reportJson(report.gates, meta)\n : reportText(report.gates, meta);\n}\n"],"mappings":"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","names":["path","path","execa","fs","path","execa","path","fs","execa","execa","execa","execa","execa","execa","execa","buildWhy","execa","execa","execa","execa","execa","fs","path","fs","path","execa","execa","execa","execa","fs","path","scoreSeverity","buildScoreMessage","path","fs","execa","execa","execa","execa","groupByFile","survivorToFinding","execa"]}
|
|
1
|
+
{"version":3,"sources":["../src/resolver.ts","../src/detector.ts","../src/adapters/tsc.ts","../src/adapters/base.ts","../src/adapters/mypy.ts","../src/adapters/ruby-syntax.ts","../src/utils.ts","../src/adapters/zeitwerk.ts","../src/scorer.ts","../src/config/defaults.ts","../src/gates/shared.ts","../src/gates/type-safety.ts","../src/adapters/lizard.ts","../src/gates/complexity.ts","../src/adapters/semgrep.ts","../src/adapters/gitleaks.ts","../src/adapters/brakeman.ts","../src/gates/security.ts","../src/adapters/madge.ts","../src/adapters/jscpd.ts","../src/adapters/knip.ts","../src/gates/architecture.ts","../src/adapters/stryker.ts","../src/adapters/mutation-shared.ts","../src/adapters/mutmut.ts","../src/adapters/mutant.ts","../src/adapters/test-command.ts","../src/gates/test-quality.ts","../src/gates/index.ts","../src/runner.ts","../src/config/profiles.ts","../src/reporter.ts","../src/index.ts"],"sourcesContent":["import path from 'node:path';\nimport fs from 'node:fs';\nimport { glob } from 'glob';\nimport { execa } from 'execa';\nimport { detectLanguage, SOURCE_EXTENSIONS } from './detector.js';\nimport type { FileEntry, ResolveMode } from './types/index.js';\n\nexport interface ResolveOptions {\n mode: ResolveMode;\n targets?: string[];\n base?: string;\n head?: string;\n staged?: boolean;\n exclude?: string[];\n workdir: string;\n}\n\nexport async function resolveFiles(options: ResolveOptions): Promise<FileEntry[]> {\n let rawPaths: string[];\n\n switch (options.mode) {\n case 'diff':\n rawPaths = await resolveDiff(options);\n break;\n case 'files':\n rawPaths = await resolveFileList(options);\n break;\n case 'dir':\n rawPaths = await resolveDirectory(options);\n break;\n case 'scan':\n rawPaths = await resolveDirectory({ ...options, targets: ['.'] });\n break;\n default:\n throw new Error(`Unknown mode: ${options.mode}`);\n }\n\n const sourceFiles = rawPaths.filter((p) => {\n const ext = path.extname(p).toLowerCase();\n return SOURCE_EXTENSIONS.includes(ext);\n });\n\n return sourceFiles.map((p) => ({\n path: path.resolve(options.workdir, p),\n relativePath: p,\n language: detectLanguage(p),\n }));\n}\n\nasync function resolveDiff(options: ResolveOptions): Promise<string[]> {\n const args = ['diff', '--name-only', '--diff-filter=ACMR'];\n\n if (options.staged) {\n args.push('--staged');\n } else {\n const base = options.base ?? 'main';\n const head = options.head ?? 'HEAD';\n args.push(`${base}...${head}`);\n }\n\n const result = await execa('git', args, { cwd: options.workdir });\n return result.stdout.trim().split('\\n').filter(Boolean);\n}\n\nasync function resolveFileList(options: ResolveOptions): Promise<string[]> {\n const targets = options.targets ?? [];\n const resolved: string[] = [];\n\n for (const target of targets) {\n if (target.includes('*') || target.includes('?')) {\n const matches = await glob(target, { cwd: options.workdir });\n resolved.push(...matches);\n } else {\n const fullPath = path.resolve(options.workdir, target);\n if (fs.existsSync(fullPath)) {\n resolved.push(target);\n }\n }\n }\n\n return resolved;\n}\n\n// Dependency and build-output directories, which hold code the project does not\n// own and cannot fix. `vendor` covers Ruby's `vendor/bundle` and PHP's Composer\n// tree; `venv`/`.venv` cover Python virtualenvs.\nconst DEFAULT_EXCLUDE = [\n '**/node_modules/**',\n '**/vendor/**',\n '**/venv/**',\n '**/.venv/**',\n '**/dist/**',\n '**/build/**',\n '**/coverage/**',\n '**/.git/**',\n];\n\nasync function resolveDirectory(options: ResolveOptions): Promise<string[]> {\n const dirs = options.targets ?? ['.'];\n const patterns = dirs.map((d) => `${d}/**/*`);\n const ignore = [...DEFAULT_EXCLUDE, ...(options.exclude ?? [])];\n\n return glob(patterns, {\n cwd: options.workdir,\n nodir: true,\n ignore,\n });\n}\n","import path from 'node:path';\nimport type { Language, FileEntry } from './types/index.js';\n\nconst EXTENSION_MAP: Record<string, Language> = {\n '.ts': 'typescript',\n '.tsx': 'typescript',\n '.js': 'javascript',\n '.jsx': 'javascript',\n '.mjs': 'javascript',\n '.cjs': 'javascript',\n '.py': 'python',\n '.rb': 'ruby',\n '.go': 'go',\n '.rs': 'rust',\n};\n\nexport const SOURCE_EXTENSIONS = Object.keys(EXTENSION_MAP);\n\nexport function detectLanguage(filePath: string): Language {\n const ext = path.extname(filePath).toLowerCase();\n return EXTENSION_MAP[ext] ?? 'unknown';\n}\n\nexport function detectPrimaryLanguage(files: FileEntry[]): Language {\n const counts = new Map<Language, number>();\n\n for (const file of files) {\n if (file.language === 'unknown') continue;\n counts.set(file.language, (counts.get(file.language) ?? 0) + 1);\n }\n\n let maxLang: Language = 'unknown';\n let maxCount = 0;\n for (const [lang, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n maxLang = lang;\n }\n }\n\n return maxLang;\n}\n","import { execa } from 'execa';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { Finding, Language } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nexport interface TscAdapterConfig extends AdapterConfig {\n strict?: boolean;\n tsconfigPath?: string;\n}\n\nconst TSC_LINE_RE = /^(.+)\\((\\d+),(\\d+)\\): (error|warning) (TS\\d+): (.+)$/;\n\nfunction resolveLocalBinary(name: string, workdir: string): string | undefined {\n const localPath = path.join(workdir, 'node_modules', '.bin', name);\n return fs.existsSync(localPath) ? localPath : undefined;\n}\n\nfunction buildTscArgs(config: TscAdapterConfig, tsconfigPath: string, hasTsconfig: boolean, files: string[]): string[] {\n const args = ['--noEmit', '--pretty', 'false'];\n if (hasTsconfig) {\n args.push('--project', tsconfigPath);\n } else {\n if (config.strict) args.push('--strict');\n args.push(...files);\n }\n return args;\n}\n\nfunction parseTscOutput(stdout: string, workdir: string, fileSet: Set<string>, hasTsconfig: boolean): Finding[] {\n const findings: Finding[] = [];\n\n for (const line of stdout.split('\\n')) {\n const match = line.match(TSC_LINE_RE);\n if (!match) continue;\n\n const [, filePath, lineNum, , severity, code, message] = match;\n const relativePath = filePath.startsWith('/')\n ? path.relative(workdir, filePath)\n : filePath;\n\n if (hasTsconfig && !fileSet.has(relativePath)) continue;\n\n findings.push({\n file: relativePath,\n line: parseInt(lineNum, 10),\n severity: severity === 'error' ? 'blocker' : 'warning',\n metric: 'type_error',\n message,\n why: `TypeScript compiler error ${code}: the code will not compile.`,\n suggestion: 'Fix the type error to ensure type safety.',\n metadata: { code, source: 'tsc' },\n });\n }\n\n return findings;\n}\n\nexport class TscAdapter implements ToolAdapter {\n name = 'tsc';\n supportedLanguages: Language[] = ['typescript'];\n\n async isAvailable(workdir?: string): Promise<boolean> {\n if (workdir && resolveLocalBinary('tsc', workdir)) return true;\n return isBinaryAvailable('tsc');\n }\n\n async run(files: string[], config: TscAdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) return { findings: [] };\n\n const tsconfigPath = config.tsconfigPath\n ? path.resolve(config.workdir, config.tsconfigPath)\n : path.join(config.workdir, 'tsconfig.json');\n\n const hasTsconfig = fs.existsSync(tsconfigPath);\n const args = buildTscArgs(config, tsconfigPath, hasTsconfig, files);\n const binary = resolveLocalBinary('tsc', config.workdir) ?? 'tsc';\n\n const result = await execa(binary, args, {\n cwd: config.workdir,\n reject: false,\n });\n\n const stdout = result.stdout || '';\n if (!stdout.trim()) return { findings: [] };\n\n const fileSet = new Set(files);\n return { findings: parseTscOutput(stdout, config.workdir, fileSet, hasTsconfig) };\n }\n}\n","import { execa } from 'execa';\nimport type { Language } from '../types/index.js';\nimport type { Finding } from '../types/index.js';\n\nexport interface AdapterConfig {\n workdir: string;\n thresholds: Record<string, number>;\n}\n\nexport interface AdapterResult {\n findings: Finding[];\n totalFunctions?: number;\n}\n\nexport interface ToolAdapter {\n name: string;\n supportedLanguages: Language[];\n isAvailable(): Promise<boolean>;\n run(files: string[], config: AdapterConfig): Promise<AdapterResult>;\n}\n\nexport async function isBinaryAvailable(command: string): Promise<boolean> {\n try {\n await execa(command, ['--version']);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function getBinaryVersion(command: string): Promise<string | undefined> {\n try {\n const { stdout } = await execa(command, ['--version']);\n const match = stdout.match(/(\\d+\\.\\d+\\.\\d+)/);\n return match?.[1];\n } catch {\n return undefined;\n }\n}\n","import { execa } from 'execa';\nimport type { Finding, Language } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nexport interface MypyAdapterConfig extends AdapterConfig {\n strict?: boolean;\n}\n\nconst MYPY_LINE_RE = /^(.+):(\\d+): (error|warning|note): (.+?)(?:\\s+\\[(.+)\\])?$/;\n\nexport class MypyAdapter implements ToolAdapter {\n name = 'mypy';\n supportedLanguages: Language[] = ['python'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('mypy');\n }\n\n async run(files: string[], config: MypyAdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) return { findings: [] };\n\n const args = ['--no-color-output', '--no-error-summary'];\n if (config.strict) args.push('--strict');\n args.push(...files);\n\n const result = await execa('mypy', args, {\n cwd: config.workdir,\n reject: false,\n });\n\n const stdout = result.stdout || '';\n if (!stdout.trim()) return { findings: [] };\n\n const findings: Finding[] = [];\n\n for (const line of stdout.split('\\n')) {\n const match = line.match(MYPY_LINE_RE);\n if (!match) continue;\n\n const [, filePath, lineNum, severity, message, code] = match;\n\n findings.push({\n file: filePath,\n line: parseInt(lineNum, 10),\n severity: mapMypySeverity(severity),\n metric: 'type_error',\n message,\n why: buildMypyWhy(severity, code),\n suggestion: 'Fix the type annotation or value to satisfy the type checker.',\n metadata: { code: code ?? undefined, source: 'mypy' },\n });\n }\n\n return { findings };\n }\n}\n\nfunction mapMypySeverity(level: string): Finding['severity'] {\n switch (level) {\n case 'error':\n return 'blocker';\n case 'warning':\n return 'warning';\n default:\n return 'info';\n }\n}\n\nfunction buildMypyWhy(severity: string, code: string | undefined): string {\n const parts: string[] = [];\n if (severity === 'error') {\n parts.push('mypy type error: the code has an incorrect type annotation or usage');\n } else if (severity === 'warning') {\n parts.push('mypy warning: potential type issue detected');\n } else {\n parts.push('mypy note: additional type information');\n }\n if (code) parts.push(`[${code}]`);\n return parts.join(' ');\n}\n","import { execa } from 'execa';\nimport type { Finding, Language } from '../types/index.js';\nimport type { AdapterConfig, AdapterResult, ToolAdapter } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { chunk } from '../utils.js';\n\nconst RUBY_SYNTAX_LINE = /^(.*?):(\\d+):.*(?:syntax error|unterminated|unexpected)/i;\n\nexport class RubySyntaxAdapter implements ToolAdapter {\n name = 'ruby';\n supportedLanguages: Language[] = ['ruby'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('ruby');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n const findings: Finding[] = [];\n\n for (const batch of chunk(files, 8)) {\n const results = await Promise.all(batch.map(async (file) => ({\n file,\n result: await execa('ruby', ['-c', file], {\n cwd: config.workdir,\n reject: false,\n }),\n })));\n\n for (const { file, result } of results) {\n if (result.exitCode === 0) continue;\n findings.push(buildSyntaxFinding(file, `${result.stderr}\\n${result.stdout}`));\n }\n }\n\n return { findings };\n }\n}\n\nfunction buildSyntaxFinding(file: string, output: string): Finding {\n const relevantLine = output.split('\\n').find((line) => RUBY_SYNTAX_LINE.test(line));\n const match = relevantLine ? RUBY_SYNTAX_LINE.exec(relevantLine) : null;\n\n return {\n file: match?.[1] || file,\n line: match ? Number.parseInt(match[2], 10) : 0,\n severity: 'blocker',\n metric: 'ruby_syntax',\n message: relevantLine?.trim() || `Ruby could not parse ${file}`,\n why: 'Ruby files must parse successfully before Rails can load the application.',\n suggestion: 'Fix the reported Ruby syntax error.',\n metadata: { source: 'ruby' },\n };\n}\n","export function chunk<T>(arr: T[], size: number): T[][] {\n if (size <= 0) return [arr];\n const chunks: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size));\n }\n return chunks;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { execa } from 'execa';\nimport type { Finding, Language } from '../types/index.js';\nimport type { AdapterConfig, AdapterResult, ToolAdapter } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nexport class ZeitwerkAdapter implements ToolAdapter {\n name = 'zeitwerk';\n supportedLanguages: Language[] = ['ruby'];\n\n isRailsProject(workdir: string): boolean {\n return fs.existsSync(path.join(workdir, 'Gemfile'))\n && fs.existsSync(path.join(workdir, 'config', 'application.rb'));\n }\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('bundle');\n }\n\n async run(_files: string[], config: AdapterConfig): Promise<AdapterResult> {\n const result = await execa('bundle', ['exec', 'rails', 'zeitwerk:check'], {\n cwd: config.workdir,\n env: { RAILS_ENV: 'test' },\n reject: false,\n });\n\n if (result.exitCode === 0) return { findings: [] };\n\n const detail = lastOutputLine(`${result.stderr}\\n${result.stdout}`);\n return {\n findings: [{\n file: 'config/application.rb',\n line: 0,\n severity: 'blocker',\n metric: 'rails_zeitwerk',\n message: detail ? `Rails Zeitwerk check failed: ${detail}` : 'Rails Zeitwerk check failed',\n why: 'Rails must boot and autoload application constants consistently.',\n suggestion: 'Run RAILS_ENV=test bundle exec rails zeitwerk:check in the project environment.',\n metadata: { source: 'zeitwerk', exitCode: result.exitCode },\n }],\n };\n }\n}\n\nfunction lastOutputLine(output: string): string | undefined {\n return output.split('\\n').map((line) => line.trim()).filter(Boolean).at(-1)?.slice(0, 500);\n}\n","import type { Finding, GateResult } from './types/index.js';\n\nexport interface ScoreInput {\n totalFunctions: number;\n findings: Finding[];\n}\n\nexport function calculateComplexityScore(input: ScoreInput): number {\n if (input.totalFunctions === 0) return 100;\n const violationCount = input.findings.length;\n const cleanCount = Math.max(0, input.totalFunctions - violationCount);\n return Math.round((cleanCount / input.totalFunctions) * 100);\n}\n\nexport function deriveStatus(score: number, findings: Finding[]): GateResult['status'] {\n const hasBlockers = findings.some((f) => f.severity === 'blocker');\n if (hasBlockers) return 'fail';\n if (score < 70) return 'fail';\n if (score < 85) return 'warn';\n return 'pass';\n}\n\nexport function calculateSecurityScore(input: { findings: Finding[] }): number {\n let score = 100;\n\n for (const finding of input.findings) {\n switch (finding.severity) {\n case 'blocker':\n score -= 25;\n break;\n case 'warning':\n score -= 10;\n break;\n case 'info':\n score -= 3;\n break;\n }\n }\n\n return Math.max(0, score);\n}\n\nexport function calculateTypeSafetyScore(input: { findings: Finding[] }): number {\n let score = 100;\n\n for (const finding of input.findings) {\n switch (finding.severity) {\n case 'blocker':\n score -= 10;\n break;\n case 'warning':\n score -= 5;\n break;\n case 'info':\n score -= 2;\n break;\n }\n }\n\n return Math.max(0, score);\n}\n\nexport function calculateArchitectureScore(input: { findings: Finding[] }): number {\n let score = 100;\n\n for (const finding of input.findings) {\n switch (finding.severity) {\n case 'blocker':\n score -= 15;\n break;\n case 'warning':\n score -= 7;\n break;\n case 'info':\n score -= 3;\n break;\n }\n }\n\n return Math.max(0, score);\n}\n\nexport function calculateTestQualityScore(input: { mutationScore: number }): number {\n return Math.round(Math.max(0, Math.min(100, input.mutationScore)));\n}\n\nexport function overallStatus(results: GateResult[]): 'pass' | 'fail' | 'warn' {\n if (results.some((r) => r.status === 'fail')) return 'fail';\n if (results.some((r) => r.status === 'warn' || r.status === 'skip')) return 'warn';\n return 'pass';\n}\n","import type { ComplexityThresholds, SecurityConfig, TypeSafetyConfig, ArchitectureConfig, TestQualityConfig } from '../types/index.js';\n\nexport const DEFAULT_COMPLEXITY: ComplexityThresholds = {\n cyclomatic: 10,\n length: 40,\n arguments: 4,\n nesting: 3,\n};\n\nexport const DEFAULT_SECURITY: SecurityConfig = {\n semgrepRules: ['p/security-audit', 'p/secrets'],\n gitleaksEnabled: true,\n brakemanEnabled: true,\n};\n\nexport const DEFAULT_TYPE_SAFETY: TypeSafetyConfig = {\n strict: false,\n mypyEnabled: true,\n rubySyntaxEnabled: true,\n railsZeitwerkEnabled: true,\n};\n\nexport const DEFAULT_JSCPD_EXCLUDE: string[] = [\n '**/test/**',\n '**/tests/**',\n '**/__tests__/**',\n '**/*.test.*',\n '**/*.spec.*',\n '**/docs/**',\n '**/*.md',\n '**/fixtures/**',\n '**/mocks/**',\n '**/node_modules/**',\n '**/dist/**',\n '**/vendor/**',\n];\n\nexport const DEFAULT_ARCHITECTURE: ArchitectureConfig = {\n madgeEnabled: true,\n jscpdEnabled: true,\n knipEnabled: true,\n};\n\nexport const DEFAULT_TEST_QUALITY: TestQualityConfig = {\n strykerEnabled: true,\n mutmutEnabled: true,\n mutantEnabled: true,\n mutationScoreThreshold: 80,\n timeout: 300000,\n maxSurvivorFindings: 5,\n};\n","import type { GateResult } from '../types/index.js';\n\nexport function toolMissingResult(gate: string, start: number, message: string, suggestion: string): GateResult {\n return {\n gate,\n score: 0,\n status: 'skip',\n duration_ms: Date.now() - start,\n findings: [\n {\n file: '',\n line: 0,\n severity: 'info',\n metric: 'tool_missing',\n message,\n why: `The ${gate} gate requires at least one tool to function.`,\n suggestion,\n },\n ],\n };\n}\n","import type { Gate, GateContext, GateResult, Finding, TypeSafetyConfig } from '../types/index.js';\nimport { TscAdapter, type TscAdapterConfig } from '../adapters/tsc.js';\nimport { MypyAdapter, type MypyAdapterConfig } from '../adapters/mypy.js';\nimport { RubySyntaxAdapter } from '../adapters/ruby-syntax.js';\nimport { ZeitwerkAdapter } from '../adapters/zeitwerk.js';\nimport { calculateTypeSafetyScore, deriveStatus } from '../scorer.js';\nimport { DEFAULT_TYPE_SAFETY } from '../config/defaults.js';\nimport { toolMissingResult } from './shared.js';\n\nexport class TypeSafetyGate implements Gate {\n name = 'type_safety';\n private tsc = new TscAdapter();\n private mypy = new MypyAdapter();\n private ruby = new RubySyntaxAdapter();\n private zeitwerk = new ZeitwerkAdapter();\n\n async run(ctx: GateContext): Promise<GateResult> {\n const start = Date.now();\n const config: TypeSafetyConfig = ctx.config.typeSafety ?? DEFAULT_TYPE_SAFETY;\n\n if (ctx.language === 'typescript') {\n return this.runTsc(ctx, config, start);\n }\n\n if (ctx.language === 'python' && config.mypyEnabled) {\n return this.runMypy(ctx, config, start);\n }\n\n if (ctx.language === 'ruby' && config.rubySyntaxEnabled !== false) {\n return this.runRuby(ctx, config, start);\n }\n\n const suggestion = ctx.language === 'python'\n ? 'Enable mypyEnabled in profile or install mypy: pip install mypy'\n : 'No type checker supported for this language yet.';\n return toolMissingResult(this.name, start, `No type checker available for language: ${ctx.language}`, suggestion);\n }\n\n private getFiles(ctx: GateContext, adapter: { supportedLanguages: readonly string[] }): string[] {\n return ctx.files\n .filter((f) => adapter.supportedLanguages.includes(f.language))\n .map((f) => f.relativePath);\n }\n\n private emptyResult(start: number): GateResult {\n return { gate: this.name, score: 100, status: 'pass', duration_ms: Date.now() - start, findings: [] };\n }\n\n private async runTsc(ctx: GateContext, config: TypeSafetyConfig, start: number): Promise<GateResult> {\n const available = await this.tsc.isAvailable(ctx.workdir);\n if (!available) {\n return toolMissingResult(this.name, start, 'tsc is not installed', 'Install with: npm install -g typescript');\n }\n\n const files = this.getFiles(ctx, this.tsc);\n if (files.length === 0) return this.emptyResult(start);\n\n const adapterConfig: TscAdapterConfig = {\n workdir: ctx.workdir,\n thresholds: {},\n strict: config.strict,\n tsconfigPath: config.tsconfigPath,\n };\n\n const result = await this.tsc.run(files, adapterConfig);\n return this.buildResult(result.findings, start);\n }\n\n private async runMypy(ctx: GateContext, config: TypeSafetyConfig, start: number): Promise<GateResult> {\n const available = await this.mypy.isAvailable();\n if (!available) {\n return toolMissingResult(this.name, start, 'mypy is not installed', 'Install with: pip install mypy');\n }\n\n const files = this.getFiles(ctx, this.mypy);\n if (files.length === 0) return this.emptyResult(start);\n\n const adapterConfig: MypyAdapterConfig = {\n workdir: ctx.workdir,\n thresholds: {},\n strict: config.strict,\n };\n\n const result = await this.mypy.run(files, adapterConfig);\n return this.buildResult(result.findings, start);\n }\n\n private async runRuby(ctx: GateContext, config: TypeSafetyConfig, start: number): Promise<GateResult> {\n if (!await this.ruby.isAvailable()) {\n return toolMissingResult(\n this.name,\n start,\n 'Ruby is not installed in the validation environment',\n 'Run the validator from the project Ruby/Docker environment.',\n );\n }\n\n const files = this.getFiles(ctx, this.ruby);\n if (files.length === 0) return this.emptyResult(start);\n\n const adapterConfig = { workdir: ctx.workdir, thresholds: {} };\n const syntaxResult = await this.ruby.run(files, adapterConfig);\n const findings = [...syntaxResult.findings];\n if (findings.length > 0) return this.buildResult(findings, start);\n\n if (config.railsZeitwerkEnabled !== false && this.zeitwerk.isRailsProject(ctx.workdir)) {\n if (await this.zeitwerk.isAvailable()) {\n const zeitwerkResult = await this.zeitwerk.run(files, adapterConfig);\n findings.push(...zeitwerkResult.findings);\n } else {\n findings.push({\n file: 'Gemfile',\n line: 0,\n severity: 'warning',\n metric: 'rails_check_skipped',\n message: 'Rails Zeitwerk check was skipped because Bundler is unavailable',\n why: 'Ruby syntax alone does not verify that Rails can boot and autoload constants.',\n suggestion: 'Run the validator inside the project Docker image with Bundler available.',\n metadata: { source: 'zeitwerk' },\n });\n }\n }\n\n const result = this.buildResult(findings, start);\n if (findings.some((finding) => finding.metric === 'rails_check_skipped') && result.status === 'pass') {\n result.status = 'warn';\n }\n return result;\n }\n\n private buildResult(findings: Finding[], start: number): GateResult {\n const score = calculateTypeSafetyScore({ findings });\n const status = deriveStatus(score, findings);\n return { gate: this.name, score, status, duration_ms: Date.now() - start, findings };\n }\n\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { chunk } from '../utils.js';\n\nexport class LizardAdapter implements ToolAdapter {\n name = 'lizard';\n supportedLanguages: Language[] = [\n 'typescript',\n 'javascript',\n 'python',\n 'ruby',\n 'go',\n 'rust',\n ];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('lizard');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) {\n return { findings: [], totalFunctions: 0 };\n }\n\n const allFindings: Finding[] = [];\n let totalFunctions = 0;\n\n for (const batch of chunk(files, 50)) {\n const result = await execa('lizard', [...batch, '--csv'], {\n cwd: config.workdir,\n reject: false,\n });\n\n const parsed = parseLizardCsv(result.stdout, config.thresholds);\n allFindings.push(...parsed.findings);\n totalFunctions += parsed.totalFunctions;\n }\n\n return { findings: allFindings, totalFunctions };\n }\n}\n\ninterface ParseResult {\n findings: Finding[];\n totalFunctions: number;\n}\n\ninterface FunctionMetrics {\n nloc: number;\n ccn: number;\n params: number;\n file: string;\n func: string;\n start: number;\n end: number;\n}\n\nfunction parseCsvRow(fields: string[]): FunctionMetrics | null {\n if (fields.length < 11) return null;\n const ccn = parseInt(fields[1], 10);\n if (isNaN(ccn)) return null;\n return {\n nloc: parseInt(fields[0], 10),\n ccn,\n params: parseInt(fields[3], 10),\n file: fields[6],\n func: fields[7],\n start: parseInt(fields[9], 10),\n end: parseInt(fields[10], 10),\n };\n}\n\nfunction detectViolations(m: FunctionMetrics, thresholds: Record<string, number>): string[] {\n const violations: string[] = [];\n if (m.ccn > (thresholds.cyclomatic ?? 10)) violations.push('cyclomatic');\n if (m.nloc > (thresholds.length ?? 40)) violations.push('length');\n if (m.params > (thresholds.arguments ?? 4)) violations.push('arguments');\n return violations;\n}\n\nfunction metricsToFinding(m: FunctionMetrics, violations: string[], thresholds: Record<string, number>): Finding {\n return {\n file: m.file,\n line: m.start,\n end_line: m.end,\n function: m.func,\n severity: determineSeverity(m, thresholds),\n metric: 'complexity',\n value: m.ccn,\n threshold: thresholds.cyclomatic ?? 10,\n message: buildMessage(m, violations, thresholds),\n why: buildWhy(m, violations),\n suggestion: buildSuggestion(violations),\n metadata: { nloc: m.nloc, ccn: m.ccn, params: m.params, violations },\n };\n}\n\nfunction parseLizardCsv(csv: string, thresholds: Record<string, number>): ParseResult {\n const lines = csv.trim().split('\\n');\n if (lines.length <= 1) return { findings: [], totalFunctions: 0 };\n\n const findings: Finding[] = [];\n let totalFunctions = 0;\n\n for (const line of lines.slice(1)) {\n const m = parseCsvRow(parseCSVLine(line));\n if (!m) continue;\n totalFunctions++;\n\n const violations = detectViolations(m, thresholds);\n if (violations.length === 0) continue;\n\n findings.push(metricsToFinding(m, violations, thresholds));\n }\n\n return { findings, totalFunctions };\n}\n\nfunction determineSeverity(m: FunctionMetrics, thresholds: Record<string, number>): Finding['severity'] {\n const ccnRatio = m.ccn / (thresholds.cyclomatic ?? 10);\n const nlocRatio = m.nloc / (thresholds.length ?? 40);\n if (ccnRatio > 1.5 || nlocRatio > 1.5) return 'blocker';\n return 'warning';\n}\n\nfunction buildMessage(m: FunctionMetrics, violations: string[], thresholds: Record<string, number>): string {\n const parts: string[] = [];\n if (violations.includes('cyclomatic')) {\n parts.push(`Cyclomatic: ${m.ccn} (max: ${thresholds.cyclomatic ?? 10})`);\n }\n if (violations.includes('length')) {\n parts.push(`NLOC: ${m.nloc} (max: ${thresholds.length ?? 40})`);\n }\n if (violations.includes('arguments')) {\n parts.push(`Params: ${m.params} (max: ${thresholds.arguments ?? 4})`);\n }\n return parts.join(' | ');\n}\n\nfunction buildWhy(m: FunctionMetrics, violations: string[]): string {\n if (violations.includes('cyclomatic') && violations.includes('length')) {\n return `${m.ccn} execution paths in ${m.nloc} lines. Difficult to test exhaustively and high risk of bugs on change.`;\n }\n if (violations.includes('cyclomatic')) {\n return `${m.ccn} execution paths make this function hard to test and maintain.`;\n }\n if (violations.includes('length')) {\n return `${m.nloc} lines suggests this function does more than one thing.`;\n }\n if (violations.includes('arguments')) {\n return 'Too many parameters indicates this function has too many responsibilities or needs a config object.';\n }\n return 'Function exceeds complexity thresholds.';\n}\n\nfunction buildSuggestion(violations: string[]): string {\n if (violations.includes('cyclomatic') || violations.includes('length')) {\n return 'Extract into smaller, focused functions with single responsibility.';\n }\n if (violations.includes('arguments')) {\n return 'Group related parameters into an options/config object.';\n }\n return 'Simplify this function.';\n}\n\nfunction parseCSVLine(line: string): string[] {\n const fields: string[] = [];\n let current = '';\n let inQuotes = false;\n for (const char of line) {\n if (char === '\"') {\n inQuotes = !inQuotes;\n } else if (char === ',' && !inQuotes) {\n fields.push(current.trim());\n current = '';\n } else {\n current += char;\n }\n }\n fields.push(current.trim());\n return fields;\n}\n\n","import type { Gate, GateContext, GateResult } from '../types/index.js';\nimport { LizardAdapter } from '../adapters/lizard.js';\nimport { calculateComplexityScore, deriveStatus } from '../scorer.js';\nimport { toolMissingResult } from './shared.js';\n\nexport class ComplexityGate implements Gate {\n name = 'complexity';\n private adapter = new LizardAdapter();\n\n async run(ctx: GateContext): Promise<GateResult> {\n const start = Date.now();\n\n const available = await this.adapter.isAvailable();\n if (!available) {\n return toolMissingResult(this.name, start, 'lizard is not installed', 'Install with: pip install lizard');\n }\n\n const supportedFiles = ctx.files\n .filter((f) => this.adapter.supportedLanguages.includes(f.language))\n .map((f) => f.relativePath);\n\n if (supportedFiles.length === 0) {\n return {\n gate: this.name,\n score: 100,\n status: 'pass',\n duration_ms: Date.now() - start,\n findings: [],\n };\n }\n\n const { findings, totalFunctions = 0 } = await this.adapter.run(supportedFiles, {\n workdir: ctx.workdir,\n thresholds: {\n cyclomatic: ctx.config.complexity.cyclomatic,\n length: ctx.config.complexity.length,\n arguments: ctx.config.complexity.arguments,\n },\n });\n\n const score = calculateComplexityScore({ totalFunctions, findings });\n const status = deriveStatus(score, findings);\n const duration_ms = Date.now() - start;\n\n return { gate: this.name, score, status, duration_ms, findings };\n }\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { chunk } from '../utils.js';\n\nexport interface SemgrepAdapterConfig extends AdapterConfig {\n rules?: string[];\n}\n\nexport class SemgrepAdapter implements ToolAdapter {\n name = 'semgrep';\n supportedLanguages: Language[] = [\n 'typescript',\n 'javascript',\n 'python',\n 'ruby',\n 'go',\n 'rust',\n ];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('semgrep');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) {\n return { findings: [] };\n }\n\n const rules = (config as SemgrepAdapterConfig).rules ?? ['p/security-audit', 'p/secrets'];\n const allFindings: Finding[] = [];\n\n for (const batch of chunk(files, 50)) {\n const configArgs = rules.flatMap((r) => ['--config', r]);\n const result = await execa(\n 'semgrep',\n [...configArgs, '--json', ...batch],\n { cwd: config.workdir, reject: false },\n );\n\n const parsed = parseSemgrepJson(result.stdout || '');\n if (!parsed || ![0, 1].includes(result.exitCode ?? -1) || parsed.errors.length > 0) {\n allFindings.push(toolErrorFinding(result.exitCode));\n continue;\n }\n allFindings.push(...parsed.findings);\n }\n\n return { findings: allFindings };\n }\n}\n\ninterface SemgrepOutput {\n results: SemgrepResult[];\n errors: unknown[];\n paths: { scanned: string[]; skipped: string[] };\n}\n\ninterface SemgrepResult {\n check_id: string;\n path: string;\n start: { line: number; col: number };\n end: { line: number; col: number };\n extra: {\n message: string;\n severity: string;\n metadata?: {\n cwe?: string[];\n owasp?: string[];\n confidence?: string;\n };\n fix?: string;\n lines?: string;\n };\n}\n\nfunction parseSemgrepJson(json: string): { findings: Finding[]; errors: unknown[] } | null {\n let output: SemgrepOutput;\n try {\n output = JSON.parse(json) as SemgrepOutput;\n } catch {\n return null;\n }\n\n if (!output.results || !Array.isArray(output.results)) {\n return null;\n }\n\n const findings = output.results.map((r) => ({\n file: r.path,\n line: r.start.line,\n end_line: r.end.line,\n severity: mapSeverity(r.extra.severity),\n metric: 'security',\n message: r.extra.message,\n why: buildWhy(r),\n suggestion: r.extra.fix ?? undefined,\n metadata: {\n ruleId: r.check_id,\n cwe: r.extra.metadata?.cwe,\n owasp: r.extra.metadata?.owasp,\n confidence: r.extra.metadata?.confidence,\n source: 'semgrep',\n },\n }));\n return { findings, errors: Array.isArray(output.errors) ? output.errors : [] };\n}\n\nfunction toolErrorFinding(exitCode: number | undefined): Finding {\n return {\n file: '',\n line: 0,\n severity: 'blocker',\n metric: 'security_tool_error',\n message: 'Semgrep failed or produced an invalid report',\n why: 'A failed security scan cannot be interpreted as having no vulnerabilities.',\n suggestion: 'Run Semgrep directly and verify network access, rules, and JSON output.',\n metadata: { source: 'semgrep', exitCode },\n };\n}\n\nfunction mapSeverity(severity: string): Finding['severity'] {\n switch (severity) {\n case 'ERROR':\n return 'blocker';\n case 'WARNING':\n return 'warning';\n case 'INFO':\n return 'info';\n default:\n return 'warning';\n }\n}\n\nfunction buildWhy(result: SemgrepResult): string {\n const parts: string[] = [];\n if (result.extra.metadata?.cwe?.length) {\n parts.push(result.extra.metadata.cwe.join(', '));\n }\n if (result.extra.metadata?.owasp?.length) {\n parts.push(result.extra.metadata.owasp.join(', '));\n }\n if (parts.length === 0) {\n return `Security issue detected by rule ${result.check_id}.`;\n }\n return `${parts.join(' | ')}. Detected by rule ${result.check_id}.`;\n}\n","import { execa } from 'execa';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nexport class GitleaksAdapter implements ToolAdapter {\n name = 'gitleaks';\n supportedLanguages: Language[] = [\n 'typescript',\n 'javascript',\n 'python',\n 'ruby',\n 'go',\n 'rust',\n 'unknown',\n ];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('gitleaks');\n }\n\n async run(_files: string[], config: AdapterConfig): Promise<AdapterResult> {\n const reportDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'validator-gitleaks-'));\n const reportPath = path.join(reportDirectory, 'report.json');\n\n try {\n const result = await execa(\n 'gitleaks',\n ['detect', '--source', config.workdir, '--no-git', '-f', 'json', '--report-path', reportPath],\n { cwd: config.workdir, reject: false },\n );\n const output = fs.existsSync(reportPath)\n ? fs.readFileSync(reportPath, 'utf8')\n : result.stdout;\n\n if ((!output || output.trim() === '') && result.exitCode === 0) {\n return { findings: [] };\n }\n\n const allLeaks = parseGitleaksJson(output);\n if (!allLeaks || ![0, 1].includes(result.exitCode ?? -1)) {\n return { findings: [toolErrorFinding(result.exitCode)] };\n }\n return {\n findings: allLeaks.map((finding) => ({\n ...finding,\n file: path.isAbsolute(finding.file)\n ? path.relative(config.workdir, finding.file)\n : finding.file,\n })),\n };\n } finally {\n fs.rmSync(reportDirectory, { recursive: true, force: true });\n }\n }\n}\n\ninterface GitleaksLeak {\n Description: string;\n StartLine: number;\n EndLine: number;\n File: string;\n RuleID: string;\n Entropy: number;\n Fingerprint: string;\n}\n\nfunction parseGitleaksJson(json: string): Finding[] | null {\n let leaks: GitleaksLeak[];\n try {\n leaks = JSON.parse(json) as GitleaksLeak[];\n } catch {\n return null;\n }\n\n if (!Array.isArray(leaks)) {\n return null;\n }\n\n return leaks.map((leak) => ({\n file: leak.File,\n line: leak.StartLine,\n end_line: leak.EndLine,\n severity: 'blocker' as const,\n metric: 'security',\n message: `Secret detected: ${leak.Description}`,\n why: `Exposed secrets can lead to unauthorized access. Rule: ${leak.RuleID}.`,\n suggestion: 'Remove the secret and rotate the credential. Use environment variables or a secrets manager.',\n metadata: {\n ruleId: leak.RuleID,\n entropy: leak.Entropy,\n fingerprint: leak.Fingerprint,\n source: 'gitleaks',\n },\n }));\n}\n\nfunction toolErrorFinding(exitCode: number | undefined): Finding {\n return {\n file: '',\n line: 0,\n severity: 'blocker',\n metric: 'security_tool_error',\n message: 'Gitleaks failed or produced an invalid report',\n why: 'A failed secret scan cannot be interpreted as having no exposed credentials.',\n suggestion: 'Run Gitleaks directly and verify its configuration and JSON output.',\n metadata: { source: 'gitleaks', exitCode },\n };\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { execa } from 'execa';\nimport type { Finding, Language } from '../types/index.js';\nimport type { AdapterConfig, AdapterResult, ToolAdapter } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\ninterface BrakemanWarning {\n warning_type: string;\n warning_code: number;\n fingerprint: string;\n check_name: string;\n message: string;\n file: string;\n line?: number;\n confidence: 'High' | 'Medium' | 'Weak';\n}\n\ninterface BrakemanReport {\n warnings: BrakemanWarning[];\n errors?: string[];\n}\n\nexport class BrakemanAdapter implements ToolAdapter {\n name = 'brakeman';\n supportedLanguages: Language[] = ['ruby'];\n\n isRailsProject(workdir: string): boolean {\n return fs.existsSync(path.join(workdir, 'Gemfile'))\n && fs.existsSync(path.join(workdir, 'config', 'application.rb'));\n }\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('brakeman');\n }\n\n async run(_files: string[], config: AdapterConfig): Promise<AdapterResult> {\n const result = await execa(\n 'brakeman',\n ['--format', 'json', '--quiet', '--no-exit-on-warn'],\n { cwd: config.workdir, reject: false },\n );\n\n const report = parseReport(result.stdout || '');\n if (!report || result.exitCode !== 0 || report.errors?.length) {\n return { findings: [toolErrorFinding(result.exitCode)] };\n }\n\n return { findings: report.warnings.map(toFinding) };\n }\n}\n\nfunction parseReport(output: string): BrakemanReport | null {\n try {\n const report = JSON.parse(output) as BrakemanReport;\n return Array.isArray(report.warnings) ? report : null;\n } catch {\n return null;\n }\n}\n\nfunction toFinding(warning: BrakemanWarning): Finding {\n return {\n file: warning.file,\n line: warning.line ?? 0,\n severity: warning.confidence === 'High'\n ? 'blocker'\n : warning.confidence === 'Medium' ? 'warning' : 'info',\n metric: 'rails_security',\n message: warning.message,\n why: `${warning.warning_type} detected by Brakeman's ${warning.check_name} check.`,\n suggestion: 'Review the affected Rails code and apply the mitigation recommended by Brakeman.',\n metadata: {\n source: 'brakeman',\n warningCode: warning.warning_code,\n fingerprint: warning.fingerprint,\n confidence: warning.confidence,\n },\n };\n}\n\nfunction toolErrorFinding(exitCode: number | undefined): Finding {\n return {\n file: '',\n line: 0,\n severity: 'blocker',\n metric: 'security_tool_error',\n message: 'Brakeman failed or produced an invalid report',\n why: 'A failed Rails security scan cannot be interpreted as having no vulnerabilities.',\n suggestion: 'Run brakeman --format json --no-exit-on-warn directly and fix the reported execution error.',\n metadata: { source: 'brakeman', exitCode },\n };\n}\n","import type { Gate, GateContext, GateResult, Finding, SecurityConfig } from '../types/index.js';\nimport { SemgrepAdapter, type SemgrepAdapterConfig } from '../adapters/semgrep.js';\nimport { GitleaksAdapter } from '../adapters/gitleaks.js';\nimport { BrakemanAdapter } from '../adapters/brakeman.js';\nimport { calculateSecurityScore, deriveStatus } from '../scorer.js';\nimport { DEFAULT_SECURITY } from '../config/defaults.js';\nimport { toolMissingResult } from './shared.js';\n\nexport class SecurityGate implements Gate {\n name = 'security';\n private semgrep = new SemgrepAdapter();\n private gitleaks = new GitleaksAdapter();\n private brakeman = new BrakemanAdapter();\n\n async run(ctx: GateContext): Promise<GateResult> {\n const start = Date.now();\n const securityConfig: SecurityConfig = ctx.config.security ?? DEFAULT_SECURITY;\n\n const semgrepAvailable = await this.semgrep.isAvailable();\n const gitleaksAvailable = securityConfig.gitleaksEnabled\n ? await this.gitleaks.isAvailable()\n : false;\n const brakemanApplicable = ctx.language === 'ruby'\n && securityConfig.brakemanEnabled !== false\n && this.brakeman.isRailsProject(ctx.workdir);\n const brakemanAvailable = brakemanApplicable ? await this.brakeman.isAvailable() : false;\n\n if (!semgrepAvailable && !gitleaksAvailable && !brakemanAvailable) {\n return toolMissingResult(this.name, start, 'No security tools are installed', 'Install Semgrep, Gitleaks, or Brakeman.');\n }\n\n const allFindings: Finding[] = [];\n if (brakemanApplicable && !brakemanAvailable) {\n allFindings.push({\n file: 'Gemfile',\n line: 0,\n severity: 'info',\n metric: 'rails_security_skipped',\n message: 'Brakeman is not installed; Rails-specific security checks were skipped',\n why: 'Generic security rules do not cover all Rails-specific vulnerability patterns.',\n suggestion: 'Install Brakeman or use the Rails validator image.',\n metadata: { source: 'brakeman' },\n });\n }\n\n if (semgrepAvailable) {\n const supportedFiles = ctx.files\n .filter((f) => this.semgrep.supportedLanguages.includes(f.language))\n .map((f) => f.relativePath);\n\n if (supportedFiles.length > 0) {\n const semgrepConfig: SemgrepAdapterConfig = {\n workdir: ctx.workdir,\n thresholds: {},\n rules: securityConfig.semgrepRules,\n };\n const result = await this.semgrep.run(supportedFiles, semgrepConfig);\n allFindings.push(...result.findings);\n }\n }\n\n if (gitleaksAvailable) {\n const allFiles = ctx.files.map((f) => f.relativePath);\n const result = await this.gitleaks.run(allFiles, {\n workdir: ctx.workdir,\n thresholds: {},\n });\n allFindings.push(...result.findings);\n }\n\n if (brakemanAvailable) {\n const result = await this.brakeman.run([], {\n workdir: ctx.workdir,\n thresholds: {},\n });\n allFindings.push(...result.findings);\n }\n\n const score = calculateSecurityScore({ findings: allFindings });\n const derivedStatus = deriveStatus(score, allFindings);\n const status = allFindings.some((finding) => finding.metric === 'rails_security_skipped')\n && derivedStatus === 'pass'\n ? 'warn'\n : derivedStatus;\n const duration_ms = Date.now() - start;\n\n return { gate: this.name, score, status, duration_ms, findings: allFindings };\n }\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nfunction parseCycles(stdout: string): string[][] | null {\n if (!stdout.trim()) return null;\n try {\n const cycles = JSON.parse(stdout) as string[][];\n if (!Array.isArray(cycles) || cycles.length === 0) return null;\n return cycles;\n } catch {\n return null;\n }\n}\n\nfunction cycleToFinding(cycle: string[]): Finding {\n const cycleDesc = cycle.join(' → ') + ' → ' + cycle[0];\n return {\n file: cycle[0],\n line: 0,\n severity: 'blocker',\n metric: 'circular_dependency',\n message: `Circular dependency: ${cycleDesc}`,\n why: 'Circular dependencies make the code harder to test, refactor, and reason about.',\n suggestion: 'Break the cycle by extracting shared code into a separate module.',\n metadata: { cycle, source: 'madge' },\n };\n}\n\nexport class MadgeAdapter implements ToolAdapter {\n name = 'madge';\n supportedLanguages: Language[] = ['typescript', 'javascript'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('madge');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) return { findings: [] };\n\n const result = await execa('madge', ['--circular', '--json', config.workdir], {\n cwd: config.workdir,\n reject: false,\n });\n\n const cycles = parseCycles(result.stdout || '');\n if (!cycles) return { findings: [] };\n\n const fileSet = new Set(files);\n const findings = cycles\n .filter((cycle) => Array.isArray(cycle) && cycle.length > 0)\n .filter((cycle) => cycle.some((f) => fileSet.has(f)))\n .map(cycleToFinding);\n\n return { findings };\n }\n}\n","import { execa } from 'execa';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\nexport interface JscpdAdapterConfig extends AdapterConfig {\n minLines?: number;\n minTokens?: number;\n exclude?: string[];\n}\n\ninterface JscpdClone {\n format: string;\n lines: number;\n tokens: number;\n firstFile: { name: string; startLoc: { line: number; column: number }; endLoc: { line: number; column: number } };\n secondFile: { name: string; startLoc: { line: number; column: number }; endLoc: { line: number; column: number } };\n}\n\ninterface JscpdReport {\n duplicates: JscpdClone[];\n statistics: unknown;\n}\n\nfunction buildArgs(config: JscpdAdapterConfig, tmpDir: string): string[] {\n const minLines = config.minLines ?? 5;\n const minTokens = config.minTokens ?? 50;\n const exclude = config.exclude ?? [];\n\n const args = [\n '--min-lines', String(minLines),\n '--min-tokens', String(minTokens),\n '--reporters', 'json',\n '--silent',\n '--output', tmpDir,\n ];\n\n for (const pattern of exclude) {\n args.push('--ignore', pattern);\n }\n\n args.push(config.workdir);\n return args;\n}\n\nfunction parseReport(reportPath: string): JscpdReport | null {\n if (!fs.existsSync(reportPath)) return null;\n\n const raw = fs.readFileSync(reportPath, 'utf-8');\n try {\n const report = JSON.parse(raw) as JscpdReport;\n if (!report.duplicates || !Array.isArray(report.duplicates)) return null;\n return report;\n } catch {\n return null;\n }\n}\n\nfunction cloneToFinding(clone: JscpdClone, workdir: string): Finding {\n const firstRel = path.relative(workdir, clone.firstFile.name);\n const secondRel = path.relative(workdir, clone.secondFile.name);\n\n return {\n file: firstRel,\n line: clone.firstFile.startLoc.line,\n end_line: clone.firstFile.endLoc.line,\n severity: 'warning',\n metric: 'code_duplication',\n message: `${clone.lines} lines duplicated with ${secondRel}:${clone.secondFile.startLoc.line}`,\n why: 'Duplicated code increases maintenance burden and risk of inconsistent changes.',\n suggestion: 'Extract the duplicated logic into a shared function or module.',\n metadata: {\n lines: clone.lines,\n tokens: clone.tokens,\n secondFile: secondRel,\n secondLine: clone.secondFile.startLoc.line,\n source: 'jscpd',\n },\n };\n}\n\nexport class JscpdAdapter implements ToolAdapter {\n name = 'jscpd';\n supportedLanguages: Language[] = ['typescript', 'javascript', 'python', 'ruby'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('jscpd');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) return { findings: [] };\n\n const jscpdConfig = config as JscpdAdapterConfig;\n const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jscpd-'));\n\n try {\n const args = buildArgs(jscpdConfig, tmpDir);\n await execa('jscpd', args, { cwd: config.workdir, reject: false });\n\n const report = parseReport(path.join(tmpDir, 'jscpd-report.json'));\n if (!report) return { findings: [] };\n\n const fileSet = new Set(files);\n\n return {\n findings: report.duplicates\n .filter((clone) => {\n const firstRel = path.relative(config.workdir, clone.firstFile.name);\n const secondRel = path.relative(config.workdir, clone.secondFile.name);\n return fileSet.has(firstRel) || fileSet.has(secondRel);\n })\n .map((clone) => cloneToFinding(clone, config.workdir)),\n };\n } finally {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n }\n }\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\n\ninterface KnipIssue {\n name: string;\n line?: number;\n col?: number;\n pos?: number;\n}\n\ninterface KnipFileIssue {\n file: string;\n dependencies?: KnipIssue[];\n devDependencies?: KnipIssue[];\n exports?: KnipIssue[];\n types?: KnipIssue[];\n duplicates?: KnipIssue[][];\n}\n\ninterface KnipReport {\n files: string[];\n issues: KnipFileIssue[];\n}\n\nfunction collectUnusedFiles(report: KnipReport, fileSet: Set<string>): Finding[] {\n if (!report.files || !Array.isArray(report.files)) return [];\n\n return report.files\n .filter((file) => fileSet.has(file))\n .map((file) => ({\n file,\n line: 0,\n severity: 'info' as const,\n metric: 'dead_code',\n message: `Unused file: ${file}`,\n why: 'Unused files add confusion and increase bundle/maintenance cost.',\n suggestion: 'Remove the file if it is no longer needed.',\n metadata: { type: 'file', source: 'knip' },\n }));\n}\n\nfunction exportToFinding(file: string, exp: KnipIssue): Finding {\n return {\n file,\n line: exp.line ?? 0,\n severity: 'info',\n metric: 'unused_export',\n message: `Unused export: ${exp.name}`,\n why: 'Unused exports indicate dead code that may confuse consumers.',\n suggestion: `Remove the export or make '${exp.name}' internal.`,\n metadata: { type: 'export', exportName: exp.name, source: 'knip' },\n };\n}\n\nfunction typeToFinding(file: string, typ: KnipIssue): Finding {\n return {\n file,\n line: typ.line ?? 0,\n severity: 'info',\n metric: 'unused_export',\n message: `Unused exported type: ${typ.name}`,\n why: 'Unused type exports indicate dead code.',\n suggestion: `Remove the type export '${typ.name}' if no longer needed.`,\n metadata: { type: 'type', exportName: typ.name, source: 'knip' },\n };\n}\n\nfunction collectUnusedExports(report: KnipReport, fileSet: Set<string>): Finding[] {\n if (!report.issues || !Array.isArray(report.issues)) return [];\n\n const findings: Finding[] = [];\n\n for (const issue of report.issues) {\n if (!fileSet.has(issue.file)) continue;\n if (issue.exports) findings.push(...issue.exports.map((e) => exportToFinding(issue.file, e)));\n if (issue.types) findings.push(...issue.types.map((t) => typeToFinding(issue.file, t)));\n }\n\n return findings;\n}\n\nexport class KnipAdapter implements ToolAdapter {\n name = 'knip';\n supportedLanguages: Language[] = ['typescript'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('knip');\n }\n\n async run(files: string[], config: AdapterConfig): Promise<AdapterResult> {\n if (files.length === 0) return { findings: [] };\n\n const result = await execa('knip', ['--reporter', 'json'], {\n cwd: config.workdir,\n reject: false,\n });\n\n const stdout = result.stdout || '';\n if (!stdout.trim()) return { findings: [] };\n\n let report: KnipReport;\n try {\n report = JSON.parse(stdout) as KnipReport;\n } catch {\n return { findings: [] };\n }\n\n const fileSet = new Set(files);\n\n return {\n findings: [\n ...collectUnusedFiles(report, fileSet),\n ...collectUnusedExports(report, fileSet),\n ],\n };\n }\n}\n","import type { Gate, GateContext, GateResult, Finding, ArchitectureConfig } from '../types/index.js';\nimport { MadgeAdapter } from '../adapters/madge.js';\nimport { JscpdAdapter, type JscpdAdapterConfig } from '../adapters/jscpd.js';\nimport { KnipAdapter } from '../adapters/knip.js';\nimport { calculateArchitectureScore, deriveStatus } from '../scorer.js';\nimport { DEFAULT_ARCHITECTURE, DEFAULT_JSCPD_EXCLUDE } from '../config/defaults.js';\nimport type { ToolAdapter, AdapterConfig } from '../adapters/base.js';\nimport { toolMissingResult } from './shared.js';\n\ninterface ToolAvailability {\n madge: boolean;\n jscpd: boolean;\n knip: boolean;\n}\n\nexport class ArchitectureGate implements Gate {\n name = 'architecture';\n private madge = new MadgeAdapter();\n private jscpd = new JscpdAdapter();\n private knip = new KnipAdapter();\n\n async run(ctx: GateContext): Promise<GateResult> {\n const start = Date.now();\n const config: ArchitectureConfig = ctx.config.architecture ?? DEFAULT_ARCHITECTURE;\n const available = await this.checkAvailability(config, ctx);\n\n if (!available.madge && !available.jscpd && !available.knip) {\n return toolMissingResult(this.name, start, 'No architecture tools available', 'Install with: npm install -g madge jscpd knip');\n }\n\n const allFindings = await this.collectFindings(available, config, ctx);\n const score = calculateArchitectureScore({ findings: allFindings });\n const status = deriveStatus(score, allFindings);\n\n return { gate: this.name, score, status, duration_ms: Date.now() - start, findings: allFindings };\n }\n\n private async checkAvailability(config: ArchitectureConfig, ctx: GateContext): Promise<ToolAvailability> {\n const madgeApplicable = config.madgeEnabled && this.madge.supportedLanguages.includes(ctx.language);\n const jscpdApplicable = config.jscpdEnabled;\n const knipApplicable = config.knipEnabled && this.knip.supportedLanguages.includes(ctx.language);\n\n return {\n madge: madgeApplicable ? await this.madge.isAvailable() : false,\n jscpd: jscpdApplicable ? await this.jscpd.isAvailable() : false,\n knip: knipApplicable ? await this.knip.isAvailable() : false,\n };\n }\n\n private async collectFindings(available: ToolAvailability, config: ArchitectureConfig, ctx: GateContext): Promise<Finding[]> {\n const allFindings: Finding[] = [];\n\n if (available.madge) {\n const findings = await this.runAdapter(this.madge, ctx, { workdir: ctx.workdir, thresholds: {} });\n allFindings.push(...findings);\n }\n\n if (available.jscpd) {\n const jscpdConfig: JscpdAdapterConfig = {\n workdir: ctx.workdir,\n thresholds: {},\n minLines: config.jscpdMinLines,\n minTokens: config.jscpdMinTokens,\n exclude: config.jscpdExclude ?? DEFAULT_JSCPD_EXCLUDE,\n };\n const findings = await this.runAdapter(this.jscpd, ctx, jscpdConfig);\n allFindings.push(...findings);\n }\n\n if (available.knip) {\n const findings = await this.runAdapter(this.knip, ctx, { workdir: ctx.workdir, thresholds: {} });\n allFindings.push(...findings);\n }\n\n return allFindings;\n }\n\n private async runAdapter(adapter: ToolAdapter, ctx: GateContext, config: AdapterConfig): Promise<Finding[]> {\n const files = ctx.files\n .filter((f) => adapter.supportedLanguages.includes(f.language))\n .map((f) => f.relativePath);\n\n if (files.length === 0) return [];\n const result = await adapter.run(files, config);\n return result.findings;\n }\n\n}\n","import { execa } from 'execa';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { timeoutResult } from './mutation-shared.js';\n\nexport interface StrykerAdapterConfig extends AdapterConfig {\n timeout?: number;\n mutationScoreThreshold?: number;\n maxSurvivorFindings?: number;\n}\n\ninterface StrykerMutant {\n id: string;\n mutatorName: string;\n replacement?: string;\n status: string;\n location: { start: { line: number; column: number }; end: { line: number; column: number } };\n}\n\ninterface StrykerFileResult {\n language?: string;\n source?: string;\n mutants: StrykerMutant[];\n}\n\ninterface StrykerReport {\n schemaVersion?: string;\n files: Record<string, StrykerFileResult>;\n}\n\ninterface FileMutationScore {\n file: string;\n killed: number;\n survived: number;\n noCoverage: number;\n timeout: number;\n total: number;\n score: number;\n}\n\nfunction calculateFileScore(mutants: StrykerMutant[]): { killed: number; survived: number; noCoverage: number; timeout: number; total: number; score: number } {\n let killed = 0;\n let survived = 0;\n let noCoverage = 0;\n let timeout = 0;\n let invalid = 0;\n\n for (const m of mutants) {\n switch (m.status) {\n case 'Killed': killed++; break;\n case 'Survived': survived++; break;\n case 'NoCoverage': noCoverage++; break;\n case 'Timeout': timeout++; break;\n case 'CompileError':\n case 'RuntimeError': invalid++; break;\n }\n }\n\n const total = mutants.length - invalid;\n const score = total > 0 ? ((killed + timeout) / total) * 100 : 100;\n\n return { killed, survived, noCoverage, timeout, total, score };\n}\n\nfunction scoreSeverity(score: number): 'blocker' | 'warning' | 'info' {\n if (score < 40) return 'blocker';\n if (score < 70) return 'warning';\n return 'info';\n}\n\nfunction buildScoreMessage(score: number, threshold: number, survived: number, noCoverage: number): string {\n return 'Mutation score ' + Math.round(score) + '% is below threshold ' + threshold + '% (' + survived + ' survived, ' + noCoverage + ' no coverage)';\n}\n\nfunction fileScoreToFinding(fileScore: FileMutationScore, threshold: number): Finding {\n const severity = scoreSeverity(fileScore.score);\n return {\n file: fileScore.file,\n line: 0,\n severity,\n metric: 'mutation_score',\n value: Math.round(fileScore.score),\n threshold,\n message: buildScoreMessage(fileScore.score, threshold, fileScore.survived, fileScore.noCoverage),\n why: 'A low mutation score means tests do not detect code changes, indicating weak or missing test coverage.',\n suggestion: 'Add or improve tests for this file to kill surviving mutants.',\n metadata: { killed: fileScore.killed, survived: fileScore.survived, noCoverage: fileScore.noCoverage, source: 'stryker' },\n };\n}\n\nfunction formatMutantMessage(mutant: StrykerMutant): string {\n const base = 'Surviving mutant: ' + mutant.mutatorName;\n return mutant.replacement ? base + ' → ' + mutant.replacement : base;\n}\n\nfunction survivorToFinding(file: string, mutant: StrykerMutant): Finding {\n return {\n file,\n line: mutant.location.start.line,\n end_line: mutant.location.end.line,\n severity: 'info',\n metric: 'surviving_mutant',\n message: formatMutantMessage(mutant),\n why: 'No test detects this code change, meaning this logic path is not properly verified.',\n suggestion: 'Add a test that would fail if this mutation were applied.',\n metadata: { mutatorName: mutant.mutatorName, status: mutant.status, source: 'stryker' },\n };\n}\n\nfunction findReportPath(workdir: string): string | undefined {\n const candidates = [\n path.join(workdir, 'reports', 'mutation', 'mutation.json'),\n path.join(workdir, 'reports', 'mutation.json'),\n ];\n return candidates.find((p) => fs.existsSync(p));\n}\n\nfunction readReport(workdir: string): StrykerReport | null {\n const reportPath = findReportPath(workdir);\n if (!reportPath) return null;\n\n try {\n const raw = fs.readFileSync(reportPath, 'utf-8');\n return JSON.parse(raw) as StrykerReport;\n } catch {\n return null;\n }\n}\n\nfunction processReport(report: StrykerReport, files: string[], threshold: number, maxSurvivorFindings: number): AdapterResult & { mutationScore: number } {\n const fileSet = new Set(files);\n const findings: Finding[] = [];\n let totalKilled = 0;\n let totalValid = 0;\n\n for (const [filePath, fileResult] of Object.entries(report.files)) {\n if (!fileSet.has(filePath)) continue;\n\n const stats = calculateFileScore(fileResult.mutants);\n totalKilled += stats.killed + stats.timeout;\n totalValid += stats.total;\n\n if (stats.score < threshold) {\n const fileScore: FileMutationScore = { file: filePath, ...stats };\n findings.push(fileScoreToFinding(fileScore, threshold));\n\n const survivors = fileResult.mutants\n .filter((m) => m.status === 'Survived' || m.status === 'NoCoverage')\n .slice(0, maxSurvivorFindings);\n findings.push(...survivors.map((m) => survivorToFinding(filePath, m)));\n }\n }\n\n const mutationScore = totalValid > 0 ? (totalKilled / totalValid) * 100 : 100;\n return { findings, mutationScore };\n}\n\nexport class StrykerAdapter implements ToolAdapter {\n name = 'stryker';\n supportedLanguages: Language[] = ['typescript', 'javascript'];\n\n async isAvailable(workdir?: string): Promise<boolean> {\n if (workdir) {\n const localBin = path.join(workdir, 'node_modules', '.bin', 'stryker');\n if (fs.existsSync(localBin)) return true;\n }\n return await isBinaryAvailable('stryker');\n }\n\n async run(files: string[], config: StrykerAdapterConfig): Promise<AdapterResult & { mutationScore: number }> {\n if (files.length === 0) return { findings: [], mutationScore: 100 };\n\n const timeout = config.timeout ?? 300000;\n const timedOut = await this.executeStryker(files, config, timeout);\n if (timedOut) return timeoutResult('Stryker', timeout);\n\n const report = readReport(config.workdir);\n if (!report) return { findings: [], mutationScore: 100 };\n\n return processReport(report, files, config.mutationScoreThreshold ?? 80, config.maxSurvivorFindings ?? 5);\n }\n\n private async executeStryker(files: string[], config: StrykerAdapterConfig, timeout: number): Promise<boolean> {\n const mutatePattern = files.join(',');\n const args = ['run', '--reporters', 'json', '--mutate', mutatePattern];\n\n const useNpx = fs.existsSync(path.join(config.workdir, 'node_modules', '.bin', 'stryker'));\n const command = useNpx ? 'npx' : 'stryker';\n const execArgs = useNpx ? ['stryker', ...args] : args;\n\n const result = await execa(command, execArgs, {\n cwd: config.workdir,\n reject: false,\n timeout,\n });\n\n return !!result.timedOut;\n }\n}\n","import type { Finding } from '../types/index.js';\nimport type { AdapterResult } from './base.js';\n\nfunction scoreSeverity(score: number): 'blocker' | 'warning' | 'info' {\n if (score < 40) return 'blocker';\n if (score < 70) return 'warning';\n return 'info';\n}\n\nfunction buildScoreMessage(score: number, threshold: number, survived: number, total: number): string {\n return 'Mutation score ' + Math.round(score) + '% is below threshold ' + threshold + '% (' + survived + ' survived of ' + total + ')';\n}\n\nexport function timeoutResult(tool: string, timeout: number): AdapterResult & { mutationScore: number; timedOut: boolean } {\n return {\n findings: [{\n file: '', line: 0, severity: 'blocker', metric: 'mutation_timeout',\n message: tool + ' timed out after ' + timeout + 'ms',\n why: 'Mutation testing exceeded the configured timeout.',\n suggestion: 'Increase the timeout or reduce the number of files to mutate.',\n }],\n mutationScore: 0,\n timedOut: true,\n };\n}\n\nexport interface FileScoreInput {\n file: string;\n score: number;\n threshold: number;\n survived: number;\n total: number;\n killed: number;\n source: string;\n}\n\nexport function fileScoreFinding(input: FileScoreInput): Finding {\n return {\n file: input.file,\n line: 0,\n severity: scoreSeverity(input.score),\n metric: 'mutation_score',\n value: Math.round(input.score),\n threshold: input.threshold,\n message: buildScoreMessage(input.score, input.threshold, input.survived, input.total),\n why: 'A low mutation score means tests do not detect code changes, indicating weak or missing test coverage.',\n suggestion: 'Add or improve tests for this file to kill surviving mutants.',\n metadata: { killed: input.killed, survived: input.survived, source: input.source },\n };\n}\n","import { execa } from 'execa';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { timeoutResult, fileScoreFinding } from './mutation-shared.js';\n\nexport interface MutmutAdapterConfig extends AdapterConfig {\n timeout?: number;\n mutationScoreThreshold?: number;\n maxSurvivorFindings?: number;\n}\n\ninterface MutantResult {\n file: string;\n name: string;\n status: 'killed' | 'survived';\n line?: number;\n}\n\nfunction matchToResult(match: RegExpExecArray): MutantResult {\n const classname = match[1];\n const name = match[2];\n const closingType = match[3];\n const body = match[4] ?? '';\n\n const isSelfClosing = closingType.trim().startsWith('/');\n const survived = !isSelfClosing && body.includes('<failure');\n const file = classname.replace(/\\./g, '/') + '.py';\n const lineMatch = name.match(/line\\s+(\\d+)/i) ?? name.match(/mutant\\s+(\\d+)/i);\n const line = lineMatch ? parseInt(lineMatch[1], 10) : undefined;\n\n return { file, name, status: survived ? 'survived' : 'killed', line };\n}\n\nfunction parseJunitXml(xml: string): MutantResult[] {\n const results: MutantResult[] = [];\n const testcaseRe = /<testcase\\s+classname=\"([^\"]*)\"[^>]*?name=\"([^\"]*)\"[^>]*?(\\/\\s*>|>([\\s\\S]*?)<\\/testcase>)/g;\n let match: RegExpExecArray | null;\n\n while ((match = testcaseRe.exec(xml)) !== null) {\n results.push(matchToResult(match));\n }\n\n return results;\n}\n\ninterface FileStats {\n killed: number;\n survived: number;\n total: number;\n score: number;\n survivors: MutantResult[];\n}\n\nfunction groupByFile(results: MutantResult[]): Map<string, FileStats> {\n const groups = new Map<string, { killed: number; survived: number; survivors: MutantResult[] }>();\n\n for (const r of results) {\n const group = groups.get(r.file) ?? { killed: 0, survived: 0, survivors: [] };\n if (r.status === 'killed') {\n group.killed++;\n } else {\n group.survived++;\n group.survivors.push(r);\n }\n groups.set(r.file, group);\n }\n\n const fileStats = new Map<string, FileStats>();\n for (const [file, g] of groups) {\n const total = g.killed + g.survived;\n const score = total > 0 ? (g.killed / total) * 100 : 100;\n fileStats.set(file, { killed: g.killed, survived: g.survived, total, score, survivors: g.survivors });\n }\n\n return fileStats;\n}\n\nfunction fileStatsToFindings(file: string, stats: FileStats, threshold: number, maxSurvivorFindings: number): Finding[] {\n const findings: Finding[] = [fileScoreFinding({ file, score: stats.score, threshold, survived: stats.survived, total: stats.total, killed: stats.killed, source: 'mutmut' })];\n\n for (const survivor of stats.survivors.slice(0, maxSurvivorFindings)) {\n findings.push({\n file,\n line: survivor.line ?? 0,\n severity: 'info',\n metric: 'surviving_mutant',\n message: 'Surviving mutant: ' + survivor.name,\n why: 'No test detects this code change, meaning this logic path is not properly verified.',\n suggestion: 'Add a test that would fail if this mutation were applied.',\n metadata: { mutantName: survivor.name, source: 'mutmut' },\n });\n }\n\n return findings;\n}\n\nexport class MutmutAdapter implements ToolAdapter {\n name = 'mutmut';\n supportedLanguages: Language[] = ['python'];\n\n async isAvailable(): Promise<boolean> {\n return isBinaryAvailable('mutmut');\n }\n\n async run(files: string[], config: MutmutAdapterConfig): Promise<AdapterResult & { mutationScore: number }> {\n if (files.length === 0) return { findings: [], mutationScore: 100 };\n\n const timeout = config.timeout ?? 300000;\n const xml = await this.executeMutmut(files, config, timeout);\n if (xml === null) return timeoutResult('mutmut', timeout);\n if (!xml.trim()) return { findings: [], mutationScore: 100 };\n\n return this.processXml(xml, files, config.mutationScoreThreshold ?? 80, config.maxSurvivorFindings ?? 5);\n }\n\n private async executeMutmut(files: string[], config: MutmutAdapterConfig, timeout: number): Promise<string | null> {\n const pathsToMutate = files.join(',');\n\n const runResult = await execa('mutmut', ['run', `--paths-to-mutate=${pathsToMutate}`, '--CI', '--no-progress'], {\n cwd: config.workdir,\n reject: false,\n timeout,\n });\n\n if (runResult.timedOut) return null;\n\n const xmlResult = await execa('mutmut', ['junitxml'], {\n cwd: config.workdir,\n reject: false,\n });\n\n return xmlResult.stdout || '';\n }\n\n private processXml(xml: string, files: string[], threshold: number, maxSurvivorFindings: number): AdapterResult & { mutationScore: number } {\n const mutantResults = parseJunitXml(xml);\n if (mutantResults.length === 0) return { findings: [], mutationScore: 100 };\n\n const fileStatsMap = groupByFile(mutantResults);\n const fileSet = new Set(files);\n const findings: Finding[] = [];\n let totalKilled = 0;\n let totalMutants = 0;\n\n for (const [file, stats] of fileStatsMap) {\n if (!fileSet.has(file)) continue;\n\n totalKilled += stats.killed;\n totalMutants += stats.total;\n\n if (stats.score < threshold) {\n findings.push(...fileStatsToFindings(file, stats, threshold, maxSurvivorFindings));\n }\n }\n\n const mutationScore = totalMutants > 0 ? (totalKilled / totalMutants) * 100 : 100;\n return { findings, mutationScore };\n }\n}\n","import { execa } from 'execa';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { Language, Finding } from '../types/index.js';\nimport type { ToolAdapter, AdapterConfig, AdapterResult } from './base.js';\nimport { isBinaryAvailable } from './base.js';\nimport { timeoutResult, fileScoreFinding } from './mutation-shared.js';\n\nexport interface MutantAdapterConfig extends AdapterConfig {\n timeout?: number;\n mutationScoreThreshold?: number;\n maxSurvivorFindings?: number;\n usage?: 'opensource' | 'commercial';\n}\n\ninterface MutantResultEntry {\n status: 'alive' | 'killed' | 'timeout';\n subject: string;\n file: string;\n line: number;\n}\n\ninterface FileStats {\n killed: number;\n survived: number;\n timeout: number;\n total: number;\n score: number;\n survivors: MutantResultEntry[];\n}\n\nconst RESULT_LINE_RE = /^(alive|evil|killed|timeout):(.+):([^:]+\\.rb):(\\d+)(?::.*)?$/;\nconst COVERAGE_RE = /Coverage:\\s+([\\d.]+)%/;\n\nfunction parseOutput(stdout: string): { entries: MutantResultEntry[]; overallScore: number | null } {\n const entries: MutantResultEntry[] = [];\n let overallScore: number | null = null;\n\n for (const line of stdout.split('\\n')) {\n const resultMatch = RESULT_LINE_RE.exec(line);\n if (resultMatch) {\n entries.push({\n status: resultMatch[1] === 'evil' ? 'alive' : resultMatch[1] as 'alive' | 'killed' | 'timeout',\n subject: resultMatch[2],\n file: resultMatch[3],\n line: parseInt(resultMatch[4], 10),\n });\n continue;\n }\n\n const coverageMatch = COVERAGE_RE.exec(line);\n if (coverageMatch) {\n overallScore = parseFloat(coverageMatch[1]);\n }\n }\n\n return { entries, overallScore };\n}\n\nfunction groupByFile(entries: MutantResultEntry[]): Map<string, FileStats> {\n const groups = new Map<string, { killed: number; survived: number; timeout: number; survivors: MutantResultEntry[] }>();\n\n for (const entry of entries) {\n const group = groups.get(entry.file) ?? { killed: 0, survived: 0, timeout: 0, survivors: [] };\n switch (entry.status) {\n case 'killed': group.killed++; break;\n case 'alive': group.survived++; group.survivors.push(entry); break;\n case 'timeout': group.timeout++; break;\n }\n groups.set(entry.file, group);\n }\n\n const fileStats = new Map<string, FileStats>();\n for (const [file, g] of groups) {\n const total = g.killed + g.survived + g.timeout;\n const score = total > 0 ? (g.killed / total) * 100 : 100;\n fileStats.set(file, { killed: g.killed, survived: g.survived, timeout: g.timeout, total, score, survivors: g.survivors });\n }\n\n return fileStats;\n}\n\nfunction fileStatsToFinding(file: string, stats: FileStats, threshold: number): Finding {\n return fileScoreFinding({ file, score: stats.score, threshold, survived: stats.survived, total: stats.total, killed: stats.killed, source: 'mutant' });\n}\n\nfunction survivorToFinding(entry: MutantResultEntry): Finding {\n return {\n file: entry.file,\n line: entry.line,\n severity: 'info',\n metric: 'surviving_mutant',\n message: 'Surviving mutant in ' + entry.subject,\n why: 'No test detects this code change, meaning this logic path is not properly verified.',\n suggestion: 'Add a test that would fail if this mutation were applied.',\n metadata: { subject: entry.subject, source: 'mutant' },\n };\n}\n\ninterface ProcessOptions {\n entries: MutantResultEntry[];\n overallScore: number | null;\n files: string[];\n threshold: number;\n maxSurvivorFindings: number;\n}\n\nfunction processEntries(opts: ProcessOptions): AdapterResult & { mutationScore: number } {\n const fileStatsMap = groupByFile(opts.entries);\n const fileSet = new Set(opts.files);\n const findings: Finding[] = [];\n let totalKilled = 0;\n let totalMutants = 0;\n\n for (const [file, stats] of fileStatsMap) {\n if (!fileSet.has(file)) continue;\n\n totalKilled += stats.killed;\n totalMutants += stats.total;\n\n if (stats.score < opts.threshold) {\n findings.push(fileStatsToFinding(file, stats, opts.threshold));\n findings.push(...stats.survivors.slice(0, opts.maxSurvivorFindings).map(survivorToFinding));\n }\n }\n\n const mutationScore = opts.overallScore ?? (totalMutants > 0 ? (totalKilled / totalMutants) * 100 : 100);\n return { findings, mutationScore };\n}\n\nexport class MutantAdapter implements ToolAdapter {\n name = 'mutant';\n supportedLanguages: Language[] = ['ruby'];\n\n async isAvailable(workdir = process.cwd()): Promise<boolean> {\n if (!fs.existsSync(path.join(workdir, 'Gemfile'))) {\n return isBinaryAvailable('mutant');\n }\n\n try {\n const result = await execa('bundle', ['exec', 'mutant', '--version'], {\n cwd: workdir,\n reject: false,\n });\n return result.exitCode === 0;\n } catch {\n return false;\n }\n }\n\n async run(files: string[], config: MutantAdapterConfig): Promise<AdapterResult & { mutationScore: number }> {\n if (files.length === 0) return { findings: [], mutationScore: 100 };\n\n const timeout = config.timeout ?? 300000;\n const threshold = config.mutationScoreThreshold ?? 80;\n const maxSurvivorFindings = config.maxSurvivorFindings ?? 5;\n\n if (!config.usage) {\n return toolError(\n 'Mutant requires an explicit usage policy',\n 'Set --mutant-usage opensource or --mutant-usage commercial according to the project license.',\n );\n }\n\n let execution;\n try {\n execution = await this.executeMutant(files, config.workdir, timeout, config.usage);\n } catch (error) {\n const detail = error instanceof Error ? error.message : 'unknown execution error';\n return toolError(`Mutant could not start: ${detail}`, 'Verify Bundler, Mutant, and the project test environment.');\n }\n if (execution.timedOut) return timeoutResult('mutant', timeout);\n const stdout = execution.stdout;\n if (!stdout.trim()) {\n return toolError('Mutant produced no report', 'Run Mutant through the project bundle and verify its RSpec integration.');\n }\n\n if (![0, 1].includes(execution.exitCode ?? -1)) {\n return toolError(\n `Mutant failed with exit code ${execution.exitCode ?? 'unknown'}`,\n 'Run Mutant directly and fix its bundle, licence, Rails, or RSpec configuration.',\n );\n }\n\n const parsed = parseOutput(stdout);\n const entries = parsed.entries.map((entry) => ({\n ...entry,\n file: path.isAbsolute(entry.file) ? path.relative(config.workdir, entry.file) : entry.file,\n }));\n const { overallScore } = parsed;\n if (entries.length === 0 && overallScore === null) {\n return toolError('Mutant output could not be parsed', 'Check the installed Mutant version and its command output.');\n }\n\n return processEntries({ entries, overallScore, files, threshold, maxSurvivorFindings });\n }\n\n private async executeMutant(\n files: string[],\n workdir: string,\n timeout: number,\n usage: 'opensource' | 'commercial',\n ): Promise<{ stdout: string; timedOut: boolean; exitCode?: number }> {\n const bundled = fs.existsSync(path.join(workdir, 'Gemfile'));\n const command = bundled ? 'bundle' : 'mutant';\n const roots = [...new Set(files.map((file) => file.split('/')[0]).filter((root) => root === 'app' || root === 'lib'))];\n const railsArgs = fs.existsSync(path.join(workdir, 'config', 'environment.rb'))\n ? ['--require', './config/environment']\n : [];\n const mutantArgs = [\n 'run',\n '--usage', usage,\n ...roots.flatMap((root) => ['--include', root]),\n ...railsArgs,\n '--integration', 'rspec',\n '--jobs', '1',\n '--',\n ...files.map((file) => `source:${file}`),\n ];\n const args = bundled ? ['exec', 'mutant', ...mutantArgs] : mutantArgs;\n const result = await execa(command, args, {\n cwd: workdir,\n env: { RAILS_ENV: 'test', CI: 'true' },\n reject: false,\n timeout,\n });\n\n return { stdout: result.stdout || '', timedOut: result.timedOut, exitCode: result.exitCode };\n }\n}\n\nfunction toolError(message: string, suggestion: string): AdapterResult & { mutationScore: number } {\n return {\n findings: [{\n file: '',\n line: 0,\n severity: 'blocker',\n metric: 'mutation_tool_error',\n message,\n why: 'A failed mutation test cannot be treated as a perfect mutation score.',\n suggestion,\n metadata: { source: 'mutant' },\n }],\n mutationScore: 0,\n };\n}\n","import { execaCommand } from 'execa';\nimport type { Finding, Language } from '../types/index.js';\nimport type { AdapterConfig, AdapterResult, ToolAdapter } from './base.js';\n\nexport interface TestCommandAdapterConfig extends AdapterConfig {\n command: string;\n timeout: number;\n}\n\nexport class TestCommandAdapter implements ToolAdapter {\n name = 'test-command';\n supportedLanguages: Language[] = ['typescript', 'javascript', 'python', 'ruby', 'go', 'rust'];\n\n async isAvailable(): Promise<boolean> {\n return true;\n }\n\n async run(_files: string[], config: TestCommandAdapterConfig): Promise<AdapterResult & { mutationScore: number }> {\n let result;\n try {\n result = await execaCommand(config.command, {\n cwd: config.workdir,\n env: { CI: 'true' },\n reject: false,\n timeout: config.timeout,\n });\n } catch (error) {\n const detail = error instanceof Error ? error.message : 'unknown execution error';\n return this.failure(`Test command could not start: ${detail}`, 'test_command_failed');\n }\n\n if (result.timedOut) {\n return this.failure(`Test command timed out after ${config.timeout}ms`, 'test_command_timeout');\n }\n\n if (result.exitCode !== 0) {\n const detail = diagnosticLine(result.stderr) ?? diagnosticLine(result.stdout);\n const message = detail\n ? `Test command failed with exit code ${result.exitCode}: ${detail}`\n : `Test command failed with exit code ${result.exitCode}`;\n return this.failure(message, 'test_command_failed');\n }\n\n return { findings: [], mutationScore: 100 };\n }\n\n private failure(message: string, metric: string): AdapterResult & { mutationScore: number } {\n const finding: Finding = {\n file: '',\n line: 0,\n severity: 'blocker',\n metric,\n message,\n why: 'The project-defined test suite must complete successfully.',\n suggestion: 'Run the configured test command directly and inspect its full logs.',\n metadata: { source: 'test-command' },\n };\n return { findings: [finding], mutationScore: 0 };\n }\n}\n\nfunction diagnosticLine(output: string): string | undefined {\n const lines = output\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line && !/^=+$/.test(line));\n const errorLine = lines.find((line) => /error|failed|cannot|denied|no such file|docker:/i.test(line));\n return (errorLine ?? lines.at(-1))?.slice(0, 500);\n}\n","import type { Gate, GateContext, GateResult, Finding, TestQualityConfig } from '../types/index.js';\nimport { StrykerAdapter, type StrykerAdapterConfig } from '../adapters/stryker.js';\nimport { MutmutAdapter, type MutmutAdapterConfig } from '../adapters/mutmut.js';\nimport { MutantAdapter, type MutantAdapterConfig } from '../adapters/mutant.js';\nimport { TestCommandAdapter } from '../adapters/test-command.js';\nimport { calculateTestQualityScore, deriveStatus } from '../scorer.js';\nimport { DEFAULT_TEST_QUALITY } from '../config/defaults.js';\nimport { toolMissingResult } from './shared.js';\n\ninterface ToolAvailability {\n stryker: boolean;\n mutmut: boolean;\n mutant: boolean;\n testCommand: boolean;\n}\n\nexport class TestQualityGate implements Gate {\n name = 'test_quality';\n private stryker = new StrykerAdapter();\n private mutmut = new MutmutAdapter();\n private mutant = new MutantAdapter();\n private testCommand = new TestCommandAdapter();\n\n async run(ctx: GateContext): Promise<GateResult> {\n const start = Date.now();\n const config: TestQualityConfig = ctx.config.testQuality ?? DEFAULT_TEST_QUALITY;\n const available = await this.checkAvailability(config, ctx);\n\n if (!available.stryker && !available.mutmut && !available.mutant && !available.testCommand) {\n return toolMissingResult(this.name, start, 'No mutation testing tools available', 'Install: npm i -D @stryker-mutator/core | pip install mutmut | gem install mutant');\n }\n\n const { findings, mutationScore, mutationRan } = await this.collectFindings(available, config, ctx);\n const score = calculateTestQualityScore({ mutationScore });\n const hasBlocker = findings.some((finding) => finding.severity === 'blocker');\n const status = !mutationRan && available.testCommand && !hasBlocker\n ? 'warn'\n : score < config.mutationScoreThreshold ? 'fail' : deriveStatus(score, findings);\n\n return { gate: this.name, score, status, duration_ms: Date.now() - start, findings };\n }\n\n private async checkAvailability(config: TestQualityConfig, ctx: GateContext): Promise<ToolAvailability> {\n const tsOrJs = ctx.language === 'typescript' || ctx.language === 'javascript';\n const isPython = ctx.language === 'python';\n const isRuby = ctx.language === 'ruby';\n\n return {\n stryker: config.strykerEnabled && tsOrJs ? await this.stryker.isAvailable(ctx.workdir) : false,\n mutmut: config.mutmutEnabled && isPython ? await this.mutmut.isAvailable() : false,\n mutant: config.mutantEnabled && isRuby && (!config.testCommand || Boolean(config.mutantUsage))\n ? await this.mutant.isAvailable(ctx.workdir)\n : false,\n testCommand: Boolean(config.testCommand),\n };\n }\n\n private async collectFindings(available: ToolAvailability, config: TestQualityConfig, ctx: GateContext): Promise<{ findings: Finding[]; mutationScore: number; mutationRan: boolean }> {\n const allFindings: Finding[] = [];\n const scores: number[] = [];\n\n const adapters: { available: boolean; adapter: { supportedLanguages: readonly string[]; run: (files: string[], config: any) => Promise<{ findings: Finding[]; mutationScore: number; timedOut?: boolean }> } }[] = [\n { available: available.stryker, adapter: this.stryker },\n { available: available.mutmut, adapter: this.mutmut },\n { available: available.mutant, adapter: this.mutant },\n ];\n\n for (const { available: isAvail, adapter } of adapters) {\n if (!isAvail) continue;\n const result = await this.runAdapter(adapter, ctx, config);\n if (result) {\n allFindings.push(...result.findings);\n if (!result.timedOut) {\n scores.push(result.mutationScore);\n }\n }\n }\n\n if (available.testCommand && config.testCommand) {\n const result = await this.testCommand.run(ctx.files.map((file) => file.relativePath), {\n workdir: ctx.workdir,\n thresholds: {},\n command: config.testCommand,\n timeout: config.timeout,\n });\n allFindings.push(...result.findings);\n if (result.findings.length === 0 && scores.length === 0) {\n allFindings.push({\n file: '',\n line: 0,\n severity: 'info',\n metric: 'mutation_not_run',\n message: 'Project tests passed, but mutation testing was not run',\n why: 'A passing test suite does not measure whether tests detect behavioral changes.',\n suggestion: 'Configure Mutant in the project bundle to obtain a mutation score.',\n metadata: { source: 'test-command' },\n });\n }\n }\n\n const mutationScore = scores.length > 0 ? Math.min(...scores) : 0;\n return { findings: allFindings, mutationScore, mutationRan: scores.length > 0 };\n }\n\n private async runAdapter(adapter: { supportedLanguages: readonly string[]; run: (files: string[], config: any) => Promise<{ findings: Finding[]; mutationScore: number; timedOut?: boolean }> }, ctx: GateContext, config: TestQualityConfig): Promise<{ findings: Finding[]; mutationScore: number; timedOut?: boolean } | null> {\n const files = ctx.files\n .filter((f) => adapter.supportedLanguages.includes(f.language))\n .map((f) => f.relativePath);\n\n if (files.length === 0) return null;\n\n return adapter.run(files, {\n workdir: ctx.workdir,\n thresholds: {},\n timeout: config.timeout,\n mutationScoreThreshold: config.mutationScoreThreshold,\n maxSurvivorFindings: config.maxSurvivorFindings,\n usage: config.mutantUsage,\n });\n }\n}\n","import type { Gate } from '../types/index.js';\nimport { TypeSafetyGate } from './type-safety.js';\nimport { ComplexityGate } from './complexity.js';\nimport { SecurityGate } from './security.js';\nimport { ArchitectureGate } from './architecture.js';\nimport { TestQualityGate } from './test-quality.js';\n\nconst GATE_REGISTRY = new Map<string, Gate>();\n\nfunction registerGate(gate: Gate): void {\n GATE_REGISTRY.set(gate.name, gate);\n}\n\nexport function getGate(name: string): Gate | undefined {\n return GATE_REGISTRY.get(name);\n}\n\nexport function getAllGateNames(): string[] {\n return Array.from(GATE_REGISTRY.keys());\n}\n\nregisterGate(new TypeSafetyGate());\nregisterGate(new ComplexityGate());\nregisterGate(new SecurityGate());\nregisterGate(new ArchitectureGate());\nregisterGate(new TestQualityGate());\n","import type { GateContext, GateResult } from './types/index.js';\nimport { getGate } from './gates/index.js';\n\nexport async function runGates(ctx: GateContext, gateNames: string[]): Promise<GateResult[]> {\n const results: GateResult[] = [];\n\n for (const name of gateNames) {\n const gate = getGate(name);\n if (!gate) {\n results.push({\n gate: name,\n score: 0,\n status: 'skip',\n duration_ms: 0,\n findings: [\n {\n file: '',\n line: 0,\n severity: 'info',\n metric: 'gate_not_found',\n message: `Gate \"${name}\" is not implemented yet.`,\n why: 'This gate has not been registered.',\n },\n ],\n });\n continue;\n }\n\n const result = await gate.run(ctx);\n results.push(result);\n\n if (result.status === 'fail') break;\n }\n\n return results;\n}\n","import type { ProfileConfig } from '../types/index.js';\nimport { DEFAULT_COMPLEXITY, DEFAULT_SECURITY, DEFAULT_TYPE_SAFETY, DEFAULT_ARCHITECTURE, DEFAULT_TEST_QUALITY } from './defaults.js';\n\nconst PROFILES: Record<string, ProfileConfig> = {\n default: {\n name: 'default',\n complexity: DEFAULT_COMPLEXITY,\n security: DEFAULT_SECURITY,\n typeSafety: DEFAULT_TYPE_SAFETY,\n architecture: DEFAULT_ARCHITECTURE,\n testQuality: DEFAULT_TEST_QUALITY,\n },\n critical: {\n name: 'critical',\n complexity: {\n cyclomatic: 6,\n length: 30,\n arguments: 3,\n nesting: 2,\n },\n security: {\n semgrepRules: ['p/security-audit', 'p/secrets', 'p/owasp-top-ten'],\n gitleaksEnabled: true,\n },\n typeSafety: {\n strict: true,\n mypyEnabled: true,\n },\n architecture: {\n madgeEnabled: true,\n jscpdEnabled: true,\n knipEnabled: true,\n jscpdMinLines: 3,\n jscpdMinTokens: 30,\n },\n testQuality: {\n strykerEnabled: true,\n mutmutEnabled: true,\n mutantEnabled: true,\n mutationScoreThreshold: 90,\n timeout: 600000,\n maxSurvivorFindings: 10,\n },\n },\n prototype: {\n name: 'prototype',\n complexity: {\n cyclomatic: 15,\n length: 60,\n arguments: 6,\n nesting: 4,\n },\n security: {\n semgrepRules: ['p/security-audit'],\n gitleaksEnabled: false,\n },\n typeSafety: {\n strict: false,\n mypyEnabled: false,\n },\n architecture: {\n madgeEnabled: false,\n jscpdEnabled: false,\n knipEnabled: false,\n },\n testQuality: {\n strykerEnabled: false,\n mutmutEnabled: false,\n mutantEnabled: false,\n mutationScoreThreshold: 60,\n timeout: 120000,\n maxSurvivorFindings: 3,\n },\n },\n};\n\nexport function getProfile(name: string): ProfileConfig {\n const profile = PROFILES[name];\n if (!profile) {\n throw new Error(`Unknown profile: ${name}. Available: ${Object.keys(PROFILES).join(', ')}`);\n }\n return profile;\n}\n","import chalk from 'chalk';\nimport { stripVTControlCharacters } from 'node:util';\nimport type { GateResult } from './types/index.js';\nimport { overallStatus } from './scorer.js';\n\nexport interface ReportMeta {\n mode: string;\n filesAnalyzed: number;\n}\n\nexport interface TextReportOptions {\n ansi?: boolean;\n}\n\nexport function reportText(\n results: GateResult[],\n meta: ReportMeta,\n options: TextReportOptions = {},\n): string {\n const lines: string[] = [];\n\n lines.push(chalk.bold('=== VALIDATOR REPORT ==='));\n lines.push(`Files analyzed: ${meta.filesAnalyzed} (mode: ${meta.mode})`);\n lines.push('');\n\n for (const result of results) {\n const icon = statusIcon(result.status);\n const score = `${result.score}%`.padStart(4);\n const duration = `(${(result.duration_ms / 1000).toFixed(1)}s)`;\n lines.push(`${icon} ${result.gate.padEnd(20)} ${score} ${duration}`);\n }\n\n const allFindings = results.flatMap((r) => r.findings);\n if (allFindings.length > 0) {\n lines.push('');\n lines.push(chalk.bold('--- FINDINGS ---'));\n lines.push('');\n\n for (const f of allFindings) {\n const sev =\n f.severity === 'blocker'\n ? chalk.red('[BLOCKER]')\n : f.severity === 'warning'\n ? chalk.yellow('[WARNING]')\n : chalk.blue('[INFO]');\n const loc = f.function ? `${f.file}:${f.line} — ${f.function}` : `${f.file}:${f.line}`;\n lines.push(`${sev} ${loc}`);\n lines.push(` ${f.message}`);\n if (f.why) lines.push(` ${chalk.dim('Why:')} ${f.why}`);\n if (f.suggestion) lines.push(` ${chalk.dim('Fix:')} ${f.suggestion}`);\n lines.push('');\n }\n }\n\n const overall = overallStatus(results);\n const blockerCount = allFindings.filter((f) => f.severity === 'blocker').length;\n const warnCount = allFindings.filter((f) => f.severity === 'warning').length;\n lines.push(\n `RESULT: ${overall.toUpperCase()} (${blockerCount} blockers, ${warnCount} warnings)`,\n );\n\n const report = lines.join('\\n');\n return options.ansi === false ? stripVTControlCharacters(report) : report;\n}\n\nexport function reportJson(results: GateResult[], meta: ReportMeta): string {\n const allFindings = results.flatMap((r) => r.findings);\n const report = {\n version: '0.1.0',\n timestamp: new Date().toISOString(),\n mode: meta.mode,\n files_analyzed: meta.filesAnalyzed,\n overall: {\n status: overallStatus(results),\n blocked_by: results.filter((r) => r.status === 'fail').map((r) => r.gate),\n total_findings: allFindings.length,\n blockers: allFindings.filter((f) => f.severity === 'blocker').length,\n warnings: allFindings.filter((f) => f.severity === 'warning').length,\n },\n gates: Object.fromEntries(results.map((r) => [r.gate, r])),\n };\n return JSON.stringify(\n report,\n (_key, value) => typeof value === 'string' ? stripVTControlCharacters(value) : value,\n 2,\n );\n}\n\nfunction statusIcon(status: string): string {\n switch (status) {\n case 'pass':\n return chalk.green('[PASS]');\n case 'fail':\n return chalk.red('[FAIL]');\n case 'warn':\n return chalk.yellow('[WARN]');\n case 'skip':\n return chalk.gray('[SKIP]');\n default:\n return '[????]';\n }\n}\n","import { resolveFiles } from './resolver.js';\nimport { runGates } from './runner.js';\nimport { detectPrimaryLanguage } from './detector.js';\nimport { getProfile } from './config/profiles.js';\nimport { getAllGateNames } from './gates/index.js';\nimport type { GateResult, OutputFormat, ResolveMode } from './types/index.js';\nimport { reportJson, reportText } from './reporter.js';\nimport { overallStatus } from './scorer.js';\n\nexport type { Gate, GateContext, GateResult, Finding } from './types/index.js';\nexport type { ProfileConfig, ComplexityThresholds, SecurityConfig, TypeSafetyConfig, ArchitectureConfig, TestQualityConfig, ValidatorConfig } from './types/index.js';\nexport type { Language, FileEntry } from './types/index.js';\n\nexport interface ValidateOptions {\n mode: ResolveMode;\n targets?: string[];\n base?: string;\n head?: string;\n staged?: boolean;\n profile?: string;\n gates?: string[];\n workdir?: string;\n exclude?: string[];\n testCommand?: string;\n testTimeout?: number;\n mutantUsage?: 'opensource' | 'commercial';\n}\n\nexport interface ValidationReport {\n status: 'pass' | 'fail' | 'warn';\n gates: GateResult[];\n filesAnalyzed: number;\n blockers: number;\n warnings: number;\n}\n\nexport async function validate(options: ValidateOptions): Promise<ValidationReport> {\n if (options.testTimeout !== undefined\n && (!Number.isInteger(options.testTimeout) || options.testTimeout <= 0)) {\n throw new Error('testTimeout must be a positive integer');\n }\n const workdir = options.workdir ?? process.cwd();\n const selectedProfile = getProfile(options.profile ?? 'default');\n const profile = options.testCommand || options.testTimeout || options.mutantUsage\n ? {\n ...selectedProfile,\n testQuality: {\n ...selectedProfile.testQuality!,\n testCommand: options.testCommand,\n timeout: options.testTimeout ?? selectedProfile.testQuality!.timeout,\n mutantUsage: options.mutantUsage,\n },\n }\n : selectedProfile;\n const gateNames = options.gates ?? getAllGateNames();\n\n const files = await resolveFiles({\n mode: options.mode,\n targets: options.targets,\n base: options.base,\n head: options.head,\n staged: options.staged,\n exclude: options.exclude,\n workdir,\n });\n\n const language = detectPrimaryLanguage(files);\n const results = await runGates({ files, config: profile, workdir, language }, gateNames);\n\n const allFindings = results.flatMap((r) => r.findings);\n\n return {\n status: overallStatus(results),\n gates: results,\n filesAnalyzed: files.length,\n blockers: allFindings.filter((f) => f.severity === 'blocker').length,\n warnings: allFindings.filter((f) => f.severity === 'warning').length,\n };\n}\n\nexport function formatReport(\n report: ValidationReport,\n format: OutputFormat = 'text',\n mode = 'scan',\n): string {\n const meta = { mode, filesAnalyzed: report.filesAnalyzed };\n return format === 'json'\n ? reportJson(report.gates, meta)\n : reportText(report.gates, meta);\n}\n"],"mappings":"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","names":["path","path","execa","fs","path","execa","path","fs","execa","execa","execa","execa","execa","fs","path","execa","fs","path","execa","execa","execa","execa","execa","buildWhy","execa","fs","path","fs","path","execa","toolErrorFinding","fs","path","execa","fs","path","execa","toolErrorFinding","execa","execa","execa","fs","os","path","parseReport","fs","path","os","execa","execa","execa","execa","fs","path","scoreSeverity","buildScoreMessage","path","fs","execa","execa","execa","execa","fs","path","groupByFile","survivorToFinding","fs","path","execa"]}
|