claude-use 11.14.0 → 11.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.
package/dist/cli.cjs CHANGED
@@ -34093,7 +34093,7 @@ var init_package = __esm({
34093
34093
  "package.json"() {
34094
34094
  package_default = {
34095
34095
  name: "claude-use",
34096
- version: "11.14.0",
34096
+ version: "11.15.0",
34097
34097
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
34098
34098
  license: "MIT",
34099
34099
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -44666,7 +44666,7 @@ var require_client = __commonJS({
44666
44666
  "use strict";
44667
44667
  var assert2 = require("node:assert");
44668
44668
  var net5 = require("node:net");
44669
- var http8 = require("node:http");
44669
+ var http9 = require("node:http");
44670
44670
  var util2 = require_util2();
44671
44671
  var { ClientStats } = require_stats();
44672
44672
  var { channels } = require_diagnostics();
@@ -44724,7 +44724,7 @@ var require_client = __commonJS({
44724
44724
  var connectH1 = require_client_h1();
44725
44725
  var connectH2 = require_client_h2();
44726
44726
  var kClosedResolve = /* @__PURE__ */ Symbol("kClosedResolve");
44727
- var getDefaultNodeMaxHeaderSize = http8 && http8.maxHeaderSize && Number.isInteger(http8.maxHeaderSize) && http8.maxHeaderSize > 0 ? () => http8.maxHeaderSize : () => {
44727
+ var getDefaultNodeMaxHeaderSize = http9 && http9.maxHeaderSize && Number.isInteger(http9.maxHeaderSize) && http9.maxHeaderSize > 0 ? () => http9.maxHeaderSize : () => {
44728
44728
  throw new InvalidArgumentError2("http module not available or http.maxHeaderSize invalid");
44729
44729
  };
44730
44730
  var noop = () => {
@@ -62424,9 +62424,9 @@ function expectedSha256(sidecar) {
62424
62424
  const first = sidecar.trim().split(/\s+/)[0];
62425
62425
  return first === "" ? void 0 : first;
62426
62426
  }
62427
- async function mustDownload(http8, url2) {
62427
+ async function mustDownload(http9, url2) {
62428
62428
  try {
62429
- return await http8.download(url2);
62429
+ return await http9.download(url2);
62430
62430
  } catch (error63) {
62431
62431
  throw new UpdateDownloadError(`could not download ${url2}: ${error63 instanceof Error ? error63.message : String(error63)}`);
62432
62432
  }
@@ -64124,8 +64124,8 @@ function zaiWindow(limit) {
64124
64124
  ...limit.remaining === void 0 ? {} : { remaining: limit.remaining }
64125
64125
  };
64126
64126
  }
64127
- async function openRouterGet(url2, schema, apiKey, http8, signal) {
64128
- const response = await http8(url2, { authorization: `Bearer ${apiKey}`, accept: "application/json" }, signal);
64127
+ async function openRouterGet(url2, schema, apiKey, http9, signal) {
64128
+ const response = await http9(url2, { authorization: `Bearer ${apiKey}`, accept: "application/json" }, signal);
64129
64129
  if (response.status === HTTP_FORBIDDEN) {
64130
64130
  return "forbidden";
64131
64131
  }
@@ -64201,8 +64201,8 @@ var init_providerQuota = __esm({
64201
64201
  zaiQuotaAdapter = {
64202
64202
  source: ZAI_SOURCE,
64203
64203
  matches: (baseUrl) => URL.canParse(baseUrl) && new URL(baseUrl).hostname === ZAI_HOST,
64204
- fetch: async (apiKey, http8, signal, nowMs) => {
64205
- const response = await http8(ZAI_QUOTA_URL, { authorization: apiKey, accept: "application/json" }, signal);
64204
+ fetch: async (apiKey, http9, signal, nowMs) => {
64205
+ const response = await http9(ZAI_QUOTA_URL, { authorization: apiKey, accept: "application/json" }, signal);
64206
64206
  if (response.status !== HTTP_OK) {
64207
64207
  throw new ProviderQuotaError(ZAI_SOURCE, `answered HTTP ${String(response.status)}`);
64208
64208
  }
@@ -64246,12 +64246,12 @@ var init_providerQuota = __esm({
64246
64246
  openRouterQuotaAdapter = {
64247
64247
  source: OPENROUTER_SOURCE,
64248
64248
  matches: (baseUrl) => URL.canParse(baseUrl) && new URL(baseUrl).hostname === OPENROUTER_HOST,
64249
- fetch: async (apiKey, http8, signal, nowMs) => {
64250
- const key = await openRouterGet(OPENROUTER_KEY_URL, OpenRouterKeySchema, apiKey, http8, signal);
64249
+ fetch: async (apiKey, http9, signal, nowMs) => {
64250
+ const key = await openRouterGet(OPENROUTER_KEY_URL, OpenRouterKeySchema, apiKey, http9, signal);
64251
64251
  if (key === "forbidden") {
64252
64252
  throw new ProviderQuotaError(OPENROUTER_SOURCE, "/api/v1/key refused the key (HTTP 403)");
64253
64253
  }
64254
- const credits = await openRouterGet(OPENROUTER_CREDITS_URL, OpenRouterCreditsSchema, apiKey, http8, signal);
64254
+ const credits = await openRouterGet(OPENROUTER_CREDITS_URL, OpenRouterCreditsSchema, apiKey, http9, signal);
64255
64255
  const { limit, limit_remaining: limitRemaining, limit_reset: limitReset, free_model_daily_requests: free, is_free_tier: isFreeTier } = key.data;
64256
64256
  const windows = [];
64257
64257
  if (limit !== null && limit > 0) {
@@ -64302,9 +64302,9 @@ var init_providerQuota = __esm({
64302
64302
  antigravityQuotaAdapter = {
64303
64303
  source: ANTIGRAVITY_SOURCE,
64304
64304
  matches: (baseUrl) => URL.canParse(baseUrl) && new URL(baseUrl).hostname === ANTIGRAVITY_HOST,
64305
- fetch: async (apiKey, http8, signal, nowMs) => {
64305
+ fetch: async (apiKey, http9, signal, nowMs) => {
64306
64306
  const headers = { authorization: `Bearer ${apiKey}`, "content-type": "application/json", "user-agent": CCPA_USER_AGENT };
64307
- const summaryResponse = await http8(ANTIGRAVITY_QUOTA_URL, headers, signal, { method: "POST", body: JSON.stringify({ project: "aicode-consumers" }) });
64307
+ const summaryResponse = await http9(ANTIGRAVITY_QUOTA_URL, headers, signal, { method: "POST", body: JSON.stringify({ project: "aicode-consumers" }) });
64308
64308
  if (summaryResponse.status !== HTTP_OK) {
64309
64309
  throw new ProviderQuotaError(ANTIGRAVITY_SOURCE, `answered HTTP ${String(summaryResponse.status)}`);
64310
64310
  }
@@ -64318,7 +64318,7 @@ var init_providerQuota = __esm({
64318
64318
  if (!parsed.success) {
64319
64319
  throw new ProviderQuotaError(ANTIGRAVITY_SOURCE, `answered an unexpected shape: ${parsed.error.issues.map((issue2) => `${issue2.path.join(".")}: ${issue2.message}`).join("; ")}`);
64320
64320
  }
64321
- const tokenResponse = await http8(`${GOOGLE_TOKENINFO_URL}?access_token=${encodeURIComponent(apiKey)}`, { accept: "application/json" }, signal);
64321
+ const tokenResponse = await http9(`${GOOGLE_TOKENINFO_URL}?access_token=${encodeURIComponent(apiKey)}`, { accept: "application/json" }, signal);
64322
64322
  let account;
64323
64323
  if (tokenResponse.status === HTTP_OK) {
64324
64324
  try {
@@ -64330,7 +64330,7 @@ var init_providerQuota = __esm({
64330
64330
  }
64331
64331
  }
64332
64332
  let level;
64333
- const userResponse = await http8(ANTIGRAVITY_USER_URL, headers, signal, { method: "POST", body: "{}" });
64333
+ const userResponse = await http9(ANTIGRAVITY_USER_URL, headers, signal, { method: "POST", body: "{}" });
64334
64334
  if (userResponse.status === HTTP_OK) {
64335
64335
  try {
64336
64336
  const tiers = AntigravityUserSchema.parse(JSON.parse(userResponse.text));
@@ -101699,7 +101699,7 @@ var require_schemes = __commonJS({
101699
101699
  urnComponent.nss = (uuidComponent.uuid || "").toLowerCase();
101700
101700
  return urnComponent;
101701
101701
  }
101702
- var http8 = (
101702
+ var http9 = (
101703
101703
  /** @type {SchemeHandler} */
101704
101704
  {
101705
101705
  scheme: "http",
@@ -101712,7 +101712,7 @@ var require_schemes = __commonJS({
101712
101712
  /** @type {SchemeHandler} */
101713
101713
  {
101714
101714
  scheme: "https",
101715
- domainHost: http8.domainHost,
101715
+ domainHost: http9.domainHost,
101716
101716
  parse: httpParse,
101717
101717
  serialize: httpSerialize
101718
101718
  }
@@ -101756,7 +101756,7 @@ var require_schemes = __commonJS({
101756
101756
  var SCHEMES = (
101757
101757
  /** @type {Record<SchemeName, SchemeHandler>} */
101758
101758
  {
101759
- http: http8,
101759
+ http: http9,
101760
101760
  https: https6,
101761
101761
  ws,
101762
101762
  wss,
@@ -114550,23 +114550,23 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
114550
114550
  };
114551
114551
  writeFrontDoorState(fs24, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
114552
114552
  const previousSticky = lastPort;
114553
- let http8;
114553
+ let http9;
114554
114554
  try {
114555
- http8 = await ports.startProviderListener(lastPort);
114555
+ http9 = await ports.startProviderListener(lastPort);
114556
114556
  } catch (error63) {
114557
114557
  ports.doorHealth.listenerFailed("provider", error63 instanceof Error ? error63.message : String(error63));
114558
114558
  return fail(`could not start the provider listener: ${error63 instanceof Error ? error63.message : String(error63)}`);
114559
114559
  }
114560
- if (previousSticky !== void 0 && http8.port !== previousSticky) {
114561
- ports.log(`agent-shim frontdoor supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(http8.port)} (sessions launched against the old port are stale until they relaunch)`);
114560
+ if (previousSticky !== void 0 && http9.port !== previousSticky) {
114561
+ ports.log(`agent-shim frontdoor supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(http9.port)} (sessions launched against the old port are stale until they relaunch)`);
114562
114562
  }
114563
- lastPort = http8.port;
114563
+ lastPort = http9.port;
114564
114564
  const previousStickyConnect = lastConnectPort;
114565
114565
  let connect3;
114566
114566
  try {
114567
114567
  connect3 = await ports.startConnectListener(lastConnectPort);
114568
114568
  } catch (error63) {
114569
- await http8.close();
114569
+ await http9.close();
114570
114570
  ports.doorHealth.listenerFailed("connect", error63 instanceof Error ? error63.message : String(error63));
114571
114571
  return fail(`could not start the CONNECT surface: ${error63 instanceof Error ? error63.message : String(error63)}`);
114572
114572
  }
@@ -114580,7 +114580,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
114580
114580
  direct = await ports.startDirectListener(lastDirectPort);
114581
114581
  } catch (error63) {
114582
114582
  await connect3.close();
114583
- await http8.close();
114583
+ await http9.close();
114584
114584
  ports.doorHealth.listenerFailed("direct", error63 instanceof Error ? error63.message : String(error63));
114585
114585
  return fail(`could not start the direct listener: ${error63 instanceof Error ? error63.message : String(error63)}`);
114586
114586
  }
@@ -114589,10 +114589,10 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
114589
114589
  }
114590
114590
  lastDirectPort = direct.port;
114591
114591
  writeFrontDoorDirectRecord(fs24, paths.frontdoorDirectRecordsDir, { pid: ports.ownPid, directPort: direct.port });
114592
- writeFrontDoorState(fs24, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http8.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
114593
- ports.doorHealth.generation({ providerPort: http8.port, connectPort: connect3.port, directPort: direct.port });
114592
+ writeFrontDoorState(fs24, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http9.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
114593
+ ports.doorHealth.generation({ providerPort: http9.port, connectPort: connect3.port, directPort: direct.port });
114594
114594
  fs24.removeRecursive(paths.frontdoorLockFile);
114595
- ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http8.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
114595
+ ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http9.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
114596
114596
  const watchdog = ports.startWatchdog?.();
114597
114597
  let idleSince;
114598
114598
  let ticks = 0;
@@ -114610,7 +114610,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
114610
114610
  watchdog?.stop();
114611
114611
  await direct.close();
114612
114612
  await connect3.close();
114613
- await http8.close();
114613
+ await http9.close();
114614
114614
  ports.closeRcStreamHub();
114615
114615
  removeFrontDoorDirectRecord(fs24, paths.frontdoorDirectRecordsDir, ports.ownPid);
114616
114616
  };
@@ -127772,6 +127772,7 @@ function translateRequest(body, config2) {
127772
127772
  var import_node_crypto21 = require("node:crypto");
127773
127773
 
127774
127774
  // src/antigravity/signatures.ts
127775
+ var UNVERIFIED_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
127775
127776
  var MAX_REMEMBERED = 1024;
127776
127777
  var signatures = /* @__PURE__ */ new Map();
127777
127778
  function rememberToolCallSignature(toolUseId, signature) {
@@ -127933,8 +127934,8 @@ function messagesToGeminiContents(messages, names, toolIdToName) {
127933
127934
  name: sanitizedName,
127934
127935
  args: isRecord8(block2.input) ? block2.input : {}
127935
127936
  },
127936
- // The relay remembered the signature the backend attached to this exact call; echoing it back is what the backend requires of a repeated function call.
127937
- ...signature === void 0 ? {} : { thoughtSignature: signature }
127937
+ // The relay remembered the signature the backend attached to this exact call; echoing it back is what the backend requires of a repeated function call. A call with none remembered (made before a door restart, evicted from the bounded store, or produced by another model in a resumed session) gets the backend's documented bypass, since history is resent whole on every request and a single unsigned call would otherwise fail the whole conversation for good.
127938
+ thoughtSignature: signature ?? UNVERIFIED_THOUGHT_SIGNATURE
127938
127939
  });
127939
127940
  } else if (isToolResultBlock(block2)) {
127940
127941
  const toolName = toolIdToName.get(block2.tool_use_id) ?? "unknown_tool";
@@ -128077,9 +128078,9 @@ init_cloudUpstream();
128077
128078
  var MS_PER_SECOND8 = 1e3;
128078
128079
  var DEFAULT_RETRY_AFTER_SECONDS = 60;
128079
128080
  var FRACTION_DIGITS = 3;
128080
- var EXHAUSTED_FRACTION = "1.000";
128081
128081
  var GEMINI_5H_KEYS = ["gemini-5h", "gemini_5h", "gemini"];
128082
128082
  var GEMINI_WEEKLY_KEYS = ["gemini-weekly", "gemini_weekly"];
128083
+ var ARGON_WEEKLY_KEYS = ["gemini-argon-wtu-weekly"];
128083
128084
  var THIRD_PARTY_5H_KEYS = ["3p-5h", "claude-5h", "3p_5h", "claude_5h", "claude"];
128084
128085
  var THIRD_PARTY_WEEKLY_KEYS = ["3p-weekly", "claude-weekly", "3p_weekly", "claude_weekly"];
128085
128086
  function findBucket(quota, keys) {
@@ -128092,7 +128093,11 @@ function findBucket(quota, keys) {
128092
128093
  return void 0;
128093
128094
  }
128094
128095
  function selectAntigravityBuckets(quota, model) {
128095
- const isGemini = (model ?? "").toLowerCase().includes("gemini");
128096
+ const lower = (model ?? "").toLowerCase();
128097
+ if (lower.includes("argon")) {
128098
+ return { fiveHour: void 0, weekly: findBucket(quota, ARGON_WEEKLY_KEYS) };
128099
+ }
128100
+ const isGemini = lower.includes("gemini");
128096
128101
  return {
128097
128102
  fiveHour: findBucket(quota, isGemini ? GEMINI_5H_KEYS : THIRD_PARTY_5H_KEYS),
128098
128103
  weekly: findBucket(quota, isGemini ? GEMINI_WEEKLY_KEYS : THIRD_PARTY_WEEKLY_KEYS)
@@ -128135,6 +128140,10 @@ function unifiedAntigravityQuotaHeaders(params) {
128135
128140
  const reset5h = calculateResetTimestamp(nowSec, b5h?.reset_in_seconds);
128136
128141
  const used7d = calculateUtilization(bWk?.remaining_fraction);
128137
128142
  const reset7d = calculateResetTimestamp(nowSec, bWk?.reset_in_seconds);
128143
+ const exhaustion = rejected ? antigravityQuotaExhaustion(params.quota, params.model, params.nowMs) : void 0;
128144
+ if (rejected && exhaustion === void 0) {
128145
+ return {};
128146
+ }
128138
128147
  if (!rejected && used5h === void 0 && reset5h === void 0 && used7d === void 0 && reset7d === void 0) {
128139
128148
  return {};
128140
128149
  }
@@ -128146,31 +128155,45 @@ function unifiedAntigravityQuotaHeaders(params) {
128146
128155
  headers["anthropic-ratelimit-unified-5h-utilization"] = used5h;
128147
128156
  headers["anthropic-ratelimit-unified-5h-reset"] = reset5h;
128148
128157
  earliestResetSec = Number(reset5h);
128158
+ if (rejected) {
128159
+ headers["anthropic-ratelimit-unified-5h-status"] = exhaustion?.exhaustedWindows.includes("five_hour") === true ? "rejected" : "allowed";
128160
+ }
128149
128161
  }
128150
128162
  if (used7d !== void 0 && reset7d !== void 0) {
128151
128163
  headers["anthropic-ratelimit-unified-7d-utilization"] = used7d;
128152
128164
  headers["anthropic-ratelimit-unified-7d-reset"] = reset7d;
128153
128165
  const reset7dSec = Number(reset7d);
128154
128166
  earliestResetSec = earliestResetSec === void 0 ? reset7dSec : Math.min(earliestResetSec, reset7dSec);
128155
- }
128156
- if (rejected) {
128157
- const retrySec = params.retryAfterSeconds ?? DEFAULT_RETRY_AFTER_SECONDS;
128158
- const fallbackReset = String(nowSec + retrySec);
128159
- if (headers["anthropic-ratelimit-unified-5h-utilization"] === void 0) {
128160
- headers["anthropic-ratelimit-unified-5h-utilization"] = EXHAUSTED_FRACTION;
128161
- headers["anthropic-ratelimit-unified-5h-reset"] = fallbackReset;
128167
+ if (rejected) {
128168
+ headers["anthropic-ratelimit-unified-7d-status"] = exhaustion?.exhaustedWindows.includes("seven_day") === true ? "rejected" : "allowed";
128162
128169
  }
128163
- if (headers["anthropic-ratelimit-unified-7d-utilization"] === void 0) {
128164
- headers["anthropic-ratelimit-unified-7d-utilization"] = EXHAUSTED_FRACTION;
128165
- headers["anthropic-ratelimit-unified-7d-reset"] = fallbackReset;
128166
- }
128167
- earliestResetSec = earliestResetSec === void 0 ? nowSec + retrySec : Math.min(earliestResetSec, nowSec + retrySec);
128170
+ }
128171
+ if (exhaustion !== void 0) {
128172
+ headers["anthropic-ratelimit-unified-representative-claim"] = exhaustion.window;
128173
+ headers["anthropic-ratelimit-unified-reset"] = String(exhaustion.resetSec);
128174
+ headers["retry-after"] = String(Math.max(1, exhaustion.resetSec - nowSec));
128175
+ headers["x-should-retry"] = "false";
128176
+ return headers;
128168
128177
  }
128169
128178
  if (earliestResetSec !== void 0) {
128170
128179
  headers["anthropic-ratelimit-unified-reset"] = String(earliestResetSec);
128171
128180
  }
128172
128181
  return headers;
128173
128182
  }
128183
+ function antigravityQuotaExhaustion(quota, model, nowMs) {
128184
+ const { fiveHour, weekly } = selectAntigravityBuckets(quota ?? {}, model);
128185
+ const nowSec = Math.floor(nowMs / MS_PER_SECOND8);
128186
+ const spent = [];
128187
+ for (const [window, bucket] of [["five_hour", fiveHour], ["seven_day", weekly]]) {
128188
+ const remaining = bucket?.remaining_fraction;
128189
+ const resetIn = bucket?.reset_in_seconds;
128190
+ if (remaining !== void 0 && Number.isFinite(remaining) && remaining <= 0 && resetIn !== void 0 && Number.isFinite(resetIn) && resetIn >= 0) {
128191
+ spent.push({ window, resetSec: nowSec + Math.ceil(resetIn) });
128192
+ }
128193
+ }
128194
+ const binding = spent.reduce((latest, next) => latest === void 0 || next.resetSec > latest.resetSec ? next : latest, void 0);
128195
+ return binding === void 0 ? void 0 : { window: binding.window, resetSec: binding.resetSec, exhaustedWindows: spent.map((entry) => entry.window) };
128196
+ }
128174
128197
  function isRecord9(value2) {
128175
128198
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
128176
128199
  }
@@ -128238,6 +128261,7 @@ var ANTIGRAVITY_QUOTA_REFRESH_MS = 6e4;
128238
128261
  function createCachedAntigravityQuotaSource(params) {
128239
128262
  let cachedAt = Number.NEGATIVE_INFINITY;
128240
128263
  let cached2;
128264
+ let readAtMs = Number.NEGATIVE_INFINITY;
128241
128265
  let refresh;
128242
128266
  const refreshMs = params.refreshMs ?? ANTIGRAVITY_QUOTA_REFRESH_MS;
128243
128267
  const run = async () => {
@@ -128245,20 +128269,26 @@ function createCachedAntigravityQuotaSource(params) {
128245
128269
  const read = await params.fetchSummary(nowMs);
128246
128270
  if (read !== void 0) {
128247
128271
  cached2 = read;
128272
+ readAtMs = nowMs;
128248
128273
  }
128249
128274
  cachedAt = params.now();
128250
128275
  };
128251
128276
  return () => {
128252
128277
  const nowMs = params.now();
128253
- if (nowMs - cachedAt < refreshMs) {
128254
- return cached2;
128278
+ if (nowMs - cachedAt >= refreshMs) {
128279
+ refresh ??= run().finally(() => {
128280
+ refresh = void 0;
128281
+ });
128255
128282
  }
128256
- refresh ??= run().finally(() => {
128257
- refresh = void 0;
128258
- });
128259
- return cached2;
128283
+ return cached2 === void 0 ? void 0 : ageQuotaMap(cached2, nowMs - readAtMs);
128260
128284
  };
128261
128285
  }
128286
+ function ageQuotaMap(quota, elapsedMs) {
128287
+ const elapsedSec = elapsedMs / MS_PER_SECOND8;
128288
+ return Object.fromEntries(
128289
+ Object.entries(quota).map(([key, bucket]) => [key, bucket?.reset_in_seconds === void 0 ? bucket : { ...bucket, reset_in_seconds: Math.max(0, bucket.reset_in_seconds - elapsedSec) }])
128290
+ );
128291
+ }
128262
128292
 
128263
128293
  // src/frontdoor/providerRoute.ts
128264
128294
  init_credential();
@@ -129215,6 +129245,11 @@ async function* callLocalAntigravity(params) {
129215
129245
  }
129216
129246
 
129217
129247
  // src/antigravity/route.ts
129248
+ var MS_PER_SECOND10 = 1e3;
129249
+ function exhaustedMessage(exhaustion) {
129250
+ const window = exhaustion.window === "five_hour" ? "5-hour" : "weekly";
129251
+ return `Antigravity ${window} limit reached; it resets at ${new Date(exhaustion.resetSec * MS_PER_SECOND10).toISOString()}.`;
129252
+ }
129218
129253
  function createAntigravityRoute(ports) {
129219
129254
  const fallbackId = ports.fallbackId ?? (() => (0, import_node_crypto22.randomUUID)());
129220
129255
  return async (request7) => {
@@ -129299,14 +129334,10 @@ function createAntigravityRoute(ports) {
129299
129334
  } catch (error63) {
129300
129335
  if (error63 instanceof AntigravityUpstreamError) {
129301
129336
  const is429 = error63.status === HTTP_STATUS.tooManyRequests;
129302
- const retryAfter = is429 ? parseRetryAfterSeconds(error63.retryAfter) : void 0;
129303
- const quotaHeaders3 = unifiedAntigravityQuotaHeaders({
129304
- quota: ports.quotaSource?.(),
129305
- rejected: is429,
129306
- nowMs,
129307
- retryAfterSeconds: retryAfter,
129308
- model: requestedModel
129309
- });
129337
+ const quota = ports.quotaSource?.();
129338
+ const quotaHeaders3 = unifiedAntigravityQuotaHeaders({ quota, rejected: is429, nowMs, model: translated.model });
129339
+ const retryAfter = is429 && quotaHeaders3["retry-after"] === void 0 ? parseRetryAfterSeconds(error63.retryAfter) : void 0;
129340
+ const exhaustion = is429 ? antigravityQuotaExhaustion(quota, translated.model, nowMs) : void 0;
129310
129341
  const errorType = is429 ? "rate_limit_error" : "api_error";
129311
129342
  return {
129312
129343
  status: error63.status,
@@ -129315,7 +129346,7 @@ function createAntigravityRoute(ports) {
129315
129346
  ...quotaHeaders3,
129316
129347
  ...retryAfter !== void 0 ? { "retry-after": String(retryAfter) } : {}
129317
129348
  },
129318
- body: JSON.stringify({ type: "error", error: { type: errorType, message: error63.message } })
129349
+ body: JSON.stringify({ type: "error", error: { type: errorType, message: exhaustion === void 0 ? error63.message : exhaustedMessage(exhaustion) } })
129319
129350
  };
129320
129351
  }
129321
129352
  const errMsg = error63 instanceof Error ? error63.message : String(error63);
@@ -129329,7 +129360,7 @@ function createAntigravityRoute(ports) {
129329
129360
  quota: ports.quotaSource?.(),
129330
129361
  rejected: false,
129331
129362
  nowMs,
129332
- model: requestedModel
129363
+ model: translated.model
129333
129364
  });
129334
129365
  const stream = async function* () {
129335
129366
  try {
@@ -129931,7 +129962,7 @@ init_account();
129931
129962
  var RC_SELF_HOST_OAUTH_HOST = "platform.claude.com";
129932
129963
  var RC_SELF_HOST_SCOPE_LIST = ["user:profile", "user:inference", "user:sessions:claude_code", "user:mcp_servers", "user:file_upload"];
129933
129964
  var RC_SELF_HOST_OAUTH_TOKEN_TTL_SECONDS = 3600;
129934
- var MS_PER_SECOND10 = 1e3;
129965
+ var MS_PER_SECOND11 = 1e3;
129935
129966
  var HTTP_SERVICE_UNAVAILABLE = 503;
129936
129967
  function isRecord12(value2) {
129937
129968
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
@@ -129987,7 +130018,7 @@ function createRcSelfHostLocal(deps) {
129987
130018
  }
129988
130019
  if (method === "POST" && pathname.startsWith("/api/eval/")) {
129989
130020
  await deps.readBody(request7, CONTROL_BODY_CAP_BYTES);
129990
- answerServerJson(response, HTTP_STATUS.ok, { features: growthBookFeatures(), dateUpdated: Math.floor(deps.now() / MS_PER_SECOND10) });
130021
+ answerServerJson(response, HTTP_STATUS.ok, { features: growthBookFeatures(), dateUpdated: Math.floor(deps.now() / MS_PER_SECOND11) });
129991
130022
  return true;
129992
130023
  }
129993
130024
  if (method === "GET" && pathname === "/api/oauth/profile") {
@@ -130171,12 +130202,12 @@ function eventExcerpt(text2) {
130171
130202
  return text2.length <= RC_PENDING_SUMMARY_EXCERPT_CHARS ? text2 : `${text2.slice(0, RC_PENDING_SUMMARY_EXCERPT_CHARS)}...`;
130172
130203
  }
130173
130204
  var PERCENT_SCALE = 100;
130174
- var MS_PER_SECOND11 = 1e3;
130205
+ var MS_PER_SECOND12 = 1e3;
130175
130206
  function percentOf(fraction) {
130176
130207
  return `${String(Math.round(fraction * PERCENT_SCALE))}%`;
130177
130208
  }
130178
130209
  function resetInstantOf(epochSeconds) {
130179
- return new Date(epochSeconds * MS_PER_SECOND11).toISOString();
130210
+ return new Date(epochSeconds * MS_PER_SECOND12).toISOString();
130180
130211
  }
130181
130212
  function formatRcRateLimitInfo(info) {
130182
130213
  const parts = [info.status];
@@ -131611,7 +131642,7 @@ var RC_COMPAT_SESSIONS_PATH = "/v1/sessions";
131611
131642
  var RC_SESSION_ID_PREFIX2 = "cse_";
131612
131643
  var RC_SELF_HOST_API_BASE_URL = "https://api.anthropic.com";
131613
131644
  var HTTP_CONFLICT = 409;
131614
- var MS_PER_SECOND12 = 1e3;
131645
+ var MS_PER_SECOND13 = 1e3;
131615
131646
  var HTTP_SERVICE_UNAVAILABLE2 = 503;
131616
131647
  var RC_SELF_HOST_WORKER_JWT_TTL_SECONDS = 46800;
131617
131648
  var RC_SELF_HOST_KEEPALIVE_MS = 15e3;
@@ -131711,7 +131742,7 @@ function parseJsonObject5(body) {
131711
131742
  function mintWorkerJwt(randomToken, issuedAt) {
131712
131743
  const encode3 = (value2) => Buffer.from(JSON.stringify(value2), "utf8").toString("base64url");
131713
131744
  const header = encode3({ alg: "HS256", typ: "JWT" });
131714
- const payload = encode3({ exp: Math.floor((issuedAt + RC_SELF_HOST_WORKER_JWT_TTL_SECONDS * MS_PER_SECOND12) / MS_PER_SECOND12), iat: Math.floor(issuedAt / MS_PER_SECOND12) });
131745
+ const payload = encode3({ exp: Math.floor((issuedAt + RC_SELF_HOST_WORKER_JWT_TTL_SECONDS * MS_PER_SECOND13) / MS_PER_SECOND13), iat: Math.floor(issuedAt / MS_PER_SECOND13) });
131715
131746
  return `${header}.${payload}.${Buffer.from(randomToken(), "utf8").toString("base64url")}`;
131716
131747
  }
131717
131748
  function createRcSelfHostSurface(deps) {
@@ -133299,9 +133330,84 @@ function antigravityStacksWithDefault(fs24, homeDir) {
133299
133330
  return typeof statusLine === "object" && statusLine !== null && "stack_with_default" in statusLine && statusLine.stack_with_default === true;
133300
133331
  }
133301
133332
 
133333
+ // src/statusline/headroom.ts
133334
+ var import_node_http4 = __toESM(require("node:http"), 1);
133335
+ init_zod();
133336
+ var HEADROOM_TIMEOUT_MS = 500;
133337
+ var HTTP_OK2 = 200;
133338
+ var SessionRowSchema = external_exports.object({
133339
+ tokens_saved: external_exports.number().nonnegative().optional(),
133340
+ savings_percent: external_exports.number().nonnegative().optional(),
133341
+ compression_savings_usd: external_exports.number().nonnegative().optional()
133342
+ });
133343
+ function headroomSessionIdOf(payload, env) {
133344
+ if (typeof payload === "object" && payload !== null && "session_id" in payload && typeof payload.session_id === "string" && payload.session_id.trim() !== "") {
133345
+ return payload.session_id.trim();
133346
+ }
133347
+ for (const line of (env.ANTHROPIC_CUSTOM_HEADERS ?? "").split("\n")) {
133348
+ const separator = line.indexOf(":");
133349
+ if (separator !== -1 && line.slice(0, separator).trim().toLowerCase() === "x-agent-shim-session" && line.slice(separator + 1).trim() !== "") {
133350
+ return line.slice(separator + 1).trim();
133351
+ }
133352
+ }
133353
+ return void 0;
133354
+ }
133355
+ function headroomTargetOf(env, supervisedSocketPath) {
133356
+ const url2 = env.HEADROOM_PROXY_URL?.trim();
133357
+ if (url2 !== void 0 && url2 !== "") {
133358
+ return { kind: "http", baseUrl: url2.replace(/\/+$/, "") };
133359
+ }
133360
+ return supervisedSocketPath === void 0 ? void 0 : { kind: "socket", socketPath: supervisedSocketPath };
133361
+ }
133362
+ async function fetchHeadroomSessionStats(get3, target, sessionId) {
133363
+ let response;
133364
+ try {
133365
+ response = await get3(target, `/stats/sessions/${encodeURIComponent(sessionId)}`, HEADROOM_TIMEOUT_MS);
133366
+ } catch {
133367
+ return void 0;
133368
+ }
133369
+ if (response.status !== HTTP_OK2) {
133370
+ return void 0;
133371
+ }
133372
+ let body;
133373
+ try {
133374
+ body = JSON.parse(response.text);
133375
+ } catch {
133376
+ return void 0;
133377
+ }
133378
+ const row = SessionRowSchema.safeParse(body);
133379
+ if (!row.success) {
133380
+ return void 0;
133381
+ }
133382
+ const stats = { tokensSaved: row.data.tokens_saved, savingsPercent: row.data.savings_percent, savingsUsd: row.data.compression_savings_usd };
133383
+ return stats.tokensSaved === void 0 && stats.savingsPercent === void 0 && stats.savingsUsd === void 0 ? void 0 : stats;
133384
+ }
133385
+ var realHeadroomGet = async (target, requestPath, timeoutMs) => {
133386
+ if (target.kind === "http") {
133387
+ const response = await fetch(`${target.baseUrl}${requestPath}`, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(timeoutMs) });
133388
+ return { status: response.status, text: await response.text() };
133389
+ }
133390
+ return await new Promise((resolve2, reject) => {
133391
+ const request7 = import_node_http4.default.request({ socketPath: target.socketPath, path: requestPath, method: "GET", headers: { accept: "application/json", host: "localhost" }, timeout: timeoutMs }, (response) => {
133392
+ const chunks = [];
133393
+ response.on("data", (chunk) => {
133394
+ chunks.push(chunk);
133395
+ });
133396
+ response.on("end", () => {
133397
+ resolve2({ status: response.statusCode ?? 0, text: Buffer.concat(chunks).toString("utf8") });
133398
+ });
133399
+ });
133400
+ request7.on("timeout", () => {
133401
+ request7.destroy(new Error("headroom lookup timed out"));
133402
+ });
133403
+ request7.on("error", reject);
133404
+ request7.end();
133405
+ });
133406
+ };
133407
+
133302
133408
  // src/statusline/enrich.ts
133303
133409
  var FULL_PERCENT = 100;
133304
- var MS_PER_SECOND13 = 1e3;
133410
+ var MS_PER_SECOND14 = 1e3;
133305
133411
  function identityOf(env) {
133306
133412
  const headers = env.ANTHROPIC_CUSTOM_HEADERS;
133307
133413
  if (headers !== void 0) {
@@ -133358,7 +133464,7 @@ function payloadWindow(rateLimits, key) {
133358
133464
  const resetsAt = window.resets_at;
133359
133465
  return {
133360
133466
  used: Math.min(FULL_PERCENT, Math.max(0, window.used_percentage)),
133361
- resetAt: typeof resetsAt === "number" && Number.isFinite(resetsAt) ? new Date(resetsAt * MS_PER_SECOND13).toISOString() : void 0
133467
+ resetAt: typeof resetsAt === "number" && Number.isFinite(resetsAt) ? new Date(resetsAt * MS_PER_SECOND14).toISOString() : void 0
133362
133468
  };
133363
133469
  }
133364
133470
  function payloadWindowsOf(payload) {
@@ -133386,7 +133492,7 @@ function antigravityWindowsOf(payload, nowMs) {
133386
133492
  const { fiveHour, weekly } = selectAntigravityBuckets(buckets, model);
133387
133493
  const windowOf2 = (bucket) => ({
133388
133494
  used: bucket?.remaining_fraction === void 0 || !Number.isFinite(bucket.remaining_fraction) ? void 0 : (1 - Math.min(1, Math.max(0, bucket.remaining_fraction))) * FULL_PERCENT,
133389
- resetAt: bucket?.reset_in_seconds === void 0 || !Number.isFinite(bucket.reset_in_seconds) ? void 0 : new Date(nowMs + bucket.reset_in_seconds * MS_PER_SECOND13).toISOString()
133495
+ resetAt: bucket?.reset_in_seconds === void 0 || !Number.isFinite(bucket.reset_in_seconds) ? void 0 : new Date(nowMs + bucket.reset_in_seconds * MS_PER_SECOND14).toISOString()
133390
133496
  });
133391
133497
  const five = windowOf2(fiveHour);
133392
133498
  const seven = windowOf2(weekly);
@@ -133413,7 +133519,8 @@ function enrichStatuslinePayload(params) {
133413
133519
  fiveHourResetAt: void 0,
133414
133520
  sevenDayUsed: void 0,
133415
133521
  sevenDayResetAt: void 0,
133416
- providerQuotaWindows: []
133522
+ providerQuotaWindows: [],
133523
+ headroom: params.headroom
133417
133524
  };
133418
133525
  if (params.snapshot !== void 0) {
133419
133526
  const scopedName = providerScopedState(params.snapshot, params.providerName, params.env.AGENT_SHIM_PROVIDER);
@@ -133486,6 +133593,7 @@ var TWENTY = 20;
133486
133593
  var RESERVED_COLUMNS = 4;
133487
133594
  var SEPARATOR2 = " | ";
133488
133595
  var FULL_PERCENT2 = 100;
133596
+ var ONE_PERCENT = 1;
133489
133597
  var USED_RED_AT = 0.9;
133490
133598
  var USED_YELLOW_AT = 0.7;
133491
133599
  var ESCAPE_CHAR_CODE = 27;
@@ -133543,14 +133651,30 @@ function formatDuration(seconds) {
133543
133651
  }
133544
133652
  return `${String(minutes)}m`;
133545
133653
  }
133654
+ function headroomText(stats) {
133655
+ if (stats === void 0) {
133656
+ return void 0;
133657
+ }
133658
+ const overall = stats.savingsPercent === void 0 ? void 0 : `${stats.savingsPercent.toFixed(stats.savingsPercent < ONE_PERCENT ? 2 : 1)}% overall`;
133659
+ const parts = [
133660
+ stats.tokensSaved === void 0 ? void 0 : `${formatTokens(stats.tokensSaved)} saved`,
133661
+ overall,
133662
+ stats.savingsUsd === void 0 ? void 0 : `$${stats.savingsUsd.toFixed(2)}`
133663
+ ].filter((part) => part !== void 0);
133664
+ return parts.length === 0 ? void 0 : `headroom ${parts.join(" \xB7 ")}`;
133665
+ }
133666
+ function cacheHitText(hitFraction) {
133667
+ const clamped = Math.max(0, Math.min(1, hitFraction));
133668
+ return ` (Cache: ${statusColor(clamped, false)}${(clamped * FULL_PERCENT2).toFixed(0)}%${RESET})`;
133669
+ }
133546
133670
  function cacheShareText(view) {
133547
133671
  const hitRatio = view.cacheHitRatio;
133548
133672
  if (hitRatio !== void 0 && Number.isFinite(hitRatio)) {
133549
- return ` (Cache: ${(Math.max(0, Math.min(1, hitRatio)) * FULL_PERCENT2).toFixed(0)}%)`;
133673
+ return cacheHitText(hitRatio);
133550
133674
  }
133551
133675
  const promptTotal = (view.cacheReadTokens ?? 0) + (view.freshInputTokens ?? 0);
133552
133676
  if (promptTotal > 0 && (view.cacheReadTokens ?? 0) > 0) {
133553
- return ` (Cache: ${((view.cacheReadTokens ?? 0) / promptTotal * FULL_PERCENT2).toFixed(0)}%)`;
133677
+ return cacheHitText((view.cacheReadTokens ?? 0) / promptTotal);
133554
133678
  }
133555
133679
  return "";
133556
133680
  }
@@ -133753,6 +133877,10 @@ function renderStatuslineBlock(summary, view, terminalWidth, nowMs) {
133753
133877
  if (summary.identity !== void 0 && summary.provider !== void 0 && summary.identity !== summary.providerAccountEmail && summary.identity !== summary.loginAccountEmail) {
133754
133878
  header.push(new Segment("static", summary.identity));
133755
133879
  }
133880
+ const savings = headroomText(summary.headroom);
133881
+ if (savings !== void 0) {
133882
+ header.push(new Segment("static", savings));
133883
+ }
133756
133884
  const contextGroup = [];
133757
133885
  if (view.contextUsedPercentage !== void 0) {
133758
133886
  const fraction = Math.max(0, Math.min(1, view.contextUsedPercentage / FULL_PERCENT2));
@@ -133882,7 +134010,11 @@ function registerStatuslineCommand(program2, deps) {
133882
134010
  }
133883
134011
  }
133884
134012
  const nowMs = Date.now();
133885
- const { payload: enriched, summary } = enrichStatuslinePayload({ payload, env: process.env, snapshot, account, providerName, nowMs });
134013
+ const socketTarget = headroomSocketTarget(realFarmFs, realHeadroomSocketTrust, deps.paths);
134014
+ const target = headroomTargetOf(process.env, socketTarget === void 0 || socketTarget.refused !== void 0 ? void 0 : socketTarget.socketPath);
134015
+ const sessionId = headroomSessionIdOf(payload, process.env);
134016
+ const headroom = target === void 0 || sessionId === void 0 ? void 0 : await fetchHeadroomSessionStats(realHeadroomGet, target, sessionId);
134017
+ const { payload: enriched, summary } = enrichStatuslinePayload({ payload, env: process.env, snapshot, account, providerName, nowMs, headroom });
133886
134018
  const renderer = process.env.AGENT_SHIM_STATUSLINE_CMD;
133887
134019
  if (renderer !== void 0 && renderer !== "") {
133888
134020
  const child = (0, import_node_child_process7.spawn)("/bin/sh", ["-c", renderer], { stdio: ["pipe", "inherit", "inherit"] });
@@ -144181,7 +144313,7 @@ function registerDoctorCommand(program2, deps) {
144181
144313
 
144182
144314
  // src/headroom/commands.ts
144183
144315
  var import_node_fs22 = __toESM(require("node:fs"), 1);
144184
- var import_node_http4 = __toESM(require("node:http"), 1);
144316
+ var import_node_http5 = __toESM(require("node:http"), 1);
144185
144317
  var import_node_path56 = __toESM(require("node:path"), 1);
144186
144318
  var import_node_child_process9 = require("node:child_process");
144187
144319
  init_commandDeps();
@@ -144353,7 +144485,7 @@ function headroomProxyArgs(socketPath, allowlistFile, settings2) {
144353
144485
  }
144354
144486
  async function readyOverSocket(socketPath) {
144355
144487
  return await new Promise((resolve2) => {
144356
- const probe = import_node_http4.default.get({ socketPath, path: "/readyz", timeout: READY_FETCH_TIMEOUT_MS }, (response) => {
144488
+ const probe = import_node_http5.default.get({ socketPath, path: "/readyz", timeout: READY_FETCH_TIMEOUT_MS }, (response) => {
144357
144489
  response.resume();
144358
144490
  resolve2(response.statusCode === HTTP_STATUS.ok);
144359
144491
  });
package/dist/index.cjs CHANGED
@@ -2841,7 +2841,7 @@ var init_package = __esm({
2841
2841
  "package.json"() {
2842
2842
  package_default = {
2843
2843
  name: "claude-use",
2844
- version: "11.14.0",
2844
+ version: "11.15.0",
2845
2845
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
2846
2846
  license: "MIT",
2847
2847
  author: "Joseph Mearman <joseph@mearman.co.uk>",
package/dist/index.mjs CHANGED
@@ -2817,7 +2817,7 @@ var init_package = __esm({
2817
2817
  "package.json"() {
2818
2818
  package_default = {
2819
2819
  name: "claude-use",
2820
- version: "11.14.0",
2820
+ version: "11.15.0",
2821
2821
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
2822
2822
  license: "MIT",
2823
2823
  author: "Joseph Mearman <joseph@mearman.co.uk>",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-use",
3
- "version": "11.14.0",
3
+ "version": "11.15.0",
4
4
  "description": "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
5
5
  "license": "MIT",
6
6
  "author": "Joseph Mearman <joseph@mearman.co.uk>",