claude-use 11.24.0 → 11.26.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/index.mjs CHANGED
@@ -223,7 +223,7 @@ function isTimeZone(name) {
223
223
  return false;
224
224
  }
225
225
  }
226
- var CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, ANTIGRAVITY_TIERS, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_MODEL, ANTIGRAVITY_DEFAULT_TIER_MODELS, ANTIGRAVITY_DEFAULT_EFFORT, AntigravityModelTargetSchema, AntigravityProviderConfigSchema, CODEX_TIERS, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_LOGIN, CODEX_DEFAULT_MODEL, CODEX_DEFAULT_TIER_MODELS, CODEX_DEFAULT_EFFORT, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, WHOLE_PERCENT_MAX, CompactAtUtilisationSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
226
+ var CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, ANTIGRAVITY_MODES, CLAUDE_TIERS, ANTIGRAVITY_EFFORTS, ANTIGRAVITY_DEFAULT_MODE, ANTIGRAVITY_DEFAULT_MODEL, ANTIGRAVITY_DEFAULT_TIER_MODELS, ANTIGRAVITY_DEFAULT_EFFORT, AntigravityModelTargetSchema, AntigravityProviderConfigSchema, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_LOGIN, CODEX_DEFAULT_MODEL, CODEX_DEFAULT_TIER_MODELS, CODEX_DEFAULT_EFFORT, CodexProviderConfigSchema, ProviderRouteSchema, PickerModelSchema, PickerModelsSchema, ProviderCatalogueSchema, HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, WHOLE_PERCENT_MAX, CompactAtUtilisationSchema, PoolSchema, WEEKDAYS, AnchorSchema, JOB_WINDOWS, JobTriggerSchema, JobTargetSchema, JobSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
227
227
  var init_schema = __esm({
228
228
  "src/config/schema.ts"() {
229
229
  "use strict";
@@ -321,7 +321,7 @@ var init_schema = __esm({
321
321
  });
322
322
  PROVIDER_KINDS = ["http", "codex", "antigravity"];
323
323
  ANTIGRAVITY_MODES = ["cloud", "local"];
324
- ANTIGRAVITY_TIERS = ["fable", "opus", "sonnet", "haiku"];
324
+ CLAUDE_TIERS = ["fable", "opus", "sonnet", "haiku"];
325
325
  ANTIGRAVITY_EFFORTS = ["none", "low", "medium", "high", "xhigh", "max"];
326
326
  ANTIGRAVITY_DEFAULT_MODE = "cloud";
327
327
  ANTIGRAVITY_DEFAULT_MODEL = "gemini-3.8-flash-high";
@@ -338,7 +338,7 @@ var init_schema = __esm({
338
338
  mode: z.enum(ANTIGRAVITY_MODES).optional(),
339
339
  /** The model a request maps to when no tier matches its model name. */
340
340
  defaultModel: z.string().min(1).optional(),
341
- /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `ANTIGRAVITY_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. A value is one model or an ordered list of candidates: the request goes to the first whose quota windows are not spent, and when every candidate is spent, to the one whose binding window lifts soonest. */
341
+ /** Model name mapping. A key naming a tier (`fable`, `opus`, `sonnet`, `haiku`) overrides that tier's shipped model and is matched by substring of the requested name in `CLAUDE_TIERS` order; any other key is an alias, matched against the whole requested name case-insensitively, so `/model <alias>` selects its backend model. An alias outranks every other rule, including the pass-through of backend names. A value is one model or an ordered list of candidates: the request goes to the first whose quota windows are not spent, and when every candidate is spent, to the one whose binding window lifts soonest. */
342
342
  models: z.record(z.string().min(1), AntigravityModelTargetSchema).optional(),
343
343
  /** When every candidate of the tier a request names has no quota left, serve it from the next tier down, and onward through the lower tiers, instead of failing with the quota limit. Applies to a name that selects a tier (`/model fable`), not to an alias or a backend model name. Defaults to false. */
344
344
  degradeDownTiers: z.boolean().optional(),
@@ -361,7 +361,6 @@ var init_schema = __esm({
361
361
  socketPath: z.string().min(1).optional()
362
362
  }).optional()
363
363
  });
364
- CODEX_TIERS = ["fable", "opus", "sonnet", "haiku"];
365
364
  CODEX_EFFORTS = ["none", "low", "medium", "high"];
366
365
  CODEX_LOGINS = ["codex-cli", "chatgpt-sign-in"];
367
366
  CODEX_DEFAULT_LOGIN = "codex-cli";
@@ -376,7 +375,7 @@ var init_schema = __esm({
376
375
  CodexProviderConfigSchema = z.strictObject({
377
376
  /** The codex model a request maps to when no tier matches its model name. */
378
377
  defaultModel: z.string().min(1).optional(),
379
- /** Per-tier overrides of the shipped mapping, matched by substring of the requested model name in `CODEX_TIERS` order. */
378
+ /** Per-tier overrides of the shipped mapping, matched by substring of the requested model name in `CLAUDE_TIERS` order. */
380
379
  models: z.strictObject({
381
380
  fable: z.string().min(1).optional(),
382
381
  opus: z.string().min(1).optional(),
@@ -396,6 +395,19 @@ var init_schema = __esm({
396
395
  /** The model name to rewrite the request to before it reaches the target, for a provider that expects another form (OpenRouter's `anthropic/claude-...` for instance). A route that rewrites reads the whole body, the one copy the rewrite needs. */
397
396
  model: z.string().min(1).optional()
398
397
  });
398
+ PickerModelSchema = z.strictObject({
399
+ model: z.string().min(1),
400
+ tier: z.enum(CLAUDE_TIERS),
401
+ label: z.string().min(1).optional(),
402
+ description: z.string().min(1).optional()
403
+ });
404
+ PickerModelsSchema = z.array(PickerModelSchema).refine((models) => new Set(models.map((entry) => entry.model)).size === models.length, { message: "pickerModels names a model more than once" });
405
+ ProviderCatalogueSchema = z.strictObject({
406
+ tier: z.enum(CLAUDE_TIERS),
407
+ include: z.array(z.string().min(1)).min(1).optional(),
408
+ exclude: z.array(z.string().min(1)).min(1).optional(),
409
+ url: z.url().optional()
410
+ });
399
411
  HttpProviderSchema = z.strictObject({
400
412
  $schema: z.string().optional(),
401
413
  kind: z.literal("http").optional(),
@@ -403,6 +415,10 @@ var init_schema = __esm({
403
415
  baseUrl: z.url(),
404
416
  credential: ProviderCredentialSchema,
405
417
  env: ProviderEnvSchema.optional(),
418
+ /** Extra models `/model` lists beside the ones the tier settings name. */
419
+ pickerModels: PickerModelsSchema.optional(),
420
+ /** The provider's own model catalogue, listed in `/model` when set. */
421
+ catalogue: ProviderCatalogueSchema.optional(),
406
422
  /** Per-request routing: when present, each request this provider would serve is matched against the list in order, and the first definite match is sent to that entry's provider instead (itself resolved exactly as a directly dialled request would be). Unmatched requests stay on this provider. */
407
423
  routes: z.array(ProviderRouteSchema).optional()
408
424
  });
@@ -412,6 +428,8 @@ var init_schema = __esm({
412
428
  displayName: z.string().min(1),
413
429
  credential: ProviderCredentialSchema,
414
430
  env: ProviderEnvSchema.optional(),
431
+ /** Extra models `/model` lists beside the ones the tier settings name. */
432
+ pickerModels: PickerModelsSchema.optional(),
415
433
  codex: CodexProviderConfigSchema.optional()
416
434
  });
417
435
  AntigravityProviderSchema = z.strictObject({
@@ -420,6 +438,8 @@ var init_schema = __esm({
420
438
  displayName: z.string().min(1),
421
439
  credential: ProviderCredentialSchema,
422
440
  env: ProviderEnvSchema.optional(),
441
+ /** Extra models `/model` lists beside the ones the tier settings name. */
442
+ pickerModels: PickerModelsSchema.optional(),
423
443
  antigravity: AntigravityProviderConfigSchema.optional()
424
444
  });
425
445
  ProviderSchema = z.discriminatedUnion("kind", [HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema]);
@@ -609,7 +629,7 @@ function parseIgnoringUnrecognisedKeys(schema, raw) {
609
629
  return second.success ? { success: true, data: second.data, ignored } : { success: false, issues: second.error.issues };
610
630
  }
611
631
  function describeIgnoredKeys(filePath, ignored) {
612
- const places = ignored.map(({ path: path42, keys }) => `${path42.length === 0 ? "" : `${path42.map(String).join(".")}.`}${keys.join(", ")}`);
632
+ const places = ignored.map(({ path: path43, keys }) => `${path43.length === 0 ? "" : `${path43.map(String).join(".")}.`}${keys.join(", ")}`);
613
633
  return `${filePath} has settings this version of agent-shim does not know and ignores: ${places.join("; ")}. A newer release may read them.`;
614
634
  }
615
635
  function noteIgnoredKeys(filePath, ignored) {
@@ -631,9 +651,9 @@ function restoreIgnoredKeys(filePath, value) {
631
651
  return value;
632
652
  }
633
653
  const restored = structuredClone(value);
634
- for (const { path: path42, values } of ignored) {
654
+ for (const { path: path43, values } of ignored) {
635
655
  let holder = restored;
636
- for (const step of path42) {
656
+ for (const step of path43) {
637
657
  holder = isRecord(holder) ? holder[step] : void 0;
638
658
  }
639
659
  if (isRecord(holder)) {
@@ -2911,7 +2931,7 @@ var init_package = __esm({
2911
2931
  "package.json"() {
2912
2932
  package_default = {
2913
2933
  name: "claude-use",
2914
- version: "11.24.0",
2934
+ version: "11.26.0",
2915
2935
  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.",
2916
2936
  license: "MIT",
2917
2937
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -6020,6 +6040,7 @@ function buildLayoutPaths(root) {
6020
6040
  usageDir: path23.join(root, "usage"),
6021
6041
  usageLogDir: path23.join(root, "usage", "log"),
6022
6042
  usageSnapshotsDir: path23.join(root, "usage", "snapshots"),
6043
+ catalogueDir: path23.join(root, "catalogues"),
6023
6044
  usagePicksFile: path23.join(root, "usage", "picks.json"),
6024
6045
  usageAnchorsFile: path23.join(root, "usage", "anchors.json"),
6025
6046
  usageJobsFile: path23.join(root, "usage", "jobs.json"),
@@ -6464,7 +6485,10 @@ function loadProvider(providersDir, name, port) {
6464
6485
  const raw = port.readConfigFile(filePath);
6465
6486
  return raw === void 0 ? void 0 : parseProviderFile(filePath, raw);
6466
6487
  }
6467
- function listProviders(paths) {
6488
+ function reportInvalidProvider(name, message) {
6489
+ console.error(`agent-shim: providers/${name}.json is invalid and was skipped: ${message}`);
6490
+ }
6491
+ function listProviders(paths, onInvalid = reportInvalidProvider) {
6468
6492
  const names = listProviderNames(
6469
6493
  (dir) => fs7.readdirSync(dir),
6470
6494
  paths.providersDir
@@ -6478,7 +6502,7 @@ function listProviders(paths) {
6478
6502
  if (!(error instanceof ConfigValidationError || error instanceof LegacyProviderFileError)) {
6479
6503
  throw error;
6480
6504
  }
6481
- console.error(`agent-shim: providers/${name}.json is invalid and was skipped: ${error.message}`);
6505
+ onInvalid(name, error.message);
6482
6506
  continue;
6483
6507
  }
6484
6508
  if (provider !== void 0) {
@@ -6528,6 +6552,9 @@ function addProvider(paths, name, input) {
6528
6552
  if (kind === "http" && input.baseUrl === void 0) {
6529
6553
  throw new ProviderKindMismatchError("An http provider needs --base-url.");
6530
6554
  }
6555
+ if (kind !== "http" && input.catalogue !== void 0) {
6556
+ throw new ProviderKindMismatchError("A model catalogue applies only to an http provider.");
6557
+ }
6531
6558
  if (kind !== "codex" && !isEmptyCodexConfig(input.codex)) {
6532
6559
  throw new ProviderKindMismatchError("Codex settings apply only to a codex provider (--kind codex).");
6533
6560
  }
@@ -6537,10 +6564,11 @@ function addProvider(paths, name, input) {
6537
6564
  const shared = {
6538
6565
  displayName: input.displayName,
6539
6566
  credential: { sources: input.sources, ...input.target === void 0 ? {} : { target: input.target } },
6540
- ...input.env === void 0 || Object.keys(input.env).length === 0 ? {} : { env: input.env }
6567
+ ...input.env === void 0 || Object.keys(input.env).length === 0 ? {} : { env: input.env },
6568
+ ...input.pickerModels === void 0 || input.pickerModels.length === 0 ? {} : { pickerModels: input.pickerModels }
6541
6569
  };
6542
6570
  const parsed = ProviderSchema.safeParse(
6543
- kind === "codex" ? { kind, ...shared, ...isEmptyCodexConfig(input.codex) ? {} : { codex: input.codex } } : kind === "antigravity" ? { kind, ...shared, ...isEmptyAntigravityConfig(input.antigravity) ? {} : { antigravity: input.antigravity } } : { ...shared, baseUrl: input.baseUrl }
6571
+ kind === "codex" ? { kind, ...shared, ...isEmptyCodexConfig(input.codex) ? {} : { codex: input.codex } } : kind === "antigravity" ? { kind, ...shared, ...isEmptyAntigravityConfig(input.antigravity) ? {} : { antigravity: input.antigravity } } : { ...shared, baseUrl: input.baseUrl, ...input.catalogue === void 0 ? {} : { catalogue: input.catalogue } }
6544
6572
  );
6545
6573
  if (!parsed.success) {
6546
6574
  throw new ConfigValidationError(providerJsonPath(paths, name), parsed.error.issues);
@@ -6555,6 +6583,12 @@ function updateProvider(paths, name, input) {
6555
6583
  }
6556
6584
  const unset = new Set(input.unsetEnv);
6557
6585
  const env = Object.fromEntries(Object.entries({ ...existing.env, ...input.env }).filter(([key]) => !unset.has(key)));
6586
+ const unsetPicker = new Set(input.unsetPickerModels);
6587
+ const added = new Map((input.pickerModels ?? []).map((entry) => [entry.model, entry]));
6588
+ const pickerModels = [
6589
+ ...(existing.pickerModels ?? []).filter((entry) => !unsetPicker.has(entry.model)).map((entry) => added.get(entry.model) ?? entry),
6590
+ ...[...added.values()].filter((entry) => !(existing.pickerModels ?? []).some((kept) => kept.model === entry.model))
6591
+ ];
6558
6592
  const target = input.target ?? existing.credential.target;
6559
6593
  const cache = input.cache === void 0 ? existing.credential.cache : input.cache === false ? void 0 : input.cache;
6560
6594
  if (isCodexProvider(existing) && input.baseUrl !== void 0) {
@@ -6563,6 +6597,9 @@ function updateProvider(paths, name, input) {
6563
6597
  if (isAntigravityProvider(existing) && input.baseUrl !== void 0) {
6564
6598
  throw new ProviderKindMismatchError(`Provider "${name}" is an antigravity provider, which has no base URL.`);
6565
6599
  }
6600
+ if ((isCodexProvider(existing) || isAntigravityProvider(existing)) && input.catalogue !== void 0 && input.catalogue !== false) {
6601
+ throw new ProviderKindMismatchError(`Provider "${name}" is not an http provider; a model catalogue applies only to an http provider.`);
6602
+ }
6566
6603
  if (!isCodexProvider(existing) && !isEmptyCodexConfig(input.codex)) {
6567
6604
  throw new ProviderKindMismatchError(`Provider "${name}" is not a codex provider; codex settings apply only to a codex provider.`);
6568
6605
  }
@@ -6576,7 +6613,8 @@ function updateProvider(paths, name, input) {
6576
6613
  ...target === void 0 ? {} : { target },
6577
6614
  ...cache === void 0 ? {} : { cache }
6578
6615
  },
6579
- env: Object.keys(env).length === 0 ? void 0 : env
6616
+ env: Object.keys(env).length === 0 ? void 0 : env,
6617
+ pickerModels: pickerModels.length === 0 ? void 0 : pickerModels
6580
6618
  };
6581
6619
  let candidate;
6582
6620
  if (isCodexProvider(existing)) {
@@ -6594,7 +6632,8 @@ function updateProvider(paths, name, input) {
6594
6632
  };
6595
6633
  candidate = { ...existing, ...shared, antigravity: isEmptyAntigravityConfig(antigravity) ? void 0 : antigravity };
6596
6634
  } else {
6597
- candidate = { ...existing, ...shared, ...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl } };
6635
+ const catalogue = input.catalogue === void 0 ? existing.catalogue : input.catalogue === false ? void 0 : input.catalogue;
6636
+ candidate = { ...existing, ...shared, catalogue, ...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl } };
6598
6637
  }
6599
6638
  const parsed = ProviderSchema.safeParse(candidate);
6600
6639
  if (!parsed.success) {
@@ -7919,7 +7958,7 @@ function candidatesOf(target) {
7919
7958
  return typeof target === "string" ? [target] : target;
7920
7959
  }
7921
7960
  function isAntigravityTier(key) {
7922
- return ANTIGRAVITY_TIERS.some((tier) => tier === key);
7961
+ return CLAUDE_TIERS.some((tier) => tier === key);
7923
7962
  }
7924
7963
  function resolveAntigravityConfig(config) {
7925
7964
  const overrides = config?.models ?? {};
@@ -7984,7 +8023,56 @@ var init_translate2 = __esm({
7984
8023
  }
7985
8024
  });
7986
8025
 
8026
+ // src/providerCatalogue.ts
8027
+ import path38 from "node:path";
8028
+ import picomatch4 from "picomatch";
8029
+ import { z as z30 } from "zod";
8030
+ function catalogueCachePath(paths, name) {
8031
+ return path38.join(paths.catalogueDir, `${name}.json`);
8032
+ }
8033
+ function parseCatalogueCache(text) {
8034
+ if (text === void 0) {
8035
+ return void 0;
8036
+ }
8037
+ try {
8038
+ const parsed = CatalogueCacheSchema.safeParse(JSON.parse(text));
8039
+ return parsed.success ? parsed.data : void 0;
8040
+ } catch {
8041
+ return void 0;
8042
+ }
8043
+ }
8044
+ function filterCatalogue(models, catalogue) {
8045
+ const included = catalogue.include === void 0 ? void 0 : picomatch4(catalogue.include, { dot: true });
8046
+ const excluded = catalogue.exclude === void 0 ? void 0 : picomatch4(catalogue.exclude, { dot: true });
8047
+ return models.filter((model) => included?.(model.id) !== false && excluded?.(model.id) !== true);
8048
+ }
8049
+ var DEFAULT_CANDIDATE_URLS, MS_PER_SECOND7, SECONDS_PER_HOUR2, HOURS_PER_DAY5, MS_PER_HOUR5, HOURS_BETWEEN_RETRIES, CATALOGUE_MAX_AGE_MS, CATALOGUE_RETRY_MS, CATALOGUE_REQUEST_SECONDS, CATALOGUE_REQUEST_TIMEOUT_MS, CATALOGUE_REFRESH_TIMEOUT_MS, CatalogueModelSchema, CatalogueCacheSchema;
8050
+ var init_providerCatalogue = __esm({
8051
+ "src/providerCatalogue.ts"() {
8052
+ "use strict";
8053
+ DEFAULT_CANDIDATE_URLS = 2;
8054
+ MS_PER_SECOND7 = 1e3;
8055
+ SECONDS_PER_HOUR2 = 3600;
8056
+ HOURS_PER_DAY5 = 24;
8057
+ MS_PER_HOUR5 = SECONDS_PER_HOUR2 * MS_PER_SECOND7;
8058
+ HOURS_BETWEEN_RETRIES = 1;
8059
+ CATALOGUE_MAX_AGE_MS = HOURS_PER_DAY5 * MS_PER_HOUR5;
8060
+ CATALOGUE_RETRY_MS = HOURS_BETWEEN_RETRIES * MS_PER_HOUR5;
8061
+ CATALOGUE_REQUEST_SECONDS = 10;
8062
+ CATALOGUE_REQUEST_TIMEOUT_MS = CATALOGUE_REQUEST_SECONDS * MS_PER_SECOND7;
8063
+ CATALOGUE_REFRESH_TIMEOUT_MS = DEFAULT_CANDIDATE_URLS * CATALOGUE_REQUEST_TIMEOUT_MS;
8064
+ CatalogueModelSchema = z30.strictObject({ id: z30.string().min(1), name: z30.string().min(1).optional() });
8065
+ CatalogueCacheSchema = z30.strictObject({ fetchedAt: z30.number(), url: z30.string().min(1), models: z30.array(CatalogueModelSchema) });
8066
+ }
8067
+ });
8068
+
7987
8069
  // src/launcher/modelPicker.ts
8070
+ function labelOf(model) {
8071
+ return model.toLowerCase().endsWith(CONTEXT_MARKER_1M) ? model.slice(0, -CONTEXT_MARKER_1M.length) : model;
8072
+ }
8073
+ function describedAs(model, description) {
8074
+ return model.toLowerCase().endsWith(CONTEXT_MARKER_1M) ? `${description}; 1M context` : description;
8075
+ }
7988
8076
  function joined(parts) {
7989
8077
  const last = parts[parts.length - 1];
7990
8078
  return last === void 0 || parts.length === 1 ? last ?? "" : `${parts.slice(0, -1).join(", ")} and ${last}`;
@@ -7998,7 +8086,7 @@ function rowOf2(model, reaches) {
7998
8086
  const fallbacks = reaches.filter((reach) => reach.standing === "fallback").map((reach) => reach.tier);
7999
8087
  const serves = firsts.length === 0 ? [] : [`Serves the ${joined(firsts)} tier${firsts.length === 1 ? "" : "s"}`];
8000
8088
  const falls = fallbacks.length === 0 ? [] : [`${serves.length === 0 ? "Fallback" : "fallback"} for ${joined(fallbacks)}`];
8001
- return { model, label: model, description: [...serves, ...falls].join("; "), behavesAs: TIER_BEHAVES_AS[lead.tier] };
8089
+ return { model, label: labelOf(model), description: describedAs(model, [...serves, ...falls].join("; ")), behavesAs: TIER_BEHAVES_AS[lead.tier] };
8002
8090
  }
8003
8091
  function rowsOfTable(table) {
8004
8092
  const reachesByModel = /* @__PURE__ */ new Map();
@@ -8015,47 +8103,63 @@ function rowsOfTable(table) {
8015
8103
  }
8016
8104
  function antigravityRows(provider) {
8017
8105
  const config = resolveAntigravityConfig(provider.antigravity);
8018
- const tiers = rowsOfTable(ANTIGRAVITY_TIERS.map((tier) => [tier, config.models[tier]]));
8106
+ const tiers = rowsOfTable(CLAUDE_TIERS.map((tier) => [tier, config.models[tier]]));
8019
8107
  const behavesAsOf = new Map(tiers.map((row) => [row.model, row.behavesAs]));
8020
8108
  const aliases = [...config.aliases].flatMap(([alias, candidates]) => {
8021
8109
  const [first] = candidates;
8022
8110
  const behavesAs = first === void 0 ? void 0 : behavesAsOf.get(first);
8023
- return behavesAs === void 0 ? [] : [{ model: alias, label: alias, description: `Alias for ${candidates.join(", then ")}`, behavesAs }];
8111
+ return behavesAs === void 0 ? [] : [{ model: alias, label: labelOf(alias), description: `Alias for ${candidates.join(", then ")}`, behavesAs }];
8024
8112
  });
8025
8113
  return [...tiers, ...aliases];
8026
8114
  }
8027
8115
  function codexRows(provider) {
8028
8116
  const config = resolveCodexConfig(provider.codex);
8029
- return rowsOfTable(CODEX_TIERS.map((tier) => [tier, [config.models[tier]]]));
8117
+ return rowsOfTable(CLAUDE_TIERS.map((tier) => [tier, [config.models[tier]]]));
8030
8118
  }
8031
8119
  function httpRows(provider) {
8032
8120
  const env = provider.env ?? {};
8033
- const table = CODEX_TIERS.flatMap((tier) => {
8121
+ const table = CLAUDE_TIERS.flatMap((tier) => {
8034
8122
  const model = env[TIER_ENV_VARIABLES[tier]];
8035
8123
  return model === void 0 || model === "" ? [] : [[tier, [model]]];
8036
8124
  });
8037
8125
  return rowsOfTable(table);
8038
8126
  }
8039
- function providerModelRows(provider) {
8040
- if (provider.kind === "codex") {
8041
- return codexRows(provider);
8042
- }
8043
- if (provider.kind === "antigravity") {
8044
- return antigravityRows(provider);
8127
+ function declaredRow(entry) {
8128
+ return {
8129
+ model: entry.model,
8130
+ label: entry.label ?? labelOf(entry.model),
8131
+ description: entry.description ?? describedAs(entry.model, `Declared by the provider for the ${entry.tier} tier`),
8132
+ behavesAs: TIER_BEHAVES_AS[entry.tier]
8133
+ };
8134
+ }
8135
+ function catalogueRows(provider, models) {
8136
+ if (provider.kind !== void 0 && provider.kind !== "http" || provider.catalogue === void 0) {
8137
+ return [];
8045
8138
  }
8046
- return httpRows(provider);
8139
+ const { tier } = provider.catalogue;
8140
+ return filterCatalogue(models, provider.catalogue).map((model) => ({ model: model.id, label: labelOf(model.id), description: describedAs(model.id, model.name === void 0 ? "Listed by the provider" : `Listed by the provider as ${model.name}`), behavesAs: TIER_BEHAVES_AS[tier] })).sort((left, right) => left.model.localeCompare(right.model));
8141
+ }
8142
+ function providerModelRows(provider, catalogue = []) {
8143
+ const derived = provider.kind === "codex" ? codexRows(provider) : provider.kind === "antigravity" ? antigravityRows(provider) : httpRows(provider);
8144
+ const declared = (provider.pickerModels ?? []).map(declaredRow);
8145
+ const declaredModels = new Set(declared.map((row) => row.model));
8146
+ const named = [...derived.filter((row) => !declaredModels.has(row.model)), ...declared];
8147
+ const taken = new Set(named.map((row) => labelOf(row.model)));
8148
+ return [...named, ...catalogueRows(provider, catalogue).filter((row) => !taken.has(labelOf(row.model)))];
8047
8149
  }
8048
- function modelPickerSettings(provider) {
8049
- const options = providerModelRows(provider);
8150
+ function modelPickerSettings(provider, catalogue = []) {
8151
+ const options = providerModelRows(provider, catalogue);
8050
8152
  return options.length === 0 ? void 0 : JSON.stringify({ modelPicker: { options, replaceBuiltInOptions: true } });
8051
8153
  }
8052
- var TIER_BEHAVES_AS, TIER_ENV_VARIABLES;
8154
+ var CONTEXT_MARKER_1M, TIER_BEHAVES_AS, TIER_ENV_VARIABLES;
8053
8155
  var init_modelPicker = __esm({
8054
8156
  "src/launcher/modelPicker.ts"() {
8055
8157
  "use strict";
8056
8158
  init_translate();
8057
8159
  init_translate2();
8160
+ init_providerCatalogue();
8058
8161
  init_schema();
8162
+ CONTEXT_MARKER_1M = "[1m]";
8059
8163
  TIER_BEHAVES_AS = Object.freeze({
8060
8164
  fable: "claude-fable-5-1",
8061
8165
  opus: "claude-opus-5-5",
@@ -8271,7 +8375,7 @@ var init_launchHook = __esm({
8271
8375
 
8272
8376
  // src/launcher.ts
8273
8377
  import { randomUUID as randomUUID4 } from "node:crypto";
8274
- import path38 from "node:path";
8378
+ import path39 from "node:path";
8275
8379
  function resolveIdentityCredential(identity, credential, env, port) {
8276
8380
  if (port === void 0) {
8277
8381
  return { ok: false, status: 1, message: `agent-shim: identity ${identity} needs its credential resolved, but this launcher has no credential port wired` };
@@ -8387,7 +8491,7 @@ function decideLaunch(params, readOnly) {
8387
8491
  identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
8388
8492
  globalDefaultConfigProfile: params.globalDefaultConfigProfile
8389
8493
  });
8390
- if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs13.readConfigFile(path38.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
8494
+ if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs13.readConfigFile(path39.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
8391
8495
  log.error(
8392
8496
  `agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
8393
8497
  );
@@ -8497,7 +8601,8 @@ function decideLaunch(params, readOnly) {
8497
8601
  log.info(`agent-shim: identity ${loginlessProvider.identity} has no stored login, so Remote Control, which needs one, is off for this launch; provider ${loginlessProvider.provider} runs without it`);
8498
8602
  }
8499
8603
  const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
8500
- const pickerSettings = selectedProvider === void 0 ? void 0 : modelPickerSettings(selectedProvider.definition);
8604
+ const catalogue = selectedProvider === void 0 ? void 0 : parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, selectedProvider.name)));
8605
+ const pickerSettings = selectedProvider === void 0 ? void 0 : modelPickerSettings(selectedProvider.definition, catalogue?.models);
8501
8606
  const callerSettings = hasSettingsArgument(parsedArgv.rest);
8502
8607
  if (pickerSettings !== void 0 && callerSettings && !readOnly) {
8503
8608
  log.info("agent-shim: this launch passes its own --settings, so /model keeps Claude Code's own model names instead of listing the provider's models");
@@ -8508,7 +8613,7 @@ function decideLaunch(params, readOnly) {
8508
8613
  extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
8509
8614
  passthrough: withLauncherSettings(params.supervised === void 0 ? parsedArgv.rest : withSupervision(parsedArgv.rest, params.supervised), launcherSettings)
8510
8615
  });
8511
- const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path38.join(paths.identitiesDir, identityDecision.name);
8616
+ const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path39.join(paths.identitiesDir, identityDecision.name);
8512
8617
  const decision = {
8513
8618
  identitySource: identityDecision.source,
8514
8619
  configDirEscapeHatch: identityDecision.configDirEscapeHatch,
@@ -8549,7 +8654,7 @@ function prepareLaunch(params) {
8549
8654
  );
8550
8655
  const updateCheck = runLaunchUpdateCheck({
8551
8656
  mode: params.updateMode ?? "off",
8552
- checkPath: path38.join(paths.root, "update.check"),
8657
+ checkPath: path39.join(paths.root, "update.check"),
8553
8658
  currentVersion: package_default.version,
8554
8659
  port: params.update
8555
8660
  });
@@ -8697,6 +8802,7 @@ var init_launcher = __esm({
8697
8802
  init_extraFlags();
8698
8803
  init_claudeSession();
8699
8804
  init_modelPicker();
8805
+ init_providerCatalogue();
8700
8806
  init_pool();
8701
8807
  init_resumeContext();
8702
8808
  init_lock();
@@ -8715,12 +8821,12 @@ var init_launcher = __esm({
8715
8821
  });
8716
8822
 
8717
8823
  // src/ownCli.ts
8718
- import path39 from "node:path";
8824
+ import path40 from "node:path";
8719
8825
  function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string" ? __AGENT_SHIM_DIST_DIR__ : void 0) {
8720
8826
  if (distDir === void 0) {
8721
8827
  throw new OwnCliPathUnknownError();
8722
8828
  }
8723
- return path39.join(distDir, OWN_CLI_FILE_NAME);
8829
+ return path40.join(distDir, OWN_CLI_FILE_NAME);
8724
8830
  }
8725
8831
  var OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
8726
8832
  var init_ownCli = __esm({
@@ -8750,10 +8856,10 @@ var init_selfIdentity = __esm({
8750
8856
 
8751
8857
  // src/frontdoor/trust.ts
8752
8858
  import { createHash as createHash7 } from "node:crypto";
8753
- import path40 from "node:path";
8859
+ import path41 from "node:path";
8754
8860
  function resolveTrustBundle(params) {
8755
8861
  const { caCertFile, bundlesDir, variable, inherited, fs: fs13 } = params;
8756
- if (inherited === void 0 || inherited === "" || path40.resolve(inherited) === path40.resolve(caCertFile)) {
8862
+ if (inherited === void 0 || inherited === "" || path41.resolve(inherited) === path41.resolve(caCertFile)) {
8757
8863
  return { path: caCertFile };
8758
8864
  }
8759
8865
  const caPem = fs13.readFileUtf8(caCertFile);
@@ -8771,7 +8877,7 @@ function resolveTrustBundle(params) {
8771
8877
  }
8772
8878
  const combined = `${inheritedPem.trimEnd()}
8773
8879
  ${caPem}`;
8774
- const bundle = path40.join(bundlesDir, `${createHash7("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
8880
+ const bundle = path41.join(bundlesDir, `${createHash7("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
8775
8881
  if (!fs13.exists(bundle)) {
8776
8882
  fs13.mkdirp(bundlesDir);
8777
8883
  fs13.writeFileAtomic(bundle, combined);
@@ -8849,7 +8955,7 @@ var init_realFrontDoorPort = __esm({
8849
8955
 
8850
8956
  // src/launchWiring.ts
8851
8957
  import os8 from "node:os";
8852
- import path41 from "node:path";
8958
+ import path42 from "node:path";
8853
8959
  import { randomUUID as randomUUID5 } from "node:crypto";
8854
8960
  function buildFarmRuntime(paths, cwd) {
8855
8961
  const home = os8.homedir();
@@ -8903,7 +9009,7 @@ function realPrepareLaunchParams(paths, options) {
8903
9009
  headroom: realHeadroomPort(paths, { spawnDaemon: options.spawnDaemon, cwd: farm.runtime.cwd }),
8904
9010
  frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
8905
9011
  credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
8906
- hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: realRunPort }, { farmRoot: path41.join(paths.identitiesDir, identity), hasCredentialBlock: false }).state !== "signed-out",
9012
+ hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: realRunPort }, { farmRoot: path42.join(paths.identitiesDir, identity), hasCredentialBlock: false }).state !== "signed-out",
8907
9013
  ...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
8908
9014
  ...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
8909
9015
  ...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
@@ -9178,76 +9284,76 @@ var init_identityClaude = __esm({
9178
9284
  });
9179
9285
 
9180
9286
  // src/usage/providerQuota.ts
9181
- import { z as z30 } from "zod";
9182
- var MS_PER_SECOND7, SECONDS_PER_HOUR2, HOURS_PER_DAY5, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema, ANTIGRAVITY_HOST, ANTIGRAVITY_QUOTA_URL, ANTIGRAVITY_USER_URL, FIVE_HOURS2, DAYS_PER_WEEK2, FIVE_HOURS_MS, WEEK_MS, AntigravityBucketSchema, AntigravitySummarySchema, GoogleTokenInfoSchema, AntigravityUserSchema;
9287
+ import { z as z31 } from "zod";
9288
+ var MS_PER_SECOND8, SECONDS_PER_HOUR3, HOURS_PER_DAY6, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema, ANTIGRAVITY_HOST, ANTIGRAVITY_QUOTA_URL, ANTIGRAVITY_USER_URL, FIVE_HOURS2, DAYS_PER_WEEK2, FIVE_HOURS_MS, WEEK_MS, AntigravityBucketSchema, AntigravitySummarySchema, GoogleTokenInfoSchema, AntigravityUserSchema;
9183
9289
  var init_providerQuota = __esm({
9184
9290
  "src/usage/providerQuota.ts"() {
9185
9291
  "use strict";
9186
9292
  init_cloudUpstream();
9187
9293
  init_schema2();
9188
- MS_PER_SECOND7 = 1e3;
9189
- SECONDS_PER_HOUR2 = 3600;
9190
- HOURS_PER_DAY5 = 24;
9294
+ MS_PER_SECOND8 = 1e3;
9295
+ SECONDS_PER_HOUR3 = 3600;
9296
+ HOURS_PER_DAY6 = 24;
9191
9297
  DAYS_PER_MONTH = 30;
9192
9298
  ZAI_HOST = "api.z.ai";
9193
9299
  ZAI_QUOTA_URL = `https://${ZAI_HOST}/api/monitor/usage/quota/limit`;
9194
9300
  ZAI_UNIT_HOURS = 3;
9195
9301
  ZAI_UNIT_MONTHS = 5;
9196
9302
  ZAI_UNIT_MS = /* @__PURE__ */ new Map([
9197
- [ZAI_UNIT_HOURS, SECONDS_PER_HOUR2 * MS_PER_SECOND7],
9198
- [ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY5 * SECONDS_PER_HOUR2 * MS_PER_SECOND7]
9303
+ [ZAI_UNIT_HOURS, SECONDS_PER_HOUR3 * MS_PER_SECOND8],
9304
+ [ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND8]
9199
9305
  ]);
9200
- ZaiLimitSchema = z30.object({
9201
- type: z30.string(),
9202
- unit: z30.number().int(),
9203
- number: z30.number().int().positive(),
9204
- percentage: z30.number().nonnegative(),
9205
- nextResetTime: z30.number().positive().optional(),
9206
- usage: z30.number().nonnegative().optional(),
9207
- currentValue: z30.number().nonnegative().optional(),
9208
- remaining: z30.number().nonnegative().optional()
9306
+ ZaiLimitSchema = z31.object({
9307
+ type: z31.string(),
9308
+ unit: z31.number().int(),
9309
+ number: z31.number().int().positive(),
9310
+ percentage: z31.number().nonnegative(),
9311
+ nextResetTime: z31.number().positive().optional(),
9312
+ usage: z31.number().nonnegative().optional(),
9313
+ currentValue: z31.number().nonnegative().optional(),
9314
+ remaining: z31.number().nonnegative().optional()
9209
9315
  });
9210
- ZaiResponseSchema = z30.object({
9211
- success: z30.boolean(),
9212
- msg: z30.string().optional(),
9213
- data: z30.object({ level: z30.string().optional(), limits: z30.array(ZaiLimitSchema) })
9316
+ ZaiResponseSchema = z31.object({
9317
+ success: z31.boolean(),
9318
+ msg: z31.string().optional(),
9319
+ data: z31.object({ level: z31.string().optional(), limits: z31.array(ZaiLimitSchema) })
9214
9320
  });
9215
9321
  OPENROUTER_HOST = "openrouter.ai";
9216
9322
  OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
9217
9323
  OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
9218
- MS_PER_DAY3 = HOURS_PER_DAY5 * SECONDS_PER_HOUR2 * MS_PER_SECOND7;
9219
- OpenRouterKeySchema = z30.object({
9220
- data: z30.object({
9221
- limit: z30.number().nonnegative().nullable(),
9222
- limit_remaining: z30.number().nullable(),
9223
- limit_reset: z30.string().nullable(),
9224
- is_free_tier: z30.boolean().optional(),
9225
- free_model_daily_requests: z30.object({ used: z30.number().nonnegative(), limit: z30.number().nonnegative(), remaining: z30.number() }).optional()
9324
+ MS_PER_DAY3 = HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND8;
9325
+ OpenRouterKeySchema = z31.object({
9326
+ data: z31.object({
9327
+ limit: z31.number().nonnegative().nullable(),
9328
+ limit_remaining: z31.number().nullable(),
9329
+ limit_reset: z31.string().nullable(),
9330
+ is_free_tier: z31.boolean().optional(),
9331
+ free_model_daily_requests: z31.object({ used: z31.number().nonnegative(), limit: z31.number().nonnegative(), remaining: z31.number() }).optional()
9226
9332
  })
9227
9333
  });
9228
- OpenRouterCreditsSchema = z30.object({ data: z30.object({ total_credits: z30.number().nonnegative(), total_usage: z30.number().nonnegative() }) });
9334
+ OpenRouterCreditsSchema = z31.object({ data: z31.object({ total_credits: z31.number().nonnegative(), total_usage: z31.number().nonnegative() }) });
9229
9335
  ANTIGRAVITY_HOST = "daily-cloudcode-pa.googleapis.com";
9230
9336
  ANTIGRAVITY_QUOTA_URL = `https://${ANTIGRAVITY_HOST}/v1internal:retrieveUserQuotaSummary`;
9231
9337
  ANTIGRAVITY_USER_URL = `https://${ANTIGRAVITY_HOST}/v1internal:loadCodeAssist`;
9232
9338
  FIVE_HOURS2 = 5;
9233
9339
  DAYS_PER_WEEK2 = 7;
9234
- FIVE_HOURS_MS = FIVE_HOURS2 * SECONDS_PER_HOUR2 * MS_PER_SECOND7;
9235
- WEEK_MS = DAYS_PER_WEEK2 * HOURS_PER_DAY5 * SECONDS_PER_HOUR2 * MS_PER_SECOND7;
9236
- AntigravityBucketSchema = z30.object({
9237
- bucketId: z30.string(),
9238
- remainingFraction: z30.number().optional(),
9239
- resetTime: z30.string().optional()
9340
+ FIVE_HOURS_MS = FIVE_HOURS2 * SECONDS_PER_HOUR3 * MS_PER_SECOND8;
9341
+ WEEK_MS = DAYS_PER_WEEK2 * HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND8;
9342
+ AntigravityBucketSchema = z31.object({
9343
+ bucketId: z31.string(),
9344
+ remainingFraction: z31.number().optional(),
9345
+ resetTime: z31.string().optional()
9240
9346
  });
9241
- AntigravitySummarySchema = z30.object({ groups: z30.array(z30.object({ buckets: z30.array(AntigravityBucketSchema) })) });
9242
- GoogleTokenInfoSchema = z30.object({
9243
- email: z30.string().optional(),
9244
- sub: z30.string().optional()
9347
+ AntigravitySummarySchema = z31.object({ groups: z31.array(z31.object({ buckets: z31.array(AntigravityBucketSchema) })) });
9348
+ GoogleTokenInfoSchema = z31.object({
9349
+ email: z31.string().optional(),
9350
+ sub: z31.string().optional()
9245
9351
  });
9246
- AntigravityUserSchema = z30.object({
9352
+ AntigravityUserSchema = z31.object({
9247
9353
  /** The code-assist tier context, which defaults to the free tier for every account. */
9248
- currentTier: z30.object({ name: z30.string().optional(), id: z30.string().optional() }).optional(),
9354
+ currentTier: z31.object({ name: z31.string().optional(), id: z31.string().optional() }).optional(),
9249
9355
  /** The account's paid subscription; absent when the account has none. */
9250
- paidTier: z30.object({ name: z30.string().optional(), id: z30.string().optional() }).optional()
9356
+ paidTier: z31.object({ name: z31.string().optional(), id: z31.string().optional() }).optional()
9251
9357
  });
9252
9358
  }
9253
9359
  });
@@ -9876,8 +9982,8 @@ function parseConnectTarget(authority) {
9876
9982
  function isInterceptedHost(host, interceptHosts) {
9877
9983
  return interceptHosts.includes(host);
9878
9984
  }
9879
- function servedByPipeline(path42) {
9880
- return path42?.startsWith(ROUTED_PATH_PREFIX) === true;
9985
+ function servedByPipeline(path43) {
9986
+ return path43?.startsWith(ROUTED_PATH_PREFIX) === true;
9881
9987
  }
9882
9988
  var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
9883
9989
  "connection",
@@ -10671,11 +10777,11 @@ function createRcSessionTracker(deps) {
10671
10777
  };
10672
10778
  const observeExchange = (request4) => {
10673
10779
  const method = (request4.method ?? "").toUpperCase();
10674
- const path42 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
10675
- if (!path42.startsWith(RC_SESSIONS_PATH_PREFIX)) {
10780
+ const path43 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
10781
+ if (!path43.startsWith(RC_SESSIONS_PATH_PREFIX)) {
10676
10782
  return void 0;
10677
10783
  }
10678
- const tail = path42.slice(RC_SESSIONS_PATH_PREFIX.length);
10784
+ const tail = path43.slice(RC_SESSIONS_PATH_PREFIX.length);
10679
10785
  const facts = {
10680
10786
  oauthAuthorization: oauthAuthorizationOf(request4.headers),
10681
10787
  anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
@@ -11065,8 +11171,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
11065
11171
  function isRcReadFileEncoding(value) {
11066
11172
  return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
11067
11173
  }
11068
- function buildRcReadFilePayload(requestId, path42, options) {
11069
- return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path42, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
11174
+ function buildRcReadFilePayload(requestId, path43, options) {
11175
+ return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path43, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
11070
11176
  }
11071
11177
  function buildRcFileSuggestionsPayload(requestId, query) {
11072
11178
  return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
@@ -11168,15 +11274,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
11168
11274
  const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
11169
11275
  return result.ok ? { ...result, requestId } : result;
11170
11276
  }
11171
- async function readRcSessionFile(deps, sessionId, path42, options) {
11172
- if (path42 === "") {
11277
+ async function readRcSessionFile(deps, sessionId, path43, options) {
11278
+ if (path43 === "") {
11173
11279
  return { ok: false, message: "a read-file write needs a non-empty path: the SDK's own field names the file the worker resolves against the session's cwd, and an empty string names none" };
11174
11280
  }
11175
11281
  if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
11176
11282
  return { ok: false, message: "a read-file write's max-bytes is a positive whole number of bytes: the SDK's own field caps the read, and a zero or negative cap reads nothing" };
11177
11283
  }
11178
11284
  const requestId = deps.newUuid();
11179
- const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path42, options), `read ${path42} from session ${sessionId}`);
11285
+ const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path43, options), `read ${path43} from session ${sessionId}`);
11180
11286
  return result.ok ? { ...result, requestId } : result;
11181
11287
  }
11182
11288
  async function suggestRcSessionFiles(deps, sessionId, query) {
@@ -11345,11 +11451,11 @@ function createRcControlHandler(deps) {
11345
11451
  path: "read-file",
11346
11452
  read: (body) => {
11347
11453
  const session = bodyString(body, "session");
11348
- const path42 = bodyString(body, "path");
11454
+ const path43 = bodyString(body, "path");
11349
11455
  const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
11350
11456
  const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
11351
- const refused2 = session === void 0 || path42 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
11352
- return refused2 ? { error: `the read-file body must be JSON naming a non-empty session id and path, maxBytes only as a positive whole number or absent, and an encoding the SDK's own type permits (${RC_READ_FILE_ENCODINGS.join(", ")}) or none` } : { session, run: async () => await deps.readFile(session, path42, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
11457
+ const refused2 = session === void 0 || path43 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
11458
+ return refused2 ? { error: `the read-file body must be JSON naming a non-empty session id and path, maxBytes only as a positive whole number or absent, and an encoding the SDK's own type permits (${RC_READ_FILE_ENCODINGS.join(", ")}) or none` } : { session, run: async () => await deps.readFile(session, path43, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
11353
11459
  }
11354
11460
  },
11355
11461
  {
@@ -11659,9 +11765,9 @@ function requestIdOfBody(body) {
11659
11765
  }
11660
11766
  function frontDoorRcControl(transport, token) {
11661
11767
  const headers = { authorization: `Bearer ${token}` };
11662
- const listAnswerOf = async (path42, what) => {
11768
+ const listAnswerOf = async (path43, what) => {
11663
11769
  try {
11664
- return await transport.request({ method: "GET", path: path42, headers });
11770
+ return await transport.request({ method: "GET", path: path43, headers });
11665
11771
  } catch (error) {
11666
11772
  throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
11667
11773
  }
@@ -11733,10 +11839,10 @@ function frontDoorRcControl(transport, token) {
11733
11839
  }
11734
11840
  return pending;
11735
11841
  };
11736
- const writeOf = async (path42, body, describeFailure2) => {
11842
+ const writeOf = async (path43, body, describeFailure2) => {
11737
11843
  let answer;
11738
11844
  try {
11739
- answer = await transport.request({ method: "POST", path: path42, headers: { ...headers, "content-type": "application/json" }, body });
11845
+ answer = await transport.request({ method: "POST", path: path43, headers: { ...headers, "content-type": "application/json" }, body });
11740
11846
  } catch (error) {
11741
11847
  return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
11742
11848
  }
@@ -11767,10 +11873,10 @@ function frontDoorRcControl(transport, token) {
11767
11873
  endSession: async (sessionId, reason) => await writeOf(`${CONTROL_PATH_PREFIX}/end-session`, JSON.stringify({ session: sessionId, ...reason === void 0 ? {} : { reason } }), (status, message) => `ending ${sessionId} failed (HTTP ${String(status)}): ${message}`),
11768
11874
  getUsage: async (sessionId, skipBehaviors) => await writeOf(`${CONTROL_PATH_PREFIX}/get-usage`, JSON.stringify({ session: sessionId, ...skipBehaviors === void 0 ? {} : { skipBehaviors } }), (status, message) => `requesting the usage of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
11769
11875
  getContextUsage: async (sessionId, detail) => await writeOf(`${CONTROL_PATH_PREFIX}/get-context-usage`, JSON.stringify({ session: sessionId, ...detail === void 0 ? {} : { detail } }), (status, message) => `requesting the context usage of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
11770
- readFile: async (sessionId, path42, options) => await writeOf(
11876
+ readFile: async (sessionId, path43, options) => await writeOf(
11771
11877
  `${CONTROL_PATH_PREFIX}/read-file`,
11772
- JSON.stringify({ session: sessionId, path: path42, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
11773
- (status, message) => `reading ${path42} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
11878
+ JSON.stringify({ session: sessionId, path: path43, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
11879
+ (status, message) => `reading ${path43} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
11774
11880
  ),
11775
11881
  fileSuggestions: async (sessionId, query) => await writeOf(`${CONTROL_PATH_PREFIX}/file-suggestions`, JSON.stringify({ session: sessionId, query }), (status, message) => `requesting file suggestions from ${sessionId} failed (HTTP ${String(status)}): ${message}`),
11776
11882
  keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
@@ -11929,12 +12035,12 @@ function tlsFacts(options) {
11929
12035
  }
11930
12036
  function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
11931
12037
  const agent = new ExemptTlsAgent();
11932
- const post = async (path42, headers, body) => await new Promise((resolve, reject) => {
12038
+ const post = async (path43, headers, body) => await new Promise((resolve, reject) => {
11933
12039
  const options = {
11934
12040
  host: target.host,
11935
12041
  port: target.port,
11936
12042
  method: "POST",
11937
- path: path42,
12043
+ path: path43,
11938
12044
  // The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
11939
12045
  headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
11940
12046
  agent
@@ -11999,12 +12105,12 @@ function lateRcStreamDial(resolve) {
11999
12105
  }
12000
12106
  function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
12001
12107
  const agent = new ExemptTlsAgent();
12002
- const request4 = async (method, path42, headers, body, signal) => await new Promise((resolve, reject) => {
12108
+ const request4 = async (method, path43, headers, body, signal) => await new Promise((resolve, reject) => {
12003
12109
  const options = {
12004
12110
  host: target.host,
12005
12111
  port: target.port,
12006
12112
  method,
12007
- path: path42,
12113
+ path: path43,
12008
12114
  // The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
12009
12115
  headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
12010
12116
  agent,
@@ -12046,9 +12152,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
12046
12152
  return { status, body: await readAll(response) };
12047
12153
  },
12048
12154
  openStream: async (sessionId, headers, resume, signal) => {
12049
- const path42 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
12155
+ const path43 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
12050
12156
  const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
12051
- const { status, response } = await request4("GET", path42, streamHeaders, void 0, signal);
12157
+ const { status, response } = await request4("GET", path43, streamHeaders, void 0, signal);
12052
12158
  if (!isSuccessful2(status)) {
12053
12159
  await readAll(response);
12054
12160
  return { status, chunks: NO_CHUNKS };
@@ -13200,19 +13306,19 @@ function writePools(paths, pools) {
13200
13306
  applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
13201
13307
  }
13202
13308
  function poolCycleOf(pools, name) {
13203
- const walk = (current, path42) => {
13309
+ const walk = (current, path43) => {
13204
13310
  for (const entry of pools[current]?.identities ?? []) {
13205
13311
  const nested = poolNameOf(poolMemberIdentity(entry));
13206
13312
  if (nested === void 0) {
13207
13313
  continue;
13208
13314
  }
13209
13315
  if (nested === name) {
13210
- return [...path42, nested];
13316
+ return [...path43, nested];
13211
13317
  }
13212
- if (path42.includes(nested)) {
13318
+ if (path43.includes(nested)) {
13213
13319
  continue;
13214
13320
  }
13215
- const found = walk(nested, [...path42, nested]);
13321
+ const found = walk(nested, [...path43, nested]);
13216
13322
  if (found !== void 0) {
13217
13323
  return found;
13218
13324
  }
@@ -15491,7 +15597,7 @@ function profileValue(name, paths) {
15491
15597
  function createConfigApiRouter(deps) {
15492
15598
  const authed = doorApiAuth(deps.expectedToken);
15493
15599
  const { paths } = deps;
15494
- const route = (path42, summary) => authed.meta(openapi3({ method: "POST", path: path42, summary, tags: [CONFIG_API_TAG] }));
15600
+ const route = (path43, summary) => authed.meta(openapi3({ method: "POST", path: path43, summary, tags: [CONFIG_API_TAG] }));
15495
15601
  return {
15496
15602
  config: {
15497
15603
  identity: {