vibesec
Version:
Security scanner for AI-generated code - detects vulnerabilities in vibe-coded projects
144 lines • 6.37 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlainTextReporter = void 0;
const chalk_1 = __importDefault(require("chalk"));
const types_1 = require("../scanner/core/types");
class PlainTextReporter {
generate(result) {
const lines = [];
lines.push(chalk_1.default.bold('═'.repeat(70)));
lines.push(chalk_1.default.bold.cyan(' VibeSec Security Scan Results'));
lines.push(chalk_1.default.bold('═'.repeat(70)));
lines.push('');
lines.push(chalk_1.default.gray(`📁 Scanned: ${result.scan.path}`));
lines.push(chalk_1.default.gray(`📊 Files scanned: ${result.scan.filesScanned}`));
lines.push(chalk_1.default.gray(`⏱️ Duration: ${result.scan.duration.toFixed(2)}s`));
lines.push('');
lines.push(this.formatSeverityCount('CRITICAL', result.summary.bySeverity.critical));
lines.push(this.formatSeverityCount('HIGH', result.summary.bySeverity.high));
lines.push(this.formatSeverityCount('MEDIUM', result.summary.bySeverity.medium));
lines.push(this.formatSeverityCount('LOW', result.summary.bySeverity.low));
lines.push('');
if (result.findings.length === 0) {
lines.push(chalk_1.default.green.bold('✅ No security issues detected!'));
lines.push('');
}
else {
lines.push(chalk_1.default.bold('═'.repeat(70)));
lines.push('');
const grouped = this.groupBySeverity(result.findings);
const severityOrder = [
types_1.Severity.CRITICAL,
types_1.Severity.HIGH,
types_1.Severity.MEDIUM,
types_1.Severity.LOW,
];
for (const severity of severityOrder) {
const findings = grouped[severity] || [];
if (findings.length === 0)
continue;
for (const finding of findings) {
lines.push(this.formatFinding(finding));
lines.push(chalk_1.default.bold('─'.repeat(70)));
lines.push('');
}
}
}
lines.push(chalk_1.default.bold('═'.repeat(70)));
lines.push('');
lines.push(chalk_1.default.bold('📋 Summary:'));
lines.push(` ✓ ${result.summary.total} security issues detected`);
if (result.summary.bySeverity.critical > 0) {
lines.push(chalk_1.default.red(` ✓ ${result.summary.bySeverity.critical} require immediate attention (CRITICAL)`));
}
lines.push(' ✓ All issues include fix recommendations');
lines.push('');
if (result.summary.total > 0) {
lines.push(chalk_1.default.bold('💡 Next Steps:'));
lines.push(' 1. Fix CRITICAL issues immediately');
lines.push(' 2. Review HIGH severity issues');
lines.push(" 3. Run 'vibesec scan .' again to verify fixes");
lines.push('');
}
lines.push(chalk_1.default.bold('═'.repeat(70)));
return lines.join('\n');
}
formatSeverityCount(label, count) {
const emoji = this.getSeverityEmoji(label.toLowerCase());
const color = this.getSeverityColor(label.toLowerCase());
return color(`${emoji} ${label} Issues: ${count}`);
}
formatFinding(finding) {
const lines = [];
const emoji = this.getSeverityEmoji(finding.severity);
const color = this.getSeverityColor(finding.severity);
lines.push(color.bold(`${emoji} ${finding.severity.toUpperCase()}: ${finding.title}`));
lines.push('');
lines.push(chalk_1.default.gray(`📍 Location: ${finding.location.file}:${finding.location.line}`));
lines.push(chalk_1.default.gray('📝 Code:'));
lines.push(chalk_1.default.gray(finding.snippet));
lines.push('');
lines.push(chalk_1.default.yellow(`⚠️ Risk: ${finding.description}`));
lines.push('');
lines.push(chalk_1.default.green('✅ Fix:'));
lines.push(finding.fix.recommendation);
lines.push('');
if (finding.fix.before) {
lines.push(chalk_1.default.gray(' Before:'));
lines.push(chalk_1.default.red(` ${finding.fix.before}`));
lines.push('');
}
if (finding.fix.references.length > 0) {
lines.push(chalk_1.default.gray('📚 References:'));
finding.fix.references.forEach((ref) => {
lines.push(chalk_1.default.gray(` - ${ref}`));
});
lines.push('');
}
if (finding.metadata.cwe || finding.metadata.owasp) {
const meta = [];
if (finding.metadata.cwe)
meta.push(finding.metadata.cwe);
if (finding.metadata.owasp)
meta.push(`OWASP ${finding.metadata.owasp}`);
lines.push(chalk_1.default.gray(`🔖 ${meta.join(' • ')}`));
lines.push('');
}
return lines.join('\n');
}
getSeverityEmoji(severity) {
const emojis = {
[types_1.Severity.CRITICAL]: '🔴',
[types_1.Severity.HIGH]: '🟡',
[types_1.Severity.MEDIUM]: '🟢',
[types_1.Severity.LOW]: '⚪',
};
return emojis[severity] || '⚪';
}
getSeverityColor(severity) {
const colors = {
[types_1.Severity.CRITICAL]: chalk_1.default.red,
[types_1.Severity.HIGH]: chalk_1.default.yellow,
[types_1.Severity.MEDIUM]: chalk_1.default.blue,
[types_1.Severity.LOW]: chalk_1.default.gray,
};
return colors[severity] || chalk_1.default.white;
}
groupBySeverity(findings) {
const grouped = {
[types_1.Severity.CRITICAL]: [],
[types_1.Severity.HIGH]: [],
[types_1.Severity.MEDIUM]: [],
[types_1.Severity.LOW]: [],
};
for (const finding of findings) {
grouped[finding.severity].push(finding);
}
return grouped;
}
}
exports.PlainTextReporter = PlainTextReporter;
//# sourceMappingURL=plaintext.js.map