agent-shim 8.6.0 → 8.8.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.8.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
 
@@ -61964,6 +62003,21 @@ function createAccountReader(fs19, identitiesDir) {
61964
62003
  }
61965
62004
 
61966
62005
  // src/usage/plan.ts
62006
+ var PlanClassSchema = external_exports.union([
62007
+ external_exports.strictObject({
62008
+ kind: external_exports.literal("subscription"),
62009
+ /** The plan's size as a multiple of the smallest subscription tier (Max 5x is 5, Max 20x is 20). */
62010
+ capacity: external_exports.number().positive(),
62011
+ /** False when the tier string named no multiplier and no tier this project knows, so `capacity` is the neutral 1 rather than a reading. */
62012
+ recognised: external_exports.boolean(),
62013
+ /** The tier string the classification rests on, when the account had one. */
62014
+ tier: external_exports.string().optional()
62015
+ }),
62016
+ external_exports.strictObject({
62017
+ kind: external_exports.literal("pay-per-use"),
62018
+ tier: external_exports.string().optional()
62019
+ })
62020
+ ]);
61967
62021
  var TIER_MULTIPLIER = /(?:^|_)(\d+)x$/;
61968
62022
  var ZERO_TIER = /(?:^|_)zero$/;
61969
62023
  var BASE_TIER = /(?:^|_)(?:pro|free)$/;
@@ -63101,7 +63155,7 @@ function candidateView(candidate) {
63101
63155
  feasible: candidate.feasible,
63102
63156
  ...candidate.blockedUntilMs === void 0 ? {} : { blockedUntil: new Date(candidate.blockedUntilMs).toISOString() },
63103
63157
  plan: candidate.plan,
63104
- reasons: candidate.reasons
63158
+ reasons: [...candidate.reasons]
63105
63159
  };
63106
63160
  }
63107
63161
  function collectPoolPick(params) {
@@ -63120,15 +63174,93 @@ function collectPoolPick(params) {
63120
63174
  directory: params.directory,
63121
63175
  ...ranking.pick === void 0 ? {} : { pick: ranking.pick.identity },
63122
63176
  candidates: ranking.candidates.map(candidateView),
63123
- missing,
63177
+ missing: [...missing],
63124
63178
  ...ranking.earliestReturn === void 0 ? {} : { earliestReturn: { identity: ranking.earliestReturn.identity, at: new Date(ranking.earliestReturn.atMs).toISOString() } },
63125
63179
  ...sticky.problem === void 0 ? {} : { stickyProblem: sticky.problem }
63126
63180
  };
63127
63181
  }
63128
63182
 
63129
- // src/providersStore.ts
63183
+ // src/realCredentialCache.ts
63184
+ var import_node_child_process3 = require("node:child_process");
63130
63185
  var import_node_fs9 = __toESM(require("node:fs"), 1);
63131
63186
  var import_node_path27 = __toESM(require("node:path"), 1);
