claude-use 9.6.0 → 9.7.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/cli.cjs CHANGED
@@ -26769,7 +26769,7 @@ function isCodexProvider(provider) {
26769
26769
  function poolMemberIdentity(member) {
26770
26770
  return typeof member === "string" ? member : member.identity;
26771
26771
  }
26772
- 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, CredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, CODEX_TIERS, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_LOGIN, CODEX_DEFAULT_MODEL, CODEX_DEFAULT_TIER_MODELS, CODEX_DEFAULT_EFFORT, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, 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;
26772
+ 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, CODEX_TIERS, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_LOGIN, CODEX_DEFAULT_MODEL, CODEX_DEFAULT_TIER_MODELS, CODEX_DEFAULT_EFFORT, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, 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;
26773
26773
  var init_schema = __esm({
26774
26774
  "src/config/schema.ts"() {
26775
26775
  "use strict";
@@ -26825,20 +26825,33 @@ var init_schema = __esm({
26825
26825
  /** How long the command may run before it is killed and counted as failed. Defaults to `CREDENTIAL_COMMAND_TIMEOUT_MS`, or `CREDENTIAL_INTERACTIVE_TIMEOUT_MS` for an interactive source. */
26826
26826
  timeoutMs: external_exports.int().positive().optional()
26827
26827
  };
26828
+ EnvCredentialSourceSchema = external_exports.strictObject({ env: external_exports.string().min(1) });
26829
+ FileCredentialSourceSchema = external_exports.strictObject({
26830
+ file: external_exports.string().min(1).refine((filePath) => filePath.startsWith("~/") || import_node_path4.default.isAbsolute(filePath), {
26831
+ message: "a credential file must be an absolute or ~-rooted path, since a launch can start in any directory"
26832
+ })
26833
+ });
26834
+ CommandCredentialSourceSchema = external_exports.strictObject({ command: ArgvSchema, ...CommandSourceOptions });
26835
+ OpCredentialSourceSchema = external_exports.strictObject({ op: external_exports.string().startsWith("op://"), ...CommandSourceOptions });
26836
+ KeychainCredentialSourceSchema = external_exports.strictObject({
26837
+ keychain: external_exports.strictObject({ service: external_exports.string().min(1), account: external_exports.string().min(1).optional() }),
26838
+ ...CommandSourceOptions
26839
+ });
26840
+ LiteralCredentialSourceSchema = external_exports.strictObject({ literal: external_exports.string().min(1) });
26828
26841
  CredentialSourceSchema = external_exports.union([
26829
- external_exports.strictObject({ env: external_exports.string().min(1) }),
26830
- external_exports.strictObject({
26831
- file: external_exports.string().min(1).refine((filePath) => filePath.startsWith("~/") || import_node_path4.default.isAbsolute(filePath), {
26832
- message: "a credential file must be an absolute or ~-rooted path, since a launch can start in any directory"
26833
- })
26834
- }),
26835
- external_exports.strictObject({ command: ArgvSchema, ...CommandSourceOptions }),
26836
- external_exports.strictObject({ op: external_exports.string().startsWith("op://"), ...CommandSourceOptions }),
26837
- external_exports.strictObject({
26838
- keychain: external_exports.strictObject({ service: external_exports.string().min(1), account: external_exports.string().min(1).optional() }),
26839
- ...CommandSourceOptions
26840
- }),
26841
- external_exports.strictObject({ literal: external_exports.string().min(1) })
26842
+ EnvCredentialSourceSchema,
26843
+ FileCredentialSourceSchema,
26844
+ CommandCredentialSourceSchema,
26845
+ OpCredentialSourceSchema,
26846
+ KeychainCredentialSourceSchema,
26847
+ LiteralCredentialSourceSchema
26848
+ ]);
26849
+ RemoteCredentialSourceSchema = external_exports.union([
26850
+ EnvCredentialSourceSchema,
26851
+ FileCredentialSourceSchema,
26852
+ OpCredentialSourceSchema,
26853
+ KeychainCredentialSourceSchema,
26854
+ LiteralCredentialSourceSchema
26842
26855
  ]);
26843
26856
  CREDENTIAL_CACHE_STORES = ["keychain", "file"];
26844
26857
  CredentialCacheSchema = external_exports.strictObject({
@@ -27454,8 +27467,8 @@ function verifyHeadroomSocket(socketPath, ports) {
27454
27467
  }
27455
27468
  const uid = ports.currentUid();
27456
27469
  const directory = import_node_path7.default.dirname(socketPath);
27457
- const refusal = ownerOnlyRefusal("socket directory", directory, ports.lstat(directory), "dir", uid) ?? ownerOnlyRefusal("socket", socketPath, ports.lstat(socketPath), "socket", uid);
27458
- return refusal === void 0 ? { socketPath } : { refused: refusal };
27470
+ const refusal2 = ownerOnlyRefusal("socket directory", directory, ports.lstat(directory), "dir", uid) ?? ownerOnlyRefusal("socket", socketPath, ports.lstat(socketPath), "socket", uid);
27471
+ return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
27459
27472
  }
27460
27473
  function prepareHeadroomSocket(fs21, ports, paths, supervisorPid) {
27461
27474
  const unsupported = platformRefusal(ports.platform);
@@ -27473,8 +27486,8 @@ function prepareHeadroomSocket(fs21, ports, paths, supervisorPid) {
27473
27486
  return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
27474
27487
  }
27475
27488
  fs21.mkdirPrivate(paths.headroomSocketDir);
27476
- const refusal = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
27477
- return refusal === void 0 ? { socketPath } : { refused: refusal };
27489
+ const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
27490
+ return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
27478
27491
  }
27479
27492
  function pruneStaleHeadroomSockets(fs21, paths, isRunning) {
27480
27493
  const removed = [];
@@ -33229,7 +33242,7 @@ var init_package = __esm({
33229
33242
  "package.json"() {
33230
33243
  package_default = {
33231
33244
  name: "claude-use",
33232
- version: "9.6.0",
33245
+ version: "9.7.0",
33233
33246
  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.",
33234
33247
  license: "MIT",
33235
33248
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -34028,14 +34041,14 @@ function capacityOf(plan) {
34028
34041
  return plan.kind === "subscription" ? plan.capacity : 1;
34029
34042
  }
34030
34043
  function assessRefusedNested(member, nested, nowMs) {
34031
- const refusal = nested.earliestReturn === void 0 ? { reason: `no member of pool "${nested.pool}" can be picked` } : { reason: `every member of pool "${nested.pool}" is refused; ${nested.earliestReturn.identity} returns at ${new Date(nested.earliestReturn.atMs).toISOString()} (in ${formatAge(nested.earliestReturn.atMs - nowMs)})`, blockedUntilMs: nested.earliestReturn.atMs };
34044
+ const refusal2 = nested.earliestReturn === void 0 ? { reason: `no member of pool "${nested.pool}" can be picked` } : { reason: `every member of pool "${nested.pool}" is refused; ${nested.earliestReturn.identity} returns at ${new Date(nested.earliestReturn.atMs).toISOString()} (in ${formatAge(nested.earliestReturn.atMs - nowMs)})`, blockedUntilMs: nested.earliestReturn.atMs };
34032
34045
  return {
34033
34046
  candidate: {
34034
34047
  identity: member.identity,
34035
34048
  class: "ineligible",
34036
- ...refusal.blockedUntilMs === void 0 ? {} : { blockedUntilMs: refusal.blockedUntilMs },
34049
+ ...refusal2.blockedUntilMs === void 0 ? {} : { blockedUntilMs: refusal2.blockedUntilMs },
34037
34050
  plan: planOf(member.account),
34038
- reasons: [refusal.reason]
34051
+ reasons: [refusal2.reason]
34039
34052
  }
34040
34053
  };
34041
34054
  }
@@ -34126,7 +34139,7 @@ function rankPool(input2) {
34126
34139
  const assessments = members2.map((member) => ({ member, ...assess(member, nowMs) }));
34127
34140
  const demands = assessments.flatMap(({ candidate, burn }) => burn === void 0 ? [] : [burn * capacityOf(candidate.plan)]);
34128
34141
  const sharedDemand = demands.length === 0 ? void 0 : Math.max(...demands);
34129
- const guarded = assessments.map((assessment) => {
34142
+ const guarded2 = assessments.map((assessment) => {
34130
34143
  const { candidate } = assessment;
34131
34144
  if (candidate.class === "ineligible" || assessment.member.policy === void 0) {
34132
34145
  return assessment;
@@ -34141,7 +34154,7 @@ function rankPool(input2) {
34141
34154
  }
34142
34155
  return { ...assessment, candidate: { ...candidate, class: "ineligible", reasons: [`skipped by policy (${verdict.checked.join(", ")}: did not hold)`, ...candidate.reasons] } };
34143
34156
  });
34144
- const candidates = guarded.map((assessment) => {
34157
+ const candidates = guarded2.map((assessment) => {
34145
34158
  const { candidate, fiveHour, burn } = assessment;
34146
34159
  const pace = burn ?? (sharedDemand === void 0 ? void 0 : sharedDemand / capacityOf(candidate.plan));
34147
34160
  const { sevenDay, sevenDayBurn } = assessment;
@@ -108445,6 +108458,48 @@ function removeProfile(paths, name) {
108445
108458
  requireProfileExists(paths, name);
108446
108459
  import_node_fs5.default.rmSync(profileJsonPath(paths, name));
108447
108460
  }
108461
+ function applyProfileChange(paths, name, change) {
108462
+ let touched = false;
108463
+ if (change.category !== void 0) {
108464
+ setProfileCategories(paths, name, change.category);
108465
+ touched = true;
108466
+ }
108467
+ if (change.entry !== void 0) {
108468
+ setProfileEntries(paths, name, change.entry);
108469
+ touched = true;
108470
+ }
108471
+ if (change.extends !== void 0 || change.description !== void 0) {
108472
+ setProfileMetadata(paths, name, {
108473
+ ...change.extends === void 0 ? {} : { extends: change.extends === false ? [] : change.extends },
108474
+ ...change.description === void 0 ? {} : { description: change.description }
108475
+ });
108476
+ touched = true;
108477
+ }
108478
+ const launchPatch = {};
108479
+ if (change.launchSkipPermissions !== void 0) {
108480
+ launchPatch.skipPermissions = change.launchSkipPermissions;
108481
+ }
108482
+ if (change.launchRemoteControl !== void 0) {
108483
+ launchPatch.remoteControl = change.launchRemoteControl;
108484
+ }
108485
+ if (change.launchHeadroom !== void 0) {
108486
+ launchPatch.headroom = change.launchHeadroom;
108487
+ }
108488
+ if (change.launchTrackUsage !== void 0) {
108489
+ launchPatch.trackUsage = change.launchTrackUsage;
108490
+ }
108491
+ if (change.launchProvider !== void 0) {
108492
+ launchPatch.provider = change.launchProvider === false ? void 0 : change.launchProvider;
108493
+ }
108494
+ if (change.launchClaudeVersion !== void 0) {
108495
+ launchPatch.claudeVersion = change.launchClaudeVersion === false ? void 0 : change.launchClaudeVersion;
108496
+ }
108497
+ if (Object.keys(launchPatch).length > 0) {
108498
+ setProfileLaunchFlags(paths, name, launchPatch);
108499
+ touched = true;
108500
+ }
108501
+ return touched;
108502
+ }
108448
108503
 
108449
108504
  // src/poolStore.ts
108450
108505
  init_store();
@@ -108579,6 +108634,14 @@ var InvalidIdentityNameError = class extends CliError {
108579
108634
  function identityJsonPath(paths, name) {
108580
108635
  return import_node_path13.default.join(paths.identitiesDir, name, "identity.json");
108581
108636
  }
108637
+ function requireIdentityNames(paths, names) {
108638
+ const existing = new Set(listIdentities(paths).map((entry) => entry.name));
108639
+ for (const name of names) {
108640
+ if (poolNameOf(name) === void 0 && !existing.has(name)) {
108641
+ throw new IdentityNotFoundError(name);
108642
+ }
108643
+ }
108644
+ }
108582
108645
  function identityExists(paths, name) {
108583
108646
  return import_node_fs6.default.existsSync(identityJsonPath(paths, name));
108584
108647
  }
@@ -108787,6 +108850,16 @@ function removeDirectoryRule(paths, rulePath) {
108787
108850
  }
108788
108851
  writeDirectoryRules(paths, { ...current, rules: nextRules });
108789
108852
  }
108853
+ function requireRuleSelector(paths, selector) {
108854
+ if (selector.startsWith(POOL_SELECTOR_PREFIX)) {
108855
+ const poolName = selector.slice(POOL_SELECTOR_PREFIX.length);
108856
+ if (readPools(paths)[poolName] === void 0) {
108857
+ throw new PoolNotFoundError(poolName);
108858
+ }
108859
+ } else if (readIdentity(paths, selector) === void 0) {
108860
+ throw new IdentityNotFoundError(selector);
108861
+ }
108862
+ }
108790
108863
 
108791
108864
  // src/configure.ts
108792
108865
  init_legacy();
@@ -109318,7 +109391,31 @@ var import_node_path22 = __toESM(require("node:path"), 1);
109318
109391
  init_commandDeps();
109319
109392
 
109320
109393
  // src/cli/credentialOption.ts
109394
+ init_cliError();
109395
+ init_schema();
109396
+
109397
+ // src/credentialCacheChange.ts
109398
+ init_cliError();
109321
109399
  init_schema();
109400
+ function mergeCredentialCache(request7, existing) {
109401
+ if (request7.enabled === false) {
109402
+ return false;
109403
+ }
109404
+ if (request7.ttl === void 0 && request7.store === void 0 && request7.enabled !== true) {
109405
+ return void 0;
109406
+ }
109407
+ const parsed = CredentialCacheSchema.safeParse({
109408
+ ...existing,
109409
+ ...request7.ttl === void 0 ? {} : { ttl: request7.ttl },
109410
+ ...request7.store === void 0 ? {} : { store: request7.store }
109411
+ });
109412
+ if (!parsed.success) {
109413
+ throw new UsageError(parsed.error.issues.map((issue2) => issue2.message).join("; "));
109414
+ }
109415
+ return parsed.data;
109416
+ }
109417
+
109418
+ // src/cli/credentialOption.ts
109322
109419
  var CREDENTIAL_SOURCE_SYNTAX = "env:<VAR>, file:<path>, command:<program and arguments>, op:<op://reference>, keychain:<service>[:<account>], literal:<placeholder>, or a JSON source object";
109323
109420
  function parseCredentialSource(spec) {
109324
109421
  let candidate;
@@ -109373,21 +109470,18 @@ function addCredentialCacheOptions(command) {
109373
109470
  ).option("--credential-cache", "Cache this credential in the default store with no expiry (add --credential-cache-ttl for one).").option("--no-credential-cache", "Stop caching this credential. Run `credential forget` first to drop the stored copy.");
109374
109471
  }
109375
109472
  function cacheChange(options, existing) {
109376
- if (options.credentialCache === false) {
109377
- return false;
109378
- }
109379
- if (options.credentialCacheTtl === void 0 && options.credentialCacheStore === void 0 && options.credentialCache !== true) {
109380
- return void 0;
109381
- }
109382
- const parsed = CredentialCacheSchema.safeParse({
109383
- ...existing,
109384
- ...options.credentialCacheTtl === void 0 ? {} : { ttl: options.credentialCacheTtl },
109385
- ...options.credentialCacheStore === void 0 ? {} : { store: options.credentialCacheStore }
109386
- });
109387
- if (!parsed.success) {
109388
- throw new InvalidArgumentError(parsed.error.issues.map((issue2) => issue2.message).join("; "));
109473
+ try {
109474
+ return mergeCredentialCache(
109475
+ {
109476
+ ...options.credentialCache === void 0 ? {} : { enabled: options.credentialCache },
109477
+ ...options.credentialCacheTtl === void 0 ? {} : { ttl: options.credentialCacheTtl },
109478
+ ...options.credentialCacheStore === void 0 ? {} : { store: options.credentialCacheStore }
109479
+ },
109480
+ existing
109481
+ );
109482
+ } catch (error63) {
109483
+ throw error63 instanceof UsageError ? new InvalidArgumentError(error63.message) : error63;
109389
109484
  }
109390
- return parsed.data;
109391
109485
  }
109392
109486
 
109393
109487
  // src/identityManager.ts
@@ -109502,48 +109596,6 @@ async function ensureProfileExists(deps, name) {
109502
109596
  function toProfileView(name, profile, globalDefault) {
109503
109597
  return { name, globalDefault: name === globalDefault, ...profile, $schema: void 0 };
109504
109598
  }
109505
- function applyProfileSet(paths, name, options) {
109506
- let touched = false;
109507
- if (options.category !== void 0) {
109508
- setProfileCategories(paths, name, options.category);
109509
- touched = true;
109510
- }
109511
- if (options.entry !== void 0) {
109512
- setProfileEntries(paths, name, options.entry);
109513
- touched = true;
109514
- }
109515
- if (options.extends !== void 0 || options.description !== void 0) {
109516
- setProfileMetadata(paths, name, {
109517
- ...options.extends === void 0 ? {} : { extends: options.extends === false ? [] : options.extends },
109518
- ...options.description === void 0 ? {} : { description: options.description }
109519
- });
109520
- touched = true;
109521
- }
109522
- const launchPatch = {};
109523
- if (options.launchSkipPermissions !== void 0) {
109524
- launchPatch.skipPermissions = options.launchSkipPermissions;
109525
- }
109526
- if (options.launchRemoteControl !== void 0) {
109527
- launchPatch.remoteControl = options.launchRemoteControl;
109528
- }
109529
- if (options.launchHeadroom !== void 0) {
109530
- launchPatch.headroom = options.launchHeadroom;
109531
- }
109532
- if (options.launchTrackUsage !== void 0) {
109533
- launchPatch.trackUsage = options.launchTrackUsage;
109534
- }
109535
- if (options.launchProvider !== void 0) {
109536
- launchPatch.provider = options.launchProvider === false ? void 0 : options.launchProvider;
109537
- }
109538
- if (options.launchClaudeVersion !== void 0) {
109539
- launchPatch.claudeVersion = options.launchClaudeVersion === false ? void 0 : options.launchClaudeVersion;
109540
- }
109541
- if (Object.keys(launchPatch).length > 0) {
109542
- setProfileLaunchFlags(paths, name, launchPatch);
109543
- touched = true;
109544
- }
109545
- return touched;
109546
- }
109547
109599
  function registerProfileCommand(program2, deps) {
109548
109600
  const { paths } = deps;
109549
109601
  const profile = withExamples(
@@ -109592,7 +109644,7 @@ function registerProfileCommand(program2, deps) {
109592
109644
  throw new PromptCancelledError();
109593
109645
  }
109594
109646
  } else {
109595
- applyProfileSet(paths, name, options);
109647
+ applyProfileChange(paths, name, options);
109596
109648
  }
109597
109649
  reportMutation(json2, { action: "updated", kind: "profile", name, value: readProfile(paths, name) }, () => {
109598
109650
  console.log(`Updated configuration profile "${name}".`);
@@ -110892,6 +110944,7 @@ var HTTP_STATUS = {
110892
110944
  forbidden: 403,
110893
110945
  notFound: 404,
110894
110946
  methodNotAllowed: 405,
110947
+ conflict: 409,
110895
110948
  payloadTooLarge: 413,
110896
110949
  tooManyRequests: 429,
110897
110950
  /** Not sent to anyone: the client is gone. Recorded for a response abandoned because the client disconnected, following the convention nginx uses for the same case. */
@@ -122911,9 +122964,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
122911
122964
  if (request7.method === "GET" && request7.url === `${RC_ORPC_PATH_PREFIX}${RC_OPENAPI_DOC_PATH}`) {
122912
122965
  const token = doorApiBearer(request7.headers);
122913
122966
  if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
122914
- const refusal = new ORPCError("UNAUTHORIZED", { message: "the front door's OpenAPI document demands this generation's control token as a Bearer credential" });
122967
+ const refusal2 = new ORPCError("UNAUTHORIZED", { message: "the front door's OpenAPI document demands this generation's control token as a Bearer credential" });
122915
122968
  response.writeHead(HTTP_STATUS.unauthorized, { "content-type": "application/json" });
122916
- response.end(JSON.stringify(refusal.toJSON()));
122969
+ response.end(JSON.stringify(refusal2.toJSON()));
122917
122970
  return { matched: true };
122918
122971
  }
122919
122972
  try {
@@ -122921,9 +122974,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
122921
122974
  response.writeHead(HTTP_STATUS.ok, { "content-type": "application/json" });
122922
122975
  response.end(JSON.stringify(doc));
122923
122976
  } catch (error63) {
122924
- const refusal = new ORPCError("INTERNAL_SERVER_ERROR", { message: `the OpenAPI document could not be generated from the door's own router: ${error63 instanceof Error ? error63.message : String(error63)}` });
122977
+ const refusal2 = new ORPCError("INTERNAL_SERVER_ERROR", { message: `the OpenAPI document could not be generated from the door's own router: ${error63 instanceof Error ? error63.message : String(error63)}` });
122925
122978
  response.writeHead(HTTP_STATUS.internalServerError, { "content-type": "application/json" });
122926
- response.end(JSON.stringify(refusal.toJSON()));
122979
+ response.end(JSON.stringify(refusal2.toJSON()));
122927
122980
  }
122928
122981
  return { matched: true };
122929
122982
  }
@@ -122991,6 +123044,438 @@ function createCodexApiRouter(deps) {
122991
123044
  };
122992
123045
  }
122993
123046
 
123047
+ // src/frontdoor/configApi.ts
123048
+ init_cliError();
123049
+ init_schema();
123050
+ init_credential();
123051
+ init_identity();
123052
+ init_providersStore();
123053
+
123054
+ // src/frontdoor/configSchemas.ts
123055
+ init_zod();
123056
+ init_schema();
123057
+ var RemovalConfirmationSchema = external_exports.boolean();
123058
+ var CredentialWriteSchema = (targets) => external_exports.strictObject({
123059
+ sources: external_exports.array(RemoteCredentialSourceSchema).min(1).optional(),
123060
+ target: external_exports.enum(targets).optional(),
123061
+ cache: external_exports.union([external_exports.literal(false), CredentialCacheSchema]).optional()
123062
+ });
123063
+ var CredentialSummarySchema2 = external_exports.strictObject({
123064
+ target: external_exports.enum(CREDENTIAL_TARGETS),
123065
+ sources: external_exports.readonly(external_exports.array(
123066
+ external_exports.discriminatedUnion("kind", [
123067
+ external_exports.strictObject({ kind: external_exports.literal("env"), variable: external_exports.string() }),
123068
+ external_exports.strictObject({ kind: external_exports.literal("file"), path: external_exports.string() }),
123069
+ external_exports.strictObject({ kind: external_exports.literal("command"), program: external_exports.string() }),
123070
+ external_exports.strictObject({ kind: external_exports.literal("op"), reference: external_exports.string() }),
123071
+ external_exports.strictObject({ kind: external_exports.literal("keychain"), service: external_exports.string(), account: external_exports.string().optional() }),
123072
+ external_exports.strictObject({ kind: external_exports.literal("literal") })
123073
+ ])
123074
+ )),
123075
+ cache: CredentialCacheSchema.optional()
123076
+ });
123077
+ var mutationOutput = (kind, action) => external_exports.strictObject({ action: external_exports.literal(action), kind: external_exports.literal(kind), name: external_exports.string() });
123078
+ var storedMutationOutput = (kind, action, value2) => external_exports.strictObject({ action: external_exports.literal(action), kind: external_exports.literal(kind), name: external_exports.string(), value: value2 });
123079
+ var IdentityValueSchema = external_exports.strictObject({
123080
+ name: external_exports.string(),
123081
+ defaultConfigProfile: external_exports.string().optional(),
123082
+ allowAmbientCredential: external_exports.boolean(),
123083
+ credential: CredentialSummarySchema2.optional()
123084
+ });
123085
+ var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
123086
+ var ProviderValueSchema = external_exports.strictObject({
123087
+ name: external_exports.string(),
123088
+ kind: external_exports.enum(PROVIDER_KINDS),
123089
+ displayName: external_exports.string(),
123090
+ baseUrl: external_exports.string().optional(),
123091
+ codex: CodexProviderConfigSchema.optional(),
123092
+ credential: CredentialSummarySchema2,
123093
+ env: external_exports.record(external_exports.string(), external_exports.string()).optional()
123094
+ });
123095
+ var ConfigNameInputSchema = external_exports.strictObject({ name: external_exports.string().min(1) });
123096
+ var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created", IdentityValueSchema);
123097
+ var ConfigIdentitySetInputSchema = external_exports.strictObject({
123098
+ name: external_exports.string().min(1),
123099
+ defaultConfigProfile: external_exports.union([external_exports.string().min(1), external_exports.literal(false)]).optional(),
123100
+ allowAmbientCredential: external_exports.boolean().optional(),
123101
+ credential: external_exports.union([external_exports.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional()
123102
+ });
123103
+ var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
123104
+ var ConfigIdentityRemoveInputSchema = external_exports.strictObject({ name: external_exports.string().min(1), confirm: RemovalConfirmationSchema });
123105
+ var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
123106
+ var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
123107
+ var ConfigProfileAddInputSchema = external_exports.strictObject({
123108
+ name: external_exports.string().min(1),
123109
+ extends: external_exports.array(external_exports.string().min(1)).optional(),
123110
+ description: external_exports.string().optional()
123111
+ });
123112
+ var ConfigProfileAddOutputSchema = storedMutationOutput("profile", "created", ProfileValueSchema);
123113
+ var ConfigProfileSetInputSchema = external_exports.strictObject({
123114
+ name: external_exports.string().min(1),
123115
+ category: external_exports.record(external_exports.string(), external_exports.boolean()).optional(),
123116
+ entry: external_exports.record(external_exports.string(), external_exports.boolean()).optional(),
123117
+ extends: external_exports.union([external_exports.array(external_exports.string().min(1)), external_exports.literal(false)]).optional(),
123118
+ description: external_exports.union([external_exports.string(), external_exports.literal(false)]).optional(),
123119
+ launch: external_exports.strictObject({
123120
+ skipPermissions: external_exports.boolean().optional(),
123121
+ remoteControl: external_exports.boolean().optional(),
123122
+ headroom: external_exports.boolean().optional(),
123123
+ trackUsage: external_exports.boolean().optional(),
123124
+ provider: external_exports.union([external_exports.string().min(1), external_exports.literal(false)]).optional(),
123125
+ claudeVersion: external_exports.union([external_exports.string().min(1), external_exports.literal(false)]).optional()
123126
+ }).optional()
123127
+ });
123128
+ var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
123129
+ var ConfigProfileRemoveInputSchema = external_exports.strictObject({ name: external_exports.string().min(1), confirm: RemovalConfirmationSchema });
123130
+ var ConfigProfileRemoveOutputSchema = mutationOutput("profile", "removed");
123131
+ var ConfigProfileUseOutputSchema = mutationOutput("profile", "selected");
123132
+ var PoolMembersInputSchema = external_exports.array(external_exports.string().min(1)).min(1);
123133
+ var ConfigPoolAddInputSchema = external_exports.strictObject({
123134
+ name: external_exports.string().min(1),
123135
+ identities: PoolMembersInputSchema,
123136
+ preference: external_exports.enum(POOL_PREFERENCES).optional()
123137
+ });
123138
+ var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
123139
+ var ConfigPoolSetInputSchema = external_exports.strictObject({
123140
+ name: external_exports.string().min(1),
123141
+ identities: PoolMembersInputSchema.optional(),
123142
+ preference: external_exports.union([external_exports.enum(POOL_PREFERENCES), external_exports.literal(false)]).optional()
123143
+ });
123144
+ var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
123145
+ var ConfigPoolRemoveInputSchema = external_exports.strictObject({ name: external_exports.string().min(1), confirm: RemovalConfirmationSchema });
123146
+ var ConfigPoolRemoveOutputSchema = mutationOutput("pool", "removed");
123147
+ var ConfigPoolUseOutputSchema = mutationOutput("pool", "selected");
123148
+ var ConfigProviderAddInputSchema = external_exports.strictObject({
123149
+ name: external_exports.string().min(1),
123150
+ kind: external_exports.enum(PROVIDER_KINDS).optional(),
123151
+ displayName: external_exports.string().min(1),
123152
+ baseUrl: external_exports.string().min(1).optional(),
123153
+ credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).required({ sources: true }),
123154
+ codex: CodexProviderConfigSchema.optional()
123155
+ });
123156
+ var ConfigProviderAddOutputSchema = storedMutationOutput("provider", "created", ProviderValueSchema);
123157
+ var ConfigProviderSetInputSchema = external_exports.strictObject({
123158
+ name: external_exports.string().min(1),
123159
+ displayName: external_exports.string().min(1).optional(),
123160
+ baseUrl: external_exports.string().min(1).optional(),
123161
+ credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).optional(),
123162
+ codex: CodexProviderConfigSchema.optional()
123163
+ });
123164
+ var ConfigProviderSetOutputSchema = storedMutationOutput("provider", "updated", ProviderValueSchema);
123165
+ var ConfigProviderRemoveInputSchema = external_exports.strictObject({ name: external_exports.string().min(1), confirm: RemovalConfirmationSchema });
123166
+ var ConfigProviderRemoveOutputSchema = mutationOutput("provider", "removed");
123167
+ var ConfigRuleAddInputSchema = external_exports.strictObject({
123168
+ path: external_exports.string().min(1),
123169
+ configProfile: external_exports.string().min(1).optional(),
123170
+ identity: external_exports.string().min(1).optional()
123171
+ });
123172
+ var ConfigRuleAddOutputSchema = storedMutationOutput("rule", "created", DirectoryRuleSchema);
123173
+ var ConfigRuleSetInputSchema = external_exports.strictObject({
123174
+ path: external_exports.string().min(1),
123175
+ configProfile: external_exports.union([external_exports.string().min(1), external_exports.literal(false)]).optional(),
123176
+ identity: external_exports.union([external_exports.string().min(1), external_exports.literal(false)]).optional()
123177
+ });
123178
+ var ConfigRuleSetOutputSchema = storedMutationOutput("rule", "updated", DirectoryRuleSchema);
123179
+ var ConfigRuleRemoveInputSchema = external_exports.strictObject({ path: external_exports.string().min(1), confirm: RemovalConfirmationSchema });
123180
+ var ConfigRuleRemoveOutputSchema = mutationOutput("rule", "removed");
123181
+
123182
+ // src/frontdoor/configApi.ts
123183
+ var CONFIG_API_TAG = "config";
123184
+ function refusal(error63) {
123185
+ if (error63 instanceof IdentityNotFoundError || error63 instanceof ProfileNotFoundError || error63 instanceof PoolNotFoundError || error63 instanceof ProviderNotFoundError || error63 instanceof DirectoryRuleNotFoundError) {
123186
+ throw new ORPCError("NOT_FOUND", { message: error63.message });
123187
+ }
123188
+ if (error63 instanceof IdentityAlreadyExistsError || error63 instanceof ProfileAlreadyExistsError || error63 instanceof PoolAlreadyExistsError || error63 instanceof ProviderAlreadyExistsError || error63 instanceof DirectoryRuleAlreadyExistsError) {
123189
+ throw new ORPCError("CONFLICT", { message: error63.message });
123190
+ }
123191
+ if (error63 instanceof CliError) {
123192
+ throw new ORPCError("BAD_REQUEST", { message: error63.message });
123193
+ }
123194
+ throw error63;
123195
+ }
123196
+ function guarded(write) {
123197
+ try {
123198
+ return write();
123199
+ } catch (error63) {
123200
+ return refusal(error63);
123201
+ }
123202
+ }
123203
+ function requireConfirmation(confirm, what) {
123204
+ if (!confirm) {
123205
+ throw new ORPCError("BAD_REQUEST", { message: `removing ${what} needs confirm: true, the API's form of the CLI's --yes` });
123206
+ }
123207
+ }
123208
+ function requireChange(given, fields) {
123209
+ if (!given) {
123210
+ throw new ORPCError("BAD_REQUEST", { message: `Nothing to change: pass ${fields}.` });
123211
+ }
123212
+ }
123213
+ function identityValue(name, paths) {
123214
+ const identity = readIdentity(paths, name);
123215
+ if (identity === void 0) {
123216
+ throw new IdentityNotFoundError(name);
123217
+ }
123218
+ return {
123219
+ name: identity.name,
123220
+ ...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
123221
+ allowAmbientCredential: identity.allowAmbientCredential,
123222
+ ...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) }
123223
+ };
123224
+ }
123225
+ function providerValue(name, provider) {
123226
+ return {
123227
+ name,
123228
+ kind: provider.kind ?? "http",
123229
+ displayName: provider.displayName,
123230
+ ...isCodexProvider(provider) ? provider.codex === void 0 ? {} : { codex: provider.codex } : { baseUrl: provider.baseUrl },
123231
+ credential: summariseCredential(provider.credential),
123232
+ ...provider.env === void 0 ? {} : { env: provider.env }
123233
+ };
123234
+ }
123235
+ function profileValue(name, paths) {
123236
+ const profile = { ...readProfile(paths, name) };
123237
+ delete profile.$schema;
123238
+ return profile;
123239
+ }
123240
+ function createConfigApiRouter(deps) {
123241
+ const authed = doorApiAuth(deps.expectedToken);
123242
+ const { paths } = deps;
123243
+ const route = (path48, summary) => authed.meta(openapi({ method: "POST", path: path48, summary, tags: [CONFIG_API_TAG] }));
123244
+ return {
123245
+ config: {
123246
+ identity: {
123247
+ add: route("/rest/config/identity/add", "Create an identity").input(ConfigNameInputSchema).output(ConfigIdentityAddOutputSchema).handler(
123248
+ ({ input: input2 }) => guarded(() => {
123249
+ addIdentity(paths, input2.name);
123250
+ return { action: "created", kind: "identity", name: input2.name, value: identityValue(input2.name, paths) };
123251
+ })
123252
+ ),
123253
+ set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting or credential").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
123254
+ ({ input: input2 }) => guarded(() => {
123255
+ requireChange(input2.defaultConfigProfile !== void 0 || input2.allowAmbientCredential !== void 0 || input2.credential !== void 0, "defaultConfigProfile, allowAmbientCredential or credential");
123256
+ if (!identityExists(paths, input2.name)) {
123257
+ throw new IdentityNotFoundError(input2.name);
123258
+ }
123259
+ if (typeof input2.defaultConfigProfile === "string") {
123260
+ requireProfileExists(paths, input2.defaultConfigProfile);
123261
+ }
123262
+ if (input2.defaultConfigProfile !== void 0) {
123263
+ setDefaultConfigProfile(paths, input2.name, input2.defaultConfigProfile === false ? void 0 : input2.defaultConfigProfile);
123264
+ }
123265
+ if (input2.allowAmbientCredential !== void 0) {
123266
+ setAllowAmbientCredential(paths, input2.name, input2.allowAmbientCredential);
123267
+ }
123268
+ if (input2.credential === false) {
123269
+ setIdentityCredential(paths, input2.name, false);
123270
+ } else if (input2.credential !== void 0) {
123271
+ const { sources, target, cache } = input2.credential;
123272
+ const merged = cache === void 0 ? void 0 : mergeCredentialCache(cache === false ? { enabled: false } : { ...cache, enabled: true }, readIdentity(paths, input2.name)?.credential?.cache);
123273
+ const change = {
123274
+ ...sources === void 0 ? {} : { sources },
123275
+ ...target === void 0 ? {} : { target },
123276
+ ...merged === void 0 ? {} : { cache: merged }
123277
+ };
123278
+ setIdentityCredential(paths, input2.name, change);
123279
+ }
123280
+ return { action: "updated", kind: "identity", name: input2.name, value: identityValue(input2.name, paths) };
123281
+ })
123282
+ ),
123283
+ remove: route("/rest/config/identity/remove", "Delete an identity and its directory").input(ConfigIdentityRemoveInputSchema).output(ConfigIdentityRemoveOutputSchema).handler(({ input: input2 }) => {
123284
+ requireConfirmation(input2.confirm, `identity "${input2.name}" and its directory`);
123285
+ return guarded(() => {
123286
+ removeIdentity(paths, input2.name);
123287
+ return { action: "removed", kind: "identity", name: input2.name };
123288
+ });
123289
+ }),
123290
+ use: route("/rest/config/identity/use", "Select the active identity").input(ConfigNameInputSchema).output(ConfigIdentityUseOutputSchema).handler(
123291
+ ({ input: input2 }) => guarded(() => {
123292
+ if (poolNameOf(input2.name) === void 0 && !identityExists(paths, input2.name)) {
123293
+ throw new IdentityNotFoundError(input2.name);
123294
+ }
123295
+ useIdentity(paths, input2.name);
123296
+ return { action: "selected", kind: "identity", name: input2.name };
123297
+ })
123298
+ )
123299
+ },
123300
+ profile: {
123301
+ add: route("/rest/config/profile/add", "Create a configuration profile").input(ConfigProfileAddInputSchema).output(ConfigProfileAddOutputSchema).handler(
123302
+ ({ input: input2 }) => guarded(() => {
123303
+ createProfile(paths, input2.name, input2.extends, input2.description);
123304
+ return { action: "created", kind: "profile", name: input2.name, value: profileValue(input2.name, paths) };
123305
+ })
123306
+ ),
123307
+ set: route("/rest/config/profile/set", "Update a configuration profile's categories, entries, extends list, description or launch settings").input(ConfigProfileSetInputSchema).output(ConfigProfileSetOutputSchema).handler(
123308
+ ({ input: input2 }) => guarded(() => {
123309
+ const { launch } = input2;
123310
+ requireChange(
123311
+ input2.category !== void 0 || input2.entry !== void 0 || input2.extends !== void 0 || input2.description !== void 0 || launch !== void 0,
123312
+ "category, entry, extends, description or launch"
123313
+ );
123314
+ requireProfileExists(paths, input2.name);
123315
+ applyProfileChange(paths, input2.name, {
123316
+ ...input2.category === void 0 ? {} : { category: input2.category },
123317
+ ...input2.entry === void 0 ? {} : { entry: input2.entry },
123318
+ ...input2.extends === void 0 ? {} : { extends: input2.extends },
123319
+ ...input2.description === void 0 ? {} : { description: input2.description },
123320
+ ...launch?.skipPermissions === void 0 ? {} : { launchSkipPermissions: launch.skipPermissions },
123321
+ ...launch?.remoteControl === void 0 ? {} : { launchRemoteControl: launch.remoteControl },
123322
+ ...launch?.headroom === void 0 ? {} : { launchHeadroom: launch.headroom },
123323
+ ...launch?.trackUsage === void 0 ? {} : { launchTrackUsage: launch.trackUsage },
123324
+ ...launch?.provider === void 0 ? {} : { launchProvider: launch.provider },
123325
+ ...launch?.claudeVersion === void 0 ? {} : { launchClaudeVersion: launch.claudeVersion }
123326
+ });
123327
+ return { action: "updated", kind: "profile", name: input2.name, value: profileValue(input2.name, paths) };
123328
+ })
123329
+ ),
123330
+ remove: route("/rest/config/profile/remove", "Delete a configuration profile").input(ConfigProfileRemoveInputSchema).output(ConfigProfileRemoveOutputSchema).handler(({ input: input2 }) => {
123331
+ requireConfirmation(input2.confirm, `configuration profile "${input2.name}"`);
123332
+ return guarded(() => {
123333
+ removeProfile(paths, input2.name);
123334
+ return { action: "removed", kind: "profile", name: input2.name };
123335
+ });
123336
+ }),
123337
+ use: route("/rest/config/profile/use", "Make a configuration profile the global default").input(ConfigNameInputSchema).output(ConfigProfileUseOutputSchema).handler(
123338
+ ({ input: input2 }) => guarded(() => {
123339
+ requireProfileExists(paths, input2.name);
123340
+ setGlobalDefaultProfile(paths, input2.name);
123341
+ return { action: "selected", kind: "profile", name: input2.name };
123342
+ })
123343
+ )
123344
+ },
123345
+ pool: {
123346
+ add: route("/rest/config/pool/add", "Define a pool").input(ConfigPoolAddInputSchema).output(ConfigPoolAddOutputSchema).handler(
123347
+ ({ input: input2 }) => guarded(() => {
123348
+ requireIdentityNames(paths, input2.identities);
123349
+ const created = addPool(paths, input2.name, input2.identities, input2.preference);
123350
+ return { action: "created", kind: "pool", name: input2.name, value: created };
123351
+ })
123352
+ ),
123353
+ set: route("/rest/config/pool/set", "Replace a pool's members, its preference or both").input(ConfigPoolSetInputSchema).output(ConfigPoolSetOutputSchema).handler(
123354
+ ({ input: input2 }) => guarded(() => {
123355
+ requireChange(input2.identities !== void 0 || input2.preference !== void 0, "identities or preference");
123356
+ const existing = requirePool(paths, input2.name);
123357
+ if (input2.identities !== void 0) {
123358
+ requireIdentityNames(paths, input2.identities);
123359
+ }
123360
+ const members2 = input2.identities ?? existing.identities;
123361
+ const preference = input2.preference === void 0 ? existing.preference : input2.preference === false ? void 0 : input2.preference;
123362
+ return { action: "updated", kind: "pool", name: input2.name, value: setPool(paths, input2.name, members2, preference) };
123363
+ })
123364
+ ),
123365
+ remove: route("/rest/config/pool/remove", "Delete a pool").input(ConfigPoolRemoveInputSchema).output(ConfigPoolRemoveOutputSchema).handler(({ input: input2 }) => {
123366
+ requireConfirmation(input2.confirm, `pool "${input2.name}"`);
123367
+ return guarded(() => {
123368
+ removePool(paths, input2.name);
123369
+ return { action: "removed", kind: "pool", name: input2.name };
123370
+ });
123371
+ }),
123372
+ use: route("/rest/config/pool/use", "Make launches with no other selection pick a member of a pool").input(ConfigNameInputSchema).output(ConfigPoolUseOutputSchema).handler(
123373
+ ({ input: input2 }) => guarded(() => {
123374
+ if (readPools(paths)[input2.name] === void 0) {
123375
+ throw new PoolNotFoundError(input2.name);
123376
+ }
123377
+ useIdentity(paths, `pool:${input2.name}`);
123378
+ return { action: "selected", kind: "pool", name: input2.name };
123379
+ })
123380
+ )
123381
+ },
123382
+ provider: {
123383
+ add: route("/rest/config/provider/add", "Create an API provider definition").input(ConfigProviderAddInputSchema).output(ConfigProviderAddOutputSchema).handler(
123384
+ ({ input: input2 }) => guarded(() => {
123385
+ const created = addProvider(paths, input2.name, {
123386
+ ...input2.kind === void 0 ? {} : { kind: input2.kind },
123387
+ displayName: input2.displayName,
123388
+ ...input2.baseUrl === void 0 ? {} : { baseUrl: input2.baseUrl },
123389
+ sources: input2.credential.sources,
123390
+ ...input2.credential.target === void 0 ? {} : { target: input2.credential.target },
123391
+ ...input2.codex === void 0 ? {} : { codex: input2.codex }
123392
+ });
123393
+ const cache = input2.credential.cache;
123394
+ const stored = cache === void 0 || cache === false ? created : updateProvider(paths, input2.name, { cache });
123395
+ return { action: "created", kind: "provider", name: input2.name, value: providerValue(input2.name, stored) };
123396
+ })
123397
+ ),
123398
+ set: route("/rest/config/provider/set", "Update an API provider definition").input(ConfigProviderSetInputSchema).output(ConfigProviderSetOutputSchema).handler(
123399
+ ({ input: input2 }) => guarded(() => {
123400
+ requireChange(input2.displayName !== void 0 || input2.baseUrl !== void 0 || input2.credential !== void 0 || input2.codex !== void 0, "displayName, baseUrl, credential or codex");
123401
+ const existing = readProvider(paths, input2.name);
123402
+ if (existing === void 0) {
123403
+ throw new ProviderNotFoundError(input2.name);
123404
+ }
123405
+ const credential = input2.credential;
123406
+ if (input2.baseUrl !== void 0 && !isCodexProvider(existing) && input2.baseUrl !== existing.baseUrl && credential?.sources === void 0) {
123407
+ throw new ORPCError("BAD_REQUEST", { message: `Changing the base URL of provider "${input2.name}" requires a credential block in the same call: the stored credential is not sent to a different endpoint.` });
123408
+ }
123409
+ const cache = credential?.cache === void 0 ? void 0 : mergeCredentialCache(credential.cache === false ? { enabled: false } : { ...credential.cache, enabled: true }, existing.credential.cache);
123410
+ const updated = updateProvider(paths, input2.name, {
123411
+ ...input2.displayName === void 0 ? {} : { displayName: input2.displayName },
123412
+ ...input2.baseUrl === void 0 ? {} : { baseUrl: input2.baseUrl },
123413
+ ...credential?.sources === void 0 ? {} : { sources: credential.sources },
123414
+ ...credential?.target === void 0 ? {} : { target: credential.target },
123415
+ ...cache === void 0 ? {} : { cache },
123416
+ ...input2.codex === void 0 ? {} : { codex: input2.codex }
123417
+ });
123418
+ return { action: "updated", kind: "provider", name: input2.name, value: providerValue(input2.name, updated) };
123419
+ })
123420
+ ),
123421
+ remove: route("/rest/config/provider/remove", "Delete an API provider definition").input(ConfigProviderRemoveInputSchema).output(ConfigProviderRemoveOutputSchema).handler(({ input: input2 }) => {
123422
+ requireConfirmation(input2.confirm, `provider "${input2.name}"`);
123423
+ return guarded(() => {
123424
+ if (!providerExists(paths, input2.name)) {
123425
+ throw new ProviderNotFoundError(input2.name);
123426
+ }
123427
+ removeProvider(paths, input2.name);
123428
+ return { action: "removed", kind: "provider", name: input2.name };
123429
+ });
123430
+ })
123431
+ },
123432
+ rule: {
123433
+ add: route("/rest/config/rule/add", "Add a directory rule for a path").input(ConfigRuleAddInputSchema).output(ConfigRuleAddOutputSchema).handler(
123434
+ ({ input: input2 }) => guarded(() => {
123435
+ if (input2.identity !== void 0) {
123436
+ requireRuleSelector(paths, input2.identity);
123437
+ }
123438
+ if (input2.configProfile !== void 0) {
123439
+ requireProfileExists(paths, input2.configProfile);
123440
+ }
123441
+ const created = addDirectoryRule(paths, input2.path, {
123442
+ ...input2.configProfile === void 0 ? {} : { configProfile: input2.configProfile },
123443
+ ...input2.identity === void 0 ? {} : { identity: input2.identity }
123444
+ });
123445
+ return { action: "created", kind: "rule", name: input2.path, value: created };
123446
+ })
123447
+ ),
123448
+ set: route("/rest/config/rule/set", "Update the directory rule for a path").input(ConfigRuleSetInputSchema).output(ConfigRuleSetOutputSchema).handler(
123449
+ ({ input: input2 }) => guarded(() => {
123450
+ requireChange(input2.configProfile !== void 0 || input2.identity !== void 0, "configProfile or identity");
123451
+ if (typeof input2.identity === "string") {
123452
+ requireRuleSelector(paths, input2.identity);
123453
+ }
123454
+ if (typeof input2.configProfile === "string") {
123455
+ requireProfileExists(paths, input2.configProfile);
123456
+ }
123457
+ const updated = updateDirectoryRule(paths, input2.path, {
123458
+ ...input2.configProfile === void 0 ? {} : { configProfile: input2.configProfile },
123459
+ ...input2.identity === void 0 ? {} : { identity: input2.identity }
123460
+ });
123461
+ return { action: "updated", kind: "rule", name: input2.path, value: updated };
123462
+ })
123463
+ ),
123464
+ remove: route("/rest/config/rule/remove", "Remove the directory rule for a path").input(ConfigRuleRemoveInputSchema).output(ConfigRuleRemoveOutputSchema).handler(({ input: input2 }) => {
123465
+ requireConfirmation(input2.confirm, `the directory rule for "${input2.path}"`);
123466
+ return guarded(() => {
123467
+ if (!listDirectoryRules(paths).some((entry) => entry.path === input2.path)) {
123468
+ throw new DirectoryRuleNotFoundError(input2.path);
123469
+ }
123470
+ removeDirectoryRule(paths, input2.path);
123471
+ return { action: "removed", kind: "rule", name: input2.path };
123472
+ });
123473
+ })
123474
+ }
123475
+ }
123476
+ };
123477
+ }
123478
+
122994
123479
  // src/frontdoor/eventSchemas.ts
122995
123480
  init_zod();
122996
123481
  var DOOR_EVENT_SOURCE_RC = "rc";
@@ -123241,7 +123726,7 @@ function createControlApiRouter(deps) {
123241
123726
  function createDoorApiRouter(deps) {
123242
123727
  const control = createControlApiRouter(deps);
123243
123728
  const lifecycle = createLifecycleApiRouter(deps);
123244
- return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
123729
+ return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
123245
123730
  }
123246
123731
  function createDoorApiNodeHandler(deps) {
123247
123732
  return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
@@ -126299,9 +126784,9 @@ async function serveRcCompatSessions(ctx, pathname, compatPath) {
126299
126784
  const slash = rest.indexOf("/");
126300
126785
  const address = slash === -1 ? rest : rest.slice(0, slash);
126301
126786
  const compatTail = slash === -1 ? "" : rest.slice(slash + 1);
126302
- const refusal = ctx.credentialRefusal(request7.headers);
126303
- if (refusal !== void 0) {
126304
- await ctx.unauthorized(response, refusal);
126787
+ const refusal2 = ctx.credentialRefusal(request7.headers);
126788
+ if (refusal2 !== void 0) {
126789
+ await ctx.unauthorized(response, refusal2);
126305
126790
  return;
126306
126791
  }
126307
126792
  const session = ctx.sessions.get(address) ?? ctx.sessions.get(`cse_${address}`);
@@ -126379,9 +126864,9 @@ function conversationRow(conversation) {
126379
126864
  }
126380
126865
  async function serveRcConversations(ctx, pathname, method) {
126381
126866
  const { request: request7, response, conversations } = ctx;
126382
- const refusal = ctx.credentialRefusal(request7.headers);
126383
- if (refusal !== void 0) {
126384
- await ctx.unauthorized(response, refusal);
126867
+ const refusal2 = ctx.credentialRefusal(request7.headers);
126868
+ if (refusal2 !== void 0) {
126869
+ await ctx.unauthorized(response, refusal2);
126385
126870
  return;
126386
126871
  }
126387
126872
  if (pathname === RC_CONVERSATIONS_PATH_PREFIX) {
@@ -126602,9 +127087,9 @@ async function fetchThroughWebProxy(url2, deps) {
126602
127087
  try {
126603
127088
  let redirects = 0;
126604
127089
  for (; ; ) {
126605
- const refusal = await checkTarget(current, deps);
126606
- if (refusal !== void 0) {
126607
- return refusal;
127090
+ const refusal2 = await checkTarget(current, deps);
127091
+ if (refusal2 !== void 0) {
127092
+ return refusal2;
126608
127093
  }
126609
127094
  let hop;
126610
127095
  try {
@@ -126974,8 +127459,8 @@ data: ${JSON.stringify(envelope)}
126974
127459
  "doubled-scheme-word": "the self-hosted Remote Control surface reads one Bearer scheme word, and this call's Authorization header carried it twice: a persisted session record holds the whole header value with the scheme word included, so prefixing Bearer onto it presents a different credential",
126975
127460
  unrecognised: "the self-hosted Remote Control surface did not recognise the presented credential"
126976
127461
  };
126977
- const unauthorized = async (response, refusal) => {
126978
- await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[refusal] } });
127462
+ const unauthorized = async (response, refusal2) => {
127463
+ await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[refusal2] } });
126979
127464
  };
126980
127465
  const serveSessionPath = async (session, tail, request7, response) => {
126981
127466
  const method = request7.method.toUpperCase();
@@ -126986,9 +127471,9 @@ data: ${JSON.stringify(envelope)}
126986
127471
  session.lastTrafficAt = deps.now();
126987
127472
  if (tail === "") {
126988
127473
  if (method === "PATCH" || method === "PUT") {
126989
- const refusal = credentialRefusal(request7.headers);
126990
- if (refusal !== void 0) {
126991
- await unauthorized(response, refusal);
127474
+ const refusal2 = credentialRefusal(request7.headers);
127475
+ if (refusal2 !== void 0) {
127476
+ await unauthorized(response, refusal2);
126992
127477
  return;
126993
127478
  }
126994
127479
  const body = parseJsonObject5(await readBody3(request7.body, CONTROL_BODY_CAP_BYTES));
@@ -127011,9 +127496,9 @@ data: ${JSON.stringify(envelope)}
127011
127496
  return;
127012
127497
  }
127013
127498
  if (tail === "bridge" && method === "POST") {
127014
- const refusal = credentialRefusal(request7.headers);
127015
- if (refusal !== void 0) {
127016
- await unauthorized(response, refusal);
127499
+ const refusal2 = credentialRefusal(request7.headers);
127500
+ if (refusal2 !== void 0) {
127501
+ await unauthorized(response, refusal2);
127017
127502
  return;
127018
127503
  }
127019
127504
  const workerJwt = mintWorkerJwt(deps.randomToken, deps.now());
@@ -127023,9 +127508,9 @@ data: ${JSON.stringify(envelope)}
127023
127508
  return;
127024
127509
  }
127025
127510
  if (tail === "archive" && method === "POST") {
127026
- const refusal = credentialRefusal(request7.headers);
127027
- if (refusal !== void 0) {
127028
- await unauthorized(response, refusal);
127511
+ const refusal2 = credentialRefusal(request7.headers);
127512
+ if (refusal2 !== void 0) {
127513
+ await unauthorized(response, refusal2);
127029
127514
  return;
127030
127515
  }
127031
127516
  retireSession(session);
@@ -127036,9 +127521,9 @@ data: ${JSON.stringify(envelope)}
127036
127521
  if (tail === "worker" || tail.startsWith("worker/")) {
127037
127522
  const workerTail = tail === "worker" ? "" : tail.slice("worker/".length);
127038
127523
  const webProxy = workerTail === "web-fetch" || workerTail === "web-search";
127039
- const refusal = webProxy ? workerOrCredentialRefusal(request7.headers, session) : workerRefusal(request7.headers, session);
127040
- if (refusal !== void 0) {
127041
- await unauthorized(response, refusal);
127524
+ const refusal2 = webProxy ? workerOrCredentialRefusal(request7.headers, session) : workerRefusal(request7.headers, session);
127525
+ if (refusal2 !== void 0) {
127526
+ await unauthorized(response, refusal2);
127042
127527
  return;
127043
127528
  }
127044
127529
  if (workerTail === "" && method === "GET") {
@@ -127969,6 +128454,7 @@ function realFrontDoorSupervisorPorts(paths) {
127969
128454
  [
127970
128455
  createDoorApiNodeHandler({
127971
128456
  expectedToken: rcControlToken,
128457
+ paths,
127972
128458
  statusOf: rcTracker.statusOf,
127973
128459
  pendingOf: rcTracker.pendingOf,
127974
128460
  inject: rcInject,
@@ -138579,7 +139065,6 @@ function registerHeadroomCommand(program2, deps) {
138579
139065
  init_commandDeps();
138580
139066
  init_cliError();
138581
139067
  init_schema();
138582
- init_identity();
138583
139068
  init_schema();
138584
139069
  init_realPorts();
138585
139070
  init_preflight();
@@ -138593,14 +139078,6 @@ function formatPoolPick(report, nowMs) {
138593
139078
  });
138594
139079
  return [head, ...rows, ...report.missing.map((name) => ` (skipped: ${name} is not an identity)`), ...report.stickyProblem === void 0 ? [] : [`Note: ${report.stickyProblem}; the last-pick record was ignored.`]];
138595
139080
  }
138596
- function requireIdentities(paths, names) {
138597
- const existing = new Set(listIdentities(paths).map((entry) => entry.name));
138598
- for (const name of names) {
138599
- if (poolNameOf(name) === void 0 && !existing.has(name)) {
138600
- throw new IdentityNotFoundError(name);
138601
- }
138602
- }
138603
- }
138604
139081
  function membersOf(options) {
138605
139082
  if (options.identity === void 0 || options.identity.length === 0) {
138606
139083
  throw new UsageError("A pool needs at least one member: pass --identity <name> (repeatable).");
@@ -138617,7 +139094,7 @@ function registerPoolCommand(program2, deps) {
138617
139094
  withExamples(
138618
139095
  pool.command("add <name>").description("Define a pool. Fails if one with this name already exists.").option("--identity <name>", "A member: an identity name, or pool:<name> to nest another pool with its own policy (repeatable).", collectRepeated).addOption(new Option("--preference <mode>", PREFERENCE_DESCRIPTION).choices(POOL_PREFERENCES)).option("--json", "Print the result as JSON.").action((name, options) => {
138619
139096
  const members2 = membersOf(options);
138620
- requireIdentities(paths, members2);
139097
+ requireIdentityNames(paths, members2);
138621
139098
  const created = addPool(paths, name, members2, options.preference);
138622
139099
  reportMutation(options.json, { action: "created", kind: "pool", name, value: created }, () => {
138623
139100
  console.log(`Created pool "${name}" with ${members2.join(", ")}.`);
@@ -138633,7 +139110,7 @@ function registerPoolCommand(program2, deps) {
138633
139110
  }
138634
139111
  const members2 = options.identity === void 0 ? existing.identities : membersOf(options);
138635
139112
  if (options.identity !== void 0) {
138636
- requireIdentities(paths, membersOf(options));
139113
+ requireIdentityNames(paths, membersOf(options));
138637
139114
  }
138638
139115
  const preference = options.preference === void 0 ? existing.preference : options.preference === false ? void 0 : options.preference;
138639
139116
  const updated = setPool(paths, name, members2, preference);
@@ -138889,21 +139366,13 @@ function registerProviderCommand(program2, deps) {
138889
139366
  // src/directoryRules.ts
138890
139367
  init_commandDeps();
138891
139368
  init_cliError();
138892
- init_schema();
138893
139369
  function describeRule(rule) {
138894
139370
  const parts = Object.entries(rule).filter(([key]) => key !== "path").map(([key, value2]) => `${key}=${typeof value2 === "string" ? value2 : JSON.stringify(value2)}`);
138895
139371
  return parts.length === 0 ? "(nothing)" : parts.join(", ");
138896
139372
  }
138897
139373
  async function checkRuleTargets(deps, options) {
138898
139374
  if (typeof options.identity === "string") {
138899
- if (options.identity.startsWith(POOL_SELECTOR_PREFIX)) {
138900
- const poolName = options.identity.slice(POOL_SELECTOR_PREFIX.length);
138901
- if (readPools(deps.paths)[poolName] === void 0) {
138902
- throw new PoolNotFoundError(poolName);
138903
- }
138904
- } else if (readIdentity(deps.paths, options.identity) === void 0) {
138905
- throw new IdentityNotFoundError(options.identity);
138906
- }
139375
+ requireRuleSelector(deps.paths, options.identity);
138907
139376
  }
138908
139377
  if (typeof options.configProfile === "string") {
138909
139378
  await ensureProfileExists(deps, options.configProfile);