claude-use 11.54.0 → 11.54.1

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/cli.cjs CHANGED
@@ -29129,6 +29129,7 @@ function realIsProcessAlive(pid) {
29129
29129
  }
29130
29130
  }
29131
29131
  function realIsProcessZombie(pid) {
29132
+ refuseToBlockInRole("a synchronous process-table read");
29132
29133
  const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "stat=", "-p", String(pid)], { encoding: "utf8" });
29133
29134
  return result.status === 0 && result.stdout.trim().startsWith("Z");
29134
29135
  }
@@ -29136,6 +29137,7 @@ function realIsProcessRunning(pid) {
29136
29137
  return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
29137
29138
  }
29138
29139
  function realIsFrontDoorSupervisor(pid) {
29140
+ refuseToBlockInRole("a synchronous process-table read");
29139
29141
  const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "pid=,command=", "-p", String(pid)], { encoding: "utf8" });
29140
29142
  return result.status === 0 && parseFrontDoorSupervisorPids(result.stdout).includes(pid);
29141
29143
  }
@@ -29184,15 +29186,39 @@ function realReadFileTail(filePath, fromByte, maxBytes) {
29184
29186
  }
29185
29187
  }
29186
29188
  function realProcessCommandLine(pid) {
29189
+ refuseToBlockInRole("a synchronous process-table read");
29187
29190
  const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8", timeout: PS_TIMEOUT_MS });
29188
29191
  return result.status === 0 ? result.stdout.trim() : void 0;
29189
29192
  }
29190
29193
  function realFrontDoorLiveness(pids) {
29194
+ refuseToBlockInRole("a synchronous process-table read");
29191
29195
  return frontDoorLivenessOf(pids, (asked) => {
29192
29196
  const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "pid=,stat=,command=", "-p", asked.map(String).join(",")], { encoding: "utf8", timeout: PS_TIMEOUT_MS });
29193
29197
  return { status: result.status, stdout: result.stdout, stderr: result.stderr, ...result.error === void 0 ? {} : { error: result.error } };
29194
29198
  });
29195
29199
  }
29200
+ async function readProcessStates(pids) {
29201
+ return await new Promise((resolve2) => {
29202
+ (0, import_node_child_process2.execFile)("ps", ["-o", "pid=,stat=", "-p", pids.map(String).join(",")], { encoding: "utf8", timeout: PS_TIMEOUT_MS }, (_error, stdout2) => {
29203
+ const states = /* @__PURE__ */ new Map();
29204
+ for (const line of stdout2.split("\n")) {
29205
+ const [pidText, stat] = line.trim().split(/\s+/);
29206
+ if (stat !== void 0) {
29207
+ states.set(Number(pidText), stat);
29208
+ }
29209
+ }
29210
+ resolve2(states);
29211
+ });
29212
+ });
29213
+ }
29214
+ async function realRunningAmong(pids) {
29215
+ const existing = pids.filter(realIsProcessAlive);
29216
+ if (existing.length === 0) {
29217
+ return /* @__PURE__ */ new Set();
29218
+ }
29219
+ const states = await readProcessStates(existing);
29220
+ return new Set(existing.filter((pid) => states.get(pid)?.startsWith("Z") !== true));
29221
+ }
29196
29222
  function expandHome(filePath) {
29197
29223
  return filePath.startsWith("~/") ? import_node_path9.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
29198
29224
  }
@@ -35674,9 +35700,9 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
35674
35700
  const watchdog = ports.startWatchdog?.();
35675
35701
  let idleSince;
35676
35702
  let ticks = 0;
