claude-use 11.34.0 → 11.36.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
@@ -1434,6 +1434,9 @@ function flattenLayers(layers, options) {
1434
1434
  if (layer.launch.explain !== void 0) {
1435
1435
  launch.explain = layer.launch.explain;
1436
1436
  }
1437
+ if (layer.launch.routeByName !== void 0) {
1438
+ launch.routeByName = layer.launch.routeByName;
1439
+ }
1437
1440
  }
1438
1441
  if (layer.models !== void 0) {
1439
1442
  models = mergeModels(models, layer.models);
@@ -2862,7 +2865,7 @@ var init_capability = __esm({
2862
2865
  });
2863
2866
 
2864
2867
  // src/frontdoor/route.ts
2865
- var IDENTITY_HEADER, SESSION_HEADER, PROVIDER_HEADER, HEADROOM_FLAG_HEADER, PROJECT_ID_HEADER, AUTH_HEADER;
2868
+ var IDENTITY_HEADER, SESSION_HEADER, PROVIDER_HEADER, HEADROOM_FLAG_HEADER, ROUTE_BY_NAME_HEADER, PROJECT_ID_HEADER, AUTH_HEADER;
2866
2869
  var init_route = __esm({
2867
2870
  "src/frontdoor/route.ts"() {
2868
2871
  "use strict";
@@ -2870,6 +2873,7 @@ var init_route = __esm({
2870
2873
  SESSION_HEADER = "x-agent-shim-session";
2871
2874
  PROVIDER_HEADER = "x-agent-shim-provider";
2872
2875
  HEADROOM_FLAG_HEADER = "x-agent-shim-headroom";
2876
+ ROUTE_BY_NAME_HEADER = "x-agent-shim-route-by-name";
2873
2877
  PROJECT_ID_HEADER = "x-headroom-project-id";
2874
2878
  AUTH_HEADER = "x-agent-shim-auth";
2875
2879
  }
@@ -3078,7 +3082,7 @@ var init_package = __esm({
3078
3082
  "package.json"() {
3079
3083
  package_default = {
3080
3084
  name: "claude-use",
3081
- version: "11.34.0",
3085
+ version: "11.36.0",
3082
3086
  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.",
3083
3087
  license: "MIT",
3084
3088
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -6231,6 +6235,196 @@ var init_poolPick = __esm({
6231
6235
  }
6232
6236
  });
6233
6237
 
6238
+ // src/configProfilesStore.ts
6239
+ import fs4 from "node:fs";
6240
+ import path22 from "node:path";
6241
+ function profileJsonPath(paths, name) {
6242
+ return path22.join(paths.configProfilesDir, `${name}.json`);
6243
+ }
6244
+ function profileExists(paths, name) {
6245
+ return fs4.existsSync(profileJsonPath(paths, name));
6246
+ }
6247
+ function requireProfileExists(paths, name) {
6248
+ if (!profileExists(paths, name)) {
6249
+ throw new ProfileNotFoundError(name);
6250
+ }
6251
+ }
6252
+ function readProfile(paths, name) {
6253
+ return readJson(profileJsonPath(paths, name), ConfigProfileSchema);
6254
+ }
6255
+ function createProfile(paths, name, extendsList, description) {
6256
+ if (profileExists(paths, name)) {
6257
+ throw new ProfileAlreadyExistsError(name);
6258
+ }
6259
+ const filePath = profileJsonPath(paths, name);
6260
+ const parsed = ConfigProfileSchema.safeParse({
6261
+ ...description === void 0 ? {} : { description },
6262
+ ...extendsList !== void 0 && extendsList.length > 0 ? { extends: [...extendsList] } : {}
6263
+ });
6264
+ if (!parsed.success) {
6265
+ throw new ConfigValidationError(filePath, parsed.error.issues);
6266
+ }
6267
+ writeJsonAtomic(filePath, parsed.data);
6268
+ return parsed.data;
6269
+ }
6270
+ function listProfiles(paths) {
6271
+ if (!fs4.existsSync(paths.configProfilesDir)) {
6272
+ return [];
6273
+ }
6274
+ const names = fs4.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort();
6275
+ const result = [];
6276
+ for (const name of names) {
6277
+ const profile = readProfile(paths, name);
6278
+ if (profile !== void 0) {
6279
+ result.push({ name, profile });
6280
+ }
6281
+ }
6282
+ return result;
6283
+ }
6284
+ function globalConfigPath(paths) {
6285
+ return paths.globalConfigFile;
6286
+ }
6287
+ function readGlobalConfig(paths) {
6288
+ return readJson(globalConfigPath(paths), GlobalConfigSchema);
6289
+ }
6290
+ function setGlobalDefaultProfile(paths, name) {
6291
+ return applyPatch(
6292
+ globalConfigPath(paths),
6293
+ GlobalConfigSchema,
6294
+ { defaultConfigProfile: name },
6295
+ { defaults: {} }
6296
+ );
6297
+ }
6298
+ function validateCategoryNames(patch) {
6299
+ for (const key of Object.keys(patch)) {
6300
+ if (!isOverridableCategory(key)) {
6301
+ throw new InvalidCategoryNameError(key);
6302
+ }
6303
+ }
6304
+ }
6305
+ function setProfileCategories(paths, name, patch) {
6306
+ requireProfileExists(paths, name);
6307
+ const expandedPatch = expandAllCategoryKey(patch);
6308
+ validateCategoryNames(expandedPatch);
6309
+ const existing = readProfile(paths, name) ?? {};
6310
+ const mergedCategories = { ...existing.categories, ...expandedPatch };
6311
+ return applyPatch(profileJsonPath(paths, name), ConfigProfileSchema, { categories: mergedCategories });
6312
+ }
6313
+ function setProfileEntries(paths, name, patch) {
6314
+ requireProfileExists(paths, name);
6315
+ const existing = readProfile(paths, name) ?? {};
6316
+ const mergedEntries = { ...existing.entries, ...patch };
6317
+ return applyPatch(profileJsonPath(paths, name), ConfigProfileSchema, { entries: mergedEntries });
6318
+ }
6319
+ function setProfileLaunchFlags(paths, name, patch) {
6320
+ requireProfileExists(paths, name);
6321
+ const existing = readProfile(paths, name) ?? {};
6322
+ const mergedLaunch = { ...existing.launch, ...patch };
6323
+ return applyPatch(profileJsonPath(paths, name), ConfigProfileSchema, {
6324
+ // Read as `unknown` so the check sees the `undefined` a cleared key holds, which LaunchFlags' optional properties hide from the value type.
6325
+ launch: Object.values(mergedLaunch).every((value) => value === void 0) ? void 0 : mergedLaunch
6326
+ });
6327
+ }
6328
+ function setProfileMetadata(paths, name, patch) {
6329
+ requireProfileExists(paths, name);
6330
+ return applyPatch(profileJsonPath(paths, name), ConfigProfileSchema, {
6331
+ ...patch.extends === void 0 ? {} : { extends: patch.extends.length === 0 ? void 0 : [...patch.extends] },
6332
+ ...patch.description === void 0 ? {} : { description: patch.description === false ? void 0 : patch.description }
6333
+ });
6334
+ }
6335
+ function removeProfile(paths, name) {
6336
+ requireProfileExists(paths, name);
6337
+ fs4.rmSync(profileJsonPath(paths, name));
6338
+ }
6339
+ function applyProfileChange(paths, name, change) {
6340
+ let touched = false;
6341
+ if (change.category !== void 0) {
6342
+ setProfileCategories(paths, name, change.category);
6343
+ touched = true;
6344
+ }
6345
+ if (change.entry !== void 0) {
6346
+ setProfileEntries(paths, name, change.entry);
6347
+ touched = true;
6348
+ }
6349
+ if (change.extends !== void 0 || change.description !== void 0) {
6350
+ setProfileMetadata(paths, name, {
6351
+ ...change.extends === void 0 ? {} : { extends: change.extends === false ? [] : change.extends },
6352
+ ...change.description === void 0 ? {} : { description: change.description }
6353
+ });
6354
+ touched = true;
6355
+ }
6356
+ const launchPatch = {};
6357
+ if (change.launchSkipPermissions !== void 0) {
6358
+ launchPatch.skipPermissions = change.launchSkipPermissions;
6359
+ }
6360
+ if (change.launchRemoteControl !== void 0) {
6361
+ launchPatch.remoteControl = change.launchRemoteControl;
6362
+ }
6363
+ if (change.launchHeadroom !== void 0) {
6364
+ launchPatch.headroom = change.launchHeadroom;
6365
+ }
6366
+ if (change.launchTrackUsage !== void 0) {
6367
+ launchPatch.trackUsage = change.launchTrackUsage;
6368
+ }
6369
+ if (change.launchProvider !== void 0) {
6370
+ launchPatch.provider = change.launchProvider === false ? void 0 : change.launchProvider;
6371
+ }
6372
+ if (change.launchClaudeVersion !== void 0) {
6373
+ launchPatch.claudeVersion = change.launchClaudeVersion === false ? void 0 : change.launchClaudeVersion;
6374
+ }
6375
+ if (change.launchDelay !== void 0) {
6376
+ launchPatch.delay = change.launchDelay === false ? void 0 : change.launchDelay;
6377
+ }
6378
+ if (change.launchPause !== void 0) {
6379
+ launchPatch.pause = change.launchPause;
6380
+ }
6381
+ if (change.launchExplain !== void 0) {
6382
+ launchPatch.explain = change.launchExplain;
6383
+ }
6384
+ if (change.launchRouteByName !== void 0) {
6385
+ launchPatch.routeByName = change.launchRouteByName;
6386
+ }
6387
+ if (Object.keys(launchPatch).length > 0) {
6388
+ setProfileLaunchFlags(paths, name, launchPatch);
6389
+ touched = true;
6390
+ }
6391
+ return touched;
6392
+ }
6393
+ var ProfileNotFoundError, ProfileAlreadyExistsError, InvalidCategoryNameError;
6394
+ var init_configProfilesStore = __esm({
6395
+ "src/configProfilesStore.ts"() {
6396
+ "use strict";
6397
+ init_store();
6398
+ init_schema();
6399
+ init_cliError();
6400
+ init_load();
6401
+ ProfileNotFoundError = class extends CliError {
6402
+ constructor(profileName) {
6403
+ super(`No configuration profile named "${profileName}". Run \`agent-shim profile add ${profileName}\` first.`);
6404
+ this.profileName = profileName;
6405
+ this.name = "ProfileNotFoundError";
6406
+ }
6407
+ profileName;
6408
+ };
6409
+ ProfileAlreadyExistsError = class extends CliError {
6410
+ constructor(profileName) {
6411
+ super(`A configuration profile named "${profileName}" already exists.`);
6412
+ this.profileName = profileName;
6413
+ this.name = "ProfileAlreadyExistsError";
6414
+ }
6415
+ profileName;
6416
+ };
6417
+ InvalidCategoryNameError = class extends CliError {
6418
+ constructor(categoryName) {
6419
+ super(`"${categoryName}" is not a category a configuration profile may toggle (runtime, history, knowledge, settings).`);
6420
+ this.categoryName = categoryName;
6421
+ this.name = "InvalidCategoryNameError";
6422
+ }
6423
+ categoryName;
6424
+ };
6425
+ }
6426
+ });
6427
+
6234
6428
  // src/paths.ts
6235
6429
  import fs5 from "node:fs";
6236
6430
  import os5 from "node:os";
@@ -7271,6 +7465,62 @@ var init_claudeShim = __esm({
7271
7465
  }
7272
7466
  });
7273
7467
 
7468
+ // src/modelsStore.ts
7469
+ function readModels(paths) {
7470
+ return readGlobalConfig(paths)?.models;
7471
+ }
7472
+ function memberKindOf(ref, models) {
7473
+ if (ref.startsWith("acct:")) {
7474
+ return "account";
7475
+ }
7476
+ if (ref.startsWith("family:")) {
7477
+ return "family";
7478
+ }
7479
+ return models?.virtual !== void 0 && ref in models.virtual ? "virtual" : "provider";
7480
+ }
7481
+ function expandMembers(name, models) {
7482
+ const virtual = models?.virtual ?? {};
7483
+ const expanded = [];
7484
+ const walk = (current, chain) => {
7485
+ const nested = virtual[current];
7486
+ if (nested !== void 0) {
7487
+ if (chain.includes(current)) {
7488
+ throw new Error(`virtual model cycle: ${[...chain, current].join(" -> ")}`);
7489
+ }
7490
+ for (const member of nested.members) {
7491
+ walk(member, [...chain, current]);
7492
+ }
7493
+ return;
7494
+ }
7495
+ if (!expanded.includes(current)) {
7496
+ expanded.push(current);
7497
+ }
7498
+ };
7499
+ const top = virtual[name];
7500
+ if (top === void 0) {
7501
+ throw new VirtualModelNotFoundError(name);
7502
+ }
7503
+ for (const member of top.members) {
7504
+ walk(member, [name]);
7505
+ }
7506
+ return expanded;
7507
+ }
7508
+ var VirtualModelNotFoundError;
7509
+ var init_modelsStore = __esm({
7510
+ "src/modelsStore.ts"() {
7511
+ "use strict";
7512
+ init_store();
7513
+ init_schema();
7514
+ init_configProfilesStore();
7515
+ VirtualModelNotFoundError = class extends Error {
7516
+ constructor(name) {
7517
+ super(`No virtual model named "${name}".`);
7518
+ this.name = "VirtualModelNotFoundError";
7519
+ }
7520
+ };
7521
+ }
7522
+ });
7523
+
7274
7524
  // src/frontdoor/probe.ts
7275
7525
  import { Worker } from "node:worker_threads";
7276
7526
  function probeFrontDoorSync(port, caPem) {
@@ -7692,7 +7942,8 @@ var init_argv = __esm({
7692
7942
  { flag: "--remote-control", key: "remoteControl" },
7693
7943
  { flag: "--wait", key: "wait" },
7694
7944
  { flag: "--pause", key: "pause" },
7695
- { flag: "--explain", key: "explain" }
7945
+ { flag: "--explain", key: "explain" },
7946
+ { flag: "--route-by-name", key: "routeByName" }
7696
7947
  ];
7697
7948
  LAUNCHER_FLAG_NAMES = [
7698
7949
  ...VALUED_FLAGS,
@@ -7883,6 +8134,7 @@ function resolveLaunchFlags(params) {
7883
8134
  trackUsage: params.flags?.trackUsage ?? parseEnvBool("AGENT_SHIM_TRACK_USAGE", params.env.AGENT_SHIM_TRACK_USAGE) ?? params.cascade?.trackUsage ?? true,
7884
8135
  pause: params.flags?.pause ?? parseEnvBool("AGENT_SHIM_PAUSE", params.env.AGENT_SHIM_PAUSE) ?? params.cascade?.pause ?? false,
7885
8136
  explain: params.flags?.explain ?? parseEnvBool("AGENT_SHIM_EXPLAIN", params.env.AGENT_SHIM_EXPLAIN) ?? params.cascade?.explain ?? false,
8137
+ routeByName: params.flags?.routeByName ?? parseEnvBool("AGENT_SHIM_ROUTE_BY_NAME", params.env.AGENT_SHIM_ROUTE_BY_NAME) ?? params.cascade?.routeByName ?? false,
7886
8138
  delayMs: resolveDelayMs(params)
7887
8139
  };
7888
8140
  }
@@ -7951,6 +8203,7 @@ function buildEnv(params) {
7951
8203
  { name: SESSION_HEADER, value: params.sessionId },
7952
8204
  { name: AUTH_HEADER, value: params.frontdoor.sessionToken },
7953
8205
  ...params.provider === void 0 ? [] : [{ name: PROVIDER_HEADER, value: params.provider.name }],
8206
+ ...params.routeByName ? [{ name: ROUTE_BY_NAME_HEADER, value: "1" }] : [],
7954
8207
  ...params.headroom === void 0 ? [] : [
7955
8208
  { name: HEADROOM_FLAG_HEADER, value: "1" },
7956
8209
  { name: PROJECT_ID_HEADER, value: params.headroom.projectId }
@@ -8591,8 +8844,40 @@ function providerModelRows(provider, catalogue = []) {
8591
8844
  const taken = new Set(named.map((row) => labelOf(row.model)));
8592
8845
  return [...named, ...catalogueRows(provider, catalogue).filter((row) => !taken.has(labelOf(row.model)))];
8593
8846
  }
8847
+ function routedModelRows(models, providers) {
8848
+ const hidden = new Set(models.hide ?? []);
8849
+ const shown = models.show === void 0 ? void 0 : new Set(models.show);
8850
+ const visible = (model) => shown === void 0 ? !hidden.has(model) : shown.has(model);
8851
+ const tierOf = (model) => {
8852
+ for (const [, provider] of providers) {
8853
+ if (provider.kind !== void 0 && provider.kind !== "http") {
8854
+ continue;
8855
+ }
8856
+ const env = provider.env ?? {};
8857
+ const match = Object.entries(env).find(([, value]) => value === model);
8858
+ if (match?.[0].endsWith("_MODEL") === true) {
8859
+ const tier = match[0].replace("ANTHROPIC_DEFAULT_", "").replace("_MODEL", "").toLowerCase();
8860
+ return tier === "fable" || tier === "opus" || tier === "sonnet" || tier === "haiku" ? tier : void 0;
8861
+ }
8862
+ }
8863
+ return void 0;
8864
+ };
8865
+ const virtual = Object.entries(models.virtual ?? {}).flatMap(([name, definition]) => {
8866
+ if (!visible(name)) {
8867
+ return [];
8868
+ }
8869
+ const first = definition.members.find((member) => member.includes("/"));
8870
+ const tier = first === void 0 ? void 0 : tierOf(first.split("/").slice(1).join("/"));
8871
+ const behavesAs = tier === void 0 ? void 0 : TIER_BEHAVES_AS[tier];
8872
+ return behavesAs === void 0 ? [] : [{ model: name, label: name, description: `Virtual (${definition.mode})`, behavesAs }];
8873
+ });
8874
+ const concrete = providers.flatMap(([name, provider]) => providerModelRows(provider).map((row) => ({ ...row, model: `${name}/${row.model}`, label: `${name} / ${row.label}`, description: `${name}: ${row.description}` })));
8875
+ return [...virtual, ...concrete.filter((row) => visible(row.model))];
8876
+ }
8594
8877
  function modelPickerSettings(provider, catalogue = []) {
8595
- const options = providerModelRows(provider, catalogue);
8878
+ return modelPickerSettingsFromRows(providerModelRows(provider, catalogue));
8879
+ }
8880
+ function modelPickerSettingsFromRows(options) {
8596
8881
  return options.length === 0 ? void 0 : JSON.stringify({ modelPicker: { options, replaceBuiltInOptions: true } });
8597
8882
  }
8598
8883
  var CONTEXT_MARKER_1M, TIER_BEHAVES_AS, TIER_ENV_VARIABLES;
@@ -9031,6 +9316,7 @@ function decideLaunch(params, readOnly) {
9031
9316
  ...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage },
9032
9317
  ...parsedArgv.pause === void 0 ? {} : { pause: parsedArgv.pause },
9033
9318
  ...parsedArgv.explain === void 0 ? {} : { explain: parsedArgv.explain },
9319
+ ...parsedArgv.routeByName === void 0 ? {} : { routeByName: parsedArgv.routeByName },
9034
9320
  ...parsedArgv.delay === void 0 ? {} : { delay: parsedArgv.delay }
9035
9321
  }
9036
9322
  });
@@ -9041,7 +9327,8 @@ function decideLaunch(params, readOnly) {
9041
9327
  }
9042
9328
  const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
9043
9329
  const catalogue = selectedProvider === void 0 ? void 0 : parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, selectedProvider.name)));
9044
- const pickerSettings = selectedProvider === void 0 ? void 0 : modelPickerSettings(selectedProvider.definition, catalogue?.models);
9330
+ const routesByName = flags.routeByName || selectedProvider !== void 0 && isRouterProvider(selectedProvider.definition);
9331
+ const pickerSettings = routesByName ? modelPickerSettingsFromRows(routedModelRows(readModels(paths) ?? {}, listProviders(paths).map((entry) => [entry.name, entry.provider]))) : selectedProvider === void 0 ? void 0 : modelPickerSettings(selectedProvider.definition, catalogue?.models);
9045
9332
  const callerSettings = hasSettingsArgument(parsedArgv.rest);
9046
9333
  if (pickerSettings !== void 0 && callerSettings) {
9047
9334
  notes.push("--settings was passed, so /model keeps Claude Code's own model names");
@@ -9174,7 +9461,8 @@ function prepareLaunch(params) {
9174
9461
  ...frontDoor === void 0 ? {} : { frontdoor: frontDoor },
9175
9462
  ...headroom === void 0 ? {} : { headroom },
9176
9463
  sessionId,
9177
- remoteControl: resolvedFlags.remoteControl
9464
+ remoteControl: resolvedFlags.remoteControl,
9465
+ routeByName: resolvedFlags.routeByName || resolvedProvider !== void 0 && isRouterProvider(resolvedProvider.definition)
9178
9466
  });
9179
9467
  const releases = [...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
9180
9468
  const release = () => {
@@ -9201,7 +9489,8 @@ function resolveLaunch(params) {
9201
9489
  ...frontDoor ? { frontdoor: { port: 0, connectPort: 0, trustBundlePath: "", sessionToken: "" } } : {},
9202
9490
  ...decided.flags.headroom ? { headroom: { socketPath: "", projectId: "" } } : {},
9203
9491
  sessionId: "",
9204
- remoteControl: decided.flags.remoteControl
9492
+ remoteControl: decided.flags.remoteControl,
9493
+ routeByName: decided.flags.routeByName
9205
9494
  });
9206
9495
  const credentialNames = decided.identityCredentialBlock === void 0 ? [] : Object.keys(credentialVariables(decided.identityCredentialBlock.target ?? "bearer", ""));
9207
9496
  const environment = [.../* @__PURE__ */ new Set([...Object.keys(built).filter((name) => built[name] !== env[name]), ...credentialNames])].sort();
@@ -9213,7 +9502,7 @@ function resolveLaunch(params) {
9213
9502
  bin: decided.bin,
9214
9503
  args: decided.args,
9215
9504
  ...credential === void 0 ? {} : { credential },
9216
- routing: { frontDoor, headroom: decided.flags.headroom },
9505
+ routing: { frontDoor, headroom: decided.flags.headroom, routeByName: decided.flags.routeByName },
9217
9506
  environment
9218
9507
  };
9219
9508
  }
@@ -9253,6 +9542,8 @@ var init_launcher = __esm({
9253
9542
  init_launchReport();
9254
9543
  init_modelPicker();
9255
9544
  init_providerCatalogue();
9545
+ init_modelsStore();
9546
+ init_providersStore();
9256
9547
  init_pool();
9257
9548
  init_resumeContext();
9258
9549
  init_lock();
@@ -13545,189 +13836,7 @@ function collectPoolPick(params) {
13545
13836
 
13546
13837
  // src/poolStore.ts
13547
13838
  init_cliError();
13548
-
13549
- // src/configProfilesStore.ts
13550
- init_store();
13551
- init_schema();
13552
- init_cliError();
13553
- init_load();
13554
- import fs4 from "node:fs";
13555
- import path22 from "node:path";
13556
- var ProfileNotFoundError = class extends CliError {
13557
- constructor(profileName) {
13558
- super(`No configuration profile named "${profileName}". Run \`agent-shim profile add ${profileName}\` first.`);
13559
- this.profileName = profileName;
13560
- this.name = "ProfileNotFoundError";
13561
- }
13562
- profileName;
13563
- };
13564
- var ProfileAlreadyExistsError = class extends CliError {
13565
- constructor(profileName) {
13566
- super(`A configuration profile named "${profileName}" already exists.`);
13567
- this.profileName = profileName;
13568
- this.name = "ProfileAlreadyExistsError";
13569
- }
13570
- profileName;
13571
- };
13572
- var InvalidCategoryNameError = class extends CliError {
13573
- constructor(categoryName) {
13574
- super(`"${categoryName}" is not a category a configuration profile may toggle (runtime, history, knowledge, settings).`);
13575
- this.categoryName = categoryName;
13576
- this.name = "InvalidCategoryNameError";
13577
- }
13578
- categoryName;
13579
- };
13580
- function profileJsonPath(paths, name) {
13581
- return path22.join(paths.configProfilesDir, `${name}.json`);
13582
- }
13583
- function profileExists(paths, name) {
13584
- return fs4.existsSync(profileJsonPath(paths, name));
13585
- }
13586
- function requireProfileExists(paths, name) {
13587
- if (!profileExists(paths, name)) {
13588
- throw new ProfileNotFoundError(name);
13589
- }
13590
- }
13591
- function readProfile(paths, name) {
13592
- return readJson(profileJsonPath(paths, name), ConfigProfileSchema);
13593
- }
13594
- function createProfile(paths, name, extendsList, description) {
13595
- if (profileExists(paths, name)) {
13596
- throw new ProfileAlreadyExistsError(name);
13597
- }
13598
- const filePath = profileJsonPath(paths, name);
13599
- const parsed = ConfigProfileSchema.safeParse({
13600
- ...description === void 0 ? {} : { description },
13601
- ...extendsList !== void 0 && extendsList.length > 0 ? { extends: [...extendsList] } : {}
13602
- });
13603
- if (!parsed.success) {
13604
- throw new ConfigValidationError(filePath, parsed.error.issues);
13605
- }
13606
- writeJsonAtomic(filePath, parsed.data);
13607
- return parsed.data;
13608
- }
13609
- function listProfiles(paths) {
13610
- if (!fs4.existsSync(paths.configProfilesDir)) {
13611
- return [];
13612
- }
13613
- const names = fs4.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort();
13614
- const result = [];
13615
- for (const name of names) {
13616
- const profile = readProfile(paths, name);
13617
- if (profile !== void 0) {
13618
- result.push({ name, profile });
13619
- }
13620
- }
13621
- return result;
13622
- }
13623
- function globalConfigPath(paths) {
13624
- return paths.globalConfigFile;
13625
- }
13626
- function readGlobalConfig(paths) {
13627
- return readJson(globalConfigPath(paths), GlobalConfigSchema);
13628
- }
13629
- function setGlobalDefaultProfile(paths, name) {
13630
- return applyPatch(
13631
- globalConfigPath(paths),
13632
- GlobalConfigSchema,
13633
- { defaultConfigProfile: name },
13634
- { defaults: {} }
13635
- );
13636
- }
13637
- function validateCategoryNames(patch) {
13638
- for (const key of Object.keys(patch)) {
13639
- if (!isOverridableCategory(key)) {
13640
- throw new InvalidCategoryNameError(key);
13641
- }
13642
- }
13643
- }
13644
- function setProfileCategories(paths, name, patch) {
13645
- requireProfileExists(paths, name);
13646
- const expandedPatch = expandAllCategoryKey(patch);
13647
- validateCategoryNames(expandedPatch);
13648
- const existing = readProfile(paths, name) ?? {};
13649
- const mergedCategories = { ...existing.categories, ...expandedPatch };
13650
- return applyPatch(profileJsonPath(paths, name), ConfigProfileSchema, { categories: mergedCategories });
13651
- }
13652
- function setProfileEntries(paths, name, patch) {
13653
- requireProfileExists(paths, name);
13654
- const existing = readProfile(paths, name) ?? {};
13655
- const mergedEntries = { ...existing.entries, ...patch };
13656
- return applyPatch(profileJsonPath(paths, name), ConfigProfileSchema, { entries: mergedEntries });
13657
- }
13658
- function setProfileLaunchFlags(paths, name, patch) {
13659
- requireProfileExists(paths, name);
13660
- const existing = readProfile(paths, name) ?? {};
13661
- const mergedLaunch = { ...existing.launch, ...patch };
13662
- return applyPatch(profileJsonPath(paths, name), ConfigProfileSchema, {
13663
- // Read as `unknown` so the check sees the `undefined` a cleared key holds, which LaunchFlags' optional properties hide from the value type.
13664
- launch: Object.values(mergedLaunch).every((value) => value === void 0) ? void 0 : mergedLaunch
13665
- });
13666
- }
13667
- function setProfileMetadata(paths, name, patch) {
13668
- requireProfileExists(paths, name);
13669
- return applyPatch(profileJsonPath(paths, name), ConfigProfileSchema, {
13670
- ...patch.extends === void 0 ? {} : { extends: patch.extends.length === 0 ? void 0 : [...patch.extends] },
13671
- ...patch.description === void 0 ? {} : { description: patch.description === false ? void 0 : patch.description }
13672
- });
13673
- }
13674
- function removeProfile(paths, name) {
13675
- requireProfileExists(paths, name);
13676
- fs4.rmSync(profileJsonPath(paths, name));
13677
- }
13678
- function applyProfileChange(paths, name, change) {
13679
- let touched = false;
13680
- if (change.category !== void 0) {
13681
- setProfileCategories(paths, name, change.category);
13682
- touched = true;
13683
- }
13684
- if (change.entry !== void 0) {
13685
- setProfileEntries(paths, name, change.entry);
13686
- touched = true;
13687
- }
13688
- if (change.extends !== void 0 || change.description !== void 0) {
13689
- setProfileMetadata(paths, name, {
13690
- ...change.extends === void 0 ? {} : { extends: change.extends === false ? [] : change.extends },
13691
- ...change.description === void 0 ? {} : { description: change.description }
13692
- });
13693
- touched = true;
13694
- }
13695
- const launchPatch = {};
13696
- if (change.launchSkipPermissions !== void 0) {
13697
- launchPatch.skipPermissions = change.launchSkipPermissions;
13698
- }
13699
- if (change.launchRemoteControl !== void 0) {
13700
- launchPatch.remoteControl = change.launchRemoteControl;
13701
- }
13702
- if (change.launchHeadroom !== void 0) {
13703
- launchPatch.headroom = change.launchHeadroom;
13704
- }
13705
- if (change.launchTrackUsage !== void 0) {
13706
- launchPatch.trackUsage = change.launchTrackUsage;
13707
- }
13708
- if (change.launchProvider !== void 0) {
13709
- launchPatch.provider = change.launchProvider === false ? void 0 : change.launchProvider;
13710
- }
13711
- if (change.launchClaudeVersion !== void 0) {
13712
- launchPatch.claudeVersion = change.launchClaudeVersion === false ? void 0 : change.launchClaudeVersion;
13713
- }
13714
- if (change.launchDelay !== void 0) {
13715
- launchPatch.delay = change.launchDelay === false ? void 0 : change.launchDelay;
13716
- }
13717
- if (change.launchPause !== void 0) {
13718
- launchPatch.pause = change.launchPause;
13719
- }
13720
- if (change.launchExplain !== void 0) {
13721
- launchPatch.explain = change.launchExplain;
13722
- }
13723
- if (Object.keys(launchPatch).length > 0) {
13724
- setProfileLaunchFlags(paths, name, launchPatch);
13725
- touched = true;
13726
- }
13727
- return touched;
13728
- }
13729
-
13730
- // src/poolStore.ts
13839
+ init_configProfilesStore();
13731
13840
  init_store();
13732
13841
  init_schema();
13733
13842
  init_identity();
@@ -14808,53 +14917,8 @@ init_credentialCache();
14808
14917
  init_realCredentialCache();
14809
14918
  init_source();
14810
14919
 
14811
- // src/modelsStore.ts
14812
- init_store();
14813
- init_schema();
14814
- var VirtualModelNotFoundError = class extends Error {
14815
- constructor(name) {
14816
- super(`No virtual model named "${name}".`);
14817
- this.name = "VirtualModelNotFoundError";
14818
- }
14819
- };
14820
- function memberKindOf(ref, models) {
14821
- if (ref.startsWith("acct:")) {
14822
- return "account";
14823
- }
14824
- if (ref.startsWith("family:")) {
14825
- return "family";
14826
- }
14827
- return models?.virtual !== void 0 && ref in models.virtual ? "virtual" : "provider";
14828
- }
14829
- function expandMembers(name, models) {
14830
- const virtual = models?.virtual ?? {};
14831
- const expanded = [];
14832
- const walk = (current, chain) => {
14833
- const nested = virtual[current];
14834
- if (nested !== void 0) {
14835
- if (chain.includes(current)) {
14836
- throw new Error(`virtual model cycle: ${[...chain, current].join(" -> ")}`);
14837
- }
14838
- for (const member of nested.members) {
14839
- walk(member, [...chain, current]);
14840
- }
14841
- return;
14842
- }
14843
- if (!expanded.includes(current)) {
14844
- expanded.push(current);
14845
- }
14846
- };
14847
- const top = virtual[name];
14848
- if (top === void 0) {
14849
- throw new VirtualModelNotFoundError(name);
14850
- }
14851
- for (const member of top.members) {
14852
- walk(member, [name]);
14853
- }
14854
- return expanded;
14855
- }
14856
-
14857
14920
  // src/models/doctor.ts
14921
+ init_modelsStore();
14858
14922
  function modelsFindings(input) {
14859
14923
  const findings = [];
14860
14924
  const { models } = input;
@@ -14909,6 +14973,9 @@ function modelsFindings(input) {
14909
14973
  return findings;
14910
14974
  }
14911
14975
 
14976
+ // src/doctorReport.ts
14977
+ init_configProfilesStore();
14978
+
14912
14979
  // src/headroom/allowlistDrift.ts
14913
14980
  init_earlierRelease();
14914
14981
  init_state2();
@@ -15849,9 +15916,10 @@ function createCodexApiRouter(deps) {
15849
15916
  // src/frontdoor/configApi.ts
15850
15917
  init_cliError();
15851
15918
  init_schema();
15919
+ init_configProfilesStore();
15920
+ init_credential();
15852
15921
  import { ORPCError as ORPCError2 } from "@orpc/client";
15853
15922
  import { openapi as openapi3 } from "@orpc/openapi";
15854
- init_credential();
15855
15923
 
15856
15924
  // src/credentialCacheChange.ts
15857
15925
  init_cliError();
@@ -16059,7 +16127,8 @@ var ConfigProfileSetInputSchema = z24.strictObject({
16059
16127
  claudeVersion: z24.union([z24.string().min(1), z24.literal(false)]).optional(),
16060
16128
  delay: z24.union([z24.string().regex(DURATION_RE), z24.literal(false)]).optional(),
16061
16129
  pause: z24.boolean().optional(),
16062
- explain: z24.boolean().optional()
16130
+ explain: z24.boolean().optional(),
16131
+ routeByName: z24.boolean().optional()
16063
16132
  }).optional()
16064
16133
  });
16065
16134
  var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
@@ -16271,7 +16340,8 @@ function createConfigApiRouter(deps) {
16271
16340
  ...launch?.claudeVersion === void 0 ? {} : { launchClaudeVersion: launch.claudeVersion },
16272
16341
  ...launch?.delay === void 0 ? {} : { launchDelay: launch.delay },
16273
16342
  ...launch?.pause === void 0 ? {} : { launchPause: launch.pause },
16274
- ...launch?.explain === void 0 ? {} : { launchExplain: launch.explain }
16343
+ ...launch?.explain === void 0 ? {} : { launchExplain: launch.explain },
16344
+ ...launch?.routeByName === void 0 ? {} : { launchRouteByName: launch.routeByName }
16275
16345
  });
16276
16346
  return { action: "updated", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
16277
16347
  })
@@ -16582,6 +16652,7 @@ var LaunchFlagsSchema = z26.strictObject({
16582
16652
  trackUsage: z26.boolean(),
16583
16653
  pause: z26.boolean(),
16584
16654
  explain: z26.boolean(),
16655
+ routeByName: z26.boolean(),
16585
16656
  /** How long the launch waits after its own output before it starts claude, in milliseconds. */
16586
16657
  delayMs: z26.number()
16587
16658
  });
@@ -16595,7 +16666,7 @@ var LaunchResolveOutputSchema = z26.strictObject({
16595
16666
  args: z26.readonly(z26.array(z26.string())),
16596
16667
  /** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
16597
16668
  credential: z26.strictObject({ subject: z26.enum(["provider", "identity"]), name: z26.string(), summary: CredentialSummarySchema }).optional(),
16598
- routing: z26.strictObject({ frontDoor: z26.boolean(), headroom: z26.boolean() }),
16669
+ routing: z26.strictObject({ frontDoor: z26.boolean(), headroom: z26.boolean(), routeByName: z26.boolean() }),
16599
16670
  /** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
16600
16671
  environment: z26.readonly(z26.array(z26.string())),
16601
16672
  warnings: z26.readonly(z26.array(z26.string()))
@@ -19226,6 +19297,7 @@ init_guard();
19226
19297
  init_paths();
19227
19298
  init_cliError();
19228
19299
  init_schema();
19300
+ init_configProfilesStore();
19229
19301
  init_providersStore();
19230
19302
  init_launcher();
19231
19303
  init_spawn();