export type ScopeType = 'project' | 'branch' | 'detached-head'; export interface ScopeDescriptor { scopeType: ScopeType; branchRef?: string | null; headOid?: string | null; worktreePath?: string | null; } export declare function normalizeScopePath(rawPath: string): string; /** * The key form of a *file* path, for the read ledger's `(scope_key, path)` key. * * Deliberately not `normalizeScopePath`, which lowercases unconditionally. * That is right for a repository root — the odds of two roots differing only by * case are negligible — but wrong for arbitrary source files, where `Makefile` * and `makefile` genuinely coexist on a case-sensitive filesystem and folding * them would merge two files into one ledger row. Case is folded where the * filesystem is case-insensitive: win32, and **darwin**, whose APFS/HFS+ * volumes are case-insensitive by default — omitting darwin would leave macOS * with the duplicate-row bug this function exists to prevent. * * Known residual: this is `path.resolve`, not `realpath`. A symlink or a * junction still produces two keys for one file. Resolving links would mean a * syscall per read on the flush path and would fail for a path that no longer * exists, so it is deliberately not done here — the same trade `normalizeScopePath` * makes, and unlike store identity (Story 2.5) where realpath is mandatory * because the answer decides which database is opened. * * Normalizing at all is not cosmetic: `path` is both the primary key and the * argument handed to the filesystem. Measured before this existed, * `C:/x/a.ts`, `C:\x\a.ts` and `c:\x\a.ts` produced three rows for one file, * and a *relative* key was worse — the key was the literal string while the * bytes came from the flushing process's cwd, so one key described different * files. Story 3.3 compares by this key, so a path resolved differently at * compare time would report "not read" for a file that was read. */ export declare function normalizeFilePathKey(rawPath: string): string; /** * The stored form of a read-ledger path: relative to the scope root when the * file lives under it, absolute otherwise. * * The repository prefix is exactly what is redundant with `scope_key`, and * carrying it twice is what breached Story 3.1's AC #5 — 417.8 bytes/file for a * 135-character absolute path against a 400-byte ceiling. Stripping it also * shrinks the flat index the hot path greps on every read. * * The two forms stay distinguishable without a flag: a relative key never * starts with `/` and never carries a `:` prefix, which is asserted by * test rather than assumed. A file outside the scope root (a system header, a * file in a sibling checkout) keeps its absolute key and is still correct — * just larger, which is the right trade for the rare case. */ export declare function toScopeRelativeKey(rawPath: string, scopeRoot: string | null | undefined): string; /** True when a stored key is already absolute (POSIX root or a Windows drive). */ export declare function isAbsoluteFileKey(key: string): boolean; export declare function deriveProjectScopeKey(rootPath: string): string; export declare function deriveBranchScopeKey(gitRoot: string, worktreePath: string, branchRef: string): string; export declare function deriveDetachedScopeKey(gitRoot: string, worktreePath: string, headOid: string): string; export declare function formatScopeLabel(scope: ScopeDescriptor): string; //# sourceMappingURL=keys.d.ts.map