(baseline: Diagnostic[], current: Diagnostic[])
| 77 | return `${d.file}|${d.code ?? ''}|${d.message.trim().toLowerCase()}`; |
| 78 | } |
| 79 | export function diffDiagnostics(baseline: Diagnostic[], current: Diagnostic[]): Diagnostic[] { |
| 80 | const counts = new Map<string, number>(); |
| 81 | for (const d of baseline) { |
| 82 | const s = diagSignature(d); |
| 83 | counts.set(s, (counts.get(s) ?? 0) + 1); |
| 84 | } |
| 85 | const fresh: Diagnostic[] = []; |
| 86 | for (const d of current) { |
| 87 | const s = diagSignature(d); |
| 88 | const remaining = counts.get(s) ?? 0; |
| 89 | if (remaining > 0) counts.set(s, remaining - 1); // consume a pre-existing occurrence |
| 90 | else fresh.push(d); // genuinely new |
| 91 | } |
| 92 | return fresh; |
| 93 | } |
| 94 | |
| 95 | /** Build the corrective message fed back to the model when touched files don't compile. |
| 96 | * Pure. `attempt`/`max` let the wording escalate. */ |
no test coverage detected