/** Current schema version. Bump this integer on every breaking schema change. */ export declare const PERSISTED_CONFIG_VERSION = 1; /** Shape of the provider block. SP4 will extend semantics; SP0 reserves the shape. */ export interface PersistedProvider { /** Provider id — never the API key value. */ name: string; /** Where the key lives: "keychain" | "file" | "env". Never the value. */ keyLocation: 'keychain' | 'file' | 'env'; } /** Top-level schema for ~/.wigolo/config.json. */ export interface PersistedConfig { version: number; settings: Record; /** Reserved for SP4. Optional so SP0 does not break if absent. */ provider?: PersistedProvider; } /** Patch type for writePersistedConfig. All fields optional (merge-patch). */ export type PersistedConfigPatch = Partial>; /** * Settings keys that map to secret values in the runtime config and must NEVER * be persisted to config.json. These are config.json-readable in config.ts, so * without this guard a caller could round-trip an API key onto disk in plain * text. Strip them on the write path. Keys go to the keychain/env only. */ export declare const SETTINGS_SECRETS_DENYLIST: Set; /** * Minimal keychain surface used by the proxy/solver/reader credential split. * Kept as an injectable indirection so the persistence logic is testable * without a real OS keychain (which is unavailable in CI / sandboxes). */ export interface CredentialKeychain { available(): boolean; set(user: string, value: string): void; get(user: string): string | null; del(user: string): void; } /** Test hook: override (or reset with null) the credential keychain adapter. */ export declare function _setCredentialKeychainForTests(kc: CredentialKeychain | null): void; /** * Read a credential from the active keychain adapter. Shared by the config * resolve path so it honours the same (test-injectable) adapter used on the * write path — otherwise a test's injected keychain wouldn't be consulted at * resolve time. */ export declare function readCredentialFromKeychain(user: string): string | null; /** Reset the in-process cache. Call in tests to isolate between cases. */ export declare function resetPersistedConfig(): void; /** * Read and cache the persisted config from `configPath`. * - Missing file → returns `{ version: CURRENT, settings: {} }`. * - Unparseable JSON → returns `{ version: CURRENT, settings: {} }`. * - Legacy (version-less) or version < CURRENT → migrates in memory AND writes * the upgraded envelope back to disk atomically (spec §Migration). The * write-back uses the private `atomicWrite` so it never re-enters this * reader (recursion guard). * - Future version → reads as-is, tolerates unknown fields, no rewrite. * Results are cached per-process; call `resetPersistedConfig()` in tests. */ export declare function readPersistedConfig(configPath: string): PersistedConfig; /** * Write a merge-patch to the persisted config atomically (temp file + rename, * 0o600 permissions). Merge-patch semantics: only keys present in * `patch.settings` are updated; keys absent from the patch are preserved. * * Secrets guard: * - any `key` field inside `patch.provider` is stripped — only `name` and * `keyLocation` are serialized. * - any denylisted secret settings key (SETTINGS_SECRETS_DENYLIST) is * stripped from `patch.settings` before merge — API keys never hit disk. */ export declare function writePersistedConfig(configPath: string, patch: PersistedConfigPatch): void; /** * Return the default config path: `WIGOLO_CONFIG_PATH` env var if set, * otherwise `~/.wigolo/config.json`. * Exported so getConfig() can look it up without duplicating the logic. */ export declare function defaultConfigPath(): string; //# sourceMappingURL=persisted-config.d.ts.map