/** * Cursor-addressed output retention. * * Cursors address the session's canonical safe byte stream — redacted bytes, not * raw child bytes and not a rendered view — so plain and encoded views share one * stable source and `nextCursor` stays independent of rendered length. * * Appends are serialized in callback observation order and never ordered by wall * clock. Ingestion deliberately takes no session mutation lock so a chatty child * cannot block Close. */ import { type Unsubscribe } from "./runtime.js"; import { type ArtifactReference, type OutputPage, type OutputStream, type OutputView, type SessionOperation, type StableError } from "./types.js"; /** Durable sink for canonical redacted bytes. */ export interface OutputSink { /** Returns false when the sink is applying backpressure. */ append(bytes: Uint8Array): boolean; waitForDrain(): Promise; reference(): ArtifactReference; /** True once the configured capture limit demands session termination. */ readonly limitReached: boolean; readonly failed: boolean; } export interface OutputStoreOptions { readonly memoryWindowBytes: number; readonly pageBytes: number; readonly redactionOverlapBytes: number; readonly sink: OutputSink; /** Invoked when the sink asks for, then releases, transport backpressure. */ readonly onPause?: (() => void) | undefined; readonly onResume?: (() => void) | undefined; /** Raised when persistence fails or the capture limit demands termination. */ readonly onPersistenceStop?: ((reason: "output-limit" | "persist-failed") => void) | undefined; } export interface PageOptions { readonly cursor: number; readonly view: OutputView; readonly maxBytes?: number | undefined; readonly operation: SessionOperation; readonly sessionId: string; } export type PageOutcome = { readonly ok: true; readonly page: OutputPage; } | { readonly ok: false; readonly error: StableError; readonly page: OutputPage; }; export declare class OutputStore { private readonly options; private readonly events; private readonly redactors; private readonly notifier; private retainedBytes; private earliest; private latest; private omittedBytes; private paused; private closed; constructor(options: OutputStoreOptions); get earliestCursor(): number; get latestCursor(): number; /** Monotonic generation used as the quiet-detection baseline. */ get generation(): number; get artifact(): ArtifactReference; registerExactSecret(value: string): void; subscribe(listener: (generation: number) => void): Unsubscribe; private redactorFor; /** Ingest raw transport bytes. Redaction happens before cursor assignment. */ ingest(stream: OutputStream, raw: Uint8Array, observedAt: number): void; /** Flush retained redaction overlap; called once during finalization. */ finish(): void; private commit; private evict; private persist; /** Build a contiguous page starting at `cursor`. */ page(options: PageOptions): PageOutcome; private buildPage; dispose(): void; }