openlimiter 0.1.0 → 0.4.0
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/cli.d.ts +11 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +237 -42
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +112 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +253 -8
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/ingest.d.ts +24 -1
- package/dist/ingest.d.ts.map +1 -1
- package/dist/ingest.js +34 -0
- package/dist/ingest.js.map +1 -1
- package/dist/render.d.ts +138 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +357 -0
- package/dist/render.js.map +1 -0
- package/dist/serve.d.ts +36 -3
- package/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +220 -128
- package/dist/serve.js.map +1 -1
- package/dist/statusline.d.ts +91 -0
- package/dist/statusline.d.ts.map +1 -0
- package/dist/statusline.js +328 -0
- package/dist/statusline.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { PROVIDER_CODES, floorFixed, freshness } from "@openlimiter/core";
|
|
2
|
+
import { STATUSLINE_BAR_SEGMENTS, meterBar } from "./render.js";
|
|
3
|
+
/**
|
|
4
|
+
* Statusline layout, version two.
|
|
5
|
+
*
|
|
6
|
+
* Version one was one plain line of provider names and percentages, and every
|
|
7
|
+
* person who wanted to see pressure at a glance ended up drawing their own bar
|
|
8
|
+
* around it. This module draws it instead: one compact cell per provider,
|
|
9
|
+
* `NAME bar percent`, with the overall reason code leading the row, and a
|
|
10
|
+
* second row when the first one runs out of columns.
|
|
11
|
+
*
|
|
12
|
+
* The old line is still here. `bars false` returns it byte for byte through the
|
|
13
|
+
* adapter that has always produced it, because a format somebody wrote a script
|
|
14
|
+
* against is a promise, and the way to change a promise is to leave the old one
|
|
15
|
+
* reachable.
|
|
16
|
+
*
|
|
17
|
+
* Nothing in this file decides a number. Percentages, freshness, the reason
|
|
18
|
+
* code and the recommendation all arrive already decided by the engine; this is
|
|
19
|
+
* ordering, measuring and wrapping.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Which half of the row a provider belongs in.
|
|
23
|
+
*
|
|
24
|
+
* A subscription is a window that refills on a clock, so its percentage is
|
|
25
|
+
* about how much of today is left. A credit or API balance is money, so its
|
|
26
|
+
* percentage is about how much of the plan is left forever. Reading the two
|
|
27
|
+
* kinds in one undifferentiated row invites treating a spent balance like a
|
|
28
|
+
* window that will come back, so the subscriptions come first and the priced
|
|
29
|
+
* meters sit at the end where they read as a different kind of fact.
|
|
30
|
+
*
|
|
31
|
+
* The table is exhaustive over the provider codes on purpose: a provider added
|
|
32
|
+
* to the engine will not compile until somebody says which half it is in.
|
|
33
|
+
*/
|
|
34
|
+
const PROVIDER_CLASS = {
|
|
35
|
+
CLAUDE: "subscription",
|
|
36
|
+
CODEX: "subscription",
|
|
37
|
+
ANTIGRAVITY: "subscription",
|
|
38
|
+
OPENCODE: "subscription",
|
|
39
|
+
MANUAL: "subscription",
|
|
40
|
+
OPENROUTER: "api"
|
|
41
|
+
};
|
|
42
|
+
export const DEFAULT_PROVIDER_ORDER = [
|
|
43
|
+
...PROVIDER_CODES.filter((code) => PROVIDER_CLASS[code] === "subscription"),
|
|
44
|
+
...PROVIDER_CODES.filter((code) => PROVIDER_CLASS[code] === "api")
|
|
45
|
+
];
|
|
46
|
+
const providerCodes = new Set(PROVIDER_CODES);
|
|
47
|
+
/**
|
|
48
|
+
* The order the configured ids ask for, completed by the built in order.
|
|
49
|
+
*
|
|
50
|
+
* An id this version does not know, and an id named twice, are both dropped
|
|
51
|
+
* rather than rejected. This runs on every redraw of somebody else's status
|
|
52
|
+
* row; a stale provider id left in a configuration file is not a reason to
|
|
53
|
+
* stop drawing the providers that are still there.
|
|
54
|
+
*/
|
|
55
|
+
export function resolveProviderOrder(configured) {
|
|
56
|
+
const listed = [];
|
|
57
|
+
for (const id of configured) {
|
|
58
|
+
const code = id.toUpperCase();
|
|
59
|
+
if (!providerCodes.has(code))
|
|
60
|
+
continue;
|
|
61
|
+
const provider = code;
|
|
62
|
+
if (listed.includes(provider))
|
|
63
|
+
continue;
|
|
64
|
+
listed.push(provider);
|
|
65
|
+
}
|
|
66
|
+
return [
|
|
67
|
+
...listed,
|
|
68
|
+
...DEFAULT_PROVIDER_ORDER.filter((code) => !listed.includes(code))
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
/** Shortest window first, then money, then anything unrecognised. */
|
|
72
|
+
const METER_CLASS_RANK = {
|
|
73
|
+
session: 0,
|
|
74
|
+
daily: 1,
|
|
75
|
+
weekly: 2,
|
|
76
|
+
monthly: 3,
|
|
77
|
+
credits: 4,
|
|
78
|
+
other: 5
|
|
79
|
+
};
|
|
80
|
+
const SIX_HOURS = 21_600;
|
|
81
|
+
const ONE_DAY = 86_400;
|
|
82
|
+
const SEVEN_DAYS = 604_800;
|
|
83
|
+
const THIRTY_ONE_DAYS = 2_678_400;
|
|
84
|
+
/**
|
|
85
|
+
* The classes a meter name maps to when its window states no duration.
|
|
86
|
+
*
|
|
87
|
+
* Only names this project already emits, plus the obvious synonyms a hand
|
|
88
|
+
* written manual document reaches for. Anything else is `other` and sorts
|
|
89
|
+
* last, which is the honest answer: an unrecognised name is not evidence of a
|
|
90
|
+
* short window.
|
|
91
|
+
*/
|
|
92
|
+
const METER_NAME_CLASS = {
|
|
93
|
+
SESSION: "session",
|
|
94
|
+
PRIMARY: "session",
|
|
95
|
+
FIVE_HOUR: "session",
|
|
96
|
+
HOURLY: "session",
|
|
97
|
+
DAILY: "daily",
|
|
98
|
+
DAY: "daily",
|
|
99
|
+
WEEKLY: "weekly",
|
|
100
|
+
WEEK: "weekly",
|
|
101
|
+
SEVEN_DAY: "weekly",
|
|
102
|
+
MONTHLY: "monthly",
|
|
103
|
+
MONTH: "monthly",
|
|
104
|
+
CREDITS: "credits",
|
|
105
|
+
BALANCE: "credits"
|
|
106
|
+
};
|
|
107
|
+
/**
|
|
108
|
+
* Which kind of window a reading measures.
|
|
109
|
+
*
|
|
110
|
+
* The window's own duration decides it wherever a connector states one,
|
|
111
|
+
* because a duration is a fact and a name is a label. The name table is the
|
|
112
|
+
* fallback for the connectors that state a window kind and no length.
|
|
113
|
+
*/
|
|
114
|
+
export function meterClass(snapshot) {
|
|
115
|
+
if (snapshot.unit === "CREDITS" || snapshot.window.kind === "lifetime") {
|
|
116
|
+
return "credits";
|
|
117
|
+
}
|
|
118
|
+
const duration = snapshot.window.durationSeconds;
|
|
119
|
+
if (duration !== undefined) {
|
|
120
|
+
if (duration <= SIX_HOURS)
|
|
121
|
+
return "session";
|
|
122
|
+
if (duration <= ONE_DAY)
|
|
123
|
+
return "daily";
|
|
124
|
+
if (duration <= SEVEN_DAYS)
|
|
125
|
+
return "weekly";
|
|
126
|
+
if (duration <= THIRTY_ONE_DAYS)
|
|
127
|
+
return "monthly";
|
|
128
|
+
return "other";
|
|
129
|
+
}
|
|
130
|
+
return METER_NAME_CLASS[snapshot.meter] ?? "other";
|
|
131
|
+
}
|
|
132
|
+
/** Two spaces between cells, so a reader can tell one cell from the next. */
|
|
133
|
+
export const CELL_GAP = " ";
|
|
134
|
+
function buildCell(label, snapshot, state, color, wide) {
|
|
135
|
+
const percent = floorFixed(snapshot.value, 1) + "%";
|
|
136
|
+
const bar = (paint) => meterBar(snapshot.value, state, paint, STATUSLINE_BAR_SEGMENTS, wide);
|
|
137
|
+
return {
|
|
138
|
+
plain: label + " " + bar(false) + " " + percent,
|
|
139
|
+
painted: label + " " + bar(color) + " " + percent,
|
|
140
|
+
percent: snapshot.value
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function readingsFor(snapshots, provider, now) {
|
|
144
|
+
return snapshots
|
|
145
|
+
.filter((snapshot) => snapshot.provider === provider && snapshot.unit === "PERCENT")
|
|
146
|
+
.map((snapshot) => ({
|
|
147
|
+
snapshot,
|
|
148
|
+
state: freshness(snapshot.observedAt, snapshot.expiresAt, now)
|
|
149
|
+
}))
|
|
150
|
+
.filter((reading) => reading.state !== "unknown")
|
|
151
|
+
.sort((left, right) => {
|
|
152
|
+
const rank = METER_CLASS_RANK[meterClass(left.snapshot)] -
|
|
153
|
+
METER_CLASS_RANK[meterClass(right.snapshot)];
|
|
154
|
+
if (rank !== 0)
|
|
155
|
+
return rank;
|
|
156
|
+
return left.snapshot.meter < right.snapshot.meter ? -1 : 1;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* One cell per provider, or one per meter.
|
|
161
|
+
*
|
|
162
|
+
* The filter is the same one the advice policy uses, so the cells and the
|
|
163
|
+
* reason code leading them are always describing the same set of readings. A
|
|
164
|
+
* provider with several meters shows its worst one, because a status row exists
|
|
165
|
+
* to tell you what is about to stop you, and the meter closest to its cap is
|
|
166
|
+
* that. The full set is one `openlimiter snapshot` away, and `meters all` puts
|
|
167
|
+
* it back in the row for anyone who wants it there.
|
|
168
|
+
*
|
|
169
|
+
* `wide` is the terminal's 256 colour claim, handed straight to the shared bar
|
|
170
|
+
* so a statusline cell and a table row draw the same reading in the same band
|
|
171
|
+
* colour. Left off, the bar reads the environment for itself.
|
|
172
|
+
*/
|
|
173
|
+
export function statuslineCells(snapshots, now, order, meters, color, wide) {
|
|
174
|
+
const cells = [];
|
|
175
|
+
for (const provider of order) {
|
|
176
|
+
const readings = readingsFor(snapshots, provider, now);
|
|
177
|
+
if (readings.length === 0)
|
|
178
|
+
continue;
|
|
179
|
+
if (meters === "all") {
|
|
180
|
+
for (const reading of readings) {
|
|
181
|
+
cells.push(buildCell(provider + ":" + reading.snapshot.meter, reading.snapshot, reading.state, color, wide));
|
|
182
|
+
}
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
let worst = readings[0];
|
|
186
|
+
for (const reading of readings.slice(1)) {
|
|
187
|
+
if (reading.snapshot.value > worst.snapshot.value)
|
|
188
|
+
worst = reading;
|
|
189
|
+
}
|
|
190
|
+
cells.push(buildCell(provider, worst.snapshot, worst.state, color, wide));
|
|
191
|
+
}
|
|
192
|
+
return cells;
|
|
193
|
+
}
|
|
194
|
+
/* ------------------------------------------------------------------ layout */
|
|
195
|
+
/**
|
|
196
|
+
* Everything that is not a cell.
|
|
197
|
+
*
|
|
198
|
+
* The reason code, the recommendation and the unknown list are the same three
|
|
199
|
+
* fields the 0.1.0 line carried and they carry the same words, moved to the
|
|
200
|
+
* front so that the row can end wherever the cells end. They are never wrapped
|
|
201
|
+
* and never dropped: a row of bars with no verdict in front of it is a picture,
|
|
202
|
+
* not a status.
|
|
203
|
+
*/
|
|
204
|
+
export function statuslineHead(advice) {
|
|
205
|
+
const recommendation = advice.recommendation.code === "PREFER"
|
|
206
|
+
? " PREFER " + advice.recommendation.provider
|
|
207
|
+
: " NONE";
|
|
208
|
+
const unknown = advice.unknownProviders.length === 0
|
|
209
|
+
? ""
|
|
210
|
+
: " UNKNOWN " + advice.unknownProviders.join(",");
|
|
211
|
+
return "OpenLimiter " + advice.reason + recommendation + unknown;
|
|
212
|
+
}
|
|
213
|
+
function moreCell(dropped) {
|
|
214
|
+
const text = "+" + String(dropped) + " more";
|
|
215
|
+
return { plain: text, painted: text, percent: Number.NEGATIVE_INFINITY };
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Fill the rows left to right and report where it got to.
|
|
219
|
+
*
|
|
220
|
+
* A cell is placed whole or not at all, so the break always lands between two
|
|
221
|
+
* cells. Nothing is ever cut in half, because half a bar reads as a reading and
|
|
222
|
+
* is not one.
|
|
223
|
+
*/
|
|
224
|
+
function packed(head, cells, width, rows) {
|
|
225
|
+
const laid = [];
|
|
226
|
+
let index = 0;
|
|
227
|
+
for (let row = 0; row < rows; row += 1) {
|
|
228
|
+
const current = [];
|
|
229
|
+
let used = row === 0 ? head.length : 0;
|
|
230
|
+
while (index < cells.length) {
|
|
231
|
+
const cell = cells[index];
|
|
232
|
+
const needed = used === 0
|
|
233
|
+
? cell.plain.length
|
|
234
|
+
: used + CELL_GAP.length + cell.plain.length;
|
|
235
|
+
if (needed > width)
|
|
236
|
+
break;
|
|
237
|
+
used = needed;
|
|
238
|
+
current.push(cell);
|
|
239
|
+
index += 1;
|
|
240
|
+
}
|
|
241
|
+
laid.push(current);
|
|
242
|
+
}
|
|
243
|
+
return laid;
|
|
244
|
+
}
|
|
245
|
+
function fittedCount(rows) {
|
|
246
|
+
return rows.reduce((total, row) => total + row.length, 0);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* The worst cells, restored to display order.
|
|
250
|
+
*
|
|
251
|
+
* When the row cannot hold everything, what it drops has to be the readings
|
|
252
|
+
* that matter least, and the reading that matters least is the one furthest
|
|
253
|
+
* from its cap. Ties keep display order, so the choice is stable between
|
|
254
|
+
* redraws of the same data.
|
|
255
|
+
*/
|
|
256
|
+
function worstCells(cells, keep) {
|
|
257
|
+
return cells
|
|
258
|
+
.map((cell, index) => ({ cell, index }))
|
|
259
|
+
.sort((left, right) => right.cell.percent - left.cell.percent || left.index - right.index)
|
|
260
|
+
.slice(0, keep)
|
|
261
|
+
.sort((left, right) => left.index - right.index)
|
|
262
|
+
.map((entry) => entry.cell);
|
|
263
|
+
}
|
|
264
|
+
function paintRows(head, rows) {
|
|
265
|
+
const lines = [];
|
|
266
|
+
rows.forEach((row, index) => {
|
|
267
|
+
const body = row.map((cell) => cell.painted).join(CELL_GAP);
|
|
268
|
+
if (index === 0) {
|
|
269
|
+
lines.push(body === "" ? head : head + CELL_GAP + body);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (body !== "")
|
|
273
|
+
lines.push(body);
|
|
274
|
+
});
|
|
275
|
+
return lines.join("\n");
|
|
276
|
+
}
|
|
277
|
+
/** What the statusline says when it has nothing bounded to say. */
|
|
278
|
+
export const STATUSLINE_UNKNOWN = "OpenLimiter UNKNOWN";
|
|
279
|
+
/**
|
|
280
|
+
* Draw the whole line, stacking it rather than truncating it.
|
|
281
|
+
*
|
|
282
|
+
* The budget is a budget, not a terminal measurement: nothing here asks the
|
|
283
|
+
* operating system how wide the window is, because a statusline host runs this
|
|
284
|
+
* command with no terminal attached and the answer would be an invention. The
|
|
285
|
+
* number in the configuration is the number that is honoured.
|
|
286
|
+
*/
|
|
287
|
+
export function renderStatuslineLayout(input) {
|
|
288
|
+
const { advice, config } = input;
|
|
289
|
+
if (!advice.inject || advice.reason === "UNKNOWN")
|
|
290
|
+
return STATUSLINE_UNKNOWN;
|
|
291
|
+
const cells = statuslineCells(input.snapshots, input.now, resolveProviderOrder(config.order), config.meters, input.color, input.wide);
|
|
292
|
+
if (cells.length === 0)
|
|
293
|
+
return STATUSLINE_UNKNOWN;
|
|
294
|
+
const head = statuslineHead(advice);
|
|
295
|
+
const whole = packed(head, cells, config.width, config.rows);
|
|
296
|
+
if (fittedCount(whole) === cells.length)
|
|
297
|
+
return paintRows(head, whole);
|
|
298
|
+
/*
|
|
299
|
+
* Something has to go. Give up one cell at a time, worst kept first, until
|
|
300
|
+
* what is left plus the count of what was dropped fits inside the rows. The
|
|
301
|
+
* search starts at the number that already fitted, which is an upper bound,
|
|
302
|
+
* and it is bounded below by zero, which is the row with only a head on it.
|
|
303
|
+
*/
|
|
304
|
+
for (let keep = fittedCount(whole); keep >= 0; keep -= 1) {
|
|
305
|
+
const shown = [...worstCells(cells, keep), moreCell(cells.length - keep)];
|
|
306
|
+
const attempt = packed(head, shown, config.width, config.rows);
|
|
307
|
+
if (fittedCount(attempt) === shown.length)
|
|
308
|
+
return paintRows(head, attempt);
|
|
309
|
+
}
|
|
310
|
+
return head;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Whether this render may paint.
|
|
314
|
+
*
|
|
315
|
+
* `NO_COLOR` wins over every setting, including `always`. It is the one
|
|
316
|
+
* convention a person can set once, for every tool on the machine, and a
|
|
317
|
+
* configuration file inside one tool is not the place to overrule it.
|
|
318
|
+
*/
|
|
319
|
+
export function statuslineColor(setting, environment, automatic) {
|
|
320
|
+
if (environment["NO_COLOR"] !== undefined)
|
|
321
|
+
return false;
|
|
322
|
+
if (setting === "never")
|
|
323
|
+
return false;
|
|
324
|
+
if (setting === "always")
|
|
325
|
+
return true;
|
|
326
|
+
return automatic;
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=statusline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statusline.js","sourceRoot":"","sources":["../src/statusline.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openlimiter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "A local command line meter for AI quota, usage, and reset times.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"NOTICE"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@openlimiter/adapters": "0.
|
|
26
|
-
"@openlimiter/
|
|
27
|
-
"@openlimiter/
|
|
25
|
+
"@openlimiter/adapters": "0.4.0",
|
|
26
|
+
"@openlimiter/connectors": "0.4.0",
|
|
27
|
+
"@openlimiter/core": "0.4.0"
|
|
28
28
|
},
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|