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.cjs CHANGED
@@ -228,7 +228,15 @@ 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, 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;
231
+ function isTimeZone(name) {
232
+ try {
233
+ new Intl.DateTimeFormat("en", { timeZone: name });
234
+ return true;
235
+ } catch {
236
+ return false;
237
+ }
238
+ }
239
+ 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, WEEKDAYS, AnchorSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
232
240
  var init_schema = __esm({
233
241
  "src/config/schema.ts"() {
234
242
  "use strict";
@@ -468,12 +476,20 @@ var init_schema = __esm({
468
476
  update: UpdateGlobalConfigSchema.optional(),
469
477
  pools: import_zod.z.record(PoolNameSchema, PoolSchema).optional()
470
478
  });
479
+ WEEKDAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
480
+ AnchorSchema = import_zod.z.strictObject({
481
+ days: import_zod.z.array(import_zod.z.enum(WEEKDAYS)).min(1).refine((days) => new Set(days).size === days.length, "an anchor names each weekday at most once"),
482
+ time: import_zod.z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, "a 24-hour time such as 06:00"),
483
+ timeZone: import_zod.z.string().refine(isTimeZone, "an IANA time zone such as Europe/London").optional()
484
+ });
471
485
  IdentitySchema = import_zod.z.strictObject({
472
486
  $schema: import_zod.z.string().optional(),
473
487
  name: import_zod.z.string().min(1).regex(/^[A-Za-z0-9][A-Za-z0-9._@-]*$/),
474
488
  defaultConfigProfile: import_zod.z.string().min(1).optional(),
475
489
  allowAmbientCredential: import_zod.z.boolean().default(false),
476
- credential: CredentialSchema.optional()
490
+ credential: CredentialSchema.optional(),
491
+ /** 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. */
492
+ anchors: import_zod.z.array(AnchorSchema).min(1).optional()
477
493
  });
478
494
  CategoryClassificationSchema = import_zod.z.strictObject({
479
495
  $schema: import_zod.z.string().optional(),
@@ -2595,7 +2611,7 @@ function listFrontDoorSessions(fs12, sessionsDir) {
2595
2611
  try {
2596
2612
  const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs12.readFileUtf8(import_node_path8.default.join(sessionsDir, name)) ?? ""));
2597
2613
  if (parsed.success) {
2598
- sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
2614
+ sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
2599
2615
  }
2600
2616
  } catch {
2601
2617
  continue;
@@ -2623,7 +2639,7 @@ var init_state = __esm({
2623
2639
  import_node_path8 = __toESM(require("node:path"), 1);
2624
2640
  import_zod3 = require("zod");
2625
2641
  FRONT_DOOR_PROTOCOL = 3;
2626
- FrontDoorSessionSchema = import_zod3.z.strictObject({ pid: import_zod3.z.number().int().positive(), startedAt: import_zod3.z.number(), token: import_zod3.z.string().min(1) });
2642
+ FrontDoorSessionSchema = import_zod3.z.strictObject({ pid: import_zod3.z.number().int().positive(), startedAt: import_zod3.z.number(), token: import_zod3.z.string().min(1), supervisorPid: import_zod3.z.number().int().positive().optional() });
2627
2643
  FrontDoorStateSchema = import_zod3.z.strictObject({
2628
2644
  /**
2629
2645
  * 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`).
@@ -2663,7 +2679,7 @@ var init_package = __esm({
2663
2679
  "package.json"() {
2664
2680
  package_default = {
2665
2681
  name: "claude-use",
2666
- version: "9.12.1",
2682
+ version: "9.14.0",
2667
2683
  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.",
2668
2684
  license: "MIT",
2669
2685
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -2766,6 +2782,36 @@ var init_package = __esm({
2766
2782
  }
2767
2783
  });
2768
2784
 
2785
+ // src/frontdoor/supervisorProcesses.ts
2786
+ function parseFrontDoorSupervisorPids(psOutput) {
2787
+ const pids = [];
2788
+ for (const line of psOutput.split("\n")) {
2789
+ const [pidText, ...argumentsList] = line.trim().split(/\s+/);
2790
+ const pid = Number(pidText);
2791
+ if (Number.isInteger(pid) && pid > 0 && argumentsList.includes(FRONT_DOOR_SUPERVISOR_ARGUMENT)) {
2792
+ pids.push(pid);
2793
+ }
2794
+ }
2795
+ return pids.sort((a, b) => a - b);
2796
+ }
2797
+ function listFrontDoorSupervisors(run, uid) {
2798
+ const result = run.run("ps", ["-U", String(uid), "-o", "pid=,command="]);
2799
+ if (result.status === null) {
2800
+ return { ok: false, message: "ps could not be run" };
2801
+ }
2802
+ if (result.status !== 0) {
2803
+ return { ok: false, message: `ps exited ${String(result.status)}${result.stderr.trim() === "" ? "" : `: ${result.stderr.trim()}`}` };
2804
+ }
2805
+ return { ok: true, pids: parseFrontDoorSupervisorPids(result.stdout) };
2806
+ }
2807
+ var FRONT_DOOR_SUPERVISOR_ARGUMENT;
2808
+ var init_supervisorProcesses = __esm({
2809
+ "src/frontdoor/supervisorProcesses.ts"() {
2810
+ "use strict";
2811
+ FRONT_DOOR_SUPERVISOR_ARGUMENT = "__frontdoor-supervisor";
2812
+ }
2813
+ });
2814
+
2769
2815
  // src/headroom/state.ts
2770
2816
  function parseJson(raw, schema) {
2771
2817
  if (raw === void 0 || raw.trim() === "") {
@@ -3363,9 +3409,15 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3363
3409
  await ports.sleep(HEADROOM_POLL_MS);
3364
3410
  }
3365
3411
  }
3412
+ function currentHeadroomAllowlistInputs(fs12, paths) {
3413
+ return {
3414
+ providers: readAllProviders(fs12, paths.providersDir).map((entry) => entry.provider),
3415
+ frontDoorOrigin: frontDoorOrigin(readFrontDoorState(fs12, paths.frontdoorStateFile))
3416
+ };
3417
+ }
3366
3418
  function currentHeadroomAllowlist(fs12, paths) {
3367
- const providers = readAllProviders(fs12, paths.providersDir).map((entry) => entry.provider);
3368
- return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(fs12, paths.frontdoorStateFile))));
3419
+ const inputs = currentHeadroomAllowlistInputs(fs12, paths);
3420
+ return headroomAllowlist(headroomUpstreams(inputs.providers, inputs.frontDoorOrigin));
3369
3421
  }
3370
3422
  function allowlistOf(ports) {
3371
3423
  return currentHeadroomAllowlist(ports.fs, ports.paths);
@@ -3428,8 +3480,8 @@ function realIsProcessRunning(pid) {
3428
3480
  return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
3429
3481
  }
3430
3482
  function realIsFrontDoorSupervisor(pid) {
3431
- const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8" });
3432
- return result.status === 0 && result.stdout.split(/\s+/).includes(FRONT_DOOR_SUPERVISOR_SUBCOMMAND);
3483
+ const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "pid=,command=", "-p", String(pid)], { encoding: "utf8" });
3484
+ return result.status === 0 && parseFrontDoorSupervisorPids(result.stdout).includes(pid);
3433
3485
  }
3434
3486
  function expandHome2(filePath) {
3435
3487
  return filePath.startsWith("~/") ? import_node_path13.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
@@ -3628,7 +3680,7 @@ function realResolveClaudeBinary(isOwnBinary) {
3628
3680
  function realInstalledClaudeVersions() {
3629
3681
  return installedVersions(listVersionsDir(defaultVersionsDir()));
3630
3682
  }
3631
- var import_node_child_process2, import_node_crypto8, import_node_fs2, import_node_os2, import_node_path13, import_node_sea, 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;
3683
+ var import_node_child_process2, import_node_crypto8, import_node_fs2, import_node_os2, import_node_path13, import_node_sea, 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;
3632
3684
  var init_realPorts = __esm({
3633
3685
  "src/realPorts.ts"() {
3634
3686
  "use strict";
@@ -3640,6 +3692,7 @@ var init_realPorts = __esm({
3640
3692
  import_node_sea = require("node:sea");
3641
3693
  init_load();
3642
3694
  init_versionDiscovery();
3695
+ init_supervisorProcesses();
3643
3696
  init_ensure();
3644
3697
  init_supervisor();
3645
3698
  init_state2();
@@ -3769,7 +3822,6 @@ var init_realPorts = __esm({
3769
3822
  }
3770
3823
  };
3771
3824
  INT32_BYTE_LENGTH = 4;
3772
- FRONT_DOOR_SUPERVISOR_SUBCOMMAND = "__frontdoor-supervisor";
3773
3825
  realRunPort = {
3774
3826
  run(command, args) {
3775
3827
  const result = (0, import_node_child_process2.spawnSync)(command, [...args], { encoding: "utf8" });
@@ -4676,7 +4728,7 @@ function assessIdentity(member, nowMs) {
4676
4728
  );
4677
4729
  if (blockedUntil > nowMs) {
4678
4730
  if (unified.overageStatus === "allowed") {
4679
- return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
4731
+ 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] } };
4680
4732
  }
4681
4733
  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] } };
4682
4734
  }
@@ -4791,7 +4843,8 @@ function rankPool(input) {
4791
4843
  return {
4792
4844
  candidates: ordered,
4793
4845
  ...pick === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick },
4794
- ...movedOff === void 0 || pick === void 0 ? {} : { movedOff }
4846
+ ...movedOff === void 0 || pick === void 0 ? {} : { movedOff },
4847
+ ...pick?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick.identity, atMs: pick.planReturnsAtMs } }
4795
4848
  };
4796
4849
  }
4797
4850
  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;
@@ -5270,6 +5323,7 @@ function buildLayoutPaths(root) {
5270
5323
  usageLogDir: import_node_path22.default.join(root, "usage", "log"),
5271
5324
  usageSnapshotsDir: import_node_path22.default.join(root, "usage", "snapshots"),
5272
5325
  usagePicksFile: import_node_path22.default.join(root, "usage", "picks.json"),
5326
+ usageAnchorsFile: import_node_path22.default.join(root, "usage", "anchors.json"),
5273
5327
  mcpPermissionsFile: import_node_path22.default.join(root, "mcp", "permissions.json")
5274
5328
  };
5275
5329
  }
@@ -6204,7 +6258,7 @@ function ensureFrontDoor(params) {
6204
6258
  }
6205
6259
  if (verdict.ok) {
6206
6260
  const token = (0, import_node_crypto9.randomUUID)();
6207
- writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token });
6261
+ writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid });
6208
6262
  return { port: state.port, connectPort: state.connectPort, token };
6209
6263
  }
6210
6264
  lastRejection = `the listener on 127.0.0.1:${String(state.port)} (recorded for pid ${String(supervisorPid)}) failed authentication: ${verdict.reason}`;
@@ -6739,7 +6793,12 @@ function resolvePoolLaunch(params) {
6739
6793
  if (graph.ranking.candidates.length === 0) {
6740
6794
  return { ok: false, message: `agent-shim: no member of pool "${poolName}" is an existing identity.` };
6741
6795
  }
6742
- const { pick, earliestReturn, movedOff } = graph.ranking;
6796
+ const { pick, earliestReturn, movedOff, planReturn } = graph.ranking;
6797
+ if (pick !== void 0 && params.wait && planReturn !== void 0) {
6798
+ log.info(`agent-shim: pool "${poolName}" would continue ${planReturn.identity} on extra usage; waiting until ${new Date(planReturn.atMs).toISOString()} for its plan window`);
6799
+ params.sleep(Math.max(planReturn.atMs - nowMs, 0));
6800
+ continue;
6801
+ }
6743
6802
  if (pick !== void 0) {
6744
6803
  if (params.recordPick) {
6745
6804
  recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
@@ -7767,6 +7826,57 @@ var init_anthropicUsageRefresh = __esm({
7767
7826
  }
7768
7827
  });
7769
7828
 
7829
+ // src/usage/identityClaude.ts
7830
+ function definedEnvironment(env) {
7831
+ return Object.fromEntries(Object.entries(env).flatMap(([name, value]) => value === void 0 ? [] : [[name, value]]));
7832
+ }
7833
+ function identityLaunchArgv(identity, flags) {
7834
+ return [`@${identity}`, IDENTITY_ONLY_FLAG, ...flags];
7835
+ }
7836
+ async function withIdentityClaude(params, identity, flags, use) {
7837
+ const refusals = [];
7838
+ const plan = prepareLaunch(
7839
+ realPrepareLaunchParams(params.paths, {
7840
+ proc: {
7841
+ env: Object.fromEntries(Object.entries(process.env).filter(([name]) => name !== CONFIG_DIR_VARIABLE)),
7842
+ argv: [...identityLaunchArgv(identity, flags)],
7843
+ exit: (code) => {
7844
+ throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
7845
+ }
7846
+ },
7847
+ log: {
7848
+ info: () => void 0,
7849
+ warn: () => void 0,
7850
+ error: (message) => {
7851
+ refusals.push(message);
7852
+ }
7853
+ },
7854
+ spawnDaemon: params.spawnDaemon,
7855
+ farm: buildFarmRuntime(params.paths, params.cwd)
7856
+ })
7857
+ );
7858
+ const abort = new AbortController();
7859
+ const timer = setTimeout(() => {
7860
+ abort.abort();
7861
+ }, params.timeoutMs);
7862
+ try {
7863
+ return await use({ bin: plan.bin, env: definedEnvironment(plan.env), cwd: params.cwd, abort });
7864
+ } finally {
7865
+ clearTimeout(timer);
7866
+ plan.release();
7867
+ }
7868
+ }
7869
+ var CONFIG_DIR_VARIABLE, IDENTITY_ONLY_FLAG;
7870
+ var init_identityClaude = __esm({
7871
+ "src/usage/identityClaude.ts"() {
7872
+ "use strict";
7873
+ init_launchWiring();
7874
+ init_launcher();
7875
+ CONFIG_DIR_VARIABLE = "CLAUDE_CONFIG_DIR";
7876
+ IDENTITY_ONLY_FLAG = "--no-provider";
7877
+ }
7878
+ });
7879
+
7770
7880
  // src/usage/providerQuota.ts
7771
7881
  var import_zod25, 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;
7772
7882
  var init_providerQuota = __esm({
@@ -7837,9 +7947,6 @@ var realAnthropicUsageProbe_exports = {};
7837
7947
  __export(realAnthropicUsageProbe_exports, {
7838
7948
  createRealAnthropicUsageRefresher: () => createRealAnthropicUsageRefresher
7839
7949
  });
7840
- function definedEnvironment(env) {
7841
- return Object.fromEntries(Object.entries(env).flatMap(([name, value]) => value === void 0 ? [] : [[name, value]]));
7842
- }
7843
7950
  function idlePrompt(signal) {
7844
7951
  return {
7845
7952
  [Symbol.asyncIterator]: () => ({
@@ -7852,58 +7959,28 @@ function idlePrompt(signal) {
7852
7959
  };
7853
7960
  }
7854
7961
  function createRealAnthropicUsageProbe(params) {
7855
- return async (identity) => {
7856
- const refusals = [];
7857
- const plan = prepareLaunch(
7858
- realPrepareLaunchParams(params.paths, {
7859
- proc: {
7860
- env: Object.fromEntries(Object.entries(process.env).filter(([name]) => name !== CONFIG_DIR_VARIABLE)),
7861
- argv: [`@${identity}`, ...PROBE_LAUNCH_FLAGS],
7862
- exit: (code) => {
7863
- throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
7864
- }
7865
- },
7866
- log: {
7867
- info: () => void 0,
7868
- warn: () => void 0,
7869
- error: (message) => {
7870
- refusals.push(message);
7871
- }
7872
- },
7873
- spawnDaemon: params.spawnDaemon,
7874
- farm: buildFarmRuntime(params.paths, params.cwd)
7875
- })
7876
- );
7962
+ return async (identity) => await withIdentityClaude(params, identity, PROBE_LAUNCH_FLAGS, async ({ bin, env, cwd, abort }) => {
7877
7963
  const { query } = await import("@anthropic-ai/claude-agent-sdk");
7878
- const abort = new AbortController();
7879
- const timer = setTimeout(() => {
7880
- abort.abort();
7881
- }, params.timeoutMs);
7882
- try {
7883
- const session = query({
7884
- prompt: idlePrompt(abort.signal),
7885
- options: {
7886
- pathToClaudeCodeExecutable: plan.bin,
7887
- env: definedEnvironment(plan.env),
7888
- cwd: params.cwd,
7889
- abortController: abort,
7890
- settingSources: [],
7891
- mcpServers: {},
7892
- strictMcpConfig: true,
7893
- persistSession: false
7894
- }
7895
- });
7896
- try {
7897
- const report = await session.usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET({ skipBehaviors: true });
7898
- return unifiedFromReportedLimits(report.rate_limits_available ? report.rate_limits : null);
7899
- } finally {
7900
- session.close();
7964
+ const session = query({
7965
+ prompt: idlePrompt(abort.signal),
7966
+ options: {
7967
+ pathToClaudeCodeExecutable: bin,
7968
+ env,
7969
+ cwd,
7970
+ abortController: abort,
7971
+ settingSources: [],
7972
+ mcpServers: {},
7973
+ strictMcpConfig: true,
7974
+ persistSession: false
7901
7975
  }
7976
+ });
7977
+ try {
7978
+ const report = await session.usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET({ skipBehaviors: true });
7979
+ return unifiedFromReportedLimits(report.rate_limits_available ? report.rate_limits : null);
7902
7980
  } finally {
7903
- clearTimeout(timer);
7904
- plan.release();
7981
+ session.close();
7905
7982
  }
7906
- };
7983
+ });
7907
7984
  }
7908
7985
  function createRealAnthropicUsageRefresher(params) {
7909
7986
  return createAnthropicUsageRefresher({
@@ -7916,18 +7993,16 @@ function createRealAnthropicUsageRefresher(params) {
7916
7993
  concurrency: (0, import_node_os8.availableParallelism)()
7917
7994
  });
7918
7995
  }
7919
- var import_node_os8, PROBE_LAUNCH_FLAGS, CONFIG_DIR_VARIABLE;
7996
+ var import_node_os8, PROBE_LAUNCH_FLAGS;
7920
7997
  var init_realAnthropicUsageProbe = __esm({
7921
7998
  "src/usage/realAnthropicUsageProbe.ts"() {
7922
7999
  "use strict";
7923
8000
  import_node_os8 = require("node:os");
7924
- init_launchWiring();
7925
- init_launcher();
7926
8001
  init_anthropicUsageRefresh();
8002
+ init_identityClaude();
7927
8003
  init_middleware();
7928
8004
  init_quotaRefresh();
7929
8005
  PROBE_LAUNCH_FLAGS = ["--no-headroom", "--no-remote-control"];
7930
- CONFIG_DIR_VARIABLE = "CLAUDE_CONFIG_DIR";
7931
8006
  }
7932
8007
  });
7933
8008
 
@@ -8701,16 +8776,27 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
8701
8776
  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)}`);
8702
8777
  let idleSince;
8703
8778
  let ticks = 0;
8779
+ const supersedingOwner = () => {
8780
+ const owner = readFrontDoorState(fs12, paths.frontdoorStateFile)?.supervisorPid;
8781
+ return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
8782
+ };
8783
+ let supersededBy;
8784
+ let served;
8704
8785
  const binaryReplaced = () => {
8705
8786
  const current = ports.statOwnExecutable();
8706
8787
  return current !== void 0 && servingBinary !== void 0 && (current.dev !== servingBinary.dev || current.ino !== servingBinary.ino || current.size !== servingBinary.size || current.mtimeMs !== servingBinary.mtimeMs);
8707
8788
  };
8708
- const shutdown = async () => {
8789
+ const closeServing = async () => {
8709
8790
  await direct.close();
8710
8791
  await connect3.close();
8711
8792
  await http3.close();
8712
8793
  ports.closeRcStreamHub();
8713
- writeFrontDoorState(fs12, paths.frontdoorStateFile, sticky());
8794
+ };
8795
+ const shutdown = async () => {
8796
+ await closeServing();
8797
+ if (supersedingOwner() === void 0) {
8798
+ writeFrontDoorState(fs12, paths.frontdoorStateFile, sticky());
8799
+ }
8714
8800
  return 0;
8715
8801
  };
8716
8802
  for (; ; ) {
@@ -8723,7 +8809,28 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
8723
8809
  ports.observeLaunchRegistry(listed, pruned);
8724
8810
  ports.checkQuotaExpiry();
8725
8811
  const prunedPids = new Set(pruned);
8726
- if (listed.filter((session) => !prunedPids.has(session.pid)).length === 0) {
8812
+ const live = listed.filter((session) => !prunedPids.has(session.pid));
8813
+ if (supersededBy === void 0) {
8814
+ supersededBy = supersedingOwner();
8815
+ if (supersededBy !== void 0) {
8816
+ 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`);
8817
+ ports.doorHealth.superseded(supersededBy);
8818
+ await ports.sleep(FRONTDOOR_POLL_MS);
8819
+ continue;
8820
+ }
8821
+ } else {
8822
+ const owner = supersededBy;
8823
+ 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));
8824
+ if (served.length === 0) {
8825
+ ports.log("agent-shim frontdoor supervisor: the sessions this superseded door served have ended; closing the front door and exiting");
8826
+ ports.doorHealth.drained();
8827
+ await closeServing();
8828
+ return 0;
8829
+ }
8830
+ await ports.sleep(FRONTDOOR_POLL_MS);
8831
+ continue;
8832
+ }
8833
+ if (live.length === 0) {
8727
8834
  if (ticks > 1 && binaryReplaced()) {
8728
8835
  ports.log("agent-shim frontdoor supervisor: the installed binary changed and no sessions are live; turning the door over for the next launch");
8729
8836
  ports.doorHealth.binaryTurnover();
@@ -12715,6 +12822,12 @@ function listIdentities(paths) {
12715
12822
  }
12716
12823
  return result;
12717
12824
  }
12825
+ function setIdentityAnchors(paths, identityName, anchors) {
12826
+ if (!identityExists(paths, identityName)) {
12827
+ throw new IdentityNotFoundError(identityName);
12828
+ }
12829
+ return applyPatch(identityJsonPath(paths, identityName), IdentitySchema, { anchors: anchors === void 0 ? void 0 : [...anchors] });
12830
+ }
12718
12831
  function setDefaultConfigProfile(paths, identityName, profileName) {
12719
12832
  if (!identityExists(paths, identityName)) {
12720
12833
  throw new IdentityNotFoundError(identityName);
@@ -12877,7 +12990,55 @@ init_credential();
12877
12990
  init_credentialCache();
12878
12991
  init_realCredentialCache();
12879
12992
  init_source();
12993
+
12994
+ // src/headroom/allowlistDrift.ts
12995
+ init_state2();
12996
+ function diagnoseAllowlistDrift(params) {
12997
+ const { recordedHash, providers, frontDoorOrigin: frontDoorOrigin2 } = params;
12998
+ if (recordedHash === void 0 || recordedHash === hashAllowlist(headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin2)))) {
12999
+ return void 0;
13000
+ }
13001
+ const originIsInput = providers.length > 0 && frontDoorOrigin2 !== void 0;
13002
+ if (!originIsInput) {
13003
+ return ["provider-files"];
13004
+ }
13005
+ return recordedHash === hashAllowlist(headroomAllowlist(headroomUpstreams(providers, void 0))) ? ["front-door-origin"] : ["provider-files", "front-door-origin"];
13006
+ }
13007
+
13008
+ // src/doctorReport.ts
12880
13009
  init_state2();
13010
+ init_supervisor();
13011
+ init_state();
13012
+
13013
+ // src/doctorFrontDoor.ts
13014
+ function pushFrontDoor(push, supervisors, registeredPid) {
13015
+ if (!supervisors.ok) {
13016
+ push("frontdoor", "warn", `Could not list processes to look for duplicate front door supervisors: ${supervisors.message}.`);
13017
+ return;
13018
+ }
13019
+ const { pids } = supervisors;
13020
+ if (pids.length === 0) {
13021
+ push("frontdoor", "pass", "No front door supervisor is running.");
13022
+ return;
13023
+ }
13024
+ const [only, ...rest] = pids;
13025
+ if (only !== void 0 && rest.length === 0) {
13026
+ push("frontdoor", "pass", `One front door supervisor is running (pid ${String(only)}).`);
13027
+ return;
13028
+ }
13029
+ 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.";
13030
+ for (const pid of pids.filter((candidate) => candidate !== registeredPid)) {
13031
+ push(
13032
+ "frontdoor",
13033
+ "fail",
13034
+ `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.`,
13035
+ String(pid)
13036
+ );
13037
+ }
13038
+ }
13039
+
13040
+ // src/doctorReport.ts
13041
+ init_supervisorProcesses();
12881
13042
  init_legacy();
12882
13043
  init_providersStore();
12883
13044
  init_guard();
@@ -12900,7 +13061,8 @@ var DOCTOR_SECTIONS = [
12900
13061
  "global-config",
12901
13062
  "categories-local",
12902
13063
  "active-identity",
12903
- "headroom"
13064
+ "headroom",
13065
+ "frontdoor"
12904
13066
  ];
12905
13067
  function refinePathShadow(status, ownExecutablePath, realpath) {
12906
13068
  if (status.status !== "shadowed") {
@@ -13296,6 +13458,17 @@ function runDoctor(params) {
13296
13458
  `Headroom daemon is up on unix socket ${state.socketPath} (supervisor ${String(state.supervisorPid)}, daemon ${String(state.headroomPid)}).`
13297
13459
  );
13298
13460
  }
13461
+ const allowlist = params.headroom.allowlist;
13462
+ if (supervisorAlive && headroomAlive && state.socketPath !== void 0 && allowlist?.driftInputs?.includes("front-door-origin") === true) {
13463
+ const origin = allowlist.frontDoorOrigin ?? "";
13464
+ const certainty = allowlist.driftInputs.includes("provider-files") ? "may exclude" : "excludes";
13465
+ push(
13466
+ "headroom",
13467
+ "fail",
13468
+ `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.`,
13469
+ String(state.headroomPid)
13470
+ );
13471
+ }
13299
13472
  if (state.lastError !== void 0 && supervisorAlive) {
13300
13473
  push("headroom", "warn", `Headroom recorded a previous error: ${state.lastError}`);
13301
13474
  }
@@ -13308,6 +13481,10 @@ function runDoctor(params) {
13308
13481
  }
13309
13482
  }
13310
13483
  }
13484
+ if (params.frontDoor !== void 0) {
13485
+ const validated3 = params.frontDoor.state.raw === void 0 ? void 0 : validateJson(FrontDoorStateSchema, params.frontDoor.state);
13486
+ pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0);
13487
+ }
13311
13488
  if (params.activeIdentity.raw === void 0) {
13312
13489
  push("active-identity", "pass", "No active identity set.");
13313
13490
  } else {
@@ -13337,6 +13514,7 @@ var SECTION_TITLES = {
13337
13514
  "directory-rules": "Directory rules",
13338
13515
  "global-config": "Global config",
13339
13516
  headroom: "Headroom daemon",
13517
+ frontdoor: "Front door",
13340
13518
  "categories-local": "categories.local.json",
13341
13519
  "active-identity": "Active identity"
13342
13520
  };
@@ -13354,6 +13532,7 @@ var SECTION_ORDER = [
13354
13532
  "directory-rules",
13355
13533
  "global-config",
13356
13534
  "headroom",
13535
+ "frontdoor",
13357
13536
  "categories-local",
13358
13537
  "active-identity"
13359
13538
  ];
@@ -13431,6 +13610,9 @@ function collectDoctorReport(params) {
13431
13610
  shimState.targetPath,
13432
13611
  realpathOrSelf
13433
13612
  );
13613
+ const uid = process.getuid?.();
13614
+ const allowlistInputs = currentHeadroomAllowlistInputs(realFarmFs, paths);
13615
+ const servingHeadroom = resolveServingHeadroomState(realFarmFs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, realIsProcessRunning);
13434
13616
  const report = runDoctor({
13435
13617
  env: params.env,
13436
13618
  credentialCache: realCredentialCacheEnv(paths),
@@ -13469,8 +13651,13 @@ function collectDoctorReport(params) {
13469
13651
  const statePath = resolved?.path ?? paths.headroomStateFile;
13470
13652
  return { path: statePath, raw: realFarmFs.readFileUtf8(statePath) };
13471
13653
  })(),
13472
- isRunning: realIsProcessRunning
13473
- }
13654
+ isRunning: realIsProcessRunning,
13655
+ allowlist: {
13656
+ driftInputs: diagnoseAllowlistDrift({ recordedHash: servingHeadroom?.state.allowlistHash, ...allowlistInputs }),
13657
+ frontDoorOrigin: allowlistInputs.frontDoorOrigin
13658
+ }
13659
+ },
13660
+ ...uid === void 0 ? {} : { frontDoor: { state: { path: paths.frontdoorStateFile, raw: realFsPort.readFileUtf8(paths.frontdoorStateFile) }, supervisors: listFrontDoorSupervisors(realRunPort, uid) } }
13474
13661
  });
13475
13662
  return report;
13476
13663
  }
@@ -13745,7 +13932,8 @@ var IdentityValueSchema = import_zod22.z.strictObject({
13745
13932
  name: import_zod22.z.string(),
13746
13933
  defaultConfigProfile: import_zod22.z.string().optional(),
13747
13934
  allowAmbientCredential: import_zod22.z.boolean(),
13748
- credential: CredentialSummarySchema2.optional()
13935
+ credential: CredentialSummarySchema2.optional(),
13936
+ anchors: import_zod22.z.array(AnchorSchema).optional()
13749
13937
  });
13750
13938
  var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
13751
13939
  var ProviderValueSchema = import_zod22.z.strictObject({
@@ -13763,7 +13951,9 @@ var ConfigIdentitySetInputSchema = import_zod22.z.strictObject({
13763
13951
  name: import_zod22.z.string().min(1),
13764
13952
  defaultConfigProfile: import_zod22.z.union([import_zod22.z.string().min(1), import_zod22.z.literal(false)]).optional(),
13765
13953
  allowAmbientCredential: import_zod22.z.boolean().optional(),
13766
- credential: import_zod22.z.union([import_zod22.z.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional()
13954
+ credential: import_zod22.z.union([import_zod22.z.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional(),
13955
+ /** `false` removes the anchors; a list replaces them. */
13956
+ anchors: import_zod22.z.union([import_zod22.z.literal(false), import_zod22.z.array(AnchorSchema).min(1)]).optional()
13767
13957
  });
13768
13958
  var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
13769
13959
  var ConfigIdentityRemoveInputSchema = import_zod22.z.strictObject({ name: import_zod22.z.string().min(1), confirm: RemovalConfirmationSchema });
@@ -13884,7 +14074,8 @@ function identityValue(name, paths) {
13884
14074
  name: identity.name,
13885
14075
  ...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
13886
14076
  allowAmbientCredential: identity.allowAmbientCredential,
13887
- ...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) }
14077
+ ...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) },
14078
+ ...identity.anchors === void 0 ? {} : { anchors: identity.anchors }
13888
14079
  };
13889
14080
  }
13890
14081
  function providerValue(name, provider) {
@@ -13915,9 +14106,9 @@ function createConfigApiRouter(deps) {
13915
14106
  return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
13916
14107
  })
13917
14108
  ),
