agent-shim 8.5.1 → 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 +770 -734
- package/dist/index.cjs +71 -24
- package/dist/index.mjs +71 -24
- 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
|
|
@@ -55107,18 +55107,14 @@ function discoverClaudeBinary(options) {
|
|
|
55107
55107
|
version: highestVersion
|
|
55108
55108
|
};
|
|
55109
55109
|
}
|
|
55110
|
-
const ownInstallDirs = new Set(options.ownInstallDirs.map((dir) => import_node_path3.default.resolve(dir)));
|
|
55111
55110
|
for (const dir of options.pathDirs) {
|
|
55112
|
-
if (ownInstallDirs.has(import_node_path3.default.resolve(dir))) {
|
|
55113
|
-
continue;
|
|
55114
|
-
}
|
|
55115
55111
|
const found = options.findExecutableInDir(dir, "claude");
|
|
55116
|
-
if (found !== void 0) {
|
|
55112
|
+
if (found !== void 0 && !options.isOwnBinary(found)) {
|
|
55117
55113
|
return { path: found, source: "path-fallback" };
|
|
55118
55114
|
}
|
|
55119
55115
|
}
|
|
55120
55116
|
throw new Error(
|
|
55121
|
-
`Could not find a claude binary. Looked for genuinely-executable versioned binaries under "${versionsDir}" (missing, empty, or containing nothing executable) and for a "claude" executable on PATH (
|
|
55117
|
+
`Could not find a claude binary. Looked for genuinely-executable versioned binaries under "${versionsDir}" (missing, empty, or containing nothing executable) and for a "claude" executable on PATH (never this tool's own binary). Install Claude Code, or set the versions directory / PATH correctly, then try again.`
|
|
55122
55118
|
);
|
|
55123
55119
|
}
|
|
55124
55120
|
|
|
@@ -55509,13 +55505,24 @@ function ensureHeadroom(params) {
|
|
|
55509
55505
|
const { paths, ports } = params;
|
|
55510
55506
|
const deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
|
|
55511
55507
|
let spawnedSupervisor = false;
|
|
55508
|
+
let awaitingAllowlist = false;
|
|
55512
55509
|
for (; ; ) {
|
|
55513
55510
|
const state = readHeadroomState(ports.fs, paths.headroomStateFile);
|
|
55514
55511
|
if (state?.supervisorPid !== void 0 && ports.isRunning(state.supervisorPid)) {
|
|
55515
55512
|
const daemonUp = state.socketPath !== void 0 && state.headroomPid !== void 0 && ports.isRunning(state.headroomPid);
|
|
55516
55513
|
if (daemonUp && state.socketPath !== void 0) {
|
|
55517
|
-
|
|
55518
|
-
|
|
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;
|
|
55519
55526
|
}
|
|
55520
55527
|
if (state.lastError !== void 0) {
|
|
55521
55528
|
throw new HeadroomStartError(
|
|
@@ -55543,13 +55550,535 @@ function ensureHeadroom(params) {
|
|
|
55543
55550
|
if (ports.now() >= deadline) {
|
|
55544
55551
|
const lastError = state?.lastError;
|
|
55545
55552
|
throw new HeadroomStartError(
|
|
55546
|
-
`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}`
|
|
55547
55554
|
);
|
|
55548
55555
|
}
|
|
55549
55556
|
ports.sleep(HEADROOM_LAUNCHER_POLL_MS);
|
|
55550
55557
|
}
|
|
55551
55558
|
}
|
|
55552
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
|
+
|
|
55553
56082
|
// src/realPorts.ts
|
|
55554
56083
|
function isEnoent2(error62) {
|
|
55555
56084
|
return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === "ENOENT";
|
|
@@ -55673,7 +56202,7 @@ var realFarmFs = {
|
|
|
55673
56202
|
},
|
|
55674
56203
|
hashFile(filePath) {
|
|
55675
56204
|
try {
|
|
55676
|
-
return (0,
|
|
56205
|
+
return (0, import_node_crypto4.createHash)("sha256").update(import_node_fs3.default.readFileSync(filePath)).digest("hex");
|
|
55677
56206
|
} catch (error62) {
|
|
55678
56207
|
if (isEnoent2(error62) || isErrorWithCode(error62, "EISDIR")) {
|
|
55679
56208
|
return void 0;
|
|
@@ -55708,7 +56237,7 @@ var realRunPort = {
|
|
|
55708
56237
|
}
|
|
55709
56238
|
};
|
|
55710
56239
|
function expandHome(filePath) {
|
|
55711
|
-
return filePath.startsWith("~/") ?
|
|
56240
|
+
return filePath.startsWith("~/") ? import_node_path8.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
|
|
55712
56241
|
}
|
|
55713
56242
|
var MACOS_GUI_SESSION_MANAGER = "Aqua";
|
|
55714
56243
|
function hasDesktopSession() {
|
|
@@ -55784,7 +56313,7 @@ function spawnDetachedSupervisor(paths, subcommand, logPath) {
|
|
|
55784
56313
|
return spawnDetachedDaemon(selfInvocation([subcommand]), paths, subcommand, logPath);
|
|
55785
56314
|
}
|
|
55786
56315
|
function spawnDetachedDaemon(invocation, paths, subcommand, logPath) {
|
|
55787
|
-
import_node_fs3.default.mkdirSync(
|
|
56316
|
+
import_node_fs3.default.mkdirSync(import_node_path8.default.dirname(logPath), { recursive: true });
|
|
55788
56317
|
const logFd = import_node_fs3.default.openSync(logPath, "a");
|
|
55789
56318
|
try {
|
|
55790
56319
|
const child = (0, import_node_child_process2.spawn)(invocation.command, invocation.args, detachedDaemonSpawnOptions(logFd, { ...process.env, AGENT_SHIM_HOME: paths.root }));
|
|
@@ -55825,10 +56354,11 @@ var realHeadroomSocketTrust = {
|
|
|
55825
56354
|
};
|
|
55826
56355
|
function realHeadroomPort(paths, options) {
|
|
55827
56356
|
return {
|
|
55828
|
-
ensure: () => {
|
|
56357
|
+
ensure: ({ routesProvider }) => {
|
|
55829
56358
|
const up = ensureHeadroom({
|
|
55830
56359
|
paths,
|
|
55831
56360
|
launcherPid: process.pid,
|
|
56361
|
+
...routesProvider ? { requiredAllowlistHash: () => hashAllowlist(currentHeadroomAllowlist(realFarmFs, paths)) } : {},
|
|
55832
56362
|
ports: {
|
|
55833
56363
|
fs: realFarmFs,
|
|
55834
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.
|
|
@@ -55882,7 +56412,7 @@ function listVersionsDir(dir) {
|
|
|
55882
56412
|
throw error62;
|
|
55883
56413
|
}
|
|
55884
56414
|
return entries.filter((entry) => entry.isFile()).map((entry) => {
|
|
55885
|
-
const fullPath =
|
|
56415
|
+
const fullPath = import_node_path8.default.join(dir, entry.name);
|
|
55886
56416
|
const stat = import_node_fs3.default.statSync(fullPath);
|
|
55887
56417
|
return {
|
|
55888
56418
|
name: entry.name,
|
|
@@ -55897,7 +56427,7 @@ function windowsPathExtensions(pathext) {
|
|
|
55897
56427
|
return (pathext ?? WINDOWS_DEFAULT_PATHEXT).split(";").map((ext) => ext.trim()).filter((ext) => ext.length > 0);
|
|
55898
56428
|
}
|
|
55899
56429
|
function resolveExecutableCandidate(dir, name, env) {
|
|
55900
|
-
const candidate =
|
|
56430
|
+
const candidate = import_node_path8.default.join(dir, name);
|
|
55901
56431
|
if (env.platform === "win32") {
|
|
55902
56432
|
const extensions = windowsPathExtensions(env.pathext);
|
|
55903
56433
|
const alreadyHasRecognisedExtension = extensions.some((ext) => candidate.toLowerCase().endsWith(ext.toLowerCase()));
|
|
@@ -55946,13 +56476,13 @@ function resolveOwnExecutablePath(env) {
|
|
|
55946
56476
|
if (env.argv1 !== void 0 && !env.argv1.includes("/") && !env.argv1.includes("\\")) {
|
|
55947
56477
|
return searchPathForExecutable(env.pathDirs, env.argv1, env.findExecutableInDir) ?? env.execPath;
|
|
55948
56478
|
}
|
|
55949
|
-
const candidate = env.argv1 === void 0 ? env.execPath :
|
|
55950
|
-
const candidateDir =
|
|
55951
|
-
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);
|
|
55952
56482
|
if (candidateDirOnPath) {
|
|
55953
56483
|
return candidate;
|
|
55954
56484
|
}
|
|
55955
|
-
const viaPath = searchPathForExecutable(env.pathDirs,
|
|
56485
|
+
const viaPath = searchPathForExecutable(env.pathDirs, import_node_path8.default.basename(candidate), env.findExecutableInDir);
|
|
55956
56486
|
return viaPath ?? candidate;
|
|
55957
56487
|
}
|
|
55958
56488
|
function realOwnExecutablePath() {
|
|
@@ -55960,7 +56490,7 @@ function realOwnExecutablePath() {
|
|
|
55960
56490
|
argv1: process.argv[1],
|
|
55961
56491
|
execPath: process.execPath,
|
|
55962
56492
|
cwd: process.cwd(),
|
|
55963
|
-
pathDirs: (process.env.PATH ?? "").split(
|
|
56493
|
+
pathDirs: (process.env.PATH ?? "").split(import_node_path8.default.delimiter).filter((dir) => dir !== ""),
|
|
55964
56494
|
findExecutableInDir
|
|
55965
56495
|
});
|
|
55966
56496
|
}
|
|
@@ -55970,12 +56500,12 @@ function resolveContentSourcePath(env) {
|
|
|
55970
56500
|
function realContentSourcePath() {
|
|
55971
56501
|
return resolveContentSourcePath({ isSea: (0, import_node_sea.isSea)(), execPath: process.execPath, argv1: process.argv[1] });
|
|
55972
56502
|
}
|
|
55973
|
-
function realResolveClaudeBinary(
|
|
56503
|
+
function realResolveClaudeBinary(isOwnBinary) {
|
|
55974
56504
|
return () => discoverClaudeBinary({
|
|
55975
56505
|
listVersionsDir,
|
|
55976
|
-
pathDirs: (process.env.PATH ?? "").split(
|
|
56506
|
+
pathDirs: (process.env.PATH ?? "").split(import_node_path8.default.delimiter).filter((dir) => dir !== ""),
|
|
55977
56507
|
findExecutableInDir,
|
|
55978
|
-
|
|
56508
|
+
isOwnBinary
|
|
55979
56509
|
});
|
|
55980
56510
|
}
|
|
55981
56511
|
|
|
@@ -56017,16 +56547,22 @@ function commandFilename(ownExecutablePath, commandName) {
|
|
|
56017
56547
|
function isInvokedAsClaude(invokedName) {
|
|
56018
56548
|
return invokedName === "claude" || invokedName.toLowerCase() === "claude.exe";
|
|
56019
56549
|
}
|
|
56020
|
-
function
|
|
56021
|
-
const dirs = [import_node_path7.default.dirname(ownExecutablePath)];
|
|
56550
|
+
function resolveOwnBinaryCheck(paths, contentSourcePath) {
|
|
56022
56551
|
const state = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
56023
|
-
|
|
56024
|
-
|
|
56025
|
-
|
|
56026
|
-
|
|
56552
|
+
const recordedTarget = state === void 0 ? void 0 : import_node_path9.default.resolve(state.targetPath);
|
|
56553
|
+
let ownStat;
|
|
56554
|
+
return (candidate) => {
|
|
56555
|
+
if (recordedTarget !== void 0 && import_node_path9.default.resolve(candidate) === recordedTarget) {
|
|
56556
|
+
return true;
|
|
56557
|
+
}
|
|
56558
|
+
ownStat ??= statOrUndefined(contentSourcePath);
|
|
56559
|
+
const candidateStat = statOrUndefined(candidate);
|
|
56560
|
+
return ownStat !== void 0 && candidateStat !== void 0 && // A platform reporting no inode number for either file must not read every candidate as this tool.
|
|
56561
|
+
ownStat.ino !== 0 && candidateStat.ino !== 0 && candidateStat.dev === ownStat.dev && candidateStat.ino === ownStat.ino;
|
|
56562
|
+
};
|
|
56027
56563
|
}
|
|
56028
56564
|
function resolveClaudeTargetPath(ownExecutablePath, dir) {
|
|
56029
|
-
return
|
|
56565
|
+
return import_node_path9.default.join(dir ?? import_node_path9.default.dirname(ownExecutablePath), claudeTargetFilename(ownExecutablePath));
|
|
56030
56566
|
}
|
|
56031
56567
|
function isEnoent3(error62) {
|
|
56032
56568
|
return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === "ENOENT";
|
|
@@ -56044,6 +56580,16 @@ function lstatOrUndefined(target) {
|
|
|
56044
56580
|
throw error62;
|
|
56045
56581
|
}
|
|
56046
56582
|
}
|
|
56583
|
+
function statOrUndefined(target) {
|
|
56584
|
+
try {
|
|
56585
|
+
return import_node_fs4.default.statSync(target);
|
|
56586
|
+
} catch (error62) {
|
|
56587
|
+
if (isEnoent3(error62)) {
|
|
56588
|
+
return void 0;
|
|
56589
|
+
}
|
|
56590
|
+
throw error62;
|
|
56591
|
+
}
|
|
56592
|
+
}
|
|
56047
56593
|
var nodeLinkFs = { link: import_node_fs4.default.linkSync, copyFile: import_node_fs4.default.copyFileSync, chmod: import_node_fs4.default.chmodSync };
|
|
56048
56594
|
function enableClaudeShim(params, linkFs = nodeLinkFs) {
|
|
56049
56595
|
const realContentPath = import_node_fs4.default.realpathSync(params.contentSourcePath);
|
|
@@ -56051,13 +56597,13 @@ function enableClaudeShim(params, linkFs = nodeLinkFs) {
|
|
|
56051
56597
|
throw new UnsupportedShimSourceError(realContentPath);
|
|
56052
56598
|
}
|
|
56053
56599
|
const targetPath = resolveClaudeTargetPath(params.ownExecutablePath, params.dir);
|
|
56054
|
-
import_node_fs4.default.mkdirSync(
|
|
56600
|
+
import_node_fs4.default.mkdirSync(import_node_path9.default.dirname(targetPath), { recursive: true });
|
|
56055
56601
|
const existing = lstatOrUndefined(targetPath);
|
|
56056
56602
|
if (existing !== void 0) {
|
|
56057
56603
|
const ownStat = import_node_fs4.default.statSync(realContentPath);
|
|
56058
56604
|
const state = readJson(params.paths.claudeShimFile, ClaudeShimStateSchema);
|
|
56059
56605
|
const sameInode = existing.dev === ownStat.dev && existing.ino === ownStat.ino;
|
|
56060
|
-
const markerMatches = state !== void 0 &&
|
|
56606
|
+
const markerMatches = state !== void 0 && import_node_path9.default.resolve(state.targetPath) === targetPath;
|
|
56061
56607
|
if (!sameInode && !markerMatches && !params.force) {
|
|
56062
56608
|
throw new ForeignClaudeEntryError(targetPath, "enable");
|
|
56063
56609
|
}
|
|
@@ -56082,7 +56628,7 @@ function enableClaudeShim(params, linkFs = nodeLinkFs) {
|
|
|
56082
56628
|
function disableClaudeShim(params) {
|
|
56083
56629
|
const realContentPath = import_node_fs4.default.realpathSync(params.contentSourcePath);
|
|
56084
56630
|
const state = readJson(params.paths.claudeShimFile, ClaudeShimStateSchema);
|
|
56085
|
-
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);
|
|
56086
56632
|
const existing = lstatOrUndefined(targetPath);
|
|
56087
56633
|
if (existing === void 0) {
|
|
56088
56634
|
if (state !== void 0) {
|
|
@@ -56092,7 +56638,7 @@ function disableClaudeShim(params) {
|
|
|
56092
56638
|
}
|
|
56093
56639
|
const ownStat = import_node_fs4.default.statSync(realContentPath);
|
|
56094
56640
|
const sameInode = existing.dev === ownStat.dev && existing.ino === ownStat.ino;
|
|
56095
|
-
const markerMatches = state !== void 0 &&
|
|
56641
|
+
const markerMatches = state !== void 0 && import_node_path9.default.resolve(state.targetPath) === targetPath;
|
|
56096
56642
|
if (!sameInode && !markerMatches && !params.force) {
|
|
56097
56643
|
throw new ForeignClaudeEntryError(targetPath, "disable");
|
|
56098
56644
|
}
|
|
@@ -56101,15 +56647,15 @@ function disableClaudeShim(params) {
|
|
|
56101
56647
|
return { action: "disabled", targetPath };
|
|
56102
56648
|
}
|
|
56103
56649
|
function findPathShadow(params) {
|
|
56104
|
-
const resolvedTargetDir =
|
|
56650
|
+
const resolvedTargetDir = import_node_path9.default.resolve(params.targetDir);
|
|
56105
56651
|
for (const dir of params.pathDirs) {
|
|
56106
56652
|
const found = params.findExecutableInDir(dir, params.targetFilename);
|
|
56107
56653
|
if (found === void 0) {
|
|
56108
56654
|
continue;
|
|
56109
56655
|
}
|
|
56110
|
-
return
|
|
56656
|
+
return import_node_path9.default.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
|
|
56111
56657
|
}
|
|
56112
|
-
return params.pathDirs.some((dir) =>
|
|
56658
|
+
return params.pathDirs.some((dir) => import_node_path9.default.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
|
|
56113
56659
|
}
|
|
56114
56660
|
function registerShimCommand(program2, deps) {
|
|
56115
56661
|
const { paths } = deps;
|
|
@@ -56127,21 +56673,21 @@ function registerShimCommand(program2, deps) {
|
|
|
56127
56673
|
ownExecutablePath,
|
|
56128
56674
|
contentSourcePath,
|
|
56129
56675
|
platform: process.platform,
|
|
56130
|
-
...options.dir === void 0 ? {} : { dir:
|
|
56676
|
+
...options.dir === void 0 ? {} : { dir: import_node_path9.default.resolve(options.dir) },
|
|
56131
56677
|
force: options.force ?? false
|
|
56132
56678
|
});
|
|
56133
56679
|
console.log(`${result.action === "enabled" ? "Installed" : "Reinstalled"} \`claude\` at ${result.targetPath} (${result.method}).`);
|
|
56134
56680
|
const shadow = findPathShadow({
|
|
56135
|
-
pathDirs: (process.env.PATH ?? "").split(
|
|
56136
|
-
targetDir:
|
|
56137
|
-
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),
|
|
56138
56684
|
findExecutableInDir
|
|
56139
56685
|
});
|
|
56140
56686
|
if (shadow.status === "not-on-path") {
|
|
56141
|
-
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.`);
|
|
56142
56688
|
} else if (shadow.status === "shadowed") {
|
|
56143
56689
|
console.warn(
|
|
56144
|
-
`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.`
|
|
56145
56691
|
);
|
|
56146
56692
|
}
|
|
56147
56693
|
});
|
|
@@ -56153,7 +56699,7 @@ function registerShimCommand(program2, deps) {
|
|
|
56153
56699
|
paths,
|
|
56154
56700
|
ownExecutablePath,
|
|
56155
56701
|
contentSourcePath,
|
|
56156
|
-
...options.dir === void 0 ? {} : { dir:
|
|
56702
|
+
...options.dir === void 0 ? {} : { dir: import_node_path9.default.resolve(options.dir) },
|
|
56157
56703
|
force: options.force ?? false
|
|
56158
56704
|
});
|
|
56159
56705
|
console.log(
|
|
@@ -56209,7 +56755,7 @@ function aliasLegacyWireHeaders(headers) {
|
|
|
56209
56755
|
// src/configure.ts
|
|
56210
56756
|
var import_node_fs8 = __toESM(require("node:fs"), 1);
|
|
56211
56757
|
var import_node_os4 = __toESM(require("node:os"), 1);
|
|
56212
|
-
var
|
|
56758
|
+
var import_node_path20 = __toESM(require("node:path"), 1);
|
|
56213
56759
|
|
|
56214
56760
|
// node_modules/.pnpm/@clack+core@1.5.1/node_modules/@clack/core/dist/index.mjs
|
|
56215
56761
|
var import_node_util3 = require("node:util");
|
|
@@ -57478,10 +58024,10 @@ function classifyEntries(names, options) {
|
|
|
57478
58024
|
|
|
57479
58025
|
// src/identityStore.ts
|
|
57480
58026
|
var import_node_fs6 = __toESM(require("node:fs"), 1);
|
|
57481
|
-
var
|
|
58027
|
+
var import_node_path13 = __toESM(require("node:path"), 1);
|
|
57482
58028
|
|
|
57483
58029
|
// src/launcher/identity.ts
|
|
57484
|
-
var
|
|
58030
|
+
var import_node_path10 = __toESM(require("node:path"), 1);
|
|
57485
58031
|
function poolNameOf(selector) {
|
|
57486
58032
|
return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
|
|
57487
58033
|
}
|
|
@@ -57530,12 +58076,12 @@ function decideConfigProfile(params) {
|
|
|
57530
58076
|
return { source: "none" };
|
|
57531
58077
|
}
|
|
57532
58078
|
function loadIdentity(identitiesDir, name, fs19) {
|
|
57533
|
-
return loadConfigFile(
|
|
58079
|
+
return loadConfigFile(import_node_path10.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs19.readConfigFile);
|
|
57534
58080
|
}
|
|
57535
58081
|
|
|
57536
58082
|
// src/configProfilesStore.ts
|
|
57537
58083
|
var import_node_fs5 = __toESM(require("node:fs"), 1);
|
|
57538
|
-
var
|
|
58084
|
+
var import_node_path11 = __toESM(require("node:path"), 1);
|
|
57539
58085
|
var ProfileNotFoundError = class extends CliError {
|
|
57540
58086
|
constructor(profileName) {
|
|
57541
58087
|
super(`No configuration profile named "${profileName}". Run \`agent-shim profile add ${profileName}\` first.`);
|
|
@@ -57561,7 +58107,7 @@ var InvalidCategoryNameError = class extends CliError {
|
|
|
57561
58107
|
categoryName;
|
|
57562
58108
|
};
|
|
57563
58109
|
function profileJsonPath(paths, name) {
|
|
57564
|
-
return
|
|
58110
|
+
return import_node_path11.default.join(paths.configProfilesDir, `${name}.json`);
|
|
57565
58111
|
}
|
|
57566
58112
|
function profileExists(paths, name) {
|
|
57567
58113
|
return import_node_fs5.default.existsSync(profileJsonPath(paths, name));
|
|
@@ -57722,8 +58268,8 @@ function removePool(paths, name) {
|
|
|
57722
58268
|
}
|
|
57723
58269
|
|
|
57724
58270
|
// src/launcher/lock.ts
|
|
57725
|
-
var
|
|
57726
|
-
var
|
|
58271
|
+
var import_node_crypto5 = require("node:crypto");
|
|
58272
|
+
var import_node_path12 = __toESM(require("node:path"), 1);
|
|
57727
58273
|
var DEFAULT_STALE_AFTER_MS = 12e4;
|
|
57728
58274
|
var DEFAULT_RETRY_DELAY_MS = 50;
|
|
57729
58275
|
var DEFAULT_MAX_ATTEMPTS = 200;
|
|
@@ -57742,7 +58288,7 @@ var IdentityLockBusyError = class extends CliError {
|
|
|
57742
58288
|
holderPid;
|
|
57743
58289
|
};
|
|
57744
58290
|
function identityLockPath(dir, identity) {
|
|
57745
|
-
return
|
|
58291
|
+
return import_node_path12.default.join(dir, `.${identity}.lock`);
|
|
57746
58292
|
}
|
|
57747
58293
|
function parseLockRecord(raw) {
|
|
57748
58294
|
if (raw === void 0) {
|
|
@@ -57771,7 +58317,7 @@ function acquireIdentityLock(params) {
|
|
|
57771
58317
|
const staleAfterMs = params.staleAfterMs ?? DEFAULT_STALE_AFTER_MS;
|
|
57772
58318
|
const retryDelayMs = params.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS;
|
|
57773
58319
|
const maxAttempts = params.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
|
|
57774
|
-
const token = (0,
|
|
58320
|
+
const token = (0, import_node_crypto5.randomUUID)();
|
|
57775
58321
|
if (params.fs.lstat(params.dir) === void 0) {
|
|
57776
58322
|
params.fs.mkdirp(params.dir);
|
|
57777
58323
|
}
|
|
@@ -57836,7 +58382,7 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
57836
58382
|
attemptedName;
|
|
57837
58383
|
};
|
|
57838
58384
|
function identityJsonPath(paths, name) {
|
|
57839
|
-
return
|
|
58385
|
+
return import_node_path13.default.join(paths.identitiesDir, name, "identity.json");
|
|
57840
58386
|
}
|
|
57841
58387
|
function identityExists(paths, name) {
|
|
57842
58388
|
return import_node_fs6.default.existsSync(identityJsonPath(paths, name));
|
|
@@ -57937,7 +58483,7 @@ function setIdentityCredential(paths, identityName, change) {
|
|
|
57937
58483
|
});
|
|
57938
58484
|
}
|
|
57939
58485
|
function belongsToIdentity(entry, name) {
|
|
57940
|
-
return entry === name || entry ===
|
|
58486
|
+
return entry === name || entry === import_node_path13.default.basename(identityLockPath("", name)) || entry.startsWith(`.${name}.scratch.`) || entry.startsWith(`.${name}.previous.`);
|
|
57941
58487
|
}
|
|
57942
58488
|
function removeIdentity(paths, name) {
|
|
57943
58489
|
if (!identityExists(paths, name)) {
|
|
@@ -57945,7 +58491,7 @@ function removeIdentity(paths, name) {
|
|
|
57945
58491
|
}
|
|
57946
58492
|
for (const entry of import_node_fs6.default.readdirSync(paths.identitiesDir)) {
|
|
57947
58493
|
if (belongsToIdentity(entry, name)) {
|
|
57948
|
-
import_node_fs6.default.rmSync(
|
|
58494
|
+
import_node_fs6.default.rmSync(import_node_path13.default.join(paths.identitiesDir, entry), { recursive: true, force: true });
|
|
57949
58495
|
}
|
|
57950
58496
|
}
|
|
57951
58497
|
if (readActiveIdentity(paths) === name) {
|
|
@@ -58044,32 +58590,32 @@ function removeDirectoryRule(paths, rulePath) {
|
|
|
58044
58590
|
}
|
|
58045
58591
|
|
|
58046
58592
|
// src/launcher/cascade.ts
|
|
58047
|
-
var
|
|
58593
|
+
var import_node_path16 = __toESM(require("node:path"), 1);
|
|
58048
58594
|
|
|
58049
58595
|
// src/pathNorm.ts
|
|
58050
|
-
var
|
|
58596
|
+
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
58051
58597
|
function expandTilde(value, home) {
|
|
58052
58598
|
if (value === "~") {
|
|
58053
58599
|
return home;
|
|
58054
58600
|
}
|
|
58055
58601
|
if (value.startsWith("~/")) {
|
|
58056
|
-
return
|
|
58602
|
+
return import_node_path14.default.join(home, value.slice(2));
|
|
58057
58603
|
}
|
|
58058
58604
|
return value;
|
|
58059
58605
|
}
|
|
58060
58606
|
function normaliseRulePath(rulePath, home) {
|
|
58061
|
-
return
|
|
58607
|
+
return import_node_path14.default.resolve(expandTilde(rulePath, home));
|
|
58062
58608
|
}
|
|
58063
58609
|
function isAncestorOrSelf(ancestor, descendant) {
|
|
58064
58610
|
if (ancestor === descendant) {
|
|
58065
58611
|
return true;
|
|
58066
58612
|
}
|
|
58067
|
-
const withSeparator = ancestor.endsWith(
|
|
58613
|
+
const withSeparator = ancestor.endsWith(import_node_path14.default.sep) ? ancestor : `${ancestor}${import_node_path14.default.sep}`;
|
|
58068
58614
|
return descendant.startsWith(withSeparator);
|
|
58069
58615
|
}
|
|
58070
58616
|
|
|
58071
58617
|
// src/resolve/walk.ts
|
|
58072
|
-
var
|
|
58618
|
+
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
58073
58619
|
|
|
58074
58620
|
// src/resolve/extends.ts
|
|
58075
58621
|
function lineariseProfile(rootName, load) {
|
|
@@ -58137,10 +58683,10 @@ function profileLayers(rootName, load, startId) {
|
|
|
58137
58683
|
|
|
58138
58684
|
// src/resolve/walk.ts
|
|
58139
58685
|
function walkDirectoryAncestors(cwd, options) {
|
|
58140
|
-
const limit =
|
|
58686
|
+
const limit = import_node_path15.default.resolve(options.limit ?? options.home);
|
|
58141
58687
|
const isReadable = options.isReadable ?? (() => true);
|
|
58142
58688
|
const collected = [];
|
|
58143
|
-
let current =
|
|
58689
|
+
let current = import_node_path15.default.resolve(cwd);
|
|
58144
58690
|
for (; ; ) {
|
|
58145
58691
|
if (!isReadable(current)) {
|
|
58146
58692
|
break;
|
|
@@ -58149,7 +58695,7 @@ function walkDirectoryAncestors(cwd, options) {
|
|
|
58149
58695
|
if (current === limit) {
|
|
58150
58696
|
break;
|
|
58151
58697
|
}
|
|
58152
|
-
const parent =
|
|
58698
|
+
const parent = import_node_path15.default.dirname(current);
|
|
58153
58699
|
if (parent === current) {
|
|
58154
58700
|
break;
|
|
58155
58701
|
}
|
|
@@ -58242,7 +58788,7 @@ function loadCascadeInput(params) {
|
|
|
58242
58788
|
const globalConfig2 = loadConfigFile(params.paths.globalConfigFile, GlobalConfigSchema, params.read);
|
|
58243
58789
|
const directoryRules = loadConfigFile(params.paths.directoryRulesFile, DirectoryRulesSchema, params.read);
|
|
58244
58790
|
const loadProfile = (name) => {
|
|
58245
|
-
const filepath =
|
|
58791
|
+
const filepath = import_node_path16.default.join(params.paths.configProfilesDir, `${name}.json`);
|
|
58246
58792
|
const loaded = loadConfigFile(filepath, ConfigProfileSchema, params.read);
|
|
58247
58793
|
if (loaded === void 0) {
|
|
58248
58794
|
return void 0;
|
|
@@ -58257,8 +58803,8 @@ function loadCascadeInput(params) {
|
|
|
58257
58803
|
});
|
|
58258
58804
|
const levels = [];
|
|
58259
58805
|
for (const dir of dirs) {
|
|
58260
|
-
const portable = loadConfigFile(
|
|
58261
|
-
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);
|
|
58262
58808
|
const rules = (directoryRules?.config.rules ?? []).map((rule, index) => ({ rule, index })).filter(({ rule }) => normaliseRulePath(rule.path, params.home) === dir).map(({ rule, index }) => {
|
|
58263
58809
|
const entryOrder = directoryRules?.ruleEntryOrders[index];
|
|
58264
58810
|
return {
|
|
@@ -58307,7 +58853,7 @@ function readDirectorySelections(loaded) {
|
|
|
58307
58853
|
}
|
|
58308
58854
|
|
|
58309
58855
|
// src/launcher/farm.ts
|
|
58310
|
-
var
|
|
58856
|
+
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
58311
58857
|
|
|
58312
58858
|
// src/resolve/reconcile.ts
|
|
58313
58859
|
function parentOf(rel) {
|
|
@@ -58975,7 +59521,7 @@ function dedupeDiagnostics(diagnostics) {
|
|
|
58975
59521
|
}
|
|
58976
59522
|
|
|
58977
59523
|
// src/resolve/plan.ts
|
|
58978
|
-
var
|
|
59524
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
58979
59525
|
function parentOf2(rel) {
|
|
58980
59526
|
const index = rel.lastIndexOf("/");
|
|
58981
59527
|
return index === -1 ? "" : rel.slice(0, index);
|
|
@@ -59025,7 +59571,7 @@ function planFarm(params) {
|
|
|
59025
59571
|
}
|
|
59026
59572
|
return value;
|
|
59027
59573
|
};
|
|
59028
|
-
const linkTarget = (rel) =>
|
|
59574
|
+
const linkTarget = (rel) => import_node_path17.default.join(params.facts.claudeHome, rel);
|
|
59029
59575
|
const visit2 = (rel) => {
|
|
59030
59576
|
const fact = params.facts.entries.get(rel);
|
|
59031
59577
|
const decision = params.decisions.get(rel);
|
|
@@ -59158,7 +59704,7 @@ var FarmManifestSchema = external_exports.strictObject({
|
|
|
59158
59704
|
links: external_exports.array(external_exports.strictObject({ rel: external_exports.string(), target: external_exports.string() }))
|
|
59159
59705
|
});
|
|
59160
59706
|
function readFarmManifest(fs19, farmRoot) {
|
|
59161
|
-
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));
|
|
59162
59708
|
if (raw === void 0) {
|
|
59163
59709
|
return void 0;
|
|
59164
59710
|
}
|
|
@@ -59174,7 +59720,7 @@ function readFarmManifest(fs19, farmRoot) {
|
|
|
59174
59720
|
function buildEntryFacts(params) {
|
|
59175
59721
|
const entries = /* @__PURE__ */ new Map();
|
|
59176
59722
|
const visit2 = (rel) => {
|
|
59177
|
-
const absolute =
|
|
59723
|
+
const absolute = import_node_path18.default.join(params.claudeHome, rel);
|
|
59178
59724
|
const stat = params.fs.lstat(absolute);
|
|
59179
59725
|
if (stat === void 0) {
|
|
59180
59726
|
return void 0;
|
|
@@ -59217,7 +59763,7 @@ function buildEntryFacts(params) {
|
|
|
59217
59763
|
};
|
|
59218
59764
|
}
|
|
59219
59765
|
function listSubtree(fs19, root, rel) {
|
|
59220
|
-
const absolute =
|
|
59766
|
+
const absolute = import_node_path18.default.join(root, rel);
|
|
59221
59767
|
const stat = fs19.lstat(absolute);
|
|
59222
59768
|
if (stat === void 0) {
|
|
59223
59769
|
return [];
|
|
@@ -59247,7 +59793,7 @@ function reconciliationScope(fs19, farmRoot, manifest) {
|
|
|
59247
59793
|
if (manifest !== void 0) {
|
|
59248
59794
|
return topLevelScopeRoots(manifest.materialised);
|
|
59249
59795
|
}
|
|
59250
|
-
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();
|
|
59251
59797
|
}
|
|
59252
59798
|
function collectFarmListing(fs19, farmRoot, scopeRoots) {
|
|
59253
59799
|
return scopeRoots.flatMap((root) => listSubtree(fs19, farmRoot, root));
|
|
@@ -59255,7 +59801,7 @@ function collectFarmListing(fs19, farmRoot, scopeRoots) {
|
|
|
59255
59801
|
function collectCanonicalCounterparts(fs19, claudeHome, farmListing) {
|
|
59256
59802
|
const out = [];
|
|
59257
59803
|
for (const entry of farmListing) {
|
|
59258
|
-
const absolute =
|
|
59804
|
+
const absolute = import_node_path18.default.join(claudeHome, entry.rel);
|
|
59259
59805
|
const stat = fs19.lstat(absolute);
|
|
59260
59806
|
if (stat === void 0) {
|
|
59261
59807
|
continue;
|
|
@@ -59285,21 +59831,21 @@ function carryOver(params) {
|
|
|
59285
59831
|
if (accounted.has(name)) {
|
|
59286
59832
|
continue;
|
|
59287
59833
|
}
|
|
59288
|
-
const stat = params.fs.lstat(
|
|
59834
|
+
const stat = params.fs.lstat(import_node_path18.default.join(params.previousRoot, name));
|
|
59289
59835
|
if (stat === void 0 || stat.kind === "symlink") {
|
|
59290
59836
|
continue;
|
|
59291
59837
|
}
|
|
59292
|
-
if (params.fs.lstat(
|
|
59838
|
+
if (params.fs.lstat(import_node_path18.default.join(params.farmRoot, name)) !== void 0) {
|
|
59293
59839
|
const category = params.classification === void 0 ? void 0 : classifyEntries([name], params.classification).classification.get(name);
|
|
59294
59840
|
if (category === "runtime") {
|
|
59295
|
-
params.fs.removeRecursive(
|
|
59841
|
+
params.fs.removeRecursive(import_node_path18.default.join(params.previousRoot, name));
|
|
59296
59842
|
autoResolved.push(name);
|
|
59297
59843
|
continue;
|
|
59298
59844
|
}
|
|
59299
59845
|
collided.push(name);
|
|
59300
59846
|
continue;
|
|
59301
59847
|
}
|
|
59302
|
-
params.fs.rename(
|
|
59848
|
+
params.fs.rename(import_node_path18.default.join(params.previousRoot, name), import_node_path18.default.join(params.farmRoot, name));
|
|
59303
59849
|
carried.push(name);
|
|
59304
59850
|
}
|
|
59305
59851
|
return { carried, autoResolved, collided };
|
|
@@ -59307,9 +59853,9 @@ function carryOver(params) {
|
|
|
59307
59853
|
function buildScratchTree(params) {
|
|
59308
59854
|
params.fs.mkdirp(params.scratchRoot);
|
|
59309
59855
|
for (const entry of params.plan.entries) {
|
|
59310
|
-
const absolute =
|
|
59856
|
+
const absolute = import_node_path18.default.join(params.scratchRoot, entry.rel);
|
|
59311
59857
|
if (entry.kind === "link") {
|
|
59312
|
-
params.fs.mkdirp(
|
|
59858
|
+
params.fs.mkdirp(import_node_path18.default.dirname(absolute));
|
|
59313
59859
|
params.fs.symlink(entry.target, absolute);
|
|
59314
59860
|
continue;
|
|
59315
59861
|
}
|
|
@@ -59318,14 +59864,14 @@ function buildScratchTree(params) {
|
|
|
59318
59864
|
}
|
|
59319
59865
|
}
|
|
59320
59866
|
params.fs.writeFileUtf8(
|
|
59321
|
-
|
|
59867
|
+
import_node_path18.default.join(params.scratchRoot, FARM_MANIFEST_FILENAME),
|
|
59322
59868
|
`${JSON.stringify(params.manifest, null, 2)}
|
|
59323
59869
|
`
|
|
59324
59870
|
);
|
|
59325
59871
|
}
|
|
59326
59872
|
function swapIn(params) {
|
|
59327
59873
|
if (params.fs.lstat(params.farmRoot) === void 0) {
|
|
59328
|
-
params.fs.mkdirp(
|
|
59874
|
+
params.fs.mkdirp(import_node_path18.default.dirname(params.farmRoot));
|
|
59329
59875
|
params.fs.rename(params.scratchRoot, params.farmRoot);
|
|
59330
59876
|
return { carried: [], autoResolved: [], collided: [] };
|
|
59331
59877
|
}
|
|
@@ -59349,14 +59895,14 @@ function recoverInterruptedSwap(params) {
|
|
|
59349
59895
|
const names = [...params.fs.readdir(params.identitiesDir)].sort();
|
|
59350
59896
|
const removedScratch = [];
|
|
59351
59897
|
for (const name of names.filter((candidate) => candidate.startsWith(scratchPrefix))) {
|
|
59352
|
-
params.fs.removeRecursive(
|
|
59898
|
+
params.fs.removeRecursive(import_node_path18.default.join(params.identitiesDir, name));
|
|
59353
59899
|
removedScratch.push(name);
|
|
59354
59900
|
}
|
|
59355
59901
|
let previous = names.filter((candidate) => candidate.startsWith(previousPrefix));
|
|
59356
59902
|
let restoredFrom;
|
|
59357
59903
|
const first = previous[0];
|
|
59358
59904
|
if (first !== void 0 && params.fs.lstat(params.farmRoot) === void 0) {
|
|
59359
|
-
params.fs.rename(
|
|
59905
|
+
params.fs.rename(import_node_path18.default.join(params.identitiesDir, first), params.farmRoot);
|
|
59360
59906
|
restoredFrom = first;
|
|
59361
59907
|
previous = previous.slice(1);
|
|
59362
59908
|
}
|
|
@@ -59364,7 +59910,7 @@ function recoverInterruptedSwap(params) {
|
|
|
59364
59910
|
const autoResolved = [];
|
|
59365
59911
|
const retained = [];
|
|
59366
59912
|
for (const name of previous) {
|
|
59367
|
-
const previousRoot =
|
|
59913
|
+
const previousRoot = import_node_path18.default.join(params.identitiesDir, name);
|
|
59368
59914
|
const result = carryOver({
|
|
59369
59915
|
fs: params.fs,
|
|
59370
59916
|
previousRoot,
|
|
@@ -59389,7 +59935,7 @@ function recoverInterruptedSwap(params) {
|
|
|
59389
59935
|
};
|
|
59390
59936
|
}
|
|
59391
59937
|
function recoverFarm(params) {
|
|
59392
|
-
const farmRoot =
|
|
59938
|
+
const farmRoot = import_node_path18.default.join(params.identitiesDir, params.identity);
|
|
59393
59939
|
const lock = acquireIdentityLock({
|
|
59394
59940
|
identity: params.identity,
|
|
59395
59941
|
dir: params.identitiesDir,
|
|
@@ -59448,16 +59994,16 @@ function executeReconciliation(params) {
|
|
|
59448
59994
|
});
|
|
59449
59995
|
continue;
|
|
59450
59996
|
}
|
|
59451
|
-
const from =
|
|
59452
|
-
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);
|
|
59453
59999
|
if (action.kind === "adopt") {
|
|
59454
|
-
params.fs.mkdirp(
|
|
60000
|
+
params.fs.mkdirp(import_node_path18.default.dirname(canonical));
|
|
59455
60001
|
params.fs.copyRecursive(from, canonical);
|
|
59456
60002
|
adopted.push(action.rel);
|
|
59457
60003
|
continue;
|
|
59458
60004
|
}
|
|
59459
60005
|
const preserved = `${canonical}.farm-conflict-${String(params.nowMs)}`;
|
|
59460
|
-
params.fs.mkdirp(
|
|
60006
|
+
params.fs.mkdirp(import_node_path18.default.dirname(canonical));
|
|
59461
60007
|
params.fs.copyRecursive(from, preserved);
|
|
59462
60008
|
conflicts.push(action.rel);
|
|
59463
60009
|
}
|
|
@@ -59482,7 +60028,7 @@ function farmAlreadyMatches(existing, next) {
|
|
|
59482
60028
|
return existing.identity === next.identity && existing.claudeHome === next.claudeHome && sameStrings(existing.materialised, next.materialised) && sameLinks(existing.links, next.links);
|
|
59483
60029
|
}
|
|
59484
60030
|
function resyncFarm(params) {
|
|
59485
|
-
const farmRoot =
|
|
60031
|
+
const farmRoot = import_node_path18.default.join(params.identitiesDir, params.identity);
|
|
59486
60032
|
const lock = acquireIdentityLock({
|
|
59487
60033
|
identity: params.identity,
|
|
59488
60034
|
dir: params.identitiesDir,
|
|
@@ -59562,8 +60108,8 @@ function resyncFarm(params) {
|
|
|
59562
60108
|
diagnostics
|
|
59563
60109
|
};
|
|
59564
60110
|
}
|
|
59565
|
-
const scratchRoot =
|
|
59566
|
-
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}`);
|
|
59567
60113
|
buildScratchTree({ fs: params.fs, scratchRoot, plan: resolved.farm, manifest });
|
|
59568
60114
|
const swap = swapIn({ fs: params.fs, farmRoot, scratchRoot, previousRoot, classification: params.classification });
|
|
59569
60115
|
if (swap.retainedPrevious !== void 0) {
|
|
@@ -59622,14 +60168,14 @@ function recoveryDiagnostics(recovery, identity) {
|
|
|
59622
60168
|
// src/paths.ts
|
|
59623
60169
|
var import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
59624
60170
|
var import_node_os3 = __toESM(require("node:os"), 1);
|
|
59625
|
-
var
|
|
60171
|
+
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
59626
60172
|
function resolveAgentShimHome(env = process.env, home = import_node_os3.default.homedir(), isDirectory = isExistingDirectory) {
|
|
59627
60173
|
const fromEnv = env.AGENT_SHIM_HOME;
|
|
59628
60174
|
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
59629
60175
|
return fromEnv;
|
|
59630
60176
|
}
|
|
59631
|
-
const current =
|
|
59632
|
-
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);
|
|
59633
60179
|
return !isDirectory(current) && isDirectory(legacy) ? legacy : current;
|
|
59634
60180
|
}
|
|
59635
60181
|
function isExistingDirectory(candidate) {
|
|
@@ -59640,40 +60186,40 @@ function resolveClaudeHome() {
|
|
|
59640
60186
|
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
59641
60187
|
return fromEnv;
|
|
59642
60188
|
}
|
|
59643
|
-
return
|
|
60189
|
+
return import_node_path19.default.join(import_node_os3.default.homedir(), ".claude");
|
|
59644
60190
|
}
|
|
59645
60191
|
function buildLayoutPaths(root) {
|
|
59646
60192
|
return {
|
|
59647
60193
|
root,
|
|
59648
|
-
identitiesDir:
|
|
59649
|
-
configProfilesDir:
|
|
59650
|
-
providersDir:
|
|
59651
|
-
directoryRulesFile:
|
|
59652
|
-
activeIdentityFile:
|
|
59653
|
-
globalConfigFile:
|
|
59654
|
-
categoriesLocalFile:
|
|
59655
|
-
claudeShimFile:
|
|
59656
|
-
headroomDir:
|
|
59657
|
-
headroomStateFile:
|
|
59658
|
-
headroomSocketDir:
|
|
59659
|
-
headroomLockFile:
|
|
59660
|
-
headroomSessionsDir:
|
|
59661
|
-
logsDir:
|
|
59662
|
-
headroomLogPath:
|
|
59663
|
-
frontdoorDir:
|
|
59664
|
-
frontdoorCaDir:
|
|
59665
|
-
frontdoorCaCertFile:
|
|
59666
|
-
frontdoorCaKeyFile:
|
|
59667
|
-
frontdoorCaBundlesDir:
|
|
59668
|
-
frontdoorStateFile:
|
|
59669
|
-
frontdoorLockFile:
|
|
59670
|
-
frontdoorControlTokenFile:
|
|
59671
|
-
frontdoorSessionsDir:
|
|
59672
|
-
frontdoorLogPath:
|
|
59673
|
-
usageDir:
|
|
59674
|
-
usageLogDir:
|
|
59675
|
-
usageSnapshotsDir:
|
|
59676
|
-
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")
|
|
59677
60223
|
};
|
|
59678
60224
|
}
|
|
59679
60225
|
function resolveLayoutPaths() {
|
|
@@ -59755,7 +60301,7 @@ function chooseWriteTarget(params) {
|
|
|
59755
60301
|
for (let index = params.levels.length - 1; index >= 0; index -= 1) {
|
|
59756
60302
|
const level = params.levels[index];
|
|
59757
60303
|
if (level !== void 0 && (level.hasPortable || level.hasPortableLocal)) {
|
|
59758
|
-
return { tier: "portable-local", localConfigPath:
|
|
60304
|
+
return { tier: "portable-local", localConfigPath: import_node_path20.default.join(level.dir, level.portableLocalFilename) };
|
|
59759
60305
|
}
|
|
59760
60306
|
}
|
|
59761
60307
|
const normalisedCwd = normaliseRulePath(params.cwd, params.home);
|
|
@@ -59848,11 +60394,11 @@ function buildWriteTargetLevels(cwd, home, walkUpLimit) {
|
|
|
59848
60394
|
const limit = walkUpLimit === void 0 ? void 0 : expandTilde(walkUpLimit, home);
|
|
59849
60395
|
const dirs = walkDirectoryAncestors(cwd, { home, ...limit === void 0 ? {} : { limit } });
|
|
59850
60396
|
return dirs.map((dir) => {
|
|
59851
|
-
const hasLocal = import_node_fs8.default.existsSync(
|
|
59852
|
-
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));
|
|
59853
60399
|
return {
|
|
59854
60400
|
dir,
|
|
59855
|
-
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)),
|
|
59856
60402
|
hasPortableLocal: hasLocal || hasLegacyLocal,
|
|
59857
60403
|
portableLocalFilename: !hasLocal && hasLegacyLocal ? LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME : PORTABLE_LOCAL_CONFIG_FILENAME
|
|
59858
60404
|
};
|
|
@@ -60196,7 +60742,7 @@ function resolveLaunchIdentity(paths, cwd) {
|
|
|
60196
60742
|
}
|
|
60197
60743
|
|
|
60198
60744
|
// src/identityManager.ts
|
|
60199
|
-
var
|
|
60745
|
+
var import_node_path22 = __toESM(require("node:path"), 1);
|
|
60200
60746
|
|
|
60201
60747
|
// src/cli/credentialOption.ts
|
|
60202
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";
|
|
@@ -60304,7 +60850,7 @@ var CREDENTIAL_COMMAND_TIMEOUT_MS = 1e4;
|
|
|
60304
60850
|
var CREDENTIAL_INTERACTIVE_TIMEOUT_MS = 12e4;
|
|
60305
60851
|
var GROUP_OTHER_PERMISSION_BITS = 63;
|
|
60306
60852
|
var PERMISSION_BITS2 = 511;
|
|
60307
|
-
var
|
|
60853
|
+
var OCTAL_RADIX2 = 8;
|
|
60308
60854
|
function commandArgv(source) {
|
|
60309
60855
|
if ("command" in source) {
|
|
60310
60856
|
return source.command;
|
|
@@ -60397,7 +60943,7 @@ function trySource(source, params) {
|
|
|
60397
60943
|
}
|
|
60398
60944
|
if (read.mode !== void 0 && (read.mode & GROUP_OTHER_PERMISSION_BITS) !== 0) {
|
|
60399
60945
|
return none(
|
|
60400
|
-
`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}\``,
|
|
60401
60947
|
true
|
|
60402
60948
|
);
|
|
60403
60949
|
}
|
|
@@ -60465,11 +61011,11 @@ function credentialVariables(target, token) {
|
|
|
60465
61011
|
}
|
|
60466
61012
|
|
|
60467
61013
|
// src/launcher/farmResolve.ts
|
|
60468
|
-
var
|
|
61014
|
+
var import_node_path21 = __toESM(require("node:path"), 1);
|
|
60469
61015
|
async function resolveFarmConflicts(params) {
|
|
60470
|
-
const farmRoot =
|
|
61016
|
+
const farmRoot = import_node_path21.default.join(params.identitiesDir, params.identity);
|
|
60471
61017
|
const previousPrefix = `.${params.identity}.previous.`;
|
|
60472
|
-
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));
|
|
60473
61019
|
const resolved = [];
|
|
60474
61020
|
const autoResolved = [];
|
|
60475
61021
|
const removed = [];
|
|
@@ -60492,11 +61038,11 @@ async function resolveFarmConflicts(params) {
|
|
|
60492
61038
|
continue;
|
|
60493
61039
|
}
|
|
60494
61040
|
if (choice === "keep-new") {
|
|
60495
|
-
params.fs.removeRecursive(
|
|
61041
|
+
params.fs.removeRecursive(import_node_path21.default.join(previousRoot, name));
|
|
60496
61042
|
continue;
|
|
60497
61043
|
}
|
|
60498
|
-
params.fs.removeRecursive(
|
|
60499
|
-
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));
|
|
60500
61046
|
}
|
|
60501
61047
|
if (anySkipped) {
|
|
60502
61048
|
retained.push(previousRoot);
|
|
@@ -60835,7 +61381,7 @@ function toIdentityView(paths, entry) {
|
|
|
60835
61381
|
return {
|
|
60836
61382
|
name: entry.name,
|
|
60837
61383
|
active: entry.isActive,
|
|
60838
|
-
directory:
|
|
61384
|
+
directory: import_node_path22.default.join(paths.identitiesDir, entry.name),
|
|
60839
61385
|
...entry.problem === void 0 ? {
|
|
60840
61386
|
...entry.identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: entry.identity.defaultConfigProfile },
|
|
60841
61387
|
allowAmbientCredential: entry.identity.allowAmbientCredential,
|
|
@@ -60982,7 +61528,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60982
61528
|
if (!identityExists(paths, name)) {
|
|
60983
61529
|
throw new IdentityNotFoundError(name);
|
|
60984
61530
|
}
|
|
60985
|
-
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)}`);
|
|
60986
61532
|
removeIdentity(paths, name);
|
|
60987
61533
|
reportMutation(options.json, { action: "removed", kind: "identity", name }, () => {
|
|
60988
61534
|
console.log(`Removed identity "${name}".`);
|
|
@@ -61040,7 +61586,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
61040
61586
|
// package.json
|
|
61041
61587
|
var package_default = {
|
|
61042
61588
|
name: "agent-shim",
|
|
61043
|
-
version: "8.5.
|
|
61589
|
+
version: "8.5.3",
|
|
61044
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.",
|
|
61045
61591
|
license: "MIT",
|
|
61046
61592
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -61136,7 +61682,7 @@ var package_default = {
|
|
|
61136
61682
|
};
|
|
61137
61683
|
|
|
61138
61684
|
// src/check.ts
|
|
61139
|
-
var
|
|
61685
|
+
var import_node_path29 = __toESM(require("node:path"), 1);
|
|
61140
61686
|
|
|
61141
61687
|
// src/checkReport.ts
|
|
61142
61688
|
var import_node_os5 = __toESM(require("node:os"), 1);
|
|
@@ -61190,10 +61736,10 @@ function quotaWarnings(snapshot, provider, nowMs) {
|
|
|
61190
61736
|
}
|
|
61191
61737
|
|
|
61192
61738
|
// src/usage/poolPick.ts
|
|
61193
|
-
var
|
|
61739
|
+
var import_node_path26 = __toESM(require("node:path"), 1);
|
|
61194
61740
|
|
|
61195
61741
|
// src/usage/account.ts
|
|
61196
|
-
var
|
|
61742
|
+
var import_node_path23 = __toESM(require("node:path"), 1);
|
|
61197
61743
|
|
|
61198
61744
|
// src/usage/schema.ts
|
|
61199
61745
|
var USAGE_SCHEMA_VERSION = 1;
|
|
@@ -61362,7 +61908,7 @@ function isIdentityName(name) {
|
|
|
61362
61908
|
return IdentitySchema.shape.name.safeParse(name).success;
|
|
61363
61909
|
}
|
|
61364
61910
|
function claudeJsonPath(identitiesDir, identity) {
|
|
61365
|
-
return
|
|
61911
|
+
return import_node_path23.default.join(identitiesDir, identity, CLAUDE_JSON);
|
|
61366
61912
|
}
|
|
61367
61913
|
function readAccountMetadata(fs19, identitiesDir, identity) {
|
|
61368
61914
|
if (!isIdentityName(identity)) {
|
|
@@ -62170,7 +62716,7 @@ function rankPool(input2) {
|
|
|
62170
62716
|
}
|
|
62171
62717
|
|
|
62172
62718
|
// src/usage/read.ts
|
|
62173
|
-
var
|
|
62719
|
+
var import_node_path24 = __toESM(require("node:path"), 1);
|
|
62174
62720
|
var SEGMENT_RE = /^(\d{4}-\d{2}-\d{2})\.(\d+)\.jsonl$/;
|
|
62175
62721
|
var DAY_MS = 864e5;
|
|
62176
62722
|
function segmentDay(epochMs) {
|
|
@@ -62197,7 +62743,7 @@ function readUsageLog(fs19, logDir, options = {}) {
|
|
|
62197
62743
|
if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
|
|
62198
62744
|
continue;
|
|
62199
62745
|
}
|
|
62200
|
-
const contents = fs19.readFileUtf8(
|
|
62746
|
+
const contents = fs19.readFileUtf8(import_node_path24.default.join(logDir, segment.name));
|
|
62201
62747
|
if (contents === void 0) {
|
|
62202
62748
|
continue;
|
|
62203
62749
|
}
|
|
@@ -62239,7 +62785,7 @@ function snapshotPath(snapshotsDir, identity) {
|
|
|
62239
62785
|
if (!isIdentityName(identity)) {
|
|
62240
62786
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
62241
62787
|
}
|
|
62242
|
-
return
|
|
62788
|
+
return import_node_path24.default.join(snapshotsDir, `${identity}.json`);
|
|
62243
62789
|
}
|
|
62244
62790
|
function readUsageSnapshot(fs19, snapshotsDir, identity) {
|
|
62245
62791
|
const file2 = snapshotPath(snapshotsDir, identity);
|
|
@@ -62323,7 +62869,7 @@ function summariseUsage(records) {
|
|
|
62323
62869
|
}
|
|
62324
62870
|
|
|
62325
62871
|
// src/usage/store.ts
|
|
62326
|
-
var
|
|
62872
|
+
var import_node_path25 = __toESM(require("node:path"), 1);
|
|
62327
62873
|
var DAY_MS2 = 864e5;
|
|
62328
62874
|
var DAYS_IN_WEEK = 7;
|
|
62329
62875
|
var USAGE_RETENTION_MS = DAYS_IN_WEEK * DAY_MS2;
|
|
@@ -62331,7 +62877,7 @@ function pruneUsageLog(fs19, logDir, nowMs) {
|
|
|
62331
62877
|
const cutoff = nowMs - USAGE_RETENTION_MS;
|
|
62332
62878
|
for (const segment of listLogSegments(fs19, logDir)) {
|
|
62333
62879
|
if (segment.endsAt <= cutoff) {
|
|
62334
|
-
fs19.removeRecursive(
|
|
62880
|
+
fs19.removeRecursive(import_node_path25.default.join(logDir, segment.name));
|
|
62335
62881
|
}
|
|
62336
62882
|
}
|
|
62337
62883
|
}
|
|
@@ -62412,7 +62958,7 @@ function createUsageStore(deps) {
|
|
|
62412
62958
|
pruneUsageLog(fs19, paths.usageLogDir, nowMs);
|
|
62413
62959
|
prunedDay = day;
|
|
62414
62960
|
}
|
|
62415
|
-
fs19.appendFilePrivate(
|
|
62961
|
+
fs19.appendFilePrivate(import_node_path25.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record2)}
|
|
62416
62962
|
`);
|
|
62417
62963
|
if (record2.identity !== void 0) {
|
|
62418
62964
|
rewriteSnapshot(record2.identity, (current) => ({ ...current?.providers, [record2.provider]: foldProviderState(current?.providers[record2.provider], record2) }));
|
|
@@ -62488,7 +63034,7 @@ function recordStickyPick(fs19, picksFile, directory, identity, nowMs) {
|
|
|
62488
63034
|
const current = readPicksFile(fs19, picksFile).file.picks;
|
|
62489
63035
|
const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
|
|
62490
63036
|
const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
|
|
62491
|
-
fs19.mkdirPrivate(
|
|
63037
|
+
fs19.mkdirPrivate(import_node_path26.default.dirname(picksFile));
|
|
62492
63038
|
fs19.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
|
|
62493
63039
|
`);
|
|
62494
63040
|
}
|
|
@@ -62582,7 +63128,7 @@ function collectPoolPick(params) {
|
|
|
62582
63128
|
|
|
62583
63129
|
// src/providersStore.ts
|
|
62584
63130
|
var import_node_fs9 = __toESM(require("node:fs"), 1);
|
|
62585
|
-
var
|
|
63131
|
+
var import_node_path27 = __toESM(require("node:path"), 1);
|
|
62586
63132
|
var ProviderNotFoundError = class extends CliError {
|
|
62587
63133
|
constructor(name) {
|
|
62588
63134
|
super(`No provider named "${name}". Run \`agent-shim provider add ${name}\` first.`);
|
|
@@ -62611,7 +63157,7 @@ var InvalidProviderNameError = class extends CliError {
|
|
|
62611
63157
|
};
|
|
62612
63158
|
var PROVIDER_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._@-]*$/;
|
|
62613
63159
|
function providerJsonPath(paths, name) {
|
|
62614
|
-
return
|
|
63160
|
+
return import_node_path27.default.join(paths.providersDir, `${name}.json`);
|
|
62615
63161
|
}
|
|
62616
63162
|
function providerExists(paths, name) {
|
|
62617
63163
|
return import_node_fs9.default.existsSync(providerJsonPath(paths, name));
|
|
@@ -62687,7 +63233,7 @@ function readProvider(paths, name) {
|
|
|
62687
63233
|
return parseProviderFile(filePath, raw);
|
|
62688
63234
|
}
|
|
62689
63235
|
function loadProvider(providersDir, name, port) {
|
|
62690
|
-
const filePath =
|
|
63236
|
+
const filePath = import_node_path27.default.join(providersDir, `${name}.json`);
|
|
62691
63237
|
const raw = port.readConfigFile(filePath);
|
|
62692
63238
|
return raw === void 0 ? void 0 : parseProviderFile(filePath, raw);
|
|
62693
63239
|
}
|
|
@@ -62849,7 +63395,7 @@ function resolveProvider(params) {
|
|
|
62849
63395
|
}
|
|
62850
63396
|
|
|
62851
63397
|
// src/checkReport.ts
|
|
62852
|
-
var
|
|
63398
|
+
var import_node_path28 = __toESM(require("node:path"), 1);
|
|
62853
63399
|
|
|
62854
63400
|
// src/cli/envBool.ts
|
|
62855
63401
|
var InvalidEnvBoolError = class extends UsageError {
|
|
@@ -63249,10 +63795,10 @@ function collectCheckReport(params) {
|
|
|
63249
63795
|
}).input;
|
|
63250
63796
|
const providerName = cascadeProviderName(cascade);
|
|
63251
63797
|
const provider = providerName === void 0 ? void 0 : loadCheckProvider(paths, providerName);
|
|
63252
|
-
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);
|
|
63253
63799
|
const settingsFiles = {
|
|
63254
|
-
"settings.json": realFsPort.readFileUtf8(
|
|
63255
|
-
"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"))
|
|
63256
63802
|
};
|
|
63257
63803
|
const report = runCheck({
|
|
63258
63804
|
cwd,
|
|
@@ -63286,7 +63832,7 @@ function registerCheckCommand(program2, deps) {
|
|
|
63286
63832
|
const command = program2.command("check [path]").description(
|
|
63287
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."
|
|
63288
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) => {
|
|
63289
|
-
const cwd = pathArg === void 0 ? process.cwd() :
|
|
63835
|
+
const cwd = pathArg === void 0 ? process.cwd() : import_node_path29.default.resolve(pathArg);
|
|
63290
63836
|
const report = collectCheckReport({ paths, cwd, ...options.identity === void 0 ? {} : { identity: options.identity }, env: process.env });
|
|
63291
63837
|
if (options.json === true) {
|
|
63292
63838
|
printJson(checkReportToJson(report));
|
|
@@ -63303,123 +63849,10 @@ function registerCheckCommand(program2, deps) {
|
|
|
63303
63849
|
}
|
|
63304
63850
|
|
|
63305
63851
|
// src/codex/commands.ts
|
|
63306
|
-
var
|
|
63852
|
+
var import_node_crypto7 = require("node:crypto");
|
|
63307
63853
|
var import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
63308
63854
|
var import_node_os6 = __toESM(require("node:os"), 1);
|
|
63309
|
-
var
|
|
63310
|
-
|
|
63311
|
-
// src/frontdoor/state.ts
|
|
63312
|
-
var import_node_path28 = __toESM(require("node:path"), 1);
|
|
63313
|
-
var FRONT_DOOR_PROTOCOL = 2;
|
|
63314
|
-
var FrontDoorSessionSchema = external_exports.strictObject({ pid: external_exports.number().int().positive(), startedAt: external_exports.number(), token: external_exports.string().min(1) });
|
|
63315
|
-
var FrontDoorStateSchema = external_exports.strictObject({
|
|
63316
|
-
/**
|
|
63317
|
-
* 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`).
|
|
63318
|
-
*/
|
|
63319
|
-
protocol: external_exports.number().int().nonnegative().optional(),
|
|
63320
|
-
/** The supervisor process serving the front door. Alive means both listeners are up in that process. */
|
|
63321
|
-
supervisorPid: external_exports.number().int().positive().optional(),
|
|
63322
|
-
/** 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. */
|
|
63323
|
-
port: external_exports.number().int().positive().optional(),
|
|
63324
|
-
/**
|
|
63325
|
-
* 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.
|
|
63326
|
-
*/
|
|
63327
|
-
lastPort: external_exports.number().int().positive().optional(),
|
|
63328
|
-
/**
|
|
63329
|
-
* 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`.
|
|
63330
|
-
*/
|
|
63331
|
-
connectPort: external_exports.number().int().positive().optional(),
|
|
63332
|
-
/**
|
|
63333
|
-
* 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.
|
|
63334
|
-
*/
|
|
63335
|
-
lastConnectPort: external_exports.number().int().positive().optional(),
|
|
63336
|
-
/**
|
|
63337
|
-
* 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.
|
|
63338
|
-
*/
|
|
63339
|
-
directPort: external_exports.number().int().positive().optional(),
|
|
63340
|
-
/** The sticky port preference for the direct listener, for the reason `directPort` gives. */
|
|
63341
|
-
lastDirectPort: external_exports.number().int().positive().optional(),
|
|
63342
|
-
/** The last fatal error, kept across shutdowns so `frontdoor status` can explain a front door that is not running. */
|
|
63343
|
-
lastError: external_exports.string().optional()
|
|
63344
|
-
});
|
|
63345
|
-
function readFrontDoorState(fs19, stateFile) {
|
|
63346
|
-
let raw;
|
|
63347
|
-
try {
|
|
63348
|
-
raw = fs19.readFileUtf8(stateFile);
|
|
63349
|
-
} catch {
|
|
63350
|
-
return void 0;
|
|
63351
|
-
}
|
|
63352
|
-
if (raw === void 0 || raw.trim() === "") {
|
|
63353
|
-
return void 0;
|
|
63354
|
-
}
|
|
63355
|
-
try {
|
|
63356
|
-
const parsed = FrontDoorStateSchema.safeParse(JSON.parse(raw));
|
|
63357
|
-
return parsed.success ? parsed.data : void 0;
|
|
63358
|
-
} catch {
|
|
63359
|
-
return void 0;
|
|
63360
|
-
}
|
|
63361
|
-
}
|
|
63362
|
-
function writeFrontDoorState(fs19, stateFile, state) {
|
|
63363
|
-
fs19.mkdirp(import_node_path28.default.dirname(stateFile));
|
|
63364
|
-
fs19.writeFileUtf8(stateFile, `${JSON.stringify(state, null, 2)}
|
|
63365
|
-
`);
|
|
63366
|
-
}
|
|
63367
|
-
function frontDoorOrigin(state) {
|
|
63368
|
-
const port = state?.directPort ?? state?.lastDirectPort;
|
|
63369
|
-
return port === void 0 ? void 0 : `http://127.0.0.1:${String(port)}`;
|
|
63370
|
-
}
|
|
63371
|
-
function writeFrontDoorSession(fs19, sessionsDir, session) {
|
|
63372
|
-
fs19.mkdirPrivate(sessionsDir);
|
|
63373
|
-
fs19.writeFilePrivate(import_node_path28.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
63374
|
-
`);
|
|
63375
|
-
}
|
|
63376
|
-
function listFrontDoorSessions(fs19, sessionsDir) {
|
|
63377
|
-
const sessions = [];
|
|
63378
|
-
for (const name of fs19.readdir(sessionsDir)) {
|
|
63379
|
-
if (!name.endsWith(".json")) {
|
|
63380
|
-
continue;
|
|
63381
|
-
}
|
|
63382
|
-
try {
|
|
63383
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs19.readFileUtf8(import_node_path28.default.join(sessionsDir, name)) ?? ""));
|
|
63384
|
-
if (parsed.success) {
|
|
63385
|
-
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
|
|
63386
|
-
}
|
|
63387
|
-
} catch {
|
|
63388
|
-
continue;
|
|
63389
|
-
}
|
|
63390
|
-
}
|
|
63391
|
-
return sessions.sort((a2, b) => a2.pid - b.pid);
|
|
63392
|
-
}
|
|
63393
|
-
function removeFrontDoorSession(fs19, sessionsDir, pid) {
|
|
63394
|
-
fs19.removeRecursive(import_node_path28.default.join(sessionsDir, `${String(pid)}.json`));
|
|
63395
|
-
}
|
|
63396
|
-
function pruneDeadFrontDoorSessions(fs19, sessionsDir, isRunning) {
|
|
63397
|
-
const removed = [];
|
|
63398
|
-
for (const session of listFrontDoorSessions(fs19, sessionsDir)) {
|
|
63399
|
-
if (!isRunning(session.pid)) {
|
|
63400
|
-
removeFrontDoorSession(fs19, sessionsDir, session.pid);
|
|
63401
|
-
removed.push(session.pid);
|
|
63402
|
-
}
|
|
63403
|
-
}
|
|
63404
|
-
return removed;
|
|
63405
|
-
}
|
|
63406
|
-
function liveSessionTokens(fs19, sessionsDir) {
|
|
63407
|
-
const tokens = /* @__PURE__ */ new Set();
|
|
63408
|
-
for (const name of fs19.readdir(sessionsDir)) {
|
|
63409
|
-
if (!name.endsWith(".json")) {
|
|
63410
|
-
continue;
|
|
63411
|
-
}
|
|
63412
|
-
try {
|
|
63413
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs19.readFileUtf8(import_node_path28.default.join(sessionsDir, name)) ?? ""));
|
|
63414
|
-
if (parsed.success) {
|
|
63415
|
-
tokens.add(parsed.data.token);
|
|
63416
|
-
}
|
|
63417
|
-
} catch {
|
|
63418
|
-
continue;
|
|
63419
|
-
}
|
|
63420
|
-
}
|
|
63421
|
-
return tokens;
|
|
63422
|
-
}
|
|
63855
|
+
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
63423
63856
|
|
|
63424
63857
|
// src/codex/agent.ts
|
|
63425
63858
|
var import_undici = __toESM(require_undici(), 1);
|
|
@@ -63568,7 +64001,7 @@ function createCodexAuthStore(authPath, ports) {
|
|
|
63568
64001
|
}
|
|
63569
64002
|
|
|
63570
64003
|
// src/codex/upstream.ts
|
|
63571
|
-
var
|
|
64004
|
+
var import_node_crypto6 = require("node:crypto");
|
|
63572
64005
|
|
|
63573
64006
|
// src/codex/http.ts
|
|
63574
64007
|
var HTTP_STATUS = {
|
|
@@ -63622,7 +64055,7 @@ function sessionIdFor(userId, randomId) {
|
|
|
63622
64055
|
if (userId === void 0 || userId === "") {
|
|
63623
64056
|
return randomId();
|
|
63624
64057
|
}
|
|
63625
|
-
const hex3 = (0,
|
|
64058
|
+
const hex3 = (0, import_node_crypto6.createHash)("sha256").update(`agent-shim codex session
|
|
63626
64059
|
${userId}`).digest("hex");
|
|
63627
64060
|
let next = 0;
|
|
63628
64061
|
return UUID_TEMPLATE.replace(/x/g, () => hex3.charAt(next++));
|
|
@@ -63658,10 +64091,10 @@ async function callCodex(ports, request7, sessionId, signal) {
|
|
|
63658
64091
|
// src/codex/commands.ts
|
|
63659
64092
|
function codexHome(env, home) {
|
|
63660
64093
|
const fromEnv = env.CODEX_HOME;
|
|
63661
|
-
return fromEnv !== void 0 && fromEnv !== "" ? fromEnv :
|
|
64094
|
+
return fromEnv !== void 0 && fromEnv !== "" ? fromEnv : import_node_path30.default.join(home, ".codex");
|
|
63662
64095
|
}
|
|
63663
64096
|
function codexUsageSnapshotPath() {
|
|
63664
|
-
return
|
|
64097
|
+
return import_node_path30.default.join(resolveClaudeHome(), "codex-quota.json");
|
|
63665
64098
|
}
|
|
63666
64099
|
function isEnoent4(error62) {
|
|
63667
64100
|
return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === "ENOENT";
|
|
@@ -63690,7 +64123,7 @@ function writeUsageSnapshot(log, snapshot) {
|
|
|
63690
64123
|
const target = codexUsageSnapshotPath();
|
|
63691
64124
|
const temp = `${target}.${String(process.pid)}.tmp`;
|
|
63692
64125
|
try {
|
|
63693
|
-
import_node_fs10.default.mkdirSync(
|
|
64126
|
+
import_node_fs10.default.mkdirSync(import_node_path30.default.dirname(target), { recursive: true });
|
|
63694
64127
|
import_node_fs10.default.writeFileSync(temp, `${JSON.stringify(snapshot, null, 2)}
|
|
63695
64128
|
`);
|
|
63696
64129
|
import_node_fs10.default.renameSync(temp, target);
|
|
@@ -63701,14 +64134,14 @@ function writeUsageSnapshot(log, snapshot) {
|
|
|
63701
64134
|
function createCodexRoutePorts(log) {
|
|
63702
64135
|
const agent = createUpstreamAgent();
|
|
63703
64136
|
const upstreamFetch = createUpstreamFetch(agent);
|
|
63704
|
-
const auth = createCodexAuthStore(
|
|
64137
|
+
const auth = createCodexAuthStore(import_node_path30.default.join(codexHome(process.env, import_node_os6.default.homedir()), "auth.json"), {
|
|
63705
64138
|
fs: realCodexAuthFs,
|
|
63706
64139
|
fetch: upstreamFetch,
|
|
63707
64140
|
now: () => /* @__PURE__ */ new Date(),
|
|
63708
|
-
tempSuffix: `${String(process.pid)}.${(0,
|
|
64141
|
+
tempSuffix: `${String(process.pid)}.${(0, import_node_crypto7.randomUUID)()}`
|
|
63709
64142
|
});
|
|
63710
64143
|
return {
|
|
63711
|
-
upstream: { fetch: upstreamFetch, auth, timers: realTimers, randomId:
|
|
64144
|
+
upstream: { fetch: upstreamFetch, auth, timers: realTimers, randomId: import_node_crypto7.randomUUID },
|
|
63712
64145
|
writeUsageSnapshot: (snapshot) => {
|
|
63713
64146
|
writeUsageSnapshot(log, snapshot);
|
|
63714
64147
|
},
|
|
@@ -63775,85 +64208,10 @@ function registerCodexCommand(program2, deps) {
|
|
|
63775
64208
|
}
|
|
63776
64209
|
|
|
63777
64210
|
// src/frontdoor/commands.ts
|
|
63778
|
-
var
|
|
64211
|
+
var import_node_crypto12 = require("node:crypto");
|
|
63779
64212
|
var import_node_path31 = __toESM(require("node:path"), 1);
|
|
63780
64213
|
var import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
63781
64214
|
|
|
63782
|
-
// src/headroom/socket.ts
|
|
63783
|
-
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
63784
|
-
var GROUP_OR_OTHER_BITS = 63;
|
|
63785
|
-
var OCTAL_RADIX2 = 8;
|
|
63786
|
-
var MODE_DIGITS = 4;
|
|
63787
|
-
var HEADROOM_SOCKET_SUFFIX = ".sock";
|
|
63788
|
-
var HEADROOM_SOCKET_NAME = /^(\d+)\.sock$/;
|
|
63789
|
-
var UNIX_SOCKET_PATH_MAX_BYTES = 103;
|
|
63790
|
-
var PLATFORMS_WITHOUT_UNIX_SOCKETS = ["win32"];
|
|
63791
|
-
function headroomSocketPath(paths, supervisorPid) {
|
|
63792
|
-
return import_node_path30.default.join(paths.headroomSocketDir, `${String(supervisorPid)}${HEADROOM_SOCKET_SUFFIX}`);
|
|
63793
|
-
}
|
|
63794
|
-
function platformRefusal(platform) {
|
|
63795
|
-
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;
|
|
63796
|
-
}
|
|
63797
|
-
function ownerOnlyRefusal(label, target, stat, expected, uid) {
|
|
63798
|
-
if (stat === void 0) {
|
|
63799
|
-
return `the headroom ${label} ${target} does not exist`;
|
|
63800
|
-
}
|
|
63801
|
-
if (stat.kind === "symlink") {
|
|
63802
|
-
return `the headroom ${label} ${target} is a symlink; it must be the real ${expected === "dir" ? "directory" : "socket"}`;
|
|
63803
|
-
}
|
|
63804
|
-
if (stat.kind !== expected) {
|
|
63805
|
-
return `the headroom ${label} ${target} is not a ${expected === "dir" ? "directory" : "socket"}`;
|
|
63806
|
-
}
|
|
63807
|
-
if (stat.uid !== uid) {
|
|
63808
|
-
return `the headroom ${label} ${target} is owned by uid ${String(stat.uid)}, not by this user (uid ${String(uid)})`;
|
|
63809
|
-
}
|
|
63810
|
-
if ((stat.mode & GROUP_OR_OTHER_BITS) !== 0) {
|
|
63811
|
-
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`;
|
|
63812
|
-
}
|
|
63813
|
-
return void 0;
|
|
63814
|
-
}
|
|
63815
|
-
function verifyHeadroomSocket(socketPath, ports) {
|
|
63816
|
-
const unsupported = platformRefusal(ports.platform);
|
|
63817
|
-
if (unsupported !== void 0) {
|
|
63818
|
-
return { refused: unsupported };
|
|
63819
|
-
}
|
|
63820
|
-
const uid = ports.currentUid();
|
|
63821
|
-
const directory = import_node_path30.default.dirname(socketPath);
|
|
63822
|
-
const refusal = ownerOnlyRefusal("socket directory", directory, ports.lstat(directory), "dir", uid) ?? ownerOnlyRefusal("socket", socketPath, ports.lstat(socketPath), "socket", uid);
|
|
63823
|
-
return refusal === void 0 ? { socketPath } : { refused: refusal };
|
|
63824
|
-
}
|
|
63825
|
-
function prepareHeadroomSocket(fs19, ports, paths, supervisorPid) {
|
|
63826
|
-
const unsupported = platformRefusal(ports.platform);
|
|
63827
|
-
if (unsupported !== void 0) {
|
|
63828
|
-
return { refused: unsupported };
|
|
63829
|
-
}
|
|
63830
|
-
const socketPath = headroomSocketPath(paths, supervisorPid);
|
|
63831
|
-
const length = Buffer.byteLength(socketPath, "utf8");
|
|
63832
|
-
if (length > UNIX_SOCKET_PATH_MAX_BYTES) {
|
|
63833
|
-
return {
|
|
63834
|
-
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`
|
|
63835
|
-
};
|
|
63836
|
-
}
|
|
63837
|
-
if (ports.lstat(paths.headroomSocketDir)?.kind === "symlink") {
|
|
63838
|
-
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
63839
|
-
}
|
|
63840
|
-
fs19.mkdirPrivate(paths.headroomSocketDir);
|
|
63841
|
-
const refusal = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
63842
|
-
return refusal === void 0 ? { socketPath } : { refused: refusal };
|
|
63843
|
-
}
|
|
63844
|
-
function pruneStaleHeadroomSockets(fs19, paths, isRunning) {
|
|
63845
|
-
const removed = [];
|
|
63846
|
-
for (const name of fs19.readdir(paths.headroomSocketDir)) {
|
|
63847
|
-
const pid = HEADROOM_SOCKET_NAME.exec(name)?.[1];
|
|
63848
|
-
if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
|
|
63849
|
-
continue;
|
|
63850
|
-
}
|
|
63851
|
-
fs19.removeRecursive(import_node_path30.default.join(paths.headroomSocketDir, name));
|
|
63852
|
-
removed.push(name);
|
|
63853
|
-
}
|
|
63854
|
-
return removed;
|
|
63855
|
-
}
|
|
63856
|
-
|
|
63857
64215
|
// src/frontdoor/custody.ts
|
|
63858
64216
|
var CREDENTIAL_HEADERS = ["authorization", "x-api-key"];
|
|
63859
64217
|
var SEQUESTERED_CREDENTIAL = "agent-shim-sequestered";
|
|
@@ -63955,7 +64313,7 @@ function createDoorPipelines(deps) {
|
|
|
63955
64313
|
}
|
|
63956
64314
|
|
|
63957
64315
|
// src/frontdoor/capability.ts
|
|
63958
|
-
var
|
|
64316
|
+
var import_node_crypto8 = require("node:crypto");
|
|
63959
64317
|
var CONNECT_PROXY_USER = "agent-shim";
|
|
63960
64318
|
var CONNECT_PROXY_REALM = "agent-shim front door";
|
|
63961
64319
|
var BASIC_SCHEME = "basic";
|
|
@@ -63977,13 +64335,13 @@ function capabilityFromProxyAuthorization(value) {
|
|
|
63977
64335
|
return password === "" ? void 0 : password;
|
|
63978
64336
|
}
|
|
63979
64337
|
function digest(token) {
|
|
63980
|
-
return (0,
|
|
64338
|
+
return (0, import_node_crypto8.createHash)("sha256").update(token, "utf8").digest();
|
|
63981
64339
|
}
|
|
63982
64340
|
function isLiveCapability(presented, live) {
|
|
63983
64341
|
const presentedDigest = digest(presented);
|
|
63984
64342
|
let matched = false;
|
|
63985
64343
|
for (const token of live) {
|
|
63986
|
-
const equal = (0,
|
|
64344
|
+
const equal = (0, import_node_crypto8.timingSafeEqual)(presentedDigest, digest(token));
|
|
63987
64345
|
matched = equal || matched;
|
|
63988
64346
|
}
|
|
63989
64347
|
return matched;
|
|
@@ -64127,11 +64485,11 @@ function createFileCapture(file2, now = () => /* @__PURE__ */ new Date()) {
|
|
|
64127
64485
|
}
|
|
64128
64486
|
|
|
64129
64487
|
// src/frontdoor/connect.ts
|
|
64130
|
-
var
|
|
64488
|
+
var import_node_crypto10 = require("node:crypto");
|
|
64131
64489
|
var fs12 = __toESM(require("node:fs"), 1);
|
|
64132
64490
|
|
|
64133
64491
|
// src/frontdoor/x509.ts
|
|
64134
|
-
var
|
|
64492
|
+
var import_node_crypto9 = require("node:crypto");
|
|
64135
64493
|
var import_node_net = __toESM(require("node:net"), 1);
|
|
64136
64494
|
var TAG_BOOLEAN = 1;
|
|
64137
64495
|
var TAG_INTEGER = 2;
|
|
@@ -64283,7 +64641,7 @@ function ipBytes(address) {
|
|
|
64283
64641
|
return bytes;
|
|
64284
64642
|
}
|
|
64285
64643
|
function keyIdentifier(publicKey) {
|
|
64286
|
-
return (0,
|
|
64644
|
+
return (0, import_node_crypto9.createHash)("sha1").update(publicKey.export({ type: "pkcs1", format: "der" })).digest();
|
|
64287
64645
|
}
|
|
64288
64646
|
function readElement(buffer, offset) {
|
|
64289
64647
|
const tag = buffer[offset];
|
|
@@ -64329,7 +64687,7 @@ ${body.join("\n")}
|
|
|
64329
64687
|
`;
|
|
64330
64688
|
}
|
|
64331
64689
|
function randomSerial() {
|
|
64332
|
-
const bytes = (0,
|
|
64690
|
+
const bytes = (0, import_node_crypto9.randomBytes)(SERIAL_NUMBER_BYTES);
|
|
64333
64691
|
bytes[0] = (bytes[0] ?? 0) & BASE_128_PAYLOAD_MASK | HIGH_BIT >> 1;
|
|
64334
64692
|
return bytes;
|
|
64335
64693
|
}
|
|
@@ -64344,7 +64702,7 @@ function assemble(spec) {
|
|
|
64344
64702
|
spec.subjectPublicKey.export({ type: "spki", format: "der" }),
|
|
64345
64703
|
tlv(TAG_EXTENSIONS, sequence(...spec.extensions))
|
|
64346
64704
|
);
|
|
64347
|
-
const signature = (0,
|
|
64705
|
+
const signature = (0, import_node_crypto9.sign)("sha256", tbs, spec.signingKey);
|
|
64348
64706
|
return sequence(tbs, SIGNATURE_ALGORITHM, wholeBitString(signature));
|
|
64349
64707
|
}
|
|
64350
64708
|
function subjectKeyIdentifierExtension(publicKey) {
|
|
@@ -64354,7 +64712,7 @@ function basicConstraintsExtension(isCa) {
|
|
|
64354
64712
|
return extension(OID_BASIC_CONSTRAINTS, true, sequence(...isCa ? [boolean4(true)] : []));
|
|
64355
64713
|
}
|
|
64356
64714
|
function rsaKeyPair() {
|
|
64357
|
-
return (0,
|
|
64715
|
+
return (0, import_node_crypto9.generateKeyPairSync)("rsa", { modulusLength: RSA_MODULUS_BITS });
|
|
64358
64716
|
}
|
|
64359
64717
|
function keyPem(privateKey) {
|
|
64360
64718
|
return privateKey.export({ type: "pkcs8", format: "pem" });
|
|
@@ -64378,8 +64736,8 @@ function issueLeafCertificate(ca, names, notBefore, notAfter) {
|
|
|
64378
64736
|
if (commonName === void 0) {
|
|
64379
64737
|
throw new Error("a leaf certificate needs at least one name");
|
|
64380
64738
|
}
|
|
64381
|
-
const caCertificate = new
|
|
64382
|
-
const caPrivateKey = (0,
|
|
64739
|
+
const caCertificate = new import_node_crypto9.X509Certificate(ca.certPem);
|
|
64740
|
+
const caPrivateKey = (0, import_node_crypto9.createPrivateKey)(ca.keyPem);
|
|
64383
64741
|
const { publicKey, privateKey } = rsaKeyPair();
|
|
64384
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)));
|
|
64385
64743
|
const der = assemble({
|
|
@@ -64455,7 +64813,7 @@ function pumpTapSession(secure, openUpstream, tap, prefix = Buffer.alloc(0)) {
|
|
|
64455
64813
|
// src/frontdoor/supervisor.ts
|
|
64456
64814
|
var FRONTDOOR_SUPERVISOR_STILL_RUNNING = -1;
|
|
64457
64815
|
var FRONTDOOR_POLL_MS = 1e3;
|
|
64458
|
-
var
|
|
64816
|
+
var MS_PER_MINUTE2 = 6e4;
|
|
64459
64817
|
async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {}) {
|
|
64460
64818
|
const { fs: fs19, paths } = ports;
|
|
64461
64819
|
const previous = readFrontDoorState(fs19, paths.frontdoorStateFile);
|
|
@@ -64523,7 +64881,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
64523
64881
|
pruneDeadFrontDoorSessions(fs19, paths.frontdoorSessionsDir, ports.isRunning);
|
|
64524
64882
|
if (listFrontDoorSessions(fs19, paths.frontdoorSessionsDir).length === 0) {
|
|
64525
64883
|
idleSince ??= ports.now();
|
|
64526
|
-
if (ports.now() - idleSince >= idleShutdownMinutes *
|
|
64884
|
+
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE2) {
|
|
64527
64885
|
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
64528
64886
|
await direct.close();
|
|
64529
64887
|
await connect3.close();
|
|
@@ -64642,8 +65000,8 @@ function ensureCa(store, generate) {
|
|
|
64642
65000
|
}
|
|
64643
65001
|
function caParses(ca) {
|
|
64644
65002
|
try {
|
|
64645
|
-
new
|
|
64646
|
-
(0,
|
|
65003
|
+
new import_node_crypto10.X509Certificate(ca.certPem);
|
|
65004
|
+
(0, import_node_crypto10.createPrivateKey)(ca.keyPem);
|
|
64647
65005
|
return true;
|
|
64648
65006
|
} catch {
|
|
64649
65007
|
return false;
|
|
@@ -66018,7 +66376,7 @@ async function serveRouted(request7, deps) {
|
|
|
66018
66376
|
}
|
|
66019
66377
|
|
|
66020
66378
|
// src/codex/translate.ts
|
|
66021
|
-
var
|
|
66379
|
+
var import_node_crypto11 = require("node:crypto");
|
|
66022
66380
|
|
|
66023
66381
|
// src/codex/anthropic.ts
|
|
66024
66382
|
var TextBlockSchema = external_exports.looseObject({ type: external_exports.literal("text"), text: external_exports.string() });
|
|
@@ -66130,7 +66488,7 @@ function shortToolName(name, names) {
|
|
|
66130
66488
|
if (name.length <= CODEX_TOOL_NAME_LIMIT) {
|
|
66131
66489
|
return name;
|
|
66132
66490
|
}
|
|
66133
|
-
const hash2 = (0,
|
|
66491
|
+
const hash2 = (0, import_node_crypto11.createHash)("sha256").update(name).digest("hex").slice(0, TOOL_NAME_HASH_CHARS);
|
|
66134
66492
|
const shortened = `${name.slice(0, CODEX_TOOL_NAME_LIMIT - TOOL_NAME_HASH_CHARS - 1)}_${hash2}`;
|
|
66135
66493
|
names.set(shortened, name);
|
|
66136
66494
|
return shortened;
|
|
@@ -66988,6 +67346,11 @@ function singleHeader(headers, name) {
|
|
|
66988
67346
|
const value = headers[name];
|
|
66989
67347
|
return typeof value === "string" ? value : void 0;
|
|
66990
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
|
+
}
|
|
66991
67354
|
function sessionCreateId(body) {
|
|
66992
67355
|
let parsed;
|
|
66993
67356
|
try {
|
|
@@ -67131,7 +67494,7 @@ function createRcSessionTracker(deps) {
|
|
|
67131
67494
|
}
|
|
67132
67495
|
const tail = path41.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
67133
67496
|
const facts = {
|
|
67134
|
-
|
|
67497
|
+
oauthAuthorization: oauthAuthorizationOf(request7.headers),
|
|
67135
67498
|
anthropicVersion: singleHeader(request7.headers, "anthropic-version"),
|
|
67136
67499
|
anthropicClientPlatform: singleHeader(request7.headers, "anthropic-client-platform")
|
|
67137
67500
|
};
|
|
@@ -67173,7 +67536,7 @@ function createRcSessionTracker(deps) {
|
|
|
67173
67536
|
}
|
|
67174
67537
|
const entry = entries.get(id) ?? birth(id, facts);
|
|
67175
67538
|
entry.lastSeenAt = deps.now();
|
|
67176
|
-
entry.
|
|
67539
|
+
entry.oauthAuthorization = facts.oauthAuthorization ?? entry.oauthAuthorization;
|
|
67177
67540
|
entry.anthropicVersion = facts.anthropicVersion ?? entry.anthropicVersion;
|
|
67178
67541
|
entry.anthropicClientPlatform = facts.anthropicClientPlatform ?? entry.anthropicClientPlatform;
|
|
67179
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;
|
|
@@ -67261,7 +67624,7 @@ function createRcSessionTracker(deps) {
|
|
|
67261
67624
|
},
|
|
67262
67625
|
credentialOf: (sessionId) => {
|
|
67263
67626
|
const entry = entries.get(sessionId);
|
|
67264
|
-
return entry === void 0 ? void 0 : { authorization: entry.
|
|
67627
|
+
return entry === void 0 ? void 0 : { authorization: entry.oauthAuthorization, anthropicVersion: entry.anthropicVersion, anthropicClientPlatform: entry.anthropicClientPlatform };
|
|
67265
67628
|
},
|
|
67266
67629
|
completePending: (sessionId, requestId) => {
|
|
67267
67630
|
entries.get(sessionId)?.pending.delete(requestId);
|
|
@@ -67363,6 +67726,9 @@ function rcEventWriteResultFromAnswer(answer) {
|
|
|
67363
67726
|
}
|
|
67364
67727
|
return { ok: true, sequenceNums };
|
|
67365
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
|
+
}
|
|
67366
67732
|
function rcWriteHeaders(credential) {
|
|
67367
67733
|
const headers = { "content-type": "application/json" };
|
|
67368
67734
|
if (credential.authorization !== void 0) {
|
|
@@ -67381,6 +67747,9 @@ async function injectRcUserMessage(deps, sessionId, text2) {
|
|
|
67381
67747
|
if (credential === void 0) {
|
|
67382
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)` };
|
|
67383
67749
|
}
|
|
67750
|
+
if (credential.authorization === void 0) {
|
|
67751
|
+
return noOAuthCredentialResult(sessionId);
|
|
67752
|
+
}
|
|
67384
67753
|
const body = JSON.stringify(buildRcEventWriteBody(buildRcUserMessagePayload(deps.newUuid(), sessionId, text2)));
|
|
67385
67754
|
let answer;
|
|
67386
67755
|
try {
|
|
@@ -67399,6 +67768,9 @@ async function answerRcControlRequest(deps, sessionId, requestId, decision) {
|
|
|
67399
67768
|
if (credential === void 0) {
|
|
67400
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)` };
|
|
67401
67770
|
}
|
|
67771
|
+
if (credential.authorization === void 0) {
|
|
67772
|
+
return noOAuthCredentialResult(sessionId);
|
|
67773
|
+
}
|
|
67402
67774
|
if (!deps.pendingOf(sessionId).some((pending) => pending.requestId === requestId)) {
|
|
67403
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` };
|
|
67404
67776
|
}
|
|
@@ -67720,7 +68092,7 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
67720
68092
|
let directPort = 0;
|
|
67721
68093
|
const codexPorts = createCodexRoutePorts(log);
|
|
67722
68094
|
const rcTracker = createRcSessionTracker({ now: () => Date.now(), idleMs: RC_IDLE_EXPIRY_MS });
|
|
67723
|
-
const rcControlToken = (0,
|
|
68095
|
+
const rcControlToken = (0, import_node_crypto12.randomUUID)();
|
|
67724
68096
|
const resolveRoute = rcObservingResolver(createProviderRouteResolver({ fs: realFsPort, providersDir: paths.providersDir, codexPorts, directPort: () => directPort }), rcTracker);
|
|
67725
68097
|
const isLiveToken = (token) => isLiveCapability(token, liveSessionTokens(realFarmFs, paths.frontdoorSessionsDir));
|
|
67726
68098
|
const usageStore = createUsageStore({
|
|
@@ -67747,8 +68119,8 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
67747
68119
|
now: () => Date.now(),
|
|
67748
68120
|
headroomSocket: () => headroomSocketTarget(realFarmFs, realHeadroomSocketTrust, paths),
|
|
67749
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.
|
|
67750
|
-
hopSecret: (0,
|
|
67751
|
-
custody: createCredentialCustody(() => (0,
|
|
68122
|
+
hopSecret: (0, import_node_crypto12.randomUUID)(),
|
|
68123
|
+
custody: createCredentialCustody(() => (0, import_node_crypto12.randomUUID)()),
|
|
67752
68124
|
log
|
|
67753
68125
|
});
|
|
67754
68126
|
let ca;
|
|
@@ -67774,7 +68146,7 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
67774
68146
|
startProviderListener: async (preferredPort) => {
|
|
67775
68147
|
const authority = loadCa();
|
|
67776
68148
|
const rcDial = realRcEventDial();
|
|
67777
|
-
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);
|
|
67778
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);
|
|
67779
68151
|
realFarmFs.mkdirp(paths.frontdoorDir);
|
|
67780
68152
|
realFarmFs.writeFilePrivate(paths.frontdoorControlTokenFile, `${rcControlToken}
|
|
@@ -67798,7 +68170,7 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
67798
68170
|
},
|
|
67799
68171
|
startConnectListener: async (preferredPort) => {
|
|
67800
68172
|
const transparentPort = process.env.AGENT_SHIM_TRANSPARENT_SURFACE === void 0 ? void 0 : Number(process.env.AGENT_SHIM_TRANSPARENT_SURFACE);
|
|
67801
|
-
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)();
|
|
67802
68174
|
if (transparentCapability !== void 0) {
|
|
67803
68175
|
writeFrontDoorSession(realFarmFs, paths.frontdoorSessionsDir, { pid: process.pid, startedAt: Date.now(), token: transparentCapability });
|
|
67804
68176
|
}
|
|
@@ -68584,33 +68956,6 @@ function subjectName(positional, provider) {
|
|
|
68584
68956
|
// src/doctorReport.ts
|
|
68585
68957
|
var import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
68586
68958
|
var import_node_path34 = __toESM(require("node:path"), 1);
|
|
68587
|
-
|
|
68588
|
-
// src/headroom/source.ts
|
|
68589
|
-
var GIT_SPEC_RE = /git\+[^@\s]+(?:@([^\s#]+))?/;
|
|
68590
|
-
var COMMIT_SHA_RE = /^[0-9a-f]{40}$/i;
|
|
68591
|
-
var DirectUrlSchema = external_exports.object({ vcs_info: external_exports.object({ commit_id: external_exports.string() }) });
|
|
68592
|
-
function isMovingGitSource(spec) {
|
|
68593
|
-
const match = GIT_SPEC_RE.exec(spec);
|
|
68594
|
-
if (match === null) {
|
|
68595
|
-
return false;
|
|
68596
|
-
}
|
|
68597
|
-
const ref = match[1];
|
|
68598
|
-
return ref === void 0 || !COMMIT_SHA_RE.test(ref);
|
|
68599
|
-
}
|
|
68600
|
-
function pinnedGitCommit(spec) {
|
|
68601
|
-
const ref = GIT_SPEC_RE.exec(spec)?.[1];
|
|
68602
|
-
return ref !== void 0 && COMMIT_SHA_RE.test(ref) ? ref.toLowerCase() : void 0;
|
|
68603
|
-
}
|
|
68604
|
-
function parseInstalledCommit(directUrlJson) {
|
|
68605
|
-
try {
|
|
68606
|
-
const parsed = DirectUrlSchema.safeParse(JSON.parse(directUrlJson));
|
|
68607
|
-
return parsed.success ? parsed.data.vcs_info.commit_id.toLowerCase() : void 0;
|
|
68608
|
-
} catch {
|
|
68609
|
-
return void 0;
|
|
68610
|
-
}
|
|
68611
|
-
}
|
|
68612
|
-
|
|
68613
|
-
// src/doctorReport.ts
|
|
68614
68959
|
function refinePathShadow(status, ownExecutablePath, realpath) {
|
|
68615
68960
|
if (status.status !== "shadowed") {
|
|
68616
68961
|
return status;
|
|
@@ -69034,7 +69379,7 @@ function collectDoctorReport(params) {
|
|
|
69034
69379
|
const ownExecutablePath = realOwnExecutablePath();
|
|
69035
69380
|
let binaryDiscovery;
|
|
69036
69381
|
try {
|
|
69037
|
-
const binary = realResolveClaudeBinary(
|
|
69382
|
+
const binary = realResolveClaudeBinary(resolveOwnBinaryCheck(paths, realContentSourcePath()))();
|
|
69038
69383
|
binaryDiscovery = { ok: true, binary };
|
|
69039
69384
|
} catch (error62) {
|
|
69040
69385
|
binaryDiscovery = { ok: false, message: error62 instanceof Error ? error62.message : String(error62) };
|
|
@@ -69118,7 +69463,7 @@ var import_node_child_process5 = require("node:child_process");
|
|
|
69118
69463
|
var import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
69119
69464
|
|
|
69120
69465
|
// src/frontdoor/ensure.ts
|
|
69121
|
-
var
|
|
69466
|
+
var import_node_crypto13 = require("node:crypto");
|
|
69122
69467
|
var FRONTDOOR_START_TIMEOUT_MS = 3e4;
|
|
69123
69468
|
var FRONTDOOR_LAUNCHER_POLL_MS = 100;
|
|
69124
69469
|
var FrontDoorStartError = class extends CliError {
|
|
@@ -69152,7 +69497,7 @@ function ensureFrontDoor(params) {
|
|
|
69152
69497
|
continue;
|
|
69153
69498
|
}
|
|
69154
69499
|
if (verdict.ok) {
|
|
69155
|
-
const token = (0,
|
|
69500
|
+
const token = (0, import_node_crypto13.randomUUID)();
|
|
69156
69501
|
writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token });
|
|
69157
69502
|
return { port: state.port, connectPort: state.connectPort, token };
|
|
69158
69503
|
}
|
|
@@ -69256,7 +69601,7 @@ function probeFrontDoorSync(port, caPem) {
|
|
|
69256
69601
|
}
|
|
69257
69602
|
|
|
69258
69603
|
// src/frontdoor/trust.ts
|
|
69259
|
-
var
|
|
69604
|
+
var import_node_crypto14 = require("node:crypto");
|
|
69260
69605
|
var import_node_path35 = __toESM(require("node:path"), 1);
|
|
69261
69606
|
var BUNDLE_NAME_HEX_DIGITS = 16;
|
|
69262
69607
|
function resolveTrustBundle(params) {
|
|
@@ -69279,7 +69624,7 @@ function resolveTrustBundle(params) {
|
|
|
69279
69624
|
}
|
|
69280
69625
|
const combined = `${inheritedPem.trimEnd()}
|
|
69281
69626
|
${caPem}`;
|
|
69282
|
-
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`);
|
|
69283
69628
|
if (!fs19.exists(bundle)) {
|
|
69284
69629
|
fs19.mkdirp(bundlesDir);
|
|
69285
69630
|
fs19.writeFileAtomic(bundle, combined);
|
|
@@ -69332,315 +69677,6 @@ function realFrontDoorPort(paths, spawnDaemon) {
|
|
|
69332
69677
|
};
|
|
69333
69678
|
}
|
|
69334
69679
|
|
|
69335
|
-
// src/headroom/settings.ts
|
|
69336
|
-
var import_node_crypto14 = require("node:crypto");
|
|
69337
|
-
function settingsOf(config2) {
|
|
69338
|
-
return {
|
|
69339
|
-
...config2.mode === void 0 ? {} : { mode: config2.mode },
|
|
69340
|
-
...config2.targetRatio === void 0 ? {} : { targetRatio: config2.targetRatio },
|
|
69341
|
-
...config2.ccr === void 0 ? {} : { ccr: config2.ccr },
|
|
69342
|
-
...config2.rolloutChannel === void 0 ? {} : { rolloutChannel: config2.rolloutChannel },
|
|
69343
|
-
...config2.interceptToolResults === void 0 ? {} : { interceptToolResults: config2.interceptToolResults },
|
|
69344
|
-
...config2.readMaturation === void 0 ? {} : { readMaturation: config2.readMaturation }
|
|
69345
|
-
};
|
|
69346
|
-
}
|
|
69347
|
-
function settingsArgs(settings2) {
|
|
69348
|
-
return [
|
|
69349
|
-
...settings2.mode === void 0 ? [] : ["--mode", settings2.mode],
|
|
69350
|
-
...settings2.targetRatio === void 0 ? [] : ["--target-ratio", String(settings2.targetRatio)],
|
|
69351
|
-
...settings2.ccr === "lossless" ? ["--lossless"] : [],
|
|
69352
|
-
...settings2.ccr === "none" ? ["--no-ccr"] : [],
|
|
69353
|
-
...settings2.interceptToolResults === true ? ["--intercept-tool-results"] : [],
|
|
69354
|
-
...settings2.readMaturation === true ? ["--read-maturation"] : []
|
|
69355
|
-
];
|
|
69356
|
-
}
|
|
69357
|
-
function settingsEnv(settings2) {
|
|
69358
|
-
return settings2.rolloutChannel === void 0 ? {} : { HEADROOM_ROLLOUT_CHANNEL: settings2.rolloutChannel };
|
|
69359
|
-
}
|
|
69360
|
-
function hashSettings(settings2) {
|
|
69361
|
-
return (0, import_node_crypto14.createHash)("sha256").update(JSON.stringify([...settingsArgs(settings2), JSON.stringify(settingsEnv(settings2))])).digest("hex");
|
|
69362
|
-
}
|
|
69363
|
-
|
|
69364
|
-
// src/headroom/supervisor.ts
|
|
69365
|
-
function resolveSupervisorConfig(configured) {
|
|
69366
|
-
return {
|
|
69367
|
-
source: configured.source ?? HEADROOM_DEFAULT_SOURCE,
|
|
69368
|
-
idleShutdownMinutes: configured.idleShutdownMinutes ?? HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES,
|
|
69369
|
-
settings: settingsOf(configured)
|
|
69370
|
-
};
|
|
69371
|
-
}
|
|
69372
|
-
var HEADROOM_BACKOFF_BASE_MS = 500;
|
|
69373
|
-
var HEADROOM_BACKOFF_CAP_MS = 3e4;
|
|
69374
|
-
var HEADROOM_START_RETRY_BUDGET = 5;
|
|
69375
|
-
var HEADROOM_READY_TIMEOUT_MS = 15e3;
|
|
69376
|
-
var HEADROOM_POLL_MS = 1e3;
|
|
69377
|
-
var MS_PER_MINUTE2 = 6e4;
|
|
69378
|
-
var STOP_POLL_MS = 100;
|
|
69379
|
-
var TERM_GRACE_MS = 1500;
|
|
69380
|
-
var KILL_GRACE_MS = 1500;
|
|
69381
|
-
function stopSupervisedProcess(pid, primitives) {
|
|
69382
|
-
const send = (signal) => {
|
|
69383
|
-
try {
|
|
69384
|
-
primitives.signal(pid, signal);
|
|
69385
|
-
} catch {
|
|
69386
|
-
}
|
|
69387
|
-
};
|
|
69388
|
-
send("SIGTERM");
|
|
69389
|
-
if (awaitExit(pid, primitives, TERM_GRACE_MS)) {
|
|
69390
|
-
return "exited-on-term";
|
|
69391
|
-
}
|
|
69392
|
-
send("SIGKILL");
|
|
69393
|
-
if (awaitExit(pid, primitives, KILL_GRACE_MS)) {
|
|
69394
|
-
return "killed";
|
|
69395
|
-
}
|
|
69396
|
-
return "still-running";
|
|
69397
|
-
}
|
|
69398
|
-
function awaitExit(pid, primitives, budgetMs) {
|
|
69399
|
-
const deadline = primitives.now() + budgetMs;
|
|
69400
|
-
while (primitives.isRunning(pid)) {
|
|
69401
|
-
if (primitives.now() >= deadline) {
|
|
69402
|
-
return false;
|
|
69403
|
-
}
|
|
69404
|
-
primitives.waitMs(STOP_POLL_MS);
|
|
69405
|
-
}
|
|
69406
|
-
return true;
|
|
69407
|
-
}
|
|
69408
|
-
function backoffForAttempt(attempt) {
|
|
69409
|
-
return Math.min(HEADROOM_BACKOFF_CAP_MS, HEADROOM_BACKOFF_BASE_MS * 2 ** (attempt - 1));
|
|
69410
|
-
}
|
|
69411
|
-
function versionSatisfies(version2, source) {
|
|
69412
|
-
if (version2 === void 0) {
|
|
69413
|
-
return false;
|
|
69414
|
-
}
|
|
69415
|
-
const specifier = /==|>=|<=|!=|>|<|~=/.exec(source);
|
|
69416
|
-
if (specifier === null) {
|
|
69417
|
-
return true;
|
|
69418
|
-
}
|
|
69419
|
-
const installed = parseVersion(version2);
|
|
69420
|
-
const wanted = parseVersion(source.slice(specifier.index + specifier[0].length));
|
|
69421
|
-
if (installed === void 0 || wanted === void 0) {
|
|
69422
|
-
return true;
|
|
69423
|
-
}
|
|
69424
|
-
const cmp = compareVersions2(installed, wanted);
|
|
69425
|
-
switch (specifier[0]) {
|
|
69426
|
-
case "==":
|
|
69427
|
-
return cmp === 0;
|
|
69428
|
-
case "!=":
|
|
69429
|
-
return cmp !== 0;
|
|
69430
|
-
case ">=":
|
|
69431
|
-
return cmp >= 0;
|
|
69432
|
-
case "<=":
|
|
69433
|
-
return cmp <= 0;
|
|
69434
|
-
case ">":
|
|
69435
|
-
return cmp > 0;
|
|
69436
|
-
case "<":
|
|
69437
|
-
return cmp < 0;
|
|
69438
|
-
case "~=":
|
|
69439
|
-
return compareVersions2(installed.slice(0, Math.max(0, wanted.length - 1)), wanted.slice(0, Math.max(0, wanted.length - 1))) === 0 && cmp >= 0;
|
|
69440
|
-
default:
|
|
69441
|
-
return true;
|
|
69442
|
-
}
|
|
69443
|
-
}
|
|
69444
|
-
function parseVersion(input2) {
|
|
69445
|
-
const match = /(\d+)(\.\d+)*/.exec(input2);
|
|
69446
|
-
if (match === null) {
|
|
69447
|
-
return void 0;
|
|
69448
|
-
}
|
|
69449
|
-
return match[0].split(".").map((part) => Number.parseInt(part, 10));
|
|
69450
|
-
}
|
|
69451
|
-
function compareVersions2(a2, b) {
|
|
69452
|
-
for (let index = 0; index < Math.max(a2.length, b.length); index += 1) {
|
|
69453
|
-
const left = a2[index] ?? 0;
|
|
69454
|
-
const right = b[index] ?? 0;
|
|
69455
|
-
if (left !== right) {
|
|
69456
|
-
return left - right;
|
|
69457
|
-
}
|
|
69458
|
-
}
|
|
69459
|
-
return 0;
|
|
69460
|
-
}
|
|
69461
|
-
var HEADROOM_SUPERVISOR_STILL_RUNNING = -1;
|
|
69462
|
-
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
69463
|
-
const { fs: fs19, paths } = ports;
|
|
69464
|
-
let config2 = initialConfig;
|
|
69465
|
-
const previousState = readHeadroomState(fs19, paths.headroomStateFile);
|
|
69466
|
-
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
69467
|
-
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
69468
|
-
return 0;
|
|
69469
|
-
}
|
|
69470
|
-
let installedSource = previousState?.installedSource;
|
|
69471
|
-
const ownsState = () => {
|
|
69472
|
-
const owner = readHeadroomState(fs19, paths.headroomStateFile)?.supervisorPid;
|
|
69473
|
-
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
69474
|
-
};
|
|
69475
|
-
const writeOwnState = (state) => {
|
|
69476
|
-
if (!ownsState()) {
|
|
69477
|
-
return false;
|
|
69478
|
-
}
|
|
69479
|
-
writeHeadroomState(fs19, paths.headroomStateFile, state);
|
|
69480
|
-
return true;
|
|
69481
|
-
};
|
|
69482
|
-
const fail = (message) => {
|
|
69483
|
-
if (writeOwnState({ lastError: message })) {
|
|
69484
|
-
fs19.removeRecursive(paths.headroomLockFile);
|
|
69485
|
-
}
|
|
69486
|
-
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
69487
|
-
return 1;
|
|
69488
|
-
};
|
|
69489
|
-
const ensureInstalled = () => {
|
|
69490
|
-
const version3 = ports.headroomVersion();
|
|
69491
|
-
const versionOk = version3 !== void 0 && versionSatisfies(version3, config2.source);
|
|
69492
|
-
const pinned = pinnedGitCommit(config2.source);
|
|
69493
|
-
const commitOk = pinned === void 0 || ports.installedCommit() === pinned;
|
|
69494
|
-
if (versionOk && commitOk && (installedSource === void 0 || installedSource === config2.source)) {
|
|
69495
|
-
installedSource = config2.source;
|
|
69496
|
-
return true;
|
|
69497
|
-
}
|
|
69498
|
-
ports.log(`agent-shim headroom supervisor: installing headroom from ${config2.source}`);
|
|
69499
|
-
const result = ports.install(config2.source);
|
|
69500
|
-
if (!result.ok) {
|
|
69501
|
-
return false;
|
|
69502
|
-
}
|
|
69503
|
-
installedSource = config2.source;
|
|
69504
|
-
return true;
|
|
69505
|
-
};
|
|
69506
|
-
const socket = prepareHeadroomSocket(fs19, ports.socketTrust, paths, ports.ownPid);
|
|
69507
|
-
if (socket.refused !== void 0) {
|
|
69508
|
-
return fail(socket.refused);
|
|
69509
|
-
}
|
|
69510
|
-
const { socketPath } = socket;
|
|
69511
|
-
pruneStaleHeadroomSockets(fs19, paths, ports.isRunning);
|
|
69512
|
-
if (!ensureInstalled()) {
|
|
69513
|
-
return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
|
|
69514
|
-
}
|
|
69515
|
-
const version2 = ports.headroomVersion() ?? "unknown";
|
|
69516
|
-
writeOwnState({ supervisorPid: ports.ownPid, version: version2, installedSource });
|
|
69517
|
-
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${allowlistOf(ports).join(", ")}]`);
|
|
69518
|
-
const orphanPid = previousState?.headroomPid;
|
|
69519
|
-
if (orphanPid !== void 0 && ports.isRunning(orphanPid)) {
|
|
69520
|
-
ports.log(`agent-shim headroom supervisor: stopping daemon pid ${String(orphanPid)} left behind by the previous supervisor`);
|
|
69521
|
-
ports.stopProcess(orphanPid);
|
|
69522
|
-
}
|
|
69523
|
-
let headroomPid;
|
|
69524
|
-
let runningHash;
|
|
69525
|
-
let runningSettingsHash;
|
|
69526
|
-
let consecutiveFailures = 0;
|
|
69527
|
-
let idleSince;
|
|
69528
|
-
let superseded = false;
|
|
69529
|
-
let ticks = 0;
|
|
69530
|
-
for (; ; ) {
|
|
69531
|
-
if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
|
|
69532
|
-
return HEADROOM_SUPERVISOR_STILL_RUNNING;
|
|
69533
|
-
}
|
|
69534
|
-
ticks += 1;
|
|
69535
|
-
config2 = ports.readConfig();
|
|
69536
|
-
const settingsHash = hashSettings(config2.settings);
|
|
69537
|
-
const allowlist = allowlistOf(ports);
|
|
69538
|
-
const allowlistHash = hashAllowlist(allowlist);
|
|
69539
|
-
pruneDeadSessions(fs19, paths.headroomSessionsDir, ports.isRunning);
|
|
69540
|
-
const ownsNow = ownsState();
|
|
69541
|
-
if (!ownsNow && !superseded) {
|
|
69542
|
-
ports.log("agent-shim headroom supervisor: another supervisor now owns the state file; serving this daemon's own sessions until they end");
|
|
69543
|
-
}
|
|
69544
|
-
superseded = !ownsNow;
|
|
69545
|
-
const crashed = headroomPid !== void 0 && !ports.isRunning(headroomPid);
|
|
69546
|
-
if (headroomPid === void 0 || crashed) {
|
|
69547
|
-
if (crashed) {
|
|
69548
|
-
ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} died`);
|
|
69549
|
-
headroomPid = void 0;
|
|
69550
|
-
runningHash = void 0;
|
|
69551
|
-
runningSettingsHash = void 0;
|
|
69552
|
-
writeOwnState({
|
|
69553
|
-
supervisorPid: ports.ownPid,
|
|
69554
|
-
version: version2,
|
|
69555
|
-
installedSource
|
|
69556
|
-
});
|
|
69557
|
-
}
|
|
69558
|
-
if (consecutiveFailures >= HEADROOM_START_RETRY_BUDGET) {
|
|
69559
|
-
return fail(`headroom failed to become ready ${String(consecutiveFailures)} times in a row; giving up`);
|
|
69560
|
-
}
|
|
69561
|
-
if (installedSource !== config2.source && !ensureInstalled()) {
|
|
69562
|
-
return fail(`could not install headroom from ${config2.source}: install failed (is uv installed and on PATH?)`);
|
|
69563
|
-
}
|
|
69564
|
-
const pid = ports.spawnHeadroom(socketPath, allowlist, config2.settings);
|
|
69565
|
-
const ready = await waitUntilReady(ports, socketPath);
|
|
69566
|
-
if (ready) {
|
|
69567
|
-
consecutiveFailures = 0;
|
|
69568
|
-
headroomPid = pid;
|
|
69569
|
-
runningHash = allowlistHash;
|
|
69570
|
-
runningSettingsHash = settingsHash;
|
|
69571
|
-
const recorded = writeOwnState({
|
|
69572
|
-
supervisorPid: ports.ownPid,
|
|
69573
|
-
headroomPid: pid,
|
|
69574
|
-
socketPath,
|
|
69575
|
-
version: version2,
|
|
69576
|
-
allowlistHash,
|
|
69577
|
-
settingsHash,
|
|
69578
|
-
installedSource: config2.source
|
|
69579
|
-
});
|
|
69580
|
-
if (recorded) {
|
|
69581
|
-
fs19.removeRecursive(paths.headroomLockFile);
|
|
69582
|
-
}
|
|
69583
|
-
idleSince = void 0;
|
|
69584
|
-
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on unix socket ${socketPath}`);
|
|
69585
|
-
} else {
|
|
69586
|
-
ports.stopProcess(pid);
|
|
69587
|
-
consecutiveFailures += 1;
|
|
69588
|
-
ports.log(
|
|
69589
|
-
`agent-shim headroom supervisor: headroom did not become ready on unix socket ${socketPath} (attempt ${String(consecutiveFailures)} of ${String(HEADROOM_START_RETRY_BUDGET)})`
|
|
69590
|
-
);
|
|
69591
|
-
await ports.sleep(backoffForAttempt(consecutiveFailures));
|
|
69592
|
-
continue;
|
|
69593
|
-
}
|
|
69594
|
-
} else {
|
|
69595
|
-
if (runningHash !== allowlistHash || runningSettingsHash !== settingsHash || installedSource !== config2.source) {
|
|
69596
|
-
if (sessionsForSupervisor(fs19, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
69597
|
-
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
69598
|
-
ports.stopProcess(headroomPid);
|
|
69599
|
-
headroomPid = void 0;
|
|
69600
|
-
runningHash = void 0;
|
|
69601
|
-
runningSettingsHash = void 0;
|
|
69602
|
-
continue;
|
|
69603
|
-
}
|
|
69604
|
-
}
|
|
69605
|
-
const sessions = sessionsForSupervisor(fs19, paths.headroomSessionsDir, ports.ownPid);
|
|
69606
|
-
if (sessions.length === 0) {
|
|
69607
|
-
idleSince ??= ports.now();
|
|
69608
|
-
const idleMs = ports.now() - idleSince;
|
|
69609
|
-
if (idleMs >= config2.idleShutdownMinutes * MS_PER_MINUTE2) {
|
|
69610
|
-
ports.log(
|
|
69611
|
-
`agent-shim headroom supervisor: no sessions for ${String(config2.idleShutdownMinutes)} minute(s); stopping headroom and exiting`
|
|
69612
|
-
);
|
|
69613
|
-
ports.stopProcess(headroomPid);
|
|
69614
|
-
writeOwnState({ version: version2 });
|
|
69615
|
-
return 0;
|
|
69616
|
-
}
|
|
69617
|
-
} else {
|
|
69618
|
-
idleSince = void 0;
|
|
69619
|
-
}
|
|
69620
|
-
}
|
|
69621
|
-
await ports.sleep(HEADROOM_POLL_MS);
|
|
69622
|
-
}
|
|
69623
|
-
}
|
|
69624
|
-
function currentHeadroomAllowlist(fs19, paths) {
|
|
69625
|
-
const providers = readAllProviders(fs19, paths.providersDir).map((entry) => entry.provider);
|
|
69626
|
-
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(fs19, paths.frontdoorStateFile))));
|
|
69627
|
-
}
|
|
69628
|
-
function allowlistOf(ports) {
|
|
69629
|
-
return currentHeadroomAllowlist(ports.fs, ports.paths);
|
|
69630
|
-
}
|
|
69631
|
-
async function waitUntilReady(ports, socketPath) {
|
|
69632
|
-
const deadline = ports.now() + HEADROOM_READY_TIMEOUT_MS;
|
|
69633
|
-
for (; ; ) {
|
|
69634
|
-
if (await ports.ready(socketPath)) {
|
|
69635
|
-
return true;
|
|
69636
|
-
}
|
|
69637
|
-
if (ports.now() >= deadline) {
|
|
69638
|
-
return false;
|
|
69639
|
-
}
|
|
69640
|
-
await ports.sleep(HEADROOM_POLL_MS);
|
|
69641
|
-
}
|
|
69642
|
-
}
|
|
69643
|
-
|
|
69644
69680
|
// src/headroom/commands.ts
|
|
69645
69681
|
function collectHeadroomStatus(fsPort, paths, isRunning) {
|
|
69646
69682
|
const state = readHeadroomState(fsPort, paths.headroomStateFile) ?? {};
|
|
@@ -71028,7 +71064,7 @@ function prepareLaunch(params) {
|
|
|
71028
71064
|
let headroom;
|
|
71029
71065
|
const headroomPort = params.headroom;
|
|
71030
71066
|
if (resolvedFlags.headroom && headroomPort !== void 0) {
|
|
71031
|
-
headroom = headroomPort.ensure();
|
|
71067
|
+
headroom = headroomPort.ensure({ routesProvider: resolvedProvider !== void 0 });
|
|
71032
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}`;
|
|
71033
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})`);
|
|
71034
71070
|
} else if (resolvedFlags.headroom) {
|
|
@@ -71114,7 +71150,7 @@ function realPrepareLaunchParams(paths, options) {
|
|
|
71114
71150
|
fs: realFsPort,
|
|
71115
71151
|
proc: options.proc,
|
|
71116
71152
|
log: options.log,
|
|
71117
|
-
resolveClaudeBinary: realResolveClaudeBinary(
|
|
71153
|
+
resolveClaudeBinary: realResolveClaudeBinary(resolveOwnBinaryCheck(paths, realContentSourcePath())),
|
|
71118
71154
|
farm: farm.runtime,
|
|
71119
71155
|
headroom: realHeadroomPort(paths, { spawnDaemon: options.spawnDaemon, cwd: farm.runtime.cwd }),
|
|
71120
71156
|
frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
|