/** * Restore the live project `cleo.db` from a named snapshot or a backup id, * safely (T13240). The project store holds the tasks AND the brain tables * (`tasks.db` and `brain.db` are only labels on older backups), so this one * restore covers both. * * The order is what makes it safe: * * 1. Resolve the source: a snapshot file under this project's * `.cleo/backups/` (another location only with `allowExternal`), or the * store file of a backup id (`.cleo/backups/sqlite/.meta.json`). A * snapshot with a non-empty `-wal` beside it is refused: its newest * commits are not in the file. * 2. Copy it to a private file next to the live store and verify the COPY * (what is placed is exactly what was checked): a SQLite header, * `PRAGMA integrity_check` = ok, and a project store's shape. * 3. Refuse while anything else uses the live store: this process's handles * are closed first, then any live writer lease of another process, or any * other connection holding the file open, refuses (re-checked under the * first-open lock that a store's first open also takes). * 4. Under that lock, keep the replaced store: copy it (with its `-wal`), * fold the WAL into the copy, and list it as a `pre-restore-*` backup, so * `--id` undoes the restore. * 5. Remove the live `-wal`/`-shm`/`-journal` (they belong to the replaced * file), rename the verified copy over `cleo.db`, and check the result. * 6. For a backup id that captured the docs byte surfaces (T13708): before * step 3's lock, refuse while a docs database is open elsewhere and keep * the live docs bytes under the same `pre-restore-*` backup; after the * swap, place every verified docs byte. Anything that fails verification * makes the result `partial`, with `warnings` (T13709). If a live docs * database cannot be kept, the restore aborts before any swap. A backup * holding only docs bytes (the docs-only undo of a restore onto a project * with no live store) restores them alone. * * Residual: a process that opens the store between the check under the lock * and the rename (milliseconds; a first open waits on the same lock). And * a docs write (`cleo docs add`) between the docs keep in step 6 (before the * first-open lock) and the docs placement (after it is released) lands in * neither the kept nor the restored manifest: stop every cleo process first. * * @task T13240 * @module store/restore-store */ import type { StoreRestoreResult } from '@cleocode/contracts'; /** Options of {@link restoreStoreSnapshot}. Exactly one of `snapshot` and `backupId`. */ export interface StoreRestoreOptions { /** The project whose `.cleo/cleo.db` is restored (project scope). */ readonly projectRoot: string; /** * `project` (default): the project's `.cleo/cleo.db` (tasks and brain). * `global`: `/cleo.db`, the global store (global brain, nexus, * agent registry), with its backups under `/backups/` (T13245). */ readonly scope?: 'project' | 'global'; /** A snapshot file (a `VACUUM INTO` copy, e.g. `cleo-identity-refill-*.db` or `tasks-*.db`). */ readonly snapshot?: string; /** A backup id from `cleo backup list`. */ readonly backupId?: string; /** Verify and report, write nothing. */ readonly dryRun?: boolean; /** Accept a snapshot outside this project's `.cleo/backups/` (another store's file). */ readonly allowExternal?: boolean; /** From a git worktree: allow overwriting the owning project's live store. */ readonly confirmOwnerStore?: boolean; /** The invocation directory (the worktree guard; core never falls back to `process.cwd()`). */ readonly cwd: string; /** * When the live store cannot even be read (a damaged file), whether another * process uses it cannot be checked: proceed only with this, the operator's * statement that every cleo process is stopped (`--force`). It never * overrides a live writer that WAS detected. */ readonly assumeStoppedIfUnverifiable?: boolean; /** Clock (tests). */ readonly now?: Date; /** * Called inside the swap window, after the live sidecars are removed and * before the rename, with the marker held (tests: a racing open). * * @internal */ readonly beforeSwap?: () => void; } /** * Restore the live project `cleo.db` from a named snapshot or a backup id * (T13240). See the module comment for the order of the steps. * * @param opts - The source, the project and the guards. * @returns What was verified, kept and placed (or would be, on a dry run). * @throws {CleoError} `E_RESTORE_SOURCE`, `E_RESTORE_EXTERNAL`, * `E_RESTORE_SNAPSHOT_INCOMPLETE`, `E_RESTORE_SNAPSHOT_CORRUPT`, * `E_RESTORE_SNAPSHOT_SHAPE`, `E_RESTORE_STORE_BUSY`, or the worktree guard's refusal. * @task T13240 */ export declare function restoreStoreSnapshot(opts: StoreRestoreOptions): Promise; //# sourceMappingURL=restore-store.d.ts.map