agent-shim 9.2.0 → 9.3.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
@@ -32540,7 +32540,7 @@ function isRateLimitHeader(name) {
32540
32540
  const lower = name.toLowerCase();
32541
32541
  return lower === "retry-after" || lower.startsWith("anthropic-ratelimit-") || lower.startsWith("x-ratelimit-") || lower.startsWith("ratelimit") || lower.startsWith("x-codex-");
32542
32542
  }
32543
- var USAGE_SCHEMA_VERSION, VersionSchema, InstantSchema, TokenCountSchema, TokenUsageSchema, LIMIT_KINDS, LimitClassificationSchema, UsageRecordSchema, QuotaWindowSchema, UnifiedRateLimitSchema, RateLimitStateSchema, LimitEventSchema, ProviderQuotaWindowSchema, ProviderQuotaSchema, ProviderUsageStateSchema, AccountMetadataSchema, UsageSnapshotSchema;
32543
+ var USAGE_SCHEMA_VERSION, VersionSchema, InstantSchema, TokenCountSchema, TokenUsageSchema, LIMIT_KINDS, LimitClassificationSchema, UsageRecordSchema, QuotaWindowSchema, ExtraUsageSpendSchema, UnifiedRateLimitSchema, RateLimitStateSchema, LimitEventSchema, ProviderQuotaWindowSchema, ProviderQuotaSchema, ProviderUsageStateSchema, AccountMetadataSchema, UsageSnapshotSchema;
32544
32544
  var init_schema2 = __esm({
32545
32545
  "src/usage/schema.ts"() {
32546
32546
  "use strict";
@@ -32605,13 +32605,25 @@ var init_schema2 = __esm({
32605
32605
  utilization: external_exports.number().nonnegative().optional(),
32606
32606
  resetsAt: InstantSchema.optional(),
32607
32607
  /** The window's own status (`allowed`, `allowed_warning`, `rejected`). */
32608
- status: external_exports.string().optional()
32608
+ status: external_exports.string().optional(),
32609
+ /** The fraction of the window's grace allowance used, while the upstream reports the window in grace (the five-hour window only). Requests are served beyond the window's own full mark while it grows, but refusals have been seen at a small value, so nothing ranks on it. */
32610
+ graceUtilization: external_exports.number().nonnegative().optional()
32611
+ });
32612
+ ExtraUsageSpendSchema = external_exports.strictObject({
32613
+ /** Spent so far in the allowance's period, in the currency's minor units (pence, cents). */
32614
+ usedMinor: external_exports.number().nonnegative(),
32615
+ /** The allowance's cap in the same units, when it has one. */
32616
+ limitMinor: external_exports.number().nonnegative().optional(),
32617
+ /** The ISO 4217 currency code. */
32618
+ currency: external_exports.string()
32609
32619
  });
32610
32620
  UnifiedRateLimitSchema = external_exports.strictObject({
32611
32621
  /** The overall status: `allowed`, `allowed_warning` or `rejected`. */
32612
32622
  status: external_exports.string().optional(),
32613
32623
  fiveHour: QuotaWindowSchema.optional(),
32614
32624
  sevenDay: QuotaWindowSchema.optional(),
32625
+ /** The weekly window of the models whose usage may continue as extra usage (`7d_oi`), reported by some plans beside the all-models weekly window. */
32626
+ sevenDayOverageIncluded: QuotaWindowSchema.optional(),
32615
32627
  /** The window that currently binds. */
32616
32628
  representativeClaim: external_exports.string().optional(),
32617
32629
  /** When the binding window resets. */
@@ -32623,13 +32635,21 @@ var init_schema2 = __esm({
32623
32635
  /** When the extra-usage allowance resets. */
32624
32636
  overageResetsAt: InstantSchema.optional(),
32625
32637
  /** Why extra usage is unavailable, as the upstream names it (`out_of_credits`, for one). */
32626
- overageDisabledReason: external_exports.string().optional()
32638
+ overageDisabledReason: external_exports.string().optional(),
32639
+ /** Whether the response was served on extra usage, as the upstream states it. */
32640
+ overageInUse: external_exports.boolean().optional(),
32641
+ /** The allowance in money, from the usage endpoint (the response headers state only the fraction). */
32642
+ extraUsageSpend: ExtraUsageSpendSchema.optional(),
32643
+ /** True when the upstream offers a fallback while a window is rejected: some requests, by model, are still served, though the rest are refused. */
32644
+ fallbackAvailable: external_exports.boolean().optional()
32627
32645
  });
32628
32646
  RateLimitStateSchema = external_exports.strictObject({
32629
32647
  observedAt: InstantSchema,
32630
32648
  /** Every quota and rate-limit header on that response, by name. */
32631
32649
  headers: external_exports.record(external_exports.string(), external_exports.string()),
32632
- unified: UnifiedRateLimitSchema.optional()
32650
+ unified: UnifiedRateLimitSchema.optional(),
32651
+ /** When the usage endpoint last answered that it has no plan windows for the account, which a later response replaces. Its answer leaves the recorded `unified` state alone (a response's headers may be the only source of it), so this alone says the question was asked. */
32652
+ planWindowsUnavailableAt: InstantSchema.optional()
32633
32653
  });
32634
32654
  LimitEventSchema = LimitClassificationSchema.extend({
32635
32655
  observedAt: InstantSchema,
@@ -32723,6 +32743,13 @@ function nonNegativeNumber(value2) {
32723
32743
  const parsed = Number(value2);
32724
32744
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
32725
32745
  }
32746
+ function booleanHeader(value2) {
32747
+ return value2 === "true" ? true : value2 === "false" ? false : void 0;
32748
+ }
32749
+ function withGrace(window, headers) {
32750
+ const graceUtilization = headers[`${UNIFIED_PREFIX}grace-status`] === "active" ? nonNegativeNumber(headers[`${UNIFIED_PREFIX}grace-5h-utilization`]) : void 0;
32751
+ return window === void 0 || graceUtilization === void 0 ? window : { ...window, graceUtilization };
32752
+ }
32726
32753
  function unifiedWindow(headers, window) {
32727
32754
  const utilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}${window}-utilization`]);
32728
32755
  const resetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}${window}-reset`]);
@@ -32737,33 +32764,39 @@ function parseUnifiedRateLimit(headers) {
32737
32764
  return void 0;
32738
32765
  }
32739
32766
  const status = headers[`${UNIFIED_PREFIX}status`];
32740
- const fiveHour = unifiedWindow(headers, "5h");
32767
+ const fiveHour = withGrace(unifiedWindow(headers, "5h"), headers);
32741
32768
  const sevenDay = unifiedWindow(headers, "7d");
32769
+ const sevenDayOverageIncluded = unifiedWindow(headers, "7d_oi");
32742
32770
  const representativeClaim = headers[`${UNIFIED_PREFIX}representative-claim`];
32743
32771
  const resetAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}reset`]);
32744
32772
  const overageStatus = headers[`${UNIFIED_PREFIX}overage-status`];
32745
32773
  const overageUtilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}overage-utilization`]);
32746
32774
  const overageResetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}overage-reset`]);
32747
32775
  const overageDisabledReason = headers[`${UNIFIED_PREFIX}overage-disabled-reason`];
32776
+ const overageInUse = booleanHeader(headers[`${UNIFIED_PREFIX}overage-in-use`]);
32748
32777
  return {
32749
32778
  ...status === void 0 ? {} : { status },
32750
32779
  ...fiveHour === void 0 ? {} : { fiveHour },
32751
32780
  ...sevenDay === void 0 ? {} : { sevenDay },
32781
+ ...sevenDayOverageIncluded === void 0 ? {} : { sevenDayOverageIncluded },
32752
32782
  ...representativeClaim === void 0 ? {} : { representativeClaim },
32753
32783
  ...resetAt === void 0 ? {} : { resetAt },
32754
32784
  ...overageStatus === void 0 ? {} : { overageStatus },
32755
32785
  ...overageUtilization === void 0 ? {} : { overageUtilization },
32756
32786
  ...overageResetsAt === void 0 ? {} : { overageResetsAt },
32757
- ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
32787
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason },
32788
+ ...overageInUse === void 0 ? {} : { overageInUse },
32789
+ ...headers[`${UNIFIED_PREFIX}fallback`] === "available" ? { fallbackAvailable: true } : {}
32758
32790
  };
32759
32791
  }
32760
32792
  function overageFactsOf(unified) {
32761
- const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason } = unified;
32793
+ const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason, overageInUse } = unified;
32762
32794
  return {
32763
32795
  ...overageStatus === void 0 ? {} : { overageStatus },
32764
32796
  ...overageUtilization === void 0 ? {} : { overageUtilization },
32765
32797
  ...overageResetsAt === void 0 ? {} : { overageResetsAt },
32766
- ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
32798
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason },
32799
+ ...overageInUse === void 0 ? {} : { overageInUse }
32767
32800
  };
32768
32801
  }
32769
32802
  function overageWindowOf(unified) {
@@ -33191,7 +33224,7 @@ var init_package = __esm({
33191
33224
  "package.json"() {
33192
33225
  package_default = {
33193
33226
  name: "agent-shim",
33194
- version: "9.2.0",
33227
+ version: "9.3.0",
33195
33228
  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.",
33196
33229
  license: "MIT",
33197
33230
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -33377,7 +33410,11 @@ var init_account = __esm({
33377
33410
 
33378
33411
  // src/usage/plan.ts
33379
33412
  function planOf(account) {
33380
- const tier = account?.organizationRateLimitTier ?? account?.userRateLimitTier;
33413
+ const userTier = account?.userRateLimitTier;
33414
+ if (userTier !== void 0 && ZERO_TIER.test(userTier)) {
33415
+ return { kind: "pay-per-use", tier: userTier };
33416
+ }
33417
+ const tier = account?.organizationRateLimitTier ?? userTier;
33381
33418
  const tierField = tier === void 0 ? {} : { tier };
33382
33419
  if (tier === void 0) {
33383
33420
  return { kind: "subscription", capacity: 1, recognised: false };
@@ -34039,7 +34076,7 @@ function assessIdentity(member, nowMs) {
34039
34076
  if (unified.overageStatus === "allowed") {
34040
34077
  return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
34041
34078
  }
34042
- return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...windowReasons, ...overageReasons, ...planReasons] } };
34079
+ return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...unified.fallbackAvailable === true ? ["a fallback is on offer, so requests for some models may still be served"] : [], ...windowReasons, ...overageReasons, ...planReasons] } };
34043
34080
  }
34044
34081
  if (plan.kind === "pay-per-use" || fiveHourWindow === void 0 && sevenDayWindow === void 0) {
34045
34082
  const headroom = overage?.utilization === void 0 ? void 0 : Math.max(0, 1 - overage.utilization);
@@ -34438,9 +34475,8 @@ function createUsageStore(deps) {
34438
34475
  recordRateLimit: (identity, provider, rateLimit) => rewriteSnapshot(identity, (current) => {
34439
34476
  const state = current?.providers[provider] ?? {};
34440
34477
  const keep = state.rateLimit !== void 0 && state.rateLimit.observedAt.localeCompare(rateLimit.observedAt) > 0;
34441
- const earlier = state.rateLimit?.unified;
34442
- const carried = rateLimit.unified === void 0 || rateLimit.unified.overageStatus !== void 0 || earlier === void 0 ? void 0 : overageFactsOf(earlier);
34443
- const merged = carried === void 0 || rateLimit.unified === void 0 ? rateLimit : { ...rateLimit, unified: { ...rateLimit.unified, ...carried } };
34478
+ const earlier = state.rateLimit;
34479
+ const merged = rateLimit.unified === void 0 ? { ...earlier ?? rateLimit, planWindowsUnavailableAt: rateLimit.observedAt } : { ...rateLimit, unified: { ...earlier?.unified === void 0 ? {} : overageFactsOf(earlier.unified), ...rateLimit.unified } };
34444
34480
  return { ...current?.providers, [provider]: { ...state, rateLimit: keep ? state.rateLimit : merged } };
34445
34481
  })
34446
34482
  };
@@ -60957,22 +60993,38 @@ function windowOf(reported) {
60957
60993
  ...utilization !== void 0 && utilization >= 1 ? { status: "rejected" } : {}
60958
60994
  };
60959
60995
  }
60996
+ function extraUsageOf(reported) {
60997
+ const extra = reported?.extra_usage;
60998
+ if (extra === null || extra === void 0) {
60999
+ return void 0;
61000
+ }
61001
+ const utilization = extra.utilization === null ? void 0 : extra.utilization / PERCENT2;
61002
+ const currency = extra.currency ?? void 0;
61003
+ const spend = extra.used_credits === null || currency === void 0 ? void 0 : { usedMinor: extra.used_credits, ...extra.monthly_limit === null ? {} : { limitMinor: extra.monthly_limit }, currency };
61004
+ return {
61005
+ overageStatus: !extra.is_enabled || utilization !== void 0 && utilization >= 1 ? "rejected" : "allowed",
61006
+ ...utilization === void 0 ? {} : { overageUtilization: utilization },
61007
+ ...spend === void 0 ? {} : { extraUsageSpend: spend }
61008
+ };
61009
+ }
60960
61010
  function unifiedFromReportedLimits(reported) {
60961
61011
  const fiveHour = windowOf(reported?.five_hour);
60962
61012
  const sevenDay = windowOf(reported?.seven_day);
60963
- if (fiveHour === void 0 && sevenDay === void 0) {
61013
+ const extraUsage = extraUsageOf(reported);
61014
+ if (fiveHour === void 0 && sevenDay === void 0 && extraUsage === void 0) {
60964
61015
  return void 0;
60965
61016
  }
60966
- return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay } };
61017
+ return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay }, ...extraUsage };
60967
61018
  }
60968
61019
  function isAnthropicUsageProbeable(member) {
60969
- const unified = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified;
60970
- return planOf(member.account ?? member.snapshot?.account).kind === "subscription" && (unified === void 0 || soleOverageWindow(unified) === void 0);
61020
+ return planOf(member.account ?? member.snapshot?.account).kind === "subscription";
60971
61021
  }
60972
61022
  function isAnthropicUsageStale(member, nowMs) {
60973
61023
  const rateLimit = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit;
60974
- const freshnessMs = rateLimit?.unified === void 0 ? NO_PLAN_WINDOWS_FRESHNESS_MS : ANTHROPIC_USAGE_FRESHNESS_MS;
60975
- return isAnthropicUsageProbeable(member) && (rateLimit === void 0 || nowMs - Date.parse(rateLimit.observedAt) >= freshnessMs);
61024
+ const answeredNothing = rateLimit?.unified === void 0 || rateLimit.planWindowsUnavailableAt !== void 0;
61025
+ const freshnessMs = answeredNothing ? NO_PLAN_WINDOWS_FRESHNESS_MS : ANTHROPIC_USAGE_FRESHNESS_MS;
61026
+ const checkedAt = rateLimit === void 0 ? void 0 : Date.parse(rateLimit.planWindowsUnavailableAt ?? rateLimit.observedAt);
61027
+ return isAnthropicUsageProbeable(member) && (checkedAt === void 0 || nowMs - checkedAt >= freshnessMs);
60976
61028
  }
60977
61029
  function poolIdentityNames(pools, poolName) {
60978
61030
  const seenPools = /* @__PURE__ */ new Set();
@@ -61053,7 +61105,6 @@ var init_anthropicUsageRefresh = __esm({
61053
61105
  init_middleware();
61054
61106
  init_pick();
61055
61107
  init_plan2();
61056
- init_rateLimit();
61057
61108
  PERCENT2 = 100;
61058
61109
  ANTHROPIC_USAGE_FRESHNESS_MS = FIVE_HOUR_WINDOW_MS / PERCENT2;
61059
61110
  NO_PLAN_WINDOWS_FRESHNESS_MS = SEVEN_DAY_WINDOW_MS / PERCENT2;
@@ -119099,26 +119150,40 @@ function collectUsageReport(fs21, paths, filters) {
119099
119150
  };
119100
119151
  }
119101
119152
  var PERCENT4 = 100;
119153
+ var DECIMAL_RADIX = 10;
119102
119154
  function formatWindow(label, window) {
119103
119155
  if (window === void 0) {
119104
119156
  return void 0;
119105
119157
  }
119106
119158
  const used = window.utilization === void 0 ? "usage unknown" : `${String(Math.round(window.utilization * PERCENT4))}% used`;
119107
- return `${label} ${used}${window.resetsAt === void 0 ? "" : `, resets ${window.resetsAt}`}${window.status === void 0 ? "" : ` (${window.status})`}`;
119159
+ const grace = window.graceUtilization === void 0 ? "" : `, in grace, ${String(Math.round(window.graceUtilization * PERCENT4))}% of the allowance used`;
119160
+ return `${label} ${used}${grace}${window.resetsAt === void 0 ? "" : `, resets ${window.resetsAt}`}${window.status === void 0 ? "" : ` (${window.status})`}`;
119161
+ }
119162
+ function formatMoney(minor, currency) {
119163
+ const format = new Intl.NumberFormat("en-GB", { style: "currency", currency });
119164
+ const { maximumFractionDigits } = format.resolvedOptions();
119165
+ return format.format(minor / DECIMAL_RADIX ** (maximumFractionDigits ?? 0));
119108
119166
  }
119109
119167
  function extraUsageParts(unified) {
119110
119168
  const window = overageWindowOf(unified);
119111
119169
  const measured = window?.utilization !== void 0 || window?.resetsAt !== void 0;
119112
119170
  const fact = window === void 0 ? void 0 : measured ? formatWindow("extra usage", window) : `extra usage ${window.status ?? "unknown"}`;
119113
- return [...fact === void 0 ? [] : [fact], ...unified.overageDisabledReason === void 0 ? [] : [`extra usage disabled: ${unified.overageDisabledReason}`]];
119171
+ const spend = unified.extraUsageSpend;
119172
+ const money = spend === void 0 ? void 0 : `extra usage spend ${formatMoney(spend.usedMinor, spend.currency)}${spend.limitMinor === void 0 ? "" : ` of ${formatMoney(spend.limitMinor, spend.currency)}`}`;
119173
+ return [
119174
+ ...fact === void 0 ? [] : [fact],
119175
+ ...money === void 0 ? [] : [money],
119176
+ ...unified.overageInUse === true ? ["served on extra usage"] : [],
119177
+ ...unified.overageDisabledReason === void 0 ? [] : [`extra usage disabled: ${unified.overageDisabledReason}`]
119178
+ ];
119114
119179
  }
119115
119180
  function formatRateLimit(state) {
119116
119181
  const { unified } = state;
119117
119182
  if (unified === void 0) {
119118
119183
  return `rate-limit headers (as of ${state.observedAt}): ${Object.entries(state.headers).map(([name, value2]) => `${name}=${value2}`).join(", ")}`;
119119
119184
  }
119120
- const parts = [formatWindow("5h", unified.fiveHour), formatWindow("7d", unified.sevenDay)].filter((part) => part !== void 0);
119121
- return `quota (as of ${state.observedAt}): ${[...parts, `status ${unified.status ?? "unknown"}`, ...extraUsageParts(unified)].join("; ")}`;
119185
+ const parts = [formatWindow("5h", unified.fiveHour), formatWindow("7d", unified.sevenDay), formatWindow("7d overage-included", unified.sevenDayOverageIncluded)].filter((part) => part !== void 0);
119186
+ return `quota (as of ${state.observedAt}): ${[...parts, `status ${unified.status ?? "unknown"}`, ...unified.fallbackAvailable === true ? ["fallback available"] : [], ...extraUsageParts(unified)].join("; ")}`;
119122
119187
  }
119123
119188
  function formatLimit(limit) {
119124
119189
  const wait2 = [
package/dist/index.cjs CHANGED
@@ -2649,7 +2649,7 @@ var init_package = __esm({
2649
2649
  "package.json"() {
2650
2650
  package_default = {
2651
2651
  name: "agent-shim",
2652
- version: "9.2.0",
2652
+ version: "9.3.0",
2653
2653
  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.",
2654
2654
  license: "MIT",
2655
2655
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4025,7 +4025,7 @@ var init_identity = __esm({
4025
4025
  });
4026
4026
 
4027
4027
  // src/usage/schema.ts
4028
- var import_zod7, USAGE_SCHEMA_VERSION, VersionSchema, InstantSchema, TokenCountSchema, TokenUsageSchema, LIMIT_KINDS, LimitClassificationSchema, UsageRecordSchema, QuotaWindowSchema, UnifiedRateLimitSchema, RateLimitStateSchema, LimitEventSchema, ProviderQuotaWindowSchema, ProviderQuotaSchema, ProviderUsageStateSchema, AccountMetadataSchema, UsageSnapshotSchema;
4028
+ var import_zod7, USAGE_SCHEMA_VERSION, VersionSchema, InstantSchema, TokenCountSchema, TokenUsageSchema, LIMIT_KINDS, LimitClassificationSchema, UsageRecordSchema, QuotaWindowSchema, ExtraUsageSpendSchema, UnifiedRateLimitSchema, RateLimitStateSchema, LimitEventSchema, ProviderQuotaWindowSchema, ProviderQuotaSchema, ProviderUsageStateSchema, AccountMetadataSchema, UsageSnapshotSchema;
4029
4029
  var init_schema2 = __esm({
4030
4030
  "src/usage/schema.ts"() {
4031
4031
  "use strict";
@@ -4090,13 +4090,25 @@ var init_schema2 = __esm({
4090
4090
  utilization: import_zod7.z.number().nonnegative().optional(),
4091
4091
  resetsAt: InstantSchema.optional(),
4092
4092
  /** The window's own status (`allowed`, `allowed_warning`, `rejected`). */
4093
- status: import_zod7.z.string().optional()
4093
+ status: import_zod7.z.string().optional(),
4094
+ /** The fraction of the window's grace allowance used, while the upstream reports the window in grace (the five-hour window only). Requests are served beyond the window's own full mark while it grows, but refusals have been seen at a small value, so nothing ranks on it. */
4095
+ graceUtilization: import_zod7.z.number().nonnegative().optional()
4096
+ });
4097
+ ExtraUsageSpendSchema = import_zod7.z.strictObject({
4098
+ /** Spent so far in the allowance's period, in the currency's minor units (pence, cents). */
4099
+ usedMinor: import_zod7.z.number().nonnegative(),
4100
+ /** The allowance's cap in the same units, when it has one. */
4101
+ limitMinor: import_zod7.z.number().nonnegative().optional(),
4102
+ /** The ISO 4217 currency code. */
4103
+ currency: import_zod7.z.string()
4094
4104
  });
4095
4105
  UnifiedRateLimitSchema = import_zod7.z.strictObject({
4096
4106
  /** The overall status: `allowed`, `allowed_warning` or `rejected`. */
4097
4107
  status: import_zod7.z.string().optional(),
4098
4108
  fiveHour: QuotaWindowSchema.optional(),
4099
4109
  sevenDay: QuotaWindowSchema.optional(),
4110
+ /** The weekly window of the models whose usage may continue as extra usage (`7d_oi`), reported by some plans beside the all-models weekly window. */
4111
+ sevenDayOverageIncluded: QuotaWindowSchema.optional(),
4100
4112
  /** The window that currently binds. */
4101
4113
  representativeClaim: import_zod7.z.string().optional(),
4102
4114
  /** When the binding window resets. */
@@ -4108,13 +4120,21 @@ var init_schema2 = __esm({
4108
4120
  /** When the extra-usage allowance resets. */
4109
4121
  overageResetsAt: InstantSchema.optional(),
4110
4122
  /** Why extra usage is unavailable, as the upstream names it (`out_of_credits`, for one). */
4111
- overageDisabledReason: import_zod7.z.string().optional()
4123
+ overageDisabledReason: import_zod7.z.string().optional(),
4124
+ /** Whether the response was served on extra usage, as the upstream states it. */
4125
+ overageInUse: import_zod7.z.boolean().optional(),
4126
+ /** The allowance in money, from the usage endpoint (the response headers state only the fraction). */
4127
+ extraUsageSpend: ExtraUsageSpendSchema.optional(),
4128
+ /** True when the upstream offers a fallback while a window is rejected: some requests, by model, are still served, though the rest are refused. */
4129
+ fallbackAvailable: import_zod7.z.boolean().optional()
4112
4130
  });
4113
4131
  RateLimitStateSchema = import_zod7.z.strictObject({
4114
4132
  observedAt: InstantSchema,
4115
4133
  /** Every quota and rate-limit header on that response, by name. */
4116
4134
  headers: import_zod7.z.record(import_zod7.z.string(), import_zod7.z.string()),
4117
- unified: UnifiedRateLimitSchema.optional()
4135
+ unified: UnifiedRateLimitSchema.optional(),
4136
+ /** When the usage endpoint last answered that it has no plan windows for the account, which a later response replaces. Its answer leaves the recorded `unified` state alone (a response's headers may be the only source of it), so this alone says the question was asked. */
4137
+ planWindowsUnavailableAt: InstantSchema.optional()
4118
4138
  });
4119
4139
  LimitEventSchema = LimitClassificationSchema.extend({
4120
4140
  observedAt: InstantSchema,
@@ -4268,7 +4288,11 @@ var init_account = __esm({
4268
4288
 
4269
4289
  // src/usage/plan.ts
4270
4290
  function planOf(account) {
4271
- const tier = account?.organizationRateLimitTier ?? account?.userRateLimitTier;
4291
+ const userTier = account?.userRateLimitTier;
4292
+ if (userTier !== void 0 && ZERO_TIER.test(userTier)) {
4293
+ return { kind: "pay-per-use", tier: userTier };
4294
+ }
4295
+ const tier = account?.organizationRateLimitTier ?? userTier;
4272
4296
  const tierField = tier === void 0 ? {} : { tier };
4273
4297
  if (tier === void 0) {
4274
4298
  return { kind: "subscription", capacity: 1, recognised: false };
@@ -4323,6 +4347,13 @@ function nonNegativeNumber(value) {
4323
4347
  const parsed = Number(value);
4324
4348
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
4325
4349
  }
4350
+ function booleanHeader(value) {
4351
+ return value === "true" ? true : value === "false" ? false : void 0;
4352
+ }
4353
+ function withGrace(window, headers) {
4354
+ const graceUtilization = headers[`${UNIFIED_PREFIX}grace-status`] === "active" ? nonNegativeNumber(headers[`${UNIFIED_PREFIX}grace-5h-utilization`]) : void 0;
4355
+ return window === void 0 || graceUtilization === void 0 ? window : { ...window, graceUtilization };
4356
+ }
4326
4357
  function unifiedWindow(headers, window) {
4327
4358
  const utilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}${window}-utilization`]);
