agent-shim 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 +88 -35
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2573,7 +2573,7 @@ function listFrontDoorSessions(fs12, sessionsDir) {
|
|
|
2573
2573
|
try {
|
|
2574
2574
|
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs12.readFileUtf8(path8.join(sessionsDir, name)) ?? ""));
|
|
2575
2575
|
if (parsed.success) {
|
|
2576
|
-
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
|
|
2576
|
+
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
|
|
2577
2577
|
}
|
|
2578
2578
|
} catch {
|
|
2579
2579
|
continue;
|
|
@@ -2599,7 +2599,7 @@ var init_state = __esm({
|
|
|
2599
2599
|
"src/frontdoor/state.ts"() {
|
|
2600
2600
|
"use strict";
|
|
2601
2601
|
FRONT_DOOR_PROTOCOL = 3;
|
|
2602
|
-
FrontDoorSessionSchema = z3.strictObject({ pid: z3.number().int().positive(), startedAt: z3.number(), token: z3.string().min(1) });
|
|
2602
|
+
FrontDoorSessionSchema = z3.strictObject({ pid: z3.number().int().positive(), startedAt: z3.number(), token: z3.string().min(1), supervisorPid: z3.number().int().positive().optional() });
|
|
2603
2603
|
FrontDoorStateSchema = z3.strictObject({
|
|
2604
2604
|
/**
|
|
2605
2605
|
* 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`).
|
|
@@ -2639,7 +2639,7 @@ var init_package = __esm({
|
|
|
2639
2639
|
"package.json"() {
|
|
2640
2640
|
package_default = {
|
|
2641
2641
|
name: "agent-shim",
|
|
2642
|
-
version: "9.
|
|
2642
|
+
version: "9.13.0",
|
|
2643
2643
|
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.",
|
|
2644
2644
|
license: "MIT",
|
|
2645
2645
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -2742,6 +2742,36 @@ var init_package = __esm({
|
|
|
2742
2742
|
}
|
|
2743
2743
|
});
|
|
2744
2744
|
|
|
2745
|
+
// src/frontdoor/supervisorProcesses.ts
|
|
2746
|
+
function parseFrontDoorSupervisorPids(psOutput) {
|
|
2747
|
+
const pids = [];
|
|
2748
|
+
for (const line of psOutput.split("\n")) {
|
|
2749
|
+
const [pidText, ...argumentsList] = line.trim().split(/\s+/);
|
|
2750
|
+
const pid = Number(pidText);
|
|
2751
|
+
if (Number.isInteger(pid) && pid > 0 && argumentsList.includes(FRONT_DOOR_SUPERVISOR_ARGUMENT)) {
|
|
2752
|
+
pids.push(pid);
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
return pids.sort((a, b) => a - b);
|
|
2756
|
+
}
|
|
2757
|
+
function listFrontDoorSupervisors(run, uid) {
|
|
2758
|
+
const result = run.run("ps", ["-U", String(uid), "-o", "pid=,command="]);
|
|
2759
|
+
if (result.status === null) {
|
|
2760
|
+
return { ok: false, message: "ps could not be run" };
|
|
2761
|
+
}
|
|
2762
|
+
if (result.status !== 0) {
|
|
2763
|
+
return { ok: false, message: `ps exited ${String(result.status)}${result.stderr.trim() === "" ? "" : `: ${result.stderr.trim()}`}` };
|
|
2764
|
+
}
|
|
2765
|
+
return { ok: true, pids: parseFrontDoorSupervisorPids(result.stdout) };
|
|
2766
|
+
}
|
|
2767
|
+
var FRONT_DOOR_SUPERVISOR_ARGUMENT;
|
|
2768
|
+
var init_supervisorProcesses = __esm({
|
|
2769
|
+
"src/frontdoor/supervisorProcesses.ts"() {
|
|
2770
|
+
"use strict";
|
|
2771
|
+
FRONT_DOOR_SUPERVISOR_ARGUMENT = "__frontdoor-supervisor";
|
|
2772
|
+
}
|
|
2773
|
+
});
|
|
2774
|
+
|
|
2745
2775
|
// src/headroom/state.ts
|
|
2746
2776
|
import { createHash as createHash3 } from "node:crypto";
|
|
2747
2777
|
import path11 from "node:path";
|
|
@@ -3338,9 +3368,15 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3338
3368
|
await ports.sleep(HEADROOM_POLL_MS);
|
|
3339
3369
|
}
|
|
3340
3370
|
}
|
|
3371
|
+
function currentHeadroomAllowlistInputs(fs12, paths) {
|
|
3372
|
+
return {
|
|
3373
|
+
providers: readAllProviders(fs12, paths.providersDir).map((entry) => entry.provider),
|
|
3374
|
+
frontDoorOrigin: frontDoorOrigin(readFrontDoorState(fs12, paths.frontdoorStateFile))
|
|
3375
|
+
};
|
|
3376
|
+
}
|
|
3341
3377
|
function currentHeadroomAllowlist(fs12, paths) {
|
|
3342
|
-
const
|
|
3343
|
-
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin
|
|
3378
|
+
const inputs = currentHeadroomAllowlistInputs(fs12, paths);
|
|
3379
|
+
return headroomAllowlist(headroomUpstreams(inputs.providers, inputs.frontDoorOrigin));
|
|
3344
3380
|
}
|
|
3345
3381
|
function allowlistOf(ports) {
|
|
3346
3382
|
return currentHeadroomAllowlist(ports.fs, ports.paths);
|
|
@@ -3408,6 +3444,10 @@ function realIsProcessZombie(pid) {
|
|
|
3408
3444
|
function realIsProcessRunning(pid) {
|
|
3409
3445
|
return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
|
|
3410
3446
|
}
|
|
3447
|
+
function realIsFrontDoorSupervisor(pid) {
|
|
3448
|
+
const result = spawnSync("ps", ["-o", "pid=,command=", "-p", String(pid)], { encoding: "utf8" });
|
|
3449
|
+
return result.status === 0 && parseFrontDoorSupervisorPids(result.stdout).includes(pid);
|
|
3450
|
+
}
|
|
3411
3451
|
function expandHome2(filePath) {
|
|
3412
3452
|
return filePath.startsWith("~/") ? path13.join(os3.homedir(), filePath.slice(1)) : filePath;
|
|
3413
3453
|
}
|
|
@@ -3611,6 +3651,7 @@ var init_realPorts = __esm({
|
|
|
3611
3651
|
"use strict";
|
|
3612
3652
|
init_load();
|
|
3613
3653
|
init_versionDiscovery();
|
|
3654
|
+
init_supervisorProcesses();
|
|
3614
3655
|
init_ensure();
|
|
3615
3656
|
init_supervisor();
|
|
3616
3657
|
init_state2();
|
|
@@ -4645,7 +4686,7 @@ function assessIdentity(member, nowMs) {
|
|
|
4645
4686
|
);
|
|
4646
4687
|
if (blockedUntil > nowMs) {
|
|
4647
4688
|
if (unified.overageStatus === "allowed") {
|
|
4648
|
-
return { candidate: { ...base, class: "pay-per-use", reasons: [`plan exhausted until ${new Date(blockedUntil).toISOString()}, continues as extra usage`, ...windowReasons, ...planReasons] } };
|
|
4689
|
+
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] } };
|
|
4649
4690
|
}
|
|
4650
4691
|
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] } };
|
|
4651
4692
|
}
|
|
@@ -4760,7 +4801,8 @@ function rankPool(input) {
|
|
|
4760
4801
|
return {
|
|
4761
4802
|
candidates: ordered,
|
|
4762
4803
|
...pick === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick },
|
|
4763
|
-
...movedOff === void 0 || pick === void 0 ? {} : { movedOff }
|
|
4804
|
+
...movedOff === void 0 || pick === void 0 ? {} : { movedOff },
|
|
4805
|
+
...pick?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick.identity, atMs: pick.planReturnsAtMs } }
|
|
4764
4806
|
};
|
|
4765
4807
|
}
|
|
4766
4808
|
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;
|
|
@@ -6140,32 +6182,50 @@ function ensureFrontDoor(params) {
|
|
|
6140
6182
|
let replaced = false;
|
|
6141
6183
|
const distrusted = /* @__PURE__ */ new Set();
|
|
6142
6184
|
let lastRejection;
|
|
6185
|
+
const verifyWithRetry = (port) => {
|
|
6186
|
+
let verdict = ports.verifyListener(port);
|
|
6187
|
+
for (let attempt = 1; !verdict.ok && attempt < FRONTDOOR_PROBE_ATTEMPTS; attempt += 1) {
|
|
6188
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6189
|
+
verdict = ports.verifyListener(port);
|
|
6190
|
+
}
|
|
6191
|
+
return verdict;
|
|
6192
|
+
};
|
|
6193
|
+
const stopAndAwaitExit = (supervisorPid, failure) => {
|
|
6194
|
+
ports.stopSupervisor(supervisorPid);
|
|
6195
|
+
while (ports.isRunning(supervisorPid)) {
|
|
6196
|
+
if (ports.now() >= deadline) {
|
|
6197
|
+
throw new FrontDoorStartError(`${failure}. Daemon log: ${paths.frontdoorLogPath}`);
|
|
6198
|
+
}
|
|
6199
|
+
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6200
|
+
}
|
|
6201
|
+
};
|
|
6143
6202
|
for (; ; ) {
|
|
6144
6203
|
const state = readFrontDoorState(ports.fs, paths.frontdoorStateFile);
|
|
6145
6204
|
const supervisorPid = state?.supervisorPid;
|
|
6146
6205
|
if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
|
|
6147
6206
|
if (state?.port !== void 0 && state.connectPort !== void 0) {
|
|
6148
|
-
const verdict =
|
|
6207
|
+
const verdict = verifyWithRetry(state.port);
|
|
6149
6208
|
if (verdict.ok && !replaced && !spawned && (params.replace === true || (state.protocol ?? 0) < FRONT_DOOR_PROTOCOL)) {
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
}
|
|
6155
|
-
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6156
|
-
}
|
|
6209
|
+
stopAndAwaitExit(
|
|
6210
|
+
supervisorPid,
|
|
6211
|
+
`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`
|
|
6212
|
+
);
|
|
6157
6213
|
replaced = true;
|
|
6158
6214
|
continue;
|
|
6159
6215
|
}
|
|
6160
6216
|
if (verdict.ok) {
|
|
6161
6217
|
const token = randomUUID3();
|
|
6162
|
-
writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token });
|
|
6218
|
+
writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid });
|
|
6163
6219
|
return { port: state.port, connectPort: state.connectPort, token };
|
|
6164
6220
|
}
|
|
6165
6221
|
lastRejection = `the listener on 127.0.0.1:${String(state.port)} (recorded for pid ${String(supervisorPid)}) failed authentication: ${verdict.reason}`;
|
|
6166
6222
|
if (spawned) {
|
|
6167
6223
|
throw new FrontDoorStartError(`${lastRejection}; refusing to send this session's credentials to it. Daemon log: ${paths.frontdoorLogPath}`);
|
|
6168
6224
|
}
|
|
6225
|
+
if (ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
6226
|
+
stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
6227
|
+
continue;
|
|
6228
|
+
}
|
|
6169
6229
|
distrusted.add(supervisorPid);
|
|
6170
6230
|
continue;
|
|
6171
6231
|
}
|
|
@@ -6196,7 +6256,7 @@ function ensureFrontDoor(params) {
|
|
|
6196
6256
|
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
6197
6257
|
}
|
|
6198
6258
|
}
|
|
6199
|
-
var FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FrontDoorStartError;
|
|
6259
|
+
var FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FRONTDOOR_PROBE_ATTEMPTS, FrontDoorStartError;
|
|
6200
6260
|
var init_ensure2 = __esm({
|
|
6201
6261
|
"src/frontdoor/ensure.ts"() {
|
|
6202
6262
|
"use strict";
|
|
@@ -6205,6 +6265,7 @@ var init_ensure2 = __esm({
|
|
|
6205
6265
|
init_state();
|
|
6206
6266
|
FRONTDOOR_START_TIMEOUT_MS = 3e4;
|
|
6207
6267
|
FRONTDOOR_LAUNCHER_POLL_MS = 100;
|
|
6268
|
+
FRONTDOOR_PROBE_ATTEMPTS = 3;
|
|
6208
6269
|
FrontDoorStartError = class extends CliError {
|
|
6209
6270
|
constructor(message) {
|
|
6210
6271
|
super(message);
|
|
@@ -6688,7 +6749,12 @@ function resolvePoolLaunch(params) {
|
|
|
6688
6749
|
if (graph.ranking.candidates.length === 0) {
|
|
6689
6750
|
return { ok: false, message: `agent-shim: no member of pool "${poolName}" is an existing identity.` };
|
|
6690
6751
|
}
|
|
6691
|
-
const { pick, earliestReturn, movedOff } = graph.ranking;
|
|
6752
|
+
const { pick, earliestReturn, movedOff, planReturn } = graph.ranking;
|
|
6753
|
+
if (pick !== void 0 && params.wait && planReturn !== void 0) {
|
|
6754
|
+
log.info(`agent-shim: pool "${poolName}" would continue ${planReturn.identity} on extra usage; waiting until ${new Date(planReturn.atMs).toISOString()} for its plan window`);
|
|
6755
|
+
params.sleep(Math.max(planReturn.atMs - nowMs, 0));
|
|
6756
|
+
continue;
|
|
6757
|
+
}
|
|
6692
6758
|
if (pick !== void 0) {
|
|
6693
6759
|
if (params.recordPick) {
|
|
6694
6760
|
recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
|
|
@@ -7391,6 +7457,7 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
7391
7457
|
now: () => Date.now(),
|
|
7392
7458
|
sleep: realSleepSync,
|
|
7393
7459
|
spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
|
|
7460
|
+
isFrontDoorSupervisor: realIsFrontDoorSupervisor,
|
|
7394
7461
|
stopSupervisor: (pid) => {
|
|
7395
7462
|
process.kill(pid, "SIGTERM");
|
|
7396
7463
|
},
|
|
@@ -8291,16 +8358,27 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
8291
8358
|
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)}`);
|
|
8292
8359
|
let idleSince;
|
|
8293
8360
|
let ticks = 0;
|
|
8361
|
+
const supersedingOwner = () => {
|
|
8362
|
+
const owner = readFrontDoorState(fs12, paths.frontdoorStateFile)?.supervisorPid;
|
|
8363
|
+
return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
|
|
8364
|
+
};
|
|
8365
|
+
let supersededBy;
|
|
8366
|
+
let served;
|
|
8294
8367
|
const binaryReplaced = () => {
|
|
8295
8368
|
const current = ports.statOwnExecutable();
|
|
8296
8369
|
return current !== void 0 && servingBinary !== void 0 && (current.dev !== servingBinary.dev || current.ino !== servingBinary.ino || current.size !== servingBinary.size || current.mtimeMs !== servingBinary.mtimeMs);
|
|
8297
8370
|
};
|
|
8298
|
-
const
|
|
8371
|
+
const closeServing = async () => {
|
|
8299
8372
|
await direct.close();
|
|
8300
8373
|
await connect3.close();
|
|
8301
8374
|
await http3.close();
|
|
8302
8375
|
ports.closeRcStreamHub();
|
|
8303
|
-
|
|
8376
|
+
};
|
|
8377
|
+
const shutdown = async () => {
|
|
8378
|
+
await closeServing();
|
|
8379
|
+
if (supersedingOwner() === void 0) {
|
|
8380
|
+
writeFrontDoorState(fs12, paths.frontdoorStateFile, sticky());
|
|
8381
|
+
}
|
|
8304
8382
|
return 0;
|
|
8305
8383
|
};
|
|
8306
8384
|
for (; ; ) {
|
|
@@ -8313,7 +8391,28 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
8313
8391
|
ports.observeLaunchRegistry(listed, pruned);
|
|
8314
8392
|
ports.checkQuotaExpiry();
|
|
8315
8393
|
const prunedPids = new Set(pruned);
|
|
8316
|
-
|
|
8394
|
+
const live = listed.filter((session) => !prunedPids.has(session.pid));
|
|
8395
|
+
if (supersededBy === void 0) {
|
|
8396
|
+
supersededBy = supersedingOwner();
|
|
8397
|
+
if (supersededBy !== void 0) {
|
|
8398
|
+
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`);
|
|
8399
|
+
ports.doorHealth.superseded(supersededBy);
|
|
8400
|
+
await ports.sleep(FRONTDOOR_POLL_MS);
|
|
8401
|
+
continue;
|
|
8402
|
+
}
|
|
8403
|
+
} else {
|
|
8404
|
+
const owner = supersededBy;
|
|
8405
|
+
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));
|
|
8406
|
+
if (served.length === 0) {
|
|
8407
|
+
ports.log("agent-shim frontdoor supervisor: the sessions this superseded door served have ended; closing the front door and exiting");
|
|
8408
|
+
ports.doorHealth.drained();
|
|
8409
|
+
await closeServing();
|
|
8410
|
+
return 0;
|
|
8411
|
+
}
|
|
8412
|
+
await ports.sleep(FRONTDOOR_POLL_MS);
|
|
8413
|
+
continue;
|
|
8414
|
+
}
|
|
8415
|
+
if (live.length === 0) {
|
|
8317
8416
|
if (ticks > 1 && binaryReplaced()) {
|
|
8318
8417
|
ports.log("agent-shim frontdoor supervisor: the installed binary changed and no sessions are live; turning the door over for the next launch");
|
|
8319
8418
|
ports.doorHealth.binaryTurnover();
|
|
@@ -12467,7 +12566,55 @@ init_credential();
|
|
|
12467
12566
|
init_credentialCache();
|
|
12468
12567
|
init_realCredentialCache();
|
|
12469
12568
|
init_source();
|
|
12569
|
+
|
|
12570
|
+
// src/headroom/allowlistDrift.ts
|
|
12571
|
+
init_state2();
|
|
12572
|
+
function diagnoseAllowlistDrift(params) {
|
|
12573
|
+
const { recordedHash, providers, frontDoorOrigin: frontDoorOrigin2 } = params;
|
|
12574
|
+
if (recordedHash === void 0 || recordedHash === hashAllowlist(headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin2)))) {
|
|
12575
|
+
return void 0;
|
|
12576
|
+
}
|
|
12577
|
+
const originIsInput = providers.length > 0 && frontDoorOrigin2 !== void 0;
|
|
12578
|
+
if (!originIsInput) {
|
|
12579
|
+
return ["provider-files"];
|
|
12580
|
+
}
|
|
12581
|
+
return recordedHash === hashAllowlist(headroomAllowlist(headroomUpstreams(providers, void 0))) ? ["front-door-origin"] : ["provider-files", "front-door-origin"];
|
|
12582
|
+
}
|
|
12583
|
+
|
|
12584
|
+
// src/doctorReport.ts
|
|
12470
12585
|
init_state2();
|
|
12586
|
+
init_supervisor();
|
|
12587
|
+
init_state();
|
|
12588
|
+
|
|
12589
|
+
// src/doctorFrontDoor.ts
|
|
12590
|
+
function pushFrontDoor(push, supervisors, registeredPid) {
|
|
12591
|
+
if (!supervisors.ok) {
|
|
12592
|
+
push("frontdoor", "warn", `Could not list processes to look for duplicate front door supervisors: ${supervisors.message}.`);
|
|
12593
|
+
return;
|
|
12594
|
+
}
|
|
12595
|
+
const { pids } = supervisors;
|
|
12596
|
+
if (pids.length === 0) {
|
|
12597
|
+
push("frontdoor", "pass", "No front door supervisor is running.");
|
|
12598
|
+
return;
|
|
12599
|
+
}
|
|
12600
|
+
const [only, ...rest] = pids;
|
|
12601
|
+
if (only !== void 0 && rest.length === 0) {
|
|
12602
|
+
push("frontdoor", "pass", `One front door supervisor is running (pid ${String(only)}).`);
|
|
12603
|
+
return;
|
|
12604
|
+
}
|
|
12605
|
+
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.";
|
|
12606
|
+
for (const pid of pids.filter((candidate) => candidate !== registeredPid)) {
|
|
12607
|
+
push(
|
|
12608
|
+
"frontdoor",
|
|
12609
|
+
"fail",
|
|
12610
|
+
`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.`,
|
|
12611
|
+
String(pid)
|
|
12612
|
+
);
|
|
12613
|
+
}
|
|
12614
|
+
}
|
|
12615
|
+
|
|
12616
|
+
// src/doctorReport.ts
|
|
12617
|
+
init_supervisorProcesses();
|
|
12471
12618
|
init_legacy();
|
|
12472
12619
|
init_providersStore();
|
|
12473
12620
|
init_guard();
|
|
@@ -12490,7 +12637,8 @@ var DOCTOR_SECTIONS = [
|
|
|
12490
12637
|
"global-config",
|
|
12491
12638
|
"categories-local",
|
|
12492
12639
|
"active-identity",
|
|
12493
|
-
"headroom"
|
|
12640
|
+
"headroom",
|
|
12641
|
+
"frontdoor"
|
|
12494
12642
|
];
|
|
12495
12643
|
function refinePathShadow(status, ownExecutablePath, realpath) {
|
|
12496
12644
|
if (status.status !== "shadowed") {
|
|
@@ -12886,6 +13034,17 @@ function runDoctor(params) {
|
|
|
12886
13034
|
`Headroom daemon is up on unix socket ${state.socketPath} (supervisor ${String(state.supervisorPid)}, daemon ${String(state.headroomPid)}).`
|
|
12887
13035
|
);
|
|
12888
13036
|
}
|
|
13037
|
+
const allowlist = params.headroom.allowlist;
|
|
13038
|
+
if (supervisorAlive && headroomAlive && state.socketPath !== void 0 && allowlist?.driftInputs?.includes("front-door-origin") === true) {
|
|
13039
|
+
const origin = allowlist.frontDoorOrigin ?? "";
|
|
13040
|
+
const certainty = allowlist.driftInputs.includes("provider-files") ? "may exclude" : "excludes";
|
|
13041
|
+
push(
|
|
13042
|
+
"headroom",
|
|
13043
|
+
"fail",
|
|
13044
|
+
`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.`,
|
|
13045
|
+
String(state.headroomPid)
|
|
13046
|
+
);
|
|
13047
|
+
}
|
|
12889
13048
|
if (state.lastError !== void 0 && supervisorAlive) {
|
|
12890
13049
|
push("headroom", "warn", `Headroom recorded a previous error: ${state.lastError}`);
|
|
12891
13050
|
}
|
|
@@ -12898,6 +13057,10 @@ function runDoctor(params) {
|
|
|
12898
13057
|
}
|
|
12899
13058
|
}
|
|
12900
13059
|
}
|
|
13060
|
+
if (params.frontDoor !== void 0) {
|
|
13061
|
+
const validated3 = params.frontDoor.state.raw === void 0 ? void 0 : validateJson(FrontDoorStateSchema, params.frontDoor.state);
|
|
13062
|
+
pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0);
|
|
13063
|
+
}
|
|
12901
13064
|
if (params.activeIdentity.raw === void 0) {
|
|
12902
13065
|
push("active-identity", "pass", "No active identity set.");
|
|
12903
13066
|
} else {
|
|
@@ -12927,6 +13090,7 @@ var SECTION_TITLES = {
|
|
|
12927
13090
|
"directory-rules": "Directory rules",
|
|
12928
13091
|
"global-config": "Global config",
|
|
12929
13092
|
headroom: "Headroom daemon",
|
|
13093
|
+
frontdoor: "Front door",
|
|
12930
13094
|
"categories-local": "categories.local.json",
|
|
12931
13095
|
"active-identity": "Active identity"
|
|
12932
13096
|
};
|
|
@@ -12944,6 +13108,7 @@ var SECTION_ORDER = [
|
|
|
12944
13108
|
"directory-rules",
|
|
12945
13109
|
"global-config",
|
|
12946
13110
|
"headroom",
|
|
13111
|
+
"frontdoor",
|
|
12947
13112
|
"categories-local",
|
|
12948
13113
|
"active-identity"
|
|
12949
13114
|
];
|
|
@@ -13021,6 +13186,9 @@ function collectDoctorReport(params) {
|
|
|
13021
13186
|
shimState.targetPath,
|
|
13022
13187
|
realpathOrSelf
|
|
13023
13188
|
);
|
|
13189
|
+
const uid = process.getuid?.();
|
|
13190
|
+
const allowlistInputs = currentHeadroomAllowlistInputs(realFarmFs, paths);
|
|
13191
|
+
const servingHeadroom = resolveServingHeadroomState(realFarmFs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, realIsProcessRunning);
|
|
13024
13192
|
const report = runDoctor({
|
|
13025
13193
|
env: params.env,
|
|
13026
13194
|
credentialCache: realCredentialCacheEnv(paths),
|
|
@@ -13059,8 +13227,13 @@ function collectDoctorReport(params) {
|
|
|
13059
13227
|
const statePath = resolved?.path ?? paths.headroomStateFile;
|
|
13060
13228
|
return { path: statePath, raw: realFarmFs.readFileUtf8(statePath) };
|
|
13061
13229
|
})(),
|
|
13062
|
-
isRunning: realIsProcessRunning
|
|
13063
|
-
|
|
13230
|
+
isRunning: realIsProcessRunning,
|
|
13231
|
+
allowlist: {
|
|
13232
|
+
driftInputs: diagnoseAllowlistDrift({ recordedHash: servingHeadroom?.state.allowlistHash, ...allowlistInputs }),
|
|
13233
|
+
frontDoorOrigin: allowlistInputs.frontDoorOrigin
|
|
13234
|
+
}
|
|
13235
|
+
},
|
|
13236
|
+
...uid === void 0 ? {} : { frontDoor: { state: { path: paths.frontdoorStateFile, raw: realFsPort.readFileUtf8(paths.frontdoorStateFile) }, supervisors: listFrontDoorSupervisors(realRunPort, uid) } }
|
|
13064
13237
|
});
|
|
13065
13238
|
return report;
|
|
13066
13239
|
}
|
|
@@ -13762,7 +13935,9 @@ var DoorHealthEventSchema = z23.discriminatedUnion("kind", [
|
|
|
13762
13935
|
z23.strictObject({ kind: z23.literal("generation"), pid: z23.number().int().positive(), providerPort: z23.number().int().positive(), connectPort: z23.number().int().positive(), directPort: z23.number().int().positive(), observedAt: z23.number() }),
|
|
13763
13936
|
z23.strictObject({ kind: z23.literal("listenerFailed"), pid: z23.number().int().positive(), listener: z23.enum(["provider", "connect", "direct"]), message: z23.string(), observedAt: z23.number() }),
|
|
13764
13937
|
z23.strictObject({ kind: z23.literal("binaryTurnover"), pid: z23.number().int().positive(), observedAt: z23.number() }),
|
|
13765
|
-
z23.strictObject({ kind: z23.literal("idleShutdown"), pid: z23.number().int().positive(), observedAt: z23.number() })
|
|
13938
|
+
z23.strictObject({ kind: z23.literal("idleShutdown"), pid: z23.number().int().positive(), observedAt: z23.number() }),
|
|
13939
|
+
z23.strictObject({ kind: z23.literal("superseded"), pid: z23.number().int().positive(), ownerPid: z23.number().int().positive(), observedAt: z23.number() }),
|
|
13940
|
+
z23.strictObject({ kind: z23.literal("drained"), pid: z23.number().int().positive(), observedAt: z23.number() })
|
|
13766
13941
|
]);
|
|
13767
13942
|
var QuotaExpiringEventSchema = z23.strictObject({
|
|
13768
13943
|
identity: z23.string().min(1),
|
|
@@ -14259,6 +14434,12 @@ function createDoorHealthPublisher(hub, now, pid) {
|
|
|
14259
14434
|
},
|
|
14260
14435
|
binaryTurnover: () => {
|
|
14261
14436
|
publisher.publish({ kind: "binaryTurnover", pid, observedAt: now() });
|
|
14437
|
+
},
|
|
14438
|
+
superseded: (ownerPid) => {
|
|
14439
|
+
publisher.publish({ kind: "superseded", pid, ownerPid, observedAt: now() });
|
|
14440
|
+
},
|
|
14441
|
+
drained: () => {
|
|
14442
|
+
publisher.publish({ kind: "drained", pid, observedAt: now() });
|
|
14262
14443
|
}
|
|
14263
14444
|
};
|
|
14264
14445
|
}
|