/**
 * CredentialProvider — cross-platform abstraction for Claude Code OAuth credential access.
 *
 * Implementations:
 * - KeychainCredentialProvider: macOS Keychain (os-encrypted, production-proven)
 * - ClaudeConfigCredentialProvider: File-based fallback (all platforms, 0600 permissions)
 *
 * Part of the Instar Quota Migration spec (Phase 1).
 */
import { type CredentialWriteFunnel, type FunnelResult } from '../core/CredentialWriteFunnel.js';
export interface ClaudeCredentials {
    accessToken: string;
    expiresAt: number;
    refreshToken?: string;
    email?: string;
}
export interface AccountInfo {
    email: string;
    name: string | null;
    hasToken: boolean;
    tokenExpired: boolean;
}
export type SecurityLevel = 'os-encrypted' | 'file-permission-only';
export interface CredentialProvider {
    /** Read the current active credentials */
    readCredentials(): Promise<ClaudeCredentials | null>;
    /** Write/update credentials */
    writeCredentials(creds: ClaudeCredentials): Promise<void>;
    /** Delete credentials for a specific account */
    deleteCredentials?(email: string): Promise<void>;
    /** List all known accounts */
    listAccounts?(): Promise<AccountInfo[]>;
    /** Platform identifier */
    platform: string;
    /** Security level of this provider's storage */
    securityLevel: SecurityLevel;
}
/**
 * Redact a token for safe logging. Shows first 4 chars only.
 * Returns "[TOKEN:abc1****]" format.
 */
export declare function redactToken(token: string): string;
/**
 * Redact an email for safe logging.
 * Returns "[EMAIL:j***@***.com]" format.
 */
export declare function redactEmail(email: string): string;
export declare class KeychainCredentialProvider implements CredentialProvider {
    readonly platform = "darwin";
    readonly securityLevel: SecurityLevel;
    private keychainAccount;
    constructor();
    readCredentials(): Promise<ClaudeCredentials | null>;
    writeCredentials(creds: ClaudeCredentials): Promise<void>;
    deleteCredentials(_email: string): Promise<void>;
}
/**
 * Reads credentials from Claude Code's local config files.
 * Falls back to file-based storage with enforced 0600 permissions.
 *
 * Config path: ~/.claude/ (standard Claude Code config directory)
 */
export declare class ClaudeConfigCredentialProvider implements CredentialProvider {
    readonly platform: NodeJS.Platform;
    readonly securityLevel: SecurityLevel;
    private configDir;
    constructor(configDir?: string);
    readCredentials(): Promise<ClaudeCredentials | null>;
    writeCredentials(creds: ClaudeCredentials): Promise<void>;
    deleteCredentials(_email: string): Promise<void>;
    private parseCredentialFile;
}
/**
 * Create the best available credential provider for the current platform.
 *
 * Priority:
 * 1. macOS: Keychain (os-encrypted)
 * 2. All platforms: File-based (~/.claude/) with 0600 permissions
 *
 * Note: keytar support (Linux libsecret, Windows Credential Manager)
 * is planned but not yet implemented. When added, it will slot between
 * Keychain and file-based in the priority chain.
 */
export declare function createDefaultProvider(): CredentialProvider;
/**
 * The default config-home slot a `CredentialProvider` writes to — the keychain's
 * `Claude Code-credentials` service is the `~/.claude` home. Callers that target a
 * non-default home pass that home as `slot` instead.
 */
export declare const DEFAULT_CREDENTIAL_SLOT: string;
/**
 * Thrown by `writeCredentialsSerialized` when the target slot is owned by the credential
 * re-pointing ledger (census #9). A competing writer (AccountSwitcher / `/switch-account` /
 * `autoMigrate`) writing that slot would graft a Frankenstein blob over the ledger's tenant and
 * silently resurrect a stranded account (spec §2.7). This is a NAMED, NON-DESTRUCTIVE refusal —
 * nothing was written — pointing the caller at the sanctioned replacement.
 */
export declare class CredentialWriteRepointingOwnedError extends Error {
    constructor(reason: string);
}
/**
 * Manager-level refusal gate for the competing-writer census row (#9). Injected at the funnel
 * chokepoint so a refusal lives at the MANAGER, not only on the two known routes — any future
 * caller of `writeCredentialsSerialized` inherits it (the "every item a unique source" dodge the
 * flood-ceiling lesson warns against, applied to credential writes).
 *
 *   `shouldRefuse(slot)` → true ⇒ the write is refused (the slot is repointing-owned). It receives
 *   the canonicalized slot key so the gate matches the ledger's spelling regardless of caller
 *   input. Returns false (or the gate being absent) ⇒ the write proceeds exactly as today.
 */
export interface CredentialWriteRefusalGate {
    shouldRefuse(canonicalSlot: string): boolean;
}
/** Install (or clear, with `undefined`) the process-shared competing-writer refusal gate. */
export declare function setCredentialWriteRefusalGate(gate: CredentialWriteRefusalGate | undefined): void;
/**
 * Serialize a `provider.writeCredentials` through the per-slot credential funnel (Step 4b).
 *
 * This is the ONLY sanctioned path for an external caller (e.g. AccountSwitcher) to write the
 * active account credential: it shares the per-slot lock with the QuotaPoller refresh write and
 * the swap executor (Step 5), so a switch can never interleave with a refresh on the same slot.
 * The companion lint (`lint-no-unfunneled-credential-write.js`) forbids calling
 * `provider.writeCredentials(...)` directly outside this funnel-owning module.
 *
 * Census #9 (manager-level competing-writer refusal): when the process-shared refusal gate (or an
 * explicitly-passed `refusalGate`) reports the target slot is repointing-owned, the write is
 * REFUSED here at the manager — BEFORE the funnel lock — with a `CredentialWriteRepointingOwnedError`.
 * This is the funnel: a non-route caller can't dodge it. Refusal is non-destructive (nothing was
 * written) and names the sanctioned replacement (`POST /credentials/set-default`).
 *
 * Returns the funnel result. `ran:false` means the lock was busy and the write was SKIPPED (the
 * caller decides whether to surface "busy, try again"); it is never a credential corruption.
 */
export declare function writeCredentialsSerialized(provider: Pick<CredentialProvider, 'writeCredentials'>, slot: string, creds: ClaudeCredentials, funnel?: CredentialWriteFunnel, refusalGate?: CredentialWriteRefusalGate | undefined): Promise<FunnelResult<void>>;
//# sourceMappingURL=CredentialProvider.d.ts.map