agent-shim 8.6.0 → 8.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -60816,6 +60816,54 @@ function cacheChange(options, existing) {
60816
60816
  return parsed.data;
60817
60817
  }
60818
60818
 
60819
+ // src/usage/preflight.ts
60820
+ var MS_PER_SECOND = 1e3;
60821
+ var SECONDS_PER_MINUTE = 60;
60822
+ var MINUTES_PER_HOUR = 60;
60823
+ var HOURS_PER_DAY = 24;
60824
+ var WARNING_STATUSES = /* @__PURE__ */ new Set(["allowed_warning", "rejected"]);
60825
+ function formatAge(ms) {
60826
+ const minutes = Math.floor(ms / (MS_PER_SECOND * SECONDS_PER_MINUTE));
60827
+ if (minutes < MINUTES_PER_HOUR) {
60828
+ return `${String(Math.max(minutes, 0))}m`;
60829
+ }
60830
+ const hours = Math.floor(minutes / MINUTES_PER_HOUR);
60831
+ return hours < HOURS_PER_DAY ? `${String(hours)}h` : `${String(Math.floor(hours / HOURS_PER_DAY))}d`;
60832
+ }
60833
+ function effectiveWindow(window, nowMs) {
60834
+ const resetsAtMs = window.resetsAt === void 0 ? void 0 : Date.parse(window.resetsAt);
60835
+ if (resetsAtMs !== void 0 && resetsAtMs <= nowMs) {
60836
+ return { reset: true, utilization: 0 };
60837
+ }
60838
+ return {
60839
+ reset: false,
60840
+ ...window.utilization === void 0 ? {} : { utilization: window.utilization },
60841
+ ...resetsAtMs === void 0 ? {} : { resetsAtMs },
60842
+ ...window.status === void 0 ? {} : { status: window.status }
60843
+ };
60844
+ }
60845
+ function quotaWarnings(snapshot, provider, nowMs) {
60846
+ const rateLimit = snapshot?.providers[provider]?.rateLimit;
60847
+ const unified = rateLimit?.unified;
60848
+ if (snapshot === void 0 || rateLimit === void 0 || unified === void 0) {
60849
+ return [];
60850
+ }
60851
+ const age = formatAge(nowMs - Date.parse(rateLimit.observedAt));
60852
+ const windows = [
60853
+ { name: "five-hour", window: unified.fiveHour },
60854
+ { name: "seven-day", window: unified.sevenDay }
60855
+ ];
60856
+ return windows.flatMap(({ name, window }) => {
60857
+ const effective = window === void 0 ? void 0 : effectiveWindow(window, nowMs);
60858
+ if (window === void 0 || effective?.status === void 0 || !WARNING_STATUSES.has(effective.status)) {
60859
+ return [];
60860
+ }
60861
+ const reset = window.resetsAt === void 0 ? "" : `, resets ${window.resetsAt}`;
60862
+ const verdict = effective.status === "rejected" ? "exhausted" : "nearly used";
60863
+ return [`agent-shim: identity ${snapshot.identity}: the ${name} quota is ${verdict}${reset} (last seen ${age} ago)`];
60864
+ });
60865
+ }
60866
+
60819
60867
  // src/credentialCache.ts
60820
60868
  var MS_PER_UNIT = { s: 1e3, m: 6e4, h: 36e5, d: 864e5 };
