claude-use 9.12.0 → 9.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +225 -28
- package/dist/index.cjs +206 -25
- package/dist/index.mjs +206 -25
- package/dist/types/index.d.ts +60 -7
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2595,7 +2595,7 @@ function listFrontDoorSessions(fs12, sessionsDir) {
|
|
|
2595
2595
|
try {
|
|
2596
2596
|
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs12.readFileUtf8(import_node_path8.default.join(sessionsDir, name)) ?? ""));
|
|
2597
2597
|
if (parsed.success) {
|
|
2598
|
-
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
|
|
2598
|
+
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
|
|
2599
2599
|
}
|
|
2600
2600
|
} catch {
|
|
2601
2601
|
continue;
|
|
@@ -2623,7 +2623,7 @@ var init_state = __esm({
|
|
|
2623
2623
|
import_node_path8 = __toESM(require("node:path"), 1);
|
|
2624
2624
|
import_zod3 = require("zod");
|
|
2625
2625
|
FRONT_DOOR_PROTOCOL = 3;
|
|
2626
|
-
FrontDoorSessionSchema = import_zod3.z.strictObject({ pid: import_zod3.z.number().int().positive(), startedAt: import_zod3.z.number(), token: import_zod3.z.string().min(1) });
|
|
2626
|
+
FrontDoorSessionSchema = import_zod3.z.strictObject({ pid: import_zod3.z.number().int().positive(), startedAt: import_zod3.z.number(), token: import_zod3.z.string().min(1), supervisorPid: import_zod3.z.number().int().positive().optional() });
|
|
2627
2627
|
FrontDoorStateSchema = import_zod3.z.strictObject({
|
|
2628
2628
|
/**
|
|
2629
2629
|
* The launcher-to-door wire protocol this supervisor speaks, written once it is serving; absent in state written by a release that predates the field, which `ensureFrontDoor` reads as protocol 0. A launcher replaces a door whose protocol is lower than its own (see `FRONT_DOOR_PROTOCOL`).
|
|
@@ -2663,7 +2663,7 @@ var init_package = __esm({
|
|
|
2663
2663
|
"package.json"() {
|
|
2664
2664
|
package_default = {
|
|
2665
2665
|
name: "claude-use",
|
|
2666
|
-
version: "9.
|
|
2666
|
+
version: "9.13.0",
|
|
2667
2667
|
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.",
|
|
2668
2668
|
license: "MIT",
|
|
2669
2669
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -2766,6 +2766,36 @@ var init_package = __esm({
|
|
|
2766
2766
|
}
|
|
2767
2767
|
});
|
|
2768
2768
|
|
|
2769
|
+
// src/frontdoor/supervisorProcesses.ts
|
|
2770
|
+
function parseFrontDoorSupervisorPids(psOutput) {
|
|
2771
|
+
const pids = [];
|
|
2772
|
+
for (const line of psOutput.split("\n")) {
|
|
2773
|
+
const [pidText, ...argumentsList] = line.trim().split(/\s+/);
|
|
2774
|
+
const pid = Number(pidText);
|
|
2775
|
+
if (Number.isInteger(pid) && pid > 0 && argumentsList.includes(FRONT_DOOR_SUPERVISOR_ARGUMENT)) {
|
|
2776
|
+
pids.push(pid);
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
return pids.sort((a, b) => a - b);
|
|
2780
|
+
}
|
|
2781
|
+
function listFrontDoorSupervisors(run, uid) {
|
|
2782
|
+
const result = run.run("ps", ["-U", String(uid), "-o", "pid=,command="]);
|
|
2783
|
+
if (result.status === null) {
|
|
2784
|
+
return { ok: false, message: "ps could not be run" };
|
|
2785
|
+
}
|
|
2786
|
+
if (result.status !== 0) {
|
|
2787
|
+
return { ok: false, message: `ps exited ${String(result.status)}${result.stderr.trim() === "" ? "" : `: ${result.stderr.trim()}`}` };
|
|
2788
|
+
}
|
|
2789
|
+
return { ok: true, pids: parseFrontDoorSupervisorPids(result.stdout) };
|
|
2790
|
+
}
|
|
2791
|
+
var FRONT_DOOR_SUPERVISOR_ARGUMENT;
|
|
2792
|
+
var init_supervisorProcesses = __esm({
|
|
2793
|
+
"src/frontdoor/supervisorProcesses.ts"() {
|
|
2794
|
+
"use strict";
|
|
2795
|
+
FRONT_DOOR_SUPERVISOR_ARGUMENT = "__frontdoor-supervisor";
|
|
2796
|
+
}
|
|
2797
|
+
});
|
|
2798
|
+
|
|
2769
2799
|
// src/headroom/state.ts
|
|
2770
2800
|
function parseJson(raw, schema) {
|
|
2771
2801
|
if (raw === void 0 || raw.trim() === "") {
|
|
@@ -3363,9 +3393,15 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3363
3393
|
await ports.sleep(HEADROOM_POLL_MS);
|
|
3364
3394
|
}
|
|
3365
3395
|
}
|
|
3396
|
+
function currentHeadroomAllowlistInputs(fs12, paths) {
|
|
3397
|
+
return {
|
|
3398
|
+
providers: readAllProviders(fs12, paths.providersDir).map((entry) => entry.provider),
|
|
3399
|
+
frontDoorOrigin: frontDoorOrigin(readFrontDoorState(fs12, paths.frontdoorStateFile))
|
|
3400
|
+
};
|
|
3401
|
+
}
|
|
3366
3402
|
function currentHeadroomAllowlist(fs12, paths) {
|
|
3367
|
-
const
|
|
3368
|
-
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin
|
|
3403
|
+
const inputs = currentHeadroomAllowlistInputs(fs12, paths);
|
|
3404
|
+
return headroomAllowlist(headroomUpstreams(inputs.providers, inputs.frontDoorOrigin));
|
|
3369
3405
|
}
|
|
3370
3406
|
function allowlistOf(ports) {
|
|
3371
3407
|
return currentHeadroomAllowlist(ports.fs, ports.paths);
|
|
@@ -3427,6 +3463,10 @@ function realIsProcessZombie(pid) {
|
|
|
3427
3463
|
function realIsProcessRunning(pid) {
|
|
3428
3464
|
return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
|
|
3429
3465
|
}
|
|
3466
|
+
function realIsFrontDoorSupervisor(pid) {
|
|
3467
|
+
const result = (0, import_node_child_process2.spawnSync)("ps", ["-o", "pid=,command=", "-p", String(pid)], { encoding: "utf8" });
|
|
3468
|
+
return result.status === 0 && parseFrontDoorSupervisorPids(result.stdout).includes(pid);
|
|
3469
|
+
}
|
|
3430
3470
|
function expandHome2(filePath) {
|
|
3431
3471
|
return filePath.startsWith("~/") ? import_node_path13.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
|
|
3432
3472
|
}
|
|
@@ -3636,6 +3676,7 @@ var init_realPorts = __esm({
|
|
|
3636
3676
|
import_node_sea = require("node:sea");
|
|
3637
3677
|
init_load();
|
|
3638
3678
|
init_versionDiscovery();
|
|
3679
|
+
init_supervisorProcesses();
|
|
3639
3680
|
init_ensure();
|
|
3640
3681
|
init_supervisor();
|
|
3641
3682
|
init_state2();
|
|
@@ -4671,7 +4712,7 @@ function assessIdentity(member, nowMs) {
|
|
|
4671
4712
|
);
|
|
4672
4713
|
if (blockedUntil > nowMs) {
|
|
4673
4714
|
if (unified.overageStatus === "allowed") {
|
|
4674
|
-
return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
|
|
4715
|
+
return { candidate: { ...base, class: "pay-per-use", planReturnsAtMs: blockedUntil, reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)}), continues as extra usage`, ...windowReasons, ...planReasons] } };
|
|
4675
4716
|
}
|
|
4676
4717
|
return { candidate: { ...base, class: "ineligible", blockedUntilMs: blockedUntil, reasons: [`refused until ${new Date(blockedUntil).toISOString()} (in ${formatAge(blockedUntil - nowMs)})`, ...unified.fallbackAvailable === true ? ["a fallback is on offer, so requests for some models may still be served"] : [], ...windowReasons, ...overageReasons, ...planReasons] } };
|
|
4677
4718
|
}
|
|
@@ -4786,7 +4827,8 @@ function rankPool(input) {
|
|
|
4786
4827
|
return {
|
|
4787
4828
|
candidates: ordered,
|
|
4788
4829
|
...pick === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick },
|
|
4789
|
-
...movedOff === void 0 || pick === void 0 ? {} : { movedOff }
|
|
4830
|
+
...movedOff === void 0 || pick === void 0 ? {} : { movedOff },
|
|
4831
|
+
...pick?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick.identity, atMs: pick.planReturnsAtMs } }
|
|
4790
4832
|
};
|
|
4791
4833
|
}
|
|
4792
4834
|
var MS_PER_SECOND4, MS_PER_HOUR2, HOURS_PER_DAY2, FIVE_HOURS, PROMPT_CACHE_TTL_HOURS, PERCENT, SEVEN_DAYS, FIVE_HOUR_WINDOW_MS, SEVEN_DAY_WINDOW_MS, PROMPT_CACHE_TTL_MS, CLASS_ORDER;
|
|
@@ -6166,32 +6208,50 @@ function ensureFrontDoor(params) {
|
|
|
6166
6208
|
let replaced = false;
|
|
6167
6209
|
const distrusted = /* @__PURE__ */ new Set();
|
|
6168
6210
|
let lastRejection;
|
|
6211
|
+
const verifyWithRetry = (port) => {
|
|
6212
|
+
let verdict = ports.verifyListener(port);
|
|
6213
|
+
for (let attempt = 1; !verdict.ok && attempt < FRONTDOOR_PROBE_ATTEMPTS; attempt += 1) {
|
|
6214
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6215
|
+
verdict = ports.verifyListener(port);
|
|
6216
|
+
}
|
|
6217
|
+
return verdict;
|
|
6218
|
+
};
|
|
6219
|
+
const stopAndAwaitExit = (supervisorPid, failure) => {
|
|
6220
|
+
ports.stopSupervisor(supervisorPid);
|
|
6221
|
+
while (ports.isRunning(supervisorPid)) {
|
|
6222
|
+
if (ports.now() >= deadline) {
|
|
6223
|
+
throw new FrontDoorStartError(`${failure}. Daemon log: ${paths.frontdoorLogPath}`);
|
|
6224
|
+
}
|
|
6225
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6226
|
+
}
|
|
6227
|
+
};
|
|
6169
6228
|
for (; ; ) {
|
|
6170
6229
|
const state = readFrontDoorState(ports.fs, paths.frontdoorStateFile);
|
|
6171
6230
|
const supervisorPid = state?.supervisorPid;
|
|
6172
6231
|
if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
|
|
6173
6232
|
if (state?.port !== void 0 && state.connectPort !== void 0) {
|
|
6174
|
-
const verdict =
|
|
6233
|
+
const verdict = verifyWithRetry(state.port);
|
|
6175
6234
|
if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
}
|
|
6181
|
-
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6182
|
-
}
|
|
6235
|
+
stopAndAwaitExit(
|
|
6236
|
+
supervisorPid,
|
|
6237
|
+
`the front door (pid ${String(supervisorPid)}, protocol ${String(state.protocol ?? 0)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit`
|
|
6238
|
+
);
|
|
6183
6239
|
replaced = true;
|
|
6184
6240
|
continue;
|
|
6185
6241
|
}
|
|
6186
6242
|
if (verdict.ok) {
|
|
6187
6243
|
const token = (0, import_node_crypto9.randomUUID)();
|
|
6188
|
-
writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token });
|
|
6244
|
+
writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid });
|
|
6189
6245
|
return { port: state.port, connectPort: state.connectPort, token };
|
|
6190
6246
|
}
|
|
6191
6247
|
lastRejection = `the listener on 127.0.0.1:${String(state.port)} (recorded for pid ${String(supervisorPid)}) failed authentication: ${verdict.reason}`;
|
|
6192
6248
|
if (spawned) {
|
|
6193
6249
|
throw new FrontDoorStartError(`${lastRejection}; refusing to send this session's credentials to it. Daemon log: ${paths.frontdoorLogPath}`);
|
|
6194
6250
|
}
|
|
6251
|
+
if (ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
6252
|
+
stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
6253
|
+
continue;
|
|
6254
|
+
}
|
|
6195
6255
|
distrusted.add(supervisorPid);
|
|
6196
6256
|
continue;
|
|
6197
6257
|
}
|
|
@@ -6222,7 +6282,7 @@ function ensureFrontDoor(params) {
|
|
|
6222
6282
|
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6223
6283
|
}
|
|
6224
6284
|
}
|
|
6225
|
-
var import_node_crypto9, FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FrontDoorStartError;
|
|
6285
|
+
var import_node_crypto9, FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FRONTDOOR_PROBE_ATTEMPTS, FrontDoorStartError;
|
|
6226
6286
|
var init_ensure2 = __esm({
|
|
6227
6287
|
"src/frontdoor/ensure.ts"() {
|
|
6228
6288
|
"use strict";
|
|
@@ -6232,6 +6292,7 @@ var init_ensure2 = __esm({
|
|
|
6232
6292
|
init_state();
|
|
6233
6293
|
FRONTDOOR_START_TIMEOUT_MS = 3e4;
|
|
6234
6294
|
FRONTDOOR_LAUNCHER_POLL_MS = 100;
|
|
6295
|
+
FRONTDOOR_PROBE_ATTEMPTS = 3;
|
|
6235
6296
|
FrontDoorStartError = class extends CliError {
|
|
6236
6297
|
constructor(message) {
|
|
6237
6298
|
super(message);
|
|
@@ -6715,7 +6776,12 @@ function resolvePoolLaunch(params) {
|
|
|
6715
6776
|
if (graph.ranking.candidates.length === 0) {
|
|
6716
6777
|
return { ok: false, message: `agent-shim: no member of pool "${poolName}" is an existing identity.` };
|
|
6717
6778
|
}
|
|
6718
|
-
const { pick, earliestReturn, movedOff } = graph.ranking;
|
|
6779
|
+
const { pick, earliestReturn, movedOff, planReturn } = graph.ranking;
|
|
6780
|
+
if (pick !== void 0 && params.wait && planReturn !== void 0) {
|
|
6781
|
+
log.info(`agent-shim: pool "${poolName}" would continue ${planReturn.identity} on extra usage; waiting until ${new Date(planReturn.atMs).toISOString()} for its plan window`);
|
|
6782
|
+
params.sleep(Math.max(planReturn.atMs - nowMs, 0));
|
|
6783
|
+
continue;
|
|
6784
|
+
}
|
|
6719
6785
|
if (pick !== void 0) {
|
|
6720
6786
|
if (params.recordPick) {
|
|
6721
6787
|
recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
|
|
@@ -7418,6 +7484,7 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
7418
7484
|
now: () => Date.now(),
|
|
7419
7485
|
sleep: realSleepSync,
|
|
7420
7486
|
spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
|
|
7487
|
+
isFrontDoorSupervisor: realIsFrontDoorSupervisor,
|
|
7421
7488
|
stopSupervisor: (pid) => {
|
|
7422
7489
|
process.kill(pid, "SIGTERM");
|
|
7423
7490
|
},
|
|
@@ -8676,16 +8743,27 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
8676
8743
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http3.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
|
|
8677
8744
|
let idleSince;
|
|
8678
8745
|
let ticks = 0;
|
|
8746
|
+
const supersedingOwner = () => {
|
|
8747
|
+
const owner = readFrontDoorState(fs12, paths.frontdoorStateFile)?.supervisorPid;
|
|
8748
|
+
return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
|
|
8749
|
+
};
|
|
8750
|
+
let supersededBy;
|
|
8751
|
+
let served;
|
|
8679
8752
|
const binaryReplaced = () => {
|
|
8680
8753
|
const current = ports.statOwnExecutable();
|
|
8681
8754
|
return current !== void 0 && servingBinary !== void 0 && (current.dev !== servingBinary.dev || current.ino !== servingBinary.ino || current.size !== servingBinary.size || current.mtimeMs !== servingBinary.mtimeMs);
|
|
8682
8755
|
};
|
|
8683
|
-
const
|
|
8756
|
+
const closeServing = async () => {
|
|
8684
8757
|
await direct.close();
|
|
8685
8758
|
await connect3.close();
|
|
8686
8759
|
await http3.close();
|
|
8687
8760
|
ports.closeRcStreamHub();
|
|
8688
|
-
|
|
8761
|
+
};
|
|
8762
|
+
const shutdown = async () => {
|
|
8763
|
+
await closeServing();
|
|
8764
|
+
if (supersedingOwner() === void 0) {
|
|
8765
|
+
writeFrontDoorState(fs12, paths.frontdoorStateFile, sticky());
|
|
8766
|
+
}
|
|
8689
8767
|
return 0;
|
|
8690
8768
|
};
|
|
8691
8769
|
for (; ; ) {
|
|
@@ -8698,7 +8776,28 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
8698
8776
|
ports.observeLaunchRegistry(listed, pruned);
|
|
8699
8777
|
ports.checkQuotaExpiry();
|
|
8700
8778
|
const prunedPids = new Set(pruned);
|
|
8701
|
-
|
|
8779
|
+
const live = listed.filter((session) => !prunedPids.has(session.pid));
|
|
8780
|
+
if (supersededBy === void 0) {
|
|
8781
|
+
supersededBy = supersedingOwner();
|
|
8782
|
+
if (supersededBy !== void 0) {
|
|
8783
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: supervisor ${String(supersededBy)} now owns the front door; taking no new sessions and exiting once the sessions this door serves have ended`);
|
|
8784
|
+
ports.doorHealth.superseded(supersededBy);
|
|
8785
|
+
await ports.sleep(FRONTDOOR_POLL_MS);
|
|
8786
|
+
continue;
|
|
8787
|
+
}
|
|
8788
|
+
} else {
|
|
8789
|
+
const owner = supersededBy;
|
|
8790
|
+
served = (served ?? live.filter((session) => session.pid !== ports.ownPid && session.pid !== owner && (session.supervisorPid === void 0 || session.supervisorPid === ports.ownPid))).filter((own) => live.some((session) => session.pid === own.pid && session.startedAt === own.startedAt));
|
|
8791
|
+
if (served.length === 0) {
|
|
8792
|
+
ports.log("agent-shim frontdoor supervisor: the sessions this superseded door served have ended; closing the front door and exiting");
|
|
8793
|
+
ports.doorHealth.drained();
|
|
8794
|
+
await closeServing();
|
|
8795
|
+
return 0;
|
|
8796
|
+
}
|
|
8797
|
+
await ports.sleep(FRONTDOOR_POLL_MS);
|
|
8798
|
+
continue;
|
|
8799
|
+
}
|
|
8800
|
+
if (live.length === 0) {
|
|
8702
8801
|
if (ticks > 1 && binaryReplaced()) {
|
|
8703
8802
|
ports.log("agent-shim frontdoor supervisor: the installed binary changed and no sessions are live; turning the door over for the next launch");
|
|
8704
8803
|
ports.doorHealth.binaryTurnover();
|
|
@@ -12852,7 +12951,55 @@ init_credential();
|
|
|
12852
12951
|
init_credentialCache();
|
|
12853
12952
|
init_realCredentialCache();
|
|
12854
12953
|
init_source();
|
|
12954
|
+
|
|
12955
|
+
// src/headroom/allowlistDrift.ts
|
|
12956
|
+
init_state2();
|
|
12957
|
+
function diagnoseAllowlistDrift(params) {
|
|
12958
|
+
const { recordedHash, providers, frontDoorOrigin: frontDoorOrigin2 } = params;
|
|
12959
|
+
if (recordedHash === void 0 || recordedHash === hashAllowlist(headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin2)))) {
|
|
12960
|
+
return void 0;
|
|
12961
|
+
}
|
|
12962
|
+
const originIsInput = providers.length > 0 && frontDoorOrigin2 !== void 0;
|
|
12963
|
+
if (!originIsInput) {
|
|
12964
|
+
return ["provider-files"];
|
|
12965
|
+
}
|
|
12966
|
+
return recordedHash === hashAllowlist(headroomAllowlist(headroomUpstreams(providers, void 0))) ? ["front-door-origin"] : ["provider-files", "front-door-origin"];
|
|
12967
|
+
}
|
|
12968
|
+
|
|
12969
|
+
// src/doctorReport.ts
|
|
12855
12970
|
init_state2();
|
|
12971
|
+
init_supervisor();
|
|
12972
|
+
init_state();
|
|
12973
|
+
|
|
12974
|
+
// src/doctorFrontDoor.ts
|
|
12975
|
+
function pushFrontDoor(push, supervisors, registeredPid) {
|
|
12976
|
+
if (!supervisors.ok) {
|
|
12977
|
+
push("frontdoor", "warn", `Could not list processes to look for duplicate front door supervisors: ${supervisors.message}.`);
|
|
12978
|
+
return;
|
|
12979
|
+
}
|
|
12980
|
+
const { pids } = supervisors;
|
|
12981
|
+
if (pids.length === 0) {
|
|
12982
|
+
push("frontdoor", "pass", "No front door supervisor is running.");
|
|
12983
|
+
return;
|
|
12984
|
+
}
|
|
12985
|
+
const [only, ...rest] = pids;
|
|
12986
|
+
if (only !== void 0 && rest.length === 0) {
|
|
12987
|
+
push("frontdoor", "pass", `One front door supervisor is running (pid ${String(only)}).`);
|
|
12988
|
+
return;
|
|
12989
|
+
}
|
|
12990
|
+
const serving = registeredPid !== void 0 && pids.includes(registeredPid) ? `The front door state file names pid ${String(registeredPid)} as the serving supervisor.` : "The front door state file names no running supervisor.";
|
|
12991
|
+
for (const pid of pids.filter((candidate) => candidate !== registeredPid)) {
|
|
12992
|
+
push(
|
|
12993
|
+
"frontdoor",
|
|
12994
|
+
"fail",
|
|
12995
|
+
`Front door supervisor pid ${String(pid)} is running beside ${String(pids.length - 1)} other(s). ${serving} Stop it with \`kill ${String(pid)}\`; launches still connected to it lose their door.`,
|
|
12996
|
+
String(pid)
|
|
12997
|
+
);
|
|
12998
|
+
}
|
|
12999
|
+
}
|
|
13000
|
+
|
|
13001
|
+
// src/doctorReport.ts
|
|
13002
|
+
init_supervisorProcesses();
|
|
12856
13003
|
init_legacy();
|
|
12857
13004
|
init_providersStore();
|
|
12858
13005
|
init_guard();
|
|
@@ -12875,7 +13022,8 @@ var DOCTOR_SECTIONS = [
|
|
|
12875
13022
|
"global-config",
|
|
12876
13023
|
"categories-local",
|
|
12877
13024
|
"active-identity",
|
|
12878
|
-
"headroom"
|
|
13025
|
+
"headroom",
|
|
13026
|
+
"frontdoor"
|
|
12879
13027
|
];
|
|
12880
13028
|
function refinePathShadow(status, ownExecutablePath, realpath) {
|
|
12881
13029
|
if (status.status !== "shadowed") {
|
|
@@ -13271,6 +13419,17 @@ function runDoctor(params) {
|
|
|
13271
13419
|
`Headroom daemon is up on unix socket ${state.socketPath} (supervisor ${String(state.supervisorPid)}, daemon ${String(state.headroomPid)}).`
|
|
13272
13420
|
);
|
|
13273
13421
|
}
|
|
13422
|
+
const allowlist = params.headroom.allowlist;
|
|
13423
|
+
if (supervisorAlive && headroomAlive && state.socketPath !== void 0 && allowlist?.driftInputs?.includes("front-door-origin") === true) {
|
|
13424
|
+
const origin = allowlist.frontDoorOrigin ?? "";
|
|
13425
|
+
const certainty = allowlist.driftInputs.includes("provider-files") ? "may exclude" : "excludes";
|
|
13426
|
+
push(
|
|
13427
|
+
"headroom",
|
|
13428
|
+
"fail",
|
|
13429
|
+
`Headroom daemon ${String(state.headroomPid)} was started with an allowlist that ${certainty} the serving front door's direct origin ${origin}, so it refuses every request a provider launch sends back through the door. Its supervisor restarts it once no launch is registered against it; \`agent-shim headroom status\` lists the registered launches, and \`--no-headroom\` launches are unaffected.`,
|
|
13430
|
+
String(state.headroomPid)
|
|
13431
|
+
);
|
|
13432
|
+
}
|
|
13274
13433
|
if (state.lastError !== void 0 && supervisorAlive) {
|
|
13275
13434
|
push("headroom", "warn", `Headroom recorded a previous error: ${state.lastError}`);
|
|
13276
13435
|
}
|
|
@@ -13283,6 +13442,10 @@ function runDoctor(params) {
|
|
|
13283
13442
|
}
|
|
13284
13443
|
}
|
|
13285
13444
|
}
|
|
13445
|
+
if (params.frontDoor !== void 0) {
|
|
13446
|
+
const validated3 = params.frontDoor.state.raw === void 0 ? void 0 : validateJson(FrontDoorStateSchema, params.frontDoor.state);
|
|
13447
|
+
pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0);
|
|
13448
|
+
}
|
|
13286
13449
|
if (params.activeIdentity.raw === void 0) {
|
|
13287
13450
|
push("active-identity", "pass", "No active identity set.");
|
|
13288
13451
|
} else {
|
|
@@ -13312,6 +13475,7 @@ var SECTION_TITLES = {
|
|
|
13312
13475
|
"directory-rules": "Directory rules",
|
|
13313
13476
|
"global-config": "Global config",
|
|
13314
13477
|
headroom: "Headroom daemon",
|
|
13478
|
+
frontdoor: "Front door",
|
|
13315
13479
|
"categories-local": "categories.local.json",
|
|
13316
13480
|
"active-identity": "Active identity"
|
|
13317
13481
|
};
|
|
@@ -13329,6 +13493,7 @@ var SECTION_ORDER = [
|
|
|
13329
13493
|
"directory-rules",
|
|
13330
13494
|
"global-config",
|
|
13331
13495
|
"headroom",
|
|
13496
|
+
"frontdoor",
|
|
13332
13497
|
"categories-local",
|
|
13333
13498
|
"active-identity"
|
|
13334
13499
|
];
|
|
@@ -13406,6 +13571,9 @@ function collectDoctorReport(params) {
|
|
|
13406
13571
|
shimState.targetPath,
|
|
13407
13572
|
realpathOrSelf
|
|
13408
13573
|
);
|
|
13574
|
+
const uid = process.getuid?.();
|
|
13575
|
+
const allowlistInputs = currentHeadroomAllowlistInputs(realFarmFs, paths);
|
|
13576
|
+
const servingHeadroom = resolveServingHeadroomState(realFarmFs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, realIsProcessRunning);
|
|
13409
13577
|
const report = runDoctor({
|
|
13410
13578
|
env: params.env,
|
|
13411
13579
|
credentialCache: realCredentialCacheEnv(paths),
|
|
@@ -13444,8 +13612,13 @@ function collectDoctorReport(params) {
|
|
|
13444
13612
|
const statePath = resolved?.path ?? paths.headroomStateFile;
|
|
13445
13613
|
return { path: statePath, raw: realFarmFs.readFileUtf8(statePath) };
|
|
13446
13614
|
})(),
|
|
13447
|
-
isRunning: realIsProcessRunning
|
|
13448
|
-
|
|
13615
|
+
isRunning: realIsProcessRunning,
|
|
13616
|
+
allowlist: {
|
|
13617
|
+
driftInputs: diagnoseAllowlistDrift({ recordedHash: servingHeadroom?.state.allowlistHash, ...allowlistInputs }),
|
|
13618
|
+
frontDoorOrigin: allowlistInputs.frontDoorOrigin
|
|
13619
|
+
}
|
|
13620
|
+
},
|
|
13621
|
+
...uid === void 0 ? {} : { frontDoor: { state: { path: paths.frontdoorStateFile, raw: realFsPort.readFileUtf8(paths.frontdoorStateFile) }, supervisors: listFrontDoorSupervisors(realRunPort, uid) } }
|
|
13449
13622
|
});
|
|
13450
13623
|
return report;
|
|
13451
13624
|
}
|
|
@@ -14147,7 +14320,9 @@ var DoorHealthEventSchema = import_zod23.z.discriminatedUnion("kind", [
|
|
|
14147
14320
|
import_zod23.z.strictObject({ kind: import_zod23.z.literal("generation"), pid: import_zod23.z.number().int().positive(), providerPort: import_zod23.z.number().int().positive(), connectPort: import_zod23.z.number().int().positive(), directPort: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() }),
|
|
14148
14321
|
import_zod23.z.strictObject({ kind: import_zod23.z.literal("listenerFailed"), pid: import_zod23.z.number().int().positive(), listener: import_zod23.z.enum(["provider", "connect", "direct"]), message: import_zod23.z.string(), observedAt: import_zod23.z.number() }),
|
|
14149
14322
|
import_zod23.z.strictObject({ kind: import_zod23.z.literal("binaryTurnover"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() }),
|
|
14150
|
-
import_zod23.z.strictObject({ kind: import_zod23.z.literal("idleShutdown"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() })
|
|
14323
|
+
import_zod23.z.strictObject({ kind: import_zod23.z.literal("idleShutdown"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() }),
|
|
14324
|
+
import_zod23.z.strictObject({ kind: import_zod23.z.literal("superseded"), pid: import_zod23.z.number().int().positive(), ownerPid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() }),
|
|
14325
|
+
import_zod23.z.strictObject({ kind: import_zod23.z.literal("drained"), pid: import_zod23.z.number().int().positive(), observedAt: import_zod23.z.number() })
|
|
14151
14326
|
]);
|
|
14152
14327
|
var QuotaExpiringEventSchema = import_zod23.z.strictObject({
|
|
14153
14328
|
identity: import_zod23.z.string().min(1),
|
|
@@ -14644,6 +14819,12 @@ function createDoorHealthPublisher(hub, now, pid) {
|
|
|
14644
14819
|
},
|
|
14645
14820
|
binaryTurnover: () => {
|
|
14646
14821
|
publisher.publish({ kind: "binaryTurnover", pid, observedAt: now() });
|
|
14822
|
+
},
|
|
14823
|
+
superseded: (ownerPid) => {
|
|
14824
|
+
publisher.publish({ kind: "superseded", pid, ownerPid, observedAt: now() });
|
|
14825
|
+
},
|
|
14826
|
+
drained: () => {
|
|
14827
|
+
publisher.publish({ kind: "drained", pid, observedAt: now() });
|
|
14647
14828
|
}
|
|
14648
14829
|
};
|
|
14649
14830
|
}
|