export declare class ConfigStorage {
    private readonly encryptionKey;
    private readonly configDir;
    private readonly configFile;
    private readonly encryptionKeyFile;
    constructor(profile?: string);
    /**
     * Ensure profile directory exists
     */
    private ensureConfigDir;
    /**
     * Get or create encryption key for AES-256-GCM
     */
    private getOrCreateEncryptionKey;
    /**
     * Encrypt string using AES-256-GCM
     */
    private encrypt;
    /**
     * Decrypt string using AES-256-GCM
     */
    private decrypt;
    /**
     * Read config file (create if doesn't exist)
     */
    private readConfig;
    /**
     * Write config file
     */
    private writeConfig;
    /**
     * Save encrypted API token for provider
     */
    saveToken(provider: string, token: string): void;
    /**
     * Get decrypted API token for provider
     */
    getToken(provider: string): string | null;
    /**
     * Get token metadata (without decrypting)
     */
    getTokenMetadata(provider: string): {
        createdAt: string;
        updatedAt: string;
    } | null;
    /**
     * Remove API token for provider
     */
    removeToken(provider: string): void;
    /**
     * Check if token exists for provider
     */
    hasToken(provider: string): boolean;
    /**
     * Save encrypted credentials for provider
     */
    saveCredentials(provider: string, credentials: any): void;
    /**
     * Get decrypted credentials for provider
     */
    getCredentials(provider: string): any | null;
    hasCredentials(provider: string): boolean;
    removeCredentials(provider: string): void;
    /**
     * List all configured providers
     */
    listProviders(): string[];
    /**
     * Get config file path (for debugging)
     */
    getConfigPath(): string;
    /**
     * Save API URL
     */
    saveApiUrl(url: string): void;
    /**
     * Returns the ISO timestamp of the last apiUrl update, or null if never tracked.
     */
    getApiUrlUpdatedAt(): string | null;
    /**
     * Get API URL.
     * Resolution order:
     *   1. Saved value in this profile's config.json
     *   2. FLUI_API_URL env var
     *   3. Derived from clusters.json (master IP + nip token)
     * Returns null when no source provides a value — callers must decide whether
     * to error out (e.g. command needs API access) or just skip.
     */
    getApiUrl(): string | null;
    /**
     * Same as getApiUrl but throws a CLI-friendly error when no URL is configured.
     * Use this from commands that cannot work without an API endpoint.
     */
    getApiUrlOrThrow(): string;
    /**
     * Remove API URL from config
     */
    removeApiUrl(): void;
    /**
     * Save encrypted API key for CLI M2M access
     */
    setApiKey(key: string): void;
    /**
     * Get decrypted API key for CLI M2M access
     * Falls back to FLUI_API_KEY environment variable
     */
    getApiKey(): string | null;
    /**
     * Read a non-secret preference from the active profile. Returns null when unset.
     * Preferences live in a dedicated namespace so they never collide with tokens/apiKey/metadata.
     */
    getPreference<T = unknown>(key: string): T | null;
    /**
     * Persist a non-secret preference under the active profile.
     * Use null/undefined to clear via `removePreference` instead.
     */
    setPreference(key: string, value: unknown): void;
    removePreference(key: string): void;
    getAllPreferences(): Record<string, unknown>;
    getAcmeIssuances(): AcmeIssuance[];
    recordAcmeIssuance(entry: Omit<AcmeIssuance, 'issuedAt'>): void;
    countAcmeIssuances(domains: string, server: 'production' | 'staging'): number;
}
export interface AcmeIssuance {
    domains: string;
    server: 'production' | 'staging';
    issuedAt: string;
}
