import { structuredPatch } from 'diff'; /** * Creates a smart diff that returns full content when changes exceed threshold. * * When more than `threshold` (default 50%) of lines have changed, showing a diff * is not useful - we return the full new content instead. */ export function createSmartDiff(options) { const { oldContent, newContent, threshold = 0.5, label = 'content' } = options; const patch = structuredPatch(label, label, oldContent, newContent, 'previous', 'current', { context: 3, }); // Count added and removed lines let addedLines = 0; let removedLines = 0; for (const hunk of patch.hunks) { for (const line of hunk.lines) { if (line.startsWith('+')) { addedLines++; } else if (line.startsWith('-')) { removedLines++; } } } // No changes - return full content if (addedLines === 0 && removedLines === 0) { return { type: 'no-change', content: newContent }; } // Calculate change ratio: use max(added, removed) since a replacement counts as both // This ensures the ratio stays in 0-100% range const oldLineCount = oldContent.split('\n').length; const newLineCount = newContent.split('\n').length; const maxLines = Math.max(oldLineCount, newLineCount, 1); // Avoid division by zero const changedLines = Math.max(addedLines, removedLines); const changeRatio = Math.min(changedLines / maxLines, 1); // Cap at 100% // Build unified diff string from structured patch const diffLines = [`--- ${label} (previous)`, `+++ ${label} (current)`]; for (const hunk of patch.hunks) { diffLines.push(`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`); diffLines.push(...hunk.lines); } const diffString = diffLines.join('\n'); // Return full content if changes exceed threshold OR if diff is longer than full content if (changeRatio >= threshold || diffString.length >= newContent.length) { return { type: 'full', content: newContent }; } return { type: 'diff', content: diffString }; } //# sourceMappingURL=diff-utils.js.map