@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/README.md +28 -1
- package/dist/board/board.css +1 -1
- package/dist/board/board.js +2 -2
- package/dist/main.js +154 -1
- package/dist/main.js.map +1 -1
- package/dist/native/darwin-arm64/rudder-native +0 -0
- package/dist/native/darwin-x64/rudder-native +0 -0
- package/dist/native/linux-x64/rudder-native +0 -0
- package/dist/report.d.ts +74 -0
- package/dist/report.js +412 -0
- package/dist/report.js.map +1 -0
- package/dist/usage.d.ts +9 -1
- package/dist/usage.js +79 -6
- package/dist/usage.js.map +1 -1
- package/package.json +1 -1
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
|
|
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 =
|
|
608
|
-
|
|
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`" };
|