claude-use 9.12.0 → 9.13.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
@@ -2595,7 +2595,7 @@ function listFrontDoorSessions(fs12, sessionsDir) {
2595
2595
  try {
2596
2596
  const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs12.readFileUtf8(import_node_path8.default.join(sessionsDir, name)) ?? ""));
2597
2597
  if (parsed.success) {
2598
- sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
2598
+ sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
2599
2599
  }
2600
2600
  } catch {
2601
2601
  continue;
@@ -2623,7 +2623,7 @@ var init_state = __esm({
2623
2623
  import_node_path8 = __toESM(require("node:path"), 1);
2624
2624
  import_zod3 = require("zod");
2625
2625
  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) });
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), supervisorPid: import_zod3.z.number().int().positive().optional() });
2627
2627
  FrontDoorStateSchema = import_zod3.z.strictObject({
2628
2628
  /**
2629
2629
  * 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 +2663,7 @@ var init_package = __esm({
2663
2663
  "package.json"() {
2664
2664
  package_default = {
2665
2665
  name: "claude-use",
2666
- version: "9.12.0",
2666
+ version: "9.13.0",
2667
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.",
2668
2668
  license: "MIT",
2669
2669
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -2766,6 +2766,36 @@ var init_package = __esm({
2766
2766
  }
2767
2767
  });
2768
2768
 
2769
+ // src/frontdoor/supervisorProcesses.ts
2770
+ function parseFrontDoorSupervisorPids(psOutput) {
2771
+ const pids = [];
2772
+ for (const line of psOutput.split("\n")) {
2773
+ const [pidText, ...argumentsList] = line.trim().split(/\s+/);
2774
+ const pid = Number(pidText);
2775
+ if (Number.isInteger(pid) && pid > 0 && argumentsList.includes(FRONT_DOOR_SUPERVISOR_ARGUMENT)) {
2776
+ pids.push(pid);
2777
+ }
2778
+ }
2779
+ return pids.sort((a, b) => a - b);
2780
+ }
2781
+ function listFrontDoorSupervisors(run, uid) {
2782
+ const result = run.run("ps", ["-U", String(uid), "-o", "pid=,command="]);
2783
+ if (result.status === null) {
2784
+ return { ok: false, message: "ps could not be run" };
2785
+ }
2786
+ if (result.status !== 0) {
2787
+ return { ok: false, message: `ps exited ${String(result.status)}${result.stderr.trim() === "" ? "" : `: ${result.stderr.trim()}`}` };
2788
+ }
2789
+ return { ok: true, pids: parseFrontDoorSupervisorPids(result.stdout) };
2790
+ }
2791
+ var FRONT_DOOR_SUPERVISOR_ARGUMENT;
2792
+ var init_supervisorProcesses = __esm({
2793
+ "src/frontdoor/supervisorProcesses.ts"() {
2794
+ "use strict";
2795
+ FRONT_DOOR_SUPERVISOR_ARGUMENT = "__frontdoor-supervisor";
2796
+ }
2797
+ });
2798
+
2769
2799
  // src/headroom/state.ts
2770
2800
  function parseJson(raw, schema) {
2771
2801
  if (raw === void 0 || raw.trim() === "") {
@@ -3363,9 +3393,15 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3363
3393
  await ports.sleep(HEADROOM_POLL_MS);
3364
3394
  }
3365
3395
  }
3396
+ function currentHeadroomAllowlistInputs(fs12, paths) {
3397
+ return {
3398
+ providers: readAllProviders(fs12, paths.providersDir).map((entry) => entry.provider),
3399
+ frontDoorOrigin: frontDoorOrigin(readFrontDoorState(fs12, paths.frontdoorStateFile))
3400
+ };
3401
+ }
3366
3402
  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))));
3403
+ const inputs = currentHeadroomAllowlistInputs(fs12, paths);
3404
+ return headroomAllowlist(headroomUpstreams(inputs.providers, inputs.frontDoorOrigin));
3369
3405
  }
3370
3406
  function allowlistOf(ports) {
3371
3407
  return currentHeadroomAllowlist(ports.fs, ports.paths);
@@ -3427,6 +3463,10 @@ function realIsProcessZombie(pid) {
3427
3463
  function realIsProcessRunning(pid) {
3428
3464
  return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
3429
3465
  }
3466
+ function realIsFrontDoorSupervisor(pid) {
3467
+ const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "pid=,command=", "-p", String(pid)], { encoding: "utf8" });
3468
+ return result.status === 0 && parseFrontDoorSupervisorPids(result.stdout).includes(pid);
3469
+ }
3430
3470
  function expandHome2(filePath) {
3431
3471
  return filePath.startsWith("~/") ? import_node_path13.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
3432
3472
  }
@@ -3636,6 +3676,7 @@ var init_realPorts = __esm({
3636
3676
  import_node_sea = require("node:sea");
3637
3677
  init_load();
3638
3678
  init_versionDiscovery();
3679
+ init_supervisorProcesses();
3639
3680
  init_ensure();
3640
3681
  init_supervisor();
3641
3682
  init_state2();
@@ -4671,7 +4712,7 @@ function assessIdentity(member, nowMs) {
4671
4712
  );
4672
4713
  if (blockedUntil > nowMs) {
4673
4714
  if (unified.overageStatus === "allowed") {
4674
- return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
4715
+ 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] } };
4675
4716
  }
4676
4717
  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] } };
4677
4718
  }
@@ -4786,7 +4827,8 @@ function rankPool(input) {
4786
4827
  return {
4787
4828
  candidates: ordered,
4788
4829
  ...pick === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick },
4789
- ...movedOff === void 0 || pick === void 0 ? {} : { movedOff }
4830
+ ...movedOff === void 0 || pick === void 0 ? {} : { movedOff },
4831
+ ...pick?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick.identity, atMs: pick.planReturnsAtMs } }
4790
4832
  };
4791
4833
  }
4792
4834
  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;
@@ -6166,32 +6208,50 @@ function ensureFrontDoor(params) {
6166
6208
  let replaced = false;
6167
6209
  const distrusted = /* @__PURE__ */ new Set();
6168
6210
  let lastRejection;
6211
+ const verifyWithRetry = (port) => {
6212
+ let verdict = ports.verifyListener(port);
6213
+ for (let attempt = 1; !verdict.ok && attempt < FRONTDOOR_PROBE_ATTEMPTS; attempt += 1) {
6214
+ ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
6215
+ verdict = ports.verifyListener(port);
6216
+ }
6217
+ return verdict;
6218
+ };
6219
+ const stopAndAwaitExit = (supervisorPid, failure) => {
6220
+ ports.stopSupervisor(supervisorPid);
6221
+ while (ports.isRunning(supervisorPid)) {
6222
+ if (ports.now() >= deadline) {
6223
+ throw new FrontDoorStartError(`${failure}. Daemon log: ${paths.frontdoorLogPath}`);
6224
+ }
6225
+ ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
6226
+ }
6227
+ };
6169
6228
  for (; ; ) {
6170
6229
  const state = readFrontDoorState(ports.fs, paths.frontdoorStateFile);
6171
6230
  const supervisorPid = state?.supervisorPid;
6172
6231
  if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
6173
6232
  if (state?.port !== void 0 && state.connectPort !== void 0) {
6174
- const verdict = ports.verifyListener(state.port);
6233
+ const verdict = verifyWithRetry(state.port);
6175
6234
  if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
6176
- ports.stopSupervisor(supervisorPid);
6177
- while (ports.isRunning(supervisorPid)) {
6178
- if (ports.now() >= deadline) {
6179
- throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit. Daemon log: ${paths.frontdoorLogPath}`);
6180
- }
6181
- ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
6182
- }
6235
+ stopAndAwaitExit(
6236
+ supervisorPid,
6237
+ `the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit`
6238
+ );
6183
6239
  replaced = true;
6184
6240
  continue;
6185
6241
  }
6186
6242
  if (verdict.ok) {
6187
6243
  const token = (0, import_node_crypto9.randomUUID)();
6188
- writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token });
6244
+ writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid });
6189
6245
  return { port: state.port, connectPort: state.connectPort, token };
6190
6246
  }
6191
6247
  lastRejection = `the listener on 127.0.0.1:${String(state.port)} (recorded for pid ${String(supervisorPid)}) failed authentication: ${verdict.reason}`;
6192
6248
  if (spawned) {
6193
6249
  throw new FrontDoorStartError(`${lastRejection}; refusing to send this session's credentials to it. Daemon log: ${paths.frontdoorLogPath}`);
6194
6250
  }
6251
+ if (ports.isFrontDoorSupervisor(supervisorPid)) {
6252
+ stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
6253
+ continue;
6254
+ }
6195
6255
  distrusted.add(supervisorPid);
6196
6256
  continue;
6197
6257
  }
@@ -6222,7 +6282,7 @@ function ensureFrontDoor(params) {
6222
6282
  ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
6223
6283
  }
6224
6284
  }
6225
- var import_node_crypto9, FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FrontDoorStartError;
6285
+ var import_node_crypto9, FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FRONTDOOR_PROBE_ATTEMPTS, FrontDoorStartError;
6226
6286
  var init_ensure2 = __esm({
6227
6287
  "src/frontdoor/ensure.ts"() {
6228
6288
  "use strict";
@@ -6232,6 +6292,7 @@ var init_ensure2 = __esm({
6232
6292
  init_state();
6233
6293
  FRONTDOOR_START_TIMEOUT_MS = 3e4;
6234
6294
  FRONTDOOR_LAUNCHER_POLL_MS = 100;
6295
+ FRONTDOOR_PROBE_ATTEMPTS = 3;
6235
6296
  FrontDoorStartError = class extends CliError {
6236
6297
  constructor(message) {
6237
6298
  super(message);
@@ -6715,7 +6776,12 @@ function resolvePoolLaunch(params) {
6715
6776
  if (graph.ranking.candidates.length === 0) {
6716
6777
  return { ok: false, message: `agent-shim: no member of pool "${poolName}" is an existing identity.` };
6717
6778
  }
6718
- const { pick, earliestReturn, movedOff } = graph.ranking;
6779
+ const { pick, earliestReturn, movedOff, planReturn } = graph.ranking;
6780
+ if (pick !== void 0 && params.wait && planReturn !== void 0) {
6781
+ log.info(`agent-shim: pool "${poolName}" would continue ${planReturn.identity} on extra usage; waiting until ${new Date(planReturn.atMs).toISOString()} for its plan window`);
6782
+ params.sleep(Math.max(planReturn.atMs - nowMs, 0));
6783
+ continue;
6784
+ }
6719
6785
  if (pick !== void 0) {
6720
6786
  if (params.recordPick) {
6721
6787
  recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
@@ -7418,6 +7484,7 @@ function realEnsurePorts(paths, spawnDaemon) {
7418
7484
  now: () => Date.now(),
7419
7485
  sleep: realSleepSync,
7420
7486
  spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
7487
+ isFrontDoorSupervisor: realIsFrontDoorSupervisor,
7421
7488
  stopSupervisor: (pid) => {
7422
7489
  process.kill(pid, "SIGTERM");
7423
7490
  },
@@ -8676,16 +8743,27 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
8676
8743
  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)}`);
8677
8744
  let idleSince;
8678
8745
  let ticks = 0;
8746
+ const supersedingOwner = () => {
8747
+ const owner = readFrontDoorState(fs12, paths.frontdoorStateFile)?.supervisorPid;
8748
+ return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
8749
+ };
8750
+ let supersededBy;
8751
+ let served;
8679
8752
  const binaryReplaced = () => {
8680
8753
  const current = ports.statOwnExecutable();
8681
8754
  return current !== void 0 && servingBinary !== void 0 && (current.dev !== servingBinary.dev || current.ino !== servingBinary.ino || current.size !== servingBinary.size || current.mtimeMs !== servingBinary.mtimeMs);
8682
8755
  };
8683
- const shutdown = async () => {
8756
+ const closeServing = async () => {
8684
8757
  await direct.close();
8685
8758
  await connect3.close();
8686
8759
  await http3.close();
8687
8760
  ports.closeRcStreamHub();
8688
- writeFrontDoorState(fs12, paths.frontdoorStateFile, sticky());
8761
+ };
8762
+ const shutdown = async () => {
8763
+ await closeServing();
8764
+ if (supersedingOwner() === void 0) {
8765
+ writeFrontDoorState(fs12, paths.frontdoorStateFile, sticky());
8766
+ }
8689
8767
  return 0;
8690
8768
  };
8691
8769
  for (; ; ) {
@@ -8698,7 +8776,28 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
8698
8776
  ports.observeLaunchRegistry(listed, pruned);
8699
8777
  ports.checkQuotaExpiry();
8700
8778
  const prunedPids = new Set(pruned);
8701
- if (listed.filter((session) => !prunedPids.has(session.pid)).length === 0) {
8779
+ const live = listed.filter((session) => !prunedPids.has(session.pid));
8780
+ if (supersededBy === void 0) {
8781
+ supersededBy = supersedingOwner();
8782
+ if (supersededBy !== void 0) {
8783
+ 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`);
8784
+ ports.doorHealth.superseded(supersededBy);
8785
+ await ports.sleep(FRONTDOOR_POLL_MS);
8786
+ continue;
8787
+ }
8788
+ } else {
8789
+ const owner = supersededBy;
8790
+ 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));
8791
+ if (served.length === 0) {
8792
+ ports.log("agent-shim frontdoor supervisor: the sessions this superseded door served have ended; closing the front door and exiting");
8793
+ ports.doorHealth.drained();
8794
+ await closeServing();
8795
+ return 0;
8796
+ }
8797
+ await ports.sleep(FRONTDOOR_POLL_MS);
8798
+ continue;
8799
+ }
8800
+ if (live.length === 0) {
8702
8801
  if (ticks > 1 && binaryReplaced()) {
8703
8802
  ports.log("agent-shim frontdoor supervisor: the installed binary changed and no sessions are live; turning the door over for the next launch");
8704
8803
  ports.doorHealth.binaryTurnover();
@@ -12852,7 +12951,55 @@ init_credential();
12852
12951
  init_credentialCache();
12853
12952
  init_realCredentialCache();
12854
12953
  init_source();
12954
+
12955
+ // src/headroom/allowlistDrift.ts
12956
+ init_state2();
12957
+ function diagnoseAllowlistDrift(params) {
12958
+ const { recordedHash, providers, frontDoorOrigin: frontDoorOrigin2 } = params;
12959
+ if (recordedHash === void 0 || recordedHash === hashAllowlist(headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin2)))) {
12960
+ return void 0;
12961
+ }
12962
+ const originIsInput = providers.length > 0 && frontDoorOrigin2 !== void 0;
12963
+ if (!originIsInput) {
12964
+ return ["provider-files"];
12965
+ }
12966
+ return recordedHash === hashAllowlist(headroomAllowlist(headroomUpstreams(providers, void 0))) ? ["front-door-origin"] : ["provider-files", "front-door-origin"];
12967
+ }
12968
+
12969
+ // src/doctorReport.ts
12855
12970
  init_state2();
12971
+ init_supervisor();
12972
+ init_state();
12973
+
12974
+ // src/doctorFrontDoor.ts
12975
+ function pushFrontDoor(push, supervisors, registeredPid) {
12976
+ if (!supervisors.ok) {
12977
+ push("frontdoor", "warn", `Could not list processes to look for duplicate front door supervisors: ${supervisors.message}.`);
12978
+ return;
12979
+ }
12980
+ const { pids } = supervisors;
12981
+ if (pids.length === 0) {
12982
+ push("frontdoor", "pass", "No front door supervisor is running.");
12983
+ return;
12984
+ }
12985
+ const [only, ...rest] = pids;
12986
+ if (only !== void 0 && rest.length === 0) {
12987
+ push("frontdoor", "pass", `One front door supervisor is running (pid ${String(only)}).`);
12988
+ return;
12989
+ }
12990
+ 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.";
12991
+ for (const pid of pids.filter((candidate) => candidate !== registeredPid)) {
12992
+ push(
12993
+ "frontdoor",
12994
+ "fail",
12995
+ `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.`,
12996
+ String(pid)
12997
+ );
12998
+ }
12999
+ }
13000
+
13001
+ // src/doctorReport.ts
13002
+ init_supervisorProcesses();
12856
13003
  init_legacy();
12857
13004
  init_providersStore();
12858
13005
  init_guard();
@@ -12875,7 +13022,8 @@ var DOCTOR_SECTIONS = [
12875
13022
  "global-config",
12876
13023
  "categories-local",
12877
13024
  "active-identity",
12878
- "headroom"
13025
+ "headroom",
13026
+ "frontdoor"
12879
13027
  ];
12880
13028
  function refinePathShadow(status, ownExecutablePath, realpath) {
12881
13029
  if (status.status !== "shadowed") {
@@ -13271,6 +13419,17 @@ function runDoctor(params) {
13271
13419
  `Headroom daemon is up on unix socket ${state.socketPath} (supervisor ${String(state.supervisorPid)}, daemon ${String(state.headroomPid)}).`
13272
13420
  );
13273
13421
  }
13422
+ const allowlist = params.headroom.allowlist;
13423
+ if (supervisorAlive && headroomAlive && state.socketPath !== void 0 && allowlist?.driftInputs?.includes("front-door-origin") === true) {
13424
+ const origin = allowlist.frontDoorOrigin ?? "";
13425
+ const certainty = allowlist.driftInputs.includes("provider-files") ? "may exclude" : "excludes";
13426
+ push(
13427
+ "headroom",
13428
+ "fail",
13429
+ `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.`,
13430
+ String(state.headroomPid)
13431
+ );
13432
+ }
13274
13433
  if (state.lastError !== void 0 && supervisorAlive) {
13275
13434
  push("headroom", "warn", `Headroom recorded a previous error: ${state.lastError}`);
13276
13435
  }
@@ -13283,6 +13442,10 @@ function runDoctor(params) {
13283
13442
  }
13284
13443
  }
13285
13444
  }
13445
+ if (params.frontDoor !== void 0) {
13446
+ const validated3 = params.frontDoor.state.raw === void 0 ? void 0 : validateJson(FrontDoorStateSchema, params.frontDoor.state);
13447
+ pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0);
13448
+ }
13286
13449
  if (params.activeIdentity.raw === void 0) {
13287
13450
  push("active-identity", "pass", "No active identity set.");
13288
13451
  } else {
@@ -13312,6 +13475,7 @@ var SECTION_TITLES = {
13312
13475
  "directory-rules": "Directory rules",
13313
13476
  "global-config": "Global config",
13314
13477
  headroom: "Headroom daemon",
13478
+ frontdoor: "Front door",
13315
13479
  "categories-local": "categories.local.json",
13316
13480
  "active-identity": "Active identity"
13317
13481
  };
@@ -13329,6 +13493,7 @@ var SECTION_ORDER = [
13329
13493
  "directory-rules",
13330
13494
  "global-config",
13331
13495
  "headroom",
13496
+ "frontdoor",
13332
13497
  "categories-local",
13333
13498
  "active-identity"
13334
13499
  ];
@@ -13406,6 +13571,9 @@ function collectDoctorReport(params) {
13406
13571
  shimState.targetPath,
13407
13572
  realpathOrSelf
13408
13573
  );
13574
+ const uid = process.getuid?.();
13575
+ const allowlistInputs = currentHeadroomAllowlistInputs(realFarmFs, paths);
13576
+ const servingHeadroom = resolveServingHeadroomState(realFarmFs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, realIsProcessRunning);
13409
13577
  const report = runDoctor({
13410
13578
  env: params.env,
13411
13579
  credentialCache: realCredentialCacheEnv(paths),
@@ -13444,8 +13612,13 @@ function collectDoctorReport(params) {
13444
13612
  const statePath = resolved?.path ?? paths.headroomStateFile;
13445
13613
  return { path: statePath, raw: realFarmFs.readFileUtf8(statePath) };
13446
13614
  })(),
13447
- isRunning: realIsProcessRunning
13448
- }
13615
+ isRunning: realIsProcessRunning,
13616
+ allowlist: {
13617
+ driftInputs: diagnoseAllowlistDrift({ recordedHash: servingHeadroom?.state.allowlistHash, ...allowlistInputs }),
13618
+ frontDoorOrigin: allowlistInputs.frontDoorOrigin
13619
+ }
13620
+ },
13621
+ ...uid === void 0 ? {} : { frontDoor: { state: { path: paths.frontdoorStateFile, raw: realFsPort.readFileUtf8(paths.frontdoorStateFile) }, supervisors: listFrontDoorSupervisors(realRunPort, uid) } }
13449
13622
  });
13450
13623
  return report;
13451
13624
  }
@@ -14147,7 +14320,9 @@ var DoorHealthEventSchema = import_zod23.z.discriminatedUnion("kind", [
14147
14320
  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() }),
14148
14321
  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() }),
14149
14322
  import_zod23.z.strictObject({ kind: import_zod23.z.literal("binaryTurnover"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() }),
14150
- import_zod23.z.strictObject({ kind: import_zod23.z.literal("idleShutdown"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() })
14323
+ import_zod23.z.strictObject({ kind: import_zod23.z.literal("idleShutdown"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() }),
14324
+ 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() }),
14325
+ import_zod23.z.strictObject({ kind: import_zod23.z.literal("drained"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() })
14151
14326
  ]);
14152
14327
  var QuotaExpiringEventSchema = import_zod23.z.strictObject({
14153
14328
  identity: import_zod23.z.string().min(1),
@@ -14644,6 +14819,12 @@ function createDoorHealthPublisher(hub, now, pid) {
14644
14819
  },
14645
14820
  binaryTurnover: () => {
14646
14821
  publisher.publish({ kind: "binaryTurnover", pid, observedAt: now() });
14822
+ },
14823
+ superseded: (ownerPid) => {
14824
+ publisher.publish({ kind: "superseded", pid, ownerPid, observedAt: now() });
14825
+ },
14826
+ drained: () => {
14827
+ publisher.publish({ kind: "drained", pid, observedAt: now() });
14647
14828
  }
14648
14829
  };
14649
14830
  }