import type { ProjectId, SessionId, TurnId } from '../../types/ids/index.js'; import type { TurnExecutionStatus } from '../../types/session/turn.js'; import type { ChildSessionSummary, EvidenceHit, EvidenceSearchOptions, IndexableRecord, IndexedBatch, IndexedPendingDecision, IndexedSession, IndexedSessionStatus, IndexedTurn, IndexedTurnStatus, ListSessionsOptions, SessionIndex, SessionLogInput, SessionLogLocation, SessionStaleness } from './index.js'; import { type ExternalRefClaim, type ExternalRefKind, type ExternalRefTarget } from './refs.js'; /** * Deriving the index from the logs: reading a log's records, finding every * log under a home, and the one projection from records to rows that both * backends share. A full rebuild and an incremental update run the same * projection over the same records, which is why they agree. */ export declare class SessionIndexError extends Error { readonly name = "SessionIndexError"; } /** The indexed head of a log: where reading continues. */ export interface IndexedLogPosition { /** Bytes already read: the end of the head record. */ readonly offset: number; readonly seq: number; readonly sha256: string; } /** * Read a session log's records in order, each with its pointer, from the * start or from an indexed head. * * A tolerant read: it stops, without throwing, at the first line that is torn, * does not parse, or breaks the chain (a seq out of order, or a `prev` that * does not name the line before it). What it yields is always an intact * prefix. Repairing the log is the log's own business, not the index's. */ export declare function readIndexableRecords(path: string, from?: IndexedLogPosition): AsyncGenerator; /** * Every session log under `home`: `projects//.jsonl` and, * recursively, `/subagents/.jsonl`. * * A directory under `projects/` whose name is a UUID is the old layout * (`legacy`) and is never read; a new slug can never look like one. */ export declare function discoverSessionLogs(home: string): Promise; export interface SessionRow { id: SessionId; slug: string; projectId: ProjectId; parentId: SessionId | null; rootId: SessionId; depth: number; title: string | null; archived: boolean; status: IndexedSessionStatus; createdAt: string; updatedAt: string; logPath: string; logBytes: number; headSeq: number; headSha256: string; } export interface TurnRow { id: TurnId; sessionId: SessionId; status: IndexedTurnStatus; stopReason: string | null; startedAt: string; endedAt: string | null; tokens: number; costUsd: number; userPreview: string | null; originKind: string | null; } export interface DecisionRow { decisionId: string; sessionId: SessionId; turnId: TurnId; checkpointId: string; deadlineAt: string | null; } export interface ChildRow { sessionId: SessionId; childId: SessionId; turnId: TurnId; toolCallId: string; kind: string; description: string; path: string; batchId: string | null; batchName: string | null; batchPhase: string | null; status: TurnExecutionStatus; stopReason: string | null; tokens: number; costUsd: number; spawnedAt: string; endedAt: string | null; } export interface BatchRow { batchId: string; sessionId: SessionId; name: string; phase: string | null; agentsDone: number; agentsTotal: number; tokensTotal: number; } export interface EvidenceRow { sessionId: SessionId; turnId: TurnId | null; seq: number; part: number; source: string; toolName: string | null; isError: boolean | null; text: string; } /** * The writes and reads the projection needs, inside one transaction. The * SQLite backend runs them as statements, the scan backend on maps. */ export interface IndexSink { getSession(id: SessionId): SessionRow | undefined; putSession(row: SessionRow): void; putProject(slug: string, projectId: ProjectId, cwd: string): void; getTurn(sessionId: SessionId, turnId: TurnId): TurnRow | undefined; putTurn(row: TurnRow): void; putDecision(row: DecisionRow): void; deleteDecision(sessionId: SessionId, decisionId: string): void; deleteTurnDecisions(sessionId: SessionId, turnId: TurnId): void; /** Records a claim unless the session already claims that name. */ claimRef(claim: ExternalRefClaim): void; releaseRef(protocol: string, kind: ExternalRefKind, externalId: string, sessionId: SessionId): void; getChild(sessionId: SessionId, childId: SessionId): ChildRow | undefined; putChild(row: ChildRow): void; getBatch(sessionId: SessionId, batchId: string): BatchRow | undefined; putBatch(row: BatchRow): void; putEvidence(row: EvidenceRow): void; /** Removes every row derived from one session's log. */ clearSession(sessionId: SessionId): void; } export declare function sessionView(row: SessionRow): IndexedSession; export declare function turnView(row: TurnRow): IndexedTurn; export declare function decisionView(row: DecisionRow): IndexedPendingDecision; export declare function childView(row: ChildRow, session: SessionRow | undefined): ChildSessionSummary; export declare function batchView(row: BatchRow): IndexedBatch; export declare function evidenceView(row: EvidenceRow, match: { hit: number; start: number; end: number; }): EvidenceHit; /** Ascending by the given keys, compared as strings or numbers. */ export declare function compareBy(...keys: ((row: T) => string | number)[]): (a: T, b: T) => number; /** * Everything both backends share: indexing records, comparing a log with the * index, refreshing and syncing. A backend supplies the transaction, the sink * and the queries. */ export declare abstract class SessionIndexBase implements SessionIndex { abstract readonly backend: 'sqlite' | 'scan'; /** Run `work` in one write transaction (`BEGIN IMMEDIATE` in SQLite). */ protected abstract transaction(work: (sink: IndexSink) => T): T; protected abstract readSession(sessionId: SessionId): SessionRow | undefined; protected abstract indexedSessionIds(): SessionId[]; abstract listSessions(options?: ListSessionsOptions): Promise; abstract listTurns(sessionId: SessionId): Promise; abstract listChildren(sessionId: SessionId): Promise; abstract listPendingDecisions(options?: { sessionId?: SessionId; }): Promise; abstract resolveExternal(protocol: string, kind: ExternalRefKind, externalId: string): Promise; abstract listExternalRefs(sessionId: SessionId): Promise; abstract batches(options?: { sessionId?: SessionId; }): Promise; abstract searchEvidence(options: EvidenceSearchOptions): Promise; abstract close(): void; getSession(sessionId: SessionId): Promise; indexSession(input: SessionLogInput): Promise; staleness(location: SessionLogLocation): Promise; refresh(location: SessionLogLocation): Promise; sync(home: string): Promise; } /** Whether a path exists; any error other than ENOENT is thrown. */ export declare function pathExists(path: string): Promise; //# sourceMappingURL=rebuild.d.ts.map