/**
 * Paste collapse for the composer.
 *
 * Large blobs of text pasted into the composer blow out the visible
 * height and destroy the authoring band's feel. Codex-cli solves this
 * by showing a compact placeholder like `[Pasted 1950 chars / 24 lines]`
 * in the visible field while retaining the raw content for submission.
 *
 * This module provides:
 *   - detectPasteInsert: given previous and next controlled values (and
 *     cursor positions), identify an insert that exceeds a size threshold
 *     — that's our heuristic for a paste. Typing adds a few chars per
 *     onChange; paste adds many at once.
 *   - collapsePaste: replace the inserted segment with a unique
 *     placeholder token in the visible value, stashing the raw segment
 *     in a store keyed by the token.
 *   - expandPlaceholders: substitute every placeholder token in a
 *     visible value with its stashed raw content (call before submit).
 *
 * Design choices:
 *   - Placeholder tokens are plain-text markers — not sentinel chars —
 *     so users can see what happened and copy/paste the composer value
 *     through the normal terminal paste path if desired.
 *   - Placeholder insertion point matches the user's insertion point,
 *     so history navigation / edits work as if the placeholder were a
 *     single atomic string. If the user edits inside the placeholder,
 *     the token pattern breaks and the raw content is silently dropped
 *     (submit falls back to the edited visible string). Acceptable —
 *     user visibly broke the token; they can retype.
 *
 * Threshold: 200 chars OR 5+ lines. Anything below reads as typed
 * content (even rapid typing rarely chunks above ~50 chars per onChange).
 */
export interface PasteStore {
    /** Map from placeholder token → original pasted text. */
    readonly entries: Map<string, string>;
    /** Sequential id counter for deterministic token naming. */
    nextId: number;
}
export declare function createPasteStore(): PasteStore;
export declare function resetPasteStore(store: PasteStore): void;
export interface PasteInsert {
    readonly index: number;
    readonly inserted: string;
}
/**
 * Identify a pure-insert diff between `prev` and `next` by comparing
 * common prefix and suffix. Returns null when the change is not a pure
 * insert (e.g. a deletion, a replacement, or multi-point edit).
 *
 * Cursor positions are intentionally NOT required: TextInput's onChange
 * fires before the cursor-offset callback, so the parent has no reliable
 * cursor-at-change-time signal. Diff-by-prefix is robust enough for
 * paste detection because a single paste produces exactly one insertion
 * segment.
 */
export declare function detectPasteInsert(prev: string, next: string): PasteInsert | null;
export declare function shouldCollapse(inserted: string): boolean;
export interface CollapseResult {
    readonly value: string;
    readonly cursor: number;
    readonly token: string;
}
/**
 * Replace the inserted segment with a placeholder token, registering
 * the original text in the store. Returns the new visible value and
 * the cursor position after the placeholder.
 */
export declare function collapsePaste(store: PasteStore, prev: string, insert: PasteInsert): CollapseResult;
/**
 * Remove paste store entries whose token is no longer present in
 * `visibleValue`. Call this inside handleInputChange after any
 * setInputValue to GC orphaned entries (placeholder deleted by
 * Backspace, Ctrl+U, or select-all-delete).
 *
 * O(store.size) — at most ~5 entries in practice.
 */
export declare function pruneStaleTokens(store: PasteStore, visibleValue: string): void;
/**
 * Substitute every placeholder token present in `visible` with its
 * registered raw content. Tokens not found in the store are left
 * unchanged (user typed something that merely looks like a token).
 */
export declare function expandPlaceholders(visible: string, store: PasteStore): string;
export interface BurstState {
    /** Value at the start of the current burst window. Empty when no burst is active. */
    anchorValue: string;
    /** Wall-clock ms when the anchor was captured. 0 → no active burst. */
    anchorAt: number;
}
export declare function createBurstState(): BurstState;
/**
 * Reset the burst state so the next onChange starts a fresh anchor.
 * Call after a successful collapse so subsequent typing isn't
 * re-collapsed against the stale anchor.
 */
export declare function resetBurst(state: BurstState): void;
export interface BurstCollapseResult {
    readonly value: string;
    readonly cursor: number;
    readonly token: string;
}
/**
 * Detect whether the current onChange completes a chunked-paste
 * burst and, if so, collapse the entire accumulated insert (anchor
 * → next) into a placeholder. Returns null when the burst threshold
 * isn't met yet — caller should fall through to the per-event
 * collapse path.
 *
 * Side effects on `state`:
 *   - Refreshes the anchor (anchorValue=prev, anchorAt=now) when
 *     the previous burst window expired or no anchor exists.
 *   - Resets the anchor on a successful collapse so the placeholder
 *     becomes the new baseline.
 *
 * Caller is responsible for ensuring `prev` is the parent's current
 * controlled `inputValue` and `next` is the just-arrived value from
 * TextInput.
 */
export declare function tryBurstCollapse(state: BurstState, store: PasteStore, prev: string, next: string, now?: number): BurstCollapseResult | null;