35677
- const supersedingOwner = () => {
35703
+ const supersedingOwner = async () => {
35678
35704
  const owner = readFrontDoorState(fs30, paths.frontdoorStateFile)?.supervisorPid;
35679
- return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
35705
+ return owner !== void 0 && owner !== ports.ownPid && (await ports.runningAmong([owner])).has(owner) ? owner : void 0;
35680
35706
  };
35681
35707
  let supersededBy;
35682
35708
  let served;
@@ -35701,7 +35727,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
35701
35727
  watchdog?.stop();
35702
35728
  ports.stopBackgroundWork?.();
35703
35729
  const drained = [direct.drain(), connect3.drain(), http9.drain()];
35704
- if (supersedingOwner() === void 0) {
35730
+ if (await supersedingOwner() === void 0) {
35705
35731
  writeFrontDoorState(fs30, paths.frontdoorStateFile, sticky());
35706
35732
  }
35707
35733
  markFrontDoorDraining(fs30, paths.frontdoorDrainingDir, ports.ownPid);
@@ -35722,7 +35748,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
35722
35748
  };
35723
35749
  const shutdown = async () => {
35724
35750
  await closeServing();
35725
- if (supersedingOwner() === void 0) {
35751
+ if (await supersedingOwner() === void 0) {
35726
35752
  writeFrontDoorState(fs30, paths.frontdoorStateFile, sticky());
35727
35753
  }
35728
35754
  return 0;
@@ -35738,13 +35764,14 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
35738
35764
  }
35739
35765
  ticks += 1;
35740
35766
  const listed = listFrontDoorSessions(fs30, paths.frontdoorSessionsDir);
35741
- const pruned = pruneDeadFrontDoorSessions(fs30, paths.frontdoorSessionsDir, ports.isRunning);
35767
+ const running = await ports.runningAmong(listed.map((session) => session.pid));
35768
+ const pruned = pruneDeadFrontDoorSessions(fs30, paths.frontdoorSessionsDir, (pid) => running.has(pid));
35742
35769
  ports.observeLaunchRegistry(listed, pruned);
35743
35770
  ports.checkQuotaExpiry();
35744
35771
  const prunedPids = new Set(pruned);
35745
35772
  const live = listed.filter((session) => !prunedPids.has(session.pid));
35746
35773
  if (supersededBy === void 0) {
35747
- supersededBy = supersedingOwner();
35774
+ supersededBy = await supersedingOwner();
35748
35775
  if (supersededBy !== void 0) {
35749
35776
  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`);
35750
35777
  ports.doorHealth.superseded(supersededBy);
@@ -36288,7 +36315,7 @@ var init_package = __esm({
36288
36315
  "package.json"() {
36289
36316
  package_default = {
36290
36317
  name: "claude-use",
36291
- version: "11.54.0",
36318
+ version: "11.54.1",
36292
36319
  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.",
36293
36320
  license: "MIT",
36294
36321
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -136526,6 +136553,7 @@ function realFrontDoorSupervisorPorts(paths, respawnGeneration, retire, trackTun
136526
136553
  });
136527
136554
  },
136528
136555
  isRunning: realIsProcessRunning,
136556
+ runningAmong: realRunningAmong,
136529
136557
  // The turnover check's file identity, over the installed entry resolved once at door start: re-resolving per tick would re-run the PATH scan every second and could theoretically flip between two files, while the entry itself is fixed for as long as this door lives. The existence check prefers the agent-shim sibling only when it is really there (see watchedInstallEntry).
136530
136558
  statOwnExecutable: realStatOwnExecutable(watchedInstallEntry(realOwnExecutablePath(), (candidate) => import_node_fs21.default.existsSync(candidate))),
136531
136559
  startProviderListener: async (preferredPort) => {
@@ -136800,7 +136828,7 @@ function registerFrontDoorCommand(program2, deps) {
136800
136828
  exit: deps.exit,
136801
136829
  facts: () => ({
136802
136830
  tunnels: openTunnels(),
136803
- liveSessions: listFrontDoorSessions(realFarmFs, paths.frontdoorSessionsDir).filter((session) => session.pid !== ownPid && realIsProcessRunning(session.pid)).length,
136831
+ liveSessions: listFrontDoorSessions(realFarmFs, paths.frontdoorSessionsDir).filter((session) => session.pid !== ownPid && realIsProcessAlive(session.pid)).length,
136804
136832
  protocol: FRONT_DOOR_PROTOCOL,
136805
136833
  uptimeSeconds: Math.round(process.uptime())
136806
136834
  })
package/dist/index.cjs CHANGED
@@ -3828,9 +3828,9 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3828
3828
  const watchdog = ports.startWatchdog?.();
3829
3829
  let idleSince;
3830
3830
  let ticks = 0;
3831
- const supersedingOwner = () => {
3831
+ const supersedingOwner = async () => {
3832
3832
  const owner = readFrontDoorState(fs14, paths.frontdoorStateFile)?.supervisorPid;
3833
- return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
3833
+ return owner !== void 0 && owner !== ports.ownPid && (await ports.runningAmong([owner])).has(owner) ? owner : void 0;
3834
3834
  };
3835
3835
  let supersededBy;
3836
3836
  let served;
@@ -3855,7 +3855,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3855
3855
  watchdog?.stop();
3856
3856
  ports.stopBackgroundWork?.();
3857
3857
  const drained = [direct.drain(), connect3.drain(), http3.drain()];
3858
- if (supersedingOwner() === void 0) {
3858
+ if (await supersedingOwner() === void 0) {
3859
3859
  writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
3860
3860
  }
3861
3861
  markFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
@@ -3876,7 +3876,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3876
3876
  };
3877
3877
  const shutdown = async () => {
3878
3878
  await closeServing();
3879
- if (supersedingOwner() === void 0) {
3879
+ if (await supersedingOwner() === void 0) {
3880
3880
  writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
3881
3881
  }
3882
3882
  return 0;
@@ -3892,13 +3892,14 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3892
3892
  }
3893
3893
  ticks += 1;
3894
3894
  const listed = listFrontDoorSessions(fs14, paths.frontdoorSessionsDir);
3895
- const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, ports.isRunning);
3895
+ const running = await ports.runningAmong(listed.map((session) => session.pid));
3896
+ const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, (pid) => running.has(pid));
3896
3897
  ports.observeLaunchRegistry(listed, pruned);
3897
3898
  ports.checkQuotaExpiry();
3898
3899
  const prunedPids = new Set(pruned);
3899
3900
  const live = listed.filter((session) => !prunedPids.has(session.pid));
3900
3901
  if (supersededBy === void 0) {
3901
- supersededBy = supersedingOwner();
3902
+ supersededBy = await supersedingOwner();
3902
3903
  if (supersededBy !== void 0) {
3903
3904
  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`);
3904
3905
  ports.doorHealth.superseded(supersededBy);
@@ -4398,7 +4399,7 @@ var init_package = __esm({
4398
4399
  "package.json"() {
4399
4400
  package_default = {
4400
4401
  name: "claude-use",
4401
- version: "11.54.0",
4402
+ version: "11.54.1",
4402
4403
  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.",
4403
4404
  license: "MIT",
4404
4405
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -5652,6 +5653,7 @@ function realIsProcessAlive(pid) {
5652
5653
  }
5653
5654
  }
5654
5655
  function realIsProcessZombie(pid) {
5656
+ refuseToBlockInRole("a synchronous process-table read");
5655
5657
  const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "stat=", "-p", String(pid)], { encoding: "utf8" });
5656
5658
  return result.status === 0 && result.stdout.trim().startsWith("Z");
5657
5659
  }
@@ -5659,14 +5661,17 @@ function realIsProcessRunning(pid) {
5659
5661
  return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
5660
5662
  }
5661
5663
  function realIsFrontDoorSupervisor(pid) {
5664
+ refuseToBlockInRole("a synchronous process-table read");
5662
5665
  const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "pid=,command=", "-p", String(pid)], { encoding: "utf8" });
5663
5666
  return result.status === 0 && parseFrontDoorSupervisorPids(result.stdout).includes(pid);
5664
5667
  }
5665
5668
  function realProcessCommandLine(pid) {
5669
+ refuseToBlockInRole("a synchronous process-table read");
5666
5670
  const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8", timeout: PS_TIMEOUT_MS });
5667
5671
  return result.status === 0 ? result.stdout.trim() : void 0;
5668
5672
  }
5669
5673
  function realFrontDoorLiveness(pids) {
5674
+ refuseToBlockInRole("a synchronous process-table read");
5670
5675
  return frontDoorLivenessOf(pids, (asked) => {
5671
5676
  const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "pid=,stat=,command=", "-p", asked.map(String).join(",")], { encoding: "utf8", timeout: PS_TIMEOUT_MS });
5672
5677
  return { status: result.status, stdout: result.stdout, stderr: result.stderr, ...result.error === void 0 ? {} : { error: result.error } };
package/dist/index.mjs CHANGED
@@ -3805,9 +3805,9 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3805
3805
  const watchdog = ports.startWatchdog?.();
3806
3806
  let idleSince;
3807
3807
  let ticks = 0;
3808
- const supersedingOwner = () => {
3808
+ const supersedingOwner = async () => {
3809
3809
  const owner = readFrontDoorState(fs14, paths.frontdoorStateFile)?.supervisorPid;
3810
- return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
3810
+ return owner !== void 0 && owner !== ports.ownPid && (await ports.runningAmong([owner])).has(owner) ? owner : void 0;
3811
3811
  };
3812
3812
  let supersededBy;
3813
3813
  let served;
@@ -3832,7 +3832,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3832
3832
  watchdog?.stop();
3833
3833
  ports.stopBackgroundWork?.();
3834
3834
  const drained = [direct.drain(), connect3.drain(), http3.drain()];
3835
- if (supersedingOwner() === void 0) {
3835
+ if (await supersedingOwner() === void 0) {
3836
3836
  writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
3837
3837
  }
3838
3838
  markFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
@@ -3853,7 +3853,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3853
3853
  };
3854
3854
  const shutdown = async () => {
3855
3855
  await closeServing();
3856
- if (supersedingOwner() === void 0) {
3856
+ if (await supersedingOwner() === void 0) {
3857
3857
  writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
3858
3858
  }
3859
3859
  return 0;
@@ -3869,13 +3869,14 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
3869
3869
  }
3870
3870
  ticks += 1;
3871
3871
  const listed = listFrontDoorSessions(fs14, paths.frontdoorSessionsDir);
3872
- const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, ports.isRunning);
3872
+ const running = await ports.runningAmong(listed.map((session) => session.pid));
3873
+ const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, (pid) => running.has(pid));
3873
3874
  ports.observeLaunchRegistry(listed, pruned);
3874
3875
  ports.checkQuotaExpiry();
3875
3876
  const prunedPids = new Set(pruned);
3876
3877
  const live = listed.filter((session) => !prunedPids.has(session.pid));
3877
3878
  if (supersededBy === void 0) {
3878
- supersededBy = supersedingOwner();
3879
+ supersededBy = await supersedingOwner();
3879
3880
  if (supersededBy !== void 0) {
3880
3881
  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`);
3881
3882
  ports.doorHealth.superseded(supersededBy);
@@ -4374,7 +4375,7 @@ var init_package = __esm({
4374
4375
  "package.json"() {
4375
4376
  package_default = {
4376
4377
  name: "claude-use",
4377
- version: "11.54.0",
4378
+ version: "11.54.1",
4378
4379
  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.",
4379
4380
  license: "MIT",
4380
4381
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -5608,7 +5609,7 @@ var init_logStyle = __esm({
5608
5609
  });
5609
5610
 
5610
5611
  // src/realPorts.ts
5611
- import { spawn as spawn2, spawnSync } from "node:child_process";
5612
+ import { execFile, spawn as spawn2, spawnSync } from "node:child_process";
5612
5613
  import { createHash as createHash5 } from "node:crypto";
5613
5614
  import fs3 from "node:fs";
5614
5615
  import os3 from "node:os";
@@ -5633,6 +5634,7 @@ function realIsProcessAlive(pid) {
5633
5634
  }
5634
5635
  }
5635
5636
  function realIsProcessZombie(pid) {
5637
+ refuseToBlockInRole("a synchronous process-table read");
5636
5638
  const result = spawnSync("ps", ["-o", "stat=", "-p", String(pid)], { encoding: "utf8" });
5637
5639
  return result.status === 0 && result.stdout.trim().startsWith("Z");
5638
5640
  }
@@ -5640,14 +5642,17 @@ function realIsProcessRunning(pid) {
5640
5642
  return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
5641
5643
  }
5642
5644
  function realIsFrontDoorSupervisor(pid) {
5645
+ refuseToBlockInRole("a synchronous process-table read");
5643
5646
  const result = spawnSync("ps", ["-o", "pid=,command=", "-p", String(pid)], { encoding: "utf8" });
5644
5647
  return result.status === 0 && parseFrontDoorSupervisorPids(result.stdout).includes(pid);
5645
5648
  }
5646
5649
  function realProcessCommandLine(pid) {
5650
+ refuseToBlockInRole("a synchronous process-table read");
5647
5651
  const result = spawnSync("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8", timeout: PS_TIMEOUT_MS });
5648
5652
  return result.status === 0 ? result.stdout.trim() : void 0;
5649
5653
  }
5650
5654
  function realFrontDoorLiveness(pids) {
5655
+ refuseToBlockInRole("a synchronous process-table read");
5651
5656
  return frontDoorLivenessOf(pids, (asked) => {
5652
5657
  const result = spawnSync("ps", ["-o", "pid=,stat=,command=", "-p", asked.map(String).join(",")], { encoding: "utf8", timeout: PS_TIMEOUT_MS });
5653
5658
  return { status: result.status, stdout: result.stdout, stderr: result.stderr, ...result.error === void 0 ? {} : { error: result.error } };
@@ -21111,6 +21111,10 @@ interface FrontDoorSupervisorPorts {
21111
21111
  readonly sleep: (ms: number) => Promise<void>;
21112
21112
  /** Zombie-aware liveness, the notion every coordination decision in this project uses. */
21113
21113
  readonly isRunning: (pid: number) => boolean;
21114
+ /**
21115
+ * Which of `pids` are running, by the same zombie-aware notion as `isRunning` but answered without blocking the event loop. Everything the supervisor asks while it serves goes through this: it asks about every registered session once a tick, and a synchronous process-table read per session would hold the loop that answers every session for as long as the machine took to run them.
21116
+ */
21117
+ readonly runningAmong: (pids: readonly number[]) => Promise<ReadonlySet<number>>;
21114
21118
  /**
21115
21119
  * Starts the provider listener in this process on `preferredPort` (falling back to any free port when the sticky one is taken, decided at bind time rather than by a racy check-then-bind probe) and resolves once it has bound and answered its own health probe over TLS. This is the HTTPS listener every provider session's base URL points at, serving a loopback leaf signed by agent-shim's CA.
21116
21120
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-use",
3
- "version": "11.54.0",
3
+ "version": "11.54.1",
4
4
  "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.",
5
5
  "license": "MIT",
6
6
  "author": "Joseph Mearman <joseph@mearman.co.uk>",