import type { Message } from "@kenkaiiii/gg-ai";
import type { CompactionAnchorRemap } from "./compaction/compactor.js";
import type { AutopilotMarkerPayload, AppMarkerPayload, KenTurnPayload } from "./session-manager.js";
/**
 * Move a transcript anchor (`afterMessageCount`) from the pre-compaction
 * message list onto the compacted one.
 *
 * Compaction folds the leading `summarizedCount` non-system messages into a
 * `prefixCount`-message summary block and keeps the rest verbatim. Anchors
 * inside the collapsed region land right after the summary (their surrounding
 * conversation no longer exists); anchors in the retained tail shift by the
 * difference. Without this, re-persisted markers keep indices from a much
 * longer transcript — they then replay far too late, or past the end, which is
 * what bunches old Ken bubbles and error rows at the bottom on resume.
 */
export declare function remapAnchorForCompaction(anchor: number, remap: CompactionAnchorRemap): number;
/**
 * Drop the read-only file-order position before writing a marker back to disk.
 * It describes where a marker sat in the file it was READ from, so persisting
 * it into a rewritten file would bake in a position that no longer applies —
 * the next load recomputes it anyway.
 */
export declare function stripRecordedPosition<T extends {
    recordedAfterMessageCount?: number;
}>(payload: T): Omit<T, "recordedAfterMessageCount">;
export interface HistoryAutopilotMarker extends AutopilotMarkerPayload {
    /** Stable seed derived from persisted marker data for deterministic UI copy. */
    copySeed: string;
}
export declare function autopilotMarkerCopySeed(marker: AutopilotMarkerPayload): string;
/**
 * Normalize persisted autopilot markers for transcript replay.
 *
 * Stale anchors are pulled back to where the marker was actually written (see
 * {@link resolveAnchor}); anything still outside the restored transcript is
 * dropped rather than replayed at EOF, which is what bunched old Ken all-clear
 * bubbles at the bottom. Exact duplicate payloads from old rewrite/re-persist
 * paths are deduped.
 */
export declare function normalizeAutopilotMarkersForHistory(markers: readonly AutopilotMarkerPayload[], maxAfterMessageCount: number): HistoryAutopilotMarker[];
/**
 * Normalize persisted app transcript markers for replay: drop markers whose
 * anchor points beyond the restored message list (stale after compaction) and
 * dedupe exact payloads (old rewrite paths could re-append). Mirrors
 * {@link normalizeAutopilotMarkersForHistory}.
 */
export declare function normalizeAppMarkersForHistory(markers: readonly AppMarkerPayload[], maxAfterMessageCount: number): AppMarkerPayload[];
/**
 * Normalize persisted Ken turns for replay. Unlike autopilot/app markers, Ken
 * turns carry real conversation — an out-of-range anchor (stale after
 * compaction) is CLAMPED to the last message instead of dropped, so the
 * exchange still renders (at the end, in order) rather than vanishing. Exact
 * duplicate payloads (old rewrite/re-persist paths) are deduped.
 */
export declare function normalizeKenTurnsForHistory(turns: readonly KenTurnPayload[], maxAfterMessageCount: number): KenTurnPayload[];
export interface RestoredUserRow {
    /** The typed text as the live bubble showed it. */
    text: string;
    /** Attached image data URLs. */
    images: string[];
    /** True when the message carried a video the model could NOT watch natively
     *  (live showed an info row after the bubble). */
    videoWarning: boolean;
    /** True when autopilot injected this turn (the message carried the
     *  situational-awareness preamble). No human typed it, and the live
     *  transcript showed NO user bubble for it — only the Ken-tinted autopilot
     *  marker. Resume must skip the row, or the injected body renders twice:
     *  once styled as Ken's marker, once raw as a user message. */
    autopilotInjected: boolean;
}
/** Rebuild the live user bubble from a persisted user message's content. */
export declare function restoreUserRow(content: Message["content"]): RestoredUserRow;
/**
 * Reverse a prompt-template command's expansion by matching the restored body
 * against the known templates.
 *
 * Best-effort only: it works while a template is byte-identical to the one that
 * produced the message, and templates drift (edited `.gg/commands/*.md`,
 * reworded built-ins, app-vs-CLI phrasing). Prefer the invocation recorded at
 * send time — see {@link resolveRestoredCommand}. Returns null when the text
 * isn't a known command body (an ordinary user message).
 */
export declare function detectPromptCommand(text: string, candidates: ReadonlyArray<{
    name: string;
    prompt: string;
}>): string | null;
/**
 * The `/name [args]` chip a restored user row should show, or null for an
 * ordinary message.
 *
 * The invocation persisted with the prompt wins: it's exactly what the user
 * typed and survives any later template edit. Sessions recorded before that was
 * persisted fall back to matching the expanded body, which is why an edited
 * command used to resume as its raw multi-KB template.
 */
export declare function resolveRestoredCommand(persistedCommand: string | null | undefined, text: string, candidates: ReadonlyArray<{
    name: string;
    prompt: string;
}>): string | null;
/**
 * Split a persisted assistant message into per-bubble texts. Live streaming
 * ends the assistant bubble at every server_tool_call (see useAgentEvents'
 * server_tool_call case), so pre- and post-tool text render as separate rows.
 * Persisted content keeps that structure as separate text blocks — emit one
 * text per block instead of gluing them into a single row on resume.
 */
export declare function restoreAssistantTexts(content: Message["content"]): string[];
//# sourceMappingURL=session-history.d.ts.map