import { type ExecFileSyncOptions } from 'node:child_process'; /** * The slice of `execFileSync` the Keychain adapter needs. A narrow type so a * test can inject a fake `security` runner without casts. Production passes * the real `execFileSync` (the constructor default). */ export type SecurityExec = (file: string, args: readonly string[], options: ExecFileSyncOptions) => Buffer | string; export interface ClaudeAiOauth { accessToken: string; refreshToken: string; expiresAt: number | string; scopes?: string[]; subscriptionType?: string; rateLimitTier?: string; } export interface KeychainData { claudeAiOauth?: ClaudeAiOauth; mcpOAuth?: Record; } /** A Keychain generic-password item identified by its service + account. */ export interface KeychainItemRef { service: string; account: string; } /** * Pull every `Claude Code-credentials*` generic-password item out of a * `security dump-keychain` listing. The dump prints one block per item * prefixed by `keychain: "..."`; each block carries a `"svce"` and an `"acct"` * attribute. We keep the items whose service starts with the OAuth service * name (the global item plus any per-config-dir `-` variants), de-duped. * Pure (no I/O) so the parsing is unit-testable without spawning `security`. */ export declare function parseClaudeOAuthItems(dump: string): KeychainItemRef[]; /** * The OS-username account field claude v2.x uses for OAuth lookups. * Mirrors the binary's `uV()` helper: prefer `process.env.USER`, fall * back to `os.userInfo().username`, and substitute "claude-code-user" * if neither yields a value that looks like a unix username. */ export declare function claudeKeychainAccount(): string; /** * Compute the Keychain service name claude v2.x uses for the given * config dir. With CLAUDE_CONFIG_DIR unset (the default ~/.claude * case) the service is just `Claude Code-credentials`. With any other * config dir, an 8-char SHA-256 prefix of the absolute path is * appended. Path normalisation matches claude's: NFC-normalised * absolute path. The empty-string sentinel means "treat as default". */ export declare function claudeKeychainServiceFor(configDir: string | null | undefined): string; export interface CredentialStore { readOAuth(): KeychainData | null; writeOAuth(data: KeychainData): void; readOAuthForConfigDir(configDir: string | null): KeychainData | null; writeOAuthForConfigDir(configDir: string | null, data: KeychainData, trustedBins?: string[]): void; deleteOAuthForConfigDir(configDir: string | null): boolean; available(): boolean; readApiKey(email: string): string | null; writeApiKey(email: string, key: string): boolean; deleteApiKey(email: string): boolean; listOAuthKeychainItems(): KeychainItemRef[]; setPartitionList(service: string, account: string, partitions: string): boolean; } /** Production adapter over the macOS `security` CLI. */ export declare class KeychainAdapter implements CredentialStore { private readonly exec; private oauthWarned; private apiKeyWarned; constructor(exec?: SecurityExec); private warnOAuthBypass; readOAuth(): KeychainData | null; writeOAuth(data: KeychainData): void; readOAuthForConfigDir(configDir: string | null): KeychainData | null; writeOAuthForConfigDir(configDir: string | null, data: KeychainData, trustedBins?: string[]): void; deleteOAuthForConfigDir(configDir: string | null): boolean; private writeOAuthAtService; private readOAuthAtService; private deleteOAuthAtService; private warnApiKeyBypass; available(): boolean; readApiKey(email: string): string | null; writeApiKey(email: string, key: string): boolean; deleteApiKey(email: string): boolean; listOAuthKeychainItems(): KeychainItemRef[]; setPartitionList(_service: string, _account: string, _partitions: string): boolean; } /** * Non-macOS adapter: credentials live in the plain JSON files there, so every * Keychain operation is a no-op. `available()` still emits the API-key bypass * warning under the disable flag to match the previous keychainAvailable() * ordering (flag checked before platform). */ export declare class NoopCredentialStore implements CredentialStore { private apiKeyWarned; readOAuth(): KeychainData | null; writeOAuth(): void; readOAuthForConfigDir(): KeychainData | null; writeOAuthForConfigDir(): void; deleteOAuthForConfigDir(): boolean; available(): boolean; readApiKey(): string | null; writeApiKey(): boolean; deleteApiKey(): boolean; listOAuthKeychainItems(): KeychainItemRef[]; setPartitionList(): boolean; } /** * Composition default: pick the adapter by platform at load. `process.platform` * is fixed for the process lifetime, so this selection is safe to cache (the * DISABLE flag, which tests flip at runtime, is read per-call inside the * adapters, not here). */ export declare const defaultCredentialStore: CredentialStore;