agent-shim 11.25.0 → 11.27.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
@@ -34,7 +34,10 @@ var init_categories_default = __esm({
34
34
  "usage-data",
35
35
  "ide",
36
36
  "cache",
37
- "scheduled_tasks.lock"
37
+ "scheduled_tasks.lock",
38
+ "policy-limits.json*",
39
+ "remote-settings.json*",
40
+ "state"
38
41
  ],
39
42
  history: [
40
43
  "projects",
@@ -223,7 +226,7 @@ function isTimeZone(name) {
223
226
  return false;
224
227
  }
225
228
  }
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, 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;
229
+ 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
230
  var init_schema = __esm({
228
231
  "src/config/schema.ts"() {
229
232
  "use strict";
@@ -402,6 +405,12 @@ var init_schema = __esm({
402
405
  description: z.string().min(1).optional()
403
406
  });
404
407
  PickerModelsSchema = z.array(PickerModelSchema).refine((models) => new Set(models.map((entry) => entry.model)).size === models.length, { message: "pickerModels names a model more than once" });
408
+ ProviderCatalogueSchema = z.strictObject({
409
+ tier: z.enum(CLAUDE_TIERS),
410
+ include: z.array(z.string().min(1)).min(1).optional(),
411
+ exclude: z.array(z.string().min(1)).min(1).optional(),
412
+ url: z.url().optional()
413
+ });
405
414
  HttpProviderSchema = z.strictObject({
406
415
  $schema: z.string().optional(),
407
416
  kind: z.literal("http").optional(),
@@ -411,6 +420,8 @@ var init_schema = __esm({
411
420
  env: ProviderEnvSchema.optional(),
412
421
  /** Extra models `/model` lists beside the ones the tier settings name. */
413
422
  pickerModels: PickerModelsSchema.optional(),
423
+ /** The provider's own model catalogue, listed in `/model` when set. */
424
+ catalogue: ProviderCatalogueSchema.optional(),
414
425
  /** 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. */
415
426
  routes: z.array(ProviderRouteSchema).optional()
416
427
  });
@@ -621,7 +632,7 @@ function parseIgnoringUnrecognisedKeys(schema, raw) {
621
632
  return second.success ? { success: true, data: second.data, ignored } : { success: false, issues: second.error.issues };
622
633
  }
623
634
  function describeIgnoredKeys(filePath, ignored) {
624
- const places = ignored.map(({ path: path42, keys }) => `${path42.length === 0 ? "" : `${path42.map(String).join(".")}.`}${keys.join(", ")}`);
635
+ const places = ignored.map(({ path: path43, keys }) => `${path43.length === 0 ? "" : `${path43.map(String).join(".")}.`}${keys.join(", ")}`);
625
636
  return `${filePath} has settings this version of agent-shim does not know and ignores: ${places.join("; ")}. A newer release may read them.`;
626
637
  }
627
638
  function noteIgnoredKeys(filePath, ignored) {
@@ -643,9 +654,9 @@ function restoreIgnoredKeys(filePath, value) {
643
654
  return value;
644
655
  }
645
656
  const restored = structuredClone(value);
646
- for (const { path: path42, values } of ignored) {
657
+ for (const { path: path43, values } of ignored) {
647
658
  let holder = restored;
648
- for (const step of path42) {
659
+ for (const step of path43) {
649
660
  holder = isRecord(holder) ? holder[step] : void 0;
650
661
  }
651
662
  if (isRecord(holder)) {
@@ -1453,6 +1464,12 @@ var init_flatten = __esm({
1453
1464
  });
1454
1465
 
1455
1466
  // src/resolve/decide.ts
1467
+ function unclassifiedEntryMessage(names) {
1468
+ const quoted = names.map((name) => `"${name}"`).join(", ");
1469
+ const subject = names.length === 1 ? `${quoted} is not` : `${String(names.length)} entries are not`;
1470
+ const excluded = names.length === 1 ? "it is excluded" : `they are excluded: ${quoted}`;
1471
+ return `${subject} in the category map, so ${excluded}. Run \`agent-shim configure\` to classify ${names.length === 1 ? "it" : "them"}, which records the answer in the local overlay without touching the shipped default map.`;
1472
+ }
1456
1473
  function selectRule(relPath, flattened, context) {
1457
1474
  const eliminated = [];
1458
1475
  for (const rule of matchingRules(flattened, relPath)) {
@@ -1490,7 +1507,7 @@ function resolveEntry(relPath, params) {
1490
1507
  diagnostics.push({
1491
1508
  code: "UNCLASSIFIED_ENTRY",
1492
1509
  severity: "warning",
1493
- message: `"${head}" is not in the category map, so it is excluded. Run \`agent-shim configure\` to classify it, which records the answer in the local overlay without touching the shipped default map.`,
1510
+ message: unclassifiedEntryMessage([head]),
1494
1511
  subject: head
1495
1512
  });
1496
1513
  return { decision: { relPath, shared: false, via: "unclassified", category }, diagnostics };
@@ -2923,7 +2940,7 @@ var init_package = __esm({
2923
2940
  "package.json"() {
2924
2941
  package_default = {
2925
2942
  name: "agent-shim",
2926
- version: "11.25.0",
2943
+ version: "11.27.0",
2927
2944
  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.",
2928
2945
  license: "MIT",
2929
2946
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4088,6 +4105,40 @@ var init_supervisor = __esm({
4088
4105
  }
4089
4106
  });
4090
4107
 
4108
+ // src/logStyle.ts
4109
+ import { styleText } from "node:util";
4110
+ function styledDiagnostic(style, colour, line) {
4111
+ const lead = DIAGNOSTIC_LEAD.exec(line);
4112
+ if (lead === null) {
4113
+ return style([colour], line);
4114
+ }
4115
+ const [whole, prefix = "", code = "", separator = ""] = lead;
4116
+ return `${style([colour], prefix)}${style([colour, "bold"], code)}${style([colour], `${separator}${line.slice(whole.length)}`)}`;
4117
+ }
4118
+ function createLogPort(sinks, styleFor) {
4119
+ return {
4120
+ info: (message) => {
4121
+ sinks.out(styleFor.out(["dim"], message));
4122
+ },
4123
+ warn: (message) => {
4124
+ sinks.warn(styledDiagnostic(styleFor.err, "yellow", message));
4125
+ },
4126
+ error: (message) => {
4127
+ sinks.err(styledDiagnostic(styleFor.err, "red", message));
4128
+ }
4129
+ };
4130
+ }
4131
+ function styleTextFor(stream) {
4132
+ return (formats, text) => styleText([...formats], text, { stream });
4133
+ }
4134
+ var DIAGNOSTIC_LEAD;
4135
+ var init_logStyle = __esm({
4136
+ "src/logStyle.ts"() {
4137
+ "use strict";
4138
+ DIAGNOSTIC_LEAD = /^(agent-shim: )([A-Z][A-Z0-9_]*)(: )/;
4139
+ }
4140
+ });
4141
+
4091
4142
  // src/realPorts.ts
4092
4143
  import { spawn as spawn2, spawnSync } from "node:child_process";
4093
4144
  import { createHash as createHash5 } from "node:crypto";
@@ -4332,7 +4383,7 @@ function realResolveClaudeBinary(isOwnBinary) {
4332
4383
  function realInstalledClaudeVersions() {
4333
4384
  return installedVersions(listVersionsDir(defaultVersionsDir()));
4334
4385
  }
4335
- var realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, PS_TIMEOUT_MS, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
4386
+ var realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, PS_TIMEOUT_MS, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, realLogPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
4336
4387
  var init_realPorts = __esm({
4337
4388
  "src/realPorts.ts"() {
4338
4389
  "use strict";
@@ -4343,6 +4394,7 @@ var init_realPorts = __esm({
4343
4394
  init_ensure();
4344
4395
  init_supervisor();
4345
4396
  init_state2();
4397
+ init_logStyle();
4346
4398
  realFsPort = {
4347
4399
  readFileUtf8(filePath) {
4348
4400
  try {
@@ -4548,6 +4600,16 @@ var init_realPorts = __esm({
4548
4600
  argv: process.argv.slice(2),
4549
4601
  exit: (code) => process.exit(code)
4550
4602
  };
4603
+ realLogPort = createLogPort(
4604
+ { out: (line) => {
4605
+ console.log(line);
4606
+ }, warn: (line) => {
4607
+ console.warn(line);
4608
+ }, err: (line) => {
4609
+ console.error(line);
4610
+ } },
4611
+ { out: styleTextFor(process.stdout), err: styleTextFor(process.stderr) }
4612
+ );
4551
4613
  EXECUTE_BITS_MASK = 73;
4552
4614
  WINDOWS_DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PS1";
4553
4615
  }
@@ -6032,6 +6094,7 @@ function buildLayoutPaths(root) {
6032
6094
  usageDir: path23.join(root, "usage"),
6033
6095
  usageLogDir: path23.join(root, "usage", "log"),
6034
6096
  usageSnapshotsDir: path23.join(root, "usage", "snapshots"),
6097
+ catalogueDir: path23.join(root, "catalogues"),
6035
6098
  usagePicksFile: path23.join(root, "usage", "picks.json"),
6036
6099
  usageAnchorsFile: path23.join(root, "usage", "anchors.json"),
6037
6100
  usageJobsFile: path23.join(root, "usage", "jobs.json"),
@@ -6476,7 +6539,10 @@ function loadProvider(providersDir, name, port) {
6476
6539
  const raw = port.readConfigFile(filePath);
6477
6540
  return raw === void 0 ? void 0 : parseProviderFile(filePath, raw);
6478
6541
  }
6479
- function listProviders(paths) {
6542
+ function reportInvalidProvider(name, message) {
6543
+ console.error(`agent-shim: providers/${name}.json is invalid and was skipped: ${message}`);
6544
+ }
6545
+ function listProviders(paths, onInvalid = reportInvalidProvider) {
6480
6546
  const names = listProviderNames(
6481
6547
  (dir) => fs7.readdirSync(dir),
6482
6548
  paths.providersDir
@@ -6490,7 +6556,7 @@ function listProviders(paths) {
6490
6556
  if (!(error instanceof ConfigValidationError || error instanceof LegacyProviderFileError)) {
6491
6557
  throw error;
6492
6558
  }
6493
- console.error(`agent-shim: providers/${name}.json is invalid and was skipped: ${error.message}`);
6559
+ onInvalid(name, error.message);
6494
6560
  continue;
6495
6561
  }
6496
6562
  if (provider !== void 0) {
@@ -6540,6 +6606,9 @@ function addProvider(paths, name, input) {
6540
6606
  if (kind === "http" && input.baseUrl === void 0) {
6541
6607
  throw new ProviderKindMismatchError("An http provider needs --base-url.");
6542
6608
  }
6609
+ if (kind !== "http" && input.catalogue !== void 0) {
6610
+ throw new ProviderKindMismatchError("A model catalogue applies only to an http provider.");
6611
+ }
6543
6612
  if (kind !== "codex" && !isEmptyCodexConfig(input.codex)) {
6544
6613
  throw new ProviderKindMismatchError("Codex settings apply only to a codex provider (--kind codex).");
6545
6614
  }
@@ -6553,7 +6622,7 @@ function addProvider(paths, name, input) {
6553
6622
  ...input.pickerModels === void 0 || input.pickerModels.length === 0 ? {} : { pickerModels: input.pickerModels }
6554
6623
  };
6555
6624
  const parsed = ProviderSchema.safeParse(
6556
- kind === "codex" ? { kind, ...shared, ...isEmptyCodexConfig(input.codex) ? {} : { codex: input.codex } } : kind === "antigravity" ? { kind, ...shared, ...isEmptyAntigravityConfig(input.antigravity) ? {} : { antigravity: input.antigravity } } : { ...shared, baseUrl: input.baseUrl }
6625
+ 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 } }
6557
6626
  );
6558
6627
  if (!parsed.success) {
6559
6628
  throw new ConfigValidationError(providerJsonPath(paths, name), parsed.error.issues);
@@ -6582,6 +6651,9 @@ function updateProvider(paths, name, input) {
6582
6651
  if (isAntigravityProvider(existing) && input.baseUrl !== void 0) {
6583
6652
  throw new ProviderKindMismatchError(`Provider "${name}" is an antigravity provider, which has no base URL.`);
6584
6653
  }
6654
+ if ((isCodexProvider(existing) || isAntigravityProvider(existing)) && input.catalogue !== void 0 && input.catalogue !== false) {
6655
+ throw new ProviderKindMismatchError(`Provider "${name}" is not an http provider; a model catalogue applies only to an http provider.`);
6656
+ }
6585
6657
  if (!isCodexProvider(existing) && !isEmptyCodexConfig(input.codex)) {
6586
6658
  throw new ProviderKindMismatchError(`Provider "${name}" is not a codex provider; codex settings apply only to a codex provider.`);
6587
6659
  }
@@ -6614,7 +6686,8 @@ function updateProvider(paths, name, input) {
6614
6686
  };
6615
6687
  candidate = { ...existing, ...shared, antigravity: isEmptyAntigravityConfig(antigravity) ? void 0 : antigravity };
6616
6688
  } else {
6617
- candidate = { ...existing, ...shared, ...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl } };
6689
+ const catalogue = input.catalogue === void 0 ? existing.catalogue : input.catalogue === false ? void 0 : input.catalogue;
6690
+ candidate = { ...existing, ...shared, catalogue, ...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl } };
6618
6691
  }
6619
6692
  const parsed = ProviderSchema.safeParse(candidate);
6620
6693
  if (!parsed.success) {
@@ -7844,6 +7917,42 @@ var init_claudeSession = __esm({
7844
7917
  }
7845
7918
  });
7846
7919
 
7920
+ // src/launcher/diagnostics.ts
7921
+ function diagnosticLines(diagnostics) {
7922
+ const unclassified = [...new Set(diagnostics.filter((diagnostic) => diagnostic.code === "UNCLASSIFIED_ENTRY").map((diagnostic) => diagnostic.subject))];
7923
+ const lines = [];
7924
+ let unclassifiedReported = false;
7925
+ for (const diagnostic of diagnostics) {
7926
+ if (diagnostic.severity === "info") {
7927
+ continue;
7928
+ }
7929
+ if (diagnostic.code === "UNCLASSIFIED_ENTRY") {
7930
+ if (!unclassifiedReported) {
7931
+ unclassifiedReported = true;
7932
+ lines.push({ severity: diagnostic.severity, text: `agent-shim: ${diagnostic.code}: ${unclassifiedEntryMessage(unclassified.filter((name) => name !== void 0))}` });
7933
+ }
7934
+ continue;
7935
+ }
7936
+ lines.push({ severity: diagnostic.severity, text: `agent-shim: ${diagnostic.code}: ${diagnostic.message}` });
7937
+ }
7938
+ return lines;
7939
+ }
7940
+ function reportDiagnostics(log, diagnostics, options) {
7941
+ for (const line of diagnosticLines(diagnostics)) {
7942
+ if (line.severity === "error" && !options.errorsAsWarnings) {
7943
+ log.error(line.text);
7944
+ } else {
7945
+ log.warn(line.text);
7946
+ }
7947
+ }
7948
+ }
7949
+ var init_diagnostics = __esm({
7950
+ "src/launcher/diagnostics.ts"() {
7951
+ "use strict";
7952
+ init_decide();
7953
+ }
7954
+ });
7955
+
7847
7956
  // src/antigravity/cloudUpstream.ts
7848
7957
  var init_cloudUpstream = __esm({
7849
7958
  "src/antigravity/cloudUpstream.ts"() {
@@ -8004,6 +8113,49 @@ var init_translate2 = __esm({
8004
8113
  }
8005
8114
  });
8006
8115
 
8116
+ // src/providerCatalogue.ts
8117
+ import path38 from "node:path";
8118
+ import picomatch4 from "picomatch";
8119
+ import { z as z30 } from "zod";
8120
+ function catalogueCachePath(paths, name) {
8121
+ return path38.join(paths.catalogueDir, `${name}.json`);
8122
+ }
8123
+ function parseCatalogueCache(text) {
8124
+ if (text === void 0) {
8125
+ return void 0;
8126
+ }
8127
+ try {
8128
+ const parsed = CatalogueCacheSchema.safeParse(JSON.parse(text));
8129
+ return parsed.success ? parsed.data : void 0;
8130
+ } catch {
8131
+ return void 0;
8132
+ }
8133
+ }
8134
+ function filterCatalogue(models, catalogue) {
8135
+ const included = catalogue.include === void 0 ? void 0 : picomatch4(catalogue.include, { dot: true });
8136
+ const excluded = catalogue.exclude === void 0 ? void 0 : picomatch4(catalogue.exclude, { dot: true });
8137
+ return models.filter((model) => included?.(model.id) !== false && excluded?.(model.id) !== true);
8138
+ }
8139
+ 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;
8140
+ var init_providerCatalogue = __esm({
8141
+ "src/providerCatalogue.ts"() {
8142
+ "use strict";
8143
+ DEFAULT_CANDIDATE_URLS = 2;
8144
+ MS_PER_SECOND7 = 1e3;
8145
+ SECONDS_PER_HOUR2 = 3600;
8146
+ HOURS_PER_DAY5 = 24;
8147
+ MS_PER_HOUR5 = SECONDS_PER_HOUR2 * MS_PER_SECOND7;
8148
+ HOURS_BETWEEN_RETRIES = 1;
8149
+ CATALOGUE_MAX_AGE_MS = HOURS_PER_DAY5 * MS_PER_HOUR5;
8150
+ CATALOGUE_RETRY_MS = HOURS_BETWEEN_RETRIES * MS_PER_HOUR5;
8151
+ CATALOGUE_REQUEST_SECONDS = 10;
8152
+ CATALOGUE_REQUEST_TIMEOUT_MS = CATALOGUE_REQUEST_SECONDS * MS_PER_SECOND7;
8153
+ CATALOGUE_REFRESH_TIMEOUT_MS = DEFAULT_CANDIDATE_URLS * CATALOGUE_REQUEST_TIMEOUT_MS;
8154
+ CatalogueModelSchema = z30.strictObject({ id: z30.string().min(1), name: z30.string().min(1).optional() });
8155
+ CatalogueCacheSchema = z30.strictObject({ fetchedAt: z30.number(), url: z30.string().min(1), models: z30.array(CatalogueModelSchema) });
8156
+ }
8157
+ });
8158
+
8007
8159
  // src/launcher/modelPicker.ts
8008
8160
  function labelOf(model) {
8009
8161
  return model.toLowerCase().endsWith(CONTEXT_MARKER_1M) ? model.slice(0, -CONTEXT_MARKER_1M.length) : model;
@@ -8070,14 +8222,23 @@ function declaredRow(entry) {
8070
8222
  behavesAs: TIER_BEHAVES_AS[entry.tier]
8071
8223
  };
8072
8224
  }
8073
- function providerModelRows(provider) {
8225
+ function catalogueRows(provider, models) {
8226
+ if (provider.kind !== void 0 && provider.kind !== "http" || provider.catalogue === void 0) {
8227
+ return [];
8228
+ }
8229
+ const { tier } = provider.catalogue;
8230
+ 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));
8231
+ }
8232
+ function providerModelRows(provider, catalogue = []) {
8074
8233
  const derived = provider.kind === "codex" ? codexRows(provider) : provider.kind === "antigravity" ? antigravityRows(provider) : httpRows(provider);
8075
8234
  const declared = (provider.pickerModels ?? []).map(declaredRow);
8076
8235
  const declaredModels = new Set(declared.map((row) => row.model));
8077
- return [...derived.filter((row) => !declaredModels.has(row.model)), ...declared];
8236
+ const named = [...derived.filter((row) => !declaredModels.has(row.model)), ...declared];
8237
+ const taken = new Set(named.map((row) => labelOf(row.model)));
8238
+ return [...named, ...catalogueRows(provider, catalogue).filter((row) => !taken.has(labelOf(row.model)))];
8078
8239
  }
8079
- function modelPickerSettings(provider) {
8080
- const options = providerModelRows(provider);
8240
+ function modelPickerSettings(provider, catalogue = []) {
8241
+ const options = providerModelRows(provider, catalogue);
8081
8242
  return options.length === 0 ? void 0 : JSON.stringify({ modelPicker: { options, replaceBuiltInOptions: true } });
8082
8243
  }
8083
8244
  var CONTEXT_MARKER_1M, TIER_BEHAVES_AS, TIER_ENV_VARIABLES;
@@ -8086,6 +8247,7 @@ var init_modelPicker = __esm({
8086
8247
  "use strict";
8087
8248
  init_translate();
8088
8249
  init_translate2();
8250
+ init_providerCatalogue();
8089
8251
  init_schema();
8090
8252
  CONTEXT_MARKER_1M = "[1m]";
8091
8253
  TIER_BEHAVES_AS = Object.freeze({
@@ -8303,7 +8465,7 @@ var init_launchHook = __esm({
8303
8465
 
8304
8466
  // src/launcher.ts
8305
8467
  import { randomUUID as randomUUID4 } from "node:crypto";
8306
- import path38 from "node:path";
8468
+ import path39 from "node:path";
8307
8469
  function resolveIdentityCredential(identity, credential, env, port) {
8308
8470
  if (port === void 0) {
8309
8471
  return { ok: false, status: 1, message: `agent-shim: identity ${identity} needs its credential resolved, but this launcher has no credential port wired` };
@@ -8419,7 +8581,7 @@ function decideLaunch(params, readOnly) {
8419
8581
  identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
8420
8582
  globalDefaultConfigProfile: params.globalDefaultConfigProfile
8421
8583
  });
8422
- if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs13.readConfigFile(path38.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
8584
+ if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs13.readConfigFile(path39.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
8423
8585
  log.error(
8424
8586
  `agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
8425
8587
  );
@@ -8499,17 +8661,7 @@ function decideLaunch(params, readOnly) {
8499
8661
  const flattened = flattenLayers(assembled.layers, { home: params.farm.home });
8500
8662
  cascadeLaunch = flattened.launch;
8501
8663
  if (readOnly || farmContext === void 0) {
8502
- for (const diagnostic of [...assembled.diagnostics, ...flattened.diagnostics]) {
8503
- if (diagnostic.severity === "info") {
8504
- continue;
8505
- }
8506
- const message = `agent-shim: ${diagnostic.code}: ${diagnostic.message}`;
8507
- if (diagnostic.severity === "error" && !readOnly) {
8508
- log.error(message);
8509
- } else {
8510
- log.warn(message);
8511
- }
8512
- }
8664
+ reportDiagnostics(log, [...assembled.diagnostics, ...flattened.diagnostics], { errorsAsWarnings: readOnly });
8513
8665
  }
8514
8666
  }
8515
8667
  const pinnedVersion = resolveClaudeVersion({ env, ...parsedArgv.claudeVersion === void 0 ? {} : { flag: parsedArgv.claudeVersion }, ...cascadeLaunch?.claudeVersion === void 0 ? {} : { cascade: cascadeLaunch.claudeVersion } });
@@ -8529,7 +8681,8 @@ function decideLaunch(params, readOnly) {
8529
8681
  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`);
8530
8682
  }
8531
8683
  const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
8532
- const pickerSettings = selectedProvider === void 0 ? void 0 : modelPickerSettings(selectedProvider.definition);
8684
+ const catalogue = selectedProvider === void 0 ? void 0 : parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, selectedProvider.name)));
8685
+ const pickerSettings = selectedProvider === void 0 ? void 0 : modelPickerSettings(selectedProvider.definition, catalogue?.models);
8533
8686
  const callerSettings = hasSettingsArgument(parsedArgv.rest);
8534
8687
  if (pickerSettings !== void 0 && callerSettings && !readOnly) {
8535
8688
  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");
@@ -8540,7 +8693,7 @@ function decideLaunch(params, readOnly) {
8540
8693
  extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
8541
8694
  passthrough: withLauncherSettings(params.supervised === void 0 ? parsedArgv.rest : withSupervision(parsedArgv.rest, params.supervised), launcherSettings)
8542
8695
  });
8543
- const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path38.join(paths.identitiesDir, identityDecision.name);
8696
+ const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path39.join(paths.identitiesDir, identityDecision.name);
8544
8697
  const decision = {
8545
8698
  identitySource: identityDecision.source,
8546
8699
  configDirEscapeHatch: identityDecision.configDirEscapeHatch,
@@ -8581,7 +8734,7 @@ function prepareLaunch(params) {
8581
8734
  );
8582
8735
  const updateCheck = runLaunchUpdateCheck({
8583
8736
  mode: params.updateMode ?? "off",
8584
- checkPath: path38.join(paths.root, "update.check"),
8737
+ checkPath: path39.join(paths.root, "update.check"),
8585
8738
  currentVersion: package_default.version,
8586
8739
  port: params.update
8587
8740
  });
@@ -8613,16 +8766,12 @@ function prepareLaunch(params) {
8613
8766
  }
8614
8767
  throw error;
8615
8768
  }
8616
- for (const diagnostic of result.diagnostics) {
8617
- if (diagnostic.severity === "error") {
8618
- log.error(`agent-shim: ${diagnostic.code}: ${diagnostic.message}`);
8619
- } else if (diagnostic.severity === "warning") {
8620
- log.warn(`agent-shim: ${diagnostic.code}: ${diagnostic.message}`);
8621
- }
8769
+ reportDiagnostics(log, result.diagnostics, { errorsAsWarnings: false });
8770
+ if (!result.noOp) {
8771
+ log.info(
8772
+ `agent-shim: farm at ${result.farmRoot} resynced (${String(result.manifest.links.length)} link(s), ${String(result.manifest.materialised.length)} built director(ies)${result.adopted.length === 0 ? "" : `, ${String(result.adopted.length)} adopted into ${resyncFarmRuntime.claudeHome}`})`
8773
+ );
8622
8774
  }
8623
- log.info(
8624
- result.noOp ? `agent-shim: farm at ${result.farmRoot} already matches the resolved cascade` : `agent-shim: farm at ${result.farmRoot} resynced (${String(result.manifest.links.length)} link(s), ${String(result.manifest.materialised.length)} built director(ies)${result.adopted.length === 0 ? "" : `, ${String(result.adopted.length)} adopted into ${resyncFarmRuntime.claudeHome}`})`
8625
- );
8626
8775
  }
8627
8776
  if (decided.pinnedVersion !== void 0) {
8628
8777
  log.info(`agent-shim: Claude Code ${decided.pinnedVersion.version} (pinned by ${decided.pinnedVersion.source})`);
@@ -8728,7 +8877,9 @@ var init_launcher = __esm({
8728
8877
  init_flags();
8729
8878
  init_extraFlags();
8730
8879
  init_claudeSession();
8880
+ init_diagnostics();
8731
8881
  init_modelPicker();
8882
+ init_providerCatalogue();
8732
8883
  init_pool();
8733
8884
  init_resumeContext();
8734
8885
  init_lock();
@@ -8747,12 +8898,12 @@ var init_launcher = __esm({
8747
8898
  });
8748
8899
 
8749
8900
  // src/ownCli.ts
8750
- import path39 from "node:path";
8901
+ import path40 from "node:path";
8751
8902
  function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string" ? __AGENT_SHIM_DIST_DIR__ : void 0) {
8752
8903
  if (distDir === void 0) {
8753
8904
  throw new OwnCliPathUnknownError();
8754
8905
  }
8755
- return path39.join(distDir, OWN_CLI_FILE_NAME);
8906
+ return path40.join(distDir, OWN_CLI_FILE_NAME);
8756
8907
  }
8757
8908
  var OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
8758
8909
  var init_ownCli = __esm({
@@ -8782,10 +8933,10 @@ var init_selfIdentity = __esm({
8782
8933
 
8783
8934
  // src/frontdoor/trust.ts
8784
8935
  import { createHash as createHash7 } from "node:crypto";
8785
- import path40 from "node:path";
8936
+ import path41 from "node:path";
8786
8937
  function resolveTrustBundle(params) {
8787
8938
  const { caCertFile, bundlesDir, variable, inherited, fs: fs13 } = params;
8788
- if (inherited === void 0 || inherited === "" || path40.resolve(inherited) === path40.resolve(caCertFile)) {
8939
+ if (inherited === void 0 || inherited === "" || path41.resolve(inherited) === path41.resolve(caCertFile)) {
8789
8940
  return { path: caCertFile };
8790
8941
  }
8791
8942
  const caPem = fs13.readFileUtf8(caCertFile);
@@ -8803,7 +8954,7 @@ function resolveTrustBundle(params) {
8803
8954
  }
8804
8955
  const combined = `${inheritedPem.trimEnd()}
8805
8956
  ${caPem}`;
8806
- const bundle = path40.join(bundlesDir, `${createHash7("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
8957
+ const bundle = path41.join(bundlesDir, `${createHash7("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
8807
8958
  if (!fs13.exists(bundle)) {
8808
8959
  fs13.mkdirp(bundlesDir);
8809
8960
  fs13.writeFileAtomic(bundle, combined);
@@ -8881,7 +9032,7 @@ var init_realFrontDoorPort = __esm({
8881
9032
 
8882
9033
  // src/launchWiring.ts
8883
9034
  import os8 from "node:os";
8884
- import path41 from "node:path";
9035
+ import path42 from "node:path";
8885
9036
  import { randomUUID as randomUUID5 } from "node:crypto";
8886
9037
  function buildFarmRuntime(paths, cwd) {
8887
9038
  const home = os8.homedir();
@@ -8935,7 +9086,7 @@ function realPrepareLaunchParams(paths, options) {
8935
9086
  headroom: realHeadroomPort(paths, { spawnDaemon: options.spawnDaemon, cwd: farm.runtime.cwd }),
8936
9087
  frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
8937
9088
  credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
8938
- hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: realRunPort }, { farmRoot: path41.join(paths.identitiesDir, identity), hasCredentialBlock: false }).state !== "signed-out",
9089
+ hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: realRunPort }, { farmRoot: path42.join(paths.identitiesDir, identity), hasCredentialBlock: false }).state !== "signed-out",
8939
9090
  ...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
8940
9091
  ...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
8941
9092
  ...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
@@ -9210,76 +9361,76 @@ var init_identityClaude = __esm({
9210
9361
  });
9211
9362
 
9212
9363
  // src/usage/providerQuota.ts
9213
- import { z as z30 } from "zod";
9214
- 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;
9364
+ import { z as z31 } from "zod";
9365
+ 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;
9215
9366
  var init_providerQuota = __esm({
9216
9367
  "src/usage/providerQuota.ts"() {
9217
9368
  "use strict";
9218
9369
  init_cloudUpstream();
9219
9370
  init_schema2();
9220
- MS_PER_SECOND7 = 1e3;
9221
- SECONDS_PER_HOUR2 = 3600;
9222
- HOURS_PER_DAY5 = 24;
9371
+ MS_PER_SECOND8 = 1e3;
9372
+ SECONDS_PER_HOUR3 = 3600;
9373
+ HOURS_PER_DAY6 = 24;
9223
9374
  DAYS_PER_MONTH = 30;
9224
9375
  ZAI_HOST = "api.z.ai";
9225
9376
  ZAI_QUOTA_URL = `https://${ZAI_HOST}/api/monitor/usage/quota/limit`;
9226
9377
  ZAI_UNIT_HOURS = 3;
9227
9378
  ZAI_UNIT_MONTHS = 5;
9228
9379
  ZAI_UNIT_MS = /* @__PURE__ */ new Map([
9229
- [ZAI_UNIT_HOURS, SECONDS_PER_HOUR2 * MS_PER_SECOND7],
9230
- [ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY5 * SECONDS_PER_HOUR2 * MS_PER_SECOND7]
9380
+ [ZAI_UNIT_HOURS, SECONDS_PER_HOUR3 * MS_PER_SECOND8],
9381
+ [ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND8]
9231
9382
  ]);
9232
- ZaiLimitSchema = z30.object({
9233
- type: z30.string(),
9234
- unit: z30.number().int(),
9235
- number: z30.number().int().positive(),
9236
- percentage: z30.number().nonnegative(),
9237
- nextResetTime: z30.number().positive().optional(),
9238
- usage: z30.number().nonnegative().optional(),
9239
- currentValue: z30.number().nonnegative().optional(),
9240
- remaining: z30.number().nonnegative().optional()
9383
+ ZaiLimitSchema = z31.object({
9384
+ type: z31.string(),
9385
+ unit: z31.number().int(),
9386
+ number: z31.number().int().positive(),
9387
+ percentage: z31.number().nonnegative(),
9388
+ nextResetTime: z31.number().positive().optional(),
9389
+ usage: z31.number().nonnegative().optional(),
9390
+ currentValue: z31.number().nonnegative().optional(),
9391
+ remaining: z31.number().nonnegative().optional()
9241
9392
  });
9242
- ZaiResponseSchema = z30.object({
9243
- success: z30.boolean(),
9244
- msg: z30.string().optional(),
9245
- data: z30.object({ level: z30.string().optional(), limits: z30.array(ZaiLimitSchema) })
9393
+ ZaiResponseSchema = z31.object({
9394
+ success: z31.boolean(),
9395
+ msg: z31.string().optional(),
9396
+ data: z31.object({ level: z31.string().optional(), limits: z31.array(ZaiLimitSchema) })
9246
9397
  });
9247
9398
  OPENROUTER_HOST = "openrouter.ai";
9248
9399
  OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
9249
9400
  OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
9250
- MS_PER_DAY3 = HOURS_PER_DAY5 * SECONDS_PER_HOUR2 * MS_PER_SECOND7;
9251
- OpenRouterKeySchema = z30.object({
9252
- data: z30.object({
9253
- limit: z30.number().nonnegative().nullable(),
9254
- limit_remaining: z30.number().nullable(),
9255
- limit_reset: z30.string().nullable(),
9256
- is_free_tier: z30.boolean().optional(),
9257
- free_model_daily_requests: z30.object({ used: z30.number().nonnegative(), limit: z30.number().nonnegative(), remaining: z30.number() }).optional()
9401
+ MS_PER_DAY3 = HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND8;
9402
+ OpenRouterKeySchema = z31.object({
9403
+ data: z31.object({
9404
+ limit: z31.number().nonnegative().nullable(),
9405
+ limit_remaining: z31.number().nullable(),
9406
+ limit_reset: z31.string().nullable(),
9407
+ is_free_tier: z31.boolean().optional(),
9408
+ free_model_daily_requests: z31.object({ used: z31.number().nonnegative(), limit: z31.number().nonnegative(), remaining: z31.number() }).optional()
9258
9409
  })
9259
9410
  });
9260
- OpenRouterCreditsSchema = z30.object({ data: z30.object({ total_credits: z30.number().nonnegative(), total_usage: z30.number().nonnegative() }) });
9411
+ OpenRouterCreditsSchema = z31.object({ data: z31.object({ total_credits: z31.number().nonnegative(), total_usage: z31.number().nonnegative() }) });
9261
9412
  ANTIGRAVITY_HOST = "daily-cloudcode-pa.googleapis.com";
9262
9413
  ANTIGRAVITY_QUOTA_URL = `https://${ANTIGRAVITY_HOST}/v1internal:retrieveUserQuotaSummary`;
9263
9414
  ANTIGRAVITY_USER_URL = `https://${ANTIGRAVITY_HOST}/v1internal:loadCodeAssist`;
9264
9415
  FIVE_HOURS2 = 5;
9265
9416
  DAYS_PER_WEEK2 = 7;
9266
- FIVE_HOURS_MS = FIVE_HOURS2 * SECONDS_PER_HOUR2 * MS_PER_SECOND7;
9267
- WEEK_MS = DAYS_PER_WEEK2 * HOURS_PER_DAY5 * SECONDS_PER_HOUR2 * MS_PER_SECOND7;
9268
- AntigravityBucketSchema = z30.object({
9269
- bucketId: z30.string(),
9270
- remainingFraction: z30.number().optional(),
9271
- resetTime: z30.string().optional()
9417
+ FIVE_HOURS_MS = FIVE_HOURS2 * SECONDS_PER_HOUR3 * MS_PER_SECOND8;
9418
+ WEEK_MS = DAYS_PER_WEEK2 * HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND8;
9419
+ AntigravityBucketSchema = z31.object({
9420
+ bucketId: z31.string(),
9421
+ remainingFraction: z31.number().optional(),
9422
+ resetTime: z31.string().optional()
9272
9423
  });
9273
- AntigravitySummarySchema = z30.object({ groups: z30.array(z30.object({ buckets: z30.array(AntigravityBucketSchema) })) });
9274
- GoogleTokenInfoSchema = z30.object({
9275
- email: z30.string().optional(),
9276
- sub: z30.string().optional()
9424
+ AntigravitySummarySchema = z31.object({ groups: z31.array(z31.object({ buckets: z31.array(AntigravityBucketSchema) })) });
9425
+ GoogleTokenInfoSchema = z31.object({
9426
+ email: z31.string().optional(),
9427
+ sub: z31.string().optional()
9277
9428
  });
9278
- AntigravityUserSchema = z30.object({
9429
+ AntigravityUserSchema = z31.object({
9279
9430
  /** The code-assist tier context, which defaults to the free tier for every account. */
9280
- currentTier: z30.object({ name: z30.string().optional(), id: z30.string().optional() }).optional(),
9431
+ currentTier: z31.object({ name: z31.string().optional(), id: z31.string().optional() }).optional(),
9281
9432
  /** The account's paid subscription; absent when the account has none. */
9282
- paidTier: z30.object({ name: z30.string().optional(), id: z30.string().optional() }).optional()
9433
+ paidTier: z31.object({ name: z31.string().optional(), id: z31.string().optional() }).optional()
9283
9434
  });
9284
9435
  }
9285
9436
  });
@@ -9908,8 +10059,8 @@ function parseConnectTarget(authority) {
9908
10059
  function isInterceptedHost(host, interceptHosts) {
9909
10060
  return interceptHosts.includes(host);
9910
10061
  }
9911
- function servedByPipeline(path42) {
9912
- return path42?.startsWith(ROUTED_PATH_PREFIX) === true;
10062
+ function servedByPipeline(path43) {
10063
+ return path43?.startsWith(ROUTED_PATH_PREFIX) === true;
9913
10064
  }
9914
10065
  var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
9915
10066
  "connection",
@@ -10703,11 +10854,11 @@ function createRcSessionTracker(deps) {
10703
10854
  };
10704
10855
  const observeExchange = (request4) => {
10705
10856
  const method = (request4.method ?? "").toUpperCase();
10706
- const path42 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
10707
- if (!path42.startsWith(RC_SESSIONS_PATH_PREFIX)) {
10857
+ const path43 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
10858
+ if (!path43.startsWith(RC_SESSIONS_PATH_PREFIX)) {
10708
10859
  return void 0;
10709
10860
  }
10710
- const tail = path42.slice(RC_SESSIONS_PATH_PREFIX.length);
10861
+ const tail = path43.slice(RC_SESSIONS_PATH_PREFIX.length);
10711
10862
  const facts = {
10712
10863
  oauthAuthorization: oauthAuthorizationOf(request4.headers),
10713
10864
  anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
@@ -11097,8 +11248,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
11097
11248
  function isRcReadFileEncoding(value) {
11098
11249
  return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
11099
11250
  }
11100
- function buildRcReadFilePayload(requestId, path42, options) {
11101
- return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path42, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
11251
+ function buildRcReadFilePayload(requestId, path43, options) {
11252
+ return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path43, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
11102
11253
  }
11103
11254
  function buildRcFileSuggestionsPayload(requestId, query) {
11104
11255
  return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
@@ -11200,15 +11351,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
11200
11351
  const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
11201
11352
  return result.ok ? { ...result, requestId } : result;
11202
11353
  }
11203
- async function readRcSessionFile(deps, sessionId, path42, options) {
11204
- if (path42 === "") {
11354
+ async function readRcSessionFile(deps, sessionId, path43, options) {
11355
+ if (path43 === "") {
11205
11356
  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" };
11206
11357
  }
11207
11358
  if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
11208
11359
  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" };
11209
11360
  }
11210
11361
  const requestId = deps.newUuid();
11211
- const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path42, options), `read ${path42} from session ${sessionId}`);
11362
+ const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path43, options), `read ${path43} from session ${sessionId}`);
11212
11363
  return result.ok ? { ...result, requestId } : result;
11213
11364
  }
11214
11365
  async function suggestRcSessionFiles(deps, sessionId, query) {
@@ -11377,11 +11528,11 @@ function createRcControlHandler(deps) {
11377
11528
  path: "read-file",
11378
11529
  read: (body) => {
11379
11530
  const session = bodyString(body, "session");
11380
- const path42 = bodyString(body, "path");
11531
+ const path43 = bodyString(body, "path");
11381
11532
  const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
11382
11533
  const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
11383
- const refused2 = session === void 0 || path42 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
11384
- 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 } }) };
11534
+ const refused2 = session === void 0 || path43 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
11535
+ 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 } }) };
11385
11536
  }
11386
11537
  },
11387
11538
  {
@@ -11691,9 +11842,9 @@ function requestIdOfBody(body) {
11691
11842
  }
11692
11843
  function frontDoorRcControl(transport, token) {
11693
11844
  const headers = { authorization: `Bearer ${token}` };
11694
- const listAnswerOf = async (path42, what) => {
11845
+ const listAnswerOf = async (path43, what) => {
11695
11846
  try {
11696
- return await transport.request({ method: "GET", path: path42, headers });
11847
+ return await transport.request({ method: "GET", path: path43, headers });
11697
11848
  } catch (error) {
11698
11849
  throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
11699
11850
  }
@@ -11765,10 +11916,10 @@ function frontDoorRcControl(transport, token) {
11765
11916
  }
11766
11917
  return pending;
11767
11918
  };
11768
- const writeOf = async (path42, body, describeFailure2) => {
11919
+ const writeOf = async (path43, body, describeFailure2) => {
11769
11920
  let answer;
11770
11921
  try {
11771
- answer = await transport.request({ method: "POST", path: path42, headers: { ...headers, "content-type": "application/json" }, body });
11922
+ answer = await transport.request({ method: "POST", path: path43, headers: { ...headers, "content-type": "application/json" }, body });
11772
11923
  } catch (error) {
11773
11924
  return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
11774
11925
  }
@@ -11799,10 +11950,10 @@ function frontDoorRcControl(transport, token) {
11799
11950
  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}`),
11800
11951
  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}`),
11801
11952
  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}`),
11802
- readFile: async (sessionId, path42, options) => await writeOf(
11953
+ readFile: async (sessionId, path43, options) => await writeOf(
11803
11954
  `${CONTROL_PATH_PREFIX}/read-file`,
11804
- JSON.stringify({ session: sessionId, path: path42, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
11805
- (status, message) => `reading ${path42} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
11955
+ JSON.stringify({ session: sessionId, path: path43, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
11956
+ (status, message) => `reading ${path43} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
11806
11957
  ),
11807
11958
  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}`),
11808
11959
  keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
@@ -11961,12 +12112,12 @@ function tlsFacts(options) {
11961
12112
  }
11962
12113
  function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
11963
12114
  const agent = new ExemptTlsAgent();
11964
- const post = async (path42, headers, body) => await new Promise((resolve, reject) => {
12115
+ const post = async (path43, headers, body) => await new Promise((resolve, reject) => {
11965
12116
  const options = {
11966
12117
  host: target.host,
11967
12118
  port: target.port,
11968
12119
  method: "POST",
11969
- path: path42,
12120
+ path: path43,
11970
12121
  // 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.
11971
12122
  headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
11972
12123
  agent
@@ -12031,12 +12182,12 @@ function lateRcStreamDial(resolve) {
12031
12182
  }
12032
12183
  function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
12033
12184
  const agent = new ExemptTlsAgent();
12034
- const request4 = async (method, path42, headers, body, signal) => await new Promise((resolve, reject) => {
12185
+ const request4 = async (method, path43, headers, body, signal) => await new Promise((resolve, reject) => {
12035
12186
  const options = {
12036
12187
  host: target.host,
12037
12188
  port: target.port,
12038
12189
  method,
12039
- path: path42,
12190
+ path: path43,
12040
12191
  // 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.
12041
12192
  headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
12042
12193
  agent,
@@ -12078,9 +12229,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
12078
12229
  return { status, body: await readAll(response) };
12079
12230
  },
12080
12231
  openStream: async (sessionId, headers, resume, signal) => {
12081
- 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)}`;
12232
+ 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)}`;
12082
12233
  const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
12083
- const { status, response } = await request4("GET", path42, streamHeaders, void 0, signal);
12234
+ const { status, response } = await request4("GET", path43, streamHeaders, void 0, signal);
12084
12235
  if (!isSuccessful2(status)) {
12085
12236
  await readAll(response);
12086
12237
  return { status, chunks: NO_CHUNKS };
@@ -13232,19 +13383,19 @@ function writePools(paths, pools) {
13232
13383
  applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
13233
13384
  }
13234
13385
  function poolCycleOf(pools, name) {
13235
- const walk = (current, path42) => {
13386
+ const walk = (current, path43) => {
13236
13387
  for (const entry of pools[current]?.identities ?? []) {
13237
13388
  const nested = poolNameOf(poolMemberIdentity(entry));
13238
13389
  if (nested === void 0) {
13239
13390
  continue;
13240
13391
  }
13241
13392
  if (nested === name) {
13242
- return [...path42, nested];
13393
+ return [...path43, nested];
13243
13394
  }
13244
- if (path42.includes(nested)) {
13395
+ if (path43.includes(nested)) {
13245
13396
  continue;
13246
13397
  }
13247
- const found = walk(nested, [...path42, nested]);
13398
+ const found = walk(nested, [...path43, nested]);
13248
13399
  if (found !== void 0) {
13249
13400
  return found;
13250
13401
  }
@@ -15523,7 +15674,7 @@ function profileValue(name, paths) {
15523
15674
  function createConfigApiRouter(deps) {
15524
15675
  const authed = doorApiAuth(deps.expectedToken);
15525
15676
  const { paths } = deps;
15526
- const route = (path42, summary) => authed.meta(openapi3({ method: "POST", path: path42, summary, tags: [CONFIG_API_TAG] }));
15677
+ const route = (path43, summary) => authed.meta(openapi3({ method: "POST", path: path43, summary, tags: [CONFIG_API_TAG] }));
15527
15678
  return {
15528
15679
  config: {
15529
15680
  identity: {