claude-use 9.12.1 → 9.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -209,7 +209,15 @@ function isCodexProvider(provider) {
209
209
  function poolMemberIdentity(member) {
210
210
  return typeof member === "string" ? member : member.identity;
211
211
  }
212
- var CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, 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;
212
+ function isTimeZone(name) {
213
+ try {
214
+ new Intl.DateTimeFormat("en", { timeZone: name });
215
+ return true;
216
+ } catch {
217
+ return false;
218
+ }
219
+ }
220
+ var CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, 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, WEEKDAYS, AnchorSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
213
221
  var init_schema = __esm({
214
222
  "src/config/schema.ts"() {
215
223
  "use strict";
@@ -446,12 +454,20 @@ var init_schema = __esm({
446
454
  update: UpdateGlobalConfigSchema.optional(),
447
455
  pools: z.record(PoolNameSchema, PoolSchema).optional()
448
456
  });
457
+ WEEKDAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
458
+ AnchorSchema = z.strictObject({
459
+ days: z.array(z.enum(WEEKDAYS)).min(1).refine((days) => new Set(days).size === days.length, "an anchor names each weekday at most once"),
460
+ time: z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "a 24-hour time such as 06:00"),
461
+ timeZone: z.string().refine(isTimeZone, "an IANA time zone such as Europe/London").optional()
462
+ });
449
463
  IdentitySchema = z.strictObject({
450
464
  $schema: z.string().optional(),
451
465
  name: z.string().min(1).regex(/^[A-Za-z0-9][A-Za-z0-9._@-]*$/),
452
466
  defaultConfigProfile: z.string().min(1).optional(),
453
467
  allowAmbientCredential: z.boolean().default(false),
454
- credential: CredentialSchema.optional()
468
+ credential: CredentialSchema.optional(),
469
+ /** When this identity's five-hour window should be open: the front door opens one at each anchor if none is. Absent, nothing is opened on a schedule. */
470
+ anchors: z.array(AnchorSchema).min(1).optional()
455
471
  });
456
472
  CategoryClassificationSchema = z.strictObject({
457
473
  $schema: z.string().optional(),
@@ -2573,7 +2589,7 @@ function listFrontDoorSessions(fs12, sessionsDir) {
2573
2589
  try {
2574
2590
  const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs12.readFileUtf8(path8.join(sessionsDir, name)) ?? ""));
2575
2591
  if (parsed.success) {
2576
- sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
2592
+ sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
2577
2593
  }
2578
2594
  } catch {
2579
2595
  continue;
@@ -2599,7 +2615,7 @@ var init_state = __esm({
2599
2615
  "src/frontdoor/state.ts"() {
2600
2616
  "use strict";
2601
2617
  FRONT_DOOR_PROTOCOL = 3;
2602
- FrontDoorSessionSchema = z3.strictObject({ pid: z3.number().int().positive(), startedAt: z3.number(), token: z3.string().min(1) });
2618
+ FrontDoorSessionSchema = z3.strictObject({ pid: z3.number().int().positive(), startedAt: z3.number(), token: z3.string().min(1), supervisorPid: z3.number().int().positive().optional() });
2603
2619
  FrontDoorStateSchema = z3.strictObject({
2604
2620
  /**
2605
2621
  * The launcher-to-door wire protocol this supervisor speaks, written once it is serving; absent in state written by a release that predates the field, which `ensureFrontDoor` reads as protocol 0. A launcher replaces a door whose protocol is lower than its own (see `FRONT_DOOR_PROTOCOL`).
@@ -2639,7 +2655,7 @@ var init_package = __esm({
2639
2655
  "package.json"() {
2640
2656
  package_default = {
2641
2657
  name: "claude-use",
2642
- version: "9.12.1",
2658
+ version: "9.14.0",
2643
2659
  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.",
2644
2660
  license: "MIT",
2645
2661
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -2742,6 +2758,36 @@ var init_package = __esm({
2742
2758
  }
2743
2759
  });
2744
2760
 
2761
+ // src/frontdoor/supervisorProcesses.ts
2762
+ function parseFrontDoorSupervisorPids(psOutput) {
2763
+ const pids = [];
2764
+ for (const line of psOutput.split("\n")) {
2765
+ const [pidText, ...argumentsList] = line.trim().split(/\s+/);
2766
+ const pid = Number(pidText);
2767
+ if (Number.isInteger(pid) && pid > 0 && argumentsList.includes(FRONT_DOOR_SUPERVISOR_ARGUMENT)) {
2768
+ pids.push(pid);
2769
+ }
2770
+ }
2771
+ return pids.sort((a, b) => a - b);
2772
+ }
2773
+ function listFrontDoorSupervisors(run, uid) {
2774
+ const result = run.run("ps", ["-U", String(uid), "-o", "pid=,command="]);
2775
+ if (result.status === null) {
2776
+ return { ok: false, message: "ps could not be run" };
2777
+ }
2778
+ if (result.status !== 0) {
2779
+ return { ok: false, message: `ps exited ${String(result.status)}${result.stderr.trim() === "" ? "" : `: ${result.stderr.trim()}`}` };
2780
+ }
2781
+ return { ok: true, pids: parseFrontDoorSupervisorPids(result.stdout) };
2782
+ }
2783
+ var FRONT_DOOR_SUPERVISOR_ARGUMENT;
2784
+ var init_supervisorProcesses = __esm({
2785
+ "src/frontdoor/supervisorProcesses.ts"() {
2786
+ "use strict";
2787
+ FRONT_DOOR_SUPERVISOR_ARGUMENT = "__frontdoor-supervisor";
2788
+ }
2789
+ });
2790
+
2745
2791
  // src/headroom/state.ts
2746
2792
  import { createHash as createHash3 } from "node:crypto";
2747
2793
  import path11 from "node:path";
@@ -3338,9 +3384,15 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3338
3384
  await ports.sleep(HEADROOM_POLL_MS);
3339
3385
  }
3340
3386
  }
3387
+ function currentHeadroomAllowlistInputs(fs12, paths) {
3388
+ return {
3389
+ providers: readAllProviders(fs12, paths.providersDir).map((entry) => entry.provider),
3390
+ frontDoorOrigin: frontDoorOrigin(readFrontDoorState(fs12, paths.frontdoorStateFile))
3391
+ };
3392
+ }
3341
3393
  function currentHeadroomAllowlist(fs12, paths) {
3342
- const providers = readAllProviders(fs12, paths.providersDir).map((entry) => entry.provider);
3343
- return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(fs12, paths.frontdoorStateFile))));
3394
+ const inputs = currentHeadroomAllowlistInputs(fs12, paths);
3395
+ return headroomAllowlist(headroomUpstreams(inputs.providers, inputs.frontDoorOrigin));
3344
3396
  }
3345
3397
  function allowlistOf(ports) {
3346
3398
  return currentHeadroomAllowlist(ports.fs, ports.paths);
@@ -3409,8 +3461,8 @@ function realIsProcessRunning(pid) {
3409
3461
  return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
3410
3462
  }
3411
3463
  function realIsFrontDoorSupervisor(pid) {
3412
- const result = spawnSync("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8" });
3413
- return result.status === 0 && result.stdout.split(/\s+/).includes(FRONT_DOOR_SUPERVISOR_SUBCOMMAND);
3464
+ const result = spawnSync("ps", ["-o", "pid=,command=", "-p", String(pid)], { encoding: "utf8" });
3465
+ return result.status === 0 && parseFrontDoorSupervisorPids(result.stdout).includes(pid);
3414
3466
  }
3415
3467
  function expandHome2(filePath) {
3416
3468
  return filePath.startsWith("~/") ? path13.join(os3.homedir(), filePath.slice(1)) : filePath;
@@ -3609,12 +3661,13 @@ function realResolveClaudeBinary(isOwnBinary) {
3609
3661
  function realInstalledClaudeVersions() {
3610
3662
  return installedVersions(listVersionsDir(defaultVersionsDir()));
3611
3663
  }
3612
- var realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, FRONT_DOOR_SUPERVISOR_SUBCOMMAND, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
3664
+ var realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
3613
3665
  var init_realPorts = __esm({
3614
3666
  "src/realPorts.ts"() {
3615
3667
  "use strict";
3616
3668
  init_load();
3617
3669
  init_versionDiscovery();
3670
+ init_supervisorProcesses();
3618
3671
  init_ensure();
3619
3672
  init_supervisor();
3620
3673
  init_state2();
@@ -3744,7 +3797,6 @@ var init_realPorts = __esm({
3744
3797
  }
3745
3798
  };
3746
3799
  INT32_BYTE_LENGTH = 4;
3747
- FRONT_DOOR_SUPERVISOR_SUBCOMMAND = "__frontdoor-supervisor";
3748
3800
  realRunPort = {
3749
3801
  run(command, args) {
3750
3802
  const result = spawnSync(command, [...args], { encoding: "utf8" });
@@ -4650,7 +4702,7 @@ function assessIdentity(member, nowMs) {
4650
4702
  );
4651
4703
  if (blockedUntil > nowMs) {
4652
4704
  if (unified.overageStatus === "allowed") {
4653
- return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
4705
+ return { candidate: { ...base, class: "pay-per-use", planReturnsAtMs: blockedUntil, reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)}), continues as extra usage`, ...windowReasons, ...planReasons] } };
4654
4706
  }
4655
4707
  return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...unified.fallbackAvailable === true ? ["a fallback is on offer, so requests for some models may still be served"] : [], ...windowReasons, ...overageReasons, ...planReasons] } };
4656
4708
  }
@@ -4765,7 +4817,8 @@ function rankPool(input) {
4765
4817
  return {
4766
4818
  candidates: ordered,
4767
4819
  ...pick === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick },
4768
- ...movedOff === void 0 || pick === void 0 ? {} : { movedOff }
4820
+ ...movedOff === void 0 || pick === void 0 ? {} : { movedOff },
4821
+ ...pick?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick.identity, atMs: pick.planReturnsAtMs } }
4769
4822
  };
4770
4823
  }
4771
4824
  var MS_PER_SECOND4, MS_PER_HOUR2, HOURS_PER_DAY2, FIVE_HOURS, PROMPT_CACHE_TTL_HOURS, PERCENT, SEVEN_DAYS, FIVE_HOUR_WINDOW_MS, SEVEN_DAY_WINDOW_MS, PROMPT_CACHE_TTL_MS, CLASS_ORDER;
@@ -5247,6 +5300,7 @@ function buildLayoutPaths(root) {
5247
5300
  usageLogDir: path22.join(root, "usage", "log"),
5248
5301
  usageSnapshotsDir: path22.join(root, "usage", "snapshots"),
5249
5302
  usagePicksFile: path22.join(root, "usage", "picks.json"),
5303
+ usageAnchorsFile: path22.join(root, "usage", "anchors.json"),
5250
5304
  mcpPermissionsFile: path22.join(root, "mcp", "permissions.json")
5251
5305
  };
5252
5306
  }
@@ -6178,7 +6232,7 @@ function ensureFrontDoor(params) {
6178
6232
  }
6179
6233
  if (verdict.ok) {
6180
6234
  const token = randomUUID3();
6181
- writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token });
6235
+ writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid });
6182
6236
  return { port: state.port, connectPort: state.connectPort, token };
6183
6237
  }
6184
6238
  lastRejection = `the listener on 127.0.0.1:${String(state.port)} (recorded for pid ${String(supervisorPid)}) failed authentication: ${verdict.reason}`;
@@ -6712,7 +6766,12 @@ function resolvePoolLaunch(params) {
6712
6766
  if (graph.ranking.candidates.length === 0) {
6713
6767
  return { ok: false, message: `agent-shim: no member of pool "${poolName}" is an existing identity.` };
6714
6768
  }
6715
- const { pick, earliestReturn, movedOff } = graph.ranking;
6769
+ const { pick, earliestReturn, movedOff, planReturn } = graph.ranking;
6770
+ if (pick !== void 0 && params.wait && planReturn !== void 0) {
6771
+ log.info(`agent-shim: pool "${poolName}" would continue ${planReturn.identity} on extra usage; waiting until ${new Date(planReturn.atMs).toISOString()} for its plan window`);
6772
+ params.sleep(Math.max(planReturn.atMs - nowMs, 0));
6773
+ continue;
6774
+ }
6716
6775
  if (pick !== void 0) {
6717
6776
  if (params.recordPick) {
6718
6777
  recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
@@ -7739,6 +7798,57 @@ var init_anthropicUsageRefresh = __esm({
7739
7798
  }
7740
7799
  });
7741
7800
 
7801
+ // src/usage/identityClaude.ts
7802
+ function definedEnvironment(env) {
7803
+ return Object.fromEntries(Object.entries(env).flatMap(([name, value]) => value === void 0 ? [] : [[name, value]]));
7804
+ }
7805
+ function identityLaunchArgv(identity, flags) {
7806
+ return [`@${identity}`, IDENTITY_ONLY_FLAG, ...flags];
7807
+ }
7808
+ async function withIdentityClaude(params, identity, flags, use) {
7809
+ const refusals = [];
7810
+ const plan = prepareLaunch(
7811
+ realPrepareLaunchParams(params.paths, {
7812
+ proc: {
7813
+ env: Object.fromEntries(Object.entries(process.env).filter(([name]) => name !== CONFIG_DIR_VARIABLE)),
7814
+ argv: [...identityLaunchArgv(identity, flags)],
7815
+ exit: (code) => {
7816
+ throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
7817
+ }
7818
+ },
7819
+ log: {
7820
+ info: () => void 0,
7821
+ warn: () => void 0,
7822
+ error: (message) => {
7823
+ refusals.push(message);
7824
+ }
7825
+ },
7826
+ spawnDaemon: params.spawnDaemon,
7827
+ farm: buildFarmRuntime(params.paths, params.cwd)
7828
+ })
7829
+ );
7830
+ const abort = new AbortController();
7831
+ const timer = setTimeout(() => {
7832
+ abort.abort();
7833
+ }, params.timeoutMs);
7834
+ try {
7835
+ return await use({ bin: plan.bin, env: definedEnvironment(plan.env), cwd: params.cwd, abort });
7836
+ } finally {
7837
+ clearTimeout(timer);
7838
+ plan.release();
7839
+ }
7840
+ }
7841
+ var CONFIG_DIR_VARIABLE, IDENTITY_ONLY_FLAG;
7842
+ var init_identityClaude = __esm({
7843
+ "src/usage/identityClaude.ts"() {
7844
+ "use strict";
7845
+ init_launchWiring();
7846
+ init_launcher();
7847
+ CONFIG_DIR_VARIABLE = "CLAUDE_CONFIG_DIR";
7848
+ IDENTITY_ONLY_FLAG = "--no-provider";
7849
+ }
7850
+ });
7851
+
7742
7852
  // src/usage/providerQuota.ts
7743
7853
  import { z as z25 } from "zod";
7744
7854
  var MS_PER_SECOND7, SECONDS_PER_HOUR, HOURS_PER_DAY4, 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;
@@ -7810,9 +7920,6 @@ __export(realAnthropicUsageProbe_exports, {
7810
7920
  createRealAnthropicUsageRefresher: () => createRealAnthropicUsageRefresher
7811
7921
  });
7812
7922
  import { availableParallelism } from "node:os";
7813
- function definedEnvironment(env) {
7814
- return Object.fromEntries(Object.entries(env).flatMap(([name, value]) => value === void 0 ? [] : [[name, value]]));
7815
- }
7816
7923
  function idlePrompt(signal) {
7817
7924
  return {
7818
7925
  [Symbol.asyncIterator]: () => ({
@@ -7825,58 +7932,28 @@ function idlePrompt(signal) {
7825
7932
  };
7826
7933
  }
7827
7934
  function createRealAnthropicUsageProbe(params) {
7828
- return async (identity) => {
7829
- const refusals = [];
7830
- const plan = prepareLaunch(
7831
- realPrepareLaunchParams(params.paths, {
7832
- proc: {
7833
- env: Object.fromEntries(Object.entries(process.env).filter(([name]) => name !== CONFIG_DIR_VARIABLE)),
7834
- argv: [`@${identity}`, ...PROBE_LAUNCH_FLAGS],
7835
- exit: (code) => {
7836
- throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
7837
- }
7838
- },
7839
- log: {
7840
- info: () => void 0,
7841
- warn: () => void 0,
7842
- error: (message) => {
7843
- refusals.push(message);
7844
- }
7845
- },
7846
- spawnDaemon: params.spawnDaemon,
7847
- farm: buildFarmRuntime(params.paths, params.cwd)
7848
- })
7849
- );
7935
+ return async (identity) => await withIdentityClaude(params, identity, PROBE_LAUNCH_FLAGS, async ({ bin, env, cwd, abort }) => {
7850
7936
  const { query } = await import("@anthropic-ai/claude-agent-sdk");
7851
- const abort = new AbortController();
7852
- const timer = setTimeout(() => {
7853
- abort.abort();
7854
- }, params.timeoutMs);
7855
- try {
7856
- const session = query({
7857
- prompt: idlePrompt(abort.signal),
7858
- options: {
7859
- pathToClaudeCodeExecutable: plan.bin,
7860
- env: definedEnvironment(plan.env),
7861
- cwd: params.cwd,
7862
- abortController: abort,
7863
- settingSources: [],
7864
- mcpServers: {},
7865
- strictMcpConfig: true,
7866
- persistSession: false
7867
- }
7868
- });
7869
- try {
7870
- const report = await session.usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET({ skipBehaviors: true });
7871
- return unifiedFromReportedLimits(report.rate_limits_available ? report.rate_limits : null);
7872
- } finally {
7873
- session.close();
7937
+ const session = query({
7938
+ prompt: idlePrompt(abort.signal),
7939
+ options: {
7940
+ pathToClaudeCodeExecutable: bin,
7941
+ env,
7942
+ cwd,
7943
+ abortController: abort,
7944
+ settingSources: [],
7945
+ mcpServers: {},
7946
+ strictMcpConfig: true,
7947
+ persistSession: false
7874
7948
  }
7949
+ });
7950
+ try {
7951
+ const report = await session.usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET({ skipBehaviors: true });
7952
+ return unifiedFromReportedLimits(report.rate_limits_available ? report.rate_limits : null);
7875
7953
  } finally {
7876
- clearTimeout(timer);
7877
- plan.release();
7954
+ session.close();
7878
7955
  }
7879
- };
7956
+ });
7880
7957
  }
7881
7958
  function createRealAnthropicUsageRefresher(params) {
7882
7959
  return createAnthropicUsageRefresher({
@@ -7889,17 +7966,15 @@ function createRealAnthropicUsageRefresher(params) {
7889
7966
  concurrency: availableParallelism()
7890
7967
  });
7891
7968
  }
7892
- var PROBE_LAUNCH_FLAGS, CONFIG_DIR_VARIABLE;
7969
+ var PROBE_LAUNCH_FLAGS;
7893
7970
  var init_realAnthropicUsageProbe = __esm({
7894
7971
  "src/usage/realAnthropicUsageProbe.ts"() {
7895
7972
  "use strict";
7896
- init_launchWiring();
7897
- init_launcher();
7898
7973
  init_anthropicUsageRefresh();
7974
+ init_identityClaude();
7899
7975
  init_middleware();
7900
7976
  init_quotaRefresh();
7901
7977
  PROBE_LAUNCH_FLAGS = ["--no-headroom", "--no-remote-control"];
7902
- CONFIG_DIR_VARIABLE = "CLAUDE_CONFIG_DIR";
7903
7978
  }
7904
7979
  });
7905
7980
 
@@ -8316,16 +8391,27 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
8316
8391
  ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http3.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
8317
8392
  let idleSince;
8318
8393
  let ticks = 0;
8394
+ const supersedingOwner = () => {
8395
+ const owner = readFrontDoorState(fs12, paths.frontdoorStateFile)?.supervisorPid;
8396
+ return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
8397
+ };
8398
+ let supersededBy;
8399
+ let served;
8319
8400
  const binaryReplaced = () => {
8320
8401
  const current = ports.statOwnExecutable();
8321
8402
  return current !== void 0 && servingBinary !== void 0 && (current.dev !== servingBinary.dev || current.ino !== servingBinary.ino || current.size !== servingBinary.size || current.mtimeMs !== servingBinary.mtimeMs);
8322
8403
  };
8323
- const shutdown = async () => {
8404
+ const closeServing = async () => {
8324
8405
  await direct.close();
8325
8406
  await connect3.close();
8326
8407
  await http3.close();
8327
8408
  ports.closeRcStreamHub();
8328
- writeFrontDoorState(fs12, paths.frontdoorStateFile, sticky());
8409
+ };
8410
+ const shutdown = async () => {
8411
+ await closeServing();
8412
+ if (supersedingOwner() === void 0) {
8413
+ writeFrontDoorState(fs12, paths.frontdoorStateFile, sticky());
8414
+ }
8329
8415
  return 0;
8330
8416
  };
8331
8417
  for (; ; ) {
@@ -8338,7 +8424,28 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
8338
8424
  ports.observeLaunchRegistry(listed, pruned);
8339
8425
  ports.checkQuotaExpiry();
8340
8426
  const prunedPids = new Set(pruned);
8341
- if (listed.filter((session) => !prunedPids.has(session.pid)).length === 0) {
8427
+ const live = listed.filter((session) => !prunedPids.has(session.pid));
8428
+ if (supersededBy === void 0) {
8429
+ supersededBy = supersedingOwner();
8430
+ if (supersededBy !== void 0) {
8431
+ ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: supervisor ${String(supersededBy)} now owns the front door; taking no new sessions and exiting once the sessions this door serves have ended`);
8432
+ ports.doorHealth.superseded(supersededBy);
8433
+ await ports.sleep(FRONTDOOR_POLL_MS);
8434
+ continue;
8435
+ }
8436
+ } else {
8437
+ const owner = supersededBy;
8438
+ served = (served ?? live.filter((session) => session.pid !== ports.ownPid && session.pid !== owner && (session.supervisorPid === void 0 || session.supervisorPid === ports.ownPid))).filter((own) => live.some((session) => session.pid === own.pid && session.startedAt === own.startedAt));
8439
+ if (served.length === 0) {
8440
+ ports.log("agent-shim frontdoor supervisor: the sessions this superseded door served have ended; closing the front door and exiting");
8441
+ ports.doorHealth.drained();
8442
+ await closeServing();
8443
+ return 0;
8444
+ }
8445
+ await ports.sleep(FRONTDOOR_POLL_MS);
8446
+ continue;
8447
+ }
8448
+ if (live.length === 0) {
8342
8449
  if (ticks > 1 && binaryReplaced()) {
8343
8450
  ports.log("agent-shim frontdoor supervisor: the installed binary changed and no sessions are live; turning the door over for the next launch");
8344
8451
  ports.doorHealth.binaryTurnover();
@@ -12330,6 +12437,12 @@ function listIdentities(paths) {
12330
12437
  }
12331
12438
  return result;
12332
12439
  }
12440
+ function setIdentityAnchors(paths, identityName, anchors) {
12441
+ if (!identityExists(paths, identityName)) {
12442
+ throw new IdentityNotFoundError(identityName);
12443
+ }
12444
+ return applyPatch(identityJsonPath(paths, identityName), IdentitySchema, { anchors: anchors === void 0 ? void 0 : [...anchors] });
12445
+ }
12333
12446
  function setDefaultConfigProfile(paths, identityName, profileName) {
12334
12447
  if (!identityExists(paths, identityName)) {
12335
12448
  throw new IdentityNotFoundError(identityName);
@@ -12492,7 +12605,55 @@ init_credential();
12492
12605
  init_credentialCache();
12493
12606
  init_realCredentialCache();
12494
12607
  init_source();
12608
+
12609
+ // src/headroom/allowlistDrift.ts
12610
+ init_state2();
12611
+ function diagnoseAllowlistDrift(params) {
12612
+ const { recordedHash, providers, frontDoorOrigin: frontDoorOrigin2 } = params;
12613
+ if (recordedHash === void 0 || recordedHash === hashAllowlist(headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin2)))) {
12614
+ return void 0;
12615
+ }
12616
+ const originIsInput = providers.length > 0 && frontDoorOrigin2 !== void 0;
12617
+ if (!originIsInput) {
12618
+ return ["provider-files"];
12619
+ }
12620
+ return recordedHash === hashAllowlist(headroomAllowlist(headroomUpstreams(providers, void 0))) ? ["front-door-origin"] : ["provider-files", "front-door-origin"];
12621
+ }
12622
+
12623
+ // src/doctorReport.ts
12495
12624
  init_state2();
12625
+ init_supervisor();
12626
+ init_state();
12627
+
12628
+ // src/doctorFrontDoor.ts
12629
+ function pushFrontDoor(push, supervisors, registeredPid) {
12630
+ if (!supervisors.ok) {
12631
+ push("frontdoor", "warn", `Could not list processes to look for duplicate front door supervisors: ${supervisors.message}.`);
12632
+ return;
12633
+ }
12634
+ const { pids } = supervisors;
12635
+ if (pids.length === 0) {
12636
+ push("frontdoor", "pass", "No front door supervisor is running.");
12637
+ return;
12638
+ }
12639
+ const [only, ...rest] = pids;
12640
+ if (only !== void 0 && rest.length === 0) {
12641
+ push("frontdoor", "pass", `One front door supervisor is running (pid ${String(only)}).`);
12642
+ return;
12643
+ }
12644
+ const serving = registeredPid !== void 0 && pids.includes(registeredPid) ? `The front door state file names pid ${String(registeredPid)} as the serving supervisor.` : "The front door state file names no running supervisor.";
12645
+ for (const pid of pids.filter((candidate) => candidate !== registeredPid)) {
12646
+ push(
12647
+ "frontdoor",
12648
+ "fail",
12649
+ `Front door supervisor pid ${String(pid)} is running beside ${String(pids.length - 1)} other(s). ${serving} Stop it with \`kill ${String(pid)}\`; launches still connected to it lose their door.`,
12650
+ String(pid)
12651
+ );
12652
+ }
12653
+ }
12654
+
12655
+ // src/doctorReport.ts
12656
+ init_supervisorProcesses();
12496
12657
  init_legacy();
12497
12658
  init_providersStore();
12498
12659
  init_guard();
@@ -12515,7 +12676,8 @@ var DOCTOR_SECTIONS = [
12515
12676
  "global-config",
12516
12677
  "categories-local",
12517
12678
  "active-identity",
12518
- "headroom"
12679
+ "headroom",
12680
+ "frontdoor"
12519
12681
  ];
12520
12682
  function refinePathShadow(status, ownExecutablePath, realpath) {
12521
12683
  if (status.status !== "shadowed") {
@@ -12911,6 +13073,17 @@ function runDoctor(params) {
12911
13073
  `Headroom daemon is up on unix socket ${state.socketPath} (supervisor ${String(state.supervisorPid)}, daemon ${String(state.headroomPid)}).`
12912
13074
  );
12913
13075
  }
13076
+ const allowlist = params.headroom.allowlist;
13077
+ if (supervisorAlive && headroomAlive && state.socketPath !== void 0 && allowlist?.driftInputs?.includes("front-door-origin") === true) {
13078
+ const origin = allowlist.frontDoorOrigin ?? "";
13079
+ const certainty = allowlist.driftInputs.includes("provider-files") ? "may exclude" : "excludes";
13080
+ push(
13081
+ "headroom",
13082
+ "fail",
13083
+ `Headroom daemon ${String(state.headroomPid)} was started with an allowlist that ${certainty} the serving front door's direct origin ${origin}, so it refuses every request a provider launch sends back through the door. Its supervisor restarts it once no launch is registered against it; \`agent-shim headroom status\` lists the registered launches, and \`--no-headroom\` launches are unaffected.`,
13084
+ String(state.headroomPid)
13085
+ );
13086
+ }
12914
13087
  if (state.lastError !== void 0 && supervisorAlive) {
12915
13088
  push("headroom", "warn", `Headroom recorded a previous error: ${state.lastError}`);
12916
13089
  }
@@ -12923,6 +13096,10 @@ function runDoctor(params) {
12923
13096
  }
12924
13097
  }
12925
13098
  }
13099
+ if (params.frontDoor !== void 0) {
13100
+ const validated3 = params.frontDoor.state.raw === void 0 ? void 0 : validateJson(FrontDoorStateSchema, params.frontDoor.state);
13101
+ pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0);
13102
+ }
12926
13103
  if (params.activeIdentity.raw === void 0) {
12927
13104
  push("active-identity", "pass", "No active identity set.");
12928
13105
  } else {
@@ -12952,6 +13129,7 @@ var SECTION_TITLES = {
12952
13129
  "directory-rules": "Directory rules",
12953
13130
  "global-config": "Global config",
12954
13131
  headroom: "Headroom daemon",
13132
+ frontdoor: "Front door",
12955
13133
  "categories-local": "categories.local.json",
12956
13134
  "active-identity": "Active identity"
12957
13135
  };
@@ -12969,6 +13147,7 @@ var SECTION_ORDER = [
12969
13147
  "directory-rules",
12970
13148
  "global-config",
12971
13149
  "headroom",
13150
+ "frontdoor",
12972
13151
  "categories-local",
12973
13152
  "active-identity"
12974
13153
  ];
@@ -13046,6 +13225,9 @@ function collectDoctorReport(params) {
13046
13225
  shimState.targetPath,
13047
13226
  realpathOrSelf
13048
13227
  );
13228
+ const uid = process.getuid?.();
13229
+ const allowlistInputs = currentHeadroomAllowlistInputs(realFarmFs, paths);
13230
+ const servingHeadroom = resolveServingHeadroomState(realFarmFs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, realIsProcessRunning);
13049
13231
  const report = runDoctor({
13050
13232
  env: params.env,
13051
13233
  credentialCache: realCredentialCacheEnv(paths),
@@ -13084,8 +13266,13 @@ function collectDoctorReport(params) {
13084
13266
  const statePath = resolved?.path ?? paths.headroomStateFile;
13085
13267
  return { path: statePath, raw: realFarmFs.readFileUtf8(statePath) };
13086
13268
  })(),
13087
- isRunning: realIsProcessRunning
13088
- }
13269
+ isRunning: realIsProcessRunning,
13270
+ allowlist: {
13271
+ driftInputs: diagnoseAllowlistDrift({ recordedHash: servingHeadroom?.state.allowlistHash, ...allowlistInputs }),
13272
+ frontDoorOrigin: allowlistInputs.frontDoorOrigin
13273
+ }
13274
+ },
13275
+ ...uid === void 0 ? {} : { frontDoor: { state: { path: paths.frontdoorStateFile, raw: realFsPort.readFileUtf8(paths.frontdoorStateFile) }, supervisors: listFrontDoorSupervisors(realRunPort, uid) } }
13089
13276
  });
13090
13277
  return report;
13091
13278
  }
@@ -13360,7 +13547,8 @@ var IdentityValueSchema = z22.strictObject({
13360
13547
  name: z22.string(),
13361
13548
  defaultConfigProfile: z22.string().optional(),
13362
13549
  allowAmbientCredential: z22.boolean(),
13363
- credential: CredentialSummarySchema2.optional()
13550
+ credential: CredentialSummarySchema2.optional(),
13551
+ anchors: z22.array(AnchorSchema).optional()
13364
13552
  });
13365
13553
  var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
13366
13554
  var ProviderValueSchema = z22.strictObject({
@@ -13378,7 +13566,9 @@ var ConfigIdentitySetInputSchema = z22.strictObject({
13378
13566
  name: z22.string().min(1),
13379
13567
  defaultConfigProfile: z22.union([z22.string().min(1), z22.literal(false)]).optional(),
13380
13568
  allowAmbientCredential: z22.boolean().optional(),
13381
- credential: z22.union([z22.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional()
13569
+ credential: z22.union([z22.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional(),
13570
+ /** `false` removes the anchors; a list replaces them. */
13571
+ anchors: z22.union([z22.literal(false), z22.array(AnchorSchema).min(1)]).optional()
13382
13572
  });
13383
13573
  var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
13384
13574
  var ConfigIdentityRemoveInputSchema = z22.strictObject({ name: z22.string().min(1), confirm: RemovalConfirmationSchema });
@@ -13499,7 +13689,8 @@ function identityValue(name, paths) {
13499
13689
  name: identity.name,
13500
13690
  ...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
13501
13691
  allowAmbientCredential: identity.allowAmbientCredential,
13502
- ...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) }
13692
+ ...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) },
13693
+ ...identity.anchors === void 0 ? {} : { anchors: identity.anchors }
13503
13694
  };
13504
13695
  }
13505
13696
  function providerValue(name, provider) {
@@ -13530,9 +13721,9 @@ function createConfigApiRouter(deps) {
13530
13721
  return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
13531
13722
  })
13532
13723
  ),
13533
- set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting or credential").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
13724
+ set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting, credential or anchors").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
13534
13725
  ({ input }) => guarded(() => {
13535
- requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0, "defaultConfigProfile, allowAmbientCredential or credential");
13726
+ requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0 || input.anchors !== void 0, "defaultConfigProfile, allowAmbientCredential, credential or anchors");
13536
13727
  if (!identityExists(paths, input.name)) {
13537
13728
  throw new IdentityNotFoundError(input.name);
13538
13729
  }
@@ -13557,6 +13748,9 @@ function createConfigApiRouter(deps) {
13557
13748
  };
13558
13749
  setIdentityCredential(paths, input.name, change);
13559
13750
  }
13751
+ if (input.anchors !== void 0) {
13752
+ setIdentityAnchors(paths, input.name, input.anchors === false ? void 0 : input.anchors);
13753
+ }
13560
13754
  return { action: "updated", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
13561
13755
  })
