(query: string, matches: ApproachMatch[], opts: { topK?: number } = {})
| 120 | * there's only one match (nothing to diff). |
| 121 | */ |
| 122 | export function renderApproachDiffs(query: string, matches: ApproachMatch[], opts: { topK?: number } = {}): string { |
| 123 | if (matches.length === 0) return `No past work on this project resembles "${query}".`; |
| 124 | const top = matches.slice(0, opts.topK ?? 4); |
| 125 | const ref = top[0]!; |
| 126 | const lines: string[] = [`How you approached similar work before — "${query}":`, '']; |
| 127 | |
| 128 | lines.push(`★ Best match [${tag(ref)} · ${ref.when} · ${Math.round(ref.score * 100)}% match]`); |
| 129 | lines.push(` ${head(ref.text)}`); |
| 130 | const rf = fileLinks(ref.files); |
| 131 | if (rf) lines.push(rf); |
| 132 | |
| 133 | if (top.length > 1) { |
| 134 | lines.push('', 'How the other attempts DIFFERED from it:'); |
| 135 | const refFiles = new Set(ref.files ?? []); |
| 136 | top.slice(1).forEach((m, i) => { |
| 137 | lines.push('', `${i + 2}. [${tag(m)} · ${m.when} · ${Math.round(m.score * 100)}% match] ${head(m.text, 100)}`); |
| 138 | if (isMultiline(ref.text) && isMultiline(m.text)) { |
| 139 | lines.push(' ```diff', ...lineDiff(ref.text, m.text).slice(0, 14).map(l => ' ' + l), ' ```'); |
| 140 | } else { |
| 141 | const d = termDiff(ref.text, m.text); |
| 142 | if (d.added.length) lines.push(` + this one adds: ${d.added.join(', ')}`); |
| 143 | if (d.missing.length) lines.push(` − it lacks: ${d.missing.join(', ')}`); |
| 144 | if (!d.added.length && !d.missing.length) lines.push(' ≈ same approach, different occasion'); |
| 145 | } |
| 146 | const fl = fileLinks(m.files, refFiles); |
| 147 | if (fl) lines.push(fl.replace('files:', 'files (+ = not in best match):')); |
| 148 | }); |
| 149 | |
| 150 | const core = commonCore(top.map(m => m.text)); |
| 151 | if (core.length >= 2) lines.push('', `Stable core across all ${top.length}: ${core.join(', ')} — this is how you consistently approach it here.`); |
| 152 | } |
| 153 | lines.push(...renderTimeline(top)); |
| 154 | return lines.join('\n'); |
| 155 | } |
no test coverage detected