/**
* Compute an inline HTML diff between two strings.
*
* For content with block-level HTML elements (p, h1-h6, etc.), aligns blocks
* by tag name and diffs within each block individually, preventing diff markers
* from crossing element boundaries.
*
* For plain text or inline-only HTML, uses flat word-level diffing with
* post-processing to merge long runs of consecutive modifications.
*/
export declare function computeDiff(before: string, after: string): string;
/**
* Render the new value entirely as an insertion, with no deletions.
*
* Used when diffing against the original is pointless — e.g. translations,
* where virtually the whole text changes and an interleaved del/ins diff is
* just noise. The result reuses the same markup as computeDiff, so the
* approval preview styling is identical.
*
* Block-level HTML is preserved by wrapping each block's inner content in
* rather than wrapping the block tags themselves.
*/
export declare function computeInsertion(after: string): string;
/**
* One chunk of a field's diff that can be individually accepted or rejected
* by the user. A markup field becomes an ordered list of segments; lists
* (/) become a `list` segment whose children are the individual
* - atoms.
*
* Acceptance semantics (see `reassembleValue`):
* - matched: accepted → afterHtml, rejected → beforeHtml
* - inserted: accepted → keep, rejected → drop
* - deleted: accepted → drop (matches after), rejected → restore (matches before)
*/
export type AtomicSegment = {
kind: 'atomic';
id: string;
tag: string;
openTag: string;
closeTag: string;
beforeHtml: string;
afterHtml: string;
changed: boolean;
status: 'matched' | 'inserted' | 'deleted';
};
export type ListSegment = {
kind: 'list';
id: string;
tag: 'ul' | 'ol';
openTag: string;
closeTag: string;
children: AtomicSegment[];
};
export type Segment = AtomicSegment | ListSegment;
/**
* Split a before/after value pair into chunks the user can individually
* accept or reject. Returns null when chunk-level approval can't apply:
*
* - non-markup fields
* - either side contains inline-only HTML or stray top-level text
* (`parseBlocks` returns null)
* - both sides empty
*
* Two-level structure: top-level block alignment, then a one-level recurse
* into matched
/ blocks whose innerHTML differs. - is the leaf.
*
* Used for both rewrites (word-diff preview) and translations
* (insertion-only preview). The difference is at the renderer.
*/
export declare function splitIntoSegments(before: string, after: string, fieldType: 'plain' | 'markup'): Segment[] | null;
/**
* True when at least one segment (or list child) actually changes. Use to
* skip the approval row for fields where the proposed value already matches
* the current value chunk-for-chunk.
*/
export declare function segmentsHaveChanges(segments: Segment[]): boolean;
/**
* Render segments as preview HTML with `data-chunk-index` attributes on each
* atomic block, so the approval UI can locate each chunk's DOM bounds. The
* resulting markup replaces the editable's innerHTML during preview, just
* like `computeDiff` / `computeInsertion`.
*
* `insertionsOnly` matches the existing prop on DiffApproval — translations
* render new content as a single per leaf, rewrites render word-diffs.
*
* `acceptedById` (optional) makes the preview track per-segment acceptance:
* rejected matched segments render their original content with no markers,
* rejected insertions render as deletions, rejected deletions render plain.
* Defaults to "all accepted" when omitted (initial render).
*/
export declare function renderSegmentDiff(segments: Segment[], opts?: {
insertionsOnly?: boolean;
acceptedById?: Record;
}): string;
/**
* Reassemble a field value from segments using per-segment acceptance.
* Acceptance defaults to `true` for any unmapped segment id, mirroring the
* DiffApproval initial state.
*
* For `list` segments the wrapper is emitted only when at least one child
* survives — accepting a full deletion of every item drops the list itself.
*/
export declare function reassembleValue(segments: Segment[], acceptedById: Record): string;
/**
* Walk a segment list and return every atomic segment in reading order,
* including those inside list wrappers. Used by the approval UI for
* keyboard nav, selection initialisation, and the rejected-segments
* feedback to the agent.
*/
export declare function flattenSegments(segments: Segment[]): AtomicSegment[];