import type { BatchItem, BatchProgress } from './batch-progress-types.js'; /** * The record's path for one batch. * * `batchId` is caller-supplied and becomes a path segment, so it is checked * before it is joined: `..` and an absolute path would otherwise let a caller * write outside the session's batch directory, and a nested `a/b` would write * outside the directory the batch owns. */ export declare function batchProgressPath(projectRoot: string, sessionId: string, batchId: string): string; /** * The canonical form of a file set: POSIX separators, no leading `./`, no * duplicates, sorted. * * Two callers that measured the same file differently — one agent on Windows * reporting a backslash-spelled path, another reporting the same path with * forward slashes — must end up with the same string, or the disjointness * check that decides whether two items may run in parallel waves reads them as * disjoint and two agents edit one file. Sorting makes the stored set * comparable, not just its members. */ export declare function normalizeFileSet(files: readonly string[]): readonly string[]; /** * Read one batch's record. `null` when the batch has no record yet — the * "no progress" answer, distinct from a record that exists but is unreadable. * * A malformed record throws rather than reading as `null`: the two answers * mean opposite things to the caller, and a batch that silently loses its * history restarts the work it had already done. */ export declare function readBatchProgress(projectRoot: string, sessionId: string, batchId: string): BatchProgress | null; /** * Write one batch's record, atomically. * * The timestamp is the writer's, not the caller's: the record's value is * "when this batch last moved", and a caller that supplied its own clock * would make that unanswerable. */ export declare function writeBatchProgress(projectRoot: string, sessionId: string, progress: BatchProgress): void; /** * Append one item to a batch's record and write it back. * * The append is read → merge → write, and the merge is by item id: an item * that is already in the record is replaced by the new version, so an item * that moves from `pending` to `diagnosed` to `fixed` is one row that changes * status rather than three rows. That is what lets the recovery read "which * items are still pending" by filtering one field. * * A batch with no record yet gets one, so the first append does not need a * separate create step — the record is written as the batch runs, not before. */ export declare function appendBatchItem(projectRoot: string, sessionId: string, batchId: string, item: BatchItem): void;