4328
4359
  const resetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}${window}-reset`]);
@@ -4337,33 +4368,39 @@ function parseUnifiedRateLimit(headers) {
4337
4368
  return void 0;
4338
4369
  }
4339
4370
  const status = headers[`${UNIFIED_PREFIX}status`];
4340
- const fiveHour = unifiedWindow(headers, "5h");
4371
+ const fiveHour = withGrace(unifiedWindow(headers, "5h"), headers);
4341
4372
  const sevenDay = unifiedWindow(headers, "7d");
4373
+ const sevenDayOverageIncluded = unifiedWindow(headers, "7d_oi");
4342
4374
  const representativeClaim = headers[`${UNIFIED_PREFIX}representative-claim`];
4343
4375
  const resetAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}reset`]);
4344
4376
  const overageStatus = headers[`${UNIFIED_PREFIX}overage-status`];
4345
4377
  const overageUtilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}overage-utilization`]);
4346
4378
  const overageResetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}overage-reset`]);
4347
4379
  const overageDisabledReason = headers[`${UNIFIED_PREFIX}overage-disabled-reason`];
4380
+ const overageInUse = booleanHeader(headers[`${UNIFIED_PREFIX}overage-in-use`]);
4348
4381
  return {
4349
4382
  ...status === void 0 ? {} : { status },
4350
4383
  ...fiveHour === void 0 ? {} : { fiveHour },
4351
4384
  ...sevenDay === void 0 ? {} : { sevenDay },
4385
+ ...sevenDayOverageIncluded === void 0 ? {} : { sevenDayOverageIncluded },
4352
4386
  ...representativeClaim === void 0 ? {} : { representativeClaim },
4353
4387
  ...resetAt === void 0 ? {} : { resetAt },
4354
4388
  ...overageStatus === void 0 ? {} : { overageStatus },
4355
4389
  ...overageUtilization === void 0 ? {} : { overageUtilization },
4356
4390
  ...overageResetsAt === void 0 ? {} : { overageResetsAt },
4357
- ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
4391
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason },
4392
+ ...overageInUse === void 0 ? {} : { overageInUse },
4393
+ ...headers[`${UNIFIED_PREFIX}fallback`] === "available" ? { fallbackAvailable: true } : {}
4358
4394
  };
4359
4395
  }
4360
4396
  function overageFactsOf(unified) {
4361
- const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason } = unified;
4397
+ const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason, overageInUse } = unified;
4362
4398
  return {
4363
4399
  ...overageStatus === void 0 ? {} : { overageStatus },
4364
4400
  ...overageUtilization === void 0 ? {} : { overageUtilization },
4365
4401
  ...overageResetsAt === void 0 ? {} : { overageResetsAt },
4366
- ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
4402
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason },
4403
+ ...overageInUse === void 0 ? {} : { overageInUse }
4367
4404
  };
4368
4405
  }
4369
4406
  function overageWindowOf(unified) {
@@ -4602,7 +4639,7 @@ function assessIdentity(member, nowMs) {
4602
4639
  if (unified.overageStatus === "allowed") {
4603
4640
  return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
4604
4641
  }
4605
- return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...windowReasons, ...overageReasons, ...planReasons] } };
4642
+ return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...unified.fallbackAvailable === true ? ["a fallback is on offer, so requests for some models may still be served"] : [], ...windowReasons, ...overageReasons, ...planReasons] } };
4606
4643
  }
4607
4644
  if (plan.kind === "pay-per-use" || fiveHourWindow === void 0 && sevenDayWindow === void 0) {
4608
4645
  const headroom = overage?.utilization === void 0 ? void 0 : Math.max(0, 1 - overage.utilization);
@@ -4952,9 +4989,8 @@ function createUsageStore(deps) {
4952
4989
  recordRateLimit: (identity, provider, rateLimit) => rewriteSnapshot(identity, (current) => {
4953
4990
  const state = current?.providers[provider] ?? {};
4954
4991
  const keep = state.rateLimit !== void 0 && state.rateLimit.observedAt.localeCompare(rateLimit.observedAt) > 0;
4955
- const earlier = state.rateLimit?.unified;
4956
- const carried = rateLimit.unified === void 0 || rateLimit.unified.overageStatus !== void 0 || earlier === void 0 ? void 0 : overageFactsOf(earlier);
4957
- const merged = carried === void 0 || rateLimit.unified === void 0 ? rateLimit : { ...rateLimit, unified: { ...rateLimit.unified, ...carried } };
4992
+ const earlier = state.rateLimit;
4993
+ const merged = rateLimit.unified === void 0 ? { ...earlier ?? rateLimit, planWindowsUnavailableAt: rateLimit.observedAt } : { ...rateLimit, unified: { ...earlier?.unified === void 0 ? {} : overageFactsOf(earlier.unified), ...rateLimit.unified } };
4958
4994
  return { ...current?.providers, [provider]: { ...state, rateLimit: keep ? state.rateLimit : merged } };
4959
4995
  })
4960
4996
  };
@@ -7409,22 +7445,38 @@ function windowOf(reported) {
7409
7445
  ...utilization !== void 0 && utilization >= 1 ? { status: "rejected" } : {}
7410
7446
  };
7411
7447
  }
7448
+ function extraUsageOf(reported) {
7449
+ const extra = reported?.extra_usage;
7450
+ if (extra === null || extra === void 0) {
7451
+ return void 0;
7452
+ }
7453
+ const utilization = extra.utilization === null ? void 0 : extra.utilization / PERCENT2;
7454
+ const currency = extra.currency ?? void 0;
7455
+ const spend = extra.used_credits === null || currency === void 0 ? void 0 : { usedMinor: extra.used_credits, ...extra.monthly_limit === null ? {} : { limitMinor: extra.monthly_limit }, currency };
7456
+ return {
7457
+ overageStatus: !extra.is_enabled || utilization !== void 0 && utilization >= 1 ? "rejected" : "allowed",
7458
+ ...utilization === void 0 ? {} : { overageUtilization: utilization },
7459
+ ...spend === void 0 ? {} : { extraUsageSpend: spend }
7460
+ };
7461
+ }
7412
7462
  function unifiedFromReportedLimits(reported) {
7413
7463
  const fiveHour = windowOf(reported?.five_hour);
7414
7464
  const sevenDay = windowOf(reported?.seven_day);
7415
- if (fiveHour === void 0 && sevenDay === void 0) {
7465
+ const extraUsage = extraUsageOf(reported);
7466
+ if (fiveHour === void 0 && sevenDay === void 0 && extraUsage === void 0) {
7416
7467
  return void 0;
7417
7468
  }
7418
- return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay } };
7469
+ return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay }, ...extraUsage };
7419
7470
  }
