// Live Command Code quota from the alpha billing API. Shared by the TUI plugin // (loaded from source) and scripts/quota.mjs. Endpoints, validated against // api.commandcode.ai: // // GET /alpha/whoami // GET /alpha/billing/credits?orgId= // GET /alpha/billing/subscriptions?orgId= // GET /alpha/usage/summary?orgId= // // These are the same endpoints the `cmd` CLI `/usage` command reads. This module uses // global fetch only, so the built provider stays runtime-dependency-free. import { DEFAULT_BASE_URL } from "./constants.js"; import { redact } from "./redact.js"; export const QUOTA_TIMEOUT_MS = 15_000; export type QuotaWindowId = "fiveHour" | "weekly" | "monthly"; export type QuotaWindow = { id: QuotaWindowId; label: string; used: number; cap: number; resetAtMs: number | null; exceeded: boolean; }; export type QuotaCredits = { monthly: number; purchased: number; free: number; remaining: number; }; export type QuotaAccount = { login: string; keyName?: string; orgId: string | null; }; export type QuotaPlan = { id: string; status: string; currentPeriodStart?: string; currentPeriodEnd?: string; }; export type QuotaSummary = { totalCost: number; totalCount: number; totalTokens?: number; periodBasis?: string; }; export type Quota = { account: QuotaAccount; plan: QuotaPlan | null; credits: QuotaCredits | null; summary: QuotaSummary | null; windows: QuotaWindow[]; unavailable: QuotaWindowId[]; fetchedAt: number; }; export type QuotaErrorKind = "config" | "http" | "network" | "timeout"; export type QuotaResult = | { ok: true; quota: Quota } | { ok: false; error: { kind: QuotaErrorKind; message: string } }; export type QuotaFetchOptions = { apiKey: string; baseURL?: string; orgId?: string; timeoutMs?: number; fetchImpl?: typeof fetch; }; function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } function numberValue(value: unknown): number | undefined { return typeof value === "number" && Number.isFinite(value) ? value : undefined; } function stringValue(value: unknown): string | undefined { return typeof value === "string" && value.length > 0 ? value : undefined; } /** Epoch ms. Upstream has shipped both seconds and ms; >= 1e12 is treated as ms. */ function resetAtMs(value: unknown): number | null { let n: number | undefined; if (typeof value === "number" && Number.isFinite(value)) n = value; else if (typeof value === "string" && value.trim().length > 0) { const text = value.trim(); n = /^\d+$/.test(text) ? Number(text) : Date.parse(text); } if (n === undefined || !Number.isFinite(n) || n < 0) return null; return n >= 1e12 ? Math.round(n) : Math.round(n * 1000); } function parseWindow(id: QuotaWindowId, label: string, value: unknown): QuotaWindow | null { if (!isRecord(value)) return null; const used = numberValue(value.used); const cap = numberValue(value.cap); if (used === undefined || cap === undefined || (used === 0 && cap === 0)) return null; return { id, label, used, cap, resetAtMs: resetAtMs(value.resetAt), exceeded: value.exceeded === true || (cap > 0 && used >= cap), }; } function parseCredits(value: unknown): { credits: QuotaCredits; windows: QuotaWindow[] } | null { if (!isRecord(value) || !isRecord(value.credits)) return null; const c = value.credits; const monthly = numberValue(c.monthlyCredits) ?? 0; const purchased = numberValue(c.purchasedCredits) ?? 0; const free = numberValue(c.freeCredits) ?? 0; const limits = isRecord(value.windowLimits) ? value.windowLimits : {}; const windows: QuotaWindow[] = []; const fiveHour = parseWindow("fiveHour", "5-hour", limits.fiveHour); const weekly = parseWindow("weekly", "Weekly", limits.weekly); if (fiveHour) windows.push(fiveHour); if (weekly) windows.push(weekly); return { credits: { monthly, purchased, free, remaining: monthly + purchased + free }, windows }; } function parseAccount(value: unknown): QuotaAccount | null { if (!isRecord(value)) return null; const org = isRecord(value.org) ? value.org : undefined; const user = isRecord(value.user) ? value.user : undefined; const login = (user ? (stringValue(user.userName) ?? stringValue(user.name)) : undefined) ?? (org ? stringValue(org.login) : undefined); if (!login) return null; const keyName = user ? (stringValue(user.keyName) ?? stringValue(user.displayName)) : undefined; return { login, orgId: org ? (stringValue(org.id) ?? null) : null, ...(keyName ? { keyName } : {}) }; } function parsePlan(value: unknown): QuotaPlan | null { if (!isRecord(value) || !isRecord(value.data)) return null; const data = value.data; const id = stringValue(data.planId); const status = stringValue(data.status); if (!id && !status) return null; const start = stringValue(data.currentPeriodStart); const end = stringValue(data.currentPeriodEnd); return { id: id ?? "unknown", status: status ?? "unknown", ...(start ? { currentPeriodStart: start } : {}), ...(end ? { currentPeriodEnd: end } : {}), }; } function parseSummary(value: unknown): QuotaSummary | null { if (!isRecord(value)) return null; const totalCost = numberValue(value.totalCost); const totalCount = numberValue(value.totalCount); if (totalCost === undefined || totalCount === undefined) return null; const totalTokens = numberValue(value.totalTokens); const periodBasis = stringValue(value.periodBasis); return { totalCost, totalCount, ...(totalTokens === undefined ? {} : { totalTokens }), ...(periodBasis === undefined ? {} : { periodBasis }), }; } function periodEndMs(plan: QuotaPlan | null): number | null { if (!plan?.currentPeriodEnd) return null; return resetAtMs(plan.currentPeriodEnd); } class QuotaHttpError extends Error { readonly status: number; readonly body: string; constructor(status: number, body: string) { super(`HTTP ${status}`); this.name = "QuotaHttpError"; this.status = status; this.body = body; } } class QuotaTimeoutError extends Error { constructor() { super("Command Code quota request timed out"); this.name = "QuotaTimeoutError"; } } function isAuthError(error: unknown): boolean { return error instanceof QuotaHttpError && (error.status === 401 || error.status === 403); } export async function fetchQuota(options: QuotaFetchOptions): Promise { if (!options.apiKey) { return { ok: false, error: { kind: "config", message: "No Command Code API key found" } }; } const baseURL = (options.baseURL ?? DEFAULT_BASE_URL).replace(/\/+$/, ""); const fetchImpl = options.fetchImpl ?? fetch; const timeoutMs = options.timeoutMs ?? QUOTA_TIMEOUT_MS; const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeoutMs); const headers = { accept: "application/json", authorization: /^Bearer\s/i.test(options.apiKey) ? options.apiKey : `Bearer ${options.apiKey}`, }; const request = async (path: string, params?: Record): Promise => { if (controller.signal.aborted) throw new QuotaTimeoutError(); const search = new URLSearchParams(); for (const [key, value] of Object.entries(params ?? {})) if (value) search.set(key, value); const query = search.toString(); let response: Response; try { response = await fetchImpl(`${baseURL}${path}${query ? `?${query}` : ""}`, { method: "GET", headers, signal: controller.signal, }); } catch (error) { if (controller.signal.aborted) throw new QuotaTimeoutError(); throw error; } if (!response.ok) throw new QuotaHttpError(response.status, await response.text().catch(() => "")); return (await response.json()) as unknown; }; try { const whoamiRaw = await request("/alpha/whoami"); const account = parseAccount(whoamiRaw); if (!account) { return { ok: false, error: { kind: "http", message: "Command Code returned an unrecognized account response" }, }; } const orgId = options.orgId ?? account.orgId ?? undefined; const unavailable: QuotaWindowId[] = []; let credits: QuotaCredits | null = null; let windows: QuotaWindow[] = []; try { const parsed = parseCredits(await request("/alpha/billing/credits", { orgId })); if (parsed) { credits = parsed.credits; windows = parsed.windows; } } catch (error) { if (isAuthError(error) || error instanceof QuotaTimeoutError) { return { ok: false, error: quotaError(error) }; } } let plan: QuotaPlan | null = null; try { plan = parsePlan(await request("/alpha/billing/subscriptions", { orgId })); } catch (error) { if (isAuthError(error) || error instanceof QuotaTimeoutError) { return { ok: false, error: quotaError(error) }; } } let summary: QuotaSummary | null = null; try { summary = parseSummary(await request("/alpha/usage/summary", { orgId, since: plan?.currentPeriodStart })); } catch (error) { if (isAuthError(error) || error instanceof QuotaTimeoutError) { return { ok: false, error: quotaError(error) }; } } if (credits) { const spent = summary?.totalCost; if (spent !== undefined) { windows.push({ id: "monthly", label: "Monthly", used: spent, cap: spent + credits.remaining, resetAtMs: periodEndMs(plan), exceeded: credits.remaining <= 0, }); } else { unavailable.push("monthly"); } } else { unavailable.push("monthly"); } if (!credits && !summary) { return { ok: false, error: { kind: "http", message: "Command Code returned no recognized usage data for the account", }, }; } return { ok: true, quota: { account, plan, credits, summary, windows, unavailable, fetchedAt: Date.now(), }, }; } catch (error) { return { ok: false, error: quotaError(error) }; } finally { clearTimeout(timer); } } function quotaError(error: unknown): { kind: QuotaErrorKind; message: string } { if (error instanceof QuotaTimeoutError) return { kind: "timeout", message: error.message }; if (error instanceof QuotaHttpError) { const detail = error.body.trim().slice(0, 200); const hint = error.status === 401 || error.status === 403 ? " (check the API key)" : ""; return { kind: "http", message: redact(`Command Code quota request failed (${error.status})${hint}: ${detail}`), }; } return { kind: "network", message: redact(`Command Code quota request failed: ${error instanceof Error ? error.message : String(error)}`), }; } export function percent(used: number, cap: number): number { if (!(cap > 0)) return 0; return Math.round((used / cap) * 100); } export function quotaBar(used: number, cap: number, width = 10): string { const fraction = cap > 0 ? Math.min(1, Math.max(0, used / cap)) : 0; const filled = Math.round(fraction * width); return `${"█".repeat(filled)}${"░".repeat(width - filled)}`; } /** Compact countdown, e.g. `3h 12m` / `2d 4h`. Empty when there is no reset. */ export function formatReset(resetAtMs: number | null, now: number = Date.now()): string { if (resetAtMs === null) return ""; const diff = resetAtMs - now; if (diff <= 0) return "soon"; const minutes = Math.ceil(diff / 60_000); if (minutes < 60) return `${minutes}m`; const hours = Math.floor(minutes / 60); const mins = minutes % 60; if (hours < 24) return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`; const days = Math.floor(hours / 24); const rem = hours % 24; return rem > 0 ? `${days}d ${rem}h` : `${days}d`; } function formatTokens(tokens: number): string { if (tokens >= 1_000_000_000) return `${(tokens / 1_000_000_000).toFixed(1)}B`; if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`; if (tokens >= 1_000) return `${(tokens / 1_000).toFixed(1)}k`; return String(tokens); } function formatWindowLine(w: QuotaWindow, now: number): string { const pct = Math.min(percent(w.used, w.cap), 999); const reset = formatReset(w.resetAtMs, now); const amount = w.id === "monthly" ? `$${w.used.toFixed(2)} / $${w.cap.toFixed(2)}` : `${w.used.toFixed(2)} / ${w.cap.toFixed(2)} credits`; return `${w.label.padEnd(8)} ${quotaBar(w.used, w.cap)} ${String(pct).padStart(3)}% ${amount}${ reset ? ` (resets in ${reset})` : "" }`; } function planLine(plan: QuotaPlan, now: number): string { const name = plan.id.replace(/[_-]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()); const status = plan.status ? ` · ${plan.status}` : ""; const end = periodEndMs(plan); if (end === null) return `Plan: ${name}${status}`; const remaining = end - now; const days = Math.ceil(remaining / 86_400_000); const date = new Date(end).toISOString().slice(0, 10); const when = days > 0 ? `renews ${date} (${days}d)` : days === 0 ? `renews ${date} (today)` : `renewed ${date}`; return `Plan: ${name}${status} · ${when}`; } /** Human-readable multi-line quota summary for the `/cc-usage` command and CLI. */ export function formatQuota(quota: Quota, now: number = Date.now()): string { const lines: string[] = []; lines.push(quota.account.keyName ?? quota.account.login); if (quota.plan) lines.push(planLine(quota.plan, now)); if (quota.windows.length > 0) { lines.push(""); for (const w of quota.windows) lines.push(formatWindowLine(w, now)); } if (quota.credits) { const parts = [`monthly $${quota.credits.monthly.toFixed(2)}`, `purchased $${quota.credits.purchased.toFixed(2)}`]; if (quota.credits.free > 0) parts.push(`free $${quota.credits.free.toFixed(2)}`); lines.push("", `Credits: ${parts.join(" / ")}`); } if (quota.summary) { const period = quota.plan?.currentPeriodStart ? "this billing period" : "total"; const tokens = quota.summary.totalTokens === undefined ? "" : ` · ${formatTokens(quota.summary.totalTokens)} tokens`; lines.push( `Usage: ${quota.summary.totalCount.toLocaleString("en-US")} requests · $${quota.summary.totalCost.toFixed(2)} (${period})${tokens}`, ); } if (quota.unavailable.length > 0) lines.push("", `Unavailable: ${quota.unavailable.join(", ")}`); return lines.join("\n"); }