/** * Account storage load/save pipeline. * * Split out of `lib/storage.ts` in RC-2. This module owns: * - the `.gitignore` side-effect when writing into a project repo, * - the legacy project + global storage migrations triggered on ENOENT, * - the project-global fallback seed flow, * - the atomic write (temp file + rename + EEMPTY guard), * - and the `withAccountStorageTransaction` read-modify-write primitive * that every mutating caller above the storage layer uses. * * The error-handling contract is subtle and load-bearing: forward-compat * (`UNSUPPORTED_SCHEMA_VERSION`) and unknown-V2 failures MUST reach the * caller. Swallowing either would overwrite future-schema credentials or * silently discard a user's V2 file, which is exactly the class of bug the * audit flagged. */ import { type AccountStorageV3 } from "./migrations.js"; export declare function consumeLastWrittenAccountsDigest(path?: string): string | undefined; export declare function __resetCollisionWarningThrottleForTests(): void; /** * Loads OAuth accounts from disk storage. * Automatically migrates v1 storage to v3 format if needed. * @returns AccountStorageV3 if file exists and is valid, null otherwise * @throws StorageError (code `UNSUPPORTED_SCHEMA_VERSION`) when the on-disk * `version` field is greater than the newest format this plugin understands. * Surfacing the error stops a downgraded plugin from overwriting the user's * future-schema credentials with a stale or empty payload. */ export declare function loadAccounts(): Promise; /** * Executes a read-modify-write transaction under the storage lock and exposes * an unlocked persist callback so nested save operations do not deadlock. */ export declare function withAccountStorageTransaction(handler: (current: AccountStorageV3 | null, persist: (storage: AccountStorageV3) => Promise) => Promise): Promise; /** * Persists account storage to disk using atomic write (temp file + rename). * Creates the .opencode directory if it doesn't exist. * Verifies file was written correctly and provides detailed error messages. * @param storage - Account storage data to save * @throws StorageError with platform-aware hints on failure */ export declare function saveAccounts(storage: AccountStorageV3): Promise; /** * Deletes the account storage file from disk. * Silently ignores if file doesn't exist. * * Ordering (F1 post-merge MEDIUM finding): unlink the on-disk JSON FIRST, * then delete the keychain entry. If we cleared the keychain first and the * unlink failed for a non-ENOENT reason (EACCES, EBUSY, filesystem drift), * a subsequent load with opt-in still on would take the "no keychain entry, * fall back to JSON" branch (see `loadAccountsInternal`) and resurrect the * credentials from the still-present JSON file. Callers typically run * `clearAccounts` to recover from a compromised token, so a silent * resurrection is a meaningful failure mode. * * Fail-safe invariant: if the JSON unlink fails (non-ENOENT), we skip the * keychain delete and log at `error`. Both copies remain in sync so the * caller can retry safely. The operation is still best-effort (never * throws) to preserve the existing contract above the storage layer. * * @throws StorageError (code `TEST_HOME_ESCAPE`) - the single exception to * best-effort, and inert outside vitest. The guard refuses the deletion, so * absorbing it would return success for a clear that never happened. */ export declare function clearAccounts(): Promise; //# sourceMappingURL=load-save.d.ts.map