claude-usage-limits 1.41.0 → 1.41.1
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.41.
|
|
4
|
+
"version": "1.41.1",
|
|
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.41.
|
|
3
|
+
"version": "1.41.1",
|
|
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.41.
|
|
3
|
+
"version": "1.41.1",
|
|
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",
|
|
@@ -957,12 +957,57 @@ function taskAction(action) {
|
|
|
957
957
|
return '"' + action.execute + '" ' + action.argument;
|
|
958
958
|
}
|
|
959
959
|
|
|
960
|
+
// THE SCHEDULER SWITCH.
|
|
961
|
+
//
|
|
962
|
+
// Task Scheduler is machine-wide. A fake HOME, a fake CLAUDE_CONFIG_DIR or a
|
|
963
|
+
// test's temp folder changes where the relay keeps its records, and nothing at
|
|
964
|
+
// all about where its wakes go. Found 2026-09-25 23:55: an adversarial run of
|
|
965
|
+
// the relay hook with HOME and USERPROFILE pointed at sandbox folders
|
|
966
|
+
// registered 8 REAL tasks, two of them for the real session id, which would
|
|
967
|
+
// have resumed a second copy of the live conversation. So the real scheduler
|
|
968
|
+
// is only touched when nothing says this is a test or a sandbox:
|
|
969
|
+
// USAGE_LIMITS_SCHEDULER=real always real (the escape hatch)
|
|
970
|
+
// USAGE_LIMITS_SCHEDULER=dry-run never real
|
|
971
|
+
// NODE_TEST_CONTEXT set by `node --test` for every test file,
|
|
972
|
+
// and inherited by what a test spawns
|
|
973
|
+
// a redirected home os.homedir() is not the account's own
|
|
974
|
+
// A dry run registers nothing, cancels nothing, and says so in its answer.
|
|
975
|
+
function sandboxedHome() {
|
|
976
|
+
let real;
|
|
977
|
+
try {
|
|
978
|
+
real = os.userInfo().homedir;
|
|
979
|
+
} catch (err) {
|
|
980
|
+
return false;
|
|
981
|
+
}
|
|
982
|
+
if (!real) return false;
|
|
983
|
+
const norm = (p) => {
|
|
984
|
+
const resolved = path.resolve(p).replace(/[\\/]+$/, '');
|
|
985
|
+
return process.platform === 'linux' ? resolved : resolved.toLowerCase();
|
|
986
|
+
};
|
|
987
|
+
return norm(real) !== norm(os.homedir());
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
function schedulerMode() {
|
|
991
|
+
const said = String(process.env.USAGE_LIMITS_SCHEDULER || '').trim().toLowerCase();
|
|
992
|
+
if (said === 'real') return { dry: false, why: null };
|
|
993
|
+
if (said === 'dry-run' || said === 'dry') return { dry: true, why: 'USAGE_LIMITS_SCHEDULER=' + said };
|
|
994
|
+
if (process.env.NODE_TEST_CONTEXT) return { dry: true, why: 'running under node --test' };
|
|
995
|
+
if (sandboxedHome()) return { dry: true, why: 'the home folder is redirected to ' + os.homedir() };
|
|
996
|
+
return { dry: false, why: null };
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
function dryRun(mode) {
|
|
1000
|
+
return { ok: true, how: 'dry-run', dry: true, warning: 'no wake was registered (' + mode.why + ')' };
|
|
1001
|
+
}
|
|
1002
|
+
|
|
960
1003
|
function scheduleWindows(when, argv, name, cwd, deadline) {
|
|
961
1004
|
// No time left is a plain refusal, not a hung hook - and not a launcher
|
|
962
1005
|
// written for a task that is never registered.
|
|
963
1006
|
if (Number.isFinite(deadline) && remainingMs(deadline, PS_ROUTE_MS) < 1500) {
|
|
964
1007
|
return { ok: false, error: 'no time left in this hook to register the wake; it will arm on the next prompt' };
|
|
965
1008
|
}
|
|
1009
|
+
const mode = schedulerMode();
|
|
1010
|
+
if (mode.dry) return dryRun(mode);
|
|
966
1011
|
let lastVerifyError = null;
|
|
967
1012
|
const date = new Date(when);
|
|
968
1013
|
const stamp =
|
|
@@ -1074,6 +1119,8 @@ function scheduleWindows(when, argv, name, cwd, deadline) {
|
|
|
1074
1119
|
}
|
|
1075
1120
|
|
|
1076
1121
|
function schedulePosix(when, argv, name, cwd, deadline) {
|
|
1122
|
+
const mode = schedulerMode();
|
|
1123
|
+
if (mode.dry) return dryRun(mode);
|
|
1077
1124
|
const seconds = Math.max(60, Math.round((when - Date.now()) / 1000));
|
|
1078
1125
|
// `at` is the right tool and is absent on most desktops now. A detached
|
|
1079
1126
|
// sleeper is second best: it survives the terminal closing, but not a
|
|
@@ -1121,6 +1168,8 @@ function schedule(when, argv, name, cwd, deadline) {
|
|
|
1121
1168
|
}
|
|
1122
1169
|
|
|
1123
1170
|
function cancelSchedule(name) {
|
|
1171
|
+
// A dry run never touches a task, including one a real run registered.
|
|
1172
|
+
if (schedulerMode().dry) return true;
|
|
1124
1173
|
if (process.platform === 'win32') {
|
|
1125
1174
|
const run = spawnSync(
|
|
1126
1175
|
'powershell.exe',
|
|
@@ -1915,7 +1964,7 @@ if (require.main === module) {
|
|
|
1915
1964
|
);
|
|
1916
1965
|
}
|
|
1917
1966
|
|
|
1918
|
-
module.exports = { workWithContinuation, reapLost, hiddenAction, headlessAvailable, HEADLESS_HOST, HIDDEN_HOST, BUGCHECK_LINE,
|
|
1967
|
+
module.exports = { workWithContinuation, reapLost, schedulerMode, sandboxedHome, hiddenAction, headlessAvailable, HEADLESS_HOST, HIDDEN_HOST, BUGCHECK_LINE,
|
|
1919
1968
|
taskAction, wakeLauncherFile, wakeLauncherScript, writeWakeLauncher, sweepWakeLaunchers, batchArg, describeSpawn, PS_ROUTE_MS, SCHTASKS_MS,
|
|
1920
1969
|
records, armedFor, putRecord, dropRecord, preflightPrompts, claudeJsonFile, projectKeys, isHome, launchDirFor, applySetting, settingIs,
|
|
1921
1970
|
DEFAULTS,
|