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.
- package/README.md +1 -0
- package/dist/cli.cjs +1065 -882
- 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
|
|
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 =
|
|
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(...
|
|
7679
|
+
function or(...fs14) {
|
|
7680
7680
|
return (...args) => {
|
|
7681
7681
|
let lastResult;
|
|
7682
|
-
for (const f of
|
|
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
|
|
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 (
|
|
9266
|
+
if (fs14 === void 0) {
|
|
9267
9267
|
try {
|
|
9268
|
-
|
|
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 (!
|
|
9280
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
9302
|
+
fs14.writeSync(traceFd, `
|
|
9303
9303
|
]
|
|
9304
9304
|
`);
|
|
9305
|
-
|
|
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
|
-
|
|
9377
|
+
fs14.writeSync(traceFd, `,
|
|
9378
9378
|
{"pid":1,"tid":1,"ph":"${eventType}","cat":"${phase}","ts":${time3},"name":"${name}"`);
|
|
9379
|
-
if (extras)
|
|
9380
|
-
if (args)
|
|
9381
|
-
|
|
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 =
|
|
9403
|
+
const typesFd = fs14.openSync(typesPath, "w");
|
|
9404
9404
|
const recursionIdentityMap = /* @__PURE__ */ new Map();
|
|
9405
|
-
|
|
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
|
-
|
|
9501
|
+
fs14.writeSync(typesFd, JSON.stringify(descriptor));
|
|
9502
9502
|
if (i2 < numTypes - 1) {
|
|
9503
|
-
|
|
9503
|
+
fs14.writeSync(typesFd, ",\n");
|
|
9504
9504
|
}
|
|
9505
9505
|
}
|
|
9506
|
-
|
|
9507
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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
|
|
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 =
|
|
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
|
|
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" ||
|
|
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(
|
|
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
|
|
228299
|
+
var net4 = require("node:net");
|
|
228300
228300
|
var { InvalidArgumentError: InvalidArgumentError2 } = require_errors();
|
|
228301
228301
|
function parseAddress(address) {
|
|
228302
|
-
if (
|
|
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 (
|
|
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 (
|
|
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
|
|
285663
|
-
var
|
|
285664
|
-
/** How long the
|
|
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
|
-
|
|
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(
|
|
285747
|
+
function readHeadroomState(fs14, stateFile) {
|
|
285748
285748
|
try {
|
|
285749
|
-
return parseJson(
|
|
285749
|
+
return parseJson(fs14.readFileUtf8(stateFile), HeadroomStateSchema);
|
|
285750
285750
|
} catch {
|
|
285751
285751
|
return void 0;
|
|
285752
285752
|
}
|
|
285753
285753
|
}
|
|
285754
|
-
function writeHeadroomState(
|
|
285755
|
-
|
|
285756
|
-
|
|
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,
|
|
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 &&
|
|
285777
|
-
upstreams.push({ baseUrl:
|
|
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(
|
|
285784
|
+
function readAllProviders(fs14, providersDir) {
|
|
285785
285785
|
const result = [];
|
|
285786
|
-
for (const name of
|
|
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(
|
|
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(
|
|
285802
|
-
|
|
285803
|
-
|
|
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(
|
|
285807
|
-
|
|
285806
|
+
function removeSession(fs14, sessionsDir, pid) {
|
|
285807
|
+
fs14.removeRecursive(import_node_path5.default.join(sessionsDir, `${String(pid)}.json`));
|
|
285808
285808
|
}
|
|
285809
|
-
function listSessions(
|
|
285809
|
+
function listSessions(fs14, sessionsDir) {
|
|
285810
285810
|
const sessions = [];
|
|
285811
|
-
for (const name of
|
|
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(
|
|
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(
|
|
285826
|
+
function pruneDeadSessions(fs14, sessionsDir, isRunning) {
|
|
285827
285827
|
const removed = [];
|
|
285828
|
-
for (const session of listSessions(
|
|
285828
|
+
for (const session of listSessions(fs14, sessionsDir)) {
|
|
285829
285829
|
if (!isRunning(session.pid)) {
|
|
285830
|
-
removeSession(
|
|
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(
|
|
285836
|
+
function readStartLock(fs14, lockFile) {
|
|
285837
285837
|
try {
|
|
285838
|
-
return parseJson(
|
|
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(
|
|
289004
|
-
const raw =
|
|
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(
|
|
289062
|
+
function listSubtree(fs14, root, rel) {
|
|
289063
289063
|
const absolute = import_node_path11.default.join(root, rel);
|
|
289064
|
-
const stat =
|
|
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 = [...
|
|
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 =
|
|
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(
|
|
289089
|
+
function reconciliationScope(fs14, farmRoot, manifest) {
|
|
289090
289090
|
if (manifest !== void 0) {
|
|
289091
289091
|
return topLevelScopeRoots(manifest.materialised);
|
|
289092
289092
|
}
|
|
289093
|
-
return [...
|
|
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(
|
|
289096
|
-
return scopeRoots.flatMap((root) => listSubtree(
|
|
289095
|
+
function collectFarmListing(fs14, farmRoot, scopeRoots) {
|
|
289096
|
+
return scopeRoots.flatMap((root) => listSubtree(fs14, farmRoot, root));
|
|
289097
289097
|
}
|
|
289098
|
-
function collectCanonicalCounterparts(
|
|
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 =
|
|
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 =
|
|
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,
|
|
290596
|
-
return loadConfigFile(import_node_path17.default.join(identitiesDir, name, "identity.json"), IdentitySchema,
|
|
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
|
-
|
|
290637
|
-
|
|
290638
|
-
|
|
290639
|
-
|
|
290640
|
-
|
|
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.
|
|
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/
|
|
292306
|
+
// src/frontdoor/state.ts
|
|
292309
292307
|
var import_node_path22 = __toESM(require("node:path"), 1);
|
|
292310
|
-
var
|
|
292311
|
-
/** The supervisor process
|
|
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
|
|
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
|
-
/**
|
|
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 `
|
|
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
|
|
292320
|
+
function readFrontDoorState(fs14, stateFile) {
|
|
292323
292321
|
let raw;
|
|
292324
292322
|
try {
|
|
292325
|
-
raw =
|
|
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 =
|
|
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
|
|
292340
|
-
|
|
292341
|
-
|
|
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
|
|
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/
|
|
292777
|
-
var
|
|
292778
|
-
|
|
292779
|
-
|
|
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 = "
|
|
292709
|
+
this.name = "FrontDoorStartError";
|
|
292783
292710
|
}
|
|
292784
292711
|
};
|
|
292785
|
-
function
|
|
292712
|
+
function ensureFrontDoor(params) {
|
|
292786
292713
|
const { paths, ports } = params;
|
|
292787
|
-
const deadline = ports.now() +
|
|
292714
|
+
const deadline = ports.now() + FRONTDOOR_START_TIMEOUT_MS;
|
|
292788
292715
|
let spawned = false;
|
|
292789
292716
|
for (; ; ) {
|
|
292790
|
-
const state =
|
|
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
|
|
292793
|
-
writeSession(ports.fs, paths.
|
|
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
|
|
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.
|
|
292801
|
-
const created = ports.fs.writeFileExclusive(paths.
|
|
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.
|
|
292734
|
+
const lock = readStartLock(ports.fs, paths.frontdoorLockFile);
|
|
292808
292735
|
if (lock === void 0 || !ports.isRunning(lock.pid)) {
|
|
292809
|
-
ports.fs.removeRecursive(paths.
|
|
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
|
|
292817
|
-
`claude-use: the
|
|
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(
|
|
292747
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
292821
292748
|
}
|
|
292822
292749
|
}
|
|
292823
292750
|
|
|
292824
|
-
// src/
|
|
292825
|
-
var
|
|
292826
|
-
|
|
292827
|
-
|
|
292828
|
-
|
|
292829
|
-
|
|
292830
|
-
|
|
292831
|
-
|
|
292832
|
-
|
|
292833
|
-
|
|
292834
|
-
|
|
292835
|
-
|
|
292836
|
-
|
|
292837
|
-
|
|
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
|
-
|
|
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
|
|
293260
|
-
return JSON.stringify({ type: "error", error: { type:
|
|
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:
|
|
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: ${
|
|
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 =
|
|
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/
|
|
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
|
|
293462
|
-
response.
|
|
293442
|
+
async function writeRouteResponse(routed, response, signal) {
|
|
293443
|
+
response.start(routed.status, routed.headers);
|
|
293463
293444
|
if (typeof routed.body === "string") {
|
|
293464
|
-
response.
|
|
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 (
|
|
293450
|
+
if (signal.aborted) {
|
|
293469
293451
|
return;
|
|
293470
293452
|
}
|
|
293471
|
-
|
|
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
|
|
293486
|
-
|
|
293487
|
-
|
|
293488
|
-
|
|
293489
|
-
|
|
293490
|
-
|
|
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.
|
|
293501
|
-
response.
|
|
293502
|
-
|
|
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
|
|
293506
|
-
|
|
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
|
|
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 ?? "?"} ${
|
|
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
|
|
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/
|
|
293524
|
-
var
|
|
293525
|
-
var
|
|
293526
|
-
var
|
|
293527
|
-
|
|
293528
|
-
|
|
293529
|
-
const
|
|
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
|
-
|
|
293535
|
-
|
|
293536
|
-
ports.log(`claude-use
|
|
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
|
-
|
|
293540
|
-
const
|
|
293541
|
-
|
|
293542
|
-
|
|
293543
|
-
ports.
|
|
293544
|
-
}
|
|
293545
|
-
|
|
293546
|
-
|
|
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
|
|
293655
|
+
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
293552
293656
|
}
|
|
293553
293657
|
ticks += 1;
|
|
293554
|
-
pruneDeadSessions(
|
|
293555
|
-
|
|
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 *
|
|
293591
|
-
ports.log(`claude-use
|
|
293592
|
-
|
|
293593
|
-
|
|
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(
|
|
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/
|
|
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
|
-
|
|
293625
|
-
|
|
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
|
-
|
|
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:
|
|
293757
|
-
|
|
293758
|
-
|
|
293759
|
-
|
|
293760
|
-
|
|
293761
|
-
|
|
293762
|
-
|
|
293763
|
-
|
|
293764
|
-
|
|
293765
|
-
|
|
293766
|
-
|
|
293767
|
-
|
|
293768
|
-
|
|
293769
|
-
|
|
293770
|
-
|
|
293771
|
-
|
|
293772
|
-
|
|
293773
|
-
|
|
293774
|
-
|
|
293775
|
-
|
|
293776
|
-
|
|
293777
|
-
|
|
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
|
|
293720
|
+
function realFrontDoorPort(paths) {
|
|
293807
293721
|
return {
|
|
293808
|
-
ensure: () =>
|
|
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, "
|
|
293730
|
+
spawnSupervisor: (layout) => spawnDetachedSupervisor(layout, "__frontdoor-supervisor", layout.frontdoorLogPath)
|
|
293817
293731
|
}
|
|
293818
293732
|
}),
|
|
293819
293733
|
release: () => {
|
|
293820
|
-
removeSession(realFarmFs, paths.
|
|
293734
|
+
removeSession(realFarmFs, paths.frontdoorSessionsDir, process.pid);
|
|
293821
293735
|
}
|
|
293822
293736
|
};
|
|
293823
293737
|
}
|
|
293824
|
-
function
|
|
293825
|
-
const state =
|
|
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
|
-
|
|
293830
|
-
|
|
293831
|
-
|
|
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
|
|
293748
|
+
function formatFrontDoorStatus(status) {
|
|
293836
293749
|
const lines = [];
|
|
293837
|
-
|
|
293838
|
-
|
|
293839
|
-
|
|
293840
|
-
|
|
293841
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
293867
|
-
const status =
|
|
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
|
|
293784
|
+
for (const line of formatFrontDoorStatus(status)) {
|
|
293873
293785
|
console.log(line);
|
|
293874
293786
|
}
|
|
293875
293787
|
}),
|
|
293876
|
-
["claude-use
|
|
293788
|
+
["claude-use frontdoor status", "claude-use frontdoor status --json"]
|
|
293877
293789
|
);
|
|
293878
|
-
program2.command("
|
|
293879
|
-
const idleShutdownMinutes = readGlobalConfig(paths)?.
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
294563
|
-
return { name, path:
|
|
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 &&
|
|
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
|
|
294634
|
-
var
|
|
294635
|
-
var
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
-
|
|
295019
|
-
|
|
295020
|
-
|
|
295021
|
-
|
|
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
|
|
295262
|
+
async function realFreePort() {
|
|
295081
295263
|
return await new Promise((resolve, reject) => {
|
|
295082
|
-
const server2 =
|
|
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
|
|
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:
|
|
295306
|
+
freePort: realFreePort,
|
|
295125
295307
|
isPortFree: realIsPortFree,
|
|
295126
295308
|
spawnHeadroom: (port, allowlist) => {
|
|
295127
|
-
|
|
295128
|
-
const logFd =
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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,
|
|
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
|
-
|
|
295364
|
+
import_node_fs12.default.appendFileSync(paths.headroomLogPath, result.stdout);
|
|
295183
295365
|
}
|
|
295184
295366
|
if (result.stderr !== "") {
|
|
295185
|
-
|
|
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,
|
|
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
|
-
|
|
295209
|
-
|
|
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:
|
|
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 =
|
|
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,
|
|
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 &&
|
|
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:
|
|
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
|
|
295894
|
+
const frontDoorPort = params.frontdoor;
|
|
295712
295895
|
if (resolvedProvider !== void 0 && isCodexProvider(resolvedProvider.definition)) {
|
|
295713
|
-
if (
|
|
295714
|
-
log.error(`claude-use: provider ${resolvedProvider.name} is a codex provider, but this launcher has no
|
|
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
|
|
295718
|
-
routedProvider = { ...resolvedProvider, baseUrl:
|
|
295719
|
-
log.info(`claude-use: provider ${resolvedProvider.name} served by the
|
|
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
|
|
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], ...
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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 },
|