import type { Logger } from './types.js'; import type { UserTitleStore } from './user-title-store.js'; export interface DehydratedSession { /** Claude session id (basename of the JSONL file, no extension). */ claudeSessionId: string; /** Absolute path of the JSONL on disk. */ jsonlPath: string; /** mtime of the JSONL, ISO-8601. Newest write wins as the row's startedAt. */ startedAt: string; /** Byte size of the JSONL, for ordering tiebreaker and operator surfaces. */ sizeBytes: number; /** Resolved display name: user override (UserTitleStore) when set, * else tail.aiTitle verbatim, else null. Task 253 added the * operator-stamped layer over Task 146's aiTitle-only resolution. */ displayName: string | null; /** Provenance of `displayName`. 'user' when a user override resolved * it; 'ai' when the JSONL's aiTitle resolved it; null when neither * source had a value (pre-first-turn session with no rename yet). */ titleSource: 'user' | 'ai' | null; /** last ai-title line parsed from the JSONL tail, or null. The * Claude desktop client writes `{"type":"ai-title","aiTitle":"…"}` once it * has enough turns to summarise a session; we read the most recent such * line and surface it as the second-tier display name. */ aiTitle: string | null; /** ISO timestamp of the last user|assistant turn in the parsed tail, or null. */ lastMessageAt: string | null; /** Task 1801 — ISO timestamp of the FIRST user|assistant turn in the whole * transcript, or null when it holds none yet. This is the conversation's * start, and the only honest source for an age figure: the sidecar's * `startedAt` re-stamps to the current PTY on resume, and the JSONL mtime is * the LAST write. Read from the head, never the tail. */ firstMessageAt: string | null; /** Count of user|assistant turns found in the parsed tail. Lower bound when capped. */ turnCount: number; /** True when the tail was clipped to tailMaxBytes — turnCount is a lower bound. */ capped: boolean; /** Model id from the most recent assistant turn in the parsed tail * (`message.model` field claude writes on every assistant line). Null * when no assistant turn is in the window — alive session pre-first-turn * or tail clipped above any assistant line. */ model: string | null; /** Context tokens consumed by the most recent assistant turn carrying a * `message.usage` object: input + cache-creation + cache-read + output. * This is the live "context window used" signal (cache-read carries the * cumulative prompt). Null when no usage-bearing assistant turn is in the * window. */ usedTokens: number | null; } /** Test seam — the memo is module state, so a suite that rewrites a fixture at * a path it already read must clear it. */ export declare function __clearFirstTurnCache(): void; /** * Find a single dehydrated row by claudeSessionId. Returns null if the JSONL * is missing. Drives /:sessionId/meta, the /events SSE rowToPayload, and the * /spawn + /rc-spawn return-payload builders via http-server's `toPayload`. */ export declare function readJsonlSession(spawnCwd: string, claudeSessionId: string, tailMaxBytes: number, logger?: Logger, userTitleStore?: UserTitleStore): DehydratedSession | null; /** Task 1565 — the path-taking enrichment core. `readJsonlSession` derives the * path from `spawnCwd`'s slug; this reads from an explicit path instead, so a * caller that resolved the JSONL by the all-slug scan * (`findExistingJsonlForSessionId`) enriches the same session under any slug. * This is the single site the /meta footer enrichment uses so it can never * disagree with the transcript scan about where a session's JSONL is. */ export declare function readJsonlSessionAtPath(jsonlPath: string, claudeSessionId: string, tailMaxBytes: number, logger?: Logger, userTitleStore?: UserTitleStore): DehydratedSession | null; //# sourceMappingURL=jsonl-enumerator.d.ts.map