claude-use 11.32.0 → 11.33.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
@@ -226,7 +226,7 @@ function isTimeZone(name) {
226
226
  return false;
227
227
  }
228
228
  }
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;
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, 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, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
230
230
  var init_schema = __esm({
231
231
  "src/config/schema.ts"() {
232
232
  "use strict";
@@ -452,13 +452,54 @@ var init_schema = __esm({
452
452
  antigravity: AntigravityProviderConfigSchema.optional()
453
453
  });
454
454
  ProviderSchema = z.discriminatedUnion("kind", [HttpProviderSchema, CodexProviderSchema, AntigravityProviderSchema]);
455
+ SELECTION_MODES = ["ordered", "most-allowance", "soonest-reset", "spread", "adaptive", "lowest-latency", "highest-success", "cheapest"];
456
+ VirtualModelSchema = z.strictObject({
457
+ /** How the virtual model chooses its member for a request. */
458
+ mode: z.enum(SELECTION_MODES),
459
+ /** The members to choose among, in preference order where the mode reads order. Each names a target (`z/glm-5.3`), an account model (`acct:work/opus`), another virtual model, or a family (`family:<canonical>`). */
460
+ members: z.array(z.string().min(1)).min(1)
461
+ });
462
+ ModelPricesSchema = z.strictObject({
463
+ input: z.number().positive(),
464
+ output: z.number().positive()
465
+ });
466
+ ModelsConfigSchema = z.strictObject({
467
+ /** Virtual models, by name. */
468
+ virtual: z.record(z.string().min(1), VirtualModelSchema).optional(),
469
+ /** Which model ref each Claude tier (`fable`, `opus`, `sonnet`, `haiku`) points at: a concrete target, an account model, a virtual model, or a family. */
470
+ tiers: z.strictObject({
471
+ fable: z.string().min(1).optional(),
472
+ opus: z.string().min(1).optional(),
473
+ sonnet: z.string().min(1).optional(),
474
+ haiku: z.string().min(1).optional()
475
+ }).optional(),
476
+ /** Prices per model ref, for the `cheapest` mode. */
477
+ prices: z.record(z.string().min(1), ModelPricesSchema).optional(),
478
+ /** Model refs hidden from the picker and from routing, whatever else names them. */
479
+ hide: z.array(z.string().min(1)).optional(),
480
+ /** When set, the only model refs visible; everything else is hidden. */
481
+ show: z.array(z.string().min(1)).optional()
482
+ });
483
+ ModelsLayerSchema = z.strictObject({
484
+ virtual: z.record(z.string().min(1), z.union([VirtualModelSchema, z.null()])).optional(),
485
+ tiers: z.strictObject({
486
+ fable: z.union([z.string().min(1), z.null()]).optional(),
487
+ opus: z.union([z.string().min(1), z.null()]).optional(),
488
+ sonnet: z.union([z.string().min(1), z.null()]).optional(),
489
+ haiku: z.union([z.string().min(1), z.null()]).optional()
490
+ }).optional(),
491
+ prices: z.record(z.string().min(1), z.union([ModelPricesSchema, z.null()])).optional(),
492
+ hide: z.array(z.string().min(1)).optional(),
493
+ show: z.array(z.string().min(1)).optional()
494
+ });
455
495
  ConfigProfileSchema = z.strictObject({
456
496
  $schema: z.string().optional(),
457
497
  description: z.string().optional(),
458
498
  extends: z.array(z.string().min(1)).optional(),
459
499
  categories: CategoryMapSchema.optional(),
460
500
  entries: EntriesSchema.optional(),
461
- launch: LaunchSchema.optional()
501
+ launch: LaunchSchema.optional(),
502
+ models: ModelsLayerSchema.optional()
462
503
  });
463
504
  POOL_SELECTOR_PREFIX = "pool:";
464
505
  POOL_NAME_PATTERN = "[A-Za-z0-9][A-Za-z0-9._-]*";
@@ -568,6 +609,7 @@ var init_schema = __esm({
568
609
  frontdoor: FrontDoorGlobalConfigSchema.optional(),
569
610
  update: UpdateGlobalConfigSchema.optional(),
570
611
  pools: z.record(PoolNameSchema, PoolSchema).optional(),
612
+ models: ModelsConfigSchema.optional(),
571
613
  jobs: z.record(PoolNameSchema, JobSchema).optional()
572
614
  });
573
615
  IdentitySchema = z.strictObject({
@@ -1344,6 +1386,7 @@ function flattenLayers(layers, options) {
1344
1386
  const rules = /* @__PURE__ */ new Map();
1345
1387
  const launch = {};
1346
1388
  const diagnostics = [];
1389
+ let models;
1347
1390
  for (const layer of layers) {
1348
1391
  if (layer.categories !== void 0) {
1349
1392
  for (const [name, value] of Object.entries(layer.categories)) {
@@ -1382,6 +1425,9 @@ function flattenLayers(layers, options) {
1382
1425
  launch.explain = layer.launch.explain;
1383
1426
  }
1384
1427
  }
1428
+ if (layer.models !== void 0) {
1429
+ models = mergeModels(models, layer.models);
1430
+ }
1385
1431
  if (layer.entries === void 0) {
1386
1432
  continue;
1387
1433
  }
@@ -1444,7 +1490,7 @@ function flattenLayers(layers, options) {
1444
1490
  rules.set(pattern, rule);
1445
1491
  }
1446
1492
  }
1447
- return { categories, rules, launch, diagnostics };
1493
+ return { categories, rules, launch, ...models === void 0 ? {} : { models }, diagnostics };
1448
1494
  }
1449
1495
  function orderedKeys(layer) {
1450
1496
  const present = new Set(Object.keys(layer.entries ?? {}));
@@ -1469,6 +1515,67 @@ function matchingRules(flattened, relPath) {
1469
1515
  }
1470
1516
  return matches.sort((a, b) => compareSpecificity(b, a));
1471
1517
  }
1518
+ function mergeModels(current, layer) {
1519
+ const pieces = { ...current ?? {} };
1520
+ if (layer.virtual !== void 0) {
1521
+ const virtual = {};
1522
+ for (const [name, definition] of Object.entries(current?.virtual ?? {})) {
1523
+ if (layer.virtual[name] === void 0) {
1524
+ virtual[name] = definition;
1525
+ }
1526
+ }
1527
+ for (const [name, definition] of Object.entries(layer.virtual)) {
1528
+ if (definition !== null) {
1529
+ virtual[name] = definition;
1530
+ }
1531
+ }
1532
+ pieces.virtual = virtual;
1533
+ }
1534
+ if (layer.tiers !== void 0) {
1535
+ const tiers = {};
1536
+ for (const tier of ["fable", "opus", "sonnet", "haiku"]) {
1537
+ const ref = layer.tiers[tier];
1538
+ const inherited = current?.tiers?.[tier];
1539
+ if (ref !== null && ref !== void 0) {
1540
+ tiers[tier] = ref;
1541
+ } else if (ref === void 0 && inherited !== void 0) {
1542
+ tiers[tier] = inherited;
1543
+ }
1544
+ }
1545
+ pieces.tiers = tiers;
1546
+ }
1547
+ if (layer.prices !== void 0) {
1548
+ const priced = {};
1549
+ for (const [ref, prices] of Object.entries(current?.prices ?? {})) {
1550
+ if (layer.prices[ref] === void 0) {
1551
+ priced[ref] = prices;
1552
+ }
1553
+ }
1554
+ for (const [ref, prices] of Object.entries(layer.prices)) {
1555
+ if (prices !== null) {
1556
+ priced[ref] = prices;
1557
+ }
1558
+ }
1559
+ pieces.prices = priced;
1560
+ }
1561
+ if (layer.hide !== void 0) {
1562
+ pieces.hide = layer.hide;
1563
+ }
1564
+ if (layer.show !== void 0) {
1565
+ pieces.show = layer.show;
1566
+ }
1567
+ const merged = modelsOf(pieces);
1568
+ return Object.keys(merged).length === 0 ? void 0 : merged;
1569
+ }
1570
+ function modelsOf(pieces) {
1571
+ return {
1572
+ ...pieces.virtual === void 0 || Object.keys(pieces.virtual).length === 0 ? {} : { virtual: pieces.virtual },
1573
+ ...pieces.tiers === void 0 || Object.keys(pieces.tiers).length === 0 ? {} : { tiers: pieces.tiers },
1574
+ ...pieces.prices === void 0 || Object.keys(pieces.prices).length === 0 ? {} : { prices: pieces.prices },
1575
+ ...pieces.hide === void 0 || pieces.hide.length === 0 ? {} : { hide: [...pieces.hide] },
1576
+ ...pieces.show === void 0 || pieces.show.length === 0 ? {} : { show: [...pieces.show] }
1577
+ };
1578
+ }
1472
1579
  var init_flatten = __esm({
1473
1580
  "src/resolve/flatten.ts"() {
1474
1581
  "use strict";
@@ -1843,7 +1950,8 @@ function profileLayers(rootName, load, startId) {
1843
1950
  ...source.profile.categories === void 0 ? {} : { categories: source.profile.categories },
1844
1951
  ...source.profile.entries === void 0 ? {} : { entries: source.profile.entries },
1845
1952
  ...source.entryOrder === void 0 ? {} : { entryOrder: source.entryOrder },
1846
- ...source.profile.launch === void 0 ? {} : { launch: source.profile.launch }
1953
+ ...source.profile.launch === void 0 ? {} : { launch: source.profile.launch },
1954
+ ...source.profile.models === void 0 ? {} : { models: source.profile.models }
1847
1955
  });
1848
1956
  nextId += 1;
1849
1957
  }
@@ -1932,7 +2040,8 @@ function assembleCascade(input) {
1932
2040
  ...source.config.categories === void 0 ? {} : { categories: source.config.categories },
1933
2041
  ...source.config.entries === void 0 ? {} : { entries: source.config.entries },
1934
2042
  ...source.entryOrder === void 0 ? {} : { entryOrder: source.entryOrder },
1935
- ...source.config.launch === void 0 ? {} : { launch: source.config.launch }
2043
+ ...source.config.launch === void 0 ? {} : { launch: source.config.launch },
2044
+ ...source.config.models === void 0 ? {} : { models: source.config.models }
1936
2045
  });
1937
2046
  nextId += 1;
1938
2047
  }
@@ -2959,7 +3068,7 @@ var init_package = __esm({
2959
3068
  "package.json"() {
2960
3069
  package_default = {
2961
3070
  name: "claude-use",
2962
- version: "11.32.0",
3071
+ version: "11.33.0",
2963
3072
  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.",
2964
3073
  license: "MIT",
2965
3074
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -14672,6 +14781,107 @@ init_credentialCache();
14672
14781
  init_realCredentialCache();
14673
14782
  init_source();
14674
14783
 
14784
+ // src/modelsStore.ts
14785
+ init_store();
14786
+ init_schema();
14787
+ var VirtualModelNotFoundError = class extends Error {
14788
+ constructor(name) {
14789
+ super(`No virtual model named "${name}".`);
14790
+ this.name = "VirtualModelNotFoundError";
14791
+ }
14792
+ };
14793
+ function memberKindOf(ref, models) {
14794
+ if (ref.startsWith("acct:")) {
14795
+ return "account";
14796
+ }
14797
+ if (ref.startsWith("family:")) {
14798
+ return "family";
14799
+ }
14800
+ return models?.virtual !== void 0 && ref in models.virtual ? "virtual" : "provider";
14801
+ }
14802
+ function expandMembers(name, models) {
14803
+ const virtual = models?.virtual ?? {};
14804
+ const expanded = [];
14805
+ const walk = (current, chain) => {
14806
+ const nested = virtual[current];
14807
+ if (nested !== void 0) {
14808
+ if (chain.includes(current)) {
14809
+ throw new Error(`virtual model cycle: ${[...chain, current].join(" -> ")}`);
14810
+ }
14811
+ for (const member of nested.members) {
14812
+ walk(member, [...chain, current]);
14813
+ }
14814
+ return;
14815
+ }
14816
+ if (!expanded.includes(current)) {
14817
+ expanded.push(current);
14818
+ }
14819
+ };
14820
+ const top = virtual[name];
14821
+ if (top === void 0) {
14822
+ throw new VirtualModelNotFoundError(name);
14823
+ }
14824
+ for (const member of top.members) {
14825
+ walk(member, [name]);
14826
+ }
14827
+ return expanded;
14828
+ }
14829
+
14830
+ // src/models/doctor.ts
14831
+ function modelsFindings(input) {
14832
+ const findings = [];
14833
+ const { models } = input;
14834
+ const providers = new Set(input.providers);
14835
+ const identities = new Set(input.identities);
14836
+ const virtualNames = new Set(Object.keys(models.virtual ?? {}));
14837
+ for (const [name, model] of Object.entries(models.virtual ?? {})) {
14838
+ for (const member of model.members) {
14839
+ const kind = memberKindOf(member, models);
14840
+ if (kind === "provider" && !member.includes("/")) {
14841
+ findings.push({ severity: "fail", message: `Virtual model "${name}" names member "${member}", which is neither a defined virtual model nor a provider model (a provider model is <provider>/<model>).` });
14842
+ } else if (kind === "provider" && !providers.has(member.split("/")[0] ?? "")) {
14843
+ findings.push({ severity: "fail", message: `Virtual model "${name}" names member "${member}", but no provider "${member.split("/")[0] ?? ""}" is defined.` });
14844
+ }
14845
+ if (kind === "virtual" && !virtualNames.has(member)) {
14846
+ findings.push({ severity: "fail", message: `Virtual model "${name}" names member "${member}", but no virtual model "${member}" is defined.` });
14847
+ }
14848
+ if (kind === "account") {
14849
+ const identity = member.slice("acct:".length).split("/")[0] ?? "";
14850
+ if (!identities.has(identity)) {
14851
+ findings.push({ severity: "fail", message: `Virtual model "${name}" names member "${member}", but no identity "${identity}" is defined.` });
14852
+ }
14853
+ }
14854
+ }
14855
+ try {
14856
+ expandMembers(name, models);
14857
+ } catch (error) {
14858
+ findings.push({ severity: "fail", message: `Virtual model "${name}" cannot be expanded: ${error instanceof Error ? error.message : String(error)}` });
14859
+ }
14860
+ if (model.mode === "cheapest") {
14861
+ const expanded = expandMembers(name, models);
14862
+ const unpriced = expanded.filter((member) => models.prices?.[member] === void 0 && memberKindOf(member, models) !== "virtual");
14863
+ if (unpriced.length > 0) {
14864
+ findings.push({ severity: "warn", message: `Virtual model "${name}" chooses by price, but no prices are set for: ${unpriced.join(", ")}.` });
14865
+ }
14866
+ }
14867
+ }
14868
+ for (const [tier, ref] of Object.entries(models.tiers ?? {})) {
14869
+ const kind = memberKindOf(ref, models);
14870
+ const known = kind === "virtual" ? virtualNames.has(ref) : kind === "provider" ? providers.has(ref.split("/")[0] ?? "") : true;
14871
+ if (!known) {
14872
+ findings.push({ severity: "fail", message: `Tier ${tier} points at "${ref}", which names nothing defined.` });
14873
+ }
14874
+ }
14875
+ const hidden = new Set(models.hide ?? []);
14876
+ const shown = new Set(models.show ?? []);
14877
+ for (const ref of hidden) {
14878
+ if (shown.has(ref)) {
14879
+ findings.push({ severity: "fail", message: `Model ref "${ref}" is both hidden and in the show-only list.` });
14880
+ }
14881
+ }
14882
+ return findings;
14883
+ }
14884
+
14675
14885
  // src/headroom/allowlistDrift.ts
14676
14886
  init_earlierRelease();
14677
14887
  init_state2();
@@ -14858,7 +15068,8 @@ var DOCTOR_SECTIONS = [
14858
15068
  "categories-local",
14859
15069
  "active-identity",
14860
15070
  "headroom",
14861
- "frontdoor"
15071
+ "frontdoor",
15072
+ "models"
14862
15073
  ];
14863
15074
  function refinePathShadow(status, ownExecutablePath, realpath) {
14864
15075
  if (status.status !== "shadowed") {
@@ -15010,6 +15221,9 @@ function pushLegacyName(push, params) {
15010
15221
  );
15011
15222
  }
15012
15223
  }
15224
+ function parsedModelsOf(paths) {
15225
+ return readGlobalConfig(paths)?.models;
15226
+ }
15013
15227
  function runDoctor(params) {
15014
15228
  const findings = [];
15015
15229
  const push = (section, severity, message, subject) => {
@@ -15211,6 +15425,17 @@ function runDoctor(params) {
15211
15425
  }
15212
15426
  }
15213
15427
  }
15428
+ {
15429
+ const models = params.models;
15430
+ if (models === void 0) {
15431
+ push("models", "pass", "No models block configured.");
15432
+ } else {
15433
+ for (const finding of modelsFindings({ models, providers: params.providers.map((entry) => entry.name), identities: params.identities.map((entry) => entry.name) })) {
15434
+ push("models", finding.severity, finding.message);
15435
+ }
15436
+ push("models", "pass", "The models block is consistent.");
15437
+ }
15438
+ }
15214
15439
  if (params.categoriesLocal.raw === void 0) {
15215
15440
  push("categories-local", "pass", "No categories.local.json configured.");
15216
15441
  } else {
@@ -15305,6 +15530,7 @@ function runDoctor(params) {
15305
15530
  return { findings, ok: !findings.some((finding) => finding.severity === "fail") };
15306
15531
  }
15307
15532
  var SECTION_TITLES = {
15533
+ models: "Virtual models",
15308
15534
  "ambient-credential": "Ambient-credential exposure",
15309
15535
  "binary-discovery": "Claude Code binary discovery",
15310
15536
  "claude-shim": "`claude` command shim",
@@ -15437,6 +15663,7 @@ function collectDoctorReport(params) {
15437
15663
  providers,
15438
15664
  directoryRules: { path: paths.directoryRulesFile, raw: realFsPort.readFileUtf8(paths.directoryRulesFile) },
15439
15665
  globalConfig: { path: paths.globalConfigFile, raw: realFsPort.readFileUtf8(paths.globalConfigFile) },
15666
+ models: parsedModelsOf(paths),
15440
15667
  categoriesLocal: { path: paths.categoriesLocalFile, raw: realFsPort.readFileUtf8(paths.categoriesLocalFile) },
15441
15668
  activeIdentity: { path: paths.activeIdentityFile, raw: realFsPort.readFileUtf8(paths.activeIdentityFile) },
15442
15669
  binaryDiscovery,