/**
 * Transcript reader — pure module that parses an agent JSONL transcript and
 * returns a paginated, optionally regex-filtered envelope.
 *
 * No HTTP, no sandbox concerns: file content is provided by the caller via
 * the `readContent` argument. Path resolution + sandbox-aware reads happen
 * in the server route handler that wires this module to `sessionFileRead`.
 *
 * See `src/server/server.ts` (`GET /api/sessions/:id/transcript`) for the
 * HTTP surface and design doc for the contract.
 */
export interface ReadTranscriptParams {
    offset?: number;
    limit?: number;
    pattern?: string;
    caseSensitive?: boolean;
    context?: number;
    verbose?: boolean;
}
export interface CompactToolUse {
    name: string;
    inputPreview: string;
}
export interface CompactToolResult {
    name?: string;
    preview: string;
}
export interface CompactMessage {
    index: number;
    role: string;
    ts: string | null;
    text: string;
    toolUses?: CompactToolUse[];
    toolResults?: CompactToolResult[];
}
export interface VerboseMessage {
    index: number;
    role: string;
    ts: string | null;
    content: unknown;
    /** Full pi-coding-agent message object (`entry.message`). Carries
     *  toolCallId/toolName/details/isError for toolResult rows and any
     *  other fields the renderer-side `<message-list>` component expects.
     *  Only populated for the orphan-history (`before-compaction`) path
     *  where the client renders these rows via the same Lit components
     *  that render the live transcript. `readTranscript` callers (read_session
     *  tool) still get just `content`. */
    message?: Record<string, unknown>;
}
export type TranscriptMessage = CompactMessage | VerboseMessage;
export interface ReadTranscriptEnvelope {
    total: number;
    matchCount?: number;
    returned: number;
    offsetStart: number;
    offsetEnd: number;
    messages: TranscriptMessage[];
}
export type ReadTranscriptError = "transcript_unavailable" | "invalid_regex" | "invalid_params" | "compaction_not_found";
export declare class TranscriptReaderError extends Error {
    code: ReadTranscriptError;
    constructor(code: ReadTranscriptError, message?: string);
}
interface RawMessage {
    index: number;
    role: string;
    ts: string | null;
    content: unknown;
    /** Pi-coding-agent session-entry id (`SessionEntryBase.id`). May be
     *  null for legacy files whose entries lacked an explicit `id`. */
    entryId: string | null;
    /** Pi-coding-agent's entry `type` field (e.g. "message", "compaction").
     *  Used by `readOrphanedBeforeCompaction` to spot the legacy in-jsonl
     *  compaction marker when the sidecar doesn't carry firstKeptEntryId. */
    entryType: string;
    /** Full `entry.message` object — captured for the verbose orphan path
     *  which needs toolCallId/toolName/etc. for `<message-list>` rendering.
     *  Other paths read `content` directly. */
    fullMessage: Record<string, unknown>;
}
export declare function parseJsonl(content: string): RawMessage[];
/**
 * Resolve an offset against `length`, allowing negative indexing (Python-style).
 *
 * - `offset >= 0` is returned as-is (may be > length, signalling out-of-range).
 * - `offset < 0` is treated as `length + offset`, clamped to 0 at the lower bound.
 *   (e.g. offset=-1 in a list of 5 → 4; offset=-20 in a list of 5 → 0.)
 */
export declare function resolveOffset(offset: number, length: number): number;
export interface ReadTranscriptOptions {
    /** Async loader returning the raw JSONL contents. */
    readContent: () => Promise<string | null>;
}
export interface ReadOrphanedParams {
    /** Required. Sidecar entry id whose firstKeptEntryId defines the split. */
    compactionId: string;
    /** Optional pagination cursor — entry index within the orphaned slice
     *  of the last item returned by the previous page. Pass back
     *  `envelope.nextCursor`. */
    cursor?: number;
    /** Default 50, range 1..200. */
    limit?: number;
    /** When true, return full `entry.message` objects (with toolCallId,
     *  toolName, details, etc.) so the client can render rows via the
     *  same `<message-list>` Lit component as the live transcript.
     *  Default false — returns the compact preview shape. */
    verbose?: boolean;
}
export interface ReadOrphanedEnvelope {
    /** Total orphaned entries for this compaction (independent of pagination). */
    total: number;
    returned: number;
    /** Pass back as `cursor` for the next page. Null when no more pages. */
    nextCursor: number | null;
    messages: CompactMessage[] | VerboseMessage[];
}
export interface ReadOrphanedOptions {
    readContent: () => Promise<string | null>;
    /** First-kept entry id from the sidecar. When null, fall back to
     *  scanning the jsonl for an in-file `type:"compaction"` marker. */
    firstKeptEntryId: string | null;
}
/**
 * Return the orphaned (pre-compaction) entries for the named compaction.
 *
 * Branch-split rules (see docs/design/persist-compaction-history.md §4.1):
 *
 *  - If `firstKeptEntryId` is non-null: scan parsed entries for the entry
 *    whose `id` matches. Everything strictly before that index is
 *    orphaned.
 *  - If `firstKeptEntryId` is null (legacy sidecar entries written before
 *    the field was plumbed through, or hard failures): fall back to
 *    finding the FIRST `type:"compaction"` entry in the jsonl. Pi-coding-
 *    agent appends that compaction entry to mark the boundary; everything
 *    BEFORE it on the active branch is what was rolled into the summary.
 *  - If neither resolves: return total=0 (no fabricated history).
 */
export declare function readOrphanedBeforeCompaction(params: ReadOrphanedParams, opts: ReadOrphanedOptions): Promise<ReadOrphanedEnvelope>;
export declare function readTranscript(params: ReadTranscriptParams, opts: ReadTranscriptOptions): Promise<ReadTranscriptEnvelope>;
export {};
//# sourceMappingURL=transcript-reader.d.ts.map