claude-use 9.4.2 → 9.5.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/README.md CHANGED
@@ -133,6 +133,7 @@ agent-shim codex status [--json]
133
133
  agent-shim codex login [--no-open] [--json] # Sign in with ChatGPT, for providers with `codex.login: chatgpt-sign-in`
134
134
  agent-shim codex logout [--json]
135
135
  agent-shim frontdoor status [--json]
136
+ agent-shim frontdoor restart [--json] # replace the serving door in place; running sessions reach it on their next request
136
137
  agent-shim frontdoor rc list [--json]
137
138
  agent-shim frontdoor rc status [<cse_id>] [--json]
138
139
  agent-shim frontdoor rc pending [<cse_id>] [--json]
@@ -155,7 +156,7 @@ agent-shim frontdoor rc watch [<cse_id>] [--json]
155
156
  agent-shim frontdoor rc selfhost mint <identity> [--force] [--json]
156
157
  agent-shim usage [--identity <name>] [--provider <name>] [--since <duration>] [--refresh] [--json]
157
158
  agent-shim account show [<identity>] [--refresh] [--json]
158
- agent-shim update [--check] [--mode <off|notify|auto>] [--json]
159
+ agent-shim update [--check] [--restart-door] [--mode <off|notify|auto>] [--json]
159
160
  agent-shim completion <bash|zsh|fish>
160
161
  agent-shim shim enable [--dir <path>] [--force]
161
162
  agent-shim shim disable [--dir <path>] [--force]
