@viraatdas/rudder 2.14.68 → 2.14.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/report.js ADDED
@@ -0,0 +1,412 @@
1
+ import path from "node:path";
2
+ import fsp from "node:fs/promises";
3
+ import { readJson, nowIso, slugPrefix, } from "./util.js";
4
+ const RUDDER_DIR = ".rudder";
5
+ const RUNS_DIR = "runs";
6
+ /**
7
+ * Load all run records from .rudder/runs/
8
+ */
9
+ export async function loadAllRuns(repoRoot) {
10
+ const runsPath = path.join(repoRoot, RUDDER_DIR, RUNS_DIR);
11
+ try {
12
+ const entries = await fsp.readdir(runsPath, { withFileTypes: true });
13
+ const runs = [];
14
+ for (const entry of entries) {
15
+ if (!entry.isDirectory())
16
+ continue;
17
+ const runJsonPath = path.join(runsPath, entry.name, "run.json");
18
+ const run = await readJson(runJsonPath);
19
+ if (run) {
20
+ runs.push(run);
21
+ }
22
+ }
23
+ return runs.sort((a, b) => {
24
+ const dateA = new Date(b.createdAt);
25
+ const dateB = new Date(a.createdAt);
26
+ return dateA.getTime() - dateB.getTime();
27
+ });
28
+ }
29
+ catch (e) {
30
+ if (e.code === "ENOENT") {
31
+ return [];
32
+ }
33
+ throw e;
34
+ }
35
+ }
36
+ /**
37
+ * Calculate metrics from a run record
38
+ */
39
+ function runToMetrics(run) {
40
+ const created = new Date(run.createdAt);
41
+ const updated = new Date(run.updatedAt);
42
+ const duration = (updated.getTime() - created.getTime()) / 1000;
43
+ return {
44
+ id: run.id,
45
+ task: run.task,
46
+ taskSummary: run.taskSummary || run.taskSummaryLlm ? "auto-summarized" : undefined,
47
+ backend: run.backend,
48
+ model: run.model,
49
+ status: run.status,
50
+ createdAt: run.createdAt,
51
+ updatedAt: run.updatedAt,
52
+ duration,
53
+ durationReadable: formatDuration(duration),
54
+ inputTokens: run.tokens?.input,
55
+ outputTokens: run.tokens?.output,
56
+ totalTokens: (run.tokens?.input || 0) + (run.tokens?.output || 0) || undefined,
57
+ mergeStatus: run.merge?.status,
58
+ workspacePath: run.workspace?.path,
59
+ inWorkspace: run.workspace?.enabled,
60
+ };
61
+ }
62
+ /**
63
+ * Format duration in seconds to human-readable string
64
+ */
65
+ function formatDuration(seconds) {
66
+ if (seconds < 60)
67
+ return `${Math.round(seconds)}s`;
68
+ if (seconds < 3600)
69
+ return `${Math.round(seconds / 60)}m`;
70
+ const hours = Math.round(seconds / 3600);
71
+ const mins = Math.round((seconds % 3600) / 60);
72
+ return mins > 0 ? `${hours}h${mins}m` : `${hours}h`;
73
+ }
74
+ /**
75
+ * Filter runs based on options
76
+ */
77
+ function filterRuns(runs, options) {
78
+ let filtered = runs;
79
+ // Status filter
80
+ if (options.status) {
81
+ const statuses = Array.isArray(options.status)
82
+ ? options.status
83
+ : [options.status];
84
+ filtered = filtered.filter(r => statuses.includes(r.status));
85
+ }
86
+ // Backend filter
87
+ if (options.backend) {
88
+ const backends = Array.isArray(options.backend)
89
+ ? options.backend
90
+ : [options.backend];
91
+ filtered = filtered.filter(r => backends.includes(r.backend));
92
+ }
93
+ // Model filter
94
+ if (options.model) {
95
+ filtered = filtered.filter(r => r.model?.toLowerCase().includes(options.model.toLowerCase()));
96
+ }
97
+ // Date range filter
98
+ if (options.after) {
99
+ filtered = filtered.filter(r => r.createdAt >= options.after);
100
+ }
101
+ if (options.before) {
102
+ filtered = filtered.filter(r => r.createdAt <= options.before);
103
+ }
104
+ // Limit
105
+ if (options.limit) {
106
+ filtered = filtered.slice(0, options.limit);
107
+ }
108
+ return filtered;
109
+ }
110
+ /**
111
+ * Sort runs by specified column
112
+ */
113
+ function sortRuns(runs, options) {
114
+ const metrics = runs.map(runToMetrics);
115
+ const sortBy = options.sortBy || "created";
116
+ const reverse = options.reverse || false;
117
+ const sortFn = (a, b) => {
118
+ let cmp = 0;
119
+ switch (sortBy) {
120
+ case "created":
121
+ cmp = a.createdAt.localeCompare(b.createdAt);
122
+ break;
123
+ case "updated":
124
+ cmp = a.updatedAt.localeCompare(b.updatedAt);
125
+ break;
126
+ case "duration":
127
+ cmp = (a.duration || 0) - (b.duration || 0);
128
+ break;
129
+ case "tokens":
130
+ cmp = (a.totalTokens || 0) - (b.totalTokens || 0);
131
+ break;
132
+ case "status":
133
+ cmp = a.status.localeCompare(b.status);
134
+ break;
135
+ default:
136
+ cmp = 0;
137
+ }
138
+ return reverse ? -cmp : cmp;
139
+ };
140
+ return metrics.sort(sortFn);
141
+ }
142
+ /**
143
+ * Generate summary statistics
144
+ */
145
+ function generateSummary(runs) {
146
+ const statusCounts = {
147
+ created: 0,
148
+ running: 0,
149
+ steering: 0,
150
+ verifying: 0,
151
+ completed: 0,
152
+ failed: 0,
153
+ cancelled: 0,
154
+ paused: 0,
155
+ orphaned: 0,
156
+ migrated: 0,
157
+ "merge-conflict": 0,
158
+ merged: 0,
159
+ };
160
+ const backendCounts = {
161
+ claude: 0,
162
+ codex: 0,
163
+ acpx: 0,
164
+ opencode: 0,
165
+ };
166
+ let totalDuration = 0;
167
+ let durableRuns = 0;
168
+ let totalTokens = 0;
169
+ let tokensRuns = 0;
170
+ let mergeConflicts = 0;
171
+ let successful = 0;
172
+ for (const run of runs) {
173
+ statusCounts[run.status]++;
174
+ backendCounts[run.backend]++;
175
+ const duration = (new Date(run.updatedAt).getTime() -
176
+ new Date(run.createdAt).getTime()) /
177
+ 1000;
178
+ if (run.status === "completed" || run.status === "merged") {
179
+ totalDuration += duration;
180
+ durableRuns++;
181
+ successful++;
182
+ }
183
+ else if (run.status === "failed" ||
184
+ run.status === "cancelled" ||
185
+ run.status === "orphaned") {
186
+ // Counts in denominator but not numerator
187
+ }
188
+ else {
189
+ // In-flight runs might finish, don't count yet
190
+ }
191
+ if (run.tokens) {
192
+ totalTokens += (run.tokens.input || 0) + (run.tokens.output || 0);
193
+ tokensRuns++;
194
+ }
195
+ if (run.hadMergeConflict || run.merge?.status === "conflict") {
196
+ mergeConflicts++;
197
+ }
198
+ }
199
+ const timeRange = runs.length > 0
200
+ ? {
201
+ earliest: runs[runs.length - 1].createdAt,
202
+ latest: runs[0].createdAt,
203
+ }
204
+ : undefined;
205
+ return {
206
+ totalRuns: runs.length,
207
+ statusCounts,
208
+ backendCounts,
209
+ avgDuration: durableRuns > 0 ? totalDuration / durableRuns : undefined,
210
+ totalTokens: totalTokens > 0 ? totalTokens : undefined,
211
+ avgTokens: tokensRuns > 0 ? totalTokens / tokensRuns : undefined,
212
+ mergeConflictRate: runs.length > 0 ? (mergeConflicts / runs.length) * 100 : undefined,
213
+ successRate: runs.length > 0
214
+ ? ((successful / runs.length) * 100)
215
+ : undefined,
216
+ timeRange,
217
+ };
218
+ }
219
+ /**
220
+ * Format as table (default)
221
+ */
222
+ function formatTable(metrics, summary) {
223
+ const lines = [];
224
+ // Header
225
+ lines.push("ID | Task (first 30) | Backend | Model | Status | Duration | Tokens");
226
+ lines.push("-".repeat(145));
227
+ // Rows
228
+ for (const m of metrics) {
229
+ const taskDisplay = (m.task || "").substring(0, 30).padEnd(24);
230
+ const modelDisplay = (m.model || "").substring(0, 17).padEnd(17);
231
+ const tokens = m.totalTokens ? String(m.totalTokens.toLocaleString()) : "—";
232
+ const row = [
233
+ slugPrefix(m.id, "id", 20).padEnd(20),
234
+ taskDisplay,
235
+ m.backend.padEnd(7),
236
+ modelDisplay,
237
+ m.status.padEnd(16),
238
+ String(m.durationReadable || "—").padEnd(11),
239
+ tokens,
240
+ ].join(" | ");
241
+ lines.push(row);
242
+ }
243
+ // Summary
244
+ if (summary) {
245
+ lines.push("");
246
+ lines.push("SUMMARY");
247
+ lines.push("-".repeat(145));
248
+ lines.push(`Total runs: ${summary.totalRuns}`);
249
+ lines.push(`Statuses: ` + Object.entries(summary.statusCounts)
250
+ .filter(([_, count]) => count > 0)
251
+ .map(([status, count]) => `${status}=${count}`)
252
+ .join(", "));
253
+ lines.push(`Backends: ` + Object.entries(summary.backendCounts)
254
+ .filter(([_, count]) => count > 0)
255
+ .map(([backend, count]) => `${backend}=${count}`)
256
+ .join(", "));
257
+ if (summary.avgDuration !== undefined) {
258
+ lines.push(`Avg duration (completed): ${formatDuration(summary.avgDuration)}`);
259
+ }
260
+ if (summary.totalTokens !== undefined) {
261
+ lines.push(`Total tokens: ${summary.totalTokens.toLocaleString()}`);
262
+ }
263
+ if (summary.avgTokens !== undefined) {
264
+ lines.push(`Avg tokens/run: ${Math.round(summary.avgTokens).toLocaleString()}`);
265
+ }
266
+ if (summary.mergeConflictRate !== undefined) {
267
+ lines.push(`Merge conflict rate: ${summary.mergeConflictRate.toFixed(1)}%`);
268
+ }
269
+ if (summary.successRate !== undefined) {
270
+ lines.push(`Success rate: ${summary.successRate.toFixed(1)}%`);
271
+ }
272
+ if (summary.timeRange) {
273
+ lines.push(`Time range: ${summary.timeRange.earliest} to ${summary.timeRange.latest}`);
274
+ }
275
+ }
276
+ return lines.join("\n");
277
+ }
278
+ /**
279
+ * Format as JSON
280
+ */
281
+ function formatJson(metrics, summary) {
282
+ const output = {
283
+ runs: metrics,
284
+ ...(summary && { summary }),
285
+ };
286
+ return JSON.stringify(output, null, 2);
287
+ }
288
+ /**
289
+ * Format as Markdown
290
+ */
291
+ function formatMarkdown(metrics, summary) {
292
+ const lines = [];
293
+ lines.push("# Rudder Runs Report");
294
+ lines.push("");
295
+ lines.push(`Generated: ${nowIso()}`);
296
+ lines.push("");
297
+ if (summary) {
298
+ lines.push("## Summary");
299
+ lines.push("");
300
+ lines.push(`- **Total runs:** ${summary.totalRuns}`);
301
+ if (summary.avgDuration !== undefined) {
302
+ lines.push(`- **Avg duration:** ${formatDuration(summary.avgDuration)}`);
303
+ }
304
+ if (summary.totalTokens !== undefined) {
305
+ lines.push(`- **Total tokens:** ${summary.totalTokens.toLocaleString()}`);
306
+ }
307
+ if (summary.avgTokens !== undefined) {
308
+ lines.push(`- **Avg tokens per run:** ${Math.round(summary.avgTokens).toLocaleString()}`);
309
+ }
310
+ if (summary.successRate !== undefined) {
311
+ lines.push(`- **Success rate:** ${summary.successRate.toFixed(1)}%`);
312
+ }
313
+ if (summary.mergeConflictRate !== undefined) {
314
+ lines.push(`- **Merge conflict rate:** ${summary.mergeConflictRate.toFixed(1)}%`);
315
+ }
316
+ lines.push("");
317
+ lines.push("### Status Breakdown");
318
+ lines.push("");
319
+ for (const [status, count] of Object.entries(summary.statusCounts)) {
320
+ if (count > 0) {
321
+ lines.push(`- ${status}: ${count}`);
322
+ }
323
+ }
324
+ lines.push("");
325
+ lines.push("### Backend Breakdown");
326
+ lines.push("");
327
+ for (const [backend, count] of Object.entries(summary.backendCounts)) {
328
+ if (count > 0) {
329
+ lines.push(`- ${backend}: ${count}`);
330
+ }
331
+ }
332
+ lines.push("");
333
+ }
334
+ lines.push("## Runs");
335
+ lines.push("");
336
+ lines.push("| ID | Task | Backend | Model | Status | Duration | Tokens |");
337
+ lines.push("|---|---|---|---|---|---|---|");
338
+ for (const m of metrics) {
339
+ const id = slugPrefix(m.id, "id", 8);
340
+ const task = (m.task || "").substring(0, 40).replace(/\|/g, "\\|");
341
+ const model = (m.model || "—").substring(0, 20);
342
+ const tokens = m.totalTokens
343
+ ? String(m.totalTokens.toLocaleString())
344
+ : "—";
345
+ lines.push(`| ${id} | ${task} | ${m.backend} | ${model} | ${m.status} | ${String(m.durationReadable || "—")} | ${tokens} |`);
346
+ }
347
+ return lines.join("\n");
348
+ }
349
+ /**
350
+ * Format as CSV
351
+ */
352
+ function formatCsv(metrics) {
353
+ const lines = [];
354
+ // Header
355
+ lines.push("ID,Task,Backend,Model,Status,CreatedAt,UpdatedAt,Duration(s),InputTokens,OutputTokens,TotalTokens,MergeStatus,InWorkspace");
356
+ // Rows
357
+ for (const m of metrics) {
358
+ const task = (m.task || "").replace(/"/g, '""'); // CSV escape
359
+ const row = [
360
+ m.id,
361
+ `"${task}"`,
362
+ m.backend,
363
+ m.model || "",
364
+ m.status,
365
+ m.createdAt,
366
+ m.updatedAt,
367
+ m.duration?.toFixed(0) || "",
368
+ m.inputTokens || "",
369
+ m.outputTokens || "",
370
+ m.totalTokens || "",
371
+ m.mergeStatus || "",
372
+ m.inWorkspace ? "yes" : "no",
373
+ ];
374
+ lines.push(row.join(","));
375
+ }
376
+ return lines.join("\n");
377
+ }
378
+ /**
379
+ * Generate and output a report
380
+ */
381
+ export async function generateReport(repoRoot, options = {}) {
382
+ const runs = await loadAllRuns(repoRoot);
383
+ const filtered = filterRuns(runs, options);
384
+ const sorted = sortRuns(filtered, options);
385
+ const summary = options.summary !== false ? generateSummary(filtered) : undefined;
386
+ const format = options.format || "table";
387
+ switch (format) {
388
+ case "json":
389
+ return formatJson(sorted, summary);
390
+ case "markdown":
391
+ return formatMarkdown(sorted, summary);
392
+ case "csv":
393
+ return formatCsv(sorted);
394
+ case "table":
395
+ default:
396
+ return formatTable(sorted, summary);
397
+ }
398
+ }
399
+ /**
400
+ * Print report to stdout
401
+ */
402
+ export async function printReport(repoRoot, options = {}) {
403
+ try {
404
+ const report = await generateReport(repoRoot, options);
405
+ console.log(report);
406
+ }
407
+ catch (e) {
408
+ console.error(`Failed to generate report: ${e instanceof Error ? e.message : String(e)}`);
409
+ process.exit(1);
410
+ }
411
+ }
412
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
package/dist/usage.d.ts CHANGED
@@ -127,6 +127,8 @@ export type AccountQuota = {
127
127
  email: string | null;
128
128
  plan: string | null;
129
129
  windows: QuotaWindow[];
130
+ /** Human-readable reason a request would be rejected or throttled right now (rate limit hit, credits depleted), or null when clear. */
131
+ blocked: string | null;
130
132
  /** Human-readable reason the meters are missing, with the fix. */
131
133
  error: string | null;
132
134
  fetchedAt: string;
@@ -136,7 +138,13 @@ export type QuotaReport = {
136
138
  fetchedAt: string;
137
139
  ttlSeconds: number;
138
140
  };
139
- /** Pure: Claude's `/api/oauth/usage` body → meters. */
141
+ /**
142
+ * Pure: Claude's `/api/oauth/usage` body → meters. Newer accounts stop
143
+ * populating `seven_day_opus`/`seven_day_sonnet` (both come back `null`) and
144
+ * report the active model's weekly sub-limit in `usage.limits[]` instead,
145
+ * keyed by `scope.model.display_name` — e.g. a Fable-heavy week shows a
146
+ * higher "Weekly · Fable" percent than the blended `seven_day` figure.
147
+ */
140
148
  export declare function parseClaudeQuota(usage: any, profile: any, fallbackPlan: string | null): Omit<AccountQuota, "fetchedAt" | "provider">;
141
149
  /** Pure: Codex's `/backend-api/wham/usage` body → meters. */
142
150
  export declare function parseCodexQuota(body: any): Omit<AccountQuota, "fetchedAt" | "provider">;
package/dist/usage.js CHANGED
@@ -518,7 +518,13 @@ function planLabel(tier, fallback) {
518
518
  return fallback.charAt(0).toUpperCase() + fallback.slice(1);
519
519
  return null;
520
520
  }
521
- /** Pure: Claude's `/api/oauth/usage` body → meters. */
521
+ /**
522
+ * Pure: Claude's `/api/oauth/usage` body → meters. Newer accounts stop
523
+ * populating `seven_day_opus`/`seven_day_sonnet` (both come back `null`) and
524
+ * report the active model's weekly sub-limit in `usage.limits[]` instead,
525
+ * keyed by `scope.model.display_name` — e.g. a Fable-heavy week shows a
526
+ * higher "Weekly · Fable" percent than the blended `seven_day` figure.
527
+ */
522
528
  export function parseClaudeQuota(usage, profile, fallbackPlan) {
523
529
  const windows = [];
524
530
  const push = (label, w) => {
@@ -530,17 +536,32 @@ export function parseClaudeQuota(usage, profile, fallbackPlan) {
530
536
  push("Weekly", usage?.seven_day);
531
537
  push("Weekly · Opus", usage?.seven_day_opus);
532
538
  push("Weekly · Sonnet", usage?.seven_day_sonnet);
539
+ const seenScopes = new Set(windows.map((w) => w.label));
540
+ for (const limit of Array.isArray(usage?.limits) ? usage.limits : []) {
541
+ if (!limit?.is_active || typeof limit.percent !== "number")
542
+ continue;
543
+ const model = limit.scope?.model?.display_name;
544
+ if (typeof model !== "string" || !model)
545
+ continue;
546
+ const label = `Weekly · ${model}`;
547
+ if (seenScopes.has(label))
548
+ continue;
549
+ seenScopes.add(label);
550
+ windows.push({ label, percent: Math.max(0, Math.min(100, Math.round(limit.percent))), resetsAt: limit.resets_at ?? null });
551
+ }
533
552
  const extra = usage?.extra_usage;
534
553
  if (extra?.is_enabled && typeof extra.utilization === "number") {
535
554
  windows.push({ label: "Extra usage", percent: Math.round(extra.utilization), resetsAt: null });
536
555
  }
537
556
  const email = typeof profile?.account?.email === "string" ? profile.account.email : null;
538
557
  const plan = planLabel(profile?.organization?.rate_limit_tier, fallbackPlan);
539
- return { email, plan, windows, error: windows.length ? null : "this plan does not expose limits" };
558
+ const lockedReason = [usage?.five_hour, usage?.seven_day].map((w) => w?.locked_reason).find((r) => typeof r === "string" && r);
559
+ const blocked = lockedReason ? `blocked — ${String(lockedReason).replace(/_/g, " ")}` : null;
560
+ return { email, plan, windows, blocked, error: windows.length ? null : "this plan does not expose limits" };
540
561
  }
541
562
  async function fetchClaudeQuota() {
542
563
  const fetchedAt = new Date().toISOString();
543
- const base = { provider: "claude", email: null, plan: null, windows: [], fetchedAt };
564
+ const base = { provider: "claude", email: null, plan: null, windows: [], blocked: null, fetchedAt };
544
565
  const creds = await readClaudeCredentials();
545
566
  if (!creds)
546
567
  return { ...base, error: "not signed in — run `claude` and log in" };
@@ -583,6 +604,54 @@ async function readCodexCredentials() {
583
604
  return null;
584
605
  }
585
606
  }
607
+ /**
608
+ * Codex's own `plan_type` enum (from `codex-backend-openapi-models`, the
609
+ * generated client OpenAI ships inside the Codex CLI source): guest, free,
610
+ * go, plus, pro, prolite, free_workspace, team,
611
+ * self_serve_business_prolite, self_serve_business_usage_based, business,
612
+ * ent26, enterprise_cbp_automation, enterprise_cbp_usage_based, education,
613
+ * quorum, k12, enterprise, edu, edu_plus, edu_pro. Exact-match the common
614
+ * ones for a clean label; title-case anything else rather than leaving
615
+ * underscores in an unfamiliar tier's name.
616
+ */
617
+ const CODEX_PLAN_LABELS = {
618
+ guest: "Guest",
619
+ free: "Free",
620
+ go: "Go",
621
+ plus: "Plus",
622
+ pro: "Pro",
623
+ prolite: "Pro Lite",
624
+ free_workspace: "Free (workspace)",
625
+ team: "Team",
626
+ business: "Business",
627
+ enterprise: "Enterprise",
628
+ education: "Education",
629
+ quorum: "Quorum",
630
+ k12: "K-12",
631
+ edu: "Edu",
632
+ edu_plus: "Edu Plus",
633
+ edu_pro: "Edu Pro",
634
+ };
635
+ function codexPlanLabel(planType) {
636
+ if (typeof planType !== "string" || !planType)
637
+ return null;
638
+ const known = CODEX_PLAN_LABELS[planType.toLowerCase()];
639
+ if (known)
640
+ return known;
641
+ return planType
642
+ .split(/[_\s]+/)
643
+ .filter(Boolean)
644
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
645
+ .join(" ");
646
+ }
647
+ /** Human labels for `rate_limit_reached_type.type`, from the same generated Codex client. */
648
+ const CODEX_BLOCK_REASONS = {
649
+ rate_limit_reached: "rate limit reached",
650
+ workspace_owner_credits_depleted: "workspace owner's credits are depleted",
651
+ workspace_member_credits_depleted: "workspace member credits are depleted",
652
+ workspace_owner_usage_limit_reached: "workspace owner's usage limit reached",
653
+ workspace_member_usage_limit_reached: "workspace member usage limit reached",
654
+ };
586
655
  /** Pure: Codex's `/backend-api/wham/usage` body → meters. */
587
656
  export function parseCodexQuota(body) {
588
657
  const windows = [];
@@ -604,12 +673,16 @@ export function parseCodexQuota(body) {
604
673
  pushWindow(name, extra?.rate_limit?.secondary_window);
605
674
  }
606
675
  const email = typeof body?.email === "string" ? body.email : null;
607
- const plan = planLabel(null, typeof body?.plan_type === "string" ? body.plan_type : null);
608
- return { email, plan, windows, error: windows.length ? null : "this plan does not expose limits" };
676
+ const plan = codexPlanLabel(body?.plan_type);
677
+ const reachedKind = body?.rate_limit_reached_type?.type;
678
+ const blocked = body?.rate_limit?.limit_reached
679
+ ? `blocked — ${CODEX_BLOCK_REASONS[reachedKind] ?? (typeof reachedKind === "string" ? reachedKind.replace(/_/g, " ") : "rate limit reached")}`
680
+ : null;
681
+ return { email, plan, windows, blocked, error: windows.length ? null : "this plan does not expose limits" };
609
682
  }
610
683
  async function fetchCodexQuota() {
611
684
  const fetchedAt = new Date().toISOString();
612
- const base = { provider: "codex", email: null, plan: null, windows: [], fetchedAt };
685
+ const base = { provider: "codex", email: null, plan: null, windows: [], blocked: null, fetchedAt };
613
686
  const creds = await readCodexCredentials();
614
687
  if (!creds)
615
688
  return { ...base, error: "not signed in — run `codex login`" };