/** * Config file repair — crash-safe restore from backup (Amendment 1, T11997). * * Checks a JSON config file for parse failures. When the live file is * corrupt, the routine: * * 1. Quarantines the corrupt file beside the target (`.corrupt-`). * 2. Scans available backup snapshots for the NEWEST valid (parseable) candidate. * 3. Restores the best candidate atomically (tmp-rename) only when JSON parse * fails AND no active write window is detected. * 4. Appends a structured audit record to `.cleo/audit/config-repair.jsonl` * that the `cleo health` surface can consume. * * Key invariants (Amendment 1): * - Never silently restore a stale backup — always quarantine first, then * restore the newest valid candidate. * - Restore only when `JSON.parse` fails on the live file (not merely on * schema drift). * - A `.tmp` survivor from a previously interrupted write (write-file-atomic * pattern) takes priority over numbered backups when it is both newer and * valid JSON. * * @task T11997 * @epic T11992 */ /** Outcome of a {@link repairConfigFile} call. */ export type ConfigRepairOutcome = 'healthy' | 'restored-from-backup' | 'restored-from-tmp' | 'quarantined-no-candidate' | 'skipped-active-write'; /** Structured result of {@link repairConfigFile}. */ export interface ConfigRepairResult { /** What happened. */ readonly outcome: ConfigRepairOutcome; /** Absolute path to the config file that was checked/restored. */ readonly configPath: string; /** Absolute path to the backup used for restore (when applicable). */ readonly restoredFrom?: string; /** Absolute path to the quarantine file (when a corrupt file was renamed). */ readonly quarantinedTo?: string; /** Human-readable detail. */ readonly detail: string; } /** * Check and optionally repair a JSON config file. * * Safe to call on config paths that do not yet exist — returns `'healthy'` * immediately when the file is absent (a missing file is not a corrupt file). * * @param configPath - Absolute path to the config JSON file to check. * @param backupDir - Directory containing numbered `.1`, `.2`, … backups. * Pass `null` to skip backup-based restore. * @param cwd - Project root for audit-log path resolution. * @returns Structured {@link ConfigRepairResult}. * * @example * ```ts * import { repairConfigFile } from '@cleocode/core/config/config-repair'; * * const result = await repairConfigFile( * '/home/user/.local/share/cleo/config.json', * '/home/user/.local/share/cleo/backups', * '/home/user/projects/myapp', * ); * if (result.outcome === 'restored-from-backup') { * console.log(`Restored from ${result.restoredFrom}`); * } * ``` * * @task T11997 */ export declare function repairConfigFile(configPath: string, backupDir: string | null, cwd: string): Promise; //# sourceMappingURL=config-repair.d.ts.map