eslint-plugin-ai-guard 1.1.13 → 1.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 +337 -233
- package/dist/cli/index.js +1013 -104
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.mts +23 -4
- package/dist/index.d.ts +23 -4
- package/dist/index.js +385 -55
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +375 -55
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -3
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../cli/utils/config-manager.ts","../../cli/index.ts","../../cli/commands/run.ts","../../cli/utils/eslint-runner.ts","../../cli/utils/logger.ts","../../cli/commands/init.ts","../../cli/utils/detector.ts","../../cli/commands/doctor.ts","../../cli/commands/preset.ts","../../cli/commands/ignore.ts","../../cli/commands/baseline.ts","../../cli/commands/init-context.ts"],"sourcesContent":["import fs from 'fs';\r\nimport path from 'path';\r\nimport type { ConfigType } from './detector.js';\r\n\r\nexport type Preset = 'recommended' | 'strict' | 'security';\r\n\r\n// ─── File I/O primitives ──────────────────────────────────────────────────────\r\n\r\nexport function backupConfig(configPath: string): string {\r\n const backupPath = `${configPath}.bak`;\r\n fs.copyFileSync(configPath, backupPath);\r\n return backupPath;\r\n}\r\n\r\nexport function readConfig(configPath: string): string {\r\n return fs.readFileSync(configPath, 'utf-8');\r\n}\r\n\r\nexport function writeConfig(configPath: string, content: string): void {\r\n fs.writeFileSync(configPath, content, 'utf-8');\r\n}\r\n\r\n// ─── Flat Config Generator (ESLint v9) ────────────────────────────────────────\r\n//\r\n// Generates a clean eslint.config.mjs that:\r\n// 1. Uses direct spread of the preset config object (no object wrapping)\r\n// 2. Explicitly names plugin so IDEs resolve it\r\n// 3. Puts ignores first so they apply to all following configs\r\n\r\nexport function generateFlatConfig(preset: Preset): string {\r\n return `import aiGuard from 'eslint-plugin-ai-guard';\r\n\r\nexport default [\r\n // Ignore generated / dependency directories\r\n {\r\n ignores: [\r\n 'node_modules/**',\r\n '.next/**',\r\n 'dist/**',\r\n 'build/**',\r\n 'coverage/**',\r\n 'out/**',\r\n ],\r\n },\r\n\r\n // ai-guard: catch AI-generated code patterns\r\n {\r\n plugins: {\r\n 'ai-guard': aiGuard,\r\n },\r\n rules: {\r\n ...aiGuard.configs.${preset}.rules,\r\n },\r\n },\r\n];\r\n`;\r\n}\r\n\r\n// ─── Legacy Config Generator (ESLint v8) ──────────────────────────────────────\r\n\r\nexport function generateLegacyConfig(preset: Preset): string {\r\n return `module.exports = {\r\n plugins: ['ai-guard'],\r\n extends: ['plugin:ai-guard/${preset}'],\r\n ignorePatterns: [\r\n 'node_modules/',\r\n '.next/',\r\n 'dist/',\r\n 'build/',\r\n 'coverage/',\r\n 'out/',\r\n ],\r\n};\r\n`;\r\n}\r\n\r\n// ─── Flat Config Patching (ESLint v9) ─────────────────────────────────────────\r\n\r\nconst AI_GUARD_MARKER = 'eslint-plugin-ai-guard';\r\n\r\nexport function isInvalidAiGuardConfig(content: string): boolean {\r\n if (!content.includes('eslint-plugin-ai-guard') && !content.includes('ai-guard')) {\r\n return false;\r\n }\r\n\r\n // Old invalid shape: plugin assigned to aiGuard.default\r\n if (/['\"]ai-guard['\"]\\s*:\\s*aiGuard\\.default/.test(content)) return true;\r\n\r\n // Old invalid shape: rules sourced directly from aiGuard.recommended/strict/security\r\n if (/\\.\\.\\.aiGuard\\.(recommended|strict|security)\\.rules/.test(content)) return true;\r\n if (/rules\\s*:\\s*aiGuard\\.(recommended|strict|security)\\.rules/.test(content)) return true;\r\n\r\n return false;\r\n}\r\n\r\nexport function repairInvalidFlatConfig(content: string): string {\r\n let repaired = content;\r\n \r\n // 1. Fix plugin assignment: 'ai-guard': aiGuard.default -> 'ai-guard': aiGuard\r\n repaired = repaired.replace(/(['\"]ai-guard['\"]\\s*:\\s*)aiGuard\\.default/g, '$1aiGuard');\r\n \r\n // 2. Fix raw assignment: rules: aiGuard.PRESET.rules -> rules: { ...aiGuard.configs.PRESET.rules }\r\n repaired = repaired.replace(\r\n /rules\\s*:\\s*aiGuard\\.([a-zA-Z0-9_]+)\\.rules(,?)/g,\r\n 'rules: {\\n ...aiGuard.configs.$1.rules,\\n }$2',\r\n );\r\n \r\n // 3. Fix spread assignment: ...aiGuard.PRESET.rules -> ...aiGuard.configs.PRESET.rules\r\n repaired = repaired.replace(/\\.\\.\\.aiGuard\\.([a-zA-Z0-9_]+)\\.rules/g, '...aiGuard.configs.$1.rules');\r\n \r\n return repaired;\r\n}\r\n\r\nexport function patchFlatConfig(existing: string, preset: Preset): string {\r\n if (isInvalidAiGuardConfig(existing)) {\r\n return repairInvalidFlatConfig(existing);\r\n }\r\n\r\n // If already configured and valid — leave untouched\r\n if (existing.includes(AI_GUARD_MARKER)) {\r\n return existing;\r\n }\r\n\r\n const importLine = `import aiGuard from 'eslint-plugin-ai-guard';\\n`;\r\n\r\n const rulesBlock = `\r\n // ai-guard injected by ai-guard CLI\r\n {\r\n plugins: {\r\n 'ai-guard': aiGuard,\r\n },\r\n rules: {\r\n ...aiGuard.configs.${preset}.rules,\r\n },\r\n },\r\n`;\r\n\r\n // Prepend import after the last existing import, or at the very top\r\n let patched = existing;\r\n const lastImportIdx = findLastImportEnd(patched);\r\n if (lastImportIdx > -1) {\r\n patched =\r\n patched.slice(0, lastImportIdx) +\r\n importLine +\r\n patched.slice(lastImportIdx);\r\n } else {\r\n patched = importLine + patched;\r\n }\r\n\r\n // Insert rule block before the closing `];` of the export default array\r\n const lastBracket = patched.lastIndexOf('];');\r\n if (lastBracket !== -1) {\r\n patched =\r\n patched.slice(0, lastBracket) + rulesBlock + patched.slice(lastBracket);\r\n }\r\n\r\n return patched;\r\n}\r\n\r\n/** Find index just after the last `import … from '…';` line */\r\nfunction findLastImportEnd(src: string): number {\r\n const lines = src.split('\\n');\r\n let lastImportLine = -1;\r\n let charCount = 0;\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n if (/^\\s*import\\s+/.test(line)) lastImportLine = i;\r\n charCount += line.length + 1; // +1 for \\n\r\n }\r\n if (lastImportLine === -1) return -1;\r\n\r\n // Recalculate offset to end of that line\r\n let offset = 0;\r\n for (let i = 0; i <= lastImportLine; i++) {\r\n offset += lines[i].length + 1;\r\n }\r\n return offset;\r\n}\r\n\r\n// ─── Legacy Config Patching (ESLint v8) ───────────────────────────────────────\r\n\r\nexport function patchLegacyConfig(existing: string, preset: Preset): string {\r\n if (existing.includes('ai-guard')) {\r\n return existing; // already configured\r\n }\r\n\r\n let patched = existing;\r\n\r\n if (patched.includes('plugins:')) {\r\n patched = patched.replace(/plugins:\\s*\\[/, `plugins: ['ai-guard', `);\r\n } else {\r\n patched = patched.replace(\r\n 'module.exports = {',\r\n `module.exports = {\\n plugins: ['ai-guard'],`,\r\n );\r\n }\r\n\r\n if (patched.includes('extends:')) {\r\n patched = patched.replace(\r\n /extends:\\s*\\[/,\r\n `extends: ['plugin:ai-guard/${preset}', `,\r\n );\r\n } else {\r\n patched = patched.replace(\r\n 'module.exports = {',\r\n `module.exports = {\\n extends: ['plugin:ai-guard/${preset}'],`,\r\n );\r\n }\r\n\r\n return patched;\r\n}\r\n\r\nexport function switchFlatPreset(existing: string, preset: Preset): string {\r\n let patched = existing;\r\n\r\n patched = patched.replace(\r\n /\\.\\.\\.aiGuard\\.configs\\.(recommended|strict|security)\\.rules/g,\r\n `...aiGuard.configs.${preset}.rules`,\r\n );\r\n\r\n patched = patched.replace(\r\n /['\"]ai-guard\\/(recommended|strict|security)['\"]/g,\r\n `'ai-guard/${preset}'`,\r\n );\r\n\r\n return patched;\r\n}\r\n\r\nexport function switchLegacyPreset(existing: string, preset: Preset): string {\r\n let patched = existing;\r\n\r\n patched = patched.replace(\r\n /['\"]plugin:ai-guard\\/(recommended|strict|security)['\"]/g,\r\n `'plugin:ai-guard/${preset}'`,\r\n );\r\n\r\n patched = patched.replace(\r\n /['\"]ai-guard\\/(recommended|strict|security)['\"]/g,\r\n `'ai-guard/${preset}'`,\r\n );\r\n\r\n return patched;\r\n}\r\n\r\n// ─── Nuke-ignore removal ──────────────────────────────────────────────────────\r\n\r\n/**\r\n * Remove `ignorePatterns: [\"**\\/*\"]` from legacy configs.\r\n * Returns `{ content, changed }`.\r\n */\r\nexport function removeNukeIgnore(existing: string): {\r\n content: string;\r\n changed: boolean;\r\n} {\r\n const nukePatterns = [/\"?\\*\\*\\/\\*\"?/g];\r\n const hasNuke =\r\n existing.includes('\"**/*\"') || existing.includes(\"'**/*'\");\r\n\r\n if (!hasNuke) return { content: existing, changed: false };\r\n\r\n // Replace the entire ignorePatterns array value when it contains **/*\r\n let patched = existing\r\n .replace(\r\n /ignorePatterns:\\s*\\[.*?\\*\\*\\/\\*.*?\\]/gs,\r\n `ignorePatterns: ['node_modules/', '.next/', 'dist/', 'build/', 'coverage/']`,\r\n )\r\n .replace(\r\n /ignores:\\s*\\[.*?\\*\\*\\/\\*.*?\\]/gs,\r\n `ignores: ['node_modules/**', '.next/**', 'dist/**', 'build/**', 'coverage/**']`,\r\n );\r\n\r\n // Safety: if the regex above didn't match (complex multi-line), fall back to\r\n // a line-by-line strip of **/* entries\r\n for (const re of nukePatterns) {\r\n patched = patched.replace(re, '');\r\n }\r\n\r\n return { content: patched, changed: patched !== existing };\r\n}\r\n\r\n// ─── Ignore pattern helpers ───────────────────────────────────────────────────\r\n\r\nconst DEFAULT_FLAT_IGNORES = [\r\n 'node_modules/**',\r\n '.next/**',\r\n 'dist/**',\r\n 'build/**',\r\n 'coverage/**',\r\n 'out/**',\r\n];\r\n\r\nconst DEFAULT_LEGACY_IGNORES = [\r\n 'node_modules/',\r\n '.next/',\r\n 'dist/',\r\n 'build/',\r\n 'coverage/',\r\n 'out/',\r\n];\r\n\r\nexport function addIgnoresToFlatConfig(existing: string): string {\r\n if (existing.includes('ignores:')) return existing;\r\n\r\n const block = `\r\n // Default ignores added by ai-guard CLI\r\n {\r\n ignores: ${JSON.stringify(DEFAULT_FLAT_IGNORES)},\r\n },\r\n`;\r\n\r\n const lastBracket = existing.lastIndexOf('];');\r\n if (lastBracket !== -1) {\r\n return existing.slice(0, lastBracket) + block + existing.slice(lastBracket);\r\n }\r\n return existing;\r\n}\r\n\r\nexport function addIgnoresToLegacyConfig(existing: string): string {\r\n if (existing.includes('ignorePatterns')) return existing;\r\n return existing.replace(\r\n 'module.exports = {',\r\n `module.exports = {\\n ignorePatterns: ${JSON.stringify(DEFAULT_LEGACY_IGNORES)},`,\r\n );\r\n}\r\n\r\n// ─── Config file path resolution ──────────────────────────────────────────────\r\n\r\nexport function getConfigFilePath(\r\n configType: ConfigType,\r\n cwd = process.cwd(),\r\n): string {\r\n switch (configType) {\r\n case 'flat-js':\r\n return path.join(cwd, 'eslint.config.js');\r\n case 'flat-mjs':\r\n return path.join(cwd, 'eslint.config.mjs');\r\n case 'flat-cjs':\r\n return path.join(cwd, 'eslint.config.cjs');\r\n case 'eslintrc-js':\r\n return path.join(cwd, '.eslintrc.js');\r\n case 'eslintrc-cjs':\r\n return path.join(cwd, '.eslintrc.cjs');\r\n case 'eslintrc-json':\r\n return path.join(cwd, '.eslintrc.json');\r\n default:\r\n return path.join(cwd, '.eslintrc.js');\r\n }\r\n}\r\n\r\n// ─── Post-init config validation ──────────────────────────────────────────────\r\n\r\n/**\r\n * Lightweight structural validation of a generated/patched flat config.\r\n * Does NOT require ESLint to be loadable — just checks the text.\r\n * Returns an array of problem strings; empty = looks valid.\r\n */\r\nexport function validateFlatConfigText(content: string): string[] {\r\n const problems: string[] = [];\r\n\r\n if (!content.includes('export default')) {\r\n problems.push('Missing `export default` — file must be an ES module');\r\n }\r\n if (!content.includes('eslint-plugin-ai-guard') && !content.includes('aiGuard')) {\r\n problems.push('Plugin import not found — ai-guard plugin may not be referenced');\r\n }\r\n if (!content.trim().endsWith('];') && !content.trim().endsWith('];')) {\r\n // minor — not fatal\r\n }\r\n\r\n // Detect nuke ignore that would prevent any files from being linted\r\n if (content.includes('\"**/*\"') || content.includes(\"'**/*'\")) {\r\n problems.push(\r\n 'Config contains \"**/*\" ignore pattern — this will prevent all files from being linted',\r\n );\r\n }\r\n\r\n return problems;\r\n}\r\n\r\nexport function validateLegacyConfigText(content: string): string[] {\r\n const problems: string[] = [];\r\n\r\n if (!content.includes('module.exports')) {\r\n problems.push('Missing `module.exports` — legacy config must use CJS exports');\r\n }\r\n if (!content.includes('ai-guard')) {\r\n problems.push('Plugin not referenced — add ai-guard to plugins and extends');\r\n }\r\n if (content.includes('\"**/*\"') || content.includes(\"'**/*'\")) {\r\n problems.push(\r\n 'Config contains \"**/*\" ignore pattern — this will prevent all files from being linted',\r\n );\r\n }\r\n\r\n return problems;\r\n}\r\n","import { Command } from 'commander';\nimport fs from 'fs';\nimport path from 'path';\nimport { registerRunCommand } from './commands/run.js';\nimport { registerInitCommand } from './commands/init.js';\nimport { registerDoctorCommand } from './commands/doctor.js';\nimport { registerPresetCommand } from './commands/preset.js';\nimport { registerIgnoreCommand } from './commands/ignore.js';\nimport { registerBaselineCommand } from './commands/baseline.js';\nimport { registerInitContextCommand } from './commands/init-context.js';\nimport { log } from './utils/logger.js';\n\n// ─── Version resolution ───────────────────────────────────────────────────────\n\nfunction getVersion(): string {\n try {\n // In the bundled CLI output, __dirname is available (CJS bundle).\n const pkgPath = path.resolve(__dirname, '../../package.json');\n const raw = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(raw) as { version?: string };\n return typeof pkg.version === 'string' ? pkg.version : '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n\n// ─── Program ──────────────────────────────────────────────────────────────────\n\nconst program = new Command();\n\nprogram\n .name('ai-guard')\n .description(\n 'Production-grade CLI for eslint-plugin-ai-guard\\n' +\n 'Catch AI-generated code issues instantly — no ESLint config required.\\n\\n' +\n 'Quick start:\\n' +\n ' npx ai-guard run Scan current project\\n' +\n ' npx ai-guard init Auto-configure ESLint\\n' +\n ' npx ai-guard init-context Generate AI agent rules\\n' +\n ' npx ai-guard doctor Check your setup\\n' +\n ' npx ai-guard baseline Save baseline, track new issues only',\n )\n .version(getVersion(), '-v, --version', 'Print version number')\n .helpOption('-h, --help', 'Show help');\n\n// ─── Register commands ────────────────────────────────────────────────────────\n\nregisterRunCommand(program);\nregisterInitCommand(program);\nregisterDoctorCommand(program);\nregisterPresetCommand(program);\nregisterIgnoreCommand(program);\nregisterBaselineCommand(program);\nregisterInitContextCommand(program);\n\n// ─── Global error handling ────────────────────────────────────────────────────\n\nprogram.configureOutput({\n writeErr(str) {\n // Strip commander's default \"error: \" prefix for cleaner output\n const cleaned = str.replace(/^error:\\s*/i, '').trim();\n log.error(cleaned);\n },\n});\n\nprocess.on('unhandledRejection', (reason: unknown) => {\n const msg =\n reason instanceof Error ? reason.message : String(reason);\n log.error(`Unexpected error: ${msg}`);\n log.info('If this looks like a bug, please report it at:');\n log.info(' https://github.com/YashJadhav21/eslint-plugin-ai-guard/issues');\n process.exit(1);\n});\n\nprocess.on('SIGINT', () => {\n log.blank();\n log.info('Cancelled.');\n process.exit(0);\n});\n\n// ─── Parse args ───────────────────────────────────────────────────────────────\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err);\n log.error(msg);\n process.exit(1);\n});\n","import type { Command } from 'commander';\r\nimport ora from 'ora';\r\nimport chalk from 'chalk';\r\nimport { runEslint, type Preset } from '../utils/eslint-runner.js';\r\nimport { log } from '../utils/logger.js';\r\nimport type { RunResult } from '../utils/eslint-runner.js';\r\n\r\nexport function registerRunCommand(program: Command): void {\r\n program\r\n .command('run')\r\n .description('Run ai-guard rules on your project (zero ESLint config required)')\r\n .option('--path <dir>', 'Directory or file to scan', '.')\r\n .option('--strict', 'Use the strict rule preset (all rules at error)')\r\n .option('--security', 'Use the security-only rule preset')\r\n .option('--json', 'Output results as JSON')\r\n .option(\r\n '--max-warnings <n>',\r\n 'Fail if warnings exceed this count',\r\n (value: string) => Number.parseInt(value, 10),\r\n )\r\n .action(async (opts: {\r\n path: string;\r\n strict?: boolean;\r\n security?: boolean;\r\n json?: boolean;\r\n maxWarnings?: number;\r\n }) => {\r\n if (\r\n opts.maxWarnings !== undefined &&\r\n (!Number.isInteger(opts.maxWarnings) || opts.maxWarnings < 0)\r\n ) {\r\n log.blank();\r\n log.error('--max-warnings must be a non-negative integer.');\r\n log.blank();\r\n process.exit(1);\r\n return;\r\n }\r\n\r\n const preset: Preset = opts.strict\r\n ? 'strict'\r\n : opts.security\r\n ? 'security'\r\n : 'recommended';\r\n\r\n if (opts.strict && opts.security && !opts.json) {\r\n log.warn('Both --strict and --security were provided. Using --strict.');\r\n log.blank();\r\n }\r\n\r\n if (!opts.json) {\r\n log.banner('AI GUARD RESULTS');\r\n log.blank();\r\n }\r\n\r\n const spinner = opts.json\r\n ? null\r\n : ora({ text: 'Scanning…', color: 'cyan' }).start();\r\n\r\n let result: RunResult;\r\n try {\r\n result = await runEslint({ preset, targetPath: opts.path });\r\n spinner?.stop();\r\n } catch (err: unknown) {\r\n spinner?.stop();\r\n const msg = err instanceof Error ? err.message : String(err);\r\n\r\n // Friendly TS parser error\r\n if (msg.toLowerCase().includes('typescript') && msg.toLowerCase().includes('parser')) {\r\n log.blank();\r\n log.error('TypeScript detected but parser not found.');\r\n log.blank();\r\n log.print(` ${chalk.bold('Install the TypeScript parser:')}`);\r\n log.blank();\r\n log.print(` ${chalk.cyan('npm install --save-dev @typescript-eslint/parser')}`);\r\n log.blank();\r\n } else {\r\n log.blank();\r\n log.error(msg);\r\n log.blank();\r\n log.print(` ${chalk.bold('Fix:')} Run ${chalk.cyan('ai-guard doctor')} to diagnose your setup.`);\r\n log.blank();\r\n }\r\n process.exit(1);\r\n return;\r\n }\r\n\r\n // ─── JSON mode ─────────────────────────────────────────────────────────\r\n\r\n if (opts.json) {\r\n const jsonOutput = {\r\n preset,\r\n scannedPath: opts.path,\r\n totalErrors: result.totalErrors,\r\n totalWarnings: result.totalWarnings,\r\n totalIssues: result.totalIssues,\r\n durationMs: result.durationMs,\r\n ruleBreakdown: Object.fromEntries(result.ruleBreakdown),\r\n topFiles: result.topFiles,\r\n files: result.files,\r\n };\r\n console.log(JSON.stringify(jsonOutput, null, 2));\r\n process.exit(getRunExitCode(result, opts.maxWarnings));\r\n return;\r\n }\r\n\r\n // ─── Human output ──────────────────────────────────────────────────────\r\n\r\n // Header: scan info\r\n log.success(`Scanned: ${chalk.white(opts.path)}`);\r\n log.success(`Duration: ${chalk.white(result.durationMs + 'ms')}`);\r\n log.blank();\r\n\r\n // ── Success state ────────────────────────────────────────────────────────\r\n\r\n if (result.totalIssues === 0) {\r\n log.print(\r\n ` ${chalk.green('✔')} ${chalk.bold.green('No AI issues found — your code looks clean')}`,\r\n );\r\n log.blank();\r\n process.exit(0);\r\n return;\r\n }\r\n\r\n // ── Issue summary ────────────────────────────────────────────────────────\r\n\r\n log.print(\r\n ` ${chalk.bold('Total Issues:')} ${formatIssueCount(result.totalErrors, result.totalWarnings)}`,\r\n );\r\n log.blank();\r\n\r\n // ── By Rule ─────────────────────────────────────────────────────────────\r\n\r\n if (result.ruleBreakdown.size > 0) {\r\n log.section('By Rule');\r\n\r\n const sorted = [...result.ruleBreakdown.entries()].sort(\r\n (a, b) => b[1] - a[1],\r\n );\r\n for (const [rule, count] of sorted) {\r\n // Strip the \"ai-guard/\" prefix for cleaner display\r\n const shortRule = rule.replace(/^ai-guard\\//, '');\r\n log.print(\r\n ` ${chalk.gray('•')} ${chalk.yellow(shortRule)}${chalk.gray(':')} ${chalk.white(String(count))}`,\r\n );\r\n }\r\n log.blank();\r\n }\r\n\r\n // ── Top Files ───────────────────────────────────────────────────────────\r\n\r\n if (result.topFiles.length > 0) {\r\n log.section('Top Files');\r\n\r\n for (const { path: fp, count } of result.topFiles) {\r\n log.print(\r\n ` ${chalk.gray('•')} ${chalk.white(fp)} ${chalk.gray(`(${count})`)}`,\r\n );\r\n }\r\n log.blank();\r\n }\r\n\r\n // ── Issues by File ───────────────────────────────────────────────────────\r\n\r\n log.section('Issues by File');\r\n log.blank();\r\n\r\n for (const file of result.files) {\r\n log.print(\r\n ` ${chalk.bold.white(file.filePath)} ` +\r\n chalk.gray(\r\n `(${file.errorCount} error${file.errorCount !== 1 ? 's' : ''}, ` +\r\n `${file.warningCount} warning${file.warningCount !== 1 ? 's' : ''})`,\r\n ),\r\n );\r\n\r\n for (const issue of file.issues) {\r\n const sev = issue.severity === 2\r\n ? chalk.red('error')\r\n : chalk.yellow(' warn');\r\n const loc = chalk.gray(`${String(issue.line)}:${String(issue.column)}`).padEnd(12);\r\n const ruleShort = chalk.gray(issue.ruleId.replace(/^ai-guard\\//, ''));\r\n log.print(\r\n ` ${loc} ${sev} ${chalk.white(issue.message)} ${ruleShort}`,\r\n );\r\n }\r\n\r\n log.blank();\r\n }\r\n\r\n log.divider();\r\n log.blank();\r\n\r\n // ── Next steps ───────────────────────────────────────────────────────────\r\n\r\n log.section('Next Steps');\r\n if (!result.topFiles.length) {\r\n log.info(`Run ${chalk.cyan('ai-guard init')} to wire up ESLint for your editor`);\r\n }\r\n log.info(`Run ${chalk.cyan('ai-guard baseline')} to save these issues and track only new ones`);\r\n log.info(`Run ${chalk.cyan('ai-guard ignore')} to suppress dist/build noise`);\r\n log.blank();\r\n\r\n process.exit(getRunExitCode(result, opts.maxWarnings));\r\n });\r\n}\r\n\r\nexport function getRunExitCode(result: RunResult, maxWarnings?: number): number {\r\n if (result.totalErrors > 0) return 1;\r\n if (maxWarnings !== undefined && result.totalWarnings > maxWarnings) return 1;\r\n return 0;\r\n}\r\n\r\nfunction formatIssueCount(errors: number, warnings: number): string {\r\n const parts: string[] = [];\r\n if (errors > 0) parts.push(chalk.red.bold(`${errors} error${errors !== 1 ? 's' : ''}`));\r\n if (warnings > 0) parts.push(chalk.yellow.bold(`${warnings} warning${warnings !== 1 ? 's' : ''}`));\r\n return parts.join(chalk.gray(' · '));\r\n}\r\n","import fs from 'fs';\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport { log } from './logger.js';\r\n\r\n// ─── Types ────────────────────────────────────────────────────────────────────\r\n\r\ntype RuleLevel = 'error' | 'warn' | 'off';\r\n\r\nexport type Preset = 'recommended' | 'strict' | 'security';\r\n\r\nexport interface RunOptions {\r\n preset: Preset;\r\n targetPath: string;\r\n maxWarnings?: number;\r\n jsonOutput?: boolean;\r\n}\r\n\r\nexport interface IssueDetail {\r\n ruleId: string;\r\n severity: 1 | 2;\r\n message: string;\r\n line: number;\r\n column: number;\r\n}\r\n\r\nexport interface FileResult {\r\n filePath: string;\r\n issues: IssueDetail[];\r\n errorCount: number;\r\n warningCount: number;\r\n}\r\n\r\nexport interface RunResult {\r\n files: FileResult[];\r\n totalErrors: number;\r\n totalWarnings: number;\r\n totalIssues: number;\r\n ruleBreakdown: Map<string, number>;\r\n topFiles: Array<{ path: string; count: number }>;\r\n durationMs: number;\r\n}\r\n\r\n// ─── Plugin normalizer ────────────────────────────────────────────────────────\r\n// Plugin exports `default` (ESM). When require()'d in CJS context it arrives as\r\n// { default: { rules, configs, meta } }. We normalise both shapes.\r\n\r\ntype AiGuardPlugin = {\r\n rules: Record<string, unknown>;\r\n configs?: Record<string, unknown>;\r\n meta?: Record<string, unknown>;\r\n};\r\n\r\nfunction isRecord(value: unknown): value is Record<string, unknown> {\r\n return typeof value === 'object' && value !== null;\r\n}\r\n\r\nfunction normalizePlugin(raw: unknown): AiGuardPlugin {\r\n if (isRecord(raw) && isRecord(raw.default) && isRecord(raw.default.rules)) {\r\n return raw.default as AiGuardPlugin;\r\n }\r\n if (isRecord(raw) && isRecord(raw.rules)) {\r\n return raw as AiGuardPlugin;\r\n }\r\n throw new Error(\r\n 'Could not load eslint-plugin-ai-guard. Run: npm install eslint-plugin-ai-guard',\r\n );\r\n}\r\n\r\n// ─── Preset rule maps ─────────────────────────────────────────────────────────\r\n\r\nconst RECOMMENDED_RULES: Record<string, RuleLevel> = {\r\n 'ai-guard/no-empty-catch': 'error',\r\n 'ai-guard/no-floating-promise': 'error',\r\n 'ai-guard/no-hardcoded-secret': 'error',\r\n 'ai-guard/no-eval-dynamic': 'error',\r\n 'ai-guard/no-broad-exception': 'warn',\r\n 'ai-guard/require-auth-middleware': 'warn',\r\n 'ai-guard/no-await-in-loop': 'warn',\r\n 'ai-guard/no-async-without-await': 'warn',\r\n 'ai-guard/no-sql-string-concat': 'warn',\r\n 'ai-guard/no-async-array-callback': 'warn',\r\n 'ai-guard/no-unsafe-deserialize': 'warn',\r\n 'ai-guard/require-authz-check': 'warn',\r\n};\r\n\r\nconst STRICT_RULES: Record<string, RuleLevel> = {\r\n 'ai-guard/no-empty-catch': 'error',\r\n 'ai-guard/no-broad-exception': 'error',\r\n 'ai-guard/no-catch-log-rethrow': 'error',\r\n 'ai-guard/no-catch-without-use': 'error',\r\n 'ai-guard/no-async-array-callback': 'error',\r\n 'ai-guard/no-floating-promise': 'error',\r\n 'ai-guard/no-await-in-loop': 'error',\r\n 'ai-guard/no-async-without-await': 'error',\r\n 'ai-guard/no-redundant-await': 'error',\r\n 'ai-guard/no-hardcoded-secret': 'error',\r\n 'ai-guard/no-eval-dynamic': 'error',\r\n 'ai-guard/no-sql-string-concat': 'error',\r\n 'ai-guard/no-unsafe-deserialize': 'error',\r\n 'ai-guard/require-auth-middleware': 'error',\r\n 'ai-guard/require-authz-check': 'error',\r\n 'ai-guard/no-console-in-handler': 'error',\r\n 'ai-guard/no-duplicate-logic-block': 'error',\r\n};\r\n\r\nconst SECURITY_RULES: Record<string, RuleLevel> = {\r\n 'ai-guard/no-hardcoded-secret': 'error',\r\n 'ai-guard/no-eval-dynamic': 'error',\r\n 'ai-guard/no-sql-string-concat': 'error',\r\n 'ai-guard/no-unsafe-deserialize': 'warn',\r\n 'ai-guard/require-auth-middleware': 'warn',\r\n 'ai-guard/require-authz-check': 'warn',\r\n};\r\n\r\nfunction getRules(\r\n preset: Preset,\r\n): Record<string, RuleLevel> {\r\n if (preset === 'strict') return STRICT_RULES;\r\n if (preset === 'security') return SECURITY_RULES;\r\n return RECOMMENDED_RULES;\r\n}\r\n\r\n// ─── Default ignores ──────────────────────────────────────────────────────────\r\n\r\nconst DEFAULT_IGNORE_PATTERNS = [\r\n '**/node_modules/**',\r\n '**/.next/**',\r\n '**/dist/**',\r\n '**/build/**',\r\n '**/coverage/**',\r\n '**/out/**',\r\n '**/.git/**',\r\n];\r\n\r\n// Some ESLint pattern scans should be skipped (not treated as fatal), e.g.:\r\n// - pattern has no matching files\r\n// - matched files are ignored by config/ignore rules\r\nexport function isSkippablePatternError(error: Error): boolean {\r\n const msg = error.message.toLowerCase();\r\n\r\n const hasNoFilesSignal =\r\n msg.includes('no files') ||\r\n msg.includes('no files matching');\r\n\r\n const hasIgnoredSignal =\r\n msg.includes('ignored') ||\r\n msg.includes('all files matched by') ||\r\n msg.includes('are ignored') ||\r\n msg.includes('was ignored') ||\r\n msg.includes('file ignored');\r\n\r\n return hasNoFilesSignal || hasIgnoredSignal;\r\n}\r\n\r\nasync function loadPluginModuleFromCwd(cwd: string): Promise<unknown> {\r\n const { createRequire } = await import('module');\r\n const requireFromCwd = createRequire(path.join(cwd, 'package.json'));\r\n\r\n try {\r\n const resolved = requireFromCwd.resolve('eslint-plugin-ai-guard');\r\n return import(pathToFileURL(resolved).href);\r\n } catch {\r\n // Fall through to local dist fallback.\r\n }\r\n\r\n const localDistEntry = path.join(cwd, 'dist', 'index.js');\r\n if (fs.existsSync(localDistEntry)) {\r\n return import(pathToFileURL(localDistEntry).href);\r\n }\r\n\r\n const localSrcEntry = path.join(cwd, 'src', 'index.ts');\r\n if (fs.existsSync(localSrcEntry)) {\r\n try {\r\n return import(pathToFileURL(localSrcEntry).href);\r\n } catch (err: unknown) {\r\n const reason = err instanceof Error ? err.message : String(err);\r\n log.debug(`Local src plugin import failed: ${reason}`);\r\n }\r\n }\r\n\r\n throw new Error(\r\n 'eslint-plugin-ai-guard is not installed. Run: npm install --save-dev eslint-plugin-ai-guard',\r\n );\r\n}\r\n\r\n// ─── Core runner ──────────────────────────────────────────────────────────────\r\n\r\nexport async function runEslint(options: RunOptions): Promise<RunResult> {\r\n const { ESLint } = await import('eslint').catch(() => {\r\n throw new Error(\r\n 'ESLint is not installed. Run: npm install --save-dev eslint',\r\n );\r\n });\r\n\r\n // Load the plugin — resolve relative to the user's cwd so it finds their install\r\n const rawPlugin = await loadPluginModuleFromCwd(process.cwd());\r\n\r\n const plugin = normalizePlugin(rawPlugin);\r\n const rules = getRules(options.preset);\r\n const resolvedTargetPath = path.resolve(options.targetPath);\r\n\r\n if (!fs.existsSync(resolvedTargetPath)) {\r\n throw new Error(`Path not found: ${options.targetPath}`);\r\n }\r\n\r\n const targetStat = fs.statSync(resolvedTargetPath);\r\n const isSingleFileTarget = targetStat.isFile();\r\n const eslintCwd = isSingleFileTarget\r\n ? path.dirname(resolvedTargetPath)\r\n : resolvedTargetPath;\r\n\r\n const startMs = Date.now();\r\n\r\n const JS_TS_FILES = [\r\n '**/*.js',\r\n '**/*.jsx',\r\n '**/*.ts',\r\n '**/*.tsx',\r\n '**/*.mts',\r\n '**/*.cts',\r\n '**/*.mjs',\r\n '**/*.cjs',\r\n ];\r\n\r\n // ESLint v9 programmatic API: use overrideConfigFile to disable config file\r\n // discovery and overrideConfig to inject our plugin config.\r\n // For single-file scans, set cwd to the file's directory and lint only that file.\r\n\r\n // Try to load TypeScript parser for .ts/.tsx files\r\n let tsParser: unknown = null;\r\n try {\r\n // Try user's project first, then our own node_modules\r\n try {\r\n tsParser = require(path.join(\r\n process.cwd(),\r\n 'node_modules',\r\n '@typescript-eslint',\r\n 'parser',\r\n ));\r\n } catch {\r\n tsParser = require('@typescript-eslint/parser');\r\n }\r\n } catch {\r\n // TypeScript parser not available — ts files will use default espree parser\r\n }\r\n\r\n const configBlocks: Array<Record<string, unknown>> = [\r\n // JS/JSX files — default espree parser\r\n {\r\n files: ['**/*.js', '**/*.jsx', '**/*.mjs', '**/*.cjs'],\r\n plugins: { 'ai-guard': plugin } as Record<string, unknown>,\r\n languageOptions: {\r\n parserOptions: {\r\n ecmaVersion: 'latest',\r\n sourceType: 'module',\r\n ecmaFeatures: { jsx: true },\r\n },\r\n },\r\n rules: rules as Record<string, unknown>,\r\n },\r\n // Ignore generated directories\r\n { ignores: DEFAULT_IGNORE_PATTERNS },\r\n ];\r\n\r\n if (tsParser) {\r\n configBlocks.splice(1, 0, {\r\n files: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],\r\n plugins: { 'ai-guard': plugin } as Record<string, unknown>,\r\n languageOptions: {\r\n parser: tsParser,\r\n parserOptions: {\r\n // project: true would be needed for type-aware rules — skip for speed\r\n ecmaVersion: 'latest',\r\n sourceType: 'module',\r\n },\r\n },\r\n rules: rules as Record<string, unknown>,\r\n });\r\n } else {\r\n // No TS parser — still lint ts files but they may fail to parse\r\n configBlocks.splice(1, 0, {\r\n files: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],\r\n plugins: { 'ai-guard': plugin } as Record<string, unknown>,\r\n rules: rules as Record<string, unknown>,\r\n });\r\n }\r\n\r\n const eslint = new ESLint({\r\n cwd: eslintCwd,\r\n overrideConfigFile: true as unknown as string,\r\n overrideConfig: configBlocks,\r\n });\r\n\r\n // Use relative glob patterns for directory scans, and a direct file pattern for file scans.\r\n const patterns = isSingleFileTarget\r\n ? [path.basename(resolvedTargetPath)]\r\n : JS_TS_FILES;\r\n\r\n // ESLint v9 throws if no files match a pattern — run each glob independently\r\n // and collect results, silently skipping 'no files found' errors\r\n const perPatternResults = await Promise.all(\r\n patterns.map(async (pattern) => {\r\n try {\r\n return await eslint.lintFiles([pattern]);\r\n } catch (err: unknown) {\r\n const error = err instanceof Error ? err : new Error(String(err));\r\n\r\n if (isSkippablePatternError(error)) {\r\n log.debug(`Skipping pattern '${pattern}' (no lintable files)`);\r\n return [];\r\n }\r\n\r\n // Real ESLint runtime/config/parser errors should fail fast.\r\n throw error;\r\n }\r\n }),\r\n );\r\n\r\n const rawResults = perPatternResults.flat();\r\n\r\n const durationMs = Date.now() - startMs;\r\n\r\n // ─── Process results ─────────────────────────────────────────────────────\r\n\r\n const files: FileResult[] = [];\r\n const ruleBreakdown = new Map<string, number>();\r\n let totalErrors = 0;\r\n let totalWarnings = 0;\r\n\r\n for (const result of rawResults) {\r\n if (result.messages.length === 0) continue;\r\n\r\n const issues: IssueDetail[] = result.messages.map((m) => ({\r\n ruleId: m.ruleId ?? 'unknown',\r\n severity: m.severity as 1 | 2,\r\n message: m.message,\r\n line: m.line,\r\n column: m.column,\r\n }));\r\n\r\n const errorCount = result.errorCount;\r\n const warningCount = result.warningCount;\r\n totalErrors += errorCount;\r\n totalWarnings += warningCount;\r\n\r\n for (const issue of issues) {\r\n ruleBreakdown.set(\r\n issue.ruleId,\r\n (ruleBreakdown.get(issue.ruleId) ?? 0) + 1,\r\n );\r\n }\r\n\r\n const relPath = path.relative(process.cwd(), result.filePath);\r\n files.push({ filePath: relPath, issues, errorCount, warningCount });\r\n }\r\n\r\n // Top files by issue count (top 10)\r\n const topFiles = [...files]\r\n .sort((a, b) => b.issues.length - a.issues.length)\r\n .slice(0, 10)\r\n .map((f) => ({ path: f.filePath, count: f.issues.length }));\r\n\r\n return {\r\n files,\r\n totalErrors,\r\n totalWarnings,\r\n totalIssues: totalErrors + totalWarnings,\r\n ruleBreakdown,\r\n topFiles,\r\n durationMs,\r\n };\r\n}\r\n","import chalk from 'chalk';\n\nconst PREFIX = {\n success: chalk.green('✔'),\n error: chalk.red('✖'),\n warn: chalk.yellow('⚠'),\n info: chalk.cyan('ℹ'),\n section: chalk.bold.white,\n bullet: chalk.gray('•'),\n};\n\nexport const log = {\n info(msg: string): void {\n console.log(` ${PREFIX.info} ${chalk.white(msg)}`);\n },\n\n success(msg: string): void {\n console.log(` ${PREFIX.success} ${chalk.green(msg)}`);\n },\n\n warn(msg: string): void {\n console.log(` ${PREFIX.warn} ${chalk.yellow(msg)}`);\n },\n\n error(msg: string): void {\n console.error(` ${PREFIX.error} ${chalk.red(msg)}`);\n },\n\n section(title: string): void {\n console.log('');\n console.log(chalk.bold.cyan(` ── ${title} ──`));\n console.log('');\n },\n\n rule(ruleName: string, count: number): void {\n console.log(\n ` ${PREFIX.bullet} ${chalk.yellow(ruleName)} ${chalk.gray(`(${count} issue${count !== 1 ? 's' : ''})`)}`,\n );\n },\n\n file(filePath: string, count: number): void {\n console.log(\n ` ${PREFIX.bullet} ${chalk.white(filePath)} ${chalk.gray(`→ ${count} issue${count !== 1 ? 's' : ''}`)}`,\n );\n },\n\n issue(msg: string, severity: 1 | 2, line: number, col: number): void {\n const icon = severity === 2 ? chalk.red('error') : chalk.yellow(' warn');\n console.log(\n ` ${chalk.gray(`${line}:${col}`).padEnd(12)} ${icon} ${chalk.white(msg)}`,\n );\n },\n\n divider(): void {\n console.log(chalk.gray(' ' + '─'.repeat(60)));\n },\n\n blank(): void {\n console.log('');\n },\n\n banner(title: string): void {\n console.log('');\n console.log(chalk.bold.bgCyan.black(` ${title} `));\n console.log('');\n },\n\n print(msg: string): void {\n console.log(msg);\n },\n\n debug(msg: string): void {\n if (process.env.AI_GUARD_DEBUG === '1') {\n console.log(` ${chalk.gray('·')} ${chalk.gray(msg)}`);\n }\n },\n};\n","import type { Command } from 'commander';\nimport chalk from 'chalk';\nimport path from 'path';\nimport fs from 'fs';\nimport { detect, isFlat, isLegacy, requiresFlatConfig } from '../utils/detector.js';\nimport {\n generateFlatConfig,\n generateLegacyConfig,\n patchFlatConfig,\n patchLegacyConfig,\n backupConfig,\n readConfig,\n writeConfig,\n getConfigFilePath,\n removeNukeIgnore,\n validateFlatConfigText,\n validateLegacyConfigText,\n type Preset,\n} from '../utils/config-manager.js';\nimport { log } from '../utils/logger.js';\n\n// ─── Flags ────────────────────────────────────────────────────────────────────\n\ninterface InitOptions {\n preset: string;\n flat?: boolean;\n dryRun?: boolean;\n}\n\n// ─── Error classification ────────────────────────────────────────────────────\n\ntype VerifyError =\n | { kind: 'syntax'; message: string }\n | { kind: 'module-not-found'; pkg: string; message: string }\n | { kind: 'unknown'; message: string };\n\nfunction classifyVerifyError(err: unknown): VerifyError {\n const msg = err instanceof Error ? err.message : String(err);\n const clean = msg.replace(/\\s+at\\s+.+/gm, '').trim();\n\n // Module resolution errors\n const modNotFound = clean.match(\n /Cannot find module '([^']+)'|Cannot find package '([^']+)'/,\n );\n if (modNotFound) {\n const pkg = modNotFound[1] ?? modNotFound[2] ?? 'unknown';\n return { kind: 'module-not-found', pkg, message: clean };\n }\n\n // SyntaxError / parse errors\n if (\n clean.includes('SyntaxError') ||\n clean.includes('Unexpected token') ||\n clean.includes('Invalid or unexpected token')\n ) {\n return { kind: 'syntax', message: clean };\n }\n\n return { kind: 'unknown', message: clean };\n}\n\n// ─── Programmatic ESLint verification ────────────────────────────────────────\n\n/**\n * After writing a config, try to load it via ESLint's own API.\n * Returns null on success, a classified error on failure.\n */\nasync function verifyConfigLoads(\n configPath: string,\n cwd: string,\n): Promise<null | VerifyError> {\n try {\n type EslintCtor = new (options: {\n cwd: string;\n overrideConfigFile: string;\n }) => {\n lintText: (code: string, options: { filePath: string }) => Promise<unknown>;\n };\n\n const { ESLint } = await import('eslint') as unknown as { ESLint: EslintCtor };\n\n const eslint = new ESLint({\n cwd,\n overrideConfigFile: configPath,\n });\n\n // Lint an empty JS file — forces ESLint to parse and validate the config\n await eslint.lintText('', {\n filePath: path.join(cwd, '_ai_guard_probe_.js'),\n });\n return null; // success\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n\n // \"No files\" / probe path exclusion errors are not config errors\n if (\n msg.includes('No files matching') ||\n msg.includes('_ai_guard_probe_')\n ) {\n return null;\n }\n\n return classifyVerifyError(err);\n }\n}\n\n// ─── Command registration ─────────────────────────────────────────────────────\n\nexport function registerInitCommand(program: Command): void {\n program\n .command('init')\n .description('Configure eslint-plugin-ai-guard in this project')\n .option('--preset <name>', 'Preset to use: recommended | strict | security', 'recommended')\n .option('--flat', 'Force flat config format (eslint.config.mjs) regardless of ESLint version')\n .option('--dry-run', 'Preview what would change without writing any files')\n .action(async (opts: InitOptions) => {\n const preset = (opts.preset as Preset) ?? 'recommended';\n const cwd = process.cwd();\n const isDryRun = opts.dryRun === true;\n\n log.banner('AI GUARD INIT');\n if (isDryRun) {\n log.print(` ${chalk.yellow('⚑ DRY RUN — no files will be written')}`);\n log.blank();\n }\n log.info('Detecting your project setup…');\n log.blank();\n\n const env = detect(cwd);\n\n // ─── Step 1: Environment report ──────────────────────────────────────────\n\n log.section('Environment');\n\n if (env.eslintVersion) {\n log.success(`ESLint ${env.eslintVersion} detected (v${env.eslintMajor})`);\n } else {\n log.warn('ESLint not found in node_modules');\n }\n\n if (env.pluginInstalled) {\n log.success('eslint-plugin-ai-guard is installed');\n } else {\n log.warn('eslint-plugin-ai-guard not found');\n }\n\n if (env.configType !== 'none') {\n log.success(`ESLint config found: ${chalk.white(path.relative(cwd, env.configPath ?? env.configType))}`);\n } else {\n log.info('No ESLint config found — will generate one');\n }\n\n // Warn about conflicting configs (only if not ESLint v9, as v9 auto-resolves)\n const eslintNeedsFlat = requiresFlatConfig(env.eslintMajor);\n if (env.hasConflictingConfigs && !eslintNeedsFlat) {\n log.blank();\n log.warn('Conflicting configs detected:');\n for (const p of env.allConfigPaths) {\n log.print(` ${chalk.yellow('→')} ${chalk.white(path.relative(cwd, p))}`);\n }\n log.print(` ${chalk.gray('Multiple config formats found — this can cause unpredictable behavior.')}`);\n }\n\n log.blank();\n\n // ─── Step 2: Gate on missing deps ────────────────────────────────────────\n\n const toInstall: string[] = [];\n if (!env.eslintVersion) toInstall.push('eslint');\n if (!env.pluginInstalled) toInstall.push('eslint-plugin-ai-guard');\n\n if (toInstall.length > 0) {\n log.section('Missing Dependencies');\n log.warn('The following packages are not installed:');\n log.blank();\n for (const pkg of toInstall) {\n log.print(` ${chalk.yellow('→')} ${chalk.white(pkg)}`);\n }\n log.blank();\n log.print(` ${chalk.bold('Run this first:')}`);\n log.blank();\n log.print(` ${chalk.cyan(`npm install --save-dev ${toInstall.join(' ')}`)}`);\n log.blank();\n log.print(` Then re-run ${chalk.cyan('ai-guard init')} to complete setup.`);\n log.blank();\n process.exit(1);\n return;\n }\n\n // ─── Step 3: Runtime Safety ─────────────────────────────────────────────\n\n try {\n const { createRequire } = await import('module');\n const { pathToFileURL } = await import('url');\n const req = createRequire(path.join(cwd, '_probe.js'));\n const resolvedPath = req.resolve('eslint-plugin-ai-guard');\n const aiGuard = await import(pathToFileURL(resolvedPath).href);\n const plugin = (aiGuard.default || aiGuard) as {\n configs?: Record<string, { rules?: unknown }>;\n };\n\n const hasPresetRules =\n !!plugin.configs &&\n !!plugin.configs[preset] &&\n !!plugin.configs[preset].rules;\n\n if (!hasPresetRules) {\n // Keep this as informational only; Step 6 performs definitive runtime validation.\n log.debug('Plugin precheck could not verify configs shape; continuing to validation step.');\n }\n } catch (e) {\n // If resolution fails entirely, skip the check; validation step will catch load errors\n const reason = e instanceof Error ? e.message : String(e);\n log.debug(`Skipped plugin precheck: ${reason}`);\n }\n\n // ─── Step 4: Determine config format ────────────────────────────────────\n // Priority:\n // 1. --flat flag forces flat config\n // 2. ESLint v9+ → MUST use flat config\n // 3. ESLint v8 → use legacy; unless an existing flat config is already there\n // 4. No version info → default to flat (safer)\n\n const forceFlat = opts.flat === true;\n const existingIsFlat = isFlat(env.configType);\n const existingIsLegacy = isLegacy(env.configType);\n const useFlat = forceFlat || eslintNeedsFlat || existingIsFlat || env.configType === 'none';\n\n // Guard: ESLint v9 + existing legacy config → migrate, don't re-create legacy\n if (eslintNeedsFlat && existingIsLegacy) {\n log.section('Config Migration Required');\n log.warn(`ESLint v${env.eslintMajor} requires flat config, but a legacy config was found:`);\n log.print(` ${chalk.white(path.relative(cwd, env.configPath!))}`);\n log.blank();\n log.print(` ${chalk.bold('ai-guard will create a new flat config.')}`);\n log.blank();\n }\n\n // ─── Step 5: Apply config change ────────────────────────────────────────\n\n log.section(`Configuring ESLint${isDryRun ? ' (dry run)' : ''}`);\n\n let finalConfigPath: string;\n let configWritten = false;\n\n // Nuke-ignore removal — fix before anything else\n if (env.configPath && env.hasNukeIgnore) {\n const raw = readConfig(env.configPath);\n const { content: fixed, changed } = removeNukeIgnore(raw);\n if (changed) {\n log.warn(`Removed \"**/*\" ignore pattern from ${path.relative(cwd, env.configPath)}`);\n if (!isDryRun) {\n backupConfig(env.configPath);\n writeConfig(env.configPath, fixed);\n log.success('Ignore pattern fixed');\n } else {\n log.print(` ${chalk.gray('[dry-run] would remove nuke-ignore from existing config')}`);\n }\n }\n }\n\n if (env.configType === 'none' || (eslintNeedsFlat && existingIsLegacy)) {\n // ── Generate fresh config ──────────────────────────────────────────────\n const targetName = useFlat ? 'eslint.config.mjs' : '.eslintrc.js';\n finalConfigPath = path.join(cwd, targetName);\n\n const content = useFlat\n ? generateFlatConfig(preset)\n : generateLegacyConfig(preset);\n\n if (isDryRun) {\n log.print(` ${chalk.gray(`[dry-run] would create: ${targetName}`)}`);\n log.blank();\n log.print(chalk.gray('─── Preview ─────────────────────────────────────────────'));\n log.blank();\n for (const line of content.split('\\n')) {\n log.print(chalk.gray(` ${line}`));\n }\n log.blank();\n } else {\n writeConfig(finalConfigPath, content);\n log.success(`Created ${chalk.white(targetName)}`);\n log.info(` Preset: ${chalk.cyan(preset)}`);\n log.info(` Format: ${chalk.cyan(useFlat ? 'ESLint v9 flat config (eslint.config.mjs)' : 'ESLint v8 legacy config (.eslintrc.js)')}`);\n configWritten = true;\n }\n } else if (useFlat && existingIsFlat) {\n // ── Patch existing flat config ─────────────────────────────────────────\n const { isInvalidAiGuardConfig } = await import('../utils/config-manager.js');\n const existing = readConfig(env.configPath!);\n const isInvalid = isInvalidAiGuardConfig(existing);\n const patched = patchFlatConfig(existing, preset);\n\n if (patched === existing && !isInvalid) {\n log.warn('ai-guard is already present in your config — no changes made');\n finalConfigPath = env.configPath!;\n } else if (isDryRun) {\n finalConfigPath = env.configPath!;\n log.print(` ${chalk.gray(`[dry-run] would patch: ${path.relative(cwd, env.configPath!)}`)}`);\n } else {\n const bak = backupConfig(env.configPath!);\n log.info(`Backed up → ${chalk.gray(path.relative(cwd, bak))}`);\n writeConfig(env.configPath!, patched);\n if (isInvalid) {\n log.success(`Detected invalid ai-guard config — repairing ${chalk.white(path.relative(cwd, env.configPath!))}`);\n } else {\n log.success(`Patched ${chalk.white(path.relative(cwd, env.configPath!))}`);\n }\n finalConfigPath = env.configPath!;\n configWritten = true;\n }\n } else {\n // ── Patch existing legacy config ─────────────────────────────────────\n const existing = readConfig(env.configPath!);\n const patched = patchLegacyConfig(existing, preset);\n\n if (patched === existing) {\n log.warn('ai-guard is already present in your config — no changes made');\n finalConfigPath = env.configPath!;\n } else if (isDryRun) {\n finalConfigPath = env.configPath!;\n log.print(` ${chalk.gray(`[dry-run] would patch: ${path.relative(cwd, env.configPath!)}`)}`);\n } else {\n const bak = backupConfig(env.configPath!);\n log.info(`Backed up → ${chalk.gray(path.relative(cwd, bak))}`);\n writeConfig(env.configPath!, patched);\n log.success(`Patched ${chalk.white(path.relative(cwd, env.configPath!))}`);\n finalConfigPath = env.configPath!;\n configWritten = true;\n }\n }\n\n // ── Auto cleanup legacy config (conflict resolution) ───────────────\n if (eslintNeedsFlat) {\n // Find legacy configs that might cause conflicts\n const legacyConfigs = env.allConfigPaths.filter(p => !p.includes('eslint.config.'));\n \n let cleanedUp = false;\n for (const p of legacyConfigs) {\n if (fs.existsSync(p)) {\n if (!isDryRun) {\n try {\n fs.renameSync(p, `${p}.bak`);\n cleanedUp = true;\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n log.warn(`Could not back up ${path.relative(cwd, p)}: ${reason}`);\n }\n } else {\n cleanedUp = true;\n log.print(` ${chalk.gray(`[dry-run] would rename ${path.relative(cwd, p)} to ${path.basename(p)}.bak`)}`);\n }\n }\n }\n if (cleanedUp && !isDryRun) {\n log.success('Legacy config backed up to avoid ESLint conflict');\n }\n }\n\n if (isDryRun) {\n log.blank();\n log.print(` ${chalk.yellow('Dry run complete — no files written.')}`);\n log.print(` Re-run without ${chalk.cyan('--dry-run')} to apply.`);\n log.blank();\n process.exit(0);\n return;\n }\n\n log.blank();\n\n // ─── Step 5: Structural validation ──────────────────────────────────────\n\n log.section('Validation');\n\n if (!fs.existsSync(finalConfigPath)) {\n log.error(`Config file not found after write: ${path.relative(cwd, finalConfigPath)}`);\n log.blank();\n log.print(` ${chalk.bold('Problem:')} File write may have failed.`);\n log.print(` ${chalk.bold('Fix:')} Check disk space and file permissions, then re-run.`);\n log.blank();\n process.exit(1);\n return;\n }\n\n const content = readConfig(finalConfigPath);\n const validationErrors = useFlat\n ? validateFlatConfigText(content)\n : validateLegacyConfigText(content);\n\n if (validationErrors.length > 0) {\n log.warn('Config validation found issues:');\n for (const e of validationErrors) {\n log.print(` ${chalk.red('✖')} ${e}`);\n }\n } else {\n log.success(`Config structure valid: ${chalk.white(path.relative(cwd, finalConfigPath))}`);\n }\n\n // ─── Step 6: Programmatic ESLint load verification ───────────────────────\n\n log.info('Verifying ESLint can load the config…');\n\n const loadError = await verifyConfigLoads(finalConfigPath, cwd);\n if (loadError !== null) {\n log.blank();\n\n if (loadError.kind === 'module-not-found') {\n // Missing dep — config syntax is fine, just need to install the package\n log.warn(`Could not verify: module not found: ${chalk.yellow(loadError.pkg)}`);\n log.blank();\n log.print(` ${chalk.bold('Install the missing package:')}`);\n log.print(` ${chalk.cyan(`npm install --save-dev ${loadError.pkg}`)}`);\n log.print(` Then run ${chalk.cyan('ai-guard doctor')} to confirm.`);\n log.blank();\n // Fall through — config was written correctly; missing dep is user's next step\n } else {\n // Real error — config syntax broken or unknown failure → hard fail\n log.error('ESLint failed to load the generated config.');\n log.blank();\n log.print(` ${chalk.bold('Problem:')}`);\n log.print(` ${chalk.red(loadError.message)}`);\n if (loadError.kind === 'unknown') {\n log.blank();\n log.print(` ${chalk.yellow('Generated config may be using incorrect plugin structure.')}`);\n }\n log.blank();\n log.print(` ${chalk.bold('Fix:')}`);\n log.print(` 1. Check the syntax in ${chalk.cyan(path.relative(cwd, finalConfigPath))}`);\n log.print(` 2. Make sure ${chalk.cyan('eslint-plugin-ai-guard')} is installed`);\n log.print(` 3. Run ${chalk.cyan('ai-guard doctor')} for full diagnostics`);\n log.blank();\n process.exit(1);\n return;\n }\n } else {\n log.success('ESLint loaded config successfully');\n }\n\n\n log.blank();\n\n\n\n // ─── Step 7: Success ─────────────────────────────────────────────────────\n\n log.section('Setup Complete');\n log.blank();\n\n let cleanedUpInfo = false;\n if (eslintNeedsFlat) {\n const legacyConfigs = env.allConfigPaths.filter(p => !p.includes('eslint.config.'));\n cleanedUpInfo = legacyConfigs.some(p => fs.existsSync(`${p}.bak`) && !fs.existsSync(p));\n }\n\n const lingeringConflicts = env.hasConflictingConfigs && !eslintNeedsFlat && !cleanedUpInfo;\n if (loadError === null && !lingeringConflicts) {\n log.print(` ${chalk.green('✔')} ${chalk.bold.green('Configuration validated successfully')}`);\n }\n log.print(` ${chalk.green('✔')} ${chalk.bold('ESLint config:')} ${chalk.cyan(path.relative(cwd, finalConfigPath))}`);\n log.print(` ${chalk.green('✔')} ${chalk.bold('Mode:')} ${chalk.cyan(useFlat ? `Flat config (ESLint v${env.eslintMajor ?? 9})` : `Legacy config (ESLint v${env.eslintMajor ?? 8})`)}`);\n log.print(` ${chalk.green('✔')} ${chalk.bold('Preset:')} ${chalk.cyan(preset)}`);\n log.blank();\n log.info(`Run ${chalk.cyan('npx eslint .')} → lint with your editor integration`);\n log.info(`Run ${chalk.cyan('ai-guard run')} → zero-config scan`);\n log.info(`Run ${chalk.cyan('ai-guard doctor')} → verify the full setup`);\n log.info(`Run ${chalk.cyan('ai-guard baseline')} → save baseline, track only new issues`);\n log.blank();\n });\n}\n","import fs from 'fs';\r\nimport path from 'path';\r\nimport { createRequire } from 'module';\r\n\r\n// ─── Types ────────────────────────────────────────────────────────────────────\r\n\r\nexport type ConfigType =\r\n | 'flat-js'\r\n | 'flat-mjs'\r\n | 'flat-cjs'\r\n | 'eslintrc-js'\r\n | 'eslintrc-cjs'\r\n | 'eslintrc-json'\r\n | 'eslintrc-yaml'\r\n | 'none';\r\n\r\nexport interface DetectionResult {\r\n /** Raw version string e.g. \"9.1.0\" — null if not installed */\r\n eslintVersion: string | null;\r\n eslintMajor: number | null;\r\n pluginInstalled: boolean;\r\n configType: ConfigType;\r\n configPath: string | null;\r\n /** All config files found — to detect conflicts */\r\n allConfigPaths: string[];\r\n /** True when a flat config AND a legacy config both exist */\r\n hasConflictingConfigs: boolean;\r\n /** True when config contains a pattern that ignores everything */\r\n hasNukeIgnore: boolean;\r\n}\r\n\r\n// ─── Config file registry ─────────────────────────────────────────────────────\r\n\r\nconst FLAT_CONFIG_FILES: Array<{ file: string; type: ConfigType }> = [\r\n { file: 'eslint.config.js', type: 'flat-js' },\r\n { file: 'eslint.config.mjs', type: 'flat-mjs' },\r\n { file: 'eslint.config.cjs', type: 'flat-cjs' },\r\n];\r\n\r\nconst LEGACY_CONFIG_FILES: Array<{ file: string; type: ConfigType }> = [\r\n { file: '.eslintrc.js', type: 'eslintrc-js' },\r\n { file: '.eslintrc.cjs', type: 'eslintrc-cjs' },\r\n { file: '.eslintrc.json', type: 'eslintrc-json' },\r\n { file: '.eslintrc.yaml', type: 'eslintrc-yaml' },\r\n { file: '.eslintrc.yml', type: 'eslintrc-yaml' },\r\n];\r\n\r\nconst ALL_CONFIG_FILES = [...FLAT_CONFIG_FILES, ...LEGACY_CONFIG_FILES];\r\n\r\n// ─── Helpers ──────────────────────────────────────────────────────────────────\r\n\r\nexport function isPackageInstalled(pkgName: string, cwd = process.cwd()): boolean {\r\n try {\r\n const pkgPath = path.join(cwd, 'node_modules', pkgName, 'package.json');\r\n if (fs.existsSync(pkgPath)) {\r\n return true;\r\n }\r\n\r\n const req = createRequire(path.join(cwd, 'package.json'));\r\n req.resolve(`${pkgName}/package.json`);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Read a package.json version from node_modules.\r\n * Reads directly from disk — no require() involvement — so it always\r\n * reflects the *installed* version even when running inside a bundled binary.\r\n */\r\nexport function getPackageVersion(pkgName: string, cwd = process.cwd()): string | null {\r\n try {\r\n const pkgPath = path.join(cwd, 'node_modules', pkgName, 'package.json');\r\n const resolvedPath = fs.existsSync(pkgPath)\r\n ? pkgPath\r\n : createRequire(path.join(cwd, 'package.json')).resolve(`${pkgName}/package.json`);\r\n const raw = fs.readFileSync(resolvedPath, 'utf-8');\r\n const json = JSON.parse(raw) as { version?: string };\r\n return json.version ?? null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/** Parse the major version number from a semver string */\r\nexport function parseMajor(version: string | null): number | null {\r\n if (!version) return null;\r\n const n = parseInt(version.split('.')[0], 10);\r\n return isNaN(n) ? null : n;\r\n}\r\n\r\n// ─── Config detection ─────────────────────────────────────────────────────────\r\n\r\nexport function detectConfigType(cwd = process.cwd()): {\r\n type: ConfigType;\r\n path: string | null;\r\n allPaths: string[];\r\n} {\r\n const found: string[] = [];\r\n let first: { type: ConfigType; path: string } | null = null;\r\n\r\n for (const { file, type } of ALL_CONFIG_FILES) {\r\n const fullPath = path.join(cwd, file);\r\n if (fs.existsSync(fullPath)) {\r\n found.push(fullPath);\r\n if (!first) first = { type, path: fullPath };\r\n }\r\n }\r\n\r\n return {\r\n type: first?.type ?? 'none',\r\n path: first?.path ?? null,\r\n allPaths: found,\r\n };\r\n}\r\n\r\nexport function isFlat(type: ConfigType): boolean {\r\n return type === 'flat-js' || type === 'flat-mjs' || type === 'flat-cjs';\r\n}\r\n\r\nexport function isLegacy(type: ConfigType): boolean {\r\n return (\r\n type === 'eslintrc-js' ||\r\n type === 'eslintrc-cjs' ||\r\n type === 'eslintrc-json' ||\r\n type === 'eslintrc-yaml'\r\n );\r\n}\r\n\r\n/**\r\n * Returns true if the given ESLint major version requires flat config.\r\n * ESLint 9+ uses flat config by default; ESLint 8 uses legacy config.\r\n */\r\nexport function requiresFlatConfig(eslintMajor: number | null): boolean {\r\n return eslintMajor !== null && eslintMajor >= 9;\r\n}\r\n\r\n/**\r\n * Check for \"nuke\" ignore patterns — patterns that silently exclude all files.\r\n * Common culprit: ignorePatterns: [\"**\\/*\"] or ignores: [\"**\\/*\"]\r\n */\r\nfunction detectNukeIgnore(configPath: string | null): boolean {\r\n if (!configPath) return false;\r\n try {\r\n const content = fs.readFileSync(configPath, 'utf-8');\r\n return content.includes('\"**/*\"') || content.includes(\"'**/*'\");\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n// ─── Main detection entry point ───────────────────────────────────────────────\r\n\r\nexport function detect(cwd = process.cwd()): DetectionResult {\r\n const eslintVersion = getPackageVersion('eslint', cwd);\r\n const eslintMajor = parseMajor(eslintVersion);\r\n const pluginInstalled = isPackageInstalled('eslint-plugin-ai-guard', cwd);\r\n\r\n const { type: configType, path: configPath, allPaths } = detectConfigType(cwd);\r\n\r\n // Conflict: both flat AND legacy config files exist\r\n const hasFlatConfig = allPaths.some((p) =>\r\n FLAT_CONFIG_FILES.some((c) => p.endsWith(c.file)),\r\n );\r\n const hasLegacyConfig = allPaths.some((p) =>\r\n LEGACY_CONFIG_FILES.some((c) => p.endsWith(c.file)),\r\n );\r\n const hasConflictingConfigs = hasFlatConfig && hasLegacyConfig;\r\n\r\n const hasNukeIgnore = detectNukeIgnore(configPath);\r\n\r\n return {\r\n eslintVersion,\r\n eslintMajor,\r\n pluginInstalled,\r\n configType,\r\n configPath,\r\n allConfigPaths: allPaths,\r\n hasConflictingConfigs,\r\n hasNukeIgnore,\r\n };\r\n}\r\n","import type { Command } from 'commander';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { detect, isFlat, isLegacy, requiresFlatConfig } from '../utils/detector.js';\nimport { log } from '../utils/logger.js';\nimport { readConfig } from '../utils/config-manager.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ninterface CheckResult {\n label: string;\n pass: boolean;\n detail: string;\n /** Exact command or action to fix — shown as cyan */\n fix?: string;\n /** Additional explanation shown below fix as gray */\n note?: string;\n}\n\n// ─── Programmatic config load probe ──────────────────────────────────────────\n\nasync function probeConfigLoad(\n configPath: string,\n cwd: string,\n): Promise<{ ok: boolean; error: string | null }> {\n try {\n const { ESLint } = await import('eslint') as { ESLint: any };\n const eslint = new ESLint({ cwd, overrideConfigFile: configPath });\n await eslint.lintText('', { filePath: path.join(cwd, '_probe_.js') });\n return { ok: true, error: null };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n // \"no files\" or \"probe\" errors are not config errors\n if (\n msg.includes('No files') ||\n msg.includes('no files') ||\n msg.includes('_probe_')\n ) {\n return { ok: true, error: null };\n }\n // Strip stack frames from message\n const clean = msg.replace(/\\s+at\\s+.+/gm, '').trim();\n return { ok: false, error: clean };\n }\n}\n\n// ─── Command ──────────────────────────────────────────────────────────────────\n\nexport function registerDoctorCommand(program: Command): void {\n program\n .command('doctor')\n .description('Diagnose your ai-guard setup and print actionable fixes')\n .action(async () => {\n const cwd = process.cwd();\n\n log.banner('AI GUARD DOCTOR');\n log.info('Checking your environment…');\n log.blank();\n\n const env = detect(cwd);\n const checks: CheckResult[] = [];\n\n // ── Check 1: ESLint installed ──────────────────────────────────────────\n\n checks.push({\n label: 'ESLint installed',\n pass: env.eslintVersion !== null,\n detail: env.eslintVersion\n ? `ESLint ${env.eslintVersion}`\n : 'Not found in node_modules',\n fix: env.eslintVersion\n ? undefined\n : 'npm install --save-dev eslint',\n });\n\n // ── Check 2: Plugin installed ──────────────────────────────────────────\n\n checks.push({\n label: 'eslint-plugin-ai-guard installed',\n pass: env.pluginInstalled,\n detail: env.pluginInstalled\n ? 'Found in node_modules'\n : 'Not found in node_modules',\n fix: env.pluginInstalled\n ? undefined\n : 'npm install --save-dev eslint-plugin-ai-guard',\n });\n\n // ── Check 3: ESLint config exists ─────────────────────────────────────\n\n const hasConfig = env.configType !== 'none';\n checks.push({\n label: 'ESLint config present',\n pass: hasConfig,\n detail: hasConfig\n ? `${path.relative(cwd, env.configPath ?? '')} (${env.configType})`\n : 'No eslint.config.* or .eslintrc.* found',\n fix: hasConfig\n ? undefined\n : 'ai-guard init',\n note: hasConfig\n ? undefined\n : 'This will generate the correct config format for your ESLint version',\n });\n\n // ── Check 4: Config type matches ESLint version ────────────────────────\n\n if (env.eslintMajor !== null && hasConfig) {\n const needsFlat = requiresFlatConfig(env.eslintMajor);\n const actuallyFlat = isFlat(env.configType);\n const actuallyLegacy = isLegacy(env.configType);\n const aligned =\n (needsFlat && actuallyFlat) || (!needsFlat && actuallyLegacy);\n\n checks.push({\n label: 'Config format matches ESLint version',\n pass: aligned,\n detail: aligned\n ? `${actuallyFlat ? 'Flat config' : 'Legacy config'} ✔ matches ESLint v${env.eslintMajor}`\n : `ESLint v${env.eslintMajor} requires ${needsFlat ? 'flat config (eslint.config.*)'\n : 'legacy config (.eslintrc.*)'} but found ${actuallyFlat ? 'flat' : 'legacy'} config`,\n fix: aligned\n ? undefined\n : needsFlat\n ? 'ai-guard init (will create eslint.config.mjs)'\n : 'npm install --save-dev eslint@8 (or upgrade to v9 and run ai-guard init)',\n note: aligned\n ? undefined\n : needsFlat\n ? 'ESLint v9 ignores .eslintrc.* files. The flat config must be used.'\n : undefined,\n });\n }\n\n // ── Check 5: Plugin wired in config ───────────────────────────────────\n\n if (hasConfig && env.configPath) {\n let pluginWired = false;\n let isInvalidConfig = false;\n let readError: string | null = null;\n try {\n const { isInvalidAiGuardConfig } = await import('../utils/config-manager.js');\n const content = readConfig(env.configPath);\n pluginWired =\n content.includes('ai-guard') ||\n content.includes('eslint-plugin-ai-guard');\n isInvalidConfig = isInvalidAiGuardConfig(content);\n } catch (err) {\n readError = err instanceof Error ? err.message : String(err);\n }\n\n checks.push({\n label: 'Plugin wired in config',\n pass: pluginWired && !isInvalidConfig,\n detail: readError\n ? `Could not read config: ${readError}`\n : isInvalidConfig\n ? 'Invalid ai-guard config detected (wrong export usage)'\n : pluginWired\n ? 'eslint-plugin-ai-guard referenced in config'\n : `Config exists but ai-guard plugin not found in ${path.relative(cwd, env.configPath)}`,\n fix: isInvalidConfig || (!pluginWired && !readError)\n ? 'ai-guard init (will patch/repair your existing config)'\n : undefined,\n });\n }\n\n // ── Check 6: No conflicting configs ───────────────────────────────────\n\n checks.push({\n label: 'No conflicting config files',\n pass: !env.hasConflictingConfigs,\n detail: env.hasConflictingConfigs\n ? `Conflicting config detected:\\n${env.allConfigPaths.map((p) => ` ${path.relative(cwd, p)}`).join('\\n')}`\n : 'Only one config format detected',\n fix: env.hasConflictingConfigs\n ? 'Remove or backup legacy config'\n : undefined,\n note: env.hasConflictingConfigs\n ? 'ESLint v9 silently ignores .eslintrc.* when a flat config exists. This can cause confusion.'\n : undefined,\n });\n\n // ── Check 7: No nuke-ignore pattern ───────────────────────────────────\n\n if (hasConfig && env.hasNukeIgnore) {\n checks.push({\n label: 'No \"ignore everything\" pattern',\n pass: false,\n detail: `Config contains \"**/*\" ignore pattern — this silently prevents all files from being linted`,\n fix: 'ai-guard init (will remove the pattern and replace with safe ignores)',\n });\n }\n\n // ── Check 8: ESLint version compatible ────────────────────────────────\n\n const versionOk = env.eslintMajor !== null && env.eslintMajor >= 8;\n checks.push({\n label: 'ESLint version compatible',\n pass: versionOk,\n detail: versionOk\n ? `v${env.eslintMajor} ✔ (requires ≥ v8)`\n : env.eslintMajor !== null\n ? `v${env.eslintMajor} is too old — requires ESLint ≥ 8`\n : 'ESLint not installed',\n fix: versionOk ? undefined : 'npm install --save-dev eslint@latest',\n });\n\n // ── Check 9: Programmatic config load ─────────────────────────────────\n // Only run this if we have a config and all prior config checks passed,\n // so we don't produce redundant errors.\n\n const configChecksPass = checks.every((c) => c.pass);\n if (hasConfig && env.configPath && env.pluginInstalled && configChecksPass) {\n log.info('Probing ESLint config load…');\n const probe = await probeConfigLoad(env.configPath, cwd);\n\n checks.push({\n label: 'ESLint config loads without errors',\n pass: probe.ok,\n detail: probe.ok\n ? 'ESLint loaded config successfully'\n : probe.error ?? 'Unknown error',\n fix: probe.ok\n ? undefined\n : `Check syntax in ${path.relative(cwd, env.configPath)}`,\n note: probe.ok\n ? undefined\n : 'Run: ai-guard init --dry-run to preview a fresh config',\n });\n }\n\n // ─── Render results ────────────────────────────────────────────────────\n\n log.section('Diagnostics');\n\n let allPassed = true;\n for (const check of checks) {\n const icon = check.pass ? chalk.green('✔') : chalk.red('✖');\n const label = check.pass\n ? chalk.white(check.label)\n : chalk.red.bold(check.label);\n\n log.print(` ${icon} ${label}`);\n log.print(` ${chalk.gray(check.detail)}`);\n\n if (!check.pass) {\n allPassed = false;\n if (check.fix) {\n log.print(` ${chalk.cyan('→ Fix:')} ${chalk.yellow(check.fix)}`);\n }\n if (check.note) {\n log.print(` ${chalk.gray(check.note)}`);\n }\n }\n\n log.blank();\n }\n\n log.divider();\n log.blank();\n\n if (allPassed) {\n log.print(` ${chalk.green('✔')} ${chalk.bold.green('All checks passed! Your setup is correct.')}`);\n log.blank();\n log.info(`Run ${chalk.cyan('ai-guard run')} to start scanning.`);\n log.info(`Run ${chalk.cyan('npx eslint .')} to lint with ESLint directly.`);\n } else {\n log.error('Some checks failed. Follow the fixes above.');\n log.blank();\n\n // Smart suggestion — only suggest init if it won't cause an infinite loop\n const configFormatMismatch = checks.some(\n (c) => c.label === 'Config format matches ESLint version' && !c.pass,\n );\n const configMissing = checks.some(\n (c) => c.label === 'ESLint config present' && !c.pass,\n );\n const pluginMissing = checks.some(\n (c) => c.label === 'eslint-plugin-ai-guard installed' && !c.pass,\n );\n\n if (pluginMissing) {\n log.print(\n ` Install missing packages first, then re-run ${chalk.cyan('ai-guard doctor')}.`,\n );\n } else if (configMissing || configFormatMismatch) {\n log.print(\n ` Run ${chalk.cyan('ai-guard init')} to generate the correct config for your ESLint version.`,\n );\n } else {\n log.print(\n ` Run ${chalk.cyan('ai-guard init --dry-run')} to preview what would change.`,\n );\n }\n }\n\n log.blank();\n process.exit(allPassed ? 0 : 1);\n });\n}\n","import type { Command } from 'commander';\r\nimport { select } from '@inquirer/prompts';\r\nimport chalk from 'chalk';\r\nimport { detect, isFlat } from '../utils/detector.js';\r\nimport {\r\n backupConfig,\r\n readConfig,\r\n writeConfig,\r\n patchFlatConfig,\r\n patchLegacyConfig,\r\n switchFlatPreset,\r\n switchLegacyPreset,\r\n generateFlatConfig,\r\n generateLegacyConfig,\r\n type Preset,\r\n} from '../utils/config-manager.js';\r\nimport { log } from '../utils/logger.js';\r\nimport path from 'path';\r\n\r\nexport function registerPresetCommand(program: Command): void {\r\n program\r\n .command('preset')\r\n .description('Interactively select and apply an ai-guard preset to your ESLint config')\r\n .action(async () => {\r\n const cwd = process.cwd();\r\n\r\n log.banner('AI GUARD PRESET');\r\n log.blank();\r\n\r\n const preset = await select<Preset>({\r\n message: 'Choose a preset:',\r\n choices: [\r\n {\r\n name: `${chalk.green('recommended')} — balanced defaults, low noise. Best starting point.`,\r\n value: 'recommended',\r\n },\r\n {\r\n name: `${chalk.yellow('strict')} — all rules at error. For mature codebases.`,\r\n value: 'strict',\r\n },\r\n {\r\n name: `${chalk.red('security')} — security rules only. For AppSec teams.`,\r\n value: 'security',\r\n },\r\n ],\r\n });\r\n\r\n log.blank();\r\n log.info(`Applying preset: ${chalk.cyan(preset)}`);\r\n\r\n const env = detect(cwd);\r\n const useFlat =\r\n (env.eslintMajor !== null && env.eslintMajor >= 9) ||\r\n isFlat(env.configType);\r\n\r\n if (env.configType === 'none') {\r\n // Generate fresh config with chosen preset\r\n const configPath = useFlat\r\n ? path.join(cwd, 'eslint.config.mjs')\r\n : path.join(cwd, '.eslintrc.js');\r\n\r\n const content = useFlat\r\n ? generateFlatConfig(preset)\r\n : generateLegacyConfig(preset);\r\n\r\n writeConfig(configPath, content);\r\n log.success(`Created ${chalk.white(path.relative(cwd, configPath))} with ${chalk.cyan(preset)} preset`);\r\n } else {\r\n const configPath = env.configPath!;\r\n const backupPath = backupConfig(configPath);\r\n log.info(`Backed up → ${chalk.gray(path.relative(cwd, backupPath))}`);\r\n\r\n const existing = readConfig(configPath);\r\n const withPlugin = isFlat(env.configType)\r\n ? patchFlatConfig(existing, preset)\r\n : patchLegacyConfig(existing, preset);\r\n\r\n const patched = isFlat(env.configType)\r\n ? switchFlatPreset(withPlugin, preset)\r\n : switchLegacyPreset(withPlugin, preset);\r\n\r\n if (patched === existing) {\r\n log.warn('No preset changes needed. Config already matches selected preset.');\r\n } else {\r\n writeConfig(configPath, patched);\r\n log.success(`Updated ${chalk.white(path.relative(cwd, configPath))} to ${chalk.cyan(preset)} preset`);\r\n }\r\n }\r\n\r\n log.blank();\r\n log.section('Preset Details');\r\n\r\n const presetDetails: Record<Preset, Array<{ rule: string; level: string }>> = {\r\n recommended: [\r\n { rule: 'no-empty-catch', level: chalk.red('error') },\r\n { rule: 'no-floating-promise', level: chalk.red('error') },\r\n { rule: 'no-hardcoded-secret', level: chalk.red('error') },\r\n { rule: 'no-eval-dynamic', level: chalk.red('error') },\r\n { rule: 'no-broad-exception', level: chalk.yellow('warn') },\r\n { rule: 'no-async-array-callback', level: chalk.yellow('warn') },\r\n { rule: 'no-await-in-loop', level: chalk.yellow('warn') },\r\n { rule: '+ 5 more…', level: chalk.gray('warn') },\r\n ],\r\n strict: [\r\n { rule: 'All 17 rules', level: chalk.red('error') },\r\n ],\r\n security: [\r\n { rule: 'no-hardcoded-secret', level: chalk.red('error') },\r\n { rule: 'no-eval-dynamic', level: chalk.red('error') },\r\n { rule: 'no-sql-string-concat', level: chalk.red('error') },\r\n { rule: 'no-unsafe-deserialize', level: chalk.yellow('warn') },\r\n { rule: 'require-auth-middleware', level: chalk.yellow('warn') },\r\n { rule: 'require-authz-check', level: chalk.yellow('warn') },\r\n ],\r\n };\r\n\r\n for (const { rule, level } of presetDetails[preset]) {\r\n log.print(` ${chalk.gray('•')} ${chalk.white(rule).padEnd(32)}${level}`);\r\n }\r\n\r\n log.blank();\r\n log.info(`Run ${chalk.cyan('ai-guard run')} to see results with the new preset.`);\r\n log.blank();\r\n });\r\n}\r\n","import type { Command } from 'commander';\nimport chalk from 'chalk';\nimport { detect, isFlat } from '../utils/detector.js';\nimport {\n backupConfig,\n readConfig,\n writeConfig,\n addIgnoresToFlatConfig,\n addIgnoresToLegacyConfig,\n generateFlatConfig,\n generateLegacyConfig,\n} from '../utils/config-manager.js';\nimport { log } from '../utils/logger.js';\nimport path from 'path';\n\nconst DEFAULT_IGNORES = [\n '.next/',\n 'dist/',\n 'build/',\n 'coverage/',\n 'out/',\n 'node_modules/',\n];\n\nexport function registerIgnoreCommand(program: Command): void {\n program\n .command('ignore')\n .description('Add default ignore patterns (.next, dist, build, coverage) to ESLint config')\n .action(() => {\n const cwd = process.cwd();\n\n log.banner('AI GUARD IGNORE');\n log.blank();\n log.section('Default Ignores');\n\n for (const p of DEFAULT_IGNORES) {\n log.print(` ${chalk.gray('•')} ${chalk.yellow(p)}`);\n }\n\n log.blank();\n\n const env = detect(cwd);\n\n if (env.configType === 'none') {\n // Generate a fresh minimal config with ignores\n const useFlat = env.eslintMajor !== null && env.eslintMajor >= 9;\n const configPath = useFlat\n ? path.join(cwd, 'eslint.config.mjs')\n : path.join(cwd, '.eslintrc.js');\n\n const content = useFlat\n ? generateFlatConfig('recommended')\n : generateLegacyConfig('recommended');\n\n writeConfig(configPath, content);\n log.success(`No config found — generated ${chalk.white(path.relative(cwd, configPath))} with ignores included`);\n } else {\n const configPath = env.configPath!;\n const backupPath = backupConfig(configPath);\n log.info(`Backed up → ${chalk.gray(path.relative(cwd, backupPath))}`);\n\n const existing = readConfig(configPath);\n const patched = isFlat(env.configType)\n ? addIgnoresToFlatConfig(existing)\n : addIgnoresToLegacyConfig(existing);\n\n if (patched === existing) {\n log.warn('Ignore patterns already present in config — no changes made.');\n } else {\n writeConfig(configPath, patched);\n log.success(`Patched ${chalk.white(path.relative(cwd, configPath))} with ignore patterns`);\n }\n }\n\n log.blank();\n log.info('Noisy directories will now be skipped in all future ESLint runs.');\n log.info(`Run ${chalk.cyan('ai-guard run')} to verify cleaner results.`);\n log.blank();\n });\n}\n","import type { Command } from 'commander';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport chalk from 'chalk';\r\nimport ora from 'ora';\r\nimport { runEslint, type Preset, type RunResult } from '../utils/eslint-runner.js';\r\nimport { log } from '../utils/logger.js';\r\n\r\nconst BASELINE_FILE = '.ai-guard-baseline.json';\r\n\r\n// ─── Baseline format ──────────────────────────────────────────────────────────\r\n\r\ninterface BaselineIssue {\r\n ruleId: string;\r\n message: string;\r\n line: number;\r\n column: number;\r\n}\r\n\r\ntype BaselineMode = 'strict' | 'stable';\r\n\r\ninterface BaselineEntry {\r\n filePath: string;\r\n issues: BaselineIssue[];\r\n}\r\n\r\ninterface BaselineFile {\r\n createdAt: string;\r\n preset: Preset;\r\n mode: BaselineMode;\r\n totalIssues: number;\r\n entries: BaselineEntry[];\r\n}\r\n\r\n// ─── Helpers ──────────────────────────────────────────────────────────────────\r\n\r\nfunction saveBaseline(\r\n result: RunResult,\r\n preset: Preset,\r\n mode: BaselineMode,\r\n cwd: string,\r\n): string {\r\n const entries: BaselineEntry[] = result.files.map((f) => ({\r\n filePath: f.filePath,\r\n issues: f.issues.map((i) => ({\r\n ruleId: i.ruleId,\r\n message: i.message,\r\n line: i.line,\r\n column: i.column,\r\n })),\r\n }));\r\n\r\n const baseline: BaselineFile = {\r\n createdAt: new Date().toISOString(),\r\n preset,\r\n mode,\r\n totalIssues: result.totalIssues,\r\n entries,\r\n };\r\n\r\n const baselinePath = path.join(cwd, BASELINE_FILE);\r\n fs.writeFileSync(baselinePath, JSON.stringify(baseline, null, 2), 'utf-8');\r\n return baselinePath;\r\n}\r\n\r\nfunction loadBaseline(cwd: string): BaselineFile | null {\r\n const baselinePath = path.join(cwd, BASELINE_FILE);\r\n if (!fs.existsSync(baselinePath)) return null;\r\n try {\r\n const raw = fs.readFileSync(baselinePath, 'utf-8');\r\n return JSON.parse(raw) as BaselineFile;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\ntype IssueKey = string;\r\n\r\nfunction issueKey(filePath: string, issue: BaselineIssue): IssueKey {\r\n return `${filePath}::${issue.ruleId}::${issue.line}::${issue.column}::${issue.message}`;\r\n}\r\n\r\nfunction stableIssueKey(filePath: string, issue: BaselineIssue): IssueKey {\r\n return `${filePath}::${issue.ruleId}::${issue.message}`;\r\n}\r\n\r\nfunction buildBaselineSet(baseline: BaselineFile, mode: BaselineMode): Set<IssueKey> {\r\n const toKey = mode === 'stable' ? stableIssueKey : issueKey;\r\n const set = new Set<IssueKey>();\r\n for (const entry of baseline.entries) {\r\n for (const issue of entry.issues) {\r\n set.add(toKey(entry.filePath, issue));\r\n }\r\n }\r\n return set;\r\n}\r\n\r\nfunction computeNewIssues(\r\n result: RunResult,\r\n baselineSet: Set<IssueKey>,\r\n mode: BaselineMode,\r\n): RunResult {\r\n const toKey = mode === 'stable' ? stableIssueKey : issueKey;\r\n const newFiles: RunResult['files'] = [];\r\n let totalErrors = 0;\r\n let totalWarnings = 0;\r\n const ruleBreakdown = new Map<string, number>();\r\n\r\n for (const file of result.files) {\r\n const newIssues = file.issues.filter(\r\n (i) => !baselineSet.has(toKey(file.filePath, i)),\r\n );\r\n if (newIssues.length === 0) continue;\r\n\r\n const errorCount = newIssues.filter((i) => i.severity === 2).length;\r\n const warningCount = newIssues.filter((i) => i.severity === 1).length;\r\n totalErrors += errorCount;\r\n totalWarnings += warningCount;\r\n\r\n for (const issue of newIssues) {\r\n ruleBreakdown.set(\r\n issue.ruleId,\r\n (ruleBreakdown.get(issue.ruleId) ?? 0) + 1,\r\n );\r\n }\r\n\r\n newFiles.push({ ...file, issues: newIssues, errorCount, warningCount });\r\n }\r\n\r\n const topFiles = [...newFiles]\r\n .sort((a, b) => b.issues.length - a.issues.length)\r\n .slice(0, 10)\r\n .map((f) => ({ path: f.filePath, count: f.issues.length }));\r\n\r\n return {\r\n files: newFiles,\r\n totalErrors,\r\n totalWarnings,\r\n totalIssues: totalErrors + totalWarnings,\r\n ruleBreakdown,\r\n topFiles,\r\n durationMs: result.durationMs,\r\n };\r\n}\r\n\r\n// ─── Command ──────────────────────────────────────────────────────────────────\r\n\r\nexport function registerBaselineCommand(program: Command): void {\r\n program\r\n .command('baseline')\r\n .description('Save current issues as baseline; future runs show only new issues')\r\n .option('--save', 'Save current state as the new baseline')\r\n .option('--check', 'Show only issues introduced since the last baseline')\r\n .option('--mode <name>', 'Baseline match mode: strict | stable', 'stable')\r\n .option('--path <dir>', 'Directory to scan', '.')\r\n .option('--preset <name>', 'Preset: recommended | strict | security', 'recommended')\r\n .action(async (opts: {\r\n save?: boolean;\r\n check?: boolean;\r\n mode?: string;\r\n path: string;\r\n preset: string;\r\n }) => {\r\n const cwd = process.cwd();\r\n const preset = (opts.preset as Preset) ?? 'recommended';\r\n const mode = (opts.mode as BaselineMode) ?? 'stable';\r\n\r\n if (mode !== 'strict' && mode !== 'stable') {\r\n log.error('Invalid --mode. Use strict or stable.');\r\n process.exit(1);\r\n }\r\n\r\n log.banner('AI GUARD BASELINE');\r\n log.blank();\r\n\r\n // If neither flag provided, default to --save if no baseline exists, else --check\r\n const existingBaseline = loadBaseline(cwd);\r\n const doSave = opts.save ?? (!existingBaseline && !opts.check);\r\n const doCheck = opts.check ?? (existingBaseline !== null && !opts.save);\r\n\r\n if (doSave) {\r\n log.info('Scanning project to save baseline…');\r\n const spinner = ora({ text: 'Running analysis…', color: 'cyan' }).start();\r\n\r\n let result: RunResult | undefined;\r\n try {\r\n result = await runEslint({ preset, targetPath: opts.path });\r\n spinner.stop();\r\n } catch (err: unknown) {\r\n spinner.stop();\r\n log.error(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n\r\n const baselinePath = saveBaseline(result!, preset, mode, cwd);\r\n log.success(\r\n `Baseline saved → ${chalk.white(path.relative(cwd, baselinePath))}`,\r\n );\r\n log.info(` ${result!.totalIssues} issues recorded (${result!.totalErrors} errors, ${result!.totalWarnings} warnings)`);\r\n log.info(` Preset: ${chalk.cyan(preset)}`);\r\n log.info(` Mode: ${chalk.cyan(mode)}`);\r\n log.blank();\r\n log.info('Future runs of ' + chalk.cyan('ai-guard baseline --check') + ' will show only NEW issues.');\r\n log.info('Add ' + chalk.white(BASELINE_FILE) + ' to your git repository to share baseline with your team.');\r\n log.blank();\r\n return;\r\n }\r\n\r\n if (doCheck) {\r\n if (!existingBaseline) {\r\n log.error(`No baseline found at ${chalk.white(BASELINE_FILE)}`);\r\n log.info(`Run ${chalk.cyan('ai-guard baseline --save')} first to create one.`);\r\n process.exit(1);\r\n }\r\n\r\n const baselineDate = new Date(existingBaseline.createdAt).toLocaleString();\r\n log.info(`Baseline from: ${chalk.gray(baselineDate)}`);\r\n log.info(`Baseline preset: ${chalk.cyan(existingBaseline.preset)}`);\r\n log.info(`Baseline mode: ${chalk.cyan(existingBaseline.mode ?? 'strict')}`);\r\n log.info(`Baseline issues: ${chalk.gray(existingBaseline.totalIssues)}`);\r\n log.blank();\r\n\r\n const spinner = ora({ text: 'Scanning for new issues…', color: 'cyan' }).start();\r\n\r\n let result: RunResult | undefined;\r\n try {\r\n result = await runEslint({ preset, targetPath: opts.path });\r\n spinner.stop();\r\n } catch (err: unknown) {\r\n spinner.stop();\r\n log.error(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n\r\n const compareMode = existingBaseline.mode ?? 'strict';\r\n const baselineSet = buildBaselineSet(existingBaseline!, compareMode);\r\n const newResult = computeNewIssues(result!, baselineSet, compareMode);\r\n\r\n if (newResult.totalIssues === 0) {\r\n log.success('No new issues since baseline! ✨');\r\n log.info(\r\n `Total in codebase: ${result!.totalIssues} (all existing, none new)`,\r\n );\r\n log.blank();\r\n process.exit(0);\r\n return;\r\n }\r\n\r\n log.print(\r\n chalk.bold.red(` ✖ ${newResult.totalIssues} new issue${newResult.totalIssues !== 1 ? 's' : ''} since baseline`),\r\n );\r\n log.blank();\r\n\r\n // By rule breakdown\r\n if (newResult.ruleBreakdown.size > 0) {\r\n log.section('New Issues by Rule');\r\n for (const [rule, count] of [...newResult.ruleBreakdown.entries()].sort(\r\n (a, b) => b[1] - a[1],\r\n )) {\r\n log.rule(rule, count);\r\n }\r\n }\r\n\r\n // Per-file breakdown\r\n if (newResult.files.length > 0) {\r\n log.section('New Issues by File');\r\n log.blank();\r\n for (const file of newResult.files) {\r\n log.print(\r\n ` ${chalk.bold.white(file.filePath)} ` +\r\n chalk.gray(`(${file.issues.length} new)`),\r\n );\r\n for (const issue of file.issues) {\r\n log.issue(issue.message, issue.severity, issue.line, issue.column);\r\n }\r\n }\r\n }\r\n\r\n log.blank();\r\n log.divider();\r\n log.blank();\r\n log.error(\r\n `${newResult.totalIssues} new issue${newResult.totalIssues !== 1 ? 's' : ''} introduced since baseline.`,\r\n );\r\n log.info(`Run ${chalk.cyan('ai-guard baseline --save')} to update the baseline after fixing them.`);\r\n log.blank();\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import type { Command } from 'commander';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport chalk from 'chalk';\r\nimport { checkbox, confirm } from '@inquirer/prompts';\r\nimport { log } from '../utils/logger.js';\r\n\r\n// ─── Types ────────────────────────────────────────────────────────────────────\r\n\r\ntype AgentId = 'claude' | 'cursor' | 'copilot';\r\n\r\ntype RuleCategory = 'async' | 'security' | 'error-handling' | 'quality';\r\n\r\ninterface AgentTarget {\r\n id: AgentId;\r\n label: string;\r\n filePath: string;\r\n generate: (version: string, categories: RuleCategory[]) => string;\r\n}\r\n\r\n// ─── Rule Category Mapping ────────────────────────────────────────────────────\r\n\r\nconst RULE_CATEGORIES: Record<RuleCategory, string[]> = {\r\n 'error-handling': [\r\n 'no-empty-catch',\r\n 'no-broad-exception',\r\n 'no-catch-log-rethrow',\r\n 'no-catch-without-use',\r\n ],\r\n async: [\r\n 'no-async-array-callback',\r\n 'no-floating-promise',\r\n 'no-await-in-loop',\r\n 'no-async-without-await',\r\n 'no-redundant-await',\r\n ],\r\n security: [\r\n 'no-hardcoded-secret',\r\n 'no-eval-dynamic',\r\n 'no-sql-string-concat',\r\n 'no-unsafe-deserialize',\r\n 'require-auth-middleware',\r\n 'require-authz-check',\r\n ],\r\n quality: [\r\n 'no-console-in-handler',\r\n 'no-duplicate-logic-block',\r\n ],\r\n};\r\n\r\nconst ALL_CATEGORIES: RuleCategory[] = ['error-handling', 'async', 'security', 'quality'];\r\n\r\n// ─── Template Sections ────────────────────────────────────────────────────────\r\n\r\nfunction errorHandlingSection(): string {\r\n return `## Error Handling\r\n**Never** generate empty catch blocks:\r\n ❌ try { await fetchUser() } catch (e) {}\r\n ✅ try { await fetchUser() } catch (e) { logger.error(e); throw e; }\r\n\r\n**Never** catch (e: any) — use specific types or narrow with instanceof.\r\n\r\n**Never** catch, log, and immediately rethrow without adding context:\r\n ❌ catch (e) { console.error(e); throw e; }\r\n ✅ catch (e) { throw new Error('fetchUser failed', { cause: e }); }`;\r\n}\r\n\r\nfunction asyncSection(): string {\r\n return `## Async Correctness\r\n**Never** pass async callbacks to array.map(), filter(), forEach(), or reduce():\r\n ❌ const results = ids.map(async (id) => await fetchUser(id));\r\n ✅ const results = await Promise.all(ids.map((id) => fetchUser(id)));\r\n\r\n**Never** use await inside a for...of or while loop when parallel execution\r\nis possible:\r\n ❌ for (const id of ids) { const user = await fetchUser(id); }\r\n ✅ const users = await Promise.all(ids.map(fetchUser));\r\n\r\n**Never** call an async function without await or .catch():\r\n ❌ sendEmail(user);\r\n ✅ await sendEmail(user);\r\n\r\n**Never** declare a function async if it never uses await.`;\r\n}\r\n\r\nfunction securitySection(): string {\r\n return `## Security\r\n**Never** hardcode secrets, API keys, tokens, or passwords inline:\r\n ❌ const apiKey = 'sk-prod-abc123';\r\n ✅ const apiKey = process.env.API_KEY;\r\n\r\n**Never** concatenate user input into SQL strings:\r\n ❌ db.query('SELECT * FROM users WHERE id = ' + req.params.id);\r\n ✅ db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);\r\n\r\n**Never** use eval() or new Function() with dynamic/user-supplied strings.\r\n\r\n**Never** call JSON.parse() on req.body, req.query, or req.params directly\r\nwithout schema validation.\r\n\r\n**Always** add authentication middleware before route handlers:\r\n ❌ router.get('/admin/users', getUsers);\r\n ✅ router.get('/admin/users', requireAuth, getUsers);\r\n\r\n**Always** verify that the authenticated user owns or has access to the\r\nresource being accessed when using req.params.id or similar identifiers.`;\r\n}\r\n\r\nfunction qualitySection(): string {\r\n return `## Code Quality\r\n**Never** leave console.log or console.debug statements inside HTTP route\r\nhandlers or event listeners in production code.\r\n\r\n**Never** copy-paste the same logic block consecutively — extract shared\r\nlogic into a helper function or consolidate duplicated code.`;\r\n}\r\n\r\ntype SectionFn = () => string;\r\nconst SECTION_MAP: Record<RuleCategory, SectionFn> = {\r\n 'error-handling': errorHandlingSection,\r\n async: asyncSection,\r\n security: securitySection,\r\n quality: qualitySection,\r\n};\r\n\r\nfunction getSections(categories: RuleCategory[]): string {\r\n return categories.map((cat) => SECTION_MAP[cat]()).join('\\n\\n');\r\n}\r\n\r\nfunction workflowGuidanceMarkdown(): string {\r\n return `## Workflow Guardrails\r\n- Follow user and repository instructions first; apply these rules on top.\r\n- Reuse existing project patterns and libraries before introducing new abstractions.\r\n- If a rule must be bypassed intentionally, add a suppression comment with reason:\r\n \\`ai-guard-disable <rule-name> -- reason: <why>\\`.\r\n- Before finalizing changes, run tests/lint and \\`ai-guard run\\` when available.`;\r\n}\r\n\r\nfunction workflowGuidanceCursor(): string {\r\n return `## Workflow Guardrails\r\n\r\n- Follow user and repository instructions first.\r\n- Prefer existing project patterns and dependencies.\r\n- If bypassing a rule intentionally, add: ai-guard-disable <rule-name> -- reason: <why>.\r\n- Validate generated code with tests/lint and ai-guard run when available.`;\r\n}\r\n\r\nfunction workflowGuidanceCopilot(): string {\r\n return `## Required Workflow\r\n\r\n- Follow user and repository instructions first.\r\n- Prefer edits that match existing architecture and dependencies.\r\n- If intentionally violating an ai-guard rule, add an inline suppression with a reason.\r\n- Run tests/lint and \\`ai-guard run\\` before finalizing changes when possible.`;\r\n}\r\n\r\n// ─── CLAUDE.md Template ───────────────────────────────────────────────────────\r\n\r\nfunction generateClaudeFile(version: string, categories: RuleCategory[]): string {\r\n return `<!-- DO NOT EDIT MANUALLY — generated by eslint-plugin-ai-guard -->\r\n<!-- Regenerate: npx ai-guard init-context --force -->\r\n\r\n# AI Guard Rules — Claude Code Instructions\r\n\r\nYou are coding in a project that uses eslint-plugin-ai-guard.\r\nAvoid generating the following patterns. They will be flagged as lint errors.\r\n\r\n${workflowGuidanceMarkdown()}\r\n\r\n${getSections(categories)}\r\n\r\n---\r\nGenerated by eslint-plugin-ai-guard v${version}.\r\nRun \\`npx ai-guard init-context --force\\` to regenerate.\r\n`;\r\n}\r\n\r\n// ─── .cursorrules Template ────────────────────────────────────────────────────\r\n\r\nfunction cursorErrorHandling(): string {\r\n return `## Error Handling\r\n\r\nRule: no-empty-catch\r\nBad: try { await fetchUser() } catch (e) {}\r\nGood: try { await fetchUser() } catch (e) { logger.error(e); throw e; }\r\n\r\nRule: no-broad-exception\r\nBad: catch (e: any) { handle(e); }\r\nGood: catch (e) { if (e instanceof NetworkError) { retry(); } throw e; }\r\n\r\nRule: no-catch-log-rethrow\r\nBad: catch (e) { console.error(e); throw e; }\r\nGood: catch (e) { throw new Error('fetchUser failed', { cause: e }); }`;\r\n}\r\n\r\nfunction cursorAsyncSection(): string {\r\n return `## Async Correctness\r\n\r\nRule: no-async-array-callback\r\nBad: const results = ids.map(async (id) => await fetchUser(id));\r\nGood: const results = await Promise.all(ids.map((id) => fetchUser(id)));\r\n\r\nRule: no-await-in-loop\r\nBad: for (const id of ids) { const user = await fetchUser(id); }\r\nGood: const users = await Promise.all(ids.map(fetchUser));\r\n\r\nRule: no-floating-promise\r\nBad: sendEmail(user);\r\nGood: await sendEmail(user);\r\n\r\nRule: no-async-without-await\r\nBad: async function getUser() { return db.findOne(id); }\r\nGood: function getUser() { return db.findOne(id); }`;\r\n}\r\n\r\nfunction cursorSecuritySection(): string {\r\n return `## Security\r\n\r\nRule: no-hardcoded-secret\r\nBad: const apiKey = 'sk-prod-abc123';\r\nGood: const apiKey = process.env.API_KEY;\r\n\r\nRule: no-sql-string-concat\r\nBad: db.query('SELECT * FROM users WHERE id = ' + req.params.id);\r\nGood: db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);\r\n\r\nRule: no-eval-dynamic\r\nBad: eval(userInput);\r\nGood: Use a safe parser or allowlist approach instead.\r\n\r\nRule: no-unsafe-deserialize\r\nBad: const data = JSON.parse(req.body);\r\nGood: const data = schema.parse(req.body);\r\n\r\nRule: require-auth-middleware\r\nBad: router.get('/admin/users', getUsers);\r\nGood: router.get('/admin/users', requireAuth, getUsers);\r\n\r\nRule: require-authz-check\r\nBad: const user = await db.findById(req.params.id); res.json(user);\r\nGood: const user = await db.findById(req.params.id); if (user.ownerId !== req.user.id) throw new ForbiddenError(); res.json(user);`;\r\n}\r\n\r\nfunction cursorQualitySection(): string {\r\n return `## Code Quality\r\n\r\nRule: no-console-in-handler\r\nBad: router.get('/users', (req, res) => { console.log('hit'); ... });\r\nGood: router.get('/users', (req, res) => { logger.info('hit'); ... });\r\n\r\nRule: no-duplicate-logic-block\r\nBad: Two identical consecutive code blocks copy-pasted.\r\nGood: Extract the duplicated logic into a shared helper function.`;\r\n}\r\n\r\nconst CURSOR_SECTION_MAP: Record<RuleCategory, () => string> = {\r\n 'error-handling': cursorErrorHandling,\r\n async: cursorAsyncSection,\r\n security: cursorSecuritySection,\r\n quality: cursorQualitySection,\r\n};\r\n\r\nfunction generateCursorFile(version: string, categories: RuleCategory[]): string {\r\n const sections = categories.map((cat) => CURSOR_SECTION_MAP[cat]()).join('\\n\\n');\r\n\r\n return `# AI Guard Rules — Cursor Instructions\r\n# DO NOT EDIT MANUALLY — generated by eslint-plugin-ai-guard\r\n# Regenerate: npx ai-guard init-context --force\r\n\r\nThis project uses eslint-plugin-ai-guard to catch the 17 most common\r\nanti-patterns generated by AI coding tools. Follow these rules when\r\ngenerating or editing code in this project. Violations will be flagged\r\nas lint errors.\r\n\r\n${workflowGuidanceCursor()}\r\n\r\n${sections}\r\n\r\n---\r\nThese rules mirror eslint-plugin-ai-guard v${version}.\r\nRun \\`npx ai-guard init-context --force\\` to regenerate.\r\n`;\r\n}\r\n\r\n// ─── .github/copilot-instructions.md Template ─────────────────────────────────\r\n\r\nfunction copilotQuickRef(categories: RuleCategory[]): string {\r\n const lines: string[] = [];\r\n\r\n if (categories.includes('error-handling')) {\r\n lines.push(\r\n 'Never: generate empty catch blocks',\r\n 'Never: catch (e: any) without narrowing',\r\n 'Never: catch, log, and rethrow without adding context',\r\n );\r\n }\r\n if (categories.includes('async')) {\r\n lines.push(\r\n 'Never: pass async callbacks to .map(), .filter(), .forEach()',\r\n 'Never: use await inside loops when Promise.all() works',\r\n 'Never: call async functions without await or .catch()',\r\n 'Never: mark functions async if they never await',\r\n );\r\n }\r\n if (categories.includes('security')) {\r\n lines.push(\r\n 'Never: hardcode API keys, secrets, or passwords',\r\n 'Never: concatenate user input into SQL strings',\r\n 'Never: use eval() or new Function() with dynamic input',\r\n 'Never: JSON.parse() untrusted input without validation',\r\n 'Always: add auth middleware before route handlers',\r\n 'Always: verify resource ownership in handlers',\r\n );\r\n }\r\n if (categories.includes('quality')) {\r\n lines.push(\r\n 'Never: leave console.log in route handlers',\r\n 'Never: copy-paste identical consecutive code blocks',\r\n );\r\n }\r\n\r\n return lines.map((l) => `- ${l}`).join('\\n');\r\n}\r\n\r\nfunction copilotDetails(categories: RuleCategory[]): string {\r\n const details: string[] = [];\r\n\r\n if (categories.includes('async')) {\r\n details.push(`### no-floating-promise\r\n\\`\\`\\`typescript\r\n// ❌ Bad — promise rejected silently\r\nsendEmail(user);\r\n\r\n// ✅ Good\r\nawait sendEmail(user);\r\n\\`\\`\\``);\r\n\r\n details.push(`### no-async-array-callback\r\n\\`\\`\\`typescript\r\n// ❌ Bad — returns Promise[], not values\r\nids.map(async (id) => await fetchUser(id));\r\n\r\n// ✅ Good\r\nawait Promise.all(ids.map((id) => fetchUser(id)));\r\n\\`\\`\\``);\r\n }\r\n\r\n if (categories.includes('error-handling')) {\r\n details.push(`### no-empty-catch\r\n\\`\\`\\`typescript\r\n// ❌ Bad — error swallowed silently\r\ntry { await fetchUser() } catch (e) {}\r\n\r\n// ✅ Good\r\ntry { await fetchUser() } catch (e) { logger.error(e); throw e; }\r\n\\`\\`\\``);\r\n }\r\n\r\n if (categories.includes('security')) {\r\n details.push(`### no-hardcoded-secret\r\n\\`\\`\\`typescript\r\n// ❌ Bad\r\nconst apiKey = 'sk-prod-abc123';\r\n\r\n// ✅ Good\r\nconst apiKey = process.env.API_KEY;\r\n\\`\\`\\``);\r\n\r\n details.push(`### no-sql-string-concat\r\n\\`\\`\\`typescript\r\n// ❌ Bad — SQL injection\r\ndb.query('SELECT * FROM users WHERE id = ' + req.params.id);\r\n\r\n// ✅ Good\r\ndb.query('SELECT * FROM users WHERE id = $1', [req.params.id]);\r\n\\`\\`\\``);\r\n }\r\n\r\n return details.join('\\n\\n');\r\n}\r\n\r\nfunction generateCopilotFile(version: string, categories: RuleCategory[]): string {\r\n return `<!-- DO NOT EDIT MANUALLY — generated by eslint-plugin-ai-guard -->\r\n<!-- Regenerate: npx ai-guard init-context --force -->\r\n\r\n# AI Guard — GitHub Copilot Instructions\r\n\r\nThis project uses \\`eslint-plugin-ai-guard\\`. Follow these rules to avoid\r\ngenerating patterns that will be flagged as lint errors.\r\n\r\n${workflowGuidanceCopilot()}\r\n\r\n## Quick Reference\r\n\r\n${copilotQuickRef(categories)}\r\n\r\n## Details\r\n\r\n${copilotDetails(categories)}\r\n\r\n---\r\nGenerated by eslint-plugin-ai-guard v${version}.\r\nRun \\`npx ai-guard init-context --force\\` to regenerate.\r\n`;\r\n}\r\n\r\n// ─── Agent Definitions ────────────────────────────────────────────────────────\r\n\r\nconst AGENTS: AgentTarget[] = [\r\n {\r\n id: 'claude',\r\n label: 'Claude Code',\r\n filePath: 'CLAUDE.md',\r\n generate: generateClaudeFile,\r\n },\r\n {\r\n id: 'cursor',\r\n label: 'Cursor',\r\n filePath: '.cursorrules',\r\n generate: generateCursorFile,\r\n },\r\n {\r\n id: 'copilot',\r\n label: 'GitHub Copilot',\r\n filePath: path.join('.github', 'copilot-instructions.md'),\r\n generate: generateCopilotFile,\r\n },\r\n];\r\n\r\n// ─── Helpers ──────────────────────────────────────────────────────────────────\r\n\r\nfunction getPackageVersion(cwd: string): string {\r\n try {\r\n const pkgPath = path.join(cwd, 'node_modules', 'eslint-plugin-ai-guard', 'package.json');\r\n if (fs.existsSync(pkgPath)) {\r\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { version?: string };\r\n if (pkg.version) return pkg.version;\r\n }\r\n } catch { /* fall through */ }\r\n\r\n try {\r\n const pkgPath = path.join(cwd, 'package.json');\r\n if (fs.existsSync(pkgPath)) {\r\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { version?: string };\r\n if (pkg.version) return pkg.version;\r\n }\r\n } catch { /* fall through */ }\r\n\r\n return '0.0.0';\r\n}\r\n\r\nfunction parseCategories(raw: string | undefined): RuleCategory[] {\r\n if (!raw) return ALL_CATEGORIES;\r\n const parts = raw.split(',').map((s) => s.trim().toLowerCase());\r\n const valid: RuleCategory[] = [];\r\n for (const part of parts) {\r\n if (part in RULE_CATEGORIES) {\r\n valid.push(part as RuleCategory);\r\n }\r\n }\r\n return valid.length > 0 ? valid : ALL_CATEGORIES;\r\n}\r\n\r\nfunction normalizeSelectedAgents(raw: unknown): string[] {\r\n if (Array.isArray(raw)) {\r\n return raw.filter((value): value is string => typeof value === 'string');\r\n }\r\n\r\n if (typeof raw === 'string') {\r\n return [raw];\r\n }\r\n\r\n return [];\r\n}\r\n\r\n// ─── Exported for tests ───────────────────────────────────────────────────────\r\n\r\nexport {\r\n generateClaudeFile,\r\n generateCursorFile,\r\n generateCopilotFile,\r\n parseCategories,\r\n normalizeSelectedAgents,\r\n AGENTS,\r\n ALL_CATEGORIES,\r\n};\r\nexport type { AgentTarget, RuleCategory };\r\n\r\n// ─── Command Registration ────────────────────────────────────────────────────\r\n\r\nexport function registerInitContextCommand(program: Command): void {\r\n program\r\n .command('init-context')\r\n .description(\r\n 'Generate AI agent instruction files (CLAUDE.md, .cursorrules, copilot-instructions.md)\\n' +\r\n 'so Claude Code, Cursor, and GitHub Copilot avoid the 17 most common AI anti-patterns.',\r\n )\r\n .option('-a, --all', 'Generate files for all agents (skip prompt)')\r\n .option('--force', 'Overwrite existing files without asking')\r\n .option('--dry-run', 'Print what would be generated without writing files')\r\n .option('--rules <categories>', 'Comma-separated categories: async,security,error-handling,quality')\r\n .action(async (opts: {\r\n all?: boolean;\r\n force?: boolean;\r\n dryRun?: boolean;\r\n rules?: string;\r\n }) => {\r\n const cwd = process.cwd();\r\n const version = getPackageVersion(cwd);\r\n const categories = parseCategories(opts.rules);\r\n const isDryRun = opts.dryRun === true;\r\n const isForce = opts.force === true;\r\n\r\n log.banner('AI GUARD INIT-CONTEXT');\r\n\r\n if (isDryRun) {\r\n log.print(` ${chalk.yellow('⚑ DRY RUN — no files will be written')}`);\r\n log.blank();\r\n }\r\n\r\n // ── Select agents ──────────────────────────────────────────────────────\r\n\r\n let selectedAgents: AgentTarget[];\r\n\r\n if (opts.all) {\r\n selectedAgents = [...AGENTS];\r\n } else {\r\n let selected: string[];\r\n try {\r\n selected = await checkbox({\r\n message: 'Which AI agents do you use?',\r\n choices: [\r\n { name: 'Claude Code -> writes CLAUDE.md', value: 'claude' },\r\n { name: 'Cursor -> writes .cursorrules', value: 'cursor' },\r\n { name: 'GitHub Copilot -> writes .github/copilot-instructions.md', value: 'copilot' },\r\n { name: 'All three (recommended) -> writes all files', value: 'all' },\r\n ],\r\n required: true,\r\n });\r\n } catch {\r\n log.info('Selection cancelled. Nothing to do.');\r\n return;\r\n }\r\n\r\n if (selected.length === 0) {\r\n log.info('No valid agents selected. Use --all to generate all files.');\r\n return;\r\n }\r\n\r\n if (selected.includes('all')) {\r\n selectedAgents = [...AGENTS];\r\n } else {\r\n selectedAgents = AGENTS.filter((a) => selected.includes(a.id));\r\n }\r\n }\r\n\r\n log.info(`Categories: ${chalk.cyan(categories.join(', '))}`);\r\n log.info(`Version: ${chalk.cyan(version)}`);\r\n log.blank();\r\n\r\n // ── Generate files ─────────────────────────────────────────────────────\r\n\r\n const results: { file: string; status: 'created' | 'skipped' | 'dry-run' }[] = [];\r\n\r\n for (const agent of selectedAgents) {\r\n const fullPath = path.join(cwd, agent.filePath);\r\n const exists = fs.existsSync(fullPath);\r\n\r\n if (exists && !isForce && !isDryRun) {\r\n // Ask to overwrite\r\n const overwrite = await confirm({\r\n message: `${agent.filePath} already exists. Overwrite?`,\r\n default: false,\r\n });\r\n\r\n if (!overwrite) {\r\n results.push({ file: agent.filePath, status: 'skipped' });\r\n continue;\r\n }\r\n }\r\n\r\n const content = agent.generate(version, categories);\r\n\r\n if (isDryRun) {\r\n log.section(`Preview: ${agent.filePath}`);\r\n log.print(chalk.gray('─'.repeat(60)));\r\n for (const line of content.split('\\n').slice(0, 20)) {\r\n log.print(chalk.gray(` ${line}`));\r\n }\r\n log.print(chalk.gray(' ... (truncated)'));\r\n log.print(chalk.gray('─'.repeat(60)));\r\n log.blank();\r\n results.push({ file: agent.filePath, status: 'dry-run' });\r\n continue;\r\n }\r\n\r\n // Ensure parent directory exists (for .github/copilot-instructions.md)\r\n const parentDir = path.dirname(fullPath);\r\n if (!fs.existsSync(parentDir)) {\r\n fs.mkdirSync(parentDir, { recursive: true });\r\n }\r\n\r\n fs.writeFileSync(fullPath, content, 'utf-8');\r\n results.push({ file: agent.filePath, status: 'created' });\r\n }\r\n\r\n // ── Summary ────────────────────────────────────────────────────────────\r\n\r\n log.section('Summary');\r\n\r\n for (const result of results) {\r\n switch (result.status) {\r\n case 'created':\r\n log.print(` ${chalk.green('✅')} Created ${chalk.white(result.file)}`);\r\n break;\r\n case 'skipped':\r\n log.print(` ${chalk.yellow('⏭')} Skipped ${chalk.white(result.file)} ${chalk.gray('(already exists — use --force to overwrite)')}`);\r\n break;\r\n case 'dry-run':\r\n log.print(` ${chalk.cyan('📝')} Would create ${chalk.white(result.file)}`);\r\n break;\r\n }\r\n }\r\n\r\n log.blank();\r\n\r\n if (isDryRun) {\r\n log.info('Dry run complete — no files were written.');\r\n log.info(`Re-run without ${chalk.cyan('--dry-run')} to apply.`);\r\n } else {\r\n const createdCount = results.filter((r) => r.status === 'created').length;\r\n if (createdCount > 0) {\r\n log.success(\r\n 'Done. Your AI agents will now automatically avoid the 17 most common AI-generated code anti-patterns.',\r\n );\r\n }\r\n }\r\n\r\n log.blank();\r\n });\r\n}\r\n"],"mappings":"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","names":["fs","path","import_fs","import_path","import_fs","import_path","import_chalk","chalk","createRequire","path","fs","program","ora","chalk","import_chalk","import_path","import_fs","import_fs","import_path","path","fs","path","program","chalk","createRequire","pathToFileURL","content","isInvalidAiGuardConfig","fs","import_chalk","import_path","path","program","isInvalidAiGuardConfig","chalk","import_chalk","import_path","program","chalk","path","import_chalk","import_path","program","chalk","path","import_fs","import_path","import_chalk","import_ora","path","fs","program","ora","chalk","import_fs","import_path","import_chalk","import_prompts","path","getPackageVersion","fs","program","getPackageVersion","chalk","path","fs","path","fs"]}
|
|
1
|
+
{"version":3,"sources":["../../cli/utils/config-manager.ts","../../cli/index.ts","../../cli/commands/run.ts","../../cli/utils/eslint-runner.ts","../../cli/utils/logger.ts","../../cli/commands/init.ts","../../cli/utils/detector.ts","../../cli/commands/doctor.ts","../../cli/commands/preset.ts","../../cli/commands/ignore.ts","../../cli/commands/baseline.ts","../../cli/commands/init-context.ts","../../cli/commands/report.ts"],"sourcesContent":["import fs from 'fs';\r\nimport path from 'path';\r\nimport type { ConfigType } from './detector.js';\r\n\r\nexport type Preset = 'recommended' | 'strict' | 'security';\r\n\r\n// ─── File I/O primitives ──────────────────────────────────────────────────────\r\n\r\nexport function backupConfig(configPath: string): string {\r\n const backupPath = `${configPath}.bak`;\r\n fs.copyFileSync(configPath, backupPath);\r\n return backupPath;\r\n}\r\n\r\nexport function readConfig(configPath: string): string {\r\n return fs.readFileSync(configPath, 'utf-8');\r\n}\r\n\r\nexport function writeConfig(configPath: string, content: string): void {\r\n fs.writeFileSync(configPath, content, 'utf-8');\r\n}\r\n\r\n// ─── Flat Config Generator (ESLint v9) ────────────────────────────────────────\r\n//\r\n// Generates a clean eslint.config.mjs that:\r\n// 1. Uses direct spread of the preset config object (no object wrapping)\r\n// 2. Explicitly names plugin so IDEs resolve it\r\n// 3. Puts ignores first so they apply to all following configs\r\n\r\nexport function generateFlatConfig(preset: Preset): string {\r\n return `import aiGuard from 'eslint-plugin-ai-guard';\r\n\r\nexport default [\r\n // Ignore generated / dependency directories\r\n {\r\n ignores: [\r\n 'node_modules/**',\r\n '.next/**',\r\n 'dist/**',\r\n 'build/**',\r\n 'coverage/**',\r\n 'out/**',\r\n ],\r\n },\r\n\r\n // ai-guard: catch AI-generated code patterns\r\n {\r\n plugins: {\r\n 'ai-guard': aiGuard,\r\n },\r\n rules: {\r\n ...aiGuard.configs.${preset}.rules,\r\n },\r\n },\r\n];\r\n`;\r\n}\r\n\r\n// ─── Legacy Config Generator (ESLint v8) ──────────────────────────────────────\r\n\r\nexport function generateLegacyConfig(preset: Preset): string {\r\n return `module.exports = {\r\n plugins: ['ai-guard'],\r\n extends: ['plugin:ai-guard/${preset}'],\r\n ignorePatterns: [\r\n 'node_modules/',\r\n '.next/',\r\n 'dist/',\r\n 'build/',\r\n 'coverage/',\r\n 'out/',\r\n ],\r\n};\r\n`;\r\n}\r\n\r\n// ─── Flat Config Patching (ESLint v9) ─────────────────────────────────────────\r\n\r\nconst AI_GUARD_MARKER = 'eslint-plugin-ai-guard';\r\n\r\nexport function isInvalidAiGuardConfig(content: string): boolean {\r\n if (!content.includes('eslint-plugin-ai-guard') && !content.includes('ai-guard')) {\r\n return false;\r\n }\r\n\r\n // Old invalid shape: plugin assigned to aiGuard.default\r\n if (/['\"]ai-guard['\"]\\s*:\\s*aiGuard\\.default/.test(content)) return true;\r\n\r\n // Old invalid shape: rules sourced directly from aiGuard.recommended/strict/security\r\n if (/\\.\\.\\.aiGuard\\.(recommended|strict|security)\\.rules/.test(content)) return true;\r\n if (/rules\\s*:\\s*aiGuard\\.(recommended|strict|security)\\.rules/.test(content)) return true;\r\n\r\n return false;\r\n}\r\n\r\nexport function repairInvalidFlatConfig(content: string): string {\r\n let repaired = content;\r\n \r\n // 1. Fix plugin assignment: 'ai-guard': aiGuard.default -> 'ai-guard': aiGuard\r\n repaired = repaired.replace(/(['\"]ai-guard['\"]\\s*:\\s*)aiGuard\\.default/g, '$1aiGuard');\r\n \r\n // 2. Fix raw assignment: rules: aiGuard.PRESET.rules -> rules: { ...aiGuard.configs.PRESET.rules }\r\n repaired = repaired.replace(\r\n /rules\\s*:\\s*aiGuard\\.([a-zA-Z0-9_]+)\\.rules(,?)/g,\r\n 'rules: {\\n ...aiGuard.configs.$1.rules,\\n }$2',\r\n );\r\n \r\n // 3. Fix spread assignment: ...aiGuard.PRESET.rules -> ...aiGuard.configs.PRESET.rules\r\n repaired = repaired.replace(/\\.\\.\\.aiGuard\\.([a-zA-Z0-9_]+)\\.rules/g, '...aiGuard.configs.$1.rules');\r\n \r\n return repaired;\r\n}\r\n\r\nexport function patchFlatConfig(existing: string, preset: Preset): string {\r\n if (isInvalidAiGuardConfig(existing)) {\r\n return repairInvalidFlatConfig(existing);\r\n }\r\n\r\n // If already configured and valid — leave untouched\r\n if (existing.includes(AI_GUARD_MARKER)) {\r\n return existing;\r\n }\r\n\r\n const importLine = `import aiGuard from 'eslint-plugin-ai-guard';\\n`;\r\n\r\n const rulesBlock = `\r\n // ai-guard injected by ai-guard CLI\r\n {\r\n plugins: {\r\n 'ai-guard': aiGuard,\r\n },\r\n rules: {\r\n ...aiGuard.configs.${preset}.rules,\r\n },\r\n },\r\n`;\r\n\r\n // Prepend import after the last existing import, or at the very top\r\n let patched = existing;\r\n const lastImportIdx = findLastImportEnd(patched);\r\n if (lastImportIdx > -1) {\r\n patched =\r\n patched.slice(0, lastImportIdx) +\r\n importLine +\r\n patched.slice(lastImportIdx);\r\n } else {\r\n patched = importLine + patched;\r\n }\r\n\r\n // Insert rule block before the closing `];` of the export default array\r\n const lastBracket = patched.lastIndexOf('];');\r\n if (lastBracket !== -1) {\r\n patched =\r\n patched.slice(0, lastBracket) + rulesBlock + patched.slice(lastBracket);\r\n }\r\n\r\n return patched;\r\n}\r\n\r\n/** Find index just after the last `import … from '…';` line */\r\nfunction findLastImportEnd(src: string): number {\r\n const lines = src.split('\\n');\r\n let lastImportLine = -1;\r\n let charCount = 0;\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i];\r\n if (/^\\s*import\\s+/.test(line)) lastImportLine = i;\r\n charCount += line.length + 1; // +1 for \\n\r\n }\r\n if (lastImportLine === -1) return -1;\r\n\r\n // Recalculate offset to end of that line\r\n let offset = 0;\r\n for (let i = 0; i <= lastImportLine; i++) {\r\n offset += lines[i].length + 1;\r\n }\r\n return offset;\r\n}\r\n\r\n// ─── Legacy Config Patching (ESLint v8) ───────────────────────────────────────\r\n\r\nexport function patchLegacyConfig(existing: string, preset: Preset): string {\r\n if (existing.includes('ai-guard')) {\r\n return existing; // already configured\r\n }\r\n\r\n let patched = existing;\r\n\r\n if (patched.includes('plugins:')) {\r\n patched = patched.replace(/plugins:\\s*\\[/, `plugins: ['ai-guard', `);\r\n } else {\r\n patched = patched.replace(\r\n 'module.exports = {',\r\n `module.exports = {\\n plugins: ['ai-guard'],`,\r\n );\r\n }\r\n\r\n if (patched.includes('extends:')) {\r\n patched = patched.replace(\r\n /extends:\\s*\\[/,\r\n `extends: ['plugin:ai-guard/${preset}', `,\r\n );\r\n } else {\r\n patched = patched.replace(\r\n 'module.exports = {',\r\n `module.exports = {\\n extends: ['plugin:ai-guard/${preset}'],`,\r\n );\r\n }\r\n\r\n return patched;\r\n}\r\n\r\nexport function switchFlatPreset(existing: string, preset: Preset): string {\r\n let patched = existing;\r\n\r\n patched = patched.replace(\r\n /\\.\\.\\.aiGuard\\.configs\\.(recommended|strict|security)\\.rules/g,\r\n `...aiGuard.configs.${preset}.rules`,\r\n );\r\n\r\n patched = patched.replace(\r\n /['\"]ai-guard\\/(recommended|strict|security)['\"]/g,\r\n `'ai-guard/${preset}'`,\r\n );\r\n\r\n return patched;\r\n}\r\n\r\nexport function switchLegacyPreset(existing: string, preset: Preset): string {\r\n let patched = existing;\r\n\r\n patched = patched.replace(\r\n /['\"]plugin:ai-guard\\/(recommended|strict|security)['\"]/g,\r\n `'plugin:ai-guard/${preset}'`,\r\n );\r\n\r\n patched = patched.replace(\r\n /['\"]ai-guard\\/(recommended|strict|security)['\"]/g,\r\n `'ai-guard/${preset}'`,\r\n );\r\n\r\n return patched;\r\n}\r\n\r\n// ─── Nuke-ignore removal ──────────────────────────────────────────────────────\r\n\r\n/**\r\n * Remove `ignorePatterns: [\"**\\/*\"]` from legacy configs.\r\n * Returns `{ content, changed }`.\r\n */\r\nexport function removeNukeIgnore(existing: string): {\r\n content: string;\r\n changed: boolean;\r\n} {\r\n const nukePatterns = [/\"?\\*\\*\\/\\*\"?/g];\r\n const hasNuke =\r\n existing.includes('\"**/*\"') || existing.includes(\"'**/*'\");\r\n\r\n if (!hasNuke) return { content: existing, changed: false };\r\n\r\n // Replace the entire ignorePatterns array value when it contains **/*\r\n let patched = existing\r\n .replace(\r\n /ignorePatterns:\\s*\\[.*?\\*\\*\\/\\*.*?\\]/gs,\r\n `ignorePatterns: ['node_modules/', '.next/', 'dist/', 'build/', 'coverage/']`,\r\n )\r\n .replace(\r\n /ignores:\\s*\\[.*?\\*\\*\\/\\*.*?\\]/gs,\r\n `ignores: ['node_modules/**', '.next/**', 'dist/**', 'build/**', 'coverage/**']`,\r\n );\r\n\r\n // Safety: if the regex above didn't match (complex multi-line), fall back to\r\n // a line-by-line strip of **/* entries\r\n for (const re of nukePatterns) {\r\n patched = patched.replace(re, '');\r\n }\r\n\r\n return { content: patched, changed: patched !== existing };\r\n}\r\n\r\n// ─── Ignore pattern helpers ───────────────────────────────────────────────────\r\n\r\nconst DEFAULT_FLAT_IGNORES = [\r\n 'node_modules/**',\r\n '.next/**',\r\n 'dist/**',\r\n 'build/**',\r\n 'coverage/**',\r\n 'out/**',\r\n];\r\n\r\nconst DEFAULT_LEGACY_IGNORES = [\r\n 'node_modules/',\r\n '.next/',\r\n 'dist/',\r\n 'build/',\r\n 'coverage/',\r\n 'out/',\r\n];\r\n\r\nexport function addIgnoresToFlatConfig(existing: string): string {\r\n if (existing.includes('ignores:')) return existing;\r\n\r\n const block = `\r\n // Default ignores added by ai-guard CLI\r\n {\r\n ignores: ${JSON.stringify(DEFAULT_FLAT_IGNORES)},\r\n },\r\n`;\r\n\r\n const lastBracket = existing.lastIndexOf('];');\r\n if (lastBracket !== -1) {\r\n return existing.slice(0, lastBracket) + block + existing.slice(lastBracket);\r\n }\r\n return existing;\r\n}\r\n\r\nexport function addIgnoresToLegacyConfig(existing: string): string {\r\n if (existing.includes('ignorePatterns')) return existing;\r\n return existing.replace(\r\n 'module.exports = {',\r\n `module.exports = {\\n ignorePatterns: ${JSON.stringify(DEFAULT_LEGACY_IGNORES)},`,\r\n );\r\n}\r\n\r\n// ─── Config file path resolution ──────────────────────────────────────────────\r\n\r\nexport function getConfigFilePath(\r\n configType: ConfigType,\r\n cwd = process.cwd(),\r\n): string {\r\n switch (configType) {\r\n case 'flat-js':\r\n return path.join(cwd, 'eslint.config.js');\r\n case 'flat-mjs':\r\n return path.join(cwd, 'eslint.config.mjs');\r\n case 'flat-cjs':\r\n return path.join(cwd, 'eslint.config.cjs');\r\n case 'eslintrc-js':\r\n return path.join(cwd, '.eslintrc.js');\r\n case 'eslintrc-cjs':\r\n return path.join(cwd, '.eslintrc.cjs');\r\n case 'eslintrc-json':\r\n return path.join(cwd, '.eslintrc.json');\r\n default:\r\n return path.join(cwd, '.eslintrc.js');\r\n }\r\n}\r\n\r\n// ─── Post-init config validation ──────────────────────────────────────────────\r\n\r\n/**\r\n * Lightweight structural validation of a generated/patched flat config.\r\n * Does NOT require ESLint to be loadable — just checks the text.\r\n * Returns an array of problem strings; empty = looks valid.\r\n */\r\nexport function validateFlatConfigText(content: string): string[] {\r\n const problems: string[] = [];\r\n\r\n if (!content.includes('export default')) {\r\n problems.push('Missing `export default` — file must be an ES module');\r\n }\r\n if (!content.includes('eslint-plugin-ai-guard') && !content.includes('aiGuard')) {\r\n problems.push('Plugin import not found — ai-guard plugin may not be referenced');\r\n }\r\n if (!content.trim().endsWith('];') && !content.trim().endsWith('];')) {\r\n // minor — not fatal\r\n }\r\n\r\n // Detect nuke ignore that would prevent any files from being linted\r\n if (content.includes('\"**/*\"') || content.includes(\"'**/*'\")) {\r\n problems.push(\r\n 'Config contains \"**/*\" ignore pattern — this will prevent all files from being linted',\r\n );\r\n }\r\n\r\n return problems;\r\n}\r\n\r\nexport function validateLegacyConfigText(content: string): string[] {\r\n const problems: string[] = [];\r\n\r\n if (!content.includes('module.exports')) {\r\n problems.push('Missing `module.exports` — legacy config must use CJS exports');\r\n }\r\n if (!content.includes('ai-guard')) {\r\n problems.push('Plugin not referenced — add ai-guard to plugins and extends');\r\n }\r\n if (content.includes('\"**/*\"') || content.includes(\"'**/*'\")) {\r\n problems.push(\r\n 'Config contains \"**/*\" ignore pattern — this will prevent all files from being linted',\r\n );\r\n }\r\n\r\n return problems;\r\n}\r\n","import { Command } from 'commander';\nimport fs from 'fs';\nimport path from 'path';\nimport { registerRunCommand } from './commands/run.js';\nimport { registerInitCommand } from './commands/init.js';\nimport { registerDoctorCommand } from './commands/doctor.js';\nimport { registerPresetCommand } from './commands/preset.js';\nimport { registerIgnoreCommand } from './commands/ignore.js';\nimport { registerBaselineCommand } from './commands/baseline.js';\nimport { registerInitContextCommand } from './commands/init-context.js';\nimport { registerReportCommand } from './commands/report.js';\nimport { log } from './utils/logger.js';\n\n// ─── Version resolution ───────────────────────────────────────────────────────\n\nfunction getVersion(): string {\n try {\n // In the bundled CLI output, __dirname is available (CJS bundle).\n const pkgPath = path.resolve(__dirname, '../../package.json');\n const raw = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(raw) as { version?: string };\n return typeof pkg.version === 'string' ? pkg.version : '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n\n// ─── Program ──────────────────────────────────────────────────────────────────\n\nconst program = new Command();\n\nprogram\n .name('ai-guard')\n .description(\n 'Production-grade CLI for eslint-plugin-ai-guard\\n' +\n 'Catch AI-generated code issues instantly — no ESLint config required.\\n\\n' +\n 'Quick start:\\n' +\n ' npx ai-guard run Scan current project\\n' +\n ' npx ai-guard init Auto-configure ESLint\\n' +\n ' npx ai-guard init-context Generate AI agent rules\\n' +\n ' npx ai-guard report Generate shareable HTML report\\n' +\n ' npx ai-guard doctor Check your setup\\n' +\n ' npx ai-guard baseline Save baseline, track new issues only',\n )\n .version(getVersion(), '-v, --version', 'Print version number')\n .helpOption('-h, --help', 'Show help');\n\n// ─── Register commands ────────────────────────────────────────────────────────\n\nregisterRunCommand(program);\nregisterInitCommand(program);\nregisterDoctorCommand(program);\nregisterPresetCommand(program);\nregisterIgnoreCommand(program);\nregisterBaselineCommand(program);\nregisterInitContextCommand(program);\nregisterReportCommand(program);\n\n// ─── Global error handling ────────────────────────────────────────────────────\n\nprogram.configureOutput({\n writeErr(str) {\n // Strip commander's default \"error: \" prefix for cleaner output\n const cleaned = str.replace(/^error:\\s*/i, '').trim();\n log.error(cleaned);\n },\n});\n\nprocess.on('unhandledRejection', (reason: unknown) => {\n const msg =\n reason instanceof Error ? reason.message : String(reason);\n log.error(`Unexpected error: ${msg}`);\n log.info('If this looks like a bug, please report it at:');\n log.info(' https://github.com/YashJadhav21/eslint-plugin-ai-guard/issues');\n process.exit(1);\n});\n\nprocess.on('SIGINT', () => {\n log.blank();\n log.info('Cancelled.');\n process.exit(0);\n});\n\n// ─── Parse args ───────────────────────────────────────────────────────────────\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err);\n log.error(msg);\n process.exit(1);\n});\n","import type { Command } from 'commander';\nimport ora from 'ora';\nimport chalk from 'chalk';\nimport { runEslint, type Preset, type EcosystemIssue } from '../utils/eslint-runner.js';\nimport { log, RULE_CATEGORY, CATEGORY_ICONS, CATEGORY_ORDER, CONFIDENCE_TIER } from '../utils/logger.js';\nimport type { RunResult } from '../utils/eslint-runner.js';\n\nexport function registerRunCommand(program: Command): void {\n program\n .command('run')\n .description('Run ai-guard rules on your project (zero ESLint config required)')\n .option('--path <dir>', 'Directory or file to scan', '.')\n .option('--strict', 'Use the strict rule preset (all rules at error)')\n .option('--security', 'Use the security-only rule preset')\n .option('--json', 'Output results as JSON (CI-friendly)')\n .option(\n '--max-warnings <n>',\n 'Fail with exit code 1 if warnings exceed this count',\n (value: string) => Number.parseInt(value, 10),\n )\n .option('--verbose', 'Show all issues — disable grouping of repeated warnings')\n .option('--debug-timing', 'Print per-phase timing diagnostics')\n .action(async (opts: {\n path: string;\n strict?: boolean;\n security?: boolean;\n json?: boolean;\n maxWarnings?: number;\n verbose?: boolean;\n debugTiming?: boolean;\n }) => {\n if (\n opts.maxWarnings !== undefined &&\n (!Number.isInteger(opts.maxWarnings) || opts.maxWarnings < 0)\n ) {\n log.blank();\n log.error('--max-warnings must be a non-negative integer.');\n log.blank();\n process.exit(1);\n return;\n }\n\n const preset: Preset = opts.strict\n ? 'strict'\n : opts.security\n ? 'security'\n : 'recommended';\n\n if (opts.strict && opts.security && !opts.json) {\n log.warn('Both --strict and --security were provided. Using --strict.');\n log.blank();\n }\n\n if (!opts.json) {\n log.banner('AI GUARD');\n log.blank();\n }\n\n const spinner = opts.json\n ? null\n : ora({ text: 'Scanning…', color: 'cyan' }).start();\n\n let result: RunResult;\n try {\n result = await runEslint({\n preset,\n targetPath: opts.path,\n debugTiming: opts.debugTiming,\n });\n spinner?.stop();\n } catch (err: unknown) {\n spinner?.stop();\n const msg = err instanceof Error ? err.message : String(err);\n\n if (msg.toLowerCase().includes('typescript') && msg.toLowerCase().includes('parser')) {\n log.blank();\n log.error('TypeScript detected but parser not found.');\n log.blank();\n log.print(` ${chalk.bold('Install the TypeScript parser:')}`);\n log.blank();\n log.print(` ${chalk.cyan('npm install --save-dev @typescript-eslint/parser')}`);\n log.blank();\n } else {\n log.blank();\n log.error(msg);\n log.blank();\n log.print(` ${chalk.bold('Fix:')} Run ${chalk.cyan('ai-guard doctor')} to diagnose your setup.`);\n log.blank();\n }\n process.exit(1);\n return;\n }\n\n // ─── JSON mode ─────────────────────────────────────────────────────────\n\n if (opts.json) {\n const jsonOutput = {\n preset,\n scannedPath: opts.path,\n filesScanned: result.filesScanned,\n totalErrors: result.totalErrors,\n totalWarnings: result.totalWarnings,\n totalIssues: result.totalIssues,\n durationMs: result.durationMs,\n timing: result.timing,\n ruleBreakdown: Object.fromEntries(result.ruleBreakdown),\n topFiles: result.topFiles,\n files: result.files,\n ecosystemIssues: result.ecosystemIssues,\n parserErrors: result.parserErrors,\n tsParserAvailable: result.tsParserAvailable,\n };\n console.log(JSON.stringify(jsonOutput, null, 2));\n process.exit(getRunExitCode(result, opts.maxWarnings));\n return;\n }\n\n // ─── Human output ────────────────────────────────────────────────────────\n\n // Scan stats header — note if TS parser missing\n log.scanStats(result.filesScanned, result.files.length, result.durationMs, preset);\n if (!result.tsParserAvailable) {\n log.print(\n chalk.dim(` ℹ TypeScript parser not found — .ts/.tsx files use espree fallback`) +\n chalk.dim(` (install @typescript-eslint/parser for full TS support)`),\n );\n }\n log.blank();\n\n // ── Success state ─────────────────────────────────────────────────────────\n\n if (result.totalIssues === 0 && result.ecosystemIssues.length === 0 && result.parserErrors.length === 0) {\n log.print(\n ` ${chalk.green('✔')} ${chalk.bold.green('No AI issues found')} ${chalk.gray(`— ${result.filesScanned} file${result.filesScanned !== 1 ? 's' : ''} scanned, all clean`)}`,\n );\n log.blank();\n process.exit(0);\n return;\n }\n\n if (result.totalIssues === 0) {\n log.print(\n ` ${chalk.green('✔')} ${chalk.bold.green('No AI issues found')} ${chalk.gray(`— ${result.filesScanned} file${result.filesScanned !== 1 ? 's' : ''} scanned, all clean`)}`,\n );\n log.blank();\n }\n\n // ── AI Guard Findings ─────────────────────────────────────────────────────\n\n if (result.totalIssues > 0) {\n\n // Category summary with icons\n log.section('Summary by Category');\n\n const categoryErrors: Record<string, number> = {};\n const categoryWarnings: Record<string, number> = {};\n\n for (const file of result.files) {\n for (const issue of file.issues) {\n const cat = RULE_CATEGORY[issue.ruleId] ?? 'Other';\n if (issue.severity === 2) {\n categoryErrors[cat] = (categoryErrors[cat] ?? 0) + 1;\n } else {\n categoryWarnings[cat] = (categoryWarnings[cat] ?? 0) + 1;\n }\n }\n }\n\n const allCategories = new Set([\n ...CATEGORY_ORDER,\n ...Object.keys(categoryErrors),\n ...Object.keys(categoryWarnings),\n ]);\n\n const sortedCategories = [...allCategories].filter(\n (cat) => (categoryErrors[cat] ?? 0) + (categoryWarnings[cat] ?? 0) > 0,\n );\n\n sortedCategories.sort((a, b) => {\n const ai = CATEGORY_ORDER.indexOf(a);\n const bi = CATEGORY_ORDER.indexOf(b);\n if (ai !== -1 && bi !== -1) return ai - bi;\n if (ai !== -1) return -1;\n if (bi !== -1) return 1;\n return a.localeCompare(b);\n });\n\n for (const cat of sortedCategories) {\n const icon = CATEGORY_ICONS[cat] ?? '⚪';\n log.category(icon, cat, categoryErrors[cat] ?? 0, categoryWarnings[cat] ?? 0);\n }\n\n log.blank();\n\n log.print(\n ` ${chalk.bold('Total:')} ${formatIssueCount(result.totalErrors, result.totalWarnings)}`,\n );\n log.blank();\n\n // By Rule — with confidence indicators\n if (result.ruleBreakdown.size > 0) {\n log.section('By Rule');\n\n const sorted = [...result.ruleBreakdown.entries()].sort(\n (a, b) => b[1] - a[1],\n );\n for (const [rule, count] of sorted) {\n const shortRule = rule.replace(/^ai-guard\\//, '');\n const tier = CONFIDENCE_TIER[rule];\n const tierLabel = tier === 'high'\n ? chalk.red.dim('[high]')\n : tier === 'medium'\n ? chalk.yellow.dim('[medium]')\n : chalk.gray.dim('[low]');\n log.print(\n ` ${chalk.gray('•')} ${chalk.yellow(shortRule)} ${tierLabel}${chalk.gray(':')} ${chalk.white(String(count))}`,\n );\n }\n log.blank();\n }\n\n // Top Files\n if (result.topFiles.length > 0) {\n log.section('Top Files');\n for (const { path: fp, count } of result.topFiles) {\n log.print(\n ` ${chalk.gray('•')} ${chalk.white(fp)} ${chalk.gray(`(${count})`)}`,\n );\n }\n log.blank();\n }\n\n // Issues by File — with grouping of repeated low-confidence warnings\n log.section('Issues by File');\n log.blank();\n\n const verbose = opts.verbose ?? false;\n renderIssuesByFile(result, verbose);\n }\n\n // ── ESLint Ecosystem Issues ───────────────────────────────────────────────\n // Shown SEPARATELY — these are NOT ai-guard findings\n\n if (result.ecosystemIssues.length > 0) {\n log.ecosystemSection('ESLint Config Issues');\n log.print(\n chalk.dim(` These issues come from your project's ESLint config, not from ai-guard.`),\n );\n log.blank();\n\n // Group by ruleId + message to de-duplicate\n const seen = new Map<string, { issue: EcosystemIssue; count: number }>();\n for (const issue of result.ecosystemIssues) {\n const key = `${issue.ruleId ?? 'null'}::${issue.message}`;\n const existing = seen.get(key);\n if (existing) {\n existing.count++;\n } else {\n seen.set(key, { issue, count: 1 });\n }\n }\n\n for (const { issue, count } of seen.values()) {\n log.ecosystemIssue(issue, count);\n }\n\n log.blank();\n }\n\n // ── Parser Errors ─────────────────────────────────────────────────────────\n\n if (result.parserErrors.length > 0) {\n log.ecosystemSection('Parser Errors');\n log.print(\n chalk.dim(` These files could not be parsed — not ai-guard findings.`),\n );\n log.blank();\n\n for (const pe of result.parserErrors) {\n log.parserError(pe);\n }\n\n if (!result.tsParserAvailable) {\n log.blank();\n log.print(\n ` ${chalk.cyan('→ Fix:')} ${chalk.yellow('npm install --save-dev @typescript-eslint/parser')}`,\n );\n log.print(\n chalk.dim(` TypeScript parser resolves most .ts/.tsx parse failures.`),\n );\n }\n log.blank();\n }\n\n log.divider();\n log.blank();\n\n // ── Next steps ────────────────────────────────────────────────────────────\n\n log.section('Next Steps');\n if (result.totalIssues > 0) {\n log.info(`Run ${chalk.cyan('ai-guard baseline')} to save these issues and track only new ones`);\n log.info(`Run ${chalk.cyan('ai-guard report')} to generate a shareable HTML report`);\n log.info(`Run ${chalk.cyan('ai-guard ignore')} to suppress dist/build noise`);\n }\n if (result.ecosystemIssues.length > 0) {\n log.info(`Run ${chalk.cyan('ai-guard doctor')} to diagnose ESLint config issues`);\n }\n if (!opts.verbose && hasGroupedWarnings(result)) {\n log.info(`Run with ${chalk.cyan('--verbose')} to expand grouped warnings`);\n }\n log.blank();\n\n process.exit(getRunExitCode(result, opts.maxWarnings));\n });\n}\n\n// ─── Issue rendering ──────────────────────────────────────────────────────────\n\nconst GROUP_THRESHOLD = 4; // Group if same rule appears >= this many times in a file\n\nfunction hasGroupedWarnings(result: RunResult): boolean {\n for (const file of result.files) {\n const ruleCounts = new Map<string, number>();\n for (const issue of file.issues) {\n ruleCounts.set(issue.ruleId, (ruleCounts.get(issue.ruleId) ?? 0) + 1);\n }\n for (const count of ruleCounts.values()) {\n if (count >= GROUP_THRESHOLD) return true;\n }\n }\n return false;\n}\n\nfunction renderIssuesByFile(result: RunResult, verbose: boolean): void {\n for (const file of result.files) {\n log.print(\n ` ${chalk.bold.white(file.filePath)} ` +\n chalk.gray(\n `(${file.errorCount} error${file.errorCount !== 1 ? 's' : ''}, ` +\n `${file.warningCount} warning${file.warningCount !== 1 ? 's' : ''})`,\n ),\n );\n\n if (!verbose) {\n // Group repeated low-confidence warnings\n const ruleCounts = new Map<string, Array<typeof file.issues[0]>>();\n for (const issue of file.issues) {\n const arr = ruleCounts.get(issue.ruleId) ?? [];\n arr.push(issue);\n ruleCounts.set(issue.ruleId, arr);\n }\n\n for (const issues of ruleCounts.values()) {\n const tier = CONFIDENCE_TIER[issues[0].ruleId] ?? 'low';\n // Group low-confidence warnings if they repeat heavily\n if (tier === 'low' && issues.length >= GROUP_THRESHOLD) {\n const sev = issues[0].severity === 2 ? chalk.red('error') : chalk.yellow(' warn');\n const shortRule = chalk.gray(issues[0].ruleId.replace(/^ai-guard\\//, ''));\n log.print(\n ` ${sev} ${chalk.white(issues[0].message)} ${shortRule}`,\n );\n log.print(\n chalk.dim(` ↳ ${issues.length} occurrences — run with --verbose to expand`),\n );\n } else {\n for (const issue of issues) {\n renderSingleIssue(issue);\n }\n }\n }\n } else {\n for (const issue of file.issues) {\n renderSingleIssue(issue);\n }\n }\n\n log.blank();\n }\n}\n\nfunction renderSingleIssue(issue: { ruleId: string; severity: 1 | 2; message: string; line: number; column: number }): void {\n const sev = issue.severity === 2\n ? chalk.red('error')\n : chalk.yellow(' warn');\n const loc = chalk.gray(`${String(issue.line)}:${String(issue.column)}`).padEnd(12);\n const ruleShort = chalk.gray(issue.ruleId.replace(/^ai-guard\\//, ''));\n const tier = CONFIDENCE_TIER[issue.ruleId];\n const tierTag = tier === 'high'\n ? ''\n : tier === 'medium'\n ? ''\n : chalk.dim(' [low]');\n log.print(\n ` ${loc} ${sev} ${chalk.white(issue.message)}${tierTag} ${ruleShort}`,\n );\n}\n\n// ─── Exit code ────────────────────────────────────────────────────────────────\n\nexport function getRunExitCode(result: RunResult, maxWarnings?: number): number {\n if (result.totalErrors > 0) return 1;\n if (maxWarnings !== undefined && result.totalWarnings > maxWarnings) return 1;\n return 0;\n}\n\nfunction formatIssueCount(errors: number, warnings: number): string {\n const parts: string[] = [];\n if (errors > 0) parts.push(chalk.red.bold(`${errors} error${errors !== 1 ? 's' : ''}`));\n if (warnings > 0) parts.push(chalk.yellow.bold(`${warnings} warning${warnings !== 1 ? 's' : ''}`));\n return parts.join(chalk.gray(' · '));\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { pathToFileURL } from 'url';\nimport { log } from './logger.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ntype RuleLevel = 'error' | 'warn' | 'off';\n\nexport type Preset = 'recommended' | 'strict' | 'security';\n\nexport interface RunOptions {\n preset: Preset;\n targetPath: string;\n maxWarnings?: number;\n jsonOutput?: boolean;\n debugTiming?: boolean;\n}\n\nexport interface IssueDetail {\n ruleId: string;\n severity: 1 | 2;\n message: string;\n line: number;\n column: number;\n}\n\nexport interface FileResult {\n filePath: string;\n issues: IssueDetail[]; // ai-guard/* findings only\n errorCount: number;\n warningCount: number;\n}\n\n/**\n * An issue from a non-ai-guard rule (e.g., react-hooks/exhaustive-deps not found,\n * foreign plugin rules, missing rule definitions). These are ESLint ecosystem issues\n * and must NEVER appear in ai-guard findings or affect the score/confidence.\n */\nexport interface EcosystemIssue {\n type: 'missing-rule' | 'foreign-rule' | 'config-error';\n ruleId: string | null;\n message: string;\n filePath: string;\n line: number;\n column: number;\n}\n\n/**\n * A fatal parse error — ESLint could not parse the file at all.\n * Not an ai-guard finding. Shown in a separate section.\n */\nexport interface ParserError {\n filePath: string;\n message: string;\n line: number;\n}\n\nexport interface TimingBreakdown {\n pluginLoadMs: number;\n parserLoadMs: number;\n lintMs: number;\n processMs: number;\n}\n\nexport interface RunResult {\n files: FileResult[];\n totalErrors: number;\n totalWarnings: number;\n totalIssues: number;\n filesScanned: number;\n ruleBreakdown: Map<string, number>;\n topFiles: Array<{ path: string; count: number }>;\n durationMs: number;\n timing?: TimingBreakdown;\n /** ESLint ecosystem issues — NOT ai-guard findings */\n ecosystemIssues: EcosystemIssue[];\n /** Fatal parser errors — NOT ai-guard findings */\n parserErrors: ParserError[];\n /** True if @typescript-eslint/parser was found and loaded */\n tsParserAvailable: boolean;\n}\n\n// ─── Plugin normalizer ────────────────────────────────────────────────────────\n\ntype AiGuardPlugin = {\n rules: Record<string, unknown>;\n configs?: Record<string, unknown>;\n meta?: Record<string, unknown>;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction normalizePlugin(raw: unknown): AiGuardPlugin {\n if (isRecord(raw) && isRecord(raw.default) && isRecord(raw.default.rules)) {\n return raw.default as AiGuardPlugin;\n }\n if (isRecord(raw) && isRecord(raw.rules)) {\n return raw as AiGuardPlugin;\n }\n throw new Error(\n 'Could not load eslint-plugin-ai-guard. Run: npm install eslint-plugin-ai-guard',\n );\n}\n\n// ─── Preset rule maps ─────────────────────────────────────────────────────────\n\nconst RECOMMENDED_RULES: Record<string, RuleLevel> = {\n // Reliability\n 'ai-guard/no-empty-catch': 'error',\n 'ai-guard/no-broad-exception': 'warn',\n // Async\n 'ai-guard/no-floating-promise': 'error',\n 'ai-guard/no-await-in-loop': 'warn',\n 'ai-guard/no-async-without-await': 'warn',\n 'ai-guard/no-async-array-callback': 'warn',\n // Security\n 'ai-guard/no-hardcoded-secret': 'error',\n 'ai-guard/no-eval-dynamic': 'error',\n 'ai-guard/no-sql-string-concat': 'warn',\n 'ai-guard/no-unsafe-deserialize': 'warn',\n 'ai-guard/require-auth-middleware': 'warn',\n 'ai-guard/require-authz-check': 'warn',\n // AI Patterns\n 'ai-guard/no-dead-branch': 'warn',\n};\n\nconst STRICT_RULES: Record<string, RuleLevel> = {\n // Reliability\n 'ai-guard/no-empty-catch': 'error',\n 'ai-guard/no-broad-exception': 'error',\n 'ai-guard/no-catch-log-rethrow': 'error',\n 'ai-guard/no-catch-without-use': 'error',\n // Async\n 'ai-guard/no-async-array-callback': 'error',\n 'ai-guard/no-floating-promise': 'error',\n 'ai-guard/no-await-in-loop': 'error',\n 'ai-guard/no-async-without-await': 'error',\n 'ai-guard/no-redundant-await': 'error',\n // Security\n 'ai-guard/no-hardcoded-secret': 'error',\n 'ai-guard/no-eval-dynamic': 'error',\n 'ai-guard/no-sql-string-concat': 'error',\n 'ai-guard/no-unsafe-deserialize': 'error',\n 'ai-guard/require-auth-middleware': 'error',\n 'ai-guard/require-authz-check': 'error',\n // AI Patterns\n 'ai-guard/no-console-in-handler': 'error',\n 'ai-guard/no-duplicate-logic-block': 'error',\n 'ai-guard/no-dead-branch': 'error',\n};\n\nconst SECURITY_RULES: Record<string, RuleLevel> = {\n 'ai-guard/no-hardcoded-secret': 'error',\n 'ai-guard/no-eval-dynamic': 'error',\n 'ai-guard/no-sql-string-concat': 'error',\n 'ai-guard/no-unsafe-deserialize': 'warn',\n 'ai-guard/require-auth-middleware': 'warn',\n 'ai-guard/require-authz-check': 'warn',\n};\n\nfunction getRules(preset: Preset): Record<string, RuleLevel> {\n if (preset === 'strict') return STRICT_RULES;\n if (preset === 'security') return SECURITY_RULES;\n return RECOMMENDED_RULES;\n}\n\n// ─── Default ignores ──────────────────────────────────────────────────────────\n\nconst DEFAULT_IGNORE_PATTERNS = [\n '**/node_modules/**',\n '**/.next/**',\n '**/dist/**',\n '**/build/**',\n '**/coverage/**',\n '**/out/**',\n '**/.git/**',\n];\n\nexport function isSkippablePatternError(error: Error): boolean {\n const msg = error.message.toLowerCase();\n return (\n msg.includes('no files') ||\n msg.includes('no files matching') ||\n msg.includes('ignored') ||\n msg.includes('all files matched by') ||\n msg.includes('are ignored') ||\n msg.includes('was ignored') ||\n msg.includes('file ignored')\n );\n}\n\n// ─── Message classifier ───────────────────────────────────────────────────────\n\ntype MessageSource = 'ai-guard' | 'parser-error' | 'ecosystem';\n\nfunction classifyMessage(msg: { ruleId: string | null; fatal?: boolean; message: string }): MessageSource {\n // Fatal parse errors (ESLint couldn't parse the file at all)\n if (msg.fatal === true) return 'parser-error';\n\n // Explicit parse errors in the message body\n if (msg.ruleId === null && (\n msg.message.startsWith('Parsing error') ||\n msg.message.includes('Unexpected token') ||\n msg.message.includes('SyntaxError')\n )) {\n return 'parser-error';\n }\n\n // Our rules — the only ones that count as ai-guard findings\n if (msg.ruleId && msg.ruleId.startsWith('ai-guard/')) {\n return 'ai-guard';\n }\n\n // Everything else: missing rule definitions, foreign plugin rules, config issues\n return 'ecosystem';\n}\n\nfunction classifyEcosystemType(\n msg: { ruleId: string | null; message: string },\n): EcosystemIssue['type'] {\n const lower = msg.message.toLowerCase();\n if (lower.includes('definition for rule') && lower.includes('was not found')) {\n return 'missing-rule';\n }\n if (lower.includes('configuration') || lower.includes('config')) {\n return 'config-error';\n }\n return 'foreign-rule';\n}\n\n// ─── Plugin loader ────────────────────────────────────────────────────────────\n\nasync function loadPluginModuleFromCwd(cwd: string): Promise<unknown> {\n const { createRequire } = await import('module');\n const requireFromCwd = createRequire(path.join(cwd, 'package.json'));\n\n try {\n const resolved = requireFromCwd.resolve('eslint-plugin-ai-guard');\n return import(pathToFileURL(resolved).href);\n } catch {\n // Fall through to local dist fallback.\n }\n\n const localDistEntry = path.join(cwd, 'dist', 'index.js');\n if (fs.existsSync(localDistEntry)) {\n return import(pathToFileURL(localDistEntry).href);\n }\n\n const localSrcEntry = path.join(cwd, 'src', 'index.ts');\n if (fs.existsSync(localSrcEntry)) {\n try {\n return import(pathToFileURL(localSrcEntry).href);\n } catch (err: unknown) {\n const reason = err instanceof Error ? err.message : String(err);\n log.debug(`Local src plugin import failed: ${reason}`);\n }\n }\n\n throw new Error(\n 'eslint-plugin-ai-guard is not installed. Run: npm install --save-dev eslint-plugin-ai-guard',\n );\n}\n\n// ─── Core runner ──────────────────────────────────────────────────────────────\n\nexport async function runEslint(options: RunOptions): Promise<RunResult> {\n const overallStart = Date.now();\n const timing: TimingBreakdown = {\n pluginLoadMs: 0,\n parserLoadMs: 0,\n lintMs: 0,\n processMs: 0,\n };\n\n const { ESLint } = await import('eslint').catch(() => {\n throw new Error(\n 'ESLint is not installed. Run: npm install --save-dev eslint',\n );\n });\n\n // ── Load plugin ────────────────────────────────────────────────────────────\n const pluginStart = Date.now();\n const rawPlugin = await loadPluginModuleFromCwd(process.cwd());\n const plugin = normalizePlugin(rawPlugin);\n timing.pluginLoadMs = Date.now() - pluginStart;\n\n const rules = getRules(options.preset);\n const resolvedTargetPath = path.resolve(options.targetPath);\n\n if (!fs.existsSync(resolvedTargetPath)) {\n throw new Error(`Path not found: ${options.targetPath}`);\n }\n\n const targetStat = fs.statSync(resolvedTargetPath);\n const isSingleFileTarget = targetStat.isFile();\n const eslintCwd = isSingleFileTarget\n ? path.dirname(resolvedTargetPath)\n : resolvedTargetPath;\n\n // ── Load TypeScript parser ─────────────────────────────────────────────────\n const parserStart = Date.now();\n let tsParser: unknown = null;\n let tsParserAvailable = false;\n try {\n // Prefer parser from user's project, fall back to ours\n try {\n tsParser = require(path.join(\n process.cwd(),\n 'node_modules',\n '@typescript-eslint',\n 'parser',\n ));\n } catch {\n tsParser = require('@typescript-eslint/parser');\n }\n tsParserAvailable = true;\n } catch {\n // TypeScript parser not available — ts/tsx files will use default espree parser\n log.debug('@typescript-eslint/parser not found — TypeScript files will use espree fallback');\n }\n timing.parserLoadMs = Date.now() - parserStart;\n\n // ── Build ESLint config ────────────────────────────────────────────────────\n\n const JS_TS_FILES = [\n '**/*.js',\n '**/*.jsx',\n '**/*.ts',\n '**/*.tsx',\n '**/*.mts',\n '**/*.cts',\n '**/*.mjs',\n '**/*.cjs',\n ];\n\n const configBlocks: Array<Record<string, unknown>> = [\n // JS/JSX files — default espree parser with JSX support\n {\n files: ['**/*.js', '**/*.jsx', '**/*.mjs', '**/*.cjs'],\n plugins: { 'ai-guard': plugin } as Record<string, unknown>,\n languageOptions: {\n parserOptions: {\n ecmaVersion: 'latest',\n sourceType: 'module',\n ecmaFeatures: { jsx: true },\n },\n },\n rules: rules as Record<string, unknown>,\n },\n // Ignore generated directories\n { ignores: DEFAULT_IGNORE_PATTERNS },\n ];\n\n if (tsParser) {\n // TS + TSX with TypeScript parser — JSX enabled for both\n configBlocks.splice(1, 0, {\n files: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],\n plugins: { 'ai-guard': plugin } as Record<string, unknown>,\n languageOptions: {\n parser: tsParser,\n parserOptions: {\n ecmaVersion: 'latest',\n sourceType: 'module',\n ecmaFeatures: { jsx: true },\n },\n },\n rules: rules as Record<string, unknown>,\n });\n } else {\n // No TS parser — lint ts/tsx files but they may partially fail to parse\n configBlocks.splice(1, 0, {\n files: ['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts'],\n plugins: { 'ai-guard': plugin } as Record<string, unknown>,\n languageOptions: {\n parserOptions: {\n ecmaVersion: 'latest',\n sourceType: 'module',\n ecmaFeatures: { jsx: true },\n },\n },\n rules: rules as Record<string, unknown>,\n });\n }\n\n const eslint = new ESLint({\n cwd: eslintCwd,\n overrideConfigFile: true as unknown as string,\n overrideConfig: configBlocks,\n });\n\n // ── Lint files ─────────────────────────────────────────────────────────────\n // Task 7: Use single lintFiles call with all patterns for maximum performance.\n // This avoids per-pattern ESLint API round-trips which cause massive overhead.\n\n const patterns = isSingleFileTarget\n ? [path.basename(resolvedTargetPath)]\n : JS_TS_FILES;\n\n const lintStart = Date.now();\n let rawResults: Array<{\n filePath: string;\n messages: Array<{\n ruleId: string | null;\n severity: number;\n message: string;\n line: number;\n column: number;\n fatal?: boolean;\n }>;\n errorCount: number;\n warningCount: number;\n }>;\n\n try {\n // Single call — much faster than Promise.all of individual patterns\n rawResults = await eslint.lintFiles(patterns) as typeof rawResults;\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n\n if (isSkippablePatternError(error)) {\n // If single-call fails with \"no files\", fall back to per-pattern\n log.debug('Single-call lintFiles failed with no-files, falling back to per-pattern');\n const perPatternResults = await Promise.all(\n patterns.map(async (pattern) => {\n try {\n return await eslint.lintFiles([pattern]) as typeof rawResults;\n } catch (patternErr: unknown) {\n const patternError = patternErr instanceof Error ? patternErr : new Error(String(patternErr));\n if (isSkippablePatternError(patternError)) {\n log.debug(`Skipping pattern '${pattern}' (no lintable files)`);\n return [] as typeof rawResults;\n }\n throw patternError;\n }\n }),\n );\n rawResults = perPatternResults.flat();\n } else {\n throw error;\n }\n }\n timing.lintMs = Date.now() - lintStart;\n\n // ── Process results ────────────────────────────────────────────────────────\n const processStart = Date.now();\n\n const files: FileResult[] = [];\n const ecosystemIssues: EcosystemIssue[] = [];\n const parserErrors: ParserError[] = [];\n const ruleBreakdown = new Map<string, number>();\n let totalErrors = 0;\n let totalWarnings = 0;\n const filesScanned = rawResults.length;\n\n for (const result of rawResults) {\n if (result.messages.length === 0) continue;\n\n const relPath = path.relative(process.cwd(), result.filePath);\n const aiGuardIssues: IssueDetail[] = [];\n let fileErrors = 0;\n let fileWarnings = 0;\n\n for (const m of result.messages) {\n const source = classifyMessage(m);\n\n if (source === 'parser-error') {\n parserErrors.push({\n filePath: relPath,\n message: m.message,\n line: m.line ?? 0,\n });\n continue;\n }\n\n if (source === 'ecosystem') {\n ecosystemIssues.push({\n type: classifyEcosystemType(m),\n ruleId: m.ruleId,\n message: m.message,\n filePath: relPath,\n line: m.line ?? 0,\n column: m.column ?? 0,\n });\n continue;\n }\n\n // source === 'ai-guard'\n const issue: IssueDetail = {\n ruleId: m.ruleId ?? 'unknown',\n severity: m.severity as 1 | 2,\n message: m.message,\n line: m.line,\n column: m.column,\n };\n\n aiGuardIssues.push(issue);\n\n if (m.severity === 2) {\n fileErrors++;\n totalErrors++;\n } else {\n fileWarnings++;\n totalWarnings++;\n }\n\n ruleBreakdown.set(\n issue.ruleId,\n (ruleBreakdown.get(issue.ruleId) ?? 0) + 1,\n );\n }\n\n if (aiGuardIssues.length > 0) {\n files.push({\n filePath: relPath,\n issues: aiGuardIssues,\n errorCount: fileErrors,\n warningCount: fileWarnings,\n });\n }\n }\n\n const topFiles = [...files]\n .sort((a, b) => b.issues.length - a.issues.length)\n .slice(0, 10)\n .map((f) => ({ path: f.filePath, count: f.issues.length }));\n\n timing.processMs = Date.now() - processStart;\n\n if (options.debugTiming) {\n log.debug(`Plugin load: ${timing.pluginLoadMs}ms`);\n log.debug(`Parser load: ${timing.parserLoadMs}ms`);\n log.debug(`Lint: ${timing.lintMs}ms`);\n log.debug(`Process: ${timing.processMs}ms`);\n log.debug(`Total: ${Date.now() - overallStart}ms`);\n }\n\n return {\n files,\n totalErrors,\n totalWarnings,\n totalIssues: totalErrors + totalWarnings,\n filesScanned,\n ruleBreakdown,\n topFiles,\n durationMs: Date.now() - overallStart,\n timing,\n ecosystemIssues,\n parserErrors,\n tsParserAvailable,\n };\n}\n","import chalk from 'chalk';\nimport type { EcosystemIssue, ParserError } from '../utils/eslint-runner.js';\n\n// ── Category icon + color map ──────────────────────────────────────────────────\n\nconst CATEGORY_ICONS: Record<string, string> = {\n Security: '🔴',\n Reliability: '🟠',\n 'Async Stability': '🟡',\n 'AI Patterns': '🔵',\n};\n\nconst CATEGORY_ORDER = ['Security', 'Reliability', 'Async Stability', 'AI Patterns'];\n\nexport { CATEGORY_ICONS, CATEGORY_ORDER };\n\n// ── Rule → category map ────────────────────────────────────────────────────────\n\nexport const RULE_CATEGORY: Record<string, string> = {\n 'ai-guard/no-empty-catch': 'Reliability',\n 'ai-guard/no-broad-exception': 'Reliability',\n 'ai-guard/no-catch-log-rethrow': 'Reliability',\n 'ai-guard/no-catch-without-use': 'Reliability',\n 'ai-guard/no-floating-promise': 'Async Stability',\n 'ai-guard/no-await-in-loop': 'Async Stability',\n 'ai-guard/no-async-array-callback': 'Async Stability',\n 'ai-guard/no-async-without-await': 'Async Stability',\n 'ai-guard/no-redundant-await': 'Async Stability',\n 'ai-guard/no-hardcoded-secret': 'Security',\n 'ai-guard/no-eval-dynamic': 'Security',\n 'ai-guard/no-sql-string-concat': 'Security',\n 'ai-guard/no-unsafe-deserialize': 'Security',\n 'ai-guard/require-auth-middleware': 'Security',\n 'ai-guard/require-authz-check': 'Security',\n 'ai-guard/no-console-in-handler': 'AI Patterns',\n 'ai-guard/no-duplicate-logic-block': 'AI Patterns',\n 'ai-guard/no-dead-branch': 'AI Patterns',\n};\n\n// ── Confidence tiers ──────────────────────────────────────────────────────────\n// high = very low FP rate, high signal, should always be investigated\n// medium = moderate confidence, context-dependent\n// low = style/suggestion level, may have intentional exceptions\n\nexport const CONFIDENCE_TIER: Record<string, 'high' | 'medium' | 'low'> = {\n // High confidence — near-zero false positive rate\n 'ai-guard/no-hardcoded-secret': 'high',\n 'ai-guard/no-eval-dynamic': 'high',\n 'ai-guard/no-floating-promise': 'high',\n 'ai-guard/no-empty-catch': 'high',\n // Medium confidence — context matters, usually valid\n 'ai-guard/no-sql-string-concat': 'medium',\n 'ai-guard/no-await-in-loop': 'medium',\n 'ai-guard/require-auth-middleware': 'medium',\n 'ai-guard/require-authz-check': 'medium',\n 'ai-guard/no-catch-log-rethrow': 'medium',\n 'ai-guard/no-catch-without-use': 'medium',\n 'ai-guard/no-unsafe-deserialize': 'medium',\n // Low confidence — suggestions, may be intentional\n 'ai-guard/no-async-without-await': 'low',\n 'ai-guard/no-async-array-callback': 'low',\n 'ai-guard/no-dead-branch': 'low',\n 'ai-guard/no-broad-exception': 'low',\n 'ai-guard/no-console-in-handler': 'low',\n 'ai-guard/no-duplicate-logic-block': 'low',\n 'ai-guard/no-redundant-await': 'low',\n};\n\n// ── Ecosystem issue fix suggestions ──────────────────────────────────────────\n\nconst ECOSYSTEM_FIX_HINTS: Record<string, string> = {\n 'react-hooks/exhaustive-deps': 'npm install --save-dev eslint-plugin-react-hooks',\n 'react-hooks/rules-of-hooks': 'npm install --save-dev eslint-plugin-react-hooks',\n '@typescript-eslint/': 'npm install --save-dev @typescript-eslint/eslint-plugin @typescript-eslint/parser',\n 'import/': 'npm install --save-dev eslint-plugin-import',\n 'jsx-a11y/': 'npm install --save-dev eslint-plugin-jsx-a11y',\n 'prettier/': 'npm install --save-dev eslint-plugin-prettier',\n};\n\nfunction getEcosystemFix(ruleId: string | null): string | null {\n if (!ruleId) return null;\n for (const [prefix, fix] of Object.entries(ECOSYSTEM_FIX_HINTS)) {\n if (ruleId.startsWith(prefix)) return fix;\n }\n return null;\n}\n\n// ── Logger ────────────────────────────────────────────────────────────────────\n\nconst PREFIX = {\n success: chalk.green('✔'),\n error: chalk.red('✖'),\n warn: chalk.yellow('⚠'),\n info: chalk.cyan('ℹ'),\n section: chalk.bold.white,\n bullet: chalk.gray('•'),\n ecosystem: chalk.yellow('⚠'),\n parser: chalk.magenta('⚡'),\n};\n\nexport const log = {\n info(msg: string): void {\n console.log(` ${PREFIX.info} ${chalk.white(msg)}`);\n },\n\n success(msg: string): void {\n console.log(` ${PREFIX.success} ${chalk.green(msg)}`);\n },\n\n warn(msg: string): void {\n console.log(` ${PREFIX.warn} ${chalk.yellow(msg)}`);\n },\n\n error(msg: string): void {\n console.error(` ${PREFIX.error} ${chalk.red(msg)}`);\n },\n\n section(title: string): void {\n console.log('');\n console.log(chalk.bold.cyan(` ── ${title} ──`));\n console.log('');\n },\n\n /**\n * Ecosystem section — distinct styling to communicate it's NOT ai-guard output\n */\n ecosystemSection(title: string): void {\n console.log('');\n console.log(chalk.bold.yellow(` ── ${title} ──`) + chalk.dim(' (not ai-guard findings)'));\n console.log('');\n },\n\n rule(ruleName: string, count: number): void {\n console.log(\n ` ${PREFIX.bullet} ${chalk.yellow(ruleName)} ${chalk.gray(`(${count} issue${count !== 1 ? 's' : ''})`)}`,\n );\n },\n\n file(filePath: string, count: number): void {\n console.log(\n ` ${PREFIX.bullet} ${chalk.white(filePath)} ${chalk.gray(`→ ${count} issue${count !== 1 ? 's' : ''}`)}`,\n );\n },\n\n issue(msg: string, severity: 1 | 2, line: number, col: number): void {\n const icon = severity === 2 ? chalk.red('error') : chalk.yellow(' warn');\n console.log(\n ` ${chalk.gray(`${line}:${col}`).padEnd(12)} ${icon} ${chalk.white(msg)}`,\n );\n },\n\n /**\n * Print an ESLint ecosystem issue (missing rule definition, foreign plugin rule, etc.)\n * with a clear disclaimer that this is NOT an ai-guard finding.\n */\n ecosystemIssue(issue: EcosystemIssue, count = 1): void {\n const ruleLabel = issue.ruleId ? chalk.yellow(issue.ruleId) : chalk.gray('(no rule id)');\n const typeLabel =\n issue.type === 'missing-rule'\n ? chalk.dim('[missing rule definition]')\n : issue.type === 'config-error'\n ? chalk.dim('[config error]')\n : chalk.dim('[foreign rule]');\n\n const countLabel = count > 1 ? chalk.gray(` × ${count}`) : '';\n\n console.log(` ${PREFIX.ecosystem} ${ruleLabel} ${typeLabel}${countLabel}`);\n console.log(` ${chalk.gray('File:')} ${chalk.dim(issue.filePath)}${issue.line > 0 ? chalk.dim(`:${issue.line}`) : ''}`);\n console.log(` ${chalk.gray('Msg:')} ${chalk.dim(issue.message.slice(0, 120))}`);\n\n const fix = getEcosystemFix(issue.ruleId);\n if (fix) {\n console.log(` ${chalk.cyan('→ Fix:')} ${chalk.yellow(fix)}`);\n }\n console.log(\n chalk.dim(` Note: This comes from your ESLint config, not from ai-guard.`),\n );\n console.log('');\n },\n\n /**\n * Print a parser/syntax error — clearly NOT an ai-guard finding.\n */\n parserError(pe: ParserError): void {\n console.log(` ${PREFIX.parser} ${chalk.magenta('Parse failure')} ${chalk.dim(pe.filePath)}${pe.line > 0 ? chalk.dim(`:${pe.line}`) : ''}`);\n console.log(` ${chalk.dim(pe.message.slice(0, 120))}`);\n console.log('');\n },\n\n /**\n * Print a category summary line with icon, label, and count.\n */\n category(icon: string, label: string, errors: number, warnings: number): void {\n const parts: string[] = [];\n if (errors > 0) parts.push(chalk.red(`${errors} error${errors !== 1 ? 's' : ''}`));\n if (warnings > 0) parts.push(chalk.yellow(`${warnings} warning${warnings !== 1 ? 's' : ''}`));\n const counts = parts.length > 0 ? parts.join(chalk.gray(' · ')) : chalk.gray('0');\n const labelPadded = label.padEnd(18);\n console.log(` ${icon} ${chalk.bold.white(labelPadded)} ${counts}`);\n },\n\n /**\n * Print the scan stats line.\n */\n scanStats(filesScanned: number, filesWithIssues: number, durationMs: number, preset: string): void {\n console.log(\n ` ${chalk.gray('Files scanned:')} ${chalk.white(String(filesScanned))} ` +\n `${chalk.gray('·')} ${chalk.gray('Issues in:')} ${chalk.white(String(filesWithIssues))} file${filesWithIssues !== 1 ? 's' : ''} ` +\n `${chalk.gray('·')} ${chalk.gray('Duration:')} ${chalk.white(durationMs + 'ms')} ` +\n `${chalk.gray('·')} ${chalk.gray('Preset:')} ${chalk.cyan(preset)}`,\n );\n },\n\n divider(): void {\n console.log(chalk.gray(' ' + '─'.repeat(60)));\n },\n\n blank(): void {\n console.log('');\n },\n\n banner(title: string): void {\n console.log('');\n console.log(chalk.bold.bgCyan.black(` ${title} `));\n console.log('');\n },\n\n print(msg: string): void {\n console.log(msg);\n },\n\n debug(msg: string): void {\n if (process.env.AI_GUARD_DEBUG === '1') {\n console.log(` ${chalk.gray('·')} ${chalk.gray(msg)}`);\n }\n },\n};\n","import type { Command } from 'commander';\nimport chalk from 'chalk';\nimport path from 'path';\nimport fs from 'fs';\nimport { detect, isFlat, isLegacy, requiresFlatConfig } from '../utils/detector.js';\nimport {\n generateFlatConfig,\n generateLegacyConfig,\n patchFlatConfig,\n patchLegacyConfig,\n backupConfig,\n readConfig,\n writeConfig,\n getConfigFilePath,\n removeNukeIgnore,\n validateFlatConfigText,\n validateLegacyConfigText,\n type Preset,\n} from '../utils/config-manager.js';\nimport { log } from '../utils/logger.js';\n\n// ─── Flags ────────────────────────────────────────────────────────────────────\n\ninterface InitOptions {\n preset: string;\n flat?: boolean;\n dryRun?: boolean;\n}\n\n// ─── Error classification ────────────────────────────────────────────────────\n\ntype VerifyError =\n | { kind: 'syntax'; message: string }\n | { kind: 'module-not-found'; pkg: string; message: string }\n | { kind: 'unknown'; message: string };\n\nfunction classifyVerifyError(err: unknown): VerifyError {\n const msg = err instanceof Error ? err.message : String(err);\n const clean = msg.replace(/\\s+at\\s+.+/gm, '').trim();\n\n // Module resolution errors\n const modNotFound = clean.match(\n /Cannot find module '([^']+)'|Cannot find package '([^']+)'/,\n );\n if (modNotFound) {\n const pkg = modNotFound[1] ?? modNotFound[2] ?? 'unknown';\n return { kind: 'module-not-found', pkg, message: clean };\n }\n\n // SyntaxError / parse errors\n if (\n clean.includes('SyntaxError') ||\n clean.includes('Unexpected token') ||\n clean.includes('Invalid or unexpected token')\n ) {\n return { kind: 'syntax', message: clean };\n }\n\n return { kind: 'unknown', message: clean };\n}\n\n// ─── Programmatic ESLint verification ────────────────────────────────────────\n\n/**\n * After writing a config, try to load it via ESLint's own API.\n * Returns null on success, a classified error on failure.\n */\nasync function verifyConfigLoads(\n configPath: string,\n cwd: string,\n): Promise<null | VerifyError> {\n try {\n type EslintCtor = new (options: {\n cwd: string;\n overrideConfigFile: string;\n }) => {\n lintText: (code: string, options: { filePath: string }) => Promise<unknown>;\n };\n\n const { ESLint } = await import('eslint') as unknown as { ESLint: EslintCtor };\n\n const eslint = new ESLint({\n cwd,\n overrideConfigFile: configPath,\n });\n\n // Lint an empty JS file — forces ESLint to parse and validate the config\n await eslint.lintText('', {\n filePath: path.join(cwd, '_ai_guard_probe_.js'),\n });\n return null; // success\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n\n // \"No files\" / probe path exclusion errors are not config errors\n if (\n msg.includes('No files matching') ||\n msg.includes('_ai_guard_probe_')\n ) {\n return null;\n }\n\n return classifyVerifyError(err);\n }\n}\n\n// ─── Command registration ─────────────────────────────────────────────────────\n\nexport function registerInitCommand(program: Command): void {\n program\n .command('init')\n .description('Configure eslint-plugin-ai-guard in this project')\n .option('--preset <name>', 'Preset to use: recommended | strict | security', 'recommended')\n .option('--flat', 'Force flat config format (eslint.config.mjs) regardless of ESLint version')\n .option('--dry-run', 'Preview what would change without writing any files')\n .action(async (opts: InitOptions) => {\n const preset = (opts.preset as Preset) ?? 'recommended';\n const cwd = process.cwd();\n const isDryRun = opts.dryRun === true;\n\n log.banner('AI GUARD INIT');\n if (isDryRun) {\n log.print(` ${chalk.yellow('⚑ DRY RUN — no files will be written')}`);\n log.blank();\n }\n log.info('Detecting your project setup…');\n log.blank();\n\n const env = detect(cwd);\n\n // ─── Step 1: Environment report ──────────────────────────────────────────\n\n log.section('Environment');\n\n if (env.eslintVersion) {\n log.success(`ESLint ${env.eslintVersion} detected (v${env.eslintMajor})`);\n } else {\n log.warn('ESLint not found in node_modules');\n }\n\n if (env.pluginInstalled) {\n log.success('eslint-plugin-ai-guard is installed');\n } else {\n log.warn('eslint-plugin-ai-guard not found');\n }\n\n if (env.configType !== 'none') {\n log.success(`ESLint config found: ${chalk.white(path.relative(cwd, env.configPath ?? env.configType))}`);\n } else {\n log.info('No ESLint config found — will generate one');\n }\n\n // Warn about conflicting configs (only if not ESLint v9, as v9 auto-resolves)\n const eslintNeedsFlat = requiresFlatConfig(env.eslintMajor);\n if (env.hasConflictingConfigs && !eslintNeedsFlat) {\n log.blank();\n log.warn('Conflicting configs detected:');\n for (const p of env.allConfigPaths) {\n log.print(` ${chalk.yellow('→')} ${chalk.white(path.relative(cwd, p))}`);\n }\n log.print(` ${chalk.gray('Multiple config formats found — this can cause unpredictable behavior.')}`);\n }\n\n log.blank();\n\n // ─── Step 2: Gate on missing deps ────────────────────────────────────────\n\n const toInstall: string[] = [];\n if (!env.eslintVersion) toInstall.push('eslint');\n if (!env.pluginInstalled) toInstall.push('eslint-plugin-ai-guard');\n\n if (toInstall.length > 0) {\n log.section('Missing Dependencies');\n log.warn('The following packages are not installed:');\n log.blank();\n for (const pkg of toInstall) {\n log.print(` ${chalk.yellow('→')} ${chalk.white(pkg)}`);\n }\n log.blank();\n log.print(` ${chalk.bold('Run this first:')}`);\n log.blank();\n log.print(` ${chalk.cyan(`npm install --save-dev ${toInstall.join(' ')}`)}`);\n log.blank();\n log.print(` Then re-run ${chalk.cyan('ai-guard init')} to complete setup.`);\n log.blank();\n process.exit(1);\n return;\n }\n\n // ─── Step 3: Runtime Safety ─────────────────────────────────────────────\n\n try {\n const { createRequire } = await import('module');\n const { pathToFileURL } = await import('url');\n const req = createRequire(path.join(cwd, '_probe.js'));\n const resolvedPath = req.resolve('eslint-plugin-ai-guard');\n const aiGuard = await import(pathToFileURL(resolvedPath).href);\n const plugin = (aiGuard.default || aiGuard) as {\n configs?: Record<string, { rules?: unknown }>;\n };\n\n const hasPresetRules =\n !!plugin.configs &&\n !!plugin.configs[preset] &&\n !!plugin.configs[preset].rules;\n\n if (!hasPresetRules) {\n // Keep this as informational only; Step 6 performs definitive runtime validation.\n log.debug('Plugin precheck could not verify configs shape; continuing to validation step.');\n }\n } catch (e) {\n // If resolution fails entirely, skip the check; validation step will catch load errors\n const reason = e instanceof Error ? e.message : String(e);\n log.debug(`Skipped plugin precheck: ${reason}`);\n }\n\n // ─── Step 4: Determine config format ────────────────────────────────────\n // Priority:\n // 1. --flat flag forces flat config\n // 2. ESLint v9+ → MUST use flat config\n // 3. ESLint v8 → use legacy; unless an existing flat config is already there\n // 4. No version info → default to flat (safer)\n\n const forceFlat = opts.flat === true;\n const existingIsFlat = isFlat(env.configType);\n const existingIsLegacy = isLegacy(env.configType);\n const useFlat = forceFlat || eslintNeedsFlat || existingIsFlat || env.configType === 'none';\n\n // Guard: ESLint v9 + existing legacy config → migrate, don't re-create legacy\n if (eslintNeedsFlat && existingIsLegacy) {\n log.section('Config Migration Required');\n log.warn(`ESLint v${env.eslintMajor} requires flat config, but a legacy config was found:`);\n log.print(` ${chalk.white(path.relative(cwd, env.configPath!))}`);\n log.blank();\n log.print(` ${chalk.bold('ai-guard will create a new flat config.')}`);\n log.blank();\n }\n\n // ─── Step 5: Apply config change ────────────────────────────────────────\n\n log.section(`Configuring ESLint${isDryRun ? ' (dry run)' : ''}`);\n\n let finalConfigPath: string;\n let configWritten = false;\n\n // Nuke-ignore removal — fix before anything else\n if (env.configPath && env.hasNukeIgnore) {\n const raw = readConfig(env.configPath);\n const { content: fixed, changed } = removeNukeIgnore(raw);\n if (changed) {\n log.warn(`Removed \"**/*\" ignore pattern from ${path.relative(cwd, env.configPath)}`);\n if (!isDryRun) {\n backupConfig(env.configPath);\n writeConfig(env.configPath, fixed);\n log.success('Ignore pattern fixed');\n } else {\n log.print(` ${chalk.gray('[dry-run] would remove nuke-ignore from existing config')}`);\n }\n }\n }\n\n if (env.configType === 'none' || (eslintNeedsFlat && existingIsLegacy)) {\n // ── Generate fresh config ──────────────────────────────────────────────\n const targetName = useFlat ? 'eslint.config.mjs' : '.eslintrc.js';\n finalConfigPath = path.join(cwd, targetName);\n\n const content = useFlat\n ? generateFlatConfig(preset)\n : generateLegacyConfig(preset);\n\n if (isDryRun) {\n log.print(` ${chalk.gray(`[dry-run] would create: ${targetName}`)}`);\n log.blank();\n log.print(chalk.gray('─── Preview ─────────────────────────────────────────────'));\n log.blank();\n for (const line of content.split('\\n')) {\n log.print(chalk.gray(` ${line}`));\n }\n log.blank();\n } else {\n writeConfig(finalConfigPath, content);\n log.success(`Created ${chalk.white(targetName)}`);\n log.info(` Preset: ${chalk.cyan(preset)}`);\n log.info(` Format: ${chalk.cyan(useFlat ? 'ESLint v9 flat config (eslint.config.mjs)' : 'ESLint v8 legacy config (.eslintrc.js)')}`);\n configWritten = true;\n }\n } else if (useFlat && existingIsFlat) {\n // ── Patch existing flat config ─────────────────────────────────────────\n const { isInvalidAiGuardConfig } = await import('../utils/config-manager.js');\n const existing = readConfig(env.configPath!);\n const isInvalid = isInvalidAiGuardConfig(existing);\n const patched = patchFlatConfig(existing, preset);\n\n if (patched === existing && !isInvalid) {\n log.warn('ai-guard is already present in your config — no changes made');\n finalConfigPath = env.configPath!;\n } else if (isDryRun) {\n finalConfigPath = env.configPath!;\n log.print(` ${chalk.gray(`[dry-run] would patch: ${path.relative(cwd, env.configPath!)}`)}`);\n } else {\n const bak = backupConfig(env.configPath!);\n log.info(`Backed up → ${chalk.gray(path.relative(cwd, bak))}`);\n writeConfig(env.configPath!, patched);\n if (isInvalid) {\n log.success(`Detected invalid ai-guard config — repairing ${chalk.white(path.relative(cwd, env.configPath!))}`);\n } else {\n log.success(`Patched ${chalk.white(path.relative(cwd, env.configPath!))}`);\n }\n finalConfigPath = env.configPath!;\n configWritten = true;\n }\n } else {\n // ── Patch existing legacy config ─────────────────────────────────────\n const existing = readConfig(env.configPath!);\n const patched = patchLegacyConfig(existing, preset);\n\n if (patched === existing) {\n log.warn('ai-guard is already present in your config — no changes made');\n finalConfigPath = env.configPath!;\n } else if (isDryRun) {\n finalConfigPath = env.configPath!;\n log.print(` ${chalk.gray(`[dry-run] would patch: ${path.relative(cwd, env.configPath!)}`)}`);\n } else {\n const bak = backupConfig(env.configPath!);\n log.info(`Backed up → ${chalk.gray(path.relative(cwd, bak))}`);\n writeConfig(env.configPath!, patched);\n log.success(`Patched ${chalk.white(path.relative(cwd, env.configPath!))}`);\n finalConfigPath = env.configPath!;\n configWritten = true;\n }\n }\n\n // ── Auto cleanup legacy config (conflict resolution) ───────────────\n if (eslintNeedsFlat) {\n // Find legacy configs that might cause conflicts\n const legacyConfigs = env.allConfigPaths.filter(p => !p.includes('eslint.config.'));\n \n let cleanedUp = false;\n for (const p of legacyConfigs) {\n if (fs.existsSync(p)) {\n if (!isDryRun) {\n try {\n fs.renameSync(p, `${p}.bak`);\n cleanedUp = true;\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n log.warn(`Could not back up ${path.relative(cwd, p)}: ${reason}`);\n }\n } else {\n cleanedUp = true;\n log.print(` ${chalk.gray(`[dry-run] would rename ${path.relative(cwd, p)} to ${path.basename(p)}.bak`)}`);\n }\n }\n }\n if (cleanedUp && !isDryRun) {\n log.success('Legacy config backed up to avoid ESLint conflict');\n }\n }\n\n if (isDryRun) {\n log.blank();\n log.print(` ${chalk.yellow('Dry run complete — no files written.')}`);\n log.print(` Re-run without ${chalk.cyan('--dry-run')} to apply.`);\n log.blank();\n process.exit(0);\n return;\n }\n\n log.blank();\n\n // ─── Step 5: Structural validation ──────────────────────────────────────\n\n log.section('Validation');\n\n if (!fs.existsSync(finalConfigPath)) {\n log.error(`Config file not found after write: ${path.relative(cwd, finalConfigPath)}`);\n log.blank();\n log.print(` ${chalk.bold('Problem:')} File write may have failed.`);\n log.print(` ${chalk.bold('Fix:')} Check disk space and file permissions, then re-run.`);\n log.blank();\n process.exit(1);\n return;\n }\n\n const content = readConfig(finalConfigPath);\n const validationErrors = useFlat\n ? validateFlatConfigText(content)\n : validateLegacyConfigText(content);\n\n if (validationErrors.length > 0) {\n log.warn('Config validation found issues:');\n for (const e of validationErrors) {\n log.print(` ${chalk.red('✖')} ${e}`);\n }\n } else {\n log.success(`Config structure valid: ${chalk.white(path.relative(cwd, finalConfigPath))}`);\n }\n\n // ─── Step 6: Programmatic ESLint load verification ───────────────────────\n\n log.info('Verifying ESLint can load the config…');\n\n const loadError = await verifyConfigLoads(finalConfigPath, cwd);\n if (loadError !== null) {\n log.blank();\n\n if (loadError.kind === 'module-not-found') {\n // Missing dep — config syntax is fine, just need to install the package\n log.warn(`Could not verify: module not found: ${chalk.yellow(loadError.pkg)}`);\n log.blank();\n log.print(` ${chalk.bold('Install the missing package:')}`);\n log.print(` ${chalk.cyan(`npm install --save-dev ${loadError.pkg}`)}`);\n log.print(` Then run ${chalk.cyan('ai-guard doctor')} to confirm.`);\n log.blank();\n // Fall through — config was written correctly; missing dep is user's next step\n } else {\n // Real error — config syntax broken or unknown failure → hard fail\n log.error('ESLint failed to load the generated config.');\n log.blank();\n log.print(` ${chalk.bold('Problem:')}`);\n log.print(` ${chalk.red(loadError.message)}`);\n if (loadError.kind === 'unknown') {\n log.blank();\n log.print(` ${chalk.yellow('Generated config may be using incorrect plugin structure.')}`);\n }\n log.blank();\n log.print(` ${chalk.bold('Fix:')}`);\n log.print(` 1. Check the syntax in ${chalk.cyan(path.relative(cwd, finalConfigPath))}`);\n log.print(` 2. Make sure ${chalk.cyan('eslint-plugin-ai-guard')} is installed`);\n log.print(` 3. Run ${chalk.cyan('ai-guard doctor')} for full diagnostics`);\n log.blank();\n process.exit(1);\n return;\n }\n } else {\n log.success('ESLint loaded config successfully');\n }\n\n\n log.blank();\n\n\n\n // ─── Step 7: Success ─────────────────────────────────────────────────────\n\n log.section('Setup Complete');\n log.blank();\n\n let cleanedUpInfo = false;\n if (eslintNeedsFlat) {\n const legacyConfigs = env.allConfigPaths.filter(p => !p.includes('eslint.config.'));\n cleanedUpInfo = legacyConfigs.some(p => fs.existsSync(`${p}.bak`) && !fs.existsSync(p));\n }\n\n const lingeringConflicts = env.hasConflictingConfigs && !eslintNeedsFlat && !cleanedUpInfo;\n if (loadError === null && !lingeringConflicts) {\n log.print(` ${chalk.green('✔')} ${chalk.bold.green('Configuration validated successfully')}`);\n }\n log.print(` ${chalk.green('✔')} ${chalk.bold('ESLint config:')} ${chalk.cyan(path.relative(cwd, finalConfigPath))}`);\n log.print(` ${chalk.green('✔')} ${chalk.bold('Mode:')} ${chalk.cyan(useFlat ? `Flat config (ESLint v${env.eslintMajor ?? 9})` : `Legacy config (ESLint v${env.eslintMajor ?? 8})`)}`);\n log.print(` ${chalk.green('✔')} ${chalk.bold('Preset:')} ${chalk.cyan(preset)}`);\n log.blank();\n log.info(`Run ${chalk.cyan('npx eslint .')} → lint with your editor integration`);\n log.info(`Run ${chalk.cyan('ai-guard run')} → zero-config scan`);\n log.info(`Run ${chalk.cyan('ai-guard doctor')} → verify the full setup`);\n log.info(`Run ${chalk.cyan('ai-guard baseline')} → save baseline, track only new issues`);\n log.blank();\n });\n}\n","import fs from 'fs';\r\nimport path from 'path';\r\nimport { createRequire } from 'module';\r\n\r\n// ─── Types ────────────────────────────────────────────────────────────────────\r\n\r\nexport type ConfigType =\r\n | 'flat-js'\r\n | 'flat-mjs'\r\n | 'flat-cjs'\r\n | 'eslintrc-js'\r\n | 'eslintrc-cjs'\r\n | 'eslintrc-json'\r\n | 'eslintrc-yaml'\r\n | 'none';\r\n\r\nexport interface DetectionResult {\r\n /** Raw version string e.g. \"9.1.0\" — null if not installed */\r\n eslintVersion: string | null;\r\n eslintMajor: number | null;\r\n pluginInstalled: boolean;\r\n configType: ConfigType;\r\n configPath: string | null;\r\n /** All config files found — to detect conflicts */\r\n allConfigPaths: string[];\r\n /** True when a flat config AND a legacy config both exist */\r\n hasConflictingConfigs: boolean;\r\n /** True when config contains a pattern that ignores everything */\r\n hasNukeIgnore: boolean;\r\n}\r\n\r\n// ─── Config file registry ─────────────────────────────────────────────────────\r\n\r\nconst FLAT_CONFIG_FILES: Array<{ file: string; type: ConfigType }> = [\r\n { file: 'eslint.config.js', type: 'flat-js' },\r\n { file: 'eslint.config.mjs', type: 'flat-mjs' },\r\n { file: 'eslint.config.cjs', type: 'flat-cjs' },\r\n];\r\n\r\nconst LEGACY_CONFIG_FILES: Array<{ file: string; type: ConfigType }> = [\r\n { file: '.eslintrc.js', type: 'eslintrc-js' },\r\n { file: '.eslintrc.cjs', type: 'eslintrc-cjs' },\r\n { file: '.eslintrc.json', type: 'eslintrc-json' },\r\n { file: '.eslintrc.yaml', type: 'eslintrc-yaml' },\r\n { file: '.eslintrc.yml', type: 'eslintrc-yaml' },\r\n];\r\n\r\nconst ALL_CONFIG_FILES = [...FLAT_CONFIG_FILES, ...LEGACY_CONFIG_FILES];\r\n\r\n// ─── Helpers ──────────────────────────────────────────────────────────────────\r\n\r\nexport function isPackageInstalled(pkgName: string, cwd = process.cwd()): boolean {\r\n try {\r\n const pkgPath = path.join(cwd, 'node_modules', pkgName, 'package.json');\r\n if (fs.existsSync(pkgPath)) {\r\n return true;\r\n }\r\n\r\n const req = createRequire(path.join(cwd, 'package.json'));\r\n req.resolve(`${pkgName}/package.json`);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Read a package.json version from node_modules.\r\n * Reads directly from disk — no require() involvement — so it always\r\n * reflects the *installed* version even when running inside a bundled binary.\r\n */\r\nexport function getPackageVersion(pkgName: string, cwd = process.cwd()): string | null {\r\n try {\r\n const pkgPath = path.join(cwd, 'node_modules', pkgName, 'package.json');\r\n const resolvedPath = fs.existsSync(pkgPath)\r\n ? pkgPath\r\n : createRequire(path.join(cwd, 'package.json')).resolve(`${pkgName}/package.json`);\r\n const raw = fs.readFileSync(resolvedPath, 'utf-8');\r\n const json = JSON.parse(raw) as { version?: string };\r\n return json.version ?? null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/** Parse the major version number from a semver string */\r\nexport function parseMajor(version: string | null): number | null {\r\n if (!version) return null;\r\n const n = parseInt(version.split('.')[0], 10);\r\n return isNaN(n) ? null : n;\r\n}\r\n\r\n// ─── Config detection ─────────────────────────────────────────────────────────\r\n\r\nexport function detectConfigType(cwd = process.cwd()): {\r\n type: ConfigType;\r\n path: string | null;\r\n allPaths: string[];\r\n} {\r\n const found: string[] = [];\r\n let first: { type: ConfigType; path: string } | null = null;\r\n\r\n for (const { file, type } of ALL_CONFIG_FILES) {\r\n const fullPath = path.join(cwd, file);\r\n if (fs.existsSync(fullPath)) {\r\n found.push(fullPath);\r\n if (!first) first = { type, path: fullPath };\r\n }\r\n }\r\n\r\n return {\r\n type: first?.type ?? 'none',\r\n path: first?.path ?? null,\r\n allPaths: found,\r\n };\r\n}\r\n\r\nexport function isFlat(type: ConfigType): boolean {\r\n return type === 'flat-js' || type === 'flat-mjs' || type === 'flat-cjs';\r\n}\r\n\r\nexport function isLegacy(type: ConfigType): boolean {\r\n return (\r\n type === 'eslintrc-js' ||\r\n type === 'eslintrc-cjs' ||\r\n type === 'eslintrc-json' ||\r\n type === 'eslintrc-yaml'\r\n );\r\n}\r\n\r\n/**\r\n * Returns true if the given ESLint major version requires flat config.\r\n * ESLint 9+ uses flat config by default; ESLint 8 uses legacy config.\r\n */\r\nexport function requiresFlatConfig(eslintMajor: number | null): boolean {\r\n return eslintMajor !== null && eslintMajor >= 9;\r\n}\r\n\r\n/**\r\n * Check for \"nuke\" ignore patterns — patterns that silently exclude all files.\r\n * Common culprit: ignorePatterns: [\"**\\/*\"] or ignores: [\"**\\/*\"]\r\n */\r\nfunction detectNukeIgnore(configPath: string | null): boolean {\r\n if (!configPath) return false;\r\n try {\r\n const content = fs.readFileSync(configPath, 'utf-8');\r\n return content.includes('\"**/*\"') || content.includes(\"'**/*'\");\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n// ─── Main detection entry point ───────────────────────────────────────────────\r\n\r\nexport function detect(cwd = process.cwd()): DetectionResult {\r\n const eslintVersion = getPackageVersion('eslint', cwd);\r\n const eslintMajor = parseMajor(eslintVersion);\r\n const pluginInstalled = isPackageInstalled('eslint-plugin-ai-guard', cwd);\r\n\r\n const { type: configType, path: configPath, allPaths } = detectConfigType(cwd);\r\n\r\n // Conflict: both flat AND legacy config files exist\r\n const hasFlatConfig = allPaths.some((p) =>\r\n FLAT_CONFIG_FILES.some((c) => p.endsWith(c.file)),\r\n );\r\n const hasLegacyConfig = allPaths.some((p) =>\r\n LEGACY_CONFIG_FILES.some((c) => p.endsWith(c.file)),\r\n );\r\n const hasConflictingConfigs = hasFlatConfig && hasLegacyConfig;\r\n\r\n const hasNukeIgnore = detectNukeIgnore(configPath);\r\n\r\n return {\r\n eslintVersion,\r\n eslintMajor,\r\n pluginInstalled,\r\n configType,\r\n configPath,\r\n allConfigPaths: allPaths,\r\n hasConflictingConfigs,\r\n hasNukeIgnore,\r\n };\r\n}\r\n\r\n// ─── Monorepo detection ────────────────────────────────────────────────────────\r\n\r\nexport interface MonorepoResult {\r\n isMonorepo: boolean;\r\n tool: 'pnpm' | 'npm-workspaces' | 'yarn-workspaces' | 'nx' | 'turborepo' | 'lerna' | null;\r\n packages: string[];\r\n}\r\n\r\nexport function detectMonorepo(cwd = process.cwd()): MonorepoResult {\r\n if (fs.existsSync(path.join(cwd, 'pnpm-workspace.yaml'))) {\r\n return { isMonorepo: true, tool: 'pnpm', packages: discoverWorkspacePackages(cwd) };\r\n }\r\n if (fs.existsSync(path.join(cwd, 'nx.json'))) {\r\n return { isMonorepo: true, tool: 'nx', packages: discoverWorkspacePackages(cwd) };\r\n }\r\n if (fs.existsSync(path.join(cwd, 'turbo.json'))) {\r\n return { isMonorepo: true, tool: 'turborepo', packages: discoverWorkspacePackages(cwd) };\r\n }\r\n if (fs.existsSync(path.join(cwd, 'lerna.json'))) {\r\n return { isMonorepo: true, tool: 'lerna', packages: discoverWorkspacePackages(cwd) };\r\n }\r\n try {\r\n const pkgPath = path.join(cwd, 'package.json');\r\n if (fs.existsSync(pkgPath)) {\r\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as {\r\n workspaces?: string[] | { packages?: string[] };\r\n };\r\n if (pkg.workspaces) {\r\n const tool = fs.existsSync(path.join(cwd, 'yarn.lock'))\r\n ? ('yarn-workspaces' as const)\r\n : ('npm-workspaces' as const);\r\n return { isMonorepo: true, tool, packages: discoverWorkspacePackages(cwd) };\r\n }\r\n }\r\n } catch { /* not a monorepo */ }\r\n return { isMonorepo: false, tool: null, packages: [] };\r\n}\r\n\r\nfunction discoverWorkspacePackages(cwd: string): string[] {\r\n const commonDirs = ['packages', 'apps', 'libs', 'modules', 'services'];\r\n const found: string[] = [];\r\n for (const dir of commonDirs) {\r\n const dirPath = path.join(cwd, dir);\r\n if (!fs.existsSync(dirPath)) continue;\r\n try {\r\n const entries = fs.readdirSync(dirPath, { withFileTypes: true });\r\n for (const entry of entries) {\r\n if (!entry.isDirectory()) continue;\r\n if (fs.existsSync(path.join(dirPath, entry.name, 'package.json'))) {\r\n found.push(path.join(dir, entry.name));\r\n }\r\n }\r\n } catch { /* skip */ }\r\n }\r\n return found;\r\n}\r\n","import type { Command } from 'commander';\nimport chalk from 'chalk';\nimport path from 'path';\nimport { detect, isFlat, isLegacy, requiresFlatConfig } from '../utils/detector.js';\nimport { log } from '../utils/logger.js';\nimport { readConfig } from '../utils/config-manager.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\ninterface CheckResult {\n label: string;\n pass: boolean;\n detail: string;\n /** Exact command or action to fix — shown as cyan */\n fix?: string;\n /** Additional explanation shown below fix as gray */\n note?: string;\n}\n\n// ─── Programmatic config load probe ──────────────────────────────────────────\n\nasync function probeConfigLoad(\n configPath: string,\n cwd: string,\n): Promise<{ ok: boolean; error: string | null }> {\n try {\n const { ESLint } = await import('eslint') as { ESLint: any };\n const eslint = new ESLint({ cwd, overrideConfigFile: configPath });\n await eslint.lintText('', { filePath: path.join(cwd, '_probe_.js') });\n return { ok: true, error: null };\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n // \"no files\" or \"probe\" errors are not config errors\n if (\n msg.includes('No files') ||\n msg.includes('no files') ||\n msg.includes('_probe_')\n ) {\n return { ok: true, error: null };\n }\n // Strip stack frames from message\n const clean = msg.replace(/\\s+at\\s+.+/gm, '').trim();\n return { ok: false, error: clean };\n }\n}\n\n// ─── Command ──────────────────────────────────────────────────────────────────\n\nexport function registerDoctorCommand(program: Command): void {\n program\n .command('doctor')\n .description('Diagnose your ai-guard setup and print actionable fixes')\n .action(async () => {\n const cwd = process.cwd();\n\n log.banner('AI GUARD DOCTOR');\n log.info('Checking your environment…');\n log.blank();\n\n const env = detect(cwd);\n const checks: CheckResult[] = [];\n\n // ── Check 1: ESLint installed ──────────────────────────────────────────\n\n checks.push({\n label: 'ESLint installed',\n pass: env.eslintVersion !== null,\n detail: env.eslintVersion\n ? `ESLint ${env.eslintVersion}`\n : 'Not found in node_modules',\n fix: env.eslintVersion\n ? undefined\n : 'npm install --save-dev eslint',\n });\n\n // ── Check 2: Plugin installed ──────────────────────────────────────────\n\n checks.push({\n label: 'eslint-plugin-ai-guard installed',\n pass: env.pluginInstalled,\n detail: env.pluginInstalled\n ? 'Found in node_modules'\n : 'Not found in node_modules',\n fix: env.pluginInstalled\n ? undefined\n : 'npm install --save-dev eslint-plugin-ai-guard',\n });\n\n // ── Check 3: ESLint config exists ─────────────────────────────────────\n\n const hasConfig = env.configType !== 'none';\n checks.push({\n label: 'ESLint config present',\n pass: hasConfig,\n detail: hasConfig\n ? `${path.relative(cwd, env.configPath ?? '')} (${env.configType})`\n : 'No eslint.config.* or .eslintrc.* found',\n fix: hasConfig\n ? undefined\n : 'ai-guard init',\n note: hasConfig\n ? undefined\n : 'This will generate the correct config format for your ESLint version',\n });\n\n // ── Check 4: Config type matches ESLint version ────────────────────────\n\n if (env.eslintMajor !== null && hasConfig) {\n const needsFlat = requiresFlatConfig(env.eslintMajor);\n const actuallyFlat = isFlat(env.configType);\n const actuallyLegacy = isLegacy(env.configType);\n const aligned =\n (needsFlat && actuallyFlat) || (!needsFlat && actuallyLegacy);\n\n checks.push({\n label: 'Config format matches ESLint version',\n pass: aligned,\n detail: aligned\n ? `${actuallyFlat ? 'Flat config' : 'Legacy config'} ✔ matches ESLint v${env.eslintMajor}`\n : `ESLint v${env.eslintMajor} requires ${needsFlat ? 'flat config (eslint.config.*)'\n : 'legacy config (.eslintrc.*)'} but found ${actuallyFlat ? 'flat' : 'legacy'} config`,\n fix: aligned\n ? undefined\n : needsFlat\n ? 'ai-guard init (will create eslint.config.mjs)'\n : 'npm install --save-dev eslint@8 (or upgrade to v9 and run ai-guard init)',\n note: aligned\n ? undefined\n : needsFlat\n ? 'ESLint v9 ignores .eslintrc.* files. The flat config must be used.'\n : undefined,\n });\n }\n\n // ── Check 5: Plugin wired in config ───────────────────────────────────\n\n if (hasConfig && env.configPath) {\n let pluginWired = false;\n let isInvalidConfig = false;\n let readError: string | null = null;\n try {\n const { isInvalidAiGuardConfig } = await import('../utils/config-manager.js');\n const content = readConfig(env.configPath);\n pluginWired =\n content.includes('ai-guard') ||\n content.includes('eslint-plugin-ai-guard');\n isInvalidConfig = isInvalidAiGuardConfig(content);\n } catch (err) {\n readError = err instanceof Error ? err.message : String(err);\n }\n\n checks.push({\n label: 'Plugin wired in config',\n pass: pluginWired && !isInvalidConfig,\n detail: readError\n ? `Could not read config: ${readError}`\n : isInvalidConfig\n ? 'Invalid ai-guard config detected (wrong export usage)'\n : pluginWired\n ? 'eslint-plugin-ai-guard referenced in config'\n : `Config exists but ai-guard plugin not found in ${path.relative(cwd, env.configPath)}`,\n fix: isInvalidConfig || (!pluginWired && !readError)\n ? 'ai-guard init (will patch/repair your existing config)'\n : undefined,\n });\n }\n\n // ── Check 6: No conflicting configs ───────────────────────────────────\n\n checks.push({\n label: 'No conflicting config files',\n pass: !env.hasConflictingConfigs,\n detail: env.hasConflictingConfigs\n ? `Conflicting config detected:\\n${env.allConfigPaths.map((p) => ` ${path.relative(cwd, p)}`).join('\\n')}`\n : 'Only one config format detected',\n fix: env.hasConflictingConfigs\n ? 'Remove or backup legacy config'\n : undefined,\n note: env.hasConflictingConfigs\n ? 'ESLint v9 silently ignores .eslintrc.* when a flat config exists. This can cause confusion.'\n : undefined,\n });\n\n // ── Check 7: No nuke-ignore pattern ───────────────────────────────────\n\n if (hasConfig && env.hasNukeIgnore) {\n checks.push({\n label: 'No \"ignore everything\" pattern',\n pass: false,\n detail: `Config contains \"**/*\" ignore pattern — this silently prevents all files from being linted`,\n fix: 'ai-guard init (will remove the pattern and replace with safe ignores)',\n });\n }\n\n // ── Check 8: ESLint version compatible ────────────────────────────────\n\n const versionOk = env.eslintMajor !== null && env.eslintMajor >= 8;\n checks.push({\n label: 'ESLint version compatible',\n pass: versionOk,\n detail: versionOk\n ? `v${env.eslintMajor} ✔ (requires ≥ v8)`\n : env.eslintMajor !== null\n ? `v${env.eslintMajor} is too old — requires ESLint ≥ 8`\n : 'ESLint not installed',\n fix: versionOk ? undefined : 'npm install --save-dev eslint@latest',\n });\n\n // ── Check 9: Programmatic config load ─────────────────────────────────\n // Only run this if we have a config and all prior config checks passed,\n // so we don't produce redundant errors.\n\n const configChecksPass = checks.every((c) => c.pass);\n if (hasConfig && env.configPath && env.pluginInstalled && configChecksPass) {\n log.info('Probing ESLint config load…');\n const probe = await probeConfigLoad(env.configPath, cwd);\n\n checks.push({\n label: 'ESLint config loads without errors',\n pass: probe.ok,\n detail: probe.ok\n ? 'ESLint loaded config successfully'\n : probe.error ?? 'Unknown error',\n fix: probe.ok\n ? undefined\n : `Check syntax in ${path.relative(cwd, env.configPath)}`,\n note: probe.ok\n ? undefined\n : 'Run: ai-guard init --dry-run to preview a fresh config',\n });\n }\n\n // ── Check 10: @typescript-eslint/utils resolvable at runtime ──────────\n {\n let utilsOk = false;\n let utilsVersion: string | null = null;\n try {\n const { createRequire } = await import('module');\n const req = createRequire(path.join(cwd, 'package.json'));\n const pkgPath = req.resolve('@typescript-eslint/utils/package.json');\n const pkg = JSON.parse(\n (await import('fs')).readFileSync(pkgPath, 'utf-8'),\n ) as { version?: string };\n utilsVersion = pkg.version ?? null;\n utilsOk = true;\n } catch {\n // Not found\n }\n\n if (!utilsOk) {\n // Fall back to checking our own package location\n try {\n const selfDir = path.dirname(\n new URL(import.meta.url).pathname.replace(/^\\/([A-Za-z]:)/, '$1'),\n );\n const pkgPath = path.join(selfDir, '../../node_modules/@typescript-eslint/utils/package.json');\n if ((await import('fs')).existsSync(pkgPath)) {\n utilsOk = true;\n }\n } catch { /* skip */ }\n }\n\n checks.push({\n label: '@typescript-eslint/utils available at runtime',\n pass: utilsOk,\n detail: utilsOk\n ? `Found${utilsVersion ? ` v${utilsVersion}` : ''}`\n : 'Not found — rule engine may crash on fresh installs',\n fix: utilsOk\n ? undefined\n : 'npm install @typescript-eslint/utils',\n note: utilsOk\n ? undefined\n : 'This is a runtime dependency of eslint-plugin-ai-guard rules.',\n });\n }\n\n // ── Check 11: @typescript-eslint/parser for TS projects ───────────────\n {\n let parserOk = false;\n let parserVersion: string | null = null;\n try {\n const { createRequire } = await import('module');\n const req = createRequire(path.join(cwd, 'package.json'));\n const pkgPath = req.resolve('@typescript-eslint/parser/package.json');\n const pkg = JSON.parse(\n (await import('fs')).readFileSync(pkgPath, 'utf-8'),\n ) as { version?: string };\n parserVersion = pkg.version ?? null;\n parserOk = true;\n } catch {\n // Optional — only needed for TS projects\n }\n\n const hasTsFiles = (() => {\n try {\n const { readdirSync } = require('fs');\n const files = readdirSync(cwd) as string[];\n return files.some((f: string) => f.endsWith('.ts') || f.endsWith('.tsx'));\n } catch {\n return false;\n }\n })();\n\n if (!parserOk && hasTsFiles) {\n checks.push({\n label: '@typescript-eslint/parser installed (TypeScript project)',\n pass: false,\n detail: '.ts/.tsx files detected but TypeScript parser not found',\n fix: 'npm install --save-dev @typescript-eslint/parser',\n note: 'TypeScript files will use espree fallback without this — some rules may not work correctly.',\n });\n }\n }\n\n // ─── Render results ────────────────────────────────────────────────────\n\n log.section('Diagnostics');\n\n let allPassed = true;\n for (const check of checks) {\n const icon = check.pass ? chalk.green('✔') : chalk.red('✖');\n const label = check.pass\n ? chalk.white(check.label)\n : chalk.red.bold(check.label);\n\n log.print(` ${icon} ${label}`);\n log.print(` ${chalk.gray(check.detail)}`);\n\n if (!check.pass) {\n allPassed = false;\n if (check.fix) {\n log.print(` ${chalk.cyan('→ Fix:')} ${chalk.yellow(check.fix)}`);\n }\n if (check.note) {\n log.print(` ${chalk.gray(check.note)}`);\n }\n }\n\n log.blank();\n }\n\n log.divider();\n log.blank();\n\n if (allPassed) {\n log.print(` ${chalk.green('✔')} ${chalk.bold.green('All checks passed! Your setup is correct.')}`);\n log.blank();\n log.info(`Run ${chalk.cyan('ai-guard run')} to start scanning.`);\n log.info(`Run ${chalk.cyan('npx eslint .')} to lint with ESLint directly.`);\n } else {\n log.error('Some checks failed. Follow the fixes above.');\n log.blank();\n\n // Smart suggestion — only suggest init if it won't cause an infinite loop\n const configFormatMismatch = checks.some(\n (c) => c.label === 'Config format matches ESLint version' && !c.pass,\n );\n const configMissing = checks.some(\n (c) => c.label === 'ESLint config present' && !c.pass,\n );\n const pluginMissing = checks.some(\n (c) => c.label === 'eslint-plugin-ai-guard installed' && !c.pass,\n );\n\n if (pluginMissing) {\n log.print(\n ` Install missing packages first, then re-run ${chalk.cyan('ai-guard doctor')}.`,\n );\n } else if (configMissing || configFormatMismatch) {\n log.print(\n ` Run ${chalk.cyan('ai-guard init')} to generate the correct config for your ESLint version.`,\n );\n } else {\n log.print(\n ` Run ${chalk.cyan('ai-guard init --dry-run')} to preview what would change.`,\n );\n }\n }\n\n log.blank();\n process.exit(allPassed ? 0 : 1);\n });\n}\n","import type { Command } from 'commander';\r\nimport { select } from '@inquirer/prompts';\r\nimport chalk from 'chalk';\r\nimport { detect, isFlat } from '../utils/detector.js';\r\nimport {\r\n backupConfig,\r\n readConfig,\r\n writeConfig,\r\n patchFlatConfig,\r\n patchLegacyConfig,\r\n switchFlatPreset,\r\n switchLegacyPreset,\r\n generateFlatConfig,\r\n generateLegacyConfig,\r\n type Preset,\r\n} from '../utils/config-manager.js';\r\nimport { log } from '../utils/logger.js';\r\nimport path from 'path';\r\n\r\nexport function registerPresetCommand(program: Command): void {\r\n program\r\n .command('preset')\r\n .description('Interactively select and apply an ai-guard preset to your ESLint config')\r\n .action(async () => {\r\n const cwd = process.cwd();\r\n\r\n log.banner('AI GUARD PRESET');\r\n log.blank();\r\n\r\n const preset = await select<Preset>({\r\n message: 'Choose a preset:',\r\n choices: [\r\n {\r\n name: `${chalk.green('recommended')} — balanced defaults, low noise. Best starting point.`,\r\n value: 'recommended',\r\n },\r\n {\r\n name: `${chalk.yellow('strict')} — all rules at error. For mature codebases.`,\r\n value: 'strict',\r\n },\r\n {\r\n name: `${chalk.red('security')} — security rules only. For AppSec teams.`,\r\n value: 'security',\r\n },\r\n ],\r\n });\r\n\r\n log.blank();\r\n log.info(`Applying preset: ${chalk.cyan(preset)}`);\r\n\r\n const env = detect(cwd);\r\n const useFlat =\r\n (env.eslintMajor !== null && env.eslintMajor >= 9) ||\r\n isFlat(env.configType);\r\n\r\n if (env.configType === 'none') {\r\n // Generate fresh config with chosen preset\r\n const configPath = useFlat\r\n ? path.join(cwd, 'eslint.config.mjs')\r\n : path.join(cwd, '.eslintrc.js');\r\n\r\n const content = useFlat\r\n ? generateFlatConfig(preset)\r\n : generateLegacyConfig(preset);\r\n\r\n writeConfig(configPath, content);\r\n log.success(`Created ${chalk.white(path.relative(cwd, configPath))} with ${chalk.cyan(preset)} preset`);\r\n } else {\r\n const configPath = env.configPath!;\r\n const backupPath = backupConfig(configPath);\r\n log.info(`Backed up → ${chalk.gray(path.relative(cwd, backupPath))}`);\r\n\r\n const existing = readConfig(configPath);\r\n const withPlugin = isFlat(env.configType)\r\n ? patchFlatConfig(existing, preset)\r\n : patchLegacyConfig(existing, preset);\r\n\r\n const patched = isFlat(env.configType)\r\n ? switchFlatPreset(withPlugin, preset)\r\n : switchLegacyPreset(withPlugin, preset);\r\n\r\n if (patched === existing) {\r\n log.warn('No preset changes needed. Config already matches selected preset.');\r\n } else {\r\n writeConfig(configPath, patched);\r\n log.success(`Updated ${chalk.white(path.relative(cwd, configPath))} to ${chalk.cyan(preset)} preset`);\r\n }\r\n }\r\n\r\n log.blank();\r\n log.section('Preset Details');\r\n\r\n const presetDetails: Record<Preset, Array<{ rule: string; level: string }>> = {\r\n recommended: [\r\n { rule: 'no-empty-catch', level: chalk.red('error') },\r\n { rule: 'no-floating-promise', level: chalk.red('error') },\r\n { rule: 'no-hardcoded-secret', level: chalk.red('error') },\r\n { rule: 'no-eval-dynamic', level: chalk.red('error') },\r\n { rule: 'no-broad-exception', level: chalk.yellow('warn') },\r\n { rule: 'no-async-array-callback', level: chalk.yellow('warn') },\r\n { rule: 'no-await-in-loop', level: chalk.yellow('warn') },\r\n { rule: '+ 5 more…', level: chalk.gray('warn') },\r\n ],\r\n strict: [\r\n { rule: 'All 17 rules', level: chalk.red('error') },\r\n ],\r\n security: [\r\n { rule: 'no-hardcoded-secret', level: chalk.red('error') },\r\n { rule: 'no-eval-dynamic', level: chalk.red('error') },\r\n { rule: 'no-sql-string-concat', level: chalk.red('error') },\r\n { rule: 'no-unsafe-deserialize', level: chalk.yellow('warn') },\r\n { rule: 'require-auth-middleware', level: chalk.yellow('warn') },\r\n { rule: 'require-authz-check', level: chalk.yellow('warn') },\r\n ],\r\n };\r\n\r\n for (const { rule, level } of presetDetails[preset]) {\r\n log.print(` ${chalk.gray('•')} ${chalk.white(rule).padEnd(32)}${level}`);\r\n }\r\n\r\n log.blank();\r\n log.info(`Run ${chalk.cyan('ai-guard run')} to see results with the new preset.`);\r\n log.blank();\r\n });\r\n}\r\n","import type { Command } from 'commander';\nimport chalk from 'chalk';\nimport { detect, isFlat } from '../utils/detector.js';\nimport {\n backupConfig,\n readConfig,\n writeConfig,\n addIgnoresToFlatConfig,\n addIgnoresToLegacyConfig,\n generateFlatConfig,\n generateLegacyConfig,\n} from '../utils/config-manager.js';\nimport { log } from '../utils/logger.js';\nimport path from 'path';\n\nconst DEFAULT_IGNORES = [\n '.next/',\n 'dist/',\n 'build/',\n 'coverage/',\n 'out/',\n 'node_modules/',\n];\n\nexport function registerIgnoreCommand(program: Command): void {\n program\n .command('ignore')\n .description('Add default ignore patterns (.next, dist, build, coverage) to ESLint config')\n .action(() => {\n const cwd = process.cwd();\n\n log.banner('AI GUARD IGNORE');\n log.blank();\n log.section('Default Ignores');\n\n for (const p of DEFAULT_IGNORES) {\n log.print(` ${chalk.gray('•')} ${chalk.yellow(p)}`);\n }\n\n log.blank();\n\n const env = detect(cwd);\n\n if (env.configType === 'none') {\n // Generate a fresh minimal config with ignores\n const useFlat = env.eslintMajor !== null && env.eslintMajor >= 9;\n const configPath = useFlat\n ? path.join(cwd, 'eslint.config.mjs')\n : path.join(cwd, '.eslintrc.js');\n\n const content = useFlat\n ? generateFlatConfig('recommended')\n : generateLegacyConfig('recommended');\n\n writeConfig(configPath, content);\n log.success(`No config found — generated ${chalk.white(path.relative(cwd, configPath))} with ignores included`);\n } else {\n const configPath = env.configPath!;\n const backupPath = backupConfig(configPath);\n log.info(`Backed up → ${chalk.gray(path.relative(cwd, backupPath))}`);\n\n const existing = readConfig(configPath);\n const patched = isFlat(env.configType)\n ? addIgnoresToFlatConfig(existing)\n : addIgnoresToLegacyConfig(existing);\n\n if (patched === existing) {\n log.warn('Ignore patterns already present in config — no changes made.');\n } else {\n writeConfig(configPath, patched);\n log.success(`Patched ${chalk.white(path.relative(cwd, configPath))} with ignore patterns`);\n }\n }\n\n log.blank();\n log.info('Noisy directories will now be skipped in all future ESLint runs.');\n log.info(`Run ${chalk.cyan('ai-guard run')} to verify cleaner results.`);\n log.blank();\n });\n}\n","import type { Command } from 'commander';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport chalk from 'chalk';\r\nimport ora from 'ora';\r\nimport { runEslint, type Preset, type RunResult } from '../utils/eslint-runner.js';\r\nimport { log } from '../utils/logger.js';\r\n\r\nconst BASELINE_FILE = '.ai-guard-baseline.json';\r\n\r\n// ─── Baseline format ──────────────────────────────────────────────────────────\r\n\r\ninterface BaselineIssue {\r\n ruleId: string;\r\n message: string;\r\n line: number;\r\n column: number;\r\n}\r\n\r\ntype BaselineMode = 'strict' | 'stable';\r\n\r\ninterface BaselineEntry {\r\n filePath: string;\r\n issues: BaselineIssue[];\r\n}\r\n\r\ninterface BaselineFile {\r\n createdAt: string;\r\n preset: Preset;\r\n mode: BaselineMode;\r\n totalIssues: number;\r\n entries: BaselineEntry[];\r\n}\r\n\r\n// ─── Helpers ──────────────────────────────────────────────────────────────────\r\n\r\nfunction saveBaseline(\r\n result: RunResult,\r\n preset: Preset,\r\n mode: BaselineMode,\r\n cwd: string,\r\n): string {\r\n const entries: BaselineEntry[] = result.files.map((f) => ({\r\n filePath: f.filePath,\r\n issues: f.issues.map((i) => ({\r\n ruleId: i.ruleId,\r\n message: i.message,\r\n line: i.line,\r\n column: i.column,\r\n })),\r\n }));\r\n\r\n const baseline: BaselineFile = {\r\n createdAt: new Date().toISOString(),\r\n preset,\r\n mode,\r\n totalIssues: result.totalIssues,\r\n entries,\r\n };\r\n\r\n const baselinePath = path.join(cwd, BASELINE_FILE);\r\n fs.writeFileSync(baselinePath, JSON.stringify(baseline, null, 2), 'utf-8');\r\n return baselinePath;\r\n}\r\n\r\nfunction loadBaseline(cwd: string): BaselineFile | null {\r\n const baselinePath = path.join(cwd, BASELINE_FILE);\r\n if (!fs.existsSync(baselinePath)) return null;\r\n try {\r\n const raw = fs.readFileSync(baselinePath, 'utf-8');\r\n return JSON.parse(raw) as BaselineFile;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\ntype IssueKey = string;\r\n\r\nfunction issueKey(filePath: string, issue: BaselineIssue): IssueKey {\r\n return `${filePath}::${issue.ruleId}::${issue.line}::${issue.column}::${issue.message}`;\r\n}\r\n\r\nfunction stableIssueKey(filePath: string, issue: BaselineIssue): IssueKey {\r\n return `${filePath}::${issue.ruleId}::${issue.message}`;\r\n}\r\n\r\nfunction buildBaselineSet(baseline: BaselineFile, mode: BaselineMode): Set<IssueKey> {\r\n const toKey = mode === 'stable' ? stableIssueKey : issueKey;\r\n const set = new Set<IssueKey>();\r\n for (const entry of baseline.entries) {\r\n for (const issue of entry.issues) {\r\n set.add(toKey(entry.filePath, issue));\r\n }\r\n }\r\n return set;\r\n}\r\n\r\nfunction computeNewIssues(\r\n result: RunResult,\r\n baselineSet: Set<IssueKey>,\r\n mode: BaselineMode,\r\n): RunResult {\r\n const toKey = mode === 'stable' ? stableIssueKey : issueKey;\r\n const newFiles: RunResult['files'] = [];\r\n let totalErrors = 0;\r\n let totalWarnings = 0;\r\n const ruleBreakdown = new Map<string, number>();\r\n\r\n for (const file of result.files) {\r\n const newIssues = file.issues.filter(\r\n (i) => !baselineSet.has(toKey(file.filePath, i)),\r\n );\r\n if (newIssues.length === 0) continue;\r\n\r\n const errorCount = newIssues.filter((i) => i.severity === 2).length;\r\n const warningCount = newIssues.filter((i) => i.severity === 1).length;\r\n totalErrors += errorCount;\r\n totalWarnings += warningCount;\r\n\r\n for (const issue of newIssues) {\r\n ruleBreakdown.set(\r\n issue.ruleId,\r\n (ruleBreakdown.get(issue.ruleId) ?? 0) + 1,\r\n );\r\n }\r\n\r\n newFiles.push({ ...file, issues: newIssues, errorCount, warningCount });\r\n }\r\n\r\n const topFiles = [...newFiles]\r\n .sort((a, b) => b.issues.length - a.issues.length)\r\n .slice(0, 10)\r\n .map((f) => ({ path: f.filePath, count: f.issues.length }));\r\n\r\n return {\r\n files: newFiles,\r\n totalErrors,\r\n totalWarnings,\r\n totalIssues: totalErrors + totalWarnings,\r\n ruleBreakdown,\r\n topFiles,\r\n durationMs: result.durationMs,\r\n };\r\n}\r\n\r\n// ─── Command ──────────────────────────────────────────────────────────────────\r\n\r\nexport function registerBaselineCommand(program: Command): void {\r\n program\r\n .command('baseline')\r\n .description('Save current issues as baseline; future runs show only new issues')\r\n .option('--save', 'Save current state as the new baseline')\r\n .option('--check', 'Show only issues introduced since the last baseline')\r\n .option('--mode <name>', 'Baseline match mode: strict | stable', 'stable')\r\n .option('--path <dir>', 'Directory to scan', '.')\r\n .option('--preset <name>', 'Preset: recommended | strict | security', 'recommended')\r\n .action(async (opts: {\r\n save?: boolean;\r\n check?: boolean;\r\n mode?: string;\r\n path: string;\r\n preset: string;\r\n }) => {\r\n const cwd = process.cwd();\r\n const preset = (opts.preset as Preset) ?? 'recommended';\r\n const mode = (opts.mode as BaselineMode) ?? 'stable';\r\n\r\n if (mode !== 'strict' && mode !== 'stable') {\r\n log.error('Invalid --mode. Use strict or stable.');\r\n process.exit(1);\r\n }\r\n\r\n log.banner('AI GUARD BASELINE');\r\n log.blank();\r\n\r\n // If neither flag provided, default to --save if no baseline exists, else --check\r\n const existingBaseline = loadBaseline(cwd);\r\n const doSave = opts.save ?? (!existingBaseline && !opts.check);\r\n const doCheck = opts.check ?? (existingBaseline !== null && !opts.save);\r\n\r\n if (doSave) {\r\n log.info('Scanning project to save baseline…');\r\n const spinner = ora({ text: 'Running analysis…', color: 'cyan' }).start();\r\n\r\n let result: RunResult | undefined;\r\n try {\r\n result = await runEslint({ preset, targetPath: opts.path });\r\n spinner.stop();\r\n } catch (err: unknown) {\r\n spinner.stop();\r\n log.error(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n\r\n const baselinePath = saveBaseline(result!, preset, mode, cwd);\r\n log.success(\r\n `Baseline saved → ${chalk.white(path.relative(cwd, baselinePath))}`,\r\n );\r\n log.info(` ${result!.totalIssues} issues recorded (${result!.totalErrors} errors, ${result!.totalWarnings} warnings)`);\r\n log.info(` Preset: ${chalk.cyan(preset)}`);\r\n log.info(` Mode: ${chalk.cyan(mode)}`);\r\n log.blank();\r\n log.info('Future runs of ' + chalk.cyan('ai-guard baseline --check') + ' will show only NEW issues.');\r\n log.info('Add ' + chalk.white(BASELINE_FILE) + ' to your git repository to share baseline with your team.');\r\n log.blank();\r\n return;\r\n }\r\n\r\n if (doCheck) {\r\n if (!existingBaseline) {\r\n log.error(`No baseline found at ${chalk.white(BASELINE_FILE)}`);\r\n log.info(`Run ${chalk.cyan('ai-guard baseline --save')} first to create one.`);\r\n process.exit(1);\r\n }\r\n\r\n const baselineDate = new Date(existingBaseline.createdAt).toLocaleString();\r\n log.info(`Baseline from: ${chalk.gray(baselineDate)}`);\r\n log.info(`Baseline preset: ${chalk.cyan(existingBaseline.preset)}`);\r\n log.info(`Baseline mode: ${chalk.cyan(existingBaseline.mode ?? 'strict')}`);\r\n log.info(`Baseline issues: ${chalk.gray(existingBaseline.totalIssues)}`);\r\n log.blank();\r\n\r\n const spinner = ora({ text: 'Scanning for new issues…', color: 'cyan' }).start();\r\n\r\n let result: RunResult | undefined;\r\n try {\r\n result = await runEslint({ preset, targetPath: opts.path });\r\n spinner.stop();\r\n } catch (err: unknown) {\r\n spinner.stop();\r\n log.error(err instanceof Error ? err.message : String(err));\r\n process.exit(1);\r\n }\r\n\r\n const compareMode = existingBaseline.mode ?? 'strict';\r\n const baselineSet = buildBaselineSet(existingBaseline!, compareMode);\r\n const newResult = computeNewIssues(result!, baselineSet, compareMode);\r\n\r\n if (newResult.totalIssues === 0) {\r\n log.success('No new issues since baseline! ✨');\r\n log.info(\r\n `Total in codebase: ${result!.totalIssues} (all existing, none new)`,\r\n );\r\n log.blank();\r\n process.exit(0);\r\n return;\r\n }\r\n\r\n log.print(\r\n chalk.bold.red(` ✖ ${newResult.totalIssues} new issue${newResult.totalIssues !== 1 ? 's' : ''} since baseline`),\r\n );\r\n log.blank();\r\n\r\n // By rule breakdown\r\n if (newResult.ruleBreakdown.size > 0) {\r\n log.section('New Issues by Rule');\r\n for (const [rule, count] of [...newResult.ruleBreakdown.entries()].sort(\r\n (a, b) => b[1] - a[1],\r\n )) {\r\n log.rule(rule, count);\r\n }\r\n }\r\n\r\n // Per-file breakdown\r\n if (newResult.files.length > 0) {\r\n log.section('New Issues by File');\r\n log.blank();\r\n for (const file of newResult.files) {\r\n log.print(\r\n ` ${chalk.bold.white(file.filePath)} ` +\r\n chalk.gray(`(${file.issues.length} new)`),\r\n );\r\n for (const issue of file.issues) {\r\n log.issue(issue.message, issue.severity, issue.line, issue.column);\r\n }\r\n }\r\n }\r\n\r\n log.blank();\r\n log.divider();\r\n log.blank();\r\n log.error(\r\n `${newResult.totalIssues} new issue${newResult.totalIssues !== 1 ? 's' : ''} introduced since baseline.`,\r\n );\r\n log.info(`Run ${chalk.cyan('ai-guard baseline --save')} to update the baseline after fixing them.`);\r\n log.blank();\r\n process.exit(1);\r\n }\r\n });\r\n}\r\n","import type { Command } from 'commander';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport chalk from 'chalk';\r\nimport { checkbox, confirm } from '@inquirer/prompts';\r\nimport { log } from '../utils/logger.js';\r\n\r\n// ─── Types ────────────────────────────────────────────────────────────────────\r\n\r\ntype AgentId = 'claude' | 'cursor' | 'copilot';\r\n\r\ntype RuleCategory = 'async' | 'security' | 'error-handling' | 'quality';\r\n\r\ninterface AgentTarget {\r\n id: AgentId;\r\n label: string;\r\n filePath: string;\r\n generate: (version: string, categories: RuleCategory[]) => string;\r\n}\r\n\r\n// ─── Rule Category Mapping ────────────────────────────────────────────────────\r\n\r\nconst RULE_CATEGORIES: Record<RuleCategory, string[]> = {\r\n 'error-handling': [\r\n 'no-empty-catch',\r\n 'no-broad-exception',\r\n 'no-catch-log-rethrow',\r\n 'no-catch-without-use',\r\n ],\r\n async: [\r\n 'no-async-array-callback',\r\n 'no-floating-promise',\r\n 'no-await-in-loop',\r\n 'no-async-without-await',\r\n 'no-redundant-await',\r\n ],\r\n security: [\r\n 'no-hardcoded-secret',\r\n 'no-eval-dynamic',\r\n 'no-sql-string-concat',\r\n 'no-unsafe-deserialize',\r\n 'require-auth-middleware',\r\n 'require-authz-check',\r\n ],\r\n quality: [\r\n 'no-console-in-handler',\r\n 'no-duplicate-logic-block',\r\n ],\r\n};\r\n\r\nconst ALL_CATEGORIES: RuleCategory[] = ['error-handling', 'async', 'security', 'quality'];\r\n\r\n// ─── Template Sections ────────────────────────────────────────────────────────\r\n\r\nfunction errorHandlingSection(): string {\r\n return `## Error Handling\r\n**Never** generate empty catch blocks:\r\n ❌ try { await fetchUser() } catch (e) {}\r\n ✅ try { await fetchUser() } catch (e) { logger.error(e); throw e; }\r\n\r\n**Never** catch (e: any) — use specific types or narrow with instanceof.\r\n\r\n**Never** catch, log, and immediately rethrow without adding context:\r\n ❌ catch (e) { console.error(e); throw e; }\r\n ✅ catch (e) { throw new Error('fetchUser failed', { cause: e }); }`;\r\n}\r\n\r\nfunction asyncSection(): string {\r\n return `## Async Correctness\r\n**Never** pass async callbacks to array.map(), filter(), forEach(), or reduce():\r\n ❌ const results = ids.map(async (id) => await fetchUser(id));\r\n ✅ const results = await Promise.all(ids.map((id) => fetchUser(id)));\r\n\r\n**Never** use await inside a for...of or while loop when parallel execution\r\nis possible:\r\n ❌ for (const id of ids) { const user = await fetchUser(id); }\r\n ✅ const users = await Promise.all(ids.map(fetchUser));\r\n\r\n**Never** call an async function without await or .catch():\r\n ❌ sendEmail(user);\r\n ✅ await sendEmail(user);\r\n\r\n**Never** declare a function async if it never uses await.`;\r\n}\r\n\r\nfunction securitySection(): string {\r\n return `## Security\r\n**Never** hardcode secrets, API keys, tokens, or passwords inline:\r\n ❌ const apiKey = 'sk-prod-abc123';\r\n ✅ const apiKey = process.env.API_KEY;\r\n\r\n**Never** concatenate user input into SQL strings:\r\n ❌ db.query('SELECT * FROM users WHERE id = ' + req.params.id);\r\n ✅ db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);\r\n\r\n**Never** use eval() or new Function() with dynamic/user-supplied strings.\r\n\r\n**Never** call JSON.parse() on req.body, req.query, or req.params directly\r\nwithout schema validation.\r\n\r\n**Always** add authentication middleware before route handlers:\r\n ❌ router.get('/admin/users', getUsers);\r\n ✅ router.get('/admin/users', requireAuth, getUsers);\r\n\r\n**Always** verify that the authenticated user owns or has access to the\r\nresource being accessed when using req.params.id or similar identifiers.`;\r\n}\r\n\r\nfunction qualitySection(): string {\r\n return `## Code Quality\r\n**Never** leave console.log or console.debug statements inside HTTP route\r\nhandlers or event listeners in production code.\r\n\r\n**Never** copy-paste the same logic block consecutively — extract shared\r\nlogic into a helper function or consolidate duplicated code.`;\r\n}\r\n\r\ntype SectionFn = () => string;\r\nconst SECTION_MAP: Record<RuleCategory, SectionFn> = {\r\n 'error-handling': errorHandlingSection,\r\n async: asyncSection,\r\n security: securitySection,\r\n quality: qualitySection,\r\n};\r\n\r\nfunction getSections(categories: RuleCategory[]): string {\r\n return categories.map((cat) => SECTION_MAP[cat]()).join('\\n\\n');\r\n}\r\n\r\nfunction workflowGuidanceMarkdown(): string {\r\n return `## Workflow Guardrails\r\n- Follow user and repository instructions first; apply these rules on top.\r\n- Reuse existing project patterns and libraries before introducing new abstractions.\r\n- If a rule must be bypassed intentionally, add a suppression comment with reason:\r\n \\`ai-guard-disable <rule-name> -- reason: <why>\\`.\r\n- Before finalizing changes, run tests/lint and \\`ai-guard run\\` when available.`;\r\n}\r\n\r\nfunction workflowGuidanceCursor(): string {\r\n return `## Workflow Guardrails\r\n\r\n- Follow user and repository instructions first.\r\n- Prefer existing project patterns and dependencies.\r\n- If bypassing a rule intentionally, add: ai-guard-disable <rule-name> -- reason: <why>.\r\n- Validate generated code with tests/lint and ai-guard run when available.`;\r\n}\r\n\r\nfunction workflowGuidanceCopilot(): string {\r\n return `## Required Workflow\r\n\r\n- Follow user and repository instructions first.\r\n- Prefer edits that match existing architecture and dependencies.\r\n- If intentionally violating an ai-guard rule, add an inline suppression with a reason.\r\n- Run tests/lint and \\`ai-guard run\\` before finalizing changes when possible.`;\r\n}\r\n\r\n// ─── CLAUDE.md Template ───────────────────────────────────────────────────────\r\n\r\nfunction generateClaudeFile(version: string, categories: RuleCategory[]): string {\r\n return `<!-- DO NOT EDIT MANUALLY — generated by eslint-plugin-ai-guard -->\r\n<!-- Regenerate: npx ai-guard init-context --force -->\r\n\r\n# AI Guard Rules — Claude Code Instructions\r\n\r\nYou are coding in a project that uses eslint-plugin-ai-guard.\r\nAvoid generating the following patterns. They will be flagged as lint errors.\r\n\r\n${workflowGuidanceMarkdown()}\r\n\r\n${getSections(categories)}\r\n\r\n---\r\nGenerated by eslint-plugin-ai-guard v${version}.\r\nRun \\`npx ai-guard init-context --force\\` to regenerate.\r\n`;\r\n}\r\n\r\n// ─── .cursorrules Template ────────────────────────────────────────────────────\r\n\r\nfunction cursorErrorHandling(): string {\r\n return `## Error Handling\r\n\r\nRule: no-empty-catch\r\nBad: try { await fetchUser() } catch (e) {}\r\nGood: try { await fetchUser() } catch (e) { logger.error(e); throw e; }\r\n\r\nRule: no-broad-exception\r\nBad: catch (e: any) { handle(e); }\r\nGood: catch (e) { if (e instanceof NetworkError) { retry(); } throw e; }\r\n\r\nRule: no-catch-log-rethrow\r\nBad: catch (e) { console.error(e); throw e; }\r\nGood: catch (e) { throw new Error('fetchUser failed', { cause: e }); }`;\r\n}\r\n\r\nfunction cursorAsyncSection(): string {\r\n return `## Async Correctness\r\n\r\nRule: no-async-array-callback\r\nBad: const results = ids.map(async (id) => await fetchUser(id));\r\nGood: const results = await Promise.all(ids.map((id) => fetchUser(id)));\r\n\r\nRule: no-await-in-loop\r\nBad: for (const id of ids) { const user = await fetchUser(id); }\r\nGood: const users = await Promise.all(ids.map(fetchUser));\r\n\r\nRule: no-floating-promise\r\nBad: sendEmail(user);\r\nGood: await sendEmail(user);\r\n\r\nRule: no-async-without-await\r\nBad: async function getUser() { return db.findOne(id); }\r\nGood: function getUser() { return db.findOne(id); }`;\r\n}\r\n\r\nfunction cursorSecuritySection(): string {\r\n return `## Security\r\n\r\nRule: no-hardcoded-secret\r\nBad: const apiKey = 'sk-prod-abc123';\r\nGood: const apiKey = process.env.API_KEY;\r\n\r\nRule: no-sql-string-concat\r\nBad: db.query('SELECT * FROM users WHERE id = ' + req.params.id);\r\nGood: db.query('SELECT * FROM users WHERE id = $1', [req.params.id]);\r\n\r\nRule: no-eval-dynamic\r\nBad: eval(userInput);\r\nGood: Use a safe parser or allowlist approach instead.\r\n\r\nRule: no-unsafe-deserialize\r\nBad: const data = JSON.parse(req.body);\r\nGood: const data = schema.parse(req.body);\r\n\r\nRule: require-auth-middleware\r\nBad: router.get('/admin/users', getUsers);\r\nGood: router.get('/admin/users', requireAuth, getUsers);\r\n\r\nRule: require-authz-check\r\nBad: const user = await db.findById(req.params.id); res.json(user);\r\nGood: const user = await db.findById(req.params.id); if (user.ownerId !== req.user.id) throw new ForbiddenError(); res.json(user);`;\r\n}\r\n\r\nfunction cursorQualitySection(): string {\r\n return `## Code Quality\r\n\r\nRule: no-console-in-handler\r\nBad: router.get('/users', (req, res) => { console.log('hit'); ... });\r\nGood: router.get('/users', (req, res) => { logger.info('hit'); ... });\r\n\r\nRule: no-duplicate-logic-block\r\nBad: Two identical consecutive code blocks copy-pasted.\r\nGood: Extract the duplicated logic into a shared helper function.`;\r\n}\r\n\r\nconst CURSOR_SECTION_MAP: Record<RuleCategory, () => string> = {\r\n 'error-handling': cursorErrorHandling,\r\n async: cursorAsyncSection,\r\n security: cursorSecuritySection,\r\n quality: cursorQualitySection,\r\n};\r\n\r\nfunction generateCursorFile(version: string, categories: RuleCategory[]): string {\r\n const sections = categories.map((cat) => CURSOR_SECTION_MAP[cat]()).join('\\n\\n');\r\n\r\n return `# AI Guard Rules — Cursor Instructions\r\n# DO NOT EDIT MANUALLY — generated by eslint-plugin-ai-guard\r\n# Regenerate: npx ai-guard init-context --force\r\n\r\nThis project uses eslint-plugin-ai-guard to catch the 17 most common\r\nanti-patterns generated by AI coding tools. Follow these rules when\r\ngenerating or editing code in this project. Violations will be flagged\r\nas lint errors.\r\n\r\n${workflowGuidanceCursor()}\r\n\r\n${sections}\r\n\r\n---\r\nThese rules mirror eslint-plugin-ai-guard v${version}.\r\nRun \\`npx ai-guard init-context --force\\` to regenerate.\r\n`;\r\n}\r\n\r\n// ─── .github/copilot-instructions.md Template ─────────────────────────────────\r\n\r\nfunction copilotQuickRef(categories: RuleCategory[]): string {\r\n const lines: string[] = [];\r\n\r\n if (categories.includes('error-handling')) {\r\n lines.push(\r\n 'Never: generate empty catch blocks',\r\n 'Never: catch (e: any) without narrowing',\r\n 'Never: catch, log, and rethrow without adding context',\r\n );\r\n }\r\n if (categories.includes('async')) {\r\n lines.push(\r\n 'Never: pass async callbacks to .map(), .filter(), .forEach()',\r\n 'Never: use await inside loops when Promise.all() works',\r\n 'Never: call async functions without await or .catch()',\r\n 'Never: mark functions async if they never await',\r\n );\r\n }\r\n if (categories.includes('security')) {\r\n lines.push(\r\n 'Never: hardcode API keys, secrets, or passwords',\r\n 'Never: concatenate user input into SQL strings',\r\n 'Never: use eval() or new Function() with dynamic input',\r\n 'Never: JSON.parse() untrusted input without validation',\r\n 'Always: add auth middleware before route handlers',\r\n 'Always: verify resource ownership in handlers',\r\n );\r\n }\r\n if (categories.includes('quality')) {\r\n lines.push(\r\n 'Never: leave console.log in route handlers',\r\n 'Never: copy-paste identical consecutive code blocks',\r\n );\r\n }\r\n\r\n return lines.map((l) => `- ${l}`).join('\\n');\r\n}\r\n\r\nfunction copilotDetails(categories: RuleCategory[]): string {\r\n const details: string[] = [];\r\n\r\n if (categories.includes('async')) {\r\n details.push(`### no-floating-promise\r\n\\`\\`\\`typescript\r\n// ❌ Bad — promise rejected silently\r\nsendEmail(user);\r\n\r\n// ✅ Good\r\nawait sendEmail(user);\r\n\\`\\`\\``);\r\n\r\n details.push(`### no-async-array-callback\r\n\\`\\`\\`typescript\r\n// ❌ Bad — returns Promise[], not values\r\nids.map(async (id) => await fetchUser(id));\r\n\r\n// ✅ Good\r\nawait Promise.all(ids.map((id) => fetchUser(id)));\r\n\\`\\`\\``);\r\n }\r\n\r\n if (categories.includes('error-handling')) {\r\n details.push(`### no-empty-catch\r\n\\`\\`\\`typescript\r\n// ❌ Bad — error swallowed silently\r\ntry { await fetchUser() } catch (e) {}\r\n\r\n// ✅ Good\r\ntry { await fetchUser() } catch (e) { logger.error(e); throw e; }\r\n\\`\\`\\``);\r\n }\r\n\r\n if (categories.includes('security')) {\r\n details.push(`### no-hardcoded-secret\r\n\\`\\`\\`typescript\r\n// ❌ Bad\r\nconst apiKey = 'sk-prod-abc123';\r\n\r\n// ✅ Good\r\nconst apiKey = process.env.API_KEY;\r\n\\`\\`\\``);\r\n\r\n details.push(`### no-sql-string-concat\r\n\\`\\`\\`typescript\r\n// ❌ Bad — SQL injection\r\ndb.query('SELECT * FROM users WHERE id = ' + req.params.id);\r\n\r\n// ✅ Good\r\ndb.query('SELECT * FROM users WHERE id = $1', [req.params.id]);\r\n\\`\\`\\``);\r\n }\r\n\r\n return details.join('\\n\\n');\r\n}\r\n\r\nfunction generateCopilotFile(version: string, categories: RuleCategory[]): string {\r\n return `<!-- DO NOT EDIT MANUALLY — generated by eslint-plugin-ai-guard -->\r\n<!-- Regenerate: npx ai-guard init-context --force -->\r\n\r\n# AI Guard — GitHub Copilot Instructions\r\n\r\nThis project uses \\`eslint-plugin-ai-guard\\`. Follow these rules to avoid\r\ngenerating patterns that will be flagged as lint errors.\r\n\r\n${workflowGuidanceCopilot()}\r\n\r\n## Quick Reference\r\n\r\n${copilotQuickRef(categories)}\r\n\r\n## Details\r\n\r\n${copilotDetails(categories)}\r\n\r\n---\r\nGenerated by eslint-plugin-ai-guard v${version}.\r\nRun \\`npx ai-guard init-context --force\\` to regenerate.\r\n`;\r\n}\r\n\r\n// ─── Agent Definitions ────────────────────────────────────────────────────────\r\n\r\nconst AGENTS: AgentTarget[] = [\r\n {\r\n id: 'claude',\r\n label: 'Claude Code',\r\n filePath: 'CLAUDE.md',\r\n generate: generateClaudeFile,\r\n },\r\n {\r\n id: 'cursor',\r\n label: 'Cursor',\r\n filePath: '.cursorrules',\r\n generate: generateCursorFile,\r\n },\r\n {\r\n id: 'copilot',\r\n label: 'GitHub Copilot',\r\n filePath: path.join('.github', 'copilot-instructions.md'),\r\n generate: generateCopilotFile,\r\n },\r\n];\r\n\r\n// ─── Helpers ──────────────────────────────────────────────────────────────────\r\n\r\nfunction getPackageVersion(cwd: string): string {\r\n try {\r\n const pkgPath = path.join(cwd, 'node_modules', 'eslint-plugin-ai-guard', 'package.json');\r\n if (fs.existsSync(pkgPath)) {\r\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { version?: string };\r\n if (pkg.version) return pkg.version;\r\n }\r\n } catch { /* fall through */ }\r\n\r\n try {\r\n const pkgPath = path.join(cwd, 'package.json');\r\n if (fs.existsSync(pkgPath)) {\r\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { version?: string };\r\n if (pkg.version) return pkg.version;\r\n }\r\n } catch { /* fall through */ }\r\n\r\n return '0.0.0';\r\n}\r\n\r\nfunction parseCategories(raw: string | undefined): RuleCategory[] {\r\n if (!raw) return ALL_CATEGORIES;\r\n const parts = raw.split(',').map((s) => s.trim().toLowerCase());\r\n const valid: RuleCategory[] = [];\r\n for (const part of parts) {\r\n if (part in RULE_CATEGORIES) {\r\n valid.push(part as RuleCategory);\r\n }\r\n }\r\n return valid.length > 0 ? valid : ALL_CATEGORIES;\r\n}\r\n\r\nfunction normalizeSelectedAgents(raw: unknown): string[] {\r\n if (Array.isArray(raw)) {\r\n return raw.filter((value): value is string => typeof value === 'string');\r\n }\r\n\r\n if (typeof raw === 'string') {\r\n return [raw];\r\n }\r\n\r\n return [];\r\n}\r\n\r\n// ─── Exported for tests ───────────────────────────────────────────────────────\r\n\r\nexport {\r\n generateClaudeFile,\r\n generateCursorFile,\r\n generateCopilotFile,\r\n parseCategories,\r\n normalizeSelectedAgents,\r\n AGENTS,\r\n ALL_CATEGORIES,\r\n};\r\nexport type { AgentTarget, RuleCategory };\r\n\r\n// ─── Command Registration ────────────────────────────────────────────────────\r\n\r\nexport function registerInitContextCommand(program: Command): void {\r\n program\r\n .command('init-context')\r\n .description(\r\n 'Generate AI agent instruction files (CLAUDE.md, .cursorrules, copilot-instructions.md)\\n' +\r\n 'so Claude Code, Cursor, and GitHub Copilot avoid the 17 most common AI anti-patterns.',\r\n )\r\n .option('-a, --all', 'Generate files for all agents (skip prompt)')\r\n .option('--force', 'Overwrite existing files without asking')\r\n .option('--dry-run', 'Print what would be generated without writing files')\r\n .option('--rules <categories>', 'Comma-separated categories: async,security,error-handling,quality')\r\n .action(async (opts: {\r\n all?: boolean;\r\n force?: boolean;\r\n dryRun?: boolean;\r\n rules?: string;\r\n }) => {\r\n const cwd = process.cwd();\r\n const version = getPackageVersion(cwd);\r\n const categories = parseCategories(opts.rules);\r\n const isDryRun = opts.dryRun === true;\r\n const isForce = opts.force === true;\r\n\r\n log.banner('AI GUARD INIT-CONTEXT');\r\n\r\n if (isDryRun) {\r\n log.print(` ${chalk.yellow('⚑ DRY RUN — no files will be written')}`);\r\n log.blank();\r\n }\r\n\r\n // ── Select agents ──────────────────────────────────────────────────────\r\n\r\n let selectedAgents: AgentTarget[];\r\n\r\n if (opts.all) {\r\n selectedAgents = [...AGENTS];\r\n } else {\r\n let selected: string[];\r\n try {\r\n selected = await checkbox({\r\n message: 'Which AI agents do you use?',\r\n choices: [\r\n { name: 'Claude Code -> writes CLAUDE.md', value: 'claude' },\r\n { name: 'Cursor -> writes .cursorrules', value: 'cursor' },\r\n { name: 'GitHub Copilot -> writes .github/copilot-instructions.md', value: 'copilot' },\r\n { name: 'All three (recommended) -> writes all files', value: 'all' },\r\n ],\r\n required: true,\r\n });\r\n } catch {\r\n log.info('Selection cancelled. Nothing to do.');\r\n return;\r\n }\r\n\r\n if (selected.length === 0) {\r\n log.info('No valid agents selected. Use --all to generate all files.');\r\n return;\r\n }\r\n\r\n if (selected.includes('all')) {\r\n selectedAgents = [...AGENTS];\r\n } else {\r\n selectedAgents = AGENTS.filter((a) => selected.includes(a.id));\r\n }\r\n }\r\n\r\n log.info(`Categories: ${chalk.cyan(categories.join(', '))}`);\r\n log.info(`Version: ${chalk.cyan(version)}`);\r\n log.blank();\r\n\r\n // ── Generate files ─────────────────────────────────────────────────────\r\n\r\n const results: { file: string; status: 'created' | 'skipped' | 'dry-run' }[] = [];\r\n\r\n for (const agent of selectedAgents) {\r\n const fullPath = path.join(cwd, agent.filePath);\r\n const exists = fs.existsSync(fullPath);\r\n\r\n if (exists && !isForce && !isDryRun) {\r\n // Ask to overwrite\r\n const overwrite = await confirm({\r\n message: `${agent.filePath} already exists. Overwrite?`,\r\n default: false,\r\n });\r\n\r\n if (!overwrite) {\r\n results.push({ file: agent.filePath, status: 'skipped' });\r\n continue;\r\n }\r\n }\r\n\r\n const content = agent.generate(version, categories);\r\n\r\n if (isDryRun) {\r\n log.section(`Preview: ${agent.filePath}`);\r\n log.print(chalk.gray('─'.repeat(60)));\r\n for (const line of content.split('\\n').slice(0, 20)) {\r\n log.print(chalk.gray(` ${line}`));\r\n }\r\n log.print(chalk.gray(' ... (truncated)'));\r\n log.print(chalk.gray('─'.repeat(60)));\r\n log.blank();\r\n results.push({ file: agent.filePath, status: 'dry-run' });\r\n continue;\r\n }\r\n\r\n // Ensure parent directory exists (for .github/copilot-instructions.md)\r\n const parentDir = path.dirname(fullPath);\r\n if (!fs.existsSync(parentDir)) {\r\n fs.mkdirSync(parentDir, { recursive: true });\r\n }\r\n\r\n fs.writeFileSync(fullPath, content, 'utf-8');\r\n results.push({ file: agent.filePath, status: 'created' });\r\n }\r\n\r\n // ── Summary ────────────────────────────────────────────────────────────\r\n\r\n log.section('Summary');\r\n\r\n for (const result of results) {\r\n switch (result.status) {\r\n case 'created':\r\n log.print(` ${chalk.green('✅')} Created ${chalk.white(result.file)}`);\r\n break;\r\n case 'skipped':\r\n log.print(` ${chalk.yellow('⏭')} Skipped ${chalk.white(result.file)} ${chalk.gray('(already exists — use --force to overwrite)')}`);\r\n break;\r\n case 'dry-run':\r\n log.print(` ${chalk.cyan('📝')} Would create ${chalk.white(result.file)}`);\r\n break;\r\n }\r\n }\r\n\r\n log.blank();\r\n\r\n if (isDryRun) {\r\n log.info('Dry run complete — no files were written.');\r\n log.info(`Re-run without ${chalk.cyan('--dry-run')} to apply.`);\r\n } else {\r\n const createdCount = results.filter((r) => r.status === 'created').length;\r\n if (createdCount > 0) {\r\n log.success(\r\n 'Done. Your AI agents will now automatically avoid the 17 most common AI-generated code anti-patterns.',\r\n );\r\n }\r\n }\r\n\r\n log.blank();\r\n });\r\n}\r\n","import type { Command } from 'commander';\nimport fs from 'fs';\nimport path from 'path';\nimport ora from 'ora';\nimport { runEslint, type RunResult } from '../utils/eslint-runner.js';\nimport { log } from '../utils/logger.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface ReportData {\n projectName: string;\n version: string;\n generatedAt: string;\n preset: string;\n scannedPath: string;\n durationMs: number;\n totalIssues: number;\n totalErrors: number;\n totalWarnings: number;\n score: number;\n ruleBreakdown: Record<string, number>;\n topFiles: Array<{ path: string; count: number; errors: number; warnings: number }>;\n topRules: Array<{\n rule: string;\n count: number;\n description: string;\n category: string;\n example: { file: string; line: number; column: number; message: string } | null;\n }>;\n categoryBreakdown: Record<string, number>;\n // Confidence tier breakdown\n highCount: number;\n mediumCount: number;\n lowCount: number;\n ecosystemCount: number;\n parserErrorCount: number;\n}\n\n// ─── Rule Metadata ────────────────────────────────────────────────────────────\n\nconst RULE_META: Record<string, { description: string; category: string }> = {\n 'ai-guard/no-empty-catch': { description: 'Empty catch blocks silently swallow errors', category: 'Reliability' },\n 'ai-guard/no-broad-exception': { description: 'Catching all exceptions hides bugs', category: 'Reliability' },\n 'ai-guard/no-catch-log-rethrow': { description: 'Catch-log-rethrow adds noise without context', category: 'Reliability' },\n 'ai-guard/no-catch-without-use': { description: 'Caught error is not used', category: 'Reliability' },\n 'ai-guard/no-floating-promise': { description: 'Unhandled promise can crash silently', category: 'Async Stability' },\n 'ai-guard/no-await-in-loop': { description: 'Sequential await in loops is slow; use Promise.all', category: 'Async Stability' },\n 'ai-guard/no-async-array-callback': { description: 'Async callbacks in .map()/.filter() return Promises', category: 'Async Stability' },\n 'ai-guard/no-async-without-await': { description: 'Async function never uses await', category: 'Async Stability' },\n 'ai-guard/no-redundant-await': { description: 'Redundant await in return position', category: 'Async Stability' },\n 'ai-guard/no-hardcoded-secret': { description: 'Secrets should come from environment variables', category: 'Security' },\n 'ai-guard/no-eval-dynamic': { description: 'eval() with dynamic input is a security risk', category: 'Security' },\n 'ai-guard/no-sql-string-concat': { description: 'SQL string concatenation enables injection', category: 'Security' },\n 'ai-guard/no-unsafe-deserialize': { description: 'JSON.parse on untrusted input without validation', category: 'Security' },\n 'ai-guard/require-auth-middleware': { description: 'Route handler missing authentication middleware', category: 'Security' },\n 'ai-guard/require-authz-check': { description: 'Missing authorization check for resource access', category: 'Security' },\n 'ai-guard/no-console-in-handler': { description: 'console.log in route handlers should be a logger', category: 'AI Patterns' },\n 'ai-guard/no-duplicate-logic-block': { description: 'Duplicate consecutive code blocks should be extracted', category: 'AI Patterns' },\n 'ai-guard/no-dead-branch': { description: 'Always-true/false condition creates dead or unreachable code', category: 'AI Patterns' },\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction getProjectName(cwd: string): string {\n try {\n const pkgPath = path.join(cwd, 'package.json');\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { name?: string };\n if (pkg.name) return pkg.name;\n }\n } catch { /* fall through */ }\n return path.basename(cwd);\n}\n\nfunction getPluginVersion(cwd: string): string {\n try {\n const pkgPath = path.resolve(__dirname, '../../package.json');\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { version?: string };\n if (pkg.version) return pkg.version;\n }\n } catch { /* fall through */ }\n try {\n const pkgPath = path.join(cwd, 'node_modules', 'eslint-plugin-ai-guard', 'package.json');\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { version?: string };\n if (pkg.version) return pkg.version;\n }\n } catch { /* fall through */ }\n return '0.0.0';\n}\n\nfunction calculateScore(totalErrors: number, totalWarnings: number): number {\n // Errors cost 5 points each, warnings cost 2 points each, min 0\n const penalty = totalErrors * 5 + totalWarnings * 2;\n return Math.max(0, Math.min(100, 100 - penalty));\n}\n\n// ─── Report Data Builder ──────────────────────────────────────────────────────\n\nexport function buildReportData(\n result: RunResult,\n preset: string,\n scannedPath: string,\n cwd: string,\n): ReportData {\n const projectName = getProjectName(cwd);\n const version = getPluginVersion(cwd);\n const score = calculateScore(result.totalErrors, result.totalWarnings);\n\n // Top files with error/warning breakdown\n const topFiles = result.files\n .sort((a, b) => b.issues.length - a.issues.length)\n .slice(0, 10)\n .map((f) => ({\n path: f.filePath,\n count: f.issues.length,\n errors: f.errorCount,\n warnings: f.warningCount,\n }));\n\n // Category breakdown\n const categoryBreakdown: Record<string, number> = {};\n for (const [rule, count] of result.ruleBreakdown.entries()) {\n const cat = RULE_META[rule]?.category ?? 'Other';\n categoryBreakdown[cat] = (categoryBreakdown[cat] ?? 0) + count;\n }\n\n // Top 5 rules with real examples\n const sortedRules = [...result.ruleBreakdown.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 5);\n\n const topRules = sortedRules.map(([rule, count]) => {\n const meta = RULE_META[rule] ?? { description: 'Rule violation', category: 'Other' };\n\n // Find a real example from the codebase\n let example: { file: string; line: number; column: number; message: string } | null = null;\n for (const file of result.files) {\n const issue = file.issues.find((i) => i.ruleId === rule);\n if (issue) {\n example = {\n file: file.filePath,\n line: issue.line,\n column: issue.column,\n message: issue.message,\n };\n break;\n }\n }\n\n return {\n rule: rule.replace(/^ai-guard\\//, ''),\n count,\n description: meta.description,\n category: meta.category,\n example,\n };\n });\n\n // Confidence tiers for display (computed from rule assignment)\n const CONFIDENCE_ASSIGNMENT: Record<string, 'high' | 'medium' | 'low'> = {\n 'ai-guard/no-hardcoded-secret': 'high',\n 'ai-guard/no-eval-dynamic': 'high',\n 'ai-guard/no-floating-promise': 'high',\n 'ai-guard/no-empty-catch': 'high',\n 'ai-guard/no-sql-string-concat': 'medium',\n 'ai-guard/no-await-in-loop': 'medium',\n 'ai-guard/require-auth-middleware': 'medium',\n 'ai-guard/require-authz-check': 'medium',\n 'ai-guard/no-catch-log-rethrow': 'medium',\n 'ai-guard/no-catch-without-use': 'medium',\n 'ai-guard/no-unsafe-deserialize': 'medium',\n 'ai-guard/no-async-without-await': 'low',\n 'ai-guard/no-async-array-callback': 'low',\n 'ai-guard/no-dead-branch': 'low',\n 'ai-guard/no-broad-exception': 'low',\n 'ai-guard/no-console-in-handler': 'low',\n 'ai-guard/no-duplicate-logic-block': 'low',\n 'ai-guard/no-redundant-await': 'low',\n };\n let highCount = 0;\n let mediumCount = 0;\n let lowCount = 0;\n for (const [rule, count] of result.ruleBreakdown.entries()) {\n const tier = CONFIDENCE_ASSIGNMENT[rule] ?? 'low';\n if (tier === 'high') highCount += count;\n else if (tier === 'medium') mediumCount += count;\n else lowCount += count;\n }\n const ecosystemCount = result.ecosystemIssues?.length ?? 0;\n const parserErrorCount = result.parserErrors?.length ?? 0;\n\n return {\n projectName,\n version,\n generatedAt: new Date().toISOString(),\n preset,\n scannedPath,\n durationMs: result.durationMs,\n totalIssues: result.totalIssues,\n totalErrors: result.totalErrors,\n totalWarnings: result.totalWarnings,\n score,\n ruleBreakdown: Object.fromEntries(result.ruleBreakdown),\n topFiles,\n topRules,\n categoryBreakdown,\n highCount,\n mediumCount,\n lowCount,\n ecosystemCount,\n parserErrorCount,\n };\n}\n\n// ─── HTML Template ────────────────────────────────────────────────────────────\n\nexport function generateHtml(data: ReportData): string {\n const scoreColor = data.score >= 80 ? '#10b981' : data.score >= 50 ? '#f59e0b' : '#ef4444';\n const scoreLabel = data.score >= 80 ? 'Great' : data.score >= 50 ? 'Needs Work' : 'Critical';\n const formattedDate = new Date(data.generatedAt).toLocaleString();\n\n const topFilesRows = data.topFiles.length === 0\n ? `<tr><td colspan=\"4\" style=\"text-align:center;color:#6b7280;padding:2rem;\">No issues found</td></tr>`\n : data.topFiles.map((f) => {\n const heatColor = f.errors > 0\n ? `rgba(239,68,68,${Math.min(0.9, 0.2 + f.errors * 0.1)})`\n : `rgba(245,158,11,${Math.min(0.9, 0.2 + f.warnings * 0.05)})`;\n return `\n <tr style=\"border-bottom:1px solid #1f2937;\">\n <td style=\"padding:0.75rem 1rem;font-family:monospace;font-size:0.8rem;color:#e5e7eb;max-width:300px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\" title=\"${escHtml(f.path)}\">${escHtml(f.path)}</td>\n <td style=\"padding:0.75rem 1rem;text-align:center;\"><span style=\"background:${heatColor};border-radius:9999px;padding:0.2rem 0.7rem;font-weight:600;font-size:0.85rem;\">${f.count}</span></td>\n <td style=\"padding:0.75rem 1rem;text-align:center;color:#f87171;\">${f.errors}</td>\n <td style=\"padding:0.75rem 1rem;text-align:center;color:#fbbf24;\">${f.warnings}</td>\n </tr>`;\n }).join('');\n\n const topRulesCards = data.topRules.length === 0\n ? `<div style=\"text-align:center;color:#6b7280;padding:2rem;\">No rules fired — clean codebase!</div>`\n : data.topRules.map((r, i) => {\n const catColor: Record<string, string> = {\n 'Reliability': '#ec4899', 'Async Stability': '#8b5cf6',\n 'Security': '#ef4444', 'AI Patterns': '#14b8a6', Other: '#6b7280',\n };\n const color = catColor[r.category] ?? '#6b7280';\n const exampleHtml = r.example\n ? `<div style=\"margin-top:0.75rem;background:#0f172a;border-radius:0.5rem;padding:0.75rem;border-left:3px solid ${color};\">\n <div style=\"font-size:0.75rem;color:#94a3b8;margin-bottom:0.35rem;\">${escHtml(r.example.file)}:${r.example.line}:${r.example.column}</div>\n <code style=\"font-size:0.8rem;color:#f1f5f9;white-space:pre-wrap;word-break:break-all;\">${escHtml(r.example.message)}</code>\n </div>`\n : '';\n return `\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1.25rem;display:flex;flex-direction:column;gap:0.5rem;\">\n <div style=\"display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:0.5rem;\">\n <div style=\"display:flex;align-items:center;gap:0.75rem;\">\n <span style=\"background:#1f2937;color:#9ca3af;font-size:0.75rem;padding:0.15rem 0.5rem;border-radius:9999px;\">#${i + 1}</span>\n <code style=\"font-size:0.9rem;color:#f9fafb;font-weight:600;\">${escHtml(r.rule)}</code>\n </div>\n <div style=\"display:flex;align-items:center;gap:0.5rem;\">\n <span style=\"background:${color}22;color:${color};border:1px solid ${color}44;font-size:0.72rem;border-radius:9999px;padding:0.15rem 0.6rem;\">${escHtml(r.category)}</span>\n <span style=\"background:#374151;color:#e5e7eb;font-size:0.8rem;border-radius:9999px;padding:0.2rem 0.7rem;font-weight:600;\">${r.count}×</span>\n </div>\n </div>\n <p style=\"color:#9ca3af;font-size:0.85rem;margin:0;\">${escHtml(r.description)}</p>\n ${exampleHtml}\n </div>`;\n }).join('');\n\n const categoryCards = Object.entries(data.categoryBreakdown).map(([cat, count]) => {\n const catColor: Record<string, string> = {\n 'Reliability': '#ec4899', 'Async Stability': '#8b5cf6',\n 'Security': '#ef4444', 'AI Patterns': '#14b8a6', Other: '#6b7280',\n };\n const color = catColor[cat] ?? '#6b7280';\n return `\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1.25rem;display:flex;flex-direction:column;gap:0.5rem;\">\n <div style=\"font-size:0.8rem;color:#9ca3af;\">${escHtml(cat)}</div>\n <div style=\"font-size:2rem;font-weight:700;color:${color};\">${count}</div>\n <div style=\"background:#1f2937;border-radius:9999px;height:4px;overflow:hidden;\"><div style=\"background:${color};height:100%;width:${Math.min(100, (count / Math.max(data.totalIssues, 1)) * 100)}%;transition:width 0.8s ease;\"></div></div>\n </div>`;\n }).join('');\n\n const cleanBanner = data.totalIssues === 0\n ? `<div style=\"background:#064e3b;border:1px solid #10b981;border-radius:1rem;padding:2rem;text-align:center;margin-bottom:2rem;\">\n <div style=\"font-size:2.5rem;\">🎉</div>\n <div style=\"font-size:1.5rem;font-weight:700;color:#10b981;margin:0.5rem 0;\">Clean Codebase!</div>\n <div style=\"color:#6ee7b7;\">No AI guard issues detected. Your code is production-ready.</div>\n </div>`\n : '';\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>AI Guard Report — ${escHtml(data.projectName)}</title>\n <script src=\"https://cdn.tailwindcss.com\"></script>\n <style>\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body { background: #030712; color: #f9fafb; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; min-height: 100vh; }\n @keyframes pulse-score { 0%, 100% { opacity: 1; } 50% { opacity: 0.8; } }\n @keyframes slide-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }\n .card { animation: slide-in 0.4s ease both; }\n ::-webkit-scrollbar { width: 6px; height: 6px; }\n ::-webkit-scrollbar-track { background: #111827; }\n ::-webkit-scrollbar-thumb { background: #374151; border-radius: 3px; }\n </style>\n</head>\n<body>\n\n<!-- ── Header ── -->\n<header style=\"background:linear-gradient(135deg,#0f172a 0%,#1e1b4b 50%,#0f172a 100%);border-bottom:1px solid #1f2937;padding:2rem 2rem 1.5rem;\">\n <div style=\"max-width:1100px;margin:0 auto;\">\n <div style=\"display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:1rem;\">\n <div>\n <div style=\"display:flex;align-items:center;gap:0.75rem;margin-bottom:0.4rem;\">\n <span style=\"font-size:1.5rem;\">🛡️</span>\n <span style=\"font-size:0.85rem;color:#818cf8;font-weight:600;letter-spacing:0.05em;\">AI GUARD REPORT</span>\n </div>\n <h1 style=\"font-size:1.8rem;font-weight:700;color:#f9fafb;\">${escHtml(data.projectName)}</h1>\n <p style=\"color:#6b7280;font-size:0.85rem;margin-top:0.25rem;\">Scanned: <code style=\"color:#94a3b8;\">${escHtml(data.scannedPath)}</code> · Preset: <code style=\"color:#94a3b8;\">${escHtml(data.preset)}</code> · ${data.durationMs}ms</p>\n </div>\n <div style=\"text-align:center;\">\n <div style=\"font-size:0.75rem;color:#6b7280;margin-bottom:0.75rem;letter-spacing:0.05em;\">SIGNAL CONFIDENCE</div>\n <div style=\"display:flex;flex-direction:column;gap:0.4rem;\">\n <div style=\"display:flex;align-items:center;gap:0.5rem;\">\n <span style=\"width:8px;height:8px;border-radius:50%;background:#ef4444;display:inline-block;\"></span>\n <span style=\"font-size:0.8rem;color:#f87171;font-weight:600;\">${data.highCount} high-confidence</span>\n </div>\n <div style=\"display:flex;align-items:center;gap:0.5rem;\">\n <span style=\"width:8px;height:8px;border-radius:50%;background:#f59e0b;display:inline-block;\"></span>\n <span style=\"font-size:0.8rem;color:#fbbf24;font-weight:600;\">${data.mediumCount} medium-confidence</span>\n </div>\n <div style=\"display:flex;align-items:center;gap:0.5rem;\">\n <span style=\"width:8px;height:8px;border-radius:50%;background:#6b7280;display:inline-block;\"></span>\n <span style=\"font-size:0.8rem;color:#9ca3af;font-weight:600;\">${data.lowCount} suggestions</span>\n </div>\n ${data.ecosystemCount > 0 ? `<div style=\"display:flex;align-items:center;gap:0.5rem;margin-top:0.25rem;\">\n <span style=\"font-size:0.75rem;color:#4b5563;\">⚠ ${data.ecosystemCount} config issue${data.ecosystemCount !== 1 ? 's' : ''} (not ai-guard)</span>\n </div>` : ''}\n </div>\n </div>\n </div>\n <p style=\"color:#4b5563;font-size:0.75rem;margin-top:1rem;\">Generated ${escHtml(formattedDate)}</p>\n </div>\n</header>\n\n<!-- ── Main ── -->\n<main style=\"max-width:1100px;margin:0 auto;padding:2rem;\">\n\n ${cleanBanner}\n\n <!-- Summary Cards -->\n <div class=\"card\" style=\"display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:1rem;margin-bottom:2rem;\">\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1.25rem;\">\n <div style=\"font-size:0.75rem;color:#6b7280;margin-bottom:0.5rem;\">TOTAL ISSUES</div>\n <div style=\"font-size:2.5rem;font-weight:800;color:#f9fafb;\">${data.totalIssues}</div>\n </div>\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1.25rem;\">\n <div style=\"font-size:0.75rem;color:#6b7280;margin-bottom:0.5rem;\">ERRORS</div>\n <div style=\"font-size:2.5rem;font-weight:800;color:#f87171;\">${data.totalErrors}</div>\n </div>\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1.25rem;\">\n <div style=\"font-size:0.75rem;color:#6b7280;margin-bottom:0.5rem;\">WARNINGS</div>\n <div style=\"font-size:2.5rem;font-weight:800;color:#fbbf24;\">${data.totalWarnings}</div>\n </div>\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1.25rem;\">\n <div style=\"font-size:0.75rem;color:#6b7280;margin-bottom:0.5rem;\">FILES AFFECTED</div>\n <div style=\"font-size:2.5rem;font-weight:800;color:#818cf8;\">${data.topFiles.length}</div>\n </div>\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1.25rem;\">\n <div style=\"font-size:0.75rem;color:#6b7280;margin-bottom:0.5rem;\">RULES FIRED</div>\n <div style=\"font-size:2.5rem;font-weight:800;color:#34d399;\">${Object.keys(data.ruleBreakdown).length}</div>\n </div>\n </div>\n\n <!-- Issues by Category -->\n ${Object.keys(data.categoryBreakdown).length > 0 ? `\n <section class=\"card\" style=\"margin-bottom:2rem;\">\n <h2 style=\"font-size:1rem;font-weight:600;color:#e5e7eb;margin-bottom:1rem;display:flex;align-items:center;gap:0.5rem;\">\n <span>📊</span> Issues by Category\n </h2>\n <div style=\"display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:1rem;\">\n ${categoryCards}\n </div>\n </section>` : ''}\n\n <!-- Severity Heatmap by File -->\n <section class=\"card\" style=\"margin-bottom:2rem;\">\n <h2 style=\"font-size:1rem;font-weight:600;color:#e5e7eb;margin-bottom:1rem;display:flex;align-items:center;gap:0.5rem;\">\n <span>🔥</span> Severity Heatmap — Top Files\n </h2>\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;overflow:hidden;\">\n <table style=\"width:100%;border-collapse:collapse;\">\n <thead>\n <tr style=\"background:#0f172a;text-align:left;\">\n <th style=\"padding:0.75rem 1rem;font-size:0.75rem;color:#6b7280;font-weight:500;letter-spacing:0.05em;\">FILE</th>\n <th style=\"padding:0.75rem 1rem;font-size:0.75rem;color:#6b7280;font-weight:500;letter-spacing:0.05em;text-align:center;\">ISSUES</th>\n <th style=\"padding:0.75rem 1rem;font-size:0.75rem;color:#6b7280;font-weight:500;letter-spacing:0.05em;text-align:center;\">ERRORS</th>\n <th style=\"padding:0.75rem 1rem;font-size:0.75rem;color:#6b7280;font-weight:500;letter-spacing:0.05em;text-align:center;\">WARNINGS</th>\n </tr>\n </thead>\n <tbody>\n ${topFilesRows}\n </tbody>\n </table>\n </div>\n </section>\n\n <!-- Top 5 Rules -->\n <section class=\"card\" style=\"margin-bottom:2rem;\">\n <h2 style=\"font-size:1rem;font-weight:600;color:#e5e7eb;margin-bottom:1rem;display:flex;align-items:center;gap:0.5rem;\">\n <span>⚡</span> Top Rules That Fired\n </h2>\n <div style=\"display:flex;flex-direction:column;gap:1rem;\">\n ${topRulesCards}\n </div>\n </section>\n\n <!-- Next Steps -->\n <section class=\"card\" style=\"margin-bottom:2rem;\">\n <h2 style=\"font-size:1rem;font-weight:600;color:#e5e7eb;margin-bottom:1rem;display:flex;align-items:center;gap:0.5rem;\">\n <span>🚀</span> Suggested Next Steps\n </h2>\n <div style=\"display:flex;flex-direction:column;gap:0.75rem;\">\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1rem;display:flex;align-items:flex-start;gap:0.75rem;\">\n <span style=\"font-size:1.2rem;flex-shrink:0;\">🔧</span>\n <div>\n <div style=\"color:#f9fafb;font-size:0.9rem;font-weight:500;margin-bottom:0.2rem;\">Auto-fix safe issues</div>\n <code style=\"color:#818cf8;font-size:0.8rem;\">npx ai-guard run --fix</code>\n </div>\n </div>\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1rem;display:flex;align-items:flex-start;gap:0.75rem;\">\n <span style=\"font-size:1.2rem;flex-shrink:0;\">🤖</span>\n <div>\n <div style=\"color:#f9fafb;font-size:0.9rem;font-weight:500;margin-bottom:0.2rem;\">Prevent future AI-generated issues</div>\n <code style=\"color:#818cf8;font-size:0.8rem;\">npx ai-guard init-context</code>\n </div>\n </div>\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1rem;display:flex;align-items:flex-start;gap:0.75rem;\">\n <span style=\"font-size:1.2rem;flex-shrink:0;\">📋</span>\n <div>\n <div style=\"color:#f9fafb;font-size:0.9rem;font-weight:500;margin-bottom:0.2rem;\">Save baseline & track only new issues</div>\n <code style=\"color:#818cf8;font-size:0.8rem;\">npx ai-guard baseline</code>\n </div>\n </div>\n <div style=\"background:#111827;border:1px solid #1f2937;border-radius:0.75rem;padding:1rem;display:flex;align-items:flex-start;gap:0.75rem;\">\n <span style=\"font-size:1.2rem;flex-shrink:0;\">📤</span>\n <div>\n <div style=\"color:#f9fafb;font-size:0.9rem;font-weight:500;margin-bottom:0.2rem;\">Share this report with your team</div>\n <div style=\"color:#6b7280;font-size:0.8rem;\">Send the <code style=\"color:#94a3b8;\">ai-guard-report.html</code> file — it's fully self-contained.</div>\n </div>\n </div>\n </div>\n </section>\n\n</main>\n\n<!-- ── Footer ── -->\n<footer style=\"border-top:1px solid #1f2937;padding:1.5rem 2rem;text-align:center;\">\n <p style=\"color:#4b5563;font-size:0.8rem;\">\n Generated by <a href=\"https://github.com/YashJadhav21/eslint-plugin-ai-guard\" style=\"color:#818cf8;text-decoration:none;\">eslint-plugin-ai-guard</a> v${escHtml(data.version)}\n · \n <a href=\"https://github.com/YashJadhav21/eslint-plugin-ai-guard\" style=\"color:#818cf8;text-decoration:none;\">GitHub</a>\n </p>\n</footer>\n\n</body>\n</html>`;\n}\n\n// ─── Escape ───────────────────────────────────────────────────────────────────\n\nfunction escHtml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n// ─── Command ──────────────────────────────────────────────────────────────────\n\nexport function registerReportCommand(program: Command): void {\n program\n .command('report')\n .description(\n 'Generate a beautiful HTML report of AI Guard scan results\\n' +\n 'Perfect for sharing with your team or in Slack.',\n )\n .option('--path <dir>', 'Directory or file to scan', '.')\n .option('--preset <preset>', 'Rule preset: recommended | strict | security', 'recommended')\n .option('--html', 'Generate HTML report (default behavior)')\n .option('--json', 'Output raw JSON to stdout instead of writing HTML')\n .option('--output <filename>', 'Output file name', 'ai-guard-report.html')\n .option('--no-open', 'Do not open the report in the browser after generating')\n .action(async (opts: {\n path: string;\n preset: string;\n html?: boolean;\n json?: boolean;\n output: string;\n open: boolean;\n }) => {\n const preset = (['recommended', 'strict', 'security'].includes(opts.preset)\n ? opts.preset\n : 'recommended') as 'recommended' | 'strict' | 'security';\n\n const spinner = opts.json\n ? null\n : ora({ text: 'Scanning…', color: 'cyan' }).start();\n\n let result: RunResult;\n try {\n result = await runEslint({ preset, targetPath: opts.path });\n spinner?.stop();\n } catch (err: unknown) {\n spinner?.stop();\n const msg = err instanceof Error ? err.message : String(err);\n log.error(msg);\n process.exit(1);\n return;\n }\n\n const cwd = process.cwd();\n const reportData = buildReportData(result, preset, opts.path, cwd);\n\n // ── JSON mode ────────────────────────────────────────────────────────────\n\n if (opts.json) {\n console.log(JSON.stringify(reportData, null, 2));\n process.exit(0);\n return;\n }\n\n // ── HTML mode ────────────────────────────────────────────────────────────\n\n log.banner('AI GUARD REPORT');\n log.blank();\n\n const html = generateHtml(reportData);\n const outputPath = path.resolve(cwd, opts.output);\n\n fs.writeFileSync(outputPath, html, 'utf-8');\n\n log.success(`Report saved: ${opts.output}`);\n log.info(\n `Score: ${reportData.score}/100 · ${reportData.totalErrors} errors · ${reportData.totalWarnings} warnings`,\n );\n log.blank();\n\n // Open in browser\n if (opts.open !== false) {\n try {\n const { default: open } = await import('open').catch(() => {\n // open package may not be installed — fall back to platform commands\n return { default: null };\n });\n\n if (open) {\n await open(outputPath);\n log.info('Opened in your browser.');\n } else {\n // Fallback: use platform-native open command\n const { execSync } = await import('child_process');\n const cmd = process.platform === 'win32'\n ? `start \"\" \"${outputPath}\"`\n : process.platform === 'darwin'\n ? `open \"${outputPath}\"`\n : `xdg-open \"${outputPath}\"`;\n execSync(cmd);\n log.info('Opened in your browser.');\n }\n } catch {\n log.info(`Open manually: file://${outputPath}`);\n }\n } else {\n log.info(`Open: file://${outputPath}`);\n }\n\n log.blank();\n });\n}\n"],"mappings":"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","names":["fs","path","import_fs","import_path","import_fs","import_path","import_chalk","chalk","createRequire","path","fs","program","ora","chalk","import_chalk","import_path","import_fs","import_fs","import_path","path","fs","path","program","chalk","createRequire","pathToFileURL","content","isInvalidAiGuardConfig","fs","import_chalk","import_path","path","program","isInvalidAiGuardConfig","createRequire","chalk","import_chalk","import_path","program","chalk","path","import_chalk","import_path","program","chalk","path","import_fs","import_path","import_chalk","import_ora","path","fs","program","ora","chalk","import_fs","import_path","import_chalk","import_prompts","path","getPackageVersion","fs","program","getPackageVersion","chalk","path","fs","import_fs","import_path","import_ora","path","fs","program","ora","path","fs"]}
|