claude-use 11.48.0 → 11.49.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
@@ -2452,8 +2452,8 @@ var init_lock = __esm({
2452
2452
  });
2453
2453
 
2454
2454
  // src/launcher/farm.ts
2455
- function readFarmManifest(fs13, farmRoot) {
2456
- const raw = fs13.readFileUtf8(import_node_path7.default.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs13.readFileUtf8(import_node_path7.default.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
2455
+ function readFarmManifest(fs14, farmRoot) {
2456
+ const raw = fs14.readFileUtf8(import_node_path7.default.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs14.readFileUtf8(import_node_path7.default.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
2457
2457
  if (raw === void 0) {
2458
2458
  return void 0;
2459
2459
  }
@@ -2511,9 +2511,9 @@ function buildEntryFacts(params) {
2511
2511
  entries
2512
2512
  };
2513
2513
  }
2514
- function listSubtree(fs13, root, rel) {
2514
+ function listSubtree(fs14, root, rel) {
2515
2515
  const absolute = import_node_path7.default.join(root, rel);
2516
- const stat = fs13.lstat(absolute);
2516
+ const stat = fs14.lstat(absolute);
2517
2517
  if (stat === void 0) {
2518
2518
  return [];
2519
2519
  }
@@ -2521,10 +2521,10 @@ function listSubtree(fs13, root, rel) {
2521
2521
  return [{ rel, kind: "symlink" }];
2522
2522
  }
2523
2523
  if (stat.kind === "dir") {
2524
- const children = [...fs13.readdir(absolute)].sort().flatMap((name) => listSubtree(fs13, root, `${rel}/${name}`));
2524
+ const children = [...fs14.readdir(absolute)].sort().flatMap((name) => listSubtree(fs14, root, `${rel}/${name}`));
2525
2525
  return [{ rel, kind: "dir" }, ...children];
2526
2526
  }
2527
- const contentHash = fs13.hashFile(absolute);
2527
+ const contentHash = fs14.hashFile(absolute);
2528
2528
  return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
2529
2529
  }
2530
2530
  function topLevelScopeRoots(roots) {
@@ -2538,25 +2538,25 @@ function topLevelScopeRoots(roots) {
2538
2538
  }
2539
2539
  return kept;
2540
2540
  }
2541
- function reconciliationScope(fs13, farmRoot, manifest) {
2541
+ function reconciliationScope(fs14, farmRoot, manifest) {
2542
2542
  if (manifest !== void 0) {
2543
2543
  return topLevelScopeRoots(manifest.materialised);
2544
2544
  }
2545
- return [...fs13.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs13.lstat(import_node_path7.default.join(farmRoot, name))?.kind === "dir").sort();
2545
+ return [...fs14.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs14.lstat(import_node_path7.default.join(farmRoot, name))?.kind === "dir").sort();
2546
2546
  }
2547
- function collectFarmListing(fs13, farmRoot, scopeRoots) {
2548
- return scopeRoots.flatMap((root) => listSubtree(fs13, farmRoot, root));
2547
+ function collectFarmListing(fs14, farmRoot, scopeRoots) {
2548
+ return scopeRoots.flatMap((root) => listSubtree(fs14, farmRoot, root));
2549
2549
  }
2550
- function collectCanonicalCounterparts(fs13, claudeHome, farmListing) {
2550
+ function collectCanonicalCounterparts(fs14, claudeHome, farmListing) {
2551
2551
  const out = [];
2552
2552
  for (const entry of farmListing) {
2553
2553
  const absolute = import_node_path7.default.join(claudeHome, entry.rel);
2554
- const stat = fs13.lstat(absolute);
2554
+ const stat = fs14.lstat(absolute);
2555
2555
  if (stat === void 0) {
2556
2556
  continue;
2557
2557
  }
2558
2558
  if (stat.kind === "file") {
2559
- const contentHash = fs13.hashFile(absolute);
2559
+ const contentHash = fs14.hashFile(absolute);
2560
2560
  out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
2561
2561
  continue;
2562
2562
  }
@@ -3327,10 +3327,10 @@ var init_route = __esm({
3327
3327
  });
3328
3328
 
3329
3329
  // src/frontdoor/state.ts
3330
- function readFrontDoorState(fs13, stateFile) {
3330
+ function readFrontDoorState(fs14, stateFile) {
3331
3331
  let raw;
3332
3332
  try {
3333
- raw = fs13.readFileUtf8(stateFile);
3333
+ raw = fs14.readFileUtf8(stateFile);
3334
3334
  } catch {
3335
3335
  return void 0;
3336
3336
  }
@@ -3344,9 +3344,9 @@ function readFrontDoorState(fs13, stateFile) {
3344
3344
  return void 0;
3345
3345
  }
3346
3346
  }
3347
- function writeFrontDoorState(fs13, stateFile, state) {
3348
- fs13.mkdirp(import_node_path8.default.dirname(stateFile));
3349
- fs13.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
3347
+ function writeFrontDoorState(fs14, stateFile, state) {
3348
+ fs14.mkdirp(import_node_path8.default.dirname(stateFile));
3349
+ fs14.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
3350
3350
  `);
3351
3351
  }
3352
3352
  function directOrigin(port) {
@@ -3356,27 +3356,37 @@ function frontDoorOrigin(state) {
3356
3356
  const port = state?.directPort ?? state?.lastDirectPort;
3357
3357
  return port === void 0 ? void 0 : directOrigin(port);
3358
3358
  }
3359
- function writeFrontDoorDirectRecord(fs13, recordsDir, record) {
3360
- fs13.mkdirp(recordsDir);
3361
- fs13.writeFilePrivate(import_node_path8.default.join(recordsDir, `${String(record.pid)}.json`), `${JSON.stringify({ directPort: record.directPort })}
3359
+ function writeFrontDoorDirectRecord(fs14, recordsDir, record) {
3360
+ fs14.mkdirp(recordsDir);
3361
+ fs14.writeFilePrivate(import_node_path8.default.join(recordsDir, `${String(record.pid)}.json`), `${JSON.stringify({ directPort: record.directPort })}
3362
3362
  `);
3363
3363
  }
3364
- function removeFrontDoorDirectRecord(fs13, recordsDir, pid) {
3365
- fs13.removeRecursive(import_node_path8.default.join(recordsDir, `${String(pid)}.json`));
3364
+ function removeFrontDoorDirectRecord(fs14, recordsDir, pid) {
3365
+ fs14.removeRecursive(import_node_path8.default.join(recordsDir, `${String(pid)}.json`));
3366
+ }
3367
+ function markFrontDoorDraining(fs14, markersDir, pid) {
3368
+ fs14.mkdirp(markersDir);
3369
+ fs14.writeFilePrivate(import_node_path8.default.join(markersDir, String(pid)), "\n");
3370
+ }
3371
+ function unmarkFrontDoorDraining(fs14, markersDir, pid) {
3372
+ fs14.removeRecursive(import_node_path8.default.join(markersDir, String(pid)));
3373
+ }
3374
+ function listDrainingFrontDoors(fs14, markersDir, isRunning) {
3375
+ return fs14.readdir(markersDir).flatMap((file) => /^[1-9]\d*$/.test(file) && Number.isSafeInteger(Number(file)) ? [Number(file)] : []).filter(isRunning).sort((a, b) => a - b);
3366
3376
  }
3367
3377
  function recordPid(file) {
3368
3378
  const pidText = /^([1-9]\d*)\.json$/.exec(file)?.[1];
3369
3379
  const pid = pidText === void 0 ? void 0 : Number(pidText);
3370
3380
  return pid !== void 0 && Number.isSafeInteger(pid) ? pid : void 0;
3371
3381
  }
3372
- function readDirectRecordEntry(fs13, recordsDir, file) {
3382
+ function readDirectRecordEntry(fs14, recordsDir, file) {
3373
3383
  const pid = recordPid(file);
3374
3384
  if (pid === void 0) {
3375
3385
  return void 0;
3376
3386
  }
3377
3387
  let raw;
3378
3388
  try {
3379
- raw = fs13.readFileUtf8(import_node_path8.default.join(recordsDir, file));
3389
+ raw = fs14.readFileUtf8(import_node_path8.default.join(recordsDir, file));
3380
3390
  } catch {
3381
3391
  return void 0;
3382
3392
  }
@@ -3390,47 +3400,47 @@ function readDirectRecordEntry(fs13, recordsDir, file) {
3390
3400
  return { malformed: true };
3391
3401
  }
3392
3402
  }
3393
- function listFrontDoorDirectRecords(fs13, recordsDir) {
3394
- return fs13.readdir(recordsDir).flatMap((file) => {
3395
- const entry = readDirectRecordEntry(fs13, recordsDir, file);
3403
+ function listFrontDoorDirectRecords(fs14, recordsDir) {
3404
+ return fs14.readdir(recordsDir).flatMap((file) => {
3405
+ const entry = readDirectRecordEntry(fs14, recordsDir, file);
3396
3406
  return entry?.record === void 0 ? [] : [entry.record];
3397
3407
  }).sort((a, b) => a.pid - b.pid);
3398
3408
  }
3399
- function pruneMalformedFrontDoorDirectFiles(fs13, recordsDir, isRunning) {
3400
- for (const file of fs13.readdir(recordsDir)) {
3409
+ function pruneMalformedFrontDoorDirectFiles(fs14, recordsDir, isRunning) {
3410
+ for (const file of fs14.readdir(recordsDir)) {
3401
3411
  const writer = RECORD_TEMPORARY_FILE.exec(file)?.[1];
3402
3412
  const stale = writer !== void 0 && !isRunning(Number(writer));
3403
- if (stale || readDirectRecordEntry(fs13, recordsDir, file)?.malformed === true) {
3404
- fs13.removeRecursive(import_node_path8.default.join(recordsDir, file));
3413
+ if (stale || readDirectRecordEntry(fs14, recordsDir, file)?.malformed === true) {
3414
+ fs14.removeRecursive(import_node_path8.default.join(recordsDir, file));
3405
3415
  }
3406
3416
  }
3407
3417
  }
3408
3418
  function liveFrontDoorDirectRecords(records, liveness) {
3409
3419
  return records.filter((record) => liveness.doors.has(record.pid) || liveness.unknown.has(record.pid));
3410
3420
  }
3411
- function pruneDeadFrontDoorDirectRecords(fs13, recordsDir, records, liveness) {
3421
+ function pruneDeadFrontDoorDirectRecords(fs14, recordsDir, records, liveness) {
3412
3422
  for (const record of records) {
3413
3423
  if (!liveness.doors.has(record.pid) && !liveness.unknown.has(record.pid)) {
3414
- removeFrontDoorDirectRecord(fs13, recordsDir, record.pid);
3424
+ removeFrontDoorDirectRecord(fs14, recordsDir, record.pid);
3415
3425
  }
3416
3426
  }
3417
3427
  }
3418
3428
  function recordOf(details) {
3419
3429
  return details === void 0 ? {} : { sessionId: details.sessionId, ...details.models === void 0 ? {} : { models: details.models } };
3420
3430
  }
3421
- function writeFrontDoorSession(fs13, sessionsDir, session) {
3422
- fs13.mkdirPrivate(sessionsDir);
3423
- fs13.writeFilePrivate(import_node_path8.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
3431
+ function writeFrontDoorSession(fs14, sessionsDir, session) {
3432
+ fs14.mkdirPrivate(sessionsDir);
3433
+ fs14.writeFilePrivate(import_node_path8.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
3424
3434
  `);
3425
3435
  }
3426
- function listFrontDoorSessions(fs13, sessionsDir) {
3436
+ function listFrontDoorSessions(fs14, sessionsDir) {
3427
3437
  const sessions = [];
3428
- for (const name of fs13.readdir(sessionsDir)) {
3438
+ for (const name of fs14.readdir(sessionsDir)) {
3429
3439
  if (!name.endsWith(".json")) {
3430
3440
  continue;
3431
3441
  }
3432
3442
  try {
3433
- const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs13.readFileUtf8(import_node_path8.default.join(sessionsDir, name)) ?? ""));
3443
+ const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs14.readFileUtf8(import_node_path8.default.join(sessionsDir, name)) ?? ""));
3434
3444
  if (parsed.success) {
3435
3445
  sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
3436
3446
  }
@@ -3440,14 +3450,14 @@ function listFrontDoorSessions(fs13, sessionsDir) {
3440
3450
  }
3441
3451
  return sessions.sort((a, b) => a.pid - b.pid);
3442
3452
  }
3443
- function removeFrontDoorSession(fs13, sessionsDir, pid) {
3444
- fs13.removeRecursive(import_node_path8.default.join(sessionsDir, `${String(pid)}.json`));
3453
+ function removeFrontDoorSession(fs14, sessionsDir, pid) {
3454
+ fs14.removeRecursive(import_node_path8.default.join(sessionsDir, `${String(pid)}.json`));
3445
3455
  }
3446
- function pruneDeadFrontDoorSessions(fs13, sessionsDir, isRunning) {
3456
+ function pruneDeadFrontDoorSessions(fs14, sessionsDir, isRunning) {
3447
3457
  const removed = [];
3448
- for (const session of listFrontDoorSessions(fs13, sessionsDir)) {
3458
+ for (const session of listFrontDoorSessions(fs14, sessionsDir)) {
3449
3459
  if (!isRunning(session.pid)) {
3450
- removeFrontDoorSession(fs13, sessionsDir, session.pid);
3460
+ removeFrontDoorSession(fs14, sessionsDir, session.pid);
3451
3461
  removed.push(session.pid);
3452
3462
  }
3453
3463
  }
@@ -3545,9 +3555,9 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
3545
3555
  }
3546
3556
  }
3547
3557
  async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3548
- const { fs: fs13, paths } = ports;
3558
+ const { fs: fs14, paths } = ports;
3549
3559
  const servingBinary = ports.statOwnExecutable();
3550
- const previous = readFrontDoorState(fs13, paths.frontdoorStateFile);
3560
+ const previous = readFrontDoorState(fs14, paths.frontdoorStateFile);
3551
3561
  let lastPort = previous?.lastPort;
3552
3562
  let lastConnectPort = previous?.lastConnectPort;
3553
3563
  let lastDirectPort = previous?.lastDirectPort;
@@ -3558,12 +3568,12 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3558
3568
  });
3559
3569
  const fail = (message) => {
3560
3570
  ports.closeRcStreamHub();
3561
- writeFrontDoorState(fs13, paths.frontdoorStateFile, { lastError: message, ...sticky() });
3562
- fs13.removeRecursive(paths.frontdoorLockFile);
3571
+ writeFrontDoorState(fs14, paths.frontdoorStateFile, { lastError: message, ...sticky() });
3572
+ fs14.removeRecursive(paths.frontdoorLockFile);
3563
3573
  ports.log(`agent-shim frontdoor supervisor: ${message}`);
3564
3574
  return 1;
3565
3575
  };
3566
- writeFrontDoorState(fs13, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
3576
+ writeFrontDoorState(fs14, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
3567
3577
  const previousSticky = lastPort;
3568
3578
  let http3;
3569
3579
  try {
@@ -3603,16 +3613,16 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3603
3613
  ports.log(`agent-shim frontdoor supervisor: sticky direct port ${String(previousStickyDirect)} was occupied; moving to ${String(direct.port)} (headroom admits the new address once its supervisor rewrites the allowlist file)`);
3604
3614
  }
3605
3615
  lastDirectPort = direct.port;
3606
- writeFrontDoorDirectRecord(fs13, paths.frontdoorDirectRecordsDir, { pid: ports.ownPid, directPort: direct.port });
3607
- writeFrontDoorState(fs13, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
3616
+ writeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, { pid: ports.ownPid, directPort: direct.port });
3617
+ writeFrontDoorState(fs14, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
3608
3618
  ports.doorHealth.generation({ providerPort: http3.port, connectPort: connect3.port, directPort: direct.port });
3609
- fs13.removeRecursive(paths.frontdoorLockFile);
3619
+ fs14.removeRecursive(paths.frontdoorLockFile);
3610
3620
  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)}`);
3611
3621
  const watchdog = ports.startWatchdog?.();
3612
3622
  let idleSince;
3613
3623
  let ticks = 0;
3614
3624
  const supersedingOwner = () => {
3615
- const owner = readFrontDoorState(fs13, paths.frontdoorStateFile)?.supervisorPid;
3625
+ const owner = readFrontDoorState(fs14, paths.frontdoorStateFile)?.supervisorPid;
3616
3626
  return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
3617
3627
  };
3618
3628
  let supersededBy;
@@ -3621,30 +3631,61 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3621
3631
  const current = ports.statOwnExecutable();
3622
3632
  return current !== void 0 && servingBinary !== void 0 && (current.dev !== servingBinary.dev || current.ino !== servingBinary.ino || current.size !== servingBinary.size || current.mtimeMs !== servingBinary.mtimeMs);
3623
3633
  };
3634
+ const pause = async () => {
3635
+ await new Promise((resolve) => {
3636
+ const wake = () => {
3637
+ resolve();
3638
+ };
3639
+ ports.retire?.addEventListener("abort", wake, { once: true });
3640
+ void ports.sleep(FRONTDOOR_POLL_MS).then(() => {
3641
+ ports.retire?.removeEventListener("abort", wake);
3642
+ resolve();
3643
+ });
3644
+ });
3645
+ };
3646
+ const retireByDrain = async () => {
3647
+ ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: asked to exit; releasing the front door's addresses and finishing the connections it carries`);
3648
+ watchdog?.stop();
3649
+ ports.stopBackgroundWork?.();
3650
+ const drained = [direct.drain(), connect3.drain(), http3.drain()];
3651
+ if (supersedingOwner() === void 0) {
3652
+ writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
3653
+ }
3654
+ markFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
3655
+ ports.closeRcStreamHub();
3656
+ await Promise.all(drained);
3657
+ unmarkFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
3658
+ removeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, ports.ownPid);
3659
+ ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: the connections this door carried have ended; exiting`);
3660
+ return 0;
3661
+ };
3624
3662
  const closeServing = async () => {
3625
3663
  watchdog?.stop();
3626
3664
  await direct.close();
3627
3665
  await connect3.close();
3628
3666
  await http3.close();
3629
3667
  ports.closeRcStreamHub();
3630
- removeFrontDoorDirectRecord(fs13, paths.frontdoorDirectRecordsDir, ports.ownPid);
3668
+ removeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, ports.ownPid);
3631
3669
  };
3632
3670
  const shutdown = async () => {
3633
3671
  await closeServing();
3634
3672
  if (supersedingOwner() === void 0) {
3635
- writeFrontDoorState(fs13, paths.frontdoorStateFile, sticky());
3673
+ writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
3636
3674
  }
3637
3675
  return 0;
3638
3676
  };
3639
3677
  for (; ; ) {
3640
3678
  watchdog?.beat();
3679
+ if (ports.retire?.aborted === true) {
3680
+ return await retireByDrain();
3681
+ }
3641
3682
  if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
3642
3683
  watchdog?.stop();
3643
3684
  return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
3644
3685
  }
3645
3686
  ticks += 1;
3646
- const listed = listFrontDoorSessions(fs13, paths.frontdoorSessionsDir);
3647
- const pruned = pruneDeadFrontDoorSessions(fs13, paths.frontdoorSessionsDir, ports.isRunning);
3687
+ const listed = listFrontDoorSessions(fs14, paths.frontdoorSessionsDir);
3688
+ const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, ports.isRunning);
3648
3689
  ports.observeLaunchRegistry(listed, pruned);
3649
3690
  ports.checkQuotaExpiry();
3650
3691
  const prunedPids = new Set(pruned);
@@ -3654,7 +3695,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3654
3695
  if (supersededBy !== void 0) {
3655
3696
  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`);
3656
3697
  ports.doorHealth.superseded(supersededBy);
3657
- await ports.sleep(FRONTDOOR_POLL_MS);
3698
+ await pause();
3658
3699
  continue;
3659
3700
  }
3660
3701
  } else {
@@ -3666,7 +3707,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3666
3707
  await closeServing();
3667
3708
  return 0;
3668
3709
  }
3669
- await ports.sleep(FRONTDOOR_POLL_MS);
3710
+ await pause();
3670
3711
  continue;
3671
3712
  }
3672
3713
  if (live.length === 0) {
@@ -3684,7 +3725,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3684
3725
  } else {
3685
3726
  idleSince = void 0;
3686
3727
  }
3687
- await ports.sleep(FRONTDOOR_POLL_MS);
3728
+ await pause();
3688
3729
  }
3689
3730
  }
3690
3731
  var import_node_path9, FRONTDOOR_SUPERVISOR_STILL_RUNNING, FRONTDOOR_POLL_MS, MS_PER_MINUTE;
@@ -3837,25 +3878,35 @@ ${request4.rawHeaders.reduce((accumulated, value, index) => index % 2 === 0 ? `$
3837
3878
  const transparent = config.transparentPort === void 0 || apiSession === void 0 ? void 0 : await effects.listenLoopback(config.transparentPort, (socket) => {
3838
3879
  sniAcceptor.accept(socket);
3839
3880
  });
3881
+ const closeSurface = async () => {
3882
+ ledger.close();
3883
+ await listener.close();
3884
+ await transparent?.close();
3885
+ sniAcceptor.close();
3886
+ for (const { httpSession, tlsAcceptor } of sessions) {
3887
+ tlsAcceptor.close();
3888
+ httpSession?.close();
3889
+ }
3890
+ };
3840
3891
  return {
3841
3892
  port: listener.port,
3842
3893
  ...transparent === void 0 ? {} : { transparentPort: transparent.port },
3843
- close: async () => {
3844
- ledger.close();
3845
- await listener.close();
3894
+ openTunnels: ledger.openTunnels,
3895
+ drain: async () => {
3896
+ listener.stopAccepting();
3846
3897
  await transparent?.close();
3847
- sniAcceptor.close();
3848
- for (const { httpSession, tlsAcceptor } of sessions) {
3849
- tlsAcceptor.close();
3850
- httpSession?.close();
3851
- }
3852
- }
3898
+ await ledger.retire();
3899
+ await closeSurface();
3900
+ },
3901
+ close: closeSurface
3853
3902
  };
3854
3903
  }
3855
3904
  function createConnectionLedger(limits, isLiveCapability2) {
3856
3905
  const pending = /* @__PURE__ */ new Map();
3857
3906
  const authenticated = /* @__PURE__ */ new Map();
3858
3907
  let tunnels = 0;
3908
+ const blind = /* @__PURE__ */ new Set();
3909
+ let onNoBlindTunnels;
3859
3910
  const leavePending = (socket) => {
3860
3911
  const deadline = pending.get(socket);
3861
3912
  if (deadline !== void 0) {
@@ -3892,16 +3943,45 @@ function createConnectionLedger(limits, isLiveCapability2) {
3892
3943
  });
3893
3944
  },
3894
3945
  headReceived: leavePending,
3895
- establish: (socket, capability) => {
3946
+ openTunnels: () => tunnels,
3947
+ retire: async () => {
3948
+ for (const socket of pending.keys()) {
3949
+ socket.destroy();
3950
+ }
3951
+ for (const deadline of pending.values()) {
3952
+ clearTimeout(deadline);
3953
+ }
3954
+ pending.clear();
3955
+ for (const sockets of authenticated.values()) {
3956
+ for (const socket of sockets) {
3957
+ if (!blind.has(socket)) {
3958
+ socket.destroy();
3959
+ }
3960
+ }
3961
+ }
3962
+ if (blind.size > 0) {
3963
+ await new Promise((resolve) => {
3964
+ onNoBlindTunnels = resolve;
3965
+ });
3966
+ }
3967
+ },
3968
+ establish: (socket, capability, kind) => {
3896
3969
  if (tunnels >= limits.maxTunnels) {
3897
3970
  return false;
3898
3971
  }
3899
3972
  tunnels += 1;
3973
+ if (kind === "blind") {
3974
+ blind.add(socket);
3975
+ }
3900
3976
  const sockets = authenticated.get(capability) ?? /* @__PURE__ */ new Set();
3901
3977
  sockets.add(socket);
3902
3978
  authenticated.set(capability, sockets);
3903
3979
  socket.once("close", () => {
3904
3980
  tunnels -= 1;
3981
+ blind.delete(socket);
3982
+ if (blind.size === 0) {
3983
+ onNoBlindTunnels?.();
3984
+ }
3905
3985
  sockets.delete(socket);
3906
3986
  if (sockets.size === 0 && authenticated.get(capability) === sockets) {
3907
3987
  authenticated.delete(capability);
@@ -3983,11 +4063,11 @@ function routeConnect(socket, head, context) {
3983
4063
  refuse(socket, REFUSAL.badRequest);
3984
4064
  return;
3985
4065
  }
3986
- if (!ledger.establish(socket, capability)) {
4066
+ const session = sessions.find((entry) => entry.host === target.host);
4067
+ if (!ledger.establish(socket, capability, session === void 0 ? "blind" : "terminated")) {
3987
4068
  refuse(socket, REFUSAL.serviceUnavailable);
3988
4069
  return;
3989
4070
  }
3990
- const session = sessions.find((entry) => entry.host === target.host);
3991
4071
  config.capture?.connect(target, session !== void 0);
3992
4072
  socket.write(CONNECT_ESTABLISHED);
3993
4073
  if (session !== void 0) {
@@ -4111,7 +4191,7 @@ var init_package = __esm({
4111
4191
  "package.json"() {
4112
4192
  package_default = {
4113
4193
  name: "claude-use",
4114
- version: "11.48.0",
4194
+ version: "11.49.0",
4115
4195
  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.",
4116
4196
  license: "MIT",
4117
4197
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4316,43 +4396,43 @@ function parseJson(raw, schema) {
4316
4396
  const parsed = schema.safeParse(JSON.parse(raw));
4317
4397
  return parsed.success ? parsed.data : void 0;
4318
4398
  }
4319
- function readHeadroomState(fs13, stateFile) {
4399
+ function readHeadroomState(fs14, stateFile) {
4320
4400
  try {
4321
- return parseJson(fs13.readFileUtf8(stateFile), HeadroomStateSchema);
4401
+ return parseJson(fs14.readFileUtf8(stateFile), HeadroomStateSchema);
4322
4402
  } catch {
4323
4403
  return void 0;
4324
4404
  }
4325
4405
  }
4326
- function writeHeadroomState(fs13, stateFile, state) {
4327
- fs13.mkdirp(import_node_path11.default.dirname(stateFile));
4328
- fs13.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
4406
+ function writeHeadroomState(fs14, stateFile, state) {
4407
+ fs14.mkdirp(import_node_path11.default.dirname(stateFile));
4408
+ fs14.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
4329
4409
  `);
4330
4410
  }
4331
- function resolveServingHeadroomState(fs13, files, isRunning) {
4332
- const current = readHeadroomState(fs13, files.stateFile);
4411
+ function resolveServingHeadroomState(fs14, files, isRunning) {
4412
+ const current = readHeadroomState(fs14, files.stateFile);
4333
4413
  if (current !== void 0) {
4334
4414
  return { path: files.stateFile, state: current };
4335
4415
  }
4336
- const legacy = readHeadroomState(fs13, files.legacyStateFile);
4416
+ const legacy = readHeadroomState(fs14, files.legacyStateFile);
4337
4417
  if (legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid)) {
4338
4418
  return { path: files.legacyStateFile, state: legacy };
4339
4419
  }
4340
4420
  return void 0;
4341
4421
  }
4342
- function migrateHeadroomState(fs13, files, isRunning) {
4343
- const legacy = readHeadroomState(fs13, files.legacyStateFile);
4422
+ function migrateHeadroomState(fs14, files, isRunning) {
4423
+ const legacy = readHeadroomState(fs14, files.legacyStateFile);
4344
4424
  const legacyLive = legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid);
4345
- const current = readHeadroomState(fs13, files.stateFile);
4425
+ const current = readHeadroomState(fs14, files.stateFile);
4346
4426
  if (current !== void 0 || legacyLive) {
4347
- if (!legacyLive && fs13.readFileUtf8(files.legacyStateFile) !== void 0) {
4348
- fs13.removeRecursive(files.legacyStateFile);
4427
+ if (!legacyLive && fs14.readFileUtf8(files.legacyStateFile) !== void 0) {
4428
+ fs14.removeRecursive(files.legacyStateFile);
4349
4429
  }
4350
4430
  return;
4351
4431
  }
4352
4432
  if (legacy !== void 0) {
4353
- writeHeadroomState(fs13, files.stateFile, legacy);
4433
+ writeHeadroomState(fs14, files.stateFile, legacy);
4354
4434
  }
4355
- fs13.removeRecursive(files.legacyStateFile);
4435
+ fs14.removeRecursive(files.legacyStateFile);
4356
4436
  }
4357
4437
  function hashAllowlist(allowlist) {
4358
4438
  return (0, import_node_crypto6.createHash)("sha256").update(allowlist.join("\n")).digest("hex");
@@ -4385,27 +4465,27 @@ function isAdmissibleUrl(entry) {
4385
4465
  function parseAllowlistFile(content) {
4386
4466
  return content.replace(/^\uFEFF/, "").replace(ALLOWLIST_FILE_COMMENT, "").split(ALLOWLIST_FILE_SEPARATORS).map((entry) => entry.replace(ALLOWLIST_SURROUNDING_WHITESPACE, "")).filter((entry) => entry !== "" && !ALLOWLIST_ENTRY_WHITESPACE.test(entry) && (entry.includes("://") ? isAdmissibleUrl(entry) : isBareHost(entry)));
4387
4467
  }
4388
- function writeAllowlistFile(fs13, allowlistFile, allowlist) {
4389
- fs13.mkdirPrivate(import_node_path11.default.dirname(allowlistFile));
4390
- fs13.writeFilePrivate(allowlistFile, formatAllowlistFile(allowlist));
4468
+ function writeAllowlistFile(fs14, allowlistFile, allowlist) {
4469
+ fs14.mkdirPrivate(import_node_path11.default.dirname(allowlistFile));
4470
+ fs14.writeFilePrivate(allowlistFile, formatAllowlistFile(allowlist));
4391
4471
  }
4392
- function pruneStaleAllowlistTemporaries(fs13, allowlistFile, isRunning) {
4472
+ function pruneStaleAllowlistTemporaries(fs14, allowlistFile, isRunning) {
4393
4473
  const prefix = `${import_node_path11.default.basename(allowlistFile)}.`;
4394
- for (const name of fs13.readdir(import_node_path11.default.dirname(allowlistFile))) {
4474
+ for (const name of fs14.readdir(import_node_path11.default.dirname(allowlistFile))) {
4395
4475
  const writer = name.startsWith(prefix) ? /^([1-9]\d*)\.tmp$/.exec(name.slice(prefix.length))?.[1] : void 0;
4396
4476
  if (writer !== void 0 && !isRunning(Number(writer))) {
4397
- fs13.removeRecursive(import_node_path11.default.join(import_node_path11.default.dirname(allowlistFile), name));
4477
+ fs14.removeRecursive(import_node_path11.default.join(import_node_path11.default.dirname(allowlistFile), name));
4398
4478
  }
4399
4479
  }
4400
4480
  }
4401
- function readAllProviders(fs13, providersDir) {
4481
+ function readAllProviders(fs14, providersDir) {
4402
4482
  const result = [];
4403
- for (const name of fs13.readdir(providersDir)) {
4483
+ for (const name of fs14.readdir(providersDir)) {
4404
4484
  if (!name.endsWith(".json")) {
4405
4485
  continue;
4406
4486
  }
4407
4487
  try {
4408
- const parsed = parseJson(fs13.readFileUtf8(import_node_path11.default.join(providersDir, name)), ProviderSchema);
4488
+ const parsed = parseJson(fs14.readFileUtf8(import_node_path11.default.join(providersDir, name)), ProviderSchema);
4409
4489
  if (parsed !== void 0) {
4410
4490
  result.push({ name: name.slice(0, -".json".length), provider: parsed });
4411
4491
  }
@@ -4415,22 +4495,22 @@ function readAllProviders(fs13, providersDir) {
4415
4495
  }
4416
4496
  return result;
4417
4497
  }
4418
- function writeSession(fs13, sessionsDir, session) {
4419
- fs13.mkdirp(sessionsDir);
4420
- fs13.writeFileUtf8(import_node_path11.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
4498
+ function writeSession(fs14, sessionsDir, session) {
4499
+ fs14.mkdirp(sessionsDir);
4500
+ fs14.writeFileUtf8(import_node_path11.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
4421
4501
  `);
4422
4502
  }
4423
- function removeSession(fs13, sessionsDir, pid) {
4424
- fs13.removeRecursive(import_node_path11.default.join(sessionsDir, `${String(pid)}.json`));
4503
+ function removeSession(fs14, sessionsDir, pid) {
4504
+ fs14.removeRecursive(import_node_path11.default.join(sessionsDir, `${String(pid)}.json`));
4425
4505
  }
4426
- function listSessions(fs13, sessionsDir) {
4506
+ function listSessions(fs14, sessionsDir) {
4427
4507
  const sessions = [];
4428
- for (const name of fs13.readdir(sessionsDir)) {
4508
+ for (const name of fs14.readdir(sessionsDir)) {
4429
4509
  if (!name.endsWith(".json")) {
4430
4510
  continue;
4431
4511
  }
4432
4512
  try {
4433
- const parsed = parseJson(fs13.readFileUtf8(import_node_path11.default.join(sessionsDir, name)), HeadroomSessionSchema);
4513
+ const parsed = parseJson(fs14.readFileUtf8(import_node_path11.default.join(sessionsDir, name)), HeadroomSessionSchema);
4434
4514
  if (parsed !== void 0) {
4435
4515
  sessions.push(parsed);
4436
4516
  }
@@ -4440,22 +4520,22 @@ function listSessions(fs13, sessionsDir) {
4440
4520
  }
4441
4521
  return sessions.sort((a, b) => a.pid - b.pid);
4442
4522
  }
4443
- function sessionsForSupervisor(fs13, sessionsDir, supervisorPid) {
4444
- return listSessions(fs13, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
4523
+ function sessionsForSupervisor(fs14, sessionsDir, supervisorPid) {
4524
+ return listSessions(fs14, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
4445
4525
  }
4446
- function pruneDeadSessions(fs13, sessionsDir, isRunning) {
4526
+ function pruneDeadSessions(fs14, sessionsDir, isRunning) {
4447
4527
  const removed = [];
4448
- for (const session of listSessions(fs13, sessionsDir)) {
4528
+ for (const session of listSessions(fs14, sessionsDir)) {
4449
4529
  if (!isRunning(session.pid)) {
4450
- removeSession(fs13, sessionsDir, session.pid);
4530
+ removeSession(fs14, sessionsDir, session.pid);
4451
4531
  removed.push(session.pid);
4452
4532
  }
4453
4533
  }
4454
4534
  return removed;
4455
4535
  }
4456
- function readStartLock(fs13, lockFile) {
4536
+ function readStartLock(fs14, lockFile) {
4457
4537
  try {
4458
- return parseJson(fs13.readFileUtf8(lockFile), HeadroomLockSchema);
4538
+ return parseJson(fs14.readFileUtf8(lockFile), HeadroomLockSchema);
4459
4539
  } catch {
4460
4540
  return void 0;
4461
4541
  }
@@ -4548,12 +4628,12 @@ function earlierReleaseAllowlistHash(providers, doorOrigin) {
4548
4628
  }
4549
4629
  return hashAllowlist([...entries].sort());
4550
4630
  }
4551
- function earlierReleaseDaemon(fs13, paths, daemon) {
4631
+ function earlierReleaseDaemon(fs14, paths, daemon) {
4552
4632
  if (daemonIdentity(daemon.commandLine, daemon.socketPath) !== "earlier-release") {
4553
4633
  return void 0;
4554
4634
  }
4555
- const providers = readAllProviders(fs13, paths.providersDir).map((entry) => entry.provider);
4556
- const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(fs13, paths.frontdoorStateFile)));
4635
+ const providers = readAllProviders(fs14, paths.providersDir).map((entry) => entry.provider);
4636
+ const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile)));
4557
4637
  return { admitsServingDoor: daemon.recordedHash === expected };
4558
4638
  }
4559
4639
  var EARLIER_RELEASE_ALLOWLIST, EARLIER_RELEASE_ANTHROPIC_UPSTREAM;
@@ -4578,8 +4658,8 @@ function awaitingCause(daemonPid, identity, allowlistFile) {
4578
4658
  }
4579
4659
  return `the headroom supervisor has not written an allowlist admitting this launch's upstreams to ${allowlistFile} within ${String(HEADROOM_START_TIMEOUT_MS)}ms`;
4580
4660
  }
4581
- function daemonAdmits(fs13, allowlistFile, recordedHash, required) {
4582
- const content = fs13.readFileUtf8(allowlistFile);
4661
+ function daemonAdmits(fs14, allowlistFile, recordedHash, required) {
4662
+ const content = fs14.readFileUtf8(allowlistFile);
4583
4663
  if (content === void 0 || recordedHash === void 0) {
4584
4664
  return false;
4585
4665
  }
@@ -4842,7 +4922,7 @@ function verifyAllowlistFile(allowlistFile, ports) {
4842
4922
  const replaceable = fileStat === void 0 || fileStat.kind === "file" || fileStat.kind === "symlink";
4843
4923
  return { message: refusal2, repairable: replaceable };
4844
4924
  }
4845
- function prepareHeadroomSocket(fs13, ports, paths, supervisorPid) {
4925
+ function prepareHeadroomSocket(fs14, ports, paths, supervisorPid) {
4846
4926
  const unsupported = platformRefusal(ports.platform);
4847
4927
  if (unsupported !== void 0) {
4848
4928
  return { refused: unsupported };
@@ -4857,18 +4937,18 @@ function prepareHeadroomSocket(fs13, ports, paths, supervisorPid) {
4857
4937
  if (ports.lstat(paths.headroomSocketDir)?.kind === "symlink") {
4858
4938
  return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
4859
4939
  }
4860
- fs13.mkdirPrivate(paths.headroomSocketDir);
4940
+ fs14.mkdirPrivate(paths.headroomSocketDir);
4861
4941
  const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
4862
4942
  return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
4863
4943
  }
4864
- function pruneStaleHeadroomSockets(fs13, paths, isRunning) {
4944
+ function pruneStaleHeadroomSockets(fs14, paths, isRunning) {
4865
4945
  const removed = [];
4866
- for (const name of fs13.readdir(paths.headroomSocketDir)) {
4946
+ for (const name of fs14.readdir(paths.headroomSocketDir)) {
4867
4947
  const pid = HEADROOM_SOCKET_NAME.exec(name)?.[1];
4868
4948
  if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
4869
4949
  continue;
4870
4950
  }
4871
- fs13.removeRecursive(import_node_path12.default.join(paths.headroomSocketDir, name));
4951
+ fs14.removeRecursive(import_node_path12.default.join(paths.headroomSocketDir, name));
4872
4952
  removed.push(name);
4873
4953
  }
4874
4954
  return removed;
@@ -4980,37 +5060,37 @@ function compareVersions2(a, b) {
4980
5060
  return 0;
4981
5061
  }
4982
5062
  async function runSupervisor(initialConfig, ports, options = {}) {
4983
- const { fs: fs13, paths } = ports;
5063
+ const { fs: fs14, paths } = ports;
4984
5064
  let config = initialConfig;
4985
- migrateHeadroomState(fs13, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
4986
- const previousState = resolveServingHeadroomState(fs13, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
5065
+ migrateHeadroomState(fs14, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
5066
+ const previousState = resolveServingHeadroomState(fs14, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
4987
5067
  if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
4988
5068
  ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
4989
5069
  return 0;
4990
5070
  }
4991
5071
  let installedSource = previousState?.installedSource;
4992
5072
  const ownsState = () => {
4993
- const owner = readHeadroomState(fs13, paths.headroomStateFile)?.supervisorPid;
5073
+ const owner = readHeadroomState(fs14, paths.headroomStateFile)?.supervisorPid;
4994
5074
  return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
4995
5075
  };
4996
5076
  const writeOwnState = (state) => {
4997
5077
  if (!ownsState()) {
4998
5078
  return false;
4999
5079
  }
5000
- writeHeadroomState(fs13, paths.headroomStateFile, state);
5080
+ writeHeadroomState(fs14, paths.headroomStateFile, state);
5001
5081
  return true;
5002
5082
  };
5003
5083
  const fail = (message) => {
5004
5084
  if (writeOwnState({ lastError: message })) {
5005
- fs13.removeRecursive(paths.headroomLockFile);
5085
+ fs14.removeRecursive(paths.headroomLockFile);
5006
5086
  }
5007
5087
  ports.log(`agent-shim headroom supervisor: ${message}`);
5008
5088
  return 1;
5009
5089
  };
5010
5090
  const syncAllowlistFile = (allowlist) => {
5011
5091
  try {
5012
- if (fs13.readFileUtf8(paths.headroomAllowlistFile) !== formatAllowlistFile(allowlist)) {
5013
- writeAllowlistFile(fs13, paths.headroomAllowlistFile, allowlist);
5092
+ if (fs14.readFileUtf8(paths.headroomAllowlistFile) !== formatAllowlistFile(allowlist)) {
5093
+ writeAllowlistFile(fs14, paths.headroomAllowlistFile, allowlist);
5014
5094
  ports.log(`agent-shim headroom supervisor: wrote allowlist [${allowlist.join(", ")}] to ${paths.headroomAllowlistFile}`);
5015
5095
  }
5016
5096
  return void 0;
@@ -5028,9 +5108,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5028
5108
  }
5029
5109
  ports.log(`agent-shim headroom supervisor: repairing the allowlist file: ${problem.message}`);
5030
5110
  try {
5031
- fs13.mkdirPrivate(paths.headroomDir);
5032
- fs13.mkdirPrivate(import_node_path13.default.dirname(paths.headroomAllowlistFile));
5033
- writeAllowlistFile(fs13, paths.headroomAllowlistFile, allowlist);
5111
+ fs14.mkdirPrivate(paths.headroomDir);
5112
+ fs14.mkdirPrivate(import_node_path13.default.dirname(paths.headroomAllowlistFile));
5113
+ writeAllowlistFile(fs14, paths.headroomAllowlistFile, allowlist);
5034
5114
  } catch (error) {
5035
5115
  return `could not write the headroom allowlist file ${paths.headroomAllowlistFile}: ${error instanceof Error ? error.message : String(error)}`;
5036
5116
  }
@@ -5055,20 +5135,20 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5055
5135
  installedSource = config.source;
5056
5136
  return void 0;
5057
5137
  };
5058
- const socket = prepareHeadroomSocket(fs13, ports.socketTrust, paths, ports.ownPid);
5138
+ const socket = prepareHeadroomSocket(fs14, ports.socketTrust, paths, ports.ownPid);
5059
5139
  if (socket.refused !== void 0) {
5060
5140
  return fail(socket.refused);
5061
5141
  }
5062
5142
  const { socketPath } = socket;
5063
- pruneStaleHeadroomSockets(fs13, paths, ports.isRunning);
5064
- pruneStaleAllowlistTemporaries(fs13, paths.headroomAllowlistFile, ports.isRunning);
5143
+ pruneStaleHeadroomSockets(fs14, paths, ports.isRunning);
5144
+ pruneStaleAllowlistTemporaries(fs14, paths.headroomAllowlistFile, ports.isRunning);
5065
5145
  const installFailure = ensureInstalled();
5066
5146
  if (installFailure !== void 0) {
5067
5147
  return fail(installFailure);
5068
5148
  }
5069
5149
  const version = ports.headroomVersion() ?? "unknown";
5070
5150
  writeOwnState({ supervisorPid: ports.ownPid, version, installedSource });
5071
- ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(fs13, paths, ports.frontDoorLiveness).frontDoorOrigins.join(", ")}]`);
5151
+ ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(fs14, paths, ports.frontDoorLiveness).frontDoorOrigins.join(", ")}]`);
5072
5152
  const orphanPid = previousState?.headroomPid;
5073
5153
  const orphanSocket = previousState?.socketPath ?? (previousState?.supervisorPid === void 0 ? void 0 : headroomSocketPath(paths, previousState.supervisorPid));
5074
5154
  const orphanIdentity = orphanPid === void 0 || orphanSocket === void 0 || !ports.isRunning(orphanPid) ? void 0 : daemonIdentity(ports.daemonCommandLine(orphanPid), orphanSocket);
@@ -5103,12 +5183,12 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5103
5183
  ticks += 1;
5104
5184
  config = ports.readConfig();
5105
5185
  const settingsHash = hashSettings(config.settings);
5106
- const inputs = currentHeadroomAllowlistInputs(fs13, paths, ports.frontDoorLiveness);
5107
- pruneDeadFrontDoorDirectRecords(fs13, paths.frontdoorDirectRecordsDir, inputs.frontDoorRecords, inputs.frontDoorLiveness);
5108
- pruneMalformedFrontDoorDirectFiles(fs13, paths.frontdoorDirectRecordsDir, ports.isRunning);
5186
+ const inputs = currentHeadroomAllowlistInputs(fs14, paths, ports.frontDoorLiveness);
5187
+ pruneDeadFrontDoorDirectRecords(fs14, paths.frontdoorDirectRecordsDir, inputs.frontDoorRecords, inputs.frontDoorLiveness);
5188
+ pruneMalformedFrontDoorDirectFiles(fs14, paths.frontdoorDirectRecordsDir, ports.isRunning);
5109
5189
  const allowlist = inputs.frontDoorOrigins;
5110
5190
  const allowlistHash = hashAllowlist(allowlist);
5111
- pruneDeadSessions(fs13, paths.headroomSessionsDir, ports.isRunning);
5191
+ pruneDeadSessions(fs14, paths.headroomSessionsDir, ports.isRunning);
5112
5192
  const ownsNow = ownsState();
5113
5193
  if (!ownsNow && !superseded) {
5114
5194
  ports.log("agent-shim headroom supervisor: another supervisor now owns the state file; serving this daemon's own sessions until they end");
@@ -5155,7 +5235,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5155
5235
  runningSettingsHash = settingsHash;
5156
5236
  const recorded = writeOwnState(servingState(pid));
5157
5237
  if (recorded) {
5158
- fs13.removeRecursive(paths.headroomLockFile);
5238
+ fs14.removeRecursive(paths.headroomLockFile);
5159
5239
  }
5160
5240
  idleSince = void 0;
5161
5241
  ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on unix socket ${socketPath}`);
@@ -5183,7 +5263,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5183
5263
  ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} now serves allowlist [${allowlist.join(", ")}]`);
5184
5264
  }
5185
5265
  if (runningSettingsHash !== settingsHash || installedSource !== config.source) {
5186
- if (sessionsForSupervisor(fs13, paths.headroomSessionsDir, ports.ownPid).length === 0) {
5266
+ if (sessionsForSupervisor(fs14, paths.headroomSessionsDir, ports.ownPid).length === 0) {
5187
5267
  ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
5188
5268
  ports.stopProcess(headroomPid);
5189
5269
  headroomPid = void 0;
@@ -5192,7 +5272,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5192
5272
  continue;
5193
5273
  }
5194
5274
  }
5195
- const sessions = sessionsForSupervisor(fs13, paths.headroomSessionsDir, ports.ownPid);
5275
+ const sessions = sessionsForSupervisor(fs14, paths.headroomSessionsDir, ports.ownPid);
5196
5276
  if (sessions.length === 0) {
5197
5277
  idleSince ??= ports.now();
5198
5278
  const idleMs = ports.now() - idleSince;
@@ -5217,9 +5297,9 @@ function undeterminedFrontDoors(inputs) {
5217
5297
  return reason === void 0 ? [] : [{ pid: record.pid, origin: directOrigin(record.directPort), reason }];
5218
5298
  });
5219
5299
  }
5220
- function currentHeadroomAllowlistInputs(fs13, paths, frontDoorLiveness) {
5221
- const named = frontDoorOrigin(readFrontDoorState(fs13, paths.frontdoorStateFile));
5222
- const records = listFrontDoorDirectRecords(fs13, paths.frontdoorDirectRecordsDir);
5300
+ function currentHeadroomAllowlistInputs(fs14, paths, frontDoorLiveness) {
5301
+ const named = frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile));
5302
+ const records = listFrontDoorDirectRecords(fs14, paths.frontdoorDirectRecordsDir);
5223
5303
  const liveness = frontDoorLiveness(records.map((record) => record.pid));
5224
5304
  const live = liveFrontDoorDirectRecords(records, liveness).map((record) => directOrigin(record.directPort));
5225
5305
  return {
@@ -5228,8 +5308,8 @@ function currentHeadroomAllowlistInputs(fs13, paths, frontDoorLiveness) {
5228
5308
  frontDoorOrigins: [.../* @__PURE__ */ new Set([...named === void 0 ? [] : [named], ...live])].sort()
5229
5309
  };
5230
5310
  }
5231
- function launchRequiredUpstreams(fs13, paths) {
5232
- const door = frontDoorOrigin(readFrontDoorState(fs13, paths.frontdoorStateFile));
5311
+ function launchRequiredUpstreams(fs14, paths) {
5312
+ const door = frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile));
5233
5313
  return door === void 0 ? [] : [door];
5234
5314
  }
5235
5315
  async function waitUntilReady(ports, socketPath, pid) {
@@ -5954,8 +6034,8 @@ var init_cascade = __esm({
5954
6034
  function poolNameOf(selector) {
5955
6035
  return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
5956
6036
  }
5957
- function readActiveIdentity(fs13, activeIdentityFile) {
5958
- const trimmed = fs13.readFileUtf8(activeIdentityFile)?.trim();
6037
+ function readActiveIdentity(fs14, activeIdentityFile) {
6038
+ const trimmed = fs14.readFileUtf8(activeIdentityFile)?.trim();
5959
6039
  return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
5960
6040
  }
5961
6041
  function isNonEmpty(value) {
@@ -6002,8 +6082,8 @@ function decideConfigProfile(params) {
6002
6082
  }
6003
6083
  return { source: "none" };
6004
6084
  }
6005
- function loadIdentity(identitiesDir, name, fs13) {
6006
- return loadConfigFile(import_node_path17.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs13.readConfigFile);
6085
+ function loadIdentity(identitiesDir, name, fs14) {
6086
+ return loadConfigFile(import_node_path17.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs14.readConfigFile);
6007
6087
  }
6008
6088
  var import_node_path17, IDENTITY_DECISION_SOURCES, CONFIG_PROFILE_DECISION_SOURCES;
6009
6089
  var init_identity = __esm({
@@ -6245,14 +6325,14 @@ function isIdentityName(name) {
6245
6325
  function claudeJsonPath(identitiesDir, identity) {
6246
6326
  return import_node_path18.default.join(identitiesDir, identity, CLAUDE_JSON);
6247
6327
  }
6248
- function readAccountMetadata(fs13, identitiesDir, identity) {
6328
+ function readAccountMetadata(fs14, identitiesDir, identity) {
6249
6329
  if (!isIdentityName(identity)) {
6250
6330
  throw new Error(`"${identity}" is not a valid identity name.`);
6251
6331
  }
6252
- return readAccountMetadataFile(fs13, claudeJsonPath(identitiesDir, identity));
6332
+ return readAccountMetadataFile(fs14, claudeJsonPath(identitiesDir, identity));
6253
6333
  }
6254
- function readAccountMetadataFile(fs13, file) {
6255
- const raw = fs13.readFileUtf8(file);
6334
+ function readAccountMetadataFile(fs14, file) {
6335
+ const raw = fs14.readFileUtf8(file);
6256
6336
  if (raw === void 0) {
6257
6337
  return void 0;
6258
6338
  }
@@ -6282,19 +6362,19 @@ function readAccountMetadataFile(fs13, file) {
6282
6362
  }
6283
6363
  return account.data;
6284
6364
  }
6285
- function createAccountReader(fs13, identitiesDir) {
6365
+ function createAccountReader(fs14, identitiesDir) {
6286
6366
  const cache = /* @__PURE__ */ new Map();
6287
6367
  return (identity) => {
6288
6368
  if (!isIdentityName(identity)) {
6289
6369
  throw new Error(`"${identity}" is not a valid identity name.`);
6290
6370
  }
6291
- const stat = fs13.lstat(claudeJsonPath(identitiesDir, identity));
6371
+ const stat = fs14.lstat(claudeJsonPath(identitiesDir, identity));
6292
6372
  const stamp = stat === void 0 ? "absent" : `${String(stat.mtimeMs)}:${String(stat.sizeBytes)}`;
6293
6373
  const cached = cache.get(identity);
6294
6374
  if (cached?.stamp === stamp) {
6295
6375
  return cached.account;
6296
6376
  }
6297
- const account = readAccountMetadata(fs13, identitiesDir, identity);
6377
+ const account = readAccountMetadata(fs14, identitiesDir, identity);
6298
6378
  cache.set(identity, { stamp, account });
6299
6379
  return account;
6300
6380
  };
@@ -6878,8 +6958,8 @@ function segmentDay(epochMs) {
6878
6958
  function segmentName(day, pid) {
6879
6959
  return `${day}.${String(pid)}.jsonl`;
6880
6960
  }
6881
- function listLogSegments(fs13, logDir) {
6882
- return fs13.readdir(logDir).flatMap((name) => {
6961
+ function listLogSegments(fs14, logDir) {
6962
+ return fs14.readdir(logDir).flatMap((name) => {
6883
6963
  const match = SEGMENT_RE.exec(name);
6884
6964
  const day = match?.[1];
6885
6965
  if (day === void 0) {
@@ -6888,15 +6968,15 @@ function listLogSegments(fs13, logDir) {
6888
6968
  return [{ name, day, endsAt: Date.parse(`${day}T00:00:00.000Z`) + DAY_MS }];
6889
6969
  }).sort((left, right) => left.day.localeCompare(right.day) || left.name.localeCompare(right.name));
6890
6970
  }
6891
- function readUsageLog(fs13, logDir, options = {}) {
6971
+ function readUsageLog(fs14, logDir, options = {}) {
6892
6972
  const { sinceMs } = options;
6893
6973
  const records = [];
6894
6974
  let invalidLines = 0;
6895
- for (const segment of listLogSegments(fs13, logDir)) {
6975
+ for (const segment of listLogSegments(fs14, logDir)) {
6896
6976
  if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
6897
6977
  continue;
6898
6978
  }
6899
- const contents = fs13.readFileUtf8(import_node_path19.default.join(logDir, segment.name));
6979
+ const contents = fs14.readFileUtf8(import_node_path19.default.join(logDir, segment.name));
6900
6980
  if (contents === void 0) {
6901
6981
  continue;
6902
6982
  }
@@ -6932,9 +7012,9 @@ function snapshotPath(snapshotsDir, identity) {
6932
7012
  }
6933
7013
  return import_node_path19.default.join(snapshotsDir, `${identity}.json`);
6934
7014
  }
6935
- function readUsageSnapshot(fs13, snapshotsDir, identity) {
7015
+ function readUsageSnapshot(fs14, snapshotsDir, identity) {
6936
7016
  const file = snapshotPath(snapshotsDir, identity);
6937
- const raw = fs13.readFileUtf8(file);
7017
+ const raw = fs14.readFileUtf8(file);
6938
7018
  if (raw === void 0) {
6939
7019
  return void 0;
6940
7020
  }
@@ -6950,8 +7030,8 @@ function readUsageSnapshot(fs13, snapshotsDir, identity) {
6950
7030
  }
6951
7031
  return snapshot.data;
6952
7032
  }
6953
- function listUsageSnapshots(fs13, snapshotsDir) {
6954
- return fs13.readdir(snapshotsDir).flatMap((name) => {
7033
+ function listUsageSnapshots(fs14, snapshotsDir) {
7034
+ return fs14.readdir(snapshotsDir).flatMap((name) => {
6955
7035
  if (!name.endsWith(".json")) {
6956
7036
  return [];
6957
7037
  }
@@ -6959,7 +7039,7 @@ function listUsageSnapshots(fs13, snapshotsDir) {
6959
7039
  if (!isIdentityName(identity)) {
6960
7040
  return [];
6961
7041
  }
6962
- const snapshot = readUsageSnapshot(fs13, snapshotsDir, identity);
7042
+ const snapshot = readUsageSnapshot(fs14, snapshotsDir, identity);
6963
7043
  return snapshot === void 0 ? [] : [snapshot];
6964
7044
  }).sort((left, right) => left.identity.localeCompare(right.identity));
6965
7045
  }
@@ -6984,11 +7064,11 @@ var init_read = __esm({
6984
7064
  });
6985
7065
 
6986
7066
  // src/usage/store.ts
6987
- function pruneUsageLog(fs13, logDir, nowMs) {
7067
+ function pruneUsageLog(fs14, logDir, nowMs) {
6988
7068
  const cutoff = nowMs - USAGE_RETENTION_MS;
6989
- for (const segment of listLogSegments(fs13, logDir)) {
7069
+ for (const segment of listLogSegments(fs14, logDir)) {
6990
7070
  if (segment.endsAt <= cutoff) {
6991
- fs13.removeRecursive(import_node_path20.default.join(logDir, segment.name));
7071
+ fs14.removeRecursive(import_node_path20.default.join(logDir, segment.name));
6992
7072
  }
6993
7073
  }
6994
7074
  }
@@ -7017,7 +7097,7 @@ function foldProviderState(current, record) {
7017
7097
  };
7018
7098
  }
7019
7099
  function createUsageStore(deps) {
7020
- const { fs: fs13, paths } = deps;
7100
+ const { fs: fs14, paths } = deps;
7021
7101
  let prunedDay;
7022
7102
  const rewriteSnapshot = (identity, fold) => {
7023
7103
  if (!isIdentityName(identity)) {
@@ -7026,7 +7106,7 @@ function createUsageStore(deps) {
7026
7106
  }
7027
7107
  let current;
7028
7108
  try {
7029
- current = readUsageSnapshot(fs13, paths.usageSnapshotsDir, identity);
7109
+ current = readUsageSnapshot(fs14, paths.usageSnapshotsDir, identity);
7030
7110
  } catch (error) {
7031
7111
  if (!(error instanceof UsageSnapshotError)) {
7032
7112
  throw error;
@@ -7053,8 +7133,8 @@ function createUsageStore(deps) {
7053
7133
  ...account === void 0 ? {} : { account },
7054
7134
  providers
7055
7135
  });
7056
- fs13.mkdirPrivate(paths.usageSnapshotsDir);
7057
- fs13.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
7136
+ fs14.mkdirPrivate(paths.usageSnapshotsDir);
7137
+ fs14.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
7058
7138
  `);
7059
7139
  deps.publish?.(snapshot);
7060
7140
  return true;
@@ -7063,14 +7143,14 @@ function createUsageStore(deps) {
7063
7143
  record: (input) => {
7064
7144
  const record = UsageRecordSchema.parse(input);
7065
7145
  const nowMs = deps.now();
7066
- fs13.mkdirPrivate(paths.usageDir);
7067
- fs13.mkdirPrivate(paths.usageLogDir);
7146
+ fs14.mkdirPrivate(paths.usageDir);
7147
+ fs14.mkdirPrivate(paths.usageLogDir);
7068
7148
  const day = segmentDay(nowMs);
7069
7149
  if (prunedDay !== day) {
7070
- pruneUsageLog(fs13, paths.usageLogDir, nowMs);
7150
+ pruneUsageLog(fs14, paths.usageLogDir, nowMs);
7071
7151
  prunedDay = day;
7072
7152
  }
7073
- fs13.appendFilePrivate(import_node_path20.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
7153
+ fs14.appendFilePrivate(import_node_path20.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
7074
7154
  `);
7075
7155
  deps.onRecord?.(record);
7076
7156
  if (record.identity !== void 0) {
@@ -7113,14 +7193,14 @@ var init_store2 = __esm({
7113
7193
  function errorMessage(error) {
7114
7194
  return error instanceof Error ? error.message : String(error);
7115
7195
  }
7116
- function loadPoolMembers(fs13, paths, identities, nowMs) {
7196
+ function loadPoolMembers(fs14, paths, identities, nowMs) {
7117
7197
  const windowStartMs = nowMs - FIVE_HOUR_WINDOW_MS;
7118
- const log = readUsageLog(fs13, paths.usageLogDir, { sinceMs: windowStartMs });
7198
+ const log = readUsageLog(fs14, paths.usageLogDir, { sinceMs: windowStartMs });
7119
7199
  return identities.map((identity) => {
7120
7200
  const records = log.records.filter((record) => record.identity === identity && record.provider === ANTHROPIC_PROVIDER && Date.parse(record.at) >= windowStartMs);
7121
7201
  try {
7122
- const snapshot = readUsageSnapshot(fs13, paths.usageSnapshotsDir, identity);
7123
- const account = readAccountMetadata(fs13, paths.identitiesDir, identity) ?? snapshot?.account;
7202
+ const snapshot = readUsageSnapshot(fs14, paths.usageSnapshotsDir, identity);
7203
+ const account = readAccountMetadata(fs14, paths.identitiesDir, identity) ?? snapshot?.account;
7124
7204
  return { identity, records, ...snapshot === void 0 ? {} : { snapshot }, ...account === void 0 ? {} : { account } };
7125
7205
  } catch (error) {
7126
7206
  if (error instanceof UsageSnapshotError || error instanceof AccountMetadataError) {
@@ -7214,9 +7294,9 @@ function collectPoolIdentities(pools, poolName, stack, found) {
7214
7294
  collectPoolIdentities(pools, nestedName, childStack, found);
7215
7295
  }
7216
7296
  }
7217
- function readPicksFile(fs13, file) {
7297
+ function readPicksFile(fs14, file) {
7218
7298
  const empty = { schemaVersion: SCHEMA_VERSION, picks: {} };
7219
- const raw = fs13.readFileUtf8(file);
7299
+ const raw = fs14.readFileUtf8(file);
7220
7300
  if (raw === void 0) {
7221
7301
  return { file: empty };
7222
7302
  }
@@ -7229,17 +7309,17 @@ function readPicksFile(fs13, file) {
7229
7309
  const result = PicksFileSchema.safeParse(parsed);
7230
7310
  return result.success ? { file: result.data } : { file: empty, problem: `${file} is not a picks file this agent-shim can read` };
7231
7311
  }
7232
- function readStickyPick(fs13, picksFile, directory) {
7233
- const read = readPicksFile(fs13, picksFile);
7312
+ function readStickyPick(fs14, picksFile, directory) {
7313
+ const read = readPicksFile(fs14, picksFile);
7234
7314
  const entry = read.file.picks[directory];
7235
7315
  return { ...entry === void 0 ? {} : { sticky: entry }, ...read.problem === void 0 ? {} : { problem: read.problem } };
7236
7316
  }
7237
- function recordStickyPick(fs13, picksFile, directory, identity, nowMs) {
7238
- const current = readPicksFile(fs13, picksFile).file.picks;
7317
+ function recordStickyPick(fs14, picksFile, directory, identity, nowMs) {
7318
+ const current = readPicksFile(fs14, picksFile).file.picks;
7239
7319
  const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
7240
7320
  const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
7241
- fs13.mkdirPrivate(import_node_path21.default.dirname(picksFile));
7242
- fs13.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
7321
+ fs14.mkdirPrivate(import_node_path21.default.dirname(picksFile));
7322
+ fs14.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
7243
7323
  `);
7244
7324
  }
7245
7325
  var import_node_path21, import_zod13, PoolGraphError, SCHEMA_VERSION, PickEntrySchema, PicksFileSchema;
@@ -7514,6 +7594,7 @@ function buildLayoutPaths(root) {
7514
7594
  frontdoorControlTokenFile: import_node_path23.default.join(root, "frontdoor", "control-token"),
7515
7595
  frontdoorSessionsDir: import_node_path23.default.join(root, "frontdoor", "sessions"),
7516
7596
  frontdoorDirectRecordsDir: import_node_path23.default.join(root, "frontdoor", "direct"),
7597
+ frontdoorDrainingDir: import_node_path23.default.join(root, "frontdoor", "draining"),
7517
7598
  frontdoorRcCredentialsDir: import_node_path23.default.join(root, "frontdoor", "rc-credentials"),
7518
7599
  frontdoorLogPath: import_node_path23.default.join(root, "logs", "frontdoor.log"),
7519
7600
  usageDir: import_node_path23.default.join(root, "usage"),
@@ -8590,12 +8671,12 @@ function decideSignIn(facts) {
8590
8671
  function credentialsFilePath(farmRoot) {
8591
8672
  return import_node_path26.default.join(farmRoot, CREDENTIALS_FILE);
8592
8673
  }
8593
- function identitySignIn(fs13, probe, identity) {
8674
+ function identitySignIn(fs14, probe, identity) {
8594
8675
  const probing = !identity.hasCredentialBlock;
8595
8676
  return decideSignIn({
8596
8677
  hasCredentialBlock: identity.hasCredentialBlock,
8597
8678
  keychainItem: probing && probe.platform === "darwin" && probe.run !== void 0 ? keychainHasItem(probe.run, identity.farmRoot) : void 0,
8598
- credentialsFile: probing && fs13.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
8679
+ credentialsFile: probing && fs14.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
8599
8680
  platform: probe.platform
8600
8681
  });
8601
8682
  }
@@ -9438,6 +9519,16 @@ var init_update = __esm({
9438
9519
  }
9439
9520
  });
9440
9521
 
9522
+ // src/frontdoor/replacement.ts
9523
+ function replacementLine(facts) {
9524
+ return `launcher ${String(facts.launcherPid)}: replacing front door; reason=${facts.reason} signal=${facts.signal} door=${String(facts.doorPid)} doorProtocol=${String(facts.doorProtocol)} launcherProtocol=${String(facts.launcherProtocol)} liveSessions=${String(facts.liveSessions)}`;
9525
+ }
9526
+ var init_replacement = __esm({
9527
+ "src/frontdoor/replacement.ts"() {
9528
+ "use strict";
9529
+ }
9530
+ });
9531
+
9441
9532
  // src/frontdoor/ensure.ts
9442
9533
  function ensureFrontDoor(params) {
9443
9534
  const { paths, ports } = params;
@@ -9448,7 +9539,7 @@ function ensureFrontDoor(params) {
9448
9539
  let lastRejection;
9449
9540
  let busyDoor;
9450
9541
  const liveSessionsOn = (doorPid) => listFrontDoorSessions(ports.fs, paths.frontdoorSessionsDir).filter(
9451
- (session) => session.pid !== params.launcherPid && ports.isRunning(session.pid) && (session.supervisorPid === void 0 || session.supervisorPid === doorPid)
9542
+ (session) => session.pid !== params.launcherPid && ports.isRunning(session.pid) && (session.supervisorPid === void 0 || session.supervisorPid === doorPid || !ports.isRunning(session.supervisorPid))
9452
9543
  ).length;
9453
9544
  const verifyWithRetry = (port) => {
9454
9545
  let verdict = ports.verifyListener(port);
@@ -9458,12 +9549,20 @@ function ensureFrontDoor(params) {
9458
9549
  }
9459
9550
  return verdict;
9460
9551
  };
9461
- const stopAndAwaitExit = (supervisorPid, failure) => {
9552
+ const recordReplacement = (doorPid, doorProtocol, reason, signal) => {
9553
+ ports.recordReplacement(
9554
+ replacementLine({ reason, signal, launcherPid: params.launcherPid, launcherProtocol: FRONT_DOOR_PROTOCOL, doorPid, doorProtocol, liveSessions: liveSessionsOn(doorPid) })
9555
+ );
9556
+ };
9557
+ const stopAndAwaitExit = (supervisorPid, doorProtocol, reason, failure) => {
9558
+ recordReplacement(supervisorPid, doorProtocol, reason, "SIGTERM");
9462
9559
  ports.stopSupervisor(supervisorPid);
9463
9560
  const graceEnds = ports.now() + FRONTDOOR_EXIT_GRACE_MS;
9464
9561
  let killed = false;
9465
- while (ports.isRunning(supervisorPid)) {
9562
+ const holdsAddresses = () => ports.isRunning(supervisorPid) && readFrontDoorState(ports.fs, paths.frontdoorStateFile)?.supervisorPid === supervisorPid;
9563
+ while (holdsAddresses()) {
9466
9564
  if (!killed && ports.now() >= graceEnds) {
9565
+ recordReplacement(supervisorPid, doorProtocol, reason, "SIGKILL");
9467
9566
  ports.killSupervisor(supervisorPid);
9468
9567
  killed = true;
9469
9568
  }
@@ -9478,16 +9577,19 @@ function ensureFrontDoor(params) {
9478
9577
  const supervisorPid = state?.supervisorPid;
9479
9578
  if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
9480
9579
  if (state?.port !== void 0 && state.connectPort !== void 0) {
9481
- if (supervisorPid === params.launcherPid && params.replace !== true && ports.isFrontDoorSupervisor(supervisorPid)) {
9580
+ if (supervisorPid === params.launcherPid && params.replace === void 0 && ports.isFrontDoorSupervisor(supervisorPid)) {
9482
9581
  const token = (0, import_node_crypto10.randomUUID)();
9483
9582
  writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid, ...recordOf(params.session) });
9484
9583
  return { port: state.port, connectPort: state.connectPort, token };
9485
9584
  }
9486
9585
  const verdict = verifyWithRetry(state.port);
9487
- if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
9586
+ const doorProtocol = state.protocol ?? 0;
9587
+ if (verdict.ok && !replaced && !spawned && (params.replace !== void 0 || doorProtocol < FRONT_DOOR_PROTOCOL)) {
9488
9588
  stopAndAwaitExit(
9489
9589
  supervisorPid,
9490
- `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`
9590
+ doorProtocol,
9591
+ params.replace ?? "protocol-older",
9592
+ `the front door (pid ${String(supervisorPid)}, protocol ${String(doorProtocol)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit`
9491
9593
  );
9492
9594
  replaced = true;
9493
9595
  continue;
@@ -9503,15 +9605,15 @@ function ensureFrontDoor(params) {
9503
9605
  }
9504
9606
  if (ports.isFrontDoorSupervisor(supervisorPid)) {
9505
9607
  const stranded = liveSessionsOn(supervisorPid);
9506
- if (params.replace === true && !replaced) {
9507
- stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
9608
+ if (params.replace !== void 0 && !replaced) {
9609
+ stopAndAwaitExit(supervisorPid, doorProtocol, "probe-failed-restart", `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
9508
9610
  replaced = true;
9509
9611
  continue;
9510
9612
  }
9511
9613
  if (stranded > 0) {
9512
9614
  busyDoor = { pid: supervisorPid, sessions: stranded };
9513
9615
  } else {
9514
- stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
9616
+ stopAndAwaitExit(supervisorPid, doorProtocol, "probe-failed-idle", `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
9515
9617
  continue;
9516
9618
  }
9517
9619
  } else {
@@ -9553,6 +9655,7 @@ var init_ensure2 = __esm({
9553
9655
  import_node_crypto10 = require("node:crypto");
9554
9656
  init_cliError();
9555
9657
  init_state2();
9658
+ init_replacement();
9556
9659
  init_state();
9557
9660
  FRONTDOOR_START_TIMEOUT_MS = 3e4;
9558
9661
  FRONTDOOR_LAUNCHER_POLL_MS = 100;
@@ -10080,15 +10183,15 @@ function contextTokensOfTranscript(text) {
10080
10183
  }
10081
10184
  return void 0;
10082
10185
  }
10083
- function newestTranscript(fs13, projectDir) {
10186
+ function newestTranscript(fs14, projectDir) {
10084
10187
  let newest;
10085
10188
  let newestMs = -Infinity;
10086
- for (const name of fs13.readdir(projectDir)) {
10189
+ for (const name of fs14.readdir(projectDir)) {
10087
10190
  if (!name.endsWith(".jsonl")) {
10088
10191
  continue;
10089
10192
  }
10090
10193
  const candidate = import_node_path38.default.join(projectDir, name);
10091
- const stat = fs13.lstat(candidate);
10194
+ const stat = fs14.lstat(candidate);
10092
10195
  if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
10093
10196
  newestMs = stat.mtimeMs;
10094
10197
  newest = candidate;
@@ -10096,14 +10199,14 @@ function newestTranscript(fs13, projectDir) {
10096
10199
  }
10097
10200
  return newest;
10098
10201
  }
10099
- function resumedContextTokens(fs13, params) {
10202
+ function resumedContextTokens(fs14, params) {
10100
10203
  const target = resumeTargetOf(params.passthrough);
10101
10204
  if (target === void 0) {
10102
10205
  return void 0;
10103
10206
  }
10104
10207
  const projectDir = import_node_path38.default.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
10105
- const file = target.kind === "id" ? import_node_path38.default.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs13, projectDir);
10106
- const text = file === void 0 ? void 0 : fs13.readFileUtf8(file);
10208
+ const file = target.kind === "id" ? import_node_path38.default.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs14, projectDir);
10209
+ const text = file === void 0 ? void 0 : fs14.readFileUtf8(file);
10107
10210
  return text === void 0 ? void 0 : contextTokensOfTranscript(text);
10108
10211
  }
10109
10212
  var import_node_path38;
@@ -10555,7 +10658,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
10555
10658
  return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
10556
10659
  }
10557
10660
  function pickFromPool(decided, params, parsedArgv, readOnly) {
10558
- const { paths, fs: fs13, proc, log } = params;
10661
+ const { paths, fs: fs14, proc, log } = params;
10559
10662
  if (decided.pool === void 0) {
10560
10663
  return { identityDecision: decided };
10561
10664
  }
@@ -10574,7 +10677,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
10574
10677
  selectedVia: decided.source,
10575
10678
  pools: params.pools,
10576
10679
  paths,
10577
- fs: fs13,
10680
+ fs: fs14,
10578
10681
  usageFs: farmRuntime.fs,
10579
10682
  cwd: farmRuntime.cwd,
10580
10683
  now: farmRuntime.now,
@@ -10597,7 +10700,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
10597
10700
  };
10598
10701
  }
10599
10702
  function decideLaunch(params, readOnly) {
10600
- const { paths, fs: fs13, proc, log } = params;
10703
+ const { paths, fs: fs14, proc, log } = params;
10601
10704
  const { env, argv } = proc;
10602
10705
  const parsedArgv = parseLauncherArgv(argv);
10603
10706
  const cliOverride = buildCliOverride({
@@ -10612,7 +10715,7 @@ function decideLaunch(params, readOnly) {
10612
10715
  argv0Identity: parsedArgv.identity,
10613
10716
  directoryPinnedIdentity: params.directoryPinnedIdentity,
10614
10717
  readActiveIdentityFile: () => {
10615
- const raw = fs13.readFileUtf8(paths.activeIdentityFile);
10718
+ const raw = fs14.readFileUtf8(paths.activeIdentityFile);
10616
10719
  if (raw === void 0) {
10617
10720
  return void 0;
10618
10721
  }
@@ -10647,7 +10750,7 @@ function decideLaunch(params, readOnly) {
10647
10750
  }
10648
10751
  let loadedIdentity;
10649
10752
  if (identityDecision.name !== void 0) {
10650
- loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs13);
10753
+ loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs14);
10651
10754
  if (loadedIdentity === void 0) {
10652
10755
  log.error(
10653
10756
  `agent-shim: no identity named "${identityDecision.name}" (selected via ${identityDecision.source}). Run \`agent-shim identity add ${identityDecision.name}\` first.`
@@ -10662,7 +10765,7 @@ function decideLaunch(params, readOnly) {
10662
10765
  identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
10663
10766
  globalDefaultConfigProfile: params.globalDefaultConfigProfile
10664
10767
  });
10665
- if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs13.readConfigFile(import_node_path39.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
10768
+ if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs14.readConfigFile(import_node_path39.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
10666
10769
  log.error(
10667
10770
  `agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
10668
10771
  );
@@ -10671,7 +10774,7 @@ function decideLaunch(params, readOnly) {
10671
10774
  const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
10672
10775
  const providerParams = {
10673
10776
  paths,
10674
- port: fs13,
10777
+ port: fs14,
10675
10778
  ...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
10676
10779
  ...farmContext === void 0 ? {} : { cascade: farmContext.cascade }
10677
10780
  };
@@ -10770,9 +10873,9 @@ function decideLaunch(params, readOnly) {
10770
10873
  const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
10771
10874
  const globalModels = loadConfigFile(paths.globalConfigFile, GlobalConfigSchema, params.fs.readConfigFile)?.config.models;
10772
10875
  const models = launchCascade !== void 0 && params.farm !== void 0 ? cascadeModels : globalModels;
10773
- const listedProviders = listProviderNames(fs13.readdir, paths.providersDir).flatMap((name) => {
10876
+ const listedProviders = listProviderNames(fs14.readdir, paths.providersDir).flatMap((name) => {
10774
10877
  try {
10775
- const definition = loadProvider(paths.providersDir, name, fs13);
10878
+ const definition = loadProvider(paths.providersDir, name, fs14);
10776
10879
  return definition === void 0 ? [] : [[name, definition, parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, name)))?.models ?? []]];
10777
10880
  } catch {
10778
10881
  return [];
@@ -11053,6 +11156,20 @@ var init_ownCli = __esm({
11053
11156
  }
11054
11157
  });
11055
11158
 
11159
+ // src/frontdoor/doorLog.ts
11160
+ function appendDoorLog(paths, line) {
11161
+ import_node_fs12.default.mkdirSync(paths.logsDir, { recursive: true });
11162
+ import_node_fs12.default.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
11163
+ `);
11164
+ }
11165
+ var import_node_fs12;
11166
+ var init_doorLog = __esm({
11167
+ "src/frontdoor/doorLog.ts"() {
11168
+ "use strict";
11169
+ import_node_fs12 = __toESM(require("node:fs"), 1);
11170
+ }
11171
+ });
11172
+
11056
11173
  // src/frontdoor/selfIdentity.ts
11057
11174
  function isFrontDoorSupervisorPid(pid, identify) {
11058
11175
  return declaredPid !== void 0 && pid === declaredPid && pid === process.pid || identify(pid);
@@ -11066,14 +11183,14 @@ var init_selfIdentity = __esm({
11066
11183
 
11067
11184
  // src/frontdoor/trust.ts
11068
11185
  function resolveTrustBundle(params) {
11069
- const { caCertFile, bundlesDir, variable, inherited, fs: fs13 } = params;
11186
+ const { caCertFile, bundlesDir, variable, inherited, fs: fs14 } = params;
11070
11187
  if (inherited === void 0 || inherited === "" || import_node_path41.default.resolve(inherited) === import_node_path41.default.resolve(caCertFile)) {
11071
11188
  return { path: caCertFile };
11072
11189
  }
11073
- const caPem = fs13.readFileUtf8(caCertFile);
11190
+ const caPem = fs14.readFileUtf8(caCertFile);
11074
11191
  let inheritedPem;
11075
11192
  try {
11076
- inheritedPem = fs13.readFileUtf8(inherited);
11193
+ inheritedPem = fs14.readFileUtf8(inherited);
11077
11194
  } catch (error) {
11078
11195
  return {
11079
11196
  path: caCertFile,
@@ -11086,9 +11203,9 @@ function resolveTrustBundle(params) {
11086
11203
  const combined = `${inheritedPem.trimEnd()}
11087
11204
  ${caPem}`;
11088
11205
  const bundle = import_node_path41.default.join(bundlesDir, `${(0, import_node_crypto12.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
11089
- if (!fs13.exists(bundle)) {
11090
- fs13.mkdirp(bundlesDir);
11091
- fs13.writeFileAtomic(bundle, combined);
11206
+ if (!fs14.exists(bundle)) {
11207
+ fs14.mkdirp(bundlesDir);
11208
+ fs14.writeFileAtomic(bundle, combined);
11092
11209
  }
11093
11210
  return { path: bundle };
11094
11211
  }
@@ -11111,6 +11228,9 @@ function realEnsurePorts(paths, spawnDaemon) {
11111
11228
  sleep: realSleepSync,
11112
11229
  spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
11113
11230
  isFrontDoorSupervisor: (pid) => isFrontDoorSupervisorPid(pid, realIsFrontDoorSupervisor),
11231
+ recordReplacement: (line) => {
11232
+ appendDoorLog(paths, line);
11233
+ },
11114
11234
  stopSupervisor: (pid) => {
11115
11235
  process.kill(pid, "SIGTERM");
11116
11236
  },
@@ -11118,7 +11238,7 @@ function realEnsurePorts(paths, spawnDaemon) {
11118
11238
  process.kill(pid, "SIGKILL");
11119
11239
  },
11120
11240
  // Read fresh for each probe: a replacement supervisor may have regenerated an unparseable CA, and the probe must trust exactly what the serving door's leaf chains to.
11121
- verifyListener: (port) => probeFrontDoorSync(port, import_node_fs12.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
11241
+ verifyListener: (port) => probeFrontDoorSync(port, import_node_fs13.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
11122
11242
  };
11123
11243
  }
11124
11244
  function realFrontDoorPort(paths, spawnDaemon) {
@@ -11139,22 +11259,23 @@ function realFrontDoorPort(paths, spawnDaemon) {
11139
11259
  }
11140
11260
  };
11141
11261
  }
11142
- var import_node_fs12, realTrustBundleFs;
11262
+ var import_node_fs13, realTrustBundleFs;
11143
11263
  var init_realFrontDoorPort = __esm({
11144
11264
  "src/frontdoor/realFrontDoorPort.ts"() {
11145
11265
  "use strict";
11146
- import_node_fs12 = __toESM(require("node:fs"), 1);
11266
+ import_node_fs13 = __toESM(require("node:fs"), 1);
11147
11267
  init_realPorts();
11268
+ init_doorLog();
11148
11269
  init_ensure2();
11149
11270
  init_state();
11150
11271
  init_probe();
11151
11272
  init_selfIdentity();
11152
11273
  init_trust();
11153
11274
  realTrustBundleFs = {
11154
- readFileUtf8: (file) => import_node_fs12.default.readFileSync(file, "utf8"),
11155
- exists: (file) => import_node_fs12.default.existsSync(file),
11275
+ readFileUtf8: (file) => import_node_fs13.default.readFileSync(file, "utf8"),
11276
+ exists: (file) => import_node_fs13.default.existsSync(file),
11156
11277
  mkdirp: (dir) => {
11157
- import_node_fs12.default.mkdirSync(dir, { recursive: true });
11278
+ import_node_fs13.default.mkdirSync(dir, { recursive: true });
11158
11279
  },
11159
11280
  writeFileAtomic: (file, contents) => {
11160
11281
  realFarmFs.writeFilePrivate(file, contents);
@@ -13898,6 +14019,10 @@ function realConnectEffects(ports = DOOR_SOURCE_PORTS) {
13898
14019
  }
13899
14020
  resolve({
13900
14021
  port: bound,
14022
+ // The listening socket is released by `close` at once; the connections already accepted are untouched and keep the server's `close` callback pending until they end.
14023
+ stopAccepting: () => {
14024
+ server.close();
14025
+ },
13901
14026
  close: async () => {
13902
14027
  await new Promise((closeResolve) => {
13903
14028
  server.close(() => {
@@ -14103,11 +14228,11 @@ function credentialOfJson(parsed) {
14103
14228
  function sequenceNumOfJson(value) {
14104
14229
  return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
14105
14230
  }
14106
- function createRcCredentialStore(fs13, dir) {
14107
- fs13.mkdirPrivate(dir);
14231
+ function createRcCredentialStore(fs14, dir) {
14232
+ fs14.mkdirPrivate(dir);
14108
14233
  const fileFor = (sessionId) => import_node_path10.default.join(dir, `${sessionId}.json`);
14109
14234
  const readParsed = (sessionId) => {
14110
- const raw = fs13.readFileUtf8(fileFor(sessionId));
14235
+ const raw = fs14.readFileUtf8(fileFor(sessionId));
14111
14236
  if (raw === void 0) {
14112
14237
  return void 0;
14113
14238
  }
@@ -14132,7 +14257,7 @@ function createRcCredentialStore(fs13, dir) {
14132
14257
  }
14133
14258
  const cursor = sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
14134
14259
  const record = { ...credential, ...cursor === void 0 ? {} : { highestSequenceNum: cursor } };
14135
- fs13.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
14260
+ fs14.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
14136
14261
  `);
14137
14262
  },
14138
14263
  readCursor: (sessionId) => {
@@ -14147,14 +14272,14 @@ function createRcCredentialStore(fs13, dir) {
14147
14272
  }
14148
14273
  const credential = credentialOfJson(readParsed(sessionId));
14149
14274
  const record = credential === void 0 ? { highestSequenceNum } : { ...credential, highestSequenceNum };
14150
- fs13.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
14275
+ fs14.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
14151
14276
  `);
14152
14277
  },
14153
14278
  remove: (sessionId) => {
14154
14279
  if (!isSafeSessionId(sessionId)) {
14155
14280
  return;
14156
14281
  }
14157
- fs13.removeRecursive(fileFor(sessionId));
14282
+ fs14.removeRecursive(fileFor(sessionId));
14158
14283
  }
14159
14284
  };
14160
14285
  }
@@ -16057,14 +16182,18 @@ init_supervisor2();
16057
16182
  init_state();
16058
16183
 
16059
16184
  // src/doctorFrontDoor.ts
16060
- function pushFrontDoor(push, supervisors, registeredPid, liveSessions) {
16185
+ function pushFrontDoor(push, supervisors, registeredPid, liveSessions, draining) {
16061
16186
  if (!supervisors.ok) {
16062
16187
  push("frontdoor", "warn", `Could not list processes to look for duplicate front door supervisors: ${supervisors.message}.`);
16063
16188
  return;
16064
16189
  }
16065
- const { pids } = supervisors;
16190
+ const drainingPids = supervisors.pids.filter((pid) => draining.includes(pid));
16191
+ for (const pid of drainingPids) {
16192
+ push("frontdoor", "warn", `Front door supervisor pid ${String(pid)} is draining: it has released its addresses and exits once the connections it carried have ended.`, String(pid));
16193
+ }
16194
+ const pids = supervisors.pids.filter((pid) => !draining.includes(pid));
16066
16195
  if (pids.length === 0) {
16067
- push("frontdoor", "pass", "No front door supervisor is running.");
16196
+ push("frontdoor", "pass", drainingPids.length === 0 ? "No front door supervisor is running." : "No front door supervisor is serving.");
16068
16197
  return;
16069
16198
  }
16070
16199
  const [only, ...rest] = pids;
@@ -16614,7 +16743,7 @@ function runDoctor(params) {
16614
16743
  }
16615
16744
  if (params.frontDoor !== void 0) {
16616
16745
  const validated3 = params.frontDoor.state.raw === void 0 ? void 0 : validateJson(FrontDoorStateSchema, params.frontDoor.state);
16617
- pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0, params.frontDoor.liveSessions);
16746
+ pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0, params.frontDoor.liveSessions, params.frontDoor.draining ?? []);
16618
16747
  if (params.frontDoor.listeners !== void 0) {
16619
16748
  pushFrontDoorListeners(push, params.frontDoor.listeners);
16620
16749
  }
@@ -16813,7 +16942,7 @@ function collectDoctorReport(params) {
16813
16942
  logPath: paths.headroomLogPath
16814
16943
  }
16815
16944
  },
16816
- ...uid === void 0 ? {} : { frontDoor: { state: { path: paths.frontdoorStateFile, raw: realFsPort.readFileUtf8(paths.frontdoorStateFile) }, supervisors: listFrontDoorSupervisors(realRunPort, uid), liveSessions: listFrontDoorSessions(realFarmFs, paths.frontdoorSessionsDir).filter((session) => realIsProcessRunning(session.pid)), listeners: servingDoorListeners(paths) } }
16945
+ ...uid === void 0 ? {} : { frontDoor: { state: { path: paths.frontdoorStateFile, raw: realFsPort.readFileUtf8(paths.frontdoorStateFile) }, supervisors: listFrontDoorSupervisors(realRunPort, uid), liveSessions: listFrontDoorSessions(realFarmFs, paths.frontdoorSessionsDir).filter((session) => realIsProcessRunning(session.pid)), draining: listDrainingFrontDoors(realFarmFs, paths.frontdoorDrainingDir, realIsProcessRunning), listeners: servingDoorListeners(paths) } }
16817
16946
  });
16818
16947
  return report;
16819
16948
  }
@@ -16859,6 +16988,8 @@ var HeadroomSocketTargetSchema = import_zod26.z.union([import_zod26.z.strictObje
16859
16988
  var FrontDoorStatusOutputSchema = import_zod26.z.strictObject({
16860
16989
  state: FrontDoorStateSchema,
16861
16990
  supervisorAlive: import_zod26.z.boolean(),
16991
+ /** The pids of earlier doors that released their addresses and are finishing the connections they carried: running, but not serving anything new. */
16992
+ draining: import_zod26.z.readonly(import_zod26.z.array(import_zod26.z.number().int().positive())),
16862
16993
  sessions: import_zod26.z.readonly(import_zod26.z.array(FrontDoorSessionStatusSchema)),
16863
16994
  headroomSocket: HeadroomSocketTargetSchema.optional(),
16864
16995
  logPath: import_zod26.z.string(),
@@ -17903,6 +18034,7 @@ function collectFrontDoorStatus(fsPort, socketTrust, paths, isRunning) {
17903
18034
  return {
17904
18035
  state,
17905
18036
  supervisorAlive: state.supervisorPid !== void 0 && isRunning(state.supervisorPid),
18037
+ draining: listDrainingFrontDoors(fsPort, paths.frontdoorDrainingDir, isRunning),
17906
18038
  sessions: listFrontDoorSessions(fsPort, paths.frontdoorSessionsDir).map((session) => ({ ...session, alive: isRunning(session.pid) })),
17907
18039
  headroomSocket: headroomSocketTarget(fsPort, socketTrust, paths),
17908
18040
  logPath: paths.frontdoorLogPath,
@@ -17926,6 +18058,9 @@ function formatFrontDoorStatus(status, caCertPath) {
17926
18058
  } else {
17927
18059
  lines.push(`connect surface: listening on 127.0.0.1:${String(status.state.connectPort)}, CA ${caCertPath}`);
17928
18060
  }
18061
+ if (status.draining.length > 0) {
18062
+ lines.push(`draining: ${status.draining.map(String).join(", ")} (finishing connections opened before the last restart; each exits when they have ended)`);
18063
+ }
17929
18064
  if (status.headroomSocket === void 0) {
17930
18065
  lines.push("headroom hop: the daemon is not serving (sessions asking for headroom fail until it is up)");
17931
18066
  } else if (status.headroomSocket.refused === void 0) {
@@ -18340,6 +18475,7 @@ function createRcEventFanout() {
18340
18475
  }
18341
18476
  function createRcStreamHub(deps) {
18342
18477
  const attachments = /* @__PURE__ */ new Map();
18478
+ let closed = false;
18343
18479
  const lastSavedSequenceNums = /* @__PURE__ */ new Map();
18344
18480
  const persistCursor = (sessionId) => {
18345
18481
  if (deps.saveSequenceNum === void 0) {
@@ -18498,6 +18634,9 @@ function createRcStreamHub(deps) {
18498
18634
  };
18499
18635
  return {
18500
18636
  reconcile: () => {
18637
+ if (closed) {
18638
+ return;
18639
+ }
18501
18640
  const live = new Set(deps.trackedSessions());
18502
18641
  for (const [sessionId, attachment] of attachments) {
18503
18642
  if (!live.has(sessionId)) {
@@ -18520,6 +18659,7 @@ function createRcStreamHub(deps) {
18520
18659
  }
18521
18660
  },
18522
18661
  close: () => {
18662
+ closed = true;
18523
18663
  for (const attachment of attachments.values()) {
18524
18664
  persistCursor(attachment.sessionId);
18525
18665
  const credential = deps.credentialOf(attachment.sessionId);
@@ -19824,8 +19964,8 @@ var SELF_HOST_SUBSCRIPTION_TYPE = "max";
19824
19964
  function isRecord14(value) {
19825
19965
  return typeof value === "object" && value !== null && !Array.isArray(value);
19826
19966
  }
19827
- function readJsonObject(fs13, file) {
19828
- const raw = fs13.readFileUtf8(file);
19967
+ function readJsonObject(fs14, file) {
19968
+ const raw = fs14.readFileUtf8(file);
19829
19969
  if (raw === void 0) {
19830
19970
  return void 0;
19831
19971
  }
@@ -19837,8 +19977,8 @@ function readJsonObject(fs13, file) {
19837
19977
  }
19838
19978
  return isRecord14(parsed) ? parsed : void 0;
19839
19979
  }
19840
- function readRcSelfHostRecord(fs13, frontdoorDir) {
19841
- const parsed = readJsonObject(fs13, import_node_path34.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
19980
+ function readRcSelfHostRecord(fs14, frontdoorDir) {
19981
+ const parsed = readJsonObject(fs14, import_node_path34.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
19842
19982
  if (parsed === void 0) {
19843
19983
  return void 0;
19844
19984
  }
@@ -19939,17 +20079,17 @@ function parseEntry2(project, entry) {
19939
20079
  const base = match?.[1];
19940
20080
  return base === void 0 ? { project, sessionId: entry, superseded: false, entry } : { project, sessionId: base, superseded: true, entry };
19941
20081
  }
19942
- function listSessions2(fs13, configDir) {
20082
+ function listSessions2(fs14, configDir) {
19943
20083
  const found = [];
19944
- for (const project of fs13.readdir(import_node_path35.default.join(configDir, PROJECTS_DIR))) {
20084
+ for (const project of fs14.readdir(import_node_path35.default.join(configDir, PROJECTS_DIR))) {
19945
20085
  const projectDir = import_node_path35.default.join(configDir, PROJECTS_DIR, project);
19946
20086
  const entries = /* @__PURE__ */ new Set();
19947
- for (const name of fs13.readdir(projectDir)) {
20087
+ for (const name of fs14.readdir(projectDir)) {
19948
20088
  if (name.endsWith(TRANSCRIPT_SUFFIX)) {
19949
20089
  entries.add(name.slice(0, -TRANSCRIPT_SUFFIX.length));
19950
20090
  continue;
19951
20091
  }
19952
- const children = fs13.readdir(import_node_path35.default.join(projectDir, name));
20092
+ const children = fs14.readdir(import_node_path35.default.join(projectDir, name));
19953
20093
  if (children.includes(SUBAGENTS_DIR) || children.includes(WORKFLOWS_DIR)) {
19954
20094
  entries.add(name);
19955
20095
  }
@@ -19960,9 +20100,9 @@ function listSessions2(fs13, configDir) {
19960
20100
  }
19961
20101
  return found.sort((left, right) => left.project.localeCompare(right.project) || left.entry.localeCompare(right.entry));
19962
20102
  }
19963
- function locateAgents(fs13, configDir, relativeDir, workflowRunId, report) {
20103
+ function locateAgents(fs14, configDir, relativeDir, workflowRunId, report) {
19964
20104
  const located = [];
19965
- for (const name of listDirOrReport(fs13, configDir, relativeDir, report)) {
20105
+ for (const name of listDirOrReport(fs14, configDir, relativeDir, report)) {
19966
20106
  if (!name.startsWith(AGENT_FILE_PREFIX) || !name.endsWith(META_SUFFIX)) {
19967
20107
  continue;
19968
20108
  }
@@ -20011,17 +20151,17 @@ function toNode(read, children) {
20011
20151
  function describeFailure(error) {
20012
20152
  return error instanceof Error ? error.message : String(error);
20013
20153
  }
20014
- function readFileOrReport(fs13, configDir, relative, report) {
20154
+ function readFileOrReport(fs14, configDir, relative, report) {
20015
20155
  try {
20016
- return fs13.readFileUtf8(import_node_path35.default.join(configDir, relative));
20156
+ return fs14.readFileUtf8(import_node_path35.default.join(configDir, relative));
20017
20157
  } catch (error) {
20018
20158
  report({ path: relative, reason: `could not be read: ${describeFailure(error)}` });
20019
20159
  return void 0;
20020
20160
  }
20021
20161
  }
20022
- function listDirOrReport(fs13, configDir, relative, report) {
20162
+ function listDirOrReport(fs14, configDir, relative, report) {
20023
20163
  try {
20024
- return fs13.readdir(import_node_path35.default.join(configDir, relative));
20164
+ return fs14.readdir(import_node_path35.default.join(configDir, relative));
20025
20165
  } catch (error) {
20026
20166
  report({ path: relative, reason: `could not be listed: ${describeFailure(error)}` });
20027
20167
  return [];
@@ -20044,22 +20184,22 @@ var WorkflowRunFileSchema = import_zod31.z.object({
20044
20184
  phases: import_zod31.z.array(import_zod31.z.object({ title: import_zod31.z.string() })).default([]),
20045
20185
  summary: import_zod31.z.string().optional()
20046
20186
  });
20047
- function summariseSession(fs13, configDir, ref) {
20187
+ function summariseSession(fs14, configDir, ref) {
20048
20188
  const sessionRelative = import_node_path35.default.join(PROJECTS_DIR, ref.project, ref.entry);
20049
20189
  const subagentsRelative = import_node_path35.default.join(sessionRelative, SUBAGENTS_DIR);
20050
20190
  const workflowsUnderSubagents = import_node_path35.default.join(subagentsRelative, WORKFLOWS_DIR);
20051
20191
  const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
20052
- let agentCount = fs13.readdir(import_node_path35.default.join(configDir, subagentsRelative)).filter(isMeta).length;
20053
- for (const runDir of fs13.readdir(import_node_path35.default.join(configDir, workflowsUnderSubagents))) {
20192
+ let agentCount = fs14.readdir(import_node_path35.default.join(configDir, subagentsRelative)).filter(isMeta).length;
20193
+ for (const runDir of fs14.readdir(import_node_path35.default.join(configDir, workflowsUnderSubagents))) {
20054
20194
  if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
20055
- agentCount += fs13.readdir(import_node_path35.default.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
20195
+ agentCount += fs14.readdir(import_node_path35.default.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
20056
20196
  }
20057
20197
  }
20058
- const workflowRunCount = fs13.readdir(import_node_path35.default.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
20059
- const transcript = fs13.lstat(import_node_path35.default.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
20198
+ const workflowRunCount = fs14.readdir(import_node_path35.default.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
20199
+ const transcript = fs14.lstat(import_node_path35.default.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
20060
20200
  return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
20061
20201
  }
20062
- function readSessionAgentTree(fs13, configDir, ref, options = {}) {
20202
+ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
20063
20203
  const problems = [];
20064
20204
  const report = (problem) => {
20065
20205
  problems.push(problem);
@@ -20067,15 +20207,15 @@ function readSessionAgentTree(fs13, configDir, ref, options = {}) {
20067
20207
  const sessionRelative = import_node_path35.default.join(PROJECTS_DIR, ref.project, ref.entry);
20068
20208
  const subagentsRelative = import_node_path35.default.join(sessionRelative, SUBAGENTS_DIR);
20069
20209
  const workflowsUnderSubagents = import_node_path35.default.join(subagentsRelative, WORKFLOWS_DIR);
20070
- const located = locateAgents(fs13, configDir, subagentsRelative, void 0, report);
20071
- for (const runDir of listDirOrReport(fs13, configDir, workflowsUnderSubagents, report)) {
20210
+ const located = locateAgents(fs14, configDir, subagentsRelative, void 0, report);
20211
+ for (const runDir of listDirOrReport(fs14, configDir, workflowsUnderSubagents, report)) {
20072
20212
  if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
20073
- located.push(...locateAgents(fs13, configDir, import_node_path35.default.join(workflowsUnderSubagents, runDir), runDir, report));
20213
+ located.push(...locateAgents(fs14, configDir, import_node_path35.default.join(workflowsUnderSubagents, runDir), runDir, report));
20074
20214
  }
20075
20215
  }
20076
20216
  const agents = /* @__PURE__ */ new Map();
20077
20217
  for (const candidate of located) {
20078
- const text = readFileOrReport(fs13, configDir, candidate.metaPath, report);
20218
+ const text = readFileOrReport(fs14, configDir, candidate.metaPath, report);
20079
20219
  if (text === void 0) {
20080
20220
  continue;
20081
20221
  }
@@ -20087,7 +20227,7 @@ function readSessionAgentTree(fs13, configDir, ref, options = {}) {
20087
20227
  agents.set(candidate.id, { located: candidate, meta: parsed.data });
20088
20228
  }
20089
20229
  const teamNames = [...new Set([...agents.values()].flatMap((agent) => agent.meta.teamName === void 0 ? [] : [agent.meta.teamName]))].sort();
20090
- const parentOf3 = resolveParents(fs13, configDir, agents, report);
20230
+ const parentOf3 = resolveParents(fs14, configDir, agents, report);
20091
20231
  const childrenOf = /* @__PURE__ */ new Map();
20092
20232
  const roots = [];
20093
20233
  for (const id of agents.keys()) {
@@ -20110,12 +20250,12 @@ function readSessionAgentTree(fs13, configDir, ref, options = {}) {
20110
20250
  sessionId: ref.sessionId,
20111
20251
  superseded: ref.superseded,
20112
20252
  agents: roots.sort().map(build),
20113
- tasks: readTasks(fs13, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
20114
- workflowRuns: readWorkflowRuns(fs13, configDir, import_node_path35.default.join(sessionRelative, WORKFLOWS_DIR), report),
20253
+ tasks: readTasks(fs14, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
20254
+ workflowRuns: readWorkflowRuns(fs14, configDir, import_node_path35.default.join(sessionRelative, WORKFLOWS_DIR), report),
20115
20255
  problems
20116
20256
  };
20117
20257
  }
20118
- function resolveParents(fs13, configDir, agents, report) {
20258
+ function resolveParents(fs14, configDir, agents, report) {
20119
20259
  const parentOf3 = /* @__PURE__ */ new Map();
20120
20260
  const transcriptCache = /* @__PURE__ */ new Map();
20121
20261
  const transcriptOf = (agent) => {
@@ -20123,7 +20263,7 @@ function resolveParents(fs13, configDir, agents, report) {
20123
20263
  if (cached !== void 0) {
20124
20264
  return cached;
20125
20265
  }
20126
- const text = readFileOrReport(fs13, configDir, agent.located.transcriptPath, report) ?? "";
20266
+ const text = readFileOrReport(fs14, configDir, agent.located.transcriptPath, report) ?? "";
20127
20267
  transcriptCache.set(agent.located.id, text);
20128
20268
  return text;
20129
20269
  };
@@ -20173,16 +20313,16 @@ function resolveParents(fs13, configDir, agents, report) {
20173
20313
  function ownTaskLists(sessionId) {
20174
20314
  return [sessionId, `${SHORT_SESSION_LIST_PREFIX}${sessionId.slice(0, SHORT_SESSION_ID_LENGTH)}`];
20175
20315
  }
20176
- function readTasks(fs13, configDir, ownLists, sharedLists, report) {
20316
+ function readTasks(fs14, configDir, ownLists, sharedLists, report) {
20177
20317
  const tasks = [];
20178
20318
  [...ownLists, ...sharedLists].forEach((scope, index) => {
20179
20319
  const relativeDir = import_node_path35.default.join(TASKS_DIR, scope);
20180
- for (const name of [...listDirOrReport(fs13, configDir, relativeDir, report)].sort()) {
20320
+ for (const name of [...listDirOrReport(fs14, configDir, relativeDir, report)].sort()) {
20181
20321
  if (name.startsWith(".") || !name.endsWith(JSON_SUFFIX)) {
20182
20322
  continue;
20183
20323
  }
20184
20324
  const relative = import_node_path35.default.join(relativeDir, name);
20185
- const text = readFileOrReport(fs13, configDir, relative, report);
20325
+ const text = readFileOrReport(fs14, configDir, relative, report);
20186
20326
  const parsed = TaskFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
20187
20327
  if (parsed.success) {
20188
20328
  tasks.push(index < ownLists.length ? parsed.data : { ...parsed.data, taskList: scope });
@@ -20193,14 +20333,14 @@ function readTasks(fs13, configDir, ownLists, sharedLists, report) {
20193
20333
  });
20194
20334
  return tasks;
20195
20335
  }
20196
- function readWorkflowRuns(fs13, configDir, relativeDir, report) {
20336
+ function readWorkflowRuns(fs14, configDir, relativeDir, report) {
20197
20337
  const runs = [];
20198
- for (const name of [...listDirOrReport(fs13, configDir, relativeDir, report)].sort()) {
20338
+ for (const name of [...listDirOrReport(fs14, configDir, relativeDir, report)].sort()) {
20199
20339
  if (!name.startsWith(WORKFLOW_RUN_PREFIX) || !name.endsWith(JSON_SUFFIX)) {
20200
20340
  continue;
20201
20341
  }
20202
20342
  const relative = import_node_path35.default.join(relativeDir, name);
20203
- const text = readFileOrReport(fs13, configDir, relative, report);
20343
+ const text = readFileOrReport(fs14, configDir, relative, report);
20204
20344
  const parsed = WorkflowRunFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
20205
20345
  if (!parsed.success) {
20206
20346
  if (text !== void 0) {
@@ -20226,11 +20366,11 @@ var SessionLookupError = class extends CliError {
20226
20366
  function identityConfigDir(identitiesDir, identity) {
20227
20367
  return import_node_path36.default.join(identitiesDir, identity);
20228
20368
  }
20229
- function historyStores(fs13, identitiesDir, identities) {
20369
+ function historyStores(fs14, identitiesDir, identities) {
20230
20370
  const byRealPath = /* @__PURE__ */ new Map();
20231
20371
  for (const identity of identities) {
20232
20372
  const configDir = identityConfigDir(identitiesDir, identity);
20233
- const real = fs13.realpath(import_node_path36.default.join(configDir, "projects"));
20373
+ const real = fs14.realpath(import_node_path36.default.join(configDir, "projects"));
20234
20374
  if (real === void 0) {
20235
20375
  continue;
20236
20376
  }
@@ -20243,15 +20383,15 @@ function historyStores(fs13, identitiesDir, identities) {
20243
20383
  }
20244
20384
  return [...byRealPath.values()];
20245
20385
  }
20246
- function collectSessionList(fs13, identitiesDir, identities, filters) {
20386
+ function collectSessionList(fs14, identitiesDir, identities, filters) {
20247
20387
  const names = filters.identity === void 0 ? identities : identities.filter((name) => name === filters.identity);
20248
20388
  if (filters.identity !== void 0 && names.length === 0) {
20249
20389
  throw new SessionLookupError(`no identity named "${filters.identity}"`);
20250
20390
  }
20251
20391
  const sessions = [];
20252
- for (const store of historyStores(fs13, identitiesDir, names)) {
20253
- for (const ref of listSessions2(fs13, store.configDir)) {
20254
- const summary = summariseSession(fs13, store.configDir, ref);
20392
+ for (const store of historyStores(fs14, identitiesDir, names)) {
20393
+ for (const ref of listSessions2(fs14, store.configDir)) {
20394
+ const summary = summariseSession(fs14, store.configDir, ref);
20255
20395
  if (filters.all === true || summary.agentCount > 0 || summary.workflowRunCount > 0) {
20256
20396
  sessions.push({ ...summary, identities: store.identities });
20257
20397
  }
@@ -20259,14 +20399,14 @@ function collectSessionList(fs13, identitiesDir, identities, filters) {
20259
20399
  }
20260
20400
  return sessions.sort((left, right) => (right.updatedAt ?? "").localeCompare(left.updatedAt ?? "") || left.sessionId.localeCompare(right.sessionId));
20261
20401
  }
20262
- function locateSession(fs13, identitiesDir, identities, query, onlyIdentity) {
20402
+ function locateSession(fs14, identitiesDir, identities, query, onlyIdentity) {
20263
20403
  const names = onlyIdentity === void 0 ? identities : identities.filter((name) => name === onlyIdentity);
20264
20404
  if (onlyIdentity !== void 0 && names.length === 0) {
20265
20405
  throw new SessionLookupError(`no identity named "${onlyIdentity}"`);
20266
20406
  }
20267
20407
  const matches = [];
20268
- for (const store of historyStores(fs13, identitiesDir, names)) {
20269
- for (const ref of listSessions2(fs13, store.configDir)) {
20408
+ for (const store of historyStores(fs14, identitiesDir, names)) {
20409
+ for (const ref of listSessions2(fs14, store.configDir)) {
20270
20410
  if (ref.sessionId.startsWith(query)) {
20271
20411
  matches.push({ identities: store.identities, configDir: store.configDir, ref });
20272
20412
  }
@@ -20283,9 +20423,9 @@ function locateSession(fs13, identitiesDir, identities, query, onlyIdentity) {
20283
20423
  }
20284
20424
  throw new SessionLookupError(`"${query}" matches ${String(candidates.length)} sessions: ${candidates.map((match) => `${match.ref.sessionId} (${match.identities.join(", ")})`).join("; ")}; give more of the id or pass --identity`);
20285
20425
  }
20286
- function showSession(fs13, identitiesDir, identities, query, onlyIdentity) {
20287
- const located = locateSession(fs13, identitiesDir, identities, query, onlyIdentity);
20288
- return { identities: located.identities, tree: readSessionAgentTree(fs13, located.configDir, located.ref) };
20426
+ function showSession(fs14, identitiesDir, identities, query, onlyIdentity) {
20427
+ const located = locateSession(fs14, identitiesDir, identities, query, onlyIdentity);
20428
+ return { identities: located.identities, tree: readSessionAgentTree(fs14, located.configDir, located.ref) };
20289
20429
  }
20290
20430
 
20291
20431
  // src/agents/realFs.ts