agent-shim 8.43.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2643,7 +2643,7 @@ var init_package = __esm({
2643
2643
  "package.json"() {
2644
2644
  package_default = {
2645
2645
  name: "agent-shim",
2646
- version: "8.43.0",
2646
+ version: "9.0.0",
2647
2647
  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.",
2648
2648
  license: "MIT",
2649
2649
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -2761,10 +2761,36 @@ function readHeadroomState(fs12, stateFile) {
2761
2761
  }
2762
2762
  }
2763
2763
  function writeHeadroomState(fs12, stateFile, state) {
2764
- fs12.mkdirp(import_node_path10.default.dirname(stateFile));
2764
+ fs12.mkdirp(import_node_path11.default.dirname(stateFile));
2765
2765
  fs12.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
2766
2766
  `);
2767
2767
  }
2768
+ function resolveServingHeadroomState(fs12, files, isRunning) {
2769
+ const current = readHeadroomState(fs12, files.stateFile);
2770
+ if (current !== void 0) {
2771
+ return { path: files.stateFile, state: current };
2772
+ }
2773
+ const legacy = readHeadroomState(fs12, files.legacyStateFile);
2774
+ if (legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid)) {
2775
+ return { path: files.legacyStateFile, state: legacy };
2776
+ }
2777
+ return void 0;
2778
+ }
2779
+ function migrateHeadroomState(fs12, files, isRunning) {
2780
+ const legacy = readHeadroomState(fs12, files.legacyStateFile);
2781
+ const legacyLive = legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid);
2782
+ const current = readHeadroomState(fs12, files.stateFile);
2783
+ if (current !== void 0 || legacyLive) {
2784
+ if (!legacyLive && fs12.readFileUtf8(files.legacyStateFile) !== void 0) {
2785
+ fs12.removeRecursive(files.legacyStateFile);
2786
+ }
2787
+ return;
2788
+ }
2789
+ if (legacy !== void 0) {
2790
+ writeHeadroomState(fs12, files.stateFile, legacy);
2791
+ }
2792
+ fs12.removeRecursive(files.legacyStateFile);
2793
+ }
2768
2794
  function headroomAllowlist(providers) {
2769
2795
  const urls = /* @__PURE__ */ new Set([HEADROOM_ANTHROPIC_UPSTREAM]);
2770
2796
  for (const provider of providers) {
@@ -2789,7 +2815,7 @@ function readAllProviders(fs12, providersDir) {
2789
2815
  continue;
2790
2816
  }
2791
2817
  try {
2792
- const parsed = parseJson(fs12.readFileUtf8(import_node_path10.default.join(providersDir, name)), ProviderSchema);
2818
+ const parsed = parseJson(fs12.readFileUtf8(import_node_path11.default.join(providersDir, name)), ProviderSchema);
2793
2819
  if (parsed !== void 0) {
2794
2820
  result.push({ name: name.slice(0, -".json".length), provider: parsed });
2795
2821
  }
@@ -2801,11 +2827,11 @@ function readAllProviders(fs12, providersDir) {
2801
2827
  }
2802
2828
  function writeSession(fs12, sessionsDir, session) {
2803
2829
  fs12.mkdirp(sessionsDir);
2804
- fs12.writeFileUtf8(import_node_path10.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
2830
+ fs12.writeFileUtf8(import_node_path11.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
2805
2831
  `);
2806
2832
  }
2807
2833
  function removeSession(fs12, sessionsDir, pid) {
2808
- fs12.removeRecursive(import_node_path10.default.join(sessionsDir, `${String(pid)}.json`));
2834
+ fs12.removeRecursive(import_node_path11.default.join(sessionsDir, `${String(pid)}.json`));
2809
2835
  }
2810
2836
  function listSessions(fs12, sessionsDir) {
2811
2837
  const sessions = [];
@@ -2814,7 +2840,7 @@ function listSessions(fs12, sessionsDir) {
2814
2840
  continue;
2815
2841
  }
2816
2842
  try {
2817
- const parsed = parseJson(fs12.readFileUtf8(import_node_path10.default.join(sessionsDir, name)), HeadroomSessionSchema);
2843
+ const parsed = parseJson(fs12.readFileUtf8(import_node_path11.default.join(sessionsDir, name)), HeadroomSessionSchema);
2818
2844
  if (parsed !== void 0) {
2819
2845
  sessions.push(parsed);
2820
2846
  }
@@ -2844,16 +2870,15 @@ function readStartLock(fs12, lockFile) {
2844
2870
  return void 0;
2845
2871
  }
2846
2872
  }
2847
- var import_node_crypto6, import_node_path10, import_zod5, HEADROOM_ANTHROPIC_UPSTREAM, HEADROOM_STATE_SCHEMA_VERSION, HeadroomStateSchema, HeadroomSessionSchema, HeadroomLockSchema;
2873
+ var import_node_crypto6, import_node_path11, import_zod5, HEADROOM_ANTHROPIC_UPSTREAM, HeadroomStateSchema, HeadroomSessionSchema, HeadroomLockSchema;
2848
2874
  var init_state2 = __esm({
2849
2875
  "src/headroom/state.ts"() {
2850
2876
  "use strict";
2851
2877
  import_node_crypto6 = require("node:crypto");
2852
- import_node_path10 = __toESM(require("node:path"), 1);
2878
+ import_node_path11 = __toESM(require("node:path"), 1);
2853
2879
  import_zod5 = require("zod");
2854
2880
  init_schema();
2855
2881
  HEADROOM_ANTHROPIC_UPSTREAM = "https://api.anthropic.com";
2856
- HEADROOM_STATE_SCHEMA_VERSION = 2;
2857
2882
  HeadroomStateSchema = import_zod5.z.strictObject({
2858
2883
  /** The supervisor process owning the daemon. Alive means someone is keeping headroom running. */
2859
2884
  supervisorPid: import_zod5.z.number().int().positive().optional(),
@@ -2885,8 +2910,9 @@ function ensureHeadroom(params) {
2885
2910
  const deadline = ports.now() + HEADROOM_START_TIMEOUT_MS;
2886
2911
  let spawnedSupervisor = false;
2887
2912
  let awaitingAllowlist = false;
2913
+ migrateHeadroomState(ports.fs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
2888
2914
  for (; ; ) {
2889
- const state = readHeadroomState(ports.fs, paths.headroomStateFile);
2915
+ const state = resolveServingHeadroomState(ports.fs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
2890
2916
  if (state?.supervisorPid !== void 0 && ports.isRunning(state.supervisorPid)) {
2891
2917
  const daemonUp = state.socketPath !== void 0 && state.headroomPid !== void 0 && ports.isRunning(state.headroomPid);
2892
2918
  if (daemonUp && state.socketPath !== void 0) {
@@ -2989,7 +3015,7 @@ var init_settings = __esm({
2989
3015
 
2990
3016
  // src/headroom/socket.ts
2991
3017
  function headroomSocketPath(paths, supervisorPid) {
2992
- return import_node_path11.default.join(paths.headroomSocketDir, `${String(supervisorPid)}${HEADROOM_SOCKET_SUFFIX}`);
3018
+ return import_node_path12.default.join(paths.headroomSocketDir, `${String(supervisorPid)}${HEADROOM_SOCKET_SUFFIX}`);
2993
3019
  }
2994
3020
  function platformRefusal(platform) {
2995
3021
  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;
@@ -3018,7 +3044,7 @@ function verifyHeadroomSocket(socketPath, ports) {
3018
3044
  return { refused: unsupported };
3019
3045
  }
3020
3046
  const uid = ports.currentUid();
3021
- const directory = import_node_path11.default.dirname(socketPath);
3047
+ const directory = import_node_path12.default.dirname(socketPath);
3022
3048
  const refusal = ownerOnlyRefusal("socket directory", directory, ports.lstat(directory), "dir", uid) ?? ownerOnlyRefusal("socket", socketPath, ports.lstat(socketPath), "socket", uid);
3023
3049
  return refusal === void 0 ? { socketPath } : { refused: refusal };
3024
3050
  }
@@ -3048,16 +3074,16 @@ function pruneStaleHeadroomSockets(fs12, paths, isRunning) {
3048
3074
  if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
3049
3075
  continue;
3050
3076
  }
3051
- fs12.removeRecursive(import_node_path11.default.join(paths.headroomSocketDir, name));
3077
+ fs12.removeRecursive(import_node_path12.default.join(paths.headroomSocketDir, name));
3052
3078
  removed.push(name);
3053
3079
  }
3054
3080
  return removed;
3055
3081
  }
3056
- var import_node_path11, GROUP_OR_OTHER_BITS, OCTAL_RADIX, MODE_DIGITS, HEADROOM_SOCKET_SUFFIX, HEADROOM_SOCKET_NAME, UNIX_SOCKET_PATH_MAX_BYTES, PLATFORMS_WITHOUT_UNIX_SOCKETS;
3082
+ var import_node_path12, GROUP_OR_OTHER_BITS, OCTAL_RADIX, MODE_DIGITS, HEADROOM_SOCKET_SUFFIX, HEADROOM_SOCKET_NAME, UNIX_SOCKET_PATH_MAX_BYTES, PLATFORMS_WITHOUT_UNIX_SOCKETS;
3057
3083
  var init_socket = __esm({
3058
3084
  "src/headroom/socket.ts"() {
3059
3085
  "use strict";
3060
- import_node_path11 = __toESM(require("node:path"), 1);
3086
+ import_node_path12 = __toESM(require("node:path"), 1);
3061
3087
  GROUP_OR_OTHER_BITS = 63;
3062
3088
  OCTAL_RADIX = 8;
3063
3089
  MODE_DIGITS = 4;
@@ -3156,7 +3182,8 @@ function compareVersions2(a, b) {
3156
3182
  async function runSupervisor(initialConfig, ports, options = {}) {
3157
3183
  const { fs: fs12, paths } = ports;
3158
3184
  let config = initialConfig;
3159
- const previousState = readHeadroomState(fs12, paths.headroomStateFile);
3185
+ migrateHeadroomState(fs12, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
3186
+ const previousState = resolveServingHeadroomState(fs12, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
3160
3187
  if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
3161
3188
  ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
3162
3189
  return 0;
@@ -3380,7 +3407,7 @@ function realIsProcessRunning(pid) {
3380
3407
  return realIsProcessAlive(pid) && !realIsProcessZombie(pid);
3381
3408
  }
3382
3409
  function expandHome2(filePath) {
3383
- return filePath.startsWith("~/") ? import_node_path12.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
3410
+ return filePath.startsWith("~/") ? import_node_path13.default.join(import_node_os2.default.homedir(), filePath.slice(1)) : filePath;
3384
3411
  }
3385
3412
  function hasDesktopSession() {
3386
3413
  if (process.platform === "darwin") {
@@ -3424,7 +3451,7 @@ function spawnDaemonThroughScript(script) {
3424
3451
  return (paths, subcommand, logPath) => spawnDetachedDaemon({ command: process.execPath, args: [script, subcommand] }, paths, subcommand, logPath);
3425
3452
  }
3426
3453
  function spawnDetachedDaemon(invocation, paths, subcommand, logPath) {
3427
- import_node_fs2.default.mkdirSync(import_node_path12.default.dirname(logPath), { recursive: true });
3454
+ import_node_fs2.default.mkdirSync(import_node_path13.default.dirname(logPath), { recursive: true });
3428
3455
  const logFd = import_node_fs2.default.openSync(logPath, "a");
3429
3456
  try {
3430
3457
  const child = (0, import_node_child_process.spawn)(invocation.command, invocation.args, detachedDaemonSpawnOptions(logFd, { ...process.env, AGENT_SHIM_HOME: paths.root }));
@@ -3477,7 +3504,7 @@ function listVersionsDir(dir) {
3477
3504
  throw error;
3478
3505
  }
3479
3506
  return entries.filter((entry) => entry.isFile()).map((entry) => {
3480
- const fullPath = import_node_path12.default.join(dir, entry.name);
3507
+ const fullPath = import_node_path13.default.join(dir, entry.name);
3481
3508
  const stat = import_node_fs2.default.statSync(fullPath);
3482
3509
  return {
3483
3510
  name: entry.name,
@@ -3491,7 +3518,7 @@ function windowsPathExtensions(pathext) {
3491
3518
  return (pathext ?? WINDOWS_DEFAULT_PATHEXT).split(";").map((ext) => ext.trim()).filter((ext) => ext.length > 0);
3492
3519
  }
3493
3520
  function resolveExecutableCandidate(dir, name, env) {
3494
- const candidate = import_node_path12.default.join(dir, name);
3521
+ const candidate = import_node_path13.default.join(dir, name);
3495
3522
  if (env.platform === "win32") {
3496
3523
  const extensions = windowsPathExtensions(env.pathext);
3497
3524
  const alreadyHasRecognisedExtension = extensions.some((ext) => candidate.toLowerCase().endsWith(ext.toLowerCase()));
@@ -3540,13 +3567,13 @@ function resolveOwnExecutablePath(env) {
3540
3567
  if (env.argv1 !== void 0 && !env.argv1.includes("/") && !env.argv1.includes("\\")) {
3541
3568
  return searchPathForExecutable(env.pathDirs, env.argv1, env.findExecutableInDir) ?? env.execPath;
3542
3569
  }
3543
- const candidate = env.argv1 === void 0 ? env.execPath : import_node_path12.default.resolve(env.cwd, env.argv1);
3544
- const candidateDir = import_node_path12.default.dirname(candidate);
3545
- const candidateDirOnPath = env.pathDirs.some((dir) => import_node_path12.default.resolve(dir) === candidateDir);
3570
+ const candidate = env.argv1 === void 0 ? env.execPath : import_node_path13.default.resolve(env.cwd, env.argv1);
3571
+ const candidateDir = import_node_path13.default.dirname(candidate);
3572
+ const candidateDirOnPath = env.pathDirs.some((dir) => import_node_path13.default.resolve(dir) === candidateDir);
3546
3573
  if (candidateDirOnPath) {
3547
3574
  return candidate;
3548
3575
  }
3549
- const viaPath = searchPathForExecutable(env.pathDirs, import_node_path12.default.basename(candidate), env.findExecutableInDir);
3576
+ const viaPath = searchPathForExecutable(env.pathDirs, import_node_path13.default.basename(candidate), env.findExecutableInDir);
3550
3577
  return viaPath ?? candidate;
3551
3578
  }
3552
3579
  function realOwnExecutablePath() {
@@ -3554,7 +3581,7 @@ function realOwnExecutablePath() {
3554
3581
  argv1: process.argv[1],
3555
3582
  execPath: process.execPath,
3556
3583
  cwd: process.cwd(),
3557
- pathDirs: (process.env.PATH ?? "").split(import_node_path12.default.delimiter).filter((dir) => dir !== ""),
3584
+ pathDirs: (process.env.PATH ?? "").split(import_node_path13.default.delimiter).filter((dir) => dir !== ""),
3558
3585
  findExecutableInDir
3559
3586
  });
3560
3587
  }
@@ -3567,7 +3594,7 @@ function realContentSourcePath() {
3567
3594
  function realResolveClaudeBinary(isOwnBinary) {
3568
3595
  return (request4) => discoverClaudeBinary({
3569
3596
  listVersionsDir,
3570
- pathDirs: (process.env.PATH ?? "").split(import_node_path12.default.delimiter).filter((dir) => dir !== ""),
3597
+ pathDirs: (process.env.PATH ?? "").split(import_node_path13.default.delimiter).filter((dir) => dir !== ""),
3571
3598
  findExecutableInDir,
3572
3599
  isOwnBinary,
3573
3600
  ...request4?.version === void 0 ? {} : { version: request4.version }
@@ -3576,7 +3603,7 @@ function realResolveClaudeBinary(isOwnBinary) {
3576
3603
  function realInstalledClaudeVersions() {
3577
3604
  return installedVersions(listVersionsDir(defaultVersionsDir()));
3578
3605
  }
3579
- var import_node_child_process, import_node_crypto8, import_node_fs2, import_node_os2, import_node_path12, import_node_sea, realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
3606
+ var import_node_child_process, import_node_crypto8, import_node_fs2, import_node_os2, import_node_path13, import_node_sea, realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
3580
3607
  var init_realPorts = __esm({
3581
3608
  "src/realPorts.ts"() {
3582
3609
  "use strict";
@@ -3584,7 +3611,7 @@ var init_realPorts = __esm({
3584
3611
  import_node_crypto8 = require("node:crypto");
3585
3612
  import_node_fs2 = __toESM(require("node:fs"), 1);
3586
3613
  import_node_os2 = __toESM(require("node:os"), 1);
3587
- import_node_path12 = __toESM(require("node:path"), 1);
3614
+ import_node_path13 = __toESM(require("node:path"), 1);
3588
3615
  import_node_sea = require("node:sea");
3589
3616
  init_load();
3590
3617
  init_versionDiscovery();
@@ -3800,18 +3827,18 @@ function expandTilde(value, home) {
3800
3827
  return home;
3801
3828
  }
3802
3829
  if (value.startsWith("~/")) {
3803
- return import_node_path13.default.join(home, value.slice(2));
3830
+ return import_node_path14.default.join(home, value.slice(2));
3804
3831
  }
3805
3832
  return value;
3806
3833
  }
3807
3834
  function normaliseRulePath(rulePath, home) {
3808
- return import_node_path13.default.resolve(expandTilde(rulePath, home));
3835
+ return import_node_path14.default.resolve(expandTilde(rulePath, home));
3809
3836
  }
3810
- var import_node_path13;
3837
+ var import_node_path14;
3811
3838
  var init_pathNorm = __esm({
3812
3839
  "src/pathNorm.ts"() {
3813
3840
  "use strict";
3814
- import_node_path13 = __toESM(require("node:path"), 1);
3841
+ import_node_path14 = __toESM(require("node:path"), 1);
3815
3842
  }
3816
3843
  });
3817
3844
 
@@ -3820,7 +3847,7 @@ function loadCascadeInput(params) {
3820
3847
  const globalConfig = loadConfigFile(params.paths.globalConfigFile, GlobalConfigSchema, params.read);
3821
3848
  const directoryRules = loadConfigFile(params.paths.directoryRulesFile, DirectoryRulesSchema, params.read);
3822
3849
  const loadProfile = (name) => {
3823
- const filepath = import_node_path14.default.join(params.paths.configProfilesDir, `${name}.json`);
3850
+ const filepath = import_node_path15.default.join(params.paths.configProfilesDir, `${name}.json`);
3824
3851
  const loaded = loadConfigFile(filepath, ConfigProfileSchema, params.read);
3825
3852
  if (loaded === void 0) {
3826
3853
  return void 0;
@@ -3835,8 +3862,8 @@ function loadCascadeInput(params) {
3835
3862
  });
3836
3863
  const levels = [];
3837
3864
  for (const dir of dirs) {
3838
- 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);
3839
- 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);
3865
+ const portable = loadConfigFile(import_node_path15.default.join(dir, PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(import_node_path15.default.join(dir, LEGACY_PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read);
3866
+ const portableLocal = loadConfigFile(import_node_path15.default.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(import_node_path15.default.join(dir, LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read);
3840
3867
  const rules = (directoryRules?.config.rules ?? []).map((rule, index) => ({ rule, index })).filter(({ rule }) => normaliseRulePath(rule.path, params.home) === dir).map(({ rule, index }) => {
3841
3868
  const entryOrder = directoryRules?.ruleEntryOrders[index];
3842
3869
  return {
@@ -3883,11 +3910,11 @@ function readDirectorySelections(loaded) {
3883
3910
  }
3884
3911
  return { ...identity === void 0 ? {} : { identity }, ...configProfile === void 0 ? {} : { configProfile } };
3885
3912
  }
3886
- var import_node_path14, PORTABLE_CONFIG_FILENAME, PORTABLE_LOCAL_CONFIG_FILENAME;
3913
+ var import_node_path15, PORTABLE_CONFIG_FILENAME, PORTABLE_LOCAL_CONFIG_FILENAME;
3887
3914
  var init_cascade = __esm({
3888
3915
  "src/launcher/cascade.ts"() {
3889
3916
  "use strict";
3890
- import_node_path14 = __toESM(require("node:path"), 1);
3917
+ import_node_path15 = __toESM(require("node:path"), 1);
3891
3918
  init_load();
3892
3919
  init_schema();
3893
3920
  init_pathNorm();
@@ -3951,13 +3978,13 @@ function decideConfigProfile(params) {
3951
3978
  return { source: "none" };
3952
3979
  }
3953
3980
  function loadIdentity(identitiesDir, name, fs12) {
3954
- return loadConfigFile(import_node_path15.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs12.readConfigFile);
3981
+ return loadConfigFile(import_node_path16.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs12.readConfigFile);
3955
3982
  }
3956
- var import_node_path15, IDENTITY_DECISION_SOURCES, CONFIG_PROFILE_DECISION_SOURCES;
3983
+ var import_node_path16, IDENTITY_DECISION_SOURCES, CONFIG_PROFILE_DECISION_SOURCES;
3957
3984
  var init_identity = __esm({
3958
3985
  "src/launcher/identity.ts"() {
3959
3986
  "use strict";
3960
- import_node_path15 = __toESM(require("node:path"), 1);
3987
+ import_node_path16 = __toESM(require("node:path"), 1);
3961
3988
  init_load();
3962
3989
  init_schema();
3963
3990
  IDENTITY_DECISION_SOURCES = [
@@ -4153,7 +4180,7 @@ function isIdentityName(name) {
4153
4180
  return IdentitySchema.shape.name.safeParse(name).success;
4154
4181
  }
4155
4182
  function claudeJsonPath(identitiesDir, identity) {
4156
- return import_node_path16.default.join(identitiesDir, identity, CLAUDE_JSON);
4183
+ return import_node_path17.default.join(identitiesDir, identity, CLAUDE_JSON);
4157
4184
  }
4158
4185
  function readAccountMetadata(fs12, identitiesDir, identity) {
4159
4186
  if (!isIdentityName(identity)) {
@@ -4207,11 +4234,11 @@ function createAccountReader(fs12, identitiesDir) {
4207
4234
  return account;
4208
4235
  };
4209
4236
  }
4210
- var import_node_path16, CLAUDE_JSON, AccountMetadataError;
4237
+ var import_node_path17, CLAUDE_JSON, AccountMetadataError;
4211
4238
  var init_account = __esm({
4212
4239
  "src/usage/account.ts"() {
4213
4240
  "use strict";
4214
- import_node_path16 = __toESM(require("node:path"), 1);
4241
+ import_node_path17 = __toESM(require("node:path"), 1);
4215
4242
  init_cliError();
4216
4243
  init_schema();
4217
4244
  init_schema2();
@@ -4677,7 +4704,7 @@ function readUsageLog(fs12, logDir, options = {}) {
4677
4704
  if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
4678
4705
  continue;
4679
4706
  }
4680
- const contents = fs12.readFileUtf8(import_node_path17.default.join(logDir, segment.name));
4707
+ const contents = fs12.readFileUtf8(import_node_path18.default.join(logDir, segment.name));
4681
4708
  if (contents === void 0) {
4682
4709
  continue;
4683
4710
  }
@@ -4711,7 +4738,7 @@ function snapshotPath(snapshotsDir, identity) {
4711
4738
  if (!isIdentityName(identity)) {
4712
4739
  throw new Error(`"${identity}" is not a valid identity name.`);
4713
4740
  }
4714
- return import_node_path17.default.join(snapshotsDir, `${identity}.json`);
4741
+ return import_node_path18.default.join(snapshotsDir, `${identity}.json`);
4715
4742
  }
4716
4743
  function readUsageSnapshot(fs12, snapshotsDir, identity) {
4717
4744
  const file = snapshotPath(snapshotsDir, identity);
@@ -4744,11 +4771,11 @@ function listUsageSnapshots(fs12, snapshotsDir) {
4744
4771
  return snapshot === void 0 ? [] : [snapshot];
4745
4772
  }).sort((left, right) => left.identity.localeCompare(right.identity));
4746
4773
  }
4747
- var import_node_path17, SEGMENT_RE, DAY_MS, UsageSnapshotError;
4774
+ var import_node_path18, SEGMENT_RE, DAY_MS, UsageSnapshotError;
4748
4775
  var init_read = __esm({
4749
4776
  "src/usage/read.ts"() {
4750
4777
  "use strict";
4751
- import_node_path17 = __toESM(require("node:path"), 1);
4778
+ import_node_path18 = __toESM(require("node:path"), 1);
4752
4779
  init_account();
4753
4780
  init_schema2();
4754
4781
  SEGMENT_RE = /^(\d{4}-\d{2}-\d{2})\.(\d+)\.jsonl$/;
@@ -4769,7 +4796,7 @@ function pruneUsageLog(fs12, logDir, nowMs) {
4769
4796
  const cutoff = nowMs - USAGE_RETENTION_MS;
4770
4797
  for (const segment of listLogSegments(fs12, logDir)) {
4771
4798
  if (segment.endsAt <= cutoff) {
4772
- fs12.removeRecursive(import_node_path18.default.join(logDir, segment.name));
4799
+ fs12.removeRecursive(import_node_path19.default.join(logDir, segment.name));
4773
4800
  }
4774
4801
  }
4775
4802
  }
@@ -4851,7 +4878,7 @@ function createUsageStore(deps) {
4851
4878
  pruneUsageLog(fs12, paths.usageLogDir, nowMs);
4852
4879
  prunedDay = day;
4853
4880
  }
4854
- fs12.appendFilePrivate(import_node_path18.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
4881
+ fs12.appendFilePrivate(import_node_path19.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
4855
4882
  `);
4856
4883
  if (record.identity !== void 0) {
4857
4884
  rewriteSnapshot(record.identity, (current) => ({ ...current?.providers, [record.provider]: foldProviderState(current?.providers[record.provider], record) }));
@@ -4874,11 +4901,11 @@ function createUsageStore(deps) {
4874
4901
  })
4875
4902
  };
4876
4903
  }
4877
- var import_node_path18, DAY_MS2, DAYS_IN_WEEK, USAGE_RETENTION_MS;
4904
+ var import_node_path19, DAY_MS2, DAYS_IN_WEEK, USAGE_RETENTION_MS;
4878
4905
  var init_store2 = __esm({
4879
4906
  "src/usage/store.ts"() {
4880
4907
  "use strict";
4881
- import_node_path18 = __toESM(require("node:path"), 1);
4908
+ import_node_path19 = __toESM(require("node:path"), 1);
4882
4909
  init_account();
4883
4910
  init_rateLimit();
4884
4911
  init_read();
@@ -5016,15 +5043,15 @@ function recordStickyPick(fs12, picksFile, directory, identity, nowMs) {
5016
5043
  const current = readPicksFile(fs12, picksFile).file.picks;
5017
5044
  const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
5018
5045
  const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
5019
- fs12.mkdirPrivate(import_node_path19.default.dirname(picksFile));
5046
+ fs12.mkdirPrivate(import_node_path20.default.dirname(picksFile));
5020
5047
  fs12.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
5021
5048
  `);
5022
5049
  }
5023
- var import_node_path19, import_zod10, PoolGraphError, SCHEMA_VERSION, PickEntrySchema, PicksFileSchema;
5050
+ var import_node_path20, import_zod10, PoolGraphError, SCHEMA_VERSION, PickEntrySchema, PicksFileSchema;
5024
5051
  var init_poolPick = __esm({
5025
5052
  "src/usage/poolPick.ts"() {
5026
5053
  "use strict";
5027
- import_node_path19 = __toESM(require("node:path"), 1);
5054
+ import_node_path20 = __toESM(require("node:path"), 1);
5028
5055
  import_zod10 = require("zod");
5029
5056
  init_cliError();
5030
5057
  init_identity();
@@ -5055,8 +5082,8 @@ function resolveAgentShimHome(env = process.env, home = import_node_os4.default.
5055
5082
  if (fromEnv !== void 0 && fromEnv !== "") {
5056
5083
  return fromEnv;
5057
5084
  }
5058
- const current = import_node_path21.default.join(home, HOME_DIRNAME);
5059
- const legacy = import_node_path21.default.join(home, LEGACY_HOME_DIRNAME);
5085
+ const current = import_node_path22.default.join(home, HOME_DIRNAME);
5086
+ const legacy = import_node_path22.default.join(home, LEGACY_HOME_DIRNAME);
5060
5087
  return !isDirectory(current) && isDirectory(legacy) ? legacy : current;
5061
5088
  }
5062
5089
  function isExistingDirectory(candidate) {
@@ -5067,55 +5094,55 @@ function resolveClaudeHome() {
5067
5094
  if (fromEnv !== void 0 && fromEnv !== "") {
5068
5095
  return fromEnv;
5069
5096
  }
5070
- return import_node_path21.default.join(import_node_os4.default.homedir(), ".claude");
5097
+ return import_node_path22.default.join(import_node_os4.default.homedir(), ".claude");
5071
5098
  }
5072
5099
  function buildLayoutPaths(root) {
5073
5100
  return {
5074
5101
  root,
5075
- identitiesDir: import_node_path21.default.join(root, "identities"),
5076
- configProfilesDir: import_node_path21.default.join(root, "config-profiles"),
5077
- providersDir: import_node_path21.default.join(root, "providers"),
5078
- directoryRulesFile: import_node_path21.default.join(root, "directory-rules.json"),
5079
- activeIdentityFile: import_node_path21.default.join(root, "active-identity"),
5080
- globalConfigFile: import_node_path21.default.join(root, "config.json"),
5081
- categoriesLocalFile: import_node_path21.default.join(root, "categories.local.json"),
5082
- claudeShimFile: import_node_path21.default.join(root, "claude-shim.json"),
5083
- headroomDir: import_node_path21.default.join(root, "headroom"),
5084
- headroomStateFile: import_node_path21.default.join(root, "headroom", `state.v${String(HEADROOM_STATE_SCHEMA_VERSION)}.json`),
5085
- headroomSocketDir: import_node_path21.default.join(root, "headroom", "run"),
5086
- headroomLockFile: import_node_path21.default.join(root, "headroom", "start.lock"),
5087
- headroomSessionsDir: import_node_path21.default.join(root, "headroom", "sessions"),
5088
- logsDir: import_node_path21.default.join(root, "logs"),
5089
- headroomLogPath: import_node_path21.default.join(root, "logs", "headroom.log"),
5090
- frontdoorDir: import_node_path21.default.join(root, "frontdoor"),
5091
- frontdoorCaDir: import_node_path21.default.join(root, "frontdoor", "ca"),
5092
- frontdoorCaCertFile: import_node_path21.default.join(root, "frontdoor", "ca", "ca.pem"),
5093
- frontdoorCaKeyFile: import_node_path21.default.join(root, "frontdoor", "ca", "ca.key"),
5094
- frontdoorCaBundlesDir: import_node_path21.default.join(root, "frontdoor", "ca", "bundles"),
5095
- chatgptSignInFile: import_node_path21.default.join(root, "codex", "chatgpt-sign-in.json"),
5096
- frontdoorStateFile: import_node_path21.default.join(root, "frontdoor", "state.json"),
5097
- frontdoorLockFile: import_node_path21.default.join(root, "frontdoor", "start.lock"),
5098
- frontdoorControlTokenFile: import_node_path21.default.join(root, "frontdoor", "control-token"),
5099
- frontdoorSessionsDir: import_node_path21.default.join(root, "frontdoor", "sessions"),
5100
- frontdoorRcCredentialsDir: import_node_path21.default.join(root, "frontdoor", "rc-credentials"),
5101
- frontdoorLogPath: import_node_path21.default.join(root, "logs", "frontdoor.log"),
5102
- usageDir: import_node_path21.default.join(root, "usage"),
5103
- usageLogDir: import_node_path21.default.join(root, "usage", "log"),
5104
- usageSnapshotsDir: import_node_path21.default.join(root, "usage", "snapshots"),
5105
- usagePicksFile: import_node_path21.default.join(root, "usage", "picks.json")
5102
+ identitiesDir: import_node_path22.default.join(root, "identities"),
5103
+ configProfilesDir: import_node_path22.default.join(root, "config-profiles"),
5104
+ providersDir: import_node_path22.default.join(root, "providers"),
5105
+ directoryRulesFile: import_node_path22.default.join(root, "directory-rules.json"),
5106
+ activeIdentityFile: import_node_path22.default.join(root, "active-identity"),
5107
+ globalConfigFile: import_node_path22.default.join(root, "config.json"),
5108
+ categoriesLocalFile: import_node_path22.default.join(root, "categories.local.json"),
5109
+ claudeShimFile: import_node_path22.default.join(root, "claude-shim.json"),
5110
+ headroomDir: import_node_path22.default.join(root, "headroom"),
5111
+ headroomStateFile: import_node_path22.default.join(root, "headroom", "state.json"),
5112
+ headroomLegacyStateFile: import_node_path22.default.join(root, "headroom", "state.v2.json"),
5113
+ headroomSocketDir: import_node_path22.default.join(root, "headroom", "run"),
5114
+ headroomLockFile: import_node_path22.default.join(root, "headroom", "start.lock"),
5115
+ headroomSessionsDir: import_node_path22.default.join(root, "headroom", "sessions"),
5116
+ logsDir: import_node_path22.default.join(root, "logs"),
5117
+ headroomLogPath: import_node_path22.default.join(root, "logs", "headroom.log"),
5118
+ frontdoorDir: import_node_path22.default.join(root, "frontdoor"),
5119
+ frontdoorCaDir: import_node_path22.default.join(root, "frontdoor", "ca"),
5120
+ frontdoorCaCertFile: import_node_path22.default.join(root, "frontdoor", "ca", "ca.pem"),
5121
+ frontdoorCaKeyFile: import_node_path22.default.join(root, "frontdoor", "ca", "ca.key"),
5122
+ frontdoorCaBundlesDir: import_node_path22.default.join(root, "frontdoor", "ca", "bundles"),
5123
+ chatgptSignInFile: import_node_path22.default.join(root, "codex", "chatgpt-sign-in.json"),
5124
+ frontdoorStateFile: import_node_path22.default.join(root, "frontdoor", "state.json"),
5125
+ frontdoorLockFile: import_node_path22.default.join(root, "frontdoor", "start.lock"),
5126
+ frontdoorControlTokenFile: import_node_path22.default.join(root, "frontdoor", "control-token"),
5127
+ frontdoorSessionsDir: import_node_path22.default.join(root, "frontdoor", "sessions"),
5128
+ frontdoorRcCredentialsDir: import_node_path22.default.join(root, "frontdoor", "rc-credentials"),
5129
+ frontdoorLogPath: import_node_path22.default.join(root, "logs", "frontdoor.log"),
5130
+ usageDir: import_node_path22.default.join(root, "usage"),
5131
+ usageLogDir: import_node_path22.default.join(root, "usage", "log"),
5132
+ usageSnapshotsDir: import_node_path22.default.join(root, "usage", "snapshots"),
5133
+ usagePicksFile: import_node_path22.default.join(root, "usage", "picks.json")
5106
5134
  };
5107
5135
  }
5108
5136
  function resolveLayoutPaths() {
5109
5137
  return buildLayoutPaths(resolveAgentShimHome());
5110
5138
  }
5111
- var import_node_fs4, import_node_os4, import_node_path21;
5139
+ var import_node_fs4, import_node_os4, import_node_path22;
5112
5140
  var init_paths = __esm({
5113
5141
  "src/paths.ts"() {
5114
5142
  "use strict";
5115
5143
  import_node_fs4 = __toESM(require("node:fs"), 1);
5116
5144
  import_node_os4 = __toESM(require("node:os"), 1);
5117
- import_node_path21 = __toESM(require("node:path"), 1);
5118
- init_state2();
5145
+ import_node_path22 = __toESM(require("node:path"), 1);
5119
5146
  init_legacy();
5120
5147
  }
5121
5148
  });
@@ -5220,8 +5247,8 @@ function security(args, stdin) {
5220
5247
  return { status: result.status, stdout: result.stdout };
5221
5248
  }
5222
5249
  function createRealCredentialCache(root) {
5223
- const dir = import_node_path22.default.join(root, "credential-cache");
5224
- const filePath = (owner) => import_node_path22.default.join(dir, cacheFileNameFor(owner));
5250
+ const dir = import_node_path23.default.join(root, "credential-cache");
5251
+ const filePath = (owner) => import_node_path23.default.join(dir, cacheFileNameFor(owner));
5225
5252
  return {
5226
5253
  read(store, owner) {
5227
5254
  if (store === "file") {
@@ -5267,13 +5294,13 @@ function createRealCredentialCache(root) {
5267
5294
  function realCredentialCacheEnv(paths) {
5268
5295
  return { port: createRealCredentialCache(paths.root), platform: process.platform, now: () => Date.now() };
5269
5296
  }
5270
- var import_node_child_process2, import_node_fs5, import_node_path22, KEYCHAIN_CACHE_SERVICE, CACHE_DIR_MODE, CACHE_FILE_MODE;
5297
+ var import_node_child_process2, import_node_fs5, import_node_path23, KEYCHAIN_CACHE_SERVICE, CACHE_DIR_MODE, CACHE_FILE_MODE;
5271
5298
  var init_realCredentialCache = __esm({
5272
5299
  "src/realCredentialCache.ts"() {
5273
5300
  "use strict";
5274
5301
  import_node_child_process2 = require("node:child_process");
5275
5302
  import_node_fs5 = __toESM(require("node:fs"), 1);
5276
- import_node_path22 = __toESM(require("node:path"), 1);
5303
+ import_node_path23 = __toESM(require("node:path"), 1);
5277
5304
  init_credentialCache();
5278
5305
  KEYCHAIN_CACHE_SERVICE = "agent-shim-credential-cache";
5279
5306
  CACHE_DIR_MODE = 448;
@@ -5456,7 +5483,7 @@ var init_credential = __esm({
5456
5483
 
5457
5484
  // src/providersStore.ts
5458
5485
  function providerJsonPath(paths, name) {
5459
- return import_node_path23.default.join(paths.providersDir, `${name}.json`);
5486
+ return import_node_path24.default.join(paths.providersDir, `${name}.json`);
5460
5487
  }
5461
5488
  function providerExists(paths, name) {
5462
5489
  return import_node_fs6.default.existsSync(providerJsonPath(paths, name));
@@ -5516,7 +5543,7 @@ function readProvider(paths, name) {
5516
5543
  return parseProviderFile(filePath, raw);
5517
5544
  }
5518
5545
  function loadProvider(providersDir, name, port) {
5519
- const filePath = import_node_path23.default.join(providersDir, `${name}.json`);
5546
+ const filePath = import_node_path24.default.join(providersDir, `${name}.json`);
5520
5547
  const raw = port.readConfigFile(filePath);
5521
5548
  return raw === void 0 ? void 0 : parseProviderFile(filePath, raw);
5522
5549
  }
@@ -5670,12 +5697,12 @@ function resolveProvider(params) {
5670
5697
  }
5671
5698
  return { ok: true, provider: { name, definition, credential: resolution.credential }, warnings: resolution.credential.warnings };
5672
5699
  }
5673
- var import_node_fs6, import_node_path23, ProviderNotFoundError, ProviderAlreadyExistsError, InvalidProviderNameError, PROVIDER_NAME_RE, LEGACY_PROVIDER_FIELDS, LEGACY_ENV_CREDENTIAL_KEYS, LEGACY_LITERAL_PLACEHOLDER, LegacyProviderFileError, ProviderKindMismatchError;
5700
+ var import_node_fs6, import_node_path24, ProviderNotFoundError, ProviderAlreadyExistsError, InvalidProviderNameError, PROVIDER_NAME_RE, LEGACY_PROVIDER_FIELDS, LEGACY_ENV_CREDENTIAL_KEYS, LEGACY_LITERAL_PLACEHOLDER, LegacyProviderFileError, ProviderKindMismatchError;
5674
5701
  var init_providersStore = __esm({
5675
5702
  "src/providersStore.ts"() {
5676
5703
  "use strict";
5677
5704
  import_node_fs6 = __toESM(require("node:fs"), 1);
5678
- import_node_path23 = __toESM(require("node:path"), 1);
5705
+ import_node_path24 = __toESM(require("node:path"), 1);
5679
5706
  init_load();
5680
5707
  init_store();
5681
5708
  init_schema();
@@ -5887,10 +5914,10 @@ function commandFilename(ownExecutablePath, commandName) {
5887
5914
  }
5888
5915
  function resolveOwnBinaryCheck(paths, contentSourcePath) {
5889
5916
  const state = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
5890
- const recordedTarget = state === void 0 ? void 0 : import_node_path25.default.resolve(state.targetPath);
5917
+ const recordedTarget = state === void 0 ? void 0 : import_node_path26.default.resolve(state.targetPath);
5891
5918
  let ownStat;
5892
5919
  return (candidate) => {
5893
- if (recordedTarget !== void 0 && import_node_path25.default.resolve(candidate) === recordedTarget) {
5920
+ if (recordedTarget !== void 0 && import_node_path26.default.resolve(candidate) === recordedTarget) {
5894
5921
  return true;
5895
5922
  }
5896
5923
  ownStat ??= statOrUndefined(contentSourcePath);
@@ -5913,22 +5940,22 @@ function statOrUndefined(target) {
5913
5940
  }
5914
5941
  }
5915
5942
  function findPathShadow(params) {
5916
- const resolvedTargetDir = import_node_path25.default.resolve(params.targetDir);
5943
+ const resolvedTargetDir = import_node_path26.default.resolve(params.targetDir);
5917
5944
  for (const dir of params.pathDirs) {
5918
5945
  const found = params.findExecutableInDir(dir, params.targetFilename);
5919
5946
  if (found === void 0) {
5920
5947
  continue;
5921
5948
  }
5922
- return import_node_path25.default.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
5949
+ return import_node_path26.default.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
5923
5950
  }
5924
- return params.pathDirs.some((dir) => import_node_path25.default.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
5951
+ return params.pathDirs.some((dir) => import_node_path26.default.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
5925
5952
  }
5926
- var import_node_fs7, import_node_path25, import_zod15, ClaudeShimStateSchema, nodeLinkFs;
5953
+ var import_node_fs7, import_node_path26, import_zod15, ClaudeShimStateSchema, nodeLinkFs;
5927
5954
  var init_claudeShim = __esm({
5928
5955
  "src/claudeShim.ts"() {
5929
5956
  "use strict";
5930
5957
  import_node_fs7 = __toESM(require("node:fs"), 1);
5931
- import_node_path25 = __toESM(require("node:path"), 1);
5958
+ import_node_path26 = __toESM(require("node:path"), 1);
5932
5959
  import_zod15 = require("zod");
5933
5960
  init_commandDeps();
5934
5961
  init_store();
@@ -6378,7 +6405,7 @@ function buildEnv(params) {
6378
6405
  const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
6379
6406
  let providerCustomHeaders;
6380
6407
  if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
6381
- env.CLAUDE_CONFIG_DIR = import_node_path30.default.join(params.identitiesDir, params.resolvedIdentityName);
6408
+ env.CLAUDE_CONFIG_DIR = import_node_path31.default.join(params.identitiesDir, params.resolvedIdentityName);
6382
6409
  }
6383
6410
  if (params.provider !== void 0) {
6384
6411
  const providerEnv = params.provider.definition.env ?? {};
@@ -6422,11 +6449,11 @@ function buildEnv(params) {
6422
6449
  }
6423
6450
  return env;
6424
6451
  }
6425
- var import_node_path30, LOOPBACK_HOSTS;
6452
+ var import_node_path31, LOOPBACK_HOSTS;
6426
6453
  var init_flags = __esm({
6427
6454
  "src/launcher/flags.ts"() {
6428
6455
  "use strict";
6429
- import_node_path30 = __toESM(require("node:path"), 1);
6456
+ import_node_path31 = __toESM(require("node:path"), 1);
6430
6457
  init_envBool();
6431
6458
  init_credential();
6432
6459
  init_headers();
@@ -6772,7 +6799,7 @@ function prepareLaunch(params) {
6772
6799
  identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
6773
6800
  globalDefaultConfigProfile: params.globalDefaultConfigProfile
6774
6801
  });
6775
- if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(import_node_path31.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
6802
+ if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(import_node_path32.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
6776
6803
  log.error(
6777
6804
  `agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
6778
6805
  );
@@ -6835,7 +6862,7 @@ function prepareLaunch(params) {
6835
6862
  );
6836
6863
  const updateCheck = runLaunchUpdateCheck({
6837
6864
  mode: params.updateMode ?? "off",
6838
- checkPath: import_node_path31.default.join(paths.root, "update.check"),
6865
+ checkPath: import_node_path32.default.join(paths.root, "update.check"),
6839
6866
  currentVersion: package_default.version,
6840
6867
  port: params.update
6841
6868
  });
@@ -6972,12 +6999,12 @@ function runLaunchPlan(plan, spawn2) {
6972
6999
  function runLauncher(params) {
6973
7000
  params.proc.exit(runLaunchPlan(prepareLaunch(params), params.spawn));
6974
7001
  }
6975
- var import_node_crypto10, import_node_path31;
7002
+ var import_node_crypto10, import_node_path32;
6976
7003
  var init_launcher = __esm({
6977
7004
  "src/launcher.ts"() {
6978
7005
  "use strict";
6979
7006
  import_node_crypto10 = require("node:crypto");
6980
- import_node_path31 = __toESM(require("node:path"), 1);
7007
+ import_node_path32 = __toESM(require("node:path"), 1);
6981
7008
  init_package();
6982
7009
  init_envBool();
6983
7010
  init_argv();
@@ -7008,13 +7035,13 @@ function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string"
7008
7035
  if (distDir === void 0) {
7009
7036
  throw new OwnCliPathUnknownError();
7010
7037
  }
7011
- return import_node_path32.default.join(distDir, OWN_CLI_FILE_NAME);
7038
+ return import_node_path33.default.join(distDir, OWN_CLI_FILE_NAME);
7012
7039
  }
7013
- var import_node_path32, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
7040
+ var import_node_path33, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
7014
7041
  var init_ownCli = __esm({
7015
7042
  "src/ownCli.ts"() {
7016
7043
  "use strict";
7017
- import_node_path32 = __toESM(require("node:path"), 1);
7044
+ import_node_path33 = __toESM(require("node:path"), 1);
7018
7045
  init_cliError();
7019
7046
  OWN_CLI_FILE_NAME = "cli.cjs";
7020
7047
  OwnCliPathUnknownError = class extends CliError {
@@ -7099,7 +7126,7 @@ request.on("error", (error) => finish(failed, (error.code ? error.code + ": " :
7099
7126
  // src/frontdoor/trust.ts
7100
7127
  function resolveTrustBundle(params) {
7101
7128
  const { caCertFile, bundlesDir, variable, inherited, fs: fs12 } = params;
7102
- if (inherited === void 0 || inherited === "" || import_node_path33.default.resolve(inherited) === import_node_path33.default.resolve(caCertFile)) {
7129
+ if (inherited === void 0 || inherited === "" || import_node_path34.default.resolve(inherited) === import_node_path34.default.resolve(caCertFile)) {
7103
7130
  return { path: caCertFile };
7104
7131
  }
7105
7132
  const caPem = fs12.readFileUtf8(caCertFile);
@@ -7117,19 +7144,19 @@ function resolveTrustBundle(params) {
7117
7144
  }
7118
7145
  const combined = `${inheritedPem.trimEnd()}
7119
7146
  ${caPem}`;
7120
- const bundle = import_node_path33.default.join(bundlesDir, `${(0, import_node_crypto11.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
7147
+ const bundle = import_node_path34.default.join(bundlesDir, `${(0, import_node_crypto11.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
7121
7148
  if (!fs12.exists(bundle)) {
7122
7149
  fs12.mkdirp(bundlesDir);
7123
7150
  fs12.writeFileAtomic(bundle, combined);
7124
7151
  }
7125
7152
  return { path: bundle };
7126
7153
  }
7127
- var import_node_crypto11, import_node_path33, BUNDLE_NAME_HEX_DIGITS;
7154
+ var import_node_crypto11, import_node_path34, BUNDLE_NAME_HEX_DIGITS;
7128
7155
  var init_trust = __esm({
7129
7156
  "src/frontdoor/trust.ts"() {
7130
7157
  "use strict";
7131
7158
  import_node_crypto11 = require("node:crypto");
7132
- import_node_path33 = __toESM(require("node:path"), 1);
7159
+ import_node_path34 = __toESM(require("node:path"), 1);
7133
7160
  BUNDLE_NAME_HEX_DIGITS = 16;
7134
7161
  }
7135
7162
  });
@@ -7882,6 +7909,7 @@ __export(index_exports, {
7882
7909
  updateDirectoryRule: () => updateDirectoryRule,
7883
7910
  updateProvider: () => updateProvider,
7884
7911
  useIdentity: () => useIdentity,
7912
+ watchedInstallEntry: () => watchedInstallEntry,
7885
7913
  writeDirectoryRules: () => writeDirectoryRules
7886
7914
  });
7887
7915
  module.exports = __toCommonJS(index_exports);
@@ -8219,12 +8247,22 @@ init_capability();
8219
8247
  init_route();
8220
8248
 
8221
8249
  // src/frontdoor/supervisor.ts
8250
+ var import_node_path9 = __toESM(require("node:path"), 1);
8222
8251
  init_state();
8252
+ function watchedInstallEntry(resolvedOwnExecutablePath, siblingExists) {
8253
+ const parsed = import_node_path9.default.parse(resolvedOwnExecutablePath);
8254
+ if (parsed.name === "agent-shim") {
8255
+ return resolvedOwnExecutablePath;
8256
+ }
8257
+ const sibling = import_node_path9.default.join(parsed.dir, `agent-shim${parsed.ext}`);
8258
+ return siblingExists(sibling) ? sibling : resolvedOwnExecutablePath;
8259
+ }
8223
8260
  var FRONTDOOR_SUPERVISOR_STILL_RUNNING = -1;
8224
8261
  var FRONTDOOR_POLL_MS = 1e3;
8225
8262
  var MS_PER_MINUTE = 6e4;
8226
8263
  async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {}) {
8227
8264
  const { fs: fs12, paths } = ports;
8265
+ const servingBinary = ports.statOwnExecutable();
8228
8266
  const previous = readFrontDoorState(fs12, paths.frontdoorStateFile);
8229
8267
  let lastPort = previous?.lastPort;
8230
8268
  let lastConnectPort = previous?.lastConnectPort;
@@ -8287,6 +8325,18 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
8287
8325
  ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http3.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
8288
8326
  let idleSince;
8289
8327
  let ticks = 0;
8328
+ const binaryReplaced = () => {
8329
+ const current = ports.statOwnExecutable();
8330
+ return current !== void 0 && servingBinary !== void 0 && (current.dev !== servingBinary.dev || current.ino !== servingBinary.ino || current.size !== servingBinary.size || current.mtimeMs !== servingBinary.mtimeMs);
8331
+ };
8332
+ const shutdown = async () => {
8333
+ await direct.close();
8334
+ await connect3.close();
8335
+ await http3.close();
8336
+ ports.closeRcStreamHub();
8337
+ writeFrontDoorState(fs12, paths.frontdoorStateFile, sticky());
8338
+ return 0;
8339
+ };
8290
8340
  for (; ; ) {
8291
8341
  if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
8292
8342
  return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
@@ -8298,16 +8348,16 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
8298
8348
  ports.checkQuotaExpiry();
8299
8349
  const prunedPids = new Set(pruned);
8300
8350
  if (listed.filter((session) => !prunedPids.has(session.pid)).length === 0) {
8351
+ if (ticks > 1 && binaryReplaced()) {
8352
+ ports.log("agent-shim frontdoor supervisor: the installed binary changed and no sessions are live; turning the door over for the next launch");
8353
+ ports.doorHealth.binaryTurnover();
8354
+ return await shutdown();
8355
+ }
8301
8356
  idleSince ??= ports.now();
8302
8357
  if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE) {
8303
8358
  ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
8304
8359
  ports.doorHealth.idleShutdown();
8305
- await direct.close();
8306
- await connect3.close();
8307
- await http3.close();
8308
- ports.closeRcStreamHub();
8309
- writeFrontDoorState(fs12, paths.frontdoorStateFile, sticky());
8310
- return 0;
8360
+ return await shutdown();
8311
8361
  }
8312
8362
  } else {
8313
8363
  idleSince = void 0;
@@ -8361,8 +8411,8 @@ function parseConnectTarget(authority) {
8361
8411
  function isInterceptedHost(host, interceptHosts) {
8362
8412
  return interceptHosts.includes(host);
8363
8413
  }
8364
- function servedByPipeline(path34) {
8365
- return path34?.startsWith(ROUTED_PATH_PREFIX) === true;
8414
+ function servedByPipeline(path35) {
8415
+ return path35?.startsWith(ROUTED_PATH_PREFIX) === true;
8366
8416
  }
8367
8417
  var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
8368
8418
  "connection",
@@ -8896,11 +8946,11 @@ function createRcSessionTracker(deps) {
8896
8946
  };
8897
8947
  const observeExchange = (request4) => {
8898
8948
  const method = (request4.method ?? "").toUpperCase();
8899
- const path34 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
8900
- if (!path34.startsWith(RC_SESSIONS_PATH_PREFIX)) {
8949
+ const path35 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
8950
+ if (!path35.startsWith(RC_SESSIONS_PATH_PREFIX)) {
8901
8951
  return void 0;
8902
8952
  }
8903
- const tail = path34.slice(RC_SESSIONS_PATH_PREFIX.length);
8953
+ const tail = path35.slice(RC_SESSIONS_PATH_PREFIX.length);
8904
8954
  const facts = {
8905
8955
  oauthAuthorization: oauthAuthorizationOf(request4.headers),
8906
8956
  anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
@@ -9282,8 +9332,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
9282
9332
  function isRcReadFileEncoding(value) {
9283
9333
  return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
9284
9334
  }
9285
- function buildRcReadFilePayload(requestId, path34, options) {
9286
- return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path34, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
9335
+ function buildRcReadFilePayload(requestId, path35, options) {
9336
+ return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path35, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
9287
9337
  }
9288
9338
  function buildRcFileSuggestionsPayload(requestId, query) {
9289
9339
  return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
@@ -9385,15 +9435,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
9385
9435
  const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
9386
9436
  return result.ok ? { ...result, requestId } : result;
9387
9437
  }
9388
- async function readRcSessionFile(deps, sessionId, path34, options) {
9389
- if (path34 === "") {
9438
+ async function readRcSessionFile(deps, sessionId, path35, options) {
9439
+ if (path35 === "") {
9390
9440
  return { ok: false, message: "a read-file write needs a non-empty path: the SDK's own field names the file the worker resolves against the session's cwd, and an empty string names none" };
9391
9441
  }
9392
9442
  if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
9393
9443
  return { ok: false, message: "a read-file write's max-bytes is a positive whole number of bytes: the SDK's own field caps the read, and a zero or negative cap reads nothing" };
9394
9444
  }
9395
9445
  const requestId = deps.newUuid();
9396
- const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path34, options), `read ${path34} from session ${sessionId}`);
9446
+ const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path35, options), `read ${path35} from session ${sessionId}`);
9397
9447
  return result.ok ? { ...result, requestId } : result;
9398
9448
  }
9399
9449
  async function suggestRcSessionFiles(deps, sessionId, query) {
@@ -9562,11 +9612,11 @@ function createRcControlHandler(deps) {
9562
9612
  path: "read-file",
9563
9613
  read: (body) => {
9564
9614
  const session = bodyString(body, "session");
9565
- const path34 = bodyString(body, "path");
9615
+ const path35 = bodyString(body, "path");
9566
9616
  const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
9567
9617
  const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
9568
- const refused2 = session === void 0 || path34 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
9569
- return refused2 ? { error: `the read-file body must be JSON naming a non-empty session id and path, maxBytes only as a positive whole number or absent, and an encoding the SDK's own type permits (${RC_READ_FILE_ENCODINGS.join(", ")}) or none` } : { session, run: async () => await deps.readFile(session, path34, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
9618
+ const refused2 = session === void 0 || path35 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
9619
+ return refused2 ? { error: `the read-file body must be JSON naming a non-empty session id and path, maxBytes only as a positive whole number or absent, and an encoding the SDK's own type permits (${RC_READ_FILE_ENCODINGS.join(", ")}) or none` } : { session, run: async () => await deps.readFile(session, path35, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
9570
9620
  }
9571
9621
  },
9572
9622
  {
@@ -9876,9 +9926,9 @@ function requestIdOfBody(body) {
9876
9926
  }
9877
9927
  function frontDoorRcControl(transport, token) {
9878
9928
  const headers = { authorization: `Bearer ${token}` };
9879
- const listAnswerOf = async (path34, what) => {
9929
+ const listAnswerOf = async (path35, what) => {
9880
9930
  try {
9881
- return await transport.request({ method: "GET", path: path34, headers });
9931
+ return await transport.request({ method: "GET", path: path35, headers });
9882
9932
  } catch (error) {
9883
9933
  throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
9884
9934
  }
@@ -9950,10 +10000,10 @@ function frontDoorRcControl(transport, token) {
9950
10000
  }
9951
10001
  return pending;
9952
10002
  };
9953
- const writeOf = async (path34, body, describeFailure) => {
10003
+ const writeOf = async (path35, body, describeFailure) => {
9954
10004
  let answer;
9955
10005
  try {
9956
- answer = await transport.request({ method: "POST", path: path34, headers: { ...headers, "content-type": "application/json" }, body });
10006
+ answer = await transport.request({ method: "POST", path: path35, headers: { ...headers, "content-type": "application/json" }, body });
9957
10007
  } catch (error) {
9958
10008
  return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
9959
10009
  }
@@ -9984,10 +10034,10 @@ function frontDoorRcControl(transport, token) {
9984
10034
  endSession: async (sessionId, reason) => await writeOf(`${CONTROL_PATH_PREFIX}/end-session`, JSON.stringify({ session: sessionId, ...reason === void 0 ? {} : { reason } }), (status, message) => `ending ${sessionId} failed (HTTP ${String(status)}): ${message}`),
9985
10035
  getUsage: async (sessionId, skipBehaviors) => await writeOf(`${CONTROL_PATH_PREFIX}/get-usage`, JSON.stringify({ session: sessionId, ...skipBehaviors === void 0 ? {} : { skipBehaviors } }), (status, message) => `requesting the usage of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
9986
10036
  getContextUsage: async (sessionId, detail) => await writeOf(`${CONTROL_PATH_PREFIX}/get-context-usage`, JSON.stringify({ session: sessionId, ...detail === void 0 ? {} : { detail } }), (status, message) => `requesting the context usage of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
9987
- readFile: async (sessionId, path34, options) => await writeOf(
10037
+ readFile: async (sessionId, path35, options) => await writeOf(
9988
10038
  `${CONTROL_PATH_PREFIX}/read-file`,
9989
- JSON.stringify({ session: sessionId, path: path34, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
9990
- (status, message) => `reading ${path34} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
10039
+ JSON.stringify({ session: sessionId, path: path35, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
10040
+ (status, message) => `reading ${path35} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
9991
10041
  ),
9992
10042
  fileSuggestions: async (sessionId, query) => await writeOf(`${CONTROL_PATH_PREFIX}/file-suggestions`, JSON.stringify({ session: sessionId, query }), (status, message) => `requesting file suggestions from ${sessionId} failed (HTTP ${String(status)}): ${message}`),
9993
10043
  keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
@@ -10142,12 +10192,12 @@ function tlsFacts(options) {
10142
10192
  }
10143
10193
  function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
10144
10194
  const agent = new ExemptTlsAgent();
10145
- const post = async (path34, headers, body) => await new Promise((resolve, reject) => {
10195
+ const post = async (path35, headers, body) => await new Promise((resolve, reject) => {
10146
10196
  const options = {
10147
10197
  host: target.host,
10148
10198
  port: target.port,
10149
10199
  method: "POST",
10150
- path: path34,
10200
+ path: path35,
10151
10201
  // The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
10152
10202
  headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
10153
10203
  agent
@@ -10212,12 +10262,12 @@ function lateRcStreamDial(resolve) {
10212
10262
  }
10213
10263
  function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
10214
10264
  const agent = new ExemptTlsAgent();
10215
- const request4 = async (method, path34, headers, body, signal) => await new Promise((resolve, reject) => {
10265
+ const request4 = async (method, path35, headers, body, signal) => await new Promise((resolve, reject) => {
10216
10266
  const options = {
10217
10267
  host: target.host,
10218
10268
  port: target.port,
10219
10269
  method,
10220
- path: path34,
10270
+ path: path35,
10221
10271
  // The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
10222
10272
  headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
10223
10273
  agent,
@@ -10259,9 +10309,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
10259
10309
  return { status, body: await readAll(response) };
10260
10310
  },
10261
10311
  openStream: async (sessionId, headers, resume, signal) => {
10262
- const path34 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
10312
+ const path35 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
10263
10313
  const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
10264
- const { status, response } = await request4("GET", path34, streamHeaders, void 0, signal);
10314
+ const { status, response } = await request4("GET", path35, streamHeaders, void 0, signal);
10265
10315
  if (!isSuccessful2(status)) {
10266
10316
  await readAll(response);
10267
10317
  return { status, chunks: NO_CHUNKS };
@@ -10473,7 +10523,7 @@ function realConnectEffects(ports = DOOR_SOURCE_PORTS) {
10473
10523
  }
10474
10524
 
10475
10525
  // src/frontdoor/rcCredentialStore.ts
10476
- var import_node_path9 = __toESM(require("node:path"), 1);
10526
+ var import_node_path10 = __toESM(require("node:path"), 1);
10477
10527
  function isSafeSessionId(sessionId) {
10478
10528
  return /^[A-Za-z0-9_-]+$/.test(sessionId);
10479
10529
  }
@@ -10499,7 +10549,7 @@ function sequenceNumOfJson(value) {
10499
10549
  }
10500
10550
  function createRcCredentialStore(fs12, dir) {
10501
10551
  fs12.mkdirPrivate(dir);
10502
- const fileFor = (sessionId) => import_node_path9.default.join(dir, `${sessionId}.json`);
10552
+ const fileFor = (sessionId) => import_node_path10.default.join(dir, `${sessionId}.json`);
10503
10553
  const readParsed = (sessionId) => {
10504
10554
  const raw = fs12.readFileUtf8(fileFor(sessionId));
10505
10555
  if (raw === void 0) {
@@ -10955,7 +11005,7 @@ init_cliError();
10955
11005
 
10956
11006
  // src/configProfilesStore.ts
10957
11007
  var import_node_fs3 = __toESM(require("node:fs"), 1);
10958
- var import_node_path20 = __toESM(require("node:path"), 1);
11008
+ var import_node_path21 = __toESM(require("node:path"), 1);
10959
11009
  init_store();
10960
11010
  init_schema();
10961
11011
  init_cliError();
@@ -10985,7 +11035,7 @@ var InvalidCategoryNameError = class extends CliError {
10985
11035
  categoryName;
10986
11036
  };
10987
11037
  function profileJsonPath(paths, name) {
10988
- return import_node_path20.default.join(paths.configProfilesDir, `${name}.json`);
11038
+ return import_node_path21.default.join(paths.configProfilesDir, `${name}.json`);
10989
11039
  }
10990
11040
  function profileExists(paths, name) {
10991
11041
  return import_node_fs3.default.existsSync(profileJsonPath(paths, name));
@@ -11125,19 +11175,19 @@ function writePools(paths, pools) {
11125
11175
  applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
11126
11176
  }
11127
11177
  function poolCycleOf(pools, name) {
11128
- const walk = (current, path34) => {
11178
+ const walk = (current, path35) => {
11129
11179
  for (const entry of pools[current]?.identities ?? []) {
11130
11180
  const nested = poolNameOf(poolMemberIdentity(entry));
11131
11181
  if (nested === void 0) {
11132
11182
  continue;
11133
11183
  }
11134
11184
  if (nested === name) {
11135
- return [...path34, nested];
11185
+ return [...path35, nested];
11136
11186
  }
11137
- if (path34.includes(nested)) {
11187
+ if (path35.includes(nested)) {
11138
11188
  continue;
11139
11189
  }
11140
- const found = walk(nested, [...path34, nested]);
11190
+ const found = walk(nested, [...path35, nested]);
11141
11191
  if (found !== void 0) {
11142
11192
  return found;
11143
11193
  }
@@ -11236,7 +11286,7 @@ init_paths();
11236
11286
  init_realCredentialCache();
11237
11287
  init_providersStore();
11238
11288
  init_realPorts();
11239
- var import_node_path24 = __toESM(require("node:path"), 1);
11289
+ var import_node_path25 = __toESM(require("node:path"), 1);
11240
11290
  var import_zod12 = require("zod");
11241
11291
  init_envBool();
11242
11292
  init_load();
@@ -11585,10 +11635,10 @@ function collectCheckReport(params) {
11585
11635
  }).input;
11586
11636
  const providerName = cascadeProviderName(cascade);
11587
11637
  const provider = providerName === void 0 ? void 0 : loadCheckProvider(paths, providerName);
11588
- const farmRoot = identityDecision.name === void 0 ? void 0 : import_node_path24.default.join(paths.identitiesDir, identityDecision.name);
11638
+ const farmRoot = identityDecision.name === void 0 ? void 0 : import_node_path25.default.join(paths.identitiesDir, identityDecision.name);
11589
11639
  const settingsFiles = {
11590
- "settings.json": realFsPort.readFileUtf8(import_node_path24.default.join(claudeHome, "settings.json")),
11591
- "settings.local.json": realFsPort.readFileUtf8(import_node_path24.default.join(claudeHome, "settings.local.json"))
11640
+ "settings.json": realFsPort.readFileUtf8(import_node_path25.default.join(claudeHome, "settings.json")),
11641
+ "settings.local.json": realFsPort.readFileUtf8(import_node_path25.default.join(claudeHome, "settings.local.json"))
11592
11642
  };
11593
11643
  const report = runCheck({
11594
11644
  cwd,
@@ -11808,7 +11858,7 @@ init_middleware();
11808
11858
  init_preflight();
11809
11859
 
11810
11860
  // src/frontdoor/controlSchemas.ts
11811
- var import_node_path28 = __toESM(require("node:path"), 1);
11861
+ var import_node_path29 = __toESM(require("node:path"), 1);
11812
11862
  var import_zod19 = require("zod");
11813
11863
 
11814
11864
  // src/doctorReport.ts
@@ -11817,7 +11867,7 @@ init_store();
11817
11867
 
11818
11868
  // src/identityStore.ts
11819
11869
  var import_node_fs8 = __toESM(require("node:fs"), 1);
11820
- var import_node_path26 = __toESM(require("node:path"), 1);
11870
+ var import_node_path27 = __toESM(require("node:path"), 1);
11821
11871
  init_load();
11822
11872
  init_store();
11823
11873
  init_schema();
@@ -11851,7 +11901,7 @@ var InvalidIdentityNameError = class extends CliError {
11851
11901
  attemptedName;
11852
11902
  };
11853
11903
  function identityJsonPath(paths, name) {
11854
- return import_node_path26.default.join(paths.identitiesDir, name, "identity.json");
11904
+ return import_node_path27.default.join(paths.identitiesDir, name, "identity.json");
11855
11905
  }
11856
11906
  function identityExists(paths, name) {
11857
11907
  return import_node_fs8.default.existsSync(identityJsonPath(paths, name));
@@ -11952,7 +12002,7 @@ function setIdentityCredential(paths, identityName, change) {
11952
12002
  });
11953
12003
  }
11954
12004
  function belongsToIdentity(entry, name) {
11955
- return entry === name || entry === import_node_path26.default.basename(identityLockPath("", name)) || entry.startsWith(`.${name}.scratch.`) || entry.startsWith(`.${name}.previous.`);
12005
+ return entry === name || entry === import_node_path27.default.basename(identityLockPath("", name)) || entry.startsWith(`.${name}.scratch.`) || entry.startsWith(`.${name}.previous.`);
11956
12006
  }
11957
12007
  function removeIdentity(paths, name) {
11958
12008
  if (!identityExists(paths, name)) {
@@ -11960,7 +12010,7 @@ function removeIdentity(paths, name) {
11960
12010
  }
11961
12011
  for (const entry of import_node_fs8.default.readdirSync(paths.identitiesDir)) {
11962
12012
  if (belongsToIdentity(entry, name)) {
11963
- import_node_fs8.default.rmSync(import_node_path26.default.join(paths.identitiesDir, entry), { recursive: true, force: true });
12013
+ import_node_fs8.default.rmSync(import_node_path27.default.join(paths.identitiesDir, entry), { recursive: true, force: true });
11964
12014
  }
11965
12015
  }
11966
12016
  if (readActiveIdentity2(paths) === name) {
@@ -11971,7 +12021,7 @@ function removeIdentity(paths, name) {
11971
12021
  // src/doctorReport.ts
11972
12022
  init_realPorts();
11973
12023
  var import_node_fs9 = __toESM(require("node:fs"), 1);
11974
- var import_node_path27 = __toESM(require("node:path"), 1);
12024
+ var import_node_path28 = __toESM(require("node:path"), 1);
11975
12025
 
11976
12026
  // src/codex/siwcStore.ts
11977
12027
  var import_zod18 = require("zod");
@@ -12103,8 +12153,18 @@ function validateJson(schema, input) {
12103
12153
  }
12104
12154
  return { ok: true, data: result.data };
12105
12155
  }
12156
+ function tcpPortEraRecord(raw) {
12157
+ let parsed;
12158
+ try {
12159
+ parsed = JSON.parse(raw);
12160
+ } catch {
12161
+ return false;
12162
+ }
12163
+ const has = (key) => typeof parsed === "object" && parsed !== null && key in parsed;
12164
+ return (has("port") || has("lastPort")) && !has("socketPath");
12165
+ }
12106
12166
  function pushPathResolution(push, resolution) {
12107
- const ownDir = import_node_path27.default.dirname(resolution.ownExecutablePath);
12167
+ const ownDir = import_node_path28.default.dirname(resolution.ownExecutablePath);
12108
12168
  switch (resolution.agentShim.status) {
12109
12169
  case "ok":
12110
12170
  push("path-resolution", "pass", `\`agent-shim\` on PATH resolves to this running executable, ${resolution.ownExecutablePath}.`, "agent-shim");
@@ -12203,14 +12263,14 @@ function pushProvider(push, entry, cacheEnv, signIn) {
12203
12263
  }
12204
12264
  function pushLegacyName(push, params) {
12205
12265
  const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
12206
- if (legacyVariables.length === 0 && import_node_path27.default.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
12266
+ if (legacyVariables.length === 0 && import_node_path28.default.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
12207
12267
  push("legacy-name", "pass", "Nothing here still uses the former `claude-use` name.");
12208
12268
  return;
12209
12269
  }
12210
12270
  for (const name of legacyVariables) {
12211
12271
  push("legacy-name", "warn", `${name} is the former name of ${name.replace(LEGACY_ENV_PREFIX, ENV_PREFIX)}. Rename it; the old name still works but is only a fallback.`, name);
12212
12272
  }
12213
- if (import_node_path27.default.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
12273
+ if (import_node_path28.default.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
12214
12274
  push(
12215
12275
  "legacy-name",
12216
12276
  "warn",
@@ -12412,6 +12472,8 @@ function runDoctor(params) {
12412
12472
  }
12413
12473
  if (params.headroom.state.raw === void 0) {
12414
12474
  push("headroom", "pass", "No headroom daemon has ever run; nothing to check.");
12475
+ } else if (tcpPortEraRecord(params.headroom.state.raw)) {
12476
+ push("headroom", "pass", `${params.headroom.state.path} holds a previous release's TCP-port state record; the next launch through headroom claims over it.`);
12415
12477
  } else {
12416
12478
  const validated2 = validateJson(HeadroomStateSchema, params.headroom.state);
12417
12479
  if (!validated2.ok) {
@@ -12550,18 +12612,18 @@ function collectDoctorReport(params) {
12550
12612
  const { paths } = params;
12551
12613
  const identityNames = import_node_fs9.default.existsSync(paths.identitiesDir) ? import_node_fs9.default.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort() : [];
12552
12614
  const identities = identityNames.map((name) => {
12553
- const farmRoot = import_node_path27.default.join(paths.identitiesDir, name);
12554
- const identityPath = import_node_path27.default.join(farmRoot, "identity.json");
12615
+ const farmRoot = import_node_path28.default.join(paths.identitiesDir, name);
12616
+ const identityPath = import_node_path28.default.join(farmRoot, "identity.json");
12555
12617
  return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot };
12556
12618
  });
12557
12619
  const profileNames = import_node_fs9.default.existsSync(paths.configProfilesDir) ? import_node_fs9.default.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
12558
12620
  const configProfiles = profileNames.map((name) => {
12559
- const profilePath = import_node_path27.default.join(paths.configProfilesDir, `${name}.json`);
12621
+ const profilePath = import_node_path28.default.join(paths.configProfilesDir, `${name}.json`);
12560
12622
  return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
12561
12623
  });
12562
12624
  const providerNames = import_node_fs9.default.existsSync(paths.providersDir) ? import_node_fs9.default.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
12563
12625
  const providers = providerNames.map((name) => {
12564
- const providerPath = import_node_path27.default.join(paths.providersDir, `${name}.json`);
12626
+ const providerPath = import_node_path28.default.join(paths.providersDir, `${name}.json`);
12565
12627
  return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
12566
12628
  });
12567
12629
  const ownExecutablePath = realOwnExecutablePath();
@@ -12573,12 +12635,12 @@ function collectDoctorReport(params) {
12573
12635
  binaryDiscovery = { ok: false, message: error instanceof Error ? error.message : String(error) };
12574
12636
  }
12575
12637
  const shimState = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
12576
- const pathDirs = (params.env.PATH ?? "").split(import_node_path27.default.delimiter).filter((dir) => dir !== "");
12638
+ const pathDirs = (params.env.PATH ?? "").split(import_node_path28.default.delimiter).filter((dir) => dir !== "");
12577
12639
  const claudeShimShadow = shimState === void 0 ? void 0 : refinePathShadow(
12578
12640
  findPathShadow({
12579
12641
  pathDirs,
12580
- targetDir: import_node_path27.default.dirname(shimState.targetPath),
12581
- targetFilename: import_node_path27.default.basename(shimState.targetPath),
12642
+ targetDir: import_node_path28.default.dirname(shimState.targetPath),
12643
+ targetFilename: import_node_path28.default.basename(shimState.targetPath),
12582
12644
  findExecutableInDir
12583
12645
  }),
12584
12646
  shimState.targetPath,
@@ -12604,7 +12666,7 @@ function collectDoctorReport(params) {
12604
12666
  agentShim: refinePathShadow(
12605
12667
  findPathShadow({
12606
12668
  pathDirs,
12607
- targetDir: import_node_path27.default.dirname(ownExecutablePath),
12669
+ targetDir: import_node_path28.default.dirname(ownExecutablePath),
12608
12670
  targetFilename: commandFilename(ownExecutablePath, "agent-shim"),
12609
12671
  findExecutableInDir
12610
12672
  }),
@@ -12616,7 +12678,12 @@ function collectDoctorReport(params) {
12616
12678
  run: realRunPort,
12617
12679
  platform: process.platform,
12618
12680
  headroom: {
12619
- state: { path: paths.headroomStateFile, raw: realFsPort.readFileUtf8(paths.headroomStateFile) },
12681
+ // Read-only resolution like `headroom status`: the doctor reports whichever record a launch would join, migrating nothing.
12682
+ state: (() => {
12683
+ const resolved = resolveServingHeadroomState(realFarmFs, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, realIsProcessRunning);
12684
+ const statePath = resolved?.path ?? paths.headroomStateFile;
12685
+ return { path: statePath, raw: realFarmFs.readFileUtf8(statePath) };
12686
+ })(),
12620
12687
  isRunning: realIsProcessRunning
12621
12688
  }
12622
12689
  });
@@ -12673,11 +12740,11 @@ var FrontDoorSessionsOutputSchema = import_zod19.z.strictObject({ sessions: impo
12673
12740
  var CheckRunInputSchema = import_zod19.z.strictObject({
12674
12741
  path: import_zod19.z.string().min(1),
12675
12742
  identity: import_zod19.z.string().min(1).optional()
12676
- }).refine((input) => import_node_path28.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
12743
+ }).refine((input) => import_node_path29.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
12677
12744
  var PoolPickInputSchema = import_zod19.z.strictObject({
12678
12745
  pool: import_zod19.z.string().min(1),
12679
12746
  path: import_zod19.z.string().min(1)
12680
- }).refine((input) => import_node_path28.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
12747
+ }).refine((input) => import_node_path29.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
12681
12748
  var DoctorFindingSchema = import_zod19.z.strictObject({
12682
12749
  section: import_zod19.z.enum(DOCTOR_SECTIONS),
12683
12750
  subject: import_zod19.z.string().optional(),
@@ -12719,6 +12786,7 @@ var LaunchLifecycleEventSchema = import_zod20.z.strictObject({
12719
12786
  var DoorHealthEventSchema = import_zod20.z.discriminatedUnion("kind", [
12720
12787
  import_zod20.z.strictObject({ kind: import_zod20.z.literal("generation"), pid: import_zod20.z.number().int().positive(), providerPort: import_zod20.z.number().int().positive(), connectPort: import_zod20.z.number().int().positive(), directPort: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() }),
12721
12788
  import_zod20.z.strictObject({ kind: import_zod20.z.literal("listenerFailed"), pid: import_zod20.z.number().int().positive(), listener: import_zod20.z.enum(["provider", "connect", "direct"]), message: import_zod20.z.string(), observedAt: import_zod20.z.number() }),
12789
+ import_zod20.z.strictObject({ kind: import_zod20.z.literal("binaryTurnover"), pid: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() }),
12722
12790
  import_zod20.z.strictObject({ kind: import_zod20.z.literal("idleShutdown"), pid: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() })
12723
12791
  ]);
12724
12792
  var QuotaExpiringEventSchema = import_zod20.z.strictObject({
@@ -12882,7 +12950,7 @@ init_socket();
12882
12950
  init_state2();
12883
12951
  init_state();
12884
12952
  function headroomSocketTarget(fsPort, trust, paths) {
12885
- const socketPath = readHeadroomState(fsPort, paths.headroomStateFile)?.socketPath;
12953
+ const socketPath = readHeadroomState(fsPort, paths.headroomStateFile)?.socketPath ?? readHeadroomState(fsPort, paths.headroomLegacyStateFile)?.socketPath;
12886
12954
  return socketPath === void 0 ? void 0 : verifyHeadroomSocket(socketPath, trust);
12887
12955
  }
12888
12956
  function collectFrontDoorStatus(fsPort, socketTrust, paths, isRunning) {
@@ -13090,6 +13158,9 @@ function createDoorHealthPublisher(hub, now, pid) {
13090
13158
  },
13091
13159
  idleShutdown: () => {
13092
13160
  publisher.publish({ kind: "idleShutdown", pid, observedAt: now() });
13161
+ },
13162
+ binaryTurnover: () => {
13163
+ publisher.publish({ kind: "binaryTurnover", pid, observedAt: now() });
13093
13164
  }
13094
13165
  };
13095
13166
  }
@@ -14784,7 +14855,7 @@ data: ${JSON.stringify(envelope)}
14784
14855
  }
14785
14856
 
14786
14857
  // src/frontdoor/rcSelfHostMint.ts
14787
- var import_node_path29 = __toESM(require("node:path"), 1);
14858
+ var import_node_path30 = __toESM(require("node:path"), 1);
14788
14859
  init_account();
14789
14860
  var CREDENTIALS_FILE = ".credentials.json";
14790
14861
  var CLAUDE_JSON2 = ".claude.json";
@@ -14809,7 +14880,7 @@ function readJsonObject(fs12, file) {
14809
14880
  return isRecord11(parsed) ? parsed : void 0;
14810
14881
  }
14811
14882
  function readRcSelfHostRecord(fs12, frontdoorDir) {
14812
- const parsed = readJsonObject(fs12, import_node_path29.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
14883
+ const parsed = readJsonObject(fs12, import_node_path30.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
14813
14884
  if (parsed === void 0) {
14814
14885
  return void 0;
14815
14886
  }
@@ -14823,11 +14894,11 @@ function mintRcSelfHostCredential(deps) {
14823
14894
  if (!isIdentityName(deps.identity)) {
14824
14895
  throw new Error(`"${deps.identity}" is not a valid identity name.`);
14825
14896
  }
14826
- const identityDir = import_node_path29.default.join(deps.identitiesDir, deps.identity);
14827
- const credentialsFile = import_node_path29.default.join(identityDir, CREDENTIALS_FILE);
14828
- const claudeJsonFile = import_node_path29.default.join(identityDir, CLAUDE_JSON2);
14829
- const recordDir = import_node_path29.default.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
14830
- const recordFile = import_node_path29.default.join(recordDir, RC_SELF_HOST_RECORD_FILE);
14897
+ const identityDir = import_node_path30.default.join(deps.identitiesDir, deps.identity);
14898
+ const credentialsFile = import_node_path30.default.join(identityDir, CREDENTIALS_FILE);
14899
+ const claudeJsonFile = import_node_path30.default.join(identityDir, CLAUDE_JSON2);
14900
+ const recordDir = import_node_path30.default.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
14901
+ const recordFile = import_node_path30.default.join(recordDir, RC_SELF_HOST_RECORD_FILE);
14831
14902
  const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
14832
14903
  const existingCredentials = readJsonObject(deps.fs, credentialsFile);
14833
14904
  const existingOauth = isRecord11(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
@@ -14843,7 +14914,7 @@ function mintRcSelfHostCredential(deps) {
14843
14914
  const organizationUuid = deps.newUuid();
14844
14915
  const accountUuid = deps.newUuid();
14845
14916
  const mintedAt = new Date(deps.now()).toISOString();
14846
- deps.fs.mkdirPrivate(import_node_path29.default.dirname(credentialsFile));
14917
+ deps.fs.mkdirPrivate(import_node_path30.default.dirname(credentialsFile));
14847
14918
  deps.fs.writeFilePrivate(credentialsFile, `${JSON.stringify({ ...existingCredentials, claudeAiOauth: { accessToken, refreshToken, expiresAt: null, scopes: [...RC_SELF_HOST_SCOPE_LIST], subscriptionType: SELF_HOST_SUBSCRIPTION_TYPE, rateLimitTier: null } }, null, 2)}
14848
14919
  `);
14849
14920
  const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
@@ -15376,5 +15447,6 @@ init_ownCli();
15376
15447
  updateDirectoryRule,
15377
15448
  updateProvider,
15378
15449
  useIdentity,
15450
+ watchedInstallEntry,
15379
15451
  writeDirectoryRules
15380
15452
  });