/** The subset of ConversationHistoryRepo the recorder needs — injectable for tests. */ export interface HistoryWriter { appendUser(sessionId: string, opts: { text: string; ts?: string; agentMessage?: string; }): Promise; appendAssistant(sessionId: string, opts: { text: string; ts?: string; }): Promise; appendTool(sessionId: string, opts: { toolName: string; toolInput?: string; ts?: string; toolUseId?: string; fullInput?: unknown; }): Promise; appendToolResult(sessionId: string, opts: { toolUseId: string; content: string; isError: boolean; }): Promise; } /** One persisted transcript event, passed to the optional live-publish callback. `ts` is shared * with the history entry so the web UI's de-dup (transcript query vs live tail) keys match. */ export interface PersistedTranscriptEvent { role: 'user' | 'assistant' | 'tool'; ts: string; text?: string; toolName?: string; toolInput?: string; } export interface StepTranscriptRecorder { recordUser(text: string): void; recordAssistant(text: string): void; recordTool(name: string, input: any, toolUseId?: string): void; /** DEBUG-only result sidecar; no-op when the process-wide mode was disabled at creation. */ recordToolResult(toolUseId: string, content: string, isError: boolean): void; /** Resolves once every append issued so far has settled. Never rejects — a failed * append is logged and skipped, later events still persist. */ settle(): Promise; } /** Create a live per-event recorder for a single thread step, keyed by the step's track * sessionId. Each record*() call publishes synchronously (emission order) via `onEvent` and * chains the history append behind the previous one (per-recorder order = emission order). */ export declare function createStepTranscriptRecorder(history: HistoryWriter, sessionId: string, onEvent?: (ev: PersistedTranscriptEvent) => void, onDebugUpdated?: () => void): StepTranscriptRecorder;