claude-use 4.1.0 → 4.2.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.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/dist/cli.cjs +1065 -882
  3. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -40,7 +40,7 @@ var require_resolve_from = __commonJS({
40
40
  "use strict";
41
41
  var path28 = require("path");
42
42
  var Module = require("module");
43
- var fs13 = require("fs");
43
+ var fs14 = require("fs");
44
44
  var resolveFrom = (fromDir, moduleId, silent) => {
45
45
  if (typeof fromDir !== "string") {
46
46
  throw new TypeError(`Expected \`fromDir\` to be of type \`string\`, got \`${typeof fromDir}\``);
@@ -49,7 +49,7 @@ var require_resolve_from = __commonJS({
49
49
  throw new TypeError(`Expected \`moduleId\` to be of type \`string\`, got \`${typeof moduleId}\``);
50
50
  }
51
51
  try {
52
- fromDir = fs13.realpathSync(fromDir);
52
+ fromDir = fs14.realpathSync(fromDir);
53
53
  } catch (err) {
54
54
  if (err.code === "ENOENT") {
55
55
  fromDir = path28.resolve(fromDir);
@@ -7676,10 +7676,10 @@ var require_typescript = __commonJS({
7676
7676
  function and(f, g) {
7677
7677
  return (arg) => f(arg) && g(arg);
7678
7678
  }
7679
- function or(...fs13) {
7679
+ function or(...fs14) {
7680
7680
  return (...args) => {
7681
7681
  let lastResult;
7682
- for (const f of fs13) {
7682
+ for (const f of fs14) {
7683
7683
  lastResult = f(...args);
7684
7684
  if (lastResult) {
7685
7685
  return lastResult;
@@ -9254,7 +9254,7 @@ ${lanes.join("\n")}
9254
9254
  var tracing;
9255
9255
  var tracingEnabled;
9256
9256
  ((tracingEnabled2) => {
9257
- let fs13;
9257
+ let fs14;
9258
9258
  let traceCount = 0;
9259
9259
  let traceFd = 0;
9260
9260
  let mode;
@@ -9263,9 +9263,9 @@ ${lanes.join("\n")}
9263
9263
  const legend = [];
9264
9264
  function startTracing2(tracingMode, traceDir, configFilePath) {
9265
9265
  Debug.assert(!tracing, "Tracing already started");
9266
- if (fs13 === void 0) {
9266
+ if (fs14 === void 0) {
9267
9267
  try {
9268
- fs13 = require("fs");
9268
+ fs14 = require("fs");
9269
9269
  } catch (e) {
9270
9270
  throw new Error(`tracing requires having fs
9271
9271
  (original error: ${e.message || e})`);
@@ -9276,8 +9276,8 @@ ${lanes.join("\n")}
9276
9276
  if (legendPath === void 0) {
9277
9277
  legendPath = combinePaths(traceDir, "legend.json");
9278
9278
  }
9279
- if (!fs13.existsSync(traceDir)) {
9280
- fs13.mkdirSync(traceDir, { recursive: true });
9279
+ if (!fs14.existsSync(traceDir)) {
9280
+ fs14.mkdirSync(traceDir, { recursive: true });
9281
9281
  }
9282
9282
  const countPart = mode === "build" ? `.${process.pid}-${++traceCount}` : mode === "server" ? `.${process.pid}` : ``;
9283
9283
  const tracePath = combinePaths(traceDir, `trace${countPart}.json`);
@@ -9287,10 +9287,10 @@ ${lanes.join("\n")}
9287
9287
  tracePath,
9288
9288
  typesPath
9289
9289
  });
9290
- traceFd = fs13.openSync(tracePath, "w");
9290
+ traceFd = fs14.openSync(tracePath, "w");
9291
9291
  tracing = tracingEnabled2;
9292
9292
  const meta3 = { cat: "__metadata", ph: "M", ts: 1e3 * timestamp(), pid: 1, tid: 1 };
9293
- fs13.writeSync(
9293
+ fs14.writeSync(
9294
9294
  traceFd,
9295
9295
  "[\n" + [{ name: "process_name", args: { name: "tsc" }, ...meta3 }, { name: "thread_name", args: { name: "Main" }, ...meta3 }, { name: "TracingStartedInBrowser", ...meta3, cat: "disabled-by-default-devtools.timeline" }].map((v) => JSON.stringify(v)).join(",\n")
9296
9296
  );
@@ -9299,10 +9299,10 @@ ${lanes.join("\n")}
9299
9299
  function stopTracing() {
9300
9300
  Debug.assert(tracing, "Tracing is not in progress");
9301
9301
  Debug.assert(!!typeCatalog.length === (mode !== "server"));
9302
- fs13.writeSync(traceFd, `
9302
+ fs14.writeSync(traceFd, `
9303
9303
  ]
9304
9304
  `);
9305
- fs13.closeSync(traceFd);
9305
+ fs14.closeSync(traceFd);
9306
9306
  tracing = void 0;
9307
9307
  if (typeCatalog.length) {
9308
9308
  dumpTypes(typeCatalog);
@@ -9374,11 +9374,11 @@ ${lanes.join("\n")}
9374
9374
  function writeEvent(eventType, phase, name, args, extras, time3 = 1e3 * timestamp()) {
9375
9375
  if (mode === "server" && phase === "checkTypes") return;
9376
9376
  mark("beginTracing");
9377
- fs13.writeSync(traceFd, `,
9377
+ fs14.writeSync(traceFd, `,
9378
9378
  {"pid":1,"tid":1,"ph":"${eventType}","cat":"${phase}","ts":${time3},"name":"${name}"`);
9379
- if (extras) fs13.writeSync(traceFd, `,${extras}`);
9380
- if (args) fs13.writeSync(traceFd, `,"args":${JSON.stringify(args)}`);
9381
- fs13.writeSync(traceFd, `}`);
9379
+ if (extras) fs14.writeSync(traceFd, `,${extras}`);
9380
+ if (args) fs14.writeSync(traceFd, `,"args":${JSON.stringify(args)}`);
9381
+ fs14.writeSync(traceFd, `}`);
9382
9382
  mark("endTracing");
9383
9383
  measure("Tracing", "beginTracing", "endTracing");
9384
9384
  }
@@ -9400,9 +9400,9 @@ ${lanes.join("\n")}
9400
9400
  var _a3, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
9401
9401
  mark("beginDumpTypes");
9402
9402
  const typesPath = legend[legend.length - 1].typesPath;
9403
- const typesFd = fs13.openSync(typesPath, "w");
9403
+ const typesFd = fs14.openSync(typesPath, "w");
9404
9404
  const recursionIdentityMap = /* @__PURE__ */ new Map();
9405
- fs13.writeSync(typesFd, "[");
9405
+ fs14.writeSync(typesFd, "[");
9406
9406
  const numTypes = types.length;
9407
9407
  for (let i2 = 0; i2 < numTypes; i2++) {
9408
9408
  const type = types[i2];
@@ -9498,13 +9498,13 @@ ${lanes.join("\n")}
9498
9498
  flags: Debug.formatTypeFlags(type.flags).split("|"),
9499
9499
  display
9500
9500
  };
9501
- fs13.writeSync(typesFd, JSON.stringify(descriptor));
9501
+ fs14.writeSync(typesFd, JSON.stringify(descriptor));
9502
9502
  if (i2 < numTypes - 1) {
9503
- fs13.writeSync(typesFd, ",\n");
9503
+ fs14.writeSync(typesFd, ",\n");
9504
9504
  }
9505
9505
  }
9506
- fs13.writeSync(typesFd, "]\n");
9507
- fs13.closeSync(typesFd);
9506
+ fs14.writeSync(typesFd, "]\n");
9507
+ fs14.closeSync(typesFd);
9508
9508
  mark("endDumpTypes");
9509
9509
  measure("Dump types", "beginDumpTypes", "endDumpTypes");
9510
9510
  }
@@ -9512,7 +9512,7 @@ ${lanes.join("\n")}
9512
9512
  if (!legendPath) {
9513
9513
  return;
9514
9514
  }
9515
- fs13.writeFileSync(legendPath, JSON.stringify(legend));
9515
+ fs14.writeFileSync(legendPath, JSON.stringify(legend));
9516
9516
  }
9517
9517
  tracingEnabled2.dumpLegend = dumpLegend;
9518
9518
  })(tracingEnabled || (tracingEnabled = {}));
@@ -219444,7 +219444,7 @@ var require_util2 = __commonJS({
219444
219444
  var { kDestroyed, kBodyUsed, kListeners, kBody } = require_symbols();
219445
219445
  var { IncomingMessage } = require("node:http");
219446
219446
  var stream = require("node:stream");
219447
- var net5 = require("node:net");
219447
+ var net4 = require("node:net");
219448
219448
  var { stringify } = require("node:querystring");
219449
219449
  var { EventEmitter: EE } = require("node:events");
219450
219450
  var timers = require_timers();
@@ -219593,7 +219593,7 @@ var require_util2 = __commonJS({
219593
219593
  }
219594
219594
  assert2(typeof host === "string");
219595
219595
  const servername = getHostname(host);
219596
- if (net5.isIP(servername)) {
219596
+ if (net4.isIP(servername)) {
219597
219597
  return "";
219598
219598
  }
219599
219599
  return servername;
@@ -221256,7 +221256,7 @@ var require_dispatcher_base = __commonJS({
221256
221256
  var require_connect = __commonJS({
221257
221257
  "node_modules/.pnpm/undici@7.29.1/node_modules/undici/lib/core/connect.js"(exports2, module2) {
221258
221258
  "use strict";
221259
- var net5 = require("node:net");
221259
+ var net4 = require("node:net");
221260
221260
  var assert2 = require("node:assert");
221261
221261
  var util = require_util2();
221262
221262
  var { InvalidArgumentError: InvalidArgumentError2 } = require_errors();
@@ -221339,7 +221339,7 @@ var require_connect = __commonJS({
221339
221339
  } else {
221340
221340
  assert2(!httpSocket, "httpSocket can only be sent on TLS update");
221341
221341
  port = port || 80;
221342
- socket = net5.connect({
221342
+ socket = net4.connect({
221343
221343
  highWaterMark: 64 * 1024,
221344
221344
  // Same as nodejs fs streams.
221345
221345
  ...options,
@@ -227016,7 +227016,7 @@ var require_client = __commonJS({
227016
227016
  "node_modules/.pnpm/undici@7.29.1/node_modules/undici/lib/dispatcher/client.js"(exports2, module2) {
227017
227017
  "use strict";
227018
227018
  var assert2 = require("node:assert");
227019
- var net5 = require("node:net");
227019
+ var net4 = require("node:net");
227020
227020
  var http3 = require("node:http");
227021
227021
  var util = require_util2();
227022
227022
  var { ClientStats } = require_stats();
@@ -227171,7 +227171,7 @@ var require_client = __commonJS({
227171
227171
  if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) {
227172
227172
  throw new InvalidArgumentError2("maxRequestsPerClient must be a positive number");
227173
227173
  }
227174
- if (localAddress != null && (typeof localAddress !== "string" || net5.isIP(localAddress) === 0)) {
227174
+ if (localAddress != null && (typeof localAddress !== "string" || net4.isIP(localAddress) === 0)) {
227175
227175
  throw new InvalidArgumentError2("localAddress must be valid string IP address");
227176
227176
  }
227177
227177
  if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) {
@@ -227351,7 +227351,7 @@ var require_client = __commonJS({
227351
227351
  const idx = hostname3.indexOf("]");
227352
227352
  assert2(idx !== -1);
227353
227353
  const ip = hostname3.substring(1, idx);
227354
- assert2(net5.isIPv6(ip));
227354
+ assert2(net4.isIPv6(ip));
227355
227355
  hostname3 = ip;
227356
227356
  }
227357
227357
  client[kConnecting] = true;
@@ -228296,10 +228296,10 @@ var require_socks5_utils = __commonJS({
228296
228296
  "node_modules/.pnpm/undici@7.29.1/node_modules/undici/lib/core/socks5-utils.js"(exports2, module2) {
228297
228297
  "use strict";
228298
228298
  var { Buffer: Buffer2 } = require("node:buffer");
228299
- var net5 = require("node:net");
228299
+ var net4 = require("node:net");
228300
228300
  var { InvalidArgumentError: InvalidArgumentError2 } = require_errors();
228301
228301
  function parseAddress(address) {
228302
- if (net5.isIPv4(address)) {
228302
+ if (net4.isIPv4(address)) {
228303
228303
  const parts = address.split(".").map(Number);
228304
228304
  return {
228305
228305
  type: 1,
@@ -228307,7 +228307,7 @@ var require_socks5_utils = __commonJS({
228307
228307
  buffer: Buffer2.from(parts)
228308
228308
  };
228309
228309
  }
228310
- if (net5.isIPv6(address)) {
228310
+ if (net4.isIPv6(address)) {
228311
228311
  return {
228312
228312
  type: 4,
228313
228313
  // IPv6
@@ -228330,7 +228330,7 @@ var require_socks5_utils = __commonJS({
228330
228330
  if (address.includes(".")) {
228331
228331
  const lastColonIndex = address.lastIndexOf(":");
228332
228332
  const ipv4Part = address.slice(lastColonIndex + 1);
228333
- if (net5.isIPv4(ipv4Part)) {
228333
+ if (net4.isIPv4(ipv4Part)) {
228334
228334
  const octets = ipv4Part.split(".").map(Number);
228335
228335
  const high = (octets[0] << 8 | octets[1]).toString(16);
228336
228336
  const low = (octets[2] << 8 | octets[3]).toString(16);
@@ -285659,9 +285659,9 @@ var HeadroomGlobalConfigSchema = external_exports.strictObject({
285659
285659
  });
285660
285660
  var HEADROOM_DEFAULT_SOURCE = "headroom-ai[proxy] @ git+https://github.com/ExaDev/headroom@feat/per-session-savings";
285661
285661
  var HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES = 15;
285662
- var CODEX_DEFAULT_IDLE_SHUTDOWN_MINUTES = 15;
285663
- var CodexGlobalConfigSchema = external_exports.strictObject({
285664
- /** How long the daemon may sit with no registered sessions before it exits. Defaults to CODEX_DEFAULT_IDLE_SHUTDOWN_MINUTES. */
285662
+ var FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES = 15;
285663
+ var FrontDoorGlobalConfigSchema = external_exports.strictObject({
285664
+ /** How long the front door may sit with no registered sessions before it closes and exits. Defaults to FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES. */
285665
285665
  idleShutdownMinutes: external_exports.number().int().positive().optional()
285666
285666
  });
285667
285667
  var GlobalConfigSchema = external_exports.strictObject({
@@ -285672,7 +285672,7 @@ var GlobalConfigSchema = external_exports.strictObject({
285672
285672
  entries: EntriesSchema.optional(),
285673
285673
  launch: LaunchSchema.optional(),
285674
285674
  headroom: HeadroomGlobalConfigSchema.optional(),
285675
- codex: CodexGlobalConfigSchema.optional()
285675
+ frontdoor: FrontDoorGlobalConfigSchema.optional()
285676
285676
  });
285677
285677
  var IdentitySchema = external_exports.strictObject({
285678
285678
  $schema: external_exports.string().optional(),
@@ -285744,16 +285744,16 @@ function parseJson(raw, schema) {
285744
285744
  const parsed = schema.safeParse(JSON.parse(raw));
285745
285745
  return parsed.success ? parsed.data : void 0;
285746
285746
  }
285747
- function readHeadroomState(fs13, stateFile) {
285747
+ function readHeadroomState(fs14, stateFile) {
285748
285748
  try {
285749
- return parseJson(fs13.readFileUtf8(stateFile), HeadroomStateSchema);
285749
+ return parseJson(fs14.readFileUtf8(stateFile), HeadroomStateSchema);
285750
285750
  } catch {
285751
285751
  return void 0;
285752
285752
  }
285753
285753
  }
285754
- function writeHeadroomState(fs13, stateFile, state) {
285755
- fs13.mkdirp(import_node_path5.default.dirname(stateFile));
285756
- fs13.writeFileUtf8(stateFile, `${JSON.stringify(state, null, 2)}
285754
+ function writeHeadroomState(fs14, stateFile, state) {
285755
+ fs14.mkdirp(import_node_path5.default.dirname(stateFile));
285756
+ fs14.writeFileUtf8(stateFile, `${JSON.stringify(state, null, 2)}
285757
285757
  `);
285758
285758
  }
285759
285759
  function headroomAllowlist(providers) {
@@ -285763,7 +285763,7 @@ function headroomAllowlist(providers) {
285763
285763
  }
285764
285764
  return [...urls].sort();
285765
285765
  }
285766
- function headroomUpstreams(providers, codexOrigin) {
285766
+ function headroomUpstreams(providers, frontDoorOrigin2) {
285767
285767
  const upstreams = [];
285768
285768
  let hasCodex = false;
285769
285769
  for (const provider of providers) {
@@ -285773,22 +285773,22 @@ function headroomUpstreams(providers, codexOrigin) {
285773
285773
  upstreams.push({ baseUrl: provider.baseUrl });
285774
285774
  }
285775
285775
  }
285776
- if (hasCodex && codexOrigin !== void 0) {
285777
- upstreams.push({ baseUrl: codexOrigin });
285776
+ if (hasCodex && frontDoorOrigin2 !== void 0) {
285777
+ upstreams.push({ baseUrl: frontDoorOrigin2 });
285778
285778
  }
285779
285779
  return upstreams;
285780
285780
  }
285781
285781
  function hashAllowlist(allowlist) {
285782
285782
  return (0, import_node_crypto2.createHash)("sha256").update(allowlist.join("\n")).digest("hex");
285783
285783
  }
285784
- function readAllProviders(fs13, providersDir) {
285784
+ function readAllProviders(fs14, providersDir) {
285785
285785
  const result = [];
285786
- for (const name of fs13.readdir(providersDir)) {
285786
+ for (const name of fs14.readdir(providersDir)) {
285787
285787
  if (!name.endsWith(".json")) {
285788
285788
  continue;
285789
285789
  }
285790
285790
  try {
285791
- const parsed = parseJson(fs13.readFileUtf8(import_node_path5.default.join(providersDir, name)), ProviderSchema);
285791
+ const parsed = parseJson(fs14.readFileUtf8(import_node_path5.default.join(providersDir, name)), ProviderSchema);
285792
285792
  if (parsed !== void 0) {
285793
285793
  result.push({ name: name.slice(0, -".json".length), provider: parsed });
285794
285794
  }
@@ -285798,22 +285798,22 @@ function readAllProviders(fs13, providersDir) {
285798
285798
  }
285799
285799
  return result;
285800
285800
  }
285801
- function writeSession(fs13, sessionsDir, session) {
285802
- fs13.mkdirp(sessionsDir);
285803
- fs13.writeFileUtf8(import_node_path5.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
285801
+ function writeSession(fs14, sessionsDir, session) {
285802
+ fs14.mkdirp(sessionsDir);
285803
+ fs14.writeFileUtf8(import_node_path5.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
285804
285804
  `);
285805
285805
  }
285806
- function removeSession(fs13, sessionsDir, pid) {
285807
- fs13.removeRecursive(import_node_path5.default.join(sessionsDir, `${String(pid)}.json`));
285806
+ function removeSession(fs14, sessionsDir, pid) {
285807
+ fs14.removeRecursive(import_node_path5.default.join(sessionsDir, `${String(pid)}.json`));
285808
285808
  }
285809
- function listSessions(fs13, sessionsDir) {
285809
+ function listSessions(fs14, sessionsDir) {
285810
285810
  const sessions = [];
285811
- for (const name of fs13.readdir(sessionsDir)) {
285811
+ for (const name of fs14.readdir(sessionsDir)) {
285812
285812
  if (!name.endsWith(".json")) {
285813
285813
  continue;
285814
285814
  }
285815
285815
  try {
285816
- const parsed = parseJson(fs13.readFileUtf8(import_node_path5.default.join(sessionsDir, name)), HeadroomSessionSchema);
285816
+ const parsed = parseJson(fs14.readFileUtf8(import_node_path5.default.join(sessionsDir, name)), HeadroomSessionSchema);
285817
285817
  if (parsed !== void 0) {
285818
285818
  sessions.push(parsed);
285819
285819
  }
@@ -285823,19 +285823,19 @@ function listSessions(fs13, sessionsDir) {
285823
285823
  }
285824
285824
  return sessions.sort((a2, b) => a2.pid - b.pid);
285825
285825
  }
285826
- function pruneDeadSessions(fs13, sessionsDir, isRunning) {
285826
+ function pruneDeadSessions(fs14, sessionsDir, isRunning) {
285827
285827
  const removed = [];
285828
- for (const session of listSessions(fs13, sessionsDir)) {
285828
+ for (const session of listSessions(fs14, sessionsDir)) {
285829
285829
  if (!isRunning(session.pid)) {
285830
- removeSession(fs13, sessionsDir, session.pid);
285830
+ removeSession(fs14, sessionsDir, session.pid);
285831
285831
  removed.push(session.pid);
285832
285832
  }
285833
285833
  }
285834
285834
  return removed;
285835
285835
  }
285836
- function readStartLock(fs13, lockFile) {
285836
+ function readStartLock(fs14, lockFile) {
285837
285837
  try {
285838
- return parseJson(fs13.readFileUtf8(lockFile), HeadroomLockSchema);
285838
+ return parseJson(fs14.readFileUtf8(lockFile), HeadroomLockSchema);
285839
285839
  } catch {
285840
285840
  return void 0;
285841
285841
  }
@@ -289000,8 +289000,8 @@ var FarmManifestSchema = external_exports.strictObject({
289000
289000
  materialised: external_exports.array(external_exports.string()),
289001
289001
  links: external_exports.array(external_exports.strictObject({ rel: external_exports.string(), target: external_exports.string() }))
289002
289002
  });
289003
- function readFarmManifest(fs13, farmRoot) {
289004
- const raw = fs13.readFileUtf8(import_node_path11.default.join(farmRoot, FARM_MANIFEST_FILENAME));
289003
+ function readFarmManifest(fs14, farmRoot) {
289004
+ const raw = fs14.readFileUtf8(import_node_path11.default.join(farmRoot, FARM_MANIFEST_FILENAME));
289005
289005
  if (raw === void 0) {
289006
289006
  return void 0;
289007
289007
  }
@@ -289059,9 +289059,9 @@ function buildEntryFacts(params) {
289059
289059
  entries
289060
289060
  };
289061
289061
  }
289062
- function listSubtree(fs13, root, rel) {
289062
+ function listSubtree(fs14, root, rel) {
289063
289063
  const absolute = import_node_path11.default.join(root, rel);
289064
- const stat = fs13.lstat(absolute);
289064
+ const stat = fs14.lstat(absolute);
289065
289065
  if (stat === void 0) {
289066
289066
  return [];
289067
289067
  }
@@ -289069,10 +289069,10 @@ function listSubtree(fs13, root, rel) {
289069
289069
  return [{ rel, kind: "symlink" }];
289070
289070
  }
289071
289071
  if (stat.kind === "dir") {
289072
- const children = [...fs13.readdir(absolute)].sort().flatMap((name) => listSubtree(fs13, root, `${rel}/${name}`));
289072
+ const children = [...fs14.readdir(absolute)].sort().flatMap((name) => listSubtree(fs14, root, `${rel}/${name}`));
289073
289073
  return [{ rel, kind: "dir" }, ...children];
289074
289074
  }
289075
- const contentHash = fs13.hashFile(absolute);
289075
+ const contentHash = fs14.hashFile(absolute);
289076
289076
  return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
289077
289077
  }
289078
289078
  function topLevelScopeRoots(roots) {
@@ -289086,25 +289086,25 @@ function topLevelScopeRoots(roots) {
289086
289086
  }
289087
289087
  return kept;
289088
289088
  }
289089
- function reconciliationScope(fs13, farmRoot, manifest) {
289089
+ function reconciliationScope(fs14, farmRoot, manifest) {
289090
289090
  if (manifest !== void 0) {
289091
289091
  return topLevelScopeRoots(manifest.materialised);
289092
289092
  }
289093
- return [...fs13.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && fs13.lstat(import_node_path11.default.join(farmRoot, name))?.kind === "dir").sort();
289093
+ return [...fs14.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && fs14.lstat(import_node_path11.default.join(farmRoot, name))?.kind === "dir").sort();
289094
289094
  }
289095
- function collectFarmListing(fs13, farmRoot, scopeRoots) {
289096
- return scopeRoots.flatMap((root) => listSubtree(fs13, farmRoot, root));
289095
+ function collectFarmListing(fs14, farmRoot, scopeRoots) {
289096
+ return scopeRoots.flatMap((root) => listSubtree(fs14, farmRoot, root));
289097
289097
  }
289098
- function collectCanonicalCounterparts(fs13, claudeHome, farmListing) {
289098
+ function collectCanonicalCounterparts(fs14, claudeHome, farmListing) {
289099
289099
  const out = [];
289100
289100
  for (const entry of farmListing) {
289101
289101
  const absolute = import_node_path11.default.join(claudeHome, entry.rel);
289102
- const stat = fs13.lstat(absolute);
289102
+ const stat = fs14.lstat(absolute);
289103
289103
  if (stat === void 0) {
289104
289104
  continue;
289105
289105
  }
289106
289106
  if (stat.kind === "file") {
289107
- const contentHash = fs13.hashFile(absolute);
289107
+ const contentHash = fs14.hashFile(absolute);
289108
289108
  out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
289109
289109
  continue;
289110
289110
  }
@@ -290592,8 +290592,8 @@ function decideConfigProfile(params) {
290592
290592
  }
290593
290593
  return { source: "none" };
290594
290594
  }
290595
- function loadIdentity(identitiesDir, name, fs13) {
290596
- return loadConfigFile(import_node_path17.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs13.readConfigFile);
290595
+ function loadIdentity(identitiesDir, name, fs14) {
290596
+ return loadConfigFile(import_node_path17.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs14.readConfigFile);
290597
290597
  }
290598
290598
 
290599
290599
  // src/paths.ts
@@ -290633,11 +290633,11 @@ function buildLayoutPaths(root) {
290633
290633
  headroomSessionsDir: import_node_path18.default.join(root, "headroom", "sessions"),
290634
290634
  logsDir: import_node_path18.default.join(root, "logs"),
290635
290635
  headroomLogPath: import_node_path18.default.join(root, "logs", "headroom.log"),
290636
- codexDir: import_node_path18.default.join(root, "codex"),
290637
- codexStateFile: import_node_path18.default.join(root, "codex", "state.json"),
290638
- codexLockFile: import_node_path18.default.join(root, "codex", "start.lock"),
290639
- codexSessionsDir: import_node_path18.default.join(root, "codex", "sessions"),
290640
- codexLogPath: import_node_path18.default.join(root, "logs", "codex.log")
290636
+ frontdoorDir: import_node_path18.default.join(root, "frontdoor"),
290637
+ frontdoorStateFile: import_node_path18.default.join(root, "frontdoor", "state.json"),
290638
+ frontdoorLockFile: import_node_path18.default.join(root, "frontdoor", "start.lock"),
290639
+ frontdoorSessionsDir: import_node_path18.default.join(root, "frontdoor", "sessions"),
290640
+ frontdoorLogPath: import_node_path18.default.join(root, "logs", "frontdoor.log")
290641
290641
  };
290642
290642
  }
290643
290643
  function resolveLayoutPaths() {
@@ -291151,7 +291151,7 @@ function resolveLaunchIdentity(paths, cwd) {
291151
291151
  // package.json
291152
291152
  var package_default = {
291153
291153
  name: "claude-use",
291154
- version: "4.1.0",
291154
+ version: "4.2.0",
291155
291155
  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.",
291156
291156
  license: "Apache-2.0",
291157
291157
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -292300,29 +292300,27 @@ function registerCheckCommand(program2, deps) {
292300
292300
  // src/codex/commands.ts
292301
292301
  var import_node_crypto7 = require("node:crypto");
292302
292302
  var import_node_fs9 = __toESM(require("node:fs"), 1);
292303
- var import_node_net2 = __toESM(require("node:net"), 1);
292304
292303
  var import_node_os6 = __toESM(require("node:os"), 1);
292305
292304
  var import_node_path23 = __toESM(require("node:path"), 1);
292306
- var import_node_child_process3 = require("node:child_process");
292307
292305
 
292308
- // src/codex/state.ts
292306
+ // src/frontdoor/state.ts
292309
292307
  var import_node_path22 = __toESM(require("node:path"), 1);
292310
- var CodexStateSchema = external_exports.strictObject({
292311
- /** The supervisor process keeping the translation worker alive. */
292308
+ var FrontDoorStateSchema = external_exports.strictObject({
292309
+ /** The supervisor process serving the front door. Alive means the listener is up in that process. */
292312
292310
  supervisorPid: external_exports.number().int().positive().optional(),
292313
- /** The worker process serving the translation listener. Absent while the supervisor is between restarts. */
292314
- workerPid: external_exports.number().int().positive().optional(),
292315
- /** The loopback port the worker listens on. Absent until the worker has answered its health check, so "port is set" is the ready signal a launcher polls for. */
292311
+ /** The loopback port the front-door listener serves on. Absent until the listener has bound and answered its health probe, so "port is set" is itself the ready signal a launcher polls for. */
292316
292312
  port: external_exports.number().int().positive().optional(),
292317
- /** The sticky port preference: kept across crashes, restarts and idle shutdowns so every session, whose base URL was frozen at launch, keeps finding the daemon at the same address. */
292313
+ /**
292314
+ * The sticky port preference: kept across crashes, restarts and idle shutdowns so every session, whose base URL was frozen at launch, keeps finding the front door at the same address.
292315
+ */
292318
292316
  lastPort: external_exports.number().int().positive().optional(),
292319
- /** The last fatal error, kept across shutdowns so `codex status` can explain a daemon that is not running. */
292317
+ /** The last fatal error, kept across shutdowns so `frontdoor status` can explain a front door that is not running. */
292320
292318
  lastError: external_exports.string().optional()
292321
292319
  });
292322
- function readCodexState(fs13, stateFile) {
292320
+ function readFrontDoorState(fs14, stateFile) {
292323
292321
  let raw;
292324
292322
  try {
292325
- raw = fs13.readFileUtf8(stateFile);
292323
+ raw = fs14.readFileUtf8(stateFile);
292326
292324
  } catch {
292327
292325
  return void 0;
292328
292326
  }
@@ -292330,303 +292328,22 @@ function readCodexState(fs13, stateFile) {
292330
292328
  return void 0;
292331
292329
  }
292332
292330
  try {
292333
- const parsed = CodexStateSchema.safeParse(JSON.parse(raw));
292331
+ const parsed = FrontDoorStateSchema.safeParse(JSON.parse(raw));
292334
292332
  return parsed.success ? parsed.data : void 0;
292335
292333
  } catch {
292336
292334
  return void 0;
292337
292335
  }
292338
292336
  }
292339
- function writeCodexState(fs13, stateFile, state) {
292340
- fs13.mkdirp(import_node_path22.default.dirname(stateFile));
292341
- fs13.writeFileUtf8(stateFile, `${JSON.stringify(state, null, 2)}
292337
+ function writeFrontDoorState(fs14, stateFile, state) {
292338
+ fs14.mkdirp(import_node_path22.default.dirname(stateFile));
292339
+ fs14.writeFileUtf8(stateFile, `${JSON.stringify(state, null, 2)}
292342
292340
  `);
292343
292341
  }
292344
- function codexDaemonOrigin(state) {
292342
+ function frontDoorOrigin(state) {
292345
292343
  const port = state?.port ?? state?.lastPort;
292346
292344
  return port === void 0 ? void 0 : `http://127.0.0.1:${String(port)}`;
292347
292345
  }
292348
292346
 
292349
- // src/headroom/supervisor.ts
292350
- function resolveSupervisorConfig(configured) {
292351
- return {
292352
- source: configured.source ?? HEADROOM_DEFAULT_SOURCE,
292353
- idleShutdownMinutes: configured.idleShutdownMinutes ?? HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES
292354
- };
292355
- }
292356
- var HEADROOM_BACKOFF_BASE_MS = 500;
292357
- var HEADROOM_BACKOFF_CAP_MS = 3e4;
292358
- var HEADROOM_START_RETRY_BUDGET = 5;
292359
- var HEADROOM_READY_TIMEOUT_MS = 15e3;
292360
- var HEADROOM_POLL_MS = 1e3;
292361
- var MS_PER_MINUTE = 6e4;
292362
- var STOP_POLL_MS = 100;
292363
- var TERM_GRACE_MS = 1500;
292364
- var KILL_GRACE_MS = 1500;
292365
- function stopSupervisedProcess(pid, primitives) {
292366
- const send = (signal) => {
292367
- try {
292368
- primitives.signal(pid, signal);
292369
- } catch {
292370
- }
292371
- };
292372
- send("SIGTERM");
292373
- if (awaitExit(pid, primitives, TERM_GRACE_MS)) {
292374
- return "exited-on-term";
292375
- }
292376
- send("SIGKILL");
292377
- if (awaitExit(pid, primitives, KILL_GRACE_MS)) {
292378
- return "killed";
292379
- }
292380
- return "still-running";
292381
- }
292382
- function awaitExit(pid, primitives, budgetMs) {
292383
- const deadline = primitives.now() + budgetMs;
292384
- while (primitives.isRunning(pid)) {
292385
- if (primitives.now() >= deadline) {
292386
- return false;
292387
- }
292388
- primitives.waitMs(STOP_POLL_MS);
292389
- }
292390
- return true;
292391
- }
292392
- function backoffForAttempt(attempt) {
292393
- return Math.min(HEADROOM_BACKOFF_CAP_MS, HEADROOM_BACKOFF_BASE_MS * 2 ** (attempt - 1));
292394
- }
292395
- function versionSatisfies(version2, source) {
292396
- if (version2 === void 0) {
292397
- return false;
292398
- }
292399
- const specifier = /==|>=|<=|!=|>|<|~=/.exec(source);
292400
- if (specifier === null) {
292401
- return true;
292402
- }
292403
- const installed = parseVersion(version2);
292404
- const wanted = parseVersion(source.slice(specifier.index + specifier[0].length));
292405
- if (installed === void 0 || wanted === void 0) {
292406
- return true;
292407
- }
292408
- const cmp = compareVersions2(installed, wanted);
292409
- switch (specifier[0]) {
292410
- case "==":
292411
- return cmp === 0;
292412
- case "!=":
292413
- return cmp !== 0;
292414
- case ">=":
292415
- return cmp >= 0;
292416
- case "<=":
292417
- return cmp <= 0;
292418
- case ">":
292419
- return cmp > 0;
292420
- case "<":
292421
- return cmp < 0;
292422
- case "~=":
292423
- return compareVersions2(installed.slice(0, Math.max(0, wanted.length - 1)), wanted.slice(0, Math.max(0, wanted.length - 1))) === 0 && cmp >= 0;
292424
- default:
292425
- return true;
292426
- }
292427
- }
292428
- function parseVersion(input2) {
292429
- const match = /(\d+)(\.\d+)*/.exec(input2);
292430
- if (match === null) {
292431
- return void 0;
292432
- }
292433
- return match[0].split(".").map((part) => Number.parseInt(part, 10));
292434
- }
292435
- function compareVersions2(a2, b) {
292436
- for (let index = 0; index < Math.max(a2.length, b.length); index += 1) {
292437
- const left = a2[index] ?? 0;
292438
- const right = b[index] ?? 0;
292439
- if (left !== right) {
292440
- return left - right;
292441
- }
292442
- }
292443
- return 0;
292444
- }
292445
- var HEADROOM_SUPERVISOR_STILL_RUNNING = -1;
292446
- async function runSupervisor(config2, ports, options = {}) {
292447
- const { fs: fs13, paths } = ports;
292448
- const previousState = readHeadroomState(fs13, paths.headroomStateFile);
292449
- let installedSource = previousState?.installedSource;
292450
- let lastPort = previousState?.lastPort;
292451
- let lastMitmPort = previousState?.lastMitmPort;
292452
- let daemonPort;
292453
- const sticky = () => ({
292454
- ...lastPort === void 0 ? {} : { lastPort },
292455
- ...lastMitmPort === void 0 ? {} : { lastMitmPort }
292456
- });
292457
- let mitm;
292458
- const fail = (message) => {
292459
- writeHeadroomState(fs13, paths.headroomStateFile, {
292460
- lastError: message,
292461
- ...sticky()
292462
- });
292463
- fs13.removeRecursive(paths.headroomLockFile);
292464
- ports.log(`claude-use headroom supervisor: ${message}`);
292465
- return 1;
292466
- };
292467
- const ensureInstalled = () => {
292468
- const version3 = ports.headroomVersion();
292469
- const versionOk = version3 !== void 0 && versionSatisfies(version3, config2.source);
292470
- if (versionOk && (installedSource === void 0 || installedSource === config2.source)) {
292471
- installedSource = config2.source;
292472
- return true;
292473
- }
292474
- ports.log(`claude-use headroom supervisor: installing headroom from ${config2.source}`);
292475
- const result = ports.install(config2.source);
292476
- if (!result.ok) {
292477
- return false;
292478
- }
292479
- installedSource = config2.source;
292480
- return true;
292481
- };
292482
- if (!ensureInstalled()) {
292483
- return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
292484
- }
292485
- const version2 = ports.headroomVersion() ?? "unknown";
292486
- try {
292487
- mitm = await ports.startMitm(lastMitmPort, () => daemonPort);
292488
- } catch (error62) {
292489
- return fail(`could not start the MITM proxy: ${error62 instanceof Error ? error62.message : String(error62)}`);
292490
- }
292491
- lastMitmPort = mitm.port;
292492
- if (previousState?.lastMitmPort !== void 0 && mitm.port !== previousState.lastMitmPort) {
292493
- ports.log(
292494
- `claude-use headroom supervisor: sticky MITM port ${String(previousState.lastMitmPort)} was occupied; moving to ${String(mitm.port)} (OAuth sessions launched against the old port are stale until they relaunch)`
292495
- );
292496
- }
292497
- writeHeadroomState(fs13, paths.headroomStateFile, { supervisorPid: ports.ownPid, version: version2, installedSource, mitmPort: mitm.port, ...sticky() });
292498
- ports.log(`claude-use headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${allowlistOf(ports).join(", ")}]`);
292499
- const orphanPid = previousState?.headroomPid;
292500
- if (orphanPid !== void 0 && ports.isRunning(orphanPid)) {
292501
- ports.log(`claude-use headroom supervisor: stopping daemon pid ${String(orphanPid)} left behind by the previous supervisor`);
292502
- ports.stopProcess(orphanPid);
292503
- }
292504
- let headroomPid;
292505
- let runningHash;
292506
- let consecutiveFailures = 0;
292507
- let idleSince;
292508
- let ticks = 0;
292509
- for (; ; ) {
292510
- if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
292511
- return HEADROOM_SUPERVISOR_STILL_RUNNING;
292512
- }
292513
- ticks += 1;
292514
- const allowlist = allowlistOf(ports);
292515
- const allowlistHash = hashAllowlist(allowlist);
292516
- pruneDeadSessions(fs13, paths.headroomSessionsDir, ports.isRunning);
292517
- const crashed = headroomPid !== void 0 && !ports.isRunning(headroomPid);
292518
- if (headroomPid === void 0 || crashed) {
292519
- if (crashed) {
292520
- ports.log(`claude-use headroom supervisor: headroom pid ${String(headroomPid)} died`);
292521
- headroomPid = void 0;
292522
- daemonPort = void 0;
292523
- runningHash = void 0;
292524
- writeHeadroomState(fs13, paths.headroomStateFile, {
292525
- supervisorPid: ports.ownPid,
292526
- version: version2,
292527
- installedSource,
292528
- mitmPort: mitm.port,
292529
- ...sticky()
292530
- });
292531
- }
292532
- if (consecutiveFailures >= HEADROOM_START_RETRY_BUDGET) {
292533
- return fail(`headroom failed to become ready ${String(consecutiveFailures)} times in a row; giving up`);
292534
- }
292535
- if (installedSource !== config2.source && !ensureInstalled()) {
292536
- return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
292537
- }
292538
- const previousSticky = lastPort;
292539
- const port = lastPort !== void 0 && await ports.isPortFree(lastPort) ? lastPort : await ports.freePort();
292540
- const pid = ports.spawnHeadroom(port, allowlist);
292541
- const ready = await waitUntilReady(ports, port);
292542
- if (ready) {
292543
- consecutiveFailures = 0;
292544
- headroomPid = pid;
292545
- daemonPort = port;
292546
- runningHash = allowlistHash;
292547
- lastPort = port;
292548
- if (previousSticky !== void 0 && port !== previousSticky) {
292549
- ports.log(
292550
- `claude-use headroom supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(port)} (sessions launched against the old port are stale until they relaunch)`
292551
- );
292552
- }
292553
- writeHeadroomState(fs13, paths.headroomStateFile, {
292554
- supervisorPid: ports.ownPid,
292555
- headroomPid: pid,
292556
- port,
292557
- mitmPort: mitm.port,
292558
- version: version2,
292559
- allowlistHash,
292560
- installedSource: config2.source,
292561
- ...sticky()
292562
- });
292563
- fs13.removeRecursive(paths.headroomLockFile);
292564
- idleSince = void 0;
292565
- ports.log(`claude-use headroom supervisor: headroom pid ${String(pid)} ready on 127.0.0.1:${String(port)}`);
292566
- } else {
292567
- ports.stopProcess(pid);
292568
- consecutiveFailures += 1;
292569
- ports.log(
292570
- `claude-use headroom supervisor: headroom did not become ready on port ${String(port)} (attempt ${String(consecutiveFailures)} of ${String(HEADROOM_START_RETRY_BUDGET)})`
292571
- );
292572
- await ports.sleep(backoffForAttempt(consecutiveFailures));
292573
- continue;
292574
- }
292575
- } else {
292576
- if (runningHash !== allowlistHash || installedSource !== config2.source) {
292577
- if (listSessions(fs13, paths.headroomSessionsDir).length === 0) {
292578
- ports.log("claude-use headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
292579
- ports.stopProcess(headroomPid);
292580
- headroomPid = void 0;
292581
- daemonPort = void 0;
292582
- runningHash = void 0;
292583
- continue;
292584
- }
292585
- }
292586
- const sessions = listSessions(fs13, paths.headroomSessionsDir);
292587
- if (sessions.length === 0) {
292588
- idleSince ??= ports.now();
292589
- const idleMs = ports.now() - idleSince;
292590
- if (idleMs >= config2.idleShutdownMinutes * MS_PER_MINUTE) {
292591
- ports.log(
292592
- `claude-use headroom supervisor: no sessions for ${String(config2.idleShutdownMinutes)} minute(s); stopping headroom and the MITM proxy, and exiting`
292593
- );
292594
- ports.stopProcess(headroomPid);
292595
- daemonPort = void 0;
292596
- await mitm.close();
292597
- writeHeadroomState(fs13, paths.headroomStateFile, {
292598
- version: version2,
292599
- ...sticky()
292600
- });
292601
- return 0;
292602
- }
292603
- } else {
292604
- idleSince = void 0;
292605
- }
292606
- }
292607
- await ports.sleep(HEADROOM_POLL_MS);
292608
- }
292609
- }
292610
- function currentHeadroomAllowlist(fs13, paths) {
292611
- const providers = readAllProviders(fs13, paths.providersDir).map((entry) => entry.provider);
292612
- return headroomAllowlist(headroomUpstreams(providers, codexDaemonOrigin(readCodexState(fs13, paths.codexStateFile))));
292613
- }
292614
- function allowlistOf(ports) {
292615
- return currentHeadroomAllowlist(ports.fs, ports.paths);
292616
- }
292617
- async function waitUntilReady(ports, port) {
292618
- const deadline = ports.now() + HEADROOM_READY_TIMEOUT_MS;
292619
- for (; ; ) {
292620
- if (await ports.ready(port)) {
292621
- return true;
292622
- }
292623
- if (ports.now() >= deadline) {
292624
- return false;
292625
- }
292626
- await ports.sleep(HEADROOM_POLL_MS);
292627
- }
292628
- }
292629
-
292630
292347
  // src/codex/agent.ts
292631
292348
  var import_undici = __toESM(require_undici(), 1);
292632
292349
  var CODEX_KEEP_ALIVE_CEILING_MS = 1e4;
@@ -292773,69 +292490,419 @@ function createCodexAuthStore(authPath, ports) {
292773
292490
  };
292774
292491
  }
292775
292492
 
292776
- // src/codex/ensure.ts
292777
- var CODEX_START_TIMEOUT_MS = 3e4;
292778
- var CODEX_LAUNCHER_POLL_MS = 100;
292779
- var CodexStartError = class extends CliError {
292493
+ // src/codex/upstream.ts
292494
+ var import_node_crypto6 = require("node:crypto");
292495
+
292496
+ // src/codex/http.ts
292497
+ var HTTP_STATUS = {
292498
+ ok: 200,
292499
+ badRequest: 400,
292500
+ unauthorized: 401,
292501
+ forbidden: 403,
292502
+ notFound: 404,
292503
+ methodNotAllowed: 405,
292504
+ payloadTooLarge: 413,
292505
+ tooManyRequests: 429,
292506
+ /** Not sent to anyone: the client is gone. Recorded for a response abandoned because the client disconnected, following the convention nginx uses for the same case. */
292507
+ clientClosedRequest: 499,
292508
+ internalServerError: 500,
292509
+ badGateway: 502
292510
+ };
292511
+
292512
+ // src/codex/upstream.ts
292513
+ var CODEX_RESPONSES_URL = "https://chatgpt.com/backend-api/codex/responses";
292514
+ var CODEX_UPSTREAM_TIMEOUT_MS = 3e5;
292515
+ var CODEX_HEADERS_TIMEOUT_MS = 15e3;
292516
+ var realTimers = {
292517
+ after: (ms, callback) => {
292518
+ const handle = setTimeout(callback, ms);
292519
+ return () => {
292520
+ clearTimeout(handle);
292521
+ };
292522
+ }
292523
+ };
292524
+ async function fetchUntilHeaders(fetch3, timers, url2, init) {
292525
+ for (let attempt = 1; ; attempt += 1) {
292526
+ init.signal.throwIfAborted();
292527
+ const deadline = new AbortController();
292528
+ const cancel2 = timers.after(CODEX_HEADERS_TIMEOUT_MS, () => {
292529
+ deadline.abort();
292530
+ });
292531
+ try {
292532
+ return await fetch3(url2, { ...init, signal: AbortSignal.any([init.signal, deadline.signal]) });
292533
+ } catch (error62) {
292534
+ if (deadline.signal.aborted && !init.signal.aborted && attempt === 1) {
292535
+ continue;
292536
+ }
292537
+ throw error62;
292538
+ } finally {
292539
+ cancel2();
292540
+ }
292541
+ }
292542
+ }
292543
+ var UUID_TEMPLATE = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
292544
+ function sessionIdFor(userId, randomId) {
292545
+ if (userId === void 0 || userId === "") {
292546
+ return randomId();
292547
+ }
292548
+ const hex3 = (0, import_node_crypto6.createHash)("sha256").update(`claude-use codex session
292549
+ ${userId}`).digest("hex");
292550
+ let next = 0;
292551
+ return UUID_TEMPLATE.replace(/x/g, () => hex3.charAt(next++));
292552
+ }
292553
+ function headersFor(credentials, sessionId) {
292554
+ return {
292555
+ "Content-Type": "application/json",
292556
+ Accept: "text/event-stream",
292557
+ Authorization: `Bearer ${credentials.accessToken}`,
292558
+ ...credentials.accountId === void 0 ? {} : { "chatgpt-account-id": credentials.accountId },
292559
+ "OpenAI-Beta": "responses=experimental",
292560
+ originator: "codex_cli_rs",
292561
+ session_id: sessionId
292562
+ };
292563
+ }
292564
+ async function callCodex(ports, request3, sessionId, signal) {
292565
+ const url2 = ports.url ?? CODEX_RESPONSES_URL;
292566
+ const body = JSON.stringify(request3);
292567
+ const send = async (credentials2) => await fetchUntilHeaders(ports.fetch, ports.timers, url2, {
292568
+ method: "POST",
292569
+ headers: headersFor(credentials2, sessionId),
292570
+ body,
292571
+ signal: AbortSignal.any([signal, AbortSignal.timeout(CODEX_UPSTREAM_TIMEOUT_MS)])
292572
+ });
292573
+ const credentials = await ports.auth.current();
292574
+ const first = await send(credentials);
292575
+ if (first.status !== HTTP_STATUS.unauthorized) {
292576
+ return first;
292577
+ }
292578
+ return await send(await ports.auth.refresh(credentials.accessToken));
292579
+ }
292580
+
292581
+ // src/codex/commands.ts
292582
+ function codexHome(env, home) {
292583
+ const fromEnv = env.CODEX_HOME;
292584
+ return fromEnv !== void 0 && fromEnv !== "" ? fromEnv : import_node_path23.default.join(home, ".codex");
292585
+ }
292586
+ function codexUsageSnapshotPath() {
292587
+ return import_node_path23.default.join(resolveClaudeHome(), "codex-quota.json");
292588
+ }
292589
+ function isEnoent4(error62) {
292590
+ return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === "ENOENT";
292591
+ }
292592
+ var PRIVATE_FILE_MODE = 384;
292593
+ var realCodexAuthFs = {
292594
+ read: (filePath) => {
292595
+ try {
292596
+ return import_node_fs9.default.readFileSync(filePath, "utf8");
292597
+ } catch (error62) {
292598
+ if (isEnoent4(error62)) {
292599
+ return void 0;
292600
+ }
292601
+ throw error62;
292602
+ }
292603
+ },
292604
+ writePrivate: (filePath, contents) => {
292605
+ import_node_fs9.default.writeFileSync(filePath, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
292606
+ import_node_fs9.default.chmodSync(filePath, PRIVATE_FILE_MODE);
292607
+ },
292608
+ rename: (from, to) => {
292609
+ import_node_fs9.default.renameSync(from, to);
292610
+ }
292611
+ };
292612
+ function writeUsageSnapshot(log, snapshot) {
292613
+ const target = codexUsageSnapshotPath();
292614
+ const temp = `${target}.${String(process.pid)}.tmp`;
292615
+ try {
292616
+ import_node_fs9.default.mkdirSync(import_node_path23.default.dirname(target), { recursive: true });
292617
+ import_node_fs9.default.writeFileSync(temp, `${JSON.stringify(snapshot, null, 2)}
292618
+ `);
292619
+ import_node_fs9.default.renameSync(temp, target);
292620
+ } catch (error62) {
292621
+ log(`usage snapshot write failed: ${error62 instanceof Error ? error62.message : String(error62)}`);
292622
+ }
292623
+ }
292624
+ function createCodexRoutePorts(log) {
292625
+ const agent = createUpstreamAgent();
292626
+ const upstreamFetch = createUpstreamFetch(agent);
292627
+ const auth = createCodexAuthStore(import_node_path23.default.join(codexHome(process.env, import_node_os6.default.homedir()), "auth.json"), {
292628
+ fs: realCodexAuthFs,
292629
+ fetch: upstreamFetch,
292630
+ now: () => /* @__PURE__ */ new Date(),
292631
+ tempSuffix: `${String(process.pid)}.${(0, import_node_crypto7.randomUUID)()}`
292632
+ });
292633
+ return {
292634
+ upstream: { fetch: upstreamFetch, auth, timers: realTimers, randomId: import_node_crypto7.randomUUID },
292635
+ writeUsageSnapshot: (snapshot) => {
292636
+ writeUsageSnapshot(log, snapshot);
292637
+ },
292638
+ now: () => Date.now(),
292639
+ log
292640
+ };
292641
+ }
292642
+ function codexProviderNames(fsPort, providersDir) {
292643
+ return readAllProviders(fsPort, providersDir).filter((entry) => isCodexProvider(entry.provider)).map((entry) => entry.name).sort();
292644
+ }
292645
+ function collectCodexStatus(fsPort, paths, isRunning) {
292646
+ const state = readFrontDoorState(fsPort, paths.frontdoorStateFile) ?? {};
292647
+ return {
292648
+ frontDoor: state,
292649
+ supervisorAlive: state.supervisorPid !== void 0 && isRunning(state.supervisorPid),
292650
+ sessions: listSessions(fsPort, paths.frontdoorSessionsDir).map((session) => ({ ...session, alive: isRunning(session.pid) })),
292651
+ codexProviders: codexProviderNames(fsPort, paths.providersDir),
292652
+ usageSnapshotPath: codexUsageSnapshotPath(),
292653
+ usageSnapshotExists: fsPort.readFileUtf8(codexUsageSnapshotPath()) !== void 0,
292654
+ logPath: paths.frontdoorLogPath,
292655
+ logExists: fsPort.readFileUtf8(paths.frontdoorLogPath) !== void 0
292656
+ };
292657
+ }
292658
+ function formatCodexStatus(status) {
292659
+ const lines = [];
292660
+ lines.push(
292661
+ status.frontDoor.supervisorPid === void 0 ? "front door: not running" : `front door: supervisor pid ${String(status.frontDoor.supervisorPid)} (${status.supervisorAlive ? "alive" : "NOT running"})`
292662
+ );
292663
+ if (status.frontDoor.port === void 0) {
292664
+ lines.push(`listener: not running${status.frontDoor.lastPort === void 0 ? "" : ` (next start on 127.0.0.1:${String(status.frontDoor.lastPort)})`}`);
292665
+ } else {
292666
+ lines.push(`listener: front door on 127.0.0.1:${String(status.frontDoor.port)}, serving codex providers under /providers/<name>`);
292667
+ }
292668
+ lines.push(status.codexProviders.length === 0 ? "codex providers: none defined" : `codex providers: ${status.codexProviders.join(", ")}`);
292669
+ if (status.sessions.length === 0) {
292670
+ lines.push("sessions: none");
292671
+ } else {
292672
+ const pids = status.sessions.map((session) => `${String(session.pid)}${session.alive ? "" : " (dead)"}`);
292673
+ lines.push(`sessions: ${String(status.sessions.length)} registered (${pids.join(", ")})`);
292674
+ }
292675
+ if (status.frontDoor.lastError !== void 0) {
292676
+ lines.push(`last error: ${status.frontDoor.lastError}`);
292677
+ }
292678
+ lines.push(`usage snapshot: ${status.usageSnapshotPath}${status.usageSnapshotExists ? "" : " (not created yet)"}`);
292679
+ lines.push(`daemon log: ${status.logPath}${status.logExists ? "" : " (not created yet)"}`);
292680
+ return lines;
292681
+ }
292682
+ function registerCodexCommand(program2, deps) {
292683
+ const { paths } = deps;
292684
+ const codex = withExamples(program2.command("codex").description("Inspect the codex translation the front-door daemon serves for codex providers."), ["claude-use codex status"]);
292685
+ withExamples(
292686
+ codex.command("status").description("Report the front door serving codex providers, its sessions, and the usage snapshot. Read-only.").option("--json", "Print the status as JSON.").action((options) => {
292687
+ const status = collectCodexStatus(realFarmFs, paths, realIsProcessRunning);
292688
+ if (options.json === true) {
292689
+ printJson(status);
292690
+ return;
292691
+ }
292692
+ for (const line of formatCodexStatus(status)) {
292693
+ console.log(line);
292694
+ }
292695
+ }),
292696
+ ["claude-use codex status", "claude-use codex status --json"]
292697
+ );
292698
+ }
292699
+
292700
+ // src/frontdoor/commands.ts
292701
+ var import_node_fs10 = __toESM(require("node:fs"), 1);
292702
+
292703
+ // src/frontdoor/ensure.ts
292704
+ var FRONTDOOR_START_TIMEOUT_MS = 3e4;
292705
+ var FRONTDOOR_LAUNCHER_POLL_MS = 100;
292706
+ var FrontDoorStartError = class extends CliError {
292780
292707
  constructor(message) {
292781
292708
  super(message);
292782
- this.name = "CodexStartError";
292709
+ this.name = "FrontDoorStartError";
292783
292710
  }
292784
292711
  };
292785
- function ensureCodex(params) {
292712
+ function ensureFrontDoor(params) {
292786
292713
  const { paths, ports } = params;
292787
- const deadline = ports.now() + CODEX_START_TIMEOUT_MS;
292714
+ const deadline = ports.now() + FRONTDOOR_START_TIMEOUT_MS;
292788
292715
  let spawned = false;
292789
292716
  for (; ; ) {
292790
- const state = readCodexState(ports.fs, paths.codexStateFile);
292717
+ const state = readFrontDoorState(ports.fs, paths.frontdoorStateFile);
292791
292718
  if (state?.supervisorPid !== void 0 && ports.isRunning(state.supervisorPid)) {
292792
- if (state.port !== void 0 && state.workerPid !== void 0 && ports.isRunning(state.workerPid)) {
292793
- writeSession(ports.fs, paths.codexSessionsDir, { pid: params.launcherPid, startedAt: ports.now() });
292719
+ if (state.port !== void 0) {
292720
+ writeSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now() });
292794
292721
  return { port: state.port };
292795
292722
  }
292796
292723
  if (state.lastError !== void 0) {
292797
- throw new CodexStartError(`claude-use: the codex daemon reported a fatal error and is not serving: ${state.lastError} (daemon log: ${paths.codexLogPath})`);
292724
+ throw new FrontDoorStartError(`claude-use: the front door reported a fatal error and is not serving: ${state.lastError} (daemon log: ${paths.frontdoorLogPath})`);
292798
292725
  }
292799
292726
  } else if (!spawned) {
292800
- ports.fs.mkdirp(paths.codexDir);
292801
- const created = ports.fs.writeFileExclusive(paths.codexLockFile, `${JSON.stringify({ pid: params.launcherPid, at: ports.now() })}
292727
+ ports.fs.mkdirp(paths.frontdoorDir);
292728
+ const created = ports.fs.writeFileExclusive(paths.frontdoorLockFile, `${JSON.stringify({ pid: params.launcherPid, at: ports.now() })}
292802
292729
  `);
292803
292730
  if (created) {
292804
292731
  ports.spawnSupervisor(paths);
292805
292732
  spawned = true;
292806
292733
  } else {
292807
- const lock = readStartLock(ports.fs, paths.codexLockFile);
292734
+ const lock = readStartLock(ports.fs, paths.frontdoorLockFile);
292808
292735
  if (lock === void 0 || !ports.isRunning(lock.pid)) {
292809
- ports.fs.removeRecursive(paths.codexLockFile);
292736
+ ports.fs.removeRecursive(paths.frontdoorLockFile);
292810
292737
  continue;
292811
292738
  }
292812
292739
  }
292813
292740
  }
292814
292741
  if (ports.now() >= deadline) {
292815
292742
  const lastError = state?.lastError;
292816
- throw new CodexStartError(
292817
- `claude-use: the codex daemon did not become ready within ${String(CODEX_START_TIMEOUT_MS)}ms` + (lastError === void 0 ? "" : ` (last error: ${lastError})`) + `. Daemon log: ${paths.codexLogPath}`
292743
+ throw new FrontDoorStartError(
292744
+ `claude-use: the front door did not become ready within ${String(FRONTDOOR_START_TIMEOUT_MS)}ms` + (lastError === void 0 ? "" : ` (last error: ${lastError})`) + `. Daemon log: ${paths.frontdoorLogPath}`
292818
292745
  );
292819
292746
  }
292820
- ports.sleep(CODEX_LAUNCHER_POLL_MS);
292747
+ ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
292821
292748
  }
292822
292749
  }
292823
292750
 
292824
- // src/codex/http.ts
292825
- var HTTP_STATUS = {
292826
- ok: 200,
292827
- badRequest: 400,
292828
- unauthorized: 401,
292829
- forbidden: 403,
292830
- notFound: 404,
292831
- methodNotAllowed: 405,
292832
- payloadTooLarge: 413,
292833
- tooManyRequests: 429,
292834
- /** Not sent to anyone: the client is gone. Recorded for a response abandoned because the client disconnected, following the convention nginx uses for the same case. */
292835
- clientClosedRequest: 499,
292836
- internalServerError: 500,
292837
- badGateway: 502
292838
- };
292751
+ // src/frontdoor/route.ts
292752
+ var INTERNAL_HEADER_NAMES = ["x-claude-use-identity", "x-claude-use-session", "x-claude-use-headroom"];
292753
+ var IDENTITY_HEADER = "x-claude-use-identity";
292754
+ var SESSION_HEADER = "x-claude-use-session";
292755
+ var HEADROOM_FLAG_HEADER = "x-claude-use-headroom";
292756
+ function singleHeaderValue(value) {
292757
+ if (typeof value === "string") {
292758
+ return value;
292759
+ }
292760
+ if (Array.isArray(value)) {
292761
+ return value.join(", ");
292762
+ }
292763
+ return void 0;
292764
+ }
292765
+ function internalHeaderValue(headers, name) {
292766
+ for (const [key, value] of Object.entries(headers)) {
292767
+ if (key.toLowerCase() === name) {
292768
+ return singleHeaderValue(value);
292769
+ }
292770
+ }
292771
+ return void 0;
292772
+ }
292773
+ function identifyRequest(headers) {
292774
+ const internal = new Set(INTERNAL_HEADER_NAMES);
292775
+ const forwardable = {};
292776
+ for (const [name, value] of Object.entries(headers)) {
292777
+ if (value !== void 0 && !internal.has(name.toLowerCase())) {
292778
+ forwardable[name] = value;
292779
+ }
292780
+ }
292781
+ return {
292782
+ session: {
292783
+ identity: internalHeaderValue(headers, IDENTITY_HEADER),
292784
+ sessionId: internalHeaderValue(headers, SESSION_HEADER),
292785
+ headroom: internalHeaderValue(headers, HEADROOM_FLAG_HEADER) === "1"
292786
+ },
292787
+ forwardableHeaders: forwardable
292788
+ };
292789
+ }
292790
+ var PROVIDER_PATH_PREFIX = "/providers/";
292791
+ function providerBaseUrl(port, provider) {
292792
+ return `http://127.0.0.1:${String(port)}${PROVIDER_PATH_PREFIX}${encodeURIComponent(provider)}`;
292793
+ }
292794
+ function parseProviderPath(path28) {
292795
+ if (!path28.startsWith(PROVIDER_PATH_PREFIX)) {
292796
+ return void 0;
292797
+ }
292798
+ const tail = path28.slice(PROVIDER_PATH_PREFIX.length);
292799
+ const slash = tail.indexOf("/");
292800
+ if (slash <= 0) {
292801
+ return void 0;
292802
+ }
292803
+ return { provider: decodeURIComponent(tail.slice(0, slash)), rest: tail.slice(slash) };
292804
+ }
292805
+
292806
+ // src/frontdoor/pipeline.ts
292807
+ function errorTypeFor(status) {
292808
+ switch (status) {
292809
+ case HTTP_STATUS.badRequest:
292810
+ return "invalid_request_error";
292811
+ case HTTP_STATUS.unauthorized:
292812
+ return "authentication_error";
292813
+ case HTTP_STATUS.forbidden:
292814
+ return "permission_error";
292815
+ case HTTP_STATUS.notFound:
292816
+ return "not_found_error";
292817
+ case HTTP_STATUS.tooManyRequests:
292818
+ return "rate_limit_error";
292819
+ default:
292820
+ return "api_error";
292821
+ }
292822
+ }
292823
+ function errorBody(status, message) {
292824
+ return JSON.stringify({ type: "error", error: { type: errorTypeFor(status), message } });
292825
+ }
292826
+ function createRoutedResponse(response, context) {
292827
+ const { deps, session, route } = context;
292828
+ let headersSent = false;
292829
+ const settle2 = async () => {
292830
+ await new Promise((resolve) => {
292831
+ const done = () => {
292832
+ response.off("drain", done);
292833
+ response.off("close", done);
292834
+ resolve();
292835
+ };
292836
+ response.once("drain", done);
292837
+ response.once("close", done);
292838
+ });
292839
+ };
292840
+ return {
292841
+ get headersSent() {
292842
+ return headersSent;
292843
+ },
292844
+ start: (status, headers) => {
292845
+ for (const observe of deps.responseObservers) {
292846
+ try {
292847
+ observe({ session, route, status, headers });
292848
+ } catch (error62) {
292849
+ deps.log(`front door: response observer threw for ${route}: ${error62 instanceof Error ? error62.message : String(error62)}`);
292850
+ }
292851
+ }
292852
+ response.writeHead(status, headers);
292853
+ headersSent = true;
292854
+ },
292855
+ write: async (chunk) => {
292856
+ if (response.destroyed || response.writableEnded) {
292857
+ return;
292858
+ }
292859
+ if (!response.write(chunk)) {
292860
+ await settle2();
292861
+ }
292862
+ },
292863
+ end: () => {
292864
+ response.end();
292865
+ },
292866
+ destroy: () => {
292867
+ response.destroy();
292868
+ }
292869
+ };
292870
+ }
292871
+ async function serveRouted(request3, deps) {
292872
+ const identified = identifyRequest(request3.headers);
292873
+ const routed = {
292874
+ method: request3.method,
292875
+ url: request3.url,
292876
+ headers: identified.forwardableHeaders,
292877
+ body: request3.body,
292878
+ signal: request3.signal,
292879
+ session: identified.session
292880
+ };
292881
+ const resolution = await deps.resolveRoute(routed);
292882
+ if (!resolution.ok) {
292883
+ const response2 = createRoutedResponse(request3.response, { deps, session: identified.session, route: "(unrouted)" });
292884
+ response2.start(resolution.status, { "Content-Type": "application/json" });
292885
+ await response2.write(errorBody(resolution.status, resolution.message));
292886
+ response2.end();
292887
+ return;
292888
+ }
292889
+ const response = createRoutedResponse(request3.response, { deps, session: identified.session, route: resolution.route.name });
292890
+ try {
292891
+ await resolution.route.serve(routed, response);
292892
+ } catch (error62) {
292893
+ if (request3.signal.aborted) {
292894
+ return;
292895
+ }
292896
+ deps.log(`front door: route ${resolution.route.name} failed: ${error62 instanceof Error ? `${error62.name}: ${error62.message}` : String(error62)}`);
292897
+ if (!response.headersSent) {
292898
+ response.start(HTTP_STATUS.internalServerError, { "Content-Type": "application/json" });
292899
+ await response.write(errorBody(HTTP_STATUS.internalServerError, "internal error in the claude-use front door"));
292900
+ response.end();
292901
+ return;
292902
+ }
292903
+ response.destroy();
292904
+ }
292905
+ }
292839
292906
 
292840
292907
  // src/codex/events.ts
292841
292908
  var ResponsesUsageSchema = external_exports.looseObject({
@@ -293165,82 +293232,8 @@ function createRelay(params) {
293165
293232
  return { push };
293166
293233
  }
293167
293234
 
293168
- // src/codex/upstream.ts
293169
- var import_node_crypto6 = require("node:crypto");
293170
- var CODEX_RESPONSES_URL = "https://chatgpt.com/backend-api/codex/responses";
293171
- var CODEX_UPSTREAM_TIMEOUT_MS = 3e5;
293172
- var CODEX_HEADERS_TIMEOUT_MS = 15e3;
293173
- var realTimers = {
293174
- after: (ms, callback) => {
293175
- const handle = setTimeout(callback, ms);
293176
- return () => {
293177
- clearTimeout(handle);
293178
- };
293179
- }
293180
- };
293181
- async function fetchUntilHeaders(fetch3, timers, url2, init) {
293182
- for (let attempt = 1; ; attempt += 1) {
293183
- init.signal.throwIfAborted();
293184
- const deadline = new AbortController();
293185
- const cancel2 = timers.after(CODEX_HEADERS_TIMEOUT_MS, () => {
293186
- deadline.abort();
293187
- });
293188
- try {
293189
- return await fetch3(url2, { ...init, signal: AbortSignal.any([init.signal, deadline.signal]) });
293190
- } catch (error62) {
293191
- if (deadline.signal.aborted && !init.signal.aborted && attempt === 1) {
293192
- continue;
293193
- }
293194
- throw error62;
293195
- } finally {
293196
- cancel2();
293197
- }
293198
- }
293199
- }
293200
- var UUID_TEMPLATE = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
293201
- function sessionIdFor(userId, randomId) {
293202
- if (userId === void 0 || userId === "") {
293203
- return randomId();
293204
- }
293205
- const hex3 = (0, import_node_crypto6.createHash)("sha256").update(`claude-use codex session
293206
- ${userId}`).digest("hex");
293207
- let next = 0;
293208
- return UUID_TEMPLATE.replace(/x/g, () => hex3.charAt(next++));
293209
- }
293210
- function headersFor(credentials, sessionId) {
293211
- return {
293212
- "Content-Type": "application/json",
293213
- Accept: "text/event-stream",
293214
- Authorization: `Bearer ${credentials.accessToken}`,
293215
- ...credentials.accountId === void 0 ? {} : { "chatgpt-account-id": credentials.accountId },
293216
- "OpenAI-Beta": "responses=experimental",
293217
- originator: "codex_cli_rs",
293218
- session_id: sessionId
293219
- };
293220
- }
293221
- async function callCodex(ports, request3, sessionId, signal) {
293222
- const url2 = ports.url ?? CODEX_RESPONSES_URL;
293223
- const body = JSON.stringify(request3);
293224
- const send = async (credentials2) => await fetchUntilHeaders(ports.fetch, ports.timers, url2, {
293225
- method: "POST",
293226
- headers: headersFor(credentials2, sessionId),
293227
- body,
293228
- signal: AbortSignal.any([signal, AbortSignal.timeout(CODEX_UPSTREAM_TIMEOUT_MS)])
293229
- });
293230
- const credentials = await ports.auth.current();
293231
- const first = await send(credentials);
293232
- if (first.status !== HTTP_STATUS.unauthorized) {
293233
- return first;
293234
- }
293235
- return await send(await ports.auth.refresh(credentials.accessToken));
293236
- }
293237
-
293238
293235
  // src/codex/route.ts
293239
- var CODEX_PROVIDER_PATH_PREFIX = "/providers/";
293240
- function codexProviderBaseUrl(port, provider) {
293241
- return `http://127.0.0.1:${String(port)}${CODEX_PROVIDER_PATH_PREFIX}${encodeURIComponent(provider)}`;
293242
- }
293243
- function errorTypeFor(status) {
293236
+ function errorTypeFor2(status) {
293244
293237
  switch (status) {
293245
293238
  case HTTP_STATUS.badRequest:
293246
293239
  return "invalid_request_error";
@@ -293256,32 +293249,21 @@ function errorTypeFor(status) {
293256
293249
  return "api_error";
293257
293250
  }
293258
293251
  }
293259
- function errorBody(status, message) {
293260
- return JSON.stringify({ type: "error", error: { type: errorTypeFor(status), message } });
293252
+ function errorBody2(status, message) {
293253
+ return JSON.stringify({ type: "error", error: { type: errorTypeFor2(status), message } });
293261
293254
  }
293262
293255
  function errorResponse(status, message, headers = {}) {
293263
- return { status, headers: { "Content-Type": "application/json", ...headers }, body: errorBody(status, message) };
293256
+ return { status, headers: { "Content-Type": "application/json", ...headers }, body: errorBody2(status, message) };
293264
293257
  }
293265
293258
  function errorFrame(status, message) {
293266
293259
  return `event: error
293267
- data: ${errorBody(status, message)}
293260
+ data: ${errorBody2(status, message)}
293268
293261
 
293269
293262
  `;
293270
293263
  }
293271
293264
  var UPSTREAM_DETAIL_CHARS = 2e3;
293272
293265
  var UPSTREAM_LOG_DETAIL_CHARS = 300;
293273
293266
  var CHARS_PER_TOKEN = 4;
293274
- function providerPath(path28) {
293275
- if (!path28.startsWith(CODEX_PROVIDER_PATH_PREFIX)) {
293276
- return void 0;
293277
- }
293278
- const tail = path28.slice(CODEX_PROVIDER_PATH_PREFIX.length);
293279
- const slash = tail.indexOf("/");
293280
- if (slash <= 0) {
293281
- return void 0;
293282
- }
293283
- return { provider: decodeURIComponent(tail.slice(0, slash)), rest: tail.slice(slash) };
293284
- }
293285
293267
  function parseJson2(body) {
293286
293268
  try {
293287
293269
  const value = JSON.parse(body);
@@ -293418,7 +293400,7 @@ function createCodexRoute(ports) {
293418
293400
  if (request3.method !== "POST") {
293419
293401
  return errorResponse(HTTP_STATUS.methodNotAllowed, `unsupported ${request3.method} ${request3.path}`);
293420
293402
  }
293421
- const scoped = providerPath(request3.path);
293403
+ const scoped = parseProviderPath(request3.path);
293422
293404
  if (scoped === void 0 || scoped.rest !== "/v1/messages" && scoped.rest !== "/v1/messages/count_tokens") {
293423
293405
  return errorResponse(HTTP_STATUS.notFound, `no such endpoint: ${request3.path}`);
293424
293406
  }
@@ -293434,8 +293416,7 @@ function createCodexRoute(ports) {
293434
293416
  };
293435
293417
  }
293436
293418
 
293437
- // src/codex/server.ts
293438
- var import_node_http = __toESM(require("node:http"), 1);
293419
+ // src/frontdoor/codexMount.ts
293439
293420
  var CODEX_MAX_BODY_BYTES = 67108864;
293440
293421
  var BodyTooLargeError = class extends Error {
293441
293422
  constructor() {
@@ -293446,7 +293427,7 @@ var BodyTooLargeError = class extends Error {
293446
293427
  async function readBody(request3) {
293447
293428
  const chunks = [];
293448
293429
  let size = 0;
293449
- for await (const chunk of request3) {
293430
+ for await (const chunk of request3.body) {
293450
293431
  if (!Buffer.isBuffer(chunk)) {
293451
293432
  throw new TypeError("request body chunk was not a Buffer");
293452
293433
  }
@@ -293458,291 +293439,245 @@ async function readBody(request3) {
293458
293439
  }
293459
293440
  return Buffer.concat(chunks).toString("utf8");
293460
293441
  }
293461
- async function writeResponse(response, routed) {
293462
- response.writeHead(routed.status, routed.headers);
293442
+ async function writeRouteResponse(routed, response, signal) {
293443
+ response.start(routed.status, routed.headers);
293463
293444
  if (typeof routed.body === "string") {
293464
- response.end(routed.body);
293445
+ await response.write(routed.body);
293446
+ response.end();
293465
293447
  return;
293466
293448
  }
293467
293449
  for await (const chunk of routed.body) {
293468
- if (response.destroyed) {
293450
+ if (signal.aborted) {
293469
293451
  return;
293470
293452
  }
293471
- if (!response.write(chunk)) {
293472
- await new Promise((resolve) => {
293473
- const settle2 = () => {
293474
- response.off("drain", settle2);
293475
- response.off("close", settle2);
293476
- resolve();
293477
- };
293478
- response.once("drain", settle2);
293479
- response.once("close", settle2);
293480
- });
293481
- }
293453
+ await response.write(chunk);
293482
293454
  }
293483
293455
  response.end();
293484
293456
  }
293485
- function createCodexServer(route, log) {
293486
- return import_node_http.default.createServer((request3, response) => {
293487
- const abort = new AbortController();
293488
- response.on("close", () => {
293489
- if (!response.writableFinished) {
293490
- abort.abort();
293491
- }
293492
- });
293493
- const path28 = new URL(request3.url ?? "/", "http://127.0.0.1").pathname;
293494
- const handle = async () => {
293457
+ function createCodexRouteMount(ports, upstreamBase, provider) {
293458
+ const route = createCodexRoute(ports);
293459
+ return {
293460
+ name: `codex:${provider}`,
293461
+ headroomEligible: true,
293462
+ headroomUpstream: upstreamBase,
293463
+ serve: async (request3, response) => {
293495
293464
  let body;
293496
293465
  try {
293497
293466
  body = await readBody(request3);
293498
293467
  } catch (error62) {
293499
293468
  const tooLarge = error62 instanceof BodyTooLargeError;
293500
- response.writeHead(tooLarge ? HTTP_STATUS.payloadTooLarge : HTTP_STATUS.badRequest, { "Content-Type": "application/json" });
293501
- response.end(JSON.stringify({ type: "error", error: { type: "invalid_request_error", message: error62 instanceof Error ? error62.message : String(error62) } }));
293502
- request3.destroy();
293469
+ response.start(tooLarge ? HTTP_STATUS.payloadTooLarge : HTTP_STATUS.badRequest, { "Content-Type": "application/json" });
293470
+ await response.write(
293471
+ JSON.stringify({ type: "error", error: { type: "invalid_request_error", message: error62 instanceof Error ? error62.message : String(error62) } })
293472
+ );
293473
+ response.end();
293474
+ request3.body.resume();
293503
293475
  return;
293504
293476
  }
293505
- const routed = await route({ method: request3.method ?? "GET", path: path28, body, signal: abort.signal });
293506
- if (abort.signal.aborted) {
293477
+ const path28 = new URL(request3.url, "http://127.0.0.1").pathname;
293478
+ const translated = { method: request3.method, path: path28, body, signal: request3.signal };
293479
+ const routed = await route(translated);
293480
+ if (request3.signal.aborted) {
293507
293481
  return;
293508
293482
  }
293509
- await writeResponse(response, routed);
293483
+ await writeRouteResponse(routed, response, request3.signal);
293484
+ }
293485
+ };
293486
+ }
293487
+
293488
+ // src/frontdoor/providerRoute.ts
293489
+ function createProviderRouteResolver(deps) {
293490
+ const resolve = (request3) => {
293491
+ const path28 = new URL(request3.url, "http://127.0.0.1").pathname;
293492
+ const scoped = parseProviderPath(path28);
293493
+ if (scoped === void 0) {
293494
+ return { ok: false, status: HTTP_STATUS.notFound, message: `no such endpoint: ${path28}` };
293495
+ }
293496
+ const { provider } = scoped;
293497
+ let definition;
293498
+ try {
293499
+ definition = loadProvider(deps.providersDir, provider, deps.fs);
293500
+ } catch (error62) {
293501
+ if (error62 instanceof ConfigValidationError || error62 instanceof LegacyProviderFileError) {
293502
+ return { ok: false, status: HTTP_STATUS.internalServerError, message: `provider ${provider} is invalid: ${error62 instanceof Error ? error62.message : String(error62)}` };
293503
+ }
293504
+ throw error62;
293505
+ }
293506
+ if (definition === void 0) {
293507
+ return { ok: false, status: HTTP_STATUS.notFound, message: `no provider named "${provider}"` };
293508
+ }
293509
+ if (!isCodexProvider(definition)) {
293510
+ return { ok: false, status: HTTP_STATUS.notFound, message: `provider ${provider} is an http provider, which the front door does not route directly yet` };
293511
+ }
293512
+ const codexProvider = definition;
293513
+ return {
293514
+ ok: true,
293515
+ route: createCodexRouteMount(
293516
+ { ...deps.codexPorts, loadProvider: () => ({ ok: true, config: resolveCodexConfig(codexProvider.codex) }) },
293517
+ providerBaseUrl(deps.ownPort(), provider),
293518
+ provider
293519
+ )
293520
+ };
293521
+ };
293522
+ return async (request3) => await Promise.resolve(resolve(request3));
293523
+ }
293524
+
293525
+ // src/frontdoor/server.ts
293526
+ var import_node_http = __toESM(require("node:http"), 1);
293527
+ var HEALTH_TIMEOUT_MS = 2e3;
293528
+ var HEALTH_START_BUDGET_MS = 5e3;
293529
+ var HEALTH_RETRY_MS = 50;
293530
+ function createFrontDoorServer(pipeline, log) {
293531
+ return import_node_http.default.createServer((request3, response) => {
293532
+ if (request3.method === "GET" && request3.url === "/healthz") {
293533
+ response.writeHead(HTTP_STATUS.ok, { "Content-Type": "text/plain" });
293534
+ response.end("ok");
293535
+ return;
293536
+ }
293537
+ const abort = new AbortController();
293538
+ response.on("close", () => {
293539
+ if (!response.writableFinished) {
293540
+ abort.abort();
293541
+ }
293542
+ });
293543
+ const handle = async () => {
293544
+ await pipeline({ method: request3.method ?? "GET", url: request3.url ?? "/", headers: request3.headers, body: request3, signal: abort.signal, response });
293545
+ if (!request3.readableEnded) {
293546
+ request3.resume();
293547
+ }
293510
293548
  };
293511
293549
  handle().catch((error62) => {
293512
- log(`request ${request3.method ?? "?"} ${path28} failed: ${error62 instanceof Error ? `${error62.name}: ${error62.message}` : String(error62)}`);
293550
+ log(`request ${request3.method ?? "?"} ${request3.url ?? "?"} failed: ${error62 instanceof Error ? `${error62.name}: ${error62.message}` : String(error62)}`);
293513
293551
  if (!response.headersSent) {
293514
293552
  response.writeHead(HTTP_STATUS.internalServerError, { "Content-Type": "application/json" });
293515
- response.end(JSON.stringify({ type: "error", error: { type: "api_error", message: "internal error in the codex translation daemon" } }));
293553
+ response.end(JSON.stringify({ type: "error", error: { type: "api_error", message: "internal error in the claude-use front door" } }));
293516
293554
  } else {
293517
293555
  response.destroy();
293518
293556
  }
293519
293557
  });
293520
293558
  });
293521
293559
  }
293560
+ async function frontDoorHealthy(port) {
293561
+ try {
293562
+ const response = await fetch(`http://127.0.0.1:${String(port)}/healthz`, { signal: AbortSignal.timeout(HEALTH_TIMEOUT_MS) });
293563
+ return response.ok;
293564
+ } catch {
293565
+ return false;
293566
+ }
293567
+ }
293568
+ async function listenFrontDoor(server2, preferredPort, onBound) {
293569
+ const tryListen = async (port) => await new Promise((resolve, reject) => {
293570
+ const onError = (error62) => {
293571
+ server2.off("error", onError);
293572
+ reject(error62);
293573
+ };
293574
+ server2.once("error", onError);
293575
+ server2.listen(port, "127.0.0.1", () => {
293576
+ server2.off("error", onError);
293577
+ const address = server2.address();
293578
+ const bound2 = typeof address === "object" && address !== null ? address.port : 0;
293579
+ if (bound2 === 0) {
293580
+ reject(new Error("could not bind a loopback port"));
293581
+ return;
293582
+ }
293583
+ resolve(bound2);
293584
+ });
293585
+ });
293586
+ let bound;
293587
+ if (preferredPort !== void 0) {
293588
+ try {
293589
+ bound = await tryListen(preferredPort);
293590
+ } catch {
293591
+ bound = await tryListen(0);
293592
+ }
293593
+ } else {
293594
+ bound = await tryListen(0);
293595
+ }
293596
+ onBound(bound);
293597
+ const deadline = Date.now() + HEALTH_START_BUDGET_MS;
293598
+ for (; ; ) {
293599
+ if (await frontDoorHealthy(bound)) {
293600
+ return {
293601
+ port: bound,
293602
+ close: async () => {
293603
+ await new Promise((resolve) => {
293604
+ server2.close(() => {
293605
+ resolve(void 0);
293606
+ });
293607
+ server2.closeAllConnections();
293608
+ });
293609
+ }
293610
+ };
293611
+ }
293612
+ if (Date.now() >= deadline) {
293613
+ throw new Error(`the front door listener on 127.0.0.1:${String(bound)} did not answer its health probe`);
293614
+ }
293615
+ await new Promise((resolve) => {
293616
+ setTimeout(resolve, HEALTH_RETRY_MS);
293617
+ });
293618
+ }
293619
+ }
293522
293620
 
293523
- // src/codex/supervisor.ts
293524
- var CODEX_SUPERVISOR_STILL_RUNNING = -1;
293525
- var CODEX_POLL_MS = 1e3;
293526
- var CODEX_READY_TIMEOUT_MS = 1e4;
293527
- var MS_PER_MINUTE2 = 6e4;
293528
- async function runCodexSupervisor(idleShutdownMinutes, ports, options = {}) {
293529
- const { fs: fs13, paths } = ports;
293530
- const previous = readCodexState(fs13, paths.codexStateFile);
293621
+ // src/frontdoor/supervisor.ts
293622
+ var FRONTDOOR_SUPERVISOR_STILL_RUNNING = -1;
293623
+ var FRONTDOOR_POLL_MS = 1e3;
293624
+ var MS_PER_MINUTE = 6e4;
293625
+ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {}) {
293626
+ const { fs: fs14, paths } = ports;
293627
+ const previous = readFrontDoorState(fs14, paths.frontdoorStateFile);
293531
293628
  let lastPort = previous?.lastPort;
293532
293629
  const sticky = () => lastPort === void 0 ? {} : { lastPort };
293533
293630
  const fail = (message) => {
293534
- writeCodexState(fs13, paths.codexStateFile, { lastError: message, ...sticky() });
293535
- fs13.removeRecursive(paths.codexLockFile);
293536
- ports.log(`claude-use codex supervisor: ${message}`);
293631
+ writeFrontDoorState(fs14, paths.frontdoorStateFile, { lastError: message, ...sticky() });
293632
+ fs14.removeRecursive(paths.frontdoorLockFile);
293633
+ ports.log(`claude-use frontdoor supervisor: ${message}`);
293537
293634
  return 1;
293538
293635
  };
293539
- writeCodexState(fs13, paths.codexStateFile, { supervisorPid: ports.ownPid, ...sticky() });
293540
- const orphan = previous?.workerPid;
293541
- if (orphan !== void 0 && ports.isRunning(orphan)) {
293542
- ports.log(`claude-use codex supervisor: stopping worker pid ${String(orphan)} left behind by the previous supervisor`);
293543
- ports.stopProcess(orphan);
293544
- }
293545
- let workerPid;
293546
- let failures = 0;
293636
+ writeFrontDoorState(fs14, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
293637
+ const previousSticky = lastPort;
293638
+ let listener;
293639
+ try {
293640
+ listener = await ports.startListener(lastPort);
293641
+ } catch (error62) {
293642
+ return fail(`could not start the front-door listener: ${error62 instanceof Error ? error62.message : String(error62)}`);
293643
+ }
293644
+ if (previousSticky !== void 0 && listener.port !== previousSticky) {
293645
+ ports.log(`claude-use frontdoor supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(listener.port)} (sessions launched against the old port are stale until they relaunch)`);
293646
+ }
293647
+ lastPort = listener.port;
293648
+ writeFrontDoorState(fs14, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, port: listener.port, ...sticky() });
293649
+ fs14.removeRecursive(paths.frontdoorLockFile);
293650
+ ports.log(`claude-use frontdoor supervisor ${String(ports.ownPid)}: front door listening on 127.0.0.1:${String(listener.port)}`);
293547
293651
  let idleSince;
293548
293652
  let ticks = 0;
293549
293653
  for (; ; ) {
293550
293654
  if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
293551
- return CODEX_SUPERVISOR_STILL_RUNNING;
293655
+ return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
293552
293656
  }
293553
293657
  ticks += 1;
293554
- pruneDeadSessions(fs13, paths.codexSessionsDir, ports.isRunning);
293555
- const crashed = workerPid !== void 0 && !ports.isRunning(workerPid);
293556
- if (workerPid === void 0 || crashed) {
293557
- if (crashed) {
293558
- ports.log(`claude-use codex supervisor: worker pid ${String(workerPid)} died`);
293559
- workerPid = void 0;
293560
- writeCodexState(fs13, paths.codexStateFile, { supervisorPid: ports.ownPid, ...sticky() });
293561
- }
293562
- if (failures >= HEADROOM_START_RETRY_BUDGET) {
293563
- return fail(`the codex worker failed to become ready ${String(failures)} times in a row; giving up`);
293564
- }
293565
- const previousSticky = lastPort;
293566
- const port = lastPort !== void 0 && await ports.isPortFree(lastPort) ? lastPort : await ports.freePort();
293567
- const pid = ports.spawnWorker(port);
293568
- if (await waitUntilReady2(ports, port)) {
293569
- failures = 0;
293570
- workerPid = pid;
293571
- lastPort = port;
293572
- if (previousSticky !== void 0 && port !== previousSticky) {
293573
- ports.log(
293574
- `claude-use codex supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(port)} (sessions launched against the old port are stale until they relaunch)`
293575
- );
293576
- }
293577
- writeCodexState(fs13, paths.codexStateFile, { supervisorPid: ports.ownPid, workerPid: pid, port, ...sticky() });
293578
- fs13.removeRecursive(paths.codexLockFile);
293579
- idleSince = void 0;
293580
- ports.log(`claude-use codex supervisor: worker pid ${String(pid)} ready on 127.0.0.1:${String(port)}`);
293581
- } else {
293582
- ports.stopProcess(pid);
293583
- failures += 1;
293584
- ports.log(`claude-use codex supervisor: worker did not become ready on port ${String(port)} (attempt ${String(failures)} of ${String(HEADROOM_START_RETRY_BUDGET)})`);
293585
- await ports.sleep(backoffForAttempt(failures));
293586
- continue;
293587
- }
293588
- } else if (listSessions(fs13, paths.codexSessionsDir).length === 0) {
293658
+ pruneDeadSessions(fs14, paths.frontdoorSessionsDir, ports.isRunning);
293659
+ if (listSessions(fs14, paths.frontdoorSessionsDir).length === 0) {
293589
293660
  idleSince ??= ports.now();
293590
- if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE2) {
293591
- ports.log(`claude-use codex supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); stopping the worker and exiting`);
293592
- ports.stopProcess(workerPid);
293593
- writeCodexState(fs13, paths.codexStateFile, sticky());
293661
+ if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE) {
293662
+ ports.log(`claude-use frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
293663
+ await listener.close();
293664
+ writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
293594
293665
  return 0;
293595
293666
  }
293596
293667
  } else {
293597
293668
  idleSince = void 0;
293598
293669
  }
293599
- await ports.sleep(CODEX_POLL_MS);
293600
- }
293601
- }
293602
- async function waitUntilReady2(ports, port) {
293603
- const deadline = ports.now() + CODEX_READY_TIMEOUT_MS;
293604
- for (; ; ) {
293605
- if (await ports.ready(port)) {
293606
- return true;
293607
- }
293608
- if (ports.now() >= deadline) {
293609
- return false;
293610
- }
293611
- await ports.sleep(CODEX_POLL_MS);
293670
+ await ports.sleep(FRONTDOOR_POLL_MS);
293612
293671
  }
293613
293672
  }
293614
293673
 
293615
- // src/codex/commands.ts
293616
- function codexHome(env, home) {
293617
- const fromEnv = env.CODEX_HOME;
293618
- return fromEnv !== void 0 && fromEnv !== "" ? fromEnv : import_node_path23.default.join(home, ".codex");
293619
- }
293620
- function usageSnapshotPath() {
293621
- return import_node_path23.default.join(resolveClaudeHome(), "codex-quota.json");
293622
- }
293674
+ // src/frontdoor/commands.ts
293623
293675
  function appendLog(paths, line) {
293624
- import_node_fs9.default.mkdirSync(paths.logsDir, { recursive: true });
293625
- import_node_fs9.default.appendFileSync(paths.codexLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
293626
- `);
293627
- }
293628
- function isEnoent4(error62) {
293629
- return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === "ENOENT";
293630
- }
293631
- var PRIVATE_FILE_MODE = 384;
293632
- var realCodexAuthFs = {
293633
- read: (filePath) => {
293634
- try {
293635
- return import_node_fs9.default.readFileSync(filePath, "utf8");
293636
- } catch (error62) {
293637
- if (isEnoent4(error62)) {
293638
- return void 0;
293639
- }
293640
- throw error62;
293641
- }
293642
- },
293643
- writePrivate: (filePath, contents) => {
293644
- import_node_fs9.default.writeFileSync(filePath, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
293645
- import_node_fs9.default.chmodSync(filePath, PRIVATE_FILE_MODE);
293646
- },
293647
- rename: (from, to) => {
293648
- import_node_fs9.default.renameSync(from, to);
293649
- }
293650
- };
293651
- function lookupCodexProvider(paths, name) {
293652
- let provider;
293653
- try {
293654
- provider = loadProvider(paths.providersDir, name, realFsPort);
293655
- } catch (error62) {
293656
- if (error62 instanceof ConfigValidationError || error62 instanceof LegacyProviderFileError) {
293657
- return { ok: false, status: 500, message: `provider ${name} is invalid: ${error62.message}` };
293658
- }
293659
- throw error62;
293660
- }
293661
- if (provider === void 0) {
293662
- return { ok: false, status: 404, message: `no provider named "${name}"` };
293663
- }
293664
- if (!isCodexProvider(provider)) {
293665
- return { ok: false, status: 404, message: `provider ${name} is not a codex provider` };
293666
- }
293667
- return { ok: true, config: resolveCodexConfig(provider.codex) };
293668
- }
293669
- function writeUsageSnapshot(paths, snapshot) {
293670
- const target = usageSnapshotPath();
293671
- const temp = `${target}.${String(process.pid)}.tmp`;
293672
- try {
293673
- import_node_fs9.default.mkdirSync(import_node_path23.default.dirname(target), { recursive: true });
293674
- import_node_fs9.default.writeFileSync(temp, `${JSON.stringify(snapshot, null, 2)}
293676
+ import_node_fs10.default.mkdirSync(paths.logsDir, { recursive: true });
293677
+ import_node_fs10.default.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
293675
293678
  `);
293676
- import_node_fs9.default.renameSync(temp, target);
293677
- } catch (error62) {
293678
- appendLog(paths, `codex worker: usage snapshot write failed: ${error62 instanceof Error ? error62.message : String(error62)}`);
293679
- }
293680
293679
  }
293681
- var WORKER_PARENT_POLL_MS = 1e3;
293682
- async function runWorker(paths, port, supervisorPid) {
293683
- const log = (line) => {
293684
- appendLog(paths, `codex worker ${String(process.pid)}: ${line}`);
293685
- };
293686
- const agent = createUpstreamAgent();
293687
- const upstreamFetch = createUpstreamFetch(agent);
293688
- const auth = createCodexAuthStore(import_node_path23.default.join(codexHome(process.env, import_node_os6.default.homedir()), "auth.json"), {
293689
- fs: realCodexAuthFs,
293690
- fetch: upstreamFetch,
293691
- now: () => /* @__PURE__ */ new Date(),
293692
- tempSuffix: `${String(process.pid)}.${(0, import_node_crypto7.randomUUID)()}`
293693
- });
293694
- const route = createCodexRoute({
293695
- upstream: { fetch: upstreamFetch, auth, timers: realTimers, randomId: import_node_crypto7.randomUUID },
293696
- loadProvider: (name) => lookupCodexProvider(paths, name),
293697
- writeUsageSnapshot: (snapshot) => {
293698
- writeUsageSnapshot(paths, snapshot);
293699
- },
293700
- now: () => Date.now(),
293701
- log
293702
- });
293703
- const server2 = createCodexServer(route, log);
293704
- await new Promise((resolve, reject) => {
293705
- server2.once("error", reject);
293706
- server2.listen(port, "127.0.0.1", () => {
293707
- server2.off("error", reject);
293708
- resolve();
293709
- });
293710
- });
293711
- log(`listening on 127.0.0.1:${String(port)}`);
293712
- const watch = setInterval(() => {
293713
- if (!realIsProcessRunning(supervisorPid)) {
293714
- log(`supervisor pid ${String(supervisorPid)} is gone; exiting`);
293715
- clearInterval(watch);
293716
- server2.close();
293717
- void agent.close();
293718
- }
293719
- }, WORKER_PARENT_POLL_MS);
293720
- }
293721
- async function realFreePort() {
293722
- return await new Promise((resolve, reject) => {
293723
- const server2 = import_node_net2.default.createServer();
293724
- server2.unref();
293725
- server2.on("error", reject);
293726
- server2.listen(0, "127.0.0.1", () => {
293727
- const address = server2.address();
293728
- const port = typeof address === "object" && address !== null ? address.port : 0;
293729
- server2.close(() => {
293730
- if (port === 0) {
293731
- reject(new Error("could not reserve a loopback port"));
293732
- return;
293733
- }
293734
- resolve(port);
293735
- });
293736
- });
293737
- });
293738
- }
293739
- var ownedWorkers = /* @__PURE__ */ new Map();
293740
- var exitedWorkers = /* @__PURE__ */ new Set();
293741
- function workerRunning(pid) {
293742
- return !exitedWorkers.has(pid) && realIsProcessRunning(pid);
293743
- }
293744
- var READY_FETCH_TIMEOUT_MS = 2e3;
293745
- function realCodexSupervisorPorts(paths) {
293680
+ function realFrontDoorSupervisorPorts(paths) {
293746
293681
  return {
293747
293682
  fs: realFarmFs,
293748
293683
  paths,
@@ -293753,59 +293688,38 @@ function realCodexSupervisorPorts(paths) {
293753
293688
  setTimeout(resolve, ms);
293754
293689
  });
293755
293690
  },
293756
- isRunning: workerRunning,
293757
- freePort: realFreePort,
293758
- isPortFree: realIsPortFree,
293759
- spawnWorker: (port) => {
293760
- import_node_fs9.default.mkdirSync(paths.logsDir, { recursive: true });
293761
- const logFd = import_node_fs9.default.openSync(paths.codexLogPath, "a");
293762
- try {
293763
- const invocation = selfInvocation(["__codex-worker", "--port", String(port), "--supervisor", String(process.pid)]);
293764
- const child = (0, import_node_child_process3.spawn)(invocation.command, invocation.args, detachedDaemonSpawnOptions(logFd, { ...process.env, CLAUDE_USE_HOME: paths.root }));
293765
- if (child.pid === void 0) {
293766
- throw new Error("spawning the codex worker returned no pid");
293767
- }
293768
- const pid = child.pid;
293769
- ownedWorkers.set(pid, child);
293770
- child.once("exit", (code, signal) => {
293771
- ownedWorkers.delete(pid);
293772
- exitedWorkers.add(pid);
293773
- appendLog(paths, `claude-use codex supervisor: worker ${String(pid)} exited (${signal ?? `code ${String(code)}`})`);
293774
- });
293775
- return pid;
293776
- } finally {
293777
- import_node_fs9.default.closeSync(logFd);
293778
- }
293779
- },
293780
- stopProcess: (pid) => {
293781
- const outcome = stopSupervisedProcess(pid, {
293782
- signal: (target, signal) => {
293783
- process.kill(target, signal);
293784
- },
293785
- isRunning: workerRunning,
293786
- waitMs: realSleepSync,
293787
- now: () => Date.now()
293691
+ isRunning: realIsProcessRunning,
293692
+ startListener: async (preferredPort) => {
293693
+ const log = (line) => {
293694
+ appendLog(paths, `frontdoor ${String(process.pid)}: ${line}`);
293695
+ };
293696
+ let ownPort = 0;
293697
+ const codexPorts = createCodexRoutePorts(log);
293698
+ const resolveRoute = createProviderRouteResolver({ fs: realFsPort, providersDir: paths.providersDir, codexPorts, ownPort: () => ownPort });
293699
+ const deps = {
293700
+ resolveRoute,
293701
+ responseObservers: [],
293702
+ log
293703
+ };
293704
+ const server2 = createFrontDoorServer(async (request3) => {
293705
+ await serveRouted(request3, deps);
293706
+ }, log);
293707
+ server2.on("error", (error62) => {
293708
+ appendLog(paths, `frontdoor ${String(process.pid)}: listener failed: ${error62.message}; exiting`);
293709
+ process.exit(1);
293710
+ });
293711
+ return await listenFrontDoor(server2, preferredPort, (port) => {
293712
+ ownPort = port;
293788
293713
  });
293789
- if (outcome === "still-running") {
293790
- appendLog(paths, `claude-use codex supervisor: pid ${String(pid)} survived SIGKILL within its grace; it is stuck uninterruptibly`);
293791
- }
293792
- },
293793
- ready: async (port) => {
293794
- try {
293795
- const response = await fetch(`http://127.0.0.1:${String(port)}/healthz`, { signal: AbortSignal.timeout(READY_FETCH_TIMEOUT_MS) });
293796
- return response.ok;
293797
- } catch {
293798
- return false;
293799
- }
293800
293714
  },
293801
293715
  log: (line) => {
293802
293716
  appendLog(paths, line);
293803
293717
  }
293804
293718
  };
293805
293719
  }
293806
- function realCodexPort(paths) {
293720
+ function realFrontDoorPort(paths) {
293807
293721
  return {
293808
- ensure: () => ensureCodex({
293722
+ ensure: () => ensureFrontDoor({
293809
293723
  paths,
293810
293724
  launcherPid: process.pid,
293811
293725
  ports: {
@@ -293813,33 +293727,36 @@ function realCodexPort(paths) {
293813
293727
  isRunning: realIsProcessRunning,
293814
293728
  now: () => Date.now(),
293815
293729
  sleep: realSleepSync,
293816
- spawnSupervisor: (layout) => spawnDetachedSupervisor(layout, "__codex-supervisor", layout.codexLogPath)
293730
+ spawnSupervisor: (layout) => spawnDetachedSupervisor(layout, "__frontdoor-supervisor", layout.frontdoorLogPath)
293817
293731
  }
293818
293732
  }),
293819
293733
  release: () => {
293820
- removeSession(realFarmFs, paths.codexSessionsDir, process.pid);
293734
+ removeSession(realFarmFs, paths.frontdoorSessionsDir, process.pid);
293821
293735
  }
293822
293736
  };
293823
293737
  }
293824
- function collectCodexStatus(fsPort, paths, isRunning) {
293825
- const state = readCodexState(fsPort, paths.codexStateFile) ?? {};
293738
+ function collectFrontDoorStatus(fsPort, paths, isRunning) {
293739
+ const state = readFrontDoorState(fsPort, paths.frontdoorStateFile) ?? {};
293826
293740
  return {
293827
293741
  state,
293828
293742
  supervisorAlive: state.supervisorPid !== void 0 && isRunning(state.supervisorPid),
293829
- workerAlive: state.workerPid !== void 0 && isRunning(state.workerPid),
293830
- sessions: listSessions(fsPort, paths.codexSessionsDir).map((session) => ({ ...session, alive: isRunning(session.pid) })),
293831
- logPath: paths.codexLogPath,
293832
- logExists: fsPort.readFileUtf8(paths.codexLogPath) !== void 0
293743
+ sessions: listSessions(fsPort, paths.frontdoorSessionsDir).map((session) => ({ ...session, alive: isRunning(session.pid) })),
293744
+ logPath: paths.frontdoorLogPath,
293745
+ logExists: fsPort.readFileUtf8(paths.frontdoorLogPath) !== void 0
293833
293746
  };
293834
293747
  }
293835
- function formatCodexStatus(status) {
293748
+ function formatFrontDoorStatus(status) {
293836
293749
  const lines = [];
293837
- lines.push(
293838
- status.state.supervisorPid === void 0 ? "supervisor: not running (no state recorded)" : `supervisor: pid ${String(status.state.supervisorPid)} (${status.supervisorAlive ? "alive" : "NOT running"})`
293839
- );
293840
- lines.push(
293841
- status.state.workerPid === void 0 || status.state.port === void 0 ? `worker: not running${status.state.lastPort === void 0 ? "" : ` (next start on 127.0.0.1:${String(status.state.lastPort)})`}` : `worker: pid ${String(status.state.workerPid)} (${status.workerAlive ? "alive" : "NOT running"}), listening on 127.0.0.1:${String(status.state.port)}`
293842
- );
293750
+ if (status.state.supervisorPid === void 0) {
293751
+ lines.push("supervisor: not running");
293752
+ } else {
293753
+ lines.push(`supervisor: pid ${String(status.state.supervisorPid)} (${status.supervisorAlive ? "alive" : "NOT running"})`);
293754
+ }
293755
+ if (status.state.port === void 0) {
293756
+ lines.push(`front door: not listening${status.state.lastPort === void 0 ? "" : ` (next start on 127.0.0.1:${String(status.state.lastPort)})`}`);
293757
+ } else {
293758
+ lines.push(`front door: listening on 127.0.0.1:${String(status.state.port)}, routing /providers/<name> requests`);
293759
+ }
293843
293760
  if (status.sessions.length === 0) {
293844
293761
  lines.push("sessions: none");
293845
293762
  } else {
@@ -293852,49 +293769,33 @@ function formatCodexStatus(status) {
293852
293769
  lines.push(`daemon log: ${status.logPath}${status.logExists ? "" : " (not created yet)"}`);
293853
293770
  return lines;
293854
293771
  }
293855
- function parsePositiveInt(value) {
293856
- const parsed = Number(value);
293857
- if (!Number.isInteger(parsed) || parsed <= 0) {
293858
- throw new InvalidArgumentError(`expected a positive integer, got "${value}"`);
293859
- }
293860
- return parsed;
293861
- }
293862
- function registerCodexCommand(program2, deps) {
293772
+ function registerFrontDoorCommand(program2, deps) {
293863
293773
  const { paths } = deps;
293864
- const codex = withExamples(program2.command("codex").description("Inspect the codex translation daemon that serves codex providers."), ["claude-use codex status"]);
293774
+ const frontdoor = withExamples(program2.command("frontdoor").description("Inspect the front-door daemon that routes every claude-use session."), [
293775
+ "claude-use frontdoor status"
293776
+ ]);
293865
293777
  withExamples(
293866
- codex.command("status").description("Report the codex daemon's supervisor, worker, port, sessions, and last error. Read-only.").option("--json", "Print the status as JSON.").action((options) => {
293867
- const status = collectCodexStatus(realFarmFs, paths, realIsProcessRunning);
293778
+ frontdoor.command("status").description("Report the front door's supervisor, listener, sessions, and last error. Read-only.").option("--json", "Print the status as JSON.").action((options) => {
293779
+ const status = collectFrontDoorStatus(realFarmFs, paths, realIsProcessRunning);
293868
293780
  if (options.json === true) {
293869
293781
  printJson(status);
293870
293782
  return;
293871
293783
  }
293872
- for (const line of formatCodexStatus(status)) {
293784
+ for (const line of formatFrontDoorStatus(status)) {
293873
293785
  console.log(line);
293874
293786
  }
293875
293787
  }),
293876
- ["claude-use codex status", "claude-use codex status --json"]
293788
+ ["claude-use frontdoor status", "claude-use frontdoor status --json"]
293877
293789
  );
293878
- program2.command("__codex-supervisor", { hidden: true }).description("Internal: supervise the codex translation worker. Started by the launcher; never run by hand.").allowUnknownOption().action(async () => {
293879
- const idleShutdownMinutes = readGlobalConfig(paths)?.codex?.idleShutdownMinutes ?? CODEX_DEFAULT_IDLE_SHUTDOWN_MINUTES;
293880
- process.on("exit", () => {
293881
- for (const pid of ownedWorkers.keys()) {
293882
- try {
293883
- process.kill(pid, "SIGKILL");
293884
- } catch {
293885
- }
293886
- }
293887
- });
293790
+ program2.command("__frontdoor-supervisor", { hidden: true }).description("Internal: serve the front-door routing listener. Started by the launcher; never run by hand.").allowUnknownOption().action(async () => {
293791
+ const idleShutdownMinutes = readGlobalConfig(paths)?.frontdoor?.idleShutdownMinutes ?? FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES;
293888
293792
  process.on("SIGTERM", () => {
293889
293793
  deps.exit(0);
293890
293794
  });
293891
293795
  process.on("SIGINT", () => {
293892
293796
  deps.exit(0);
293893
293797
  });
293894
- deps.exit(await runCodexSupervisor(idleShutdownMinutes, realCodexSupervisorPorts(paths)));
293895
- });
293896
- program2.command("__codex-worker", { hidden: true }).description("Internal: serve the codex translation listener. Started by the codex supervisor; never run by hand.").requiredOption("--port <port>", "Loopback port to listen on.", parsePositiveInt).requiredOption("--supervisor <pid>", "The supervising process; the worker exits once it is gone.", parsePositiveInt).action(async (options) => {
293897
- await runWorker(paths, options.port, options.supervisor);
293798
+ deps.exit(await runFrontDoorSupervisor(idleShutdownMinutes, realFrontDoorSupervisorPorts(paths)));
293898
293799
  });
293899
293800
  }
293900
293801
 
@@ -294171,7 +294072,7 @@ function registerCompletionCommand(program2) {
294171
294072
  }
294172
294073
 
294173
294074
  // src/doctor.ts
294174
- var import_node_fs10 = __toESM(require("node:fs"), 1);
294075
+ var import_node_fs11 = __toESM(require("node:fs"), 1);
294175
294076
  var import_node_path24 = __toESM(require("node:path"), 1);
294176
294077
  function refinePathShadow(status, ownExecutablePath, realpath) {
294177
294078
  if (status.status !== "shadowed") {
@@ -294536,7 +294437,7 @@ function formatDoctorReport(report) {
294536
294437
  }
294537
294438
  function realpathOrSelf(target) {
294538
294439
  try {
294539
- return import_node_fs10.default.realpathSync(target);
294440
+ return import_node_fs11.default.realpathSync(target);
294540
294441
  } catch {
294541
294442
  return target;
294542
294443
  }
@@ -294546,21 +294447,21 @@ function registerDoctorCommand(program2, deps) {
294546
294447
  const command = program2.command("doctor").description(
294547
294448
  "Audit the whole ~/.claude-use config graph: every identity, every configuration profile's extends chain, every provider, directory-rules.json, config.json, categories.local.json, active-identity, and real Claude Code binary discoverability. Identity/directory-agnostic, unlike `check`. Exits 1 when any check fails."
294548
294449
  ).option("--json", "Print the report as JSON.").action((options) => {
294549
- const identityNames = import_node_fs10.default.existsSync(paths.identitiesDir) ? import_node_fs10.default.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort() : [];
294450
+ const identityNames = import_node_fs11.default.existsSync(paths.identitiesDir) ? import_node_fs11.default.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort() : [];
294550
294451
  const identities = identityNames.map((name) => {
294551
294452
  const farmRoot = import_node_path24.default.join(paths.identitiesDir, name);
294552
294453
  const identityPath = import_node_path24.default.join(farmRoot, "identity.json");
294553
294454
  return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot };
294554
294455
  });
294555
- const profileNames = import_node_fs10.default.existsSync(paths.configProfilesDir) ? import_node_fs10.default.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
294456
+ const profileNames = import_node_fs11.default.existsSync(paths.configProfilesDir) ? import_node_fs11.default.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
294556
294457
  const configProfiles = profileNames.map((name) => {
294557
294458
  const profilePath = import_node_path24.default.join(paths.configProfilesDir, `${name}.json`);
294558
294459
  return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
294559
294460
  });
294560
- const providerNames = import_node_fs10.default.existsSync(paths.providersDir) ? import_node_fs10.default.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
294461
+ const providerNames = import_node_fs11.default.existsSync(paths.providersDir) ? import_node_fs11.default.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
294561
294462
  const providers = providerNames.map((name) => {
294562
- const providerPath2 = import_node_path24.default.join(paths.providersDir, `${name}.json`);
294563
- return { name, path: providerPath2, raw: realFsPort.readFileUtf8(providerPath2) };
294463
+ const providerPath = import_node_path24.default.join(paths.providersDir, `${name}.json`);
294464
+ return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
294564
294465
  });
294565
294466
  const ownExecutablePath = realOwnExecutablePath();
294566
294467
  let binaryDiscovery;
@@ -294592,7 +294493,7 @@ function registerDoctorCommand(program2, deps) {
294592
294493
  categoriesLocal: { path: paths.categoriesLocalFile, raw: realFsPort.readFileUtf8(paths.categoriesLocalFile) },
294593
294494
  activeIdentity: { path: paths.activeIdentityFile, raw: realFsPort.readFileUtf8(paths.activeIdentityFile) },
294594
294495
  binaryDiscovery,
294595
- claudeShim: { state: shimState, targetExists: shimState !== void 0 && import_node_fs10.default.existsSync(shimState.targetPath) },
294496
+ claudeShim: { state: shimState, targetExists: shimState !== void 0 && import_node_fs11.default.existsSync(shimState.targetPath) },
294596
294497
  pathResolution: {
294597
294498
  ownExecutablePath,
294598
294499
  claudeUse: refinePathShadow(
@@ -294630,15 +294531,15 @@ function registerDoctorCommand(program2, deps) {
294630
294531
  }
294631
294532
 
294632
294533
  // src/headroom/commands.ts
294633
- var import_node_fs11 = __toESM(require("node:fs"), 1);
294634
- var import_node_net3 = __toESM(require("node:net"), 1);
294635
- var import_node_child_process4 = require("node:child_process");
294534
+ var import_node_fs12 = __toESM(require("node:fs"), 1);
294535
+ var import_node_net2 = __toESM(require("node:net"), 1);
294536
+ var import_node_child_process3 = require("node:child_process");
294636
294537
 
294637
294538
  // src/headroom/mitm.ts
294638
- var fs11 = __toESM(require("node:fs"), 1);
294539
+ var fs12 = __toESM(require("node:fs"), 1);
294639
294540
  var http2 = __toESM(require("node:http"), 1);
294640
294541
  var https = __toESM(require("node:https"), 1);
294641
- var net3 = __toESM(require("node:net"), 1);
294542
+ var net2 = __toESM(require("node:net"), 1);
294642
294543
  var tls = __toESM(require("node:tls"), 1);
294643
294544
  var import_node_forge = __toESM(require_lib3(), 1);
294644
294545
  var MITM_INTERCEPT_HOST = "api.anthropic.com";
@@ -294873,7 +294774,7 @@ function realMitmEffects() {
294873
294774
  const tlsAgent = new https.Agent({ keepAlive: true });
294874
294775
  const listenOnce = async (port, onSocket) => await new Promise((resolve, reject) => {
294875
294776
  const accepted = /* @__PURE__ */ new Set();
294876
- const server2 = net3.createServer((socket) => {
294777
+ const server2 = net2.createServer((socket) => {
294877
294778
  accepted.add(socket);
294878
294779
  socket.on("close", () => {
294879
294780
  accepted.delete(socket);
@@ -294946,7 +294847,7 @@ function realMitmEffects() {
294946
294847
  };
294947
294848
  },
294948
294849
  connectTcp: async (host, port) => await new Promise((resolve, reject) => {
294949
- const socket = net3.connect({ host, port });
294850
+ const socket = net2.connect({ host, port });
294950
294851
  socket.once("connect", () => {
294951
294852
  resolve(socket);
294952
294853
  });
@@ -295000,7 +294901,7 @@ function isEnoent5(error62) {
295000
294901
  function realMitmCertStore(paths) {
295001
294902
  const read = (file2) => {
295002
294903
  try {
295003
- return fs11.readFileSync(file2, "utf8");
294904
+ return fs12.readFileSync(file2, "utf8");
295004
294905
  } catch (error62) {
295005
294906
  if (isEnoent5(error62)) {
295006
294907
  return void 0;
@@ -295015,12 +294916,293 @@ function realMitmCertStore(paths) {
295015
294916
  return certPem === void 0 || keyPem === void 0 ? void 0 : { certPem, keyPem };
295016
294917
  },
295017
294918
  writeCa: (ca) => {
295018
- fs11.mkdirSync(paths.headroomCaDir, { recursive: true });
295019
- fs11.writeFileSync(paths.headroomCaCertFile, ca.certPem, "utf8");
295020
- fs11.writeFileSync(paths.headroomCaKeyFile, ca.keyPem, { encoding: "utf8", mode: CA_KEY_FILE_MODE });
295021
- fs11.chmodSync(paths.headroomCaKeyFile, CA_KEY_FILE_MODE);
294919
+ fs12.mkdirSync(paths.headroomCaDir, { recursive: true });
294920
+ fs12.writeFileSync(paths.headroomCaCertFile, ca.certPem, "utf8");
294921
+ fs12.writeFileSync(paths.headroomCaKeyFile, ca.keyPem, { encoding: "utf8", mode: CA_KEY_FILE_MODE });
294922
+ fs12.chmodSync(paths.headroomCaKeyFile, CA_KEY_FILE_MODE);
294923
+ }
294924
+ };
294925
+ }
294926
+
294927
+ // src/headroom/supervisor.ts
294928
+ function resolveSupervisorConfig(configured) {
294929
+ return {
294930
+ source: configured.source ?? HEADROOM_DEFAULT_SOURCE,
294931
+ idleShutdownMinutes: configured.idleShutdownMinutes ?? HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES
294932
+ };
294933
+ }
294934
+ var HEADROOM_BACKOFF_BASE_MS = 500;
294935
+ var HEADROOM_BACKOFF_CAP_MS = 3e4;
294936
+ var HEADROOM_START_RETRY_BUDGET = 5;
294937
+ var HEADROOM_READY_TIMEOUT_MS = 15e3;
294938
+ var HEADROOM_POLL_MS = 1e3;
294939
+ var MS_PER_MINUTE2 = 6e4;
294940
+ var STOP_POLL_MS = 100;
294941
+ var TERM_GRACE_MS = 1500;
294942
+ var KILL_GRACE_MS = 1500;
294943
+ function stopSupervisedProcess(pid, primitives) {
294944
+ const send = (signal) => {
294945
+ try {
294946
+ primitives.signal(pid, signal);
294947
+ } catch {
294948
+ }
294949
+ };
294950
+ send("SIGTERM");
294951
+ if (awaitExit(pid, primitives, TERM_GRACE_MS)) {
294952
+ return "exited-on-term";
294953
+ }
294954
+ send("SIGKILL");
294955
+ if (awaitExit(pid, primitives, KILL_GRACE_MS)) {
294956
+ return "killed";
294957
+ }
294958
+ return "still-running";
294959
+ }
294960
+ function awaitExit(pid, primitives, budgetMs) {
294961
+ const deadline = primitives.now() + budgetMs;
294962
+ while (primitives.isRunning(pid)) {
294963
+ if (primitives.now() >= deadline) {
294964
+ return false;
294965
+ }
294966
+ primitives.waitMs(STOP_POLL_MS);
294967
+ }
294968
+ return true;
294969
+ }
294970
+ function backoffForAttempt(attempt) {
294971
+ return Math.min(HEADROOM_BACKOFF_CAP_MS, HEADROOM_BACKOFF_BASE_MS * 2 ** (attempt - 1));
294972
+ }
294973
+ function versionSatisfies(version2, source) {
294974
+ if (version2 === void 0) {
294975
+ return false;
294976
+ }
294977
+ const specifier = /==|>=|<=|!=|>|<|~=/.exec(source);
294978
+ if (specifier === null) {
294979
+ return true;
294980
+ }
294981
+ const installed = parseVersion(version2);
294982
+ const wanted = parseVersion(source.slice(specifier.index + specifier[0].length));
294983
+ if (installed === void 0 || wanted === void 0) {
294984
+ return true;
294985
+ }
294986
+ const cmp = compareVersions2(installed, wanted);
294987
+ switch (specifier[0]) {
294988
+ case "==":
294989
+ return cmp === 0;
294990
+ case "!=":
294991
+ return cmp !== 0;
294992
+ case ">=":
294993
+ return cmp >= 0;
294994
+ case "<=":
294995
+ return cmp <= 0;
294996
+ case ">":
294997
+ return cmp > 0;
294998
+ case "<":
294999
+ return cmp < 0;
295000
+ case "~=":
295001
+ return compareVersions2(installed.slice(0, Math.max(0, wanted.length - 1)), wanted.slice(0, Math.max(0, wanted.length - 1))) === 0 && cmp >= 0;
295002
+ default:
295003
+ return true;
295004
+ }
295005
+ }
295006
+ function parseVersion(input2) {
295007
+ const match = /(\d+)(\.\d+)*/.exec(input2);
295008
+ if (match === null) {
295009
+ return void 0;
295010
+ }
295011
+ return match[0].split(".").map((part) => Number.parseInt(part, 10));
295012
+ }
295013
+ function compareVersions2(a2, b) {
295014
+ for (let index = 0; index < Math.max(a2.length, b.length); index += 1) {
295015
+ const left = a2[index] ?? 0;
295016
+ const right = b[index] ?? 0;
295017
+ if (left !== right) {
295018
+ return left - right;
295019
+ }
295020
+ }
295021
+ return 0;
295022
+ }
295023
+ var HEADROOM_SUPERVISOR_STILL_RUNNING = -1;
295024
+ async function runSupervisor(config2, ports, options = {}) {
295025
+ const { fs: fs14, paths } = ports;
295026
+ const previousState = readHeadroomState(fs14, paths.headroomStateFile);
295027
+ let installedSource = previousState?.installedSource;
295028
+ let lastPort = previousState?.lastPort;
295029
+ let lastMitmPort = previousState?.lastMitmPort;
295030
+ let daemonPort;
295031
+ const sticky = () => ({
295032
+ ...lastPort === void 0 ? {} : { lastPort },
295033
+ ...lastMitmPort === void 0 ? {} : { lastMitmPort }
295034
+ });
295035
+ let mitm;
295036
+ const fail = (message) => {
295037
+ writeHeadroomState(fs14, paths.headroomStateFile, {
295038
+ lastError: message,
295039
+ ...sticky()
295040
+ });
295041
+ fs14.removeRecursive(paths.headroomLockFile);
295042
+ ports.log(`claude-use headroom supervisor: ${message}`);
295043
+ return 1;
295044
+ };
295045
+ const ensureInstalled = () => {
295046
+ const version3 = ports.headroomVersion();
295047
+ const versionOk = version3 !== void 0 && versionSatisfies(version3, config2.source);
295048
+ if (versionOk && (installedSource === void 0 || installedSource === config2.source)) {
295049
+ installedSource = config2.source;
295050
+ return true;
295022
295051
  }
295052
+ ports.log(`claude-use headroom supervisor: installing headroom from ${config2.source}`);
295053
+ const result = ports.install(config2.source);
295054
+ if (!result.ok) {
295055
+ return false;
295056
+ }
295057
+ installedSource = config2.source;
295058
+ return true;
295023
295059
  };
295060
+ if (!ensureInstalled()) {
295061
+ return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
295062
+ }
295063
+ const version2 = ports.headroomVersion() ?? "unknown";
295064
+ try {
295065
+ mitm = await ports.startMitm(lastMitmPort, () => daemonPort);
295066
+ } catch (error62) {
295067
+ return fail(`could not start the MITM proxy: ${error62 instanceof Error ? error62.message : String(error62)}`);
295068
+ }
295069
+ lastMitmPort = mitm.port;
295070
+ if (previousState?.lastMitmPort !== void 0 && mitm.port !== previousState.lastMitmPort) {
295071
+ ports.log(
295072
+ `claude-use headroom supervisor: sticky MITM port ${String(previousState.lastMitmPort)} was occupied; moving to ${String(mitm.port)} (OAuth sessions launched against the old port are stale until they relaunch)`
295073
+ );
295074
+ }
295075
+ writeHeadroomState(fs14, paths.headroomStateFile, { supervisorPid: ports.ownPid, version: version2, installedSource, mitmPort: mitm.port, ...sticky() });
295076
+ ports.log(`claude-use headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${allowlistOf(ports).join(", ")}]`);
295077
+ const orphanPid = previousState?.headroomPid;
295078
+ if (orphanPid !== void 0 && ports.isRunning(orphanPid)) {
295079
+ ports.log(`claude-use headroom supervisor: stopping daemon pid ${String(orphanPid)} left behind by the previous supervisor`);
295080
+ ports.stopProcess(orphanPid);
295081
+ }
295082
+ let headroomPid;
295083
+ let runningHash;
295084
+ let consecutiveFailures = 0;
295085
+ let idleSince;
295086
+ let ticks = 0;
295087
+ for (; ; ) {
295088
+ if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
295089
+ return HEADROOM_SUPERVISOR_STILL_RUNNING;
295090
+ }
295091
+ ticks += 1;
295092
+ const allowlist = allowlistOf(ports);
295093
+ const allowlistHash = hashAllowlist(allowlist);
295094
+ pruneDeadSessions(fs14, paths.headroomSessionsDir, ports.isRunning);
295095
+ const crashed = headroomPid !== void 0 && !ports.isRunning(headroomPid);
295096
+ if (headroomPid === void 0 || crashed) {
295097
+ if (crashed) {
295098
+ ports.log(`claude-use headroom supervisor: headroom pid ${String(headroomPid)} died`);
295099
+ headroomPid = void 0;
295100
+ daemonPort = void 0;
295101
+ runningHash = void 0;
295102
+ writeHeadroomState(fs14, paths.headroomStateFile, {
295103
+ supervisorPid: ports.ownPid,
295104
+ version: version2,
295105
+ installedSource,
295106
+ mitmPort: mitm.port,
295107
+ ...sticky()
295108
+ });
295109
+ }
295110
+ if (consecutiveFailures >= HEADROOM_START_RETRY_BUDGET) {
295111
+ return fail(`headroom failed to become ready ${String(consecutiveFailures)} times in a row; giving up`);
295112
+ }
295113
+ if (installedSource !== config2.source && !ensureInstalled()) {
295114
+ return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
295115
+ }
295116
+ const previousSticky = lastPort;
295117
+ const port = lastPort !== void 0 && await ports.isPortFree(lastPort) ? lastPort : await ports.freePort();
295118
+ const pid = ports.spawnHeadroom(port, allowlist);
295119
+ const ready = await waitUntilReady(ports, port);
295120
+ if (ready) {
295121
+ consecutiveFailures = 0;
295122
+ headroomPid = pid;
295123
+ daemonPort = port;
295124
+ runningHash = allowlistHash;
295125
+ lastPort = port;
295126
+ if (previousSticky !== void 0 && port !== previousSticky) {
295127
+ ports.log(
295128
+ `claude-use headroom supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(port)} (sessions launched against the old port are stale until they relaunch)`
295129
+ );
295130
+ }
295131
+ writeHeadroomState(fs14, paths.headroomStateFile, {
295132
+ supervisorPid: ports.ownPid,
295133
+ headroomPid: pid,
295134
+ port,
295135
+ mitmPort: mitm.port,
295136
+ version: version2,
295137
+ allowlistHash,
295138
+ installedSource: config2.source,
295139
+ ...sticky()
295140
+ });
295141
+ fs14.removeRecursive(paths.headroomLockFile);
295142
+ idleSince = void 0;
295143
+ ports.log(`claude-use headroom supervisor: headroom pid ${String(pid)} ready on 127.0.0.1:${String(port)}`);
295144
+ } else {
295145
+ ports.stopProcess(pid);
295146
+ consecutiveFailures += 1;
295147
+ ports.log(
295148
+ `claude-use headroom supervisor: headroom did not become ready on port ${String(port)} (attempt ${String(consecutiveFailures)} of ${String(HEADROOM_START_RETRY_BUDGET)})`
295149
+ );
295150
+ await ports.sleep(backoffForAttempt(consecutiveFailures));
295151
+ continue;
295152
+ }
295153
+ } else {
295154
+ if (runningHash !== allowlistHash || installedSource !== config2.source) {
295155
+ if (listSessions(fs14, paths.headroomSessionsDir).length === 0) {
295156
+ ports.log("claude-use headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
295157
+ ports.stopProcess(headroomPid);
295158
+ headroomPid = void 0;
295159
+ daemonPort = void 0;
295160
+ runningHash = void 0;
295161
+ continue;
295162
+ }
295163
+ }
295164
+ const sessions = listSessions(fs14, paths.headroomSessionsDir);
295165
+ if (sessions.length === 0) {
295166
+ idleSince ??= ports.now();
295167
+ const idleMs = ports.now() - idleSince;
295168
+ if (idleMs >= config2.idleShutdownMinutes * MS_PER_MINUTE2) {
295169
+ ports.log(
295170
+ `claude-use headroom supervisor: no sessions for ${String(config2.idleShutdownMinutes)} minute(s); stopping headroom and the MITM proxy, and exiting`
295171
+ );
295172
+ ports.stopProcess(headroomPid);
295173
+ daemonPort = void 0;
295174
+ await mitm.close();
295175
+ writeHeadroomState(fs14, paths.headroomStateFile, {
295176
+ version: version2,
295177
+ ...sticky()
295178
+ });
295179
+ return 0;
295180
+ }
295181
+ } else {
295182
+ idleSince = void 0;
295183
+ }
295184
+ }
295185
+ await ports.sleep(HEADROOM_POLL_MS);
295186
+ }
295187
+ }
295188
+ function currentHeadroomAllowlist(fs14, paths) {
295189
+ const providers = readAllProviders(fs14, paths.providersDir).map((entry) => entry.provider);
295190
+ return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile))));
295191
+ }
295192
+ function allowlistOf(ports) {
295193
+ return currentHeadroomAllowlist(ports.fs, ports.paths);
295194
+ }
295195
+ async function waitUntilReady(ports, port) {
295196
+ const deadline = ports.now() + HEADROOM_READY_TIMEOUT_MS;
295197
+ for (; ; ) {
295198
+ if (await ports.ready(port)) {
295199
+ return true;
295200
+ }
295201
+ if (ports.now() >= deadline) {
295202
+ return false;
295203
+ }
295204
+ await ports.sleep(HEADROOM_POLL_MS);
295205
+ }
295024
295206
  }
295025
295207
 
295026
295208
  // src/headroom/commands.ts
@@ -295077,9 +295259,9 @@ function formatHeadroomStatus(status) {
295077
295259
  lines.push(`daemon log: ${status.logPath}${status.logExists ? "" : " (not created yet)"}`);
295078
295260
  return lines;
295079
295261
  }
295080
- async function realFreePort2() {
295262
+ async function realFreePort() {
295081
295263
  return await new Promise((resolve, reject) => {
295082
- const server2 = import_node_net3.default.createServer();
295264
+ const server2 = import_node_net2.default.createServer();
295083
295265
  server2.unref();
295084
295266
  server2.on("error", reject);
295085
295267
  server2.listen(0, "127.0.0.1", () => {
@@ -295097,7 +295279,7 @@ async function realFreePort2() {
295097
295279
  }
295098
295280
  var ownedHeadroom = /* @__PURE__ */ new Map();
295099
295281
  var exitedHeadroom = /* @__PURE__ */ new Set();
295100
- var READY_FETCH_TIMEOUT_MS2 = 2e3;
295282
+ var READY_FETCH_TIMEOUT_MS = 2e3;
295101
295283
  function headroomPidRunning(pid) {
295102
295284
  return !exitedHeadroom.has(pid) && realIsProcessRunning(pid);
295103
295285
  }
@@ -295121,13 +295303,13 @@ function realSupervisorPorts(paths) {
295121
295303
  });
295122
295304
  },
295123
295305
  isRunning: headroomPidRunning,
295124
- freePort: realFreePort2,
295306
+ freePort: realFreePort,
295125
295307
  isPortFree: realIsPortFree,
295126
295308
  spawnHeadroom: (port, allowlist) => {
295127
- import_node_fs11.default.mkdirSync(paths.logsDir, { recursive: true });
295128
- const logFd = import_node_fs11.default.openSync(paths.headroomLogPath, "a");
295309
+ import_node_fs12.default.mkdirSync(paths.logsDir, { recursive: true });
295310
+ const logFd = import_node_fs12.default.openSync(paths.headroomLogPath, "a");
295129
295311
  try {
295130
- const child = (0, import_node_child_process4.spawn)("headroom", ["proxy", "--host", "127.0.0.1", "--port", String(port)], {
295312
+ const child = (0, import_node_child_process3.spawn)("headroom", ["proxy", "--host", "127.0.0.1", "--port", String(port)], {
295131
295313
  detached: true,
295132
295314
  stdio: ["ignore", logFd, logFd],
295133
295315
  env: headroomSpawnEnv(process.env, allowlist)
@@ -295140,12 +295322,12 @@ function realSupervisorPorts(paths) {
295140
295322
  child.once("exit", (code, signal) => {
295141
295323
  ownedHeadroom.delete(pid);
295142
295324
  exitedHeadroom.add(pid);
295143
- import_node_fs11.default.appendFileSync(paths.headroomLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} claude-use headroom supervisor: headroom exited (${signal ?? `code ${String(code)}`})
295325
+ import_node_fs12.default.appendFileSync(paths.headroomLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} claude-use headroom supervisor: headroom exited (${signal ?? `code ${String(code)}`})
295144
295326
  `);
295145
295327
  });
295146
295328
  return pid;
295147
295329
  } finally {
295148
- import_node_fs11.default.closeSync(logFd);
295330
+ import_node_fs12.default.closeSync(logFd);
295149
295331
  }
295150
295332
  },
295151
295333
  stopProcess: (pid) => {
@@ -295158,7 +295340,7 @@ function realSupervisorPorts(paths) {
295158
295340
  now: () => Date.now()
295159
295341
  });
295160
295342
  if (outcome === "still-running") {
295161
- import_node_fs11.default.appendFileSync(
295343
+ import_node_fs12.default.appendFileSync(
295162
295344
  paths.headroomLogPath,
295163
295345
  `${(/* @__PURE__ */ new Date()).toISOString()} claude-use headroom supervisor: pid ${String(pid)} survived SIGKILL within its grace; it is stuck uninterruptibly
295164
295346
  `
@@ -295167,27 +295349,27 @@ function realSupervisorPorts(paths) {
295167
295349
  },
295168
295350
  ready: async (port) => {
295169
295351
  try {
295170
- const response = await fetch(`http://127.0.0.1:${String(port)}/readyz`, { signal: AbortSignal.timeout(READY_FETCH_TIMEOUT_MS2) });
295352
+ const response = await fetch(`http://127.0.0.1:${String(port)}/readyz`, { signal: AbortSignal.timeout(READY_FETCH_TIMEOUT_MS) });
295171
295353
  return response.ok;
295172
295354
  } catch {
295173
295355
  return false;
295174
295356
  }
295175
295357
  },
295176
295358
  install: (spec) => {
295177
- const result = (0, import_node_child_process4.spawnSync)("uv", ["tool", "install", spec], { encoding: "utf8" });
295359
+ const result = (0, import_node_child_process3.spawnSync)("uv", ["tool", "install", spec], { encoding: "utf8" });
295178
295360
  if (result.error !== void 0) {
295179
295361
  return { ok: false, error: `uv is not installed or not on PATH (${result.error.message})` };
295180
295362
  }
295181
295363
  if (result.stdout !== "") {
295182
- import_node_fs11.default.appendFileSync(paths.headroomLogPath, result.stdout);
295364
+ import_node_fs12.default.appendFileSync(paths.headroomLogPath, result.stdout);
295183
295365
  }
295184
295366
  if (result.stderr !== "") {
295185
- import_node_fs11.default.appendFileSync(paths.headroomLogPath, result.stderr);
295367
+ import_node_fs12.default.appendFileSync(paths.headroomLogPath, result.stderr);
295186
295368
  }
295187
295369
  return result.status === 0 ? { ok: true } : { ok: false, error: `uv tool install exited ${String(result.status)}` };
295188
295370
  },
295189
295371
  headroomVersion: () => {
295190
- const result = (0, import_node_child_process4.spawnSync)("headroom", ["--version"], { encoding: "utf8" });
295372
+ const result = (0, import_node_child_process3.spawnSync)("headroom", ["--version"], { encoding: "utf8" });
295191
295373
  return result.status === 0 ? result.stdout.trim() : void 0;
295192
295374
  },
295193
295375
  startMitm: async (preferredPort, headroomPort) => {
@@ -295205,8 +295387,8 @@ function realSupervisorPorts(paths) {
295205
295387
  );
295206
295388
  },
295207
295389
  log: (line) => {
295208
- import_node_fs11.default.mkdirSync(paths.logsDir, { recursive: true });
295209
- import_node_fs11.default.appendFileSync(paths.headroomLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
295390
+ import_node_fs12.default.mkdirSync(paths.logsDir, { recursive: true });
295391
+ import_node_fs12.default.appendFileSync(paths.headroomLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
295210
295392
  `);
295211
295393
  }
295212
295394
  };
@@ -295305,6 +295487,7 @@ function buildProgram(deps) {
295305
295487
  registerShimCommand(program2, deps);
295306
295488
  registerHeadroomCommand(program2, deps);
295307
295489
  registerCodexCommand(program2, deps);
295490
+ registerFrontDoorCommand(program2, deps);
295308
295491
  registerRunCommand(program2, deps.runClaude);
295309
295492
  registerCompletionCommand(program2);
295310
295493
  return program2;
@@ -295542,7 +295725,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
295542
295725
  return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
295543
295726
  }
295544
295727
  function runLauncher(params) {
295545
- const { paths, fs: fs13, spawn: spawn4, proc, log } = params;
295728
+ const { paths, fs: fs14, spawn: spawn3, proc, log } = params;
295546
295729
  const { env, argv } = proc;
295547
295730
  const parsedArgv = parseLauncherArgv(argv);
295548
295731
  const cliOverride = buildCliOverride({
@@ -295557,7 +295740,7 @@ function runLauncher(params) {
295557
295740
  argv0Identity: parsedArgv.identity,
295558
295741
  directoryPinnedIdentity: params.directoryPinnedIdentity,
295559
295742
  readActiveIdentityFile: () => {
295560
- const raw = fs13.readFileUtf8(paths.activeIdentityFile);
295743
+ const raw = fs14.readFileUtf8(paths.activeIdentityFile);
295561
295744
  if (raw === void 0) {
295562
295745
  return void 0;
295563
295746
  }
@@ -295591,7 +295774,7 @@ function runLauncher(params) {
295591
295774
  }
295592
295775
  let loadedIdentity;
295593
295776
  if (identityDecision.name !== void 0) {
295594
- loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs13);
295777
+ loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs14);
295595
295778
  if (loadedIdentity === void 0) {
295596
295779
  log.error(
295597
295780
  `claude-use: no identity named "${identityDecision.name}" (selected via ${identityDecision.source}). Run \`claude-use identity add ${identityDecision.name}\` first.`
@@ -295606,7 +295789,7 @@ function runLauncher(params) {
295606
295789
  identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
295607
295790
  globalDefaultConfigProfile: params.globalDefaultConfigProfile
295608
295791
  });
295609
- if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs13.readConfigFile(import_node_path26.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
295792
+ if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs14.readConfigFile(import_node_path26.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
295610
295793
  log.error(
295611
295794
  `claude-use: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`claude-use profile add ${configProfileDecision.name}\` first.`
295612
295795
  );
@@ -295615,7 +295798,7 @@ function runLauncher(params) {
295615
295798
  const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
295616
295799
  const provider = parsedArgv.provider === false ? void 0 : resolveProvider({
295617
295800
  paths,
295618
- port: fs13,
295801
+ port: fs14,
295619
295802
  env,
295620
295803
  ...params.credentials === void 0 ? {} : { credentials: params.credentials },
295621
295804
  ...parsedArgv.provider === void 0 ? {} : { cliProvider: parsedArgv.provider },
@@ -295708,20 +295891,20 @@ function runLauncher(params) {
295708
295891
  }
295709
295892
  });
295710
295893
  let routedProvider;
295711
- const codexPort = params.codex;
295894
+ const frontDoorPort = params.frontdoor;
295712
295895
  if (resolvedProvider !== void 0 && isCodexProvider(resolvedProvider.definition)) {
295713
- if (codexPort === void 0) {
295714
- log.error(`claude-use: provider ${resolvedProvider.name} is a codex provider, but this launcher has no codex daemon port wired; refusing to launch without it.`);
295896
+ if (frontDoorPort === void 0) {
295897
+ log.error(`claude-use: provider ${resolvedProvider.name} is a codex provider, but this launcher has no front-door daemon port wired; refusing to launch without it.`);
295715
295898
  proc.exit(1);
295716
295899
  } else {
295717
- const codex = codexPort.ensure();
295718
- routedProvider = { ...resolvedProvider, baseUrl: codexProviderBaseUrl(codex.port, resolvedProvider.name) };
295719
- log.info(`claude-use: provider ${resolvedProvider.name} served by the codex daemon on 127.0.0.1:${String(codex.port)}`);
295900
+ const frontDoor = frontDoorPort.ensure();
295901
+ routedProvider = { ...resolvedProvider, baseUrl: providerBaseUrl(frontDoor.port, resolvedProvider.name) };
295902
+ log.info(`claude-use: provider ${resolvedProvider.name} served by the front door on 127.0.0.1:${String(frontDoor.port)}`);
295720
295903
  }
295721
295904
  } else if (resolvedProvider !== void 0 && !isCodexProvider(resolvedProvider.definition)) {
295722
295905
  routedProvider = { ...resolvedProvider, baseUrl: resolvedProvider.definition.baseUrl };
295723
295906
  }
295724
- const codexRelease = routedProvider !== void 0 && isCodexProvider(routedProvider.definition) ? codexPort?.release : void 0;
295907
+ const frontDoorRelease = routedProvider !== void 0 && isCodexProvider(routedProvider.definition) ? frontDoorPort?.release : void 0;
295725
295908
  let headroom;
295726
295909
  const headroomPort = params.headroom;
295727
295910
  if (resolvedFlags.headroom && headroomPort !== void 0) {
@@ -295746,9 +295929,9 @@ function runLauncher(params) {
295746
295929
  ...identityCredential === void 0 ? {} : { identityCredential },
295747
295930
  ...headroom === void 0 ? {} : { headroom }
295748
295931
  });
295749
- const releases = [...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...codexRelease === void 0 ? [] : [codexRelease]];
295932
+ const releases = [...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
295750
295933
  if (releases.length === 0) {
295751
- spawnClaude({ bin: discovered.path, args: finalArgv, env: finalEnv, spawn: spawn4, proc });
295934
+ spawnClaude({ bin: discovered.path, args: finalArgv, env: finalEnv, spawn: spawn3, proc });
295752
295935
  }
295753
295936
  const releaseAll = () => {
295754
295937
  for (const release of releases) {
@@ -295760,7 +295943,7 @@ function runLauncher(params) {
295760
295943
  bin: discovered.path,
295761
295944
  args: finalArgv,
295762
295945
  env: finalEnv,
295763
- spawn: spawn4,
295946
+ spawn: spawn3,
295764
295947
  proc,
295765
295948
  beforeExit: releaseAll
295766
295949
  });
@@ -295865,7 +296048,7 @@ async function runClaude(argvOverride) {
295865
296048
  resolveClaudeBinary: realResolveClaudeBinary(resolveOwnInstallDirs(paths, realOwnExecutablePath())),
295866
296049
  farm: farm.runtime,
295867
296050
  headroom: realHeadroomPort(paths),
295868
- codex: realCodexPort(paths),
296051
+ frontdoor: realFrontDoorPort(paths),
295869
296052
  credentials: realCredentialPort,
295870
296053
  ...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
295871
296054
  ...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },