agent-shim 9.2.1 → 9.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.1",
33227
+ version: "9.3.1",
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>",
@@ -34043,7 +34076,7 @@ function assessIdentity(member, nowMs) {
34043
34076
  if (unified.overageStatus === "allowed") {
34044
34077
  return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
34045
34078
  }
34046
- 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] } };
34047
34080
  }
34048
34081
  if (plan.kind === "pay-per-use" || fiveHourWindow === void 0 && sevenDayWindow === void 0) {
34049
34082
  const headroom = overage?.utilization === void 0 ? void 0 : Math.max(0, 1 - overage.utilization);
@@ -34442,9 +34475,8 @@ function createUsageStore(deps) {
34442
34475
  recordRateLimit: (identity, provider, rateLimit) => rewriteSnapshot(identity, (current) => {
34443
34476
  const state = current?.providers[provider] ?? {};
34444
34477
  const keep = state.rateLimit !== void 0 && state.rateLimit.observedAt.localeCompare(rateLimit.observedAt) > 0;
34445
- const earlier = state.rateLimit?.unified;
34446
- const carried = rateLimit.unified === void 0 || rateLimit.unified.overageStatus !== void 0 || earlier === void 0 ? void 0 : overageFactsOf(earlier);
34447
- 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 } };
34448
34480
  return { ...current?.providers, [provider]: { ...state, rateLimit: keep ? state.rateLimit : merged } };
34449
34481
  })
34450
34482
  };
@@ -60961,22 +60993,38 @@ function windowOf(reported) {
60961
60993
  ...utilization !== void 0 && utilization >= 1 ? { status: "rejected" } : {}
60962
60994
  };
60963
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
+ }
60964
61010
  function unifiedFromReportedLimits(reported) {
60965
61011
  const fiveHour = windowOf(reported?.five_hour);
60966
61012
  const sevenDay = windowOf(reported?.seven_day);
60967
- if (fiveHour === void 0 && sevenDay === void 0) {
61013
+ const extraUsage = extraUsageOf(reported);
61014
+ if (fiveHour === void 0 && sevenDay === void 0 && extraUsage === void 0) {
60968
61015
  return void 0;
60969
61016
  }
60970
- return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay } };
61017
+ return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay }, ...extraUsage };
60971
61018
  }
60972
61019
  function isAnthropicUsageProbeable(member) {
60973
- const unified = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified;
60974
- 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";
60975
61021
  }
60976
61022
  function isAnthropicUsageStale(member, nowMs) {
60977
61023
  const rateLimit = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit;
60978
- const freshnessMs = rateLimit?.unified === void 0 ? NO_PLAN_WINDOWS_FRESHNESS_MS : ANTHROPIC_USAGE_FRESHNESS_MS;
60979
- 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);
60980
61028
  }
60981
61029
  function poolIdentityNames(pools, poolName) {
60982
61030
  const seenPools = /* @__PURE__ */ new Set();
@@ -61057,7 +61105,6 @@ var init_anthropicUsageRefresh = __esm({
61057
61105
  init_middleware();
61058
61106
  init_pick();
61059
61107
  init_plan2();
61060
- init_rateLimit();
61061
61108
  PERCENT2 = 100;
61062
61109
  ANTHROPIC_USAGE_FRESHNESS_MS = FIVE_HOUR_WINDOW_MS / PERCENT2;
61063
61110
  NO_PLAN_WINDOWS_FRESHNESS_MS = SEVEN_DAY_WINDOW_MS / PERCENT2;
@@ -119103,26 +119150,40 @@ function collectUsageReport(fs21, paths, filters) {
119103
119150
  };
119104
119151
  }
119105
119152
  var PERCENT4 = 100;
119153
+ var DECIMAL_RADIX = 10;
119106
119154
  function formatWindow(label, window) {
119107
119155
  if (window === void 0) {
119108
119156
  return void 0;
119109
119157
  }
119110
119158
  const used = window.utilization === void 0 ? "usage unknown" : `${String(Math.round(window.utilization * PERCENT4))}% used`;
119111
- 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));
119112
119166
  }
119113
119167
  function extraUsageParts(unified) {
119114
119168
  const window = overageWindowOf(unified);
119115
119169
  const measured = window?.utilization !== void 0 || window?.resetsAt !== void 0;
119116
119170
  const fact = window === void 0 ? void 0 : measured ? formatWindow("extra usage", window) : `extra usage ${window.status ?? "unknown"}`;
119117
- 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
+ ];
119118
119179
  }
119119
119180
  function formatRateLimit(state) {
119120
119181
  const { unified } = state;
119121
119182
  if (unified === void 0) {
119122
119183
  return `rate-limit headers (as of ${state.observedAt}): ${Object.entries(state.headers).map(([name, value2]) => `${name}=${value2}`).join(", ")}`;
119123
119184
  }
119124
- const parts = [formatWindow("5h", unified.fiveHour), formatWindow("7d", unified.sevenDay)].filter((part) => part !== void 0);
119125
- 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("; ")}`;
119126
119187
  }
119127
119188
  function formatLimit(limit) {
119128
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.1",
2652
+ version: "9.3.1",
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,
@@ -4327,6 +4347,13 @@ function nonNegativeNumber(value) {
4327
4347
  const parsed = Number(value);
4328
4348
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
4329
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
+ }
4330
4357
  function unifiedWindow(headers, window) {
4331
4358
  const utilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}${window}-utilization`]);
4332
4359
  const resetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}${window}-reset`]);
@@ -4341,33 +4368,39 @@ function parseUnifiedRateLimit(headers) {
4341
4368
  return void 0;
4342
4369
  }
4343
4370
  const status = headers[`${UNIFIED_PREFIX}status`];
4344
- const fiveHour = unifiedWindow(headers, "5h");
4371
+ const fiveHour = withGrace(unifiedWindow(headers, "5h"), headers);
4345
4372
  const sevenDay = unifiedWindow(headers, "7d");
4373
+ const sevenDayOverageIncluded = unifiedWindow(headers, "7d_oi");
4346
4374
  const representativeClaim = headers[`${UNIFIED_PREFIX}representative-claim`];
4347
4375
  const resetAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}reset`]);
4348
4376
  const overageStatus = headers[`${UNIFIED_PREFIX}overage-status`];
4349
4377
  const overageUtilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}overage-utilization`]);
4350
4378
  const overageResetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}overage-reset`]);
4351
4379
  const overageDisabledReason = headers[`${UNIFIED_PREFIX}overage-disabled-reason`];
4380
+ const overageInUse = booleanHeader(headers[`${UNIFIED_PREFIX}overage-in-use`]);
4352
4381
  return {
4353
4382
  ...status === void 0 ? {} : { status },
4354
4383
  ...fiveHour === void 0 ? {} : { fiveHour },
4355
4384
  ...sevenDay === void 0 ? {} : { sevenDay },
4385
+ ...sevenDayOverageIncluded === void 0 ? {} : { sevenDayOverageIncluded },
4356
4386
  ...representativeClaim === void 0 ? {} : { representativeClaim },
4357
4387
  ...resetAt === void 0 ? {} : { resetAt },
4358
4388
  ...overageStatus === void 0 ? {} : { overageStatus },
4359
4389
  ...overageUtilization === void 0 ? {} : { overageUtilization },
4360
4390
  ...overageResetsAt === void 0 ? {} : { overageResetsAt },
4361
- ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
4391
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason },
4392
+ ...overageInUse === void 0 ? {} : { overageInUse },
4393
+ ...headers[`${UNIFIED_PREFIX}fallback`] === "available" ? { fallbackAvailable: true } : {}
4362
4394
  };
4363
4395
  }
4364
4396
  function overageFactsOf(unified) {
4365
- const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason } = unified;
4397
+ const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason, overageInUse } = unified;
4366
4398
  return {
4367
4399
  ...overageStatus === void 0 ? {} : { overageStatus },
4368
4400
  ...overageUtilization === void 0 ? {} : { overageUtilization },
4369
4401
  ...overageResetsAt === void 0 ? {} : { overageResetsAt },
4370
- ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
4402
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason },
4403
+ ...overageInUse === void 0 ? {} : { overageInUse }
4371
4404
  };
4372
4405
  }
4373
4406
  function overageWindowOf(unified) {
@@ -4606,7 +4639,7 @@ function assessIdentity(member, nowMs) {
4606
4639
  if (unified.overageStatus === "allowed") {
4607
4640
  return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
4608
4641
  }
4609
- 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] } };
4610
4643
  }
4611
4644
  if (plan.kind === "pay-per-use" || fiveHourWindow === void 0 && sevenDayWindow === void 0) {
4612
4645
  const headroom = overage?.utilization === void 0 ? void 0 : Math.max(0, 1 - overage.utilization);
@@ -4956,9 +4989,8 @@ function createUsageStore(deps) {
4956
4989
  recordRateLimit: (identity, provider, rateLimit) => rewriteSnapshot(identity, (current) => {
4957
4990
  const state = current?.providers[provider] ?? {};
4958
4991
  const keep = state.rateLimit !== void 0 && state.rateLimit.observedAt.localeCompare(rateLimit.observedAt) > 0;
4959
- const earlier = state.rateLimit?.unified;
4960
- const carried = rateLimit.unified === void 0 || rateLimit.unified.overageStatus !== void 0 || earlier === void 0 ? void 0 : overageFactsOf(earlier);
4961
- 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 } };
4962
4994
  return { ...current?.providers, [provider]: { ...state, rateLimit: keep ? state.rateLimit : merged } };
4963
4995
  })
4964
4996
  };
@@ -7413,22 +7445,38 @@ function windowOf(reported) {
7413
7445
  ...utilization !== void 0 && utilization >= 1 ? { status: "rejected" } : {}
7414
7446
  };
7415
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
+ }
7416
7462
  function unifiedFromReportedLimits(reported) {
7417
7463
  const fiveHour = windowOf(reported?.five_hour);
7418
7464
  const sevenDay = windowOf(reported?.seven_day);
7419
- if (fiveHour === void 0 && sevenDay === void 0) {
7465
+ const extraUsage = extraUsageOf(reported);
7466
+ if (fiveHour === void 0 && sevenDay === void 0 && extraUsage === void 0) {
7420
7467
  return void 0;
7421
7468
  }
7422
- return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay } };
7469
+ return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay }, ...extraUsage };
7423
7470
  }
7424
7471
  function isAnthropicUsageProbeable(member) {
7425
- const unified = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified;
7426
- 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";
7427
7473
  }
7428
7474
  function isAnthropicUsageStale(member, nowMs) {
7429
7475
  const rateLimit = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit;
7430
- const freshnessMs = rateLimit?.unified === void 0 ? NO_PLAN_WINDOWS_FRESHNESS_MS : ANTHROPIC_USAGE_FRESHNESS_MS;
7431
- 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);
7432
7480
  }
7433
7481
  function poolIdentityNames(pools, poolName) {
7434
7482
  const seenPools = /* @__PURE__ */ new Set();
@@ -7509,7 +7557,6 @@ var init_anthropicUsageRefresh = __esm({
7509
7557
  init_middleware();
7510
7558
  init_pick();
7511
7559
  init_plan2();
7512
- init_rateLimit();
7513
7560
  PERCENT2 = 100;
7514
7561
  ANTHROPIC_USAGE_FRESHNESS_MS = FIVE_HOUR_WINDOW_MS / PERCENT2;
7515
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.1",
2628
+ version: "9.3.1",
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,
@@ -4301,6 +4321,13 @@ function nonNegativeNumber(value) {
4301
4321
  const parsed = Number(value);
4302
4322
  return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
4303
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
+ }
4304
4331
  function unifiedWindow(headers, window) {
4305
4332
  const utilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}${window}-utilization`]);
4306
4333
  const resetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}${window}-reset`]);
@@ -4315,33 +4342,39 @@ function parseUnifiedRateLimit(headers) {
4315
4342
  return void 0;
4316
4343
  }
4317
4344
  const status = headers[`${UNIFIED_PREFIX}status`];
4318
- const fiveHour = unifiedWindow(headers, "5h");
4345
+ const fiveHour = withGrace(unifiedWindow(headers, "5h"), headers);
4319
4346
  const sevenDay = unifiedWindow(headers, "7d");
4347
+ const sevenDayOverageIncluded = unifiedWindow(headers, "7d_oi");
4320
4348
  const representativeClaim = headers[`${UNIFIED_PREFIX}representative-claim`];
4321
4349
  const resetAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}reset`]);
4322
4350
  const overageStatus = headers[`${UNIFIED_PREFIX}overage-status`];
4323
4351
  const overageUtilization = nonNegativeNumber(headers[`${UNIFIED_PREFIX}overage-utilization`]);
4324
4352
  const overageResetsAt = epochSecondsToIso(headers[`${UNIFIED_PREFIX}overage-reset`]);
4325
4353
  const overageDisabledReason = headers[`${UNIFIED_PREFIX}overage-disabled-reason`];
4354
+ const overageInUse = booleanHeader(headers[`${UNIFIED_PREFIX}overage-in-use`]);
4326
4355
  return {
4327
4356
  ...status === void 0 ? {} : { status },
4328
4357
  ...fiveHour === void 0 ? {} : { fiveHour },
4329
4358
  ...sevenDay === void 0 ? {} : { sevenDay },
4359
+ ...sevenDayOverageIncluded === void 0 ? {} : { sevenDayOverageIncluded },
4330
4360
  ...representativeClaim === void 0 ? {} : { representativeClaim },
4331
4361
  ...resetAt === void 0 ? {} : { resetAt },
4332
4362
  ...overageStatus === void 0 ? {} : { overageStatus },
4333
4363
  ...overageUtilization === void 0 ? {} : { overageUtilization },
4334
4364
  ...overageResetsAt === void 0 ? {} : { overageResetsAt },
4335
- ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
4365
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason },
4366
+ ...overageInUse === void 0 ? {} : { overageInUse },
4367
+ ...headers[`${UNIFIED_PREFIX}fallback`] === "available" ? { fallbackAvailable: true } : {}
4336
4368
  };
4337
4369
  }
4338
4370
  function overageFactsOf(unified) {
4339
- const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason } = unified;
4371
+ const { overageStatus, overageUtilization, overageResetsAt, overageDisabledReason, overageInUse } = unified;
4340
4372
  return {
4341
4373
  ...overageStatus === void 0 ? {} : { overageStatus },
4342
4374
  ...overageUtilization === void 0 ? {} : { overageUtilization },
4343
4375
  ...overageResetsAt === void 0 ? {} : { overageResetsAt },
4344
- ...overageDisabledReason === void 0 ? {} : { overageDisabledReason }
4376
+ ...overageDisabledReason === void 0 ? {} : { overageDisabledReason },
4377
+ ...overageInUse === void 0 ? {} : { overageInUse }
4345
4378
  };
4346
4379
  }
4347
4380
  function overageWindowOf(unified) {
@@ -4580,7 +4613,7 @@ function assessIdentity(member, nowMs) {
4580
4613
  if (unified.overageStatus === "allowed") {
4581
4614
  return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
4582
4615
  }
4583
- 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] } };
4584
4617
  }
4585
4618
  if (plan.kind === "pay-per-use" || fiveHourWindow === void 0 && sevenDayWindow === void 0) {
4586
4619
  const headroom = overage?.utilization === void 0 ? void 0 : Math.max(0, 1 - overage.utilization);
@@ -4931,9 +4964,8 @@ function createUsageStore(deps) {
4931
4964
  recordRateLimit: (identity, provider, rateLimit) => rewriteSnapshot(identity, (current) => {
4932
4965
  const state = current?.providers[provider] ?? {};
4933
4966
  const keep = state.rateLimit !== void 0 && state.rateLimit.observedAt.localeCompare(rateLimit.observedAt) > 0;
4934
- const earlier = state.rateLimit?.unified;
4935
- const carried = rateLimit.unified === void 0 || rateLimit.unified.overageStatus !== void 0 || earlier === void 0 ? void 0 : overageFactsOf(earlier);
4936
- 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 } };
4937
4969
  return { ...current?.providers, [provider]: { ...state, rateLimit: keep ? state.rateLimit : merged } };
4938
4970
  })
4939
4971
  };
@@ -7385,22 +7417,38 @@ function windowOf(reported) {
7385
7417
  ...utilization !== void 0 && utilization >= 1 ? { status: "rejected" } : {}
7386
7418
  };
7387
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
+ }
7388
7434
  function unifiedFromReportedLimits(reported) {
7389
7435
  const fiveHour = windowOf(reported?.five_hour);
7390
7436
  const sevenDay = windowOf(reported?.seven_day);
7391
- if (fiveHour === void 0 && sevenDay === void 0) {
7437
+ const extraUsage = extraUsageOf(reported);
7438
+ if (fiveHour === void 0 && sevenDay === void 0 && extraUsage === void 0) {
7392
7439
  return void 0;
7393
7440
  }
7394
- return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay } };
7441
+ return { ...fiveHour === void 0 ? {} : { fiveHour }, ...sevenDay === void 0 ? {} : { sevenDay }, ...extraUsage };
7395
7442
  }
7396
7443
  function isAnthropicUsageProbeable(member) {
7397
- const unified = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified;
7398
- 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";
7399
7445
  }
7400
7446
  function isAnthropicUsageStale(member, nowMs) {
7401
7447
  const rateLimit = member.snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit;
7402
- const freshnessMs = rateLimit?.unified === void 0 ? NO_PLAN_WINDOWS_FRESHNESS_MS : ANTHROPIC_USAGE_FRESHNESS_MS;
7403
- 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);
7404
7452
  }
7405
7453
  function poolIdentityNames(pools, poolName) {
7406
7454
  const seenPools = /* @__PURE__ */ new Set();
@@ -7481,7 +7529,6 @@ var init_anthropicUsageRefresh = __esm({
7481
7529
  init_middleware();
7482
7530
  init_pick();
7483
7531
  init_plan2();
7484
- init_rateLimit();
7485
7532
  PERCENT2 = 100;
7486
7533
  ANTHROPIC_USAGE_FRESHNESS_MS = FIVE_HOUR_WINDOW_MS / PERCENT2;
7487
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<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-shim",
3
- "version": "9.2.1",
3
+ "version": "9.3.1",
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>",