@nolans01/agent-validator 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +299 -0
- package/dist/cli.js +1899 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.js +1804 -0
- package/dist/index.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nolans01/agent-validator",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Deterministic code quality validation orchestrator for TypeScript, Python, and Ruby projects",
|
|
5
|
+
"author": "Nolan S <nolan1scott3@gmail.com>",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20.0.0"
|
|
9
|
+
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/NolanS-OMG/agent-validator.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/NolanS-OMG/agent-validator/issues"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/NolanS-OMG/agent-validator#readme",
|
|
18
|
+
"bin": {
|
|
19
|
+
"validator": "dist/cli.js"
|
|
20
|
+
},
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"import": "./dist/index.js",
|
|
24
|
+
"types": "./dist/index.d.ts"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup",
|
|
38
|
+
"dev": "tsup --watch",
|
|
39
|
+
"test": "vitest",
|
|
40
|
+
"test:run": "vitest run",
|
|
41
|
+
"lint": "tsc --noEmit",
|
|
42
|
+
"prepublishOnly": "npm run build"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"chalk": "^5.4.1",
|
|
46
|
+
"commander": "^13.1.0",
|
|
47
|
+
"execa": "^9.5.3",
|
|
48
|
+
"glob": "^11.0.3"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@stryker-mutator/core": "^9.6.1",
|
|
52
|
+
"@types/node": "^22.15.0",
|
|
53
|
+
"tsup": "^8.5.0",
|
|
54
|
+
"typescript": "^5.8.0",
|
|
55
|
+
"vitest": "^3.1.0"
|
|
56
|
+
},
|
|
57
|
+
"keywords": [
|
|
58
|
+
"code-quality",
|
|
59
|
+
"complexity",
|
|
60
|
+
"static-analysis",
|
|
61
|
+
"validator",
|
|
62
|
+
"ai",
|
|
63
|
+
"agent",
|
|
64
|
+
"typescript",
|
|
65
|
+
"python",
|
|
66
|
+
"ruby",
|
|
67
|
+
"mutation-testing",
|
|
68
|
+
"security",
|
|
69
|
+
"linter"
|
|
70
|
+
],
|
|
71
|
+
"license": "MIT"
|
|
72
|
+
}
|