13918
- set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting or credential").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
14109
+ set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting, credential or anchors").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
13919
14110
  ({ input }) => guarded(() => {
13920
- requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0, "defaultConfigProfile, allowAmbientCredential or credential");
14111
+ requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0 || input.anchors !== void 0, "defaultConfigProfile, allowAmbientCredential, credential or anchors");
13921
14112
  if (!identityExists(paths, input.name)) {
13922
14113
  throw new IdentityNotFoundError(input.name);
13923
14114
  }
@@ -13942,6 +14133,9 @@ function createConfigApiRouter(deps) {
13942
14133
  };
13943
14134
  setIdentityCredential(paths, input.name, change);
13944
14135
  }
14136
+ if (input.anchors !== void 0) {
14137
+ setIdentityAnchors(paths, input.name, input.anchors === false ? void 0 : input.anchors);
14138
+ }
13945
14139
  return { action: "updated", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
13946
14140
  })
13947
14141
  ),
@@ -14172,7 +14366,9 @@ var DoorHealthEventSchema = import_zod23.z.discriminatedUnion("kind", [
14172
14366
  import_zod23.z.strictObject({ kind: import_zod23.z.literal("generation"), pid: import_zod23.z.number().int().positive(), providerPort: import_zod23.z.number().int().positive(), connectPort: import_zod23.z.number().int().positive(), directPort: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() }),
14173
14367
  import_zod23.z.strictObject({ kind: import_zod23.z.literal("listenerFailed"), pid: import_zod23.z.number().int().positive(), listener: import_zod23.z.enum(["provider", "connect", "direct"]), message: import_zod23.z.string(), observedAt: import_zod23.z.number() }),
14174
14368
  import_zod23.z.strictObject({ kind: import_zod23.z.literal("binaryTurnover"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() }),
14175
- import_zod23.z.strictObject({ kind: import_zod23.z.literal("idleShutdown"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() })
14369
+ import_zod23.z.strictObject({ kind: import_zod23.z.literal("idleShutdown"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() }),
14370
+ import_zod23.z.strictObject({ kind: import_zod23.z.literal("superseded"), pid: import_zod23.z.number().int().positive(), ownerPid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() }),
14371
+ import_zod23.z.strictObject({ kind: import_zod23.z.literal("drained"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() })
14176
14372
  ]);
14177
14373
  var QuotaExpiringEventSchema = import_zod23.z.strictObject({
14178
14374
  identity: import_zod23.z.string().min(1),
@@ -14669,6 +14865,12 @@ function createDoorHealthPublisher(hub, now, pid) {
14669
14865
  },
14670
14866
  binaryTurnover: () => {
14671
14867
  publisher.publish({ kind: "binaryTurnover", pid, observedAt: now() });
14868
+ },
14869
+ superseded: (ownerPid) => {
14870
+ publisher.publish({ kind: "superseded", pid, ownerPid, observedAt: now() });
14871
+ },
14872
+ drained: () => {
14873
+ publisher.publish({ kind: "drained", pid, observedAt: now() });
14672
14874
  }
14673
14875
  };
14674
14876
  }