agent-shim 11.82.0 → 11.83.1

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.mjs CHANGED
@@ -1278,7 +1278,7 @@ function parseIgnoringUnrecognisedKeys(schema, raw) {
1278
1278
  return second.success ? { success: true, data: second.data, ignored } : { success: false, issues: second.error.issues };
1279
1279
  }
1280
1280
  function describeIgnoredKeys(filePath, ignored) {
1281
- const places = ignored.map(({ path: path42, keys }) => `${path42.length === 0 ? "" : `${path42.map(String).join(".")}.`}${keys.join(", ")}`);
1281
+ const places = ignored.map(({ path: path45, keys }) => `${path45.length === 0 ? "" : `${path45.map(String).join(".")}.`}${keys.join(", ")}`);
1282
1282
  return `${filePath} has settings this version of agent-shim does not know and ignores: ${places.join("; ")}. A newer release may read them.`;
1283
1283
  }
1284
1284
  function noteIgnoredKeys(filePath, ignored) {
@@ -1300,9 +1300,9 @@ function restoreIgnoredKeys(filePath, value) {
1300
1300
  return value;
1301
1301
  }
1302
1302
  const restored = structuredClone(value);
1303
- for (const { path: path42, values } of ignored) {
1303
+ for (const { path: path45, values } of ignored) {
1304
1304
  let holder = restored;
1305
- for (const step of path42) {
1305
+ for (const step of path45) {
1306
1306
  holder = isRecord(holder) ? holder[step] : void 0;
1307
1307
  }
1308
1308
  if (isRecord(holder)) {
@@ -1350,6 +1350,12 @@ function captureRuleEntryOrders(value) {
1350
1350
  }
1351
1351
  return rules.map((rule) => captureEntryOrder(rule));
1352
1352
  }
1353
+ function unparseableFile(error, filepath) {
1354
+ if (error instanceof SyntaxError) {
1355
+ return new ConfigFileNotJsonError(filepath);
1356
+ }
1357
+ return error instanceof Error && error.name === "YAMLException" ? new ConfigFileNotJsonError(filepath, "YAML") : void 0;
1358
+ }
1353
1359
  function cosmiconfigReader(explorer = createExplorer()) {
1354
1360
  return (filepath) => {
1355
1361
  let result;
@@ -1360,7 +1366,7 @@ function cosmiconfigReader(explorer = createExplorer()) {
1360
1366
  if (code === "ENOENT") {
1361
1367
  return void 0;
1362
1368
  }
1363
- throw error;
1369
+ throw unparseableFile(error, filepath) ?? error;
1364
1370
  }
1365
1371
  if (result === null || result.isEmpty === true) {
1366
1372
  return void 0;
@@ -1385,7 +1391,7 @@ function loadConfigFile(filepath, schema, read = cosmiconfigReader()) {
1385
1391
  ruleEntryOrders: captureRuleEntryOrders(raw)
1386
1392
  };
1387
1393
  }
1388
- var ConfigValidationError;
1394
+ var ConfigValidationError, ConfigFileNotJsonError;
1389
1395
  var init_load = __esm({
1390
1396
  "src/config/load.ts"() {
1391
1397
  "use strict";
@@ -1403,6 +1409,16 @@ ${detail}`);
1403
1409
  filepath;
1404
1410
  issues;
1405
1411
  };
1412
+ ConfigFileNotJsonError = class extends CliError {
1413
+ constructor(filepath, format = "JSON") {
1414
+ super(`${filepath} is not valid ${format}.`);
1415
+ this.filepath = filepath;
1416
+ this.format = format;
1417
+ this.name = "ConfigFileNotJsonError";
1418
+ }
1419
+ filepath;
1420
+ format;
1421
+ };
1406
1422
  }
1407
1423
  });
1408
1424
 
@@ -1418,7 +1434,12 @@ function readJson(filePath, schema, storeFs = nodeStoreFs) {
1418
1434
  if (raw === void 0) {
1419
1435
  return void 0;
1420
1436
  }
1421
- const parsed = JSON.parse(raw);
1437
+ let parsed;
1438
+ try {
1439
+ parsed = JSON.parse(raw);
1440
+ } catch (error) {
1441
+ throw error instanceof SyntaxError ? new ConfigFileNotJsonError(filePath) : error;
1442
+ }
1422
1443
  const result = parseIgnoringUnrecognisedKeys(schema, parsed);
1423
1444
  if (!result.success) {
1424
1445
  throw new ConfigValidationError(filePath, result.issues);
@@ -2921,6 +2942,14 @@ function acquireIdentityLock(params) {
2921
2942
  return {
2922
2943
  path: lockPath,
2923
2944
  token,
2945
+ refresh: () => {
2946
+ const current = parseLockRecord(params.fs.readFileUtf8(lockPath));
2947
+ if (current?.token !== token) {
2948
+ throw new IdentityLockLostError(params.identity);
2949
+ }
2950
+ params.fs.writeFilePrivate(lockPath, `${JSON.stringify({ ...current, acquiredAtMs: params.nowMs() })}
2951
+ `);
2952
+ },
2924
2953
  release: () => {
2925
2954
  const current = parseLockRecord(params.fs.readFileUtf8(lockPath));
2926
2955
  if (current !== void 0 && current.token !== token) {
@@ -2930,7 +2959,19 @@ function acquireIdentityLock(params) {
2930
2959
  }
2931
2960
  };
2932
2961
  }
2933
- const existing = parseLockRecord(params.fs.readFileUtf8(lockPath));
2962
+ const raw = params.fs.readFileUtf8(lockPath);
2963
+ if (raw === void 0) {
2964
+ continue;
2965
+ }
2966
+ let existing = parseLockRecord(raw);
2967
+ if (existing === void 0) {
2968
+ params.sleep(retryDelayMs);
2969
+ const again = params.fs.readFileUtf8(lockPath);
2970
+ if (again === void 0) {
2971
+ continue;
2972
+ }
2973
+ existing = parseLockRecord(again);
2974
+ }
2934
2975
  if (existing === void 0) {
2935
2976
  params.fs.removeRecursive(lockPath);
2936
2977
  continue;
@@ -2945,7 +2986,7 @@ function acquireIdentityLock(params) {
2945
2986
  }
2946
2987
  throw new IdentityLockBusyError(params.identity, lockPath, lastHolderPid);
2947
2988
  }
2948
- var DEFAULT_STALE_AFTER_MS, DEFAULT_RETRY_DELAY_MS, DEFAULT_MAX_ATTEMPTS, IdentityLockBusyError;
2989
+ var DEFAULT_STALE_AFTER_MS, DEFAULT_RETRY_DELAY_MS, DEFAULT_MAX_ATTEMPTS, IdentityLockLostError, IdentityLockBusyError;
2949
2990
  var init_lock = __esm({
2950
2991
  "src/launcher/lock.ts"() {
2951
2992
  "use strict";
@@ -2953,6 +2994,14 @@ var init_lock = __esm({
2953
2994
  DEFAULT_STALE_AFTER_MS = 12e4;
2954
2995
  DEFAULT_RETRY_DELAY_MS = 50;
2955
2996
  DEFAULT_MAX_ATTEMPTS = 200;
2997
+ IdentityLockLostError = class extends CliError {
2998
+ constructor(identity) {
2999
+ super(`The lock on identity "${identity}" was taken over by another process while it was held, so nothing it guards can be assumed unchanged.`);
3000
+ this.identity = identity;
3001
+ this.name = "IdentityLockLostError";
3002
+ }
3003
+ identity;
3004
+ };
2956
3005
  IdentityLockBusyError = class extends CliError {
2957
3006
  constructor(identity, lockPath, holderPid) {
2958
3007
  super(
@@ -2973,8 +3022,8 @@ var init_lock = __esm({
2973
3022
  // src/launcher/farm.ts
2974
3023
  import path8 from "node:path";
2975
3024
  import { z as z4 } from "zod";
2976
- function readFarmManifest(fs14, farmRoot) {
2977
- const raw = fs14.readFileUtf8(path8.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs14.readFileUtf8(path8.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
3025
+ function readFarmManifest(fs15, farmRoot) {
3026
+ const raw = fs15.readFileUtf8(path8.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs15.readFileUtf8(path8.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
2978
3027
  if (raw === void 0) {
2979
3028
  return void 0;
2980
3029
  }
@@ -3032,9 +3081,9 @@ function buildEntryFacts(params) {
3032
3081
  entries
3033
3082
  };
3034
3083
  }
3035
- function listSubtree(fs14, root, rel) {
3084
+ function listSubtree(fs15, root, rel) {
3036
3085
  const absolute = path8.join(root, rel);
3037
- const stat = fs14.lstat(absolute);
3086
+ const stat = fs15.lstat(absolute);
3038
3087
  if (stat === void 0) {
3039
3088
  return [];
3040
3089
  }
@@ -3042,10 +3091,10 @@ function listSubtree(fs14, root, rel) {
3042
3091
  return [{ rel, kind: "symlink" }];
3043
3092
  }
3044
3093
  if (stat.kind === "dir") {
3045
- const children = [...fs14.readdir(absolute)].sort().flatMap((name) => listSubtree(fs14, root, `${rel}/${name}`));
3094
+ const children = [...fs15.readdir(absolute)].sort().flatMap((name) => listSubtree(fs15, root, `${rel}/${name}`));
3046
3095
  return [{ rel, kind: "dir" }, ...children];
3047
3096
  }
3048
- const contentHash = fs14.hashFile(absolute);
3097
+ const contentHash = fs15.hashFile(absolute);
3049
3098
  return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
3050
3099
  }
3051
3100
  function topLevelScopeRoots(roots) {
@@ -3059,25 +3108,25 @@ function topLevelScopeRoots(roots) {
3059
3108
  }
3060
3109
  return kept;
3061
3110
  }
3062
- function reconciliationScope(fs14, farmRoot, manifest) {
3111
+ function reconciliationScope(fs15, farmRoot, manifest) {
3063
3112
  if (manifest !== void 0) {
3064
3113
  return topLevelScopeRoots(manifest.materialised);
3065
3114
  }
3066
- return [...fs14.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs14.lstat(path8.join(farmRoot, name))?.kind === "dir").sort();
3115
+ return [...fs15.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs15.lstat(path8.join(farmRoot, name))?.kind === "dir").sort();
3067
3116
  }
3068
- function collectFarmListing(fs14, farmRoot, scopeRoots) {
3069
- return scopeRoots.flatMap((root) => listSubtree(fs14, farmRoot, root));
3117
+ function collectFarmListing(fs15, farmRoot, scopeRoots) {
3118
+ return scopeRoots.flatMap((root) => listSubtree(fs15, farmRoot, root));
3070
3119
  }
3071
- function collectCanonicalCounterparts(fs14, claudeHome, farmListing) {
3120
+ function collectCanonicalCounterparts(fs15, claudeHome, farmListing) {
3072
3121
  const out = [];
3073
3122
  for (const entry of farmListing) {
3074
3123
  const absolute = path8.join(claudeHome, entry.rel);
3075
- const stat = fs14.lstat(absolute);
3124
+ const stat = fs15.lstat(absolute);
3076
3125
  if (stat === void 0) {
3077
3126
  continue;
3078
3127
  }
3079
3128
  if (stat.kind === "file") {
3080
- const contentHash = fs14.hashFile(absolute);
3129
+ const contentHash = fs15.hashFile(absolute);
3081
3130
  out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
3082
3131
  continue;
3083
3132
  }
@@ -3319,6 +3368,9 @@ function resyncFarm(params) {
3319
3368
  farmRoot,
3320
3369
  classification: params.classification
3321
3370
  });
3371
+ if (params.identityExists?.() === false) {
3372
+ throw new IdentityGoneError(params.identity);
3373
+ }
3322
3374
  const previousManifest = readFarmManifest(params.fs, farmRoot);
3323
3375
  const scope = reconciliationScope(params.fs, farmRoot, previousManifest);
3324
3376
  const farmListing = collectFarmListing(params.fs, farmRoot, scope);
@@ -3434,13 +3486,14 @@ function recoveryDiagnostics(recovery, identity) {
3434
3486
  }
3435
3487
  ];
3436
3488
  }
3437
- var FARM_MANIFEST_FILENAME, FarmManifestSchema;
3489
+ var FARM_MANIFEST_FILENAME, FarmManifestSchema, IdentityGoneError;
3438
3490
  var init_farm = __esm({
3439
3491
  "src/launcher/farm.ts"() {
3440
3492
  "use strict";
3441
3493
  init_classify();
3442
3494
  init_reconcile();
3443
3495
  init_pipeline();
3496
+ init_cliError();
3444
3497
  init_legacy();
3445
3498
  init_lock();
3446
3499
  FARM_MANIFEST_FILENAME = ".agent-shim-farm.json";
@@ -3454,6 +3507,14 @@ var init_farm = __esm({
3454
3507
  materialised: z4.array(z4.string()),
3455
3508
  links: z4.array(z4.strictObject({ rel: z4.string(), target: z4.string() }))
3456
3509
  });
3510
+ IdentityGoneError = class extends CliError {
3511
+ constructor(identity) {
3512
+ super(`Identity "${identity}" no longer exists: it was renamed or removed while this launch waited for it. Launch it under its current name.`);
3513
+ this.identity = identity;
3514
+ this.name = "IdentityGoneError";
3515
+ }
3516
+ identity;
3517
+ };
3457
3518
  }
3458
3519
  });
3459
3520
 
@@ -3848,10 +3909,10 @@ var init_route = __esm({
3848
3909
  // src/frontdoor/state.ts
3849
3910
  import path9 from "node:path";
3850
3911
  import { z as z5 } from "zod";
3851
- function readFrontDoorState(fs14, stateFile) {
3912
+ function readFrontDoorState(fs15, stateFile) {
3852
3913
  let raw;
3853
3914
  try {
3854
- raw = fs14.readFileUtf8(stateFile);
3915
+ raw = fs15.readFileUtf8(stateFile);
3855
3916
  } catch {
3856
3917
  return void 0;
3857
3918
  }
@@ -3865,9 +3926,9 @@ function readFrontDoorState(fs14, stateFile) {
3865
3926
  return void 0;
3866
3927
  }
3867
3928
  }
3868
- function writeFrontDoorState(fs14, stateFile, state) {
3869
- fs14.mkdirp(path9.dirname(stateFile));
3870
- fs14.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
3929
+ function writeFrontDoorState(fs15, stateFile, state) {
3930
+ fs15.mkdirp(path9.dirname(stateFile));
3931
+ fs15.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
3871
3932
  `);
3872
3933
  }
3873
3934
  function directOrigin(port) {
@@ -3877,37 +3938,37 @@ function frontDoorOrigin(state) {
3877
3938
  const port = state?.directPort ?? state?.lastDirectPort;
3878
3939
  return port === void 0 ? void 0 : directOrigin(port);
3879
3940
  }
3880
- function writeFrontDoorDirectRecord(fs14, recordsDir, record) {
3881
- fs14.mkdirp(recordsDir);
3882
- fs14.writeFilePrivate(path9.join(recordsDir, `${String(record.pid)}.json`), `${JSON.stringify({ directPort: record.directPort })}
3941
+ function writeFrontDoorDirectRecord(fs15, recordsDir, record) {
3942
+ fs15.mkdirp(recordsDir);
3943
+ fs15.writeFilePrivate(path9.join(recordsDir, `${String(record.pid)}.json`), `${JSON.stringify({ directPort: record.directPort })}
3883
3944
  `);
3884
3945
  }
3885
- function removeFrontDoorDirectRecord(fs14, recordsDir, pid) {
3886
- fs14.removeRecursive(path9.join(recordsDir, `${String(pid)}.json`));
3946
+ function removeFrontDoorDirectRecord(fs15, recordsDir, pid) {
3947
+ fs15.removeRecursive(path9.join(recordsDir, `${String(pid)}.json`));
3887
3948
  }
3888
- function markFrontDoorDraining(fs14, markersDir, pid) {
3889
- fs14.mkdirp(markersDir);
3890
- fs14.writeFilePrivate(path9.join(markersDir, String(pid)), "\n");
3949
+ function markFrontDoorDraining(fs15, markersDir, pid) {
3950
+ fs15.mkdirp(markersDir);
3951
+ fs15.writeFilePrivate(path9.join(markersDir, String(pid)), "\n");
3891
3952
  }
3892
- function unmarkFrontDoorDraining(fs14, markersDir, pid) {
3893
- fs14.removeRecursive(path9.join(markersDir, String(pid)));
3953
+ function unmarkFrontDoorDraining(fs15, markersDir, pid) {
3954
+ fs15.removeRecursive(path9.join(markersDir, String(pid)));
3894
3955
  }
3895
- function listDrainingFrontDoors(fs14, markersDir, isRunning) {
3896
- return fs14.readdir(markersDir).flatMap((file) => /^[1-9]\d*$/.test(file) && Number.isSafeInteger(Number(file)) ? [Number(file)] : []).filter(isRunning).sort((a, b) => a - b);
3956
+ function listDrainingFrontDoors(fs15, markersDir, isRunning) {
3957
+ return fs15.readdir(markersDir).flatMap((file) => /^[1-9]\d*$/.test(file) && Number.isSafeInteger(Number(file)) ? [Number(file)] : []).filter(isRunning).sort((a, b) => a - b);
3897
3958
  }
3898
3959
  function recordPid(file) {
3899
3960
  const pidText = /^([1-9]\d*)\.json$/.exec(file)?.[1];
3900
3961
  const pid = pidText === void 0 ? void 0 : Number(pidText);
3901
3962
  return pid !== void 0 && Number.isSafeInteger(pid) ? pid : void 0;
3902
3963
  }
3903
- function readDirectRecordEntry(fs14, recordsDir, file) {
3964
+ function readDirectRecordEntry(fs15, recordsDir, file) {
3904
3965
  const pid = recordPid(file);
3905
3966
  if (pid === void 0) {
3906
3967
  return void 0;
3907
3968
  }
3908
3969
  let raw;
3909
3970
  try {
3910
- raw = fs14.readFileUtf8(path9.join(recordsDir, file));
3971
+ raw = fs15.readFileUtf8(path9.join(recordsDir, file));
3911
3972
  } catch {
3912
3973
  return void 0;
3913
3974
  }
@@ -3921,37 +3982,37 @@ function readDirectRecordEntry(fs14, recordsDir, file) {
3921
3982
  return { malformed: true };
3922
3983
  }
3923
3984
  }
3924
- function listFrontDoorDirectRecords(fs14, recordsDir) {
3925
- return fs14.readdir(recordsDir).flatMap((file) => {
3926
- const entry = readDirectRecordEntry(fs14, recordsDir, file);
3985
+ function listFrontDoorDirectRecords(fs15, recordsDir) {
3986
+ return fs15.readdir(recordsDir).flatMap((file) => {
3987
+ const entry = readDirectRecordEntry(fs15, recordsDir, file);
3927
3988
  return entry?.record === void 0 ? [] : [entry.record];
3928
3989
  }).sort((a, b) => a.pid - b.pid);
3929
3990
  }
3930
- function pruneMalformedFrontDoorDirectFiles(fs14, recordsDir, isRunning) {
3931
- for (const file of fs14.readdir(recordsDir)) {
3991
+ function pruneMalformedFrontDoorDirectFiles(fs15, recordsDir, isRunning) {
3992
+ for (const file of fs15.readdir(recordsDir)) {
3932
3993
  const writer = RECORD_TEMPORARY_FILE.exec(file)?.[1];
3933
3994
  const stale = writer !== void 0 && !isRunning(Number(writer));
3934
- if (stale || readDirectRecordEntry(fs14, recordsDir, file)?.malformed === true) {
3935
- fs14.removeRecursive(path9.join(recordsDir, file));
3995
+ if (stale || readDirectRecordEntry(fs15, recordsDir, file)?.malformed === true) {
3996
+ fs15.removeRecursive(path9.join(recordsDir, file));
3936
3997
  }
3937
3998
  }
3938
3999
  }
3939
4000
  function liveFrontDoorDirectRecords(records, liveness) {
3940
4001
  return records.filter((record) => liveness.doors.has(record.pid) || liveness.unknown.has(record.pid));
3941
4002
  }
3942
- function pruneDeadFrontDoorDirectRecords(fs14, recordsDir, records, liveness) {
4003
+ function pruneDeadFrontDoorDirectRecords(fs15, recordsDir, records, liveness) {
3943
4004
  for (const record of records) {
3944
4005
  if (!liveness.doors.has(record.pid) && !liveness.unknown.has(record.pid)) {
3945
- removeFrontDoorDirectRecord(fs14, recordsDir, record.pid);
4006
+ removeFrontDoorDirectRecord(fs15, recordsDir, record.pid);
3946
4007
  }
3947
4008
  }
3948
4009
  }
3949
4010
  function recordOf(details) {
3950
4011
  return details === void 0 ? {} : { sessionId: details.sessionId, ...details.models === void 0 ? {} : { models: details.models } };
3951
4012
  }
3952
- function writeFrontDoorSession(fs14, sessionsDir, session) {
3953
- fs14.mkdirPrivate(sessionsDir);
3954
- fs14.writeFilePrivate(path9.join(sessionsDir, sessionRecordName(session.pid)), `${JSON.stringify(session, null, 2)}
4013
+ function writeFrontDoorSession(fs15, sessionsDir, session) {
4014
+ fs15.mkdirPrivate(sessionsDir);
4015
+ fs15.writeFilePrivate(path9.join(sessionsDir, sessionRecordName(session.pid)), `${JSON.stringify(session, null, 2)}
3955
4016
  `);
3956
4017
  }
3957
4018
  function sessionRecordName(pid) {
@@ -3963,32 +4024,32 @@ function isSessionRecordName(name) {
3963
4024
  function summaryOf(session) {
3964
4025
  return { pid: session.pid, startedAt: session.startedAt, ...session.supervisorPid === void 0 ? {} : { supervisorPid: session.supervisorPid } };
3965
4026
  }
3966
- function readFrontDoorSessionRecord(fs14, sessionsDir, name) {
4027
+ function readFrontDoorSessionRecord(fs15, sessionsDir, name) {
3967
4028
  try {
3968
- const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs14.readFileUtf8(path9.join(sessionsDir, name)) ?? ""));
4029
+ const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs15.readFileUtf8(path9.join(sessionsDir, name)) ?? ""));
3969
4030
  return parsed.success ? parsed.data : void 0;
3970
4031
  } catch {
3971
4032
  return void 0;
3972
4033
  }
3973
4034
  }
3974
- function listFrontDoorSessions(fs14, sessionsDir) {
4035
+ function listFrontDoorSessions(fs15, sessionsDir) {
3975
4036
  const sessions = [];
3976
- for (const name of fs14.readdir(sessionsDir)) {
3977
- const record = isSessionRecordName(name) ? readFrontDoorSessionRecord(fs14, sessionsDir, name) : void 0;
4037
+ for (const name of fs15.readdir(sessionsDir)) {
4038
+ const record = isSessionRecordName(name) ? readFrontDoorSessionRecord(fs15, sessionsDir, name) : void 0;
3978
4039
  if (record !== void 0) {
3979
4040
  sessions.push(summaryOf(record));
3980
4041
  }
3981
4042
  }
3982
4043
  return sessions.sort((a, b) => a.pid - b.pid);
3983
4044
  }
3984
- function removeFrontDoorSession(fs14, sessionsDir, pid) {
3985
- fs14.removeRecursive(path9.join(sessionsDir, sessionRecordName(pid)));
4045
+ function removeFrontDoorSession(fs15, sessionsDir, pid) {
4046
+ fs15.removeRecursive(path9.join(sessionsDir, sessionRecordName(pid)));
3986
4047
  }
3987
- function pruneDeadFrontDoorSessions(fs14, sessionsDir, listed, isRunning) {
4048
+ function pruneDeadFrontDoorSessions(fs15, sessionsDir, listed, isRunning) {
3988
4049
  const removed = [];
3989
4050
  for (const session of listed) {
3990
4051
  if (!isRunning(session.pid)) {
3991
- removeFrontDoorSession(fs14, sessionsDir, session.pid);
4052
+ removeFrontDoorSession(fs15, sessionsDir, session.pid);
3992
4053
  removed.push(session.pid);
3993
4054
  }
3994
4055
  }
@@ -4086,9 +4147,9 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
4086
4147
  }
4087
4148
  }
4088
4149
  async function serveFrontDoor(idleShutdownMinutes, ports, options) {
4089
- const { fs: fs14, paths } = ports;
4150
+ const { fs: fs15, paths } = ports;
4090
4151
  const servingBinary = ports.statOwnExecutable();
4091
- const previous = readFrontDoorState(fs14, paths.frontdoorStateFile);
4152
+ const previous = readFrontDoorState(fs15, paths.frontdoorStateFile);
4092
4153
  let lastPort = previous?.lastPort;
4093
4154
  let lastConnectPort = previous?.lastConnectPort;
4094
4155
  let lastDirectPort = previous?.lastDirectPort;
@@ -4102,14 +4163,14 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
4102
4163
  const fail = (message) => {
4103
4164
  ports.closeRcStreamHub();
4104
4165
  if (predecessor === void 0) {
4105
- writeFrontDoorState(fs14, paths.frontdoorStateFile, { lastError: message, ...sticky() });
4106
- fs14.removeRecursive(paths.frontdoorLockFile);
4166
+ writeFrontDoorState(fs15, paths.frontdoorStateFile, { lastError: message, ...sticky() });
4167
+ fs15.removeRecursive(paths.frontdoorLockFile);
4107
4168
  }
4108
4169
  ports.log(`agent-shim frontdoor supervisor: ${message}`);
4109
4170
  return 1;
4110
4171
  };
4111
4172
  if (predecessor === void 0) {
4112
- writeFrontDoorState(fs14, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
4173
+ writeFrontDoorState(fs15, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
4113
4174
  }
4114
4175
  const previousSticky = lastPort;
4115
4176
  let http3;
@@ -4150,11 +4211,11 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
4150
4211
  ports.log(`agent-shim frontdoor supervisor: sticky direct port ${String(previousStickyDirect)} was occupied; moving to ${String(direct.port)} (headroom admits the new address once its supervisor rewrites the allowlist file)`);
4151
4212
  }
4152
4213
  lastDirectPort = direct.port;
4153
- writeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, { pid: ports.ownPid, directPort: direct.port });
4154
- writeFrontDoorState(fs14, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
4214
+ writeFrontDoorDirectRecord(fs15, paths.frontdoorDirectRecordsDir, { pid: ports.ownPid, directPort: direct.port });
4215
+ writeFrontDoorState(fs15, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
4155
4216
  ports.doorHealth.generation({ providerPort: http3.port, connectPort: connect3.port, directPort: direct.port });
4156
4217
  if (predecessor === void 0) {
4157
- fs14.removeRecursive(paths.frontdoorLockFile);
4218
+ fs15.removeRecursive(paths.frontdoorLockFile);
4158
4219
  } else {
4159
4220
  predecessor.serving();
4160
4221
  }
@@ -4163,7 +4224,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
4163
4224
  let idleSince;
4164
4225
  let ticks = 0;
4165
4226
  const supersedingOwner = async () => {
4166
- const owner = readFrontDoorState(fs14, paths.frontdoorStateFile)?.supervisorPid;
4227
+ const owner = readFrontDoorState(fs15, paths.frontdoorStateFile)?.supervisorPid;
4167
4228
  return owner !== void 0 && owner !== ports.ownPid && (await ports.runningAmong([owner])).has(owner) ? owner : void 0;
4168
4229
  };
4169
4230
  let supersededBy;
@@ -4192,13 +4253,13 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
4192
4253
  ports.stopBackgroundWork?.();
4193
4254
  const drained = [direct.drain(), connect3.drain(), http3.drain()];
4194
4255
  if (await supersedingOwner() === void 0) {
4195
- writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
4256
+ writeFrontDoorState(fs15, paths.frontdoorStateFile, sticky());
4196
4257
  }
4197
- markFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
4258
+ markFrontDoorDraining(fs15, paths.frontdoorDrainingDir, ports.ownPid);
4198
4259
  ports.closeRcStreamHub();
4199
4260
  await Promise.all(drained);
4200
- unmarkFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
4201
- removeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, ports.ownPid);
4261
+ unmarkFrontDoorDraining(fs15, paths.frontdoorDrainingDir, ports.ownPid);
4262
+ removeFrontDoorDirectRecord(fs15, paths.frontdoorDirectRecordsDir, ports.ownPid);
4202
4263
  ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: the connections this door carried have ended; exiting`);
4203
4264
  return 0;
4204
4265
  };
@@ -4219,12 +4280,12 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
4219
4280
  await connect3.close();
4220
4281
  await http3.close();
4221
4282
  ports.closeRcStreamHub();
4222
- removeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, ports.ownPid);
4283
+ removeFrontDoorDirectRecord(fs15, paths.frontdoorDirectRecordsDir, ports.ownPid);
4223
4284
  };
4224
4285
  const shutdown = async () => {
4225
4286
  await closeServing();
4226
4287
  if (await supersedingOwner() === void 0) {
4227
- writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
4288
+ writeFrontDoorState(fs15, paths.frontdoorStateFile, sticky());
4228
4289
  }
4229
4290
  return 0;
4230
4291
  };
@@ -4243,7 +4304,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
4243
4304
  ticks += 1;
4244
4305
  const listed = ports.registry.rescan();
4245
4306
  const running = await ports.runningAmong(listed.map((session) => session.pid));
4246
- const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, listed, (pid) => running.has(pid));
4307
+ const pruned = pruneDeadFrontDoorSessions(fs15, paths.frontdoorSessionsDir, listed, (pid) => running.has(pid));
4247
4308
  ports.registry.forget(pruned);
4248
4309
  ports.observeLaunchRegistry(listed, pruned);
4249
4310
  ports.checkQuotaExpiry();
@@ -4318,8 +4379,8 @@ function parseConnectTarget(authority) {
4318
4379
  function isInterceptedHost(host, interceptHosts) {
4319
4380
  return interceptHosts.includes(host);
4320
4381
  }
4321
- function servedByPipeline(path42) {
4322
- return path42?.startsWith(ROUTED_PATH_PREFIX) === true;
4382
+ function servedByPipeline(path45) {
4383
+ return path45?.startsWith(ROUTED_PATH_PREFIX) === true;
4323
4384
  }
4324
4385
  function forwardableHeaders(headers) {
4325
4386
  const connectionTokens = new Set(
@@ -4763,7 +4824,7 @@ var init_package = __esm({
4763
4824
  "package.json"() {
4764
4825
  package_default = {
4765
4826
  name: "agent-shim",
4766
- version: "11.82.0",
4827
+ version: "11.83.1",
4767
4828
  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.",
4768
4829
  license: "MIT",
4769
4830
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4815,7 +4876,7 @@ var init_package = __esm({
4815
4876
  "@anthropic-ai/claude-agent-sdk": "0.3.292",
4816
4877
  "@clack/prompts": "^1.8.0",
4817
4878
  "@modelcontextprotocol/sdk": "1.32.0",
4818
- "@orpc/client": "2.0.0-beta.43",
4879
+ "@orpc/client": "2.0.0-beta.46",
4819
4880
  "@orpc/openapi": "2.0.0-beta.43",
4820
4881
  "@orpc/server": "2.0.0-beta.43",
4821
4882
  commander: "^15.0.0",
@@ -4989,43 +5050,43 @@ function parseJson(raw, schema) {
4989
5050
  const parsed = schema.safeParse(JSON.parse(raw));
4990
5051
  return parsed.success ? parsed.data : void 0;
4991
5052
  }
4992
- function readHeadroomState(fs14, stateFile) {
5053
+ function readHeadroomState(fs15, stateFile) {
4993
5054
  try {
4994
- return parseJson(fs14.readFileUtf8(stateFile), HeadroomStateSchema);
5055
+ return parseJson(fs15.readFileUtf8(stateFile), HeadroomStateSchema);
4995
5056
  } catch {
4996
5057
  return void 0;
4997
5058
  }
4998
5059
  }
4999
- function writeHeadroomState(fs14, stateFile, state) {
5000
- fs14.mkdirp(path12.dirname(stateFile));
5001
- fs14.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
5060
+ function writeHeadroomState(fs15, stateFile, state) {
5061
+ fs15.mkdirp(path12.dirname(stateFile));
5062
+ fs15.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
5002
5063
  `);
5003
5064
  }
5004
- function resolveServingHeadroomState(fs14, files, isRunning) {
5005
- const current = readHeadroomState(fs14, files.stateFile);
5065
+ function resolveServingHeadroomState(fs15, files, isRunning) {
5066
+ const current = readHeadroomState(fs15, files.stateFile);
5006
5067
  if (current !== void 0) {
5007
5068
  return { path: files.stateFile, state: current };
5008
5069
  }
5009
- const legacy = readHeadroomState(fs14, files.legacyStateFile);
5070
+ const legacy = readHeadroomState(fs15, files.legacyStateFile);
5010
5071
  if (legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid)) {
5011
5072
  return { path: files.legacyStateFile, state: legacy };
5012
5073
  }
5013
5074
  return void 0;
5014
5075
  }
5015
- function migrateHeadroomState(fs14, files, isRunning) {
5016
- const legacy = readHeadroomState(fs14, files.legacyStateFile);
5076
+ function migrateHeadroomState(fs15, files, isRunning) {
5077
+ const legacy = readHeadroomState(fs15, files.legacyStateFile);
5017
5078
  const legacyLive = legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid);
5018
- const current = readHeadroomState(fs14, files.stateFile);
5079
+ const current = readHeadroomState(fs15, files.stateFile);
5019
5080
  if (current !== void 0 || legacyLive) {
5020
- if (!legacyLive && fs14.readFileUtf8(files.legacyStateFile) !== void 0) {
5021
- fs14.removeRecursive(files.legacyStateFile);
5081
+ if (!legacyLive && fs15.readFileUtf8(files.legacyStateFile) !== void 0) {
5082
+ fs15.removeRecursive(files.legacyStateFile);
5022
5083
  }
5023
5084
  return;
5024
5085
  }
5025
5086
  if (legacy !== void 0) {
5026
- writeHeadroomState(fs14, files.stateFile, legacy);
5087
+ writeHeadroomState(fs15, files.stateFile, legacy);
5027
5088
  }
5028
- fs14.removeRecursive(files.legacyStateFile);
5089
+ fs15.removeRecursive(files.legacyStateFile);
5029
5090
  }
5030
5091
  function hashAllowlist(allowlist) {
5031
5092
  return createHash3("sha256").update(allowlist.join("\n")).digest("hex");
@@ -5058,27 +5119,27 @@ function isAdmissibleUrl(entry) {
5058
5119
  function parseAllowlistFile(content) {
5059
5120
  return content.replace(/^\uFEFF/, "").replace(ALLOWLIST_FILE_COMMENT, "").split(ALLOWLIST_FILE_SEPARATORS).map((entry) => entry.replace(ALLOWLIST_SURROUNDING_WHITESPACE, "")).filter((entry) => entry !== "" && !ALLOWLIST_ENTRY_WHITESPACE.test(entry) && (entry.includes("://") ? isAdmissibleUrl(entry) : isBareHost(entry)));
5060
5121
  }
5061
- function writeAllowlistFile(fs14, allowlistFile, allowlist) {
5062
- fs14.mkdirPrivate(path12.dirname(allowlistFile));
5063
- fs14.writeFilePrivate(allowlistFile, formatAllowlistFile(allowlist));
5122
+ function writeAllowlistFile(fs15, allowlistFile, allowlist) {
5123
+ fs15.mkdirPrivate(path12.dirname(allowlistFile));
5124
+ fs15.writeFilePrivate(allowlistFile, formatAllowlistFile(allowlist));
5064
5125
  }
5065
- function pruneStaleAllowlistTemporaries(fs14, allowlistFile, isRunning) {
5126
+ function pruneStaleAllowlistTemporaries(fs15, allowlistFile, isRunning) {
5066
5127
  const prefix = `${path12.basename(allowlistFile)}.`;
5067
- for (const name of fs14.readdir(path12.dirname(allowlistFile))) {
5128
+ for (const name of fs15.readdir(path12.dirname(allowlistFile))) {
5068
5129
  const writer = name.startsWith(prefix) ? /^([1-9]\d*)\.tmp$/.exec(name.slice(prefix.length))?.[1] : void 0;
5069
5130
  if (writer !== void 0 && !isRunning(Number(writer))) {
5070
- fs14.removeRecursive(path12.join(path12.dirname(allowlistFile), name));
5131
+ fs15.removeRecursive(path12.join(path12.dirname(allowlistFile), name));
5071
5132
  }
5072
5133
  }
5073
5134
  }
5074
- function readAllProviders(fs14, providersDir) {
5135
+ function readAllProviders(fs15, providersDir) {
5075
5136
  const result = [];
5076
- for (const name of fs14.readdir(providersDir)) {
5137
+ for (const name of fs15.readdir(providersDir)) {
5077
5138
  if (!name.endsWith(".json")) {
5078
5139
  continue;
5079
5140
  }
5080
5141
  try {
5081
- const parsed = parseJson(fs14.readFileUtf8(path12.join(providersDir, name)), ProviderSchema);
5142
+ const parsed = parseJson(fs15.readFileUtf8(path12.join(providersDir, name)), ProviderSchema);
5082
5143
  if (parsed !== void 0) {
5083
5144
  result.push({ name: name.slice(0, -".json".length), provider: parsed });
5084
5145
  }
@@ -5088,22 +5149,22 @@ function readAllProviders(fs14, providersDir) {
5088
5149
  }
5089
5150
  return result;
5090
5151
  }
5091
- function writeSession(fs14, sessionsDir, session) {
5092
- fs14.mkdirp(sessionsDir);
5093
- fs14.writeFileUtf8(path12.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
5152
+ function writeSession(fs15, sessionsDir, session) {
5153
+ fs15.mkdirp(sessionsDir);
5154
+ fs15.writeFileUtf8(path12.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
5094
5155
  `);
5095
5156
  }
5096
- function removeSession(fs14, sessionsDir, pid) {
5097
- fs14.removeRecursive(path12.join(sessionsDir, `${String(pid)}.json`));
5157
+ function removeSession(fs15, sessionsDir, pid) {
5158
+ fs15.removeRecursive(path12.join(sessionsDir, `${String(pid)}.json`));
5098
5159
  }
5099
- function listSessions(fs14, sessionsDir) {
5160
+ function listSessions(fs15, sessionsDir) {
5100
5161
  const sessions = [];
5101
- for (const name of fs14.readdir(sessionsDir)) {
5162
+ for (const name of fs15.readdir(sessionsDir)) {
5102
5163
  if (!name.endsWith(".json")) {
5103
5164
  continue;
5104
5165
  }
5105
5166
  try {
5106
- const parsed = parseJson(fs14.readFileUtf8(path12.join(sessionsDir, name)), HeadroomSessionSchema);
5167
+ const parsed = parseJson(fs15.readFileUtf8(path12.join(sessionsDir, name)), HeadroomSessionSchema);
5107
5168
  if (parsed !== void 0) {
5108
5169
  sessions.push(parsed);
5109
5170
  }
@@ -5113,22 +5174,22 @@ function listSessions(fs14, sessionsDir) {
5113
5174
  }
5114
5175
  return sessions.sort((a, b) => a.pid - b.pid);
5115
5176
  }
5116
- function sessionsForSupervisor(fs14, sessionsDir, supervisorPid) {
5117
- return listSessions(fs14, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
5177
+ function sessionsForSupervisor(fs15, sessionsDir, supervisorPid) {
5178
+ return listSessions(fs15, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
5118
5179
  }
5119
- function pruneDeadSessions(fs14, sessionsDir, isRunning) {
5180
+ function pruneDeadSessions(fs15, sessionsDir, isRunning) {
5120
5181
  const removed = [];
5121
- for (const session of listSessions(fs14, sessionsDir)) {
5182
+ for (const session of listSessions(fs15, sessionsDir)) {
5122
5183
  if (!isRunning(session.pid)) {
5123
- removeSession(fs14, sessionsDir, session.pid);
5184
+ removeSession(fs15, sessionsDir, session.pid);
5124
5185
  removed.push(session.pid);
5125
5186
  }
5126
5187
  }
5127
5188
  return removed;
5128
5189
  }
5129
- function readStartLock(fs14, lockFile) {
5190
+ function readStartLock(fs15, lockFile) {
5130
5191
  try {
5131
- return parseJson(fs14.readFileUtf8(lockFile), HeadroomLockSchema);
5192
+ return parseJson(fs15.readFileUtf8(lockFile), HeadroomLockSchema);
5132
5193
  } catch {
5133
5194
  return void 0;
5134
5195
  }
@@ -5218,12 +5279,12 @@ function earlierReleaseAllowlistHash(providers, doorOrigin) {
5218
5279
  }
5219
5280
  return hashAllowlist([...entries].sort());
5220
5281
  }
5221
- function earlierReleaseDaemon(fs14, paths, daemon) {
5282
+ function earlierReleaseDaemon(fs15, paths, daemon) {
5222
5283
  if (daemonIdentity(daemon.commandLine, daemon.socketPath) !== "earlier-release") {
5223
5284
  return void 0;
5224
5285
  }
5225
- const providers = readAllProviders(fs14, paths.providersDir).map((entry) => entry.provider);
5226
- const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile)));
5286
+ const providers = readAllProviders(fs15, paths.providersDir).map((entry) => entry.provider);
5287
+ const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(fs15, paths.frontdoorStateFile)));
5227
5288
  return { admitsServingDoor: daemon.recordedHash === expected };
5228
5289
  }
5229
5290
  var EARLIER_RELEASE_ALLOWLIST, EARLIER_RELEASE_ANTHROPIC_UPSTREAM;
@@ -5248,8 +5309,8 @@ function awaitingCause(daemonPid, identity, allowlistFile) {
5248
5309
  }
5249
5310
  return `the headroom supervisor has not written an allowlist admitting this launch's upstreams to ${allowlistFile} within ${String(HEADROOM_START_TIMEOUT_MS)}ms`;
5250
5311
  }
5251
- function daemonAdmits(fs14, allowlistFile, recordedHash, required) {
5252
- const content = fs14.readFileUtf8(allowlistFile);
5312
+ function daemonAdmits(fs15, allowlistFile, recordedHash, required) {
5313
+ const content = fs15.readFileUtf8(allowlistFile);
5253
5314
  if (content === void 0 || recordedHash === void 0) {
5254
5315
  return false;
5255
5316
  }
@@ -5518,7 +5579,7 @@ function verifyAllowlistFile(allowlistFile, ports) {
5518
5579
  const replaceable = fileStat === void 0 || fileStat.kind === "file" || fileStat.kind === "symlink";
5519
5580
  return { message: refusal2, repairable: replaceable };
5520
5581
  }
5521
- function prepareHeadroomSocket(fs14, ports, paths, supervisorPid) {
5582
+ function prepareHeadroomSocket(fs15, ports, paths, supervisorPid) {
5522
5583
  const unsupported = platformRefusal(ports.platform);
5523
5584
  if (unsupported !== void 0) {
5524
5585
  return { refused: unsupported };
@@ -5533,18 +5594,18 @@ function prepareHeadroomSocket(fs14, ports, paths, supervisorPid) {
5533
5594
  if (ports.lstat(paths.headroomSocketDir)?.kind === "symlink") {
5534
5595
  return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
5535
5596
  }
5536
- fs14.mkdirPrivate(paths.headroomSocketDir);
5597
+ fs15.mkdirPrivate(paths.headroomSocketDir);
5537
5598
  const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
5538
5599
  return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
5539
5600
  }
5540
- function pruneStaleHeadroomSockets(fs14, paths, isRunning) {
5601
+ function pruneStaleHeadroomSockets(fs15, paths, isRunning) {
5541
5602
  const removed = [];
5542
- for (const name of fs14.readdir(paths.headroomSocketDir)) {
5603
+ for (const name of fs15.readdir(paths.headroomSocketDir)) {
5543
5604
  const pid = HEADROOM_SOCKET_NAME.exec(name)?.[1];
5544
5605
  if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
5545
5606
  continue;
5546
5607
  }
5547
- fs14.removeRecursive(path13.join(paths.headroomSocketDir, name));
5608
+ fs15.removeRecursive(path13.join(paths.headroomSocketDir, name));
5548
5609
  removed.push(name);
5549
5610
  }
5550
5611
  return removed;
@@ -5656,37 +5717,37 @@ function compareVersions2(a, b) {
5656
5717
  return 0;
5657
5718
  }
5658
5719
  async function runSupervisor(initialConfig, ports, options = {}) {
5659
- const { fs: fs14, paths } = ports;
5720
+ const { fs: fs15, paths } = ports;
5660
5721
  let config = initialConfig;
5661
- migrateHeadroomState(fs14, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
5662
- const previousState = resolveServingHeadroomState(fs14, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
5722
+ migrateHeadroomState(fs15, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
5723
+ const previousState = resolveServingHeadroomState(fs15, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
5663
5724
  if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
5664
5725
  ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
5665
5726
  return 0;
5666
5727
  }
5667
5728
  let installedSource = previousState?.installedSource;
5668
5729
  const ownsState = () => {
5669
- const owner = readHeadroomState(fs14, paths.headroomStateFile)?.supervisorPid;
5730
+ const owner = readHeadroomState(fs15, paths.headroomStateFile)?.supervisorPid;
5670
5731
  return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
5671
5732
  };
5672
5733
  const writeOwnState = (state) => {
5673
5734
  if (!ownsState()) {
5674
5735
  return false;
5675
5736
  }
5676
- writeHeadroomState(fs14, paths.headroomStateFile, state);
5737
+ writeHeadroomState(fs15, paths.headroomStateFile, state);
5677
5738
  return true;
5678
5739
  };
5679
5740
  const fail = (message) => {
5680
5741
  if (writeOwnState({ lastError: message })) {
5681
- fs14.removeRecursive(paths.headroomLockFile);
5742
+ fs15.removeRecursive(paths.headroomLockFile);
5682
5743
  }
5683
5744
  ports.log(`agent-shim headroom supervisor: ${message}`);
5684
5745
  return 1;
5685
5746
  };
5686
5747
  const syncAllowlistFile = (allowlist) => {
5687
5748
  try {
5688
- if (fs14.readFileUtf8(paths.headroomAllowlistFile) !== formatAllowlistFile(allowlist)) {
5689
- writeAllowlistFile(fs14, paths.headroomAllowlistFile, allowlist);
5749
+ if (fs15.readFileUtf8(paths.headroomAllowlistFile) !== formatAllowlistFile(allowlist)) {
5750
+ writeAllowlistFile(fs15, paths.headroomAllowlistFile, allowlist);
5690
5751
  ports.log(`agent-shim headroom supervisor: wrote allowlist [${allowlist.join(", ")}] to ${paths.headroomAllowlistFile}`);
5691
5752
  }
5692
5753
  return void 0;
@@ -5704,9 +5765,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5704
5765
  }
5705
5766
  ports.log(`agent-shim headroom supervisor: repairing the allowlist file: ${problem.message}`);
5706
5767
  try {
5707
- fs14.mkdirPrivate(paths.headroomDir);
5708
- fs14.mkdirPrivate(path14.dirname(paths.headroomAllowlistFile));
5709
- writeAllowlistFile(fs14, paths.headroomAllowlistFile, allowlist);
5768
+ fs15.mkdirPrivate(paths.headroomDir);
5769
+ fs15.mkdirPrivate(path14.dirname(paths.headroomAllowlistFile));
5770
+ writeAllowlistFile(fs15, paths.headroomAllowlistFile, allowlist);
5710
5771
  } catch (error) {
5711
5772
  return `could not write the headroom allowlist file ${paths.headroomAllowlistFile}: ${error instanceof Error ? error.message : String(error)}`;
5712
5773
  }
@@ -5731,20 +5792,20 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5731
5792
  installedSource = config.source;
5732
5793
  return void 0;
5733
5794
  };
5734
- const socket = prepareHeadroomSocket(fs14, ports.socketTrust, paths, ports.ownPid);
5795
+ const socket = prepareHeadroomSocket(fs15, ports.socketTrust, paths, ports.ownPid);
5735
5796
  if (socket.refused !== void 0) {
5736
5797
  return fail(socket.refused);
5737
5798
  }
5738
5799
  const { socketPath } = socket;
5739
- pruneStaleHeadroomSockets(fs14, paths, ports.isRunning);
5740
- pruneStaleAllowlistTemporaries(fs14, paths.headroomAllowlistFile, ports.isRunning);
5800
+ pruneStaleHeadroomSockets(fs15, paths, ports.isRunning);
5801
+ pruneStaleAllowlistTemporaries(fs15, paths.headroomAllowlistFile, ports.isRunning);
5741
5802
  const installFailure = ensureInstalled();
5742
5803
  if (installFailure !== void 0) {
5743
5804
  return fail(installFailure);
5744
5805
  }
5745
5806
  const version = ports.headroomVersion() ?? "unknown";
5746
5807
  writeOwnState({ supervisorPid: ports.ownPid, version, installedSource });
5747
- ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(fs14, paths, ports.frontDoorLiveness).frontDoorOrigins.join(", ")}]`);
5808
+ ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(fs15, paths, ports.frontDoorLiveness).frontDoorOrigins.join(", ")}]`);
5748
5809
  const orphanPid = previousState?.headroomPid;
5749
5810
  const orphanSocket = previousState?.socketPath ?? (previousState?.supervisorPid === void 0 ? void 0 : headroomSocketPath(paths, previousState.supervisorPid));
5750
5811
  const orphanIdentity = orphanPid === void 0 || orphanSocket === void 0 || !ports.isRunning(orphanPid) ? void 0 : daemonIdentity(ports.daemonCommandLine(orphanPid), orphanSocket);
@@ -5782,12 +5843,12 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5782
5843
  }
5783
5844
  config = ports.readConfig();
5784
5845
  const settingsHash = hashSettings(config.settings);
5785
- const inputs = currentHeadroomAllowlistInputs(fs14, paths, ports.frontDoorLiveness);
5786
- pruneDeadFrontDoorDirectRecords(fs14, paths.frontdoorDirectRecordsDir, inputs.frontDoorRecords, inputs.frontDoorLiveness);
5787
- pruneMalformedFrontDoorDirectFiles(fs14, paths.frontdoorDirectRecordsDir, ports.isRunning);
5846
+ const inputs = currentHeadroomAllowlistInputs(fs15, paths, ports.frontDoorLiveness);
5847
+ pruneDeadFrontDoorDirectRecords(fs15, paths.frontdoorDirectRecordsDir, inputs.frontDoorRecords, inputs.frontDoorLiveness);
5848
+ pruneMalformedFrontDoorDirectFiles(fs15, paths.frontdoorDirectRecordsDir, ports.isRunning);
5788
5849
  const allowlist = inputs.frontDoorOrigins;
5789
5850
  const allowlistHash = hashAllowlist(allowlist);
5790
- pruneDeadSessions(fs14, paths.headroomSessionsDir, ports.isRunning);
5851
+ pruneDeadSessions(fs15, paths.headroomSessionsDir, ports.isRunning);
5791
5852
  const ownsNow = ownsState();
5792
5853
  if (!ownsNow && !superseded) {
5793
5854
  ports.log("agent-shim headroom supervisor: another supervisor now owns the state file; serving this daemon's own sessions until they end");
@@ -5834,7 +5895,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5834
5895
  runningSettingsHash = settingsHash;
5835
5896
  const recorded = writeOwnState(servingState(pid));
5836
5897
  if (recorded) {
5837
- fs14.removeRecursive(paths.headroomLockFile);
5898
+ fs15.removeRecursive(paths.headroomLockFile);
5838
5899
  }
5839
5900
  idleSince = void 0;
5840
5901
  ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on unix socket ${socketPath}`);
@@ -5862,7 +5923,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5862
5923
  ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} now serves allowlist [${allowlist.join(", ")}]`);
5863
5924
  }
5864
5925
  if (runningSettingsHash !== settingsHash || installedSource !== config.source) {
5865
- if (sessionsForSupervisor(fs14, paths.headroomSessionsDir, ports.ownPid).length === 0) {
5926
+ if (sessionsForSupervisor(fs15, paths.headroomSessionsDir, ports.ownPid).length === 0) {
5866
5927
  ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
5867
5928
  ports.stopProcess(headroomPid);
5868
5929
  headroomPid = void 0;
@@ -5871,7 +5932,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
5871
5932
  continue;
5872
5933
  }
5873
5934
  }
5874
- const sessions = sessionsForSupervisor(fs14, paths.headroomSessionsDir, ports.ownPid);
5935
+ const sessions = sessionsForSupervisor(fs15, paths.headroomSessionsDir, ports.ownPid);
5875
5936
  if (sessions.length === 0) {
5876
5937
  idleSince ??= ports.now();
5877
5938
  const idleMs = ports.now() - idleSince;
@@ -5896,9 +5957,9 @@ function undeterminedFrontDoors(inputs) {
5896
5957
  return reason === void 0 ? [] : [{ pid: record.pid, origin: directOrigin(record.directPort), reason }];
5897
5958
  });
5898
5959
  }
5899
- function currentHeadroomAllowlistInputs(fs14, paths, frontDoorLiveness) {
5900
- const named = frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile));
5901
- const records = listFrontDoorDirectRecords(fs14, paths.frontdoorDirectRecordsDir);
5960
+ function currentHeadroomAllowlistInputs(fs15, paths, frontDoorLiveness) {
5961
+ const named = frontDoorOrigin(readFrontDoorState(fs15, paths.frontdoorStateFile));
5962
+ const records = listFrontDoorDirectRecords(fs15, paths.frontdoorDirectRecordsDir);
5902
5963
  const liveness = frontDoorLiveness(records.map((record) => record.pid));
5903
5964
  const live = liveFrontDoorDirectRecords(records, liveness).map((record) => directOrigin(record.directPort));
5904
5965
  return {
@@ -5907,8 +5968,8 @@ function currentHeadroomAllowlistInputs(fs14, paths, frontDoorLiveness) {
5907
5968
  frontDoorOrigins: [.../* @__PURE__ */ new Set([...named === void 0 ? [] : [named], ...live])].sort()
5908
5969
  };
5909
5970
  }
5910
- function launchRequiredUpstreams(fs14, paths) {
5911
- const door = frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile));
5971
+ function launchRequiredUpstreams(fs15, paths) {
5972
+ const door = frontDoorOrigin(readFrontDoorState(fs15, paths.frontdoorStateFile));
5912
5973
  return door === void 0 ? [] : [door];
5913
5974
  }
5914
5975
  async function waitUntilReady(ports, socketPath, pid) {
@@ -6045,6 +6106,29 @@ function isEnoent3(error) {
6045
6106
  function isErrorWithCode(error, code) {
6046
6107
  return typeof error === "object" && error !== null && "code" in error && error.code === code;
6047
6108
  }
6109
+ function writeFileFlushed(file, contents) {
6110
+ const descriptor = fs3.openSync(file, "w", OWNER_ONLY_FILE_MODE);
6111
+ try {
6112
+ fs3.writeFileSync(descriptor, contents, "utf8");
6113
+ fs3.fchmodSync(descriptor, OWNER_ONLY_FILE_MODE);
6114
+ fs3.fsyncSync(descriptor);
6115
+ } finally {
6116
+ fs3.closeSync(descriptor);
6117
+ }
6118
+ }
6119
+ function flushDirectory(directory) {
6120
+ const descriptor = fs3.openSync(directory, "r");
6121
+ try {
6122
+ fs3.fsyncSync(descriptor);
6123
+ } catch (error) {
6124
+ const code = typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : void 0;
6125
+ if (code === void 0 || !DIRECTORY_FLUSH_UNSUPPORTED_CODES.has(code)) {
6126
+ throw error;
6127
+ }
6128
+ } finally {
6129
+ fs3.closeSync(descriptor);
6130
+ }
6131
+ }
6048
6132
  function realSleepSync(ms) {
6049
6133
  refuseToBlockInRole("a synchronous sleep");
6050
6134
  Atomics.wait(new Int32Array(new SharedArrayBuffer(INT32_BYTE_LENGTH)), 0, 0, ms);
@@ -6078,9 +6162,9 @@ function realFrontDoorLiveness(pids) {
6078
6162
  return { status: result.status, stdout: result.stdout, stderr: result.stderr, ...result.error === void 0 ? {} : { error: result.error } };
6079
6163
  });
6080
6164
  }
6081
- async function realRunAsync(command, args) {
6082
- return await new Promise((resolve) => {
6083
- execFile(command, [...args], { encoding: "utf8", timeout: PS_TIMEOUT_MS }, (error, stdout, stderr) => {
6165
+ function realRunAsyncWithin(timeoutMs) {
6166
+ return async (command, args) => await new Promise((resolve) => {
6167
+ execFile(command, [...args], { encoding: "utf8", timeout: timeoutMs }, (error, stdout, stderr) => {
6084
6168
  resolve({ status: error === null ? 0 : typeof error.code === "number" ? error.code : null, stdout, stderr });
6085
6169
  });
6086
6170
  });
@@ -6286,7 +6370,7 @@ function realResolveClaudeBinary(isOwnBinary) {
6286
6370
  function realInstalledClaudeVersions() {
6287
6371
  return installedVersions(listVersionsDir(defaultVersionsDir()));
6288
6372
  }
6289
- var realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, realFarmFs, INT32_BYTE_LENGTH, KEY_POLL_MS, CTRL_C_BYTE, realHoldPort, PS_TIMEOUT_MS, realRunPort, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, realLogPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
6373
+ var realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, DIRECTORY_FLUSH_UNSUPPORTED_CODES, realFarmFs, INT32_BYTE_LENGTH, KEY_POLL_MS, CTRL_C_BYTE, realHoldPort, PS_TIMEOUT_MS, RUN_OUTPUT_LIMIT_MIB, BYTES_PER_MIB2, RUN_OUTPUT_LIMIT_BYTES, realRunPort, ASYNC_RUN_TIMEOUT_MS, realRunAsync, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, realLogPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
6290
6374
  var init_realPorts = __esm({
6291
6375
  "src/realPorts.ts"() {
6292
6376
  "use strict";
@@ -6325,6 +6409,7 @@ var init_realPorts = __esm({
6325
6409
  OWNER_ONLY_DIR_MODE = 448;
6326
6410
  OWNER_ONLY_FILE_MODE = 384;
6327
6411
  PERMISSION_BITS = 511;
6412
+ DIRECTORY_FLUSH_UNSUPPORTED_CODES = /* @__PURE__ */ new Set(["EINVAL", "ENOTSUP", "EOPNOTSUPP"]);
6328
6413
  realFarmFs = {
6329
6414
  lstat(filePath) {
6330
6415
  let stat;
@@ -6381,12 +6466,18 @@ var init_realPorts = __esm({
6381
6466
  fs3.mkdirSync(dirPath, { recursive: true, mode: OWNER_ONLY_DIR_MODE });
6382
6467
  fs3.chmodSync(dirPath, OWNER_ONLY_DIR_MODE);
6383
6468
  },
6384
- writeFilePrivate(filePath, contents) {
6469
+ writeFilePrivate(filePath, contents, options) {
6385
6470
  const temp = `${filePath}.${String(process.pid)}.tmp`;
6386
6471
  try {
6387
- fs3.writeFileSync(temp, contents, { encoding: "utf8", mode: OWNER_ONLY_FILE_MODE });
6388
- fs3.chmodSync(temp, OWNER_ONLY_FILE_MODE);
6389
- fs3.renameSync(temp, filePath);
6472
+ if (options?.durable === true) {
6473
+ writeFileFlushed(temp, contents);
6474
+ fs3.renameSync(temp, filePath);
6475
+ flushDirectory(path15.dirname(filePath));
6476
+ } else {
6477
+ fs3.writeFileSync(temp, contents, { encoding: "utf8", mode: OWNER_ONLY_FILE_MODE });
6478
+ fs3.chmodSync(temp, OWNER_ONLY_FILE_MODE);
6479
+ fs3.renameSync(temp, filePath);
6480
+ }
6390
6481
  } catch (error) {
6391
6482
  fs3.rmSync(temp, { force: true });
6392
6483
  throw error;
@@ -6456,12 +6547,17 @@ var init_realPorts = __esm({
6456
6547
  }
6457
6548
  };
6458
6549
  PS_TIMEOUT_MS = 2e3;
6550
+ RUN_OUTPUT_LIMIT_MIB = 256;
6551
+ BYTES_PER_MIB2 = 1048576;
6552
+ RUN_OUTPUT_LIMIT_BYTES = RUN_OUTPUT_LIMIT_MIB * BYTES_PER_MIB2;
6459
6553
  realRunPort = {
6460
- run(command, args) {
6461
- const result = spawnSyncBlocking("an external command", command, args, { encoding: "utf8" });
6554
+ run(command, args, input) {
6555
+ const result = spawnSyncBlocking("an external command", command, args, { encoding: "utf8", maxBuffer: RUN_OUTPUT_LIMIT_BYTES, ...input === void 0 ? {} : { input } });
6462
6556
  return { status: result.status, stdout: result.stdout, stderr: result.stderr };
6463
6557
  }
6464
6558
  };
6559
+ ASYNC_RUN_TIMEOUT_MS = 2e3;
6560
+ realRunAsync = realRunAsyncWithin(ASYNC_RUN_TIMEOUT_MS);
6465
6561
  MACOS_GUI_SESSION_MANAGER = "Aqua";
6466
6562
  realCredentialPort = {
6467
6563
  readSecretFile(filePath) {
@@ -6653,8 +6749,8 @@ import path18 from "node:path";
6653
6749
  function poolNameOf(selector) {
6654
6750
  return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
6655
6751
  }
6656
- function readActiveIdentity(fs14, activeIdentityFile) {
6657
- const trimmed = fs14.readFileUtf8(activeIdentityFile)?.trim();
6752
+ function readActiveIdentity(fs15, activeIdentityFile) {
6753
+ const trimmed = fs15.readFileUtf8(activeIdentityFile)?.trim();
6658
6754
  return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
6659
6755
  }
6660
6756
  function isNonEmpty(value) {
@@ -6704,11 +6800,11 @@ function decideConfigProfile(params) {
6704
6800
  }
6705
6801
  return { source: "none" };
6706
6802
  }
6707
- function loadIdentity(identitiesDir, name, fs14) {
6803
+ function loadIdentity(identitiesDir, name, fs15) {
6708
6804
  if (!isFileName(name)) {
6709
6805
  throw new UnsafeNameError(name, "identity", FILE_NAME_RULE);
6710
6806
  }
6711
- return loadConfigFile(path18.join(identitiesDir, name, "identity.json"), IdentitySchema, fs14.readConfigFile);
6807
+ return loadConfigFile(path18.join(identitiesDir, name, "identity.json"), IdentitySchema, fs15.readConfigFile);
6712
6808
  }
6713
6809
  var IDENTITY_DECISION_SOURCES, IDENTITY_SOURCE_LABELS, CONFIG_PROFILE_DECISION_SOURCES;
6714
6810
  var init_identity = __esm({
@@ -6962,14 +7058,14 @@ function isIdentityName(name) {
6962
7058
  function claudeJsonPath(identitiesDir, identity) {
6963
7059
  return path19.join(identitiesDir, identity, CLAUDE_JSON);
6964
7060
  }
6965
- function readAccountMetadata(fs14, identitiesDir, identity) {
7061
+ function readAccountMetadata(fs15, identitiesDir, identity) {
6966
7062
  if (!isIdentityName(identity)) {
6967
7063
  throw new Error(`"${identity}" is not a valid identity name.`);
6968
7064
  }
6969
- return readAccountMetadataFile(fs14, claudeJsonPath(identitiesDir, identity));
7065
+ return readAccountMetadataFile(fs15, claudeJsonPath(identitiesDir, identity));
6970
7066
  }
6971
- function readAccountMetadataFile(fs14, file) {
6972
- const raw = fs14.readFileUtf8(file);
7067
+ function readAccountMetadataFile(fs15, file) {
7068
+ const raw = fs15.readFileUtf8(file);
6973
7069
  if (raw === void 0) {
6974
7070
  return void 0;
6975
7071
  }
@@ -6999,19 +7095,19 @@ function readAccountMetadataFile(fs14, file) {
6999
7095
  }
7000
7096
  return account.data;
7001
7097
  }
7002
- function createAccountReader(fs14, identitiesDir) {
7098
+ function createAccountReader(fs15, identitiesDir) {
7003
7099
  const cache = /* @__PURE__ */ new Map();
7004
7100
  return (identity) => {
7005
7101
  if (!isIdentityName(identity)) {
7006
7102
  throw new Error(`"${identity}" is not a valid identity name.`);
7007
7103
  }
7008
- const stat = fs14.lstat(claudeJsonPath(identitiesDir, identity));
7104
+ const stat = fs15.lstat(claudeJsonPath(identitiesDir, identity));
7009
7105
  const stamp = stat === void 0 ? "absent" : `${String(stat.mtimeMs)}:${String(stat.sizeBytes)}`;
7010
7106
  const cached = cache.get(identity);
7011
7107
  if (cached?.stamp === stamp) {
7012
7108
  return cached.account;
7013
7109
  }
7014
- const account = readAccountMetadata(fs14, identitiesDir, identity);
7110
+ const account = readAccountMetadata(fs15, identitiesDir, identity);
7015
7111
  cache.set(identity, { stamp, account });
7016
7112
  return account;
7017
7113
  };
@@ -7047,9 +7143,9 @@ var init_accountDescription = __esm({
7047
7143
  });
7048
7144
 
7049
7145
  // src/identityAccounts.ts
7050
- function readIdentityAccount(fs14, identitiesDir, identity) {
7146
+ function readIdentityAccount(fs15, identitiesDir, identity) {
7051
7147
  try {
7052
- const account = readAccountMetadata(fs14, identitiesDir, identity);
7148
+ const account = readAccountMetadata(fs15, identitiesDir, identity);
7053
7149
  return account === void 0 ? void 0 : { account };
7054
7150
  } catch (error) {
7055
7151
  if (error instanceof AccountMetadataError) {
@@ -7688,8 +7784,8 @@ function segmentDay(epochMs) {
7688
7784
  function segmentName(day, pid) {
7689
7785
  return `${day}.${String(pid)}.jsonl`;
7690
7786
  }
7691
- function listLogSegments(fs14, logDir) {
7692
- return fs14.readdir(logDir).flatMap((name) => {
7787
+ function listLogSegments(fs15, logDir) {
7788
+ return fs15.readdir(logDir).flatMap((name) => {
7693
7789
  const match = SEGMENT_RE.exec(name);
7694
7790
  const day = match?.[1];
7695
7791
  if (day === void 0) {
@@ -7698,15 +7794,15 @@ function listLogSegments(fs14, logDir) {
7698
7794
  return [{ name, day, endsAt: Date.parse(`${day}T00:00:00.000Z`) + DAY_MS }];
7699
7795
  }).sort((left, right) => left.day.localeCompare(right.day) || left.name.localeCompare(right.name));
7700
7796
  }
7701
- function readUsageLog(fs14, logDir, options = {}) {
7797
+ function readUsageLog(fs15, logDir, options = {}) {
7702
7798
  const { sinceMs } = options;
7703
7799
  const records = [];
7704
7800
  let invalidLines = 0;
7705
- for (const segment of listLogSegments(fs14, logDir)) {
7801
+ for (const segment of listLogSegments(fs15, logDir)) {
7706
7802
  if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
7707
7803
  continue;
7708
7804
  }
7709
- const read = readSegment(fs14, logDir, segment);
7805
+ const read = readSegment(fs15, logDir, segment);
7710
7806
  if (read === void 0) {
7711
7807
  continue;
7712
7808
  }
@@ -7720,8 +7816,8 @@ function readUsageLog(fs14, logDir, options = {}) {
7720
7816
  records.sort((left, right) => left.at.localeCompare(right.at));
7721
7817
  return { records, invalidLines };
7722
7818
  }
7723
- function readSegment(fs14, logDir, segment) {
7724
- const contents = fs14.readFileUtf8(path20.join(logDir, segment.name));
7819
+ function readSegment(fs15, logDir, segment) {
7820
+ const contents = fs15.readFileUtf8(path20.join(logDir, segment.name));
7725
7821
  if (contents === void 0) {
7726
7822
  return void 0;
7727
7823
  }
@@ -7755,9 +7851,9 @@ function snapshotPath(snapshotsDir, identity) {
7755
7851
  }
7756
7852
  return path20.join(snapshotsDir, `${identity}.json`);
7757
7853
  }
7758
- function readUsageSnapshot(fs14, snapshotsDir, identity) {
7854
+ function readUsageSnapshot(fs15, snapshotsDir, identity) {
7759
7855
  const file = snapshotPath(snapshotsDir, identity);
7760
- const raw = fs14.readFileUtf8(file);
7856
+ const raw = fs15.readFileUtf8(file);
7761
7857
  if (raw === void 0) {
7762
7858
  return void 0;
7763
7859
  }
@@ -7773,8 +7869,8 @@ function readUsageSnapshot(fs14, snapshotsDir, identity) {
7773
7869
  }
7774
7870
  return snapshot.data;
7775
7871
  }
7776
- function listUsageSnapshots(fs14, snapshotsDir) {
7777
- return fs14.readdir(snapshotsDir).flatMap((name) => {
7872
+ function listUsageSnapshots(fs15, snapshotsDir) {
7873
+ return fs15.readdir(snapshotsDir).flatMap((name) => {
7778
7874
  if (!name.endsWith(".json")) {
7779
7875
  return [];
7780
7876
  }
@@ -7782,7 +7878,7 @@ function listUsageSnapshots(fs14, snapshotsDir) {
7782
7878
  if (!isIdentityName(identity)) {
7783
7879
  return [];
7784
7880
  }
7785
- const snapshot = readUsageSnapshot(fs14, snapshotsDir, identity);
7881
+ const snapshot = readUsageSnapshot(fs15, snapshotsDir, identity);
7786
7882
  return snapshot === void 0 ? [] : [snapshot];
7787
7883
  }).sort((left, right) => left.identity.localeCompare(right.identity));
7788
7884
  }
@@ -7807,11 +7903,11 @@ var init_read = __esm({
7807
7903
 
7808
7904
  // src/usage/store.ts
7809
7905
  import path21 from "node:path";
7810
- function pruneUsageLog(fs14, logDir, nowMs) {
7906
+ function pruneUsageLog(fs15, logDir, nowMs) {
7811
7907
  const cutoff = nowMs - USAGE_RETENTION_MS;
7812
- for (const segment of listLogSegments(fs14, logDir)) {
7908
+ for (const segment of listLogSegments(fs15, logDir)) {
7813
7909
  if (segment.endsAt <= cutoff) {
7814
- fs14.removeRecursive(path21.join(logDir, segment.name));
7910
+ fs15.removeRecursive(path21.join(logDir, segment.name));
7815
7911
  }
7816
7912
  }
7817
7913
  }
@@ -7840,7 +7936,7 @@ function foldProviderState(current, record) {
7840
7936
  };
7841
7937
  }
7842
7938
  function createUsageStore(deps) {
7843
- const { fs: fs14, paths } = deps;
7939
+ const { fs: fs15, paths } = deps;
7844
7940
  let prunedDay;
7845
7941
  const rewriteSnapshot = (identity, fold) => {
7846
7942
  if (!isIdentityName(identity)) {
@@ -7849,7 +7945,7 @@ function createUsageStore(deps) {
7849
7945
  }
7850
7946
  let current;
7851
7947
  try {
7852
- current = readUsageSnapshot(fs14, paths.usageSnapshotsDir, identity);
7948
+ current = readUsageSnapshot(fs15, paths.usageSnapshotsDir, identity);
7853
7949
  } catch (error) {
7854
7950
  if (!(error instanceof UsageSnapshotError)) {
7855
7951
  throw error;
@@ -7876,8 +7972,8 @@ function createUsageStore(deps) {
7876
7972
  ...account === void 0 ? {} : { account },
7877
7973
  providers
7878
7974
  });
7879
- fs14.mkdirPrivate(paths.usageSnapshotsDir);
7880
- fs14.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
7975
+ fs15.mkdirPrivate(paths.usageSnapshotsDir);
7976
+ fs15.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
7881
7977
  `);
7882
7978
  deps.publish?.(snapshot);
7883
7979
  return true;
@@ -7886,14 +7982,14 @@ function createUsageStore(deps) {
7886
7982
  record: (input) => {
7887
7983
  const record = UsageRecordSchema.parse(input);
7888
7984
  const nowMs = deps.now();
7889
- fs14.mkdirPrivate(paths.usageDir);
7890
- fs14.mkdirPrivate(paths.usageLogDir);
7985
+ fs15.mkdirPrivate(paths.usageDir);
7986
+ fs15.mkdirPrivate(paths.usageLogDir);
7891
7987
  const day = segmentDay(nowMs);
7892
7988
  if (prunedDay !== day) {
7893
- pruneUsageLog(fs14, paths.usageLogDir, nowMs);
7989
+ pruneUsageLog(fs15, paths.usageLogDir, nowMs);
7894
7990
  prunedDay = day;
7895
7991
  }
7896
- fs14.appendFilePrivate(path21.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
7992
+ fs15.appendFilePrivate(path21.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
7897
7993
  `);
7898
7994
  deps.onRecord?.(record);
7899
7995
  if (record.identity !== void 0) {
@@ -7937,14 +8033,14 @@ import { z as z15 } from "zod";
7937
8033
  function errorMessage(error) {
7938
8034
  return error instanceof Error ? error.message : String(error);
7939
8035
  }
7940
- function loadPoolMembers(fs14, paths, identities, nowMs) {
8036
+ function loadPoolMembers(fs15, paths, identities, nowMs) {
7941
8037
  const windowStartMs = nowMs - FIVE_HOUR_WINDOW_MS;
7942
- const log = readUsageLog(fs14, paths.usageLogDir, { sinceMs: windowStartMs });
8038
+ const log = readUsageLog(fs15, paths.usageLogDir, { sinceMs: windowStartMs });
7943
8039
  return identities.map((identity) => {
7944
8040
  const records = log.records.filter((record) => record.identity === identity && record.provider === ANTHROPIC_PROVIDER && Date.parse(record.at) >= windowStartMs);
7945
8041
  try {
7946
- const snapshot = readUsageSnapshot(fs14, paths.usageSnapshotsDir, identity);
7947
- const account = readAccountMetadata(fs14, paths.identitiesDir, identity) ?? snapshot?.account;
8042
+ const snapshot = readUsageSnapshot(fs15, paths.usageSnapshotsDir, identity);
8043
+ const account = readAccountMetadata(fs15, paths.identitiesDir, identity) ?? snapshot?.account;
7948
8044
  return { identity, records, ...snapshot === void 0 ? {} : { snapshot }, ...account === void 0 ? {} : { account } };
7949
8045
  } catch (error) {
7950
8046
  if (error instanceof UsageSnapshotError || error instanceof AccountMetadataError) {
@@ -8063,9 +8159,9 @@ function collectPoolIdentities(pools, poolName, stack, found) {
8063
8159
  collectPoolIdentities(pools, nestedName, childStack, found);
8064
8160
  }
8065
8161
  }
8066
- function readPicksFile(fs14, file) {
8162
+ function readPicksFile(fs15, file) {
8067
8163
  const empty = { schemaVersion: SCHEMA_VERSION, picks: {} };
8068
- const raw = fs14.readFileUtf8(file);
8164
+ const raw = fs15.readFileUtf8(file);
8069
8165
  if (raw === void 0) {
8070
8166
  return { file: empty };
8071
8167
  }
@@ -8078,17 +8174,17 @@ function readPicksFile(fs14, file) {
8078
8174
  const result = PicksFileSchema.safeParse(parsed);
8079
8175
  return result.success ? { file: result.data } : { file: empty, problem: `${file} is not a picks file this agent-shim can read` };
8080
8176
  }
8081
- function readStickyPick(fs14, picksFile, directory) {
8082
- const read = readPicksFile(fs14, picksFile);
8177
+ function readStickyPick(fs15, picksFile, directory) {
8178
+ const read = readPicksFile(fs15, picksFile);
8083
8179
  const entry = read.file.picks[directory];
8084
8180
  return { ...entry === void 0 ? {} : { sticky: entry }, ...read.problem === void 0 ? {} : { problem: read.problem } };
8085
8181
  }
8086
- function recordStickyPick(fs14, picksFile, directory, identity, nowMs) {
8087
- const current = readPicksFile(fs14, picksFile).file.picks;
8182
+ function recordStickyPick(fs15, picksFile, directory, identity, nowMs) {
8183
+ const current = readPicksFile(fs15, picksFile).file.picks;
8088
8184
  const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
8089
8185
  const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
8090
- fs14.mkdirPrivate(path22.dirname(picksFile));
8091
- fs14.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
8186
+ fs15.mkdirPrivate(path22.dirname(picksFile));
8187
+ fs15.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
8092
8188
  `);
8093
8189
  }
8094
8190
  var PoolGraphError, SCHEMA_VERSION, PickEntrySchema, PicksFileSchema;
@@ -8121,9 +8217,9 @@ var init_poolPick = __esm({
8121
8217
 
8122
8218
  // src/statusline/keys.ts
8123
8219
  import { z as z16 } from "zod";
8124
- function valueAt(source, path42) {
8220
+ function valueAt(source, path45) {
8125
8221
  let current = source;
8126
- for (const part of path42) {
8222
+ for (const part of path45) {
8127
8223
  if (!isPlainObject(current)) {
8128
8224
  return void 0;
8129
8225
  }
@@ -8131,14 +8227,14 @@ function valueAt(source, path42) {
8131
8227
  }
8132
8228
  return current;
8133
8229
  }
8134
- function acceptsNull(path42) {
8135
- const layer = path42.reduceRight((inner, part) => ({ [part]: inner }), null);
8230
+ function acceptsNull(path45) {
8231
+ const layer = path45.reduceRight((inner, part) => ({ [part]: inner }), null);
8136
8232
  return StatuslineSchema.safeParse(layer).success;
8137
8233
  }
8138
- function keyOf(path42, declared) {
8234
+ function keyOf(path45, declared) {
8139
8235
  const optional = declared instanceof z16.ZodOptional;
8140
8236
  const leaf = optional ? declared.unwrap() : declared;
8141
- const common = { path: path42.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path42), optional, unsettable: acceptsNull(path42) };
8237
+ const common = { path: path45.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path45), optional, unsettable: acceptsNull(path45) };
8142
8238
  if (leaf instanceof z16.ZodNumber) {
8143
8239
  return { ...common, kind: "integer", choices: [] };
8144
8240
  }
@@ -8163,7 +8259,7 @@ function keyOf(path42, declared) {
8163
8259
  if (leaf instanceof z16.ZodArray && leaf.element instanceof z16.ZodString) {
8164
8260
  return { ...common, kind: "textList", choices: [] };
8165
8261
  }
8166
- throw new TypeError(`statusline setting ${path42.join(".")} has a kind the key listing does not describe`);
8262
+ throw new TypeError(`statusline setting ${path45.join(".")} has a kind the key listing does not describe`);
8167
8263
  }
8168
8264
  function walk(shape, prefix) {
8169
8265
  return Object.entries(shape).flatMap(([name, schema]) => schema instanceof z16.ZodObject ? walk(schema.shape, [...prefix, name]) : [keyOf([...prefix, name], schema)]);
@@ -8179,15 +8275,15 @@ var init_keys = __esm({
8179
8275
  });
8180
8276
 
8181
8277
  // src/statusline/change.ts
8182
- function keyNamed(path42) {
8183
- const found = statuslineKeys().find((key) => key.path === path42);
8278
+ function keyNamed(path45) {
8279
+ const found = statuslineKeys().find((key) => key.path === path45);
8184
8280
  if (found === void 0) {
8185
- throw new UsageError(`"${path42}" is not a statusline setting; \`agent-shim statusline keys\` lists them.`);
8281
+ throw new UsageError(`"${path45}" is not a statusline setting; \`agent-shim statusline keys\` lists them.`);
8186
8282
  }
8187
8283
  return found;
8188
8284
  }
8189
- function setAt(target, path42, value) {
8190
- const [head, ...rest] = path42;
8285
+ function setAt(target, path45, value) {
8286
+ const [head, ...rest] = path45;
8191
8287
  if (head === void 0) {
8192
8288
  return;
8193
8289
  }
@@ -8200,8 +8296,8 @@ function setAt(target, path42, value) {
8200
8296
  target[head] = next;
8201
8297
  setAt(next, rest, value);
8202
8298
  }
8203
- function removeAt(target, path42) {
8204
- const [head, ...rest] = path42;
8299
+ function removeAt(target, path45) {
8300
+ const [head, ...rest] = path45;
8205
8301
  if (head === void 0) {
8206
8302
  return;
8207
8303
  }
@@ -8219,13 +8315,13 @@ function removeAt(target, path42) {
8219
8315
  }
8220
8316
  function applyStatuslineChange(existing, change) {
8221
8317
  const draft = structuredClone(existing ?? {});
8222
- for (const [path42, value] of Object.entries(change.set ?? {})) {
8223
- keyNamed(path42);
8224
- setAt(draft, path42.split("."), value);
8318
+ for (const [path45, value] of Object.entries(change.set ?? {})) {
8319
+ keyNamed(path45);
8320
+ setAt(draft, path45.split("."), value);
8225
8321
  }
8226
- for (const path42 of change.unset ?? []) {
8227
- keyNamed(path42);
8228
- removeAt(draft, path42.split("."));
8322
+ for (const path45 of change.unset ?? []) {
8323
+ keyNamed(path45);
8324
+ removeAt(draft, path45.split("."));
8229
8325
  }
8230
8326
  const result = StatuslineSchema.safeParse(draft);
8231
8327
  if (!result.success) {
@@ -8514,6 +8610,8 @@ function buildLayoutPaths(root) {
8514
8610
  usageAnchorsFile: path23.join(root, "usage", "anchors.json"),
8515
8611
  usageJobsFile: path23.join(root, "usage", "jobs.json"),
8516
8612
  jobLogsDir: path23.join(root, "logs", "jobs"),
8613
+ identityRenamesDir: path23.join(root, "identity-renames"),
8614
+ launchesDir: path23.join(root, "launches"),
8517
8615
  superviseDir: path23.join(root, "supervise"),
8518
8616
  modelMovesDir: path23.join(root, "model-moves"),
8519
8617
  mcpPermissionsFile: path23.join(root, "mcp", "permissions.json")
@@ -9229,7 +9327,12 @@ function readProvider(paths, name) {
9229
9327
  if (!fs7.existsSync(filePath)) {
9230
9328
  return void 0;
9231
9329
  }
9232
- const raw = JSON.parse(fs7.readFileSync(filePath, "utf8"));
9330
+ let raw;
9331
+ try {
9332
+ raw = JSON.parse(fs7.readFileSync(filePath, "utf8"));
9333
+ } catch (error) {
9334
+ throw error instanceof SyntaxError ? new ConfigFileNotJsonError(filePath) : error;
9335
+ }
9233
9336
  return parseProviderFile(filePath, raw);
9234
9337
  }
9235
9338
  function loadProvider(providersDir, name, port) {
@@ -9251,7 +9354,7 @@ function listProviders(paths, onInvalid = reportInvalidProvider) {
9251
9354
  try {
9252
9355
  provider = readProvider(paths, name);
9253
9356
  } catch (error) {
9254
- if (!(error instanceof ConfigValidationError || error instanceof LegacyProviderFileError || error instanceof UnsafeNameError)) {
9357
+ if (!(error instanceof ConfigValidationError || error instanceof LegacyProviderFileError || error instanceof ConfigFileNotJsonError || error instanceof UnsafeNameError)) {
9255
9358
  throw error;
9256
9359
  }
9257
9360
  onInvalid(name, error.message);
@@ -9597,13 +9700,13 @@ function decideSignIn(facts) {
9597
9700
  function credentialsFilePath(farmRoot) {
9598
9701
  return path25.join(farmRoot, CREDENTIALS_FILE);
9599
9702
  }
9600
- function identitySignIn(fs14, probe, identity) {
9703
+ function identitySignIn(fs15, probe, identity) {
9601
9704
  const probing = !identity.hasCredentialBlock && identity.provider === void 0;
9602
9705
  return decideSignIn({
9603
9706
  hasCredentialBlock: identity.hasCredentialBlock,
9604
9707
  provider: identity.provider,
9605
9708
  keychainItem: probing && probe.platform === "darwin" && probe.run !== void 0 ? keychainHasItem(probe.run, identity.farmRoot) : void 0,
9606
- credentialsFile: probing && fs14.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
9709
+ credentialsFile: probing && fs15.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
9607
9710
  platform: probe.platform
9608
9711
  });
9609
9712
  }
@@ -9982,62 +10085,62 @@ var init_signatures = __esm({
9982
10085
  });
9983
10086
 
9984
10087
  // src/codex/anthropic.ts
9985
- import { z as z27 } from "zod";
10088
+ import { z as z28 } from "zod";
9986
10089
  var TextBlockSchema, Base64ImageSourceSchema, UrlImageSourceSchema, ImageBlockSchema, ToolUseBlockSchema, ToolResultContentBlockSchema, ToolResultBlockSchema, OtherBlockSchema, ContentBlockSchema, MessageSchema, ToolSchema, ToolChoiceSchema, SystemSchema, MessagesRequestSchema, CountTokensRequestSchema;
9987
10090
  var init_anthropic = __esm({
9988
10091
  "src/codex/anthropic.ts"() {
9989
10092
  "use strict";
9990
- TextBlockSchema = z27.looseObject({ type: z27.literal("text"), text: z27.string() });
9991
- Base64ImageSourceSchema = z27.looseObject({ type: z27.literal("base64"), media_type: z27.string().min(1), data: z27.string() });
9992
- UrlImageSourceSchema = z27.looseObject({ type: z27.literal("url"), url: z27.string().min(1) });
9993
- ImageBlockSchema = z27.looseObject({
9994
- type: z27.literal("image"),
9995
- source: z27.union([Base64ImageSourceSchema, UrlImageSourceSchema])
10093
+ TextBlockSchema = z28.looseObject({ type: z28.literal("text"), text: z28.string() });
10094
+ Base64ImageSourceSchema = z28.looseObject({ type: z28.literal("base64"), media_type: z28.string().min(1), data: z28.string() });
10095
+ UrlImageSourceSchema = z28.looseObject({ type: z28.literal("url"), url: z28.string().min(1) });
10096
+ ImageBlockSchema = z28.looseObject({
10097
+ type: z28.literal("image"),
10098
+ source: z28.union([Base64ImageSourceSchema, UrlImageSourceSchema])
9996
10099
  });
9997
- ToolUseBlockSchema = z27.looseObject({
9998
- type: z27.literal("tool_use"),
9999
- id: z27.string().min(1),
10000
- name: z27.string().min(1),
10001
- input: z27.unknown()
10100
+ ToolUseBlockSchema = z28.looseObject({
10101
+ type: z28.literal("tool_use"),
10102
+ id: z28.string().min(1),
10103
+ name: z28.string().min(1),
10104
+ input: z28.unknown()
10002
10105
  });
10003
- ToolResultContentBlockSchema = z27.union([TextBlockSchema, z27.looseObject({ type: z27.string() })]);
10004
- ToolResultBlockSchema = z27.looseObject({
10005
- type: z27.literal("tool_result"),
10006
- tool_use_id: z27.string().min(1),
10007
- content: z27.union([z27.string(), z27.array(ToolResultContentBlockSchema)]).optional()
10106
+ ToolResultContentBlockSchema = z28.union([TextBlockSchema, z28.looseObject({ type: z28.string() })]);
10107
+ ToolResultBlockSchema = z28.looseObject({
10108
+ type: z28.literal("tool_result"),
10109
+ tool_use_id: z28.string().min(1),
10110
+ content: z28.union([z28.string(), z28.array(ToolResultContentBlockSchema)]).optional()
10008
10111
  });
10009
- OtherBlockSchema = z27.looseObject({ type: z27.string() });
10010
- ContentBlockSchema = z27.union([TextBlockSchema, ImageBlockSchema, ToolUseBlockSchema, ToolResultBlockSchema, OtherBlockSchema]);
10011
- MessageSchema = z27.looseObject({
10012
- role: z27.enum(["user", "assistant", "system"]),
10013
- content: z27.union([z27.string(), z27.array(ContentBlockSchema)])
10112
+ OtherBlockSchema = z28.looseObject({ type: z28.string() });
10113
+ ContentBlockSchema = z28.union([TextBlockSchema, ImageBlockSchema, ToolUseBlockSchema, ToolResultBlockSchema, OtherBlockSchema]);
10114
+ MessageSchema = z28.looseObject({
10115
+ role: z28.enum(["user", "assistant", "system"]),
10116
+ content: z28.union([z28.string(), z28.array(ContentBlockSchema)])
10014
10117
  });
10015
- ToolSchema = z27.looseObject({
10016
- name: z27.string().min(1),
10017
- description: z27.string().optional(),
10018
- input_schema: z27.record(z27.string(), z27.unknown()).optional()
10118
+ ToolSchema = z28.looseObject({
10119
+ name: z28.string().min(1),
10120
+ description: z28.string().optional(),
10121
+ input_schema: z28.record(z28.string(), z28.unknown()).optional()
10019
10122
  });
10020
- ToolChoiceSchema = z27.union([
10021
- z27.looseObject({ type: z27.enum(["auto", "none", "any"]) }),
10022
- z27.looseObject({ type: z27.literal("tool"), name: z27.string().min(1) })
10123
+ ToolChoiceSchema = z28.union([
10124
+ z28.looseObject({ type: z28.enum(["auto", "none", "any"]) }),
10125
+ z28.looseObject({ type: z28.literal("tool"), name: z28.string().min(1) })
10023
10126
  ]);
10024
- SystemSchema = z27.union([z27.string(), z27.array(z27.union([TextBlockSchema, OtherBlockSchema]))]);
10025
- MessagesRequestSchema = z27.looseObject({
10026
- model: z27.string().optional(),
10127
+ SystemSchema = z28.union([z28.string(), z28.array(z28.union([TextBlockSchema, OtherBlockSchema]))]);
10128
+ MessagesRequestSchema = z28.looseObject({
10129
+ model: z28.string().optional(),
10027
10130
  system: SystemSchema.optional(),
10028
- messages: z27.array(MessageSchema),
10029
- tools: z27.array(ToolSchema).optional(),
10131
+ messages: z28.array(MessageSchema),
10132
+ tools: z28.array(ToolSchema).optional(),
10030
10133
  tool_choice: ToolChoiceSchema.optional(),
10031
- stream: z27.boolean().optional(),
10134
+ stream: z28.boolean().optional(),
10032
10135
  /** `user_id` is stable for one Claude Code session and differs between sessions, which is what makes it the right key for both the backend's prompt cache and its session header. */
10033
- metadata: z27.looseObject({ user_id: z27.string().optional() }).optional(),
10136
+ metadata: z28.looseObject({ user_id: z28.string().optional() }).optional(),
10034
10137
  /** Claude Code's effort setting. Any string is accepted; the translator honours only the levels the backend understands. */
10035
- output_config: z27.looseObject({ effort: z27.string().optional() }).optional()
10138
+ output_config: z28.looseObject({ effort: z28.string().optional() }).optional()
10036
10139
  });
10037
- CountTokensRequestSchema = z27.looseObject({
10038
- system: z27.unknown().optional(),
10039
- messages: z27.unknown().optional(),
10040
- tools: z27.unknown().optional()
10140
+ CountTokensRequestSchema = z28.looseObject({
10141
+ system: z28.unknown().optional(),
10142
+ messages: z28.unknown().optional(),
10143
+ tools: z28.unknown().optional()
10041
10144
  });
10042
10145
  }
10043
10146
  });
@@ -10121,7 +10224,7 @@ var init_translate2 = __esm({
10121
10224
 
10122
10225
  // src/providerCatalogue.ts
10123
10226
  import picomatch4 from "picomatch";
10124
- import { z as z28 } from "zod";
10227
+ import { z as z29 } from "zod";
10125
10228
  function catalogueCachePath(paths, name) {
10126
10229
  return providerFilePath(paths.catalogueDir, name);
10127
10230
  }
@@ -10157,8 +10260,8 @@ var init_providerCatalogue = __esm({
10157
10260
  CATALOGUE_REQUEST_SECONDS = 10;
10158
10261
  CATALOGUE_REQUEST_TIMEOUT_MS = CATALOGUE_REQUEST_SECONDS * MS_PER_SECOND5;
10159
10262
  CATALOGUE_REFRESH_TIMEOUT_MS = DEFAULT_CANDIDATE_URLS * CATALOGUE_REQUEST_TIMEOUT_MS;
10160
- CatalogueModelSchema = z28.strictObject({ id: z28.string().min(1), name: z28.string().min(1).optional() });
10161
- CatalogueCacheSchema = z28.strictObject({ fetchedAt: z28.number(), url: z28.string().min(1), models: z28.array(CatalogueModelSchema) });
10263
+ CatalogueModelSchema = z29.strictObject({ id: z29.string().min(1), name: z29.string().min(1).optional() });
10264
+ CatalogueCacheSchema = z29.strictObject({ fetchedAt: z29.number(), url: z29.string().min(1), models: z29.array(CatalogueModelSchema) });
10162
10265
  }
10163
10266
  });
10164
10267
 
@@ -10465,6 +10568,60 @@ var init_proxyBypass2 = __esm({
10465
10568
  }
10466
10569
  });
10467
10570
 
10571
+ // src/replayRun.ts
10572
+ function keyOf2(command, args) {
10573
+ return JSON.stringify([command, args]);
10574
+ }
10575
+ async function recordRuns(decide, runAsync) {
10576
+ const answers = /* @__PURE__ */ new Map();
10577
+ const replay = {
10578
+ run: (command, args) => {
10579
+ const answer = answers.get(keyOf2(command, args));
10580
+ if (answer === void 0) {
10581
+ throw new RunNeededError(command, args);
10582
+ }
10583
+ return answer;
10584
+ }
10585
+ };
10586
+ for (; ; ) {
10587
+ try {
10588
+ decide(replay);
10589
+ return replay;
10590
+ } catch (error) {
10591
+ if (!(error instanceof RunNeededError)) {
10592
+ throw error;
10593
+ }
10594
+ answers.set(keyOf2(error.command, error.args), await runAsync(error.command, error.args));
10595
+ }
10596
+ }
10597
+ }
10598
+ async function resolveWithAsyncRuns(decide, runAsync) {
10599
+ let result;
10600
+ await recordRuns((run) => {
10601
+ result = { value: decide(run) };
10602
+ }, runAsync);
10603
+ if (result === void 0) {
10604
+ throw new Error("the decision finished without a result");
10605
+ }
10606
+ return result.value;
10607
+ }
10608
+ var RunNeededError;
10609
+ var init_replayRun = __esm({
10610
+ "src/replayRun.ts"() {
10611
+ "use strict";
10612
+ RunNeededError = class extends Error {
10613
+ constructor(command, args) {
10614
+ super(`no recorded answer for ${command} ${args.join(" ")}`);
10615
+ this.command = command;
10616
+ this.args = args;
10617
+ this.name = "RunNeededError";
10618
+ }
10619
+ command;
10620
+ args;
10621
+ };
10622
+ }
10623
+ });
10624
+
10468
10625
  // src/update/update.ts
10469
10626
  function compareVersions3(left, right) {
10470
10627
  const parse = (version) => {
@@ -10971,6 +11128,59 @@ var init_cliOverride = __esm({
10971
11128
  }
10972
11129
  });
10973
11130
 
11131
+ // src/launcher/launchRecords.ts
11132
+ import path38 from "node:path";
11133
+ import { z as z36 } from "zod";
11134
+ function recordFile(directory, pid, identity) {
11135
+ return path38.join(directory, `${String(pid)}.${identity}${RECORD_SUFFIX}`);
11136
+ }
11137
+ function readRecord(fs15, directory, name) {
11138
+ if (!name.endsWith(RECORD_SUFFIX)) {
11139
+ return void 0;
11140
+ }
11141
+ const raw = fs15.readFileUtf8(path38.join(directory, name));
11142
+ if (raw === void 0) {
11143
+ return void 0;
11144
+ }
11145
+ let parsed;
11146
+ try {
11147
+ parsed = JSON.parse(raw);
11148
+ } catch {
11149
+ return void 0;
11150
+ }
11151
+ const result = LaunchRecordSchema.safeParse(parsed);
11152
+ return result.success ? result.data : void 0;
11153
+ }
11154
+ function registerLaunch(fs15, directory, owner, isRunning) {
11155
+ fs15.mkdirPrivate(directory);
11156
+ for (const name of fs15.readdir(directory)) {
11157
+ const record2 = readRecord(fs15, directory, name);
11158
+ if (record2 !== void 0 && !isRunning(record2.pid)) {
11159
+ fs15.removeRecursive(path38.join(directory, name));
11160
+ }
11161
+ }
11162
+ const file = recordFile(directory, owner.pid, owner.identity);
11163
+ const record = { pid: owner.pid, identity: owner.identity, startedAt: new Date(owner.startedAtMs).toISOString() };
11164
+ fs15.writeFilePrivate(file, `${JSON.stringify(record)}
11165
+ `);
11166
+ return () => {
11167
+ fs15.removeRecursive(file);
11168
+ };
11169
+ }
11170
+ var LaunchRecordSchema, RECORD_SUFFIX;
11171
+ var init_launchRecords = __esm({
11172
+ "src/launcher/launchRecords.ts"() {
11173
+ "use strict";
11174
+ LaunchRecordSchema = z36.strictObject({
11175
+ /** The launcher's process id, which is what tells a launch in progress from a record a crashed launcher left behind. */
11176
+ pid: z36.number().int().positive(),
11177
+ identity: z36.string().min(1),
11178
+ startedAt: z36.iso.datetime()
11179
+ });
11180
+ RECORD_SUFFIX = ".json";
11181
+ }
11182
+ });
11183
+
10974
11184
  // src/headroom/headers.ts
10975
11185
  function mergeAnthropicCustomHeaders(existing, additions) {
10976
11186
  const merged = /* @__PURE__ */ new Map();
@@ -11039,7 +11249,7 @@ var init_settings2 = __esm({
11039
11249
  });
11040
11250
 
11041
11251
  // src/launcher/flags.ts
11042
- import path36 from "node:path";
11252
+ import path39 from "node:path";
11043
11253
  function resolveLaunchFlags(params) {
11044
11254
  const statusline = resolveStatuslineSettings(params);
11045
11255
  return {
@@ -11095,7 +11305,7 @@ function buildEnv(params) {
11095
11305
  const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
11096
11306
  let providerCustomHeaders;
11097
11307
  if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
11098
- env.CLAUDE_CONFIG_DIR = path36.join(params.identitiesDir, params.resolvedIdentityName);
11308
+ env.CLAUDE_CONFIG_DIR = path39.join(params.identitiesDir, params.resolvedIdentityName);
11099
11309
  }
11100
11310
  if (params.provider !== void 0) {
11101
11311
  const providerEnv = params.provider.definition.kind !== void 0 && params.provider.definition.kind !== "http" ? {} : params.provider.definition.env ?? {};
@@ -11187,7 +11397,7 @@ var init_extraFlags = __esm({
11187
11397
  });
11188
11398
 
11189
11399
  // src/usage/resumeContext.ts
11190
- import path37 from "node:path";
11400
+ import path40 from "node:path";
11191
11401
  function projectDirNameOf(cwd) {
11192
11402
  return cwd.replace(/[^A-Za-z0-9]/g, "-");
11193
11403
  }
@@ -11238,15 +11448,15 @@ function contextTokensOfTranscript(text) {
11238
11448
  }
11239
11449
  return void 0;
11240
11450
  }
11241
- function newestTranscript(fs14, projectDir) {
11451
+ function newestTranscript(fs15, projectDir) {
11242
11452
  let newest;
11243
11453
  let newestMs = -Infinity;
11244
- for (const name of fs14.readdir(projectDir)) {
11454
+ for (const name of fs15.readdir(projectDir)) {
11245
11455
  if (!name.endsWith(".jsonl")) {
11246
11456
  continue;
11247
11457
  }
11248
- const candidate = path37.join(projectDir, name);
11249
- const stat = fs14.lstat(candidate);
11458
+ const candidate = path40.join(projectDir, name);
11459
+ const stat = fs15.lstat(candidate);
11250
11460
  if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
11251
11461
  newestMs = stat.mtimeMs;
11252
11462
  newest = candidate;
@@ -11254,14 +11464,14 @@ function newestTranscript(fs14, projectDir) {
11254
11464
  }
11255
11465
  return newest;
11256
11466
  }
11257
- function resumedContextTokens(fs14, params) {
11467
+ function resumedContextTokens(fs15, params) {
11258
11468
  const target = resumeTargetOf(params.passthrough);
11259
11469
  if (target === void 0) {
11260
11470
  return void 0;
11261
11471
  }
11262
- const projectDir = path37.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
11263
- const file = target.kind === "id" ? path37.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs14, projectDir);
11264
- const text = file === void 0 ? void 0 : fs14.readFileUtf8(file);
11472
+ const projectDir = path40.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
11473
+ const file = target.kind === "id" ? path40.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs15, projectDir);
11474
+ const text = file === void 0 ? void 0 : fs15.readFileUtf8(file);
11265
11475
  return text === void 0 ? void 0 : contextTokensOfTranscript(text);
11266
11476
  }
11267
11477
  var init_resumeContext = __esm({
@@ -11857,7 +12067,7 @@ var init_launchHook = __esm({
11857
12067
  // src/launcher.ts
11858
12068
  import { randomUUID as randomUUID4 } from "node:crypto";
11859
12069
  import { isDeepStrictEqual } from "node:util";
11860
- import path38 from "node:path";
12070
+ import path41 from "node:path";
11861
12071
  function resolveIdentityCredential(identity, credential, env, port) {
11862
12072
  if (port === void 0) {
11863
12073
  return { ok: false, status: 1, message: `agent-shim: identity ${identity} needs its credential resolved, but this launcher has no credential port wired` };
@@ -11866,7 +12076,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
11866
12076
  return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
11867
12077
  }
11868
12078
  function pickFromPool(decided, params, parsedArgv, readOnly) {
11869
- const { paths, fs: fs14, proc, log } = params;
12079
+ const { paths, fs: fs15, proc, log } = params;
11870
12080
  if (decided.pool === void 0) {
11871
12081
  return { identityDecision: decided };
11872
12082
  }
@@ -11885,7 +12095,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
11885
12095
  selectedVia: decided.source,
11886
12096
  pools: params.pools,
11887
12097
  paths,
11888
- fs: fs14,
12098
+ fs: fs15,
11889
12099
  usageFs: farmRuntime.fs,
11890
12100
  cwd: farmRuntime.cwd,
11891
12101
  now: farmRuntime.now,
@@ -11909,7 +12119,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
11909
12119
  };
11910
12120
  }
11911
12121
  function decideLaunch(params, readOnly) {
11912
- const { paths, fs: fs14, proc, log } = params;
12122
+ const { paths, fs: fs15, proc, log } = params;
11913
12123
  const { env, argv } = proc;
11914
12124
  const parsedArgv = parseLauncherArgv(argv);
11915
12125
  const cliOverride = buildCliOverride({
@@ -11924,7 +12134,7 @@ function decideLaunch(params, readOnly) {
11924
12134
  argv0Identity: params.pickedIdentity ?? parsedArgv.identity,
11925
12135
  directoryPinnedIdentity: params.directoryPinnedIdentity,
11926
12136
  readActiveIdentityFile: () => {
11927
- const raw = fs14.readFileUtf8(paths.activeIdentityFile);
12137
+ const raw = fs15.readFileUtf8(paths.activeIdentityFile);
11928
12138
  if (raw === void 0) {
11929
12139
  return void 0;
11930
12140
  }
@@ -11959,7 +12169,7 @@ function decideLaunch(params, readOnly) {
11959
12169
  }
11960
12170
  let loadedIdentity;
11961
12171
  if (identityDecision.name !== void 0) {
11962
- loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs14);
12172
+ loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs15);
11963
12173
  if (loadedIdentity === void 0) {
11964
12174
  log.error(
11965
12175
  `agent-shim: no identity named "${identityDecision.name}" (selected via ${identityDecision.source}). Run \`agent-shim identity add ${identityDecision.name}\` first.`
@@ -11974,7 +12184,7 @@ function decideLaunch(params, readOnly) {
11974
12184
  identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
11975
12185
  globalDefaultConfigProfile: params.globalDefaultConfigProfile
11976
12186
  });
11977
- if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs14.readConfigFile(profileFilePath(paths.configProfilesDir, configProfileDecision.name, `the configuration profile selected via ${configProfileDecision.source}`)) === void 0) {
12187
+ if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs15.readConfigFile(profileFilePath(paths.configProfilesDir, configProfileDecision.name, `the configuration profile selected via ${configProfileDecision.source}`)) === void 0) {
11978
12188
  log.error(
11979
12189
  `agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
11980
12190
  );
@@ -11983,7 +12193,7 @@ function decideLaunch(params, readOnly) {
11983
12193
  const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
11984
12194
  const providerParams = {
11985
12195
  paths,
11986
- port: fs14,
12196
+ port: fs15,
11987
12197
  ...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
11988
12198
  ...farmContext === void 0 ? {} : { cascade: farmContext.cascade },
11989
12199
  ...loadedIdentity?.config.provider === void 0 ? {} : { identityProvider: loadedIdentity.config.provider }
@@ -12095,9 +12305,9 @@ function decideLaunch(params, readOnly) {
12095
12305
  const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
12096
12306
  const globalModels = loadConfigFile(paths.globalConfigFile, GlobalConfigSchema, params.fs.readConfigFile)?.config.models;
12097
12307
  const models = launchCascade !== void 0 && params.farm !== void 0 ? cascadeModels : globalModels;
12098
- const listedProviders = listProviderNames(fs14.readdir, paths.providersDir).flatMap((name) => {
12308
+ const listedProviders = listProviderNames(fs15.readdir, paths.providersDir).flatMap((name) => {
12099
12309
  try {
12100
- const definition = loadProvider(paths.providersDir, name, fs14);
12310
+ const definition = loadProvider(paths.providersDir, name, fs15);
12101
12311
  return definition === void 0 ? [] : [[name, definition, parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, name)))?.models ?? []]];
12102
12312
  } catch {
12103
12313
  return [];
@@ -12115,7 +12325,7 @@ function decideLaunch(params, readOnly) {
12115
12325
  extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
12116
12326
  passthrough: withLauncherSettings(params.supervised === void 0 ? parsedArgv.rest : withSupervision(parsedArgv.rest, params.supervised), launcherSettings)
12117
12327
  }) : [...parsedArgv.rest];
12118
- const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path38.join(paths.identitiesDir, identityDecision.name);
12328
+ const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path41.join(paths.identitiesDir, identityDecision.name);
12119
12329
  const decision = {
12120
12330
  identitySource: identityDecision.source,
12121
12331
  configDirEscapeHatch: identityDecision.configDirEscapeHatch,
@@ -12153,6 +12363,19 @@ function decideLaunch(params, readOnly) {
12153
12363
  };
12154
12364
  }
12155
12365
  function prepareLaunch(params) {
12366
+ const removers = [];
12367
+ try {
12368
+ return prepareRegisteredLaunch(params, (remove) => {
12369
+ removers.push(remove);
12370
+ });
12371
+ } catch (error) {
12372
+ for (const remove of removers) {
12373
+ remove();
12374
+ }
12375
+ throw error;
12376
+ }
12377
+ }
12378
+ function prepareRegisteredLaunch(params, onRecorded) {
12156
12379
  const { paths, proc, log } = params;
12157
12380
  const { env } = proc;
12158
12381
  const decided = decideLaunch(params, false);
@@ -12173,14 +12396,17 @@ function prepareLaunch(params) {
12173
12396
  })
12174
12397
  ];
12175
12398
  let warnings = [];
12399
+ let unregisterLaunch;
12176
12400
  const updateCheck = runLaunchUpdateCheck({
12177
12401
  mode: params.updateMode ?? "off",
12178
- checkPath: path38.join(paths.root, "update.check"),
12402
+ checkPath: path41.join(paths.root, "update.check"),
12179
12403
  currentVersion: package_default.version,
12180
12404
  port: params.update
12181
12405
  });
12182
12406
  if (decided.farmContext !== void 0) {
12183
12407
  const { farm: resyncFarmRuntime, identity: resyncIdentity, cascade } = decided.farmContext;
12408
+ unregisterLaunch = registerLaunch(resyncFarmRuntime.fs, paths.launchesDir, { pid: resyncFarmRuntime.lock.pid, identity: resyncIdentity, startedAtMs: resyncFarmRuntime.now() }, resyncFarmRuntime.lock.isRunning);
12409
+ onRecorded(unregisterLaunch);
12184
12410
  let result;
12185
12411
  try {
12186
12412
  result = resyncFarm({
@@ -12198,10 +12424,11 @@ function prepareLaunch(params) {
12198
12424
  classification: resyncFarmRuntime.classification,
12199
12425
  now: resyncFarmRuntime.now,
12200
12426
  uniqueSuffix: resyncFarmRuntime.uniqueSuffix,
12427
+ identityExists: () => loadIdentity(paths.identitiesDir, resyncIdentity, params.fs) !== void 0,
12201
12428
  lock: resyncFarmRuntime.lock
12202
12429
  });
12203
12430
  } catch (error) {
12204
- if (error instanceof IdentityLockBusyError) {
12431
+ if (error instanceof IdentityLockBusyError || error instanceof IdentityGoneError) {
12205
12432
  log.error(error.message);
12206
12433
  proc.exit(1);
12207
12434
  }
@@ -12261,7 +12488,7 @@ function prepareLaunch(params) {
12261
12488
  proxyBypass: resolvedFlags.proxyBypass,
12262
12489
  ...resolvedFlags.statusline === void 0 ? {} : { statusline: resolvedFlags.statusline }
12263
12490
  });
12264
- const releases = [...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
12491
+ const releases = [...unregisterLaunch === void 0 ? [] : [unregisterLaunch], ...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
12265
12492
  const release = () => {
12266
12493
  for (const registered of releases) {
12267
12494
  registered();
@@ -12330,6 +12557,7 @@ var init_launcher = __esm({
12330
12557
  init_argv();
12331
12558
  init_cliOverride();
12332
12559
  init_farm();
12560
+ init_launchRecords();
12333
12561
  init_guard();
12334
12562
  init_identity();
12335
12563
  init_flags();
@@ -12365,12 +12593,12 @@ var init_launcher = __esm({
12365
12593
  });
12366
12594
 
12367
12595
  // src/ownCli.ts
12368
- import path39 from "node:path";
12596
+ import path42 from "node:path";
12369
12597
  function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string" ? __AGENT_SHIM_DIST_DIR__ : void 0) {
12370
12598
  if (distDir === void 0) {
12371
12599
  throw new OwnCliPathUnknownError();
12372
12600
  }
12373
- return path39.join(distDir, OWN_CLI_FILE_NAME);
12601
+ return path42.join(distDir, OWN_CLI_FILE_NAME);
12374
12602
  }
12375
12603
  var OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
12376
12604
  var init_ownCli = __esm({
@@ -12388,10 +12616,10 @@ var init_ownCli = __esm({
12388
12616
  });
12389
12617
 
12390
12618
  // src/frontdoor/doorLog.ts
12391
- import fs12 from "node:fs";
12619
+ import fs13 from "node:fs";
12392
12620
  function appendDoorLog(paths, line) {
12393
- fs12.mkdirSync(paths.logsDir, { recursive: true });
12394
- fs12.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
12621
+ fs13.mkdirSync(paths.logsDir, { recursive: true });
12622
+ fs13.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
12395
12623
  `);
12396
12624
  }
12397
12625
  var init_doorLog = __esm({
@@ -12416,16 +12644,16 @@ var init_selfIdentity = __esm({
12416
12644
 
12417
12645
  // src/frontdoor/trust.ts
12418
12646
  import { createHash as createHash7 } from "node:crypto";
12419
- import path40 from "node:path";
12647
+ import path43 from "node:path";
12420
12648
  function resolveTrustBundle(params) {
12421
- const { caCertFile, bundlesDir, variable, inherited, fs: fs14 } = params;
12422
- if (inherited === void 0 || inherited === "" || path40.resolve(inherited) === path40.resolve(caCertFile)) {
12649
+ const { caCertFile, bundlesDir, variable, inherited, fs: fs15 } = params;
12650
+ if (inherited === void 0 || inherited === "" || path43.resolve(inherited) === path43.resolve(caCertFile)) {
12423
12651
  return { path: caCertFile };
12424
12652
  }
12425
- const caPem = fs14.readFileUtf8(caCertFile);
12653
+ const caPem = fs15.readFileUtf8(caCertFile);
12426
12654
  let inheritedPem;
12427
12655
  try {
12428
- inheritedPem = fs14.readFileUtf8(inherited);
12656
+ inheritedPem = fs15.readFileUtf8(inherited);
12429
12657
  } catch (error) {
12430
12658
  return {
12431
12659
  path: caCertFile,
@@ -12437,10 +12665,10 @@ function resolveTrustBundle(params) {
12437
12665
  }
12438
12666
  const combined = `${inheritedPem.trimEnd()}
12439
12667
  ${caPem}`;
12440
- const bundle = path40.join(bundlesDir, `${createHash7("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
12441
- if (!fs14.exists(bundle)) {
12442
- fs14.mkdirp(bundlesDir);
12443
- fs14.writeFileAtomic(bundle, combined);
12668
+ const bundle = path43.join(bundlesDir, `${createHash7("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
12669
+ if (!fs15.exists(bundle)) {
12670
+ fs15.mkdirp(bundlesDir);
12671
+ fs15.writeFileAtomic(bundle, combined);
12444
12672
  }
12445
12673
  return { path: bundle };
12446
12674
  }
@@ -12453,7 +12681,7 @@ var init_trust = __esm({
12453
12681
  });
12454
12682
 
12455
12683
  // src/frontdoor/realFrontDoorPort.ts
12456
- import fs13 from "node:fs";
12684
+ import fs14 from "node:fs";
12457
12685
  function realEnsurePorts(paths, spawnDaemon) {
12458
12686
  return {
12459
12687
  fs: realFarmFs,
@@ -12479,7 +12707,7 @@ function realEnsurePorts(paths, spawnDaemon) {
12479
12707
  }
12480
12708
  },
12481
12709
  // Read fresh for each probe: a replacement supervisor may have regenerated an unparseable CA, and the probe must trust exactly what the serving door's leaf chains to.
12482
- verifyListener: (port) => probeFrontDoorSync(port, fs13.readFileSync(paths.frontdoorCaCertFile, "utf8"))
12710
+ verifyListener: (port) => probeFrontDoorSync(port, fs14.readFileSync(paths.frontdoorCaCertFile, "utf8"))
12483
12711
  };
12484
12712
  }
12485
12713
  function realFrontDoorPort(paths, spawnDaemon) {
@@ -12512,10 +12740,10 @@ var init_realFrontDoorPort = __esm({
12512
12740
  init_selfIdentity();
12513
12741
  init_trust();
12514
12742
  realTrustBundleFs = {
12515
- readFileUtf8: (file) => fs13.readFileSync(file, "utf8"),
12516
- exists: (file) => fs13.existsSync(file),
12743
+ readFileUtf8: (file) => fs14.readFileSync(file, "utf8"),
12744
+ exists: (file) => fs14.existsSync(file),
12517
12745
  mkdirp: (dir) => {
12518
- fs13.mkdirSync(dir, { recursive: true });
12746
+ fs14.mkdirSync(dir, { recursive: true });
12519
12747
  },
12520
12748
  writeFileAtomic: (file, contents) => {
12521
12749
  realFarmFs.writeFilePrivate(file, contents);
@@ -12524,53 +12752,9 @@ var init_realFrontDoorPort = __esm({
12524
12752
  }
12525
12753
  });
12526
12754
 
12527
- // src/replayRun.ts
12528
- function keyOf2(command, args) {
12529
- return JSON.stringify([command, args]);
12530
- }
12531
- async function recordRuns(decide, runAsync) {
12532
- const answers = /* @__PURE__ */ new Map();
12533
- const replay = {
12534
- run: (command, args) => {
12535
- const answer = answers.get(keyOf2(command, args));
12536
- if (answer === void 0) {
12537
- throw new RunNeededError(command, args);
12538
- }
12539
- return answer;
12540
- }
12541
- };
12542
- for (; ; ) {
12543
- try {
12544
- decide(replay);
12545
- return replay;
12546
- } catch (error) {
12547
- if (!(error instanceof RunNeededError)) {
12548
- throw error;
12549
- }
12550
- answers.set(keyOf2(error.command, error.args), await runAsync(error.command, error.args));
12551
- }
12552
- }
12553
- }
12554
- var RunNeededError;
12555
- var init_replayRun = __esm({
12556
- "src/replayRun.ts"() {
12557
- "use strict";
12558
- RunNeededError = class extends Error {
12559
- constructor(command, args) {
12560
- super(`no recorded answer for ${command} ${args.join(" ")}`);
12561
- this.command = command;
12562
- this.args = args;
12563
- this.name = "RunNeededError";
12564
- }
12565
- command;
12566
- args;
12567
- };
12568
- }
12569
- });
12570
-
12571
12755
  // src/launchWiring.ts
12572
12756
  import os8 from "node:os";
12573
- import path41 from "node:path";
12757
+ import path44 from "node:path";
12574
12758
  import { randomUUID as randomUUID5 } from "node:crypto";
12575
12759
  function buildFarmRuntime(paths, cwd, run = realRunPort) {
12576
12760
  const home = os8.homedir();
@@ -12625,7 +12809,7 @@ function realPrepareLaunchParams(paths, options) {
12625
12809
  frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
12626
12810
  credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
12627
12811
  hold: realHoldPort,
12628
- hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot: path41.join(paths.identitiesDir, identity), hasCredentialBlock: false, provider: void 0 }).state !== "signed-out",
12812
+ hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot: path44.join(paths.identitiesDir, identity), hasCredentialBlock: false, provider: void 0 }).state !== "signed-out",
12629
12813
  ...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
12630
12814
  ...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
12631
12815
  ...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
@@ -12910,7 +13094,7 @@ var init_identityClaude = __esm({
12910
13094
  });
12911
13095
 
12912
13096
  // src/usage/providerQuota.ts
12913
- import { z as z35 } from "zod";
13097
+ import { z as z37 } from "zod";
12914
13098
  var MS_PER_SECOND9, SECONDS_PER_HOUR3, HOURS_PER_DAY6, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY2, OpenRouterKeySchema, OpenRouterCreditsSchema, ANTIGRAVITY_HOST, ANTIGRAVITY_QUOTA_URL, ANTIGRAVITY_USER_URL, FIVE_HOURS2, DAYS_PER_WEEK2, FIVE_HOURS_MS, WEEK_MS, AntigravityBucketSchema, AntigravitySummarySchema, GoogleTokenInfoSchema, AntigravityUserSchema;
12915
13099
  var init_providerQuota = __esm({
12916
13100
  "src/usage/providerQuota.ts"() {
@@ -12929,35 +13113,35 @@ var init_providerQuota = __esm({
12929
13113
  [ZAI_UNIT_HOURS, SECONDS_PER_HOUR3 * MS_PER_SECOND9],
12930
13114
  [ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9]
12931
13115
  ]);
12932
- ZaiLimitSchema = z35.object({
12933
- type: z35.string(),
12934
- unit: z35.number().int(),
12935
- number: z35.number().int().positive(),
12936
- percentage: z35.number().nonnegative(),
12937
- nextResetTime: z35.number().positive().optional(),
12938
- usage: z35.number().nonnegative().optional(),
12939
- currentValue: z35.number().nonnegative().optional(),
12940
- remaining: z35.number().nonnegative().optional()
13116
+ ZaiLimitSchema = z37.object({
13117
+ type: z37.string(),
13118
+ unit: z37.number().int(),
13119
+ number: z37.number().int().positive(),
13120
+ percentage: z37.number().nonnegative(),
13121
+ nextResetTime: z37.number().positive().optional(),
13122
+ usage: z37.number().nonnegative().optional(),
13123
+ currentValue: z37.number().nonnegative().optional(),
13124
+ remaining: z37.number().nonnegative().optional()
12941
13125
  });
12942
- ZaiResponseSchema = z35.object({
12943
- success: z35.boolean(),
12944
- msg: z35.string().optional(),
12945
- data: z35.object({ level: z35.string().optional(), limits: z35.array(ZaiLimitSchema) })
13126
+ ZaiResponseSchema = z37.object({
13127
+ success: z37.boolean(),
13128
+ msg: z37.string().optional(),
13129
+ data: z37.object({ level: z37.string().optional(), limits: z37.array(ZaiLimitSchema) })
12946
13130
  });
12947
13131
  OPENROUTER_HOST = "openrouter.ai";
12948
13132
  OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
12949
13133
  OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
12950
13134
  MS_PER_DAY2 = HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
12951
- OpenRouterKeySchema = z35.object({
12952
- data: z35.object({
12953
- limit: z35.number().nonnegative().nullable(),
12954
- limit_remaining: z35.number().nullable(),
12955
- limit_reset: z35.string().nullable(),
12956
- is_free_tier: z35.boolean().optional(),
12957
- free_model_daily_requests: z35.object({ used: z35.number().nonnegative(), limit: z35.number().nonnegative(), remaining: z35.number() }).optional()
13135
+ OpenRouterKeySchema = z37.object({
13136
+ data: z37.object({
13137
+ limit: z37.number().nonnegative().nullable(),
13138
+ limit_remaining: z37.number().nullable(),
13139
+ limit_reset: z37.string().nullable(),
13140
+ is_free_tier: z37.boolean().optional(),
13141
+ free_model_daily_requests: z37.object({ used: z37.number().nonnegative(), limit: z37.number().nonnegative(), remaining: z37.number() }).optional()
12958
13142
  })
12959
13143
  });
12960
- OpenRouterCreditsSchema = z35.object({ data: z35.object({ total_credits: z35.number().nonnegative(), total_usage: z35.number().nonnegative() }) });
13144
+ OpenRouterCreditsSchema = z37.object({ data: z37.object({ total_credits: z37.number().nonnegative(), total_usage: z37.number().nonnegative() }) });
12961
13145
  ANTIGRAVITY_HOST = "daily-cloudcode-pa.googleapis.com";
12962
13146
  ANTIGRAVITY_QUOTA_URL = `https://${ANTIGRAVITY_HOST}/v1internal:retrieveUserQuotaSummary`;
12963
13147
  ANTIGRAVITY_USER_URL = `https://${ANTIGRAVITY_HOST}/v1internal:loadCodeAssist`;
@@ -12965,21 +13149,21 @@ var init_providerQuota = __esm({
12965
13149
  DAYS_PER_WEEK2 = 7;
12966
13150
  FIVE_HOURS_MS = FIVE_HOURS2 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
12967
13151
  WEEK_MS = DAYS_PER_WEEK2 * HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
12968
- AntigravityBucketSchema = z35.object({
12969
- bucketId: z35.string(),
12970
- remainingFraction: z35.number().optional(),
12971
- resetTime: z35.string().optional()
13152
+ AntigravityBucketSchema = z37.object({
13153
+ bucketId: z37.string(),
13154
+ remainingFraction: z37.number().optional(),
13155
+ resetTime: z37.string().optional()
12972
13156
  });
12973
- AntigravitySummarySchema = z35.object({ groups: z35.array(z35.object({ buckets: z35.array(AntigravityBucketSchema) })) });
12974
- GoogleTokenInfoSchema = z35.object({
12975
- email: z35.string().optional(),
12976
- sub: z35.string().optional()
13157
+ AntigravitySummarySchema = z37.object({ groups: z37.array(z37.object({ buckets: z37.array(AntigravityBucketSchema) })) });
13158
+ GoogleTokenInfoSchema = z37.object({
13159
+ email: z37.string().optional(),
13160
+ sub: z37.string().optional()
12977
13161
  });
12978
- AntigravityUserSchema = z35.object({
13162
+ AntigravityUserSchema = z37.object({
12979
13163
  /** The code-assist tier context, which defaults to the free tier for every account. */
12980
- currentTier: z35.object({ name: z35.string().optional(), id: z35.string().optional() }).optional(),
13164
+ currentTier: z37.object({ name: z37.string().optional(), id: z37.string().optional() }).optional(),
12981
13165
  /** The account's paid subscription; absent when the account has none. */
12982
- paidTier: z35.object({ name: z35.string().optional(), id: z35.string().optional() }).optional()
13166
+ paidTier: z37.object({ name: z37.string().optional(), id: z37.string().optional() }).optional()
12983
13167
  });
12984
13168
  }
12985
13169
  });
@@ -13358,8 +13542,8 @@ function pathnameOf(url) {
13358
13542
  return new URL(url ?? "/", "http://127.0.0.1").pathname;
13359
13543
  }
13360
13544
  function isRcSessionExchange(url) {
13361
- const path42 = pathnameOf(url);
13362
- return path42 === RC_SESSIONS_PATH_PREFIX || path42.startsWith(`${RC_SESSIONS_PATH_PREFIX}/`);
13545
+ const path45 = pathnameOf(url);
13546
+ return path45 === RC_SESSIONS_PATH_PREFIX || path45.startsWith(`${RC_SESSIONS_PATH_PREFIX}/`);
13363
13547
  }
13364
13548
  var RC_SESSION_ID_PREFIX = "cse_";
13365
13549
  var RC_IDLE_EXPIRY_MS = 45e3;
@@ -13918,8 +14102,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
13918
14102
  function isRcReadFileEncoding(value) {
13919
14103
  return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
13920
14104
  }
13921
- function buildRcReadFilePayload(requestId, path42, options) {
13922
- return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path42, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
14105
+ function buildRcReadFilePayload(requestId, path45, options) {
14106
+ return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path45, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
13923
14107
  }
13924
14108
  function buildRcFileSuggestionsPayload(requestId, query) {
13925
14109
  return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
@@ -14021,15 +14205,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
14021
14205
  const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
14022
14206
  return result.ok ? { ...result, requestId } : result;
14023
14207
  }
14024
- async function readRcSessionFile(deps, sessionId, path42, options) {
14025
- if (path42 === "") {
14208
+ async function readRcSessionFile(deps, sessionId, path45, options) {
14209
+ if (path45 === "") {
14026
14210
  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" };
14027
14211
  }
14028
14212
  if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
14029
14213
  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" };
14030
14214
  }
14031
14215
  const requestId = deps.newUuid();
14032
- const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path42, options), `read ${path42} from session ${sessionId}`);
14216
+ const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path45, options), `read ${path45} from session ${sessionId}`);
14033
14217
  return result.ok ? { ...result, requestId } : result;
14034
14218
  }
14035
14219
  async function suggestRcSessionFiles(deps, sessionId, query) {
@@ -14198,11 +14382,11 @@ function createRcControlHandler(deps) {
14198
14382
  path: "read-file",
14199
14383
  read: (body) => {
14200
14384
  const session = bodyString(body, "session");
14201
- const path42 = bodyString(body, "path");
14385
+ const path45 = bodyString(body, "path");
14202
14386
  const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
14203
14387
  const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
14204
- const refused2 = session === void 0 || path42 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
14205
- 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, path42, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
14388
+ const refused2 = session === void 0 || path45 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
14389
+ 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, path45, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
14206
14390
  }
14207
14391
  },
14208
14392
  {
@@ -14512,9 +14696,9 @@ function requestIdOfBody(body) {
14512
14696
  }
14513
14697
  function frontDoorRcControl(transport, token) {
14514
14698
  const headers = { authorization: `Bearer ${token}` };
14515
- const listAnswerOf = async (path42, what) => {
14699
+ const listAnswerOf = async (path45, what) => {
14516
14700
  try {
14517
- return await transport.request({ method: "GET", path: path42, headers });
14701
+ return await transport.request({ method: "GET", path: path45, headers });
14518
14702
  } catch (error) {
14519
14703
  throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
14520
14704
  }
@@ -14586,10 +14770,10 @@ function frontDoorRcControl(transport, token) {
14586
14770
  }
14587
14771
  return pending;
14588
14772
  };
14589
- const writeOf = async (path42, body, describeFailure2) => {
14773
+ const writeOf = async (path45, body, describeFailure2) => {
14590
14774
  let answer;
14591
14775
  try {
14592
- answer = await transport.request({ method: "POST", path: path42, headers: { ...headers, "content-type": "application/json" }, body });
14776
+ answer = await transport.request({ method: "POST", path: path45, headers: { ...headers, "content-type": "application/json" }, body });
14593
14777
  } catch (error) {
14594
14778
  return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
14595
14779
  }
@@ -14620,10 +14804,10 @@ function frontDoorRcControl(transport, token) {
14620
14804
  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}`),
14621
14805
  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}`),
14622
14806
  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}`),
14623
- readFile: async (sessionId, path42, options) => await writeOf(
14807
+ readFile: async (sessionId, path45, options) => await writeOf(
14624
14808
  `${CONTROL_PATH_PREFIX}/read-file`,
14625
- JSON.stringify({ session: sessionId, path: path42, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
14626
- (status, message) => `reading ${path42} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
14809
+ JSON.stringify({ session: sessionId, path: path45, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
14810
+ (status, message) => `reading ${path45} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
14627
14811
  ),
14628
14812
  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}`),
14629
14813
  keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
@@ -14782,12 +14966,12 @@ function tlsFacts(options) {
14782
14966
  }
14783
14967
  function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
14784
14968
  const agent = new ExemptTlsAgent();
14785
- const post = async (path42, headers, body) => await new Promise((resolve, reject) => {
14969
+ const post = async (path45, headers, body) => await new Promise((resolve, reject) => {
14786
14970
  const options = {
14787
14971
  host: target.host,
14788
14972
  port: target.port,
14789
14973
  method: "POST",
14790
- path: path42,
14974
+ path: path45,
14791
14975
  // 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.
14792
14976
  headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
14793
14977
  agent
@@ -14852,12 +15036,12 @@ function lateRcStreamDial(resolve) {
14852
15036
  }
14853
15037
  function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
14854
15038
  const agent = new ExemptTlsAgent();
14855
- const request4 = async (method, path42, headers, body, signal) => await new Promise((resolve, reject) => {
15039
+ const request4 = async (method, path45, headers, body, signal) => await new Promise((resolve, reject) => {
14856
15040
  const options = {
14857
15041
  host: target.host,
14858
15042
  port: target.port,
14859
15043
  method,
14860
- path: path42,
15044
+ path: path45,
14861
15045
  // 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.
14862
15046
  headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
14863
15047
  agent,
@@ -14899,9 +15083,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
14899
15083
  return { status, body: await readAll(response) };
14900
15084
  },
14901
15085
  openStream: async (sessionId, headers, resume, signal) => {
14902
- const path42 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
15086
+ const path45 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
14903
15087
  const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
14904
- const { status, response } = await request4("GET", path42, streamHeaders, void 0, signal);
15088
+ const { status, response } = await request4("GET", path45, streamHeaders, void 0, signal);
14905
15089
  if (!isSuccessful2(status)) {
14906
15090
  await readAll(response);
14907
15091
  return { status, chunks: NO_CHUNKS };
@@ -15151,11 +15335,11 @@ function credentialOfJson(parsed) {
15151
15335
  function sequenceNumOfJson(value) {
15152
15336
  return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
15153
15337
  }
15154
- function createRcCredentialStore(fs14, dir) {
15155
- fs14.mkdirPrivate(dir);
15338
+ function createRcCredentialStore(fs15, dir) {
15339
+ fs15.mkdirPrivate(dir);
15156
15340
  const fileFor = (sessionId) => path11.join(dir, `${sessionId}.json`);
15157
15341
  const readParsed = (sessionId) => {
15158
- const raw = fs14.readFileUtf8(fileFor(sessionId));
15342
+ const raw = fs15.readFileUtf8(fileFor(sessionId));
15159
15343
  if (raw === void 0) {
15160
15344
  return void 0;
15161
15345
  }
@@ -15180,7 +15364,7 @@ function createRcCredentialStore(fs14, dir) {
15180
15364
  }
15181
15365
  const cursor = sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
15182
15366
  const record = { ...credential, ...cursor === void 0 ? {} : { highestSequenceNum: cursor } };
15183
- fs14.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
15367
+ fs15.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
15184
15368
  `);
15185
15369
  },
15186
15370
  readCursor: (sessionId) => {
@@ -15195,14 +15379,14 @@ function createRcCredentialStore(fs14, dir) {
15195
15379
  }
15196
15380
  const credential = credentialOfJson(readParsed(sessionId));
15197
15381
  const record = credential === void 0 ? { highestSequenceNum } : { ...credential, highestSequenceNum };
15198
- fs14.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
15382
+ fs15.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
15199
15383
  `);
15200
15384
  },
15201
15385
  remove: (sessionId) => {
15202
15386
  if (!isSafeSessionId(sessionId)) {
15203
15387
  return;
15204
15388
  }
15205
- fs14.removeRecursive(fileFor(sessionId));
15389
+ fs15.removeRecursive(fileFor(sessionId));
15206
15390
  }
15207
15391
  };
15208
15392
  }
@@ -15894,19 +16078,19 @@ function writePools(paths, pools) {
15894
16078
  applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
15895
16079
  }
15896
16080
  function poolCycleOf(pools, name) {
15897
- const walk2 = (current, path42) => {
16081
+ const walk2 = (current, path45) => {
15898
16082
  for (const entry of pools[current]?.identities ?? []) {
15899
16083
  const nested = poolNameOf(poolMemberIdentity(entry));
15900
16084
  if (nested === void 0) {
15901
16085
  continue;
15902
16086
  }
15903
16087
  if (nested === name) {
15904
- return [...path42, nested];
16088
+ return [...path45, nested];
15905
16089
  }
15906
- if (path42.includes(nested)) {
16090
+ if (path45.includes(nested)) {
15907
16091
  continue;
15908
16092
  }
15909
- const found = walk2(nested, [...path42, nested]);
16093
+ const found = walk2(nested, [...path45, nested]);
15910
16094
  if (found !== void 0) {
15911
16095
  return found;
15912
16096
  }
@@ -16346,7 +16530,7 @@ function loadCheckProvider(paths, name) {
16346
16530
  try {
16347
16531
  definition = readProvider(paths, name);
16348
16532
  } catch (error) {
16349
- if (error instanceof ConfigValidationError || error instanceof LegacyProviderFileError) {
16533
+ if (error instanceof ConfigValidationError || error instanceof LegacyProviderFileError || error instanceof ConfigFileNotJsonError) {
16350
16534
  return { name, problem: error.message };
16351
16535
  }
16352
16536
  throw error;
@@ -16618,8 +16802,8 @@ var ResetRowSchema = z22.strictObject({
16618
16802
  var ResetScheduleSchema = z22.strictObject({ resets: z22.readonly(z22.array(ResetRowSchema)) });
16619
16803
 
16620
16804
  // src/frontdoor/controlSchemas.ts
16621
- import path30 from "node:path";
16622
- import { z as z29 } from "zod";
16805
+ import path32 from "node:path";
16806
+ import { z as z30 } from "zod";
16623
16807
 
16624
16808
  // src/doctorReport.ts
16625
16809
  init_claudeShim();
@@ -16628,13 +16812,211 @@ init_store();
16628
16812
 
16629
16813
  // src/identityStore.ts
16630
16814
  init_load();
16815
+ init_names();
16631
16816
  init_store();
16632
16817
  init_schema();
16633
16818
  init_cliError();
16634
16819
  init_identity();
16635
- import fs9 from "node:fs";
16636
- import path28 from "node:path";
16820
+ import fs10 from "node:fs";
16821
+ import path30 from "node:path";
16637
16822
  init_lock();
16823
+
16824
+ // src/identityRenameJournal.ts
16825
+ init_cliError();
16826
+ import path28 from "node:path";
16827
+ import { z as z24 } from "zod";
16828
+ var RenameJournalSchema = z24.strictObject({
16829
+ version: z24.literal(1),
16830
+ from: z24.string().min(1),
16831
+ to: z24.string().min(1),
16832
+ startedAt: z24.iso.datetime(),
16833
+ /** The process that began the rename, for a person reading the file. Whether it is still running is told by the locks, not by this. */
16834
+ pid: z24.number().int().positive(),
16835
+ steps: z24.array(
16836
+ z24.strictObject({
16837
+ description: z24.string().min(1),
16838
+ /** Whether the step has been applied and marked so. */
16839
+ done: z24.boolean(),
16840
+ /** Whether the step was begun: written ahead of the step, before it runs, so a process that dies after the step took effect and before `done` was written still leaves a record that it may have. */
16841
+ started: z24.boolean()
16842
+ })
16843
+ )
16844
+ });
16845
+ var JOURNAL_SUFFIX = ".json";
16846
+ var RenameJournalUnreadableError = class extends CliError {
16847
+ constructor(file, detail) {
16848
+ super(`${file} is not a rename journal this agent-shim can read (${detail}). If no rename was left unfinished, remove it; otherwise look at what it names before renaming anything.`);
16849
+ this.detail = detail;
16850
+ this.name = "RenameJournalUnreadableError";
16851
+ }
16852
+ detail;
16853
+ };
16854
+ function readRenameJournal(fs15, file) {
16855
+ const raw = fs15.readFileUtf8(file);
16856
+ if (raw === void 0) {
16857
+ return void 0;
16858
+ }
16859
+ let parsed;
16860
+ try {
16861
+ parsed = JSON.parse(raw);
16862
+ } catch {
16863
+ throw new RenameJournalUnreadableError(file, "not valid JSON");
16864
+ }
16865
+ const result = RenameJournalSchema.safeParse(parsed);
16866
+ if (!result.success) {
16867
+ throw new RenameJournalUnreadableError(file, result.error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; "));
16868
+ }
16869
+ return result.data;
16870
+ }
16871
+ function listRenameJournals(fs15, directory) {
16872
+ const journals = [];
16873
+ const unreadable = [];
16874
+ for (const name of [...fs15.readdir(directory)].sort()) {
16875
+ if (!name.endsWith(JOURNAL_SUFFIX)) {
16876
+ continue;
16877
+ }
16878
+ const file = path28.join(directory, name);
16879
+ try {
16880
+ const journal = readRenameJournal(fs15, file);
16881
+ if (journal !== void 0) {
16882
+ journals.push(journal);
16883
+ }
16884
+ } catch (error) {
16885
+ if (!(error instanceof RenameJournalUnreadableError)) {
16886
+ throw error;
16887
+ }
16888
+ unreadable.push({ file, detail: error.detail });
16889
+ }
16890
+ }
16891
+ return { journals, unreadable };
16892
+ }
16893
+ function stepMayBeApplied(step) {
16894
+ return step.done || step.started;
16895
+ }
16896
+ function recordsNothingApplied(journal) {
16897
+ return !journal.steps.some(stepMayBeApplied);
16898
+ }
16899
+ function describeUnfinishable(bothExist) {
16900
+ return bothExist ? "both names are identities" : "there is no identity under either name";
16901
+ }
16902
+ function finishabilityOf(journal, exists) {
16903
+ const underFrom = exists(journal.from);
16904
+ if (underFrom === exists(journal.to)) {
16905
+ return { finishable: false, reason: describeUnfinishable(underFrom) };
16906
+ }
16907
+ return underFrom && recordsNothingApplied(journal) ? { finishable: true, discardable: true } : { finishable: true };
16908
+ }
16909
+ function discardJournalCommand(journal) {
16910
+ return `agent-shim identity rename ${journal.from} ${journal.to} --discard-journal`;
16911
+ }
16912
+ function describeUnfinishedRename(journal, finishability) {
16913
+ const applied = journal.steps.filter(stepMayBeApplied).length;
16914
+ const progress = `an unfinished rename of identity "${journal.from}" to "${journal.to}" (${String(applied)} of ${String(journal.steps.length)} steps recorded as begun or done)`;
16915
+ return finishability.finishable ? `${progress}. Finish it with \`agent-shim identity rename ${journal.from} ${journal.to}\`; to put the name back afterwards, run \`agent-shim identity rename ${journal.to} ${journal.from}\`.${finishability.discardable === true ? ` No step is recorded as begun or done and the identity is still under "${journal.from}", so its record can be discarded with \`${discardJournalCommand(journal)}\`; that removes only the record.` : ""}` : `${progress} that cannot be finished: ${finishability.reason}. If nothing is left of it to keep, discard its record with \`${discardJournalCommand(journal)}\`; that removes only the record and changes no identity.`;
16916
+ }
16917
+ var NameHeldByUnfinishedRenameError = class extends CliError {
16918
+ constructor(action, name, journal, finishability) {
16919
+ super(`Cannot ${action} identity "${name}": there is ${describeUnfinishedRename(journal, finishability)}`);
16920
+ this.name = "NameHeldByUnfinishedRenameError";
16921
+ }
16922
+ };
16923
+ function requireNameFreeOfUnfinishedRename(fs15, directory, name, action, sameName, exists) {
16924
+ const held = listRenameJournals(fs15, directory).journals.find((journal) => [journal.from, journal.to].some((heldName) => heldName === name || sameName(name, heldName)));
16925
+ if (held !== void 0) {
16926
+ throw new NameHeldByUnfinishedRenameError(action, name, held, finishabilityOf(held, exists));
16927
+ }
16928
+ }
16929
+
16930
+ // src/keychainLogin.ts
16931
+ init_cliError();
16932
+ init_signIn();
16933
+ var ITEM_NOT_FOUND_STATUS = 44;
16934
+ var MAX_DETAIL_CHARS = 200;
16935
+ var CONTROL_CHARACTER = new RegExp("\\p{Cc}", "u");
16936
+ var KeychainLoginError = class extends CliError {
16937
+ constructor(message) {
16938
+ super(message);
16939
+ this.name = "KeychainLoginError";
16940
+ }
16941
+ };
16942
+ var KeychainLookupError = class extends KeychainLoginError {
16943
+ constructor(message) {
16944
+ super(message);
16945
+ this.name = "KeychainLookupError";
16946
+ }
16947
+ };
16948
+ function statusPhrase(status) {
16949
+ return status === null ? "without a status" : String(status);
16950
+ }
16951
+ function describe(stderr) {
16952
+ const [first] = stderr.trim().split("\n");
16953
+ return first === void 0 || first === "" ? "" : ` (${first.slice(0, MAX_DETAIL_CHARS)})`;
16954
+ }
16955
+ function lookup(run, service) {
16956
+ const result = run.run("security", ["find-generic-password", "-s", service]);
16957
+ if (result.status === 0) {
16958
+ return { found: true, attributes: result.stdout };
16959
+ }
16960
+ if (result.status === ITEM_NOT_FOUND_STATUS) {
16961
+ return { found: false };
16962
+ }
16963
+ throw new KeychainLookupError(`Could not look up the Keychain item ${service}: security exited ${statusPhrase(result.status)}${describe(result.stderr)}.`);
16964
+ }
16965
+ function plainAccountOf(attributes) {
16966
+ const line = attributes.split("\n").find((candidate) => candidate.includes('"acct"<blob>='));
16967
+ const value = line?.slice(line.indexOf("=") + 1).trim();
16968
+ const name = value === void 0 ? void 0 : /^"([^"\\]*)"$/u.exec(value)?.[1];
16969
+ return name === void 0 || name === "" || CONTROL_CHARACTER.test(name) ? void 0 : name;
16970
+ }
16971
+ function keychainDeleteCommand(service, account) {
16972
+ return `security delete-generic-password -s ${shellQuoted(service)}${account === void 0 ? "" : ` -a ${shellQuoted(account)}`}`;
16973
+ }
16974
+ function shellQuoted(value) {
16975
+ return `'${value.replace(/'/gu, "'\\''")}'`;
16976
+ }
16977
+ var KEEP_KEYCHAIN_LOGIN_DESCRIPTION = "Create the identity even though the macOS Keychain already holds a Claude Code login filed for its directory (left by an identity of that name that was renamed or removed); the identity starts signed in as that account. If another identity holds that login, the two share it. Without it that login is refused and the command that deletes it is printed.";
16978
+ function requireNoLeftoverKeychainLogin(keychain, configDir, name, keepLogin) {
16979
+ if (keepLogin || keychain.platform !== "darwin") {
16980
+ return;
16981
+ }
16982
+ const service = claudeCodeKeychainService(configDir);
16983
+ const found = lookup(keychain.run, service);
16984
+ if (!found.found) {
16985
+ return;
16986
+ }
16987
+ const account = plainAccountOf(found.attributes);
16988
+ throw new KeychainLoginError(
16989
+ `Cannot create identity "${name}": the Keychain already holds a Claude Code login filed for ${configDir} (service ${service}${account === void 0 ? "" : `, account ${account}`}), left behind by an identity of that name that was renamed or removed. A new identity there would start signed in as that account. If you do not need it, delete it with \`${keychainDeleteCommand(service, account)}\` and run the command again. To create the identity signed in as that account on purpose, run \`agent-shim identity add ${name} --keep-keychain-login\`. If another identity holds a copy of that login, as a renamed identity does when its old item could not be deleted, keeping it makes the two share one login.`
16990
+ );
16991
+ }
16992
+
16993
+ // src/sameDirectory.ts
16994
+ import fs9 from "node:fs";
16995
+ import path29 from "node:path";
16996
+ function sameDirectory(first, second) {
16997
+ const a = fs9.statSync(first, { throwIfNoEntry: false });
16998
+ const b = fs9.statSync(second, { throwIfNoEntry: false });
16999
+ if (a === void 0 || b === void 0) {
17000
+ return false;
17001
+ }
17002
+ return a.dev === b.dev && a.ino === b.ino;
17003
+ }
17004
+ function caseSwapped(name) {
17005
+ return name.replace(/[A-Za-z]/gu, (letter) => letter === letter.toLowerCase() ? letter.toUpperCase() : letter.toLowerCase());
17006
+ }
17007
+ function ignoresCase(directory) {
17008
+ if (!fs9.existsSync(directory)) {
17009
+ return false;
17010
+ }
17011
+ const probe = fs9.mkdtempSync(path29.join(directory, ".case-probe-"));
17012
+ try {
17013
+ return sameDirectory(probe, path29.join(directory, caseSwapped(path29.basename(probe))));
17014
+ } finally {
17015
+ fs9.rmSync(probe, { recursive: true, force: true });
17016
+ }
17017
+ }
17018
+
17019
+ // src/identityStore.ts
16638
17020
  var IdentityNotFoundError = class extends CliError {
16639
17021
  constructor(name) {
16640
17022
  super(`No identity named "${name}". Run \`agent-shim identity add ${name}\` first.`);
@@ -16662,7 +17044,7 @@ var InvalidIdentityNameError = class extends CliError {
16662
17044
  attemptedName;
16663
17045
  };
16664
17046
  function identityJsonPath(paths, name) {
16665
- return path28.join(paths.identitiesDir, name, "identity.json");
17047
+ return path30.join(paths.identitiesDir, name, "identity.json");
16666
17048
  }
16667
17049
  function requireIdentityNames(paths, names) {
16668
17050
  const existing = new Set(listIdentities(paths).map((entry) => entry.name));
@@ -16673,21 +17055,23 @@ function requireIdentityNames(paths, names) {
16673
17055
  }
16674
17056
  }
16675
17057
  function identityExists(paths, name) {
16676
- return fs9.existsSync(identityJsonPath(paths, name));
17058
+ return fs10.existsSync(identityJsonPath(paths, name));
16677
17059
  }
16678
17060
  function readIdentity(paths, name) {
16679
17061
  return readJson(identityJsonPath(paths, name), IdentitySchema);
16680
17062
  }
16681
- function addIdentity(paths, name) {
17063
+ function requireIdentityCreatable(paths, name) {
17064
+ requireNoUnfinishedRenameNaming(paths, name, "add");
16682
17065
  if (identityExists(paths, name)) {
16683
17066
  throw new IdentityAlreadyExistsError(name);
16684
17067
  }
16685
- const parsed = IdentitySchema.safeParse({ name, allowAmbientCredential: false });
16686
- if (!parsed.success) {
16687
- throw new InvalidIdentityNameError(name);
16688
- }
16689
- writeJsonAtomic(identityJsonPath(paths, name), parsed.data);
16690
- return parsed.data;
17068
+ requireNewIdentityName(name);
17069
+ }
17070
+ function addIdentity(paths, name) {
17071
+ requireIdentityCreatable(paths, name);
17072
+ const identity = IdentitySchema.parse({ name, allowAmbientCredential: false });
17073
+ writeJsonAtomic(identityJsonPath(paths, name), identity);
17074
+ return identity;
16691
17075
  }
16692
17076
  function useIdentity(paths, name) {
16693
17077
  const pool = poolNameOf(name);
@@ -16700,33 +17084,89 @@ function useIdentity(paths, name) {
16700
17084
  `);
16701
17085
  }
16702
17086
  function readActiveIdentity2(paths) {
16703
- if (!fs9.existsSync(paths.activeIdentityFile)) {
17087
+ if (!fs10.existsSync(paths.activeIdentityFile)) {
16704
17088
  return void 0;
16705
17089
  }
16706
- const raw = fs9.readFileSync(paths.activeIdentityFile, "utf8").trim();
17090
+ const raw = fs10.readFileSync(paths.activeIdentityFile, "utf8").trim();
16707
17091
  return raw === "" ? void 0 : raw;
16708
17092
  }
16709
17093
  function isIdentityDirectoryName(name) {
16710
17094
  return !name.startsWith(".");
16711
17095
  }
17096
+ var UNREACHABLE_CODES = /* @__PURE__ */ new Set(["ELOOP", "EACCES", "ENOTDIR"]);
17097
+ function systemErrorCode(error) {
17098
+ return typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : void 0;
17099
+ }
17100
+ function unreachableCodeOf(error) {
17101
+ const code = systemErrorCode(error);
17102
+ if (code === "ENOENT") {
17103
+ return void 0;
17104
+ }
17105
+ if (code !== void 0 && UNREACHABLE_CODES.has(code)) {
17106
+ return code;
17107
+ }
17108
+ throw error;
17109
+ }
17110
+ function followedLink(link) {
17111
+ try {
17112
+ return fs10.statSync(link).isDirectory() ? "directory" : "other";
17113
+ } catch (error) {
17114
+ const code = unreachableCodeOf(error);
17115
+ return code === void 0 ? "other" : { code };
17116
+ }
17117
+ }
17118
+ function entryRefusal(directory) {
17119
+ try {
17120
+ fs10.accessSync(directory, fs10.constants.X_OK);
17121
+ return void 0;
17122
+ } catch (error) {
17123
+ return unreachableCodeOf(error);
17124
+ }
17125
+ }
17126
+ function listIdentityDirectories(paths) {
17127
+ const names = [];
17128
+ const unreachable = [];
17129
+ if (fs10.existsSync(paths.identitiesDir)) {
17130
+ for (const entry of fs10.readdirSync(paths.identitiesDir, { withFileTypes: true })) {
17131
+ if (!isIdentityDirectoryName(entry.name)) {
17132
+ continue;
17133
+ }
17134
+ const entryPath = path30.join(paths.identitiesDir, entry.name);
17135
+ const followed = entry.isDirectory() ? "directory" : entry.isSymbolicLink() ? followedLink(entryPath) : "other";
17136
+ if (followed === "other") {
17137
+ continue;
17138
+ }
17139
+ const code = followed === "directory" ? entryRefusal(entryPath) : followed.code;
17140
+ if (code === void 0) {
17141
+ names.push(entry.name);
17142
+ } else {
17143
+ unreachable.push({ name: entry.name, code });
17144
+ }
17145
+ }
17146
+ }
17147
+ return { names: names.sort(), unreachable: unreachable.sort((a, b) => a.name.localeCompare(b.name)) };
17148
+ }
17149
+ var NOT_JSON_PROBLEM = "is not valid JSON";
16712
17150
  function readIdentityForListing(paths, name) {
16713
17151
  try {
16714
17152
  return readIdentity(paths, name);
16715
17153
  } catch (error) {
16716
- if (error instanceof ConfigValidationError || error instanceof SyntaxError) {
17154
+ if (error instanceof ConfigFileNotJsonError) {
17155
+ return { problem: NOT_JSON_PROBLEM };
17156
+ }
17157
+ if (error instanceof ConfigValidationError) {
16717
17158
  return { problem: error.message.replace(/\s*\n\s*/g, " ") };
16718
17159
  }
16719
17160
  throw error;
16720
17161
  }
16721
17162
  }
16722
17163
  function listIdentities(paths) {
16723
- if (!fs9.existsSync(paths.identitiesDir)) {
17164
+ if (!fs10.existsSync(paths.identitiesDir)) {
16724
17165
  return [];
16725
17166
  }
16726
17167
  const active = readActiveIdentity2(paths);
16727
- const names = fs9.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort();
16728
17168
  const result = [];
16729
- for (const name of names) {
17169
+ for (const name of listIdentityDirectories(paths).names) {
16730
17170
  const read = readIdentityForListing(paths, name);
16731
17171
  if (read === void 0) {
16732
17172
  continue;
@@ -16736,6 +17176,10 @@ function listIdentities(paths) {
16736
17176
  }
16737
17177
  return result;
16738
17178
  }
17179
+ function requireIdentityAddable(paths, name, keychain, keepKeychainLogin) {
17180
+ requireIdentityCreatable(paths, name);
17181
+ requireNoLeftoverKeychainLogin(keychain, path30.join(paths.identitiesDir, name), name, keepKeychainLogin);
17182
+ }
16739
17183
  function setIdentityAnchors(paths, identityName, anchors) {
16740
17184
  if (!identityExists(paths, identityName)) {
16741
17185
  throw new IdentityNotFoundError(identityName);
@@ -16788,50 +17232,70 @@ function setIdentityCredential(paths, identityName, change) {
16788
17232
  credential: { sources: [...sources], ...target === void 0 ? {} : { target }, ...cache === void 0 ? {} : { cache } }
16789
17233
  });
16790
17234
  }
17235
+ var UUID_PATTERN = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
17236
+ var FARM_SUFFIX_PATTERN = `\\.(?:scratch|previous)\\.\\d+\\.${UUID_PATTERN}`;
17237
+ function escapedForPattern(text) {
17238
+ return text.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
17239
+ }
17240
+ function isFarmEntry(entry, name) {
17241
+ return entry === name || new RegExp(`^\\.${escapedForPattern(name)}${FARM_SUFFIX_PATTERN}$`, "u").test(entry);
17242
+ }
16791
17243
  function belongsToIdentity(entry, name) {
16792
- return entry === name || entry === path28.basename(identityLockPath("", name)) || entry.startsWith(`.${name}.scratch.`) || entry.startsWith(`.${name}.previous.`);
17244
+ return isFarmEntry(entry, name) || entry === path30.basename(identityLockPath("", name));
17245
+ }
17246
+ function requireNewIdentityName(name) {
17247
+ if (!FileNameSchema.safeParse(name).success) {
17248
+ throw new InvalidIdentityNameError(name);
17249
+ }
17250
+ }
17251
+ function sameIdentityName(paths, first, second) {
17252
+ return sameDirectory(path30.join(paths.identitiesDir, first), path30.join(paths.identitiesDir, second)) || first.toLowerCase() === second.toLowerCase() && ignoresCase(paths.identitiesDir);
17253
+ }
17254
+ function requireNoUnfinishedRenameNaming(paths, name, action) {
17255
+ requireNameFreeOfUnfinishedRename({ readFileUtf8: nodeStoreFs.readFileUtf8, readdir: (directory) => fs10.existsSync(directory) ? fs10.readdirSync(directory) : [] }, paths.identityRenamesDir, name, action, (first, second) => sameIdentityName(paths, first, second), (identity) => identityExists(paths, identity));
16793
17256
  }
16794
17257
  function removeIdentity(paths, name) {
17258
+ requireNoUnfinishedRenameNaming(paths, name, "remove");
16795
17259
  if (!identityExists(paths, name)) {
16796
17260
  throw new IdentityNotFoundError(name);
16797
17261
  }
16798
- for (const entry of fs9.readdirSync(paths.identitiesDir)) {
17262
+ for (const entry of fs10.readdirSync(paths.identitiesDir)) {
16799
17263
  if (belongsToIdentity(entry, name)) {
16800
- fs9.rmSync(path28.join(paths.identitiesDir, entry), { recursive: true, force: true });
17264
+ fs10.rmSync(path30.join(paths.identitiesDir, entry), { recursive: true, force: true });
16801
17265
  }
16802
17266
  }
16803
17267
  if (readActiveIdentity2(paths) === name) {
16804
- fs9.rmSync(paths.activeIdentityFile);
17268
+ fs10.rmSync(paths.activeIdentityFile);
16805
17269
  }
16806
17270
  }
16807
17271
 
16808
17272
  // src/doctorReport.ts
16809
17273
  init_realPorts();
16810
- import fs11 from "node:fs";
16811
- import path29 from "node:path";
17274
+ import fs12 from "node:fs";
17275
+ import path31 from "node:path";
16812
17276
  init_signIn();
16813
17277
  init_identityAccounts();
16814
17278
  init_read();
16815
17279
 
16816
17280
  // src/codex/siwcStore.ts
16817
- import { z as z26 } from "zod";
17281
+ import { z as z27 } from "zod";
16818
17282
 
16819
17283
  // src/codex/auth.ts
16820
- import { z as z24 } from "zod";
16821
- var AuthFileSchema = z24.looseObject({
16822
- tokens: z24.looseObject({
16823
- access_token: z24.string().optional(),
16824
- refresh_token: z24.string().optional(),
16825
- id_token: z24.string().optional(),
16826
- account_id: z24.string().optional()
17284
+ import { z as z25 } from "zod";
17285
+ var AuthFileSchema = z25.looseObject({
17286
+ tokens: z25.looseObject({
17287
+ access_token: z25.string().optional(),
17288
+ refresh_token: z25.string().optional(),
17289
+ id_token: z25.string().optional(),
17290
+ account_id: z25.string().optional()
16827
17291
  }).nullish(),
16828
- last_refresh: z24.string().optional()
17292
+ last_refresh: z25.string().optional()
16829
17293
  });
16830
- var TokenGrantSchema = z24.looseObject({
16831
- access_token: z24.string().min(1).optional(),
16832
- refresh_token: z24.string().min(1).optional(),
16833
- id_token: z24.string().min(1).optional(),
16834
- account_id: z24.string().min(1).optional()
17294
+ var TokenGrantSchema = z25.looseObject({
17295
+ access_token: z25.string().min(1).optional(),
17296
+ refresh_token: z25.string().min(1).optional(),
17297
+ id_token: z25.string().min(1).optional(),
17298
+ account_id: z25.string().min(1).optional()
16835
17299
  });
16836
17300
  var CodexAuthError = class extends Error {
16837
17301
  constructor(message) {
@@ -16841,41 +17305,41 @@ var CodexAuthError = class extends Error {
16841
17305
  };
16842
17306
 
16843
17307
  // src/codex/siwc.ts
16844
- import { z as z25 } from "zod";
17308
+ import { z as z26 } from "zod";
16845
17309
  var SIWC_RESOURCE = "https://api.openai.com/v1";
16846
17310
  var SIWC_RESPONSES_URL = `${SIWC_RESOURCE}/responses`;
16847
17311
  var SIWC_PLAN_SCOPE = "chatgpt.tokens.use.direct";
16848
- var TokenResponseSchema = z25.looseObject({
16849
- access_token: z25.string().min(1),
16850
- refresh_token: z25.string().min(1).optional(),
16851
- id_token: z25.string().min(1).optional(),
16852
- expires_in: z25.number().positive(),
16853
- scope: z25.string().optional()
17312
+ var TokenResponseSchema = z26.looseObject({
17313
+ access_token: z26.string().min(1),
17314
+ refresh_token: z26.string().min(1).optional(),
17315
+ id_token: z26.string().min(1).optional(),
17316
+ expires_in: z26.number().positive(),
17317
+ scope: z26.string().optional()
16854
17318
  });
16855
- var JwtHeaderSchema = z25.looseObject({ alg: z25.string(), kid: z25.string().optional() });
16856
- var IdTokenClaimsSchema = z25.looseObject({
16857
- iss: z25.string(),
16858
- sub: z25.string().min(1),
16859
- aud: z25.union([z25.string(), z25.array(z25.string())]),
16860
- exp: z25.number(),
16861
- nonce: z25.string().optional(),
16862
- email: z25.string().optional()
17319
+ var JwtHeaderSchema = z26.looseObject({ alg: z26.string(), kid: z26.string().optional() });
17320
+ var IdTokenClaimsSchema = z26.looseObject({
17321
+ iss: z26.string(),
17322
+ sub: z26.string().min(1),
17323
+ aud: z26.union([z26.string(), z26.array(z26.string())]),
17324
+ exp: z26.number(),
17325
+ nonce: z26.string().optional(),
17326
+ email: z26.string().optional()
16863
17327
  });
16864
- var JwksSchema = z25.object({ keys: z25.array(z25.looseObject({ kid: z25.string().optional(), kty: z25.string() })) });
17328
+ var JwksSchema = z26.object({ keys: z26.array(z26.looseObject({ kid: z26.string().optional(), kty: z26.string() })) });
16865
17329
 
16866
17330
  // src/codex/siwcStore.ts
16867
- var SiwcGrantSchema = z26.strictObject({
16868
- clientId: z26.string().min(1),
16869
- sub: z26.string().min(1),
16870
- email: z26.string().optional(),
16871
- idToken: z26.string().min(1),
16872
- accessToken: z26.string().min(1),
16873
- refreshToken: z26.string().min(1),
16874
- scopes: z26.array(z26.string()).readonly(),
17331
+ var SiwcGrantSchema = z27.strictObject({
17332
+ clientId: z27.string().min(1),
17333
+ sub: z27.string().min(1),
17334
+ email: z27.string().optional(),
17335
+ idToken: z27.string().min(1),
17336
+ accessToken: z27.string().min(1),
17337
+ refreshToken: z27.string().min(1),
17338
+ scopes: z27.array(z27.string()).readonly(),
16875
17339
  /** When the access token stops working, in milliseconds since the epoch. */
16876
- expiresAt: z26.number()
17340
+ expiresAt: z27.number()
16877
17341
  });
16878
- var SiwcFileSchema = z26.strictObject({ registeredClientId: z26.string().min(1).optional(), grant: SiwcGrantSchema.optional() });
17342
+ var SiwcFileSchema = z27.strictObject({ registeredClientId: z27.string().min(1).optional(), grant: SiwcGrantSchema.optional() });
16879
17343
  function parseSiwcFile(raw, filePath) {
16880
17344
  let json;
16881
17345
  try {
@@ -17132,7 +17596,7 @@ function pushFrontDoorListeners(push, readings) {
17132
17596
 
17133
17597
  // src/frontdoor/listenerReadings.ts
17134
17598
  init_probe();
17135
- import fs10 from "node:fs";
17599
+ import fs11 from "node:fs";
17136
17600
  function readFrontDoorListeners(state, supervisorAlive, probes) {
17137
17601
  if (!supervisorAlive) {
17138
17602
  return [];
@@ -17152,7 +17616,7 @@ function readFrontDoorListeners(state, supervisorAlive, probes) {
17152
17616
  }
17153
17617
  function realFrontDoorListenerProbes(paths) {
17154
17618
  return {
17155
- authenticateProvider: (port) => probeFrontDoorSync(port, fs10.readFileSync(paths.frontdoorCaCertFile, "utf8")),
17619
+ authenticateProvider: (port) => probeFrontDoorSync(port, fs11.readFileSync(paths.frontdoorCaCertFile, "utf8")),
17156
17620
  connect: probeListenerAcceptSync,
17157
17621
  now: () => performance.now()
17158
17622
  };
@@ -17297,8 +17761,8 @@ function validateJson(schema, input) {
17297
17761
  let parsed;
17298
17762
  try {
17299
17763
  parsed = JSON.parse(input.raw);
17300
- } catch (error) {
17301
- return { ok: false, message: `${input.path} is not valid JSON: ${error instanceof Error ? error.message : String(error)}` };
17764
+ } catch {
17765
+ return { ok: false, message: `${input.path} is not valid JSON.` };
17302
17766
  }
17303
17767
  const result = parseIgnoringUnrecognisedKeys(schema, parsed);
17304
17768
  if (!result.success) {
@@ -17317,7 +17781,7 @@ function tcpPortEraRecord(raw) {
17317
17781
  return (has("port") || has("lastPort")) && !has("socketPath");
17318
17782
  }
17319
17783
  function pushPathResolution(push, resolution) {
17320
- const ownDir = path29.dirname(resolution.ownExecutablePath);
17784
+ const ownDir = path31.dirname(resolution.ownExecutablePath);
17321
17785
  switch (resolution.agentShim.status) {
17322
17786
  case "ok":
17323
17787
  push("path-resolution", "pass", `\`agent-shim\` on PATH resolves to this running executable, ${resolution.ownExecutablePath}.`, "agent-shim");
@@ -17404,8 +17868,8 @@ function pushProvider(push, entry, cacheEnv, signIn) {
17404
17868
  let parsed;
17405
17869
  try {
17406
17870
  parsed = JSON.parse(entry.raw);
17407
- } catch (error) {
17408
- push("provider", "fail", `${entry.path} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`, entry.name);
17871
+ } catch {
17872
+ push("provider", "fail", `${entry.path} is not valid JSON.`, entry.name);
17409
17873
  return;
17410
17874
  }
17411
17875
  const conversion = legacyProviderConversion(parsed);
@@ -17437,14 +17901,14 @@ function pushProvider(push, entry, cacheEnv, signIn) {
17437
17901
  }
17438
17902
  function pushLegacyName(push, params) {
17439
17903
  const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
17440
- if (legacyVariables.length === 0 && path29.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
17904
+ if (legacyVariables.length === 0 && path31.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
17441
17905
  push("legacy-name", "pass", "Nothing here still uses the former `claude-use` name.");
17442
17906
  return;
17443
17907
  }
17444
17908
  for (const name of legacyVariables) {
17445
17909
  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);
17446
17910
  }
17447
- if (path29.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
17911
+ if (path31.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
17448
17912
  push(
17449
17913
  "legacy-name",
17450
17914
  "warn",
@@ -17530,6 +17994,16 @@ function runDoctor(params) {
17530
17994
  }
17531
17995
  const validProfileNames = new Set(profileSources.keys());
17532
17996
  const validProviderNames = /* @__PURE__ */ new Set([...params.providers.map((entry) => entry.name), ...Object.keys(params.providerAliases ?? {})]);
17997
+ const identityNames = new Set(params.identities.filter((entry) => entry.raw !== void 0).map((entry) => entry.name));
17998
+ for (const journal of params.renameJournals?.journals ?? []) {
17999
+ push("identity", "fail", `There is ${describeUnfinishedRename(journal, finishabilityOf(journal, (name) => identityNames.has(name)))}`, journal.from);
18000
+ }
18001
+ for (const { name, code } of params.unreachableIdentities ?? []) {
18002
+ push("identity", "warn", `identities/${name} cannot be reached (${code}), so it is not counted as an identity. Repair the permissions of the directory or of what a symlink points through, or remove the entry.`, name);
18003
+ }
18004
+ for (const { file, detail } of params.renameJournals?.unreadable ?? []) {
18005
+ push("identity", "fail", `${file} is not a rename journal this agent-shim can read (${detail}), so no identity can be renamed until it is fixed or removed, and it may be the trace of a rename that was left unfinished.`, path31.basename(file));
18006
+ }
17533
18007
  const validIdentityNames = /* @__PURE__ */ new Set();
17534
18008
  const signedInAccounts = [];
17535
18009
  for (const entry of params.identities) {
@@ -17880,7 +18354,7 @@ function formatDoctorReport(report) {
17880
18354
  }
17881
18355
  function realpathOrSelf(target) {
17882
18356
  try {
17883
- return fs11.realpathSync(target);
18357
+ return fs12.realpathSync(target);
17884
18358
  } catch {
17885
18359
  return target;
17886
18360
  }
@@ -17892,11 +18366,11 @@ function servingDoorListeners(paths) {
17892
18366
  }
17893
18367
  function collectDoctorReport(params) {
17894
18368
  const { paths } = params;
17895
- const identityNames = fs11.existsSync(paths.identitiesDir) ? fs11.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort() : [];
18369
+ const { names: identityNames, unreachable: unreachableIdentities } = listIdentityDirectories(paths);
17896
18370
  const identities = identityNames.map((name) => {
17897
- const farmRoot = path29.join(paths.identitiesDir, name);
17898
- const identityPath = path29.join(farmRoot, "identity.json");
17899
- return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: fs11.existsSync(credentialsFilePath(farmRoot)), account: readIdentityAccount(realFsPort, paths.identitiesDir, name)?.account };
18371
+ const farmRoot = path31.join(paths.identitiesDir, name);
18372
+ const identityPath = path31.join(farmRoot, "identity.json");
18373
+ return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: fs12.existsSync(credentialsFilePath(farmRoot)), account: readIdentityAccount(realFsPort, paths.identitiesDir, name)?.account };
17900
18374
  });
17901
18375
  const usageSnapshots = {};
17902
18376
  for (const name of identityNames) {
@@ -17911,14 +18385,14 @@ function collectDoctorReport(params) {
17911
18385
  }
17912
18386
  }
17913
18387
  }
17914
- const profileNames = fs11.existsSync(paths.configProfilesDir) ? fs11.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
18388
+ const profileNames = fs12.existsSync(paths.configProfilesDir) ? fs12.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
17915
18389
  const configProfiles = profileNames.map((name) => {
17916
- const profilePath = path29.join(paths.configProfilesDir, `${name}.json`);
18390
+ const profilePath = path31.join(paths.configProfilesDir, `${name}.json`);
17917
18391
  return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
17918
18392
  });
17919
- const providerNames = fs11.existsSync(paths.providersDir) ? fs11.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
18393
+ const providerNames = fs12.existsSync(paths.providersDir) ? fs12.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
17920
18394
  const providers = providerNames.map((name) => {
17921
- const providerPath = path29.join(paths.providersDir, `${name}.json`);
18395
+ const providerPath = path31.join(paths.providersDir, `${name}.json`);
17922
18396
  return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
17923
18397
  });
17924
18398
  const ownExecutablePath = realOwnExecutablePath();
@@ -17930,12 +18404,12 @@ function collectDoctorReport(params) {
17930
18404
  binaryDiscovery = { ok: false, message: error instanceof Error ? error.message : String(error) };
17931
18405
  }
17932
18406
  const shimState = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
17933
- const pathDirs = (params.env.PATH ?? "").split(path29.delimiter).filter((dir) => dir !== "");
18407
+ const pathDirs = (params.env.PATH ?? "").split(path31.delimiter).filter((dir) => dir !== "");
17934
18408
  const claudeShimShadow = shimState === void 0 ? void 0 : refinePathShadow(
17935
18409
  findPathShadow({
17936
18410
  pathDirs,
17937
- targetDir: path29.dirname(shimState.targetPath),
17938
- targetFilename: path29.basename(shimState.targetPath),
18411
+ targetDir: path31.dirname(shimState.targetPath),
18412
+ targetFilename: path31.basename(shimState.targetPath),
17939
18413
  findExecutableInDir
17940
18414
  }),
17941
18415
  shimState.targetPath,
@@ -17958,6 +18432,8 @@ function collectDoctorReport(params) {
17958
18432
  configProfiles,
17959
18433
  providers,
17960
18434
  providerAliases: readProviderAliases(paths),
18435
+ renameJournals: listRenameJournals(realFarmFs, paths.identityRenamesDir),
18436
+ unreachableIdentities,
17961
18437
  directoryRules: { path: paths.directoryRulesFile, raw: realFsPort.readFileUtf8(paths.directoryRulesFile) },
17962
18438
  globalConfig: { path: paths.globalConfigFile, raw: realFsPort.readFileUtf8(paths.globalConfigFile) },
17963
18439
  models: parsedModelsOf(paths),
@@ -17965,14 +18441,14 @@ function collectDoctorReport(params) {
17965
18441
  categoriesLocal: { path: paths.categoriesLocalFile, raw: realFsPort.readFileUtf8(paths.categoriesLocalFile) },
17966
18442
  activeIdentity: { path: paths.activeIdentityFile, raw: realFsPort.readFileUtf8(paths.activeIdentityFile) },
17967
18443
  binaryDiscovery,
17968
- claudeShim: { state: shimState, targetExists: shimState !== void 0 && fs11.existsSync(shimState.targetPath) },
18444
+ claudeShim: { state: shimState, targetExists: shimState !== void 0 && fs12.existsSync(shimState.targetPath) },
17969
18445
  rootPath: paths.root,
17970
18446
  pathResolution: {
17971
18447
  ownExecutablePath,
17972
18448
  agentShim: refinePathShadow(
17973
18449
  findPathShadow({
17974
18450
  pathDirs,
17975
- targetDir: path29.dirname(ownExecutablePath),
18451
+ targetDir: path31.dirname(ownExecutablePath),
17976
18452
  targetFilename: commandFilename(ownExecutablePath, "agent-shim"),
17977
18453
  findExecutableInDir
17978
18454
  }),
@@ -18013,92 +18489,92 @@ function collectDoctorReport(params) {
18013
18489
  // src/frontdoor/controlSchemas.ts
18014
18490
  init_schema2();
18015
18491
  init_state();
18016
- var UsageListOutputSchema = z29.strictObject({ snapshots: z29.readonly(z29.array(UsageSnapshotSchema)) });
18017
- var UsageWindowsInputSchema = z29.strictObject({
18018
- identity: z29.string().min(1),
18019
- provider: z29.string().min(1).optional()
18492
+ var UsageListOutputSchema = z30.strictObject({ snapshots: z30.readonly(z30.array(UsageSnapshotSchema)) });
18493
+ var UsageWindowsInputSchema = z30.strictObject({
18494
+ identity: z30.string().min(1),
18495
+ provider: z30.string().min(1).optional()
18020
18496
  });
18021
- var EffectiveWindowSchema = z29.strictObject({
18497
+ var EffectiveWindowSchema = z30.strictObject({
18022
18498
  /** True when the window's reset time has passed, so the recorded observation describes a window that no longer exists. */
18023
- reset: z29.boolean(),
18499
+ reset: z30.boolean(),
18024
18500
  /** The fraction used: 0 for a reset window, otherwise what was last observed, absent when none was reported. */
18025
- utilization: z29.number().optional(),
18501
+ utilization: z30.number().optional(),
18026
18502
  /** The reset instant, for a window that has not reset yet and reported one. */
18027
- resetsAtMs: z29.number().optional(),
18503
+ resetsAtMs: z30.number().optional(),
18028
18504
  /** The window's own status, for a window that has not reset yet. */
18029
- status: z29.string().optional()
18505
+ status: z30.string().optional()
18030
18506
  });
18031
- var UsageWindowsOutputSchema = z29.strictObject({
18032
- identity: z29.string(),
18033
- provider: z29.string(),
18507
+ var UsageWindowsOutputSchema = z30.strictObject({
18508
+ identity: z30.string(),
18509
+ provider: z30.string(),
18034
18510
  /** When the rate-limit state the windows come from was observed. */
18035
- observedAt: z29.iso.datetime().optional(),
18511
+ observedAt: z30.iso.datetime().optional(),
18036
18512
  fiveHour: EffectiveWindowSchema.optional(),
18037
18513
  sevenDay: EffectiveWindowSchema.optional()
18038
18514
  });
18039
- var UsageLiveOutputSchema = z29.strictObject({
18515
+ var UsageLiveOutputSchema = z30.strictObject({
18040
18516
  /** The freshest observation the door holds, never narrowed by the read's session filter because it is the door's single latest statement of the account's quota; absent while no rate_limit_event has been filed at all. */
18041
18517
  latest: RcLiveRateLimitSchema.optional(),
18042
18518
  /** One observation per session whose stream has filed a rate_limit_event this door generation. */
18043
- sessions: z29.readonly(z29.array(RcLiveRateLimitSchema))
18519
+ sessions: z30.readonly(z30.array(RcLiveRateLimitSchema))
18044
18520
  });
18045
- var FrontDoorSessionStatusSchema = z29.strictObject({
18046
- pid: z29.int().positive(),
18047
- startedAt: z29.number(),
18048
- alive: z29.boolean()
18521
+ var FrontDoorSessionStatusSchema = z30.strictObject({
18522
+ pid: z30.int().positive(),
18523
+ startedAt: z30.number(),
18524
+ alive: z30.boolean()
18049
18525
  });
18050
- var HeadroomSocketTargetSchema = z29.union([z29.strictObject({ socketPath: z29.string() }), z29.strictObject({ refused: z29.string() })]);
18051
- var FrontDoorStatusOutputSchema = z29.strictObject({
18526
+ var HeadroomSocketTargetSchema = z30.union([z30.strictObject({ socketPath: z30.string() }), z30.strictObject({ refused: z30.string() })]);
18527
+ var FrontDoorStatusOutputSchema = z30.strictObject({
18052
18528
  state: FrontDoorStateSchema,
18053
- supervisorAlive: z29.boolean(),
18529
+ supervisorAlive: z30.boolean(),
18054
18530
  /** The pids of earlier doors that released their addresses and are finishing the connections they carried: running, but not serving anything new. */
18055
- draining: z29.readonly(z29.array(z29.number().int().positive())),
18056
- sessions: z29.readonly(z29.array(FrontDoorSessionStatusSchema)),
18531
+ draining: z30.readonly(z30.array(z30.number().int().positive())),
18532
+ sessions: z30.readonly(z30.array(FrontDoorSessionStatusSchema)),
18057
18533
  headroomSocket: HeadroomSocketTargetSchema.optional(),
18058
- logPath: z29.string(),
18059
- logExists: z29.boolean()
18534
+ logPath: z30.string(),
18535
+ logExists: z30.boolean()
18060
18536
  });
18061
- var FrontDoorSessionsOutputSchema = z29.strictObject({ sessions: z29.readonly(z29.array(FrontDoorSessionStatusSchema)) });
18062
- var CheckRunInputSchema = z29.strictObject({
18063
- path: z29.string().min(1),
18064
- identity: z29.string().min(1).optional()
18065
- }).refine((input) => path30.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
18066
- var PoolPickInputSchema = z29.strictObject({
18067
- pool: z29.string().min(1),
18068
- path: z29.string().min(1)
18069
- }).refine((input) => path30.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
18070
- var DoctorFindingSchema = z29.strictObject({
18071
- section: z29.enum(DOCTOR_SECTIONS),
18072
- subject: z29.string().optional(),
18073
- severity: z29.enum(DOCTOR_SEVERITIES),
18074
- message: z29.string()
18537
+ var FrontDoorSessionsOutputSchema = z30.strictObject({ sessions: z30.readonly(z30.array(FrontDoorSessionStatusSchema)) });
18538
+ var CheckRunInputSchema = z30.strictObject({
18539
+ path: z30.string().min(1),
18540
+ identity: z30.string().min(1).optional()
18541
+ }).refine((input) => path32.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
18542
+ var PoolPickInputSchema = z30.strictObject({
18543
+ pool: z30.string().min(1),
18544
+ path: z30.string().min(1)
18545
+ }).refine((input) => path32.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
18546
+ var DoctorFindingSchema = z30.strictObject({
18547
+ section: z30.enum(DOCTOR_SECTIONS),
18548
+ subject: z30.string().optional(),
18549
+ severity: z30.enum(DOCTOR_SEVERITIES),
18550
+ message: z30.string()
18075
18551
  });
18076
- var DoctorRunOutputSchema = z29.strictObject({
18552
+ var DoctorRunOutputSchema = z30.strictObject({
18077
18553
  /** False exactly when any finding is a `fail`; a `warn` never fails the report on its own. */
18078
- ok: z29.boolean(),
18079
- findings: z29.readonly(z29.array(DoctorFindingSchema))
18554
+ ok: z30.boolean(),
18555
+ findings: z30.readonly(z30.array(DoctorFindingSchema))
18080
18556
  });
18081
- var FrontDoorRestartOutputSchema = z29.strictObject({
18082
- action: z29.literal("restarting"),
18083
- previousPid: z29.int().positive()
18557
+ var FrontDoorRestartOutputSchema = z30.strictObject({
18558
+ action: z30.literal("restarting"),
18559
+ previousPid: z30.int().positive()
18084
18560
  });
18085
- var UpdateCheckOutputSchema = z29.strictObject({
18086
- current: z29.string(),
18087
- latest: z29.string(),
18088
- action: z29.enum(["current", "available", "updated"])
18561
+ var UpdateCheckOutputSchema = z30.strictObject({
18562
+ current: z30.string(),
18563
+ latest: z30.string(),
18564
+ action: z30.enum(["current", "available", "updated"])
18089
18565
  });
18090
- var CodexSignInSchema = z29.discriminatedUnion("state", [
18091
- z29.strictObject({ state: z29.literal("none") }),
18092
- z29.strictObject({ state: z29.literal("signed-in"), email: z29.string().optional(), planScope: z29.boolean(), accessTokenExpiresAt: z29.number() }),
18093
- z29.strictObject({ state: z29.literal("unreadable"), message: z29.string() })
18566
+ var CodexSignInSchema = z30.discriminatedUnion("state", [
18567
+ z30.strictObject({ state: z30.literal("none") }),
18568
+ z30.strictObject({ state: z30.literal("signed-in"), email: z30.string().optional(), planScope: z30.boolean(), accessTokenExpiresAt: z30.number() }),
18569
+ z30.strictObject({ state: z30.literal("unreadable"), message: z30.string() })
18094
18570
  ]);
18095
- var CodexStatusOutputSchema = z29.strictObject({
18571
+ var CodexStatusOutputSchema = z30.strictObject({
18096
18572
  signIn: CodexSignInSchema,
18097
- codexProviders: z29.readonly(z29.array(z29.string()))
18573
+ codexProviders: z30.readonly(z30.array(z30.string()))
18098
18574
  });
18099
- var CodexLogoutOutputSchema = z29.strictObject({
18100
- hadGrant: z29.boolean(),
18101
- revoked: z29.boolean()
18575
+ var CodexLogoutOutputSchema = z30.strictObject({
18576
+ hadGrant: z30.boolean(),
18577
+ revoked: z30.boolean()
18102
18578
  });
18103
18579
 
18104
18580
  // src/frontdoor/codexApi.ts
@@ -18253,72 +18729,74 @@ function requireRuleSelector(paths, selector) {
18253
18729
 
18254
18730
  // src/frontdoor/configApi.ts
18255
18731
  init_identity();
18732
+ init_replayRun();
18256
18733
  init_providersStore();
18257
18734
 
18258
18735
  // src/frontdoor/configSchemas.ts
18259
18736
  init_schema();
18260
18737
  init_names();
18738
+ import { z as z31 } from "zod";
18261
18739
  init_statusline();
18262
- import { z as z30 } from "zod";
18263
- var RemovalConfirmationSchema = z30.boolean();
18264
- var CredentialWriteSchema = (targets) => z30.strictObject({
18265
- sources: z30.array(RemoteCredentialSourceSchema).min(1).optional(),
18266
- target: z30.enum(targets).optional(),
18267
- cache: z30.union([z30.literal(false), CredentialCacheSchema]).optional()
18740
+ var RemovalConfirmationSchema = z31.boolean();
18741
+ var CredentialWriteSchema = (targets) => z31.strictObject({
18742
+ sources: z31.array(RemoteCredentialSourceSchema).min(1).optional(),
18743
+ target: z31.enum(targets).optional(),
18744
+ cache: z31.union([z31.literal(false), CredentialCacheSchema]).optional()
18268
18745
  });
18269
- var CredentialSummarySchema2 = z30.strictObject({
18270
- target: z30.enum(CREDENTIAL_TARGETS),
18271
- sources: z30.readonly(z30.array(
18272
- z30.discriminatedUnion("kind", [
18273
- z30.strictObject({ kind: z30.literal("env"), variable: z30.string() }),
18274
- z30.strictObject({ kind: z30.literal("file"), path: z30.string() }),
18275
- z30.strictObject({ kind: z30.literal("command"), program: z30.string() }),
18276
- z30.strictObject({ kind: z30.literal("op"), reference: z30.string() }),
18277
- z30.strictObject({ kind: z30.literal("keychain"), service: z30.string(), account: z30.string().optional() }),
18278
- z30.strictObject({ kind: z30.literal("literal") })
18746
+ var CredentialSummarySchema2 = z31.strictObject({
18747
+ target: z31.enum(CREDENTIAL_TARGETS),
18748
+ sources: z31.readonly(z31.array(
18749
+ z31.discriminatedUnion("kind", [
18750
+ z31.strictObject({ kind: z31.literal("env"), variable: z31.string() }),
18751
+ z31.strictObject({ kind: z31.literal("file"), path: z31.string() }),
18752
+ z31.strictObject({ kind: z31.literal("command"), program: z31.string() }),
18753
+ z31.strictObject({ kind: z31.literal("op"), reference: z31.string() }),
18754
+ z31.strictObject({ kind: z31.literal("keychain"), service: z31.string(), account: z31.string().optional() }),
18755
+ z31.strictObject({ kind: z31.literal("literal") })
18279
18756
  ])
18280
18757
  )),
18281
18758
  cache: CredentialCacheSchema.optional()
18282
18759
  });
18283
- var mutationOutput = (kind, action) => z30.strictObject({ action: z30.literal(action), kind: z30.literal(kind), name: z30.string() });
18284
- var storedMutationOutput = (kind, action, value) => z30.strictObject({ action: z30.literal(action), kind: z30.literal(kind), name: z30.string(), value });
18285
- var IdentityValueSchema = z30.strictObject({
18286
- name: z30.string(),
18287
- label: z30.string().optional(),
18288
- defaultConfigProfile: z30.string().optional(),
18289
- provider: z30.string().optional(),
18290
- allowAmbientCredential: z30.boolean(),
18760
+ var mutationOutput = (kind, action) => z31.strictObject({ action: z31.literal(action), kind: z31.literal(kind), name: z31.string() });
18761
+ var storedMutationOutput = (kind, action, value) => z31.strictObject({ action: z31.literal(action), kind: z31.literal(kind), name: z31.string(), value });
18762
+ var IdentityValueSchema = z31.strictObject({
18763
+ name: z31.string(),
18764
+ label: z31.string().optional(),
18765
+ defaultConfigProfile: z31.string().optional(),
18766
+ provider: z31.string().optional(),
18767
+ allowAmbientCredential: z31.boolean(),
18291
18768
  credential: CredentialSummarySchema2.optional(),
18292
- anchors: z30.array(AnchorSchema).optional()
18769
+ anchors: z31.array(AnchorSchema).optional()
18293
18770
  });
18294
18771
  var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
18295
- var ProviderValueSchema = z30.strictObject({
18296
- name: z30.string(),
18297
- kind: z30.enum(PROVIDER_KINDS),
18298
- displayName: z30.string(),
18299
- baseUrl: z30.string().optional(),
18772
+ var ProviderValueSchema = z31.strictObject({
18773
+ name: z31.string(),
18774
+ kind: z31.enum(PROVIDER_KINDS),
18775
+ displayName: z31.string(),
18776
+ baseUrl: z31.string().optional(),
18300
18777
  codex: CodexProviderConfigSchema.optional(),
18301
18778
  credential: CredentialSummarySchema2.optional(),
18302
- env: z30.record(z30.string(), z30.string()).optional()
18779
+ env: z31.record(z31.string(), z31.string()).optional()
18303
18780
  });
18304
- var ConfigNameInputSchema = z30.strictObject({ name: z30.string().min(1) });
18781
+ var ConfigNameInputSchema = z31.strictObject({ name: z31.string().min(1) });
18782
+ var ConfigIdentityAddInputSchema = z31.strictObject({ name: z31.string().min(1), keepKeychainLogin: z31.boolean().optional().describe(KEEP_KEYCHAIN_LOGIN_DESCRIPTION) });
18305
18783
  var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created", IdentityValueSchema);
18306
- var ConfigIdentitySetInputSchema = z30.strictObject({
18307
- name: z30.string().min(1),
18784
+ var ConfigIdentitySetInputSchema = z31.strictObject({
18785
+ name: z31.string().min(1),
18308
18786
  /** The identity's display label; `false` clears it. */
18309
- label: z30.union([IdentityLabelSchema, z30.literal(false)]).optional(),
18310
- defaultConfigProfile: z30.union([z30.string().min(1), z30.literal(false)]).optional(),
18787
+ label: z31.union([IdentityLabelSchema, z31.literal(false)]).optional(),
18788
+ defaultConfigProfile: z31.union([z31.string().min(1), z31.literal(false)]).optional(),
18311
18789
  /** The provider the identity exists for; `false` clears it. */
18312
- provider: z30.union([z30.string().min(1), z30.literal(false)]).optional(),
18313
- allowAmbientCredential: z30.boolean().optional(),
18314
- credential: z30.union([z30.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional(),
18790
+ provider: z31.union([z31.string().min(1), z31.literal(false)]).optional(),
18791
+ allowAmbientCredential: z31.boolean().optional(),
18792
+ credential: z31.union([z31.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional(),
18315
18793
  /** `false` removes the anchors; a list replaces them. */
18316
- anchors: z30.union([z30.literal(false), z30.array(AnchorSchema).min(1)]).optional()
18794
+ anchors: z31.union([z31.literal(false), z31.array(AnchorSchema).min(1)]).optional()
18317
18795
  });
18318
18796
  var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
18319
- var ConfigIdentityRemoveInputSchema = z30.strictObject({ name: z30.string().min(1), confirm: RemovalConfirmationSchema });
18797
+ var ConfigIdentityRemoveInputSchema = z31.strictObject({ name: z31.string().min(1), confirm: RemovalConfirmationSchema });
18320
18798
  var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
18321
- var ConfigStatuslineSetSchema = z30.record(z30.string(), z30.unknown()).superRefine((settings, context) => {
18799
+ var ConfigStatuslineSetSchema = z31.record(z31.string(), z31.unknown()).superRefine((settings, context) => {
18322
18800
  for (const key of Object.keys(settings)) {
18323
18801
  if (key === STATUSLINE_EXTRA_GROUP || key.startsWith(`${STATUSLINE_EXTRA_GROUP}.`)) {
18324
18802
  context.addIssue({ code: "custom", path: [key], message: `a config write through the API cannot set "${key}": the extra segment's command runs a program, so only your own configuration (the global config, a profile you edit yourself, a directory rule or a command-line assignment) may set it` });
@@ -18326,102 +18804,105 @@ var ConfigStatuslineSetSchema = z30.record(z30.string(), z30.unknown()).superRef
18326
18804
  }
18327
18805
  });
18328
18806
  var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
18329
- var ConfigProfileAddInputSchema = z30.strictObject({
18330
- name: z30.string().min(1),
18331
- extends: z30.array(z30.string().min(1)).optional(),
18332
- description: z30.string().optional()
18807
+ var ConfigProfileAddInputSchema = z31.strictObject({
18808
+ name: z31.string().min(1),
18809
+ extends: z31.array(z31.string().min(1)).optional(),
18810
+ description: z31.string().optional()
18333
18811
  });
18334
18812
  var ConfigProfileAddOutputSchema = storedMutationOutput("profile", "created", ProfileValueSchema);
18335
- var ConfigProfileSetInputSchema = z30.strictObject({
18336
- name: z30.string().min(1),
18337
- category: z30.record(z30.string(), z30.boolean()).optional(),
18338
- entry: z30.record(z30.string(), z30.boolean()).optional(),
18339
- extends: z30.union([z30.array(z30.string().min(1)), z30.literal(false)]).optional(),
18340
- description: z30.union([z30.string(), z30.literal(false)]).optional(),
18341
- launch: z30.strictObject({
18342
- skipPermissions: z30.boolean().optional(),
18343
- remoteControl: z30.boolean().optional(),
18344
- headroom: z30.boolean().optional(),
18345
- trackUsage: z30.boolean().optional(),
18346
- provider: z30.union([z30.string().min(1), z30.literal(false)]).optional(),
18347
- claudeVersion: z30.union([z30.string().min(1), z30.literal(false)]).optional(),
18348
- delay: z30.union([z30.string().regex(DURATION_RE), z30.literal(false)]).optional(),
18349
- pause: z30.boolean().optional(),
18350
- explain: z30.boolean().optional(),
18351
- proxyBypass: z30.union([z30.array(z30.string().min(1)), z30.literal(false)]).optional(),
18352
- statusline: z30.strictObject({
18813
+ var ConfigProfileSetInputSchema = z31.strictObject({
18814
+ name: z31.string().min(1),
18815
+ category: z31.record(z31.string(), z31.boolean()).optional(),
18816
+ entry: z31.record(z31.string(), z31.boolean()).optional(),
18817
+ extends: z31.union([z31.array(z31.string().min(1)), z31.literal(false)]).optional(),
18818
+ description: z31.union([z31.string(), z31.literal(false)]).optional(),
18819
+ launch: z31.strictObject({
18820
+ skipPermissions: z31.boolean().optional(),
18821
+ remoteControl: z31.boolean().optional(),
18822
+ headroom: z31.boolean().optional(),
18823
+ trackUsage: z31.boolean().optional(),
18824
+ provider: z31.union([z31.string().min(1), z31.literal(false)]).optional(),
18825
+ claudeVersion: z31.union([z31.string().min(1), z31.literal(false)]).optional(),
18826
+ delay: z31.union([z31.string().regex(DURATION_RE), z31.literal(false)]).optional(),
18827
+ pause: z31.boolean().optional(),
18828
+ explain: z31.boolean().optional(),
18829
+ proxyBypass: z31.union([z31.array(z31.string().min(1)), z31.literal(false)]).optional(),
18830
+ statusline: z31.strictObject({
18353
18831
  set: ConfigStatuslineSetSchema.optional(),
18354
- unset: z30.array(z30.string()).optional()
18832
+ unset: z31.array(z31.string()).optional()
18355
18833
  }).optional()
18356
18834
  }).optional()
18357
18835
  });
18358
18836
  var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
18359
- var ConfigProfileRemoveInputSchema = z30.strictObject({ name: z30.string().min(1), confirm: RemovalConfirmationSchema });
18837
+ var ConfigProfileRemoveInputSchema = z31.strictObject({ name: z31.string().min(1), confirm: RemovalConfirmationSchema });
18360
18838
  var ConfigProfileRemoveOutputSchema = mutationOutput("profile", "removed");
18361
18839
  var ConfigProfileUseOutputSchema = mutationOutput("profile", "selected");
18362
- var PoolMembersInputSchema = z30.array(z30.string().min(1)).min(1);
18363
- var ConfigPoolAddInputSchema = z30.strictObject({
18364
- name: z30.string().min(1),
18840
+ var PoolMembersInputSchema = z31.array(z31.string().min(1)).min(1);
18841
+ var ConfigPoolAddInputSchema = z31.strictObject({
18842
+ name: z31.string().min(1),
18365
18843
  identities: PoolMembersInputSchema,
18366
- preference: z30.enum(POOL_PREFERENCES).optional(),
18367
- resumeOnLimit: z30.boolean().optional(),
18368
- compactBeforeLimit: z30.boolean().optional(),
18844
+ preference: z31.enum(POOL_PREFERENCES).optional(),
18845
+ resumeOnLimit: z31.boolean().optional(),
18846
+ compactBeforeLimit: z31.boolean().optional(),
18369
18847
  compactAtUtilisation: CompactAtUtilisationSchema.optional()
18370
18848
  });
18371
18849
  var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
18372
- var ConfigPoolSetInputSchema = z30.strictObject({
18373
- name: z30.string().min(1),
18850
+ var ConfigPoolSetInputSchema = z31.strictObject({
18851
+ name: z31.string().min(1),
18374
18852
  identities: PoolMembersInputSchema.optional(),
18375
- preference: z30.union([z30.enum(POOL_PREFERENCES), z30.literal(false)]).optional(),
18376
- resumeOnLimit: z30.boolean().optional(),
18377
- compactBeforeLimit: z30.boolean().optional(),
18378
- compactAtUtilisation: z30.union([CompactAtUtilisationSchema, z30.literal(false)]).optional()
18853
+ preference: z31.union([z31.enum(POOL_PREFERENCES), z31.literal(false)]).optional(),
18854
+ resumeOnLimit: z31.boolean().optional(),
18855
+ compactBeforeLimit: z31.boolean().optional(),
18856
+ compactAtUtilisation: z31.union([CompactAtUtilisationSchema, z31.literal(false)]).optional()
18379
18857
  });
18380
18858
  var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
18381
- var ConfigPoolRemoveInputSchema = z30.strictObject({ name: z30.string().min(1), confirm: RemovalConfirmationSchema });
18859
+ var ConfigPoolRemoveInputSchema = z31.strictObject({ name: z31.string().min(1), confirm: RemovalConfirmationSchema });
18382
18860
  var ConfigPoolRemoveOutputSchema = mutationOutput("pool", "removed");
18383
18861
  var ConfigPoolUseOutputSchema = mutationOutput("pool", "selected");
18384
- var ConfigProviderAddInputSchema = z30.strictObject({
18385
- name: z30.string().min(1),
18386
- kind: z30.enum(PROVIDER_KINDS).optional(),
18387
- displayName: z30.string().min(1),
18388
- baseUrl: z30.string().min(1).optional(),
18862
+ var ConfigProviderAddInputSchema = z31.strictObject({
18863
+ name: z31.string().min(1),
18864
+ kind: z31.enum(PROVIDER_KINDS).optional(),
18865
+ displayName: z31.string().min(1),
18866
+ baseUrl: z31.string().min(1).optional(),
18389
18867
  credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).required({ sources: true }),
18390
18868
  codex: CodexProviderConfigSchema.optional()
18391
18869
  });
18392
18870
  var ConfigProviderAddOutputSchema = storedMutationOutput("provider", "created", ProviderValueSchema);
18393
- var ConfigProviderSetInputSchema = z30.strictObject({
18394
- name: z30.string().min(1),
18395
- displayName: z30.string().min(1).optional(),
18396
- baseUrl: z30.string().min(1).optional(),
18871
+ var ConfigProviderSetInputSchema = z31.strictObject({
18872
+ name: z31.string().min(1),
18873
+ displayName: z31.string().min(1).optional(),
18874
+ baseUrl: z31.string().min(1).optional(),
18397
18875
  credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).optional(),
18398
18876
  codex: CodexProviderConfigSchema.optional()
18399
18877
  });
18400
18878
  var ConfigProviderSetOutputSchema = storedMutationOutput("provider", "updated", ProviderValueSchema);
18401
- var ConfigProviderRemoveInputSchema = z30.strictObject({ name: z30.string().min(1), confirm: RemovalConfirmationSchema });
18879
+ var ConfigProviderRemoveInputSchema = z31.strictObject({ name: z31.string().min(1), confirm: RemovalConfirmationSchema });
18402
18880
  var ConfigProviderRemoveOutputSchema = mutationOutput("provider", "removed");
18403
- var ConfigRuleAddInputSchema = z30.strictObject({
18404
- path: z30.string().min(1),
18405
- configProfile: z30.string().min(1).optional(),
18406
- identity: z30.string().min(1).optional()
18881
+ var ConfigRuleAddInputSchema = z31.strictObject({
18882
+ path: z31.string().min(1),
18883
+ configProfile: z31.string().min(1).optional(),
18884
+ identity: z31.string().min(1).optional()
18407
18885
  });
18408
18886
  var ConfigRuleAddOutputSchema = storedMutationOutput("rule", "created", DirectoryRuleSchema);
18409
- var ConfigRuleSetInputSchema = z30.strictObject({
18410
- path: z30.string().min(1),
18411
- configProfile: z30.union([z30.string().min(1), z30.literal(false)]).optional(),
18412
- identity: z30.union([z30.string().min(1), z30.literal(false)]).optional()
18887
+ var ConfigRuleSetInputSchema = z31.strictObject({
18888
+ path: z31.string().min(1),
18889
+ configProfile: z31.union([z31.string().min(1), z31.literal(false)]).optional(),
18890
+ identity: z31.union([z31.string().min(1), z31.literal(false)]).optional()
18413
18891
  });
18414
18892
  var ConfigRuleSetOutputSchema = storedMutationOutput("rule", "updated", DirectoryRuleSchema);
18415
- var ConfigRuleRemoveInputSchema = z30.strictObject({ path: z30.string().min(1), confirm: RemovalConfirmationSchema });
18893
+ var ConfigRuleRemoveInputSchema = z31.strictObject({ path: z31.string().min(1), confirm: RemovalConfirmationSchema });
18416
18894
  var ConfigRuleRemoveOutputSchema = mutationOutput("rule", "removed");
18417
18895
 
18418
18896
  // src/frontdoor/configApi.ts
18419
18897
  var CONFIG_API_TAG = "config";
18420
18898
  function refusal(error) {
18899
+ if (error instanceof KeychainLookupError) {
18900
+ throw new ORPCError2("SERVICE_UNAVAILABLE", { message: error.message });
18901
+ }
18421
18902
  if (error instanceof IdentityNotFoundError || error instanceof ProfileNotFoundError || error instanceof PoolNotFoundError || error instanceof ProviderNotFoundError || error instanceof DirectoryRuleNotFoundError) {
18422
18903
  throw new ORPCError2("NOT_FOUND", { message: error.message });
18423
18904
  }
18424
- if (error instanceof IdentityAlreadyExistsError || error instanceof ProfileAlreadyExistsError || error instanceof PoolAlreadyExistsError || error instanceof ProviderAlreadyExistsError || error instanceof DirectoryRuleAlreadyExistsError) {
18905
+ if (error instanceof IdentityAlreadyExistsError || error instanceof ProfileAlreadyExistsError || error instanceof PoolAlreadyExistsError || error instanceof ProviderAlreadyExistsError || error instanceof DirectoryRuleAlreadyExistsError || error instanceof KeychainLoginError) {
18425
18906
  throw new ORPCError2("CONFLICT", { message: error.message });
18426
18907
  }
18427
18908
  if (error instanceof CliError) {
@@ -18429,6 +18910,13 @@ function refusal(error) {
18429
18910
  }
18430
18911
  throw error;
18431
18912
  }
18913
+ async function guardedAsync(write) {
18914
+ try {
18915
+ await write();
18916
+ } catch (error) {
18917
+ refusal(error);
18918
+ }
18919
+ }
18432
18920
  function guarded(write) {
18433
18921
  try {
18434
18922
  return write();
@@ -18478,16 +18966,21 @@ function profileValue(name, paths) {
18478
18966
  function createConfigApiRouter(deps) {
18479
18967
  const authed = doorApiAuth(deps.expectedToken);
18480
18968
  const { paths } = deps;
18481
- const route = (path42, summary) => authed.meta(openapi3({ method: "POST", path: path42, summary, tags: [CONFIG_API_TAG] }));
18969
+ const route = (path45, summary) => authed.meta(openapi3({ method: "POST", path: path45, summary, tags: [CONFIG_API_TAG] }));
18482
18970
  return {
18483
18971
  config: {
18484
18972
  identity: {
18485
- add: route("/rest/config/identity/add", "Create an identity").input(ConfigNameInputSchema).output(ConfigIdentityAddOutputSchema).handler(
18486
- ({ input }) => guarded(() => {
18973
+ add: route("/rest/config/identity/add", "Create an identity").input(ConfigIdentityAddInputSchema).output(ConfigIdentityAddOutputSchema).handler(async ({ input }) => {
18974
+ await guardedAsync(async () => {
18975
+ await resolveWithAsyncRuns((run) => {
18976
+ requireIdentityAddable(paths, input.name, { run, platform: deps.keychain.platform }, input.keepKeychainLogin === true);
18977
+ }, deps.keychain.runAsync);
18978
+ });
18979
+ return guarded(() => {
18487
18980
  addIdentity(paths, input.name);
18488
18981
  return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
18489
- })
18490
- ),
18982
+ });
18983
+ }),
18491
18984
  set: route("/rest/config/identity/set", "Update an identity's label, default profile, provider, ambient-credential setting, credential or anchors").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
18492
18985
  ({ input }) => guarded(() => {
18493
18986
  requireChange(input.label !== void 0 || input.defaultConfigProfile !== void 0 || input.provider !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0 || input.anchors !== void 0, "label, defaultConfigProfile, provider, allowAmbientCredential, credential or anchors");
@@ -18736,43 +19229,43 @@ import { openapi as openapi4 } from "@orpc/openapi";
18736
19229
  import { eventIterator as eventIterator2, withEventMeta as withEventMeta2 } from "@orpc/server";
18737
19230
 
18738
19231
  // src/frontdoor/eventSchemas.ts
18739
- import { z as z31 } from "zod";
19232
+ import { z as z32 } from "zod";
18740
19233
  var DOOR_EVENT_SOURCE_RC = "rc";
18741
19234
  var LAUNCH_EVENT_SOURCE = "launch";
18742
19235
  var USAGE_EVENT_SOURCE = "usage";
18743
19236
  var DOOR_HEALTH_EVENT_SOURCE = "door";
18744
19237
  var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
18745
- var DoorEventSchema = z31.strictObject({
18746
- source: z31.string().min(1),
19238
+ var DoorEventSchema = z32.strictObject({
19239
+ source: z32.string().min(1),
18747
19240
  /** A positive integer because the backbone's counters start at one and only ever increase. */
18748
- sequence: z31.number().int().positive(),
18749
- payload: z31.unknown()
19241
+ sequence: z32.number().int().positive(),
19242
+ payload: z32.unknown()
18750
19243
  });
18751
- var DoorEventSourceQuerySchema = z31.strictObject({
18752
- sources: z31.array(z31.string().min(1)).min(1).optional()
19244
+ var DoorEventSourceQuerySchema = z32.strictObject({
19245
+ sources: z32.array(z32.string().min(1)).min(1).optional()
18753
19246
  });
18754
- var LaunchLifecycleEventSchema = z31.strictObject({
18755
- kind: z31.enum(["registered", "pruned", "ended"]),
18756
- pid: z31.number().int().positive(),
18757
- startedAt: z31.number(),
18758
- observedAt: z31.number()
19247
+ var LaunchLifecycleEventSchema = z32.strictObject({
19248
+ kind: z32.enum(["registered", "pruned", "ended"]),
19249
+ pid: z32.number().int().positive(),
19250
+ startedAt: z32.number(),
19251
+ observedAt: z32.number()
18759
19252
  });
18760
- var DoorHealthEventSchema = z31.discriminatedUnion("kind", [
18761
- z31.strictObject({ kind: z31.literal("generation"), pid: z31.number().int().positive(), providerPort: z31.number().int().positive(), connectPort: z31.number().int().positive(), directPort: z31.number().int().positive(), observedAt: z31.number() }),
18762
- z31.strictObject({ kind: z31.literal("listenerFailed"), pid: z31.number().int().positive(), listener: z31.enum(["provider", "connect", "direct"]), message: z31.string(), observedAt: z31.number() }),
18763
- z31.strictObject({ kind: z31.literal("binaryTurnover"), pid: z31.number().int().positive(), observedAt: z31.number() }),
18764
- z31.strictObject({ kind: z31.literal("idleShutdown"), pid: z31.number().int().positive(), observedAt: z31.number() }),
18765
- z31.strictObject({ kind: z31.literal("superseded"), pid: z31.number().int().positive(), ownerPid: z31.number().int().positive(), observedAt: z31.number() }),
18766
- z31.strictObject({ kind: z31.literal("drained"), pid: z31.number().int().positive(), observedAt: z31.number() })
19253
+ var DoorHealthEventSchema = z32.discriminatedUnion("kind", [
19254
+ z32.strictObject({ kind: z32.literal("generation"), pid: z32.number().int().positive(), providerPort: z32.number().int().positive(), connectPort: z32.number().int().positive(), directPort: z32.number().int().positive(), observedAt: z32.number() }),
19255
+ z32.strictObject({ kind: z32.literal("listenerFailed"), pid: z32.number().int().positive(), listener: z32.enum(["provider", "connect", "direct"]), message: z32.string(), observedAt: z32.number() }),
19256
+ z32.strictObject({ kind: z32.literal("binaryTurnover"), pid: z32.number().int().positive(), observedAt: z32.number() }),
19257
+ z32.strictObject({ kind: z32.literal("idleShutdown"), pid: z32.number().int().positive(), observedAt: z32.number() }),
19258
+ z32.strictObject({ kind: z32.literal("superseded"), pid: z32.number().int().positive(), ownerPid: z32.number().int().positive(), observedAt: z32.number() }),
19259
+ z32.strictObject({ kind: z32.literal("drained"), pid: z32.number().int().positive(), observedAt: z32.number() })
18767
19260
  ]);
18768
- var QuotaExpiringEventSchema = z31.strictObject({
18769
- identity: z31.string().min(1),
18770
- provider: z31.string().min(1),
18771
- window: z31.enum(["fiveHour", "sevenDay"]),
19261
+ var QuotaExpiringEventSchema = z32.strictObject({
19262
+ identity: z32.string().min(1),
19263
+ provider: z32.string().min(1),
19264
+ window: z32.enum(["fiveHour", "sevenDay"]),
18772
19265
  /** The fraction of the window already used when it was seen expiring, always below one because a fully used window has nothing left to spend. */
18773
- utilization: z31.number().min(0).max(1),
18774
- resetsAt: z31.iso.datetime(),
18775
- observedAt: z31.number()
19266
+ utilization: z32.number().min(0).max(1),
19267
+ resetsAt: z32.iso.datetime(),
19268
+ observedAt: z32.number()
18776
19269
  });
18777
19270
 
18778
19271
  // src/frontdoor/eventsApi.ts
@@ -18855,61 +19348,61 @@ import { ORPCError as ORPCError5 } from "@orpc/client";
18855
19348
  import { openapi as openapi6 } from "@orpc/openapi";
18856
19349
 
18857
19350
  // src/frontdoor/launchSchemas.ts
18858
- import path31 from "node:path";
18859
- import { z as z32 } from "zod";
19351
+ import path33 from "node:path";
19352
+ import { z as z33 } from "zod";
18860
19353
  init_statusline();
18861
19354
  init_claudeVersion();
18862
19355
  init_identity();
18863
- var LaunchResolveInputSchema = z32.strictObject({
18864
- path: z32.string().min(1),
19356
+ var LaunchResolveInputSchema = z33.strictObject({
19357
+ path: z33.string().min(1),
18865
19358
  /** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
18866
- argv: z32.readonly(z32.array(z32.string())).optional(),
19359
+ argv: z33.readonly(z33.array(z33.string())).optional(),
18867
19360
  /** The launch's inherited environment. Absent means an empty one: the door's own environment is never a substitute for the caller's, so a caller that wants `AGENT_SHIM_*` switches or a `CLAUDE_CONFIG_DIR` considered names them here. Values are read, never reported. */
18868
- env: z32.record(z32.string(), z32.string()).optional()
18869
- }).refine((input) => path31.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
18870
- var LaunchPoolDecisionSchema = z32.strictObject({
18871
- name: z32.string(),
18872
- reasons: z32.readonly(z32.array(z32.string())),
18873
- movedOff: z32.strictObject({ identity: z32.string(), reason: z32.string() }).optional()
19361
+ env: z33.record(z33.string(), z33.string()).optional()
19362
+ }).refine((input) => path33.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
19363
+ var LaunchPoolDecisionSchema = z33.strictObject({
19364
+ name: z33.string(),
19365
+ reasons: z33.readonly(z33.array(z33.string())),
19366
+ movedOff: z33.strictObject({ identity: z33.string(), reason: z33.string() }).optional()
18874
19367
  });
18875
- var LaunchDecisionSchema = z32.strictObject({
18876
- identity: z32.string().optional(),
18877
- identitySource: z32.enum(IDENTITY_DECISION_SOURCES),
19368
+ var LaunchDecisionSchema = z33.strictObject({
19369
+ identity: z33.string().optional(),
19370
+ identitySource: z33.enum(IDENTITY_DECISION_SOURCES),
18878
19371
  pool: LaunchPoolDecisionSchema.optional(),
18879
- configDirEscapeHatch: z32.boolean(),
18880
- configDir: z32.string().optional(),
18881
- configProfile: z32.string().optional(),
18882
- configProfileSource: z32.enum(CONFIG_PROFILE_DECISION_SOURCES),
18883
- provider: z32.string().optional()
19372
+ configDirEscapeHatch: z33.boolean(),
19373
+ configDir: z33.string().optional(),
19374
+ configProfile: z33.string().optional(),
19375
+ configProfileSource: z33.enum(CONFIG_PROFILE_DECISION_SOURCES),
19376
+ provider: z33.string().optional()
18884
19377
  });
18885
- var LaunchFlagsSchema = z32.strictObject({
18886
- skipPermissions: z32.boolean(),
18887
- remoteControl: z32.boolean(),
18888
- headroom: z32.boolean(),
18889
- trackUsage: z32.boolean(),
18890
- pause: z32.boolean(),
18891
- explain: z32.boolean(),
19378
+ var LaunchFlagsSchema = z33.strictObject({
19379
+ skipPermissions: z33.boolean(),
19380
+ remoteControl: z33.boolean(),
19381
+ headroom: z33.boolean(),
19382
+ trackUsage: z33.boolean(),
19383
+ pause: z33.boolean(),
19384
+ explain: z33.boolean(),
18892
19385
  /** How long the launch waits after its own output before it starts claude, in milliseconds. */
18893
- delayMs: z32.number(),
19386
+ delayMs: z33.number(),
18894
19387
  /** The hosts the launch keeps off the front door by adding them to the child's `NO_PROXY`. */
18895
- proxyBypass: z32.array(z32.string()).readonly(),
19388
+ proxyBypass: z33.array(z33.string()).readonly(),
18896
19389
  /** How the session's built-in statusline looks, when the launch configures any of it. */
18897
19390
  statusline: StatuslineSchema.optional()
18898
19391
  });
18899
- var LaunchResolveOutputSchema = z32.strictObject({
19392
+ var LaunchResolveOutputSchema = z33.strictObject({
18900
19393
  decision: LaunchDecisionSchema,
18901
19394
  flags: LaunchFlagsSchema,
18902
- claudeVersion: z32.strictObject({ version: z32.string(), source: z32.enum(CLAUDE_VERSION_SOURCES) }).optional(),
19395
+ claudeVersion: z33.strictObject({ version: z33.string(), source: z33.enum(CLAUDE_VERSION_SOURCES) }).optional(),
18903
19396
  /** The real `claude` binary the launch would spawn, on the door's host. */
18904
- bin: z32.string(),
19397
+ bin: z33.string(),
18905
19398
  /** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
18906
- args: z32.readonly(z32.array(z32.string())),
19399
+ args: z33.readonly(z33.array(z33.string())),
18907
19400
  /** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
18908
- credential: z32.strictObject({ subject: z32.enum(["provider", "identity"]), name: z32.string(), summary: CredentialSummarySchema }).optional(),
18909
- routing: z32.strictObject({ frontDoor: z32.boolean(), headroom: z32.boolean() }),
19401
+ credential: z33.strictObject({ subject: z33.enum(["provider", "identity"]), name: z33.string(), summary: CredentialSummarySchema }).optional(),
19402
+ routing: z33.strictObject({ frontDoor: z33.boolean(), headroom: z33.boolean() }),
18910
19403
  /** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
18911
- environment: z32.readonly(z32.array(z32.string())),
18912
- warnings: z32.readonly(z32.array(z32.string()))
19404
+ environment: z33.readonly(z33.array(z33.string())),
19405
+ warnings: z33.readonly(z33.array(z33.string()))
18913
19406
  });
18914
19407
 
18915
19408
  // src/frontdoor/launchApi.ts
@@ -18945,22 +19438,22 @@ function createLaunchApiRouter(deps) {
18945
19438
  // src/frontdoor/agentTreesApi.ts
18946
19439
  import { ORPCError as ORPCError6 } from "@orpc/client";
18947
19440
  import { openapi as openapi7 } from "@orpc/openapi";
18948
- import { z as z33 } from "zod";
19441
+ import { z as z34 } from "zod";
18949
19442
  init_cliError();
18950
- var AgentTreesListInputSchema = z33.strictObject({
19443
+ var AgentTreesListInputSchema = z34.strictObject({
18951
19444
  /** Only this identity's sessions. */
18952
- identity: z33.string().optional(),
19445
+ identity: z34.string().optional(),
18953
19446
  /** Include sessions that spawned no agent and ran no workflow. */
18954
- all: z33.boolean().optional()
19447
+ all: z34.boolean().optional()
18955
19448
  });
18956
- var AgentTreesListOutputSchema = z33.array(SessionSummarySchema);
18957
- var AgentTreesShowInputSchema = z33.strictObject({
19449
+ var AgentTreesListOutputSchema = z34.array(SessionSummarySchema);
19450
+ var AgentTreesShowInputSchema = z34.strictObject({
18958
19451
  /** A session id, or an unambiguous prefix of one. */
18959
- session: z33.string().min(1),
19452
+ session: z34.string().min(1),
18960
19453
  /** Look only in this identity. */
18961
- identity: z33.string().optional()
19454
+ identity: z34.string().optional()
18962
19455
  });
18963
- var AgentTreesShowOutputSchema = z33.strictObject({ identities: z33.array(z33.string()), ...MergedAgentTreeSchema.shape });
19456
+ var AgentTreesShowOutputSchema = z34.strictObject({ identities: z34.array(z34.string()), ...MergedAgentTreeSchema.shape });
18964
19457
  function asBadRequest(error) {
18965
19458
  if (error instanceof CliError) {
18966
19459
  throw new ORPCError6("BAD_REQUEST", { message: error.message });
@@ -21047,7 +21540,7 @@ data: ${JSON.stringify(envelope)}
21047
21540
 
21048
21541
  // src/frontdoor/rcSelfHostMint.ts
21049
21542
  init_account();
21050
- import path32 from "node:path";
21543
+ import path34 from "node:path";
21051
21544
  var CREDENTIALS_FILE2 = ".credentials.json";
21052
21545
  var CLAUDE_JSON2 = ".claude.json";
21053
21546
  var RC_SELF_HOST_RECORD_DIR = "rc-selfhost";
@@ -21057,8 +21550,8 @@ var SELF_HOST_SUBSCRIPTION_TYPE = "max";
21057
21550
  function isRecord14(value) {
21058
21551
  return typeof value === "object" && value !== null && !Array.isArray(value);
21059
21552
  }
21060
- function readJsonObject(fs14, file) {
21061
- const raw = fs14.readFileUtf8(file);
21553
+ function readJsonObject(fs15, file) {
21554
+ const raw = fs15.readFileUtf8(file);
21062
21555
  if (raw === void 0) {
21063
21556
  return void 0;
21064
21557
  }
@@ -21070,8 +21563,8 @@ function readJsonObject(fs14, file) {
21070
21563
  }
21071
21564
  return isRecord14(parsed) ? parsed : void 0;
21072
21565
  }
21073
- function readRcSelfHostRecord(fs14, frontdoorDir) {
21074
- const parsed = readJsonObject(fs14, path32.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
21566
+ function readRcSelfHostRecord(fs15, frontdoorDir) {
21567
+ const parsed = readJsonObject(fs15, path34.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
21075
21568
  if (parsed === void 0) {
21076
21569
  return void 0;
21077
21570
  }
@@ -21085,11 +21578,11 @@ function mintRcSelfHostCredential(deps) {
21085
21578
  if (!isIdentityName(deps.identity)) {
21086
21579
  throw new Error(`"${deps.identity}" is not a valid identity name.`);
21087
21580
  }
21088
- const identityDir = path32.join(deps.identitiesDir, deps.identity);
21089
- const credentialsFile = path32.join(identityDir, CREDENTIALS_FILE2);
21090
- const claudeJsonFile = path32.join(identityDir, CLAUDE_JSON2);
21091
- const recordDir = path32.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
21092
- const recordFile = path32.join(recordDir, RC_SELF_HOST_RECORD_FILE);
21581
+ const identityDir = path34.join(deps.identitiesDir, deps.identity);
21582
+ const credentialsFile = path34.join(identityDir, CREDENTIALS_FILE2);
21583
+ const claudeJsonFile = path34.join(identityDir, CLAUDE_JSON2);
21584
+ const recordDir = path34.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
21585
+ const recordFile2 = path34.join(recordDir, RC_SELF_HOST_RECORD_FILE);
21093
21586
  const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
21094
21587
  const existingCredentials = readJsonObject(deps.fs, credentialsFile);
21095
21588
  const existingOauth = isRecord14(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
@@ -21105,7 +21598,7 @@ function mintRcSelfHostCredential(deps) {
21105
21598
  const organizationUuid = deps.newUuid();
21106
21599
  const accountUuid = deps.newUuid();
21107
21600
  const mintedAt = new Date(deps.now()).toISOString();
21108
- deps.fs.mkdirPrivate(path32.dirname(credentialsFile));
21601
+ deps.fs.mkdirPrivate(path34.dirname(credentialsFile));
21109
21602
  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)}
21110
21603
  `);
21111
21604
  const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
@@ -21132,9 +21625,9 @@ function mintRcSelfHostCredential(deps) {
21132
21625
  }, null, 2)}
21133
21626
  `);
21134
21627
  deps.fs.mkdirPrivate(recordDir);
21135
- deps.fs.writeFilePrivate(recordFile, `${JSON.stringify({ accessToken, refreshToken, organizationUuid, accountUuid }, null, 2)}
21628
+ deps.fs.writeFilePrivate(recordFile2, `${JSON.stringify({ accessToken, refreshToken, organizationUuid, accountUuid }, null, 2)}
21136
21629
  `);
21137
- return { identity: deps.identity, organizationUuid, credentialsFile, claudeJsonFile, recordFile, replaced: existingIsOwn };
21630
+ return { identity: deps.identity, organizationUuid, credentialsFile, claudeJsonFile, recordFile: recordFile2, replaced: existingIsOwn };
21138
21631
  }
21139
21632
 
21140
21633
  // src/index.ts
@@ -21143,25 +21636,25 @@ init_ensure2();
21143
21636
  // src/frontdoor/liveSessionRegistry.ts
21144
21637
  init_capability();
21145
21638
  init_state();
21146
- import path33 from "node:path";
21639
+ import path35 from "node:path";
21147
21640
  function sameStat(recorded, current) {
21148
21641
  return recorded?.mtimeMs === current.mtimeMs && recorded.sizeBytes === current.sizeBytes;
21149
21642
  }
21150
21643
  function createLiveSessionRegistry(ports) {
21151
- const { fs: fs14, sessionsDir } = ports;
21644
+ const { fs: fs15, sessionsDir } = ports;
21152
21645
  const known = /* @__PURE__ */ new Map();
21153
21646
  let tokens = /* @__PURE__ */ new Set();
21154
21647
  let bySessionId = /* @__PURE__ */ new Map();
21155
- const recordNames = () => fs14.readdir(sessionsDir).filter(isSessionRecordName);
21648
+ const recordNames = () => fs15.readdir(sessionsDir).filter(isSessionRecordName);
21156
21649
  const rebuildIndexes = () => {
21157
21650
  const records = [...known.values()].flatMap(({ record }) => record === void 0 ? [] : [record]);
21158
21651
  tokens = new Set(records.map((record) => record.token));
21159
21652
  bySessionId = new Map(records.flatMap((record) => record.sessionId === void 0 ? [] : [[record.sessionId, record]]));
21160
21653
  };
21161
21654
  const load = (name, stat) => {
21162
- known.set(name, { stat: { mtimeMs: stat.mtimeMs, sizeBytes: stat.sizeBytes }, record: readFrontDoorSessionRecord(fs14, sessionsDir, name) });
21655
+ known.set(name, { stat: { mtimeMs: stat.mtimeMs, sizeBytes: stat.sizeBytes }, record: readFrontDoorSessionRecord(fs15, sessionsDir, name) });
21163
21656
  };
21164
- const statOf = (name) => fs14.lstat(path33.join(sessionsDir, name));
21657
+ const statOf = (name) => fs15.lstat(path35.join(sessionsDir, name));
21165
21658
  const reconcile = () => {
21166
21659
  const names = new Set(recordNames());
21167
21660
  let changed = false;
@@ -21228,8 +21721,8 @@ init_plan2();
21228
21721
  init_poolPick();
21229
21722
 
21230
21723
  // src/agents/read.ts
21231
- import path34 from "node:path";
21232
- import { z as z34 } from "zod";
21724
+ import path36 from "node:path";
21725
+ import { z as z35 } from "zod";
21233
21726
  var PROJECTS_DIR = "projects";
21234
21727
  var TASKS_DIR = "tasks";
21235
21728
  var SUBAGENTS_DIR = "subagents";
@@ -21252,17 +21745,17 @@ function parseEntry2(project, entry) {
21252
21745
  const base = match?.[1];
21253
21746
  return base === void 0 ? { project, sessionId: entry, superseded: false, entry } : { project, sessionId: base, superseded: true, entry };
21254
21747
  }
21255
- function listSessions2(fs14, configDir) {
21748
+ function listSessions2(fs15, configDir) {
21256
21749
  const found = [];
21257
- for (const project of fs14.readdir(path34.join(configDir, PROJECTS_DIR))) {
21258
- const projectDir = path34.join(configDir, PROJECTS_DIR, project);
21750
+ for (const project of fs15.readdir(path36.join(configDir, PROJECTS_DIR))) {
21751
+ const projectDir = path36.join(configDir, PROJECTS_DIR, project);
21259
21752
  const entries = /* @__PURE__ */ new Set();
21260
- for (const name of fs14.readdir(projectDir)) {
21753
+ for (const name of fs15.readdir(projectDir)) {
21261
21754
  if (name.endsWith(TRANSCRIPT_SUFFIX)) {
21262
21755
  entries.add(name.slice(0, -TRANSCRIPT_SUFFIX.length));
21263
21756
  continue;
21264
21757
  }
21265
- const children = fs14.readdir(path34.join(projectDir, name));
21758
+ const children = fs15.readdir(path36.join(projectDir, name));
21266
21759
  if (children.includes(SUBAGENTS_DIR) || children.includes(WORKFLOWS_DIR)) {
21267
21760
  entries.add(name);
21268
21761
  }
@@ -21273,17 +21766,17 @@ function listSessions2(fs14, configDir) {
21273
21766
  }
21274
21767
  return found.sort((left, right) => left.project.localeCompare(right.project) || left.entry.localeCompare(right.entry));
21275
21768
  }
21276
- function locateAgents(fs14, configDir, relativeDir, workflowRunId, report) {
21769
+ function locateAgents(fs15, configDir, relativeDir, workflowRunId, report) {
21277
21770
  const located = [];
21278
- for (const name of listDirOrReport(fs14, configDir, relativeDir, report)) {
21771
+ for (const name of listDirOrReport(fs15, configDir, relativeDir, report)) {
21279
21772
  if (!name.startsWith(AGENT_FILE_PREFIX) || !name.endsWith(META_SUFFIX)) {
21280
21773
  continue;
21281
21774
  }
21282
21775
  const id = name.slice(AGENT_FILE_PREFIX.length, -META_SUFFIX.length);
21283
21776
  located.push({
21284
21777
  id,
21285
- metaPath: path34.join(relativeDir, name),
21286
- transcriptPath: path34.join(relativeDir, `${AGENT_FILE_PREFIX}${id}${TRANSCRIPT_SUFFIX}`),
21778
+ metaPath: path36.join(relativeDir, name),
21779
+ transcriptPath: path36.join(relativeDir, `${AGENT_FILE_PREFIX}${id}${TRANSCRIPT_SUFFIX}`),
21287
21780
  workflowRunId
21288
21781
  });
21289
21782
  }
@@ -21324,17 +21817,17 @@ function toNode(read, children) {
21324
21817
  function describeFailure(error) {
21325
21818
  return error instanceof Error ? error.message : String(error);
21326
21819
  }
21327
- function readFileOrReport(fs14, configDir, relative, report) {
21820
+ function readFileOrReport(fs15, configDir, relative, report) {
21328
21821
  try {
21329
- return fs14.readFileUtf8(path34.join(configDir, relative));
21822
+ return fs15.readFileUtf8(path36.join(configDir, relative));
21330
21823
  } catch (error) {
21331
21824
  report({ path: relative, reason: `could not be read: ${describeFailure(error)}` });
21332
21825
  return void 0;
21333
21826
  }
21334
21827
  }
21335
- function listDirOrReport(fs14, configDir, relative, report) {
21828
+ function listDirOrReport(fs15, configDir, relative, report) {
21336
21829
  try {
21337
- return fs14.readdir(path34.join(configDir, relative));
21830
+ return fs15.readdir(path36.join(configDir, relative));
21338
21831
  } catch (error) {
21339
21832
  report({ path: relative, reason: `could not be listed: ${describeFailure(error)}` });
21340
21833
  return [];
@@ -21348,47 +21841,47 @@ function parseJson2(text) {
21348
21841
  return void 0;
21349
21842
  }
21350
21843
  }
21351
- var TaskFileSchema = z34.object({ ...TaskItemSchema.omit({ taskList: true }).shape, blocks: z34.array(z34.string()).default([]), blockedBy: z34.array(z34.string()).default([]) });
21352
- var WorkflowRunFileSchema = z34.object({
21353
- runId: z34.string(),
21354
- workflowName: z34.string().optional(),
21355
- status: z34.string().optional(),
21356
- startTime: z34.number().optional(),
21357
- phases: z34.array(z34.object({ title: z34.string() })).default([]),
21358
- summary: z34.string().optional()
21844
+ var TaskFileSchema = z35.object({ ...TaskItemSchema.omit({ taskList: true }).shape, blocks: z35.array(z35.string()).default([]), blockedBy: z35.array(z35.string()).default([]) });
21845
+ var WorkflowRunFileSchema = z35.object({
21846
+ runId: z35.string(),
21847
+ workflowName: z35.string().optional(),
21848
+ status: z35.string().optional(),
21849
+ startTime: z35.number().optional(),
21850
+ phases: z35.array(z35.object({ title: z35.string() })).default([]),
21851
+ summary: z35.string().optional()
21359
21852
  });
21360
- function summariseSession(fs14, configDir, ref) {
21361
- const sessionRelative = path34.join(PROJECTS_DIR, ref.project, ref.entry);
21362
- const subagentsRelative = path34.join(sessionRelative, SUBAGENTS_DIR);
21363
- const workflowsUnderSubagents = path34.join(subagentsRelative, WORKFLOWS_DIR);
21853
+ function summariseSession(fs15, configDir, ref) {
21854
+ const sessionRelative = path36.join(PROJECTS_DIR, ref.project, ref.entry);
21855
+ const subagentsRelative = path36.join(sessionRelative, SUBAGENTS_DIR);
21856
+ const workflowsUnderSubagents = path36.join(subagentsRelative, WORKFLOWS_DIR);
21364
21857
  const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
21365
- let agentCount = fs14.readdir(path34.join(configDir, subagentsRelative)).filter(isMeta).length;
21366
- for (const runDir of fs14.readdir(path34.join(configDir, workflowsUnderSubagents))) {
21858
+ let agentCount = fs15.readdir(path36.join(configDir, subagentsRelative)).filter(isMeta).length;
21859
+ for (const runDir of fs15.readdir(path36.join(configDir, workflowsUnderSubagents))) {
21367
21860
  if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
21368
- agentCount += fs14.readdir(path34.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
21861
+ agentCount += fs15.readdir(path36.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
21369
21862
  }
21370
21863
  }
21371
- const workflowRunCount = fs14.readdir(path34.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
21372
- const transcript = fs14.lstat(path34.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
21864
+ const workflowRunCount = fs15.readdir(path36.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
21865
+ const transcript = fs15.lstat(path36.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
21373
21866
  return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
21374
21867
  }
21375
- function readSessionAgentTree(fs14, configDir, ref, options = {}) {
21868
+ function readSessionAgentTree(fs15, configDir, ref, options = {}) {
21376
21869
  const problems = [];
21377
21870
  const report = (problem) => {
21378
21871
  problems.push(problem);
21379
21872
  };
21380
- const sessionRelative = path34.join(PROJECTS_DIR, ref.project, ref.entry);
21381
- const subagentsRelative = path34.join(sessionRelative, SUBAGENTS_DIR);
21382
- const workflowsUnderSubagents = path34.join(subagentsRelative, WORKFLOWS_DIR);
21383
- const located = locateAgents(fs14, configDir, subagentsRelative, void 0, report);
21384
- for (const runDir of listDirOrReport(fs14, configDir, workflowsUnderSubagents, report)) {
21873
+ const sessionRelative = path36.join(PROJECTS_DIR, ref.project, ref.entry);
21874
+ const subagentsRelative = path36.join(sessionRelative, SUBAGENTS_DIR);
21875
+ const workflowsUnderSubagents = path36.join(subagentsRelative, WORKFLOWS_DIR);
21876
+ const located = locateAgents(fs15, configDir, subagentsRelative, void 0, report);
21877
+ for (const runDir of listDirOrReport(fs15, configDir, workflowsUnderSubagents, report)) {
21385
21878
  if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
21386
- located.push(...locateAgents(fs14, configDir, path34.join(workflowsUnderSubagents, runDir), runDir, report));
21879
+ located.push(...locateAgents(fs15, configDir, path36.join(workflowsUnderSubagents, runDir), runDir, report));
21387
21880
  }
21388
21881
  }
21389
21882
  const agents = /* @__PURE__ */ new Map();
21390
21883
  for (const candidate of located) {
21391
- const text = readFileOrReport(fs14, configDir, candidate.metaPath, report);
21884
+ const text = readFileOrReport(fs15, configDir, candidate.metaPath, report);
21392
21885
  if (text === void 0) {
21393
21886
  continue;
21394
21887
  }
@@ -21400,7 +21893,7 @@ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
21400
21893
  agents.set(candidate.id, { located: candidate, meta: parsed.data });
21401
21894
  }
21402
21895
  const teamNames = [...new Set([...agents.values()].flatMap((agent) => agent.meta.teamName === void 0 ? [] : [agent.meta.teamName]))].sort();
21403
- const parentOf3 = resolveParents(fs14, configDir, agents, report);
21896
+ const parentOf3 = resolveParents(fs15, configDir, agents, report);
21404
21897
  const childrenOf = /* @__PURE__ */ new Map();
21405
21898
  const roots = [];
21406
21899
  for (const id of agents.keys()) {
@@ -21423,12 +21916,12 @@ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
21423
21916
  sessionId: ref.sessionId,
21424
21917
  superseded: ref.superseded,
21425
21918
  agents: roots.sort().map(build),
21426
- tasks: readTasks(fs14, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
21427
- workflowRuns: readWorkflowRuns(fs14, configDir, path34.join(sessionRelative, WORKFLOWS_DIR), report),
21919
+ tasks: readTasks(fs15, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
21920
+ workflowRuns: readWorkflowRuns(fs15, configDir, path36.join(sessionRelative, WORKFLOWS_DIR), report),
21428
21921
  problems
21429
21922
  };
21430
21923
  }
21431
- function resolveParents(fs14, configDir, agents, report) {
21924
+ function resolveParents(fs15, configDir, agents, report) {
21432
21925
  const parentOf3 = /* @__PURE__ */ new Map();
21433
21926
  const transcriptCache = /* @__PURE__ */ new Map();
21434
21927
  const transcriptOf = (agent) => {
@@ -21436,7 +21929,7 @@ function resolveParents(fs14, configDir, agents, report) {
21436
21929
  if (cached !== void 0) {
21437
21930
  return cached;
21438
21931
  }
21439
- const text = readFileOrReport(fs14, configDir, agent.located.transcriptPath, report) ?? "";
21932
+ const text = readFileOrReport(fs15, configDir, agent.located.transcriptPath, report) ?? "";
21440
21933
  transcriptCache.set(agent.located.id, text);
21441
21934
  return text;
21442
21935
  };
@@ -21486,16 +21979,16 @@ function resolveParents(fs14, configDir, agents, report) {
21486
21979
  function ownTaskLists(sessionId) {
21487
21980
  return [sessionId, `${SHORT_SESSION_LIST_PREFIX}${sessionId.slice(0, SHORT_SESSION_ID_LENGTH)}`];
21488
21981
  }
21489
- function readTasks(fs14, configDir, ownLists, sharedLists, report) {
21982
+ function readTasks(fs15, configDir, ownLists, sharedLists, report) {
21490
21983
  const tasks = [];
21491
21984
  [...ownLists, ...sharedLists].forEach((scope, index) => {
21492
- const relativeDir = path34.join(TASKS_DIR, scope);
21493
- for (const name of [...listDirOrReport(fs14, configDir, relativeDir, report)].sort()) {
21985
+ const relativeDir = path36.join(TASKS_DIR, scope);
21986
+ for (const name of [...listDirOrReport(fs15, configDir, relativeDir, report)].sort()) {
21494
21987
  if (name.startsWith(".") || !name.endsWith(JSON_SUFFIX)) {
21495
21988
  continue;
21496
21989
  }
21497
- const relative = path34.join(relativeDir, name);
21498
- const text = readFileOrReport(fs14, configDir, relative, report);
21990
+ const relative = path36.join(relativeDir, name);
21991
+ const text = readFileOrReport(fs15, configDir, relative, report);
21499
21992
  const parsed = TaskFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
21500
21993
  if (parsed.success) {
21501
21994
  tasks.push(index < ownLists.length ? parsed.data : { ...parsed.data, taskList: scope });
@@ -21506,14 +21999,14 @@ function readTasks(fs14, configDir, ownLists, sharedLists, report) {
21506
21999
  });
21507
22000
  return tasks;
21508
22001
  }
21509
- function readWorkflowRuns(fs14, configDir, relativeDir, report) {
22002
+ function readWorkflowRuns(fs15, configDir, relativeDir, report) {
21510
22003
  const runs = [];
21511
- for (const name of [...listDirOrReport(fs14, configDir, relativeDir, report)].sort()) {
22004
+ for (const name of [...listDirOrReport(fs15, configDir, relativeDir, report)].sort()) {
21512
22005
  if (!name.startsWith(WORKFLOW_RUN_PREFIX) || !name.endsWith(JSON_SUFFIX)) {
21513
22006
  continue;
21514
22007
  }
21515
- const relative = path34.join(relativeDir, name);
21516
- const text = readFileOrReport(fs14, configDir, relative, report);
22008
+ const relative = path36.join(relativeDir, name);
22009
+ const text = readFileOrReport(fs15, configDir, relative, report);
21517
22010
  const parsed = WorkflowRunFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
21518
22011
  if (!parsed.success) {
21519
22012
  if (text !== void 0) {
@@ -21529,7 +22022,7 @@ function readWorkflowRuns(fs14, configDir, relativeDir, report) {
21529
22022
 
21530
22023
  // src/agents/sessions.ts
21531
22024
  init_cliError();
21532
- import path35 from "node:path";
22025
+ import path37 from "node:path";
21533
22026
  var SessionLookupError = class extends CliError {
21534
22027
  constructor(message) {
21535
22028
  super(message);
@@ -21537,13 +22030,13 @@ var SessionLookupError = class extends CliError {
21537
22030
  }
21538
22031
  };
21539
22032
  function identityConfigDir(identitiesDir, identity) {
21540
- return path35.join(identitiesDir, identity);
22033
+ return path37.join(identitiesDir, identity);
21541
22034
  }
21542
- function historyStores(fs14, identitiesDir, identities) {
22035
+ function historyStores(fs15, identitiesDir, identities) {
21543
22036
  const byRealPath = /* @__PURE__ */ new Map();
21544
22037
  for (const identity of identities) {
21545
22038
  const configDir = identityConfigDir(identitiesDir, identity);
21546
- const real = fs14.realpath(path35.join(configDir, "projects"));
22039
+ const real = fs15.realpath(path37.join(configDir, "projects"));
21547
22040
  if (real === void 0) {
21548
22041
  continue;
21549
22042
  }
@@ -21556,15 +22049,15 @@ function historyStores(fs14, identitiesDir, identities) {
21556
22049
  }
21557
22050
  return [...byRealPath.values()];
21558
22051
  }
21559
- function collectSessionList(fs14, identitiesDir, identities, filters) {
22052
+ function collectSessionList(fs15, identitiesDir, identities, filters) {
21560
22053
  const names = filters.identity === void 0 ? identities : identities.filter((name) => name === filters.identity);
21561
22054
  if (filters.identity !== void 0 && names.length === 0) {
21562
22055
  throw new SessionLookupError(`no identity named "${filters.identity}"`);
21563
22056
  }
21564
22057
  const sessions = [];
21565
- for (const store of historyStores(fs14, identitiesDir, names)) {
21566
- for (const ref of listSessions2(fs14, store.configDir)) {
21567
- const summary = summariseSession(fs14, store.configDir, ref);
22058
+ for (const store of historyStores(fs15, identitiesDir, names)) {
22059
+ for (const ref of listSessions2(fs15, store.configDir)) {
22060
+ const summary = summariseSession(fs15, store.configDir, ref);
21568
22061
  if (filters.all === true || summary.agentCount > 0 || summary.workflowRunCount > 0) {
21569
22062
  sessions.push({ ...summary, identities: store.identities });
21570
22063
  }
@@ -21572,14 +22065,14 @@ function collectSessionList(fs14, identitiesDir, identities, filters) {
21572
22065
  }
21573
22066
  return sessions.sort((left, right) => (right.updatedAt ?? "").localeCompare(left.updatedAt ?? "") || left.sessionId.localeCompare(right.sessionId));
21574
22067
  }
21575
- function locateSession(fs14, identitiesDir, identities, query, onlyIdentity) {
22068
+ function locateSession(fs15, identitiesDir, identities, query, onlyIdentity) {
21576
22069
  const names = onlyIdentity === void 0 ? identities : identities.filter((name) => name === onlyIdentity);
21577
22070
  if (onlyIdentity !== void 0 && names.length === 0) {
21578
22071
  throw new SessionLookupError(`no identity named "${onlyIdentity}"`);
21579
22072
  }
21580
22073
  const matches = [];
21581
- for (const store of historyStores(fs14, identitiesDir, names)) {
21582
- for (const ref of listSessions2(fs14, store.configDir)) {
22074
+ for (const store of historyStores(fs15, identitiesDir, names)) {
22075
+ for (const ref of listSessions2(fs15, store.configDir)) {
21583
22076
  if (ref.sessionId.startsWith(query)) {
21584
22077
  matches.push({ identities: store.identities, configDir: store.configDir, ref });
21585
22078
  }
@@ -21596,9 +22089,9 @@ function locateSession(fs14, identitiesDir, identities, query, onlyIdentity) {
21596
22089
  }
21597
22090
  throw new SessionLookupError(`"${query}" matches ${String(candidates.length)} sessions: ${candidates.map((match) => `${match.ref.sessionId} (${match.identities.join(", ")})`).join("; ")}; give more of the id or pass --identity`);
21598
22091
  }
21599
- function showSession(fs14, identitiesDir, identities, query, onlyIdentity) {
21600
- const located = locateSession(fs14, identitiesDir, identities, query, onlyIdentity);
21601
- return { identities: located.identities, tree: readSessionAgentTree(fs14, located.configDir, located.ref) };
22092
+ function showSession(fs15, identitiesDir, identities, query, onlyIdentity) {
22093
+ const located = locateSession(fs15, identitiesDir, identities, query, onlyIdentity);
22094
+ return { identities: located.identities, tree: readSessionAgentTree(fs15, located.configDir, located.ref) };
21602
22095
  }
21603
22096
 
21604
22097
  // src/agents/realFs.ts
@@ -21753,6 +22246,7 @@ export {
21753
22246
  CodexRateLimitsReadSchema,
21754
22247
  CodexSignInSchema,
21755
22248
  CodexStatusOutputSchema,
22249
+ ConfigIdentityAddInputSchema,
21756
22250
  ConfigIdentityAddOutputSchema,
21757
22251
  ConfigIdentityRemoveInputSchema,
21758
22252
  ConfigIdentityRemoveOutputSchema,