import type { HookPayload } from "./hook-registry.js"; import type { GatewayEmit } from "../shared/gateway-events.js"; /** * External-turn sync: persist turns that happened OUTSIDE a gateway run() — * i.e. typed directly into the CLI/xterm PTY view — into the gateway messages * DB, so chat mode shows them. * * Anchor mechanism: `transportMeta.transcriptSyncedThrough` holds the ISO * timestamp of the newest transcript entry already persisted by this sync. * Each sync reads the Claude transcript tail (entries strictly newer than the * anchor), inserts the user+assistant messages in order, and advances the * anchor — so a repeated Stop (or a sync racing the on-load safety net) can * never double-insert. NOTE: this is deliberately NOT `claudeSyncSince` — that * key drives the opposite direction (DB messages → injected into Claude's * prompt after a rate-limit engine-override revert) and is consumed/deleted by * the next Claude run, so it can't serve as a durable transcript anchor. * * When the anchor is absent (first external turn for a session), the last DB * message's insert time is used instead: every transcript entry of an already- * persisted turn predates the DB insert of that turn's final assistant message, * so gateway-run history is never re-inserted. */ export declare const TRANSCRIPT_SYNC_META_KEY = "transcriptSyncedThrough"; /** One user/assistant text entry from the transcript tail. */ export interface TranscriptTailEntry { role: "user" | "assistant"; content: string; /** Entry's transcript timestamp (epoch ms). */ timestampMs: number; /** Same timestamp, original ISO form (becomes the new anchor). */ timestampIso: string; } export declare function isPersistableClaudeTranscriptEntry(obj: any): boolean; export declare function transcriptEntryText(obj: any): { role: "user" | "assistant"; content: string; } | null; /** * Parse the user/assistant text entries of a Claude transcript newer than * `sinceMs`. Sidechain (sub-agent) and meta entries are skipped; array content * is reduced to its text blocks (tool_use/tool_result blocks drop out, exactly * like the full-transcript backfill in api.ts). Returns `null` when the file * can't be read — callers distinguish "unreadable" from "nothing new". */ export declare function readTranscriptTail(transcriptPath: string, sinceMs: number): TranscriptTailEntry[] | null; /** Mark a Claude transcript as already owned by the gateway completion path. */ export declare function markTranscriptSyncedThrough(sessionId: string, engineSessionId?: string, transcriptPathOverride?: string): void; /** * Persist any un-synced transcript tail for a session into the messages DB. * Primary trigger: an unclaimed Stop hook (PTY-native turn — no run() in * flight). Also callable without a payload as the on-load safety net. * * Returns the number of messages inserted. Emits `session:external-turn` * `{ sessionId }` when anything was persisted (the frontend refetches messages * on it). */ export declare function syncExternalTurn(sessionId: string, emit: GatewayEmit, payload?: HookPayload): number; /** * On-load safety net: when serving session detail, fire-and-forget a tail sync * so a PTY-native turn whose Stop was missed entirely still lands. Cheap in the * common case — the transcript's mtime is compared against the anchor BEFORE * any parsing, so an untouched transcript costs one stat(). The GET itself is * never delayed; the frontend refetches on `session:external-turn`. */ export declare function scheduleOnLoadTailSync(sessionId: string, emit: GatewayEmit): void; //# sourceMappingURL=external-turns.d.ts.map