import { spawn } from "node:child_process"; export type ProviderSetupKind = "auth" | "preflight"; export interface ProviderSetupCommandAction { readonly id: string; readonly kind: ProviderSetupKind; readonly label: string; readonly modelRefs: readonly string[]; readonly command: readonly [string, ...string[]]; readonly cwd: string; readonly detail: string; } export interface ProviderSetupPiLoginAction extends ProviderSetupCommandAction { readonly id: `pi-login:${string}`; readonly piAuthPath: string; } export type CodexLoginMode = "browser" | "device"; export interface ProviderSetupCodexLoginAction extends ProviderSetupCommandAction { readonly id: "codex-login"; readonly authMode: CodexLoginMode; } export interface ProviderSetupHttpAction { readonly id: string; readonly kind: ProviderSetupKind; readonly label: string; readonly modelRefs: readonly string[]; readonly url: string; readonly cwd: string; readonly detail: string; } export interface ProviderSetupPiApiKeyAction { readonly id: string; readonly kind: "auth"; readonly label: string; readonly modelRefs: readonly string[]; readonly provider: string; readonly envVar: string; readonly persistence: "secure-store" | "environment"; readonly piAuthPath: string; readonly cwd: string; readonly detail: string; } export type ProviderSetupAction = ProviderSetupPiLoginAction | ProviderSetupCodexLoginAction | ProviderSetupCommandAction | ProviderSetupHttpAction | ProviderSetupPiApiKeyAction; export interface ProviderSetupPlan { readonly actions: readonly ProviderSetupAction[]; /** Auth actions omitted because a credential/sign-in was detected. */ readonly detectedModelRefs: readonly string[]; } export type ProviderCredentialState = "auth_required" | "credential_detected" | "verified"; export interface DetectProviderCredentialStatesOptions { readonly modelRefs: readonly string[]; readonly cwd: string; readonly piAuthPath?: string; /** Values parsed from the destination `.env`; ambient shell credentials are intentionally excluded. */ readonly persistedEnv?: Readonly>; readonly abortSignal?: AbortSignal; readonly timeoutMs?: number; readonly execFile?: (file: string, args: readonly string[], options: { readonly cwd: string; readonly timeout: number; readonly env?: Readonly>; readonly abortSignal?: AbortSignal; }) => Promise; } export type ProviderSetupStatus = "ok" | "failed" | "skipped"; export type ProviderSetupFailureKind = "child_exit_unconfirmed" | "cleanup_failed"; export interface ProviderSetupResult { readonly action: ProviderSetupAction; readonly status: ProviderSetupStatus; readonly detail: string; readonly failureKind?: ProviderSetupFailureKind; } export interface PlanProviderSetupOptions { readonly modelRefs: readonly string[]; readonly cwd: string; readonly piAuthPath?: string; /** Internal test seam for verifying bundled Pi CLI resolution in packed layouts. */ readonly piCliPath?: string; /** Credential/status observations keyed by `claude`, `codex`, `pi:`, or provider id. */ readonly credentialStates?: Readonly>; /** Explicit repair path: rerun authentication even when a credential was detected. */ readonly forceAuthentication?: boolean; /** Direct Codex never guesses headless mode; callers select this explicitly. */ readonly codexAuthMode?: CodexLoginMode; /** Select OAuth or API-key setup for Pi providers that support both. */ readonly piAuthMethods?: Readonly>; /** API keys can be used from env without being copied into Pi's secure store. */ readonly piApiKeyPersistence?: "secure-store" | "environment"; /** Per-provider wizard selections override the global API-key persistence mode. */ readonly piApiKeyPersistenceByProvider?: Readonly>; } export interface ExecuteProviderSetupOptions { readonly spawn?: typeof spawn; readonly fetch?: typeof fetch; readonly apiKeys?: Readonly>; /** Bounded only for non-interactive local-provider preflight probes. */ readonly preflightTimeoutMs?: number; /** Test seam; automatic credential persistence fails closed on Windows. */ readonly platform?: NodeJS.Platform; /** Test seam immediately before the target pathname is claimed. */ readonly beforePiAuthPromotion?: (targetPath: string, stagedPath: string) => void | Promise; /** Test seam after exclusive link installation and before immutable-byte verification. */ readonly afterPiAuthLink?: (targetPath: string, stagedPath: string) => void | Promise; /** Test seam immediately before stale-lock identity/liveness is rechecked. */ readonly beforeStalePiAuthLockRemoval?: (lockPath: string) => void | Promise; /** Test seam after a stale lock is unlinked but before directory sync. */ readonly afterStalePiAuthLockRemoval?: (lockPath: string) => void | Promise; /** Test seam immediately before a staged Pi OAuth directory is removed. */ readonly beforePiAuthCleanup?: (stagingDir: string) => void | Promise; /** Test seam after a new lock is durable but before setup begins. */ readonly afterPiAuthLockCreated?: (lockPath: string) => void | Promise; /** Test seam before confirming an already-absent owned lock is durable. */ readonly beforePiAuthMissingLockSync?: (lockPath: string) => void | Promise; /** Test seam immediately before an API-key transaction directory is removed. */ readonly beforePiAuthTempCleanup?: (tempDir: string) => void | Promise; /** Test seam immediately before an old credential backup is removed. */ readonly beforePiAuthBackupCleanup?: (backupPath: string) => void | Promise; /** Test seam after credentials are installed but before parent-directory sync. */ readonly beforePiAuthPostMutationSync?: (authPath: string) => void | Promise; /** Stop before launching the next independent action after user interruption. */ readonly abortSignal?: AbortSignal; } export declare function resolvePiCliPath(): string; export declare function piLoginCommand(provider: string, piCliPath?: string): readonly [string, ...string[]]; export declare function piAuthRecoveryCommand(provider: string, piAuthPath?: string): string; export declare function piAuthWorkingDirectory(piAuthPath: string | undefined, cwd?: string): string; export declare function piAuthPathForSetup(piAuthPath: string | undefined, cwd?: string): string; /** * Detect credential/sign-in postconditions without authenticating or claiming * provider readiness. Only an exact live route probe may promote these states * to `verified`. */ export declare function detectProviderCredentialStates(options: DetectProviderCredentialStatesOptions): Promise>>; /** Whether a selected route has a credential in the destination agent's durable environment. */ export declare function hasDurableProviderEnvironmentCredential(rawModelRef: string, persistedEnv: Readonly>): boolean; /** * Build the minimal operational environment needed to inspect durable CLI login * state. A positive allowlist prevents unrelated shell credentials from being * inherited by Codex or Claude while retaining their standard config roots. */ export declare function credentialNeutralProviderStatusEnvironment(source?: Readonly>, durableEnvironment?: Readonly>): Record; export interface BoundedProviderCommandResult { readonly stdout: string; } /** * Run a non-interactive provider probe with a hard process-lifecycle bound. * Node's execFile timeout sends only SIGTERM and can wait forever when a CLI * traps it, so discovery uses explicit TERM-to-KILL escalation and detaches a * process whose exit still cannot be confirmed. */ export declare function runBoundedProviderCommand(file: string, args: readonly string[], options: { readonly cwd?: string; readonly timeout: number; readonly env?: Readonly>; readonly abortSignal?: AbortSignal; readonly spawn?: typeof spawn; }): Promise; export declare function planProviderSetup(options: PlanProviderSetupOptions): ProviderSetupPlan; export declare function providerSetupActionCommandLine(action: ProviderSetupAction): string; export declare function isProviderSetupPiApiKeyAction(action: ProviderSetupAction): action is ProviderSetupPiApiKeyAction; export declare function isProviderSetupPiLoginAction(action: ProviderSetupAction): action is ProviderSetupPiLoginAction; export declare function executeProviderSetupPlan(plan: ProviderSetupPlan, options?: ExecuteProviderSetupOptions): Promise; export type StalePiAuthLockRepairResult = "removed" | "active" | "unverifiable"; /** * Remove only a secure, identity-stable lock whose recorded process is proven * gone with ESRCH. Active, EPERM, malformed and racing locks are untouched. * * @internal Exported as a narrow deterministic test seam. */ export declare function repairStalePiAuthLock(path: string, ownerUid: number, options?: { readonly kill?: (pid: number, signal: 0) => true; readonly beforeRemoval?: (lockPath: string) => void | Promise; readonly afterRemoval?: (lockPath: string) => void | Promise; }): Promise; //# sourceMappingURL=provider-setup.d.ts.map