7420
7471
  function isAnthropicUsageProbeable(member) {
7421
- const unified = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified;
7422
- return planOf(member.account ?? member.snapshot?.account).kind === "subscription" && (unified === void 0 || soleOverageWindow(unified) === void 0);
7472
+ return planOf(member.account ?? member.snapshot?.account).kind === "subscription";
7423
7473
  }
7424
7474
  function isAnthropicUsageStale(member, nowMs) {
7425
7475
  const rateLimit = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit;
7426
- const freshnessMs = rateLimit?.unified === void 0 ? NO_PLAN_WINDOWS_FRESHNESS_MS : ANTHROPIC_USAGE_FRESHNESS_MS;
7427
- return isAnthropicUsageProbeable(member) && (rateLimit === void 0 || nowMs - Date.parse(rateLimit.observedAt) >= freshnessMs);
7476
+ const answeredNothing = rateLimit?.unified === void 0 || rateLimit.planWindowsUnavailableAt !== void 0;
7477
+ const freshnessMs = answeredNothing ? NO_PLAN_WINDOWS_FRESHNESS_MS : ANTHROPIC_USAGE_FRESHNESS_MS;
7478
+ const checkedAt = rateLimit === void 0 ? void 0 : Date.parse(rateLimit.planWindowsUnavailableAt ?? rateLimit.observedAt);
7479
+ return isAnthropicUsageProbeable(member) && (checkedAt === void 0 || nowMs - checkedAt >= freshnessMs);
7428
7480
  }
