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/index.cjs CHANGED
@@ -228,7 +228,7 @@ function isCodexProvider(provider) {
228
228
  function poolMemberIdentity(member) {
229
229
  return typeof member === "string" ? member : member.identity;
230
230
  }
231
- var import_node_path2, import_zod, import_trilean, 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, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, 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, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
231
+ var import_node_path2, import_zod, import_trilean, 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_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, 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, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
232
232
  var init_schema = __esm({
233
233
  "src/config/schema.ts"() {
234
234
  "use strict";
@@ -284,20 +284,33 @@ var init_schema = __esm({
284
284
  /** 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. */
285
285
  timeoutMs: import_zod.z.int().positive().optional()
286
286
  };
287
+ EnvCredentialSourceSchema = import_zod.z.strictObject({ env: import_zod.z.string().min(1) });
288
+ FileCredentialSourceSchema = import_zod.z.strictObject({
289
+ file: import_zod.z.string().min(1).refine((filePath) => filePath.startsWith("~/") || import_node_path2.default.isAbsolute(filePath), {
290
+ message: "a credential file must be an absolute or ~-rooted path, since a launch can start in any directory"
291
+ })
292
+ });
293
+ CommandCredentialSourceSchema = import_zod.z.strictObject({ command: ArgvSchema, ...CommandSourceOptions });
294
+ OpCredentialSourceSchema = import_zod.z.strictObject({ op: import_zod.z.string().startsWith("op://"), ...CommandSourceOptions });
295
+ KeychainCredentialSourceSchema = import_zod.z.strictObject({
296
+ keychain: import_zod.z.strictObject({ service: import_zod.z.string().min(1), account: import_zod.z.string().min(1).optional() }),
297
+ ...CommandSourceOptions
298
+ });
299
+ LiteralCredentialSourceSchema = import_zod.z.strictObject({ literal: import_zod.z.string().min(1) });
287
300
  CredentialSourceSchema = import_zod.z.union([
288
- import_zod.z.strictObject({ env: import_zod.z.string().min(1) }),
289
- import_zod.z.strictObject({
290
- file: import_zod.z.string().min(1).refine((filePath) => filePath.startsWith("~/") || import_node_path2.default.isAbsolute(filePath), {
291
- message: "a credential file must be an absolute or ~-rooted path, since a launch can start in any directory"
292
- })
293
- }),
294
- import_zod.z.strictObject({ command: ArgvSchema, ...CommandSourceOptions }),
295
- import_zod.z.strictObject({ op: import_zod.z.string().startsWith("op://"), ...CommandSourceOptions }),
296
- import_zod.z.strictObject({
297
- keychain: import_zod.z.strictObject({ service: import_zod.z.string().min(1), account: import_zod.z.string().min(1).optional() }),
298
- ...CommandSourceOptions
299
- }),
300
- import_zod.z.strictObject({ literal: import_zod.z.string().min(1) })
301
+ EnvCredentialSourceSchema,
302
+ FileCredentialSourceSchema,
303
+ CommandCredentialSourceSchema,
304
+ OpCredentialSourceSchema,
305
+ KeychainCredentialSourceSchema,
306
+ LiteralCredentialSourceSchema
307
+ ]);
308
+ RemoteCredentialSourceSchema = import_zod.z.union([
309
+ EnvCredentialSourceSchema,
310
+ FileCredentialSourceSchema,
311
+ OpCredentialSourceSchema,
312
+ KeychainCredentialSourceSchema,
313
+ LiteralCredentialSourceSchema
301
314
  ]);
302
315
  CREDENTIAL_CACHE_STORES = ["keychain", "file"];
303
316
  CredentialCacheSchema = import_zod.z.strictObject({
@@ -314,6 +327,7 @@ var init_schema = __esm({
314
327
  ProviderEnvSchema = import_zod.z.record(import_zod.z.string().min(1), import_zod.z.string()).refine((env) => !Object.keys(env).some((key) => RESERVED_PROVIDER_ENV_KEYS.includes(key)), {
315
328
  message: `env may not set ${RESERVED_PROVIDER_ENV_KEYS.join(", ")}: the credential block's target sets one and agent-shim removes the others`
316
329
  });
330
+ PROVIDER_KINDS = ["http", "codex"];
317
331
  CODEX_EFFORTS = ["none", "low", "medium", "high"];
318
332
  CODEX_LOGINS = ["codex-cli", "chatgpt-sign-in"];
319
333
  CODEX_DEFAULT_TIER_MODELS = Object.freeze({
@@ -2649,7 +2663,7 @@ var init_package = __esm({
2649
2663
  "package.json"() {
2650
2664
  package_default = {
2651
2665
  name: "claude-use",
2652
- version: "9.6.0",
2666
+ version: "9.7.0",
2653
2667
  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.",
2654
2668
  license: "MIT",
2655
2669
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -3052,8 +3066,8 @@ function verifyHeadroomSocket(socketPath, ports) {
3052
3066
  }
3053
3067
  const uid = ports.currentUid();
3054
3068
  const directory = import_node_path12.default.dirname(socketPath);
3055
- const refusal = ownerOnlyRefusal("socket directory", directory, ports.lstat(directory), "dir", uid) ?? ownerOnlyRefusal("socket", socketPath, ports.lstat(socketPath), "socket", uid);
3056
- return refusal === void 0 ? { socketPath } : { refused: refusal };
3069
+ const refusal2 = ownerOnlyRefusal("socket directory", directory, ports.lstat(directory), "dir", uid) ?? ownerOnlyRefusal("socket", socketPath, ports.lstat(socketPath), "socket", uid);
3070
+ return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
3057
3071
  }
3058
3072
  function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
3059
3073
  const unsupported = platformRefusal(ports.platform);
@@ -3071,8 +3085,8 @@ function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
3071
3085
  return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
3072
3086
  }
3073
3087
  fs12.mkdirPrivate(paths.headroomSocketDir);
3074
- const refusal = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
3075
- return refusal === void 0 ? { socketPath } : { refused: refusal };
3088
+ const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
3089
+ return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
3076
3090
  }
3077
3091
  function pruneStaleHeadroomSockets(fs12, paths, isRunning) {
3078
3092
  const removed = [];
@@ -4586,14 +4600,14 @@ function capacityOf(plan) {
4586
4600
  return plan.kind === "subscription" ? plan.capacity : 1;
4587
4601
  }
4588
4602
  function assessRefusedNested(member, nested, nowMs) {
4589
- 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 };
4603
+ 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 };
4590
4604
  return {
4591
4605
  candidate: {
4592
4606
  identity: member.identity,
4593
4607
  class: "ineligible",
4594
- ...refusal.blockedUntilMs === void 0 ? {} : { blockedUntilMs: refusal.blockedUntilMs },
4608
+ ...refusal2.blockedUntilMs === void 0 ? {} : { blockedUntilMs: refusal2.blockedUntilMs },
4595
4609
  plan: planOf(member.account),
4596
- reasons: [refusal.reason]
4610
+ reasons: [refusal2.reason]
4597
4611
  }
4598
4612
  };
4599
4613
  }
@@ -4684,7 +4698,7 @@ function rankPool(input) {
4684
4698
  const assessments = members.map((member) => ({ member, ...assess(member, nowMs) }));
4685
4699
  const demands = assessments.flatMap(({ candidate, burn }) => burn === void 0 ? [] : [burn * capacityOf(candidate.plan)]);
4686
4700
  const sharedDemand = demands.length === 0 ? void 0 : Math.max(...demands);
4687
- const guarded = assessments.map((assessment) => {
4701
+ const guarded2 = assessments.map((assessment) => {
4688
4702
  const { candidate } = assessment;
4689
4703
  if (candidate.class === "ineligible" || assessment.member.policy === void 0) {
4690
4704
  return assessment;
@@ -4699,7 +4713,7 @@ function rankPool(input) {
4699
4713
  }
4700
4714
  return { ...assessment, candidate: { ...candidate, class: "ineligible", reasons: [`skipped by policy (${verdict.checked.join(", ")}: did not hold)`, ...candidate.reasons] } };
4701
4715
  });
4702
- const candidates = guarded.map((assessment) => {
4716
+ const candidates = guarded2.map((assessment) => {
4703
4717
  const { candidate, fiveHour, burn } = assessment;
4704
4718
  const pace = burn ?? (sharedDemand === void 0 ? void 0 : sharedDemand / capacityOf(candidate.plan));
4705
4719
  const { sevenDay, sevenDayBurn } = assessment;
@@ -7697,11 +7711,11 @@ var init_anthropicUsageRefresh = __esm({
7697
7711
  });
7698
7712
 
7699
7713
  // src/usage/providerQuota.ts
7700
- var import_zod22, MS_PER_SECOND7, SECONDS_PER_HOUR, HOURS_PER_DAY3, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema;
7714
+ var import_zod23, MS_PER_SECOND7, SECONDS_PER_HOUR, HOURS_PER_DAY3, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema;
7701
7715
  var init_providerQuota = __esm({
7702
7716
  "src/usage/providerQuota.ts"() {
7703
7717
  "use strict";
7704
- import_zod22 = require("zod");
7718
+ import_zod23 = require("zod");
7705
7719
  init_schema2();
7706
7720
  MS_PER_SECOND7 = 1e3;
7707
7721
  SECONDS_PER_HOUR = 3600;
@@ -7715,35 +7729,35 @@ var init_providerQuota = __esm({
7715
7729
  [ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND7],
7716
7730
  [ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7]
7717
7731
  ]);
7718
- ZaiLimitSchema = import_zod22.z.object({
7719
- type: import_zod22.z.string(),
7720
- unit: import_zod22.z.number().int(),
7721
- number: import_zod22.z.number().int().positive(),
7722
- percentage: import_zod22.z.number().nonnegative(),
7723
- nextResetTime: import_zod22.z.number().positive().optional(),
7724
- usage: import_zod22.z.number().nonnegative().optional(),
7725
- currentValue: import_zod22.z.number().nonnegative().optional(),
7726
- remaining: import_zod22.z.number().nonnegative().optional()
7732
+ ZaiLimitSchema = import_zod23.z.object({
7733
+ type: import_zod23.z.string(),
7734
+ unit: import_zod23.z.number().int(),
7735
+ number: import_zod23.z.number().int().positive(),
7736
+ percentage: import_zod23.z.number().nonnegative(),
7737
+ nextResetTime: import_zod23.z.number().positive().optional(),
7738
+ usage: import_zod23.z.number().nonnegative().optional(),
7739
+ currentValue: import_zod23.z.number().nonnegative().optional(),
7740
+ remaining: import_zod23.z.number().nonnegative().optional()
7727
7741
  });
7728
- ZaiResponseSchema = import_zod22.z.object({
7729
- success: import_zod22.z.boolean(),
7730
- msg: import_zod22.z.string().optional(),
7731
- data: import_zod22.z.object({ level: import_zod22.z.string().optional(), limits: import_zod22.z.array(ZaiLimitSchema) })
7742
+ ZaiResponseSchema = import_zod23.z.object({
7743
+ success: import_zod23.z.boolean(),
7744
+ msg: import_zod23.z.string().optional(),
7745
+ data: import_zod23.z.object({ level: import_zod23.z.string().optional(), limits: import_zod23.z.array(ZaiLimitSchema) })
7732
7746
  });
7733
7747
  OPENROUTER_HOST = "openrouter.ai";
7734
7748
  OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
7735
7749
  OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
7736
7750
  MS_PER_DAY3 = HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7;
7737
- OpenRouterKeySchema = import_zod22.z.object({
7738
- data: import_zod22.z.object({
7739
- limit: import_zod22.z.number().nonnegative().nullable(),
7740
- limit_remaining: import_zod22.z.number().nullable(),
7741
- limit_reset: import_zod22.z.string().nullable(),
7742
- is_free_tier: import_zod22.z.boolean().optional(),
7743
- free_model_daily_requests: import_zod22.z.object({ used: import_zod22.z.number().nonnegative(), limit: import_zod22.z.number().nonnegative(), remaining: import_zod22.z.number() }).optional()
7751
+ OpenRouterKeySchema = import_zod23.z.object({
7752
+ data: import_zod23.z.object({
7753
+ limit: import_zod23.z.number().nonnegative().nullable(),
7754
+ limit_remaining: import_zod23.z.number().nullable(),
7755
+ limit_reset: import_zod23.z.string().nullable(),
7756
+ is_free_tier: import_zod23.z.boolean().optional(),
7757
+ free_model_daily_requests: import_zod23.z.object({ used: import_zod23.z.number().nonnegative(), limit: import_zod23.z.number().nonnegative(), remaining: import_zod23.z.number() }).optional()
7744
7758
  })
7745
7759
  });
7746
- OpenRouterCreditsSchema = import_zod22.z.object({ data: import_zod22.z.object({ total_credits: import_zod22.z.number().nonnegative(), total_usage: import_zod22.z.number().nonnegative() }) });
7760
+ OpenRouterCreditsSchema = import_zod23.z.object({ data: import_zod23.z.object({ total_credits: import_zod23.z.number().nonnegative(), total_usage: import_zod23.z.number().nonnegative() }) });
7747
7761
  }
7748
7762
  });
7749
7763
 
@@ -7878,10 +7892,44 @@ __export(index_exports, {
7878
7892
  CodexLogoutOutputSchema: () => CodexLogoutOutputSchema,
7879
7893
  CodexSignInSchema: () => CodexSignInSchema,
7880
7894
  CodexStatusOutputSchema: () => CodexStatusOutputSchema,
7895
+ ConfigIdentityAddOutputSchema: () => ConfigIdentityAddOutputSchema,
7896
+ ConfigIdentityRemoveInputSchema: () => ConfigIdentityRemoveInputSchema,
7897
+ ConfigIdentityRemoveOutputSchema: () => ConfigIdentityRemoveOutputSchema,
7898
+ ConfigIdentitySetInputSchema: () => ConfigIdentitySetInputSchema,
7899
+ ConfigIdentitySetOutputSchema: () => ConfigIdentitySetOutputSchema,
7900
+ ConfigIdentityUseOutputSchema: () => ConfigIdentityUseOutputSchema,
7901
+ ConfigNameInputSchema: () => ConfigNameInputSchema,
7902
+ ConfigPoolAddInputSchema: () => ConfigPoolAddInputSchema,
7903
+ ConfigPoolAddOutputSchema: () => ConfigPoolAddOutputSchema,
7904
+ ConfigPoolRemoveInputSchema: () => ConfigPoolRemoveInputSchema,
7905
+ ConfigPoolRemoveOutputSchema: () => ConfigPoolRemoveOutputSchema,
7906
+ ConfigPoolSetInputSchema: () => ConfigPoolSetInputSchema,
7907
+ ConfigPoolSetOutputSchema: () => ConfigPoolSetOutputSchema,
7908
+ ConfigPoolUseOutputSchema: () => ConfigPoolUseOutputSchema,
7909
+ ConfigProfileAddInputSchema: () => ConfigProfileAddInputSchema,
7910
+ ConfigProfileAddOutputSchema: () => ConfigProfileAddOutputSchema,
7911
+ ConfigProfileRemoveInputSchema: () => ConfigProfileRemoveInputSchema,
7912
+ ConfigProfileRemoveOutputSchema: () => ConfigProfileRemoveOutputSchema,
7881
7913
  ConfigProfileSchema: () => ConfigProfileSchema,
7914
+ ConfigProfileSetInputSchema: () => ConfigProfileSetInputSchema,
7915
+ ConfigProfileSetOutputSchema: () => ConfigProfileSetOutputSchema,
7916
+ ConfigProfileUseOutputSchema: () => ConfigProfileUseOutputSchema,
7917
+ ConfigProviderAddInputSchema: () => ConfigProviderAddInputSchema,
7918
+ ConfigProviderAddOutputSchema: () => ConfigProviderAddOutputSchema,
7919
+ ConfigProviderRemoveInputSchema: () => ConfigProviderRemoveInputSchema,
7920
+ ConfigProviderRemoveOutputSchema: () => ConfigProviderRemoveOutputSchema,
7921
+ ConfigProviderSetInputSchema: () => ConfigProviderSetInputSchema,
7922
+ ConfigProviderSetOutputSchema: () => ConfigProviderSetOutputSchema,
7923
+ ConfigRuleAddInputSchema: () => ConfigRuleAddInputSchema,
7924
+ ConfigRuleAddOutputSchema: () => ConfigRuleAddOutputSchema,
7925
+ ConfigRuleRemoveInputSchema: () => ConfigRuleRemoveInputSchema,
7926
+ ConfigRuleRemoveOutputSchema: () => ConfigRuleRemoveOutputSchema,
7927
+ ConfigRuleSetInputSchema: () => ConfigRuleSetInputSchema,
7928
+ ConfigRuleSetOutputSchema: () => ConfigRuleSetOutputSchema,
7882
7929
  CredentialCacheSchema: () => CredentialCacheSchema,
7883
7930
  CredentialSchema: () => CredentialSchema,
7884
7931
  CredentialSourceSchema: () => CredentialSourceSchema,
7932
+ CredentialSummarySchema: () => CredentialSummarySchema2,
7885
7933
  DOOR_EVENT_BUFFER_EVENTS: () => DOOR_EVENT_BUFFER_EVENTS,
7886
7934
  DOOR_EVENT_SOURCE_RC: () => DOOR_EVENT_SOURCE_RC,
7887
7935
  DOOR_HEALTH_EVENT_SOURCE: () => DOOR_HEALTH_EVENT_SOURCE,
@@ -8012,6 +8060,7 @@ __export(index_exports, {
8012
8060
  collectFrontDoorStatus: () => collectFrontDoorStatus,
8013
8061
  collectPoolPick: () => collectPoolPick,
8014
8062
  createCodexApiRouter: () => createCodexApiRouter,
8063
+ createConfigApiRouter: () => createConfigApiRouter,
8015
8064
  createControlApiRouter: () => createControlApiRouter,
8016
8065
  createDoorApiNodeHandler: () => createDoorApiNodeHandler,
8017
8066
  createDoorApiRouter: () => createDoorApiRouter,
@@ -9030,6 +9079,7 @@ var HTTP_STATUS = {
9030
9079
  forbidden: 403,
9031
9080
  notFound: 404,
9032
9081
  methodNotAllowed: 405,
9082
+ conflict: 409,
9033
9083
  payloadTooLarge: 413,
9034
9084
  tooManyRequests: 429,
9035
9085
  /** 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. */
@@ -11155,9 +11205,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
11155
11205
  if (request4.method === "GET" && request4.url === `${RC_ORPC_PATH_PREFIX}${RC_OPENAPI_DOC_PATH}`) {
11156
11206
  const token = doorApiBearer(request4.headers);
11157
11207
  if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
11158
- const refusal = new import_client.ORPCError("UNAUTHORIZED", { message: "the front door's OpenAPI document demands this generation's control token as a Bearer credential" });
11208
+ const refusal2 = new import_client.ORPCError("UNAUTHORIZED", { message: "the front door's OpenAPI document demands this generation's control token as a Bearer credential" });
11159
11209
  response.writeHead(HTTP_STATUS.unauthorized, { "content-type": "application/json" });
11160
- response.end(JSON.stringify(refusal.toJSON()));
11210
+ response.end(JSON.stringify(refusal2.toJSON()));
11161
11211
  return { matched: true };
11162
11212
  }
11163
11213
  try {
@@ -11165,9 +11215,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
11165
11215
  response.writeHead(HTTP_STATUS.ok, { "content-type": "application/json" });
11166
11216
  response.end(JSON.stringify(doc));
11167
11217
  } catch (error) {
11168
- const refusal = new import_client.ORPCError("INTERNAL_SERVER_ERROR", { message: `the OpenAPI document could not be generated from the door's own router: ${error instanceof Error ? error.message : String(error)}` });
11218
+ const refusal2 = new import_client.ORPCError("INTERNAL_SERVER_ERROR", { message: `the OpenAPI document could not be generated from the door's own router: ${error instanceof Error ? error.message : String(error)}` });
11169
11219
  response.writeHead(HTTP_STATUS.internalServerError, { "content-type": "application/json" });
11170
- response.end(JSON.stringify(refusal.toJSON()));
11220
+ response.end(JSON.stringify(refusal2.toJSON()));
11171
11221
  }
11172
11222
  return { matched: true };
11173
11223
  }
@@ -11216,8 +11266,8 @@ init_cliError();
11216
11266
  init_realPorts();
11217
11267
 
11218
11268
  // src/frontdoor/controlApi.ts
11219
- var import_client5 = require("@orpc/client");
11220
- var import_openapi6 = require("@orpc/openapi");
11269
+ var import_client6 = require("@orpc/client");
11270
+ var import_openapi7 = require("@orpc/openapi");
11221
11271
 
11222
11272
  // src/checkReport.ts
11223
11273
  var import_node_os5 = __toESM(require("node:os"), 1);
@@ -11401,6 +11451,48 @@ function removeProfile(paths, name) {
11401
11451
  requireProfileExists(paths, name);
11402
11452
  import_node_fs3.default.rmSync(profileJsonPath(paths, name));
11403
11453
  }
11454
+ function applyProfileChange(paths, name, change) {
11455
+ let touched = false;
11456
+ if (change.category !== void 0) {
11457
+ setProfileCategories(paths, name, change.category);
11458
+ touched = true;
11459
+ }
11460
+ if (change.entry !== void 0) {
11461
+ setProfileEntries(paths, name, change.entry);
11462
+ touched = true;
11463
+ }
11464
+ if (change.extends !== void 0 || change.description !== void 0) {
11465
+ setProfileMetadata(paths, name, {
11466
+ ...change.extends === void 0 ? {} : { extends: change.extends === false ? [] : change.extends },
11467
+ ...change.description === void 0 ? {} : { description: change.description }
11468
+ });
11469
+ touched = true;
11470
+ }
11471
+ const launchPatch = {};
11472
+ if (change.launchSkipPermissions !== void 0) {
11473
+ launchPatch.skipPermissions = change.launchSkipPermissions;
11474
+ }
11475
+ if (change.launchRemoteControl !== void 0) {
11476
+ launchPatch.remoteControl = change.launchRemoteControl;
11477
+ }
11478
+ if (change.launchHeadroom !== void 0) {
11479
+ launchPatch.headroom = change.launchHeadroom;
11480
+ }
11481
+ if (change.launchTrackUsage !== void 0) {
11482
+ launchPatch.trackUsage = change.launchTrackUsage;
11483
+ }
11484
+ if (change.launchProvider !== void 0) {
11485
+ launchPatch.provider = change.launchProvider === false ? void 0 : change.launchProvider;
11486
+ }
11487
+ if (change.launchClaudeVersion !== void 0) {
11488
+ launchPatch.claudeVersion = change.launchClaudeVersion === false ? void 0 : change.launchClaudeVersion;
11489
+ }
11490
+ if (Object.keys(launchPatch).length > 0) {
11491
+ setProfileLaunchFlags(paths, name, launchPatch);
11492
+ touched = true;
11493
+ }
11494
+ return touched;
11495
+ }
11404
11496
 
11405
11497
  // src/poolStore.ts
11406
11498
  init_store();
@@ -12174,6 +12266,14 @@ var InvalidIdentityNameError = class extends CliError {
12174
12266
  function identityJsonPath(paths, name) {
12175
12267
  return import_node_path27.default.join(paths.identitiesDir, name, "identity.json");
12176
12268
  }
12269
+ function requireIdentityNames(paths, names) {
12270
+ const existing = new Set(listIdentities(paths).map((entry) => entry.name));
12271
+ for (const name of names) {
12272
+ if (poolNameOf(name) === void 0 && !existing.has(name)) {
12273
+ throw new IdentityNotFoundError(name);
12274
+ }
12275
+ }
12276
+ }
12177
12277
  function identityExists(paths, name) {
12178
12278
  return import_node_fs8.default.existsSync(identityJsonPath(paths, name));
12179
12279
  }
@@ -13066,47 +13166,608 @@ function createCodexApiRouter(deps) {
13066
13166
  };
13067
13167
  }
13068
13168
 
13069
- // src/frontdoor/eventsApi.ts
13169
+ // src/frontdoor/configApi.ts
13070
13170
  var import_client2 = require("@orpc/client");
13071
13171
  var import_openapi3 = require("@orpc/openapi");
13172
+ init_cliError();
13173
+ init_schema();
13174
+ init_credential();
13175
+
13176
+ // src/credentialCacheChange.ts
13177
+ init_cliError();
13178
+ init_schema();
13179
+ function mergeCredentialCache(request4, existing) {
13180
+ if (request4.enabled === false) {
13181
+ return false;
13182
+ }
13183
+ if (request4.ttl === void 0 && request4.store === void 0 && request4.enabled !== true) {
13184
+ return void 0;
13185
+ }
13186
+ const parsed = CredentialCacheSchema.safeParse({
13187
+ ...existing,
13188
+ ...request4.ttl === void 0 ? {} : { ttl: request4.ttl },
13189
+ ...request4.store === void 0 ? {} : { store: request4.store }
13190
+ });
13191
+ if (!parsed.success) {
13192
+ throw new UsageError(parsed.error.issues.map((issue) => issue.message).join("; "));
13193
+ }
13194
+ return parsed.data;
13195
+ }
13196
+
13197
+ // src/directoryRulesStore.ts
13198
+ init_store();
13199
+ init_load();
13200
+ init_schema();
13201
+ init_cliError();
13202
+ var DirectoryRuleNotFoundError = class extends CliError {
13203
+ constructor(rulePath) {
13204
+ super(`No directory rule found for path "${rulePath}".`);
13205
+ this.rulePath = rulePath;
13206
+ this.name = "DirectoryRuleNotFoundError";
13207
+ }
13208
+ rulePath;
13209
+ };
13210
+ var DirectoryRuleMissingTargetError = class extends CliError {
13211
+ constructor() {
13212
+ super("A directory rule must set at least one of --config-profile or --identity.");
13213
+ this.name = "DirectoryRuleMissingTargetError";
13214
+ }
13215
+ };
13216
+ var DirectoryRuleAlreadyExistsError = class extends CliError {
13217
+ constructor(rulePath) {
13218
+ super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
13219
+ this.rulePath = rulePath;
13220
+ this.name = "DirectoryRuleAlreadyExistsError";
13221
+ }
13222
+ rulePath;
13223
+ };
13224
+ function readDirectoryRules(paths) {
13225
+ return readJson(paths.directoryRulesFile, DirectoryRulesSchema) ?? { rules: [] };
13226
+ }
13227
+ function writeDirectoryRules(paths, rules) {
13228
+ const parsed = DirectoryRulesSchema.safeParse(rules);
13229
+ if (!parsed.success) {
13230
+ throw new ConfigValidationError(paths.directoryRulesFile, parsed.error.issues);
13231
+ }
13232
+ writeJsonAtomic(paths.directoryRulesFile, parsed.data);
13233
+ }
13234
+ function listDirectoryRules(paths) {
13235
+ return readDirectoryRules(paths).rules;
13236
+ }
13237
+ function addDirectoryRule(paths, rulePath, options) {
13238
+ if (options.configProfile === void 0 && options.identity === void 0) {
13239
+ throw new DirectoryRuleMissingTargetError();
13240
+ }
13241
+ const current = readDirectoryRules(paths);
13242
+ if (current.rules.some((rule) => rule.path === rulePath)) {
13243
+ throw new DirectoryRuleAlreadyExistsError(rulePath);
13244
+ }
13245
+ const created = buildNewRule(rulePath, options);
13246
+ writeDirectoryRules(paths, { ...current, rules: [...current.rules, created] });
13247
+ return created;
13248
+ }
13249
+ function ruleHasEffect(rule) {
13250
+ return rule.configProfile !== void 0 || rule.identity !== void 0 || rule.categories !== void 0 || rule.entries !== void 0 || rule.launch !== void 0;
13251
+ }
13252
+ function updateDirectoryRule(paths, rulePath, options) {
13253
+ const current = readDirectoryRules(paths);
13254
+ const index = current.rules.findIndex((rule) => rule.path === rulePath);
13255
+ const existing = index === -1 ? void 0 : current.rules[index];
13256
+ if (existing === void 0) {
13257
+ throw new DirectoryRuleNotFoundError(rulePath);
13258
+ }
13259
+ const { configProfile, identity, ...rest } = existing;
13260
+ const nextConfigProfile = options.configProfile === void 0 ? configProfile : options.configProfile === false ? void 0 : options.configProfile;
13261
+ const nextIdentity = options.identity === void 0 ? identity : options.identity === false ? void 0 : options.identity;
13262
+ const updated = {
13263
+ ...rest,
13264
+ ...nextConfigProfile === void 0 ? {} : { configProfile: nextConfigProfile },
13265
+ ...nextIdentity === void 0 ? {} : { identity: nextIdentity }
13266
+ };
13267
+ if (!ruleHasEffect(updated)) {
13268
+ throw new DirectoryRuleMissingTargetError();
13269
+ }
13270
+ const nextRules = [...current.rules];
13271
+ nextRules[index] = updated;
13272
+ writeDirectoryRules(paths, { ...current, rules: nextRules });
13273
+ return updated;
13274
+ }
13275
+ function buildNewRule(rulePath, options) {
13276
+ return {
13277
+ path: rulePath,
13278
+ ...options.configProfile !== void 0 ? { configProfile: options.configProfile } : {},
13279
+ ...options.identity !== void 0 ? { identity: options.identity } : {}
13280
+ };
13281
+ }
13282
+ function removeDirectoryRule(paths, rulePath) {
13283
+ const current = readDirectoryRules(paths);
13284
+ const nextRules = current.rules.filter((rule) => rule.path !== rulePath);
13285
+ if (nextRules.length === current.rules.length) {
13286
+ throw new DirectoryRuleNotFoundError(rulePath);
13287
+ }
13288
+ writeDirectoryRules(paths, { ...current, rules: nextRules });
13289
+ }
13290
+ function requireRuleSelector(paths, selector) {
13291
+ if (selector.startsWith(POOL_SELECTOR_PREFIX)) {
13292
+ const poolName = selector.slice(POOL_SELECTOR_PREFIX.length);
13293
+ if (readPools(paths)[poolName] === void 0) {
13294
+ throw new PoolNotFoundError(poolName);
13295
+ }
13296
+ } else if (readIdentity(paths, selector) === void 0) {
13297
+ throw new IdentityNotFoundError(selector);
13298
+ }
13299
+ }
13300
+
13301
+ // src/frontdoor/configApi.ts
13302
+ init_identity();
13303
+ init_providersStore();
13304
+
13305
+ // src/frontdoor/configSchemas.ts
13306
+ var import_zod20 = require("zod");
13307
+ init_schema();
13308
+ var RemovalConfirmationSchema = import_zod20.z.boolean();
13309
+ var CredentialWriteSchema = (targets) => import_zod20.z.strictObject({
13310
+ sources: import_zod20.z.array(RemoteCredentialSourceSchema).min(1).optional(),
13311
+ target: import_zod20.z.enum(targets).optional(),
13312
+ cache: import_zod20.z.union([import_zod20.z.literal(false), CredentialCacheSchema]).optional()
13313
+ });
13314
+ var CredentialSummarySchema2 = import_zod20.z.strictObject({
13315
+ target: import_zod20.z.enum(CREDENTIAL_TARGETS),
13316
+ sources: import_zod20.z.readonly(import_zod20.z.array(
13317
+ import_zod20.z.discriminatedUnion("kind", [
13318
+ import_zod20.z.strictObject({ kind: import_zod20.z.literal("env"), variable: import_zod20.z.string() }),
13319
+ import_zod20.z.strictObject({ kind: import_zod20.z.literal("file"), path: import_zod20.z.string() }),
13320
+ import_zod20.z.strictObject({ kind: import_zod20.z.literal("command"), program: import_zod20.z.string() }),
13321
+ import_zod20.z.strictObject({ kind: import_zod20.z.literal("op"), reference: import_zod20.z.string() }),
13322
+ import_zod20.z.strictObject({ kind: import_zod20.z.literal("keychain"), service: import_zod20.z.string(), account: import_zod20.z.string().optional() }),
13323
+ import_zod20.z.strictObject({ kind: import_zod20.z.literal("literal") })
13324
+ ])
13325
+ )),
13326
+ cache: CredentialCacheSchema.optional()
13327
+ });
13328
+ var mutationOutput = (kind, action) => import_zod20.z.strictObject({ action: import_zod20.z.literal(action), kind: import_zod20.z.literal(kind), name: import_zod20.z.string() });
13329
+ var storedMutationOutput = (kind, action, value) => import_zod20.z.strictObject({ action: import_zod20.z.literal(action), kind: import_zod20.z.literal(kind), name: import_zod20.z.string(), value });
13330
+ var IdentityValueSchema = import_zod20.z.strictObject({
13331
+ name: import_zod20.z.string(),
13332
+ defaultConfigProfile: import_zod20.z.string().optional(),
13333
+ allowAmbientCredential: import_zod20.z.boolean(),
13334
+ credential: CredentialSummarySchema2.optional()
13335
+ });
13336
+ var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
13337
+ var ProviderValueSchema = import_zod20.z.strictObject({
13338
+ name: import_zod20.z.string(),
13339
+ kind: import_zod20.z.enum(PROVIDER_KINDS),
13340
+ displayName: import_zod20.z.string(),
13341
+ baseUrl: import_zod20.z.string().optional(),
13342
+ codex: CodexProviderConfigSchema.optional(),
13343
+ credential: CredentialSummarySchema2,
13344
+ env: import_zod20.z.record(import_zod20.z.string(), import_zod20.z.string()).optional()
13345
+ });
13346
+ var ConfigNameInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1) });
13347
+ var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created", IdentityValueSchema);
13348
+ var ConfigIdentitySetInputSchema = import_zod20.z.strictObject({
13349
+ name: import_zod20.z.string().min(1),
13350
+ defaultConfigProfile: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional(),
13351
+ allowAmbientCredential: import_zod20.z.boolean().optional(),
13352
+ credential: import_zod20.z.union([import_zod20.z.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional()
13353
+ });
13354
+ var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
13355
+ var ConfigIdentityRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
13356
+ var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
13357
+ var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
13358
+ var ConfigProfileAddInputSchema = import_zod20.z.strictObject({
13359
+ name: import_zod20.z.string().min(1),
13360
+ extends: import_zod20.z.array(import_zod20.z.string().min(1)).optional(),
13361
+ description: import_zod20.z.string().optional()
13362
+ });
13363
+ var ConfigProfileAddOutputSchema = storedMutationOutput("profile", "created", ProfileValueSchema);
13364
+ var ConfigProfileSetInputSchema = import_zod20.z.strictObject({
13365
+ name: import_zod20.z.string().min(1),
13366
+ category: import_zod20.z.record(import_zod20.z.string(), import_zod20.z.boolean()).optional(),
13367
+ entry: import_zod20.z.record(import_zod20.z.string(), import_zod20.z.boolean()).optional(),
13368
+ extends: import_zod20.z.union([import_zod20.z.array(import_zod20.z.string().min(1)), import_zod20.z.literal(false)]).optional(),
13369
+ description: import_zod20.z.union([import_zod20.z.string(), import_zod20.z.literal(false)]).optional(),
13370
+ launch: import_zod20.z.strictObject({
13371
+ skipPermissions: import_zod20.z.boolean().optional(),
13372
+ remoteControl: import_zod20.z.boolean().optional(),
13373
+ headroom: import_zod20.z.boolean().optional(),
13374
+ trackUsage: import_zod20.z.boolean().optional(),
13375
+ provider: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional(),
13376
+ claudeVersion: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional()
13377
+ }).optional()
13378
+ });
13379
+ var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
13380
+ var ConfigProfileRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
13381
+ var ConfigProfileRemoveOutputSchema = mutationOutput("profile", "removed");
13382
+ var ConfigProfileUseOutputSchema = mutationOutput("profile", "selected");
13383
+ var PoolMembersInputSchema = import_zod20.z.array(import_zod20.z.string().min(1)).min(1);
13384
+ var ConfigPoolAddInputSchema = import_zod20.z.strictObject({
13385
+ name: import_zod20.z.string().min(1),
13386
+ identities: PoolMembersInputSchema,
13387
+ preference: import_zod20.z.enum(POOL_PREFERENCES).optional()
13388
+ });
13389
+ var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
13390
+ var ConfigPoolSetInputSchema = import_zod20.z.strictObject({
13391
+ name: import_zod20.z.string().min(1),
13392
+ identities: PoolMembersInputSchema.optional(),
13393
+ preference: import_zod20.z.union([import_zod20.z.enum(POOL_PREFERENCES), import_zod20.z.literal(false)]).optional()
13394
+ });
13395
+ var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
13396
+ var ConfigPoolRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
13397
+ var ConfigPoolRemoveOutputSchema = mutationOutput("pool", "removed");
13398
+ var ConfigPoolUseOutputSchema = mutationOutput("pool", "selected");
13399
+ var ConfigProviderAddInputSchema = import_zod20.z.strictObject({
13400
+ name: import_zod20.z.string().min(1),
13401
+ kind: import_zod20.z.enum(PROVIDER_KINDS).optional(),
13402
+ displayName: import_zod20.z.string().min(1),
13403
+ baseUrl: import_zod20.z.string().min(1).optional(),
13404
+ credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).required({ sources: true }),
13405
+ codex: CodexProviderConfigSchema.optional()
13406
+ });
13407
+ var ConfigProviderAddOutputSchema = storedMutationOutput("provider", "created", ProviderValueSchema);
13408
+ var ConfigProviderSetInputSchema = import_zod20.z.strictObject({
13409
+ name: import_zod20.z.string().min(1),
13410
+ displayName: import_zod20.z.string().min(1).optional(),
13411
+ baseUrl: import_zod20.z.string().min(1).optional(),
13412
+ credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).optional(),
13413
+ codex: CodexProviderConfigSchema.optional()
13414
+ });
13415
+ var ConfigProviderSetOutputSchema = storedMutationOutput("provider", "updated", ProviderValueSchema);
13416
+ var ConfigProviderRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
13417
+ var ConfigProviderRemoveOutputSchema = mutationOutput("provider", "removed");
13418
+ var ConfigRuleAddInputSchema = import_zod20.z.strictObject({
13419
+ path: import_zod20.z.string().min(1),
13420
+ configProfile: import_zod20.z.string().min(1).optional(),
13421
+ identity: import_zod20.z.string().min(1).optional()
13422
+ });
13423
+ var ConfigRuleAddOutputSchema = storedMutationOutput("rule", "created", DirectoryRuleSchema);
13424
+ var ConfigRuleSetInputSchema = import_zod20.z.strictObject({
13425
+ path: import_zod20.z.string().min(1),
13426
+ configProfile: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional(),
13427
+ identity: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional()
13428
+ });
13429
+ var ConfigRuleSetOutputSchema = storedMutationOutput("rule", "updated", DirectoryRuleSchema);
13430
+ var ConfigRuleRemoveInputSchema = import_zod20.z.strictObject({ path: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
13431
+ var ConfigRuleRemoveOutputSchema = mutationOutput("rule", "removed");
13432
+
13433
+ // src/frontdoor/configApi.ts
13434
+ var CONFIG_API_TAG = "config";
13435
+ function refusal(error) {
13436
+ if (error instanceof IdentityNotFoundError || error instanceof ProfileNotFoundError || error instanceof PoolNotFoundError || error instanceof ProviderNotFoundError || error instanceof DirectoryRuleNotFoundError) {
13437
+ throw new import_client2.ORPCError("NOT_FOUND", { message: error.message });
13438
+ }
13439
+ if (error instanceof IdentityAlreadyExistsError || error instanceof ProfileAlreadyExistsError || error instanceof PoolAlreadyExistsError || error instanceof ProviderAlreadyExistsError || error instanceof DirectoryRuleAlreadyExistsError) {
13440
+ throw new import_client2.ORPCError("CONFLICT", { message: error.message });
13441
+ }
13442
+ if (error instanceof CliError) {
13443
+ throw new import_client2.ORPCError("BAD_REQUEST", { message: error.message });
13444
+ }
13445
+ throw error;
13446
+ }
13447
+ function guarded(write) {
13448
+ try {
13449
+ return write();
13450
+ } catch (error) {
13451
+ return refusal(error);
13452
+ }
13453
+ }
13454
+ function requireConfirmation(confirm, what) {
13455
+ if (!confirm) {
13456
+ throw new import_client2.ORPCError("BAD_REQUEST", { message: `removing ${what} needs confirm: true, the API's form of the CLI's --yes` });
13457
+ }
13458
+ }
13459
+ function requireChange(given, fields) {
13460
+ if (!given) {
13461
+ throw new import_client2.ORPCError("BAD_REQUEST", { message: `Nothing to change: pass ${fields}.` });
13462
+ }
13463
+ }
13464
+ function identityValue(name, paths) {
13465
+ const identity = readIdentity(paths, name);
13466
+ if (identity === void 0) {
13467
+ throw new IdentityNotFoundError(name);
13468
+ }
13469
+ return {
13470
+ name: identity.name,
13471
+ ...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
13472
+ allowAmbientCredential: identity.allowAmbientCredential,
13473
+ ...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) }
13474
+ };
13475
+ }
13476
+ function providerValue(name, provider) {
13477
+ return {
13478
+ name,
13479
+ kind: provider.kind ?? "http",
13480
+ displayName: provider.displayName,
13481
+ ...isCodexProvider(provider) ? provider.codex === void 0 ? {} : { codex: provider.codex } : { baseUrl: provider.baseUrl },
13482
+ credential: summariseCredential(provider.credential),
13483
+ ...provider.env === void 0 ? {} : { env: provider.env }
13484
+ };
13485
+ }
13486
+ function profileValue(name, paths) {
13487
+ const profile = { ...readProfile(paths, name) };
13488
+ delete profile.$schema;
13489
+ return profile;
13490
+ }
13491
+ function createConfigApiRouter(deps) {
13492
+ const authed = doorApiAuth(deps.expectedToken);
13493
+ const { paths } = deps;
13494
+ const route = (path36, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path36, summary, tags: [CONFIG_API_TAG] }));
13495
+ return {
13496
+ config: {
13497
+ identity: {
13498
+ add: route("/rest/config/identity/add", "Create an identity").input(ConfigNameInputSchema).output(ConfigIdentityAddOutputSchema).handler(
13499
+ ({ input }) => guarded(() => {
13500
+ addIdentity(paths, input.name);
13501
+ return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
13502
+ })
13503
+ ),
13504
+ set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting or credential").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
13505
+ ({ input }) => guarded(() => {
13506
+ requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0, "defaultConfigProfile, allowAmbientCredential or credential");
13507
+ if (!identityExists(paths, input.name)) {
13508
+ throw new IdentityNotFoundError(input.name);
13509
+ }
13510
+ if (typeof input.defaultConfigProfile === "string") {
13511
+ requireProfileExists(paths, input.defaultConfigProfile);
13512
+ }
13513
+ if (input.defaultConfigProfile !== void 0) {
13514
+ setDefaultConfigProfile(paths, input.name, input.defaultConfigProfile === false ? void 0 : input.defaultConfigProfile);
13515
+ }
13516
+ if (input.allowAmbientCredential !== void 0) {
13517
+ setAllowAmbientCredential(paths, input.name, input.allowAmbientCredential);
13518
+ }
13519
+ if (input.credential === false) {
13520
+ setIdentityCredential(paths, input.name, false);
13521
+ } else if (input.credential !== void 0) {
13522
+ const { sources, target, cache } = input.credential;
13523
+ const merged = cache === void 0 ? void 0 : mergeCredentialCache(cache === false ? { enabled: false } : { ...cache, enabled: true }, readIdentity(paths, input.name)?.credential?.cache);
13524
+ const change = {
13525
+ ...sources === void 0 ? {} : { sources },
13526
+ ...target === void 0 ? {} : { target },
13527
+ ...merged === void 0 ? {} : { cache: merged }
13528
+ };
13529
+ setIdentityCredential(paths, input.name, change);
13530
+ }
13531
+ return { action: "updated", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
13532
+ })
13533
+ ),
13534
+ remove: route("/rest/config/identity/remove", "Delete an identity and its directory").input(ConfigIdentityRemoveInputSchema).output(ConfigIdentityRemoveOutputSchema).handler(({ input }) => {
13535
+ requireConfirmation(input.confirm, `identity "${input.name}" and its directory`);
13536
+ return guarded(() => {
13537
+ removeIdentity(paths, input.name);
13538
+ return { action: "removed", kind: "identity", name: input.name };
13539
+ });
13540
+ }),
13541
+ use: route("/rest/config/identity/use", "Select the active identity").input(ConfigNameInputSchema).output(ConfigIdentityUseOutputSchema).handler(
13542
+ ({ input }) => guarded(() => {
13543
+ if (poolNameOf(input.name) === void 0 && !identityExists(paths, input.name)) {
13544
+ throw new IdentityNotFoundError(input.name);
13545
+ }
13546
+ useIdentity(paths, input.name);
13547
+ return { action: "selected", kind: "identity", name: input.name };
13548
+ })
13549
+ )
13550
+ },
13551
+ profile: {
13552
+ add: route("/rest/config/profile/add", "Create a configuration profile").input(ConfigProfileAddInputSchema).output(ConfigProfileAddOutputSchema).handler(
13553
+ ({ input }) => guarded(() => {
13554
+ createProfile(paths, input.name, input.extends, input.description);
13555
+ return { action: "created", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
13556
+ })
13557
+ ),
13558
+ set: route("/rest/config/profile/set", "Update a configuration profile's categories, entries, extends list, description or launch settings").input(ConfigProfileSetInputSchema).output(ConfigProfileSetOutputSchema).handler(
13559
+ ({ input }) => guarded(() => {
13560
+ const { launch } = input;
13561
+ requireChange(
13562
+ input.category !== void 0 || input.entry !== void 0 || input.extends !== void 0 || input.description !== void 0 || launch !== void 0,
13563
+ "category, entry, extends, description or launch"
13564
+ );
13565
+ requireProfileExists(paths, input.name);
13566
+ applyProfileChange(paths, input.name, {
13567
+ ...input.category === void 0 ? {} : { category: input.category },
13568
+ ...input.entry === void 0 ? {} : { entry: input.entry },
13569
+ ...input.extends === void 0 ? {} : { extends: input.extends },
13570
+ ...input.description === void 0 ? {} : { description: input.description },
13571
+ ...launch?.skipPermissions === void 0 ? {} : { launchSkipPermissions: launch.skipPermissions },
13572
+ ...launch?.remoteControl === void 0 ? {} : { launchRemoteControl: launch.remoteControl },
13573
+ ...launch?.headroom === void 0 ? {} : { launchHeadroom: launch.headroom },
13574
+ ...launch?.trackUsage === void 0 ? {} : { launchTrackUsage: launch.trackUsage },
13575
+ ...launch?.provider === void 0 ? {} : { launchProvider: launch.provider },
13576
+ ...launch?.claudeVersion === void 0 ? {} : { launchClaudeVersion: launch.claudeVersion }
13577
+ });
13578
+ return { action: "updated", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
13579
+ })
13580
+ ),
13581
+ remove: route("/rest/config/profile/remove", "Delete a configuration profile").input(ConfigProfileRemoveInputSchema).output(ConfigProfileRemoveOutputSchema).handler(({ input }) => {
13582
+ requireConfirmation(input.confirm, `configuration profile "${input.name}"`);
13583
+ return guarded(() => {
13584
+ removeProfile(paths, input.name);
13585
+ return { action: "removed", kind: "profile", name: input.name };
13586
+ });
13587
+ }),
13588
+ use: route("/rest/config/profile/use", "Make a configuration profile the global default").input(ConfigNameInputSchema).output(ConfigProfileUseOutputSchema).handler(
13589
+ ({ input }) => guarded(() => {
13590
+ requireProfileExists(paths, input.name);
13591
+ setGlobalDefaultProfile(paths, input.name);
13592
+ return { action: "selected", kind: "profile", name: input.name };
13593
+ })
13594
+ )
13595
+ },
13596
+ pool: {
13597
+ add: route("/rest/config/pool/add", "Define a pool").input(ConfigPoolAddInputSchema).output(ConfigPoolAddOutputSchema).handler(
13598
+ ({ input }) => guarded(() => {
13599
+ requireIdentityNames(paths, input.identities);
13600
+ const created = addPool(paths, input.name, input.identities, input.preference);
13601
+ return { action: "created", kind: "pool", name: input.name, value: created };
13602
+ })
13603
+ ),
13604
+ set: route("/rest/config/pool/set", "Replace a pool's members, its preference or both").input(ConfigPoolSetInputSchema).output(ConfigPoolSetOutputSchema).handler(
13605
+ ({ input }) => guarded(() => {
13606
+ requireChange(input.identities !== void 0 || input.preference !== void 0, "identities or preference");
13607
+ const existing = requirePool(paths, input.name);
13608
+ if (input.identities !== void 0) {
13609
+ requireIdentityNames(paths, input.identities);
13610
+ }
13611
+ const members = input.identities ?? existing.identities;
13612
+ const preference = input.preference === void 0 ? existing.preference : input.preference === false ? void 0 : input.preference;
13613
+ return { action: "updated", kind: "pool", name: input.name, value: setPool(paths, input.name, members, preference) };
13614
+ })
13615
+ ),
13616
+ remove: route("/rest/config/pool/remove", "Delete a pool").input(ConfigPoolRemoveInputSchema).output(ConfigPoolRemoveOutputSchema).handler(({ input }) => {
13617
+ requireConfirmation(input.confirm, `pool "${input.name}"`);
13618
+ return guarded(() => {
13619
+ removePool(paths, input.name);
13620
+ return { action: "removed", kind: "pool", name: input.name };
13621
+ });
13622
+ }),
13623
+ use: route("/rest/config/pool/use", "Make launches with no other selection pick a member of a pool").input(ConfigNameInputSchema).output(ConfigPoolUseOutputSchema).handler(
13624
+ ({ input }) => guarded(() => {
13625
+ if (readPools(paths)[input.name] === void 0) {
13626
+ throw new PoolNotFoundError(input.name);
13627
+ }
13628
+ useIdentity(paths, `pool:${input.name}`);
13629
+ return { action: "selected", kind: "pool", name: input.name };
13630
+ })
13631
+ )
13632
+ },
13633
+ provider: {
13634
+ add: route("/rest/config/provider/add", "Create an API provider definition").input(ConfigProviderAddInputSchema).output(ConfigProviderAddOutputSchema).handler(
13635
+ ({ input }) => guarded(() => {
13636
+ const created = addProvider(paths, input.name, {
13637
+ ...input.kind === void 0 ? {} : { kind: input.kind },
13638
+ displayName: input.displayName,
13639
+ ...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl },
13640
+ sources: input.credential.sources,
13641
+ ...input.credential.target === void 0 ? {} : { target: input.credential.target },
13642
+ ...input.codex === void 0 ? {} : { codex: input.codex }
13643
+ });
13644
+ const cache = input.credential.cache;
13645
+ const stored = cache === void 0 || cache === false ? created : updateProvider(paths, input.name, { cache });
13646
+ return { action: "created", kind: "provider", name: input.name, value: providerValue(input.name, stored) };
13647
+ })
13648
+ ),
13649
+ set: route("/rest/config/provider/set", "Update an API provider definition").input(ConfigProviderSetInputSchema).output(ConfigProviderSetOutputSchema).handler(
13650
+ ({ input }) => guarded(() => {
13651
+ requireChange(input.displayName !== void 0 || input.baseUrl !== void 0 || input.credential !== void 0 || input.codex !== void 0, "displayName, baseUrl, credential or codex");
13652
+ const existing = readProvider(paths, input.name);
13653
+ if (existing === void 0) {
13654
+ throw new ProviderNotFoundError(input.name);
13655
+ }
13656
+ const credential = input.credential;
13657
+ if (input.baseUrl !== void 0 && !isCodexProvider(existing) && input.baseUrl !== existing.baseUrl && credential?.sources === void 0) {
13658
+ throw new import_client2.ORPCError("BAD_REQUEST", { message: `Changing the base URL of provider "${input.name}" requires a credential block in the same call: the stored credential is not sent to a different endpoint.` });
13659
+ }
13660
+ const cache = credential?.cache === void 0 ? void 0 : mergeCredentialCache(credential.cache === false ? { enabled: false } : { ...credential.cache, enabled: true }, existing.credential.cache);
13661
+ const updated = updateProvider(paths, input.name, {
13662
+ ...input.displayName === void 0 ? {} : { displayName: input.displayName },
13663
+ ...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl },
13664
+ ...credential?.sources === void 0 ? {} : { sources: credential.sources },
13665
+ ...credential?.target === void 0 ? {} : { target: credential.target },
13666
+ ...cache === void 0 ? {} : { cache },
13667
+ ...input.codex === void 0 ? {} : { codex: input.codex }
13668
+ });
13669
+ return { action: "updated", kind: "provider", name: input.name, value: providerValue(input.name, updated) };
13670
+ })
13671
+ ),
13672
+ remove: route("/rest/config/provider/remove", "Delete an API provider definition").input(ConfigProviderRemoveInputSchema).output(ConfigProviderRemoveOutputSchema).handler(({ input }) => {
13673
+ requireConfirmation(input.confirm, `provider "${input.name}"`);
13674
+ return guarded(() => {
13675
+ if (!providerExists(paths, input.name)) {
13676
+ throw new ProviderNotFoundError(input.name);
13677
+ }
13678
+ removeProvider(paths, input.name);
13679
+ return { action: "removed", kind: "provider", name: input.name };
13680
+ });
13681
+ })
13682
+ },
13683
+ rule: {
13684
+ add: route("/rest/config/rule/add", "Add a directory rule for a path").input(ConfigRuleAddInputSchema).output(ConfigRuleAddOutputSchema).handler(
13685
+ ({ input }) => guarded(() => {
13686
+ if (input.identity !== void 0) {
13687
+ requireRuleSelector(paths, input.identity);
13688
+ }
13689
+ if (input.configProfile !== void 0) {
13690
+ requireProfileExists(paths, input.configProfile);
13691
+ }
13692
+ const created = addDirectoryRule(paths, input.path, {
13693
+ ...input.configProfile === void 0 ? {} : { configProfile: input.configProfile },
13694
+ ...input.identity === void 0 ? {} : { identity: input.identity }
13695
+ });
13696
+ return { action: "created", kind: "rule", name: input.path, value: created };
13697
+ })
13698
+ ),
13699
+ set: route("/rest/config/rule/set", "Update the directory rule for a path").input(ConfigRuleSetInputSchema).output(ConfigRuleSetOutputSchema).handler(
13700
+ ({ input }) => guarded(() => {
13701
+ requireChange(input.configProfile !== void 0 || input.identity !== void 0, "configProfile or identity");
13702
+ if (typeof input.identity === "string") {
13703
+ requireRuleSelector(paths, input.identity);
13704
+ }
13705
+ if (typeof input.configProfile === "string") {
13706
+ requireProfileExists(paths, input.configProfile);
13707
+ }
13708
+ const updated = updateDirectoryRule(paths, input.path, {
13709
+ ...input.configProfile === void 0 ? {} : { configProfile: input.configProfile },
13710
+ ...input.identity === void 0 ? {} : { identity: input.identity }
13711
+ });
13712
+ return { action: "updated", kind: "rule", name: input.path, value: updated };
13713
+ })
13714
+ ),
13715
+ remove: route("/rest/config/rule/remove", "Remove the directory rule for a path").input(ConfigRuleRemoveInputSchema).output(ConfigRuleRemoveOutputSchema).handler(({ input }) => {
13716
+ requireConfirmation(input.confirm, `the directory rule for "${input.path}"`);
13717
+ return guarded(() => {
13718
+ if (!listDirectoryRules(paths).some((entry) => entry.path === input.path)) {
13719
+ throw new DirectoryRuleNotFoundError(input.path);
13720
+ }
13721
+ removeDirectoryRule(paths, input.path);
13722
+ return { action: "removed", kind: "rule", name: input.path };
13723
+ });
13724
+ })
13725
+ }
13726
+ }
13727
+ };
13728
+ }
13729
+
13730
+ // src/frontdoor/eventsApi.ts
13731
+ var import_client3 = require("@orpc/client");
13732
+ var import_openapi4 = require("@orpc/openapi");
13072
13733
  var import_server3 = require("@orpc/server");
13073
13734
 
13074
13735
  // src/frontdoor/eventSchemas.ts
13075
- var import_zod20 = require("zod");
13736
+ var import_zod21 = require("zod");
13076
13737
  var DOOR_EVENT_SOURCE_RC = "rc";
13077
13738
  var LAUNCH_EVENT_SOURCE = "launch";
13078
13739
  var USAGE_EVENT_SOURCE = "usage";
13079
13740
  var DOOR_HEALTH_EVENT_SOURCE = "door";
13080
13741
  var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
13081
- var DoorEventSchema = import_zod20.z.strictObject({
13082
- source: import_zod20.z.string().min(1),
13742
+ var DoorEventSchema = import_zod21.z.strictObject({
13743
+ source: import_zod21.z.string().min(1),
13083
13744
  /** A positive integer because the backbone's counters start at one and only ever increase. */
13084
- sequence: import_zod20.z.number().int().positive(),
13085
- payload: import_zod20.z.unknown()
13086
- });
13087
- var DoorEventSourceQuerySchema = import_zod20.z.strictObject({
13088
- sources: import_zod20.z.array(import_zod20.z.string().min(1)).min(1).optional()
13089
- });
13090
- var LaunchLifecycleEventSchema = import_zod20.z.strictObject({
13091
- kind: import_zod20.z.enum(["registered", "pruned", "ended"]),
13092
- pid: import_zod20.z.number().int().positive(),
13093
- startedAt: import_zod20.z.number(),
13094
- observedAt: import_zod20.z.number()
13095
- });
13096
- var DoorHealthEventSchema = import_zod20.z.discriminatedUnion("kind", [
13097
- import_zod20.z.strictObject({ kind: import_zod20.z.literal("generation"), pid: import_zod20.z.number().int().positive(), providerPort: import_zod20.z.number().int().positive(), connectPort: import_zod20.z.number().int().positive(), directPort: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() }),
13098
- import_zod20.z.strictObject({ kind: import_zod20.z.literal("listenerFailed"), pid: import_zod20.z.number().int().positive(), listener: import_zod20.z.enum(["provider", "connect", "direct"]), message: import_zod20.z.string(), observedAt: import_zod20.z.number() }),
13099
- import_zod20.z.strictObject({ kind: import_zod20.z.literal("binaryTurnover"), pid: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() }),
13100
- import_zod20.z.strictObject({ kind: import_zod20.z.literal("idleShutdown"), pid: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() })
13745
+ sequence: import_zod21.z.number().int().positive(),
13746
+ payload: import_zod21.z.unknown()
13747
+ });
13748
+ var DoorEventSourceQuerySchema = import_zod21.z.strictObject({
13749
+ sources: import_zod21.z.array(import_zod21.z.string().min(1)).min(1).optional()
13750
+ });
13751
+ var LaunchLifecycleEventSchema = import_zod21.z.strictObject({
13752
+ kind: import_zod21.z.enum(["registered", "pruned", "ended"]),
13753
+ pid: import_zod21.z.number().int().positive(),
13754
+ startedAt: import_zod21.z.number(),
13755
+ observedAt: import_zod21.z.number()
13756
+ });
13757
+ var DoorHealthEventSchema = import_zod21.z.discriminatedUnion("kind", [
13758
+ import_zod21.z.strictObject({ kind: import_zod21.z.literal("generation"), pid: import_zod21.z.number().int().positive(), providerPort: import_zod21.z.number().int().positive(), connectPort: import_zod21.z.number().int().positive(), directPort: import_zod21.z.number().int().positive(), observedAt: import_zod21.z.number() }),
13759
+ import_zod21.z.strictObject({ kind: import_zod21.z.literal("listenerFailed"), pid: import_zod21.z.number().int().positive(), listener: import_zod21.z.enum(["provider", "connect", "direct"]), message: import_zod21.z.string(), observedAt: import_zod21.z.number() }),
13760
+ import_zod21.z.strictObject({ kind: import_zod21.z.literal("binaryTurnover"), pid: import_zod21.z.number().int().positive(), observedAt: import_zod21.z.number() }),
13761
+ import_zod21.z.strictObject({ kind: import_zod21.z.literal("idleShutdown"), pid: import_zod21.z.number().int().positive(), observedAt: import_zod21.z.number() })
13101
13762
  ]);
13102
- var QuotaExpiringEventSchema = import_zod20.z.strictObject({
13103
- identity: import_zod20.z.string().min(1),
13104
- provider: import_zod20.z.string().min(1),
13105
- window: import_zod20.z.enum(["fiveHour", "sevenDay"]),
13763
+ var QuotaExpiringEventSchema = import_zod21.z.strictObject({
13764
+ identity: import_zod21.z.string().min(1),
13765
+ provider: import_zod21.z.string().min(1),
13766
+ window: import_zod21.z.enum(["fiveHour", "sevenDay"]),
13106
13767
  /** The fraction of the window already used when it was seen expiring, always below one because a fully used window has nothing left to spend. */
13107
- utilization: import_zod20.z.number().min(0).max(1),
13108
- resetsAt: import_zod20.z.iso.datetime(),
13109
- observedAt: import_zod20.z.number()
13768
+ utilization: import_zod21.z.number().min(0).max(1),
13769
+ resetsAt: import_zod21.z.iso.datetime(),
13770
+ observedAt: import_zod21.z.number()
13110
13771
  });
13111
13772
 
13112
13773
  // src/frontdoor/eventsApi.ts
@@ -13115,12 +13776,12 @@ function createEventsApiRouter(deps) {
13115
13776
  const authed = doorApiAuth(deps.expectedToken);
13116
13777
  return {
13117
13778
  events: {
13118
- subscribe: authed.meta((0, import_openapi3.openapi)({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] })).input(DoorEventSourceQuerySchema).output((0, import_server3.eventIterator)(DoorEventSchema)).handler(async function* ({ input, signal }) {
13779
+ subscribe: authed.meta((0, import_openapi4.openapi)({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] })).input(DoorEventSourceQuerySchema).output((0, import_server3.eventIterator)(DoorEventSchema)).handler(async function* ({ input, signal }) {
13119
13780
  if (input.sources !== void 0) {
13120
13781
  const live = deps.events.sources();
13121
13782
  const unknown = input.sources.filter((source) => !live.includes(source));
13122
13783
  if (unknown.length > 0) {
13123
- throw new import_client2.ORPCError("NOT_FOUND", { message: `the door publishes no event source named ${unknown.map((source) => `"${source}"`).join(", ")}; the live sources are ${live.map((source) => `"${source}"`).join(", ")}` });
13784
+ throw new import_client3.ORPCError("NOT_FOUND", { message: `the door publishes no event source named ${unknown.map((source) => `"${source}"`).join(", ")}; the live sources are ${live.map((source) => `"${source}"`).join(", ")}` });
13124
13785
  }
13125
13786
  }
13126
13787
  const stream = deps.events.stream(input.sources);
@@ -13148,8 +13809,8 @@ function createEventsApiRouter(deps) {
13148
13809
  }
13149
13810
 
13150
13811
  // src/frontdoor/lifecycleApi.ts
13151
- var import_client3 = require("@orpc/client");
13152
- var import_openapi4 = require("@orpc/openapi");
13812
+ var import_client4 = require("@orpc/client");
13813
+ var import_openapi5 = require("@orpc/openapi");
13153
13814
  init_update();
13154
13815
  var FRONTDOOR_API_TAG = "frontdoor";
13155
13816
  var UPDATE_API_TAG = "update";
@@ -13157,24 +13818,24 @@ function createLifecycleApiRouter(deps) {
13157
13818
  const authed = doorApiAuth(deps.expectedToken);
13158
13819
  return {
13159
13820
  frontdoor: {
13160
- restart: authed.meta((0, import_openapi4.openapi)({ method: "POST", path: "/rest/frontdoor/restart", summary: "Replace the serving front door in place", description: "Answers with the pid of the door being replaced, then replaces it. The replacement is a new generation with its own control token: the caller reopens its client from the state root once the door's supervisor pid differs from the one returned.", tags: [FRONTDOOR_API_TAG] })).output(FrontDoorRestartOutputSchema).handler(({ context }) => {
13821
+ restart: authed.meta((0, import_openapi5.openapi)({ method: "POST", path: "/rest/frontdoor/restart", summary: "Replace the serving front door in place", description: "Answers with the pid of the door being replaced, then replaces it. The replacement is a new generation with its own control token: the caller reopens its client from the state root once the door's supervisor pid differs from the one returned.", tags: [FRONTDOOR_API_TAG] })).output(FrontDoorRestartOutputSchema).handler(({ context }) => {
13161
13822
  context.afterResponse(deps.restartDoor);
13162
13823
  return { action: "restarting", previousPid: deps.doorPid };
13163
13824
  })
13164
13825
  },
13165
13826
  update: {
13166
- check: authed.meta((0, import_openapi4.openapi)({ method: "GET", path: "/rest/update/check", summary: "Check whether a newer release exists", tags: [UPDATE_API_TAG] })).output(UpdateCheckOutputSchema).handler(async () => {
13827
+ check: authed.meta((0, import_openapi5.openapi)({ method: "GET", path: "/rest/update/check", summary: "Check whether a newer release exists", tags: [UPDATE_API_TAG] })).output(UpdateCheckOutputSchema).handler(async () => {
13167
13828
  try {
13168
13829
  return await deps.checkForUpdate();
13169
13830
  } catch (error) {
13170
13831
  if (error instanceof UpdateChannelError) {
13171
- throw new import_client3.ORPCError("PRECONDITION_FAILED", { message: error.message });
13832
+ throw new import_client4.ORPCError("PRECONDITION_FAILED", { message: error.message });
13172
13833
  }
13173
13834
  if (error instanceof UpdateConflictError) {
13174
- throw new import_client3.ORPCError("CONFLICT", { message: error.message });
13835
+ throw new import_client4.ORPCError("CONFLICT", { message: error.message });
13175
13836
  }
13176
13837
  if (error instanceof UpdateDownloadError) {
13177
- throw new import_client3.ORPCError("BAD_GATEWAY", { message: error.message });
13838
+ throw new import_client4.ORPCError("BAD_GATEWAY", { message: error.message });
13178
13839
  }
13179
13840
  throw error;
13180
13841
  }
@@ -13184,57 +13845,57 @@ function createLifecycleApiRouter(deps) {
13184
13845
  }
13185
13846
 
13186
13847
  // src/frontdoor/launchApi.ts
13187
- var import_client4 = require("@orpc/client");
13188
- var import_openapi5 = require("@orpc/openapi");
13848
+ var import_client5 = require("@orpc/client");
13849
+ var import_openapi6 = require("@orpc/openapi");
13189
13850
  init_cliError();
13190
13851
 
13191
13852
  // src/frontdoor/launchSchemas.ts
13192
13853
  var import_node_path30 = __toESM(require("node:path"), 1);
13193
- var import_zod21 = require("zod");
13854
+ var import_zod22 = require("zod");
13194
13855
  init_claudeVersion();
13195
13856
  init_identity();
13196
- var LaunchResolveInputSchema = import_zod21.z.strictObject({
13197
- path: import_zod21.z.string().min(1),
13857
+ var LaunchResolveInputSchema = import_zod22.z.strictObject({
13858
+ path: import_zod22.z.string().min(1),
13198
13859
  /** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
13199
- argv: import_zod21.z.readonly(import_zod21.z.array(import_zod21.z.string())).optional(),
13860
+ argv: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())).optional(),
13200
13861
  /** The launch's inherited environment. Absent means an empty one: the door's own environment is never a substitute for the caller's, so a caller that wants `AGENT_SHIM_*` switches or a `CLAUDE_CONFIG_DIR` considered names them here. Values are read, never reported. */
13201
- env: import_zod21.z.record(import_zod21.z.string(), import_zod21.z.string()).optional()
13862
+ env: import_zod22.z.record(import_zod22.z.string(), import_zod22.z.string()).optional()
13202
13863
  }).refine((input) => import_node_path30.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
13203
- var LaunchPoolDecisionSchema = import_zod21.z.strictObject({
13204
- name: import_zod21.z.string(),
13205
- reasons: import_zod21.z.readonly(import_zod21.z.array(import_zod21.z.string())),
13206
- movedOff: import_zod21.z.strictObject({ identity: import_zod21.z.string(), reason: import_zod21.z.string() }).optional()
13207
- });
13208
- var LaunchDecisionSchema = import_zod21.z.strictObject({
13209
- identity: import_zod21.z.string().optional(),
13210
- identitySource: import_zod21.z.enum(IDENTITY_DECISION_SOURCES),
13864
+ var LaunchPoolDecisionSchema = import_zod22.z.strictObject({
13865
+ name: import_zod22.z.string(),
13866
+ reasons: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
13867
+ movedOff: import_zod22.z.strictObject({ identity: import_zod22.z.string(), reason: import_zod22.z.string() }).optional()
13868
+ });
13869
+ var LaunchDecisionSchema = import_zod22.z.strictObject({
13870
+ identity: import_zod22.z.string().optional(),
13871
+ identitySource: import_zod22.z.enum(IDENTITY_DECISION_SOURCES),
13211
13872
  pool: LaunchPoolDecisionSchema.optional(),
13212
- configDirEscapeHatch: import_zod21.z.boolean(),
13213
- configDir: import_zod21.z.string().optional(),
13214
- configProfile: import_zod21.z.string().optional(),
13215
- configProfileSource: import_zod21.z.enum(CONFIG_PROFILE_DECISION_SOURCES),
13216
- provider: import_zod21.z.string().optional()
13217
- });
13218
- var LaunchFlagsSchema = import_zod21.z.strictObject({
13219
- skipPermissions: import_zod21.z.boolean(),
13220
- remoteControl: import_zod21.z.boolean(),
13221
- headroom: import_zod21.z.boolean(),
13222
- trackUsage: import_zod21.z.boolean()
13223
- });
13224
- var LaunchResolveOutputSchema = import_zod21.z.strictObject({
13873
+ configDirEscapeHatch: import_zod22.z.boolean(),
13874
+ configDir: import_zod22.z.string().optional(),
13875
+ configProfile: import_zod22.z.string().optional(),
13876
+ configProfileSource: import_zod22.z.enum(CONFIG_PROFILE_DECISION_SOURCES),
13877
+ provider: import_zod22.z.string().optional()
13878
+ });
13879
+ var LaunchFlagsSchema = import_zod22.z.strictObject({
13880
+ skipPermissions: import_zod22.z.boolean(),
13881
+ remoteControl: import_zod22.z.boolean(),
13882
+ headroom: import_zod22.z.boolean(),
13883
+ trackUsage: import_zod22.z.boolean()
13884
+ });
13885
+ var LaunchResolveOutputSchema = import_zod22.z.strictObject({
13225
13886
  decision: LaunchDecisionSchema,
13226
13887
  flags: LaunchFlagsSchema,
13227
- claudeVersion: import_zod21.z.strictObject({ version: import_zod21.z.string(), source: import_zod21.z.enum(CLAUDE_VERSION_SOURCES) }).optional(),
13888
+ claudeVersion: import_zod22.z.strictObject({ version: import_zod22.z.string(), source: import_zod22.z.enum(CLAUDE_VERSION_SOURCES) }).optional(),
13228
13889
  /** The real `claude` binary the launch would spawn, on the door's host. */
13229
- bin: import_zod21.z.string(),
13890
+ bin: import_zod22.z.string(),
13230
13891
  /** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
13231
- args: import_zod21.z.readonly(import_zod21.z.array(import_zod21.z.string())),
13892
+ args: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
13232
13893
  /** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
13233
- credential: import_zod21.z.strictObject({ subject: import_zod21.z.enum(["provider", "identity"]), name: import_zod21.z.string(), summary: CredentialSummarySchema }).optional(),
13234
- routing: import_zod21.z.strictObject({ frontDoor: import_zod21.z.boolean(), headroom: import_zod21.z.boolean() }),
13894
+ credential: import_zod22.z.strictObject({ subject: import_zod22.z.enum(["provider", "identity"]), name: import_zod22.z.string(), summary: CredentialSummarySchema }).optional(),
13895
+ routing: import_zod22.z.strictObject({ frontDoor: import_zod22.z.boolean(), headroom: import_zod22.z.boolean() }),
13235
13896
  /** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
13236
- environment: import_zod21.z.readonly(import_zod21.z.array(import_zod21.z.string())),
13237
- warnings: import_zod21.z.readonly(import_zod21.z.array(import_zod21.z.string()))
13897
+ environment: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
13898
+ warnings: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string()))
13238
13899
  });
13239
13900
 
13240
13901
  // src/frontdoor/launchApi.ts
@@ -13243,13 +13904,13 @@ function createLaunchApiRouter(deps) {
13243
13904
  const authed = doorApiAuth(deps.expectedToken);
13244
13905
  return {
13245
13906
  launch: {
13246
- resolve: authed.meta((0, import_openapi5.openapi)({ method: "POST", path: "/rest/launch/resolve", summary: "Resolve what a launch from one directory would do, without performing it", tags: [LAUNCH_API_TAG] })).input(LaunchResolveInputSchema).output(LaunchResolveOutputSchema).handler(({ input }) => {
13907
+ resolve: authed.meta((0, import_openapi6.openapi)({ method: "POST", path: "/rest/launch/resolve", summary: "Resolve what a launch from one directory would do, without performing it", tags: [LAUNCH_API_TAG] })).input(LaunchResolveInputSchema).output(LaunchResolveOutputSchema).handler(({ input }) => {
13247
13908
  try {
13248
13909
  const { resolution, warnings } = deps.resolveLaunch({ path: input.path, argv: input.argv ?? [], env: input.env ?? {} });
13249
13910
  return { ...resolution, warnings };
13250
13911
  } catch (error) {
13251
13912
  if (error instanceof CliError) {
13252
- throw new import_client4.ORPCError("BAD_REQUEST", { message: error.message });
13913
+ throw new import_client5.ORPCError("BAD_REQUEST", { message: error.message });
13253
13914
  }
13254
13915
  throw error;
13255
13916
  }
@@ -13268,11 +13929,11 @@ function createControlApiRouter(deps) {
13268
13929
  const authed = doorApiAuth(deps.expectedToken);
13269
13930
  return {
13270
13931
  usage: {
13271
- list: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
13272
- effectiveWindow: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] })).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
13932
+ list: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
13933
+ effectiveWindow: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] })).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
13273
13934
  const snapshot = deps.usageSnapshotOf(input.identity);
13274
13935
  if (snapshot === void 0) {
13275
- throw new import_client5.ORPCError("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
13936
+ throw new import_client6.ORPCError("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
13276
13937
  }
13277
13938
  const provider = input.provider ?? ANTHROPIC_PROVIDER;
13278
13939
  const rateLimit = snapshot.providers[provider]?.rateLimit;
@@ -13286,34 +13947,34 @@ function createControlApiRouter(deps) {
13286
13947
  ...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
13287
13948
  };
13288
13949
  }),
13289
- live: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] })).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
13950
+ live: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] })).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
13290
13951
  const sessions = deps.liveRateLimits(input.session);
13291
13952
  if (input.session !== void 0 && sessions.length === 0) {
13292
13953
  if (deps.list().some((session) => session.id === input.session)) {
13293
- throw new import_client5.ORPCError("NOT_FOUND", { message: `session ${input.session} has filed no rate_limit_event on its stream yet: the worker emits one only once a turn has completed, so retry after this session's next turn` });
13954
+ throw new import_client6.ORPCError("NOT_FOUND", { message: `session ${input.session} has filed no rate_limit_event on its stream yet: the worker emits one only once a turn has completed, so retry after this session's next turn` });
13294
13955
  }
13295
- throw new import_client5.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
13956
+ throw new import_client6.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
13296
13957
  }
13297
13958
  return { latest: deps.latestRateLimit(), sessions };
13298
13959
  })
13299
13960
  },
13300
13961
  frontdoor: {
13301
- status: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
13302
- sessions: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
13962
+ status: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
13963
+ sessions: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
13303
13964
  },
13304
13965
  check: {
13305
13966
  // The report's own JSON shape is the contract (the same one `check --json` prints and `checkReportSchema.ts` defines), so the procedure returns exactly that conversion.
13306
- run: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] })).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
13967
+ run: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] })).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
13307
13968
  },
13308
13969
  doctor: {
13309
- run: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
13970
+ run: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
13310
13971
  },
13311
13972
  pool: {
13312
- pick: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] })).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
13973
+ pick: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] })).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
13313
13974
  const report = deps.poolPick(input.pool, input.path);
13314
13975
  if (report === void 0) {
13315
13976
  const live = deps.poolNames();
13316
- throw new import_client5.ORPCError("NOT_FOUND", {
13977
+ throw new import_client6.ORPCError("NOT_FOUND", {
13317
13978
  message: live.length === 0 ? `no pools are configured, so none is named ${input.pool}` : `no pool is named ${input.pool}; the live pools are ${live.map((name) => `"${name}"`).join(", ")}`
13318
13979
  });
13319
13980
  }
@@ -13325,13 +13986,13 @@ function createControlApiRouter(deps) {
13325
13986
  function createDoorApiRouter(deps) {
13326
13987
  const control = createControlApiRouter(deps);
13327
13988
  const lifecycle = createLifecycleApiRouter(deps);
13328
- return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
13989
+ return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
13329
13990
  }
13330
13991
  function createDoorApiNodeHandler(deps) {
13331
13992
  return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
13332
13993
  }
13333
13994
  function frontDoorApiClient(port, ca, token) {
13334
- return (0, import_client5.createORPCClient)(frontDoorApiLink(port, ca, token));
13995
+ return (0, import_client6.createORPCClient)(frontDoorApiLink(port, ca, token));
13335
13996
  }
13336
13997
 
13337
13998
  // src/frontdoor/doorClient.ts
@@ -14137,9 +14798,9 @@ async function serveRcCompatSessions(ctx, pathname, compatPath) {
14137
14798
  const slash = rest.indexOf("/");
14138
14799
  const address = slash === -1 ? rest : rest.slice(0, slash);
14139
14800
  const compatTail = slash === -1 ? "" : rest.slice(slash + 1);
14140
- const refusal = ctx.credentialRefusal(request4.headers);
14141
- if (refusal !== void 0) {
14142
- await ctx.unauthorized(response, refusal);
14801
+ const refusal2 = ctx.credentialRefusal(request4.headers);
14802
+ if (refusal2 !== void 0) {
14803
+ await ctx.unauthorized(response, refusal2);
14143
14804
  return;
14144
14805
  }
14145
14806
  const session = ctx.sessions.get(address) ?? ctx.sessions.get(`cse_${address}`);
@@ -14217,9 +14878,9 @@ function conversationRow(conversation) {
14217
14878
  }
14218
14879
  async function serveRcConversations(ctx, pathname, method) {
14219
14880
  const { request: request4, response, conversations } = ctx;
14220
- const refusal = ctx.credentialRefusal(request4.headers);
14221
- if (refusal !== void 0) {
14222
- await ctx.unauthorized(response, refusal);
14881
+ const refusal2 = ctx.credentialRefusal(request4.headers);
14882
+ if (refusal2 !== void 0) {
14883
+ await ctx.unauthorized(response, refusal2);
14223
14884
  return;
14224
14885
  }
14225
14886
  if (pathname === RC_CONVERSATIONS_PATH_PREFIX) {
@@ -14543,9 +15204,9 @@ async function fetchThroughWebProxy(url, deps) {
14543
15204
  try {
14544
15205
  let redirects = 0;
14545
15206
  for (; ; ) {
14546
- const refusal = await checkTarget(current, deps);
14547
- if (refusal !== void 0) {
14548
- return refusal;
15207
+ const refusal2 = await checkTarget(current, deps);
15208
+ if (refusal2 !== void 0) {
15209
+ return refusal2;
14549
15210
  }
14550
15211
  let hop;
14551
15212
  try {
@@ -14915,8 +15576,8 @@ data: ${JSON.stringify(envelope)}
14915
15576
  "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",
14916
15577
  unrecognised: "the self-hosted Remote Control surface did not recognise the presented credential"
14917
15578
  };
14918
- const unauthorized = async (response, refusal) => {
14919
- await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[refusal] } });
15579
+ const unauthorized = async (response, refusal2) => {
15580
+ await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[refusal2] } });
14920
15581
  };
14921
15582
  const serveSessionPath = async (session, tail, request4, response) => {
14922
15583
  const method = request4.method.toUpperCase();
@@ -14927,9 +15588,9 @@ data: ${JSON.stringify(envelope)}
14927
15588
  session.lastTrafficAt = deps.now();
14928
15589
  if (tail === "") {
14929
15590
  if (method === "PATCH" || method === "PUT") {
14930
- const refusal = credentialRefusal(request4.headers);
14931
- if (refusal !== void 0) {
14932
- await unauthorized(response, refusal);
15591
+ const refusal2 = credentialRefusal(request4.headers);
15592
+ if (refusal2 !== void 0) {
15593
+ await unauthorized(response, refusal2);
14933
15594
  return;
14934
15595
  }
14935
15596
  const body = parseJsonObject5(await readBody2(request4.body, CONTROL_BODY_CAP_BYTES));
@@ -14952,9 +15613,9 @@ data: ${JSON.stringify(envelope)}
14952
15613
  return;
14953
15614
  }
14954
15615
  if (tail === "bridge" && method === "POST") {
14955
- const refusal = credentialRefusal(request4.headers);
14956
- if (refusal !== void 0) {
14957
- await unauthorized(response, refusal);
15616
+ const refusal2 = credentialRefusal(request4.headers);
15617
+ if (refusal2 !== void 0) {
15618
+ await unauthorized(response, refusal2);
14958
15619
  return;
14959
15620
  }
14960
15621
  const workerJwt = mintWorkerJwt(deps.randomToken, deps.now());
@@ -14964,9 +15625,9 @@ data: ${JSON.stringify(envelope)}
14964
15625
  return;
14965
15626
  }
14966
15627
  if (tail === "archive" && method === "POST") {
14967
- const refusal = credentialRefusal(request4.headers);
14968
- if (refusal !== void 0) {
14969
- await unauthorized(response, refusal);
15628
+ const refusal2 = credentialRefusal(request4.headers);
15629
+ if (refusal2 !== void 0) {
15630
+ await unauthorized(response, refusal2);
14970
15631
  return;
14971
15632
  }
14972
15633
  retireSession(session);
@@ -14977,9 +15638,9 @@ data: ${JSON.stringify(envelope)}
14977
15638
  if (tail === "worker" || tail.startsWith("worker/")) {
14978
15639
  const workerTail = tail === "worker" ? "" : tail.slice("worker/".length);
14979
15640
  const webProxy = workerTail === "web-fetch" || workerTail === "web-search";
14980
- const refusal = webProxy ? workerOrCredentialRefusal(request4.headers, session) : workerRefusal(request4.headers, session);
14981
- if (refusal !== void 0) {
14982
- await unauthorized(response, refusal);
15641
+ const refusal2 = webProxy ? workerOrCredentialRefusal(request4.headers, session) : workerRefusal(request4.headers, session);
15642
+ if (refusal2 !== void 0) {
15643
+ await unauthorized(response, refusal2);
14983
15644
  return;
14984
15645
  }
14985
15646
  if (workerTail === "" && method === "GET") {
@@ -15392,102 +16053,6 @@ init_paths();
15392
16053
  init_cliError();
15393
16054
  init_schema();
15394
16055
  init_providersStore();
15395
-
15396
- // src/directoryRulesStore.ts
15397
- init_store();
15398
- init_load();
15399
- init_schema();
15400
- init_cliError();
15401
- var DirectoryRuleNotFoundError = class extends CliError {
15402
- constructor(rulePath) {
15403
- super(`No directory rule found for path "${rulePath}".`);
15404
- this.rulePath = rulePath;
15405
- this.name = "DirectoryRuleNotFoundError";
15406
- }
15407
- rulePath;
15408
- };
15409
- var DirectoryRuleMissingTargetError = class extends CliError {
15410
- constructor() {
15411
- super("A directory rule must set at least one of --config-profile or --identity.");
15412
- this.name = "DirectoryRuleMissingTargetError";
15413
- }
15414
- };
15415
- var DirectoryRuleAlreadyExistsError = class extends CliError {
15416
- constructor(rulePath) {
15417
- super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
15418
- this.rulePath = rulePath;
15419
- this.name = "DirectoryRuleAlreadyExistsError";
15420
- }
15421
- rulePath;
15422
- };
15423
- function readDirectoryRules(paths) {
15424
- return readJson(paths.directoryRulesFile, DirectoryRulesSchema) ?? { rules: [] };
15425
- }
15426
- function writeDirectoryRules(paths, rules) {
15427
- const parsed = DirectoryRulesSchema.safeParse(rules);
15428
- if (!parsed.success) {
15429
- throw new ConfigValidationError(paths.directoryRulesFile, parsed.error.issues);
15430
- }
15431
- writeJsonAtomic(paths.directoryRulesFile, parsed.data);
15432
- }
15433
- function listDirectoryRules(paths) {
15434
- return readDirectoryRules(paths).rules;
15435
- }
15436
- function addDirectoryRule(paths, rulePath, options) {
15437
- if (options.configProfile === void 0 && options.identity === void 0) {
15438
- throw new DirectoryRuleMissingTargetError();
15439
- }
15440
- const current = readDirectoryRules(paths);
15441
- if (current.rules.some((rule) => rule.path === rulePath)) {
15442
- throw new DirectoryRuleAlreadyExistsError(rulePath);
15443
- }
15444
- const created = buildNewRule(rulePath, options);
15445
- writeDirectoryRules(paths, { ...current, rules: [...current.rules, created] });
15446
- return created;
15447
- }
15448
- function ruleHasEffect(rule) {
15449
- return rule.configProfile !== void 0 || rule.identity !== void 0 || rule.categories !== void 0 || rule.entries !== void 0 || rule.launch !== void 0;
15450
- }
15451
- function updateDirectoryRule(paths, rulePath, options) {
15452
- const current = readDirectoryRules(paths);
15453
- const index = current.rules.findIndex((rule) => rule.path === rulePath);
15454
- const existing = index === -1 ? void 0 : current.rules[index];
15455
- if (existing === void 0) {
15456
- throw new DirectoryRuleNotFoundError(rulePath);
15457
- }
15458
- const { configProfile, identity, ...rest } = existing;
15459
- const nextConfigProfile = options.configProfile === void 0 ? configProfile : options.configProfile === false ? void 0 : options.configProfile;
15460
- const nextIdentity = options.identity === void 0 ? identity : options.identity === false ? void 0 : options.identity;
15461
- const updated = {
15462
- ...rest,
15463
- ...nextConfigProfile === void 0 ? {} : { configProfile: nextConfigProfile },
15464
- ...nextIdentity === void 0 ? {} : { identity: nextIdentity }
15465
- };
15466
- if (!ruleHasEffect(updated)) {
15467
- throw new DirectoryRuleMissingTargetError();
15468
- }
15469
- const nextRules = [...current.rules];
15470
- nextRules[index] = updated;
15471
- writeDirectoryRules(paths, { ...current, rules: nextRules });
15472
- return updated;
15473
- }
15474
- function buildNewRule(rulePath, options) {
15475
- return {
15476
- path: rulePath,
15477
- ...options.configProfile !== void 0 ? { configProfile: options.configProfile } : {},
15478
- ...options.identity !== void 0 ? { identity: options.identity } : {}
15479
- };
15480
- }
15481
- function removeDirectoryRule(paths, rulePath) {
15482
- const current = readDirectoryRules(paths);
15483
- const nextRules = current.rules.filter((rule) => rule.path !== rulePath);
15484
- if (nextRules.length === current.rules.length) {
15485
- throw new DirectoryRuleNotFoundError(rulePath);
15486
- }
15487
- writeDirectoryRules(paths, { ...current, rules: nextRules });
15488
- }
15489
-
15490
- // src/index.ts
15491
16056
  init_launcher();
15492
16057
  init_spawn();
15493
16058
  init_launchWiring();
@@ -15602,10 +16167,44 @@ init_ownCli();
15602
16167
  CodexLogoutOutputSchema,
15603
16168
  CodexSignInSchema,
15604
16169
  CodexStatusOutputSchema,
16170
+ ConfigIdentityAddOutputSchema,
16171
+ ConfigIdentityRemoveInputSchema,
16172
+ ConfigIdentityRemoveOutputSchema,
16173
+ ConfigIdentitySetInputSchema,
16174
+ ConfigIdentitySetOutputSchema,
16175
+ ConfigIdentityUseOutputSchema,
16176
+ ConfigNameInputSchema,
16177
+ ConfigPoolAddInputSchema,
16178
+ ConfigPoolAddOutputSchema,
16179
+ ConfigPoolRemoveInputSchema,
16180
+ ConfigPoolRemoveOutputSchema,
16181
+ ConfigPoolSetInputSchema,
16182
+ ConfigPoolSetOutputSchema,
16183
+ ConfigPoolUseOutputSchema,
16184
+ ConfigProfileAddInputSchema,
16185
+ ConfigProfileAddOutputSchema,
16186
+ ConfigProfileRemoveInputSchema,
16187
+ ConfigProfileRemoveOutputSchema,
15605
16188
  ConfigProfileSchema,
16189
+ ConfigProfileSetInputSchema,
16190
+ ConfigProfileSetOutputSchema,
16191
+ ConfigProfileUseOutputSchema,
16192
+ ConfigProviderAddInputSchema,
16193
+ ConfigProviderAddOutputSchema,
16194
+ ConfigProviderRemoveInputSchema,
16195
+ ConfigProviderRemoveOutputSchema,
16196
+ ConfigProviderSetInputSchema,
16197
+ ConfigProviderSetOutputSchema,
16198
+ ConfigRuleAddInputSchema,
16199
+ ConfigRuleAddOutputSchema,
16200
+ ConfigRuleRemoveInputSchema,
16201
+ ConfigRuleRemoveOutputSchema,
16202
+ ConfigRuleSetInputSchema,
16203
+ ConfigRuleSetOutputSchema,
15606
16204
  CredentialCacheSchema,
15607
16205
  CredentialSchema,
15608
16206
  CredentialSourceSchema,
16207
+ CredentialSummarySchema,
15609
16208
  DOOR_EVENT_BUFFER_EVENTS,
15610
16209
  DOOR_EVENT_SOURCE_RC,
15611
16210
  DOOR_HEALTH_EVENT_SOURCE,
@@ -15736,6 +16335,7 @@ init_ownCli();
15736
16335
  collectFrontDoorStatus,
15737
16336
  collectPoolPick,
15738
16337
  createCodexApiRouter,
16338
+ createConfigApiRouter,
15739
16339
  createControlApiRouter,
15740
16340
  createDoorApiNodeHandler,
15741
16341
  createDoorApiRouter,