declare const TAKE_BLOB_BUFFER_OWNERSHIP: unique symbol; /** Limits for a single best-effort resident-cache garbage-collection pass. */ export interface ResidentCacheGcSweepOptions { readonly maxDirectories?: number; readonly maxDurationMs?: number; } export interface BlobPutResult { hash: string; path: string; get ref(): string; } export interface CheckedBlobPutResult extends BlobPutResult { bytes: number; } export declare class BlobCorruptError extends Error { readonly hash: string; readonly path: string; constructor(hash: string, path: string); } /** * A resident-cache path or blob failed the owner-only verification contract. * SessionManager catches this error to demote the entire resident store to * memory before retrying the triggering write. */ export declare class ResidentCacheTrustError extends Error { readonly reason: string; readonly path: string; /** * errno of the OS failure this rejection wrapped (`ENOENT`, `EMFILE`, `EACCES`, …), * or `undefined` when the rejection was a pure policy decision with no cause. * `reason` alone names the *step* that failed; only this names *why*, so a * demotion is diagnosable from a log line instead of requiring a debugger. */ readonly causeCode: string | undefined; /** Bounded one-line rendering of the wrapped cause for logs that must not serialize an arbitrary thrown value. */ readonly causeSummary: string | undefined; constructor(reason: string, path: string, options?: ErrorOptions); } export declare function disposeVerifiedResidentCacheInstanceDir(instanceDir: string, parentDescriptor?: number): void; /** * Best-effort cleanup of abandoned resident-cache instances. The root is * re-verified before scanning, work is bounded, and all failures fail closed. */ export declare function sweepResidentCacheRoot(root: string, options?: ResidentCacheGcSweepOptions): Promise; export declare function openVerifiedResidentCacheInstanceDir(root: string): string; /** Open the deterministic per-session managed-sidecar instance in its separate cache root. */ export declare function openVerifiedSidecarCacheInstanceDir(root: string, sessionHash: string): string; /** * Content-addressed blob store for externalizing large binary data (images) from session JSONL files. * * Files are stored at `/` with no extension. The SHA-256 hash is computed * over the raw binary data (not base64). Content-addressing makes writes idempotent and * provides automatic deduplication across sessions. */ export declare class BlobStore { readonly dir: string; constructor(dir: string); /** * Write binary data to the blob store. * @returns SHA-256 hex hash of the data */ put(data: Buffer): Promise; /** * Synchronous variant of {@link put}. Use on persistence hot paths where the caller * cannot afford the microtask hops of the async version (e.g. OOM-safe session writes). * Returns once the bytes are in the kernel page cache. */ putSync(data: Buffer, _ownership?: typeof TAKE_BLOB_BUFFER_OWNERSHIP): BlobPutResult; /** * Store a buffer that the caller will not mutate after this call returns. * Resident-cache implementations may retain that private buffer without an * additional defensive copy. */ putOwnedSync(data: Buffer): BlobPutResult; /** * Durably install binary data as an immutable content-addressed blob. * * Callers that persist references to this blob must mutate canonical session entries only * after this method returns successfully. A corrupt pre-existing target is reported with * {@link BlobCorruptError}; it is never silently overwritten or trusted. */ putImmutableSync(data: Buffer): CheckedBlobPutResult; /** Read blob by hash, returns Buffer or null if not found. */ get(hash: string): Promise; /** Synchronously read blob by hash, returns Buffer or null if not found. */ getSync(hash: string): Buffer | null; /** Read blob by hash and verify its content hash; returns null if not found. */ getChecked(hash: string): Promise; /** Synchronously read blob by hash and verify its content hash; returns null if not found. */ getCheckedSync(hash: string): Buffer | null; /** Check if a blob exists. */ has(hash: string): Promise; } interface EphemeralBlobStoreOptions { readonly adoptVerifiedDir?: boolean; readonly disposalParentDescriptor?: number; } /** Resident-cache directories still tracked by this process. Test seam. */ export declare function trackedResidentCacheDirsForTest(): string[]; export declare class EphemeralBlobStore extends BlobStore { #private; constructor(dir: string, options?: EphemeralBlobStoreOptions); /** * Adopt a directory returned by {@link openVerifiedResidentCacheInstanceDir} * without the ordinary constructor's destructive remove-and-recreate path. */ static adoptVerifiedDir(dir: string): EphemeralBlobStore; put(data: Buffer): Promise; putSync(data: Buffer, ownership?: typeof TAKE_BLOB_BUFFER_OWNERSHIP): BlobPutResult; putImmutableSync(data: Buffer): CheckedBlobPutResult; get(hash: string): Promise; getSync(hash: string): Buffer | null; /** Return a trusted in-memory copy without reopening an invalidated cache path. */ getBufferedSync(hash: string): Buffer | null; getCheckedSync(hash: string): Buffer | null; clear(): void; dispose(): void; } export interface MemoryBlobStoreOptions { /** A canonical store owns every reference in its session's resident entries. */ readonly ownership?: "cache" | "canonical"; } export declare class MemoryBlobStore extends BlobStore { #private; constructor(options?: MemoryBlobStoreOptions); put(data: Buffer): Promise; putSync(data: Buffer): BlobPutResult; putImmutableSync(data: Buffer): CheckedBlobPutResult; get(hash: string): Promise; getSync(hash: string): Buffer | null; getChecked(hash: string): Promise; getCheckedSync(hash: string): Buffer | null; has(hash: string): Promise; } export declare class ResidentBlobMissingError extends Error { readonly hash: string; readonly kind: "text" | "imageUrl" | "imageData"; readonly sessionId?: string | undefined; readonly sessionFile?: string | undefined; constructor(hash: string, kind: "text" | "imageUrl" | "imageData", sessionId?: string | undefined, sessionFile?: string | undefined); } /** Check if a data string is a blob reference. */ export declare function isBlobRef(data: string): boolean; /** Extract the SHA-256 hash from a blob reference string. */ export declare function parseBlobRef(data: string): string | null; /** Identify provider transport image data URLs so persistence can externalize and restore them losslessly. */ export declare function isImageDataUrl(data: string): boolean; /** * Externalize a provider image data URL to the blob store, returning a blob reference. * The full data URL string is preserved so transport-native history can be reconstructed on resume. */ export declare function externalizeImageDataUrl(blobStore: BlobStore, dataUrl: string): Promise; /** Synchronous variant of {@link externalizeImageDataUrl}. */ export declare function externalizeImageDataUrlSync(blobStore: BlobStore, dataUrl: string): string; /** * Externalize an image's base64 data to the blob store, returning a blob reference. * If the data is already a blob reference, returns it unchanged. */ export declare function externalizeImageData(blobStore: BlobStore, base64Data: string): Promise; /** Synchronous variant of {@link externalizeImageData}. */ export declare function externalizeImageDataSync(blobStore: BlobStore, base64Data: string): string; /** * Resolve an externalized provider image data URL back to its original string. * If the data is not a blob reference, returns it unchanged. * * LEGACY PERSISTED-IMAGE COMPATIBILITY BOUNDARY: when the persisted blob is missing * (e.g. resuming an old session whose image blob was pruned), this warns and returns * the reference as-is rather than throwing, so legacy resume degrades gracefully. * New resident byte-sensitive TEXT uses the fail-closed path instead * (`resolveTextBlobSync` -> `ResidentBlobMissingError`). Do NOT route new byte-sensitive * resident data through this warn-and-return path. */ export declare function resolveImageDataUrl(blobStore: BlobStore, data: string): Promise; /** * Resolve a blob reference back to base64 data. * If the data is not a blob reference, returns it unchanged. * * LEGACY PERSISTED-IMAGE COMPATIBILITY BOUNDARY: when the blob is missing this warns * and returns the reference as-is (downstream sees an invalid base64 ref but does not * crash), preserving legacy-session resume. Byte-sensitive resident TEXT is fail-closed * via `resolveTextBlobSync`; do NOT route new byte-sensitive resident data here. */ export declare function resolveImageData(blobStore: BlobStore, data: string): Promise; /** Synchronously resolve an externalized provider image data URL back to its original string. */ export declare function resolveImageDataUrlSync(blobStore: BlobStore, data: string): string; /** Synchronously resolve a blob reference back to base64 data. */ export declare function resolveImageDataSync(blobStore: BlobStore, data: string): string; /** * Synchronously resolve a blob reference back to utf8 text. * * FAIL-CLOSED byte-sensitive path: a missing resident blob throws * `ResidentBlobMissingError` rather than degrading, so a missing resident text blob can * never silently leak a `blob:sha256:` ref into provider payloads, UI, or exports. * (Contrast the legacy persisted-image warn-and-return resolvers above.) */ export declare function resolveTextBlobSync(blobStore: BlobStore, data: string, context?: { kind?: "text"; sessionId?: string; sessionFile?: string; }): string; /** * FAIL-CLOSED resident variant of {@link resolveImageDataUrlSync}: a missing resident * image-data-url blob throws `ResidentBlobMissingError` ("imageUrl") instead of warn-returning, * so resident byte-sensitive provider image data can never leak a `blob:sha256:` ref into * materialized entries, context, or provider payloads. The warn-and-return `resolveImageDataUrl*` * resolvers remain ONLY for legacy persisted-image resume. */ export declare function resolveResidentImageDataUrlSync(blobStore: BlobStore, data: string, context?: { sessionId?: string; sessionFile?: string; }): string; /** * FAIL-CLOSED resident variant of {@link resolveImageDataSync}: a missing resident image blob * throws `ResidentBlobMissingError` ("imageData") instead of warn-returning a placeholder. */ export declare function resolveResidentImageDataSync(blobStore: BlobStore, data: string, context?: { sessionId?: string; sessionFile?: string; }): string; /** One canonical blob file (`/`) observed on disk. */ export interface CanonicalBlobEntry { readonly hash: string; readonly path: string; readonly bytes: number; readonly mtimeMs: number; readonly mtimeNs: bigint; readonly dev: bigint; readonly ino: bigint; readonly nlink: bigint; } /** Longest possible `blob:sha256:` reference, used to bound chunked scans. */ export declare const BLOB_REFERENCE_MAX_LENGTH: number; /** Collect every `blob:sha256:` reference that appears in `text`. */ export declare function collectBlobReferences(text: string, into: Set): void; /** * List canonical blob files. Anything that is not a plain, owner-visible regular * file named after its own hash (temp files, symlinks, subdirectories) is * skipped: a sweep must never reason about entries it cannot classify. */ export declare function listCanonicalBlobs(dir: string): Promise; /** * Remove one canonical blob, fail-closed on identity drift. The entry captured * at scan time must still describe the file at unlink time (same inode, size and * mtime, still a single-link regular file), otherwise the blob is left in place. * * `beforeUnlink` runs after this function has verified the blob and immediately * before it calls unlink. Callers use it to bind external liveness evidence to * the verified blob identity, so a live reference that appears while the blob is * being revalidated prevents the destructive syscall. * * `failed` distinguishes an actual IO failure (which a caller should surface as * a failed reclaim) from a revalidation refusal (which is an ordinary KEEP). */ export declare function removeCanonicalBlob(entry: CanonicalBlobEntry, options?: { beforeUnlink?: () => Promise; }): Promise<{ removed: true; } | { removed: false; reason: string; failed?: true; }>; export {};