63187
+ var KEYCHAIN_CACHE_SERVICE = "agent-shim-credential-cache";
63188
+ var CACHE_DIR_MODE = 448;
63189
+ var CACHE_FILE_MODE = 384;
63190
+ function cacheFileNameFor(owner) {
63191
+ return `${owner.replace(/[^A-Za-z0-9._-]/g, "_")}.json`;
63192
+ }
63193
+ function parseEntry(raw) {
63194
+ let json2;
63195
+ try {
63196
+ json2 = JSON.parse(raw);
63197
+ } catch {
63198
+ return void 0;
63199
+ }
63200
+ const parsed = CachedCredentialSchema.safeParse(json2);
63201
+ return parsed.success ? parsed.data : void 0;
63202
+ }
63203
+ function requireKeychain() {
63204
+ if (process.platform !== "darwin") {
63205
+ throw new Error("the keychain credential store needs macOS; use --credential-cache-store file");
63206
+ }
63207
+ }
63208
+ function security(args, stdin2) {
63209
+ const result = (0, import_node_child_process3.spawnSync)("security", args, { encoding: "utf8", ...stdin2 === void 0 ? {} : { input: stdin2 }, stdio: ["pipe", "pipe", "ignore"] });
63210
+ return { status: result.status, stdout: result.stdout };
63211
+ }
63212
+ function createRealCredentialCache(root) {
63213
+ const dir = import_node_path27.default.join(root, "credential-cache");
63214
+ const filePath = (owner) => import_node_path27.default.join(dir, cacheFileNameFor(owner));
63215
+ return {
63216
+ read(store, owner) {
63217
+ if (store === "file") {
63218
+ try {
63219
+ return parseEntry(import_node_fs9.default.readFileSync(filePath(owner), "utf8"));
63220
+ } catch {
63221
+ return void 0;
63222
+ }
63223
+ }
63224
+ requireKeychain();
63225
+ const result = security(["find-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner, "-w"]);
63226
+ return result.status === 0 ? parseEntry(Buffer.from(result.stdout.trim(), "base64").toString("utf8")) : void 0;
63227
+ },
63228
+ write(store, owner, entry) {
63229
+ const serialised = JSON.stringify(entry);
63230
+ if (store === "file") {
63231
+ import_node_fs9.default.mkdirSync(dir, { recursive: true, mode: CACHE_DIR_MODE });
63232
+ import_node_fs9.default.chmodSync(dir, CACHE_DIR_MODE);
63233
+ const target = filePath(owner);
63234
+ const temp = `${target}.${String(process.pid)}.tmp`;
63235
+ import_node_fs9.default.writeFileSync(temp, serialised, { mode: CACHE_FILE_MODE });
63236
+ import_node_fs9.default.renameSync(temp, target);
63237
+ return;
63238
+ }
63239
+ requireKeychain();
63240
+ const encoded = Buffer.from(serialised, "utf8").toString("base64");
63241
+ const result = security(["-i"], `add-generic-password -U -s ${KEYCHAIN_CACHE_SERVICE} -a ${JSON.stringify(owner)} -w ${encoded}
63242
+ `);
63243
+ if (result.status !== 0) {
63244
+ throw new Error(`could not write the keychain credential cache for ${owner}`);
63245
+ }
63246
+ },
63247
+ remove(store, owner) {
63248
+ if (store === "file") {
63249
+ import_node_fs9.default.rmSync(filePath(owner), { force: true });
63250
+ return;
63251
+ }
63252
+ requireKeychain();
63253
+ security(["delete-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner]);
63254
+ }
63255
+ };
63256
+ }
63257
+ function realCredentialCacheEnv(paths) {
63258
+ return { port: createRealCredentialCache(paths.root), platform: process.platform, now: () => Date.now() };
63259
+ }
63260
+
63261
+ // src/providersStore.ts
63262
+ var import_node_fs10 = __toESM(require("node:fs"), 1);
63263
+ var import_node_path28 = __toESM(require("node:path"), 1);
63132
63264
  var ProviderNotFoundError = class extends CliError {
63133
63265
  constructor(name) {
63134
63266
  super(`No provider named "${name}". Run \`agent-shim provider add ${name}\` first.`);
@@ -63157,10 +63289,10 @@ var InvalidProviderNameError = class extends CliError {
63157
63289
  };
63158
63290
  var PROVIDER_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._@-]*$/;
63159
63291
  function providerJsonPath(paths, name) {
63160
- return import_node_path27.default.join(paths.providersDir, `${name}.json`);
63292
+ return import_node_path28.default.join(paths.providersDir, `${name}.json`);
63161
63293
  }
63162
63294
  function providerExists(paths, name) {
63163
- return import_node_fs9.default.existsSync(providerJsonPath(paths, name));
63295
+ return import_node_fs10.default.existsSync(providerJsonPath(paths, name));
63164
63296
  }
63165
63297
  var LEGACY_PROVIDER_FIELDS = ["tokenEnv", "tokenCommand", "authScheme"];
63166
63298
  var LEGACY_ENV_CREDENTIAL_KEYS = Object.values(CREDENTIAL_TARGET_VARS);
@@ -63226,20 +63358,20 @@ function parseProviderFile(filePath, raw) {
63226
63358
  }
63227
63359
  function readProvider(paths, name) {
63228
63360
  const filePath = providerJsonPath(paths, name);
63229
- if (!import_node_fs9.default.existsSync(filePath)) {
63361
+ if (!import_node_fs10.default.existsSync(filePath)) {
63230
63362
  return void 0;
63231
63363
  }
63232
- const raw = JSON.parse(import_node_fs9.default.readFileSync(filePath, "utf8"));
63364
+ const raw = JSON.parse(import_node_fs10.default.readFileSync(filePath, "utf8"));
63233
63365
  return parseProviderFile(filePath, raw);
63234
63366
  }
63235
63367
  function loadProvider(providersDir, name, port) {
63236
- const filePath = import_node_path27.default.join(providersDir, `${name}.json`);
63368
+ const filePath = import_node_path28.default.join(providersDir, `${name}.json`);
63237
63369
  const raw = port.readConfigFile(filePath);
63238
63370
  return raw === void 0 ? void 0 : parseProviderFile(filePath, raw);
63239
63371
  }
63240
63372
  function listProviders(paths) {
63241
63373
  const names = listProviderNames(
63242
- (dir) => import_node_fs9.default.readdirSync(dir),
63374
+ (dir) => import_node_fs10.default.readdirSync(dir),
63243
63375
  paths.providersDir
63244
63376
  );
63245
63377
  const result = [];
@@ -63358,7 +63490,7 @@ function removeProvider(paths, name) {
63358
63490
  if (!providerExists(paths, name)) {
63359
63491
  throw new ProviderNotFoundError(name);
63360
63492
  }
63361
- import_node_fs9.default.rmSync(providerJsonPath(paths, name));
63493
+ import_node_fs10.default.rmSync(providerJsonPath(paths, name));
63362
63494
  }
63363
63495
  function cascadeProviderName(cascade) {
63364
63496
  let name;
@@ -63395,7 +63527,7 @@ function resolveProvider(params) {
63395
63527
  }
63396
63528
 
63397
63529
  // src/checkReport.ts
63398
- var import_node_path28 = __toESM(require("node:path"), 1);
63530
+ var import_node_path29 = __toESM(require("node:path"), 1);
63399
63531
 
63400
63532
  // src/cli/envBool.ts
63401
63533
  var InvalidEnvBoolError = class extends UsageError {
@@ -63597,14 +63729,23 @@ function inspectSettingsExposure(params) {
63597
63729
  }
63598
63730
  return reports;
63599
63731
  }
63600
- function buildCredentialReport(provider, identity) {
63732
+ function cachedState(cacheEnv, owner, block2) {
63733
+ if (cacheEnv === void 0 || block2.cache === void 0) {
63734
+ return void 0;
63735
+ }
63736
+ return describeCachedCredential({ port: cacheEnv.port, platform: cacheEnv.platform, owner, cache: block2.cache, nowMs: cacheEnv.now() });
63737
+ }
63738
+ function buildCredentialReport(provider, identity, identityName, cacheEnv) {
63601
63739
  const identityCredential = identity?.credential === void 0 ? void 0 : summariseCredential(identity.credential);
63740
+ const identityCached = identity?.credential === void 0 || identityName === void 0 ? void 0 : cachedState(cacheEnv, `identity ${identityName}`, identity.credential);
63741
+ const providerCached = provider?.definition === void 0 ? void 0 : cachedState(cacheEnv, `provider ${provider.name}`, provider.definition.credential);
63602
63742
  return {
63603
63743
  applies: provider !== void 0 ? "provider" : identityCredential !== void 0 ? "identity" : "stored-login",
63604
63744
  ...provider === void 0 ? {} : {
63605
- provider: provider.problem === void 0 ? { name: provider.name, credential: summariseCredential(provider.definition.credential) } : { name: provider.name, problem: provider.problem }
63745
+ 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
63746
  },
63607
- ...identityCredential === void 0 ? {} : { identity: identityCredential }
63747
+ ...identityCredential === void 0 ? {} : { identity: identityCredential },
63748
+ ...identityCached === void 0 ? {} : { identityCached }
63608
63749
  };
63609
63750
  }
63610
63751
  function runCheck(params) {
@@ -63643,7 +63784,7 @@ function runCheck(params) {
63643
63784
  ambientCredential,
63644
63785
  ...keychain === void 0 ? {} : { keychain },
63645
63786
  settingsExposure,
63646
- credential: buildCredentialReport(params.provider, params.identity)
63787
+ credential: buildCredentialReport(params.provider, params.identity, params.identityName, params.credentialCache)
63647
63788
  };
63648
63789
  }
63649
63790
  function formatCheckReport(report) {
@@ -63681,12 +63822,12 @@ function formatCheckReport(report) {
63681
63822
  const { credential } = report;
63682
63823
  if (credential.provider !== void 0) {
63683
63824
  lines.push(
63684
- ` Provider ${credential.provider.name}: ${credential.provider.credential === void 0 ? `unusable: ${credential.provider.problem ?? ""}` : formatCredentialSummary(credential.provider.credential)}`
63825
+ ` 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
63826
  );
63686
63827
  }
63687
63828
  if (credential.identity !== void 0) {
63688
63829
  lines.push(
63689
- ` Identity ${report.identityName ?? "(none)"}: ${formatCredentialSummary(credential.identity)}${credential.applies === "provider" ? " (not used: the provider's credential applies)" : ""}`
63830
+ ` 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
63831
  );
63691
63832
  }
63692
63833
  if (credential.applies === "stored-login") {
@@ -63795,10 +63936,10 @@ function collectCheckReport(params) {
63795
63936
  }).input;
63796
63937
  const providerName = cascadeProviderName(cascade);
63797
63938
  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);
63939
+ const farmRoot = identityDecision.name === void 0 ? void 0 : import_node_path29.default.join(paths.identitiesDir, identityDecision.name);
63799
63940
  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"))
63941
+ "settings.json": realFsPort.readFileUtf8(import_node_path29.default.join(claudeHome, "settings.json")),
63942
+ "settings.local.json": realFsPort.readFileUtf8(import_node_path29.default.join(claudeHome, "settings.local.json"))
63802
63943
  };
63803
63944
  const report = runCheck({
63804
63945
  cwd,
@@ -63819,6 +63960,7 @@ function collectCheckReport(params) {
63819
63960
  ...loadedIdentity === void 0 ? {} : { identity: loadedIdentity.config },
63820
63961
  settingsFiles,
63821
63962
  run: realRunPort,
63963
+ credentialCache: realCredentialCacheEnv(paths),
63822
63964
  ...farmRoot === void 0 ? {} : { farmRoot },
63823
63965
  platform: process.platform,
63824
63966
  ...provider === void 0 ? {} : { provider }
@@ -63832,7 +63974,7 @@ function registerCheckCommand(program2, deps) {
63832
63974
  const command = program2.command("check [path]").description(
63833
63975
  "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
63976
  ).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);
63977
+ const cwd = pathArg === void 0 ? process.cwd() : import_node_path30.default.resolve(pathArg);
63836
63978
  const report = collectCheckReport({ paths, cwd, ...options.identity === void 0 ? {} : { identity: options.identity }, env: process.env });
63837
63979
  if (options.json === true) {
63838
63980
  printJson(checkReportToJson(report));
@@ -63850,9 +63992,9 @@ function registerCheckCommand(program2, deps) {
63850
63992
 
63851
63993
  // src/codex/commands.ts
63852
63994
  var import_node_crypto7 = require("node:crypto");
63853
- var import_node_fs10 = __toESM(require("node:fs"), 1);
63995
+ var import_node_fs11 = __toESM(require("node:fs"), 1);
63854
63996
  var import_node_os6 = __toESM(require("node:os"), 1);
63855
- var import_node_path30 = __toESM(require("node:path"), 1);
63997
+ var import_node_path31 = __toESM(require("node:path"), 1);
63856
63998
 
63857
63999
  // src/codex/agent.ts
63858
64000
  var import_undici = __toESM(require_undici(), 1);
@@ -64091,10 +64233,10 @@ async function callCodex(ports, request7, sessionId, signal) {
64091
64233
  // src/codex/commands.ts
64092
64234
  function codexHome(env, home) {
64093
64235
  const fromEnv = env.CODEX_HOME;
64094
- return fromEnv !== void 0 && fromEnv !== "" ? fromEnv : import_node_path30.default.join(home, ".codex");
64236
+ return fromEnv !== void 0 && fromEnv !== "" ? fromEnv : import_node_path31.default.join(home, ".codex");
64095
64237
  }
64096
64238
  function codexUsageSnapshotPath() {
64097
- return import_node_path30.default.join(resolveClaudeHome(), "codex-quota.json");
64239
+ return import_node_path31.default.join(resolveClaudeHome(), "codex-quota.json");
64098
64240
  }
64099
64241
  function isEnoent4(error62) {
64100
64242
  return typeof error62 === "object" && error62 !== null && "code" in error62 && error62.code === "ENOENT";
@@ -64103,7 +64245,7 @@ var PRIVATE_FILE_MODE = 384;
64103
64245
  var realCodexAuthFs = {
64104
64246
  read: (filePath) => {
64105
64247
  try {
64106
- return import_node_fs10.default.readFileSync(filePath, "utf8");
64248
+ return import_node_fs11.default.readFileSync(filePath, "utf8");
64107
64249
  } catch (error62) {
64108
64250
  if (isEnoent4(error62)) {
64109
64251
  return void 0;
@@ -64112,21 +64254,21 @@ var realCodexAuthFs = {
64112
64254
  }
64113
64255
  },
64114
64256
  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);
64257
+ import_node_fs11.default.writeFileSync(filePath, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
64258
+ import_node_fs11.default.chmodSync(filePath, PRIVATE_FILE_MODE);
64117
64259
  },
64118
64260
  rename: (from, to) => {
64119
- import_node_fs10.default.renameSync(from, to);
64261
+ import_node_fs11.default.renameSync(from, to);
64120
64262
  }
64121
64263
  };
64122
64264
  function writeUsageSnapshot(log, snapshot) {
64123
64265
  const target = codexUsageSnapshotPath();
64124
64266
  const temp = `${target}.${String(process.pid)}.tmp`;
64125
64267
  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)}
64268
+ import_node_fs11.default.mkdirSync(import_node_path31.default.dirname(target), { recursive: true });
64269
+ import_node_fs11.default.writeFileSync(temp, `${JSON.stringify(snapshot, null, 2)}
64128
64270
  `);
64129
- import_node_fs10.default.renameSync(temp, target);
64271
+ import_node_fs11.default.renameSync(temp, target);
64130
64272
  } catch (error62) {
64131
64273
  log(`usage snapshot write failed: ${error62 instanceof Error ? error62.message : String(error62)}`);
64132
64274
  }
@@ -64134,7 +64276,7 @@ function writeUsageSnapshot(log, snapshot) {
64134
64276
  function createCodexRoutePorts(log) {
64135
64277
  const agent = createUpstreamAgent();
64136
64278
  const upstreamFetch = createUpstreamFetch(agent);
64137
- const auth = createCodexAuthStore(import_node_path30.default.join(codexHome(process.env, import_node_os6.default.homedir()), "auth.json"), {
64279
+ const auth = createCodexAuthStore(import_node_path31.default.join(codexHome(process.env, import_node_os6.default.homedir()), "auth.json"), {
64138
64280
  fs: realCodexAuthFs,
64139
64281
  fetch: upstreamFetch,
64140
64282
  now: () => /* @__PURE__ */ new Date(),
@@ -64209,8 +64351,8 @@ function registerCodexCommand(program2, deps) {
64209
64351
 
64210
64352
  // src/frontdoor/commands.ts
64211
64353
  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);
64354
+ var import_node_path32 = __toESM(require("node:path"), 1);
64355
+ var import_node_fs12 = __toESM(require("node:fs"), 1);
64214
64356
 
64215
64357
  // src/frontdoor/custody.ts
64216
64358
  var CREDENTIAL_HEADERS = ["authorization", "x-api-key"];
@@ -64348,8 +64490,8 @@ function isLiveCapability(presented, live) {
64348
64490
  }
64349
64491
 
64350
64492
  // src/frontdoor/capture.ts
64351
- var fs11 = __toESM(require("node:fs"), 1);
64352
- var path31 = __toESM(require("node:path"), 1);
64493
+ var fs12 = __toESM(require("node:fs"), 1);
64494
+ var path32 = __toESM(require("node:path"), 1);
64353
64495
  var SECRET_HEADER_NAME = /authorization|cookie|token|secret|credential|api[-_]key/i;
64354
64496
  var SECRET_JSON_KEY = /token|secret|password|credential|authorization|api[-_]key/i;
64355
64497
  var SECRET_BODY_PATTERNS = [
@@ -64393,13 +64535,13 @@ function redactBody(chunk) {
64393
64535
  }
64394
64536
  var CAPTURE_ENV = "AGENT_SHIM_FRONTDOOR_CAPTURE";
64395
64537
  function captureFromEnv(env, logsDir) {
64396
- return env[CAPTURE_ENV] === "1" ? createFileCapture(path31.join(logsDir, "frontdoor-capture.jsonl")) : void 0;
64538
+ return env[CAPTURE_ENV] === "1" ? createFileCapture(path32.join(logsDir, "frontdoor-capture.jsonl")) : void 0;
64397
64539
  }
64398
64540
  function createFileCapture(file2, now = () => /* @__PURE__ */ new Date()) {
64399
- fs11.mkdirSync(path31.dirname(file2), { recursive: true });
64541
+ fs12.mkdirSync(path32.dirname(file2), { recursive: true });
64400
64542
  let nextId = 0;
64401
64543
  const append = (record2) => {
64402
- fs11.appendFileSync(file2, `${JSON.stringify({ ts: now().toISOString(), ...record2 })}
64544
+ fs12.appendFileSync(file2, `${JSON.stringify({ ts: now().toISOString(), ...record2 })}
64403
64545
  `, { mode: CAPTURE_FILE_MODE });
64404
64546
  };
64405
64547
  return {
@@ -64486,7 +64628,7 @@ function createFileCapture(file2, now = () => /* @__PURE__ */ new Date()) {
64486
64628
 
64487
64629
  // src/frontdoor/connect.ts
64488
64630
  var import_node_crypto10 = require("node:crypto");
64489
- var fs12 = __toESM(require("node:fs"), 1);
64631
+ var fs13 = __toESM(require("node:fs"), 1);
64490
64632
 
64491
64633
  // src/frontdoor/x509.ts
64492
64634
  var import_node_crypto9 = require("node:crypto");
@@ -65258,7 +65400,7 @@ function isEnoent5(error62) {
65258
65400
  function realConnectCertStore(paths) {
65259
65401
  const read = (file2) => {
65260
65402
  try {
65261
- return fs12.readFileSync(file2, "utf8");
65403
+ return fs13.readFileSync(file2, "utf8");
65262
65404
  } catch (error62) {
65263
65405
  if (isEnoent5(error62)) {
65264
65406
  return void 0;
@@ -65273,10 +65415,10 @@ function realConnectCertStore(paths) {
65273
65415
  return certPem === void 0 || keyPem2 === void 0 ? void 0 : { certPem, keyPem: keyPem2 };
65274
65416
  },
65275
65417
  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);
65418
+ fs13.mkdirSync(paths.frontdoorCaDir, { recursive: true });
65419
+ fs13.writeFileSync(paths.frontdoorCaCertFile, ca.certPem, "utf8");
65420
+ fs13.writeFileSync(paths.frontdoorCaKeyFile, ca.keyPem, { encoding: "utf8", mode: CA_KEY_FILE_MODE });
65421
+ fs13.chmodSync(paths.frontdoorCaKeyFile, CA_KEY_FILE_MODE);
65280
65422
  }
65281
65423
  };
65282
65424
  }
@@ -65541,25 +65683,19 @@ function realConnectEffects() {
65541
65683
  }
65542
65684
  };
65543
65685
  },
65544
- connectTlsUpstream: async (host, port, clientAlpn) => await new Promise((resolve, reject) => {
65545
- const dial = (localPort) => {
65546
- const raw = net2.connect({ host, port, localPort, lookup: realAddressLookup });
65547
- return tls.connect({ socket: raw, servername: host, ...clientAlpn === void 0 ? {} : { ALPNProtocols: [clientAlpn] } });
65548
- };
65549
- const settle2 = (candidate) => {
65550
- candidate.once("secureConnect", () => {
65551
- resolve(candidate);
65552
- });
65553
- candidate.once("error", (error62) => {
65554
- if ("code" in error62 && error62.code === "EADDRINUSE") {
65555
- settle2(dial(upstreamLocalPort()));
65556
- return;
65557
- }
65558
- reject(error62);
65686
+ connectTlsUpstream: async (host, port, clientAlpn) => {
65687
+ const dialled = await reservedDial({ host, port });
65688
+ if (dialled.error !== null) {
65689
+ throw dialled.error;
65690
+ }
65691
+ return await new Promise((resolve, reject) => {
65692
+ const secure = tls.connect({ socket: dialled.socket, servername: host, ...clientAlpn === void 0 ? {} : { ALPNProtocols: [clientAlpn] } });
65693
+ secure.once("secureConnect", () => {
65694
+ resolve(secure);
65559
65695
  });
65560
- };
65561
- settle2(dial(upstreamLocalPort()));
65562
- }),
65696
+ secure.once("error", reject);
65697
+ });
65698
+ },
65563
65699
  connectTcp: async (host, port) => await new Promise((resolve, reject) => {
65564
65700
  const socket = net2.connect({ host, port });
65565
65701
  socket.once("connect", () => {
@@ -68222,8 +68358,8 @@ function createRealQuotaRefresher(params) {
68222
68358
 
68223
68359
  // src/frontdoor/commands.ts
68224
68360
  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}
68361
+ import_node_fs12.default.mkdirSync(paths.logsDir, { recursive: true });
68362
+ import_node_fs12.default.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
68227
68363
  `);
68228
68364
  }
68229
68365
  function headroomSocketTarget(fsPort, trust, paths) {
@@ -68332,7 +68468,7 @@ function realFrontDoorSupervisorPorts(paths) {
68332
68468
  const leafFor = createLeafCache(loadCa(), () => /* @__PURE__ */ new Date());
68333
68469
  const capture = captureFromEnv(process.env, paths.logsDir);
68334
68470
  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")}`);
68471
+ log(`capture enabled, recording CONNECT targets and piped exchanges to ${import_node_path32.default.join(paths.logsDir, "frontdoor-capture.jsonl")}`);
68336
68472
  }
68337
68473
  const server = await startConnectServer(
68338
68474
  {
@@ -68921,16 +69057,16 @@ function registerCompletionCommand(program2) {
68921
69057
  var import_node_child_process4 = require("node:child_process");
68922
69058
 
68923
69059
  // src/identityToken.ts
68924
- var import_node_fs12 = __toESM(require("node:fs"), 1);
68925
- var import_node_path32 = __toESM(require("node:path"), 1);
69060
+ var import_node_fs13 = __toESM(require("node:fs"), 1);
69061
+ var import_node_path33 = __toESM(require("node:path"), 1);
68926
69062
  var TOKEN_FILE_MODE = 384;
68927
69063
  var TOKEN_DIR_MODE = 448;
68928
69064
  var OAUTH_TOKEN_RE = /^sk-ant-oat\d+-[A-Za-z0-9_-]+$/;
68929
69065
  function identityTokenDir(paths) {
68930
- return import_node_path32.default.join(paths.root, "credentials");
69066
+ return import_node_path33.default.join(paths.root, "credentials");
68931
69067
  }
68932
69068
  function identityTokenPath(paths, identityName) {
68933
- return import_node_path32.default.join(identityTokenDir(paths), `${identityName}.token`);
69069
+ return import_node_path33.default.join(identityTokenDir(paths), `${identityName}.token`);
68934
69070
  }
68935
69071
  function storeIdentityToken(paths, identityName, raw) {
68936
69072
  const token = raw.trim();
@@ -68938,94 +69074,16 @@ function storeIdentityToken(paths, identityName, raw) {
68938
69074
  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
69075
  }
68940
69076
  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);
69077
+ import_node_fs13.default.mkdirSync(dir, { recursive: true, mode: TOKEN_DIR_MODE });
69078
+ import_node_fs13.default.chmodSync(dir, TOKEN_DIR_MODE);
68943
69079
  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}
69080
+ const temp = import_node_path33.default.join(dir, `.${identityName}.${String(process.pid)}.tmp`);
69081
+ import_node_fs13.default.writeFileSync(temp, `${token}
68946
69082
  `, { mode: TOKEN_FILE_MODE });
68947
- import_node_fs12.default.renameSync(temp, target);
69083
+ import_node_fs13.default.renameSync(temp, target);
68948
69084
  return target;
68949
69085
  }
68950
69086
 
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
69087
  // src/credentialCommand.ts
69030
69088
  async function readStandardInput() {
69031
69089
  const chunks = [];
@@ -69224,7 +69282,14 @@ function pushPathResolution(push, resolution) {
69224
69282
  break;
69225
69283
  }
69226
69284
  }
69227
- function pushProvider(push, entry) {
69285
+ function cacheClause(cacheEnv, owner, block2) {
69286
+ if (cacheEnv === void 0 || block2.cache === void 0) {
69287
+ return { text: "", unreadable: false };
69288
+ }
69289
+ const state = describeCachedCredential({ port: cacheEnv.port, platform: cacheEnv.platform, owner, cache: block2.cache, nowMs: cacheEnv.now() });
69290
+ return { text: `; ${formatCachedCredentialState(state)}`, unreadable: state.status === "unreadable" };
69291
+ }
69292
+ function pushProvider(push, entry, cacheEnv) {
69228
69293
  if (entry.raw === void 0) {
69229
69294
  push("provider", "fail", `${entry.path} is missing.`, entry.name);
69230
69295
  return;
@@ -69246,7 +69311,8 @@ function pushProvider(push, entry) {
69246
69311
  push("provider", "fail", new ConfigValidationError(entry.path, validated.error.issues).message, entry.name);
69247
69312
  return;
69248
69313
  }
69249
- push("provider", "pass", `${entry.name} is valid (${describeProviderEndpoint(validated.data)}, credential ${describeCredential(validated.data.credential)}).`, entry.name);
69314
+ const cache = cacheClause(cacheEnv, `provider ${entry.name}`, validated.data.credential);
69315
+ push("provider", cache.unreadable ? "fail" : "pass", `${entry.name} is valid (${describeProviderEndpoint(validated.data)}, credential ${describeCredential(validated.data.credential)})${cache.text}.`, entry.name);
69250
69316
  }
69251
69317
  function pushLegacyName(push, params) {
69252
69318
  const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
@@ -69339,10 +69405,11 @@ function runDoctor(params) {
69339
69405
  );
69340
69406
  } else {
69341
69407
  const credential = validated.data.credential;
69408
+ const cache = credential === void 0 ? { text: "", unreadable: false } : cacheClause(params.credentialCache, `identity ${entry.name}`, credential);
69342
69409
  push(
69343
69410
  "identity",
69344
- "pass",
69345
- `${entry.name} is valid and authenticates with ${credential === void 0 ? "its stored login" : `credential ${describeCredential(credential)}`}.`,
69411
+ cache.unreadable ? "fail" : "pass",
69412
+ `${entry.name} is valid and authenticates with ${credential === void 0 ? "its stored login" : `credential ${describeCredential(credential)}`}${cache.text}.`,
69346
69413
  entry.name
69347
69414
  );
69348
69415
  }
@@ -69362,7 +69429,7 @@ function runDoctor(params) {
69362
69429
  return poolName === void 0 ? validIdentityNames.has(selector) : poolName in pools;
69363
69430
  };
69364
69431
  for (const entry of params.providers) {
69365
- pushProvider(push, entry);
69432
+ pushProvider(push, entry, params.credentialCache);
69366
69433
  }
69367
69434
  if (params.platform !== "darwin" || params.run === void 0) {
69368
69435
  push("keychain", "pass", "Skipped (not macOS).");
@@ -69601,6 +69668,7 @@ function collectDoctorReport(params) {
69601
69668
  );
69602
69669
  const report = runDoctor({
69603
69670
  env: params.env,
69671
+ credentialCache: realCredentialCacheEnv(paths),
69604
69672
  identities,
69605
69673
  configProfiles,
69606
69674
  providers,