/
antonnov
/
aaaaaaauto
Обзор
Документация
Войти
/
antonnov
/
aaaaaaauto
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
audit-cli.js
129 строк
4 KB
Anton211
first_commit
28 июл 2026, 15:16
28 июл 2026, 15:16
79799f0
Код
Авторство
О чём код?
#!/usr/bin/env node const { program } = require('commander'); const path = require('path'); const fs = require('fs'); const { loadTokens } = require('./src/token-parser'); const { analyzeFrontend } = require('./src/detectors'); const { buildReport } = require('./src/report'); const { generatePatches } = require('./src/fix'); function loadConfig(workdir) { const cfgPath = path.join(workdir, 'AUDIT_CONFIG.json'); if (fs.existsSync(cfgPath)) { try { return JSON.parse(fs.readFileSync(cfgPath, 'utf8')); } catch { return {}; } } return {}; } program .name('audit-cli') .description('CLI harness for AI-agent frontend audit against design system & a11y') .version('1.0.0'); program .requiredOption('--frontend <path>', 'Path to cloned frontend repository') .requiredOption('--design-system <path>', 'Path to cloned design-system repository') .option('--base <ref>', 'Base ref for git diff', 'main') .option('--head <ref>', 'Head ref for git diff', 'HEAD') .option('--workdir <path>', 'Output directory', './audit-output') .option('--full-scan', 'Scan entire codebase instead of diff only') .option('--fixes', 'Enable patches generation', true) .option('--report', 'Enable reports generation', true); program.parse(process.argv); const opts = program.opts(); const frontendPath = path.resolve(opts.frontend); const dsPath = path.resolve(opts.designSystem); const workdir = path.resolve(opts.workdir); if (!fs.existsSync(frontendPath) || !fs.existsSync(dsPath)) { console.error('Error: frontend or design-system path does not exist'); process.exit(1); } if (!fs.existsSync(path.join(frontendPath, '.git'))) { console.error('Error: frontend path is not a git repository'); process.exit(1); } if (!fs.existsSync(path.join(dsPath, '.git'))) { console.error('Error: design-system path is not a git repository'); process.exit(1); } fs.mkdirSync(workdir, { recursive: true }); fs.mkdirSync(path.join(workdir, 'fixes'), { recursive: true }); const reportPath = path.join(workdir, 'report.md'); const reportJsonPath = path.join(workdir, 'report.json'); try { const tokens = loadTokens(dsPath); const config = loadConfig(workdir); const defects = analyzeFrontend({ frontendPath, dsPath, base: opts.base, head: opts.head, fullScan: opts.fullScan, tokens, config, }); if (opts.report) { const report = buildReport({ frontendPath, dsPath, base: opts.base, head: opts.head, defects, tokens, config, }); fs.writeFileSync(reportPath, report.md, 'utf8'); fs.writeFileSync(reportJsonPath, JSON.stringify(report.json, null, 2), 'utf8'); } if (opts.fixes) { generatePatches({ frontendPath, defects, outputDir: path.join(workdir, 'fixes'), }); } const dsComponentsUsed = defects.filter((d) => d.rule === 'ds-component-used').length; const hardcode = defects.filter((d) => d.rule.startsWith('hardcode-')).length; const external = defects.filter((d) => d.rule === 'external-ui-lib').length; const a11y = defects.filter((d) => d.rule.startsWith('a11y-')).length; const totalScanned = new Set(defects.map((d) => d.file)).size; const result = { status: 'ok', workdir, report: reportPath, reportJson: reportJsonPath, fixes: fs.readdirSync(path.join(workdir, 'fixes')).map((f) => path.join(workdir, 'fixes', f)), defects: defects.length, metrics: { dsComponentsUsed, hardcodeIssues: hardcode, externalUIUsed: external, a11yIssues: a11y, filesAnalyzed: totalScanned, }, }; console.log(JSON.stringify(result, null, 2)); process.exit(0); } catch (err) { console.error('Audit error:', err.message); process.exit(2); }