import { type OAuthAccountSummary, type ResetCreditAccountStatus, type ResetCreditTarget, type UsageLimit, type UsageReport, type UsageResetCreditDetail } from "@oh-my-pi/pi-ai"; import { type CodexResetTrigger } from "./codex-auto-reset.js"; /** Why an account or grant is unsafe or unhelpful for automatic redemption. */ export type ClaudeResetSkipReason = "disabled" | "wrong-provider" | "no-identity" | "no-report" | "stale-report" | "credits-unknown" | "ineligible" | "no-credits" | "no-selected-credit" | "credit-unusable" | "credit-expired" | "provider-cooldown" | "reserve" | "outside-account-pool" | "no-blocked-window" | "unsupported-window" | "incomplete-coverage" | "no-reset-time" | "reset-too-soon" | "reset-implausible" | "no-expiring-credit" | "unsupported-program" | "window-mostly-free" | "already-attempted" | "deferred" | "cooldown"; /** Live grant eligibility and usage evidence for one deterministic planning pass. */ export interface ClaudeResetPlanInput { nowMs: number; trigger: CodexResetTrigger; provider: string; modelId: string; settings: { enabled: boolean; minBlockedMinutes: number; keepCredits: number; salvageHorizonMs: number; }; /** Fresh usage for every stored Claude account. */ reports: UsageReport[] | null; /** * Cedar/Juniper eligibility for every stored account: a live listing before * any spend, or the usage reports' inventory to find salvage candidates. */ statuses: readonly ResetCreditAccountStatus[]; /** Blocked recovery: whether a stored credential may serve the blocked session; absent allows every account. */ permitsCredential?: (credentialId: number) => boolean; attemptedKeys: ReadonlySet; deferredUntilByKey: ReadonlyMap; lastAttemptAtByAccount: ReadonlyMap; /** Provider retry hint for the active account, captured at the 429. */ activeBlockUnblockAtMs?: number; } /** One server-selected Claude grant to redeem for an exact stored credential. */ export interface ClaudeResetAction { reason: "blocked-account" | "expiring-credit"; target: ResetCreditTarget; accountKey: string; attemptKey: string; label: string; availableCount: number; remainingMs?: number; blockedWindows?: string[]; expiresInMs?: number; salvageWindow?: string; salvageUsedFraction?: number; active: boolean; program: string; title?: string; requiresLimit: boolean; } /** Account-scoped diagnostic explaining why a planning rule did not spend. */ export interface ClaudeResetSkip { accountKey: string; rule: "blocked-account" | "expiring-credit" | "account"; reason: ClaudeResetSkipReason; } /** At most one blocked-account restore followed by independent expiry salvages. */ export interface ClaudeResetPlan { actions: ClaudeResetAction[]; skipped: ClaudeResetSkip[]; } /** Whether a usage report belongs to a stored account: the organization gates, then account id, else email. */ export declare function reportMatchesStatus(report: UsageReport, status: Pick): boolean; /** * Each stored account's Cedar/Juniper status from the inventory on its usage * report, which the report fetch discovered, so a background sweep finds * salvage candidates without listing. The inventory can be carried over a * failed probe, so a spend re-plans from a live listing. An account whose * report carries no inventory is unknown, never empty. */ export declare function claudeResetStatusesFromReports(accounts: readonly OAuthAccountSummary[], reports: readonly UsageReport[]): ResetCreditAccountStatus[]; /** Limits a grant restores: the ones it clears, and only the 5h window for a Juniper grant. */ export declare function claudeCoveredLimits(limits: readonly UsageLimit[], credit: UsageResetCreditDetail): UsageLimit[]; /** The fullest covered limit by the report's or the grant's own used fraction: what a salvage spend restores. */ export declare function fullestClaudeLimit(covered: readonly UsageLimit[], credit: UsageResetCreditDetail): { limit: UsageLimit; used: number; } | undefined; /** * Pure Claude Cedar/Juniper auto-spend planner. The live listing is the sole * authority for eligibility and grant selection: an absent/failed status never * falls back to a cached report or guesses a different grant. */ export declare function planClaudeResetRedemptions(input: ClaudeResetPlanInput): ClaudeResetPlan;