/**
 * Sidecar persistence for compaction events.
 *
 * The pi-coding-agent CLI owns the canonical `.jsonl` transcript. Its
 * `compaction_end` event arrives once on the live WebSocket stream but is
 * NOT replayed by `getMessages()` after compaction — the agent only
 * returns the active branch (summary entry + tail from `firstKeptEntryId`).
 * Bobbit's rich compaction-summary card therefore disappears on reload
 * because there's nothing to anchor it to in the snapshot.
 *
 * Storage: `<stateDir>/compaction-sidecar/<sessionId>.jsonl` — host-side
 * (mirrors `skill-sidecar.ts`), so valid even for sandboxed sessions
 * whose agent `.jsonl` lives inside the container. One JSON line per
 * compaction event.
 *
 * See docs/design/persist-compaction-history.md §3.
 */
/** Sidecar record schema v1. Consumers must skip lines whose schemaVersion
 *  they don't recognise (forward-compat). */
export interface CompactionSidecarEntry {
    schemaVersion: 1;
    /** Stable id derived from startedAt + a 6-char random suffix. Used as the
     *  primary key for the REST endpoint's `?compactionId=` query param. */
    id: string;
    /** "manual" | "auto" | "overflow". Matches CompactionTrigger. */
    trigger: "manual" | "auto" | "overflow";
    tokensBefore: number | null;
    /** Best-effort post-compaction usage. Usually null at end-of-event time;
     *  may be amended by a follow-up assistant message_end's `usage`. */
    tokensAfter: number | null;
    durationMs: number;
    /** ISO-8601 timestamps. */
    startedAt: string;
    endedAt: string;
    success: boolean;
    /** Failure detail; only set on success=false. */
    error?: string;
    /** Pi-coding-agent's first-kept entry id from CompactionResult. Used by
     *  the Part B reader to slice the .jsonl into orphaned vs active.
     *  May be null if the upstream payload didn't carry it (legacy or error). */
    firstKeptEntryId: string | null;
}
/** Generate a stable compaction id `c_<startedAtMs>_<rand6>`. */
export declare function makeCompactionId(startedAtMs: number): string;
/** Initialize the sidecar dir from the gateway state directory.
 *  Called by server bootstrap, next to `initSkillSidecarDir`. */
export declare function initCompactionSidecarDir(stateDir: string): void;
/** Append one entry. Best-effort; failure logs and returns false. */
export declare function appendCompactionSidecarEntry(sessionId: string, entry: CompactionSidecarEntry): boolean;
/** Read all entries for a session. Empty array on any failure (back-compat). */
export declare function readCompactionSidecarEntries(sessionId: string): CompactionSidecarEntry[];
/** Find a single sidecar entry by id. Used by the REST endpoint. */
export declare function findCompactionSidecarEntry(sessionId: string, id: string): CompactionSidecarEntry | undefined;
/** Delete the sidecar for a session (archive purge / terminate). */
export declare function purgeCompactionSidecar(sessionId: string): void;
/**
 * Build the synthetic assistant message + paired toolResult that mirrors
 * what the live `compaction_end` path produces, except the id is the
 * sidecar's stable `entry.id` (NOT `compact_active` — that's reserved for
 * the live in-flight card so single-DOM-identity continuity isn't broken
 * during the same session).
 *
 * The renderer reads `payload.compactionId` (new field) to know it's
 * looking at a persisted sidecar row that can be expanded with
 * pre-compaction history (Part C).
 */
export declare function syntheticCompactionRowsFromSidecar(entry: CompactionSidecarEntry): [any, any];
/**
 * Splice sidecar-driven synthetic compaction rows into a message list so
 * the rich card survives reload. Runs BEFORE other post-processing so the
 * synthetic rows participate in the same truncate/skill-merge pipeline as
 * server-origin rows.
 *
 * Idempotency: if a `__compaction_summary` toolCall with the same
 * `toolCallId` is already present (live emission during the same WS
 * session), the sidecar pair is skipped for that slot — the live row
 * wins. The reducer's `hasCompactionToolCall` handles client-side dedup
 * (matching by `compact_active` for live rows vs sidecar id for
 * persisted rows).
 *
 * Position: each sidecar pair is spliced immediately BEFORE the agent's
 * own active-branch boundary — which appears in the agent's getMessages
 * output as the first entry whose role matches the keep boundary. We
 * don't have access to entry uuids in the message list, so the
 * conservative behaviour is: append at the end if no boundary is
 * resolvable. The card still renders correctly; the rendered
 * pre-compaction history (Part C) is fetched separately by id.
 */
export declare function mergeCompactionSidecarIntoMessages(sessionId: string, messages: any[]): any[];
//# sourceMappingURL=compaction-sidecar.d.ts.map