agent-shim 8.5.2 → 8.5.3
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 +744 -720
- package/dist/index.cjs +35 -9
- package/dist/index.mjs +35 -9
- package/dist/types/index.d.ts +9 -3
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -35184,7 +35184,7 @@ function debugEnabled(env) {
|
|
|
35184
35184
|
|
|
35185
35185
|
// src/claudeShim.ts
|
|
35186
35186
|
var import_node_fs4 = __toESM(require("node:fs"), 1);
|
|
35187
|
-
var
|
|
35187
|
+
var import_node_path9 = __toESM(require("node:path"), 1);
|
|
35188
35188
|
|
|
35189
35189
|
// node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/external.js
|
|
35190
35190
|
var external_exports = {};
|
|
@@ -55050,10 +55050,10 @@ function applyPatch(filePath, schema, patch, options = {}) {
|
|
|
55050
55050
|
|
|
55051
55051
|
// src/realPorts.ts
|
|
55052
55052
|
var import_node_child_process2 = require("node:child_process");
|
|
55053
|
-
var
|
|
55053
|
+
var import_node_crypto4 = require("node:crypto");
|
|
55054
55054
|
var import_node_fs3 = __toESM(require("node:fs"), 1);
|
|
55055
55055
|
var import_node_os2 = __toESM(require("node:os"), 1);
|
|
55056
|
-
var
|
|
55056
|
+
var import_node_path8 = __toESM(require("node:path"), 1);
|
|
55057
55057
|
var import_node_sea = require("node:sea");
|
|
55058
55058
|
|
|
55059
55059
|
// src/versionDiscovery.ts
|
|
@@ -55505,13 +55505,24 @@ function ensureHeadroom(params) {
|
|
|
55505
55505
|
const { paths, ports } = params;
|
|
55506
55506
|
const deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
|
|
55507
55507
|
let spawnedSupervisor = false;
|
|
55508
|
+
let awaitingAllowlist = false;
|
|
55508
55509
|
for (; ; ) {
|
|
55509
55510
|
const state = readHeadroomState(ports.fs, paths.headroomStateFile);
|
|
55510
55511
|
if (state?.supervisorPid !== void 0 && ports.isRunning(state.supervisorPid)) {
|
|
55511
55512
|
const daemonUp = state.socketPath !== void 0 && state.headroomPid !== void 0 && ports.isRunning(state.headroomPid);
|
|
55512
55513
|
if (daemonUp && state.socketPath !== void 0) {
|
|
55513
|
-
|
|
55514
|
-
|
|
55514
|
+
const required2 = params.requiredAllowlistHash?.();
|
|
55515
|
+
if (required2 === void 0 || state.allowlistHash === required2) {
|
|
55516
|
+
writeSession(ports.fs, paths.headroomSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), supervisorPid: state.supervisorPid });
|
|
55517
|
+
return { socketPath: state.socketPath };
|
|
55518
|
+
}
|
|
55519
|
+
const holders = sessionsForSupervisor(ports.fs, paths.headroomSessionsDir, state.supervisorPid).filter((session) => ports.isRunning(session.pid));
|
|
55520
|
+
if (holders.length > 0) {
|
|
55521
|
+
throw new HeadroomStartError(
|
|
55522
|
+
`agent-shim: the running headroom daemon was started before this launch's front door address and would refuse every request this launch sends through it. It restarts once the launches using it end (pid ${holders.map((session) => String(session.pid)).join(", ")}); end them and launch again, or launch with --no-headroom.`
|
|
55523
|
+
);
|
|
55524
|
+
}
|
|
55525
|
+
awaitingAllowlist = true;
|
|
55515
55526
|
}
|
|
55516
55527
|
if (state.lastError !== void 0) {
|
|
55517
55528
|
throw new HeadroomStartError(
|
|
@@ -55539,13 +55550,535 @@ function ensureHeadroom(params) {
|
|
|
55539
55550
|
if (ports.now() >= deadline) {
|
|
55540
55551
|
const lastError = state?.lastError;
|
|
55541
55552
|
throw new HeadroomStartError(
|
|
55542
|
-
`agent-shim: the headroom daemon did not become ready within ${String(HEADROOM_START_TIMEOUT_MS)}ms` + (lastError === void 0 ? "" : ` (last error: ${lastError})`) + `. Daemon log: ${paths.headroomLogPath}`
|
|
55553
|
+
`agent-shim: the headroom daemon did not become ready within ${String(HEADROOM_START_TIMEOUT_MS)}ms` + (lastError === void 0 ? "" : ` (last error: ${lastError})`) + (awaitingAllowlist ? " (the running daemon's allowlist does not admit this launch's front door, and it did not restart)" : "") + `. Daemon log: ${paths.headroomLogPath}`
|
|
55543
55554
|
);
|
|
55544
55555
|
}
|
|
55545
55556
|
ports.sleep(HEADROOM_LAUNCHER_POLL_MS);
|
|
55546
55557
|
}
|
|
55547
55558
|
}
|
|
55548
55559
|
|
|
55560
|
+
// src/frontdoor/state.ts
|
|
55561
|
+
var import_node_path6 = __toESM(require("node:path"), 1);
|
|
55562
|
+
var FRONT_DOOR_PROTOCOL = 2;
|
|
55563
|
+
var FrontDoorSessionSchema = external_exports.strictObject({ pid: external_exports.number().int().positive(), startedAt: external_exports.number(), token: external_exports.string().min(1) });
|
|
55564
|
+
var FrontDoorStateSchema = external_exports.strictObject({
|
|
55565
|
+
/**
|
|
55566
|
+
* 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`).
|
|
55567
|
+
*/
|
|
55568
|
+
protocol: external_exports.number().int().nonnegative().optional(),
|
|
55569
|
+
/** The supervisor process serving the front door. Alive means both listeners are up in that process. */
|
|
55570
|
+
supervisorPid: external_exports.number().int().positive().optional(),
|
|
55571
|
+
/** The loopback port the HTTPS provider 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. */
|
|
55572
|
+
port: external_exports.number().int().positive().optional(),
|
|
55573
|
+
/**
|
|
55574
|
+
* The sticky port preference for the provider listener: kept across crashes, restarts and idle shutdowns so every provider session, whose base URL was frozen at launch, keeps finding the front door at the same address.
|
|
55575
|
+
*/
|
|
55576
|
+
lastPort: external_exports.number().int().positive().optional(),
|
|
55577
|
+
/**
|
|
55578
|
+
* The loopback port the CONNECT surface listens on. Absent whenever no supervisor is serving it, so "connectPort is set" is the ready signal an OAuth launch polls for alongside `port`.
|
|
55579
|
+
*/
|
|
55580
|
+
connectPort: external_exports.number().int().positive().optional(),
|
|
55581
|
+
/**
|
|
55582
|
+
* The sticky port preference for the CONNECT surface, the exact analogue of `lastPort` for the second listener: it survives every shutdown, because every OAuth session's environment was frozen at launch with HTTPS_PROXY pointing at this address and a restart that moves strands them.
|
|
55583
|
+
*/
|
|
55584
|
+
lastConnectPort: external_exports.number().int().positive().optional(),
|
|
55585
|
+
/**
|
|
55586
|
+
* The loopback port the direct listener serves on: the listener a headroom hop tells the daemon to forward routed traffic back to. Sticky like the others, because headroom's allowlist admits its exact origin and an ephemeral port would invalidate the allowlist on every restart.
|
|
55587
|
+
*/
|
|
55588
|
+
directPort: external_exports.number().int().positive().optional(),
|
|
55589
|
+
/** The sticky port preference for the direct listener, for the reason `directPort` gives. */
|
|
55590
|
+
lastDirectPort: external_exports.number().int().positive().optional(),
|
|
55591
|
+
/** The last fatal error, kept across shutdowns so `frontdoor status` can explain a front door that is not running. */
|
|
55592
|
+
lastError: external_exports.string().optional()
|
|
55593
|
+
});
|
|
55594
|
+
function readFrontDoorState(fs19, stateFile) {
|
|
55595
|
+
let raw;
|
|
55596
|
+
try {
|
|
55597
|
+
raw = fs19.readFileUtf8(stateFile);
|
|
55598
|
+
} catch {
|
|
55599
|
+
return void 0;
|
|
55600
|
+
}
|
|
55601
|
+
if (raw === void 0 || raw.trim() === "") {
|
|
55602
|
+
return void 0;
|
|
55603
|
+
}
|
|
55604
|
+
try {
|
|
55605
|
+
const parsed = FrontDoorStateSchema.safeParse(JSON.parse(raw));
|
|
55606
|
+
return parsed.success ? parsed.data : void 0;
|
|
55607
|
+
} catch {
|
|
55608
|
+
return void 0;
|
|
55609
|
+
}
|
|
55610
|
+
}
|
|
55611
|
+
function writeFrontDoorState(fs19, stateFile, state) {
|
|
55612
|
+
fs19.mkdirp(import_node_path6.default.dirname(stateFile));
|
|
55613
|
+
fs19.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
55614
|
+
`);
|
|
55615
|
+
}
|
|
55616
|
+
function frontDoorOrigin(state) {
|
|
55617
|
+
const port = state?.directPort ?? state?.lastDirectPort;
|
|
55618
|
+
return port === void 0 ? void 0 : `http://127.0.0.1:${String(port)}`;
|
|
55619
|
+
}
|
|
55620
|
+
function writeFrontDoorSession(fs19, sessionsDir, session) {
|
|
55621
|
+
fs19.mkdirPrivate(sessionsDir);
|
|
55622
|
+
fs19.writeFilePrivate(import_node_path6.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
55623
|
+
`);
|
|
55624
|
+
}
|
|
55625
|
+
function listFrontDoorSessions(fs19, sessionsDir) {
|
|
55626
|
+
const sessions = [];
|
|
55627
|
+
for (const name of fs19.readdir(sessionsDir)) {
|
|
55628
|
+
if (!name.endsWith(".json")) {
|
|
55629
|
+
continue;
|
|
55630
|
+
}
|
|
55631
|
+
try {
|
|
55632
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs19.readFileUtf8(import_node_path6.default.join(sessionsDir, name)) ?? ""));
|
|
55633
|
+
if (parsed.success) {
|
|
55634
|
+
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
|
|
55635
|
+
}
|
|
55636
|
+
} catch {
|
|
55637
|
+
continue;
|
|
55638
|
+
}
|
|
55639
|
+
}
|
|
55640
|
+
return sessions.sort((a2, b) => a2.pid - b.pid);
|
|
55641
|
+
}
|
|
55642
|
+
function removeFrontDoorSession(fs19, sessionsDir, pid) {
|
|
55643
|
+
fs19.removeRecursive(import_node_path6.default.join(sessionsDir, `${String(pid)}.json`));
|
|
55644
|
+
}
|
|
55645
|
+
function pruneDeadFrontDoorSessions(fs19, sessionsDir, isRunning) {
|
|
55646
|
+
const removed = [];
|
|
55647
|
+
for (const session of listFrontDoorSessions(fs19, sessionsDir)) {
|
|
55648
|
+
if (!isRunning(session.pid)) {
|
|
55649
|
+
removeFrontDoorSession(fs19, sessionsDir, session.pid);
|
|
55650
|
+
removed.push(session.pid);
|
|
55651
|
+
}
|
|
55652
|
+
}
|
|
55653
|
+
return removed;
|
|
55654
|
+
}
|
|
55655
|
+
function liveSessionTokens(fs19, sessionsDir) {
|
|
55656
|
+
const tokens = /* @__PURE__ */ new Set();
|
|
55657
|
+
for (const name of fs19.readdir(sessionsDir)) {
|
|
55658
|
+
if (!name.endsWith(".json")) {
|
|
55659
|
+
continue;
|
|
55660
|
+
}
|
|
55661
|
+
try {
|
|
55662
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs19.readFileUtf8(import_node_path6.default.join(sessionsDir, name)) ?? ""));
|
|
55663
|
+
if (parsed.success) {
|
|
55664
|
+
tokens.add(parsed.data.token);
|
|
55665
|
+
}
|
|
55666
|
+
} catch {
|
|
55667
|
+
continue;
|
|
55668
|
+
}
|
|
55669
|
+
}
|
|
55670
|
+
return tokens;
|
|
55671
|
+
}
|
|
55672
|
+
|
|
55673
|
+
// src/headroom/settings.ts
|
|
55674
|
+
var import_node_crypto3 = require("node:crypto");
|
|
55675
|
+
function settingsOf(config2) {
|
|
55676
|
+
return {
|
|
55677
|
+
...config2.mode === void 0 ? {} : { mode: config2.mode },
|
|
55678
|
+
...config2.targetRatio === void 0 ? {} : { targetRatio: config2.targetRatio },
|
|
55679
|
+
...config2.ccr === void 0 ? {} : { ccr: config2.ccr },
|
|
55680
|
+
...config2.rolloutChannel === void 0 ? {} : { rolloutChannel: config2.rolloutChannel },
|
|
55681
|
+
...config2.interceptToolResults === void 0 ? {} : { interceptToolResults: config2.interceptToolResults },
|
|
55682
|
+
...config2.readMaturation === void 0 ? {} : { readMaturation: config2.readMaturation }
|
|
55683
|
+
};
|
|
55684
|
+
}
|
|
55685
|
+
function settingsArgs(settings2) {
|
|
55686
|
+
return [
|
|
55687
|
+
...settings2.mode === void 0 ? [] : ["--mode", settings2.mode],
|
|
55688
|
+
...settings2.targetRatio === void 0 ? [] : ["--target-ratio", String(settings2.targetRatio)],
|
|
55689
|
+
...settings2.ccr === "lossless" ? ["--lossless"] : [],
|
|
55690
|
+
...settings2.ccr === "none" ? ["--no-ccr"] : [],
|
|
55691
|
+
...settings2.interceptToolResults === true ? ["--intercept-tool-results"] : [],
|
|
55692
|
+
...settings2.readMaturation === true ? ["--read-maturation"] : []
|
|
55693
|
+
];
|
|
55694
|
+
}
|
|
55695
|
+
function settingsEnv(settings2) {
|
|
55696
|
+
return settings2.rolloutChannel === void 0 ? {} : { HEADROOM_ROLLOUT_CHANNEL: settings2.rolloutChannel };
|
|
55697
|
+
}
|
|
55698
|
+
function hashSettings(settings2) {
|
|
55699
|
+
return (0, import_node_crypto3.createHash)("sha256").update(JSON.stringify([...settingsArgs(settings2), JSON.stringify(settingsEnv(settings2))])).digest("hex");
|
|
55700
|
+
}
|
|
55701
|
+
|
|
55702
|
+
// src/headroom/socket.ts
|
|
55703
|
+
var import_node_path7 = __toESM(require("node:path"), 1);
|
|
55704
|
+
var GROUP_OR_OTHER_BITS = 63;
|
|
55705
|
+
var OCTAL_RADIX = 8;
|
|
55706
|
+
var MODE_DIGITS = 4;
|
|
55707
|
+
var HEADROOM_SOCKET_SUFFIX = ".sock";
|
|
55708
|
+
var HEADROOM_SOCKET_NAME = /^(\d+)\.sock$/;
|
|
55709
|
+
var UNIX_SOCKET_PATH_MAX_BYTES = 103;
|
|
55710
|
+
var PLATFORMS_WITHOUT_UNIX_SOCKETS = ["win32"];
|
|
55711
|
+
function headroomSocketPath(paths, supervisorPid) {
|
|
55712
|
+
return import_node_path7.default.join(paths.headroomSocketDir, `${String(supervisorPid)}${HEADROOM_SOCKET_SUFFIX}`);
|
|
55713
|
+
}
|
|
55714
|
+
function platformRefusal(platform) {
|
|
55715
|
+
return PLATFORMS_WITHOUT_UNIX_SOCKETS.includes(platform) ? `headroom routing needs a unix domain socket, which headroom cannot serve on ${platform}; agent-shim never falls back to a TCP port for this hop` : void 0;
|
|
55716
|
+
}
|
|
55717
|
+
function ownerOnlyRefusal(label, target, stat, expected, uid) {
|
|
55718
|
+
if (stat === void 0) {
|
|
55719
|
+
return `the headroom ${label} ${target} does not exist`;
|
|
55720
|
+
}
|
|
55721
|
+
if (stat.kind === "symlink") {
|
|
55722
|
+
return `the headroom ${label} ${target} is a symlink; it must be the real ${expected === "dir" ? "directory" : "socket"}`;
|
|
55723
|
+
}
|
|
55724
|
+
if (stat.kind !== expected) {
|
|
55725
|
+
return `the headroom ${label} ${target} is not a ${expected === "dir" ? "directory" : "socket"}`;
|
|
55726
|
+
}
|
|
55727
|
+
if (stat.uid !== uid) {
|
|
55728
|
+
return `the headroom ${label} ${target} is owned by uid ${String(stat.uid)}, not by this user (uid ${String(uid)})`;
|
|
55729
|
+
}
|
|
55730
|
+
if ((stat.mode & GROUP_OR_OTHER_BITS) !== 0) {
|
|
55731
|
+
return `the headroom ${label} ${target} has mode ${stat.mode.toString(OCTAL_RADIX).padStart(MODE_DIGITS, "0")}, which lets other users reach it; it must be accessible to its owner only`;
|
|
55732
|
+
}
|
|
55733
|
+
return void 0;
|
|
55734
|
+
}
|
|
55735
|
+
function verifyHeadroomSocket(socketPath, ports) {
|
|
55736
|
+
const unsupported = platformRefusal(ports.platform);
|
|
55737
|
+
if (unsupported !== void 0) {
|
|
55738
|
+
return { refused: unsupported };
|
|
55739
|
+
}
|
|
55740
|
+
const uid = ports.currentUid();
|
|
55741
|
+
const directory = import_node_path7.default.dirname(socketPath);
|
|
55742
|
+
const refusal = ownerOnlyRefusal("socket directory", directory, ports.lstat(directory), "dir", uid) ?? ownerOnlyRefusal("socket", socketPath, ports.lstat(socketPath), "socket", uid);
|
|
55743
|
+
return refusal === void 0 ? { socketPath } : { refused: refusal };
|
|
55744
|
+
}
|
|
55745
|
+
function prepareHeadroomSocket(fs19, ports, paths, supervisorPid) {
|
|
55746
|
+
const unsupported = platformRefusal(ports.platform);
|
|
55747
|
+
if (unsupported !== void 0) {
|
|
55748
|
+
return { refused: unsupported };
|
|
55749
|
+
}
|
|
55750
|
+
const socketPath = headroomSocketPath(paths, supervisorPid);
|
|
55751
|
+
const length = Buffer.byteLength(socketPath, "utf8");
|
|
55752
|
+
if (length > UNIX_SOCKET_PATH_MAX_BYTES) {
|
|
55753
|
+
return {
|
|
55754
|
+
refused: `the headroom socket path ${socketPath} is ${String(length)} bytes, longer than the ${String(UNIX_SOCKET_PATH_MAX_BYTES)} a unix socket path can hold; set AGENT_SHIM_HOME to a shorter directory`
|
|
55755
|
+
};
|
|
55756
|
+
}
|
|
55757
|
+
if (ports.lstat(paths.headroomSocketDir)?.kind === "symlink") {
|
|
55758
|
+
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
55759
|
+
}
|
|
55760
|
+
fs19.mkdirPrivate(paths.headroomSocketDir);
|
|
55761
|
+
const refusal = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
55762
|
+
return refusal === void 0 ? { socketPath } : { refused: refusal };
|
|
55763
|
+
}
|
|
55764
|
+
function pruneStaleHeadroomSockets(fs19, paths, isRunning) {
|
|
55765
|
+
const removed = [];
|
|
55766
|
+
for (const name of fs19.readdir(paths.headroomSocketDir)) {
|
|
55767
|
+
const pid = HEADROOM_SOCKET_NAME.exec(name)?.[1];
|
|
55768
|
+
if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
|
|
55769
|
+
continue;
|
|
55770
|
+
}
|
|
55771
|
+
fs19.removeRecursive(import_node_path7.default.join(paths.headroomSocketDir, name));
|
|
55772
|
+
removed.push(name);
|
|
55773
|
+
}
|
|
55774
|
+
return removed;
|
|
55775
|
+
}
|
|
55776
|
+
|
|
55777
|
+
// src/headroom/source.ts
|
|
55778
|
+
var GIT_SPEC_RE = /git\+[^@\s]+(?:@([^\s#]+))?/;
|
|
55779
|
+
var COMMIT_SHA_RE = /^[0-9a-f]{40}$/i;
|
|
55780
|
+
var DirectUrlSchema = external_exports.object({ vcs_info: external_exports.object({ commit_id: external_exports.string() }) });
|
|
55781
|
+
function isMovingGitSource(spec) {
|
|
55782
|
+
const match = GIT_SPEC_RE.exec(spec);
|
|
55783
|
+
if (match === null) {
|
|
55784
|
+
return false;
|
|
55785
|
+
}
|
|
55786
|
+
const ref = match[1];
|
|
55787
|
+
return ref === void 0 || !COMMIT_SHA_RE.test(ref);
|
|
55788
|
+
}
|
|
55789
|
+
function pinnedGitCommit(spec) {
|
|
55790
|
+
const ref = GIT_SPEC_RE.exec(spec)?.[1];
|
|
55791
|
+
return ref !== void 0 && COMMIT_SHA_RE.test(ref) ? ref.toLowerCase() : void 0;
|
|
55792
|
+
}
|
|
55793
|
+
function parseInstalledCommit(directUrlJson) {
|
|
55794
|
+
try {
|
|
55795
|
+
const parsed = DirectUrlSchema.safeParse(JSON.parse(directUrlJson));
|
|
55796
|
+
return parsed.success ? parsed.data.vcs_info.commit_id.toLowerCase() : void 0;
|
|
55797
|
+
} catch {
|
|
55798
|
+
return void 0;
|
|
55799
|
+
}
|
|
55800
|
+
}
|
|
55801
|
+
|
|
55802
|
+
// src/headroom/supervisor.ts
|
|
55803
|
+
function resolveSupervisorConfig(configured) {
|
|
55804
|
+
return {
|
|
55805
|
+
source: configured.source ?? HEADROOM_DEFAULT_SOURCE,
|
|
55806
|
+
idleShutdownMinutes: configured.idleShutdownMinutes ?? HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES,
|
|
55807
|
+
settings: settingsOf(configured)
|
|
55808
|
+
};
|
|
55809
|
+
}
|
|
55810
|
+
var HEADROOM_BACKOFF_BASE_MS = 500;
|
|
55811
|
+
var HEADROOM_BACKOFF_CAP_MS = 3e4;
|
|
55812
|
+
var HEADROOM_START_RETRY_BUDGET = 5;
|
|
55813
|
+
var HEADROOM_READY_TIMEOUT_MS = 15e3;
|
|
55814
|
+
var HEADROOM_POLL_MS = 1e3;
|
|
55815
|
+
var MS_PER_MINUTE = 6e4;
|
|
55816
|
+
var STOP_POLL_MS = 100;
|
|
55817
|
+
var TERM_GRACE_MS = 1500;
|
|
55818
|
+
var KILL_GRACE_MS = 1500;
|
|
55819
|
+
function stopSupervisedProcess(pid, primitives) {
|
|
55820
|
+
const send = (signal) => {
|
|
55821
|
+
try {
|
|
55822
|
+
primitives.signal(pid, signal);
|
|
55823
|
+
} catch {
|
|
55824
|
+
}
|
|
55825
|
+
};
|
|
55826
|
+
send("SIGTERM");
|
|
55827
|
+
if (awaitExit(pid, primitives, TERM_GRACE_MS)) {
|
|
55828
|
+
return "exited-on-term";
|
|
55829
|
+
}
|
|
55830
|
+
send("SIGKILL");
|
|
55831
|
+
if (awaitExit(pid, primitives, KILL_GRACE_MS)) {
|
|
55832
|
+
return "killed";
|
|
55833
|
+
}
|
|
55834
|
+
return "still-running";
|
|
55835
|
+
}
|
|
55836
|
+
function awaitExit(pid, primitives, budgetMs) {
|
|
55837
|
+
const deadline = primitives.now() + budgetMs;
|
|
55838
|
+
while (primitives.isRunning(pid)) {
|
|
55839
|
+
if (primitives.now() >= deadline) {
|
|
55840
|
+
return false;
|
|
55841
|
+
}
|
|
55842
|
+
primitives.waitMs(STOP_POLL_MS);
|
|
55843
|
+
}
|
|
55844
|
+
return true;
|
|
55845
|
+
}
|
|
55846
|
+
function backoffForAttempt(attempt) {
|
|
55847
|
+
return Math.min(HEADROOM_BACKOFF_CAP_MS, HEADROOM_BACKOFF_BASE_MS * 2 ** (attempt - 1));
|
|
55848
|
+
}
|
|
55849
|
+
function versionSatisfies(version2, source) {
|
|
55850
|
+
if (version2 === void 0) {
|
|
55851
|
+
return false;
|
|
55852
|
+
}
|
|
55853
|
+
const specifier = /==|>=|<=|!=|>|<|~=/.exec(source);
|
|
55854
|
+
if (specifier === null) {
|
|
55855
|
+
return true;
|
|
55856
|
+
}
|
|
55857
|
+
const installed = parseVersion(version2);
|
|
55858
|
+
const wanted = parseVersion(source.slice(specifier.index + specifier[0].length));
|
|
55859
|
+
if (installed === void 0 || wanted === void 0) {
|
|
55860
|
+
return true;
|
|
55861
|
+
}
|
|
55862
|
+
const cmp = compareVersions2(installed, wanted);
|
|
55863
|
+
switch (specifier[0]) {
|
|
55864
|
+
case "==":
|
|
55865
|
+
return cmp === 0;
|
|
55866
|
+
case "!=":
|
|
55867
|
+
return cmp !== 0;
|
|
55868
|
+
case ">=":
|
|
55869
|
+
return cmp >= 0;
|
|
55870
|
+
case "<=":
|
|
55871
|
+
return cmp <= 0;
|
|
55872
|
+
case ">":
|
|
55873
|
+
return cmp > 0;
|
|
55874
|
+
case "<":
|
|
55875
|
+
return cmp < 0;
|
|
55876
|
+
case "~=":
|
|
55877
|
+
return compareVersions2(installed.slice(0, Math.max(0, wanted.length - 1)), wanted.slice(0, Math.max(0, wanted.length - 1))) === 0 && cmp >= 0;
|
|
55878
|
+
default:
|
|
55879
|
+
return true;
|
|
55880
|
+
}
|
|
55881
|
+
}
|
|
55882
|
+
function parseVersion(input2) {
|
|
55883
|
+
const match = /(\d+)(\.\d+)*/.exec(input2);
|
|
55884
|
+
if (match === null) {
|
|
55885
|
+
return void 0;
|
|
55886
|
+
}
|
|
55887
|
+
return match[0].split(".").map((part) => Number.parseInt(part, 10));
|
|
55888
|
+
}
|
|
55889
|
+
function compareVersions2(a2, b) {
|
|
55890
|
+
for (let index = 0; index < Math.max(a2.length, b.length); index += 1) {
|
|
55891
|
+
const left = a2[index] ?? 0;
|
|
55892
|
+
const right = b[index] ?? 0;
|
|
55893
|
+
if (left !== right) {
|
|
55894
|
+
return left - right;
|
|
55895
|
+
}
|
|
55896
|
+
}
|
|
55897
|
+
return 0;
|
|
55898
|
+
}
|
|
55899
|
+
var HEADROOM_SUPERVISOR_STILL_RUNNING = -1;
|
|
55900
|
+
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
55901
|
+
const { fs: fs19, paths } = ports;
|
|
55902
|
+
let config2 = initialConfig;
|
|
55903
|
+
const previousState = readHeadroomState(fs19, paths.headroomStateFile);
|
|
55904
|
+
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
55905
|
+
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
55906
|
+
return 0;
|
|
55907
|
+
}
|
|
55908
|
+
let installedSource = previousState?.installedSource;
|
|
55909
|
+
const ownsState = () => {
|
|
55910
|
+
const owner = readHeadroomState(fs19, paths.headroomStateFile)?.supervisorPid;
|
|
55911
|
+
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
55912
|
+
};
|
|
55913
|
+
const writeOwnState = (state) => {
|
|
55914
|
+
if (!ownsState()) {
|
|
55915
|
+
return false;
|
|
55916
|
+
}
|
|
55917
|
+
writeHeadroomState(fs19, paths.headroomStateFile, state);
|
|
55918
|
+
return true;
|
|
55919
|
+
};
|
|
55920
|
+
const fail = (message) => {
|
|
55921
|
+
if (writeOwnState({ lastError: message })) {
|
|
55922
|
+
fs19.removeRecursive(paths.headroomLockFile);
|
|
55923
|
+
}
|
|
55924
|
+
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
55925
|
+
return 1;
|
|
55926
|
+
};
|
|
55927
|
+
const ensureInstalled = () => {
|
|
55928
|
+
const version3 = ports.headroomVersion();
|
|
55929
|
+
const versionOk = version3 !== void 0 && versionSatisfies(version3, config2.source);
|
|
55930
|
+
const pinned = pinnedGitCommit(config2.source);
|
|
55931
|
+
const commitOk = pinned === void 0 || ports.installedCommit() === pinned;
|
|
55932
|
+
if (versionOk && commitOk && (installedSource === void 0 || installedSource === config2.source)) {
|
|
55933
|
+
installedSource = config2.source;
|
|
55934
|
+
return true;
|
|
55935
|
+
}
|
|
55936
|
+
ports.log(`agent-shim headroom supervisor: installing headroom from ${config2.source}`);
|
|
55937
|
+
const result = ports.install(config2.source);
|
|
55938
|
+
if (!result.ok) {
|
|
55939
|
+
return false;
|
|
55940
|
+
}
|
|
55941
|
+
installedSource = config2.source;
|
|
55942
|
+
return true;
|
|
55943
|
+
};
|
|
55944
|
+
const socket = prepareHeadroomSocket(fs19, ports.socketTrust, paths, ports.ownPid);
|
|
55945
|
+
if (socket.refused !== void 0) {
|
|
55946
|
+
return fail(socket.refused);
|
|
55947
|
+
}
|
|
55948
|
+
const { socketPath } = socket;
|
|
55949
|
+
pruneStaleHeadroomSockets(fs19, paths, ports.isRunning);
|
|
55950
|
+
if (!ensureInstalled()) {
|
|
55951
|
+
return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
|
|
55952
|
+
}
|
|
55953
|
+
const version2 = ports.headroomVersion() ?? "unknown";
|
|
55954
|
+
writeOwnState({ supervisorPid: ports.ownPid, version: version2, installedSource });
|
|
55955
|
+
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${allowlistOf(ports).join(", ")}]`);
|
|
55956
|
+
const orphanPid = previousState?.headroomPid;
|
|
55957
|
+
if (orphanPid !== void 0 && ports.isRunning(orphanPid)) {
|
|
55958
|
+
ports.log(`agent-shim headroom supervisor: stopping daemon pid ${String(orphanPid)} left behind by the previous supervisor`);
|
|
55959
|
+
ports.stopProcess(orphanPid);
|
|
55960
|
+
}
|
|
55961
|
+
let headroomPid;
|
|
55962
|
+
let runningHash;
|
|
55963
|
+
let runningSettingsHash;
|
|
55964
|
+
let consecutiveFailures = 0;
|
|
55965
|
+
let idleSince;
|
|
55966
|
+
let superseded = false;
|
|
55967
|
+
let ticks = 0;
|
|
55968
|
+
for (; ; ) {
|
|
55969
|
+
if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
|
|
55970
|
+
return HEADROOM_SUPERVISOR_STILL_RUNNING;
|
|
55971
|
+
}
|
|
55972
|
+
ticks += 1;
|
|
55973
|
+
config2 = ports.readConfig();
|
|
55974
|
+
const settingsHash = hashSettings(config2.settings);
|
|
55975
|
+
const allowlist = allowlistOf(ports);
|
|
55976
|
+
const allowlistHash = hashAllowlist(allowlist);
|
|
55977
|
+
pruneDeadSessions(fs19, paths.headroomSessionsDir, ports.isRunning);
|
|
55978
|
+
const ownsNow = ownsState();
|
|
55979
|
+
if (!ownsNow && !superseded) {
|
|
55980
|
+
ports.log("agent-shim headroom supervisor: another supervisor now owns the state file; serving this daemon's own sessions until they end");
|
|
55981
|
+
}
|
|
55982
|
+
superseded = !ownsNow;
|
|
55983
|
+
const crashed = headroomPid !== void 0 && !ports.isRunning(headroomPid);
|
|
55984
|
+
if (headroomPid === void 0 || crashed) {
|
|
55985
|
+
if (crashed) {
|
|
55986
|
+
ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} died`);
|
|
55987
|
+
headroomPid = void 0;
|
|
55988
|
+
runningHash = void 0;
|
|
55989
|
+
runningSettingsHash = void 0;
|
|
55990
|
+
writeOwnState({
|
|
55991
|
+
supervisorPid: ports.ownPid,
|
|
55992
|
+
version: version2,
|
|
55993
|
+
installedSource
|
|
55994
|
+
});
|
|
55995
|
+
}
|
|
55996
|
+
if (consecutiveFailures >= HEADROOM_START_RETRY_BUDGET) {
|
|
55997
|
+
return fail(`headroom failed to become ready ${String(consecutiveFailures)} times in a row; giving up`);
|
|
55998
|
+
}
|
|
55999
|
+
if (installedSource !== config2.source && !ensureInstalled()) {
|
|
56000
|
+
return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
|
|
56001
|
+
}
|
|
56002
|
+
const pid = ports.spawnHeadroom(socketPath, allowlist, config2.settings);
|
|
56003
|
+
const ready = await waitUntilReady(ports, socketPath);
|
|
56004
|
+
if (ready) {
|
|
56005
|
+
consecutiveFailures = 0;
|
|
56006
|
+
headroomPid = pid;
|
|
56007
|
+
runningHash = allowlistHash;
|
|
56008
|
+
runningSettingsHash = settingsHash;
|
|
56009
|
+
const recorded = writeOwnState({
|
|
56010
|
+
supervisorPid: ports.ownPid,
|
|
56011
|
+
headroomPid: pid,
|
|
56012
|
+
socketPath,
|
|
56013
|
+
version: version2,
|
|
56014
|
+
allowlistHash,
|
|
56015
|
+
settingsHash,
|
|
56016
|
+
installedSource: config2.source
|
|
56017
|
+
});
|
|
56018
|
+
if (recorded) {
|
|
56019
|
+
fs19.removeRecursive(paths.headroomLockFile);
|
|
56020
|
+
}
|
|
56021
|
+
idleSince = void 0;
|
|
56022
|
+
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on unix socket ${socketPath}`);
|
|
56023
|
+
} else {
|
|
56024
|
+
ports.stopProcess(pid);
|
|
56025
|
+
consecutiveFailures += 1;
|
|
56026
|
+
ports.log(
|
|
56027
|
+
`agent-shim headroom supervisor: headroom did not become ready on unix socket ${socketPath} (attempt ${String(consecutiveFailures)} of ${String(HEADROOM_START_RETRY_BUDGET)})`
|
|
56028
|
+
);
|
|
56029
|
+
await ports.sleep(backoffForAttempt(consecutiveFailures));
|
|
56030
|
+
continue;
|
|
56031
|
+
}
|
|
56032
|
+
} else {
|
|
56033
|
+
if (runningHash !== allowlistHash || runningSettingsHash !== settingsHash || installedSource !== config2.source) {
|
|
56034
|
+
if (sessionsForSupervisor(fs19, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
56035
|
+
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
56036
|
+
ports.stopProcess(headroomPid);
|
|
56037
|
+
headroomPid = void 0;
|
|
56038
|
+
runningHash = void 0;
|
|
56039
|
+
runningSettingsHash = void 0;
|
|
56040
|
+
continue;
|
|
56041
|
+
}
|
|
56042
|
+
}
|
|
56043
|
+
const sessions = sessionsForSupervisor(fs19, paths.headroomSessionsDir, ports.ownPid);
|
|
56044
|
+
if (sessions.length === 0) {
|
|
56045
|
+
idleSince ??= ports.now();
|
|
56046
|
+
const idleMs = ports.now() - idleSince;
|
|
56047
|
+
if (idleMs >= config2.idleShutdownMinutes * MS_PER_MINUTE) {
|
|
56048
|
+
ports.log(
|
|
56049
|
+
`agent-shim headroom supervisor: no sessions for ${String(config2.idleShutdownMinutes)} minute(s); stopping headroom and exiting`
|
|
56050
|
+
);
|
|
56051
|
+
ports.stopProcess(headroomPid);
|
|
56052
|
+
writeOwnState({ version: version2 });
|
|
56053
|
+
return 0;
|
|
56054
|
+
}
|
|
56055
|
+
} else {
|
|
56056
|
+
idleSince = void 0;
|
|
56057
|
+
}
|
|
56058
|
+
}
|
|
56059
|
+
await ports.sleep(HEADROOM_POLL_MS);
|
|
56060
|
+
}
|
|
56061
|
+
}
|
|
56062
|
+
function currentHeadroomAllowlist(fs19, paths) {
|
|
56063
|
+
const providers = readAllProviders(fs19, paths.providersDir).map((entry) => entry.provider);
|
|
56064
|
+
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(fs19, paths.frontdoorStateFile))));
|
|
56065
|
+
}
|
|
56066
|
+
function allowlistOf(ports) {
|
|
56067
|
+
return currentHeadroomAllowlist(ports.fs, ports.paths);
|
|
56068
|
+
}
|
|
56069
|
+
async function waitUntilReady(ports, socketPath) {
|
|
56070
|
+
const deadline = ports.now() + HEADROOM_READY_TIMEOUT_MS;
|
|
56071
|
+
for (; ; ) {
|
|
56072
|
+
if (await ports.ready(socketPath)) {
|
|
56073
|
+
return true;
|
|
56074
|
+
}
|
|
56075
|
+
if (ports.now() >= deadline) {
|
|
56076
|
+
return false;
|
|
56077
|
+
}
|
|
56078
|
+
await ports.sleep(HEADROOM_POLL_MS);
|
|
56079
|
+
}
|
|
56080
|
+
}
|
|
56081
|
+
|
|
55549
56082
|
// src/realPorts.ts
|
|
55550
56083
|
function isEnoent2(error62) {
|
|
55551
56084
|
return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === "ENOENT";
|
|
@@ -55669,7 +56202,7 @@ var realFarmFs = {
|
|
|
55669
56202
|
},
|
|
55670
56203
|
hashFile(filePath) {
|
|
55671
56204
|
try {
|
|
55672
|
-
return (0,
|
|
56205
|
+
return (0, import_node_crypto4.createHash)("sha256").update(import_node_fs3.default.readFileSync(filePath)).digest("hex");
|
|
55673
56206
|
} catch (error62) {
|
|
55674
56207
|
if (isEnoent2(error62) || isErrorWithCode(error62, "EISDIR")) {
|
|
55675
56208
|
return void 0;
|
|
@@ -55704,7 +56237,7 @@ var realRunPort = {
|
|
|
55704
56237
|
}
|
|
55705
56238
|
};
|
|
55706
56239
|
function expandHome(filePath) {
|
|
55707
|
-
return filePath.startsWith("~/") ?
|
|
56240
|
+
return filePath.startsWith("~/") ? import_node_path8.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
|
|
55708
56241
|
}
|
|
55709
56242
|
var MACOS_GUI_SESSION_MANAGER = "Aqua";
|
|
55710
56243
|
function hasDesktopSession() {
|
|
@@ -55780,7 +56313,7 @@ function spawnDetachedSupervisor(paths, subcommand, logPath) {
|
|
|
55780
56313
|
return spawnDetachedDaemon(selfInvocation([subcommand]), paths, subcommand, logPath);
|
|
55781
56314
|
}
|
|
55782
56315
|
function spawnDetachedDaemon(invocation, paths, subcommand, logPath) {
|
|
55783
|
-
import_node_fs3.default.mkdirSync(
|
|
56316
|
+
import_node_fs3.default.mkdirSync(import_node_path8.default.dirname(logPath), { recursive: true });
|
|
55784
56317
|
const logFd = import_node_fs3.default.openSync(logPath, "a");
|
|
55785
56318
|
try {
|
|
55786
56319
|
const child = (0, import_node_child_process2.spawn)(invocation.command, invocation.args, detachedDaemonSpawnOptions(logFd, { ...process.env, AGENT_SHIM_HOME: paths.root }));
|
|
@@ -55821,10 +56354,11 @@ var realHeadroomSocketTrust = {
|
|
|
55821
56354
|
};
|
|
55822
56355
|
function realHeadroomPort(paths, options) {
|
|
55823
56356
|
return {
|
|
55824
|
-
ensure: () => {
|
|
56357
|
+
ensure: ({ routesProvider }) => {
|
|
55825
56358
|
const up = ensureHeadroom({
|
|
55826
56359
|
paths,
|
|
55827
56360
|
launcherPid: process.pid,
|
|
56361
|
+
...routesProvider ? { requiredAllowlistHash: () => hashAllowlist(currentHeadroomAllowlist(realFarmFs, paths)) } : {},
|
|
55828
56362
|
ports: {
|
|
55829
56363
|
fs: realFarmFs,
|
|
55830
56364
|
// Zombie-aware on purpose: a supervisor that died while still a child of this launcher sits unreaped until the launcher itself exits, and a defunct supervisor answering signal 0 as alive would stretch every launch to the full start timeout.
|
|
@@ -55878,7 +56412,7 @@ function listVersionsDir(dir) {
|
|
|
55878
56412
|
throw error62;
|
|
55879
56413
|
}
|
|
55880
56414
|
return entries.filter((entry) => entry.isFile()).map((entry) => {
|
|
55881
|
-
const fullPath =
|
|
56415
|
+
const fullPath = import_node_path8.default.join(dir, entry.name);
|
|
55882
56416
|
const stat = import_node_fs3.default.statSync(fullPath);
|
|
55883
56417
|
return {
|
|
55884
56418
|
name: entry.name,
|
|
@@ -55893,7 +56427,7 @@ function windowsPathExtensions(pathext) {
|
|
|
55893
56427
|
return (pathext ?? WINDOWS_DEFAULT_PATHEXT).split(";").map((ext) => ext.trim()).filter((ext) => ext.length > 0);
|
|
55894
56428
|
}
|
|
55895
56429
|
function resolveExecutableCandidate(dir, name, env) {
|
|
55896
|
-
const candidate =
|
|
56430
|
+
const candidate = import_node_path8.default.join(dir, name);
|
|
55897
56431
|
if (env.platform === "win32") {
|
|
55898
56432
|
const extensions = windowsPathExtensions(env.pathext);
|
|
55899
56433
|
const alreadyHasRecognisedExtension = extensions.some((ext) => candidate.toLowerCase().endsWith(ext.toLowerCase()));
|
|
@@ -55942,13 +56476,13 @@ function resolveOwnExecutablePath(env) {
|
|
|
55942
56476
|
if (env.argv1 !== void 0 && !env.argv1.includes("/") && !env.argv1.includes("\\")) {
|
|
55943
56477
|
return searchPathForExecutable(env.pathDirs, env.argv1, env.findExecutableInDir) ?? env.execPath;
|
|
55944
56478
|
}
|
|
55945
|
-
const candidate = env.argv1 === void 0 ? env.execPath :
|
|
55946
|
-
const candidateDir =
|
|
55947
|
-
const candidateDirOnPath = env.pathDirs.some((dir) =>
|
|
56479
|
+
const candidate = env.argv1 === void 0 ? env.execPath : import_node_path8.default.resolve(env.cwd, env.argv1);
|
|
56480
|
+
const candidateDir = import_node_path8.default.dirname(candidate);
|
|
56481
|
+
const candidateDirOnPath = env.pathDirs.some((dir) => import_node_path8.default.resolve(dir) === candidateDir);
|
|
55948
56482
|
if (candidateDirOnPath) {
|
|
55949
56483
|
return candidate;
|
|
55950
56484
|
}
|
|
55951
|
-
const viaPath = searchPathForExecutable(env.pathDirs,
|
|
56485
|
+
const viaPath = searchPathForExecutable(env.pathDirs, import_node_path8.default.basename(candidate), env.findExecutableInDir);
|
|
55952
56486
|
return viaPath ?? candidate;
|
|
55953
56487
|
}
|
|
55954
56488
|
function realOwnExecutablePath() {
|
|
@@ -55956,7 +56490,7 @@ function realOwnExecutablePath() {
|
|
|
55956
56490
|
argv1: process.argv[1],
|
|
55957
56491
|
execPath: process.execPath,
|
|
55958
56492
|
cwd: process.cwd(),
|
|
55959
|
-
pathDirs: (process.env.PATH ?? "").split(
|
|
56493
|
+
pathDirs: (process.env.PATH ?? "").split(import_node_path8.default.delimiter).filter((dir) => dir !== ""),
|
|
55960
56494
|
findExecutableInDir
|
|
55961
56495
|
});
|
|
55962
56496
|
}
|
|
@@ -55969,7 +56503,7 @@ function realContentSourcePath() {
|
|
|
55969
56503
|
function realResolveClaudeBinary(isOwnBinary) {
|
|
55970
56504
|
return () => discoverClaudeBinary({
|
|
55971
56505
|
listVersionsDir,
|
|
55972
|
-
pathDirs: (process.env.PATH ?? "").split(
|
|
56506
|
+
pathDirs: (process.env.PATH ?? "").split(import_node_path8.default.delimiter).filter((dir) => dir !== ""),
|
|
55973
56507
|
findExecutableInDir,
|
|
55974
56508
|
isOwnBinary
|
|
55975
56509
|
});
|
|
@@ -56015,10 +56549,10 @@ function isInvokedAsClaude(invokedName) {
|
|
|
56015
56549
|
}
|
|
56016
56550
|
function resolveOwnBinaryCheck(paths, contentSourcePath) {
|
|
56017
56551
|
const state = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
56018
|
-
const recordedTarget = state === void 0 ? void 0 :
|
|
56552
|
+
const recordedTarget = state === void 0 ? void 0 : import_node_path9.default.resolve(state.targetPath);
|
|
56019
56553
|
let ownStat;
|
|
56020
56554
|
return (candidate) => {
|
|
56021
|
-
if (recordedTarget !== void 0 &&
|
|
56555
|
+
if (recordedTarget !== void 0 && import_node_path9.default.resolve(candidate) === recordedTarget) {
|
|
56022
56556
|
return true;
|
|
56023
56557
|
}
|
|
56024
56558
|
ownStat ??= statOrUndefined(contentSourcePath);
|
|
@@ -56028,7 +56562,7 @@ function resolveOwnBinaryCheck(paths, contentSourcePath) {
|
|
|
56028
56562
|
};
|
|
56029
56563
|
}
|
|
56030
56564
|
function resolveClaudeTargetPath(ownExecutablePath, dir) {
|
|
56031
|
-
return
|
|
56565
|
+
return import_node_path9.default.join(dir ?? import_node_path9.default.dirname(ownExecutablePath), claudeTargetFilename(ownExecutablePath));
|
|
56032
56566
|
}
|
|
56033
56567
|
function isEnoent3(error62) {
|
|
56034
56568
|
return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === "ENOENT";
|
|
@@ -56063,13 +56597,13 @@ function enableClaudeShim(params, linkFs = nodeLinkFs) {
|
|
|
56063
56597
|
throw new UnsupportedShimSourceError(realContentPath);
|
|
56064
56598
|
}
|
|
56065
56599
|
const targetPath = resolveClaudeTargetPath(params.ownExecutablePath, params.dir);
|
|
56066
|
-
import_node_fs4.default.mkdirSync(
|
|
56600
|
+
import_node_fs4.default.mkdirSync(import_node_path9.default.dirname(targetPath), { recursive: true });
|
|
56067
56601
|
const existing = lstatOrUndefined(targetPath);
|
|
56068
56602
|
if (existing !== void 0) {
|
|
56069
56603
|
const ownStat = import_node_fs4.default.statSync(realContentPath);
|
|
56070
56604
|
const state = readJson(params.paths.claudeShimFile, ClaudeShimStateSchema);
|
|
56071
56605
|
const sameInode = existing.dev === ownStat.dev && existing.ino === ownStat.ino;
|
|
56072
|
-
const markerMatches = state !== void 0 &&
|
|
56606
|
+
const markerMatches = state !== void 0 && import_node_path9.default.resolve(state.targetPath) === targetPath;
|
|
56073
56607
|
if (!sameInode && !markerMatches && !params.force) {
|
|
56074
56608
|
throw new ForeignClaudeEntryError(targetPath, "enable");
|
|
56075
56609
|
}
|
|
@@ -56094,7 +56628,7 @@ function enableClaudeShim(params, linkFs = nodeLinkFs) {
|
|
|
56094
56628
|
function disableClaudeShim(params) {
|
|
56095
56629
|
const realContentPath = import_node_fs4.default.realpathSync(params.contentSourcePath);
|
|
56096
56630
|
const state = readJson(params.paths.claudeShimFile, ClaudeShimStateSchema);
|
|
56097
|
-
const targetPath = params.dir !== void 0 ?
|
|
56631
|
+
const targetPath = params.dir !== void 0 ? import_node_path9.default.join(params.dir, claudeTargetFilename(params.ownExecutablePath)) : state?.targetPath ?? resolveClaudeTargetPath(params.ownExecutablePath);
|
|
56098
56632
|
const existing = lstatOrUndefined(targetPath);
|
|
56099
56633
|
if (existing === void 0) {
|
|
56100
56634
|
if (state !== void 0) {
|
|
@@ -56104,7 +56638,7 @@ function disableClaudeShim(params) {
|
|
|
56104
56638
|
}
|
|
56105
56639
|
const ownStat = import_node_fs4.default.statSync(realContentPath);
|
|
56106
56640
|
const sameInode = existing.dev === ownStat.dev && existing.ino === ownStat.ino;
|
|
56107
|
-
const markerMatches = state !== void 0 &&
|
|
56641
|
+
const markerMatches = state !== void 0 && import_node_path9.default.resolve(state.targetPath) === targetPath;
|
|
56108
56642
|
if (!sameInode && !markerMatches && !params.force) {
|
|
56109
56643
|
throw new ForeignClaudeEntryError(targetPath, "disable");
|
|
56110
56644
|
}
|
|
@@ -56113,15 +56647,15 @@ function disableClaudeShim(params) {
|
|
|
56113
56647
|
return { action: "disabled", targetPath };
|
|
56114
56648
|
}
|
|
56115
56649
|
function findPathShadow(params) {
|
|
56116
|
-
const resolvedTargetDir =
|
|
56650
|
+
const resolvedTargetDir = import_node_path9.default.resolve(params.targetDir);
|
|
56117
56651
|
for (const dir of params.pathDirs) {
|
|
56118
56652
|
const found = params.findExecutableInDir(dir, params.targetFilename);
|
|
56119
56653
|
if (found === void 0) {
|
|
56120
56654
|
continue;
|
|
56121
56655
|
}
|
|
56122
|
-
return
|
|
56656
|
+
return import_node_path9.default.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
|
|
56123
56657
|
}
|
|
56124
|
-
return params.pathDirs.some((dir) =>
|
|
56658
|
+
return params.pathDirs.some((dir) => import_node_path9.default.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
|
|
56125
56659
|
}
|
|
56126
56660
|
function registerShimCommand(program2, deps) {
|
|
56127
56661
|
const { paths } = deps;
|
|
@@ -56139,21 +56673,21 @@ function registerShimCommand(program2, deps) {
|
|
|
56139
56673
|
ownExecutablePath,
|
|
56140
56674
|
contentSourcePath,
|
|
56141
56675
|
platform: process.platform,
|
|
56142
|
-
...options.dir === void 0 ? {} : { dir:
|
|
56676
|
+
...options.dir === void 0 ? {} : { dir: import_node_path9.default.resolve(options.dir) },
|
|
56143
56677
|
force: options.force ?? false
|
|
56144
56678
|
});
|
|
56145
56679
|
console.log(`${result.action === "enabled" ? "Installed" : "Reinstalled"} \`claude\` at ${result.targetPath} (${result.method}).`);
|
|
56146
56680
|
const shadow = findPathShadow({
|
|
56147
|
-
pathDirs: (process.env.PATH ?? "").split(
|
|
56148
|
-
targetDir:
|
|
56149
|
-
targetFilename:
|
|
56681
|
+
pathDirs: (process.env.PATH ?? "").split(import_node_path9.default.delimiter).filter((dir) => dir !== ""),
|
|
56682
|
+
targetDir: import_node_path9.default.dirname(result.targetPath),
|
|
56683
|
+
targetFilename: import_node_path9.default.basename(result.targetPath),
|
|
56150
56684
|
findExecutableInDir
|
|
56151
56685
|
});
|
|
56152
56686
|
if (shadow.status === "not-on-path") {
|
|
56153
|
-
console.warn(`warning: ${
|
|
56687
|
+
console.warn(`warning: ${import_node_path9.default.dirname(result.targetPath)} is not on PATH \u2014 add it, or use \`agent-shim run\` instead.`);
|
|
56154
56688
|
} else if (shadow.status === "shadowed") {
|
|
56155
56689
|
console.warn(
|
|
56156
|
-
`warning: 'claude' on PATH currently resolves to ${shadow.by}, not ${result.targetPath}. Put ${
|
|
56690
|
+
`warning: 'claude' on PATH currently resolves to ${shadow.by}, not ${result.targetPath}. Put ${import_node_path9.default.dirname(result.targetPath)} ahead of it on PATH.`
|
|
56157
56691
|
);
|
|
56158
56692
|
}
|
|
56159
56693
|
});
|
|
@@ -56165,7 +56699,7 @@ function registerShimCommand(program2, deps) {
|
|
|
56165
56699
|
paths,
|
|
56166
56700
|
ownExecutablePath,
|
|
56167
56701
|
contentSourcePath,
|
|
56168
|
-
...options.dir === void 0 ? {} : { dir:
|
|
56702
|
+
...options.dir === void 0 ? {} : { dir: import_node_path9.default.resolve(options.dir) },
|
|
56169
56703
|
force: options.force ?? false
|
|
56170
56704
|
});
|
|
56171
56705
|
console.log(
|
|
@@ -56221,7 +56755,7 @@ function aliasLegacyWireHeaders(headers) {
|
|
|
56221
56755
|
// src/configure.ts
|
|
56222
56756
|
var import_node_fs8 = __toESM(require("node:fs"), 1);
|
|
56223
56757
|
var import_node_os4 = __toESM(require("node:os"), 1);
|
|
56224
|
-
var
|
|
56758
|
+
var import_node_path20 = __toESM(require("node:path"), 1);
|
|
56225
56759
|
|
|
56226
56760
|
// node_modules/.pnpm/@clack+core@1.5.1/node_modules/@clack/core/dist/index.mjs
|
|
56227
56761
|
var import_node_util3 = require("node:util");
|
|
@@ -57490,10 +58024,10 @@ function classifyEntries(names, options) {
|
|
|
57490
58024
|
|
|
57491
58025
|
// src/identityStore.ts
|
|
57492
58026
|
var import_node_fs6 = __toESM(require("node:fs"), 1);
|
|
57493
|
-
var
|
|
58027
|
+
var import_node_path13 = __toESM(require("node:path"), 1);
|
|
57494
58028
|
|
|
57495
58029
|
// src/launcher/identity.ts
|
|
57496
|
-
var
|
|
58030
|
+
var import_node_path10 = __toESM(require("node:path"), 1);
|
|
57497
58031
|
function poolNameOf(selector) {
|
|
57498
58032
|
return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
|
|
57499
58033
|
}
|
|
@@ -57542,12 +58076,12 @@ function decideConfigProfile(params) {
|
|
|
57542
58076
|
return { source: "none" };
|
|
57543
58077
|
}
|
|
57544
58078
|
function loadIdentity(identitiesDir, name, fs19) {
|
|
57545
|
-
return loadConfigFile(
|
|
58079
|
+
return loadConfigFile(import_node_path10.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs19.readConfigFile);
|
|
57546
58080
|
}
|
|
57547
58081
|
|
|
57548
58082
|
// src/configProfilesStore.ts
|
|
57549
58083
|
var import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
57550
|
-
var
|
|
58084
|
+
var import_node_path11 = __toESM(require("node:path"), 1);
|
|
57551
58085
|
var ProfileNotFoundError = class extends CliError {
|
|
57552
58086
|
constructor(profileName) {
|
|
57553
58087
|
super(`No configuration profile named "${profileName}". Run \`agent-shim profile add ${profileName}\` first.`);
|
|
@@ -57573,7 +58107,7 @@ var InvalidCategoryNameError = class extends CliError {
|
|
|
57573
58107
|
categoryName;
|
|
57574
58108
|
};
|
|
57575
58109
|
function profileJsonPath(paths, name) {
|
|
57576
|
-
return
|
|
58110
|
+
return import_node_path11.default.join(paths.configProfilesDir, `${name}.json`);
|
|
57577
58111
|
}
|
|
57578
58112
|
function profileExists(paths, name) {
|
|
57579
58113
|
return import_node_fs5.default.existsSync(profileJsonPath(paths, name));
|
|
@@ -57734,8 +58268,8 @@ function removePool(paths, name) {
|
|
|
57734
58268
|
}
|
|
57735
58269
|
|
|
57736
58270
|
// src/launcher/lock.ts
|
|
57737
|
-
var
|
|
57738
|
-
var
|
|
58271
|
+
var import_node_crypto5 = require("node:crypto");
|
|
58272
|
+
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
57739
58273
|
var DEFAULT_STALE_AFTER_MS = 12e4;
|
|
57740
58274
|
var DEFAULT_RETRY_DELAY_MS = 50;
|
|
57741
58275
|
var DEFAULT_MAX_ATTEMPTS = 200;
|
|
@@ -57754,7 +58288,7 @@ var IdentityLockBusyError = class extends CliError {
|
|
|
57754
58288
|
holderPid;
|
|
57755
58289
|
};
|
|
57756
58290
|
function identityLockPath(dir, identity) {
|
|
57757
|
-
return
|
|
58291
|
+
return import_node_path12.default.join(dir, `.${identity}.lock`);
|
|
57758
58292
|
}
|
|
57759
58293
|
function parseLockRecord(raw) {
|
|
57760
58294
|
if (raw === void 0) {
|
|
@@ -57783,7 +58317,7 @@ function acquireIdentityLock(params) {
|
|
|
57783
58317
|
const staleAfterMs = params.staleAfterMs ?? DEFAULT_STALE_AFTER_MS;
|
|
57784
58318
|
const retryDelayMs = params.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS;
|
|
57785
58319
|
const maxAttempts = params.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
57786
|
-
const token = (0,
|
|
58320
|
+
const token = (0, import_node_crypto5.randomUUID)();
|
|
57787
58321
|
if (params.fs.lstat(params.dir) === void 0) {
|
|
57788
58322
|
params.fs.mkdirp(params.dir);
|
|
57789
58323
|
}
|
|
@@ -57848,7 +58382,7 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
57848
58382
|
attemptedName;
|
|
57849
58383
|
};
|
|
57850
58384
|
function identityJsonPath(paths, name) {
|
|
57851
|
-
return
|
|
58385
|
+
return import_node_path13.default.join(paths.identitiesDir, name, "identity.json");
|
|
57852
58386
|
}
|
|
57853
58387
|
function identityExists(paths, name) {
|
|
57854
58388
|
return import_node_fs6.default.existsSync(identityJsonPath(paths, name));
|
|
@@ -57949,7 +58483,7 @@ function setIdentityCredential(paths, identityName, change) {
|
|
|
57949
58483
|
});
|
|
57950
58484
|
}
|
|
57951
58485
|
function belongsToIdentity(entry, name) {
|
|
57952
|
-
return entry === name || entry ===
|
|
58486
|
+
return entry === name || entry === import_node_path13.default.basename(identityLockPath("", name)) || entry.startsWith(`.${name}.scratch.`) || entry.startsWith(`.${name}.previous.`);
|
|
57953
58487
|
}
|
|
57954
58488
|
function removeIdentity(paths, name) {
|
|
57955
58489
|
if (!identityExists(paths, name)) {
|
|
@@ -57957,7 +58491,7 @@ function removeIdentity(paths, name) {
|
|
|
57957
58491
|
}
|
|
57958
58492
|
for (const entry of import_node_fs6.default.readdirSync(paths.identitiesDir)) {
|
|
57959
58493
|
if (belongsToIdentity(entry, name)) {
|
|
57960
|
-
import_node_fs6.default.rmSync(
|
|
58494
|
+
import_node_fs6.default.rmSync(import_node_path13.default.join(paths.identitiesDir, entry), { recursive: true, force: true });
|
|
57961
58495
|
}
|
|
57962
58496
|
}
|
|
57963
58497
|
if (readActiveIdentity(paths) === name) {
|
|
@@ -58056,32 +58590,32 @@ function removeDirectoryRule(paths, rulePath) {
|
|
|
58056
58590
|
}
|
|
58057
58591
|
|
|
58058
58592
|
// src/launcher/cascade.ts
|
|
58059
|
-
var
|
|
58593
|
+
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
58060
58594
|
|
|
58061
58595
|
// src/pathNorm.ts
|
|
58062
|
-
var
|
|
58596
|
+
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
58063
58597
|
function expandTilde(value, home) {
|
|
58064
58598
|
if (value === "~") {
|
|
58065
58599
|
return home;
|
|
58066
58600
|
}
|
|
58067
58601
|
if (value.startsWith("~/")) {
|
|
58068
|
-
return
|
|
58602
|
+
return import_node_path14.default.join(home, value.slice(2));
|
|
58069
58603
|
}
|
|
58070
58604
|
return value;
|
|
58071
58605
|
}
|
|
58072
58606
|
function normaliseRulePath(rulePath, home) {
|
|
58073
|
-
return
|
|
58607
|
+
return import_node_path14.default.resolve(expandTilde(rulePath, home));
|
|
58074
58608
|
}
|
|
58075
58609
|
function isAncestorOrSelf(ancestor, descendant) {
|
|
58076
58610
|
if (ancestor === descendant) {
|
|
58077
58611
|
return true;
|
|
58078
58612
|
}
|
|
58079
|
-
const withSeparator = ancestor.endsWith(
|
|
58613
|
+
const withSeparator = ancestor.endsWith(import_node_path14.default.sep) ? ancestor : `${ancestor}${import_node_path14.default.sep}`;
|
|
58080
58614
|
return descendant.startsWith(withSeparator);
|
|
58081
58615
|
}
|
|
58082
58616
|
|
|
58083
58617
|
// src/resolve/walk.ts
|
|
58084
|
-
var
|
|
58618
|
+
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
58085
58619
|
|
|
58086
58620
|
// src/resolve/extends.ts
|
|
58087
58621
|
function lineariseProfile(rootName, load) {
|
|
@@ -58149,10 +58683,10 @@ function profileLayers(rootName, load, startId) {
|
|
|
58149
58683
|
|
|
58150
58684
|
// src/resolve/walk.ts
|
|
58151
58685
|
function walkDirectoryAncestors(cwd, options) {
|
|
58152
|
-
const limit =
|
|
58686
|
+
const limit = import_node_path15.default.resolve(options.limit ?? options.home);
|
|
58153
58687
|
const isReadable = options.isReadable ?? (() => true);
|
|
58154
58688
|
const collected = [];
|
|
58155
|
-
let current =
|
|
58689
|
+
let current = import_node_path15.default.resolve(cwd);
|
|
58156
58690
|
for (; ; ) {
|
|
58157
58691
|
if (!isReadable(current)) {
|
|
58158
58692
|
break;
|
|
@@ -58161,7 +58695,7 @@ function walkDirectoryAncestors(cwd, options) {
|
|
|
58161
58695
|
if (current === limit) {
|
|
58162
58696
|
break;
|
|
58163
58697
|
}
|
|
58164
|
-
const parent =
|
|
58698
|
+
const parent = import_node_path15.default.dirname(current);
|
|
58165
58699
|
if (parent === current) {
|
|
58166
58700
|
break;
|
|
58167
58701
|
}
|
|
@@ -58254,7 +58788,7 @@ function loadCascadeInput(params) {
|
|
|
58254
58788
|
const globalConfig2 = loadConfigFile(params.paths.globalConfigFile, GlobalConfigSchema, params.read);
|
|
58255
58789
|
const directoryRules = loadConfigFile(params.paths.directoryRulesFile, DirectoryRulesSchema, params.read);
|
|
58256
58790
|
const loadProfile = (name) => {
|
|
58257
|
-
const filepath =
|
|
58791
|
+
const filepath = import_node_path16.default.join(params.paths.configProfilesDir, `${name}.json`);
|
|
58258
58792
|
const loaded = loadConfigFile(filepath, ConfigProfileSchema, params.read);
|
|
58259
58793
|
if (loaded === void 0) {
|
|
58260
58794
|
return void 0;
|
|
@@ -58269,8 +58803,8 @@ function loadCascadeInput(params) {
|
|
|
58269
58803
|
});
|
|
58270
58804
|
const levels = [];
|
|
58271
58805
|
for (const dir of dirs) {
|
|
58272
|
-
const portable = loadConfigFile(
|
|
58273
|
-
const portableLocal = loadConfigFile(
|
|
58806
|
+
const portable = loadConfigFile(import_node_path16.default.join(dir, PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(import_node_path16.default.join(dir, LEGACY_PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read);
|
|
58807
|
+
const portableLocal = loadConfigFile(import_node_path16.default.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(import_node_path16.default.join(dir, LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read);
|
|
58274
58808
|
const rules = (directoryRules?.config.rules ?? []).map((rule, index) => ({ rule, index })).filter(({ rule }) => normaliseRulePath(rule.path, params.home) === dir).map(({ rule, index }) => {
|
|
58275
58809
|
const entryOrder = directoryRules?.ruleEntryOrders[index];
|
|
58276
58810
|
return {
|
|
@@ -58319,7 +58853,7 @@ function readDirectorySelections(loaded) {
|
|
|
58319
58853
|
}
|
|
58320
58854
|
|
|
58321
58855
|
// src/launcher/farm.ts
|
|
58322
|
-
var
|
|
58856
|
+
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
58323
58857
|
|
|
58324
58858
|
// src/resolve/reconcile.ts
|
|
58325
58859
|
function parentOf(rel) {
|
|
@@ -58987,7 +59521,7 @@ function dedupeDiagnostics(diagnostics) {
|
|
|
58987
59521
|
}
|
|
58988
59522
|
|
|
58989
59523
|
// src/resolve/plan.ts
|
|
58990
|
-
var
|
|
59524
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
58991
59525
|
function parentOf2(rel) {
|
|
58992
59526
|
const index = rel.lastIndexOf("/");
|
|
58993
59527
|
return index === -1 ? "" : rel.slice(0, index);
|
|
@@ -59037,7 +59571,7 @@ function planFarm(params) {
|
|
|
59037
59571
|
}
|
|
59038
59572
|
return value;
|
|
59039
59573
|
};
|
|
59040
|
-
const linkTarget = (rel) =>
|
|
59574
|
+
const linkTarget = (rel) => import_node_path17.default.join(params.facts.claudeHome, rel);
|
|
59041
59575
|
const visit2 = (rel) => {
|
|
59042
59576
|
const fact = params.facts.entries.get(rel);
|
|
59043
59577
|
const decision = params.decisions.get(rel);
|
|
@@ -59170,7 +59704,7 @@ var FarmManifestSchema = external_exports.strictObject({
|
|
|
59170
59704
|
links: external_exports.array(external_exports.strictObject({ rel: external_exports.string(), target: external_exports.string() }))
|
|
59171
59705
|
});
|
|
59172
59706
|
function readFarmManifest(fs19, farmRoot) {
|
|
59173
|
-
const raw = fs19.readFileUtf8(
|
|
59707
|
+
const raw = fs19.readFileUtf8(import_node_path18.default.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs19.readFileUtf8(import_node_path18.default.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
|
|
59174
59708
|
if (raw === void 0) {
|
|
59175
59709
|
return void 0;
|
|
59176
59710
|
}
|
|
@@ -59186,7 +59720,7 @@ function readFarmManifest(fs19, farmRoot) {
|
|
|
59186
59720
|
function buildEntryFacts(params) {
|
|
59187
59721
|
const entries = /* @__PURE__ */ new Map();
|
|
59188
59722
|
const visit2 = (rel) => {
|
|
59189
|
-
const absolute =
|
|
59723
|
+
const absolute = import_node_path18.default.join(params.claudeHome, rel);
|
|
59190
59724
|
const stat = params.fs.lstat(absolute);
|
|
59191
59725
|
if (stat === void 0) {
|
|
59192
59726
|
return void 0;
|
|
@@ -59229,7 +59763,7 @@ function buildEntryFacts(params) {
|
|
|
59229
59763
|
};
|
|
59230
59764
|
}
|
|
59231
59765
|
function listSubtree(fs19, root, rel) {
|
|
59232
|
-
const absolute =
|
|
59766
|
+
const absolute = import_node_path18.default.join(root, rel);
|
|
59233
59767
|
const stat = fs19.lstat(absolute);
|
|
59234
59768
|
if (stat === void 0) {
|
|
59235
59769
|
return [];
|
|
@@ -59259,7 +59793,7 @@ function reconciliationScope(fs19, farmRoot, manifest) {
|
|
|
59259
59793
|
if (manifest !== void 0) {
|
|
59260
59794
|
return topLevelScopeRoots(manifest.materialised);
|
|
59261
59795
|
}
|
|
59262
|
-
return [...fs19.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs19.lstat(
|
|
59796
|
+
return [...fs19.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs19.lstat(import_node_path18.default.join(farmRoot, name))?.kind === "dir").sort();
|
|
59263
59797
|
}
|
|
59264
59798
|
function collectFarmListing(fs19, farmRoot, scopeRoots) {
|
|
59265
59799
|
return scopeRoots.flatMap((root) => listSubtree(fs19, farmRoot, root));
|
|
@@ -59267,7 +59801,7 @@ function collectFarmListing(fs19, farmRoot, scopeRoots) {
|
|
|
59267
59801
|
function collectCanonicalCounterparts(fs19, claudeHome, farmListing) {
|
|
59268
59802
|
const out = [];
|
|
59269
59803
|
for (const entry of farmListing) {
|
|
59270
|
-
const absolute =
|
|
59804
|
+
const absolute = import_node_path18.default.join(claudeHome, entry.rel);
|
|
59271
59805
|
const stat = fs19.lstat(absolute);
|
|
59272
59806
|
if (stat === void 0) {
|
|
59273
59807
|
continue;
|
|
@@ -59297,21 +59831,21 @@ function carryOver(params) {
|
|
|
59297
59831
|
if (accounted.has(name)) {
|
|
59298
59832
|
continue;
|
|
59299
59833
|
}
|
|
59300
|
-
const stat = params.fs.lstat(
|
|
59834
|
+
const stat = params.fs.lstat(import_node_path18.default.join(params.previousRoot, name));
|
|
59301
59835
|
if (stat === void 0 || stat.kind === "symlink") {
|
|
59302
59836
|
continue;
|
|
59303
59837
|
}
|
|
59304
|
-
if (params.fs.lstat(
|
|
59838
|
+
if (params.fs.lstat(import_node_path18.default.join(params.farmRoot, name)) !== void 0) {
|
|
59305
59839
|
const category = params.classification === void 0 ? void 0 : classifyEntries([name], params.classification).classification.get(name);
|
|
59306
59840
|
if (category === "runtime") {
|
|
59307
|
-
params.fs.removeRecursive(
|
|
59841
|
+
params.fs.removeRecursive(import_node_path18.default.join(params.previousRoot, name));
|
|
59308
59842
|
autoResolved.push(name);
|
|
59309
59843
|
continue;
|
|
59310
59844
|
}
|
|
59311
59845
|
collided.push(name);
|
|
59312
59846
|
continue;
|
|
59313
59847
|
}
|
|
59314
|
-
params.fs.rename(
|
|
59848
|
+
params.fs.rename(import_node_path18.default.join(params.previousRoot, name), import_node_path18.default.join(params.farmRoot, name));
|
|
59315
59849
|
carried.push(name);
|
|
59316
59850
|
}
|
|
59317
59851
|
return { carried, autoResolved, collided };
|
|
@@ -59319,9 +59853,9 @@ function carryOver(params) {
|
|
|
59319
59853
|
function buildScratchTree(params) {
|
|
59320
59854
|
params.fs.mkdirp(params.scratchRoot);
|
|
59321
59855
|
for (const entry of params.plan.entries) {
|
|
59322
|
-
const absolute =
|
|
59856
|
+
const absolute = import_node_path18.default.join(params.scratchRoot, entry.rel);
|
|
59323
59857
|
if (entry.kind === "link") {
|
|
59324
|
-
params.fs.mkdirp(
|
|
59858
|
+
params.fs.mkdirp(import_node_path18.default.dirname(absolute));
|
|
59325
59859
|
params.fs.symlink(entry.target, absolute);
|
|
59326
59860
|
continue;
|
|
59327
59861
|
}
|
|
@@ -59330,14 +59864,14 @@ function buildScratchTree(params) {
|
|
|
59330
59864
|
}
|
|
59331
59865
|
}
|
|
59332
59866
|
params.fs.writeFileUtf8(
|
|
59333
|
-
|
|
59867
|
+
import_node_path18.default.join(params.scratchRoot, FARM_MANIFEST_FILENAME),
|
|
59334
59868
|
`${JSON.stringify(params.manifest, null, 2)}
|
|
59335
59869
|
`
|
|
59336
59870
|
);
|
|
59337
59871
|
}
|
|
59338
59872
|
function swapIn(params) {
|
|
59339
59873
|
if (params.fs.lstat(params.farmRoot) === void 0) {
|
|
59340
|
-
params.fs.mkdirp(
|
|
59874
|
+
params.fs.mkdirp(import_node_path18.default.dirname(params.farmRoot));
|
|
59341
59875
|
params.fs.rename(params.scratchRoot, params.farmRoot);
|
|
59342
59876
|
return { carried: [], autoResolved: [], collided: [] };
|
|
59343
59877
|
}
|
|
@@ -59361,14 +59895,14 @@ function recoverInterruptedSwap(params) {
|
|
|
59361
59895
|
const names = [...params.fs.readdir(params.identitiesDir)].sort();
|
|
59362
59896
|
const removedScratch = [];
|
|
59363
59897
|
for (const name of names.filter((candidate) => candidate.startsWith(scratchPrefix))) {
|
|
59364
|
-
params.fs.removeRecursive(
|
|
59898
|
+
params.fs.removeRecursive(import_node_path18.default.join(params.identitiesDir, name));
|
|
59365
59899
|
removedScratch.push(name);
|
|
59366
59900
|
}
|
|
59367
59901
|
let previous = names.filter((candidate) => candidate.startsWith(previousPrefix));
|
|
59368
59902
|
let restoredFrom;
|
|
59369
59903
|
const first = previous[0];
|
|
59370
59904
|
if (first !== void 0 && params.fs.lstat(params.farmRoot) === void 0) {
|
|
59371
|
-
params.fs.rename(
|
|
59905
|
+
params.fs.rename(import_node_path18.default.join(params.identitiesDir, first), params.farmRoot);
|
|
59372
59906
|
restoredFrom = first;
|
|
59373
59907
|
previous = previous.slice(1);
|
|
59374
59908
|
}
|
|
@@ -59376,7 +59910,7 @@ function recoverInterruptedSwap(params) {
|
|
|
59376
59910
|
const autoResolved = [];
|
|
59377
59911
|
const retained = [];
|
|
59378
59912
|
for (const name of previous) {
|
|
59379
|
-
const previousRoot =
|
|
59913
|
+
const previousRoot = import_node_path18.default.join(params.identitiesDir, name);
|
|
59380
59914
|
const result = carryOver({
|
|
59381
59915
|
fs: params.fs,
|
|
59382
59916
|
previousRoot,
|
|
@@ -59401,7 +59935,7 @@ function recoverInterruptedSwap(params) {
|
|
|
59401
59935
|
};
|
|
59402
59936
|
}
|
|
59403
59937
|
function recoverFarm(params) {
|
|
59404
|
-
const farmRoot =
|
|
59938
|
+
const farmRoot = import_node_path18.default.join(params.identitiesDir, params.identity);
|
|
59405
59939
|
const lock = acquireIdentityLock({
|
|
59406
59940
|
identity: params.identity,
|
|
59407
59941
|
dir: params.identitiesDir,
|
|
@@ -59460,16 +59994,16 @@ function executeReconciliation(params) {
|
|
|
59460
59994
|
});
|
|
59461
59995
|
continue;
|
|
59462
59996
|
}
|
|
59463
|
-
const from =
|
|
59464
|
-
const canonical =
|
|
59997
|
+
const from = import_node_path18.default.join(params.farmRoot, action.rel);
|
|
59998
|
+
const canonical = import_node_path18.default.join(params.claudeHome, action.rel);
|
|
59465
59999
|
if (action.kind === "adopt") {
|
|
59466
|
-
params.fs.mkdirp(
|
|
60000
|
+
params.fs.mkdirp(import_node_path18.default.dirname(canonical));
|
|
59467
60001
|
params.fs.copyRecursive(from, canonical);
|
|
59468
60002
|
adopted.push(action.rel);
|
|
59469
60003
|
continue;
|
|
59470
60004
|
}
|
|
59471
60005
|
const preserved = `${canonical}.farm-conflict-${String(params.nowMs)}`;
|
|
59472
|
-
params.fs.mkdirp(
|
|
60006
|
+
params.fs.mkdirp(import_node_path18.default.dirname(canonical));
|
|
59473
60007
|
params.fs.copyRecursive(from, preserved);
|
|
59474
60008
|
conflicts.push(action.rel);
|
|
59475
60009
|
}
|
|
@@ -59494,7 +60028,7 @@ function farmAlreadyMatches(existing, next) {
|
|
|
59494
60028
|
return existing.identity === next.identity && existing.claudeHome === next.claudeHome && sameStrings(existing.materialised, next.materialised) && sameLinks(existing.links, next.links);
|
|
59495
60029
|
}
|
|
59496
60030
|
function resyncFarm(params) {
|
|
59497
|
-
const farmRoot =
|
|
60031
|
+
const farmRoot = import_node_path18.default.join(params.identitiesDir, params.identity);
|
|
59498
60032
|
const lock = acquireIdentityLock({
|
|
59499
60033
|
identity: params.identity,
|
|
59500
60034
|
dir: params.identitiesDir,
|
|
@@ -59574,8 +60108,8 @@ function resyncFarm(params) {
|
|
|
59574
60108
|
diagnostics
|
|
59575
60109
|
};
|
|
59576
60110
|
}
|
|
59577
|
-
const scratchRoot =
|
|
59578
|
-
const previousRoot =
|
|
60111
|
+
const scratchRoot = import_node_path18.default.join(params.identitiesDir, `.${params.identity}.scratch.${params.uniqueSuffix}`);
|
|
60112
|
+
const previousRoot = import_node_path18.default.join(params.identitiesDir, `.${params.identity}.previous.${params.uniqueSuffix}`);
|
|
59579
60113
|
buildScratchTree({ fs: params.fs, scratchRoot, plan: resolved.farm, manifest });
|
|
59580
60114
|
const swap = swapIn({ fs: params.fs, farmRoot, scratchRoot, previousRoot, classification: params.classification });
|
|
59581
60115
|
if (swap.retainedPrevious !== void 0) {
|
|
@@ -59634,14 +60168,14 @@ function recoveryDiagnostics(recovery, identity) {
|
|
|
59634
60168
|
// src/paths.ts
|
|
59635
60169
|
var import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
59636
60170
|
var import_node_os3 = __toESM(require("node:os"), 1);
|
|
59637
|
-
var
|
|
60171
|
+
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
59638
60172
|
function resolveAgentShimHome(env = process.env, home = import_node_os3.default.homedir(), isDirectory = isExistingDirectory) {
|
|
59639
60173
|
const fromEnv = env.AGENT_SHIM_HOME;
|
|
59640
60174
|
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
59641
60175
|
return fromEnv;
|
|
59642
60176
|
}
|
|
59643
|
-
const current =
|
|
59644
|
-
const legacy =
|
|
60177
|
+
const current = import_node_path19.default.join(home, HOME_DIRNAME);
|
|
60178
|
+
const legacy = import_node_path19.default.join(home, LEGACY_HOME_DIRNAME);
|
|
59645
60179
|
return !isDirectory(current) && isDirectory(legacy) ? legacy : current;
|
|
59646
60180
|
}
|
|
59647
60181
|
function isExistingDirectory(candidate) {
|
|
@@ -59652,40 +60186,40 @@ function resolveClaudeHome() {
|
|
|
59652
60186
|
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
59653
60187
|
return fromEnv;
|
|
59654
60188
|
}
|
|
59655
|
-
return
|
|
60189
|
+
return import_node_path19.default.join(import_node_os3.default.homedir(), ".claude");
|
|
59656
60190
|
}
|
|
59657
60191
|
function buildLayoutPaths(root) {
|
|
59658
60192
|
return {
|
|
59659
60193
|
root,
|
|
59660
|
-
identitiesDir:
|
|
59661
|
-
configProfilesDir:
|
|
59662
|
-
providersDir:
|
|
59663
|
-
directoryRulesFile:
|
|
59664
|
-
activeIdentityFile:
|
|
59665
|
-
globalConfigFile:
|
|
59666
|
-
categoriesLocalFile:
|
|
59667
|
-
claudeShimFile:
|
|
59668
|
-
headroomDir:
|
|
59669
|
-
headroomStateFile:
|
|
59670
|
-
headroomSocketDir:
|
|
59671
|
-
headroomLockFile:
|
|
59672
|
-
headroomSessionsDir:
|
|
59673
|
-
logsDir:
|
|
59674
|
-
headroomLogPath:
|
|
59675
|
-
frontdoorDir:
|
|
59676
|
-
frontdoorCaDir:
|
|
59677
|
-
frontdoorCaCertFile:
|
|
59678
|
-
frontdoorCaKeyFile:
|
|
59679
|
-
frontdoorCaBundlesDir:
|
|
59680
|
-
frontdoorStateFile:
|
|
59681
|
-
frontdoorLockFile:
|
|
59682
|
-
frontdoorControlTokenFile:
|
|
59683
|
-
frontdoorSessionsDir:
|
|
59684
|
-
frontdoorLogPath:
|
|
59685
|
-
usageDir:
|
|
59686
|
-
usageLogDir:
|
|
59687
|
-
usageSnapshotsDir:
|
|
59688
|
-
usagePicksFile:
|
|
60194
|
+
identitiesDir: import_node_path19.default.join(root, "identities"),
|
|
60195
|
+
configProfilesDir: import_node_path19.default.join(root, "config-profiles"),
|
|
60196
|
+
providersDir: import_node_path19.default.join(root, "providers"),
|
|
60197
|
+
directoryRulesFile: import_node_path19.default.join(root, "directory-rules.json"),
|
|
60198
|
+
activeIdentityFile: import_node_path19.default.join(root, "active-identity"),
|
|
60199
|
+
globalConfigFile: import_node_path19.default.join(root, "config.json"),
|
|
60200
|
+
categoriesLocalFile: import_node_path19.default.join(root, "categories.local.json"),
|
|
60201
|
+
claudeShimFile: import_node_path19.default.join(root, "claude-shim.json"),
|
|
60202
|
+
headroomDir: import_node_path19.default.join(root, "headroom"),
|
|
60203
|
+
headroomStateFile: import_node_path19.default.join(root, "headroom", `state.v${String(HEADROOM_STATE_SCHEMA_VERSION)}.json`),
|
|
60204
|
+
headroomSocketDir: import_node_path19.default.join(root, "headroom", "run"),
|
|
60205
|
+
headroomLockFile: import_node_path19.default.join(root, "headroom", "start.lock"),
|
|
60206
|
+
headroomSessionsDir: import_node_path19.default.join(root, "headroom", "sessions"),
|
|
60207
|
+
logsDir: import_node_path19.default.join(root, "logs"),
|
|
60208
|
+
headroomLogPath: import_node_path19.default.join(root, "logs", "headroom.log"),
|
|
60209
|
+
frontdoorDir: import_node_path19.default.join(root, "frontdoor"),
|
|
60210
|
+
frontdoorCaDir: import_node_path19.default.join(root, "frontdoor", "ca"),
|
|
60211
|
+
frontdoorCaCertFile: import_node_path19.default.join(root, "frontdoor", "ca", "ca.pem"),
|
|
60212
|
+
frontdoorCaKeyFile: import_node_path19.default.join(root, "frontdoor", "ca", "ca.key"),
|
|
60213
|
+
frontdoorCaBundlesDir: import_node_path19.default.join(root, "frontdoor", "ca", "bundles"),
|
|
60214
|
+
frontdoorStateFile: import_node_path19.default.join(root, "frontdoor", "state.json"),
|
|
60215
|
+
frontdoorLockFile: import_node_path19.default.join(root, "frontdoor", "start.lock"),
|
|
60216
|
+
frontdoorControlTokenFile: import_node_path19.default.join(root, "frontdoor", "control-token"),
|
|
60217
|
+
frontdoorSessionsDir: import_node_path19.default.join(root, "frontdoor", "sessions"),
|
|
60218
|
+
frontdoorLogPath: import_node_path19.default.join(root, "logs", "frontdoor.log"),
|
|
60219
|
+
usageDir: import_node_path19.default.join(root, "usage"),
|
|
60220
|
+
usageLogDir: import_node_path19.default.join(root, "usage", "log"),
|
|
60221
|
+
usageSnapshotsDir: import_node_path19.default.join(root, "usage", "snapshots"),
|
|
60222
|
+
usagePicksFile: import_node_path19.default.join(root, "usage", "picks.json")
|
|
59689
60223
|
};
|
|
59690
60224
|
}
|
|
59691
60225
|
function resolveLayoutPaths() {
|
|
@@ -59767,7 +60301,7 @@ function chooseWriteTarget(params) {
|
|
|
59767
60301
|
for (let index = params.levels.length - 1; index >= 0; index -= 1) {
|
|
59768
60302
|
const level = params.levels[index];
|
|
59769
60303
|
if (level !== void 0 && (level.hasPortable || level.hasPortableLocal)) {
|
|
59770
|
-
return { tier: "portable-local", localConfigPath:
|
|
60304
|
+
return { tier: "portable-local", localConfigPath: import_node_path20.default.join(level.dir, level.portableLocalFilename) };
|
|
59771
60305
|
}
|
|
59772
60306
|
}
|
|
59773
60307
|
const normalisedCwd = normaliseRulePath(params.cwd, params.home);
|
|
@@ -59860,11 +60394,11 @@ function buildWriteTargetLevels(cwd, home, walkUpLimit) {
|
|
|
59860
60394
|
const limit = walkUpLimit === void 0 ? void 0 : expandTilde(walkUpLimit, home);
|
|
59861
60395
|
const dirs = walkDirectoryAncestors(cwd, { home, ...limit === void 0 ? {} : { limit } });
|
|
59862
60396
|
return dirs.map((dir) => {
|
|
59863
|
-
const hasLocal = import_node_fs8.default.existsSync(
|
|
59864
|
-
const hasLegacyLocal = import_node_fs8.default.existsSync(
|
|
60397
|
+
const hasLocal = import_node_fs8.default.existsSync(import_node_path20.default.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME));
|
|
60398
|
+
const hasLegacyLocal = import_node_fs8.default.existsSync(import_node_path20.default.join(dir, LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME));
|
|
59865
60399
|
return {
|
|
59866
60400
|
dir,
|
|
59867
|
-
hasPortable: import_node_fs8.default.existsSync(
|
|
60401
|
+
hasPortable: import_node_fs8.default.existsSync(import_node_path20.default.join(dir, PORTABLE_CONFIG_FILENAME)) || import_node_fs8.default.existsSync(import_node_path20.default.join(dir, LEGACY_PORTABLE_CONFIG_FILENAME)),
|
|
59868
60402
|
hasPortableLocal: hasLocal || hasLegacyLocal,
|
|
59869
60403
|
portableLocalFilename: !hasLocal && hasLegacyLocal ? LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME : PORTABLE_LOCAL_CONFIG_FILENAME
|
|
59870
60404
|
};
|
|
@@ -60208,7 +60742,7 @@ function resolveLaunchIdentity(paths, cwd) {
|
|
|
60208
60742
|
}
|
|
60209
60743
|
|
|
60210
60744
|
// src/identityManager.ts
|
|
60211
|
-
var
|
|
60745
|
+
var import_node_path22 = __toESM(require("node:path"), 1);
|
|
60212
60746
|
|
|
60213
60747
|
// src/cli/credentialOption.ts
|
|
60214
60748
|
var CREDENTIAL_SOURCE_SYNTAX = "env:<VAR>, file:<path>, command:<program and arguments>, op:<op://reference>, keychain:<service>[:<account>], literal:<placeholder>, or a JSON source object";
|
|
@@ -60316,7 +60850,7 @@ var CREDENTIAL_COMMAND_TIMEOUT_MS = 1e4;
|
|
|
60316
60850
|
var CREDENTIAL_INTERACTIVE_TIMEOUT_MS = 12e4;
|
|
60317
60851
|
var GROUP_OTHER_PERMISSION_BITS = 63;
|
|
60318
60852
|
var PERMISSION_BITS2 = 511;
|
|
60319
|
-
var
|
|
60853
|
+
var OCTAL_RADIX2 = 8;
|
|
60320
60854
|
function commandArgv(source) {
|
|
60321
60855
|
if ("command" in source) {
|
|
60322
60856
|
return source.command;
|
|
@@ -60409,7 +60943,7 @@ function trySource(source, params) {
|
|
|
60409
60943
|
}
|
|
60410
60944
|
if (read.mode !== void 0 && (read.mode & GROUP_OTHER_PERMISSION_BITS) !== 0) {
|
|
60411
60945
|
return none(
|
|
60412
|
-
`is readable or writable by group or others (mode ${(read.mode & PERMISSION_BITS2).toString(
|
|
60946
|
+
`is readable or writable by group or others (mode ${(read.mode & PERMISSION_BITS2).toString(OCTAL_RADIX2)}); run \`chmod 600 ${source.file}\``,
|
|
60413
60947
|
true
|
|
60414
60948
|
);
|
|
60415
60949
|
}
|
|
@@ -60477,11 +61011,11 @@ function credentialVariables(target, token) {
|
|
|
60477
61011
|
}
|
|
60478
61012
|
|
|
60479
61013
|
// src/launcher/farmResolve.ts
|
|
60480
|
-
var
|
|
61014
|
+
var import_node_path21 = __toESM(require("node:path"), 1);
|
|
60481
61015
|
async function resolveFarmConflicts(params) {
|
|
60482
|
-
const farmRoot =
|
|
61016
|
+
const farmRoot = import_node_path21.default.join(params.identitiesDir, params.identity);
|
|
60483
61017
|
const previousPrefix = `.${params.identity}.previous.`;
|
|
60484
|
-
const previousRoots = [...params.fs.readdir(params.identitiesDir)].filter((name) => name.startsWith(previousPrefix)).sort().map((name) =>
|
|
61018
|
+
const previousRoots = [...params.fs.readdir(params.identitiesDir)].filter((name) => name.startsWith(previousPrefix)).sort().map((name) => import_node_path21.default.join(params.identitiesDir, name));
|
|
60485
61019
|
const resolved = [];
|
|
60486
61020
|
const autoResolved = [];
|
|
60487
61021
|
const removed = [];
|
|
@@ -60504,11 +61038,11 @@ async function resolveFarmConflicts(params) {
|
|
|
60504
61038
|
continue;
|
|
60505
61039
|
}
|
|
60506
61040
|
if (choice === "keep-new") {
|
|
60507
|
-
params.fs.removeRecursive(
|
|
61041
|
+
params.fs.removeRecursive(import_node_path21.default.join(previousRoot, name));
|
|
60508
61042
|
continue;
|
|
60509
61043
|
}
|
|
60510
|
-
params.fs.removeRecursive(
|
|
60511
|
-
params.fs.rename(
|
|
61044
|
+
params.fs.removeRecursive(import_node_path21.default.join(farmRoot, name));
|
|
61045
|
+
params.fs.rename(import_node_path21.default.join(previousRoot, name), import_node_path21.default.join(farmRoot, name));
|
|
60512
61046
|
}
|
|
60513
61047
|
if (anySkipped) {
|
|
60514
61048
|
retained.push(previousRoot);
|
|
@@ -60847,7 +61381,7 @@ function toIdentityView(paths, entry) {
|
|
|
60847
61381
|
return {
|
|
60848
61382
|
name: entry.name,
|
|
60849
61383
|
active: entry.isActive,
|
|
60850
|
-
directory:
|
|
61384
|
+
directory: import_node_path22.default.join(paths.identitiesDir, entry.name),
|
|
60851
61385
|
...entry.problem === void 0 ? {
|
|
60852
61386
|
...entry.identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: entry.identity.defaultConfigProfile },
|
|
60853
61387
|
allowAmbientCredential: entry.identity.allowAmbientCredential,
|
|
@@ -60994,7 +61528,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60994
61528
|
if (!identityExists(paths, name)) {
|
|
60995
61529
|
throw new IdentityNotFoundError(name);
|
|
60996
61530
|
}
|
|
60997
|
-
await confirmRemoval(deps, options.yes, `identity "${name}" and its directory ${
|
|
61531
|
+
await confirmRemoval(deps, options.yes, `identity "${name}" and its directory ${import_node_path22.default.join(paths.identitiesDir, name)}`);
|
|
60998
61532
|
removeIdentity(paths, name);
|
|
60999
61533
|
reportMutation(options.json, { action: "removed", kind: "identity", name }, () => {
|
|
61000
61534
|
console.log(`Removed identity "${name}".`);
|
|
@@ -61052,7 +61586,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
61052
61586
|
// package.json
|
|
61053
61587
|
var package_default = {
|
|
61054
61588
|
name: "agent-shim",
|
|
61055
|
-
version: "8.5.
|
|
61589
|
+
version: "8.5.3",
|
|
61056
61590
|
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.",
|
|
61057
61591
|
license: "MIT",
|
|
61058
61592
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -61148,7 +61682,7 @@ var package_default = {
|
|
|
61148
61682
|
};
|
|
61149
61683
|
|
|
61150
61684
|
// src/check.ts
|
|
61151
|
-
var
|
|
61685
|
+
var import_node_path29 = __toESM(require("node:path"), 1);
|
|
61152
61686
|
|
|
61153
61687
|
// src/checkReport.ts
|
|
61154
61688
|
var import_node_os5 = __toESM(require("node:os"), 1);
|
|
@@ -61202,10 +61736,10 @@ function quotaWarnings(snapshot, provider, nowMs) {
|
|
|
61202
61736
|
}
|
|
61203
61737
|
|
|
61204
61738
|
// src/usage/poolPick.ts
|
|
61205
|
-
var
|
|
61739
|
+
var import_node_path26 = __toESM(require("node:path"), 1);
|
|
61206
61740
|
|
|
61207
61741
|
// src/usage/account.ts
|
|
61208
|
-
var
|
|
61742
|
+
var import_node_path23 = __toESM(require("node:path"), 1);
|
|
61209
61743
|
|
|
61210
61744
|
// src/usage/schema.ts
|
|
61211
61745
|
var USAGE_SCHEMA_VERSION = 1;
|
|
@@ -61374,7 +61908,7 @@ function isIdentityName(name) {
|
|
|
61374
61908
|
return IdentitySchema.shape.name.safeParse(name).success;
|
|
61375
61909
|
}
|
|
61376
61910
|
function claudeJsonPath(identitiesDir, identity) {
|
|
61377
|
-
return
|
|
61911
|
+
return import_node_path23.default.join(identitiesDir, identity, CLAUDE_JSON);
|
|
61378
61912
|
}
|
|
61379
61913
|
function readAccountMetadata(fs19, identitiesDir, identity) {
|
|
61380
61914
|
if (!isIdentityName(identity)) {
|
|
@@ -62182,7 +62716,7 @@ function rankPool(input2) {
|
|
|
62182
62716
|
}
|
|
62183
62717
|
|
|
62184
62718
|
// src/usage/read.ts
|
|
62185
|
-
var
|
|
62719
|
+
var import_node_path24 = __toESM(require("node:path"), 1);
|
|
62186
62720
|
var SEGMENT_RE = /^(\d{4}-\d{2}-\d{2})\.(\d+)\.jsonl$/;
|
|
62187
62721
|
var DAY_MS = 864e5;
|
|
62188
62722
|
function segmentDay(epochMs) {
|
|
@@ -62209,7 +62743,7 @@ function readUsageLog(fs19, logDir, options = {}) {
|
|
|
62209
62743
|
if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
|
|
62210
62744
|
continue;
|
|
62211
62745
|
}
|
|
62212
|
-
const contents = fs19.readFileUtf8(
|
|
62746
|
+
const contents = fs19.readFileUtf8(import_node_path24.default.join(logDir, segment.name));
|
|
62213
62747
|
if (contents === void 0) {
|
|
62214
62748
|
continue;
|
|
62215
62749
|
}
|
|
@@ -62251,7 +62785,7 @@ function snapshotPath(snapshotsDir, identity) {
|
|
|
62251
62785
|
if (!isIdentityName(identity)) {
|
|
62252
62786
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
62253
62787
|
}
|
|
62254
|
-
return
|
|
62788
|
+
return import_node_path24.default.join(snapshotsDir, `${identity}.json`);
|
|
62255
62789
|
}
|
|
62256
62790
|
function readUsageSnapshot(fs19, snapshotsDir, identity) {
|
|
62257
62791
|
const file2 = snapshotPath(snapshotsDir, identity);
|
|
@@ -62335,7 +62869,7 @@ function summariseUsage(records) {
|
|
|
62335
62869
|
}
|
|
62336
62870
|
|
|
62337
62871
|
// src/usage/store.ts
|
|
62338
|
-
var
|
|
62872
|
+
var import_node_path25 = __toESM(require("node:path"), 1);
|
|
62339
62873
|
var DAY_MS2 = 864e5;
|
|
62340
62874
|
var DAYS_IN_WEEK = 7;
|
|
62341
62875
|
var USAGE_RETENTION_MS = DAYS_IN_WEEK * DAY_MS2;
|
|
@@ -62343,7 +62877,7 @@ function pruneUsageLog(fs19, logDir, nowMs) {
|
|
|
62343
62877
|
const cutoff = nowMs - USAGE_RETENTION_MS;
|
|
62344
62878
|
for (const segment of listLogSegments(fs19, logDir)) {
|
|
62345
62879
|
if (segment.endsAt <= cutoff) {
|
|
62346
|
-
fs19.removeRecursive(
|
|
62880
|
+
fs19.removeRecursive(import_node_path25.default.join(logDir, segment.name));
|
|
62347
62881
|
}
|
|
62348
62882
|
}
|
|
62349
62883
|
}
|
|
@@ -62424,7 +62958,7 @@ function createUsageStore(deps) {
|
|
|
62424
62958
|
pruneUsageLog(fs19, paths.usageLogDir, nowMs);
|
|
62425
62959
|
prunedDay = day;
|
|
62426
62960
|
}
|
|
62427
|
-
fs19.appendFilePrivate(
|
|
62961
|
+
fs19.appendFilePrivate(import_node_path25.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record2)}
|
|
62428
62962
|
`);
|
|
62429
62963
|
if (record2.identity !== void 0) {
|
|
62430
62964
|
rewriteSnapshot(record2.identity, (current) => ({ ...current?.providers, [record2.provider]: foldProviderState(current?.providers[record2.provider], record2) }));
|
|
@@ -62500,7 +63034,7 @@ function recordStickyPick(fs19, picksFile, directory, identity, nowMs) {
|
|
|
62500
63034
|
const current = readPicksFile(fs19, picksFile).file.picks;
|
|
62501
63035
|
const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
|
|
62502
63036
|
const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
|
|
62503
|
-
fs19.mkdirPrivate(
|
|
63037
|
+
fs19.mkdirPrivate(import_node_path26.default.dirname(picksFile));
|
|
62504
63038
|
fs19.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
|
|
62505
63039
|
`);
|
|
62506
63040
|
}
|
|
@@ -62594,7 +63128,7 @@ function collectPoolPick(params) {
|
|
|
62594
63128
|
|
|
62595
63129
|
// src/providersStore.ts
|
|
62596
63130
|
var import_node_fs9 = __toESM(require("node:fs"), 1);
|
|
62597
|
-
var
|
|
63131
|
+
var import_node_path27 = __toESM(require("node:path"), 1);
|
|
62598
63132
|
var ProviderNotFoundError = class extends CliError {
|
|
62599
63133
|
constructor(name) {
|
|
62600
63134
|
super(`No provider named "${name}". Run \`agent-shim provider add ${name}\` first.`);
|
|
@@ -62623,7 +63157,7 @@ var InvalidProviderNameError = class extends CliError {
|
|
|
62623
63157
|
};
|
|
62624
63158
|
var PROVIDER_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._@-]*$/;
|
|
62625
63159
|
function providerJsonPath(paths, name) {
|
|
62626
|
-
return
|
|
63160
|
+
return import_node_path27.default.join(paths.providersDir, `${name}.json`);
|
|
62627
63161
|
}
|
|
62628
63162
|
function providerExists(paths, name) {
|
|
62629
63163
|
return import_node_fs9.default.existsSync(providerJsonPath(paths, name));
|
|
@@ -62699,7 +63233,7 @@ function readProvider(paths, name) {
|
|
|
62699
63233
|
return parseProviderFile(filePath, raw);
|
|
62700
63234
|
}
|
|
62701
63235
|
function loadProvider(providersDir, name, port) {
|
|
62702
|
-
const filePath =
|
|
63236
|
+
const filePath = import_node_path27.default.join(providersDir, `${name}.json`);
|
|
62703
63237
|
const raw = port.readConfigFile(filePath);
|
|
62704
63238
|
return raw === void 0 ? void 0 : parseProviderFile(filePath, raw);
|
|
62705
63239
|
}
|
|
@@ -62861,7 +63395,7 @@ function resolveProvider(params) {
|
|
|
62861
63395
|
}
|
|
62862
63396
|
|
|
62863
63397
|
// src/checkReport.ts
|
|
62864
|
-
var
|
|
63398
|
+
var import_node_path28 = __toESM(require("node:path"), 1);
|
|
62865
63399
|
|
|
62866
63400
|
// src/cli/envBool.ts
|
|
62867
63401
|
var InvalidEnvBoolError = class extends UsageError {
|
|
@@ -63261,10 +63795,10 @@ function collectCheckReport(params) {
|
|
|
63261
63795
|
}).input;
|
|
63262
63796
|
const providerName = cascadeProviderName(cascade);
|
|
63263
63797
|
const provider = providerName === void 0 ? void 0 : loadCheckProvider(paths, providerName);
|
|
63264
|
-
const farmRoot = identityDecision.name === void 0 ? void 0 :
|
|
63798
|
+
const farmRoot = identityDecision.name === void 0 ? void 0 : import_node_path28.default.join(paths.identitiesDir, identityDecision.name);
|
|
63265
63799
|
const settingsFiles = {
|
|
63266
|
-
"settings.json": realFsPort.readFileUtf8(
|
|
63267
|
-
"settings.local.json": realFsPort.readFileUtf8(
|
|
63800
|
+
"settings.json": realFsPort.readFileUtf8(import_node_path28.default.join(claudeHome, "settings.json")),
|
|
63801
|
+
"settings.local.json": realFsPort.readFileUtf8(import_node_path28.default.join(claudeHome, "settings.local.json"))
|
|
63268
63802
|
};
|
|
63269
63803
|
const report = runCheck({
|
|
63270
63804
|
cwd,
|
|
@@ -63298,7 +63832,7 @@ function registerCheckCommand(program2, deps) {
|
|
|
63298
63832
|
const command = program2.command("check [path]").description(
|
|
63299
63833
|
"Show what a launch in a directory would share or hide and why, plus credential and settings diagnostics. Never touches the farm or spawns claude."
|
|
63300
63834
|
).option("--identity <name>", "Identity to check (defaults to the identity a launch there would resolve).").option("--json", "Print the report as JSON.").option("--strict", "Exit 1 when the report carries any warning, not only on errors.").action((pathArg, options) => {
|
|
63301
|
-
const cwd = pathArg === void 0 ? process.cwd() :
|
|
63835
|
+
const cwd = pathArg === void 0 ? process.cwd() : import_node_path29.default.resolve(pathArg);
|
|
63302
63836
|
const report = collectCheckReport({ paths, cwd, ...options.identity === void 0 ? {} : { identity: options.identity }, env: process.env });
|
|
63303
63837
|
if (options.json === true) {
|
|
63304
63838
|
printJson(checkReportToJson(report));
|
|
@@ -63315,123 +63849,10 @@ function registerCheckCommand(program2, deps) {
|
|
|
63315
63849
|
}
|
|
63316
63850
|
|
|
63317
63851
|
// src/codex/commands.ts
|
|
63318
|
-
var
|
|
63852
|
+
var import_node_crypto7 = require("node:crypto");
|
|
63319
63853
|
var import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
63320
63854
|
var import_node_os6 = __toESM(require("node:os"), 1);
|
|
63321
|
-
var
|
|
63322
|
-
|
|
63323
|
-
// src/frontdoor/state.ts
|
|
63324
|
-
var import_node_path28 = __toESM(require("node:path"), 1);
|
|
63325
|
-
var FRONT_DOOR_PROTOCOL = 2;
|
|
63326
|
-
var FrontDoorSessionSchema = external_exports.strictObject({ pid: external_exports.number().int().positive(), startedAt: external_exports.number(), token: external_exports.string().min(1) });
|
|
63327
|
-
var FrontDoorStateSchema = external_exports.strictObject({
|
|
63328
|
-
/**
|
|
63329
|
-
* 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`).
|
|
63330
|
-
*/
|
|
63331
|
-
protocol: external_exports.number().int().nonnegative().optional(),
|
|
63332
|
-
/** The supervisor process serving the front door. Alive means both listeners are up in that process. */
|
|
63333
|
-
supervisorPid: external_exports.number().int().positive().optional(),
|
|
63334
|
-
/** The loopback port the HTTPS provider 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. */
|
|
63335
|
-
port: external_exports.number().int().positive().optional(),
|
|
63336
|
-
/**
|
|
63337
|
-
* The sticky port preference for the provider listener: kept across crashes, restarts and idle shutdowns so every provider session, whose base URL was frozen at launch, keeps finding the front door at the same address.
|
|
63338
|
-
*/
|
|
63339
|
-
lastPort: external_exports.number().int().positive().optional(),
|
|
63340
|
-
/**
|
|
63341
|
-
* The loopback port the CONNECT surface listens on. Absent whenever no supervisor is serving it, so "connectPort is set" is the ready signal an OAuth launch polls for alongside `port`.
|
|
63342
|
-
*/
|
|
63343
|
-
connectPort: external_exports.number().int().positive().optional(),
|
|
63344
|
-
/**
|
|
63345
|
-
* The sticky port preference for the CONNECT surface, the exact analogue of `lastPort` for the second listener: it survives every shutdown, because every OAuth session's environment was frozen at launch with HTTPS_PROXY pointing at this address and a restart that moves strands them.
|
|
63346
|
-
*/
|
|
63347
|
-
lastConnectPort: external_exports.number().int().positive().optional(),
|
|
63348
|
-
/**
|
|
63349
|
-
* The loopback port the direct listener serves on: the listener a headroom hop tells the daemon to forward routed traffic back to. Sticky like the others, because headroom's allowlist admits its exact origin and an ephemeral port would invalidate the allowlist on every restart.
|
|
63350
|
-
*/
|
|
63351
|
-
directPort: external_exports.number().int().positive().optional(),
|
|
63352
|
-
/** The sticky port preference for the direct listener, for the reason `directPort` gives. */
|
|
63353
|
-
lastDirectPort: external_exports.number().int().positive().optional(),
|
|
63354
|
-
/** The last fatal error, kept across shutdowns so `frontdoor status` can explain a front door that is not running. */
|
|
63355
|
-
lastError: external_exports.string().optional()
|
|
63356
|
-
});
|
|
63357
|
-
function readFrontDoorState(fs19, stateFile) {
|
|
63358
|
-
let raw;
|
|
63359
|
-
try {
|
|
63360
|
-
raw = fs19.readFileUtf8(stateFile);
|
|
63361
|
-
} catch {
|
|
63362
|
-
return void 0;
|
|
63363
|
-
}
|
|
63364
|
-
if (raw === void 0 || raw.trim() === "") {
|
|
63365
|
-
return void 0;
|
|
63366
|
-
}
|
|
63367
|
-
try {
|
|
63368
|
-
const parsed = FrontDoorStateSchema.safeParse(JSON.parse(raw));
|
|
63369
|
-
return parsed.success ? parsed.data : void 0;
|
|
63370
|
-
} catch {
|
|
63371
|
-
return void 0;
|
|
63372
|
-
}
|
|
63373
|
-
}
|
|
63374
|
-
function writeFrontDoorState(fs19, stateFile, state) {
|
|
63375
|
-
fs19.mkdirp(import_node_path28.default.dirname(stateFile));
|
|
63376
|
-
fs19.writeFileUtf8(stateFile, `${JSON.stringify(state, null, 2)}
|
|
63377
|
-
`);
|
|
63378
|
-
}
|
|
63379
|
-
function frontDoorOrigin(state) {
|
|
63380
|
-
const port = state?.directPort ?? state?.lastDirectPort;
|
|
63381
|
-
return port === void 0 ? void 0 : `http://127.0.0.1:${String(port)}`;
|
|
63382
|
-
}
|
|
63383
|
-
function writeFrontDoorSession(fs19, sessionsDir, session) {
|
|
63384
|
-
fs19.mkdirPrivate(sessionsDir);
|
|
63385
|
-
fs19.writeFilePrivate(import_node_path28.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
63386
|
-
`);
|
|
63387
|
-
}
|
|
63388
|
-
function listFrontDoorSessions(fs19, sessionsDir) {
|
|
63389
|
-
const sessions = [];
|
|
63390
|
-
for (const name of fs19.readdir(sessionsDir)) {
|
|
63391
|
-
if (!name.endsWith(".json")) {
|
|
63392
|
-
continue;
|
|
63393
|
-
}
|
|
63394
|
-
try {
|
|
63395
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs19.readFileUtf8(import_node_path28.default.join(sessionsDir, name)) ?? ""));
|
|
63396
|
-
if (parsed.success) {
|
|
63397
|
-
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
|
|
63398
|
-
}
|
|
63399
|
-
} catch {
|
|
63400
|
-
continue;
|
|
63401
|
-
}
|
|
63402
|
-
}
|
|
63403
|
-
return sessions.sort((a2, b) => a2.pid - b.pid);
|
|
63404
|
-
}
|
|
63405
|
-
function removeFrontDoorSession(fs19, sessionsDir, pid) {
|
|
63406
|
-
fs19.removeRecursive(import_node_path28.default.join(sessionsDir, `${String(pid)}.json`));
|
|
63407
|
-
}
|
|
63408
|
-
function pruneDeadFrontDoorSessions(fs19, sessionsDir, isRunning) {
|
|
63409
|
-
const removed = [];
|
|
63410
|
-
for (const session of listFrontDoorSessions(fs19, sessionsDir)) {
|
|
63411
|
-
if (!isRunning(session.pid)) {
|
|
63412
|
-
removeFrontDoorSession(fs19, sessionsDir, session.pid);
|
|
63413
|
-
removed.push(session.pid);
|
|
63414
|
-
}
|
|
63415
|
-
}
|
|
63416
|
-
return removed;
|
|
63417
|
-
}
|
|
63418
|
-
function liveSessionTokens(fs19, sessionsDir) {
|
|
63419
|
-
const tokens = /* @__PURE__ */ new Set();
|
|
63420
|
-
for (const name of fs19.readdir(sessionsDir)) {
|
|
63421
|
-
if (!name.endsWith(".json")) {
|
|
63422
|
-
continue;
|
|
63423
|
-
}
|
|
63424
|
-
try {
|
|
63425
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs19.readFileUtf8(import_node_path28.default.join(sessionsDir, name)) ?? ""));
|
|
63426
|
-
if (parsed.success) {
|
|
63427
|
-
tokens.add(parsed.data.token);
|
|
63428
|
-
}
|
|
63429
|
-
} catch {
|
|
63430
|
-
continue;
|
|
63431
|
-
}
|
|
63432
|
-
}
|
|
63433
|
-
return tokens;
|
|
63434
|
-
}
|
|
63855
|
+
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
63435
63856
|
|
|
63436
63857
|
// src/codex/agent.ts
|
|
63437
63858
|
var import_undici = __toESM(require_undici(), 1);
|
|
@@ -63580,7 +64001,7 @@ function createCodexAuthStore(authPath, ports) {
|
|
|
63580
64001
|
}
|
|
63581
64002
|
|
|
63582
64003
|
// src/codex/upstream.ts
|
|
63583
|
-
var
|
|
64004
|
+
var import_node_crypto6 = require("node:crypto");
|
|
63584
64005
|
|
|
63585
64006
|
// src/codex/http.ts
|
|
63586
64007
|
var HTTP_STATUS = {
|
|
@@ -63634,7 +64055,7 @@ function sessionIdFor(userId, randomId) {
|
|
|
63634
64055
|
if (userId === void 0 || userId === "") {
|
|
63635
64056
|
return randomId();
|
|
63636
64057
|
}
|
|
63637
|
-
const hex3 = (0,
|
|
64058
|
+
const hex3 = (0, import_node_crypto6.createHash)("sha256").update(`agent-shim codex session
|
|
63638
64059
|
${userId}`).digest("hex");
|
|
63639
64060
|
let next = 0;
|
|
63640
64061
|
return UUID_TEMPLATE.replace(/x/g, () => hex3.charAt(next++));
|
|
@@ -63670,10 +64091,10 @@ async function callCodex(ports, request7, sessionId, signal) {
|
|
|
63670
64091
|
// src/codex/commands.ts
|
|
63671
64092
|
function codexHome(env, home) {
|
|
63672
64093
|
const fromEnv = env.CODEX_HOME;
|
|
63673
|
-
return fromEnv !== void 0 && fromEnv !== "" ? fromEnv :
|
|
64094
|
+
return fromEnv !== void 0 && fromEnv !== "" ? fromEnv : import_node_path30.default.join(home, ".codex");
|
|
63674
64095
|
}
|
|
63675
64096
|
function codexUsageSnapshotPath() {
|
|
63676
|
-
return
|
|
64097
|
+
return import_node_path30.default.join(resolveClaudeHome(), "codex-quota.json");
|
|
63677
64098
|
}
|
|
63678
64099
|
function isEnoent4(error62) {
|
|
63679
64100
|
return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === "ENOENT";
|
|
@@ -63702,7 +64123,7 @@ function writeUsageSnapshot(log, snapshot) {
|
|
|
63702
64123
|
const target = codexUsageSnapshotPath();
|
|
63703
64124
|
const temp = `${target}.${String(process.pid)}.tmp`;
|
|
63704
64125
|
try {
|
|
63705
|
-
import_node_fs10.default.mkdirSync(
|
|
64126
|
+
import_node_fs10.default.mkdirSync(import_node_path30.default.dirname(target), { recursive: true });
|
|
63706
64127
|
import_node_fs10.default.writeFileSync(temp, `${JSON.stringify(snapshot, null, 2)}
|
|
63707
64128
|
`);
|
|
63708
64129
|
import_node_fs10.default.renameSync(temp, target);
|
|
@@ -63713,14 +64134,14 @@ function writeUsageSnapshot(log, snapshot) {
|
|
|
63713
64134
|
function createCodexRoutePorts(log) {
|
|
63714
64135
|
const agent = createUpstreamAgent();
|
|
63715
64136
|
const upstreamFetch = createUpstreamFetch(agent);
|
|
63716
|
-
const auth = createCodexAuthStore(
|
|
64137
|
+
const auth = createCodexAuthStore(import_node_path30.default.join(codexHome(process.env, import_node_os6.default.homedir()), "auth.json"), {
|
|
63717
64138
|
fs: realCodexAuthFs,
|
|
63718
64139
|
fetch: upstreamFetch,
|
|
63719
64140
|
now: () => /* @__PURE__ */ new Date(),
|
|
63720
|
-
tempSuffix: `${String(process.pid)}.${(0,
|
|
64141
|
+
tempSuffix: `${String(process.pid)}.${(0, import_node_crypto7.randomUUID)()}`
|
|
63721
64142
|
});
|
|
63722
64143
|
return {
|
|
63723
|
-
upstream: { fetch: upstreamFetch, auth, timers: realTimers, randomId:
|
|
64144
|
+
upstream: { fetch: upstreamFetch, auth, timers: realTimers, randomId: import_node_crypto7.randomUUID },
|
|
63724
64145
|
writeUsageSnapshot: (snapshot) => {
|
|
63725
64146
|
writeUsageSnapshot(log, snapshot);
|
|
63726
64147
|
},
|
|
@@ -63787,85 +64208,10 @@ function registerCodexCommand(program2, deps) {
|
|
|
63787
64208
|
}
|
|
63788
64209
|
|
|
63789
64210
|
// src/frontdoor/commands.ts
|
|
63790
|
-
var
|
|
64211
|
+
var import_node_crypto12 = require("node:crypto");
|
|
63791
64212
|
var import_node_path31 = __toESM(require("node:path"), 1);
|
|
63792
64213
|
var import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
63793
64214
|
|
|
63794
|
-
// src/headroom/socket.ts
|
|
63795
|
-
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
63796
|
-
var GROUP_OR_OTHER_BITS = 63;
|
|
63797
|
-
var OCTAL_RADIX2 = 8;
|
|
63798
|
-
var MODE_DIGITS = 4;
|
|
63799
|
-
var HEADROOM_SOCKET_SUFFIX = ".sock";
|
|
63800
|
-
var HEADROOM_SOCKET_NAME = /^(\d+)\.sock$/;
|
|
63801
|
-
var UNIX_SOCKET_PATH_MAX_BYTES = 103;
|
|
63802
|
-
var PLATFORMS_WITHOUT_UNIX_SOCKETS = ["win32"];
|
|
63803
|
-
function headroomSocketPath(paths, supervisorPid) {
|
|
63804
|
-
return import_node_path30.default.join(paths.headroomSocketDir, `${String(supervisorPid)}${HEADROOM_SOCKET_SUFFIX}`);
|
|
63805
|
-
}
|
|
63806
|
-
function platformRefusal(platform) {
|
|
63807
|
-
return PLATFORMS_WITHOUT_UNIX_SOCKETS.includes(platform) ? `headroom routing needs a unix domain socket, which headroom cannot serve on ${platform}; agent-shim never falls back to a TCP port for this hop` : void 0;
|
|
63808
|
-
}
|
|
63809
|
-
function ownerOnlyRefusal(label, target, stat, expected, uid) {
|
|
63810
|
-
if (stat === void 0) {
|
|
63811
|
-
return `the headroom ${label} ${target} does not exist`;
|
|
63812
|
-
}
|
|
63813
|
-
if (stat.kind === "symlink") {
|
|
63814
|
-
return `the headroom ${label} ${target} is a symlink; it must be the real ${expected === "dir" ? "directory" : "socket"}`;
|
|
63815
|
-
}
|
|
63816
|
-
if (stat.kind !== expected) {
|
|
63817
|
-
return `the headroom ${label} ${target} is not a ${expected === "dir" ? "directory" : "socket"}`;
|
|
63818
|
-
}
|
|
63819
|
-
if (stat.uid !== uid) {
|
|
63820
|
-
return `the headroom ${label} ${target} is owned by uid ${String(stat.uid)}, not by this user (uid ${String(uid)})`;
|
|
63821
|
-
}
|
|
63822
|
-
if ((stat.mode & GROUP_OR_OTHER_BITS) !== 0) {
|
|
63823
|
-
return `the headroom ${label} ${target} has mode ${stat.mode.toString(OCTAL_RADIX2).padStart(MODE_DIGITS, "0")}, which lets other users reach it; it must be accessible to its owner only`;
|
|
63824
|
-
}
|
|
63825
|
-
return void 0;
|
|
63826
|
-
}
|
|
63827
|
-
function verifyHeadroomSocket(socketPath, ports) {
|
|
63828
|
-
const unsupported = platformRefusal(ports.platform);
|
|
63829
|
-
if (unsupported !== void 0) {
|
|
63830
|
-
return { refused: unsupported };
|
|
63831
|
-
}
|
|
63832
|
-
const uid = ports.currentUid();
|
|
63833
|
-
const directory = import_node_path30.default.dirname(socketPath);
|
|
63834
|
-
const refusal = ownerOnlyRefusal("socket directory", directory, ports.lstat(directory), "dir", uid) ?? ownerOnlyRefusal("socket", socketPath, ports.lstat(socketPath), "socket", uid);
|
|
63835
|
-
return refusal === void 0 ? { socketPath } : { refused: refusal };
|
|
63836
|
-
}
|
|
63837
|
-
function prepareHeadroomSocket(fs19, ports, paths, supervisorPid) {
|
|
63838
|
-
const unsupported = platformRefusal(ports.platform);
|
|
63839
|
-
if (unsupported !== void 0) {
|
|
63840
|
-
return { refused: unsupported };
|
|
63841
|
-
}
|
|
63842
|
-
const socketPath = headroomSocketPath(paths, supervisorPid);
|
|
63843
|
-
const length = Buffer.byteLength(socketPath, "utf8");
|
|
63844
|
-
if (length > UNIX_SOCKET_PATH_MAX_BYTES) {
|
|
63845
|
-
return {
|
|
63846
|
-
refused: `the headroom socket path ${socketPath} is ${String(length)} bytes, longer than the ${String(UNIX_SOCKET_PATH_MAX_BYTES)} a unix socket path can hold; set AGENT_SHIM_HOME to a shorter directory`
|
|
63847
|
-
};
|
|
63848
|
-
}
|
|
63849
|
-
if (ports.lstat(paths.headroomSocketDir)?.kind === "symlink") {
|
|
63850
|
-
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
63851
|
-
}
|
|
63852
|
-
fs19.mkdirPrivate(paths.headroomSocketDir);
|
|
63853
|
-
const refusal = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
63854
|
-
return refusal === void 0 ? { socketPath } : { refused: refusal };
|
|
63855
|
-
}
|
|
63856
|
-
function pruneStaleHeadroomSockets(fs19, paths, isRunning) {
|
|
63857
|
-
const removed = [];
|
|
63858
|
-
for (const name of fs19.readdir(paths.headroomSocketDir)) {
|
|
63859
|
-
const pid = HEADROOM_SOCKET_NAME.exec(name)?.[1];
|
|
63860
|
-
if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
|
|
63861
|
-
continue;
|
|
63862
|
-
}
|
|
63863
|
-
fs19.removeRecursive(import_node_path30.default.join(paths.headroomSocketDir, name));
|
|
63864
|
-
removed.push(name);
|
|
63865
|
-
}
|
|
63866
|
-
return removed;
|
|
63867
|
-
}
|
|
63868
|
-
|
|
63869
64215
|
// src/frontdoor/custody.ts
|
|
63870
64216
|
var CREDENTIAL_HEADERS = ["authorization", "x-api-key"];
|
|
63871
64217
|
var SEQUESTERED_CREDENTIAL = "agent-shim-sequestered";
|
|
@@ -63967,7 +64313,7 @@ function createDoorPipelines(deps) {
|
|
|
63967
64313
|
}
|
|
63968
64314
|
|
|
63969
64315
|
// src/frontdoor/capability.ts
|
|
63970
|
-
var
|
|
64316
|
+
var import_node_crypto8 = require("node:crypto");
|
|
63971
64317
|
var CONNECT_PROXY_USER = "agent-shim";
|
|
63972
64318
|
var CONNECT_PROXY_REALM = "agent-shim front door";
|
|
63973
64319
|
var BASIC_SCHEME = "basic";
|
|
@@ -63989,13 +64335,13 @@ function capabilityFromProxyAuthorization(value) {
|
|
|
63989
64335
|
return password === "" ? void 0 : password;
|
|
63990
64336
|
}
|
|
63991
64337
|
function digest(token) {
|
|
63992
|
-
return (0,
|
|
64338
|
+
return (0, import_node_crypto8.createHash)("sha256").update(token, "utf8").digest();
|
|
63993
64339
|
}
|
|
63994
64340
|
function isLiveCapability(presented, live) {
|
|
63995
64341
|
const presentedDigest = digest(presented);
|
|
63996
64342
|
let matched = false;
|
|
63997
64343
|
for (const token of live) {
|
|
63998
|
-
const equal = (0,
|
|
64344
|
+
const equal = (0, import_node_crypto8.timingSafeEqual)(presentedDigest, digest(token));
|
|
63999
64345
|
matched = equal || matched;
|
|
64000
64346
|
}
|
|
64001
64347
|
return matched;
|
|
@@ -64139,11 +64485,11 @@ function createFileCapture(file2, now = () => /* @__PURE__ */ new Date()) {
|
|
|
64139
64485
|
}
|
|
64140
64486
|
|
|
64141
64487
|
// src/frontdoor/connect.ts
|
|
64142
|
-
var
|
|
64488
|
+
var import_node_crypto10 = require("node:crypto");
|
|
64143
64489
|
var fs12 = __toESM(require("node:fs"), 1);
|
|
64144
64490
|
|
|
64145
64491
|
// src/frontdoor/x509.ts
|
|
64146
|
-
var
|
|
64492
|
+
var import_node_crypto9 = require("node:crypto");
|
|
64147
64493
|
var import_node_net = __toESM(require("node:net"), 1);
|
|
64148
64494
|
var TAG_BOOLEAN = 1;
|
|
64149
64495
|
var TAG_INTEGER = 2;
|
|
@@ -64295,7 +64641,7 @@ function ipBytes(address) {
|
|
|
64295
64641
|
return bytes;
|
|
64296
64642
|
}
|
|
64297
64643
|
function keyIdentifier(publicKey) {
|
|
64298
|
-
return (0,
|
|
64644
|
+
return (0, import_node_crypto9.createHash)("sha1").update(publicKey.export({ type: "pkcs1", format: "der" })).digest();
|
|
64299
64645
|
}
|
|
64300
64646
|
function readElement(buffer, offset) {
|
|
64301
64647
|
const tag = buffer[offset];
|
|
@@ -64341,7 +64687,7 @@ ${body.join("\n")}
|
|
|
64341
64687
|
`;
|
|
64342
64688
|
}
|
|
64343
64689
|
function randomSerial() {
|
|
64344
|
-
const bytes = (0,
|
|
64690
|
+
const bytes = (0, import_node_crypto9.randomBytes)(SERIAL_NUMBER_BYTES);
|
|
64345
64691
|
bytes[0] = (bytes[0] ?? 0) & BASE_128_PAYLOAD_MASK | HIGH_BIT >> 1;
|
|
64346
64692
|
return bytes;
|
|
64347
64693
|
}
|
|
@@ -64356,7 +64702,7 @@ function assemble(spec) {
|
|
|
64356
64702
|
spec.subjectPublicKey.export({ type: "spki", format: "der" }),
|
|
64357
64703
|
tlv(TAG_EXTENSIONS, sequence(...spec.extensions))
|
|
64358
64704
|
);
|
|
64359
|
-
const signature = (0,
|
|
64705
|
+
const signature = (0, import_node_crypto9.sign)("sha256", tbs, spec.signingKey);
|
|
64360
64706
|
return sequence(tbs, SIGNATURE_ALGORITHM, wholeBitString(signature));
|
|
64361
64707
|
}
|
|
64362
64708
|
function subjectKeyIdentifierExtension(publicKey) {
|
|
@@ -64366,7 +64712,7 @@ function basicConstraintsExtension(isCa) {
|
|
|
64366
64712
|
return extension(OID_BASIC_CONSTRAINTS, true, sequence(...isCa ? [boolean4(true)] : []));
|
|
64367
64713
|
}
|
|
64368
64714
|
function rsaKeyPair() {
|
|
64369
|
-
return (0,
|
|
64715
|
+
return (0, import_node_crypto9.generateKeyPairSync)("rsa", { modulusLength: RSA_MODULUS_BITS });
|
|
64370
64716
|
}
|
|
64371
64717
|
function keyPem(privateKey) {
|
|
64372
64718
|
return privateKey.export({ type: "pkcs8", format: "pem" });
|
|
@@ -64390,8 +64736,8 @@ function issueLeafCertificate(ca, names, notBefore, notAfter) {
|
|
|
64390
64736
|
if (commonName === void 0) {
|
|
64391
64737
|
throw new Error("a leaf certificate needs at least one name");
|
|
64392
64738
|
}
|
|
64393
|
-
const caCertificate = new
|
|
64394
|
-
const caPrivateKey = (0,
|
|
64739
|
+
const caCertificate = new import_node_crypto9.X509Certificate(ca.certPem);
|
|
64740
|
+
const caPrivateKey = (0, import_node_crypto9.createPrivateKey)(ca.keyPem);
|
|
64395
64741
|
const { publicKey, privateKey } = rsaKeyPair();
|
|
64396
64742
|
const generalNames = names.map((name) => import_node_net.default.isIP(name) === 0 ? tlv(TAG_GENERAL_NAME_DNS, Buffer.from(name, "ascii")) : tlv(TAG_GENERAL_NAME_IP, ipBytes(name)));
|
|
64397
64743
|
const der = assemble({
|
|
@@ -64467,7 +64813,7 @@ function pumpTapSession(secure, openUpstream, tap, prefix = Buffer.alloc(0)) {
|
|
|
64467
64813
|
// src/frontdoor/supervisor.ts
|
|
64468
64814
|
var FRONTDOOR_SUPERVISOR_STILL_RUNNING = -1;
|
|
64469
64815
|
var FRONTDOOR_POLL_MS = 1e3;
|
|
64470
|
-
var
|
|
64816
|
+
var MS_PER_MINUTE2 = 6e4;
|
|
64471
64817
|
async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {}) {
|
|
64472
64818
|
const { fs: fs19, paths } = ports;
|
|
64473
64819
|
const previous = readFrontDoorState(fs19, paths.frontdoorStateFile);
|
|
@@ -64535,7 +64881,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
64535
64881
|
pruneDeadFrontDoorSessions(fs19, paths.frontdoorSessionsDir, ports.isRunning);
|
|
64536
64882
|
if (listFrontDoorSessions(fs19, paths.frontdoorSessionsDir).length === 0) {
|
|
64537
64883
|
idleSince ??= ports.now();
|
|
64538
|
-
if (ports.now() - idleSince >= idleShutdownMinutes *
|
|
64884
|
+
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE2) {
|
|
64539
64885
|
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
64540
64886
|
await direct.close();
|
|
64541
64887
|
await connect3.close();
|
|
@@ -64654,8 +65000,8 @@ function ensureCa(store, generate) {
|
|
|
64654
65000
|
}
|
|
64655
65001
|
function caParses(ca) {
|
|
64656
65002
|
try {
|
|
64657
|
-
new
|
|
64658
|
-
(0,
|
|
65003
|
+
new import_node_crypto10.X509Certificate(ca.certPem);
|
|
65004
|
+
(0, import_node_crypto10.createPrivateKey)(ca.keyPem);
|
|
64659
65005
|
return true;
|
|
64660
65006
|
} catch {
|
|
64661
65007
|
return false;
|
|
@@ -66030,7 +66376,7 @@ async function serveRouted(request7, deps) {
|
|
|
66030
66376
|
}
|
|
66031
66377
|
|
|
66032
66378
|
// src/codex/translate.ts
|
|
66033
|
-
var
|
|
66379
|
+
var import_node_crypto11 = require("node:crypto");
|
|
66034
66380
|
|
|
66035
66381
|
// src/codex/anthropic.ts
|
|
66036
66382
|
var TextBlockSchema = external_exports.looseObject({ type: external_exports.literal("text"), text: external_exports.string() });
|
|
@@ -66142,7 +66488,7 @@ function shortToolName(name, names) {
|
|
|
66142
66488
|
if (name.length <= CODEX_TOOL_NAME_LIMIT) {
|
|
66143
66489
|
return name;
|
|
66144
66490
|
}
|
|
66145
|
-
const hash2 = (0,
|
|
66491
|
+
const hash2 = (0, import_node_crypto11.createHash)("sha256").update(name).digest("hex").slice(0, TOOL_NAME_HASH_CHARS);
|
|
66146
66492
|
const shortened = `${name.slice(0, CODEX_TOOL_NAME_LIMIT - TOOL_NAME_HASH_CHARS - 1)}_${hash2}`;
|
|
66147
66493
|
names.set(shortened, name);
|
|
66148
66494
|
return shortened;
|
|
@@ -67000,6 +67346,11 @@ function singleHeader(headers, name) {
|
|
|
67000
67346
|
const value = headers[name];
|
|
67001
67347
|
return typeof value === "string" ? value : void 0;
|
|
67002
67348
|
}
|
|
67349
|
+
var OAUTH_AUTHORIZATION_PREFIX = "Bearer sk-ant-oat";
|
|
67350
|
+
function oauthAuthorizationOf(headers) {
|
|
67351
|
+
const value = singleHeader(headers, "authorization");
|
|
67352
|
+
return value?.startsWith(OAUTH_AUTHORIZATION_PREFIX) === true ? value : void 0;
|
|
67353
|
+
}
|
|
67003
67354
|
function sessionCreateId(body) {
|
|
67004
67355
|
let parsed;
|
|
67005
67356
|
try {
|
|
@@ -67143,7 +67494,7 @@ function createRcSessionTracker(deps) {
|
|
|
67143
67494
|
}
|
|
67144
67495
|
const tail = path41.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
67145
67496
|
const facts = {
|
|
67146
|
-
|
|
67497
|
+
oauthAuthorization: oauthAuthorizationOf(request7.headers),
|
|
67147
67498
|
anthropicVersion: singleHeader(request7.headers, "anthropic-version"),
|
|
67148
67499
|
anthropicClientPlatform: singleHeader(request7.headers, "anthropic-client-platform")
|
|
67149
67500
|
};
|
|
@@ -67185,7 +67536,7 @@ function createRcSessionTracker(deps) {
|
|
|
67185
67536
|
}
|
|
67186
67537
|
const entry = entries.get(id) ?? birth(id, facts);
|
|
67187
67538
|
entry.lastSeenAt = deps.now();
|
|
67188
|
-
entry.
|
|
67539
|
+
entry.oauthAuthorization = facts.oauthAuthorization ?? entry.oauthAuthorization;
|
|
67189
67540
|
entry.anthropicVersion = facts.anthropicVersion ?? entry.anthropicVersion;
|
|
67190
67541
|
entry.anthropicClientPlatform = facts.anthropicClientPlatform ?? entry.anthropicClientPlatform;
|
|
67191
67542
|
const bodyKind = method === "POST" && rest === `${id}/worker/events` ? "worker-events" : method === "POST" && rest === `${id}/events` ? "client-events" : method === "POST" && rest === `${id}/worker/heartbeat` ? "heartbeat" : method === "PUT" && rest === `${id}/worker` ? "worker-registration" : void 0;
|
|
@@ -67273,7 +67624,7 @@ function createRcSessionTracker(deps) {
|
|
|
67273
67624
|
},
|
|
67274
67625
|
credentialOf: (sessionId) => {
|
|
67275
67626
|
const entry = entries.get(sessionId);
|
|
67276
|
-
return entry === void 0 ? void 0 : { authorization: entry.
|
|
67627
|
+
return entry === void 0 ? void 0 : { authorization: entry.oauthAuthorization, anthropicVersion: entry.anthropicVersion, anthropicClientPlatform: entry.anthropicClientPlatform };
|
|
67277
67628
|
},
|
|
67278
67629
|
completePending: (sessionId, requestId) => {
|
|
67279
67630
|
entries.get(sessionId)?.pending.delete(requestId);
|
|
@@ -67375,6 +67726,9 @@ function rcEventWriteResultFromAnswer(answer) {
|
|
|
67375
67726
|
}
|
|
67376
67727
|
return { ok: true, sequenceNums };
|
|
67377
67728
|
}
|
|
67729
|
+
function noOAuthCredentialResult(sessionId) {
|
|
67730
|
+
return { ok: false, message: `no claude.ai OAuth bearer has been observed for session ${sessionId}: only worker calls crossed this door, and the worker JWT they carry is answered 401 on the client half. Reconnect Remote Control through this door and the create's own bearer will be observed` };
|
|
67731
|
+
}
|
|
67378
67732
|
function rcWriteHeaders(credential) {
|
|
67379
67733
|
const headers = { "content-type": "application/json" };
|
|
67380
67734
|
if (credential.authorization !== void 0) {
|
|
@@ -67393,6 +67747,9 @@ async function injectRcUserMessage(deps, sessionId, text2) {
|
|
|
67393
67747
|
if (credential === void 0) {
|
|
67394
67748
|
return { ok: false, message: `the front door has not observed Remote Control session ${sessionId}: it may never have passed through this door, or it ended or expired (an entry lives only a bounded idle period past its last observed traffic)` };
|
|
67395
67749
|
}
|
|
67750
|
+
if (credential.authorization === void 0) {
|
|
67751
|
+
return noOAuthCredentialResult(sessionId);
|
|
67752
|
+
}
|
|
67396
67753
|
const body = JSON.stringify(buildRcEventWriteBody(buildRcUserMessagePayload(deps.newUuid(), sessionId, text2)));
|
|
67397
67754
|
let answer;
|
|
67398
67755
|
try {
|
|
@@ -67411,6 +67768,9 @@ async function answerRcControlRequest(deps, sessionId, requestId, decision) {
|
|
|
67411
67768
|
if (credential === void 0) {
|
|
67412
67769
|
return { ok: false, message: `the front door has not observed Remote Control session ${sessionId}: it may never have passed through this door, or it ended or expired (an entry lives only a bounded idle period past its last observed traffic)` };
|
|
67413
67770
|
}
|
|
67771
|
+
if (credential.authorization === void 0) {
|
|
67772
|
+
return noOAuthCredentialResult(sessionId);
|
|
67773
|
+
}
|
|
67414
67774
|
if (!deps.pendingOf(sessionId).some((pending) => pending.requestId === requestId)) {
|
|
67415
67775
|
return { ok: false, message: `the front door has not observed control request ${requestId} pending on session ${sessionId}: it was answered already (by this door or by an attached client), it passed its answer deadline (the protocol's permission round-trip bound), or it never passed through this door` };
|
|
67416
67776
|
}
|
|
@@ -67732,7 +68092,7 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
67732
68092
|
let directPort = 0;
|
|
67733
68093
|
const codexPorts = createCodexRoutePorts(log);
|
|
67734
68094
|
const rcTracker = createRcSessionTracker({ now: () => Date.now(), idleMs: RC_IDLE_EXPIRY_MS });
|
|
67735
|
-
const rcControlToken = (0,
|
|
68095
|
+
const rcControlToken = (0, import_node_crypto12.randomUUID)();
|
|
67736
68096
|
const resolveRoute = rcObservingResolver(createProviderRouteResolver({ fs: realFsPort, providersDir: paths.providersDir, codexPorts, directPort: () => directPort }), rcTracker);
|
|
67737
68097
|
const isLiveToken = (token) => isLiveCapability(token, liveSessionTokens(realFarmFs, paths.frontdoorSessionsDir));
|
|
67738
68098
|
const usageStore = createUsageStore({
|
|
@@ -67759,8 +68119,8 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
67759
68119
|
now: () => Date.now(),
|
|
67760
68120
|
headroomSocket: () => headroomSocketTarget(realFarmFs, realHeadroomSocketTrust, paths),
|
|
67761
68121
|
// The per-generation capability the direct listener demands: held only in this process's memory, so a loopback process that discovers the direct port still cannot use it.
|
|
67762
|
-
hopSecret: (0,
|
|
67763
|
-
custody: createCredentialCustody(() => (0,
|
|
68122
|
+
hopSecret: (0, import_node_crypto12.randomUUID)(),
|
|
68123
|
+
custody: createCredentialCustody(() => (0, import_node_crypto12.randomUUID)()),
|
|
67764
68124
|
log
|
|
67765
68125
|
});
|
|
67766
68126
|
let ca;
|
|
@@ -67786,7 +68146,7 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
67786
68146
|
startProviderListener: async (preferredPort) => {
|
|
67787
68147
|
const authority = loadCa();
|
|
67788
68148
|
const rcDial = realRcEventDial();
|
|
67789
|
-
const rcInject = async (sessionId, text2) => await injectRcUserMessage({ credentialOf: rcTracker.credentialOf, dial: rcDial, newUuid:
|
|
68149
|
+
const rcInject = async (sessionId, text2) => await injectRcUserMessage({ credentialOf: rcTracker.credentialOf, dial: rcDial, newUuid: import_node_crypto12.randomUUID }, sessionId, text2);
|
|
67790
68150
|
const rcAnswer = async (sessionId, requestId, decision) => await answerRcControlRequest({ credentialOf: rcTracker.credentialOf, pendingOf: (id) => rcTracker.pendingOf(id), completePending: rcTracker.completePending, dial: rcDial }, sessionId, requestId, decision);
|
|
67791
68151
|
realFarmFs.mkdirp(paths.frontdoorDir);
|
|
67792
68152
|
realFarmFs.writeFilePrivate(paths.frontdoorControlTokenFile, `${rcControlToken}
|
|
@@ -67810,7 +68170,7 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
67810
68170
|
},
|
|
67811
68171
|
startConnectListener: async (preferredPort) => {
|
|
67812
68172
|
const transparentPort = process.env.AGENT_SHIM_TRANSPARENT_SURFACE === void 0 ? void 0 : Number(process.env.AGENT_SHIM_TRANSPARENT_SURFACE);
|
|
67813
|
-
const transparentCapability = transparentPort === void 0 || Number.isNaN(transparentPort) ? void 0 : (0,
|
|
68173
|
+
const transparentCapability = transparentPort === void 0 || Number.isNaN(transparentPort) ? void 0 : (0, import_node_crypto12.randomUUID)();
|
|
67814
68174
|
if (transparentCapability !== void 0) {
|
|
67815
68175
|
writeFrontDoorSession(realFarmFs, paths.frontdoorSessionsDir, { pid: process.pid, startedAt: Date.now(), token: transparentCapability });
|
|
67816
68176
|
}
|
|
@@ -68596,33 +68956,6 @@ function subjectName(positional, provider) {
|
|
|
68596
68956
|
// src/doctorReport.ts
|
|
68597
68957
|
var import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
68598
68958
|
var import_node_path34 = __toESM(require("node:path"), 1);
|
|
68599
|
-
|
|
68600
|
-
// src/headroom/source.ts
|
|
68601
|
-
var GIT_SPEC_RE = /git\+[^@\s]+(?:@([^\s#]+))?/;
|
|
68602
|
-
var COMMIT_SHA_RE = /^[0-9a-f]{40}$/i;
|
|
68603
|
-
var DirectUrlSchema = external_exports.object({ vcs_info: external_exports.object({ commit_id: external_exports.string() }) });
|
|
68604
|
-
function isMovingGitSource(spec) {
|
|
68605
|
-
const match = GIT_SPEC_RE.exec(spec);
|
|
68606
|
-
if (match === null) {
|
|
68607
|
-
return false;
|
|
68608
|
-
}
|
|
68609
|
-
const ref = match[1];
|
|
68610
|
-
return ref === void 0 || !COMMIT_SHA_RE.test(ref);
|
|
68611
|
-
}
|
|
68612
|
-
function pinnedGitCommit(spec) {
|
|
68613
|
-
const ref = GIT_SPEC_RE.exec(spec)?.[1];
|
|
68614
|
-
return ref !== void 0 && COMMIT_SHA_RE.test(ref) ? ref.toLowerCase() : void 0;
|
|
68615
|
-
}
|
|
68616
|
-
function parseInstalledCommit(directUrlJson) {
|
|
68617
|
-
try {
|
|
68618
|
-
const parsed = DirectUrlSchema.safeParse(JSON.parse(directUrlJson));
|
|
68619
|
-
return parsed.success ? parsed.data.vcs_info.commit_id.toLowerCase() : void 0;
|
|
68620
|
-
} catch {
|
|
68621
|
-
return void 0;
|
|
68622
|
-
}
|
|
68623
|
-
}
|
|
68624
|
-
|
|
68625
|
-
// src/doctorReport.ts
|
|
68626
68959
|
function refinePathShadow(status, ownExecutablePath, realpath) {
|
|
68627
68960
|
if (status.status !== "shadowed") {
|
|
68628
68961
|
return status;
|
|
@@ -69130,7 +69463,7 @@ var import_node_child_process5 = require("node:child_process");
|
|
|
69130
69463
|
var import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
69131
69464
|
|
|
69132
69465
|
// src/frontdoor/ensure.ts
|
|
69133
|
-
var
|
|
69466
|
+
var import_node_crypto13 = require("node:crypto");
|
|
69134
69467
|
var FRONTDOOR_START_TIMEOUT_MS = 3e4;
|
|
69135
69468
|
var FRONTDOOR_LAUNCHER_POLL_MS = 100;
|
|
69136
69469
|
var FrontDoorStartError = class extends CliError {
|
|
@@ -69164,7 +69497,7 @@ function ensureFrontDoor(params) {
|
|
|
69164
69497
|
continue;
|
|
69165
69498
|
}
|
|
69166
69499
|
if (verdict.ok) {
|
|
69167
|
-
const token = (0,
|
|
69500
|
+
const token = (0, import_node_crypto13.randomUUID)();
|
|
69168
69501
|
writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token });
|
|
69169
69502
|
return { port: state.port, connectPort: state.connectPort, token };
|
|
69170
69503
|
}
|
|
@@ -69268,7 +69601,7 @@ function probeFrontDoorSync(port, caPem) {
|
|
|
69268
69601
|
}
|
|
69269
69602
|
|
|
69270
69603
|
// src/frontdoor/trust.ts
|
|
69271
|
-
var
|
|
69604
|
+
var import_node_crypto14 = require("node:crypto");
|
|
69272
69605
|
var import_node_path35 = __toESM(require("node:path"), 1);
|
|
69273
69606
|
var BUNDLE_NAME_HEX_DIGITS = 16;
|
|
69274
69607
|
function resolveTrustBundle(params) {
|
|
@@ -69291,7 +69624,7 @@ function resolveTrustBundle(params) {
|
|
|
69291
69624
|
}
|
|
69292
69625
|
const combined = `${inheritedPem.trimEnd()}
|
|
69293
69626
|
${caPem}`;
|
|
69294
|
-
const bundle = import_node_path35.default.join(bundlesDir, `${(0,
|
|
69627
|
+
const bundle = import_node_path35.default.join(bundlesDir, `${(0, import_node_crypto14.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
69295
69628
|
if (!fs19.exists(bundle)) {
|
|
69296
69629
|
fs19.mkdirp(bundlesDir);
|
|
69297
69630
|
fs19.writeFileAtomic(bundle, combined);
|
|
@@ -69344,315 +69677,6 @@ function realFrontDoorPort(paths, spawnDaemon) {
|
|
|
69344
69677
|
};
|
|
69345
69678
|
}
|
|
69346
69679
|
|
|
69347
|
-
// src/headroom/settings.ts
|
|
69348
|
-
var import_node_crypto14 = require("node:crypto");
|
|
69349
|
-
function settingsOf(config2) {
|
|
69350
|
-
return {
|
|
69351
|
-
...config2.mode === void 0 ? {} : { mode: config2.mode },
|
|
69352
|
-
...config2.targetRatio === void 0 ? {} : { targetRatio: config2.targetRatio },
|
|
69353
|
-
...config2.ccr === void 0 ? {} : { ccr: config2.ccr },
|
|
69354
|
-
...config2.rolloutChannel === void 0 ? {} : { rolloutChannel: config2.rolloutChannel },
|
|
69355
|
-
...config2.interceptToolResults === void 0 ? {} : { interceptToolResults: config2.interceptToolResults },
|
|
69356
|
-
...config2.readMaturation === void 0 ? {} : { readMaturation: config2.readMaturation }
|
|
69357
|
-
};
|
|
69358
|
-
}
|
|
69359
|
-
function settingsArgs(settings2) {
|
|
69360
|
-
return [
|
|
69361
|
-
...settings2.mode === void 0 ? [] : ["--mode", settings2.mode],
|
|
69362
|
-
...settings2.targetRatio === void 0 ? [] : ["--target-ratio", String(settings2.targetRatio)],
|
|
69363
|
-
...settings2.ccr === "lossless" ? ["--lossless"] : [],
|
|
69364
|
-
...settings2.ccr === "none" ? ["--no-ccr"] : [],
|
|
69365
|
-
...settings2.interceptToolResults === true ? ["--intercept-tool-results"] : [],
|
|
69366
|
-
...settings2.readMaturation === true ? ["--read-maturation"] : []
|
|
69367
|
-
];
|
|
69368
|
-
}
|
|
69369
|
-
function settingsEnv(settings2) {
|
|
69370
|
-
return settings2.rolloutChannel === void 0 ? {} : { HEADROOM_ROLLOUT_CHANNEL: settings2.rolloutChannel };
|
|
69371
|
-
}
|
|
69372
|
-
function hashSettings(settings2) {
|
|
69373
|
-
return (0, import_node_crypto14.createHash)("sha256").update(JSON.stringify([...settingsArgs(settings2), JSON.stringify(settingsEnv(settings2))])).digest("hex");
|
|
69374
|
-
}
|
|
69375
|
-
|
|
69376
|
-
// src/headroom/supervisor.ts
|
|
69377
|
-
function resolveSupervisorConfig(configured) {
|
|
69378
|
-
return {
|
|
69379
|
-
source: configured.source ?? HEADROOM_DEFAULT_SOURCE,
|
|
69380
|
-
idleShutdownMinutes: configured.idleShutdownMinutes ?? HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES,
|
|
69381
|
-
settings: settingsOf(configured)
|
|
69382
|
-
};
|
|
69383
|
-
}
|
|
69384
|
-
var HEADROOM_BACKOFF_BASE_MS = 500;
|
|
69385
|
-
var HEADROOM_BACKOFF_CAP_MS = 3e4;
|
|
69386
|
-
var HEADROOM_START_RETRY_BUDGET = 5;
|
|
69387
|
-
var HEADROOM_READY_TIMEOUT_MS = 15e3;
|
|
69388
|
-
var HEADROOM_POLL_MS = 1e3;
|
|
69389
|
-
var MS_PER_MINUTE2 = 6e4;
|
|
69390
|
-
var STOP_POLL_MS = 100;
|
|
69391
|
-
var TERM_GRACE_MS = 1500;
|
|
69392
|
-
var KILL_GRACE_MS = 1500;
|
|
69393
|
-
function stopSupervisedProcess(pid, primitives) {
|
|
69394
|
-
const send = (signal) => {
|
|
69395
|
-
try {
|
|
69396
|
-
primitives.signal(pid, signal);
|
|
69397
|
-
} catch {
|
|
69398
|
-
}
|
|
69399
|
-
};
|
|
69400
|
-
send("SIGTERM");
|
|
69401
|
-
if (awaitExit(pid, primitives, TERM_GRACE_MS)) {
|
|
69402
|
-
return "exited-on-term";
|
|
69403
|
-
}
|
|
69404
|
-
send("SIGKILL");
|
|
69405
|
-
if (awaitExit(pid, primitives, KILL_GRACE_MS)) {
|
|
69406
|
-
return "killed";
|
|
69407
|
-
}
|
|
69408
|
-
return "still-running";
|
|
69409
|
-
}
|
|
69410
|
-
function awaitExit(pid, primitives, budgetMs) {
|
|
69411
|
-
const deadline = primitives.now() + budgetMs;
|
|
69412
|
-
while (primitives.isRunning(pid)) {
|
|
69413
|
-
if (primitives.now() >= deadline) {
|
|
69414
|
-
return false;
|
|
69415
|
-
}
|
|
69416
|
-
primitives.waitMs(STOP_POLL_MS);
|
|
69417
|
-
}
|
|
69418
|
-
return true;
|
|
69419
|
-
}
|
|
69420
|
-
function backoffForAttempt(attempt) {
|
|
69421
|
-
return Math.min(HEADROOM_BACKOFF_CAP_MS, HEADROOM_BACKOFF_BASE_MS * 2 ** (attempt - 1));
|
|
69422
|
-
}
|
|
69423
|
-
function versionSatisfies(version2, source) {
|
|
69424
|
-
if (version2 === void 0) {
|
|
69425
|
-
return false;
|
|
69426
|
-
}
|
|
69427
|
-
const specifier = /==|>=|<=|!=|>|<|~=/.exec(source);
|
|
69428
|
-
if (specifier === null) {
|
|
69429
|
-
return true;
|
|
69430
|
-
}
|
|
69431
|
-
const installed = parseVersion(version2);
|
|
69432
|
-
const wanted = parseVersion(source.slice(specifier.index + specifier[0].length));
|
|
69433
|
-
if (installed === void 0 || wanted === void 0) {
|
|
69434
|
-
return true;
|
|
69435
|
-
}
|
|
69436
|
-
const cmp = compareVersions2(installed, wanted);
|
|
69437
|
-
switch (specifier[0]) {
|
|
69438
|
-
case "==":
|
|
69439
|
-
return cmp === 0;
|
|
69440
|
-
case "!=":
|
|
69441
|
-
return cmp !== 0;
|
|
69442
|
-
case ">=":
|
|
69443
|
-
return cmp >= 0;
|
|
69444
|
-
case "<=":
|
|
69445
|
-
return cmp <= 0;
|
|
69446
|
-
case ">":
|
|
69447
|
-
return cmp > 0;
|
|
69448
|
-
case "<":
|
|
69449
|
-
return cmp < 0;
|
|
69450
|
-
case "~=":
|
|
69451
|
-
return compareVersions2(installed.slice(0, Math.max(0, wanted.length - 1)), wanted.slice(0, Math.max(0, wanted.length - 1))) === 0 && cmp >= 0;
|
|
69452
|
-
default:
|
|
69453
|
-
return true;
|
|
69454
|
-
}
|
|
69455
|
-
}
|
|
69456
|
-
function parseVersion(input2) {
|
|
69457
|
-
const match = /(\d+)(\.\d+)*/.exec(input2);
|
|
69458
|
-
if (match === null) {
|
|
69459
|
-
return void 0;
|
|
69460
|
-
}
|
|
69461
|
-
return match[0].split(".").map((part) => Number.parseInt(part, 10));
|
|
69462
|
-
}
|
|
69463
|
-
function compareVersions2(a2, b) {
|
|
69464
|
-
for (let index = 0; index < Math.max(a2.length, b.length); index += 1) {
|
|
69465
|
-
const left = a2[index] ?? 0;
|
|
69466
|
-
const right = b[index] ?? 0;
|
|
69467
|
-
if (left !== right) {
|
|
69468
|
-
return left - right;
|
|
69469
|
-
}
|
|
69470
|
-
}
|
|
69471
|
-
return 0;
|
|
69472
|
-
}
|
|
69473
|
-
var HEADROOM_SUPERVISOR_STILL_RUNNING = -1;
|
|
69474
|
-
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
69475
|
-
const { fs: fs19, paths } = ports;
|
|
69476
|
-
let config2 = initialConfig;
|
|
69477
|
-
const previousState = readHeadroomState(fs19, paths.headroomStateFile);
|
|
69478
|
-
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
69479
|
-
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
69480
|
-
return 0;
|
|
69481
|
-
}
|
|
69482
|
-
let installedSource = previousState?.installedSource;
|
|
69483
|
-
const ownsState = () => {
|
|
69484
|
-
const owner = readHeadroomState(fs19, paths.headroomStateFile)?.supervisorPid;
|
|
69485
|
-
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
69486
|
-
};
|
|
69487
|
-
const writeOwnState = (state) => {
|
|
69488
|
-
if (!ownsState()) {
|
|
69489
|
-
return false;
|
|
69490
|
-
}
|
|
69491
|
-
writeHeadroomState(fs19, paths.headroomStateFile, state);
|
|
69492
|
-
return true;
|
|
69493
|
-
};
|
|
69494
|
-
const fail = (message) => {
|
|
69495
|
-
if (writeOwnState({ lastError: message })) {
|
|
69496
|
-
fs19.removeRecursive(paths.headroomLockFile);
|
|
69497
|
-
}
|
|
69498
|
-
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
69499
|
-
return 1;
|
|
69500
|
-
};
|
|
69501
|
-
const ensureInstalled = () => {
|
|
69502
|
-
const version3 = ports.headroomVersion();
|
|
69503
|
-
const versionOk = version3 !== void 0 && versionSatisfies(version3, config2.source);
|
|
69504
|
-
const pinned = pinnedGitCommit(config2.source);
|
|
69505
|
-
const commitOk = pinned === void 0 || ports.installedCommit() === pinned;
|
|
69506
|
-
if (versionOk && commitOk && (installedSource === void 0 || installedSource === config2.source)) {
|
|
69507
|
-
installedSource = config2.source;
|
|
69508
|
-
return true;
|
|
69509
|
-
}
|
|
69510
|
-
ports.log(`agent-shim headroom supervisor: installing headroom from ${config2.source}`);
|
|
69511
|
-
const result = ports.install(config2.source);
|
|
69512
|
-
if (!result.ok) {
|
|
69513
|
-
return false;
|
|
69514
|
-
}
|
|
69515
|
-
installedSource = config2.source;
|
|
69516
|
-
return true;
|
|
69517
|
-
};
|
|
69518
|
-
const socket = prepareHeadroomSocket(fs19, ports.socketTrust, paths, ports.ownPid);
|
|
69519
|
-
if (socket.refused !== void 0) {
|
|
69520
|
-
return fail(socket.refused);
|
|
69521
|
-
}
|
|
69522
|
-
const { socketPath } = socket;
|
|
69523
|
-
pruneStaleHeadroomSockets(fs19, paths, ports.isRunning);
|
|
69524
|
-
if (!ensureInstalled()) {
|
|
69525
|
-
return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
|
|
69526
|
-
}
|
|
69527
|
-
const version2 = ports.headroomVersion() ?? "unknown";
|
|
69528
|
-
writeOwnState({ supervisorPid: ports.ownPid, version: version2, installedSource });
|
|
69529
|
-
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${allowlistOf(ports).join(", ")}]`);
|
|
69530
|
-
const orphanPid = previousState?.headroomPid;
|
|
69531
|
-
if (orphanPid !== void 0 && ports.isRunning(orphanPid)) {
|
|
69532
|
-
ports.log(`agent-shim headroom supervisor: stopping daemon pid ${String(orphanPid)} left behind by the previous supervisor`);
|
|
69533
|
-
ports.stopProcess(orphanPid);
|
|
69534
|
-
}
|
|
69535
|
-
let headroomPid;
|
|
69536
|
-
let runningHash;
|
|
69537
|
-
let runningSettingsHash;
|
|
69538
|
-
let consecutiveFailures = 0;
|
|
69539
|
-
let idleSince;
|
|
69540
|
-
let superseded = false;
|
|
69541
|
-
let ticks = 0;
|
|
69542
|
-
for (; ; ) {
|
|
69543
|
-
if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
|
|
69544
|
-
return HEADROOM_SUPERVISOR_STILL_RUNNING;
|
|
69545
|
-
}
|
|
69546
|
-
ticks += 1;
|
|
69547
|
-
config2 = ports.readConfig();
|
|
69548
|
-
const settingsHash = hashSettings(config2.settings);
|
|
69549
|
-
const allowlist = allowlistOf(ports);
|
|
69550
|
-
const allowlistHash = hashAllowlist(allowlist);
|
|
69551
|
-
pruneDeadSessions(fs19, paths.headroomSessionsDir, ports.isRunning);
|
|
69552
|
-
const ownsNow = ownsState();
|
|
69553
|
-
if (!ownsNow && !superseded) {
|
|
69554
|
-
ports.log("agent-shim headroom supervisor: another supervisor now owns the state file; serving this daemon's own sessions until they end");
|
|
69555
|
-
}
|
|
69556
|
-
superseded = !ownsNow;
|
|
69557
|
-
const crashed = headroomPid !== void 0 && !ports.isRunning(headroomPid);
|
|
69558
|
-
if (headroomPid === void 0 || crashed) {
|
|
69559
|
-
if (crashed) {
|
|
69560
|
-
ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} died`);
|
|
69561
|
-
headroomPid = void 0;
|
|
69562
|
-
runningHash = void 0;
|
|
69563
|
-
runningSettingsHash = void 0;
|
|
69564
|
-
writeOwnState({
|
|
69565
|
-
supervisorPid: ports.ownPid,
|
|
69566
|
-
version: version2,
|
|
69567
|
-
installedSource
|
|
69568
|
-
});
|
|
69569
|
-
}
|
|
69570
|
-
if (consecutiveFailures >= HEADROOM_START_RETRY_BUDGET) {
|
|
69571
|
-
return fail(`headroom failed to become ready ${String(consecutiveFailures)} times in a row; giving up`);
|
|
69572
|
-
}
|
|
69573
|
-
if (installedSource !== config2.source && !ensureInstalled()) {
|
|
69574
|
-
return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
|
|
69575
|
-
}
|
|
69576
|
-
const pid = ports.spawnHeadroom(socketPath, allowlist, config2.settings);
|
|
69577
|
-
const ready = await waitUntilReady(ports, socketPath);
|
|
69578
|
-
if (ready) {
|
|
69579
|
-
consecutiveFailures = 0;
|
|
69580
|
-
headroomPid = pid;
|
|
69581
|
-
runningHash = allowlistHash;
|
|
69582
|
-
runningSettingsHash = settingsHash;
|
|
69583
|
-
const recorded = writeOwnState({
|
|
69584
|
-
supervisorPid: ports.ownPid,
|
|
69585
|
-
headroomPid: pid,
|
|
69586
|
-
socketPath,
|
|
69587
|
-
version: version2,
|
|
69588
|
-
allowlistHash,
|
|
69589
|
-
settingsHash,
|
|
69590
|
-
installedSource: config2.source
|
|
69591
|
-
});
|
|
69592
|
-
if (recorded) {
|
|
69593
|
-
fs19.removeRecursive(paths.headroomLockFile);
|
|
69594
|
-
}
|
|
69595
|
-
idleSince = void 0;
|
|
69596
|
-
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on unix socket ${socketPath}`);
|
|
69597
|
-
} else {
|
|
69598
|
-
ports.stopProcess(pid);
|
|
69599
|
-
consecutiveFailures += 1;
|
|
69600
|
-
ports.log(
|
|
69601
|
-
`agent-shim headroom supervisor: headroom did not become ready on unix socket ${socketPath} (attempt ${String(consecutiveFailures)} of ${String(HEADROOM_START_RETRY_BUDGET)})`
|
|
69602
|
-
);
|
|
69603
|
-
await ports.sleep(backoffForAttempt(consecutiveFailures));
|
|
69604
|
-
continue;
|
|
69605
|
-
}
|
|
69606
|
-
} else {
|
|
69607
|
-
if (runningHash !== allowlistHash || runningSettingsHash !== settingsHash || installedSource !== config2.source) {
|
|
69608
|
-
if (sessionsForSupervisor(fs19, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
69609
|
-
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
69610
|
-
ports.stopProcess(headroomPid);
|
|
69611
|
-
headroomPid = void 0;
|
|
69612
|
-
runningHash = void 0;
|
|
69613
|
-
runningSettingsHash = void 0;
|
|
69614
|
-
continue;
|
|
69615
|
-
}
|
|
69616
|
-
}
|
|
69617
|
-
const sessions = sessionsForSupervisor(fs19, paths.headroomSessionsDir, ports.ownPid);
|
|
69618
|
-
if (sessions.length === 0) {
|
|
69619
|
-
idleSince ??= ports.now();
|
|
69620
|
-
const idleMs = ports.now() - idleSince;
|
|
69621
|
-
if (idleMs >= config2.idleShutdownMinutes * MS_PER_MINUTE2) {
|
|
69622
|
-
ports.log(
|
|
69623
|
-
`agent-shim headroom supervisor: no sessions for ${String(config2.idleShutdownMinutes)} minute(s); stopping headroom and exiting`
|
|
69624
|
-
);
|
|
69625
|
-
ports.stopProcess(headroomPid);
|
|
69626
|
-
writeOwnState({ version: version2 });
|
|
69627
|
-
return 0;
|
|
69628
|
-
}
|
|
69629
|
-
} else {
|
|
69630
|
-
idleSince = void 0;
|
|
69631
|
-
}
|
|
69632
|
-
}
|
|
69633
|
-
await ports.sleep(HEADROOM_POLL_MS);
|
|
69634
|
-
}
|
|
69635
|
-
}
|
|
69636
|
-
function currentHeadroomAllowlist(fs19, paths) {
|
|
69637
|
-
const providers = readAllProviders(fs19, paths.providersDir).map((entry) => entry.provider);
|
|
69638
|
-
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(fs19, paths.frontdoorStateFile))));
|
|
69639
|
-
}
|
|
69640
|
-
function allowlistOf(ports) {
|
|
69641
|
-
return currentHeadroomAllowlist(ports.fs, ports.paths);
|
|
69642
|
-
}
|
|
69643
|
-
async function waitUntilReady(ports, socketPath) {
|
|
69644
|
-
const deadline = ports.now() + HEADROOM_READY_TIMEOUT_MS;
|
|
69645
|
-
for (; ; ) {
|
|
69646
|
-
if (await ports.ready(socketPath)) {
|
|
69647
|
-
return true;
|
|
69648
|
-
}
|
|
69649
|
-
if (ports.now() >= deadline) {
|
|
69650
|
-
return false;
|
|
69651
|
-
}
|
|
69652
|
-
await ports.sleep(HEADROOM_POLL_MS);
|
|
69653
|
-
}
|
|
69654
|
-
}
|
|
69655
|
-
|
|
69656
69680
|
// src/headroom/commands.ts
|
|
69657
69681
|
function collectHeadroomStatus(fsPort, paths, isRunning) {
|
|
69658
69682
|
const state = readHeadroomState(fsPort, paths.headroomStateFile) ?? {};
|
|
@@ -71040,7 +71064,7 @@ function prepareLaunch(params) {
|
|
|
71040
71064
|
let headroom;
|
|
71041
71065
|
const headroomPort = params.headroom;
|
|
71042
71066
|
if (resolvedFlags.headroom && headroomPort !== void 0) {
|
|
71043
|
-
headroom = headroomPort.ensure();
|
|
71067
|
+
headroom = headroomPort.ensure({ routesProvider: resolvedProvider !== void 0 });
|
|
71044
71068
|
const via = resolvedProvider === void 0 ? `OAuth via the door's CONNECT surface on 127.0.0.1:${String(frontDoor?.connectPort ?? 0)}` : `provider ${resolvedProvider.name}`;
|
|
71045
71069
|
log.info(`agent-shim: routing through the front door on 127.0.0.1:${String(frontDoor?.port ?? 0)} with headroom on unix socket ${headroom.socketPath} (${via}, project ${headroom.projectId})`);
|
|
71046
71070
|
} else if (resolvedFlags.headroom) {
|