/** * Claude Code's own login state: is a config dir (or the default login) * signed in through Claude Code itself? * * Crewly does not collect, store or intermediate Claude.ai credentials * (Anthropic's Claude Code legal page). Claude Code keeps its own login in * `/.credentials.json` or, on macOS, in the keychain, so a file * check alone is wrong on a Mac: the default login of a Mac has no * `.credentials.json` at all. Two questions are therefore asked of the CLI * itself, always with Crewly's own env (no `CLAUDE_CODE_OAUTH_TOKEN`, no API * key) so a token can never make a login look native: * * - {@link readClaudeAuthStatus}: `claude auth status --json`, the CLI's own * record (`loggedIn`). Cheap, no network turn, but it keeps saying * `loggedIn: true` for an expired login. Feeds the sync "signed in" flag. * - {@link probeClaudeNativeLogin}: one tiny real turn. This is the * verification the token migration waits for before it deletes anything. * * Neither prints or reads a credential: only the exit code and the output * of the CLI are looked at. * * @module services/harness/claude-native-login */ import type { LoginState, RunCommand } from './harness.types.js'; /** Injectable dependencies. */ export interface ClaudeNativeLoginDeps { run?: RunCommand; /** Base env (default process.env) */ env?: NodeJS.ProcessEnv; homeDir?: string; /** PATH lookup of the `claude` binary */ resolveCommand?: (command: string) => string | null; /** Scratch directory the probe turn runs in */ scratchDir?: string; timeoutMs?: number; now?: () => number; } /** * Env to ask Claude Code about its OWN login: the caller's env without any * token or key, pointed at a config dir (or the default login's). * * @param baseEnv - Starting env * @param configDir - A named account's config dir; null = the default login * @returns Env for the child process */ export declare function nativeLoginEnv(baseEnv: NodeJS.ProcessEnv, configDir: string | null): NodeJS.ProcessEnv; /** * Ask the CLI whether it is signed in (`claude auth status --json`). * * @param configDir - A named account's config dir; null = the default login * @param deps - Dependencies * @returns `loggedIn` as the CLI reports it, or null when it could not be asked */ export declare function readClaudeAuthStatus(configDir: string | null, deps?: ClaudeNativeLoginDeps): Promise; /** * Refresh the cached `claude auth status` answer of accounts. * * @param accounts - Account configs: `account` is the name (null = default login), `configDir` its dir (null = default) * @param deps - Dependencies * @param maxAgeMs - Skip an account answered this recently * @returns Resolves when every account was asked (an unanswered one keeps its old answer) */ export declare function refreshClaudeNativeLogins(accounts: ReadonlyArray<{ account: string | null; configDir: string | null; }>, deps?: ClaudeNativeLoginDeps, maxAgeMs?: number): Promise; /** * The last `claude auth status` answer for an account. * * @param account - Account name; null = the default login * @returns True/false, or undefined when never asked */ export declare function cachedClaudeNativeLogin(account: string | null): boolean | undefined; /** * Set the cached answer (after a verified login or sign-out). * * @param account - Account name; null = the default login * @param loggedIn - New answer * @param now - Clock */ export declare function setCachedClaudeNativeLogin(account: string | null, loggedIn: boolean, now?: number): void; /** Forget every cached answer (tests). */ export declare function resetClaudeNativeLoginCache(): void; /** * Classify the output of a probe turn. * * @param result - Exit code and output * @returns `logged_out` on a login-expiry message; `logged_in` when the turn * worked or the account answered with a usage limit (a limit proves the * login works); else `unknown` */ export declare function classifyNativeProbe(result: { code: number | null; stdout: string; stderr: string; }): LoginState; /** * Verify a login with one real Claude turn on Claude Code's own login, with * no token or key in the env. * * @param configDir - A named account's config dir; null = the default login * @param deps - Dependencies * @returns `logged_in`, `logged_out` or `unknown`; never rejects */ export declare function probeClaudeNativeLogin(configDir: string | null, deps?: ClaudeNativeLoginDeps): Promise; //# sourceMappingURL=claude-native-login.d.ts.map