claude-use 11.40.4 → 11.41.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/README.md CHANGED
@@ -131,6 +131,10 @@ agent-shim model set <name> [--mode <mode>] [--member <ref>]...
131
131
  agent-shim model remove <name> [--yes]
132
132
  agent-shim model tier <tier> --ref <ref> | --clear
133
133
  agent-shim model price <ref> --input <usd> --output <usd> | --clear
134
+ agent-shim model same <ref> <ref>... # assert these refs are one model under several names
135
+ agent-shim model distinct <left> <right> # assert two alike names are two models
136
+ agent-shim model unassert <ref>
137
+ agent-shim model family <key> [--mode <mode>] [--name <ref>]... [--context <tokens>] [--[no-]vision|tools|thinking] | --clear
134
138
  agent-shim model list [--json]
135
139
  agent-shim model explain <name> # which member the virtual model's mode picks now, and why
136
140
  agent-shim provider remove <name> [--yes] [--json]
package/dist/cli.cjs CHANGED
@@ -26990,7 +26990,7 @@ function isTimeZone(name) {
26990
26990
  return false;
26991
26991
  }
26992
26992
  }
26993
- var import_node_path4, 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, RouterProviderSchema, AntigravityProviderSchema, ProviderSchema, SELECTION_MODES, VirtualModelSchema, ModelPricesSchema, ModelsConfigSchema, ModelsLayerSchema, 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, FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
26993
+ var import_node_path4, 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, RouterProviderSchema, AntigravityProviderSchema, ProviderSchema, SELECTION_MODES, VirtualModelSchema, ModelPricesSchema, FamilySettingsSchema, ModelsConfigSchema, ModelsLayerSchema, 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, FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
26994
26994
  var init_schema = __esm({
26995
26995
  "src/config/schema.ts"() {
26996
26996
  "use strict";
@@ -27237,6 +27237,14 @@ var init_schema = __esm({
27237
27237
  input: external_exports.number().positive(),
27238
27238
  output: external_exports.number().positive()
27239
27239
  });
27240
+ FamilySettingsSchema = external_exports.strictObject({
27241
+ names: external_exports.array(external_exports.string().min(1)).optional(),
27242
+ mode: external_exports.enum(SELECTION_MODES).optional(),
27243
+ context: external_exports.number().int().positive().optional(),
27244
+ vision: external_exports.boolean().optional(),
27245
+ tools: external_exports.boolean().optional(),
27246
+ thinking: external_exports.boolean().optional()
27247
+ });
27240
27248
  ModelsConfigSchema = external_exports.strictObject({
27241
27249
  /** Virtual models, by name. */
27242
27250
  virtual: external_exports.record(external_exports.string().min(1), VirtualModelSchema).optional(),
@@ -27252,7 +27260,13 @@ var init_schema = __esm({
27252
27260
  /** Model refs hidden from the picker and from routing, whatever else names them. */
27253
27261
  hide: external_exports.array(external_exports.string().min(1)).optional(),
27254
27262
  /** When set, the only model refs visible; everything else is hidden. */
27255
- show: external_exports.array(external_exports.string().min(1)).optional()
27263
+ show: external_exports.array(external_exports.string().min(1)).optional(),
27264
+ /** Assertions that each group of refs is one model under several names, overriding what the names alone say. */
27265
+ same: external_exports.array(external_exports.array(external_exports.string().min(1)).min(2)).optional(),
27266
+ /** Assertions that each pair of refs is two models however alike their names look. */
27267
+ distinct: external_exports.array(external_exports.tuple([external_exports.string().min(1), external_exports.string().min(1)])).optional(),
27268
+ /** Per-family settings and the names the normaliser cannot know, by family key. */
27269
+ families: external_exports.record(external_exports.string().min(1), FamilySettingsSchema).optional()
27256
27270
  });
27257
27271
  ModelsLayerSchema = external_exports.strictObject({
27258
27272
  virtual: external_exports.record(external_exports.string().min(1), external_exports.union([VirtualModelSchema, external_exports.null()])).optional(),
@@ -27264,7 +27278,10 @@ var init_schema = __esm({
27264
27278
  }).optional(),
27265
27279
  prices: external_exports.record(external_exports.string().min(1), external_exports.union([ModelPricesSchema, external_exports.null()])).optional(),
27266
27280
  hide: external_exports.array(external_exports.string().min(1)).optional(),
27267
- show: external_exports.array(external_exports.string().min(1)).optional()
27281
+ show: external_exports.array(external_exports.string().min(1)).optional(),
27282
+ same: external_exports.array(external_exports.array(external_exports.string().min(1)).min(2)).optional(),
27283
+ distinct: external_exports.array(external_exports.tuple([external_exports.string().min(1), external_exports.string().min(1)])).optional(),
27284
+ families: external_exports.record(external_exports.string().min(1), external_exports.union([FamilySettingsSchema, external_exports.null()])).optional()
27268
27285
  });
27269
27286
  ConfigProfileSchema = external_exports.strictObject({
27270
27287
  $schema: external_exports.string().optional(),
@@ -27569,7 +27586,7 @@ var init_state = __esm({
27569
27586
  "use strict";
27570
27587
  import_node_path5 = __toESM(require("node:path"), 1);
27571
27588
  init_zod();
27572
- FRONT_DOOR_PROTOCOL = 3;
27589
+ FRONT_DOOR_PROTOCOL = 4;
27573
27590
  FrontDoorSessionSchema = external_exports.strictObject({ pid: external_exports.number().int().positive(), startedAt: external_exports.number(), token: external_exports.string().min(1), supervisorPid: external_exports.number().int().positive().optional() });
27574
27591
  FrontDoorStateSchema = external_exports.strictObject({
27575
27592
  /**
@@ -32964,6 +32981,26 @@ function mergeModels(current, layer) {
32964
32981
  if (layer.show !== void 0) {
32965
32982
  pieces.show = layer.show;
32966
32983
  }
32984
+ if (layer.same !== void 0) {
32985
+ pieces.same = [...current?.same ?? [], ...layer.same.filter((group) => !(current?.same ?? []).some((known) => known.length === group.length && known.every((ref, index) => ref === group[index])))];
32986
+ }
32987
+ if (layer.distinct !== void 0) {
32988
+ pieces.distinct = [...current?.distinct ?? [], ...layer.distinct.filter(([left, right]) => !(current?.distinct ?? []).some(([a10, b]) => a10 === left && b === right))];
32989
+ }
32990
+ if (layer.families !== void 0) {
32991
+ const families = {};
32992
+ for (const [key, settings2] of Object.entries(current?.families ?? {})) {
32993
+ if (layer.families[key] === void 0) {
32994
+ families[key] = settings2;
32995
+ }
32996
+ }
32997
+ for (const [key, settings2] of Object.entries(layer.families)) {
32998
+ if (settings2 !== null) {
32999
+ families[key] = settings2;
33000
+ }
33001
+ }
33002
+ pieces.families = families;
33003
+ }
32967
33004
  const merged = modelsOf(pieces);
32968
33005
  return Object.keys(merged).length === 0 ? void 0 : merged;
32969
33006
  }
@@ -32973,7 +33010,10 @@ function modelsOf(pieces) {
32973
33010
  ...pieces.tiers === void 0 || Object.keys(pieces.tiers).length === 0 ? {} : { tiers: pieces.tiers },
32974
33011
  ...pieces.prices === void 0 || Object.keys(pieces.prices).length === 0 ? {} : { prices: pieces.prices },
32975
33012
  ...pieces.hide === void 0 || pieces.hide.length === 0 ? {} : { hide: [...pieces.hide] },
32976
- ...pieces.show === void 0 || pieces.show.length === 0 ? {} : { show: [...pieces.show] }
33013
+ ...pieces.show === void 0 || pieces.show.length === 0 ? {} : { show: [...pieces.show] },
33014
+ ...pieces.same === void 0 || pieces.same.length === 0 ? {} : { same: pieces.same.map((group) => [...group]) },
33015
+ ...pieces.distinct === void 0 || pieces.distinct.length === 0 ? {} : { distinct: pieces.distinct.map(([left, right]) => [left, right]) },
33016
+ ...pieces.families === void 0 || Object.keys(pieces.families).length === 0 ? {} : { families: pieces.families }
32977
33017
  };
32978
33018
  }
32979
33019
  var init_flatten = __esm({
@@ -34636,7 +34676,7 @@ var init_package = __esm({
34636
34676
  "package.json"() {
34637
34677
  package_default = {
34638
34678
  name: "claude-use",
34639
- version: "11.40.4",
34679
+ version: "11.41.0",
34640
34680
  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.",
34641
34681
  license: "MIT",
34642
34682
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -65690,6 +65730,15 @@ function stripEmpty(models) {
65690
65730
  if (models.show !== void 0 && models.show.length > 0) {
65691
65731
  kept.show = models.show;
65692
65732
  }
65733
+ if (models.same !== void 0 && models.same.length > 0) {
65734
+ kept.same = models.same;
65735
+ }
65736
+ if (models.distinct !== void 0 && models.distinct.length > 0) {
65737
+ kept.distinct = models.distinct;
65738
+ }
65739
+ if (models.families !== void 0 && Object.keys(models.families).length > 0) {
65740
+ kept.families = models.families;
65741
+ }
65693
65742
  return kept;
65694
65743
  }
65695
65744
  function memberKindOf(ref, models) {
@@ -65757,6 +65806,39 @@ function setTier(paths, tier, ref) {
65757
65806
  }
65758
65807
  writeModels(paths, stripEmpty({ ...current, tiers: Object.keys(tiers).length === 0 ? void 0 : tiers }));
65759
65808
  }
65809
+ function addSameGroup(paths, refs) {
65810
+ const current = readModels(paths) ?? {};
65811
+ const overlapping = (current.same ?? []).filter((group) => group.some((ref) => refs.includes(ref)));
65812
+ const rest = (current.same ?? []).filter((group) => !overlapping.includes(group));
65813
+ const joined2 = [.../* @__PURE__ */ new Set([...overlapping.flat(), ...refs])];
65814
+ writeModels(paths, stripEmpty({ ...current, same: [...rest, joined2] }));
65815
+ }
65816
+ function addDistinctPair(paths, left, right) {
65817
+ const current = readModels(paths) ?? {};
65818
+ const known = (current.distinct ?? []).some(([a10, b]) => a10 === left && b === right || a10 === right && b === left);
65819
+ if (!known) {
65820
+ writeModels(paths, stripEmpty({ ...current, distinct: [...current.distinct ?? [], [left, right]] }));
65821
+ }
65822
+ }
65823
+ function removeAssertionsNaming(paths, ref) {
65824
+ const current = readModels(paths);
65825
+ if (current === void 0) {
65826
+ return 0;
65827
+ }
65828
+ const same = (current.same ?? []).filter((group) => !group.includes(ref));
65829
+ const distinct = (current.distinct ?? []).filter(([left, right]) => left !== ref && right !== ref);
65830
+ const removed = (current.same ?? []).length - same.length + ((current.distinct ?? []).length - distinct.length);
65831
+ if (removed > 0) {
65832
+ writeModels(paths, stripEmpty({ ...current, same: same.length === 0 ? void 0 : same, distinct: distinct.length === 0 ? void 0 : distinct }));
65833
+ }
65834
+ return removed;
65835
+ }
65836
+ function setFamily(paths, key, settings2) {
65837
+ const current = readModels(paths) ?? {};
65838
+ const others = Object.fromEntries(Object.entries(current.families ?? {}).filter(([existing]) => existing !== key));
65839
+ const next = settings2 === void 0 ? others : { ...others, [key]: settings2 };
65840
+ writeModels(paths, stripEmpty({ ...current, families: Object.keys(next).length === 0 ? void 0 : next }));
65841
+ }
65760
65842
  var VirtualModelNotFoundError;
65761
65843
  var init_modelsStore = __esm({
65762
65844
  "src/modelsStore.ts"() {
@@ -119737,6 +119819,57 @@ init_source();
119737
119819
 
119738
119820
  // src/models/doctor.ts
119739
119821
  init_modelsStore();
119822
+
119823
+ // src/models/families.ts
119824
+ init_identity2();
119825
+ var FAMILY_PREFIX = "family:";
119826
+ var VARIANT_SEPARATOR = "+";
119827
+ function modelOf2(ref) {
119828
+ const slash = ref.indexOf("/");
119829
+ return slash === -1 ? ref : ref.slice(slash + 1);
119830
+ }
119831
+ function familyKeyOf(rawModel) {
119832
+ const identity = modelIdentity(rawModel);
119833
+ return identity.variant === "" ? identity.familyAndVersion : `${identity.familyAndVersion}${VARIANT_SEPARATOR}${identity.variant}`;
119834
+ }
119835
+ function assertionsOf(models) {
119836
+ return { same: models?.same ?? [], distinct: models?.distinct ?? [] };
119837
+ }
119838
+ function sameModel(left, right, assertions) {
119839
+ if (assertions.distinct.some(([a10, b]) => a10 === left && b === right || a10 === right && b === left)) {
119840
+ return false;
119841
+ }
119842
+ const leftGroup = assertions.same.find((group) => group.includes(left));
119843
+ const rightGroup = assertions.same.find((group) => group.includes(right));
119844
+ if (leftGroup !== void 0 && leftGroup === rightGroup) {
119845
+ return true;
119846
+ }
119847
+ if (leftGroup !== void 0 && !leftGroup.includes(right) || rightGroup !== void 0 && !rightGroup.includes(left)) {
119848
+ return false;
119849
+ }
119850
+ return relateModels(modelOf2(left), modelOf2(right)) === "same";
119851
+ }
119852
+ function pinnedTo(settings2, ref) {
119853
+ return settings2?.names?.some((name) => name === ref || name === modelOf2(ref)) === true;
119854
+ }
119855
+ function buildFamilies(refs, models) {
119856
+ const assertions = assertionsOf(models);
119857
+ const settingsByKey = models?.families ?? {};
119858
+ const groups = [];
119859
+ for (const ref of refs) {
119860
+ const pinnedKey = Object.entries(settingsByKey).find(([, settings2]) => pinnedTo(settings2, ref))?.[0];
119861
+ const joined2 = groups.find((group) => pinnedKey === void 0 ? group.refs.some((first) => sameModel(first, ref, assertions)) : group.key === pinnedKey);
119862
+ if (joined2 !== void 0) {
119863
+ joined2.refs.push(ref);
119864
+ } else {
119865
+ groups.push({ key: pinnedKey ?? familyKeyOf(modelOf2(ref)), refs: [ref] });
119866
+ }
119867
+ }
119868
+ return groups.map((group) => ({ key: group.key, refs: group.refs, settings: settingsByKey[group.key] ?? {} }));
119869
+ }
119870
+
119871
+ // src/models/doctor.ts
119872
+ init_identity2();
119740
119873
  function modelsFindings(input2) {
119741
119874
  const findings = [];
119742
119875
  const { models } = input2;
@@ -119781,6 +119914,38 @@ function modelsFindings(input2) {
119781
119914
  findings.push({ severity: "fail", message: `Tier ${tier} points at "${ref}", which names nothing defined.` });
119782
119915
  }
119783
119916
  }
119917
+ const modelOfRef = (ref) => ref.slice(ref.indexOf("/") + 1);
119918
+ for (const group of models.same ?? []) {
119919
+ for (let outer = 0; outer < group.length; outer += 1) {
119920
+ for (let inner = outer + 1; inner < group.length; inner += 1) {
119921
+ const left = group[outer] ?? "";
119922
+ const right = group[inner] ?? "";
119923
+ if (!left.startsWith("acct:") && !right.startsWith("acct:") && relateModels(modelOfRef(left), modelOfRef(right)) === "distinct") {
119924
+ findings.push({ severity: "warn", message: `"${left}" and "${right}" are asserted to be one model, but their names say they are different models; check the assertion is not a typo.` });
119925
+ }
119926
+ if ((models.distinct ?? []).some(([a10, b]) => a10 === left && b === right || a10 === right && b === left)) {
119927
+ findings.push({ severity: "fail", message: `"${left}" and "${right}" are asserted to be both one model and two models.` });
119928
+ }
119929
+ }
119930
+ }
119931
+ }
119932
+ for (const [name, model] of Object.entries(models.virtual ?? {})) {
119933
+ const concrete = model.members.filter((member) => memberKindOf(member, models) === "provider" && member.includes("/"));
119934
+ const looksAlike = concrete.flatMap((left, index) => concrete.slice(index + 1).filter((right) => relateModels(modelOfRef(left), modelOfRef(right)) === "same").map((right) => [left, right]));
119935
+ for (const [left, right] of looksAlike) {
119936
+ findings.push({ severity: "warn", message: `Virtual model "${name}" lists "${left}" and "${right}", which look like one model; a member ${FAMILY_PREFIX}${familyKeyOf(modelOfRef(left))} names every target of it.` });
119937
+ }
119938
+ }
119939
+ if (input2.targets !== void 0) {
119940
+ const families = buildFamilies(input2.targets, models);
119941
+ for (const [name, model] of Object.entries(models.virtual ?? {})) {
119942
+ for (const member of model.members.filter((entry) => entry.startsWith(FAMILY_PREFIX))) {
119943
+ if (!families.some((family) => `${FAMILY_PREFIX}${family.key}` === member)) {
119944
+ findings.push({ severity: "warn", message: `Virtual model "${name}" names ${member}, but no target the providers offer belongs to that family.` });
119945
+ }
119946
+ }
119947
+ }
119948
+ }
119784
119949
  const hidden = new Set(models.hide ?? []);
119785
119950
  const shown = new Set(models.show ?? []);
119786
119951
  for (const ref of hidden) {
@@ -119791,6 +119956,21 @@ function modelsFindings(input2) {
119791
119956
  return findings;
119792
119957
  }
119793
119958
 
119959
+ // src/models/targets.ts
119960
+ init_modelPicker();
119961
+ init_providerCatalogue();
119962
+ init_providersStore();
119963
+ init_realPorts();
119964
+ function providerModels(paths) {
119965
+ return listProviders(paths).flatMap((entry) => {
119966
+ const catalogue = parseCatalogueCache(realFsPort.readFileUtf8(catalogueCachePath(paths, entry.name)));
119967
+ return providerModelRows(entry.provider, catalogue?.models).map((row) => ({ provider: entry.name, model: row.model }));
119968
+ });
119969
+ }
119970
+ function targetRefs(paths) {
119971
+ return providerModels(paths).map((entry) => `${entry.provider}/${entry.model}`);
119972
+ }
119973
+
119794
119974
  // src/doctorReport.ts
119795
119975
  init_configProfilesStore();
119796
119976
 
@@ -120344,7 +120524,7 @@ function runDoctor(params) {
120344
120524
  if (models === void 0) {
120345
120525
  push("models", "pass", "No models block configured.");
120346
120526
  } else {
120347
- for (const finding of modelsFindings({ models, providers: params.providers.map((entry) => entry.name), identities: params.identities.map((entry) => entry.name) })) {
120527
+ for (const finding of modelsFindings({ models, providers: params.providers.map((entry) => entry.name), identities: params.identities.map((entry) => entry.name), ...params.modelTargets === void 0 ? {} : { targets: params.modelTargets } })) {
120348
120528
  push("models", finding.severity, finding.message);
120349
120529
  }
120350
120530
  push("models", "pass", "The models block is consistent.");
@@ -120578,6 +120758,7 @@ function collectDoctorReport(params) {
120578
120758
  directoryRules: { path: paths.directoryRulesFile, raw: realFsPort.readFileUtf8(paths.directoryRulesFile) },
120579
120759
  globalConfig: { path: paths.globalConfigFile, raw: realFsPort.readFileUtf8(paths.globalConfigFile) },
120580
120760
  models: parsedModelsOf(paths),
120761
+ modelTargets: targetRefs(paths),
120581
120762
  categoriesLocal: { path: paths.categoriesLocalFile, raw: realFsPort.readFileUtf8(paths.categoriesLocalFile) },
120582
120763
  activeIdentity: { path: paths.activeIdentityFile, raw: realFsPort.readFileUtf8(paths.activeIdentityFile) },
120583
120764
  binaryDiscovery,
@@ -147640,10 +147821,6 @@ function registerProviderCommand(program2, deps) {
147640
147821
 
147641
147822
  // src/models.ts
147642
147823
  init_commandDeps();
147643
- init_providersStore();
147644
- init_modelPicker();
147645
- init_providerCatalogue();
147646
- init_realPorts();
147647
147824
  init_schema();
147648
147825
  init_cliError();
147649
147826
  init_identity2();
@@ -147705,22 +147882,13 @@ function explainVirtualModel(paths, name) {
147705
147882
  console.log(` ${line}`);
147706
147883
  }
147707
147884
  }
147708
- function providerModels(paths) {
147709
- return listProviders(paths).flatMap((entry) => {
147710
- const catalogue = parseCatalogueCache(realFsPort.readFileUtf8(catalogueCachePath(paths, entry.name)));
147711
- return providerModelRows(entry.provider, catalogue?.models).map((row) => ({ provider: entry.name, model: row.model }));
147712
- });
147713
- }
147714
- function matchModels(models) {
147715
- const same = [];
147716
- for (const model of models) {
147717
- const group = same.find((candidates) => candidates.some((other) => relateModels(other.model, model.model) === "same" && other.provider !== model.provider));
147718
- if (group === void 0) {
147719
- same.push([model]);
147720
- } else {
147721
- group.push(model);
147722
- }
147723
- }
147885
+ function matchModels(models, config2) {
147886
+ const refOf = (model) => `${model.provider}/${model.model}`;
147887
+ const byRef = new Map(models.map((model) => [refOf(model), model]));
147888
+ const families = buildFamilies(models.map(refOf), config2);
147889
+ const familyOf = new Map(families.flatMap((family) => family.refs.map((ref) => [ref, family])));
147890
+ const same = families.map((family) => family.refs.flatMap((ref) => byRef.get(ref) ?? [])).filter((group) => new Set(group.map((entry) => entry.provider)).size > 1);
147891
+ const distinct = config2?.distinct ?? [];
147724
147892
  const similar = [];
147725
147893
  for (let outer = 0; outer < models.length; outer += 1) {
147726
147894
  for (let inner = outer + 1; inner < models.length; inner += 1) {
@@ -147729,12 +147897,13 @@ function matchModels(models) {
147729
147897
  if (left === void 0 || right === void 0 || left.provider === right.provider) {
147730
147898
  continue;
147731
147899
  }
147732
- if (relateModels(left.model, right.model) === "similar" && !same.some((group) => group.includes(left) && group.includes(right))) {
147900
+ const asserted = distinct.some(([a10, b]) => a10 === refOf(left) && b === refOf(right) || a10 === refOf(right) && b === refOf(left));
147901
+ if (!asserted && familyOf.get(refOf(left)) !== familyOf.get(refOf(right)) && relateModels(left.model, right.model) === "similar") {
147733
147902
  similar.push([left, right]);
147734
147903
  }
147735
147904
  }
147736
147905
  }
147737
- return { same: same.filter((group) => group.length > 1), similar };
147906
+ return { same, similar };
147738
147907
  }
147739
147908
  function registerModelsCommand(program2, deps) {
147740
147909
  const { paths } = deps;
@@ -147751,7 +147920,7 @@ function registerModelsCommand(program2, deps) {
147751
147920
  ["agent-shim model match"]
147752
147921
  ).action((options) => {
147753
147922
  const models = providerModels(paths);
147754
- const { same, similar } = matchModels(models);
147923
+ const { same, similar } = matchModels(models, readModels(paths));
147755
147924
  if (options.json === true) {
147756
147925
  printJson({ models, same, similar });
147757
147926
  return;
@@ -147830,7 +147999,53 @@ function registerModelsCommand(program2, deps) {
147830
147999
  console.log(options.clear === true ? `Removed prices for ${ref}.` : `Prices for ${ref}: ${String(options.input)} in, ${String(options.output)} out per million tokens.`);
147831
148000
  });
147832
148001
  withExamples(
147833
- modelsCommand.command("list").description("List the defined virtual models, the tier pointers and the visibility filter.").option("--json", "Print the models block as JSON."),
148002
+ modelsCommand.command("same <ref> <ref...>").description("Assert that these refs are one model under several names, which makes them one family a mode can route across."),
148003
+ ["agent-shim model same z/glm-5.1 o/zai-glm-51"]
148004
+ ).action((first, rest) => {
148005
+ addSameGroup(paths, [first, ...rest]);
148006
+ console.log(`Asserted one model: ${[first, ...rest].join(" = ")}`);
148007
+ });
148008
+ withExamples(
148009
+ modelsCommand.command("distinct <left> <right>").description("Assert that two refs are two models, however alike their names look, so they are never put in one family."),
148010
+ ["agent-shim model distinct z/glm-5.1 s/hf:zai-org/GLM-5.1"]
148011
+ ).action((left, right) => {
148012
+ addDistinctPair(paths, left, right);
148013
+ console.log(`Asserted two models: ${left} / ${right}`);
148014
+ });
148015
+ withExamples(
148016
+ modelsCommand.command("unassert <ref>").description("Remove every identity assertion that names this ref."),
148017
+ ["agent-shim model unassert z/glm-5.1"]
148018
+ ).action((ref) => {
148019
+ const removed = removeAssertionsNaming(paths, ref);
148020
+ console.log(removed === 0 ? `No assertion names ${ref}.` : `Removed ${String(removed)} assertion${removed === 1 ? "" : "s"} naming ${ref}.`);
148021
+ });
148022
+ withExamples(
148023
+ modelsCommand.command("family <key>").description("Set one family's own settings: how a row that selects the whole family chooses, the names the normaliser cannot know, and what every target of it can do.").option("--mode <mode>", "How a row selecting the whole family chooses among its targets.", (value2) => asMode(value2)).option("--name <ref>", "Pin a ref or bare model name into the family (repeatable).", collectRepeated).option("--context <tokens>", "The family's context window, in tokens.", (value2) => asPositiveInteger(value2)).option("--vision", "Every target of the family accepts images.").option("--no-vision", "No target of the family accepts images.").option("--tools", "Every target of the family accepts tools.").option("--no-tools", "No target of the family accepts tools.").option("--thinking", "Every target of the family thinks.").option("--no-thinking", "No target of the family thinks.").option("--clear", "Remove the family's settings instead."),
148024
+ ["agent-shim model family glm-5-1 --mode cheapest --no-vision", "agent-shim model family claude-opus-5-5 --name o/opus-latest"]
148025
+ ).action((key, options) => {
148026
+ if (options.clear === true) {
148027
+ setFamily(paths, key, void 0);
148028
+ console.log(`Removed the settings of family ${key}.`);
148029
+ return;
148030
+ }
148031
+ const existing = readModels(paths)?.families?.[key] ?? {};
148032
+ const settings2 = {
148033
+ ...existing,
148034
+ ...options.mode === void 0 ? {} : { mode: options.mode },
148035
+ ...options.name === void 0 ? {} : { names: [.../* @__PURE__ */ new Set([...existing.names ?? [], ...options.name])] },
148036
+ ...options.context === void 0 ? {} : { context: options.context },
148037
+ ...options.vision === void 0 ? {} : { vision: options.vision },
148038
+ ...options.tools === void 0 ? {} : { tools: options.tools },
148039
+ ...options.thinking === void 0 ? {} : { thinking: options.thinking }
148040
+ };
148041
+ if (Object.keys(settings2).length === 0) {
148042
+ throw new UsageError("Nothing to set: pass --mode, --name, --context, a capability flag, or --clear.");
148043
+ }
148044
+ setFamily(paths, key, settings2);
148045
+ console.log(`Family ${key}: ${JSON.stringify(settings2)}`);
148046
+ });
148047
+ withExamples(
148048
+ modelsCommand.command("list").description("List the defined virtual models, the tier pointers, the visibility filter, the identity assertions and the family settings.").option("--json", "Print the models block as JSON."),
147834
148049
  ["agent-shim model list"]
147835
148050
  ).action((options) => {
147836
148051
  const found = readModels(paths);
@@ -147854,8 +148069,24 @@ function registerModelsCommand(program2, deps) {
147854
148069
  if (found.show !== void 0) {
147855
148070
  console.log(`visible only: ${found.show.join(", ")}`);
147856
148071
  }
148072
+ for (const group of found.same ?? []) {
148073
+ console.log(`same: ${group.join(" = ")}`);
148074
+ }
148075
+ for (const [left, right] of found.distinct ?? []) {
148076
+ console.log(`distinct: ${left} / ${right}`);
148077
+ }
148078
+ for (const [key, settings2] of Object.entries(found.families ?? {})) {
148079
+ console.log(`family ${key}: ${JSON.stringify(settings2)}`);
148080
+ }
147857
148081
  });
147858
148082
  }
148083
+ function asPositiveInteger(value2) {
148084
+ const parsed = Number(value2);
148085
+ if (!Number.isInteger(parsed) || parsed <= 0) {
148086
+ throw new UsageError(`"${value2}" is not a token count: pass a positive whole number.`);
148087
+ }
148088
+ return parsed;
148089
+ }
147859
148090
  function asMode(value2) {
147860
148091
  const mode = SELECTION_MODES.find((candidate) => candidate === value2);
147861
148092
  if (mode === void 0) {