claude-use 11.14.0 → 11.16.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
@@ -27023,13 +27023,8 @@ var init_schema = __esm({
27023
27023
  mode: external_exports.enum(ANTIGRAVITY_MODES).optional(),
27024
27024
  /** The model a request maps to when no tier matches its model name. */
27025
27025
  defaultModel: external_exports.string().min(1).optional(),
27026
- /** Per-tier overrides of the shipped mapping, matched by substring of the requested model name in `ANTIGRAVITY_TIERS` order. */
27027
- models: external_exports.strictObject({
27028
- fable: external_exports.string().min(1).optional(),
27029
- opus: external_exports.string().min(1).optional(),
27030
- sonnet: external_exports.string().min(1).optional(),
27031
- haiku: external_exports.string().min(1).optional()
27032
- }).optional(),
27026
+ /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. */
27027
+ models: external_exports.record(external_exports.string().min(1), external_exports.string().min(1)).optional(),
27033
27028
  /** The reasoning effort used when the request's own effort is not one the backend accepts. */
27034
27029
  effort: external_exports.enum(ANTIGRAVITY_EFFORTS).optional(),
27035
27030
  /** Cloud-specific settings (for `mode: "cloud"`). */
@@ -34093,7 +34088,7 @@ var init_package = __esm({
34093
34088
  "package.json"() {
34094
34089
  package_default = {
34095
34090
  name: "claude-use",
34096
- version: "11.14.0",
34091
+ version: "11.16.0",
34097
34092
  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
34093
  license: "MIT",
34099
34094
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -44666,7 +44661,7 @@ var require_client = __commonJS({
44666
44661
  "use strict";
44667
44662
  var assert2 = require("node:assert");
44668
44663
  var net5 = require("node:net");
44669
- var http8 = require("node:http");
44664
+ var http9 = require("node:http");
44670
44665
  var util2 = require_util2();
44671
44666
  var { ClientStats } = require_stats();
44672
44667
  var { channels } = require_diagnostics();
@@ -44724,7 +44719,7 @@ var require_client = __commonJS({
44724
44719
  var connectH1 = require_client_h1();
44725
44720
  var connectH2 = require_client_h2();
44726
44721
  var kClosedResolve = /* @__PURE__ */ Symbol("kClosedResolve");
44727
- var getDefaultNodeMaxHeaderSize = http8 && http8.maxHeaderSize && Number.isInteger(http8.maxHeaderSize) && http8.maxHeaderSize > 0 ? () => http8.maxHeaderSize : () => {
44722
+ var getDefaultNodeMaxHeaderSize = http9 && http9.maxHeaderSize && Number.isInteger(http9.maxHeaderSize) && http9.maxHeaderSize > 0 ? () => http9.maxHeaderSize : () => {
44728
44723
  throw new InvalidArgumentError2("http module not available or http.maxHeaderSize invalid");
44729
44724
  };
44730
44725
  var noop = () => {
@@ -62424,9 +62419,9 @@ function expectedSha256(sidecar) {
62424
62419
  const first = sidecar.trim().split(/\s+/)[0];
62425
62420
  return first === "" ? void 0 : first;
62426
62421
  }
62427
- async function mustDownload(http8, url2) {
62422
+ async function mustDownload(http9, url2) {
62428
62423
  try {
62429
- return await http8.download(url2);
62424
+ return await http9.download(url2);
62430
62425
  } catch (error63) {
62431
62426
  throw new UpdateDownloadError(`could not download ${url2}: ${error63 instanceof Error ? error63.message : String(error63)}`);
62432
62427
  }
@@ -64124,8 +64119,8 @@ function zaiWindow(limit) {
64124
64119
  ...limit.remaining === void 0 ? {} : { remaining: limit.remaining }
64125
64120
  };
64126
64121
  }
64127
- async function openRouterGet(url2, schema, apiKey, http8, signal) {
64128
- const response = await http8(url2, { authorization: `Bearer ${apiKey}`, accept: "application/json" }, signal);
64122
+ async function openRouterGet(url2, schema, apiKey, http9, signal) {
64123
+ const response = await http9(url2, { authorization: `Bearer ${apiKey}`, accept: "application/json" }, signal);
64129
64124
  if (response.status === HTTP_FORBIDDEN) {
64130
64125
  return "forbidden";
64131
64126
  }
@@ -64201,8 +64196,8 @@ var init_providerQuota = __esm({
64201
64196
  zaiQuotaAdapter = {
64202
64197
  source: ZAI_SOURCE,
64203
64198
  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);
64199
+ fetch: async (apiKey, http9, signal, nowMs) => {
64200
+ const response = await http9(ZAI_QUOTA_URL, { authorization: apiKey, accept: "application/json" }, signal);
64206
64201
  if (response.status !== HTTP_OK) {
64207
64202
  throw new ProviderQuotaError(ZAI_SOURCE, `answered HTTP ${String(response.status)}`);
64208
64203
  }
@@ -64246,12 +64241,12 @@ var init_providerQuota = __esm({
64246
64241
  openRouterQuotaAdapter = {
64247
64242
  source: OPENROUTER_SOURCE,
64248
64243
  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);
64244
+ fetch: async (apiKey, http9, signal, nowMs) => {
64245
+ const key = await openRouterGet(OPENROUTER_KEY_URL, OpenRouterKeySchema, apiKey, http9, signal);
64251
64246
  if (key === "forbidden") {
64252
64247
  throw new ProviderQuotaError(OPENROUTER_SOURCE, "/api/v1/key refused the key (HTTP 403)");
64253
64248
  }
64254
- const credits = await openRouterGet(OPENROUTER_CREDITS_URL, OpenRouterCreditsSchema, apiKey, http8, signal);
64249
+ const credits = await openRouterGet(OPENROUTER_CREDITS_URL, OpenRouterCreditsSchema, apiKey, http9, signal);
64255
64250
  const { limit, limit_remaining: limitRemaining, limit_reset: limitReset, free_model_daily_requests: free, is_free_tier: isFreeTier } = key.data;
64256
64251
  const windows = [];
64257
64252
  if (limit !== null && limit > 0) {
@@ -64302,9 +64297,9 @@ var init_providerQuota = __esm({
64302
64297
  antigravityQuotaAdapter = {
64303
64298
  source: ANTIGRAVITY_SOURCE,
64304
64299
  matches: (baseUrl) => URL.canParse(baseUrl) && new URL(baseUrl).hostname === ANTIGRAVITY_HOST,
64305
- fetch: async (apiKey, http8, signal, nowMs) => {
64300
+ fetch: async (apiKey, http9, signal, nowMs) => {
64306
64301
  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" }) });
64302
+ const summaryResponse = await http9(ANTIGRAVITY_QUOTA_URL, headers, signal, { method: "POST", body: JSON.stringify({ project: "aicode-consumers" }) });
64308
64303
  if (summaryResponse.status !== HTTP_OK) {
64309
64304
  throw new ProviderQuotaError(ANTIGRAVITY_SOURCE, `answered HTTP ${String(summaryResponse.status)}`);
64310
64305
  }
@@ -64318,7 +64313,7 @@ var init_providerQuota = __esm({
64318
64313
  if (!parsed.success) {
64319
64314
  throw new ProviderQuotaError(ANTIGRAVITY_SOURCE, `answered an unexpected shape: ${parsed.error.issues.map((issue2) => `${issue2.path.join(".")}: ${issue2.message}`).join("; ")}`);
64320
64315
  }
64321
- const tokenResponse = await http8(`${GOOGLE_TOKENINFO_URL}?access_token=${encodeURIComponent(apiKey)}`, { accept: "application/json" }, signal);
64316
+ const tokenResponse = await http9(`${GOOGLE_TOKENINFO_URL}?access_token=${encodeURIComponent(apiKey)}`, { accept: "application/json" }, signal);
64322
64317
  let account;
64323
64318
  if (tokenResponse.status === HTTP_OK) {
64324
64319
  try {
@@ -64330,7 +64325,7 @@ var init_providerQuota = __esm({
64330
64325
  }
64331
64326
  }
64332
64327
  let level;
64333
- const userResponse = await http8(ANTIGRAVITY_USER_URL, headers, signal, { method: "POST", body: "{}" });
64328
+ const userResponse = await http9(ANTIGRAVITY_USER_URL, headers, signal, { method: "POST", body: "{}" });
64334
64329
  if (userResponse.status === HTTP_OK) {
64335
64330
  try {
64336
64331
  const tiers = AntigravityUserSchema.parse(JSON.parse(userResponse.text));
@@ -101699,7 +101694,7 @@ var require_schemes = __commonJS({
101699
101694
  urnComponent.nss = (uuidComponent.uuid || "").toLowerCase();
101700
101695
  return urnComponent;
101701
101696
  }
101702
- var http8 = (
101697
+ var http9 = (
101703
101698
  /** @type {SchemeHandler} */
101704
101699
  {
101705
101700
  scheme: "http",
@@ -101712,7 +101707,7 @@ var require_schemes = __commonJS({
101712
101707
  /** @type {SchemeHandler} */
101713
101708
  {
101714
101709
  scheme: "https",
101715
- domainHost: http8.domainHost,
101710
+ domainHost: http9.domainHost,
101716
101711
  parse: httpParse,
101717
101712
  serialize: httpSerialize
101718
101713
  }
@@ -101756,7 +101751,7 @@ var require_schemes = __commonJS({
101756
101751
  var SCHEMES = (
101757
101752
  /** @type {Record<SchemeName, SchemeHandler>} */
101758
101753
  {
101759
- http: http8,
101754
+ http: http9,
101760
101755
  https: https6,
101761
101756
  ws,
101762
101757
  wss,
@@ -114550,23 +114545,23 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
114550
114545
  };
114551
114546
  writeFrontDoorState(fs24, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
114552
114547
  const previousSticky = lastPort;
114553
- let http8;
114548
+ let http9;
114554
114549
  try {
114555
- http8 = await ports.startProviderListener(lastPort);
114550
+ http9 = await ports.startProviderListener(lastPort);
114556
114551
  } catch (error63) {
114557
114552
  ports.doorHealth.listenerFailed("provider", error63 instanceof Error ? error63.message : String(error63));
114558
114553
  return fail(`could not start the provider listener: ${error63 instanceof Error ? error63.message : String(error63)}`);
114559
114554
  }
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)`);
114555
+ if (previousSticky !== void 0 && http9.port !== previousSticky) {
114556
+ 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
114557
  }
114563
- lastPort = http8.port;
114558
+ lastPort = http9.port;
114564
114559
  const previousStickyConnect = lastConnectPort;
114565
114560
  let connect3;
114566
114561
  try {
114567
114562
  connect3 = await ports.startConnectListener(lastConnectPort);
114568
114563
  } catch (error63) {
114569
- await http8.close();
114564
+ await http9.close();
114570
114565
  ports.doorHealth.listenerFailed("connect", error63 instanceof Error ? error63.message : String(error63));
114571
114566
  return fail(`could not start the CONNECT surface: ${error63 instanceof Error ? error63.message : String(error63)}`);
114572
114567
  }
@@ -114580,7 +114575,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
114580
114575
  direct = await ports.startDirectListener(lastDirectPort);
114581
114576
  } catch (error63) {
114582
114577
  await connect3.close();
114583
- await http8.close();
114578
+ await http9.close();
114584
114579
  ports.doorHealth.listenerFailed("direct", error63 instanceof Error ? error63.message : String(error63));
114585
114580
  return fail(`could not start the direct listener: ${error63 instanceof Error ? error63.message : String(error63)}`);
114586
114581
  }
@@ -114589,10 +114584,10 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
114589
114584
  }
114590
114585
  lastDirectPort = direct.port;
114591
114586
  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 });
114587
+ writeFrontDoorState(fs24, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http9.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
114588
+ ports.doorHealth.generation({ providerPort: http9.port, connectPort: connect3.port, directPort: direct.port });
114594
114589
  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)}`);
114590
+ 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
114591
  const watchdog = ports.startWatchdog?.();
114597
114592
  let idleSince;
114598
114593
  let ticks = 0;
@@ -114610,7 +114605,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
114610
114605
  watchdog?.stop();
114611
114606
  await direct.close();
114612
114607
  await connect3.close();
114613
- await http8.close();
114608
+ await http9.close();
114614
114609
  ports.closeRcStreamHub();
114615
114610
  removeFrontDoorDirectRecord(fs24, paths.frontdoorDirectRecordsDir, ports.ownPid);
114616
114611
  };
@@ -127772,6 +127767,7 @@ function translateRequest(body, config2) {
127772
127767
  var import_node_crypto21 = require("node:crypto");
127773
127768
 
127774
127769
  // src/antigravity/signatures.ts
127770
+ var UNVERIFIED_THOUGHT_SIGNATURE = "skip_thought_signature_validator";
127775
127771
  var MAX_REMEMBERED = 1024;
127776
127772
  var signatures = /* @__PURE__ */ new Map();
127777
127773
  function rememberToolCallSignature(toolUseId, signature) {
@@ -127789,17 +127785,27 @@ function toolCallSignatureOf(toolUseId) {
127789
127785
 
127790
127786
  // src/antigravity/translate.ts
127791
127787
  init_schema();
127788
+ function isAntigravityTier(key) {
127789
+ return ANTIGRAVITY_TIERS.some((tier) => tier === key);
127790
+ }
127792
127791
  function resolveAntigravityConfig(config2) {
127793
- const overrides = config2?.models;
127792
+ const overrides = config2?.models ?? {};
127793
+ const aliases = /* @__PURE__ */ new Map();
127794
+ for (const [key, model] of Object.entries(overrides)) {
127795
+ if (!isAntigravityTier(key)) {
127796
+ aliases.set(key.toLowerCase(), model);
127797
+ }
127798
+ }
127794
127799
  return {
127795
127800
  mode: config2?.mode ?? ANTIGRAVITY_DEFAULT_MODE,
127796
127801
  defaultModel: config2?.defaultModel ?? ANTIGRAVITY_DEFAULT_MODEL,
127797
127802
  models: {
127798
- fable: overrides?.fable ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.fable,
127799
- opus: overrides?.opus ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.opus,
127800
- sonnet: overrides?.sonnet ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.sonnet,
127801
- haiku: overrides?.haiku ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.haiku
127803
+ fable: overrides.fable ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.fable,
127804
+ opus: overrides.opus ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.opus,
127805
+ sonnet: overrides.sonnet ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.sonnet,
127806
+ haiku: overrides.haiku ?? ANTIGRAVITY_DEFAULT_TIER_MODELS.haiku
127802
127807
  },
127808
+ aliases,
127803
127809
  effort: config2?.effort ?? ANTIGRAVITY_DEFAULT_EFFORT,
127804
127810
  cloud: {
127805
127811
  endpoint: config2?.cloud?.endpoint,
@@ -127813,12 +127819,21 @@ function resolveAntigravityConfig(config2) {
127813
127819
  };
127814
127820
  }
127815
127821
  var CONTEXT_MARKER_1M = "[1m]";
127822
+ var BACKEND_FAMILY_PREFIXES = ["gemini-", "antigravity-", "gpt-oss-"];
127823
+ var BACKEND_CLAUDE_NAME = /^claude-.+-(?:low|medium|high|thinking)$/;
127824
+ function isBackendModelName(name) {
127825
+ return BACKEND_FAMILY_PREFIXES.some((prefix) => name.startsWith(prefix)) || BACKEND_CLAUDE_NAME.test(name);
127826
+ }
127816
127827
  function mapModel2(requested, config2) {
127817
127828
  const stripped = requested.toLowerCase().endsWith(CONTEXT_MARKER_1M) ? requested.slice(0, -CONTEXT_MARKER_1M.length) : requested;
127818
- if (stripped.startsWith("gemini-") || stripped.startsWith("antigravity-")) {
127829
+ const lower = stripped.toLowerCase();
127830
+ const alias = config2.aliases.get(lower);
127831
+ if (alias !== void 0) {
127832
+ return alias;
127833
+ }
127834
+ if (isBackendModelName(stripped)) {
127819
127835
  return stripped;
127820
127836
  }
127821
- const lower = stripped.toLowerCase();
127822
127837
  const tier = ANTIGRAVITY_TIERS.find((candidate) => lower.includes(candidate));
127823
127838
  return tier === void 0 ? config2.defaultModel : config2.models[tier];
127824
127839
  }
@@ -127933,8 +127948,8 @@ function messagesToGeminiContents(messages, names, toolIdToName) {
127933
127948
  name: sanitizedName,
127934
127949
  args: isRecord8(block2.input) ? block2.input : {}
127935
127950
  },
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 }
127951
+ // 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.
127952
+ thoughtSignature: signature ?? UNVERIFIED_THOUGHT_SIGNATURE
127938
127953
  });
127939
127954
  } else if (isToolResultBlock(block2)) {
127940
127955
  const toolName = toolIdToName.get(block2.tool_use_id) ?? "unknown_tool";
@@ -128045,7 +128060,7 @@ function completeEffortSuffix(model, request7, config2) {
128045
128060
  if (splitEffortSuffix(model) !== void 0) {
128046
128061
  return model;
128047
128062
  }
128048
- const configured = [config2.defaultModel, ...Object.values(config2.models)];
128063
+ const configured = [config2.defaultModel, ...Object.values(config2.models), ...config2.aliases.values()];
128049
128064
  const effort = request7.output_config?.effort;
128050
128065
  const level = ANTIGRAVITY_EFFORTS.find((candidate) => candidate === effort) ?? config2.effort;
128051
128066
  const suffixed = `${model}-${effortSuffixOf(level)}`;
@@ -128077,9 +128092,9 @@ init_cloudUpstream();
128077
128092
  var MS_PER_SECOND8 = 1e3;
128078
128093
  var DEFAULT_RETRY_AFTER_SECONDS = 60;
128079
128094
  var FRACTION_DIGITS = 3;
128080
- var EXHAUSTED_FRACTION = "1.000";
128081
128095
  var GEMINI_5H_KEYS = ["gemini-5h", "gemini_5h", "gemini"];
128082
128096
  var GEMINI_WEEKLY_KEYS = ["gemini-weekly", "gemini_weekly"];
128097
+ var ARGON_WEEKLY_KEYS = ["gemini-argon-wtu-weekly"];
128083
128098
  var THIRD_PARTY_5H_KEYS = ["3p-5h", "claude-5h", "3p_5h", "claude_5h", "claude"];
128084
128099
  var THIRD_PARTY_WEEKLY_KEYS = ["3p-weekly", "claude-weekly", "3p_weekly", "claude_weekly"];
128085
128100
  function findBucket(quota, keys) {
@@ -128091,8 +128106,25 @@ function findBucket(quota, keys) {
128091
128106
  }
128092
128107
  return void 0;
128093
128108
  }
128109
+ var QUOTA_FAMILY_WINDOWS = [
128110
+ { label: "Gem 5h", keys: GEMINI_5H_KEYS },
128111
+ { label: "Gem Wk", keys: GEMINI_WEEKLY_KEYS },
128112
+ { label: "3P 5h", keys: THIRD_PARTY_5H_KEYS },
128113
+ { label: "3P Wk", keys: THIRD_PARTY_WEEKLY_KEYS },
128114
+ { label: "Argon Wk", keys: ARGON_WEEKLY_KEYS }
128115
+ ];
128116
+ function antigravityFamilyBuckets(quota) {
128117
+ return QUOTA_FAMILY_WINDOWS.flatMap(({ label, keys }) => {
128118
+ const bucket = findBucket(quota, keys);
128119
+ return bucket === void 0 ? [] : [{ label, bucket }];
128120
+ });
128121
+ }
128094
128122
  function selectAntigravityBuckets(quota, model) {
128095
- const isGemini = (model ?? "").toLowerCase().includes("gemini");
128123
+ const lower = (model ?? "").toLowerCase();
128124
+ if (lower.includes("argon")) {
128125
+ return { fiveHour: void 0, weekly: findBucket(quota, ARGON_WEEKLY_KEYS) };
128126
+ }
128127
+ const isGemini = lower.includes("gemini");
128096
128128
  return {
128097
128129
  fiveHour: findBucket(quota, isGemini ? GEMINI_5H_KEYS : THIRD_PARTY_5H_KEYS),
128098
128130
  weekly: findBucket(quota, isGemini ? GEMINI_WEEKLY_KEYS : THIRD_PARTY_WEEKLY_KEYS)
@@ -128135,6 +128167,10 @@ function unifiedAntigravityQuotaHeaders(params) {
128135
128167
  const reset5h = calculateResetTimestamp(nowSec, b5h?.reset_in_seconds);
128136
128168
  const used7d = calculateUtilization(bWk?.remaining_fraction);
128137
128169
  const reset7d = calculateResetTimestamp(nowSec, bWk?.reset_in_seconds);
128170
+ const exhaustion = rejected ? antigravityQuotaExhaustion(params.quota, params.model, params.nowMs) : void 0;
128171
+ if (rejected && exhaustion === void 0) {
128172
+ return {};
128173
+ }
128138
128174
  if (!rejected && used5h === void 0 && reset5h === void 0 && used7d === void 0 && reset7d === void 0) {
128139
128175
  return {};
128140
128176
  }
@@ -128146,31 +128182,45 @@ function unifiedAntigravityQuotaHeaders(params) {
128146
128182
  headers["anthropic-ratelimit-unified-5h-utilization"] = used5h;
128147
128183
  headers["anthropic-ratelimit-unified-5h-reset"] = reset5h;
128148
128184
  earliestResetSec = Number(reset5h);
128185
+ if (rejected) {
128186
+ headers["anthropic-ratelimit-unified-5h-status"] = exhaustion?.exhaustedWindows.includes("five_hour") === true ? "rejected" : "allowed";
128187
+ }
128149
128188
  }
128150
128189
  if (used7d !== void 0 && reset7d !== void 0) {
128151
128190
  headers["anthropic-ratelimit-unified-7d-utilization"] = used7d;
128152
128191
  headers["anthropic-ratelimit-unified-7d-reset"] = reset7d;
128153
128192
  const reset7dSec = Number(reset7d);
128154
128193
  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;
128194
+ if (rejected) {
128195
+ headers["anthropic-ratelimit-unified-7d-status"] = exhaustion?.exhaustedWindows.includes("seven_day") === true ? "rejected" : "allowed";
128162
128196
  }
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);
128197
+ }
128198
+ if (exhaustion !== void 0) {
128199
+ headers["anthropic-ratelimit-unified-representative-claim"] = exhaustion.window;
128200
+ headers["anthropic-ratelimit-unified-reset"] = String(exhaustion.resetSec);
128201
+ headers["retry-after"] = String(Math.max(1, exhaustion.resetSec - nowSec));
128202
+ headers["x-should-retry"] = "false";
128203
+ return headers;
128168
128204
  }
128169
128205
  if (earliestResetSec !== void 0) {
128170
128206
  headers["anthropic-ratelimit-unified-reset"] = String(earliestResetSec);
128171
128207
  }
128172
128208
  return headers;
128173
128209
  }
128210
+ function antigravityQuotaExhaustion(quota, model, nowMs) {
128211
+ const { fiveHour, weekly } = selectAntigravityBuckets(quota ?? {}, model);
128212
+ const nowSec = Math.floor(nowMs / MS_PER_SECOND8);
128213
+ const spent = [];
128214
+ for (const [window, bucket] of [["five_hour", fiveHour], ["seven_day", weekly]]) {
128215
+ const remaining = bucket?.remaining_fraction;
128216
+ const resetIn = bucket?.reset_in_seconds;
128217
+ if (remaining !== void 0 && Number.isFinite(remaining) && remaining <= 0 && resetIn !== void 0 && Number.isFinite(resetIn) && resetIn >= 0) {
128218
+ spent.push({ window, resetSec: nowSec + Math.ceil(resetIn) });
128219
+ }
128220
+ }
128221
+ const binding = spent.reduce((latest, next) => latest === void 0 || next.resetSec > latest.resetSec ? next : latest, void 0);
128222
+ return binding === void 0 ? void 0 : { window: binding.window, resetSec: binding.resetSec, exhaustedWindows: spent.map((entry) => entry.window) };
128223
+ }
128174
128224
  function isRecord9(value2) {
128175
128225
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
128176
128226
  }
@@ -128238,6 +128288,7 @@ var ANTIGRAVITY_QUOTA_REFRESH_MS = 6e4;
128238
128288
  function createCachedAntigravityQuotaSource(params) {
128239
128289
  let cachedAt = Number.NEGATIVE_INFINITY;
128240
128290
  let cached2;
128291
+ let readAtMs = Number.NEGATIVE_INFINITY;
128241
128292
  let refresh;
128242
128293
  const refreshMs = params.refreshMs ?? ANTIGRAVITY_QUOTA_REFRESH_MS;
128243
128294
  const run = async () => {
@@ -128245,20 +128296,26 @@ function createCachedAntigravityQuotaSource(params) {
128245
128296
  const read = await params.fetchSummary(nowMs);
128246
128297
  if (read !== void 0) {
128247
128298
  cached2 = read;
128299
+ readAtMs = nowMs;
128248
128300
  }
128249
128301
  cachedAt = params.now();
128250
128302
  };
128251
128303
  return () => {
128252
128304
  const nowMs = params.now();
128253
- if (nowMs - cachedAt < refreshMs) {
128254
- return cached2;
128305
+ if (nowMs - cachedAt >= refreshMs) {
128306
+ refresh ??= run().finally(() => {
128307
+ refresh = void 0;
128308
+ });
128255
128309
  }
128256
- refresh ??= run().finally(() => {
128257
- refresh = void 0;
128258
- });
128259
- return cached2;
128310
+ return cached2 === void 0 ? void 0 : ageQuotaMap(cached2, nowMs - readAtMs);
128260
128311
  };
128261
128312
  }
128313
+ function ageQuotaMap(quota, elapsedMs) {
128314
+ const elapsedSec = elapsedMs / MS_PER_SECOND8;
128315
+ return Object.fromEntries(
128316
+ 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) }])
128317
+ );
128318
+ }
128262
128319
 
128263
128320
  // src/frontdoor/providerRoute.ts
128264
128321
  init_credential();
@@ -129215,6 +129272,11 @@ async function* callLocalAntigravity(params) {
129215
129272
  }
129216
129273
 
129217
129274
  // src/antigravity/route.ts
129275
+ var MS_PER_SECOND10 = 1e3;
129276
+ function exhaustedMessage(exhaustion) {
129277
+ const window = exhaustion.window === "five_hour" ? "5-hour" : "weekly";
129278
+ return `Antigravity ${window} limit reached; it resets at ${new Date(exhaustion.resetSec * MS_PER_SECOND10).toISOString()}.`;
129279
+ }
129218
129280
  function createAntigravityRoute(ports) {
129219
129281
  const fallbackId = ports.fallbackId ?? (() => (0, import_node_crypto22.randomUUID)());
129220
129282
  return async (request7) => {
@@ -129299,14 +129361,10 @@ function createAntigravityRoute(ports) {
129299
129361
  } catch (error63) {
129300
129362
  if (error63 instanceof AntigravityUpstreamError) {
129301
129363
  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
- });
129364
+ const quota = ports.quotaSource?.();
129365
+ const quotaHeaders3 = unifiedAntigravityQuotaHeaders({ quota, rejected: is429, nowMs, model: translated.model });
129366
+ const retryAfter = is429 && quotaHeaders3["retry-after"] === void 0 ? parseRetryAfterSeconds(error63.retryAfter) : void 0;
129367
+ const exhaustion = is429 ? antigravityQuotaExhaustion(quota, translated.model, nowMs) : void 0;
129310
129368
  const errorType = is429 ? "rate_limit_error" : "api_error";
129311
129369
  return {
129312
129370
  status: error63.status,
@@ -129315,7 +129373,7 @@ function createAntigravityRoute(ports) {
129315
129373
  ...quotaHeaders3,
129316
129374
  ...retryAfter !== void 0 ? { "retry-after": String(retryAfter) } : {}
129317
129375
  },
129318
- body: JSON.stringify({ type: "error", error: { type: errorType, message: error63.message } })
129376
+ body: JSON.stringify({ type: "error", error: { type: errorType, message: exhaustion === void 0 ? error63.message : exhaustedMessage(exhaustion) } })
129319
129377
  };
129320
129378
  }
129321
129379
  const errMsg = error63 instanceof Error ? error63.message : String(error63);
@@ -129329,7 +129387,7 @@ function createAntigravityRoute(ports) {
129329
129387
  quota: ports.quotaSource?.(),
129330
129388
  rejected: false,
129331
129389
  nowMs,
129332
- model: requestedModel
129390
+ model: translated.model
129333
129391
  });
129334
129392
  const stream = async function* () {
129335
129393
  try {
@@ -129931,7 +129989,7 @@ init_account();
129931
129989
  var RC_SELF_HOST_OAUTH_HOST = "platform.claude.com";
129932
129990
  var RC_SELF_HOST_SCOPE_LIST = ["user:profile", "user:inference", "user:sessions:claude_code", "user:mcp_servers", "user:file_upload"];
129933
129991
  var RC_SELF_HOST_OAUTH_TOKEN_TTL_SECONDS = 3600;
129934
- var MS_PER_SECOND10 = 1e3;
129992
+ var MS_PER_SECOND11 = 1e3;
129935
129993
  var HTTP_SERVICE_UNAVAILABLE = 503;
129936
129994
  function isRecord12(value2) {
129937
129995
  return typeof value2 === "object" && value2 !== null && !Array.isArray(value2);
@@ -129987,7 +130045,7 @@ function createRcSelfHostLocal(deps) {
129987
130045
  }
129988
130046
  if (method === "POST" && pathname.startsWith("/api/eval/")) {
129989
130047
  await deps.readBody(request7, CONTROL_BODY_CAP_BYTES);
129990
- answerServerJson(response, HTTP_STATUS.ok, { features: growthBookFeatures(), dateUpdated: Math.floor(deps.now() / MS_PER_SECOND10) });
130048
+ answerServerJson(response, HTTP_STATUS.ok, { features: growthBookFeatures(), dateUpdated: Math.floor(deps.now() / MS_PER_SECOND11) });
129991
130049
  return true;
129992
130050
  }
129993
130051
  if (method === "GET" && pathname === "/api/oauth/profile") {
@@ -130171,12 +130229,12 @@ function eventExcerpt(text2) {
130171
130229
  return text2.length <= RC_PENDING_SUMMARY_EXCERPT_CHARS ? text2 : `${text2.slice(0, RC_PENDING_SUMMARY_EXCERPT_CHARS)}...`;
130172
130230
  }
130173
130231
  var PERCENT_SCALE = 100;
130174
- var MS_PER_SECOND11 = 1e3;
130232
+ var MS_PER_SECOND12 = 1e3;
130175
130233
  function percentOf(fraction) {
130176
130234
  return `${String(Math.round(fraction * PERCENT_SCALE))}%`;
130177
130235
  }
130178
130236
  function resetInstantOf(epochSeconds) {
130179
- return new Date(epochSeconds * MS_PER_SECOND11).toISOString();
130237
+ return new Date(epochSeconds * MS_PER_SECOND12).toISOString();
130180
130238
  }
130181
130239
  function formatRcRateLimitInfo(info) {
130182
130240
  const parts = [info.status];
@@ -131611,7 +131669,7 @@ var RC_COMPAT_SESSIONS_PATH = "/v1/sessions";
131611
131669
  var RC_SESSION_ID_PREFIX2 = "cse_";
131612
131670
  var RC_SELF_HOST_API_BASE_URL = "https://api.anthropic.com";
131613
131671
  var HTTP_CONFLICT = 409;
131614
- var MS_PER_SECOND12 = 1e3;
131672
+ var MS_PER_SECOND13 = 1e3;
131615
131673
  var HTTP_SERVICE_UNAVAILABLE2 = 503;
131616
131674
  var RC_SELF_HOST_WORKER_JWT_TTL_SECONDS = 46800;
131617
131675
  var RC_SELF_HOST_KEEPALIVE_MS = 15e3;
@@ -131711,7 +131769,7 @@ function parseJsonObject5(body) {
131711
131769
  function mintWorkerJwt(randomToken, issuedAt) {
131712
131770
  const encode3 = (value2) => Buffer.from(JSON.stringify(value2), "utf8").toString("base64url");
131713
131771
  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) });
131772
+ 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
131773
  return `${header}.${payload}.${Buffer.from(randomToken(), "utf8").toString("base64url")}`;
131716
131774
  }
131717
131775
  function createRcSelfHostSurface(deps) {
@@ -133299,9 +133357,84 @@ function antigravityStacksWithDefault(fs24, homeDir) {
133299
133357
  return typeof statusLine === "object" && statusLine !== null && "stack_with_default" in statusLine && statusLine.stack_with_default === true;
133300
133358
  }
133301
133359
 
133360
+ // src/statusline/headroom.ts
133361
+ var import_node_http4 = __toESM(require("node:http"), 1);
133362
+ init_zod();
133363
+ var HEADROOM_TIMEOUT_MS = 500;
133364
+ var HTTP_OK2 = 200;
133365
+ var SessionRowSchema = external_exports.object({
133366
+ tokens_saved: external_exports.number().nonnegative().optional(),
133367
+ savings_percent: external_exports.number().nonnegative().optional(),
133368
+ compression_savings_usd: external_exports.number().nonnegative().optional()
133369
+ });
133370
+ function headroomSessionIdOf(payload, env) {
133371
+ if (typeof payload === "object" && payload !== null && "session_id" in payload && typeof payload.session_id === "string" && payload.session_id.trim() !== "") {
133372
+ return payload.session_id.trim();
133373
+ }
133374
+ for (const line of (env.ANTHROPIC_CUSTOM_HEADERS ?? "").split("\n")) {
133375
+ const separator = line.indexOf(":");
133376
+ if (separator !== -1 && line.slice(0, separator).trim().toLowerCase() === "x-agent-shim-session" && line.slice(separator + 1).trim() !== "") {
133377
+ return line.slice(separator + 1).trim();
133378
+ }
133379
+ }
133380
+ return void 0;
133381
+ }
133382
+ function headroomTargetOf(env, supervisedSocketPath) {
133383
+ const url2 = env.HEADROOM_PROXY_URL?.trim();
133384
+ if (url2 !== void 0 && url2 !== "") {
133385
+ return { kind: "http", baseUrl: url2.replace(/\/+$/, "") };
133386
+ }
133387
+ return supervisedSocketPath === void 0 ? void 0 : { kind: "socket", socketPath: supervisedSocketPath };
133388
+ }
133389
+ async function fetchHeadroomSessionStats(get3, target, sessionId) {
133390
+ let response;
133391
+ try {
133392
+ response = await get3(target, `/stats/sessions/${encodeURIComponent(sessionId)}`, HEADROOM_TIMEOUT_MS);
133393
+ } catch {
133394
+ return void 0;
133395
+ }
133396
+ if (response.status !== HTTP_OK2) {
133397
+ return void 0;
133398
+ }
133399
+ let body;
133400
+ try {
133401
+ body = JSON.parse(response.text);
133402
+ } catch {
133403
+ return void 0;
133404
+ }
133405
+ const row = SessionRowSchema.safeParse(body);
133406
+ if (!row.success) {
133407
+ return void 0;
133408
+ }
133409
+ const stats = { tokensSaved: row.data.tokens_saved, savingsPercent: row.data.savings_percent, savingsUsd: row.data.compression_savings_usd };
133410
+ return stats.tokensSaved === void 0 && stats.savingsPercent === void 0 && stats.savingsUsd === void 0 ? void 0 : stats;
133411
+ }
133412
+ var realHeadroomGet = async (target, requestPath, timeoutMs) => {
133413
+ if (target.kind === "http") {
133414
+ const response = await fetch(`${target.baseUrl}${requestPath}`, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(timeoutMs) });
133415
+ return { status: response.status, text: await response.text() };
133416
+ }
133417
+ return await new Promise((resolve2, reject) => {
133418
+ const request7 = import_node_http4.default.request({ socketPath: target.socketPath, path: requestPath, method: "GET", headers: { accept: "application/json", host: "localhost" }, timeout: timeoutMs }, (response) => {
133419
+ const chunks = [];
133420
+ response.on("data", (chunk) => {
133421
+ chunks.push(chunk);
133422
+ });
133423
+ response.on("end", () => {
133424
+ resolve2({ status: response.statusCode ?? 0, text: Buffer.concat(chunks).toString("utf8") });
133425
+ });
133426
+ });
133427
+ request7.on("timeout", () => {
133428
+ request7.destroy(new Error("headroom lookup timed out"));
133429
+ });
133430
+ request7.on("error", reject);
133431
+ request7.end();
133432
+ });
133433
+ };
133434
+
133302
133435
  // src/statusline/enrich.ts
133303
133436
  var FULL_PERCENT = 100;
133304
- var MS_PER_SECOND13 = 1e3;
133437
+ var MS_PER_SECOND14 = 1e3;
133305
133438
  function identityOf(env) {
133306
133439
  const headers = env.ANTHROPIC_CUSTOM_HEADERS;
133307
133440
  if (headers !== void 0) {
@@ -133358,7 +133491,7 @@ function payloadWindow(rateLimits, key) {
133358
133491
  const resetsAt = window.resets_at;
133359
133492
  return {
133360
133493
  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
133494
+ resetAt: typeof resetsAt === "number" && Number.isFinite(resetsAt) ? new Date(resetsAt * MS_PER_SECOND14).toISOString() : void 0
133362
133495
  };
133363
133496
  }
133364
133497
  function payloadWindowsOf(payload) {
@@ -133367,13 +133500,12 @@ function payloadWindowsOf(payload) {
133367
133500
  const seven = isObject4(rateLimits) ? payloadWindow(rateLimits, "seven_day") : void 0;
133368
133501
  return { fiveHourUsed: five?.used, fiveHourResetAt: five?.resetAt, sevenDayUsed: seven?.used, sevenDayResetAt: seven?.resetAt };
133369
133502
  }
133370
- function antigravityWindowsOf(payload, nowMs) {
133503
+ function antigravityQuotaMapOf(payload) {
133371
133504
  const quota = isObject4(payload) ? payload.quota : void 0;
133372
133505
  if (!isObject4(quota)) {
133373
- return { fiveHourUsed: void 0, fiveHourResetAt: void 0, sevenDayUsed: void 0, sevenDayResetAt: void 0 };
133506
+ return void 0;
133374
133507
  }
133375
- const model = isObject4(payload) && isObject4(payload.model) && typeof payload.model.id === "string" ? payload.model.id : void 0;
133376
- const buckets = Object.fromEntries(
133508
+ return Object.fromEntries(
133377
133509
  Object.entries(quota).flatMap(([key, bucket]) => {
133378
133510
  if (!isObject4(bucket)) {
133379
133511
  return [];
@@ -133383,15 +133515,30 @@ function antigravityWindowsOf(payload, nowMs) {
133383
133515
  return [[key, { ...typeof remaining === "number" ? { remaining_fraction: remaining } : {}, ...typeof resetIn === "number" ? { reset_in_seconds: resetIn } : {} }]];
133384
133516
  })
133385
133517
  );
133386
- const { fiveHour, weekly } = selectAntigravityBuckets(buckets, model);
133387
- const windowOf2 = (bucket) => ({
133518
+ }
133519
+ function bucketView(bucket, nowMs) {
133520
+ return {
133388
133521
  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()
133390
- });
133391
- const five = windowOf2(fiveHour);
133392
- const seven = windowOf2(weekly);
133522
+ 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()
133523
+ };
133524
+ }
133525
+ function antigravityWindowsOf(payload, nowMs) {
133526
+ const buckets = antigravityQuotaMapOf(payload);
133527
+ if (buckets === void 0) {
133528
+ return { fiveHourUsed: void 0, fiveHourResetAt: void 0, sevenDayUsed: void 0, sevenDayResetAt: void 0 };
133529
+ }
133530
+ const model = isObject4(payload) && isObject4(payload.model) && typeof payload.model.id === "string" ? payload.model.id : void 0;
133531
+ const { fiveHour, weekly } = selectAntigravityBuckets(buckets, model);
133532
+ const five = bucketView(fiveHour, nowMs);
133533
+ const seven = bucketView(weekly, nowMs);
133393
133534
  return { fiveHourUsed: five.used, fiveHourResetAt: five.resetAt, sevenDayUsed: seven.used, sevenDayResetAt: seven.resetAt };
133394
133535
  }
133536
+ function quotaFamiliesOf(buckets, nowMs) {
133537
+ return antigravityFamilyBuckets(buckets).flatMap(({ label, bucket }) => {
133538
+ const { used, resetAt } = bucketView(bucket, nowMs);
133539
+ return used === void 0 ? [] : [{ measures: label, utilization: used / FULL_PERCENT, resetsAt: resetAt }];
133540
+ });
133541
+ }
133395
133542
  function enrichStatuslinePayload(params) {
133396
133543
  const identity = identityOf(params.env);
133397
133544
  const clientEmail = isObject4(params.payload) && typeof params.payload.email === "string" && params.payload.email !== "" ? params.payload.email : void 0;
@@ -133413,7 +133560,9 @@ function enrichStatuslinePayload(params) {
133413
133560
  fiveHourResetAt: void 0,
133414
133561
  sevenDayUsed: void 0,
133415
133562
  sevenDayResetAt: void 0,
133416
- providerQuotaWindows: []
133563
+ providerQuotaWindows: [],
133564
+ quotaFamilies: [],
133565
+ headroom: params.headroom
133417
133566
  };
133418
133567
  if (params.snapshot !== void 0) {
133419
133568
  const scopedName = providerScopedState(params.snapshot, params.providerName, params.env.AGENT_SHIM_PROVIDER);
@@ -133438,9 +133587,22 @@ function enrichStatuslinePayload(params) {
133438
133587
  }
133439
133588
  }
133440
133589
  const providerQuotaWindows = [...scopedState?.quota?.windows ?? []].sort((a10, b) => (a10.periodMs ?? Number.POSITIVE_INFINITY) - (b.periodMs ?? Number.POSITIVE_INFINITY)).map((window) => ({ measures: window.measures, utilization: window.utilization, resetsAt: window.resetsAt }));
133441
- summary = { ...summary, ...windowsOf(states), providerAccountEmail: email3, providerAccountSub: sub, providerPlan: plan, providerQuotaWindows };
133590
+ const providerBuckets = Object.fromEntries(
133591
+ (scopedState?.quota?.windows ?? []).map((window) => [
133592
+ window.measures,
133593
+ {
133594
+ remaining_fraction: 1 - window.utilization,
133595
+ ...window.resetsAt === void 0 ? {} : { reset_in_seconds: (Date.parse(window.resetsAt) - params.nowMs) / MS_PER_SECOND14 }
133596
+ }
133597
+ ])
133598
+ );
133599
+ summary = { ...summary, ...windowsOf(states), providerAccountEmail: email3, providerAccountSub: sub, providerPlan: plan, providerQuotaWindows, quotaFamilies: quotaFamiliesOf(providerBuckets, params.nowMs) };
133442
133600
  }
133443
133601
  if (summary.provider === void 0) {
133602
+ const agyBuckets = antigravityQuotaMapOf(params.payload);
133603
+ if (agyBuckets !== void 0) {
133604
+ summary = { ...summary, quotaFamilies: quotaFamiliesOf(agyBuckets, params.nowMs) };
133605
+ }
133444
133606
  for (const own2 of [antigravityWindowsOf(params.payload, params.nowMs), payloadWindowsOf(params.payload)]) {
133445
133607
  summary = {
133446
133608
  ...summary,
@@ -133486,6 +133648,7 @@ var TWENTY = 20;
133486
133648
  var RESERVED_COLUMNS = 4;
133487
133649
  var SEPARATOR2 = " | ";
133488
133650
  var FULL_PERCENT2 = 100;
133651
+ var ONE_PERCENT = 1;
133489
133652
  var USED_RED_AT = 0.9;
133490
133653
  var USED_YELLOW_AT = 0.7;
133491
133654
  var ESCAPE_CHAR_CODE = 27;
@@ -133543,14 +133706,30 @@ function formatDuration(seconds) {
133543
133706
  }
133544
133707
  return `${String(minutes)}m`;
133545
133708
  }
133709
+ function headroomText(stats) {
133710
+ if (stats === void 0) {
133711
+ return void 0;
133712
+ }
133713
+ const overall = stats.savingsPercent === void 0 ? void 0 : `${stats.savingsPercent.toFixed(stats.savingsPercent < ONE_PERCENT ? 2 : 1)}% overall`;
133714
+ const parts = [
133715
+ stats.tokensSaved === void 0 ? void 0 : `${formatTokens(stats.tokensSaved)} saved`,
133716
+ overall,
133717
+ stats.savingsUsd === void 0 ? void 0 : `$${stats.savingsUsd.toFixed(2)}`
133718
+ ].filter((part) => part !== void 0);
133719
+ return parts.length === 0 ? void 0 : `headroom ${parts.join(" \xB7 ")}`;
133720
+ }
133721
+ function cacheHitText(hitFraction) {
133722
+ const clamped = Math.max(0, Math.min(1, hitFraction));
133723
+ return ` (Cache: ${statusColor(clamped, false)}${(clamped * FULL_PERCENT2).toFixed(0)}%${RESET})`;
133724
+ }
133546
133725
  function cacheShareText(view) {
133547
133726
  const hitRatio = view.cacheHitRatio;
133548
133727
  if (hitRatio !== void 0 && Number.isFinite(hitRatio)) {
133549
- return ` (Cache: ${(Math.max(0, Math.min(1, hitRatio)) * FULL_PERCENT2).toFixed(0)}%)`;
133728
+ return cacheHitText(hitRatio);
133550
133729
  }
133551
133730
  const promptTotal = (view.cacheReadTokens ?? 0) + (view.freshInputTokens ?? 0);
133552
133731
  if (promptTotal > 0 && (view.cacheReadTokens ?? 0) > 0) {
133553
- return ` (Cache: ${((view.cacheReadTokens ?? 0) / promptTotal * FULL_PERCENT2).toFixed(0)}%)`;
133732
+ return cacheHitText((view.cacheReadTokens ?? 0) / promptTotal);
133554
133733
  }
133555
133734
  return "";
133556
133735
  }
@@ -133753,6 +133932,10 @@ function renderStatuslineBlock(summary, view, terminalWidth, nowMs) {
133753
133932
  if (summary.identity !== void 0 && summary.provider !== void 0 && summary.identity !== summary.providerAccountEmail && summary.identity !== summary.loginAccountEmail) {
133754
133933
  header.push(new Segment("static", summary.identity));
133755
133934
  }
133935
+ const savings = headroomText(summary.headroom);
133936
+ if (savings !== void 0) {
133937
+ header.push(new Segment("static", savings));
133938
+ }
133756
133939
  const contextGroup = [];
133757
133940
  if (view.contextUsedPercentage !== void 0) {
133758
133941
  const fraction = Math.max(0, Math.min(1, view.contextUsedPercentage / FULL_PERCENT2));
@@ -133763,22 +133946,26 @@ function renderStatuslineBlock(summary, view, terminalWidth, nowMs) {
133763
133946
  contextGroup.push(new Segment("bar", "", `Ctx ${tokens}`, ` ${percent2}${cache}`, fraction, true));
133764
133947
  }
133765
133948
  const quotaGroup = [];
133766
- if (summary.fiveHourUsed !== void 0) {
133767
- const fraction = Math.max(0, Math.min(1, summary.fiveHourUsed / FULL_PERCENT2));
133768
- const color = statusColor(fraction, true);
133769
- quotaGroup.push(new Segment("bar", "", "5h ", ` ${color}${summary.fiveHourUsed.toFixed(1)}%${RESET} (${formatDuration(secondsUntil(summary.fiveHourResetAt, nowMs))})`, fraction, true));
133770
- }
133771
- if (summary.sevenDayUsed !== void 0) {
133772
- const fraction = Math.max(0, Math.min(1, summary.sevenDayUsed / FULL_PERCENT2));
133773
- const color = statusColor(fraction, true);
133774
- quotaGroup.push(new Segment("bar", "", "Wk ", ` ${color}${summary.sevenDayUsed.toFixed(1)}%${RESET} (${formatDuration(secondsUntil(summary.sevenDayResetAt, nowMs))})`, fraction, true));
133775
- }
133776
- if (summary.fiveHourUsed === void 0 && summary.sevenDayUsed === void 0) {
133777
- for (const window of summary.providerQuotaWindows) {
133778
- const used = window.utilization * FULL_PERCENT2;
133779
- const fraction = Math.max(0, Math.min(1, window.utilization));
133780
- const color = statusColor(fraction, true);
133781
- quotaGroup.push(new Segment("bar", "", `${window.measures} `, ` ${color}${used.toFixed(1)}%${RESET} (${formatDuration(secondsUntil(window.resetsAt, nowMs))})`, fraction, true));
133949
+ const drawWindow = (label, fraction, resetsAt) => {
133950
+ const clamped = Math.max(0, Math.min(1, fraction));
133951
+ const color = statusColor(clamped, true);
133952
+ quotaGroup.push(new Segment("bar", "", `${label} `, ` ${color}${(fraction * FULL_PERCENT2).toFixed(1)}%${RESET} (${formatDuration(secondsUntil(resetsAt, nowMs))})`, clamped, true));
133953
+ };
133954
+ if (summary.quotaFamilies.length > 0) {
133955
+ for (const window of summary.quotaFamilies) {
133956
+ drawWindow(window.measures, window.utilization, window.resetsAt);
133957
+ }
133958
+ } else {
133959
+ if (summary.fiveHourUsed !== void 0) {
133960
+ drawWindow("5h", summary.fiveHourUsed / FULL_PERCENT2, summary.fiveHourResetAt);
133961
+ }
133962
+ if (summary.sevenDayUsed !== void 0) {
133963
+ drawWindow("Wk", summary.sevenDayUsed / FULL_PERCENT2, summary.sevenDayResetAt);
133964
+ }
133965
+ if (summary.fiveHourUsed === void 0 && summary.sevenDayUsed === void 0) {
133966
+ for (const window of summary.providerQuotaWindows) {
133967
+ drawWindow(window.measures, window.utilization, window.resetsAt);
133968
+ }
133782
133969
  }
133783
133970
  }
133784
133971
  const width = Math.max(TWENTY, terminalWidth - RESERVED_COLUMNS);
@@ -133882,7 +134069,11 @@ function registerStatuslineCommand(program2, deps) {
133882
134069
  }
133883
134070
  }
133884
134071
  const nowMs = Date.now();
133885
- const { payload: enriched, summary } = enrichStatuslinePayload({ payload, env: process.env, snapshot, account, providerName, nowMs });
134072
+ const socketTarget = headroomSocketTarget(realFarmFs, realHeadroomSocketTrust, deps.paths);
134073
+ const target = headroomTargetOf(process.env, socketTarget === void 0 || socketTarget.refused !== void 0 ? void 0 : socketTarget.socketPath);
134074
+ const sessionId = headroomSessionIdOf(payload, process.env);
134075
+ const headroom = target === void 0 || sessionId === void 0 ? void 0 : await fetchHeadroomSessionStats(realHeadroomGet, target, sessionId);
134076
+ const { payload: enriched, summary } = enrichStatuslinePayload({ payload, env: process.env, snapshot, account, providerName, nowMs, headroom });
133886
134077
  const renderer = process.env.AGENT_SHIM_STATUSLINE_CMD;
133887
134078
  if (renderer !== void 0 && renderer !== "") {
133888
134079
  const child = (0, import_node_child_process7.spawn)("/bin/sh", ["-c", renderer], { stdio: ["pipe", "inherit", "inherit"] });
@@ -144181,7 +144372,7 @@ function registerDoctorCommand(program2, deps) {
144181
144372
 
144182
144373
  // src/headroom/commands.ts
144183
144374
  var import_node_fs22 = __toESM(require("node:fs"), 1);
144184
- var import_node_http4 = __toESM(require("node:http"), 1);
144375
+ var import_node_http5 = __toESM(require("node:http"), 1);
144185
144376
  var import_node_path56 = __toESM(require("node:path"), 1);
144186
144377
  var import_node_child_process9 = require("node:child_process");
144187
144378
  init_commandDeps();
@@ -144353,7 +144544,7 @@ function headroomProxyArgs(socketPath, allowlistFile, settings2) {
144353
144544
  }
144354
144545
  async function readyOverSocket(socketPath) {
144355
144546
  return await new Promise((resolve2) => {
144356
- const probe = import_node_http4.default.get({ socketPath, path: "/readyz", timeout: READY_FETCH_TIMEOUT_MS }, (response) => {
144547
+ const probe = import_node_http5.default.get({ socketPath, path: "/readyz", timeout: READY_FETCH_TIMEOUT_MS }, (response) => {
144357
144548
  response.resume();
144358
144549
  resolve2(response.statusCode === HTTP_STATUS.ok);
144359
144550
  });
@@ -144923,7 +145114,7 @@ function registerProviderCommand(program2, deps) {
144923
145114
  new Option("--credential-target <target>", "Where the token goes: bearer sets ANTHROPIC_AUTH_TOKEN (default), apiKey sets ANTHROPIC_API_KEY.").choices(
144924
145115
  PROVIDER_CREDENTIAL_TARGETS
144925
145116
  )
144926
- ).option("--env <KEY=VALUE>", "Extra environment entry for the child (repeatable).", collectStringPair).option("--codex-default-model <model>", "Codex providers: the codex model a request maps to when no tier matches.").option("--codex-model <tier=model>", "Codex providers: the codex model one tier (fable, opus, sonnet or haiku) maps to (repeatable).", collectStringPair).addOption(new Option("--codex-effort <effort>", "Codex providers: the reasoning effort when a request asks for none the backend accepts.").choices(CODEX_EFFORTS)).addOption(new Option("--codex-login <login>", "Codex providers: which login the upstream call uses, the Codex CLI's own login or a Sign in with ChatGPT grant from `agent-shim codex login`.").choices(CODEX_LOGINS)).addOption(new Option("--antigravity-mode <mode>", "Antigravity providers: cloud (direct Gemini/Vertex) or local (ACP daemon).").choices(ANTIGRAVITY_MODES)).option("--antigravity-default-model <model>", "Antigravity providers: the model a request maps to when no tier matches.").option("--antigravity-model <tier=model>", "Antigravity providers: the model one tier (fable, opus, sonnet or haiku) maps to (repeatable).", collectStringPair).addOption(new Option("--antigravity-effort <effort>", "Antigravity providers: reasoning effort.").choices(ANTIGRAVITY_EFFORTS)).option("--antigravity-endpoint <url>", "Antigravity cloud providers: custom API endpoint URL.").option("--antigravity-project-id <id>", "Antigravity cloud providers: Google Cloud project ID (for Vertex AI).").option("--antigravity-location <loc>", "Antigravity cloud providers: Google Cloud location (for Vertex AI).").option("--antigravity-command <cmd...>", "Antigravity local providers: command to spawn ACP server.", collectRepeated).option("--antigravity-socket <path>", "Antigravity local providers: path to existing Unix domain socket.").option("--json", "Print the result as JSON.").action((name, options) => {
145117
+ ).option("--env <KEY=VALUE>", "Extra environment entry for the child (repeatable).", collectStringPair).option("--codex-default-model <model>", "Codex providers: the codex model a request maps to when no tier matches.").option("--codex-model <tier=model>", "Codex providers: the codex model one tier (fable, opus, sonnet or haiku) maps to (repeatable).", collectStringPair).addOption(new Option("--codex-effort <effort>", "Codex providers: the reasoning effort when a request asks for none the backend accepts.").choices(CODEX_EFFORTS)).addOption(new Option("--codex-login <login>", "Codex providers: which login the upstream call uses, the Codex CLI's own login or a Sign in with ChatGPT grant from `agent-shim codex login`.").choices(CODEX_LOGINS)).addOption(new Option("--antigravity-mode <mode>", "Antigravity providers: cloud (direct Gemini/Vertex) or local (ACP daemon).").choices(ANTIGRAVITY_MODES)).option("--antigravity-default-model <model>", "Antigravity providers: the model a request maps to when no tier matches.").option("--antigravity-model <tier=model>", "Antigravity providers: the model a tier (fable, opus, sonnet or haiku, matched by substring) or an alias (any other name, matched whole, selectable with /model) maps to (repeatable).", collectStringPair).addOption(new Option("--antigravity-effort <effort>", "Antigravity providers: reasoning effort.").choices(ANTIGRAVITY_EFFORTS)).option("--antigravity-endpoint <url>", "Antigravity cloud providers: custom API endpoint URL.").option("--antigravity-project-id <id>", "Antigravity cloud providers: Google Cloud project ID (for Vertex AI).").option("--antigravity-location <loc>", "Antigravity cloud providers: Google Cloud location (for Vertex AI).").option("--antigravity-command <cmd...>", "Antigravity local providers: command to spawn ACP server.", collectRepeated).option("--antigravity-socket <path>", "Antigravity local providers: path to existing Unix domain socket.").option("--json", "Print the result as JSON.").action((name, options) => {
144927
145118
  const codex = codexConfigFromOptions(options);
144928
145119
  const antigravity = antigravityConfigFromOptions(options);
144929
145120
  const created = addProvider(paths, name, {
@@ -145035,6 +145226,9 @@ function registerProviderCommand(program2, deps) {
145035
145226
  const config2 = resolveAntigravityConfig(found.antigravity);
145036
145227
  console.log(`Antigravity mode: ${config2.mode}`);
145037
145228
  console.log(`Antigravity models: ${ANTIGRAVITY_TIERS.map((tier) => `${tier}=${config2.models[tier]}`).join(", ")}, otherwise ${config2.defaultModel}`);
145229
+ if (config2.aliases.size > 0) {
145230
+ console.log(`Antigravity aliases: ${[...config2.aliases].map(([alias, model]) => `${alias}=${model}`).join(", ")}`);
145231
+ }
145038
145232
  console.log(`Antigravity effort: ${config2.effort}`);
145039
145233
  console.log(`Endpoint: ${describeProviderEndpoint(found)}`);
145040
145234
  } else {
package/dist/index.cjs CHANGED
@@ -356,13 +356,8 @@ var init_schema = __esm({
356
356
  mode: import_zod.z.enum(ANTIGRAVITY_MODES).optional(),
357
357
  /** The model a request maps to when no tier matches its model name. */
358
358
  defaultModel: import_zod.z.string().min(1).optional(),
359
- /** Per-tier overrides of the shipped mapping, matched by substring of the requested model name in `ANTIGRAVITY_TIERS` order. */
360
- models: import_zod.z.strictObject({
361
- fable: import_zod.z.string().min(1).optional(),
362
- opus: import_zod.z.string().min(1).optional(),
363
- sonnet: import_zod.z.string().min(1).optional(),
364
- haiku: import_zod.z.string().min(1).optional()
365
- }).optional(),
359
+ /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. */
360
+ models: import_zod.z.record(import_zod.z.string().min(1), import_zod.z.string().min(1)).optional(),
366
361
  /** The reasoning effort used when the request's own effort is not one the backend accepts. */
367
362
  effort: import_zod.z.enum(ANTIGRAVITY_EFFORTS).optional(),
368
363
  /** Cloud-specific settings (for `mode: "cloud"`). */
@@ -2841,7 +2836,7 @@ var init_package = __esm({
2841
2836
  "package.json"() {
2842
2837
  package_default = {
2843
2838
  name: "claude-use",
2844
- version: "11.14.0",
2839
+ version: "11.16.0",
2845
2840
  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
2841
  license: "MIT",
2847
2842
  author: "Joseph Mearman <joseph@mearman.co.uk>",
package/dist/index.mjs CHANGED
@@ -334,13 +334,8 @@ var init_schema = __esm({
334
334
  mode: z.enum(ANTIGRAVITY_MODES).optional(),
335
335
  /** The model a request maps to when no tier matches its model name. */
336
336
  defaultModel: z.string().min(1).optional(),
337
- /** Per-tier overrides of the shipped mapping, matched by substring of the requested model name in `ANTIGRAVITY_TIERS` order. */
338
- models: z.strictObject({
339
- fable: z.string().min(1).optional(),
340
- opus: z.string().min(1).optional(),
341
- sonnet: z.string().min(1).optional(),
342
- haiku: z.string().min(1).optional()
343
- }).optional(),
337
+ /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. */
338
+ models: z.record(z.string().min(1), z.string().min(1)).optional(),
344
339
  /** The reasoning effort used when the request's own effort is not one the backend accepts. */
345
340
  effort: z.enum(ANTIGRAVITY_EFFORTS).optional(),
346
341
  /** Cloud-specific settings (for `mode: "cloud"`). */
@@ -2817,7 +2812,7 @@ var init_package = __esm({
2817
2812
  "package.json"() {
2818
2813
  package_default = {
2819
2814
  name: "claude-use",
2820
- version: "11.14.0",
2815
+ version: "11.16.0",
2821
2816
  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
2817
  license: "MIT",
2823
2818
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -390,12 +390,7 @@ declare const AntigravityProviderConfigSchema: z.ZodObject<{
390
390
  local: "local";
391
391
  }>>;
392
392
  defaultModel: z.ZodOptional<z.ZodString>;
393
- models: z.ZodOptional<z.ZodObject<{
394
- fable: z.ZodOptional<z.ZodString>;
395
- opus: z.ZodOptional<z.ZodString>;
396
- sonnet: z.ZodOptional<z.ZodString>;
397
- haiku: z.ZodOptional<z.ZodString>;
398
- }, z.core.$strict>>;
393
+ models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
399
394
  effort: z.ZodOptional<z.ZodEnum<{
400
395
  none: "none";
401
396
  max: "max";
@@ -661,12 +656,7 @@ declare const ProviderSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
661
656
  local: "local";
662
657
  }>>;
663
658
  defaultModel: z.ZodOptional<z.ZodString>;
664
- models: z.ZodOptional<z.ZodObject<{
665
- fable: z.ZodOptional<z.ZodString>;
666
- opus: z.ZodOptional<z.ZodString>;
667
- sonnet: z.ZodOptional<z.ZodString>;
668
- haiku: z.ZodOptional<z.ZodString>;
669
- }, z.core.$strict>>;
659
+ models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
670
660
  effort: z.ZodOptional<z.ZodEnum<{
671
661
  none: "none";
672
662
  max: "max";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-use",
3
- "version": "11.14.0",
3
+ "version": "11.16.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>",