// These internal JSON shapes also run in standalone Node, outside Pi's peer aliases. type Check = (value: unknown) => value is T; type Static = T extends Check ? Value : never; type Fields = Record>; type ObjectValue = { [Key in keyof Shape as undefined extends Static ? never : Key]: Static; } & { [Key in keyof Shape as undefined extends Static ? Key : never]?: Static; }; const isObject = (value: unknown): value is Record => value !== null && typeof value === "object" && !Array.isArray(value); const number = (value: unknown): value is number => typeof value === "number" && Number.isFinite(value) && value >= 0; const string = (value: unknown): value is string => typeof value === "string"; const boolean = (value: unknown): value is boolean => typeof value === "boolean"; function object(shape: Shape): Check> { const fields = Object.entries(shape); return (value): value is ObjectValue => isObject(value) && fields.every(([key, check]) => check(value[key])); } function record(check: Check): Check> { return (value): value is Record => isObject(value) && Object.values(value).every(check); } function array(check: Check): Check { return (value): value is Value[] => Array.isArray(value) && value.every(check); } function optional(check: Check): Check { return (value): value is Value | undefined => value === undefined || check(value); } function literal(...values: Value[]): Check { return (value): value is Value => values.some((expected) => value === expected); } const Stats = object({ usd: number, input: number, output: number, cacheRead: number, cacheWrite: number, requests: number, unpriced: number, }); const Summary = object({ total: Stats, models: record(Stats) }); const Spend = object({ at: number, model: string, stats: Stats }); const Quota = object({ at: number, usedPercent: (value: unknown): value is number => number(value) && value <= 100, usd: number }); const HistoryCoverage = object({ sessions: number, skippedCopies: number, incompleteEntries: number, unattributedUsage: number, unreadablePaths: optional(number), warnings: array(string) }); const HistoryFields = { from: number, to: number, windowStart: number, root: string, coverage: HistoryCoverage, }; const HistoryScan = object({ ...HistoryFields, total: Summary, months: record(Summary), previous: Summary, recent: array(Spend), nonstandard: optional(boolean), }); const PeriodFields = { start: number, expectedReset: number, source: literal("inferred", "manual", "session-history"), partial: boolean, summary: Summary, approximate: optional(boolean), quota: optional(Quota), quotaPerUsd: optional(number), }; const Period = object(PeriodFields); const ClosedPeriod = object({ ...PeriodFields, end: number, closedAt: number, reason: literal("scheduled", "early", "gap", "backfill"), quotaEstimate: optional(number), }); const Account = object({ since: number, total: Summary, months: record(Summary), nonstandard: optional(boolean), recent: array(Spend), current: optional(Period), closed: record(ClosedPeriod), previous: optional(string), unassignedUsd: number, missingWeeklyObservations: number, recordingGaps: number, lastObservation: optional(number), manualResetAt: optional(number), history: optional(object({ ...HistoryFields, importedAt: number, accountIdentity: literal("unverified") })), }); const Ledger = object({ version: literal(1), accounts: record(Account), historyOwner: optional(string) }); export type SpendStats = Static; export type SpendSummary = Static; export type CodexSpend = Static; export type UsagePeriod = Static; export type UsageAccount = Static; export type UsageLedger = Static; export type UsageHistoryScan = Static; export function parseUsageHistory(value: unknown): UsageHistoryScan { if (!HistoryScan(value)) throw new Error("Invalid session history report; no history was imported."); return value; } export function parseUsageLedger(value: unknown): UsageLedger { if (!Ledger(value)) throw new Error("Unsupported or invalid Codex usage ledger; the file was not changed."); return value; } export function emptyStats(): SpendStats { return { usd: 0, input: 0, output: 0, cacheRead: 0, cacheWrite: 0, requests: 0, unpriced: 0 }; } export function emptySummary(): SpendSummary { return { total: emptyStats(), models: {} }; }