60821
60869
  var CachedCredentialSchema = external_exports.strictObject({
@@ -60843,6 +60891,45 @@ function isFresh(entry, cache, now) {
60843
60891
  }
60844
60892
  return limit === void 0 || now - entry.fetchedAt < limit;
60845
60893
  }
60894
+ function cacheAgeMs(entry, now) {
60895
+ return Math.max(0, now - entry.fetchedAt);
60896
+ }
60897
+ function describeCachedCredential(params) {
60898
+ const store = effectiveStore(params.cache, params.platform);
60899
+ let entry;
60900
+ try {
60901
+ entry = params.port.read(store, params.owner);
60902
+ } catch (error62) {
60903
+ return { store, status: "unreadable", reason: error62 instanceof Error ? error62.message : String(error62) };
60904
+ }
60905
+ if (entry === void 0) {
60906
+ return { store, status: "empty" };
60907
+ }
60908
+ const limit = ttlMs(params.cache);
60909
+ const ageMs = cacheAgeMs(entry, params.nowMs);
60910
+ return {
60911
+ store,
60912
+ status: isFresh(entry, params.cache, params.nowMs) ? "fresh" : "expired",
60913
+ ageMs,
60914
+ ...limit === void 0 ? {} : { expiresInMs: limit - ageMs }
60915
+ };
60916
+ }
60917
+ function formatCachedCredentialState(state) {
60918
+ if (state.status === "empty") {
60919
+ return `no cached entry in the ${state.store} store yet`;
60920
+ }
60921
+ if (state.status === "unreadable") {
60922
+ return `the ${state.store} store cannot be read here: ${state.reason}`;
60923
+ }
60924
+ if (state.status === "expired" && (state.expiresInMs === void 0 || state.expiresInMs > 0)) {
60925
+ return "cached with a timestamp in the future, treated as expired";
60926
+ }
60927
+ const age = `cached ${formatAge(state.ageMs)} ago`;
60928
+ if (state.expiresInMs === void 0) {
60929
+ return `${age}, no expiry`;
60930
+ }
60931
+ return state.status === "fresh" ? `${age}, expires in ${formatAge(state.expiresInMs)}` : `${age}, expired ${formatAge(-state.expiresInMs)} ago`;
60932
+ }
60846
60933
 
60847
60934
  // src/credential.ts
60848
60935
  var CREDENTIAL_UNAVAILABLE_EXIT = 64;
@@ -61586,7 +61673,7 @@ function registerIdentityCommand(program2, deps) {
61586
61673
  // package.json
61587
61674
  var package_default = {
61588
61675
  name: "agent-shim",
61589
- version: "8.6.0",
61676
+ version: "8.7.0",
61590
61677
  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.",
61591
61678
  license: "MIT",
61592
61679
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -61682,59 +61769,11 @@ var package_default = {
61682
61769
  };
61683
61770
 
61684
61771
  // src/check.ts
61685
- var import_node_path29 = __toESM(require("node:path"), 1);
61772
+ var import_node_path30 = __toESM(require("node:path"), 1);
61686
61773
 
61687
61774
  // src/checkReport.ts
61688
61775
  var import_node_os5 = __toESM(require("node:os"), 1);
61689
61776
 
61690
- // src/usage/preflight.ts
61691
- var MS_PER_SECOND = 1e3;
61692
- var SECONDS_PER_MINUTE = 60;
61693
- var MINUTES_PER_HOUR = 60;
61694
- var HOURS_PER_DAY = 24;
61695
- var WARNING_STATUSES = /* @__PURE__ */ new Set(["allowed_warning", "rejected"]);
61696
- function formatAge(ms) {
61697
- const minutes = Math.floor(ms / (MS_PER_SECOND * SECONDS_PER_MINUTE));
61698
- if (minutes < MINUTES_PER_HOUR) {
61699
- return `${String(Math.max(minutes, 0))}m`;
61700
- }
61701
- const hours = Math.floor(minutes / MINUTES_PER_HOUR);
61702
- return hours < HOURS_PER_DAY ? `${String(hours)}h` : `${String(Math.floor(hours / HOURS_PER_DAY))}d`;
61703
- }
61704
- function effectiveWindow(window, nowMs) {
61705
- const resetsAtMs = window.resetsAt === void 0 ? void 0 : Date.parse(window.resetsAt);
61706
- if (resetsAtMs !== void 0 && resetsAtMs <= nowMs) {
61707
- return { reset: true, utilization: 0 };
61708
- }
61709
- return {
61710
- reset: false,
61711
- ...window.utilization === void 0 ? {} : { utilization: window.utilization },
61712
- ...resetsAtMs === void 0 ? {} : { resetsAtMs },
61713
- ...window.status === void 0 ? {} : { status: window.status }
61714
- };
61715
- }
61716
- function quotaWarnings(snapshot, provider, nowMs) {
61717
- const rateLimit = snapshot?.providers[provider]?.rateLimit;
61718
- const unified = rateLimit?.unified;
61719
- if (snapshot === void 0 || rateLimit === void 0 || unified === void 0) {
61720
- return [];
61721
- }
61722
- const age = formatAge(nowMs - Date.parse(rateLimit.observedAt));
61723
- const windows = [
61724
- { name: "five-hour", window: unified.fiveHour },
61725
- { name: "seven-day", window: unified.sevenDay }
61726
- ];
61727
- return windows.flatMap(({ name, window }) => {
61728
- const effective = window === void 0 ? void 0 : effectiveWindow(window, nowMs);
61729
- if (window === void 0 || effective?.status === void 0 || !WARNING_STATUSES.has(effective.status)) {
61730
- return [];
61731
- }
61732
- const reset = window.resetsAt === void 0 ? "" : `, resets ${window.resetsAt}`;
61733
- const verdict = effective.status === "rejected" ? "exhausted" : "nearly used";
61734
- return [`agent-shim: identity ${snapshot.identity}: the ${name} quota is ${verdict}${reset} (last seen ${age} ago)`];
61735
- });
61736
- }
61737
-
61738
61777
  // src/usage/poolPick.ts
61739
61778
  var import_node_path26 = __toESM(require("node:path"), 1);
61740
61779
 
@@ -63126,9 +63165,87 @@ function collectPoolPick(params) {
63126
63165
  };
63127
63166
  }
63128
63167
 
63129
- // src/providersStore.ts
63168
+ // src/realCredentialCache.ts
63169
+ var import_node_child_process3 = require("node:child_process");
63130
63170
  var import_node_fs9 = __toESM(require("node:fs"), 1);
63131
63171
  var import_node_path27 = __toESM(require("node:path"), 1);
63172
+ var KEYCHAIN_CACHE_SERVICE = "agent-shim-credential-cache";
63173
+ var CACHE_DIR_MODE = 448;
63174
+ var CACHE_FILE_MODE = 384;
63175
+ function cacheFileNameFor(owner) {
63176
+ return `${owner.replace(/[^A-Za-z0-9._-]/g, "_")}.json`;
63177
+ }
63178
+ function parseEntry(raw) {
63179
+ let json2;
63180
+ try {
63181
+ json2 = JSON.parse(raw);
63182
+ } catch {
63183
+ return void 0;
63184
+ }
63185
+ const parsed = CachedCredentialSchema.safeParse(json2);
63186
+ return parsed.success ? parsed.data : void 0;
63187
+ }
63188
+ function requireKeychain() {
63189
+ if (process.platform !== "darwin") {
63190
+ throw new Error("the keychain credential store needs macOS; use --credential-cache-store file");
63191
+ }
63192
+ }
63193
+ function security(args, stdin2) {
63194
+ const result = (0, import_node_child_process3.spawnSync)("security", args, { encoding: "utf8", ...stdin2 === void 0 ? {} : { input: stdin2 }, stdio: ["pipe", "pipe", "ignore"] });
63195
+ return { status: result.status, stdout: result.stdout };
63196
+ }
63197
+ function createRealCredentialCache(root) {
63198
+ const dir = import_node_path27.default.join(root, "credential-cache");
63199
+ const filePath = (owner) => import_node_path27.default.join(dir, cacheFileNameFor(owner));
63200
+ return {
63201
+ read(store, owner) {
63202
+ if (store === "file") {
63203
+ try {
63204
+ return parseEntry(import_node_fs9.default.readFileSync(filePath(owner), "utf8"));
63205
+ } catch {
63206
+ return void 0;
63207
+ }
63208
+ }
63209
+ requireKeychain();
63210
+ const result = security(["find-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner, "-w"]);
63211
+ return result.status === 0 ? parseEntry(Buffer.from(result.stdout.trim(), "base64").toString("utf8")) : void 0;
63212
+ },
63213
+ write(store, owner, entry) {
63214
+ const serialised = JSON.stringify(entry);
63215
+ if (store === "file") {
63216
+ import_node_fs9.default.mkdirSync(dir, { recursive: true, mode: CACHE_DIR_MODE });
63217
+ import_node_fs9.default.chmodSync(dir, CACHE_DIR_MODE);
63218
+ const target = filePath(owner);
63219
+ const temp = `${target}.${String(process.pid)}.tmp`;
63220
+ import_node_fs9.default.writeFileSync(temp, serialised, { mode: CACHE_FILE_MODE });
63221
+ import_node_fs9.default.renameSync(temp, target);
63222
+ return;
63223
+ }
63224
+ requireKeychain();
63225
+ const encoded = Buffer.from(serialised, "utf8").toString("base64");
63226
+ const result = security(["-i"], `add-generic-password -U -s ${KEYCHAIN_CACHE_SERVICE} -a ${JSON.stringify(owner)} -w ${encoded}
63227
+ `);
63228
+ if (result.status !== 0) {
63229
+ throw new Error(`could not write the keychain credential cache for ${owner}`);
63230
+ }
63231
+ },
63232
+ remove(store, owner) {
63233
+ if (store === "file") {
63234
+ import_node_fs9.default.rmSync(filePath(owner), { force: true });
63235
+ return;
63236
+ }
63237
+ requireKeychain();
63238
+ security(["delete-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner]);
63239
+ }
63240
+ };
63241
+ }
63242
+ function realCredentialCacheEnv(paths) {
63243
+ return { port: createRealCredentialCache(paths.root), platform: process.platform, now: () => Date.now() };
63244
+ }
63245
+
63246
+ // src/providersStore.ts
63247
+ var import_node_fs10 = __toESM(require("node:fs"), 1);
63248
+ var import_node_path28 = __toESM(require("node:path"), 1);
63132
63249
  var ProviderNotFoundError = class extends CliError {
63133
63250
  constructor(name) {
63134
63251
  super(`No provider named "${name}". Run \`agent-shim provider add ${name}\` first.`);
@@ -63157,10 +63274,10 @@ var InvalidProviderNameError = class extends CliError {
63157
63274
  };
63158
63275
  var PROVIDER_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._@-]*$/;
63159
63276
  function providerJsonPath(paths, name) {
63160
- return import_node_path27.default.join(paths.providersDir, `${name}.json`);
63277
+ return import_node_path28.default.join(paths.providersDir, `${name}.json`);
63161
63278
  }
63162
63279
  function providerExists(paths, name) {
63163
- return import_node_fs9.default.existsSync(providerJsonPath(paths, name));
63280
+ return import_node_fs10.default.existsSync(providerJsonPath(paths, name));
63164
63281
  }
63165
63282
  var LEGACY_PROVIDER_FIELDS = ["tokenEnv", "tokenCommand", "authScheme"];
63166
63283
  var LEGACY_ENV_CREDENTIAL_KEYS = Object.values(CREDENTIAL_TARGET_VARS);
@@ -63226,20 +63343,20 @@ function parseProviderFile(filePath, raw) {
63226
63343
  }
63227
63344
  function readProvider(paths, name) {
63228
63345
  const filePath = providerJsonPath(paths, name);
63229
- if (!import_node_fs9.default.existsSync(filePath)) {
63346
+ if (!import_node_fs10.default.existsSync(filePath)) {
63230
63347
  return void 0;
63231
63348
  }
63232
- const raw = JSON.parse(import_node_fs9.default.readFileSync(filePath, "utf8"));
63349
+ const raw = JSON.parse(import_node_fs10.default.readFileSync(filePath, "utf8"));
63233
63350
  return parseProviderFile(filePath, raw);
63234
63351
  }
63235
63352
  function loadProvider(providersDir, name, port) {
63236
- const filePath = import_node_path27.default.join(providersDir, `${name}.json`);
63353
+ const filePath = import_node_path28.default.join(providersDir, `${name}.json`);
63237
63354
  const raw = port.readConfigFile(filePath);
63238
63355
  return raw === void 0 ? void 0 : parseProviderFile(filePath, raw);
63239
63356
  }
63240
63357
  function listProviders(paths) {
63241
63358
  const names = listProviderNames(
63242
- (dir) => import_node_fs9.default.readdirSync(dir),
63359
+ (dir) => import_node_fs10.default.readdirSync(dir),
63243
63360
  paths.providersDir
63244
63361
  );
63245
63362
  const result = [];
@@ -63358,7 +63475,7 @@ function removeProvider(paths, name) {
63358
63475
  if (!providerExists(paths, name)) {
63359
63476
  throw new ProviderNotFoundError(name);
63360
63477
  }
63361
- import_node_fs9.default.rmSync(providerJsonPath(paths, name));
63478
+ import_node_fs10.default.rmSync(providerJsonPath(paths, name));
63362
63479
  }
63363
63480
  function cascadeProviderName(cascade) {
63364
63481
  let name;
@@ -63395,7 +63512,7 @@ function resolveProvider(params) {
63395
63512
  }
63396
63513
 
63397
63514
  // src/checkReport.ts
63398
- var import_node_path28 = __toESM(require("node:path"), 1);
63515
+ var import_node_path29 = __toESM(require("node:path"), 1);
63399
63516
 
63400
63517
  // src/cli/envBool.ts
63401
63518
  var InvalidEnvBoolError = class extends UsageError {
@@ -63597,14 +63714,23 @@ function inspectSettingsExposure(params) {
63597
63714
  }
63598
63715
  return reports;
63599
63716
  }
63600
- function buildCredentialReport(provider, identity) {
63717
+ function cachedState(cacheEnv, owner, block2) {
63718
+ if (cacheEnv === void 0 || block2.cache === void 0) {
63719
+ return void 0;
63720
+ }
63721
+ return describeCachedCredential({ port: cacheEnv.port, platform: cacheEnv.platform, owner, cache: block2.cache, nowMs: cacheEnv.now() });
63722
+ }
63723
+ function buildCredentialReport(provider, identity, identityName, cacheEnv) {
63601
63724
  const identityCredential = identity?.credential === void 0 ? void 0 : summariseCredential(identity.credential);
63725
+ const identityCached = identity?.credential === void 0 || identityName === void 0 ? void 0 : cachedState(cacheEnv, `identity ${identityName}`, identity.credential);
63726
+ const providerCached = provider?.definition === void 0 ? void 0 : cachedState(cacheEnv, `provider ${provider.name}`, provider.definition.credential);
63602
63727
  return {
63603
63728
  applies: provider !== void 0 ? "provider" : identityCredential !== void 0 ? "identity" : "stored-login",
63604
63729
  ...provider === void 0 ? {} : {
63605
- provider: provider.problem === void 0 ? { name: provider.name, credential: summariseCredential(provider.definition.credential) } : { name: provider.name, problem: provider.problem }
63730
+ provider: provider.problem === void 0 ? { name: provider.name, credential: summariseCredential(provider.definition.credential), ...providerCached === void 0 ? {} : { cached: providerCached } } : { name: provider.name, problem: provider.problem }
63606
63731
  },
63607
- ...identityCredential === void 0 ? {} : { identity: identityCredential }
63732
+ ...identityCredential === void 0 ? {} : { identity: identityCredential },
63733
+ ...identityCached === void 0 ? {} : { identityCached }
63608
63734
  };
63609
63735
  }
63610
63736
  function runCheck(params) {
@@ -63643,7 +63769,7 @@ function runCheck(params) {
63643
63769
  ambientCredential,
63644
63770
  ...keychain === void 0 ? {} : { keychain },
63645
63771
  settingsExposure,
63646
- credential: buildCredentialReport(params.provider, params.identity)
63772
+ credential: buildCredentialReport(params.provider, params.identity, params.identityName, params.credentialCache)
63647
63773
  };
63648
63774
  }
63649
63775
  function formatCheckReport(report) {
@@ -63681,12 +63807,12 @@ function formatCheckReport(report) {
63681
63807
  const { credential } = report;
63682
63808
  if (credential.provider !== void 0) {
63683
63809
  lines.push(
63684
- ` Provider ${credential.provider.name}: ${credential.provider.credential === void 0 ? `unusable: ${credential.provider.problem ?? ""}` : formatCredentialSummary(credential.provider.credential)}`
63810
+ ` Provider ${credential.provider.name}: ${credential.provider.credential === void 0 ? `unusable: ${credential.provider.problem ?? ""}` : formatCredentialSummary(credential.provider.credential)}${credential.provider.cached === void 0 ? "" : `; ${formatCachedCredentialState(credential.provider.cached)}`}`
63685
63811
  );
63686
63812
  }
63687
63813
  if (credential.identity !== void 0) {
63688
63814
  lines.push(
63689
- ` Identity ${report.identityName ?? "(none)"}: ${formatCredentialSummary(credential.identity)}${credential.applies === "provider" ? " (not used: the provider's credential applies)" : ""}`
63815
+ ` Identity ${report.identityName ?? "(none)"}: ${formatCredentialSummary(credential.identity)}${credential.identityCached === void 0 ? "" : `; ${formatCachedCredentialState(credential.identityCached)}`}${credential.applies === "provider" ? " (not used: the provider's credential applies)" : ""}`
63690
63816
  );
63691
63817
  }
63692
63818
  if (credential.applies === "stored-login") {
@@ -63795,10 +63921,10 @@ function collectCheckReport(params) {
63795
63921
  }).input;
63796
63922
  const providerName = cascadeProviderName(cascade);
63797
63923
  const provider = providerName === void 0 ? void 0 : loadCheckProvider(paths, providerName);
63798
- const farmRoot = identityDecision.name === void 0 ? void 0 : import_node_path28.default.join(paths.identitiesDir, identityDecision.name);
63924
+ const farmRoot = identityDecision.name === void 0 ? void 0 : import_node_path29.default.join(paths.identitiesDir, identityDecision.name);
63799
63925
  const settingsFiles = {
63800
- "settings.json": realFsPort.readFileUtf8(import_node_path28.default.join(claudeHome, "settings.json")),
63801
- "settings.local.json": realFsPort.readFileUtf8(import_node_path28.default.join(claudeHome, "settings.local.json"))
63926
+ "settings.json": realFsPort.readFileUtf8(import_node_path29.default.join(claudeHome, "settings.json")),
63927
+ "settings.local.json": realFsPort.readFileUtf8(import_node_path29.default.join(claudeHome, "settings.local.json"))
63802
63928
  };
63803
63929
  const report = runCheck({
63804
63930
  cwd,
@@ -63819,6 +63945,7 @@ function collectCheckReport(params) {
63819
63945
  ...loadedIdentity === void 0 ? {} : { identity: loadedIdentity.config },
63820
63946
  settingsFiles,
63821
63947
  run: realRunPort,
63948
+ credentialCache: realCredentialCacheEnv(paths),
63822
63949
  ...farmRoot === void 0 ? {} : { farmRoot },
63823
63950
  platform: process.platform,
63824
63951
  ...provider === void 0 ? {} : { provider }
@@ -63832,7 +63959,7 @@ function registerCheckCommand(program2, deps) {
63832
63959
  const command = program2.command("check [path]").description(
63833
63960
  "Show what a launch in a directory would share or hide and why, plus credential and settings diagnostics. Never touches the farm or spawns claude."
63834
63961
  ).option("--identity <name>", "Identity to check (defaults to the identity a launch there would resolve).").option("--json", "Print the report as JSON.").option("--strict", "Exit 1 when the report carries any warning, not only on errors.").action((pathArg, options) => {
63835
- const cwd = pathArg === void 0 ? process.cwd() : import_node_path29.default.resolve(pathArg);
63962
+ const cwd = pathArg === void 0 ? process.cwd() : import_node_path30.default.resolve(pathArg);
63836
63963
  const report = collectCheckReport({ paths, cwd, ...options.identity === void 0 ? {} : { identity: options.identity }, env: process.env });
63837
63964
  if (options.json === true) {
63838
63965
  printJson(checkReportToJson(report));
@@ -63850,9 +63977,9 @@ function registerCheckCommand(program2, deps) {
63850
63977
 
63851
63978
  // src/codex/commands.ts
63852
63979
  var import_node_crypto7 = require("node:crypto");
63853
- var import_node_fs10 = __toESM(require("node:fs"), 1);
63980
+ var import_node_fs11 = __toESM(require("node:fs"), 1);
63854
63981
  var import_node_os6 = __toESM(require("node:os"), 1);
63855
- var import_node_path30 = __toESM(require("node:path"), 1);
63982
+ var import_node_path31 = __toESM(require("node:path"), 1);
63856
63983
 
63857
63984
  // src/codex/agent.ts
63858
63985
  var import_undici = __toESM(require_undici(), 1);
@@ -64091,10 +64218,10 @@ async function callCodex(ports, request7, sessionId, signal) {
64091
64218
  // src/codex/commands.ts
64092
64219
  function codexHome(env, home) {
64093
64220
  const fromEnv = env.CODEX_HOME;
64094
- return fromEnv !== void 0 && fromEnv !== "" ? fromEnv : import_node_path30.default.join(home, ".codex");
64221
+ return fromEnv !== void 0 && fromEnv !== "" ? fromEnv : import_node_path31.default.join(home, ".codex");
64095
64222
  }
64096
64223
  function codexUsageSnapshotPath() {
64097
- return import_node_path30.default.join(resolveClaudeHome(), "codex-quota.json");
64224
+ return import_node_path31.default.join(resolveClaudeHome(), "codex-quota.json");
64098
64225
  }
64099
64226
  function isEnoent4(error62) {
64100
64227
  return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === "ENOENT";
@@ -64103,7 +64230,7 @@ var PRIVATE_FILE_MODE = 384;
64103
64230
  var realCodexAuthFs = {
64104
64231
  read: (filePath) => {
64105
64232
  try {
64106
- return import_node_fs10.default.readFileSync(filePath, "utf8");
64233
+ return import_node_fs11.default.readFileSync(filePath, "utf8");
64107
64234
  } catch (error62) {
64108
64235
  if (isEnoent4(error62)) {
64109
64236
  return void 0;
@@ -64112,21 +64239,21 @@ var realCodexAuthFs = {
64112
64239
  }
64113
64240
  },
64114
64241
  writePrivate: (filePath, contents) => {
64115
- import_node_fs10.default.writeFileSync(filePath, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
64116
- import_node_fs10.default.chmodSync(filePath, PRIVATE_FILE_MODE);
64242
+ import_node_fs11.default.writeFileSync(filePath, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
64243
+ import_node_fs11.default.chmodSync(filePath, PRIVATE_FILE_MODE);
64117
64244
  },
64118
64245
  rename: (from, to) => {
64119
- import_node_fs10.default.renameSync(from, to);
64246
+ import_node_fs11.default.renameSync(from, to);
64120
64247
  }
64121
64248
  };
64122
64249
  function writeUsageSnapshot(log, snapshot) {
64123
64250
  const target = codexUsageSnapshotPath();
64124
64251
  const temp = `${target}.${String(process.pid)}.tmp`;
64125
64252
  try {
64126
- import_node_fs10.default.mkdirSync(import_node_path30.default.dirname(target), { recursive: true });
64127
- import_node_fs10.default.writeFileSync(temp, `${JSON.stringify(snapshot, null, 2)}
64253
+ import_node_fs11.default.mkdirSync(import_node_path31.default.dirname(target), { recursive: true });
64254
+ import_node_fs11.default.writeFileSync(temp, `${JSON.stringify(snapshot, null, 2)}
64128
64255
  `);
64129
- import_node_fs10.default.renameSync(temp, target);
64256
+ import_node_fs11.default.renameSync(temp, target);
64130
64257
  } catch (error62) {
64131
64258
  log(`usage snapshot write failed: ${error62 instanceof Error ? error62.message : String(error62)}`);
64132
64259
  }
@@ -64134,7 +64261,7 @@ function writeUsageSnapshot(log, snapshot) {
64134
64261
  function createCodexRoutePorts(log) {
64135
64262
  const agent = createUpstreamAgent();
64136
64263
  const upstreamFetch = createUpstreamFetch(agent);
64137
- const auth = createCodexAuthStore(import_node_path30.default.join(codexHome(process.env, import_node_os6.default.homedir()), "auth.json"), {
64264
+ const auth = createCodexAuthStore(import_node_path31.default.join(codexHome(process.env, import_node_os6.default.homedir()), "auth.json"), {
64138
64265
  fs: realCodexAuthFs,
64139
64266
  fetch: upstreamFetch,
64140
64267
  now: () => /* @__PURE__ */ new Date(),
@@ -64209,8 +64336,8 @@ function registerCodexCommand(program2, deps) {
64209
64336
 
64210
64337
  // src/frontdoor/commands.ts
64211
64338
  var import_node_crypto12 = require("node:crypto");
64212
- var import_node_path31 = __toESM(require("node:path"), 1);
64213
- var import_node_fs11 = __toESM(require("node:fs"), 1);
64339
+ var import_node_path32 = __toESM(require("node:path"), 1);
64340
+ var import_node_fs12 = __toESM(require("node:fs"), 1);
64214
64341
 
64215
64342
  // src/frontdoor/custody.ts
64216
64343
  var CREDENTIAL_HEADERS = ["authorization", "x-api-key"];
@@ -64348,8 +64475,8 @@ function isLiveCapability(presented, live) {
64348
64475
  }
64349
64476
 
64350
64477
  // src/frontdoor/capture.ts
64351
- var fs11 = __toESM(require("node:fs"), 1);
64352
- var path31 = __toESM(require("node:path"), 1);
64478
+ var fs12 = __toESM(require("node:fs"), 1);
64479
+ var path32 = __toESM(require("node:path"), 1);
64353
64480
  var SECRET_HEADER_NAME = /authorization|cookie|token|secret|credential|api[-_]key/i;
64354
64481
  var SECRET_JSON_KEY = /token|secret|password|credential|authorization|api[-_]key/i;
64355
64482
  var SECRET_BODY_PATTERNS = [
@@ -64393,13 +64520,13 @@ function redactBody(chunk) {
64393
64520
  }
64394
64521
  var CAPTURE_ENV = "AGENT_SHIM_FRONTDOOR_CAPTURE";
64395
64522
  function captureFromEnv(env, logsDir) {
64396
- return env[CAPTURE_ENV] === "1" ? createFileCapture(path31.join(logsDir, "frontdoor-capture.jsonl")) : void 0;
64523
+ return env[CAPTURE_ENV] === "1" ? createFileCapture(path32.join(logsDir, "frontdoor-capture.jsonl")) : void 0;
64397
64524
  }
64398
64525
  function createFileCapture(file2, now = () => /* @__PURE__ */ new Date()) {
64399
- fs11.mkdirSync(path31.dirname(file2), { recursive: true });
64526
+ fs12.mkdirSync(path32.dirname(file2), { recursive: true });
64400
64527
  let nextId = 0;
64401
64528
  const append = (record2) => {
64402
- fs11.appendFileSync(file2, `${JSON.stringify({ ts: now().toISOString(), ...record2 })}
64529
+ fs12.appendFileSync(file2, `${JSON.stringify({ ts: now().toISOString(), ...record2 })}
64403
64530
  `, { mode: CAPTURE_FILE_MODE });
64404
64531
  };
64405
64532
  return {
@@ -64486,7 +64613,7 @@ function createFileCapture(file2, now = () => /* @__PURE__ */ new Date()) {
64486
64613
 
64487
64614
  // src/frontdoor/connect.ts
64488
64615
  var import_node_crypto10 = require("node:crypto");
64489
- var fs12 = __toESM(require("node:fs"), 1);
64616
+ var fs13 = __toESM(require("node:fs"), 1);
64490
64617
 
64491
64618
  // src/frontdoor/x509.ts
64492
64619
  var import_node_crypto9 = require("node:crypto");
@@ -65258,7 +65385,7 @@ function isEnoent5(error62) {
65258
65385
  function realConnectCertStore(paths) {
65259
65386
  const read = (file2) => {
65260
65387
  try {
65261
- return fs12.readFileSync(file2, "utf8");
65388
+ return fs13.readFileSync(file2, "utf8");
65262
65389
  } catch (error62) {
65263
65390
  if (isEnoent5(error62)) {
65264
65391
  return void 0;
@@ -65273,10 +65400,10 @@ function realConnectCertStore(paths) {
65273
65400
  return certPem === void 0 || keyPem2 === void 0 ? void 0 : { certPem, keyPem: keyPem2 };
65274
65401
  },
65275
65402
  writeCa: (ca) => {
65276
- fs12.mkdirSync(paths.frontdoorCaDir, { recursive: true });
65277
- fs12.writeFileSync(paths.frontdoorCaCertFile, ca.certPem, "utf8");
65278
- fs12.writeFileSync(paths.frontdoorCaKeyFile, ca.keyPem, { encoding: "utf8", mode: CA_KEY_FILE_MODE });
65279
- fs12.chmodSync(paths.frontdoorCaKeyFile, CA_KEY_FILE_MODE);
65403
+ fs13.mkdirSync(paths.frontdoorCaDir, { recursive: true });
65404
+ fs13.writeFileSync(paths.frontdoorCaCertFile, ca.certPem, "utf8");
65405
+ fs13.writeFileSync(paths.frontdoorCaKeyFile, ca.keyPem, { encoding: "utf8", mode: CA_KEY_FILE_MODE });
65406
+ fs13.chmodSync(paths.frontdoorCaKeyFile, CA_KEY_FILE_MODE);
65280
65407
  }
65281
65408
  };
65282
65409
  }
@@ -68222,8 +68349,8 @@ function createRealQuotaRefresher(params) {
68222
68349
 
68223
68350
  // src/frontdoor/commands.ts
68224
68351
  function appendLog(paths, line) {
68225
- import_node_fs11.default.mkdirSync(paths.logsDir, { recursive: true });
68226
- import_node_fs11.default.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
68352
+ import_node_fs12.default.mkdirSync(paths.logsDir, { recursive: true });
68353
+ import_node_fs12.default.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
68227
68354
  `);
68228
68355
  }
68229
68356
  function headroomSocketTarget(fsPort, trust, paths) {
@@ -68332,7 +68459,7 @@ function realFrontDoorSupervisorPorts(paths) {
68332
68459
  const leafFor = createLeafCache(loadCa(), () => /* @__PURE__ */ new Date());
68333
68460
  const capture = captureFromEnv(process.env, paths.logsDir);
68334
68461
  if (capture !== void 0) {
68335
- log(`capture enabled, recording CONNECT targets and piped exchanges to ${import_node_path31.default.join(paths.logsDir, "frontdoor-capture.jsonl")}`);
68462
+ log(`capture enabled, recording CONNECT targets and piped exchanges to ${import_node_path32.default.join(paths.logsDir, "frontdoor-capture.jsonl")}`);
68336
68463
  }
68337
68464
  const server = await startConnectServer(
68338
68465
  {
@@ -68921,16 +69048,16 @@ function registerCompletionCommand(program2) {
68921
69048
  var import_node_child_process4 = require("node:child_process");
68922
69049
 
68923
69050
  // src/identityToken.ts
68924
- var import_node_fs12 = __toESM(require("node:fs"), 1);
68925
- var import_node_path32 = __toESM(require("node:path"), 1);
69051
+ var import_node_fs13 = __toESM(require("node:fs"), 1);
69052
+ var import_node_path33 = __toESM(require("node:path"), 1);
68926
69053
  var TOKEN_FILE_MODE = 384;
68927
69054
  var TOKEN_DIR_MODE = 448;
68928
69055
  var OAUTH_TOKEN_RE = /^sk-ant-oat\d+-[A-Za-z0-9_-]+$/;
68929
69056
  function identityTokenDir(paths) {
68930
- return import_node_path32.default.join(paths.root, "credentials");
69057
+ return import_node_path33.default.join(paths.root, "credentials");
68931
69058
  }
68932
69059
  function identityTokenPath(paths, identityName) {
68933
- return import_node_path32.default.join(identityTokenDir(paths), `${identityName}.token`);
69060
+ return import_node_path33.default.join(identityTokenDir(paths), `${identityName}.token`);
68934
69061
  }
68935
69062
  function storeIdentityToken(paths, identityName, raw) {
68936
69063
  const token = raw.trim();
@@ -68938,94 +69065,16 @@ function storeIdentityToken(paths, identityName, raw) {
68938
69065
  throw new UsageError("That is not a claude setup-token token (expected it to start with sk-ant-oat). Run `claude setup-token` and pass its token on standard input.");
68939
69066
  }
68940
69067
  const dir = identityTokenDir(paths);
68941
- import_node_fs12.default.mkdirSync(dir, { recursive: true, mode: TOKEN_DIR_MODE });
68942
- import_node_fs12.default.chmodSync(dir, TOKEN_DIR_MODE);
69068
+ import_node_fs13.default.mkdirSync(dir, { recursive: true, mode: TOKEN_DIR_MODE });
69069
+ import_node_fs13.default.chmodSync(dir, TOKEN_DIR_MODE);
68943
69070
  const target = identityTokenPath(paths, identityName);
68944
- const temp = import_node_path32.default.join(dir, `.${identityName}.${String(process.pid)}.tmp`);
68945
- import_node_fs12.default.writeFileSync(temp, `${token}
69071
+ const temp = import_node_path33.default.join(dir, `.${identityName}.${String(process.pid)}.tmp`);
69072
+ import_node_fs13.default.writeFileSync(temp, `${token}
68946
69073
  `, { mode: TOKEN_FILE_MODE });
68947
- import_node_fs12.default.renameSync(temp, target);
69074
+ import_node_fs13.default.renameSync(temp, target);
68948
69075
  return target;
68949
69076
  }
68950
69077
 
68951
- // src/realCredentialCache.ts
68952
- var import_node_child_process3 = require("node:child_process");
68953
- var import_node_fs13 = __toESM(require("node:fs"), 1);
68954
- var import_node_path33 = __toESM(require("node:path"), 1);
68955
- var KEYCHAIN_CACHE_SERVICE = "agent-shim-credential-cache";
68956
- var CACHE_DIR_MODE = 448;
68957
- var CACHE_FILE_MODE = 384;
68958
- function cacheFileNameFor(owner) {
68959
- return `${owner.replace(/[^A-Za-z0-9._-]/g, "_")}.json`;
68960
- }
68961
- function parseEntry(raw) {
68962
- let json2;
68963
- try {
68964
- json2 = JSON.parse(raw);
68965
- } catch {
68966
- return void 0;
68967
- }
68968
- const parsed = CachedCredentialSchema.safeParse(json2);
68969
- return parsed.success ? parsed.data : void 0;
68970
- }
68971
- function requireKeychain() {
68972
- if (process.platform !== "darwin") {
68973
- throw new Error("the keychain credential store needs macOS; use --credential-cache-store file");
68974
- }
68975
- }
68976
- function security(args, stdin2) {
68977
- const result = (0, import_node_child_process3.spawnSync)("security", args, { encoding: "utf8", ...stdin2 === void 0 ? {} : { input: stdin2 }, stdio: ["pipe", "pipe", "ignore"] });
68978
- return { status: result.status, stdout: result.stdout };
68979
- }
68980
- function createRealCredentialCache(root) {
68981
- const dir = import_node_path33.default.join(root, "credential-cache");
68982
- const filePath = (owner) => import_node_path33.default.join(dir, cacheFileNameFor(owner));
68983
- return {
68984
- read(store, owner) {
68985
- if (store === "file") {
68986
- try {
68987
- return parseEntry(import_node_fs13.default.readFileSync(filePath(owner), "utf8"));
68988
- } catch {
68989
- return void 0;
68990
- }
68991
- }
68992
- requireKeychain();
68993
- const result = security(["find-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner, "-w"]);
68994
- return result.status === 0 ? parseEntry(Buffer.from(result.stdout.trim(), "base64").toString("utf8")) : void 0;
68995
- },
68996
- write(store, owner, entry) {
68997
- const serialised = JSON.stringify(entry);
68998
- if (store === "file") {
68999
- import_node_fs13.default.mkdirSync(dir, { recursive: true, mode: CACHE_DIR_MODE });
69000
- import_node_fs13.default.chmodSync(dir, CACHE_DIR_MODE);
69001
- const target = filePath(owner);
69002
- const temp = `${target}.${String(process.pid)}.tmp`;
69003
- import_node_fs13.default.writeFileSync(temp, serialised, { mode: CACHE_FILE_MODE });
69004
- import_node_fs13.default.renameSync(temp, target);
69005
- return;
69006
- }
69007
- requireKeychain();
69008
- const encoded = Buffer.from(serialised, "utf8").toString("base64");
69009
- const result = security(["-i"], `add-generic-password -U -s ${KEYCHAIN_CACHE_SERVICE} -a ${JSON.stringify(owner)} -w ${encoded}
69010
- `);
69011
- if (result.status !== 0) {
69012
- throw new Error(`could not write the keychain credential cache for ${owner}`);
69013
- }
69014
- },
69015
- remove(store, owner) {
69016
- if (store === "file") {
69017
- import_node_fs13.default.rmSync(filePath(owner), { force: true });
69018
- return;
69019
- }
69020
- requireKeychain();
69021
- security(["delete-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner]);
69022
- }
69023
- };
69024
- }
69025
- function realCredentialCacheEnv(paths) {
69026
- return { port: createRealCredentialCache(paths.root), platform: process.platform, now: () => Date.now() };
69027
- }
69028
-
69029
69078
  // src/credentialCommand.ts
69030
69079
  async function readStandardInput() {
69031
69080
  const chunks = [];
@@ -69224,7 +69273,14 @@ function pushPathResolution(push, resolution) {
69224
69273
  break;
69225
69274
  }
69226
69275
  }
69227
- function pushProvider(push, entry) {
69276
+ function cacheClause(cacheEnv, owner, block2) {
69277
+ if (cacheEnv === void 0 || block2.cache === void 0) {
69278
+ return { text: "", unreadable: false };
69279
+ }
69280
+ const state = describeCachedCredential({ port: cacheEnv.port, platform: cacheEnv.platform, owner, cache: block2.cache, nowMs: cacheEnv.now() });
69281
+ return { text: `; ${formatCachedCredentialState(state)}`, unreadable: state.status === "unreadable" };
69282
+ }
69283
+ function pushProvider(push, entry, cacheEnv) {
69228
69284
  if (entry.raw === void 0) {
69229
69285
  push("provider", "fail", `${entry.path} is missing.`, entry.name);
69230
69286
  return;
@@ -69246,7 +69302,8 @@ function pushProvider(push, entry) {
69246
69302
  push("provider", "fail", new ConfigValidationError(entry.path, validated.error.issues).message, entry.name);
69247
69303
  return;
69248
69304
  }
69249
- push("provider", "pass", `${entry.name} is valid (${describeProviderEndpoint(validated.data)}, credential ${describeCredential(validated.data.credential)}).`, entry.name);
69305
+ const cache = cacheClause(cacheEnv, `provider ${entry.name}`, validated.data.credential);
69306
+ push("provider", cache.unreadable ? "fail" : "pass", `${entry.name} is valid (${describeProviderEndpoint(validated.data)}, credential ${describeCredential(validated.data.credential)})${cache.text}.`, entry.name);
69250
69307
  }
69251
69308
  function pushLegacyName(push, params) {
69252
69309
  const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
@@ -69339,10 +69396,11 @@ function runDoctor(params) {
69339
69396
  );
69340
69397
  } else {
69341
69398
  const credential = validated.data.credential;
69399
+ const cache = credential === void 0 ? { text: "", unreadable: false } : cacheClause(params.credentialCache, `identity ${entry.name}`, credential);
69342
69400
  push(
69343
69401
  "identity",
69344
- "pass",
69345
- `${entry.name} is valid and authenticates with ${credential === void 0 ? "its stored login" : `credential ${describeCredential(credential)}`}.`,
69402
+ cache.unreadable ? "fail" : "pass",
69403
+ `${entry.name} is valid and authenticates with ${credential === void 0 ? "its stored login" : `credential ${describeCredential(credential)}`}${cache.text}.`,
69346
69404
  entry.name
69347
69405
  );
69348
69406
  }
@@ -69362,7 +69420,7 @@ function runDoctor(params) {
69362
69420
  return poolName === void 0 ? validIdentityNames.has(selector) : poolName in pools;
69363
69421
  };
69364
69422
  for (const entry of params.providers) {
69365
- pushProvider(push, entry);
69423
+ pushProvider(push, entry, params.credentialCache);
69366
69424
  }
69367
69425
  if (params.platform !== "darwin" || params.run === void 0) {
69368
69426
  push("keychain", "pass", "Skipped (not macOS).");
@@ -69601,6 +69659,7 @@ function collectDoctorReport(params) {
69601
69659
  );
69602
69660
  const report = runDoctor({
69603
69661
  env: params.env,
69662
+ credentialCache: realCredentialCacheEnv(paths),
69604
69663
  identities,
69605
69664
  configProfiles,
69606
69665
  providers,