Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 2x 2x 2x 7x 7x 7x 7x 7x 7x 7x 7x 2x 7x 7x 7x 2x 7x 7x 7x 7x 7x 7x 7x 7x 7x 6x 6x 7x 1x 1x 1x 7x 1x 1x 1x 1x 1x 1x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 7x 1x 1x 1x 4x 4x 4x 1x 1x 4x 1x 1x 7x 7x 1x 1x 1x 1x 1x 1x 1x 1x 7x 7x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 1x 1x 7x 7x 4x 4x 4x 7x 7x 7x | import { MergedReport } from '../merger/merger';
import { t } from '../i18n/messages';
function severityEmoji(severity: string): string {
switch (severity) {
case 'error': return '🔴';
case 'warning': return '🟡';
case 'info': return '🔵';
default: return '⚪';
}
}
function formatLine(line: number): string {
return Number.isFinite(line) ? `L${line + 1}` : 'L?';
}
export function reportToMarkdown(report: MergedReport): string {
const lines: string[] = [];
lines.push(`# ${t('report.title')}`);
lines.push('');
lines.push(`**${t('report.file')}:** \`${report.filePath}\``);
lines.push(`**${t('report.language')}:** ${report.language}`);
lines.push(`**${t('report.duration')}:** ${(report.duration / 1000).toFixed(1)}s`);
if (report.adapterNames.length > 0) {
lines.push(`**${t('report.tools')}:** ${report.adapterNames.join(', ')}`);
}
if (report.degraded) {
lines.push('');
lines.push(`> ⚠️ ${t('report.degradedBanner')}`);
}
if (report.errors.length > 0) {
lines.push('');
lines.push(`## ${t('report.errors')}`);
for (const err of report.errors) {
lines.push(`- ${err}`);
}
}
lines.push('');
lines.push('---');
lines.push('');
const total = report.linterCount + report.customRuleCount + report.aiCount;
const errors = report.linterDiagnostics.filter(d => d.severity === 'error').length
+ report.customRuleDiagnostics.filter(d => d.severity === 'error').length
+ report.aiFindings.filter(f => f.severity === 'error').length;
const warnings = report.linterDiagnostics.filter(d => d.severity === 'warning').length
+ report.customRuleDiagnostics.filter(d => d.severity === 'warning').length
+ report.aiFindings.filter(f => f.severity === 'warning').length;
const infos = total - errors - warnings;
lines.push(t('report.totalSummary', { 0: String(total), 1: String(errors), 2: String(warnings), 3: String(infos) }));
lines.push('');
if (report.linterDiagnostics.length > 0) {
lines.push(t('report.staticSection', { 0: String(report.linterCount) }));
lines.push('');
for (const diag of report.linterDiagnostics) {
lines.push(`- ${severityEmoji(diag.severity)} \`${diag.ruleId}\` ${formatLine(diag.range.start.line)}`);
lines.push(` ${diag.message}`);
if (diag.suggestion) {
lines.push(` ${t('report.suggestion')}: ${diag.suggestion}`);
}
}
lines.push('');
}
if (report.customRuleDiagnostics.length > 0) {
lines.push(t('report.customSection', { 0: String(report.customRuleCount) }));
lines.push('');
for (const diag of report.customRuleDiagnostics) {
lines.push(`- ${severityEmoji(diag.severity)} \`${diag.ruleId}\` ${formatLine(diag.range.start.line)}`);
lines.push(` ${diag.message}`);
}
lines.push('');
}
if (report.aiFindings.length > 0) {
lines.push(t('report.aiSection', { 0: String(report.aiCount) }));
lines.push('');
for (const finding of report.aiFindings) {
lines.push(`- ${severityEmoji(finding.severity)} [AI] [${finding.category}] \`${finding.ruleId}\` ${formatLine(finding.line)}`);
lines.push(` **${finding.title}**`);
lines.push(` ${finding.description}`);
if (finding.suggestion) {
lines.push(` ${t('report.suggestion')}: ${finding.suggestion}`);
}
}
lines.push('');
}
if (total === 0) {
lines.push(`✅ ${t('report.noProblems')}`);
lines.push('');
}
return lines.join('\n');
}
|