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 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 import_node_path7 = __toESM(require("node:path"), 1);
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 import_node_crypto3 = require("node:crypto");
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 import_node_path6 = __toESM(require("node:path"), 1);
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 (excluding this tool's own install directory). Install Claude Code, or set the versions directory / PATH correctly, then try again.`
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
- writeSession(ports.fs, paths.headroomSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), supervisorPid: state.supervisorPid });
55518
- return { socketPath: state.socketPath };
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, import_node_crypto3.createHash)("sha256").update(import_node_fs3.default.readFileSync(filePath)).digest("hex");
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("~/") ? import_node_path6.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
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(import_node_path6.default.dirname(logPath), { recursive: true });
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 = import_node_path6.default.join(dir, entry.name);
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 = import_node_path6.default.join(dir, name);
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 : import_node_path6.default.resolve(env.cwd, env.argv1);
55950
- const candidateDir = import_node_path6.default.dirname(candidate);
55951
- const candidateDirOnPath = env.pathDirs.some((dir) => import_node_path6.default.resolve(dir) === candidateDir);
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, import_node_path6.default.basename(candidate), env.findExecutableInDir);
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(import_node_path6.default.delimiter).filter((dir) => dir !== ""),
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(ownInstallDirs) {
56503
+ function realResolveClaudeBinary(isOwnBinary) {
55974
56504
  return () => discoverClaudeBinary({
55975
56505
  listVersionsDir,
55976
- pathDirs: (process.env.PATH ?? "").split(import_node_path6.default.delimiter).filter((dir) => dir !== ""),
56506
+ pathDirs: (process.env.PATH ?? "").split(import_node_path8.default.delimiter).filter((dir) => dir !== ""),
55977
56507
  findExecutableInDir,
55978
- ownInstallDirs: [...ownInstallDirs]
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 resolveOwnInstallDirs(paths, ownExecutablePath) {
56021
- const dirs = [import_node_path7.default.dirname(ownExecutablePath)];
56550
+ function resolveOwnBinaryCheck(paths, contentSourcePath) {
56022
56551
  const state = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
56023
- if (state !== void 0) {
56024
- dirs.push(import_node_path7.default.dirname(state.targetPath));
56025
- }
56026
- return dirs;
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 import_node_path7.default.join(dir ?? import_node_path7.default.dirname(ownExecutablePath), claudeTargetFilename(ownExecutablePath));
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(import_node_path7.default.dirname(targetPath), { recursive: true });
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 && import_node_path7.default.resolve(state.targetPath) === targetPath;
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 ? import_node_path7.default.join(params.dir, claudeTargetFilename(params.ownExecutablePath)) : state?.targetPath ?? resolveClaudeTargetPath(params.ownExecutablePath);
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 && import_node_path7.default.resolve(state.targetPath) === targetPath;
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 = import_node_path7.default.resolve(params.targetDir);
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 import_node_path7.default.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
56656
+ return import_node_path9.default.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
56111
56657
  }
56112
- return params.pathDirs.some((dir) => import_node_path7.default.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
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: import_node_path7.default.resolve(options.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(import_node_path7.default.delimiter).filter((dir) => dir !== ""),
56136
- targetDir: import_node_path7.default.dirname(result.targetPath),
56137
- targetFilename: import_node_path7.default.basename(result.targetPath),
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: ${import_node_path7.default.dirname(result.targetPath)} is not on PATH \u2014 add it, or use \`agent-shim run\` instead.`);
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 ${import_node_path7.default.dirname(result.targetPath)} ahead of it on PATH.`
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: import_node_path7.default.resolve(options.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 import_node_path18 = __toESM(require("node:path"), 1);
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 import_node_path11 = __toESM(require("node:path"), 1);
58027
+ var import_node_path13 = __toESM(require("node:path"), 1);
57482
58028
 
57483
58029
  // src/launcher/identity.ts
57484
- var import_node_path8 = __toESM(require("node:path"), 1);
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(import_node_path8.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs19.readConfigFile);
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 import_node_path9 = __toESM(require("node:path"), 1);
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 import_node_path9.default.join(paths.configProfilesDir, `${name}.json`);
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 import_node_crypto4 = require("node:crypto");
57726
- var import_node_path10 = __toESM(require("node:path"), 1);
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 import_node_path10.default.join(dir, `.${identity}.lock`);
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, import_node_crypto4.randomUUID)();
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 import_node_path11.default.join(paths.identitiesDir, name, "identity.json");
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 === import_node_path11.default.basename(identityLockPath("", name)) || entry.startsWith(`.${name}.scratch.`) || entry.startsWith(`.${name}.previous.`);
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(import_node_path11.default.join(paths.identitiesDir, entry), { recursive: true, force: true });
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 import_node_path14 = __toESM(require("node:path"), 1);
58593
+ var import_node_path16 = __toESM(require("node:path"), 1);
58048
58594
 
58049
58595
  // src/pathNorm.ts
58050
- var import_node_path12 = __toESM(require("node:path"), 1);
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 import_node_path12.default.join(home, value.slice(2));
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 import_node_path12.default.resolve(expandTilde(rulePath, home));
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(import_node_path12.default.sep) ? ancestor : `${ancestor}${import_node_path12.default.sep}`;
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 import_node_path13 = __toESM(require("node:path"), 1);
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 = import_node_path13.default.resolve(options.limit ?? options.home);
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 = import_node_path13.default.resolve(cwd);
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 = import_node_path13.default.dirname(current);
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 = import_node_path14.default.join(params.paths.configProfilesDir, `${name}.json`);
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(import_node_path14.default.join(dir, PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(import_node_path14.default.join(dir, LEGACY_PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read);
58261
- const portableLocal = loadConfigFile(import_node_path14.default.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(import_node_path14.default.join(dir, LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read);
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 import_node_path16 = __toESM(require("node:path"), 1);
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 import_node_path15 = __toESM(require("node:path"), 1);
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) => import_node_path15.default.join(params.facts.claudeHome, 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(import_node_path16.default.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs19.readFileUtf8(import_node_path16.default.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
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 = import_node_path16.default.join(params.claudeHome, rel);
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 = import_node_path16.default.join(root, rel);
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(import_node_path16.default.join(farmRoot, name))?.kind === "dir").sort();
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 = import_node_path16.default.join(claudeHome, entry.rel);
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(import_node_path16.default.join(params.previousRoot, name));
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(import_node_path16.default.join(params.farmRoot, name)) !== void 0) {
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(import_node_path16.default.join(params.previousRoot, name));
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(import_node_path16.default.join(params.previousRoot, name), import_node_path16.default.join(params.farmRoot, name));
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 = import_node_path16.default.join(params.scratchRoot, entry.rel);
59856
+ const absolute = import_node_path18.default.join(params.scratchRoot, entry.rel);
59311
59857
  if (entry.kind === "link") {
59312
- params.fs.mkdirp(import_node_path16.default.dirname(absolute));
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
- import_node_path16.default.join(params.scratchRoot, FARM_MANIFEST_FILENAME),
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(import_node_path16.default.dirname(params.farmRoot));
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(import_node_path16.default.join(params.identitiesDir, name));
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(import_node_path16.default.join(params.identitiesDir, first), params.farmRoot);
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 = import_node_path16.default.join(params.identitiesDir, name);
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 = import_node_path16.default.join(params.identitiesDir, params.identity);
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 = import_node_path16.default.join(params.farmRoot, action.rel);
59452
- const canonical = import_node_path16.default.join(params.claudeHome, action.rel);
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(import_node_path16.default.dirname(canonical));
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(import_node_path16.default.dirname(canonical));
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 = import_node_path16.default.join(params.identitiesDir, params.identity);
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 = import_node_path16.default.join(params.identitiesDir, `.${params.identity}.scratch.${params.uniqueSuffix}`);
59566
- const previousRoot = import_node_path16.default.join(params.identitiesDir, `.${params.identity}.previous.${params.uniqueSuffix}`);
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 import_node_path17 = __toESM(require("node:path"), 1);
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 = import_node_path17.default.join(home, HOME_DIRNAME);
59632
- const legacy = import_node_path17.default.join(home, LEGACY_HOME_DIRNAME);
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 import_node_path17.default.join(import_node_os3.default.homedir(), ".claude");
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: import_node_path17.default.join(root, "identities"),
59649
- configProfilesDir: import_node_path17.default.join(root, "config-profiles"),
59650
- providersDir: import_node_path17.default.join(root, "providers"),
59651
- directoryRulesFile: import_node_path17.default.join(root, "directory-rules.json"),
59652
- activeIdentityFile: import_node_path17.default.join(root, "active-identity"),
59653
- globalConfigFile: import_node_path17.default.join(root, "config.json"),
59654
- categoriesLocalFile: import_node_path17.default.join(root, "categories.local.json"),
59655
- claudeShimFile: import_node_path17.default.join(root, "claude-shim.json"),
59656
- headroomDir: import_node_path17.default.join(root, "headroom"),
59657
- headroomStateFile: import_node_path17.default.join(root, "headroom", `state.v${String(HEADROOM_STATE_SCHEMA_VERSION)}.json`),
59658
- headroomSocketDir: import_node_path17.default.join(root, "headroom", "run"),
59659
- headroomLockFile: import_node_path17.default.join(root, "headroom", "start.lock"),
59660
- headroomSessionsDir: import_node_path17.default.join(root, "headroom", "sessions"),
59661
- logsDir: import_node_path17.default.join(root, "logs"),
59662
- headroomLogPath: import_node_path17.default.join(root, "logs", "headroom.log"),
59663
- frontdoorDir: import_node_path17.default.join(root, "frontdoor"),
59664
- frontdoorCaDir: import_node_path17.default.join(root, "frontdoor", "ca"),
59665
- frontdoorCaCertFile: import_node_path17.default.join(root, "frontdoor", "ca", "ca.pem"),
59666
- frontdoorCaKeyFile: import_node_path17.default.join(root, "frontdoor", "ca", "ca.key"),
59667
- frontdoorCaBundlesDir: import_node_path17.default.join(root, "frontdoor", "ca", "bundles"),
59668
- frontdoorStateFile: import_node_path17.default.join(root, "frontdoor", "state.json"),
59669
- frontdoorLockFile: import_node_path17.default.join(root, "frontdoor", "start.lock"),
59670
- frontdoorControlTokenFile: import_node_path17.default.join(root, "frontdoor", "control-token"),
59671
- frontdoorSessionsDir: import_node_path17.default.join(root, "frontdoor", "sessions"),
59672
- frontdoorLogPath: import_node_path17.default.join(root, "logs", "frontdoor.log"),
59673
- usageDir: import_node_path17.default.join(root, "usage"),
59674
- usageLogDir: import_node_path17.default.join(root, "usage", "log"),
59675
- usageSnapshotsDir: import_node_path17.default.join(root, "usage", "snapshots"),
59676
- usagePicksFile: import_node_path17.default.join(root, "usage", "picks.json")
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: import_node_path18.default.join(level.dir, level.portableLocalFilename) };
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(import_node_path18.default.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME));
59852
- const hasLegacyLocal = import_node_fs8.default.existsSync(import_node_path18.default.join(dir, LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME));
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(import_node_path18.default.join(dir, PORTABLE_CONFIG_FILENAME)) || import_node_fs8.default.existsSync(import_node_path18.default.join(dir, LEGACY_PORTABLE_CONFIG_FILENAME)),
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 import_node_path20 = __toESM(require("node:path"), 1);
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 OCTAL_RADIX = 8;
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(OCTAL_RADIX)}); run \`chmod 600 ${source.file}\``,
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 import_node_path19 = __toESM(require("node:path"), 1);
61014
+ var import_node_path21 = __toESM(require("node:path"), 1);
60469
61015
  async function resolveFarmConflicts(params) {
60470
- const farmRoot = import_node_path19.default.join(params.identitiesDir, params.identity);
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) => import_node_path19.default.join(params.identitiesDir, 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(import_node_path19.default.join(previousRoot, name));
61041
+ params.fs.removeRecursive(import_node_path21.default.join(previousRoot, name));
60496
61042
  continue;
60497
61043
  }
60498
- params.fs.removeRecursive(import_node_path19.default.join(farmRoot, name));
60499
- params.fs.rename(import_node_path19.default.join(previousRoot, name), import_node_path19.default.join(farmRoot, name));
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: import_node_path20.default.join(paths.identitiesDir, entry.name),
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 ${import_node_path20.default.join(paths.identitiesDir, name)}`);
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.1",
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 import_node_path27 = __toESM(require("node:path"), 1);
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 import_node_path24 = __toESM(require("node:path"), 1);
61739
+ var import_node_path26 = __toESM(require("node:path"), 1);
61194
61740
 
61195
61741
  // src/usage/account.ts
61196
- var import_node_path21 = __toESM(require("node:path"), 1);
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 import_node_path21.default.join(identitiesDir, identity, CLAUDE_JSON);
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 import_node_path22 = __toESM(require("node:path"), 1);
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(import_node_path22.default.join(logDir, segment.name));
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 import_node_path22.default.join(snapshotsDir, `${identity}.json`);
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 import_node_path23 = __toESM(require("node:path"), 1);
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(import_node_path23.default.join(logDir, segment.name));
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(import_node_path23.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record2)}
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(import_node_path24.default.dirname(picksFile));
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 import_node_path25 = __toESM(require("node:path"), 1);
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 import_node_path25.default.join(paths.providersDir, `${name}.json`);
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 = import_node_path25.default.join(providersDir, `${name}.json`);
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 import_node_path26 = __toESM(require("node:path"), 1);
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 : import_node_path26.default.join(paths.identitiesDir, identityDecision.name);
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(import_node_path26.default.join(claudeHome, "settings.json")),
63255
- "settings.local.json": realFsPort.readFileUtf8(import_node_path26.default.join(claudeHome, "settings.local.json"))
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() : import_node_path27.default.resolve(pathArg);
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 import_node_crypto6 = require("node:crypto");
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 import_node_path29 = __toESM(require("node:path"), 1);
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 import_node_crypto5 = require("node:crypto");
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, import_node_crypto5.createHash)("sha256").update(`agent-shim codex session
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 : import_node_path29.default.join(home, ".codex");
64094
+ return fromEnv !== void 0 && fromEnv !== "" ? fromEnv : import_node_path30.default.join(home, ".codex");
63662
64095
  }
63663
64096
  function codexUsageSnapshotPath() {
63664
- return import_node_path29.default.join(resolveClaudeHome(), "codex-quota.json");
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(import_node_path29.default.dirname(target), { recursive: true });
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(import_node_path29.default.join(codexHome(process.env, import_node_os6.default.homedir()), "auth.json"), {
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, import_node_crypto6.randomUUID)()}`
64141
+ tempSuffix: `${String(process.pid)}.${(0, import_node_crypto7.randomUUID)()}`
63709
64142
  });
63710
64143
  return {
63711
- upstream: { fetch: upstreamFetch, auth, timers: realTimers, randomId: import_node_crypto6.randomUUID },
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 import_node_crypto11 = require("node:crypto");
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 import_node_crypto7 = require("node:crypto");
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, import_node_crypto7.createHash)("sha256").update(token, "utf8").digest();
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, import_node_crypto7.timingSafeEqual)(presentedDigest, digest(token));
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 import_node_crypto9 = require("node:crypto");
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 import_node_crypto8 = require("node:crypto");
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, import_node_crypto8.createHash)("sha1").update(publicKey.export({ type: "pkcs1", format: "der" })).digest();
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, import_node_crypto8.randomBytes)(SERIAL_NUMBER_BYTES);
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, import_node_crypto8.sign)("sha256", tbs, spec.signingKey);
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, import_node_crypto8.generateKeyPairSync)("rsa", { modulusLength: RSA_MODULUS_BITS });
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 import_node_crypto8.X509Certificate(ca.certPem);
64382
- const caPrivateKey = (0, import_node_crypto8.createPrivateKey)(ca.keyPem);
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 MS_PER_MINUTE = 6e4;
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 * MS_PER_MINUTE) {
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 import_node_crypto9.X509Certificate(ca.certPem);
64646
- (0, import_node_crypto9.createPrivateKey)(ca.keyPem);
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 import_node_crypto10 = require("node:crypto");
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, import_node_crypto10.createHash)("sha256").update(name).digest("hex").slice(0, TOOL_NAME_HASH_CHARS);
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
- authorization: singleHeader(request7.headers, "authorization"),
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.authorization = facts.authorization ?? entry.authorization;
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.authorization, anthropicVersion: entry.anthropicVersion, anthropicClientPlatform: entry.anthropicClientPlatform };
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, import_node_crypto11.randomUUID)();
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, import_node_crypto11.randomUUID)(),
67751
- custody: createCredentialCustody(() => (0, import_node_crypto11.randomUUID)()),
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: import_node_crypto11.randomUUID }, sessionId, text2);
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, import_node_crypto11.randomUUID)();
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(resolveOwnInstallDirs(paths, ownExecutablePath))();
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 import_node_crypto12 = require("node:crypto");
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, import_node_crypto12.randomUUID)();
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 import_node_crypto13 = require("node:crypto");
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, import_node_crypto13.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
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(resolveOwnInstallDirs(paths, realOwnExecutablePath())),
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),