claude-usage-limits 1.14.0 → 1.15.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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "usage-limits",
|
|
3
3
|
"displayName": "Usage Limits",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.15.0",
|
|
5
5
|
"description": "Puts your remaining Claude Code usage limit into Claude's context before every prompt, so it opens with what fits in the budget instead of starting work that gets cut off. Reports headroom as turns rather than percentages, prices a job before you start it, and detects your plan tier.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Ridelink",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "usage-limits",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"description": "Reports how much of your Codex usage limit is left as turns of work rather than a percentage, prices a job before you start it, and counts the other agents sharing the same budget.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Ridelink",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-usage-limits",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"description": "Puts your remaining Claude Code usage limit into Claude's context before every prompt, so it opens with what fits in the budget instead of starting work that gets cut off. Reports headroom as turns rather than percentages, prices a job before you start it, and detects your plan tier.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -387,6 +387,23 @@ is. There are two, and only one of them is the account's budget.
|
|
|
387
387
|
this account. `node scripts/usage.js --recommend` names both levers with the
|
|
388
388
|
commands.
|
|
389
389
|
|
|
390
|
+
**The commands differ by host, and the wrong one does nothing.** `/model` and
|
|
391
|
+
`/effort` do not exist in Codex. Under Codex, change the model and effort for
|
|
392
|
+
the task in hand through Codex's own controls; `node scripts/lowpower.js on
|
|
393
|
+
--host codex --effort low --model <id>` only saves defaults for *new* sessions
|
|
394
|
+
and cannot change one already running. The budget line prints whichever
|
|
395
|
+
vocabulary the host it is running in actually understands, so use the command
|
|
396
|
+
it gives you rather than the one you remember.
|
|
397
|
+
|
|
398
|
+
**This is a lever you may pull yourself, not only an emergency exit.** Use it
|
|
399
|
+
whenever the current setting is dearer than the work in front of you needs,
|
|
400
|
+
without being asked and long before any window is tight: a mechanical rename,
|
|
401
|
+
a docs pass or a mass find-and-replace does not need the model and effort a
|
|
402
|
+
hard design decision does. Drop it for that stretch, say in one line that you
|
|
403
|
+
did and why, and put it back when the work gets hard again. An agent that only
|
|
404
|
+
ever reads this as a wall notice runs every trivial turn at the top setting and
|
|
405
|
+
then wonders where the window went.
|
|
406
|
+
|
|
390
407
|
The budget line does this arithmetic for you. Once the binding window is half
|
|
391
408
|
gone it says which lever applies, and at the wall it says outright that you are
|
|
392
409
|
not out of budget and must not stop as though you were. When it does, the
|
|
@@ -548,7 +548,13 @@ function briefText(parts) {
|
|
|
548
548
|
sentences.push(
|
|
549
549
|
'The effort setting is what is spending this: ' + bits.join(', and ') +
|
|
550
550
|
'. Keep it where the work genuinely needs the thinking and drop it where it ' +
|
|
551
|
-
'does not; it changes what every turn costs, not how many you get.'
|
|
551
|
+
'does not; it changes what every turn costs, not how many you get.' +
|
|
552
|
+
// The command, in the host's own vocabulary. /effort does not exist
|
|
553
|
+
// in Codex, and naming it there is telling Codex to do nothing while
|
|
554
|
+
// believing it acted.
|
|
555
|
+
(warning.cheaper && warning.cheaper.effort
|
|
556
|
+
? ' To drop it: ' + usage.levers(usage.currentHost()).effort(warning.cheaper.effort) + '.'
|
|
557
|
+
: '')
|
|
552
558
|
);
|
|
553
559
|
}
|
|
554
560
|
}
|
|
@@ -556,7 +562,12 @@ function briefText(parts) {
|
|
|
556
562
|
// do more cheaply on this model frees it; only running a different model
|
|
557
563
|
// does, and that has to be said, because the obvious move at 90 percent is
|
|
558
564
|
// to drop the effort and keep going, which spends the same window slower.
|
|
559
|
-
|
|
565
|
+
// Suppressed when the escape line below fires: that one says the same thing
|
|
566
|
+
// and names the model to switch to, where this one only ever managed
|
|
567
|
+
// "Use /model (or ...". Two sentences making one point is a cost paid on
|
|
568
|
+
// every prompt.
|
|
569
|
+
const namesTheSwitch = parts.escape && parts.escape.kind === 'model';
|
|
570
|
+
if (parts.family && !namesTheSwitch) {
|
|
560
571
|
sentences.push(
|
|
561
572
|
'That window counts ' + parts.family + ' turns only, so lowering effort does not free it: ' +
|
|
562
573
|
'switching model does. Use /model (or scripts/lowpower.js on --model <other>) for work ' +
|
|
@@ -575,14 +586,27 @@ function briefText(parts) {
|
|
|
575
586
|
(escape.nextLabel
|
|
576
587
|
? 'After a switch the binding window would be ' + escape.nextLabel + ' at ' + escape.nextPercent + ' per cent. '
|
|
577
588
|
: '') +
|
|
578
|
-
|
|
589
|
+
// No command rather than a wrong one: the vocabulary differs by host,
|
|
590
|
+
// and "Use undefined" is worse than saying which lever it is and
|
|
591
|
+
// leaving the reader to reach for it.
|
|
592
|
+
(escape.command ? 'Use ' + escape.command + '.' : '')
|
|
579
593
|
: escape && escape.kind === 'effort'
|
|
580
594
|
? 'A model switch does not free this window - it follows the account - but effort does: ' +
|
|
581
595
|
escape.to + ' measured ' + (escape.multiple ? escape.multiple + 'x ' : '') + 'cheaper a turn than ' +
|
|
582
|
-
(escape.from || 'the current effort') + '.
|
|
596
|
+
(escape.from || 'the current effort') + '.' + (escape.command ? ' Use ' + escape.command + '.' : '')
|
|
583
597
|
: null;
|
|
598
|
+
// Not only an emergency exit. The same lever is the right one whenever the
|
|
599
|
+
// setting is dearer than the work in front of you needs - a mechanical edit
|
|
600
|
+
// does not need the model a hard design decision does. Say so, because an
|
|
601
|
+
// agent that only ever reads this as a wall notice will run every trivial
|
|
602
|
+
// turn at the top setting and then wonder where the window went.
|
|
603
|
+
const chooseText = escapeText
|
|
604
|
+
? ' You may make that change yourself, at any point and without being asked, ' +
|
|
605
|
+
'whenever the current setting is dearer than the work needs rather than only ' +
|
|
606
|
+
'when the window is nearly gone. Say in one line that you changed it and why.'
|
|
607
|
+
: '';
|
|
584
608
|
if (escapeText && parts.binding && Number.isFinite(parts.binding.percentUsed) && parts.binding.percentUsed >= HALF_SPENT) {
|
|
585
|
-
sentences.push(escapeText);
|
|
609
|
+
sentences.push(escapeText + chooseText);
|
|
586
610
|
}
|
|
587
611
|
|
|
588
612
|
// A window that is not binding can still be the expensive one to exhaust.
|
|
@@ -950,7 +974,7 @@ async function run(now, hookInput) {
|
|
|
950
974
|
othersSummary: summariseOthers(data.windows, binding && binding.key),
|
|
951
975
|
// The way out that is not stopping. Cached with the rest of the view
|
|
952
976
|
// because it is derived from the same one pass over the windows.
|
|
953
|
-
escape: usage.escapeRoute(data.windows, binding, data.effortWarning || null),
|
|
977
|
+
escape: usage.escapeRoute(data.windows, binding, data.effortWarning || null, usage.currentHost()),
|
|
954
978
|
// Every window, trimmed to the cacheable fields, so the corrected reading
|
|
955
979
|
// can be recorded for all three columns of the status line on a cache
|
|
956
980
|
// hit too. Recording the binding window alone left the other two at
|
|
@@ -2104,8 +2104,32 @@ function criticalOthers(windows, bindingKey, threshold) {
|
|
|
2104
2104
|
// changes nothing and the lever is effort instead. Either way the point is the
|
|
2105
2105
|
// same - being at the wall is not the same as being out of budget, and an agent
|
|
2106
2106
|
// that cannot tell the difference stops early and calls it caution.
|
|
2107
|
-
|
|
2107
|
+
// The commands differ by host and getting them wrong is worse than saying
|
|
2108
|
+
// nothing: /model and /effort do not exist in Codex, and telling Codex to run
|
|
2109
|
+
// them is telling it to do nothing while believing it acted. Codex changes its
|
|
2110
|
+
// own model and effort through its own controls; the script can only save
|
|
2111
|
+
// defaults for NEW sessions, which is a different promise and is stated as one.
|
|
2112
|
+
function levers(which) {
|
|
2113
|
+
// `host` is the required module here, not a parameter - shadowing it was a
|
|
2114
|
+
// ReferenceError on the constant it owns.
|
|
2115
|
+
const codex = which === host.CODEX;
|
|
2116
|
+
return {
|
|
2117
|
+
model: (family) =>
|
|
2118
|
+
codex
|
|
2119
|
+
? "Codex's own model control (the script only saves defaults for new sessions: " +
|
|
2120
|
+
'node scripts/lowpower.js on --host codex --model <id>)'
|
|
2121
|
+
: '/model ' + (family || '<another model>') + ' (or node scripts/lowpower.js on --model <id>)',
|
|
2122
|
+
effort: (level) =>
|
|
2123
|
+
codex
|
|
2124
|
+
? "Codex's own effort control for this task (node scripts/lowpower.js on --host codex --effort " +
|
|
2125
|
+
(level || '<level>') + ' saves it for new sessions and cannot change one already running)'
|
|
2126
|
+
: '/effort ' + (level || '<level>'),
|
|
2127
|
+
};
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
function escapeRoute(windows, binding, effortNote, host) {
|
|
2108
2131
|
if (!binding || binding.percentUsed === null || binding.percentUsed === undefined) return null;
|
|
2132
|
+
const lever = levers(host || currentHost());
|
|
2109
2133
|
const live = (windows || []).filter(
|
|
2110
2134
|
(w) => w && w.percentUsed !== null && w.percentUsed !== undefined && !w.stale && w.key !== binding.key
|
|
2111
2135
|
);
|
|
@@ -2133,6 +2157,7 @@ function escapeRoute(windows, binding, effortNote) {
|
|
|
2133
2157
|
nextLabel: next ? next.label || next.key : null,
|
|
2134
2158
|
nextPercent: next ? Math.round(next.percentUsed) : null,
|
|
2135
2159
|
suggest: roomier && roomier.family ? roomier.family : null,
|
|
2160
|
+
command: lever.model(roomier && roomier.family ? roomier.family : null),
|
|
2136
2161
|
};
|
|
2137
2162
|
}
|
|
2138
2163
|
|
|
@@ -2144,6 +2169,7 @@ function escapeRoute(windows, binding, effortNote) {
|
|
|
2144
2169
|
from: effortNote.effort || null,
|
|
2145
2170
|
to: effortNote.cheaper.effort,
|
|
2146
2171
|
multiple: Number.isFinite(effortNote.cheaper.multiple) ? effortNote.cheaper.multiple : null,
|
|
2172
|
+
command: lever.effort(effortNote.cheaper.effort),
|
|
2147
2173
|
};
|
|
2148
2174
|
}
|
|
2149
2175
|
return null;
|
|
@@ -3740,6 +3766,7 @@ module.exports = {
|
|
|
3740
3766
|
bindingWindow,
|
|
3741
3767
|
criticalOthers,
|
|
3742
3768
|
escapeRoute,
|
|
3769
|
+
levers,
|
|
3743
3770
|
betterCalibration,
|
|
3744
3771
|
calibrationForPlan,
|
|
3745
3772
|
stampPlan,
|