13562
13756
  ),
@@ -13787,7 +13981,9 @@ var DoorHealthEventSchema = z23.discriminatedUnion("kind", [
13787
13981
  z23.strictObject({ kind: z23.literal("generation"), pid: z23.number().int().positive(), providerPort: z23.number().int().positive(), connectPort: z23.number().int().positive(), directPort: z23.number().int().positive(), observedAt: z23.number() }),
13788
13982
  z23.strictObject({ kind: z23.literal("listenerFailed"), pid: z23.number().int().positive(), listener: z23.enum(["provider", "connect", "direct"]), message: z23.string(), observedAt: z23.number() }),
13789
13983
  z23.strictObject({ kind: z23.literal("binaryTurnover"), pid: z23.number().int().positive(), observedAt: z23.number() }),
13790
- z23.strictObject({ kind: z23.literal("idleShutdown"), pid: z23.number().int().positive(), observedAt: z23.number() })
13984
+ z23.strictObject({ kind: z23.literal("idleShutdown"), pid: z23.number().int().positive(), observedAt: z23.number() }),
13985
+ z23.strictObject({ kind: z23.literal("superseded"), pid: z23.number().int().positive(), ownerPid: z23.number().int().positive(), observedAt: z23.number() }),
13986
+ z23.strictObject({ kind: z23.literal("drained"), pid: z23.number().int().positive(), observedAt: z23.number() })
13791
13987
  ]);
13792
13988
  var QuotaExpiringEventSchema = z23.strictObject({
13793
13989
  identity: z23.string().min(1),
@@ -14284,6 +14480,12 @@ function createDoorHealthPublisher(hub, now, pid) {
14284
14480
  },
14285
14481
  binaryTurnover: () => {
14286
14482
  publisher.publish({ kind: "binaryTurnover", pid, observedAt: now() });
14483
+ },
14484
+ superseded: (ownerPid) => {
14485
+ publisher.publish({ kind: "superseded", pid, ownerPid, observedAt: now() });
14486
+ },
14487
+ drained: () => {
14488
+ publisher.publish({ kind: "drained", pid, observedAt: now() });
14287
14489
  }
14288
14490
  };
14289
14491
  }