import { LocalCheckupError } from '../errors.js';
import type { RequestBudget, Clock } from '../rate-budget.js';
import type { CfAuthMode } from './child-env.js';
import { type CfProcessResult } from './run-cf.js';
export declare const PRE_EXPIRY_MARGIN_MS = 60000;
export declare const RATE_LIMIT_PAUSE_MS = 30000;
export declare const TRANSIENT_RETRY_DELAYS_MS: readonly [1000, 3000];
export declare const MAX_CF_INVOCATIONS = 6000;
export type WhoamiSummary = {
    authenticated: boolean;
    /** ISO timestamp of the OAuth token expiry, when cf reports a parseable one. */
    expiresAt?: string;
    scopes?: string[];
};
/** Reduce cf's whoami JSON; email, account names and the credential file path are dropped. */
export declare function parseWhoami(stdout: string): WhoamiSummary | null;
export declare function isReadOnlyScope(scope: string): boolean;
export type DoctorAuth = {
    source: 'cf_profile' | 'cf_env_token' | 'cf_default_profile';
    profile: string | null;
    authenticated: boolean;
    expiresAt?: string;
    scopes: 'known' | 'unknown';
    missingRecommendedScopes?: string[];
    writeScopeCount?: number;
};
export declare function authSourceFor(mode: CfAuthMode): DoctorAuth['source'];
/**
 * Doctor's auth view. In env mode cf reports `scopes` and `expiresAt` from the
 * active profile's stored OAuth file even while the API token is in use, so
 * both are ignored: API token permissions cannot be introspected.
 */
export declare function doctorAuth(summary: WhoamiSummary, mode: CfAuthMode, profile: string): DoctorAuth;
export declare function authRequiredError(mode: CfAuthMode, message?: string): LocalCheckupError;
export type CfCallFailure = {
    kind: 'http';
    status: number;
} | {
    kind: 'timeout';
} | {
    kind: 'output_too_large';
} | {
    kind: 'command_unavailable';
} | {
    kind: 'network';
} | {
    kind: 'cf_error';
} | {
    kind: 'auth';
};
export type CfCallOutcome = {
    ok: true;
    stdout: string;
} | {
    ok: false;
    failure: CfCallFailure;
};
export type CfCallOptions = {
    stdoutCapBytes?: number;
    /** Sets CLOUDFLARE_ACCOUNT_ID for the call; absent only for account selection. */
    accountId?: string;
};
export type CfInvoke = (argv: readonly string[], options: CfCallOptions) => Promise<CfProcessResult>;
export type SchedulerOptions = {
    invoke: CfInvoke;
    /** One serial `cf auth whoami`; it is invoked only while dispatch is paused. */
    whoami: () => Promise<CfProcessResult>;
    budget: RequestBudget;
    clock: Clock;
    authMode: CfAuthMode;
    /** Live children are killed when the run aborts. */
    terminateAll?: () => Promise<void>;
    maxInvocations?: number;
};
/** Dispatch gate shared by every worker. */
export declare class CfScheduler {
    private readonly options;
    invocations: number;
    private dispatched;
    private inFlight;
    private drainWaiters;
    private gate;
    private refreshing;
    private expiresAtMs;
    private preExpiryEnabled;
    /** Dispatch sequence number when the first 429 paused the run. */
    private rateLimitPauseSeq;
    private abortError;
    constructor(options: SchedulerOptions);
    get aborted(): Error | null;
    /** The serial whoami (re-read once if it refreshed) before fan-out. Throws CF_AUTH_REQUIRED when cf is not signed in. */
    start(): Promise<WhoamiSummary>;
    /** Abort the run: no further dispatches, live children are killed. */
    abort(error: Error): void;
    throwIfAborted(): void;
    /** One cf API call with the §F5 retry policy. */
    call(argv: readonly string[], options?: CfCallOptions): Promise<CfCallOutcome>;
    /** Wait for a request slot and an open gate; returns the dispatch sequence number. */
    private dispatch;
    private release;
    private drain;
    private shouldRefreshBeforeExpiry;
    /** Close the dispatch gate until `work` (queued after any current gate) finishes. Failures abort the run. */
    private setGate;
    /** Pause dispatch, drain in-flight calls, run up to two serial whoami calls, resume. */
    private refresh;
    private expiryHasPassed;
    private setExpiry;
    private serialWhoami;
}
/** `null` for a clean exit; otherwise the classified failure. */
export declare function toFailure(result: CfProcessResult): CfCallFailure | null;