7429
7481
  function poolIdentityNames(pools, poolName) {
7430
7482
  const seenPools = /* @__PURE__ */ new Set();
@@ -7505,7 +7557,6 @@ var init_anthropicUsageRefresh = __esm({
7505
7557
  init_middleware();
7506
7558
  init_pick();
7507
7559
  init_plan2();
7508
- init_rateLimit();
7509
7560
  PERCENT2 = 100;
7510
7561
  ANTHROPIC_USAGE_FRESHNESS_MS = FIVE_HOUR_WINDOW_MS / PERCENT2;
7511
7562
  NO_PLAN_WINDOWS_FRESHNESS_MS = SEVEN_DAY_WINDOW_MS / PERCENT2;
package/dist/index.mjs CHANGED
@@ -2625,7 +2625,7 @@ var init_package = __esm({
2625
2625
  "package.json"() {
2626
2626
  package_default = {
2627
2627
  name: "agent-shim",
2628
- version: "9.2.0",
2628
+ version: "9.3.0",
2629
2629
  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.",
2630
2630
  license: "MIT",
2631
2631
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4000,7 +4000,7 @@ var init_identity = __esm({
4000
4000
 
4001
4001
  // src/usage/schema.ts
4002
4002
  import { z as z7 } from "zod";
4003
- var USAGE_SCHEMA_VERSION, VersionSchema, InstantSchema, TokenCountSchema, TokenUsageSchema, LIMIT_KINDS, LimitClassificationSchema, UsageRecordSchema, QuotaWindowSchema, UnifiedRateLimitSchema, RateLimitStateSchema, LimitEventSchema, ProviderQuotaWindowSchema, ProviderQuotaSchema, ProviderUsageStateSchema, AccountMetadataSchema, UsageSnapshotSchema;
4003
+ var USAGE_SCHEMA_VERSION, VersionSchema, InstantSchema, TokenCountSchema, TokenUsageSchema, LIMIT_KINDS, LimitClassificationSchema, UsageRecordSchema, QuotaWindowSchema, ExtraUsageSpendSchema, UnifiedRateLimitSchema, RateLimitStateSchema, LimitEventSchema, ProviderQuotaWindowSchema, ProviderQuotaSchema, ProviderUsageStateSchema, AccountMetadataSchema, UsageSnapshotSchema;
4004
4004
  var init_schema2 = __esm({
4005
4005
  "src/usage/schema.ts"() {
4006
4006
  "use strict";
@@ -4064,13 +4064,25 @@ var init_schema2 = __esm({
4064
4064
  utilization: z7.number().nonnegative().optional(),
4065
4065
  resetsAt: InstantSchema.optional(),
4066
4066
  /** The window's own status (`allowed`, `allowed_warning`, `rejected`). */
4067
- status: z7.string().optional()
4067
+ status: z7.string().optional(),
4068
+ /** The fraction of the window's grace allowance used, while the upstream reports the window in grace (the five-hour window only). Requests are served beyond the window's own full mark while it grows, but refusals have been seen at a small value, so nothing ranks on it. */
4069
+ graceUtilization: z7.number().nonnegative().optional()
4070
+ });
4071
+ ExtraUsageSpendSchema = z7.strictObject({
4072
+ /** Spent so far in the allowance's period, in the currency's minor units (pence, cents). */
4073
+ usedMinor: z7.number().nonnegative(),
4074
+ /** The allowance's cap in the same units, when it has one. */
4075
+ limitMinor: z7.number().nonnegative().optional(),
4076
+ /** The ISO 4217 currency code. */
4077
+ currency: z7.string()
4068
4078
  });
4069
4079
  UnifiedRateLimitSchema = z7.strictObject({
4070
4080
  /** The overall status: `allowed`, `allowed_warning` or `rejected`. */
4071
4081
  status: z7.string().optional(),
4072
4082
  fiveHour: QuotaWindowSchema.optional(),
4073
4083
  sevenDay: QuotaWindowSchema.optional(),
4084
+ /** The weekly window of the models whose usage may continue as extra usage (`7d_oi`), reported by some plans beside the all-models weekly window. */
4085
+ sevenDayOverageIncluded: QuotaWindowSchema.optional(),
4074
4086
  /** The window that currently binds. */
4075
4087
  representativeClaim: z7.string().optional(),
4076
4088
  /** When the binding window resets. */
@@ -4082,13 +4094,21 @@ var init_schema2 = __esm({
4082
4094
  /** When the extra-usage allowance resets. */
4083
4095
  overageResetsAt: InstantSchema.optional(),
4084
4096
  /** Why extra usage is unavailable, as the upstream names it (`out_of_credits`, for one). */
4085
- overageDisabledReason: z7.string().optional()
4097
+ overageDisabledReason: z7.string().optional(),
4098
+ /** Whether the response was served on extra usage, as the upstream states it. */
4099
+ overageInUse: z7.boolean().optional(),
4100
+ /** The allowance in money, from the usage endpoint (the response headers state only the fraction). */
4101
+ extraUsageSpend: ExtraUsageSpendSchema.optional(),
4102
+ /** True when the upstream offers a fallback while a window is rejected: some requests, by model, are still served, though the rest are refused. */
4103
+ fallbackAvailable: z7.boolean().optional()
4086
4104
  });
4087
4105
  RateLimitStateSchema = z7.strictObject({
4088
4106
  observedAt: InstantSchema,
4089
4107
  /** Every quota and rate-limit header on that response, by name. */
4090
4108
  headers: z7.record(z7.string(), z7.string()),
4091
- unified: UnifiedRateLimitSchema.optional()
4109
+ unified: UnifiedRateLimitSchema.optional(),
4110
+ /** When the usage endpoint last answered that it has no plan windows for the account, which a later response replaces. Its answer leaves the recorded `unified` state alone (a response's headers may be the only source of it), so this alone says the question was asked. */
4111
+ planWindowsUnavailableAt: InstantSchema.optional()
4092
4112
  });
4093
4113
  LimitEventSchema = LimitClassificationSchema.extend({
4094
4114
  observedAt: InstantSchema,
@@ -4243,7 +4263,11 @@ var init_account = __esm({
4243
4263
  // src/usage/plan.ts
4244
4264
  import { z as z8 } from "zod";
4245
4265
  function planOf(account) {
4246
- const tier = account?.organizationRateLimitTier ?? account?.userRateLimitTier;
4266
+ const userTier = account?.userRateLimitTier;
4267
+ if (userTier !== void 0 && ZERO_TIER.test(userTier)) {
4268
+ return { kind: "pay-per-use", tier: userTier };
4269
+ }
4270
+ const tier = account?.organizationRateLimitTier ?? userTier;
4247
4271
  const tierField = tier === void 0 ? {} : { tier };
4248
4272
  if (tier === void 0) {
4249
4273
  return { kind: "subscription", capacity: 1, recognised: false };
@@ -4297,6 +4321,13 @@ function nonNegativeNumber(value) {
4297
4321
  const parsed = Number(value);
4298
4322
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
4299
4323
  }
4324
+ function booleanHeader(value) {
4325
+ return value === "true" ? true : value === "false" ? false : void 0;
4326
+ }
4327
+ function withGrace(window, headers) {
4328
+ const graceUtilization = headers[`${UNIFIED_PREFIX}grace-status`] === "active" ? nonNegativeNumber(headers[`${UNIFIED_PREFIX}grace-5h-utilization`]) : void 0;
4329
+ return window === void 0 || graceUtilization === void 0 ? window : { ...window, graceUtilization };
4330
+ }
4300
4331
  function unifiedWindow(headers, window) {
4301
4332
  const utilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}${window}-utilization`]);
4302
4333
  const resetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}${window}-reset`]);
@@ -4311,33 +4342,39 @@ function parseUnifiedRateLimit(headers) {
4311
4342
  return void 0;
4312
4343
  }
4313
4344
  const status = headers[`${UNIFIED_PREFIX}status`];
4314
- const fiveHour = unifiedWindow(headers, "5h");
4345
+ const fiveHour = withGrace(unifiedWindow(headers, "5h"), headers);
4315
4346
  const sevenDay = unifiedWindow(headers, "7d");
4347
+ const sevenDayOverageIncluded = unifiedWindow(headers, "7d_oi");
4316
4348
  const representativeClaim = headers[`${UNIFIED_PREFIX}representative-claim`];
4317
4349
  const resetAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}reset`]);
4318
4350
  const overageStatus = headers[`${UNIFIED_PREFIX}overage-status`];
4319
4351
  const overageUtilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}overage-utilization`]);
4320
4352
  const overageResetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}overage-reset`]);
4321
4353
  const overageDisabledReason = headers[`${UNIFIED_PREFIX}overage-disabled-reason`];
4354
+ const overageInUse = booleanHeader(headers[`${UNIFIED_PREFIX}overage-in-use`]);
4322
4355
  return {
4323
4356
  ...status === void 0 ? {} : { status },
4324
4357
  ...fiveHour === void 0 ? {} : { fiveHour },
4325
4358
  ...sevenDay === void 0 ? {} : { sevenDay },
4359
+ ...sevenDayOverageIncluded === void 0 ? {} : { sevenDayOverageIncluded },
4326
4360
  ...representativeClaim === void 0 ? {} : { representativeClaim },
4327
4361
  ...resetAt === void 0 ? {} : { resetAt },
4328
4362
  ...overageStatus === void 0 ? {} : { overageStatus },
4329
4363
  ...overageUtilization === void 0 ? {} : { overageUtilization },
4330
4364
  ...overageResetsAt === void 0 ? {} : { overageResetsAt },
4331
- ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
4365
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason },
4366
+ ...overageInUse === void 0 ? {} : { overageInUse },
4367
+ ...headers[`${UNIFIED_PREFIX}fallback`] === "available" ? { fallbackAvailable: true } : {}
4332
4368
  };
4333
4369
  }
4334
4370
  function overageFactsOf(unified) {
4335
- const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason } = unified;
4371
+ const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason, overageInUse } = unified;
4336
4372
  return {
4337
4373
  ...overageStatus === void 0 ? {} : { overageStatus },
4338
4374
  ...overageUtilization === void 0 ? {} : { overageUtilization },
4339
4375
  ...overageResetsAt === void 0 ? {} : { overageResetsAt },
4340
- ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
4376
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason },
4377
+ ...overageInUse === void 0 ? {} : { overageInUse }
4341
4378
  };
4342
4379
  }
4343
4380
  function overageWindowOf(unified) {
@@ -4576,7 +4613,7 @@ function assessIdentity(member, nowMs) {
4576
4613
  if (unified.overageStatus === "allowed") {
4577
4614
  return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
4578
4615
  }
4579
- return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...windowReasons, ...overageReasons, ...planReasons] } };
4616
+ return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...unified.fallbackAvailable === true ? ["a fallback is on offer, so requests for some models may still be served"] : [], ...windowReasons, ...overageReasons, ...planReasons] } };
4580
4617
  }
4581
4618
  if (plan.kind === "pay-per-use" || fiveHourWindow === void 0 && sevenDayWindow === void 0) {
4582
4619
  const headroom = overage?.utilization === void 0 ? void 0 : Math.max(0, 1 - overage.utilization);
@@ -4927,9 +4964,8 @@ function createUsageStore(deps) {
4927
4964
  recordRateLimit: (identity, provider, rateLimit) => rewriteSnapshot(identity, (current) => {
4928
4965
  const state = current?.providers[provider] ?? {};
4929
4966
  const keep = state.rateLimit !== void 0 && state.rateLimit.observedAt.localeCompare(rateLimit.observedAt) > 0;
4930
- const earlier = state.rateLimit?.unified;
4931
- const carried = rateLimit.unified === void 0 || rateLimit.unified.overageStatus !== void 0 || earlier === void 0 ? void 0 : overageFactsOf(earlier);
4932
- const merged = carried === void 0 || rateLimit.unified === void 0 ? rateLimit : { ...rateLimit, unified: { ...rateLimit.unified, ...carried } };
4967
+ const earlier = state.rateLimit;
4968
+ const merged = rateLimit.unified === void 0 ? { ...earlier ?? rateLimit, planWindowsUnavailableAt: rateLimit.observedAt } : { ...rateLimit, unified: { ...earlier?.unified === void 0 ? {} : overageFactsOf(earlier.unified), ...rateLimit.unified } };
4933
4969
  return { ...current?.providers, [provider]: { ...state, rateLimit: keep ? state.rateLimit : merged } };
4934
4970
  })
4935
4971
  };
@@ -7381,22 +7417,38 @@ function windowOf(reported) {
7381
7417
  ...utilization !== void 0 && utilization >= 1 ? { status: "rejected" } : {}
7382
7418
  };
7383
7419
  }
7420
+ function extraUsageOf(reported) {
7421
+ const extra = reported?.extra_usage;
7422
+ if (extra === null || extra === void 0) {
7423
+ return void 0;
7424
+ }
7425
+ const utilization = extra.utilization === null ? void 0 : extra.utilization / PERCENT2;
7426
+ const currency = extra.currency ?? void 0;
7427
+ const spend = extra.used_credits === null || currency === void 0 ? void 0 : { usedMinor: extra.used_credits, ...extra.monthly_limit === null ? {} : { limitMinor: extra.monthly_limit }, currency };
7428
+ return {
7429
+ overageStatus: !extra.is_enabled || utilization !== void 0 && utilization >= 1 ? "rejected" : "allowed",
7430
+ ...utilization === void 0 ? {} : { overageUtilization: utilization },
7431
+ ...spend === void 0 ? {} : { extraUsageSpend: spend }
7432
+ };
7433
+ }
7384
7434
  function unifiedFromReportedLimits(reported) {
7385
7435
  const fiveHour = windowOf(reported?.five_hour);
7386
7436
  const sevenDay = windowOf(reported?.seven_day);
7387
- if (fiveHour === void 0 && sevenDay === void 0) {
7437
+ const extraUsage = extraUsageOf(reported);
7438
+ if (fiveHour === void 0 && sevenDay === void 0 && extraUsage === void 0) {
7388
7439
  return void 0;
7389
7440
  }
7390
- return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay } };
7441
+ return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay }, ...extraUsage };
7391
7442
  }
7392
7443
  function isAnthropicUsageProbeable(member) {
7393
- const unified = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified;
7394
- return planOf(member.account ?? member.snapshot?.account).kind === "subscription" && (unified === void 0 || soleOverageWindow(unified) === void 0);
7444
+ return planOf(member.account ?? member.snapshot?.account).kind === "subscription";
7395
7445
  }
7396
7446
  function isAnthropicUsageStale(member, nowMs) {
7397
7447
  const rateLimit = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit;
7398
- const freshnessMs = rateLimit?.unified === void 0 ? NO_PLAN_WINDOWS_FRESHNESS_MS : ANTHROPIC_USAGE_FRESHNESS_MS;
7399
- return isAnthropicUsageProbeable(member) && (rateLimit === void 0 || nowMs - Date.parse(rateLimit.observedAt) >= freshnessMs);
7448
+ const answeredNothing = rateLimit?.unified === void 0 || rateLimit.planWindowsUnavailableAt !== void 0;
7449
+ const freshnessMs = answeredNothing ? NO_PLAN_WINDOWS_FRESHNESS_MS : ANTHROPIC_USAGE_FRESHNESS_MS;
7450
+ const checkedAt = rateLimit === void 0 ? void 0 : Date.parse(rateLimit.planWindowsUnavailableAt ?? rateLimit.observedAt);
7451
+ return isAnthropicUsageProbeable(member) && (checkedAt === void 0 || nowMs - checkedAt >= freshnessMs);
7400
7452
  }
7401
7453
  function poolIdentityNames(pools, poolName) {
7402
7454
  const seenPools = /* @__PURE__ */ new Set();
@@ -7477,7 +7529,6 @@ var init_anthropicUsageRefresh = __esm({
7477
7529
  init_middleware();
7478
7530
  init_pick();
7479
7531
  init_plan2();
7480
- init_rateLimit();
7481
7532
  PERCENT2 = 100;
7482
7533
  ANTHROPIC_USAGE_FRESHNESS_MS = FIVE_HOUR_WINDOW_MS / PERCENT2;
7483
7534
  NO_PLAN_WINDOWS_FRESHNESS_MS = SEVEN_DAY_WINDOW_MS / PERCENT2;
@@ -4617,6 +4617,7 @@ declare const QuotaWindowSchema: z.ZodObject<{
4617
4617
  utilization: z.ZodOptional<z.ZodNumber>;
4618
4618
  resetsAt: z.ZodOptional<z.ZodISODateTime>;
4619
4619
  status: z.ZodOptional<z.ZodString>;
4620
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
4620
4621
  }, z.core.$strict>;
4621
4622
  type QuotaWindow = z.infer<typeof QuotaWindowSchema>;
4622
4623
  /**
@@ -4677,11 +4678,19 @@ declare const UsageSnapshotSchema: z.ZodObject<{
4677
4678
  utilization: z.ZodOptional<z.ZodNumber>;
4678
4679
  resetsAt: z.ZodOptional<z.ZodISODateTime>;
4679
4680
  status: z.ZodOptional<z.ZodString>;
4681
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
4680
4682
  }, z.core.$strict>>;
4681
4683
  sevenDay: z.ZodOptional<z.ZodObject<{
4682
4684
  utilization: z.ZodOptional<z.ZodNumber>;
4683
4685
  resetsAt: z.ZodOptional<z.ZodISODateTime>;
4684
4686
  status: z.ZodOptional<z.ZodString>;
4687
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
4688
+ }, z.core.$strict>>;
4689
+ sevenDayOverageIncluded: z.ZodOptional<z.ZodObject<{
4690
+ utilization: z.ZodOptional<z.ZodNumber>;
4691
+ resetsAt: z.ZodOptional<z.ZodISODateTime>;
4692
+ status: z.ZodOptional<z.ZodString>;
4693
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
4685
4694
  }, z.core.$strict>>;
4686
4695
  representativeClaim: z.ZodOptional<z.ZodString>;
4687
4696
  resetAt: z.ZodOptional<z.ZodISODateTime>;
@@ -4689,7 +4698,15 @@ declare const UsageSnapshotSchema: z.ZodObject<{
4689
4698
  overageUtilization: z.ZodOptional<z.ZodNumber>;
4690
4699
  overageResetsAt: z.ZodOptional<z.ZodISODateTime>;
4691
4700
  overageDisabledReason: z.ZodOptional<z.ZodString>;
4701
+ overageInUse: z.ZodOptional<z.ZodBoolean>;
4702
+ extraUsageSpend: z.ZodOptional<z.ZodObject<{
4703
+ usedMinor: z.ZodNumber;
4704
+ limitMinor: z.ZodOptional<z.ZodNumber>;
4705
+ currency: z.ZodString;
4706
+ }, z.core.$strict>>;
4707
+ fallbackAvailable: z.ZodOptional<z.ZodBoolean>;
4692
4708
  }, z.core.$strict>>;
4709
+ planWindowsUnavailableAt: z.ZodOptional<z.ZodISODateTime>;
4693
4710
  }, z.core.$strict>>;
4694
4711
  lastLimit: z.ZodOptional<z.ZodObject<{
4695
4712
  kind: z.ZodEnum<{
@@ -5011,11 +5028,19 @@ declare function createControlApiRouter(deps: ControlApiDeps): {
5011
5028
  utilization: zod.ZodOptional<zod.ZodNumber>;
5012
5029
  resetsAt: zod.ZodOptional<zod.ZodISODateTime>;
5013
5030
  status: zod.ZodOptional<zod.ZodString>;
5031
+ graceUtilization: zod.ZodOptional<zod.ZodNumber>;
5014
5032
  }, zod_v4_core.$strict>>;
5015
5033
  sevenDay: zod.ZodOptional<zod.ZodObject<{
5016
5034
  utilization: zod.ZodOptional<zod.ZodNumber>;
5017
5035
  resetsAt: zod.ZodOptional<zod.ZodISODateTime>;
5018
5036
  status: zod.ZodOptional<zod.ZodString>;
5037
+ graceUtilization: zod.ZodOptional<zod.ZodNumber>;
5038
+ }, zod_v4_core.$strict>>;
5039
+ sevenDayOverageIncluded: zod.ZodOptional<zod.ZodObject<{
5040
+ utilization: zod.ZodOptional<zod.ZodNumber>;
5041
+ resetsAt: zod.ZodOptional<zod.ZodISODateTime>;
5042
+ status: zod.ZodOptional<zod.ZodString>;
5043
+ graceUtilization: zod.ZodOptional<zod.ZodNumber>;
5019
5044
  }, zod_v4_core.$strict>>;
5020
5045
  representativeClaim: zod.ZodOptional<zod.ZodString>;
5021
5046
  resetAt: zod.ZodOptional<zod.ZodISODateTime>;
@@ -5023,7 +5048,15 @@ declare function createControlApiRouter(deps: ControlApiDeps): {
5023
5048
  overageUtilization: zod.ZodOptional<zod.ZodNumber>;
5024
5049
  overageResetsAt: zod.ZodOptional<zod.ZodISODateTime>;
5025
5050
  overageDisabledReason: zod.ZodOptional<zod.ZodString>;
5051
+ overageInUse: zod.ZodOptional<zod.ZodBoolean>;
5052
+ extraUsageSpend: zod.ZodOptional<zod.ZodObject<{
5053
+ usedMinor: zod.ZodNumber;
5054
+ limitMinor: zod.ZodOptional<zod.ZodNumber>;
5055
+ currency: zod.ZodString;
5056
+ }, zod_v4_core.$strict>>;
5057
+ fallbackAvailable: zod.ZodOptional<zod.ZodBoolean>;
5026
5058
  }, zod_v4_core.$strict>>;
5059
+ planWindowsUnavailableAt: zod.ZodOptional<zod.ZodISODateTime>;
5027
5060
  }, zod_v4_core.$strict>>;
5028
5061
  lastLimit: zod.ZodOptional<zod.ZodObject<{
5029
5062
  kind: zod.ZodEnum<{
@@ -5595,11 +5628,19 @@ declare function createDoorApiRouter(deps: DoorApiDeps): {
5595
5628
  utilization: zod.ZodOptional<zod.ZodNumber>;
5596
5629
  resetsAt: zod.ZodOptional<zod.ZodISODateTime>;
5597
5630
  status: zod.ZodOptional<zod.ZodString>;
5631
+ graceUtilization: zod.ZodOptional<zod.ZodNumber>;
5598
5632
  }, zod_v4_core.$strict>>;
5599
5633
  sevenDay: zod.ZodOptional<zod.ZodObject<{
5600
5634
  utilization: zod.ZodOptional<zod.ZodNumber>;
5601
5635
  resetsAt: zod.ZodOptional<zod.ZodISODateTime>;
5602
5636
  status: zod.ZodOptional<zod.ZodString>;
5637
+ graceUtilization: zod.ZodOptional<zod.ZodNumber>;
5638
+ }, zod_v4_core.$strict>>;
5639
+ sevenDayOverageIncluded: zod.ZodOptional<zod.ZodObject<{
5640
+ utilization: zod.ZodOptional<zod.ZodNumber>;
5641
+ resetsAt: zod.ZodOptional<zod.ZodISODateTime>;
5642
+ status: zod.ZodOptional<zod.ZodString>;
5643
+ graceUtilization: zod.ZodOptional<zod.ZodNumber>;
5603
5644
  }, zod_v4_core.$strict>>;
5604
5645
  representativeClaim: zod.ZodOptional<zod.ZodString>;
5605
5646
  resetAt: zod.ZodOptional<zod.ZodISODateTime>;
@@ -5607,7 +5648,15 @@ declare function createDoorApiRouter(deps: DoorApiDeps): {
5607
5648
  overageUtilization: zod.ZodOptional<zod.ZodNumber>;
5608
5649
  overageResetsAt: zod.ZodOptional<zod.ZodISODateTime>;
5609
5650
  overageDisabledReason: zod.ZodOptional<zod.ZodString>;
5651
+ overageInUse: zod.ZodOptional<zod.ZodBoolean>;
5652
+ extraUsageSpend: zod.ZodOptional<zod.ZodObject<{
5653
+ usedMinor: zod.ZodNumber;
5654
+ limitMinor: zod.ZodOptional<zod.ZodNumber>;
5655
+ currency: zod.ZodString;
5656
+ }, zod_v4_core.$strict>>;
5657
+ fallbackAvailable: zod.ZodOptional<zod.ZodBoolean>;
5610
5658
  }, zod_v4_core.$strict>>;
5659
+ planWindowsUnavailableAt: zod.ZodOptional<zod.ZodISODateTime>;
5611
5660
  }, zod_v4_core.$strict>>;
5612
5661
  lastLimit: zod.ZodOptional<zod.ZodObject<{
5613
5662
  kind: zod.ZodEnum<{
@@ -6394,11 +6443,19 @@ declare const UsageListOutputSchema: z.ZodObject<{
6394
6443
  utilization: z.ZodOptional<z.ZodNumber>;
6395
6444
  resetsAt: z.ZodOptional<z.ZodISODateTime>;
6396
6445
  status: z.ZodOptional<z.ZodString>;
6446
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
6397
6447
  }, z.core.$strict>>;
6398
6448
  sevenDay: z.ZodOptional<z.ZodObject<{
6399
6449
  utilization: z.ZodOptional<z.ZodNumber>;
6400
6450
  resetsAt: z.ZodOptional<z.ZodISODateTime>;
6401
6451
  status: z.ZodOptional<z.ZodString>;
6452
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
6453
+ }, z.core.$strict>>;
6454
+ sevenDayOverageIncluded: z.ZodOptional<z.ZodObject<{
6455
+ utilization: z.ZodOptional<z.ZodNumber>;
6456
+ resetsAt: z.ZodOptional<z.ZodISODateTime>;
6457
+ status: z.ZodOptional<z.ZodString>;
6458
+ graceUtilization: z.ZodOptional<z.ZodNumber>;
6402
6459
  }, z.core.$strict>>;
6403
6460
  representativeClaim: z.ZodOptional<z.ZodString>;
6404
6461
  resetAt: z.ZodOptional<z.ZodISODateTime>;
@@ -6406,7 +6463,15 @@ declare const UsageListOutputSchema: z.ZodObject<{
6406
6463
  overageUtilization: z.ZodOptional<z.ZodNumber>;
6407
6464
  overageResetsAt: z.ZodOptional<z.ZodISODateTime>;
6408
6465
  overageDisabledReason: z.ZodOptional<z.ZodString>;
6466
+ overageInUse: z.ZodOptional<z.ZodBoolean>;
6467
+ extraUsageSpend: z.ZodOptional<z.ZodObject<{
6468
+ usedMinor: z.ZodNumber;
6469
+ limitMinor: z.ZodOptional<z.ZodNumber>;
6470
+ currency: z.ZodString;
6471
+ }, z.core.$strict>>;
6472
+ fallbackAvailable: z.ZodOptional<z.ZodBoolean>;
6409
6473
  }, z.core.$strict>>;
6474
+ planWindowsUnavailableAt: z.ZodOptional<z.ZodISODateTime>;
6410
6475
  }, z.core.$strict>>;
6411
6476
  lastLimit: z.ZodOptional<z.ZodObject<{
6412
6477
  kind: z.ZodEnum<{
@@ -7054,7 +7119,7 @@ declare const PlanClassSchema: z.ZodUnion<readonly [z.ZodObject<{
7054
7119
  }, z.core.$strict>]>;
7055
7120
  type PlanClass = z.infer<typeof PlanClassSchema>;
7056
7121
  /**
7057
- * Classifies an account from the rate-limit tier of its stored login (`organizationRateLimitTier`, which decides the organisation's limits, then `userRateLimitTier`). The tier strings are free text on Anthropic's side, so only the shapes seen are read: a trailing `<n>x` is that multiple, a bare `pro` is 1, a `zero` tier is pay-per-use. Anything else is a subscription of unrecognised size, counted as 1 and marked so the ranking can say it guessed.
7122
+ * Classifies an account from the rate-limit tier of its stored login (`organizationRateLimitTier`, which decides the organisation's limits, then `userRateLimitTier`), except that a `zero` user tier decides alone: a seat whose own allowance is zero draws on no plan whatever its organisation's tier says (a usage-based Enterprise seat sits in an organisation tier that reads as a subscription). The tier strings are free text on Anthropic's side, so only the shapes seen are read: a trailing `<n>x` is that multiple, a bare `pro` is 1, a `zero` tier is pay-per-use. Anything else is a subscription of unrecognised size, counted as 1 and marked so the ranking can say it guessed.
7058
7123
  */
7059
7124
  declare function planOf(account: AccountMetadata | undefined): PlanClass;
7060
7125
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-shim",
3
- "version": "9.2.0",
3
+ "version": "9.3.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>",