package/dist/cli.cjs CHANGED
@@ -33224,7 +33224,7 @@ var init_package = __esm({
33224
33224
  "package.json"() {
33225
33225
  package_default = {
33226
33226
  name: "claude-use",
33227
- version: "9.4.2",
33227
+ version: "9.5.0",
33228
33228
  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.",
33229
33229
  license: "MIT",
33230
33230
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -61133,11 +61133,11 @@ function ensureFrontDoor(params) {
61133
61133
  if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
61134
61134
  if (state?.port !== void 0 && state.connectPort !== void 0) {
61135
61135
  const verdict = ports.verifyListener(state.port);
61136
- if (verdict.ok && (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL && !replaced) {
61136
+ if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
61137
61137
  ports.stopSupervisor(supervisorPid);
61138
61138
  while (ports.isRunning(supervisorPid)) {
61139
61139
  if (ports.now() >= deadline) {
61140
- throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}) is older than this launcher (protocol ${String(FRONT_DOOR_PROTOCOL)}) and did not exit when asked. Daemon log: ${paths.frontdoorLogPath}`);
61140
+ throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit. Daemon log: ${paths.frontdoorLogPath}`);
61141
61141
  }
61142
61142
  ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
61143
61143
  }
@@ -61183,6 +61183,23 @@ function ensureFrontDoor(params) {
61183
61183
  ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
61184
61184
  }
61185
61185
  }
61186
+ function restartFrontDoor(params) {
61187
+ const { paths, ports } = params;
61188
+ const previousPid = readFrontDoorState(ports.fs, paths.frontdoorStateFile)?.supervisorPid;
61189
+ if (previousPid === void 0 || !ports.isRunning(previousPid)) {
61190
+ return { action: "not-running" };
61191
+ }
61192
+ try {
61193
+ ensureFrontDoor({ paths, launcherPid: params.pid, replace: true, ports });
61194
+ } finally {
61195
+ removeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, params.pid);
61196
+ }
61197
+ const pid = readFrontDoorState(ports.fs, paths.frontdoorStateFile)?.supervisorPid;
61198
+ if (pid === void 0) {
61199
+ throw new FrontDoorStartError(`the front door was replaced but its state records no supervisor. Daemon log: ${paths.frontdoorLogPath}`);
61200
+ }
61201
+ return { action: "restarted", previousPid, pid };
61202
+ }
61186
61203
  var import_node_crypto10, FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FrontDoorStartError;
61187
61204
  var init_ensure2 = __esm({
61188
61205
  "src/frontdoor/ensure.ts"() {
@@ -61311,25 +61328,27 @@ var init_trust = __esm({
61311
61328
  });
61312
61329
 
61313
61330
  // src/frontdoor/realFrontDoorPort.ts
61331
+ function realEnsurePorts(paths, spawnDaemon) {
61332
+ return {
61333
+ fs: realFarmFs,
61334
+ isRunning: realIsProcessRunning,
61335
+ now: () => Date.now(),
61336
+ sleep: realSleepSync,
61337
+ spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
61338
+ stopSupervisor: (pid) => {
61339
+ process.kill(pid, "SIGTERM");
61340
+ },
61341
+ // 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.
61342
+ verifyListener: (port) => probeFrontDoorSync(port, import_node_fs12.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
61343
+ };
61344
+ }
61345
+ function realRestartFrontDoor(paths, spawnDaemon) {
61346
+ return restartFrontDoor({ paths, pid: process.pid, ports: realEnsurePorts(paths, spawnDaemon) });
61347
+ }
61314
61348
  function realFrontDoorPort(paths, spawnDaemon) {
61315
61349
  return {
61316
61350
  ensure: (inheritedExtraCaCerts) => {
61317
- const up2 = ensureFrontDoor({
61318
- paths,
61319
- launcherPid: process.pid,
61320
- ports: {
61321
- fs: realFarmFs,
61322
- isRunning: realIsProcessRunning,
61323
- now: () => Date.now(),
61324
- sleep: realSleepSync,
61325
- spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
61326
- stopSupervisor: (pid) => {
61327
- process.kill(pid, "SIGTERM");
61328
- },
61329
- // 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.
61330
- verifyListener: (port) => probeFrontDoorSync(port, import_node_fs12.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
61331
- }
61332
- });
61351
+ const up2 = ensureFrontDoor({ paths, launcherPid: process.pid, ports: realEnsurePorts(paths, spawnDaemon) });
61333
61352
  const trust = resolveTrustBundle({ caCertFile: paths.frontdoorCaCertFile, bundlesDir: paths.frontdoorCaBundlesDir, variable: "NODE_EXTRA_CA_CERTS", inherited: inheritedExtraCaCerts, fs: realTrustBundleFs });
61334
61353
  return {
61335
61354
  port: up2.port,
@@ -61351,9 +61370,9 @@ var init_realFrontDoorPort = __esm({
61351
61370
  import_node_fs12 = __toESM(require("node:fs"), 1);
61352
61371
  init_realPorts();
61353
61372
  init_ensure2();
61373
+ init_state2();
61354
61374
  init_probe();
61355
61375
  init_trust();
61356
- init_state2();
61357
61376
  realTrustBundleFs = {
61358
61377
  readFileUtf8: (file2) => import_node_fs12.default.readFileSync(file2, "utf8"),
61359
61378
  exists: (file2) => import_node_fs12.default.existsSync(file2),
@@ -62163,7 +62182,7 @@ function runLaunchUpdateCheck(params) {
62163
62182
  return;
62164
62183
  }
62165
62184
  if (mode === "auto") {
62166
- port.spawnDetached(["update"]);
62185
+ port.spawnDetached(["update", "--restart-door"]);
62167
62186
  }
62168
62187
  if (!childStarted) {
62169
62188
  port.writeErr(updateNotifyLine(currentVersion, latest));
@@ -114785,6 +114804,9 @@ function attachingProviderCredential(route, deps) {
114785
114804
  };
114786
114805
  }
114787
114806
 
114807
+ // src/frontdoor/commands.ts
114808
+ init_realFrontDoorPort();
114809
+
114788
114810
  // src/frontdoor/rcCommands.ts
114789
114811
  var import_node_crypto19 = require("node:crypto");
114790
114812
  init_commandDeps();
@@ -117420,6 +117442,7 @@ function createRcStreamHub(deps) {
117420
117442
  };
117421
117443
  const runLoop = async (attachment) => {
117422
117444
  let retriedUnauthorized = false;
117445
+ let refusedAuthorization;
117423
117446
  for (; ; ) {
117424
117447
  if (attachment.isStopped()) {
117425
117448
  return;
@@ -117435,6 +117458,11 @@ function createRcStreamHub(deps) {
117435
117458
  }
117436
117459
  return;
117437
117460
  }
117461
+ if (refusedAuthorization !== void 0 && credential.authorization === refusedAuthorization) {
117462
+ await deps.sleep(deps.backoffMs);
117463
+ continue;
117464
+ }
117465
+ refusedAuthorization = void 0;
117438
117466
  let outcome;
117439
117467
  try {
117440
117468
  outcome = await attempt(attachment, credential);
@@ -117461,7 +117489,8 @@ function createRcStreamHub(deps) {
117461
117489
  retriedUnauthorized = true;
117462
117490
  continue;
117463
117491
  }
117464
- deps.log?.(`rc stream ${attachment.sessionId}: the client read stream refused the observed Authorization bearer past one retry; backing off`);
117492
+ deps.log?.(`rc stream ${attachment.sessionId}: the client read stream refused the observed Authorization bearer past one retry; waiting for a fresh one`);
117493
+ refusedAuthorization = credential.authorization;
117465
117494
  await deps.sleep(deps.backoffMs);
117466
117495
  retriedUnauthorized = false;
117467
117496
  }
@@ -117934,6 +117963,19 @@ function registerFrontDoorCommand(program2, deps) {
117934
117963
  }),
117935
117964
  ["agent-shim frontdoor status", "agent-shim frontdoor status --json"]
117936
117965
  );
117966
+ withExamples(
117967
+ frontdoor.command("restart").description(
117968
+ "Replace the serving front door with one started from the installed binary, in place: it binds the same ports, so running sessions reach it on their next request. A request in flight when the old door exits fails once. Does nothing when no door is serving."
117969
+ ).option("--json", "Print the result as JSON.").action((options) => {
117970
+ const result = realRestartFrontDoor(paths, spawnDetachedSupervisor);
117971
+ if (options.json === true) {
117972
+ printJson(result);
117973
+ return;
117974
+ }
117975
+ console.log(result.action === "not-running" ? "no front door is serving; nothing to restart" : `front door restarted: pid ${String(result.previousPid)} -> ${String(result.pid)}`);
117976
+ }),
117977
+ ["agent-shim frontdoor restart", "agent-shim frontdoor restart --json"]
117978
+ );
117937
117979
  registerRcCommand(frontdoor, paths);
117938
117980
  program2.command("__frontdoor-supervisor", { hidden: true }).description("Internal: serve the front-door routing listeners. Started by the launcher; never run by hand.").allowUnknownOption().action(async () => {
117939
117981
  const idleShutdownMinutes = readGlobalConfig(paths)?.frontdoor?.idleShutdownMinutes ?? FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES;
@@ -118972,6 +119014,7 @@ init_package();
118972
119014
  init_commandDeps();
118973
119015
  init_store();
118974
119016
  init_schema();
119017
+ init_realFrontDoorPort();
118975
119018
  init_realPorts();
118976
119019
  init_update();
118977
119020
  function isEnoent6(error62) {
@@ -119122,7 +119165,7 @@ function registerUpdateCommand(program2, deps, ports = realUpdatePorts) {
119122
119165
  withExamples(
119123
119166
  program2.command("update").description(
119124
119167
  "Download the newest release binary and install it over the running one. An installation that belongs to a package manager (Homebrew, npm, Scoop) names its channel and its upgrade command instead of updating in place. With --mode, set the launch-time update mode in the global config instead of updating now."
119125
- ).option("--check", "Only report whether a newer release exists; download and change nothing.").addOption(new Option("--mode <mode>", "Set what a launch does about a newer release (off: nothing; notify: print one line; auto: also apply it in the background) in the global config, then exit.").choices(UPDATE_MODES)).option("--json", "Print the result as JSON.").action(async (options) => {
119168
+ ).option("--check", "Only report whether a newer release exists; download and change nothing.").option("--restart-door", "After installing a newer release, replace the serving front door with one started from it, in place, instead of leaving the old one until its sessions end.").addOption(new Option("--mode <mode>", "Set what a launch does about a newer release (off: nothing; notify: print one line; auto: also apply it in the background) in the global config, then exit.").choices(UPDATE_MODES)).option("--json", "Print the result as JSON.").action(async (options) => {
119126
119169
  const mode = options.mode;
119127
119170
  if (mode !== void 0) {
119128
119171
  setUpdateMode(deps.paths, mode);
@@ -119140,11 +119183,15 @@ function registerUpdateCommand(program2, deps, ports = realUpdatePorts) {
119140
119183
  checkOnly: options.check === true,
119141
119184
  pid: process.pid
119142
119185
  });
119186
+ const doorRestart = options.restartDoor === true && report.action === "updated" ? realRestartFrontDoor(deps.paths, spawnDetachedSupervisor) : void 0;
119143
119187
  if (options.json === true) {
119144
- printJson(report);
119188
+ printJson(doorRestart === void 0 ? report : { ...report, frontdoor: doorRestart });
119145
119189
  return;
119146
119190
  }
119147
119191
  console.log(formatUpdateReport(report));
119192
+ if (doorRestart?.action === "restarted") {
119193
+ console.log(`front door restarted: pid ${String(doorRestart.previousPid)} -> ${String(doorRestart.pid)}`);
119194
+ }
119148
119195
  }),
119149
119196
  ["agent-shim update", "agent-shim update --check", "agent-shim update --mode auto", "agent-shim update --json"]
119150
119197
  );
package/dist/index.cjs CHANGED
@@ -2649,7 +2649,7 @@ var init_package = __esm({
2649
2649
  "package.json"() {
2650
2650
  package_default = {
2651
2651
  name: "claude-use",
2652
- version: "9.4.2",
2652
+ version: "9.5.0",
2653
2653
  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.",
2654
2654
  license: "MIT",
2655
2655
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -6078,11 +6078,11 @@ function ensureFrontDoor(params) {
6078
6078
  if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
6079
6079
  if (state?.port !== void 0 && state.connectPort !== void 0) {
6080
6080
  const verdict = ports.verifyListener(state.port);
6081
- if (verdict.ok && (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL && !replaced) {
6081
+ if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
6082
6082
  ports.stopSupervisor(supervisorPid);
6083
6083
  while (ports.isRunning(supervisorPid)) {
6084
6084
  if (ports.now() >= deadline) {
6085
- throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}) is older than this launcher (protocol ${String(FRONT_DOOR_PROTOCOL)}) and did not exit when asked. Daemon log: ${paths.frontdoorLogPath}`);
6085
+ throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit. Daemon log: ${paths.frontdoorLogPath}`);
6086
6086
  }
6087
6087
  ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
6088
6088
  }
@@ -6755,7 +6755,7 @@ function runLaunchUpdateCheck(params) {
6755
6755
  return;
6756
6756
  }
6757
6757
  if (mode === "auto") {
6758
- port.spawnDetached(["update"]);
6758
+ port.spawnDetached(["update", "--restart-door"]);
6759
6759
  }
6760
6760
  if (!childStarted) {
6761
6761
  port.writeErr(updateNotifyLine(currentVersion, latest));
@@ -7256,25 +7256,24 @@ var init_trust = __esm({
7256
7256
  });
7257
7257
 
7258
7258
  // src/frontdoor/realFrontDoorPort.ts
7259
+ function realEnsurePorts(paths, spawnDaemon) {
7260
+ return {
7261
+ fs: realFarmFs,
7262
+ isRunning: realIsProcessRunning,
7263
+ now: () => Date.now(),
7264
+ sleep: realSleepSync,
7265
+ spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
7266
+ stopSupervisor: (pid) => {
7267
+ process.kill(pid, "SIGTERM");
7268
+ },
7269
+ // 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.
7270
+ verifyListener: (port) => probeFrontDoorSync(port, import_node_fs10.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
7271
+ };
7272
+ }
7259
7273
  function realFrontDoorPort(paths, spawnDaemon) {
7260
7274
  return {
7261
7275
  ensure: (inheritedExtraCaCerts) => {
7262
- const up = ensureFrontDoor({
7263
- paths,
7264
- launcherPid: process.pid,
7265
- ports: {
7266
- fs: realFarmFs,
7267
- isRunning: realIsProcessRunning,
7268
- now: () => Date.now(),
7269
- sleep: realSleepSync,
7270
- spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
7271
- stopSupervisor: (pid) => {
7272
- process.kill(pid, "SIGTERM");
7273
- },
7274
- // 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.
7275
- verifyListener: (port) => probeFrontDoorSync(port, import_node_fs10.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
7276
- }
7277
- });
7276
+ const up = ensureFrontDoor({ paths, launcherPid: process.pid, ports: realEnsurePorts(paths, spawnDaemon) });
7278
7277
  const trust = resolveTrustBundle({ caCertFile: paths.frontdoorCaCertFile, bundlesDir: paths.frontdoorCaBundlesDir, variable: "NODE_EXTRA_CA_CERTS", inherited: inheritedExtraCaCerts, fs: realTrustBundleFs });
7279
7278
  return {
7280
7279
  port: up.port,
@@ -7296,9 +7295,9 @@ var init_realFrontDoorPort = __esm({
7296
7295
  import_node_fs10 = __toESM(require("node:fs"), 1);
7297
7296
  init_realPorts();
7298
7297
  init_ensure2();
7298
+ init_state();
7299
7299
  init_probe();
7300
7300
  init_trust();
7301
- init_state();
7302
7301
  realTrustBundleFs = {
7303
7302
  readFileUtf8: (file) => import_node_fs10.default.readFileSync(file, "utf8"),
7304
7303
  exists: (file) => import_node_fs10.default.existsSync(file),
@@ -13611,6 +13610,7 @@ function createRcStreamHub(deps) {
13611
13610
  };
13612
13611
  const runLoop = async (attachment) => {
13613
13612
  let retriedUnauthorized = false;
13613
+ let refusedAuthorization;
13614
13614
  for (; ; ) {
13615
13615
  if (attachment.isStopped()) {
13616
13616
  return;
@@ -13626,6 +13626,11 @@ function createRcStreamHub(deps) {
13626
13626
  }
13627
13627
  return;
13628
13628
  }
13629
+ if (refusedAuthorization !== void 0 && credential.authorization === refusedAuthorization) {
13630
+ await deps.sleep(deps.backoffMs);
13631
+ continue;
13632
+ }
13633
+ refusedAuthorization = void 0;
13629
13634
  let outcome;
13630
13635
  try {
13631
13636
  outcome = await attempt(attachment, credential);
@@ -13652,7 +13657,8 @@ function createRcStreamHub(deps) {
13652
13657
  retriedUnauthorized = true;
13653
13658
  continue;
13654
13659
  }
13655
- deps.log?.(`rc stream ${attachment.sessionId}: the client read stream refused the observed Authorization bearer past one retry; backing off`);
13660
+ deps.log?.(`rc stream ${attachment.sessionId}: the client read stream refused the observed Authorization bearer past one retry; waiting for a fresh one`);
13661
+ refusedAuthorization = credential.authorization;
13656
13662
  await deps.sleep(deps.backoffMs);
13657
13663
  retriedUnauthorized = false;
13658
13664
  }
package/dist/index.mjs CHANGED
@@ -2625,7 +2625,7 @@ var init_package = __esm({
2625
2625
  "package.json"() {
2626
2626
  package_default = {
2627
2627
  name: "claude-use",
2628
- version: "9.4.2",
2628
+ version: "9.5.0",
2629
2629
  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.",
2630
2630
  license: "MIT",
2631
2631
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -6052,11 +6052,11 @@ function ensureFrontDoor(params) {
6052
6052
  if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
6053
6053
  if (state?.port !== void 0 && state.connectPort !== void 0) {
6054
6054
  const verdict = ports.verifyListener(state.port);
6055
- if (verdict.ok && (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL && !replaced) {
6055
+ if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
6056
6056
  ports.stopSupervisor(supervisorPid);
6057
6057
  while (ports.isRunning(supervisorPid)) {
6058
6058
  if (ports.now() >= deadline) {
6059
- throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}) is older than this launcher (protocol ${String(FRONT_DOOR_PROTOCOL)}) and did not exit when asked. Daemon log: ${paths.frontdoorLogPath}`);
6059
+ throw new FrontDoorStartError(`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit. Daemon log: ${paths.frontdoorLogPath}`);
6060
6060
  }
6061
6061
  ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
6062
6062
  }
@@ -6728,7 +6728,7 @@ function runLaunchUpdateCheck(params) {
6728
6728
  return;
6729
6729
  }
6730
6730
  if (mode === "auto") {
6731
- port.spawnDetached(["update"]);
6731
+ port.spawnDetached(["update", "--restart-door"]);
6732
6732
  }
6733
6733
  if (!childStarted) {
6734
6734
  port.writeErr(updateNotifyLine(currentVersion, latest));
@@ -7229,25 +7229,24 @@ var init_trust = __esm({
7229
7229
 
7230
7230
  // src/frontdoor/realFrontDoorPort.ts
7231
7231
  import fs11 from "node:fs";
7232
+ function realEnsurePorts(paths, spawnDaemon) {
7233
+ return {
7234
+ fs: realFarmFs,
7235
+ isRunning: realIsProcessRunning,
7236
+ now: () => Date.now(),
7237
+ sleep: realSleepSync,
7238
+ spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
7239
+ stopSupervisor: (pid) => {
7240
+ process.kill(pid, "SIGTERM");
7241
+ },
7242
+ // 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.
7243
+ verifyListener: (port) => probeFrontDoorSync(port, fs11.readFileSync(paths.frontdoorCaCertFile, "utf8"))
7244
+ };
7245
+ }
7232
7246
  function realFrontDoorPort(paths, spawnDaemon) {
7233
7247
  return {
7234
7248
  ensure: (inheritedExtraCaCerts) => {
7235
- const up = ensureFrontDoor({
7236
- paths,
7237
- launcherPid: process.pid,
7238
- ports: {
7239
- fs: realFarmFs,
7240
- isRunning: realIsProcessRunning,
7241
- now: () => Date.now(),
7242
- sleep: realSleepSync,
7243
- spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
7244
- stopSupervisor: (pid) => {
7245
- process.kill(pid, "SIGTERM");
7246
- },
7247
- // 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.
7248
- verifyListener: (port) => probeFrontDoorSync(port, fs11.readFileSync(paths.frontdoorCaCertFile, "utf8"))
7249
- }
7250
- });
7249
+ const up = ensureFrontDoor({ paths, launcherPid: process.pid, ports: realEnsurePorts(paths, spawnDaemon) });
7251
7250
  const trust = resolveTrustBundle({ caCertFile: paths.frontdoorCaCertFile, bundlesDir: paths.frontdoorCaBundlesDir, variable: "NODE_EXTRA_CA_CERTS", inherited: inheritedExtraCaCerts, fs: realTrustBundleFs });
7252
7251
  return {
7253
7252
  port: up.port,
@@ -7268,9 +7267,9 @@ var init_realFrontDoorPort = __esm({
7268
7267
  "use strict";
7269
7268
  init_realPorts();
7270
7269
  init_ensure2();
7270
+ init_state();
7271
7271
  init_probe();
7272
7272
  init_trust();
7273
- init_state();
7274
7273
  realTrustBundleFs = {
7275
7274
  readFileUtf8: (file) => fs11.readFileSync(file, "utf8"),
7276
7275
  exists: (file) => fs11.existsSync(file),
@@ -13286,6 +13285,7 @@ function createRcStreamHub(deps) {
13286
13285
  };
13287
13286
  const runLoop = async (attachment) => {
13288
13287
  let retriedUnauthorized = false;
13288
+ let refusedAuthorization;
13289
13289
  for (; ; ) {
13290
13290
  if (attachment.isStopped()) {
13291
13291
  return;
@@ -13301,6 +13301,11 @@ function createRcStreamHub(deps) {
13301
13301
  }
13302
13302
  return;
13303
13303
  }
13304
+ if (refusedAuthorization !== void 0 && credential.authorization === refusedAuthorization) {
13305
+ await deps.sleep(deps.backoffMs);
13306
+ continue;
13307
+ }
13308
+ refusedAuthorization = void 0;
13304
13309
  let outcome;
13305
13310
  try {
13306
13311
  outcome = await attempt(attachment, credential);
@@ -13327,7 +13332,8 @@ function createRcStreamHub(deps) {
13327
13332
  retriedUnauthorized = true;
13328
13333
  continue;
13329
13334
  }
13330
- deps.log?.(`rc stream ${attachment.sessionId}: the client read stream refused the observed Authorization bearer past one retry; backing off`);
13335
+ deps.log?.(`rc stream ${attachment.sessionId}: the client read stream refused the observed Authorization bearer past one retry; waiting for a fresh one`);
13336
+ refusedAuthorization = credential.authorization;
13331
13337
  await deps.sleep(deps.backoffMs);
13332
13338
  retriedUnauthorized = false;
13333
13339
  }
@@ -5526,12 +5526,12 @@ declare function createControlApiRouter(deps: ControlApiDeps): {
5526
5526
  identity: "identity";
5527
5527
  provider: "provider";
5528
5528
  pool: "pool";
5529
+ keychain: "keychain";
5529
5530
  "ambient-credential": "ambient-credential";
5530
5531
  "binary-discovery": "binary-discovery";
5531
5532
  "claude-shim": "claude-shim";
5532
5533
  "path-resolution": "path-resolution";
5533
5534
  "legacy-name": "legacy-name";
5534
- keychain: "keychain";
5535
5535
  "directory-rules": "directory-rules";
5536
5536
  "categories-local": "categories-local";
5537
5537
  "active-identity": "active-identity";
@@ -6134,12 +6134,12 @@ declare function createDoorApiRouter(deps: DoorApiDeps): {
6134
6134
  identity: "identity";
6135
6135
  provider: "provider";
6136
6136
  pool: "pool";
6137
+ keychain: "keychain";
6137
6138
  "ambient-credential": "ambient-credential";
6138
6139
  "binary-discovery": "binary-discovery";
6139
6140
  "claude-shim": "claude-shim";
6140
6141
  "path-resolution": "path-resolution";
6141
6142
  "legacy-name": "legacy-name";
6142
- keychain: "keychain";
6143
6143
  "directory-rules": "directory-rules";
6144
6144
  "categories-local": "categories-local";
6145
6145
  "active-identity": "active-identity";
@@ -6674,12 +6674,12 @@ declare const DoctorFindingSchema: z.ZodObject<{
6674
6674
  identity: "identity";
6675
6675
  provider: "provider";
6676
6676
  pool: "pool";
6677
+ keychain: "keychain";
6677
6678
  "ambient-credential": "ambient-credential";
6678
6679
  "binary-discovery": "binary-discovery";
6679
6680
  "claude-shim": "claude-shim";
6680
6681
  "path-resolution": "path-resolution";
6681
6682
  "legacy-name": "legacy-name";
6682
- keychain: "keychain";
6683
6683
  "directory-rules": "directory-rules";
6684
6684
  "categories-local": "categories-local";
6685
6685
  "active-identity": "active-identity";
@@ -6703,12 +6703,12 @@ declare const DoctorRunOutputSchema: z.ZodObject<{
6703
6703
  identity: "identity";
6704
6704
  provider: "provider";
6705
6705
  pool: "pool";
6706
+ keychain: "keychain";
6706
6707
  "ambient-credential": "ambient-credential";
6707
6708
  "binary-discovery": "binary-discovery";
6708
6709
  "claude-shim": "claude-shim";
6709
6710
  "path-resolution": "path-resolution";
6710
6711
  "legacy-name": "legacy-name";
6711
- keychain: "keychain";
6712
6712
  "directory-rules": "directory-rules";
6713
6713
  "categories-local": "categories-local";
6714
6714
  "active-identity": "active-identity";
@@ -7017,6 +7017,8 @@ declare function ensureFrontDoor(params: {
7017
7017
  readonly paths: LayoutPaths;
7018
7018
  readonly launcherPid: number;
7019
7019
  readonly ports: EnsureFrontDoorPorts;
7020
+ /** Replaces a serving door whatever its protocol, once: the restart a binary update asks for, so the new generation serves the sessions already running without waiting for the registry to empty. */
7021
+ readonly replace?: boolean;
7020
7022
  }): {
7021
7023
  readonly port: number;
7022
7024
  readonly connectPort: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-use",
3
- "version": "9.4.2",
3
+ "version": "9.5.0",
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>",