@usagefleet/cli 1.2.142 → 1.2.150
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/collector.js +11 -4
- package/dist/guard.js +2 -1
- package/dist/index.js +1 -1
- package/dist/notifier.js +6 -3
- package/dist/release.js +1 -1
- package/dist/ui.js +8 -3
- package/dist/uploader.js +20 -0
- package/package.json +1 -1
package/dist/collector.js
CHANGED
|
@@ -12,7 +12,7 @@ import { listJsonlFiles } from './scanner.js';
|
|
|
12
12
|
import { readStore, updateStore } from './store.js';
|
|
13
13
|
import { tailFile } from './tailer.js';
|
|
14
14
|
import { tilde } from './ui.js';
|
|
15
|
-
import { postLimits, uploadBatch } from './uploader.js';
|
|
15
|
+
import { fetchGroupLimits, postLimits, uploadBatch } from './uploader.js';
|
|
16
16
|
/** Only files inside a `.../.claude/projects/...` subtree are real usage logs.
|
|
17
17
|
* Desktop session roots also hold `audit.jsonl` (a full duplicate of the same
|
|
18
18
|
* uuids) and other JSONL — restricting to this subtree mirrors Claude Code and
|
|
@@ -274,8 +274,15 @@ export async function reportLimitsOnce(cfg, log = () => {
|
|
|
274
274
|
source: report.source,
|
|
275
275
|
};
|
|
276
276
|
});
|
|
277
|
-
// Local desktop notification on freshly-crossed thresholds
|
|
278
|
-
//
|
|
279
|
-
|
|
277
|
+
// Local desktop notification on freshly-crossed thresholds, judged on the
|
|
278
|
+
// device's group slice because that is the budget it is held to. Only a device
|
|
279
|
+
// without a group falls back to the account reading. No answer from the server
|
|
280
|
+
// means no notification rather than one on the wrong number.
|
|
281
|
+
const groupLimits = await fetchGroupLimits(cfg, account?.extId);
|
|
282
|
+
if (groupLimits) {
|
|
283
|
+
maybeNotify(groupLimits.group === null
|
|
284
|
+
? report
|
|
285
|
+
: { ...report, fiveHourPct: groupLimits.sessionPct, sevenDayPct: groupLimits.weeklyPct }, undefined, log);
|
|
286
|
+
}
|
|
280
287
|
return report;
|
|
281
288
|
}
|
package/dist/guard.js
CHANGED
|
@@ -15,7 +15,8 @@ export function blockMessage(view) {
|
|
|
15
15
|
}
|
|
16
16
|
const window = view.blockedWindow === 'weekly' ? 'weekly' : '5h';
|
|
17
17
|
const limit = view.blockedModel ? `${view.blockedModel} ${window}` : window;
|
|
18
|
-
const
|
|
18
|
+
const s = (view.blockedPct ?? 100).toFixed(1);
|
|
19
|
+
const pct = s.endsWith('.0') ? s.slice(0, -2) : s;
|
|
19
20
|
const group = view.group ? `"${view.group}"` : 'this group';
|
|
20
21
|
const until = view.blockedUntil ? new Date(view.blockedUntil) : null;
|
|
21
22
|
const resets = until && !Number.isNaN(until.getTime())
|
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ function flag(name) {
|
|
|
29
29
|
}
|
|
30
30
|
return undefined;
|
|
31
31
|
}
|
|
32
|
-
/** "5h ██░░░░░░░░ 2% · weekly ████░░░░░░ 13%" — the shared limits line.
|
|
32
|
+
/** "5h ██░░░░░░░░ 2.4% · weekly ████░░░░░░ 13.0%" — the shared limits line.
|
|
33
33
|
* Bars are plain characters, so they survive a service log as well as a TTY. */
|
|
34
34
|
function limitsSummary(limits) {
|
|
35
35
|
const models = limits.modelLimits.map(m => ` · ${m.model}(${m.window}) ${bar(m.pct, 6)} ${pct(m.pct)}`).join('');
|
package/dist/notifier.js
CHANGED
|
@@ -80,9 +80,12 @@ export function maybeNotify(report, cfg = loadNotifyConfig(), log = () => {
|
|
|
80
80
|
const state = readStore(path).notify;
|
|
81
81
|
const five = evaluateWindow(state.fiveHour, report.fiveHourPct, report.fiveHourResetsAt, cfg.thresholds);
|
|
82
82
|
const seven = evaluateWindow(state.sevenDay, report.sevenDayPct, report.sevenDayResetsAt, cfg.thresholds);
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const fmt = (n) => {
|
|
84
|
+
const s = n.toFixed(1);
|
|
85
|
+
return s.endsWith('.0') ? s.slice(0, -2) : s;
|
|
86
|
+
};
|
|
87
|
+
const fivePct = fmt(report.fiveHourPct ?? 0);
|
|
88
|
+
const sevenPct = fmt(report.sevenDayPct ?? 0);
|
|
86
89
|
if (five.fire != null) {
|
|
87
90
|
sendNotification('Claude usage · 5-hour limit', `${fivePct}% of your 5-hour limit used${resetSuffix(report.fiveHourResetsAt)}.`, { urgency: urgencyFor(five.fire) });
|
|
88
91
|
log('ok', `notified · 5h at ${fivePct}% · crossed ${five.fire}%`);
|
package/dist/release.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by .github/workflows/release.yml.
|
|
2
|
-
export const RELEASE_VERSION = "1.2.
|
|
2
|
+
export const RELEASE_VERSION = "1.2.150";
|
package/dist/ui.js
CHANGED
|
@@ -86,10 +86,15 @@ export function line(glyph, text) {
|
|
|
86
86
|
}
|
|
87
87
|
/** Neutral stream glyph, for messages that are neither good nor bad news. */
|
|
88
88
|
export const note = dim('·');
|
|
89
|
-
/** Percentage
|
|
90
|
-
*
|
|
89
|
+
/** Percentage with one decimal, fixed-width so successive log lines line up
|
|
90
|
+
* (wide enough for "100.0%"). */
|
|
91
91
|
export function pct(value) {
|
|
92
|
-
|
|
92
|
+
if (value === null) {
|
|
93
|
+
return '?'.padStart(6);
|
|
94
|
+
}
|
|
95
|
+
const s = value.toFixed(1);
|
|
96
|
+
const str = s.endsWith('.0') ? s.slice(0, -2) : s;
|
|
97
|
+
return `${str}%`.padStart(6);
|
|
93
98
|
}
|
|
94
99
|
/** Usage bar, coloured by how close the window is to its limit.
|
|
95
100
|
* Unknown usage renders as an empty bar rather than a missing column. */
|
package/dist/uploader.js
CHANGED
|
@@ -101,3 +101,23 @@ export async function postLimits(report, cfg) {
|
|
|
101
101
|
return 'transient';
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
+
/** Null when the server cannot answer (offline, rejected, older than this field). */
|
|
105
|
+
export async function fetchGroupLimits(cfg, accountExtId) {
|
|
106
|
+
try {
|
|
107
|
+
const res = await fetch(`${ENDPOINT}/api/v1/limits`, {
|
|
108
|
+
headers: { 'x-api-key': tokenFor(cfg, accountExtId) },
|
|
109
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
110
|
+
});
|
|
111
|
+
if (!res.ok) {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const body = (await res.json());
|
|
115
|
+
if (typeof body?.sessionPct !== 'number' || typeof body.weeklyPct !== 'number') {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
return { group: body.group ?? null, sessionPct: body.sessionPct, weeklyPct: body.weeklyPct };
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
}
|