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 +248 -189
- package/dist/index.cjs +285 -224
- package/dist/index.mjs +284 -223
- package/dist/types/index.d.ts +25 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -5834,6 +5834,56 @@ import path16 from "node:path";
|
|
|
5834
5834
|
|
|
5835
5835
|
// src/credentialCache.ts
|
|
5836
5836
|
import { z as z7 } from "zod";
|
|
5837
|
+
|
|
5838
|
+
// src/usage/preflight.ts
|
|
5839
|
+
var MS_PER_SECOND2 = 1e3;
|
|
5840
|
+
var SECONDS_PER_MINUTE = 60;
|
|
5841
|
+
var MINUTES_PER_HOUR = 60;
|
|
5842
|
+
var HOURS_PER_DAY = 24;
|
|
5843
|
+
var WARNING_STATUSES = /* @__PURE__ */ new Set(["allowed_warning", "rejected"]);
|
|
5844
|
+
function formatAge(ms) {
|
|
5845
|
+
const minutes = Math.floor(ms / (MS_PER_SECOND2 * SECONDS_PER_MINUTE));
|
|
5846
|
+
if (minutes < MINUTES_PER_HOUR) {
|
|
5847
|
+
return `${String(Math.max(minutes, 0))}m`;
|
|
5848
|
+
}
|
|
5849
|
+
const hours = Math.floor(minutes / MINUTES_PER_HOUR);
|
|
5850
|
+
return hours < HOURS_PER_DAY ? `${String(hours)}h` : `${String(Math.floor(hours / HOURS_PER_DAY))}d`;
|
|
5851
|
+
}
|
|
5852
|
+
function effectiveWindow(window, nowMs) {
|
|
5853
|
+
const resetsAtMs = window.resetsAt === void 0 ? void 0 : Date.parse(window.resetsAt);
|
|
5854
|
+
if (resetsAtMs !== void 0 && resetsAtMs <= nowMs) {
|
|
5855
|
+
return { reset: true, utilization: 0 };
|
|
5856
|
+
}
|
|
5857
|
+
return {
|
|
5858
|
+
reset: false,
|
|
5859
|
+
...window.utilization === void 0 ? {} : { utilization: window.utilization },
|
|
5860
|
+
...resetsAtMs === void 0 ? {} : { resetsAtMs },
|
|
5861
|
+
...window.status === void 0 ? {} : { status: window.status }
|
|
5862
|
+
};
|
|
5863
|
+
}
|
|
5864
|
+
function quotaWarnings(snapshot, provider, nowMs) {
|
|
5865
|
+
const rateLimit = snapshot?.providers[provider]?.rateLimit;
|
|
5866
|
+
const unified = rateLimit?.unified;
|
|
5867
|
+
if (snapshot === void 0 || rateLimit === void 0 || unified === void 0) {
|
|
5868
|
+
return [];
|
|
5869
|
+
}
|
|
5870
|
+
const age = formatAge(nowMs - Date.parse(rateLimit.observedAt));
|
|
5871
|
+
const windows = [
|
|
5872
|
+
{ name: "five-hour", window: unified.fiveHour },
|
|
5873
|
+
{ name: "seven-day", window: unified.sevenDay }
|
|
5874
|
+
];
|
|
5875
|
+
return windows.flatMap(({ name, window }) => {
|
|
5876
|
+
const effective = window === void 0 ? void 0 : effectiveWindow(window, nowMs);
|
|
5877
|
+
if (window === void 0 || effective?.status === void 0 || !WARNING_STATUSES.has(effective.status)) {
|
|
5878
|
+
return [];
|
|
5879
|
+
}
|
|
5880
|
+
const reset = window.resetsAt === void 0 ? "" : `, resets ${window.resetsAt}`;
|
|
5881
|
+
const verdict = effective.status === "rejected" ? "exhausted" : "nearly used";
|
|
5882
|
+
return [`agent-shim: identity ${snapshot.identity}: the ${name} quota is ${verdict}${reset} (last seen ${age} ago)`];
|
|
5883
|
+
});
|
|
5884
|
+
}
|
|
5885
|
+
|
|
5886
|
+
// src/credentialCache.ts
|
|
5837
5887
|
var MS_PER_UNIT = { s: 1e3, m: 6e4, h: 36e5, d: 864e5 };
|
|
5838
5888
|
var CachedCredentialSchema = z7.strictObject({
|
|
5839
5889
|
token: z7.string().min(1),
|
|
@@ -5860,6 +5910,45 @@ function isFresh(entry, cache, now) {
|
|
|
5860
5910
|
}
|
|
5861
5911
|
return limit === void 0 || now - entry.fetchedAt < limit;
|
|
5862
5912
|
}
|
|
5913
|
+
function cacheAgeMs(entry, now) {
|
|
5914
|
+
return Math.max(0, now - entry.fetchedAt);
|
|
5915
|
+
}
|
|
5916
|
+
function describeCachedCredential(params) {
|
|
5917
|
+
const store = effectiveStore(params.cache, params.platform);
|
|
5918
|
+
let entry;
|
|
5919
|
+
try {
|
|
5920
|
+
entry = params.port.read(store, params.owner);
|
|
5921
|
+
} catch (error) {
|
|
5922
|
+
return { store, status: "unreadable", reason: error instanceof Error ? error.message : String(error) };
|
|
5923
|
+
}
|
|
5924
|
+
if (entry === void 0) {
|
|
5925
|
+
return { store, status: "empty" };
|
|
5926
|
+
}
|
|
5927
|
+
const limit = ttlMs(params.cache);
|
|
5928
|
+
const ageMs = cacheAgeMs(entry, params.nowMs);
|
|
5929
|
+
return {
|
|
5930
|
+
store,
|
|
5931
|
+
status: isFresh(entry, params.cache, params.nowMs) ? "fresh" : "expired",
|
|
5932
|
+
ageMs,
|
|
5933
|
+
...limit === void 0 ? {} : { expiresInMs: limit - ageMs }
|
|
5934
|
+
};
|
|
5935
|
+
}
|
|
5936
|
+
function formatCachedCredentialState(state) {
|
|
5937
|
+
if (state.status === "empty") {
|
|
5938
|
+
return `no cached entry in the ${state.store} store yet`;
|
|
5939
|
+
}
|
|
5940
|
+
if (state.status === "unreadable") {
|
|
5941
|
+
return `the ${state.store} store cannot be read here: ${state.reason}`;
|
|
5942
|
+
}
|
|
5943
|
+
if (state.status === "expired" && (state.expiresInMs === void 0 || state.expiresInMs > 0)) {
|
|
5944
|
+
return "cached with a timestamp in the future, treated as expired";
|
|
5945
|
+
}
|
|
5946
|
+
const age = `cached ${formatAge(state.ageMs)} ago`;
|
|
5947
|
+
if (state.expiresInMs === void 0) {
|
|
5948
|
+
return `${age}, no expiry`;
|
|
5949
|
+
}
|
|
5950
|
+
return state.status === "fresh" ? `${age}, expires in ${formatAge(state.expiresInMs)}` : `${age}, expired ${formatAge(-state.expiresInMs)} ago`;
|
|
5951
|
+
}
|
|
5863
5952
|
|
|
5864
5953
|
// src/credential.ts
|
|
5865
5954
|
var CREDENTIAL_UNAVAILABLE_EXIT = 64;
|
|
@@ -6475,54 +6564,6 @@ function readDirectorySelections(loaded) {
|
|
|
6475
6564
|
return { ...identity === void 0 ? {} : { identity }, ...configProfile === void 0 ? {} : { configProfile } };
|
|
6476
6565
|
}
|
|
6477
6566
|
|
|
6478
|
-
// src/usage/preflight.ts
|
|
6479
|
-
var MS_PER_SECOND2 = 1e3;
|
|
6480
|
-
var SECONDS_PER_MINUTE = 60;
|
|
6481
|
-
var MINUTES_PER_HOUR = 60;
|
|
6482
|
-
var HOURS_PER_DAY = 24;
|
|
6483
|
-
var WARNING_STATUSES = /* @__PURE__ */ new Set(["allowed_warning", "rejected"]);
|
|
6484
|
-
function formatAge(ms) {
|
|
6485
|
-
const minutes = Math.floor(ms / (MS_PER_SECOND2 * SECONDS_PER_MINUTE));
|
|
6486
|
-
if (minutes < MINUTES_PER_HOUR) {
|
|
6487
|
-
return `${String(Math.max(minutes, 0))}m`;
|
|
6488
|
-
}
|
|
6489
|
-
const hours = Math.floor(minutes / MINUTES_PER_HOUR);
|
|
6490
|
-
return hours < HOURS_PER_DAY ? `${String(hours)}h` : `${String(Math.floor(hours / HOURS_PER_DAY))}d`;
|
|
6491
|
-
}
|
|
6492
|
-
function effectiveWindow(window, nowMs) {
|
|
6493
|
-
const resetsAtMs = window.resetsAt === void 0 ? void 0 : Date.parse(window.resetsAt);
|
|
6494
|
-
if (resetsAtMs !== void 0 && resetsAtMs <= nowMs) {
|
|
6495
|
-
return { reset: true, utilization: 0 };
|
|
6496
|
-
}
|
|
6497
|
-
return {
|
|
6498
|
-
reset: false,
|
|
6499
|
-
...window.utilization === void 0 ? {} : { utilization: window.utilization },
|
|
6500
|
-
...resetsAtMs === void 0 ? {} : { resetsAtMs },
|
|
6501
|
-
...window.status === void 0 ? {} : { status: window.status }
|
|
6502
|
-
};
|
|
6503
|
-
}
|
|
6504
|
-
function quotaWarnings(snapshot, provider, nowMs) {
|
|
6505
|
-
const rateLimit = snapshot?.providers[provider]?.rateLimit;
|
|
6506
|
-
const unified = rateLimit?.unified;
|
|
6507
|
-
if (snapshot === void 0 || rateLimit === void 0 || unified === void 0) {
|
|
6508
|
-
return [];
|
|
6509
|
-
}
|
|
6510
|
-
const age = formatAge(nowMs - Date.parse(rateLimit.observedAt));
|
|
6511
|
-
const windows = [
|
|
6512
|
-
{ name: "five-hour", window: unified.fiveHour },
|
|
6513
|
-
{ name: "seven-day", window: unified.sevenDay }
|
|
6514
|
-
];
|
|
6515
|
-
return windows.flatMap(({ name, window }) => {
|
|
6516
|
-
const effective = window === void 0 ? void 0 : effectiveWindow(window, nowMs);
|
|
6517
|
-
if (window === void 0 || effective?.status === void 0 || !WARNING_STATUSES.has(effective.status)) {
|
|
6518
|
-
return [];
|
|
6519
|
-
}
|
|
6520
|
-
const reset = window.resetsAt === void 0 ? "" : `, resets ${window.resetsAt}`;
|
|
6521
|
-
const verdict = effective.status === "rejected" ? "exhausted" : "nearly used";
|
|
6522
|
-
return [`agent-shim: identity ${snapshot.identity}: the ${name} quota is ${verdict}${reset} (last seen ${age} ago)`];
|
|
6523
|
-
});
|
|
6524
|
-
}
|
|
6525
|
-
|
|
6526
6567
|
// src/usage/poolPick.ts
|
|
6527
6568
|
import path19 from "node:path";
|
|
6528
6569
|
import { z as z9 } from "zod";
|
|
@@ -6918,19 +6959,97 @@ function collectPoolPick(params) {
|
|
|
6918
6959
|
};
|
|
6919
6960
|
}
|
|
6920
6961
|
|
|
6962
|
+
// src/realCredentialCache.ts
|
|
6963
|
+
import { spawnSync } from "node:child_process";
|
|
6964
|
+
import fs7 from "node:fs";
|
|
6965
|
+
import path20 from "node:path";
|
|
6966
|
+
var KEYCHAIN_CACHE_SERVICE = "agent-shim-credential-cache";
|
|
6967
|
+
var CACHE_DIR_MODE = 448;
|
|
6968
|
+
var CACHE_FILE_MODE = 384;
|
|
6969
|
+
function cacheFileNameFor(owner) {
|
|
6970
|
+
return `${owner.replace(/[^A-Za-z0-9._-]/g, "_")}.json`;
|
|
6971
|
+
}
|
|
6972
|
+
function parseEntry(raw) {
|
|
6973
|
+
let json;
|
|
6974
|
+
try {
|
|
6975
|
+
json = JSON.parse(raw);
|
|
6976
|
+
} catch {
|
|
6977
|
+
return void 0;
|
|
6978
|
+
}
|
|
6979
|
+
const parsed = CachedCredentialSchema.safeParse(json);
|
|
6980
|
+
return parsed.success ? parsed.data : void 0;
|
|
6981
|
+
}
|
|
6982
|
+
function requireKeychain() {
|
|
6983
|
+
if (process.platform !== "darwin") {
|
|
6984
|
+
throw new Error("the keychain credential store needs macOS; use --credential-cache-store file");
|
|
6985
|
+
}
|
|
6986
|
+
}
|
|
6987
|
+
function security(args, stdin) {
|
|
6988
|
+
const result = spawnSync("security", args, { encoding: "utf8", ...stdin === void 0 ? {} : { input: stdin }, stdio: ["pipe", "pipe", "ignore"] });
|
|
6989
|
+
return { status: result.status, stdout: result.stdout };
|
|
6990
|
+
}
|
|
6991
|
+
function createRealCredentialCache(root) {
|
|
6992
|
+
const dir = path20.join(root, "credential-cache");
|
|
6993
|
+
const filePath = (owner) => path20.join(dir, cacheFileNameFor(owner));
|
|
6994
|
+
return {
|
|
6995
|
+
read(store, owner) {
|
|
6996
|
+
if (store === "file") {
|
|
6997
|
+
try {
|
|
6998
|
+
return parseEntry(fs7.readFileSync(filePath(owner), "utf8"));
|
|
6999
|
+
} catch {
|
|
7000
|
+
return void 0;
|
|
7001
|
+
}
|
|
7002
|
+
}
|
|
7003
|
+
requireKeychain();
|
|
7004
|
+
const result = security(["find-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner, "-w"]);
|
|
7005
|
+
return result.status === 0 ? parseEntry(Buffer.from(result.stdout.trim(), "base64").toString("utf8")) : void 0;
|
|
7006
|
+
},
|
|
7007
|
+
write(store, owner, entry) {
|
|
7008
|
+
const serialised = JSON.stringify(entry);
|
|
7009
|
+
if (store === "file") {
|
|
7010
|
+
fs7.mkdirSync(dir, { recursive: true, mode: CACHE_DIR_MODE });
|
|
7011
|
+
fs7.chmodSync(dir, CACHE_DIR_MODE);
|
|
7012
|
+
const target = filePath(owner);
|
|
7013
|
+
const temp = `${target}.${String(process.pid)}.tmp`;
|
|
7014
|
+
fs7.writeFileSync(temp, serialised, { mode: CACHE_FILE_MODE });
|
|
7015
|
+
fs7.renameSync(temp, target);
|
|
7016
|
+
return;
|
|
7017
|
+
}
|
|
7018
|
+
requireKeychain();
|
|
7019
|
+
const encoded = Buffer.from(serialised, "utf8").toString("base64");
|
|
7020
|
+
const result = security(["-i"], `add-generic-password -U -s ${KEYCHAIN_CACHE_SERVICE} -a ${JSON.stringify(owner)} -w ${encoded}
|
|
7021
|
+
`);
|
|
7022
|
+
if (result.status !== 0) {
|
|
7023
|
+
throw new Error(`could not write the keychain credential cache for ${owner}`);
|
|
7024
|
+
}
|
|
7025
|
+
},
|
|
7026
|
+
remove(store, owner) {
|
|
7027
|
+
if (store === "file") {
|
|
7028
|
+
fs7.rmSync(filePath(owner), { force: true });
|
|
7029
|
+
return;
|
|
7030
|
+
}
|
|
7031
|
+
requireKeychain();
|
|
7032
|
+
security(["delete-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner]);
|
|
7033
|
+
}
|
|
7034
|
+
};
|
|
7035
|
+
}
|
|
7036
|
+
function realCredentialCacheEnv(paths) {
|
|
7037
|
+
return { port: createRealCredentialCache(paths.root), platform: process.platform, now: () => Date.now() };
|
|
7038
|
+
}
|
|
7039
|
+
|
|
6921
7040
|
// src/realPorts.ts
|
|
6922
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
7041
|
+
import { spawn, spawnSync as spawnSync2 } from "node:child_process";
|
|
6923
7042
|
import { createHash as createHash5 } from "node:crypto";
|
|
6924
|
-
import
|
|
7043
|
+
import fs8 from "node:fs";
|
|
6925
7044
|
import os3 from "node:os";
|
|
6926
|
-
import
|
|
7045
|
+
import path22 from "node:path";
|
|
6927
7046
|
import { isSea } from "node:sea";
|
|
6928
7047
|
|
|
6929
7048
|
// src/versionDiscovery.ts
|
|
6930
7049
|
import os2 from "node:os";
|
|
6931
|
-
import
|
|
7050
|
+
import path21 from "node:path";
|
|
6932
7051
|
function defaultVersionsDir() {
|
|
6933
|
-
return
|
|
7052
|
+
return path21.join(os2.homedir(), ".local", "share", "claude", "versions");
|
|
6934
7053
|
}
|
|
6935
7054
|
var NUMERIC_DOTTED_VERSION_RE = /^\d+(?:\.\d+)*$/;
|
|
6936
7055
|
function isNumericDottedVersion(name) {
|
|
@@ -6972,7 +7091,7 @@ function discoverClaudeBinary(options) {
|
|
|
6972
7091
|
const highestVersion = pickHighestVersion(entries);
|
|
6973
7092
|
if (highestVersion !== void 0) {
|
|
6974
7093
|
return {
|
|
6975
|
-
path:
|
|
7094
|
+
path: path21.join(versionsDir, highestVersion),
|
|
6976
7095
|
source: "versions-dir",
|
|
6977
7096
|
version: highestVersion
|
|
6978
7097
|
};
|
|
@@ -6995,7 +7114,7 @@ function isEnoent3(error) {
|
|
|
6995
7114
|
var realFsPort = {
|
|
6996
7115
|
readFileUtf8(filePath) {
|
|
6997
7116
|
try {
|
|
6998
|
-
return
|
|
7117
|
+
return fs8.readFileSync(filePath, "utf8");
|
|
6999
7118
|
} catch (error) {
|
|
7000
7119
|
if (isEnoent3(error)) {
|
|
7001
7120
|
return void 0;
|
|
@@ -7006,7 +7125,7 @@ var realFsPort = {
|
|
|
7006
7125
|
readConfigFile: cosmiconfigReader(),
|
|
7007
7126
|
readdir(dirPath) {
|
|
7008
7127
|
try {
|
|
7009
|
-
return
|
|
7128
|
+
return fs8.readdirSync(dirPath);
|
|
7010
7129
|
} catch (error) {
|
|
7011
7130
|
if (isEnoent3(error)) {
|
|
7012
7131
|
return [];
|
|
@@ -7025,7 +7144,7 @@ var realFarmFs = {
|
|
|
7025
7144
|
lstat(filePath) {
|
|
7026
7145
|
let stat;
|
|
7027
7146
|
try {
|
|
7028
|
-
stat =
|
|
7147
|
+
stat = fs8.lstatSync(filePath);
|
|
7029
7148
|
} catch (error) {
|
|
7030
7149
|
if (isEnoent3(error)) {
|
|
7031
7150
|
return void 0;
|
|
@@ -7037,7 +7156,7 @@ var realFarmFs = {
|
|
|
7037
7156
|
},
|
|
7038
7157
|
readdir(dirPath) {
|
|
7039
7158
|
try {
|
|
7040
|
-
return
|
|
7159
|
+
return fs8.readdirSync(dirPath);
|
|
7041
7160
|
} catch (error) {
|
|
7042
7161
|
if (isEnoent3(error) || isErrorWithCode(error, "ENOTDIR")) {
|
|
7043
7162
|
return [];
|
|
@@ -7046,23 +7165,23 @@ var realFarmFs = {
|
|
|
7046
7165
|
}
|
|
7047
7166
|
},
|
|
7048
7167
|
mkdirp(dirPath) {
|
|
7049
|
-
|
|
7168
|
+
fs8.mkdirSync(dirPath, { recursive: true });
|
|
7050
7169
|
},
|
|
7051
7170
|
symlink(target, linkPath) {
|
|
7052
|
-
|
|
7171
|
+
fs8.symlinkSync(target, linkPath);
|
|
7053
7172
|
},
|
|
7054
7173
|
rename(from, to) {
|
|
7055
|
-
|
|
7174
|
+
fs8.renameSync(from, to);
|
|
7056
7175
|
},
|
|
7057
7176
|
removeRecursive(targetPath) {
|
|
7058
|
-
|
|
7177
|
+
fs8.rmSync(targetPath, { recursive: true, force: true });
|
|
7059
7178
|
},
|
|
7060
7179
|
copyRecursive(from, to) {
|
|
7061
|
-
|
|
7180
|
+
fs8.cpSync(from, to, { recursive: true, force: true, verbatimSymlinks: true });
|
|
7062
7181
|
},
|
|
7063
7182
|
readFileUtf8(filePath) {
|
|
7064
7183
|
try {
|
|
7065
|
-
return
|
|
7184
|
+
return fs8.readFileSync(filePath, "utf8");
|
|
7066
7185
|
} catch (error) {
|
|
7067
7186
|
if (isEnoent3(error)) {
|
|
7068
7187
|
return void 0;
|
|
@@ -7071,36 +7190,36 @@ var realFarmFs = {
|
|
|
7071
7190
|
}
|
|
7072
7191
|
},
|
|
7073
7192
|
writeFileUtf8(filePath, contents) {
|
|
7074
|
-
|
|
7193
|
+
fs8.writeFileSync(filePath, contents, "utf8");
|
|
7075
7194
|
},
|
|
7076
7195
|
mkdirPrivate(dirPath) {
|
|
7077
|
-
|
|
7078
|
-
|
|
7196
|
+
fs8.mkdirSync(dirPath, { recursive: true, mode: OWNER_ONLY_DIR_MODE });
|
|
7197
|
+
fs8.chmodSync(dirPath, OWNER_ONLY_DIR_MODE);
|
|
7079
7198
|
},
|
|
7080
7199
|
writeFilePrivate(filePath, contents) {
|
|
7081
7200
|
const temp = `${filePath}.${String(process.pid)}.tmp`;
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7201
|
+
fs8.writeFileSync(temp, contents, { encoding: "utf8", mode: OWNER_ONLY_FILE_MODE });
|
|
7202
|
+
fs8.chmodSync(temp, OWNER_ONLY_FILE_MODE);
|
|
7203
|
+
fs8.renameSync(temp, filePath);
|
|
7085
7204
|
},
|
|
7086
7205
|
appendFilePrivate(filePath, contents) {
|
|
7087
|
-
const descriptor =
|
|
7206
|
+
const descriptor = fs8.openSync(filePath, "a", OWNER_ONLY_FILE_MODE);
|
|
7088
7207
|
try {
|
|
7089
|
-
if ((
|
|
7090
|
-
|
|
7208
|
+
if ((fs8.fstatSync(descriptor).mode & PERMISSION_BITS2) !== OWNER_ONLY_FILE_MODE) {
|
|
7209
|
+
fs8.fchmodSync(descriptor, OWNER_ONLY_FILE_MODE);
|
|
7091
7210
|
}
|
|
7092
7211
|
const bytes = Buffer.from(contents, "utf8");
|
|
7093
7212
|
let written = 0;
|
|
7094
7213
|
while (written < bytes.length) {
|
|
7095
|
-
written +=
|
|
7214
|
+
written += fs8.writeSync(descriptor, bytes, written, bytes.length - written);
|
|
7096
7215
|
}
|
|
7097
7216
|
} finally {
|
|
7098
|
-
|
|
7217
|
+
fs8.closeSync(descriptor);
|
|
7099
7218
|
}
|
|
7100
7219
|
},
|
|
7101
7220
|
writeFileExclusive(filePath, contents) {
|
|
7102
7221
|
try {
|
|
7103
|
-
|
|
7222
|
+
fs8.writeFileSync(filePath, contents, { encoding: "utf8", flag: "wx" });
|
|
7104
7223
|
return true;
|
|
7105
7224
|
} catch (error) {
|
|
7106
7225
|
if (isErrorWithCode(error, "EEXIST")) {
|
|
@@ -7111,7 +7230,7 @@ var realFarmFs = {
|
|
|
7111
7230
|
},
|
|
7112
7231
|
hashFile(filePath) {
|
|
7113
7232
|
try {
|
|
7114
|
-
return createHash5("sha256").update(
|
|
7233
|
+
return createHash5("sha256").update(fs8.readFileSync(filePath)).digest("hex");
|
|
7115
7234
|
} catch (error) {
|
|
7116
7235
|
if (isEnoent3(error) || isErrorWithCode(error, "EISDIR")) {
|
|
7117
7236
|
return void 0;
|
|
@@ -7133,7 +7252,7 @@ function realIsProcessAlive(pid) {
|
|
|
7133
7252
|
}
|
|
7134
7253
|
}
|
|
7135
7254
|
function realIsProcessZombie(pid) {
|
|
7136
|
-
const result =
|
|
7255
|
+
const result = spawnSync2("ps", ["-o", "stat=", "-p", String(pid)], { encoding: "utf8" });
|
|
7137
7256
|
return result.status === 0 && result.stdout.trim().startsWith("Z");
|
|
7138
7257
|
}
|
|
7139
7258
|
function realIsProcessRunning(pid) {
|
|
@@ -7141,17 +7260,17 @@ function realIsProcessRunning(pid) {
|
|
|
7141
7260
|
}
|
|
7142
7261
|
var realRunPort = {
|
|
7143
7262
|
run(command, args) {
|
|
7144
|
-
const result =
|
|
7263
|
+
const result = spawnSync2(command, [...args], { encoding: "utf8" });
|
|
7145
7264
|
return { status: result.status, stdout: result.stdout, stderr: result.stderr };
|
|
7146
7265
|
}
|
|
7147
7266
|
};
|
|
7148
7267
|
function expandHome2(filePath) {
|
|
7149
|
-
return filePath.startsWith("~/") ?
|
|
7268
|
+
return filePath.startsWith("~/") ? path22.join(os3.homedir(), filePath.slice(1)) : filePath;
|
|
7150
7269
|
}
|
|
7151
7270
|
var MACOS_GUI_SESSION_MANAGER = "Aqua";
|
|
7152
7271
|
function hasDesktopSession() {
|
|
7153
7272
|
if (process.platform === "darwin") {
|
|
7154
|
-
const result =
|
|
7273
|
+
const result = spawnSync2("launchctl", ["managername"], { encoding: "utf8" });
|
|
7155
7274
|
return result.status === 0 && result.stdout.trim() === MACOS_GUI_SESSION_MANAGER;
|
|
7156
7275
|
}
|
|
7157
7276
|
if (process.platform === "win32") {
|
|
@@ -7165,8 +7284,8 @@ var realCredentialPort = {
|
|
|
7165
7284
|
let content;
|
|
7166
7285
|
let stat;
|
|
7167
7286
|
try {
|
|
7168
|
-
stat =
|
|
7169
|
-
content =
|
|
7287
|
+
stat = fs8.statSync(resolved);
|
|
7288
|
+
content = fs8.readFileSync(resolved, "utf8");
|
|
7170
7289
|
} catch (error) {
|
|
7171
7290
|
if (isEnoent3(error)) {
|
|
7172
7291
|
return { found: false };
|
|
@@ -7177,7 +7296,7 @@ var realCredentialPort = {
|
|
|
7177
7296
|
},
|
|
7178
7297
|
runCommand(argv, options) {
|
|
7179
7298
|
const [command, ...args] = argv;
|
|
7180
|
-
const result =
|
|
7299
|
+
const result = spawnSync2(command, args, {
|
|
7181
7300
|
encoding: "utf8",
|
|
7182
7301
|
timeout: options.timeoutMs,
|
|
7183
7302
|
stdio: options.interactive ? ["inherit", "pipe", "inherit"] : ["ignore", "pipe", "pipe"]
|
|
@@ -7219,8 +7338,8 @@ function spawnDaemonThrough(executable) {
|
|
|
7219
7338
|
return (paths, subcommand, logPath) => spawnDetachedDaemon({ command: executable, args: [subcommand] }, paths, subcommand, logPath);
|
|
7220
7339
|
}
|
|
7221
7340
|
function spawnDetachedDaemon(invocation, paths, subcommand, logPath) {
|
|
7222
|
-
|
|
7223
|
-
const logFd =
|
|
7341
|
+
fs8.mkdirSync(path22.dirname(logPath), { recursive: true });
|
|
7342
|
+
const logFd = fs8.openSync(logPath, "a");
|
|
7224
7343
|
try {
|
|
7225
7344
|
const child = spawn(invocation.command, invocation.args, detachedDaemonSpawnOptions(logFd, { ...process.env, AGENT_SHIM_HOME: paths.root }));
|
|
7226
7345
|
child.unref();
|
|
@@ -7229,7 +7348,7 @@ function spawnDetachedDaemon(invocation, paths, subcommand, logPath) {
|
|
|
7229
7348
|
}
|
|
7230
7349
|
return child.pid;
|
|
7231
7350
|
} finally {
|
|
7232
|
-
|
|
7351
|
+
fs8.closeSync(logFd);
|
|
7233
7352
|
}
|
|
7234
7353
|
}
|
|
7235
7354
|
function spawnHeadroomSupervisor(paths, spawnDaemon) {
|
|
@@ -7247,7 +7366,7 @@ var realHeadroomSocketTrust = {
|
|
|
7247
7366
|
lstat: (target) => {
|
|
7248
7367
|
let stat;
|
|
7249
7368
|
try {
|
|
7250
|
-
stat =
|
|
7369
|
+
stat = fs8.lstatSync(target);
|
|
7251
7370
|
} catch (error) {
|
|
7252
7371
|
if (isEnoent3(error)) {
|
|
7253
7372
|
return void 0;
|
|
@@ -7293,7 +7412,7 @@ var EXECUTE_BITS_MASK = 73;
|
|
|
7293
7412
|
function listVersionsDir(dir) {
|
|
7294
7413
|
let entries;
|
|
7295
7414
|
try {
|
|
7296
|
-
entries =
|
|
7415
|
+
entries = fs8.readdirSync(dir, { withFileTypes: true });
|
|
7297
7416
|
} catch (error) {
|
|
7298
7417
|
if (isEnoent3(error)) {
|
|
7299
7418
|
return [];
|
|
@@ -7301,8 +7420,8 @@ function listVersionsDir(dir) {
|
|
|
7301
7420
|
throw error;
|
|
7302
7421
|
}
|
|
7303
7422
|
return entries.filter((entry) => entry.isFile()).map((entry) => {
|
|
7304
|
-
const fullPath =
|
|
7305
|
-
const stat =
|
|
7423
|
+
const fullPath = path22.join(dir, entry.name);
|
|
7424
|
+
const stat = fs8.statSync(fullPath);
|
|
7306
7425
|
return {
|
|
7307
7426
|
name: entry.name,
|
|
7308
7427
|
isFile: true,
|
|
@@ -7316,7 +7435,7 @@ function windowsPathExtensions(pathext) {
|
|
|
7316
7435
|
return (pathext ?? WINDOWS_DEFAULT_PATHEXT).split(";").map((ext) => ext.trim()).filter((ext) => ext.length > 0);
|
|
7317
7436
|
}
|
|
7318
7437
|
function resolveExecutableCandidate(dir, name, env) {
|
|
7319
|
-
const candidate =
|
|
7438
|
+
const candidate = path22.join(dir, name);
|
|
7320
7439
|
if (env.platform === "win32") {
|
|
7321
7440
|
const extensions = windowsPathExtensions(env.pathext);
|
|
7322
7441
|
const alreadyHasRecognisedExtension = extensions.some((ext) => candidate.toLowerCase().endsWith(ext.toLowerCase()));
|
|
@@ -7336,7 +7455,7 @@ function resolveExecutableCandidate(dir, name, env) {
|
|
|
7336
7455
|
}
|
|
7337
7456
|
function realStatFileMode(candidate) {
|
|
7338
7457
|
try {
|
|
7339
|
-
const stat =
|
|
7458
|
+
const stat = fs8.statSync(candidate);
|
|
7340
7459
|
return stat.isFile() ? stat.mode : void 0;
|
|
7341
7460
|
} catch (error) {
|
|
7342
7461
|
if (isEnoent3(error)) {
|
|
@@ -7365,13 +7484,13 @@ function resolveOwnExecutablePath(env) {
|
|
|
7365
7484
|
if (env.argv1 !== void 0 && !env.argv1.includes("/") && !env.argv1.includes("\\")) {
|
|
7366
7485
|
return searchPathForExecutable(env.pathDirs, env.argv1, env.findExecutableInDir) ?? env.execPath;
|
|
7367
7486
|
}
|
|
7368
|
-
const candidate = env.argv1 === void 0 ? env.execPath :
|
|
7369
|
-
const candidateDir =
|
|
7370
|
-
const candidateDirOnPath = env.pathDirs.some((dir) =>
|
|
7487
|
+
const candidate = env.argv1 === void 0 ? env.execPath : path22.resolve(env.cwd, env.argv1);
|
|
7488
|
+
const candidateDir = path22.dirname(candidate);
|
|
7489
|
+
const candidateDirOnPath = env.pathDirs.some((dir) => path22.resolve(dir) === candidateDir);
|
|
7371
7490
|
if (candidateDirOnPath) {
|
|
7372
7491
|
return candidate;
|
|
7373
7492
|
}
|
|
7374
|
-
const viaPath = searchPathForExecutable(env.pathDirs,
|
|
7493
|
+
const viaPath = searchPathForExecutable(env.pathDirs, path22.basename(candidate), env.findExecutableInDir);
|
|
7375
7494
|
return viaPath ?? candidate;
|
|
7376
7495
|
}
|
|
7377
7496
|
function realOwnExecutablePath() {
|
|
@@ -7379,7 +7498,7 @@ function realOwnExecutablePath() {
|
|
|
7379
7498
|
argv1: process.argv[1],
|
|
7380
7499
|
execPath: process.execPath,
|
|
7381
7500
|
cwd: process.cwd(),
|
|
7382
|
-
pathDirs: (process.env.PATH ?? "").split(
|
|
7501
|
+
pathDirs: (process.env.PATH ?? "").split(path22.delimiter).filter((dir) => dir !== ""),
|
|
7383
7502
|
findExecutableInDir
|
|
7384
7503
|
});
|
|
7385
7504
|
}
|
|
@@ -7392,14 +7511,14 @@ function realContentSourcePath() {
|
|
|
7392
7511
|
function realResolveClaudeBinary(isOwnBinary) {
|
|
7393
7512
|
return () => discoverClaudeBinary({
|
|
7394
7513
|
listVersionsDir,
|
|
7395
|
-
pathDirs: (process.env.PATH ?? "").split(
|
|
7514
|
+
pathDirs: (process.env.PATH ?? "").split(path22.delimiter).filter((dir) => dir !== ""),
|
|
7396
7515
|
findExecutableInDir,
|
|
7397
7516
|
isOwnBinary
|
|
7398
7517
|
});
|
|
7399
7518
|
}
|
|
7400
7519
|
|
|
7401
7520
|
// src/checkReport.ts
|
|
7402
|
-
import
|
|
7521
|
+
import path23 from "node:path";
|
|
7403
7522
|
import { z as z10 } from "zod";
|
|
7404
7523
|
|
|
7405
7524
|
// src/cli/bool.ts
|
|
@@ -7569,14 +7688,23 @@ function inspectSettingsExposure(params) {
|
|
|
7569
7688
|
}
|
|
7570
7689
|
return reports;
|
|
7571
7690
|
}
|
|
7572
|
-
function
|
|
7691
|
+
function cachedState(cacheEnv, owner, block) {
|
|
7692
|
+
if (cacheEnv === void 0 || block.cache === void 0) {
|
|
7693
|
+
return void 0;
|
|
7694
|
+
}
|
|
7695
|
+
return describeCachedCredential({ port: cacheEnv.port, platform: cacheEnv.platform, owner, cache: block.cache, nowMs: cacheEnv.now() });
|
|
7696
|
+
}
|
|
7697
|
+
function buildCredentialReport(provider, identity, identityName, cacheEnv) {
|
|
7573
7698
|
const identityCredential = identity?.credential === void 0 ? void 0 : summariseCredential(identity.credential);
|
|
7699
|
+
const identityCached = identity?.credential === void 0 || identityName === void 0 ? void 0 : cachedState(cacheEnv, `identity ${identityName}`, identity.credential);
|
|
7700
|
+
const providerCached = provider?.definition === void 0 ? void 0 : cachedState(cacheEnv, `provider ${provider.name}`, provider.definition.credential);
|
|
7574
7701
|
return {
|
|
7575
7702
|
applies: provider !== void 0 ? "provider" : identityCredential !== void 0 ? "identity" : "stored-login",
|
|
7576
7703
|
...provider === void 0 ? {} : {
|
|
7577
|
-
provider: provider.problem === void 0 ? { name: provider.name, credential: summariseCredential(provider.definition.credential) } : { name: provider.name, problem: provider.problem }
|
|
7704
|
+
provider: provider.problem === void 0 ? { name: provider.name, credential: summariseCredential(provider.definition.credential), ...providerCached === void 0 ? {} : { cached: providerCached } } : { name: provider.name, problem: provider.problem }
|
|
7578
7705
|
},
|
|
7579
|
-
...identityCredential === void 0 ? {} : { identity: identityCredential }
|
|
7706
|
+
...identityCredential === void 0 ? {} : { identity: identityCredential },
|
|
7707
|
+
...identityCached === void 0 ? {} : { identityCached }
|
|
7580
7708
|
};
|
|
7581
7709
|
}
|
|
7582
7710
|
function runCheck(params) {
|
|
@@ -7615,7 +7743,7 @@ function runCheck(params) {
|
|
|
7615
7743
|
ambientCredential,
|
|
7616
7744
|
...keychain === void 0 ? {} : { keychain },
|
|
7617
7745
|
settingsExposure,
|
|
7618
|
-
credential: buildCredentialReport(params.provider, params.identity)
|
|
7746
|
+
credential: buildCredentialReport(params.provider, params.identity, params.identityName, params.credentialCache)
|
|
7619
7747
|
};
|
|
7620
7748
|
}
|
|
7621
7749
|
function formatCheckReport(report) {
|
|
@@ -7653,12 +7781,12 @@ function formatCheckReport(report) {
|
|
|
7653
7781
|
const { credential } = report;
|
|
7654
7782
|
if (credential.provider !== void 0) {
|
|
7655
7783
|
lines.push(
|
|
7656
|
-
` Provider ${credential.provider.name}: ${credential.provider.credential === void 0 ? `unusable: ${credential.provider.problem ?? ""}` : formatCredentialSummary(credential.provider.credential)}`
|
|
7784
|
+
` 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)}`}`
|
|
7657
7785
|
);
|
|
7658
7786
|
}
|
|
7659
7787
|
if (credential.identity !== void 0) {
|
|
7660
7788
|
lines.push(
|
|
7661
|
-
` Identity ${report.identityName ?? "(none)"}: ${formatCredentialSummary(credential.identity)}${credential.applies === "provider" ? " (not used: the provider's credential applies)" : ""}`
|
|
7789
|
+
` Identity ${report.identityName ?? "(none)"}: ${formatCredentialSummary(credential.identity)}${credential.identityCached === void 0 ? "" : `; ${formatCachedCredentialState(credential.identityCached)}`}${credential.applies === "provider" ? " (not used: the provider's credential applies)" : ""}`
|
|
7662
7790
|
);
|
|
7663
7791
|
}
|
|
7664
7792
|
if (credential.applies === "stored-login") {
|
|
@@ -7767,10 +7895,10 @@ function collectCheckReport(params) {
|
|
|
7767
7895
|
}).input;
|
|
7768
7896
|
const providerName = cascadeProviderName(cascade);
|
|
7769
7897
|
const provider = providerName === void 0 ? void 0 : loadCheckProvider(paths, providerName);
|
|
7770
|
-
const farmRoot = identityDecision.name === void 0 ? void 0 :
|
|
7898
|
+
const farmRoot = identityDecision.name === void 0 ? void 0 : path23.join(paths.identitiesDir, identityDecision.name);
|
|
7771
7899
|
const settingsFiles = {
|
|
7772
|
-
"settings.json": realFsPort.readFileUtf8(
|
|
7773
|
-
"settings.local.json": realFsPort.readFileUtf8(
|
|
7900
|
+
"settings.json": realFsPort.readFileUtf8(path23.join(claudeHome, "settings.json")),
|
|
7901
|
+
"settings.local.json": realFsPort.readFileUtf8(path23.join(claudeHome, "settings.local.json"))
|
|
7774
7902
|
};
|
|
7775
7903
|
const report = runCheck({
|
|
7776
7904
|
cwd,
|
|
@@ -7791,6 +7919,7 @@ function collectCheckReport(params) {
|
|
|
7791
7919
|
...loadedIdentity === void 0 ? {} : { identity: loadedIdentity.config },
|
|
7792
7920
|
settingsFiles,
|
|
7793
7921
|
run: realRunPort,
|
|
7922
|
+
credentialCache: realCredentialCacheEnv(paths),
|
|
7794
7923
|
...farmRoot === void 0 ? {} : { farmRoot },
|
|
7795
7924
|
platform: process.platform,
|
|
7796
7925
|
...provider === void 0 ? {} : { provider }
|
|
@@ -7799,8 +7928,8 @@ function collectCheckReport(params) {
|
|
|
7799
7928
|
}
|
|
7800
7929
|
|
|
7801
7930
|
// src/claudeShim.ts
|
|
7802
|
-
import
|
|
7803
|
-
import
|
|
7931
|
+
import fs9 from "node:fs";
|
|
7932
|
+
import path24 from "node:path";
|
|
7804
7933
|
import { z as z11 } from "zod";
|
|
7805
7934
|
var ClaudeShimStateSchema = z11.strictObject({
|
|
7806
7935
|
targetPath: z11.string().min(1),
|
|
@@ -7812,10 +7941,10 @@ function commandFilename(ownExecutablePath, commandName) {
|
|
|
7812
7941
|
}
|
|
7813
7942
|
function resolveOwnBinaryCheck(paths, contentSourcePath) {
|
|
7814
7943
|
const state = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
7815
|
-
const recordedTarget = state === void 0 ? void 0 :
|
|
7944
|
+
const recordedTarget = state === void 0 ? void 0 : path24.resolve(state.targetPath);
|
|
7816
7945
|
let ownStat;
|
|
7817
7946
|
return (candidate) => {
|
|
7818
|
-
if (recordedTarget !== void 0 &&
|
|
7947
|
+
if (recordedTarget !== void 0 && path24.resolve(candidate) === recordedTarget) {
|
|
7819
7948
|
return true;
|
|
7820
7949
|
}
|
|
7821
7950
|
ownStat ??= statOrUndefined(contentSourcePath);
|
|
@@ -7829,7 +7958,7 @@ function isEnoent4(error) {
|
|
|
7829
7958
|
}
|
|
7830
7959
|
function statOrUndefined(target) {
|
|
7831
7960
|
try {
|
|
7832
|
-
return
|
|
7961
|
+
return fs9.statSync(target);
|
|
7833
7962
|
} catch (error) {
|
|
7834
7963
|
if (isEnoent4(error)) {
|
|
7835
7964
|
return void 0;
|
|
@@ -7837,22 +7966,22 @@ function statOrUndefined(target) {
|
|
|
7837
7966
|
throw error;
|
|
7838
7967
|
}
|
|
7839
7968
|
}
|
|
7840
|
-
var nodeLinkFs = { link:
|
|
7969
|
+
var nodeLinkFs = { link: fs9.linkSync, copyFile: fs9.copyFileSync, chmod: fs9.chmodSync };
|
|
7841
7970
|
function findPathShadow(params) {
|
|
7842
|
-
const resolvedTargetDir =
|
|
7971
|
+
const resolvedTargetDir = path24.resolve(params.targetDir);
|
|
7843
7972
|
for (const dir of params.pathDirs) {
|
|
7844
7973
|
const found = params.findExecutableInDir(dir, params.targetFilename);
|
|
7845
7974
|
if (found === void 0) {
|
|
7846
7975
|
continue;
|
|
7847
7976
|
}
|
|
7848
|
-
return
|
|
7977
|
+
return path24.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
|
|
7849
7978
|
}
|
|
7850
|
-
return params.pathDirs.some((dir) =>
|
|
7979
|
+
return params.pathDirs.some((dir) => path24.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
|
|
7851
7980
|
}
|
|
7852
7981
|
|
|
7853
7982
|
// src/doctorReport.ts
|
|
7854
|
-
import
|
|
7855
|
-
import
|
|
7983
|
+
import fs10 from "node:fs";
|
|
7984
|
+
import path25 from "node:path";
|
|
7856
7985
|
function refinePathShadow(status, ownExecutablePath, realpath) {
|
|
7857
7986
|
if (status.status !== "shadowed") {
|
|
7858
7987
|
return status;
|
|
@@ -7876,7 +8005,7 @@ function validateJson(schema, input) {
|
|
|
7876
8005
|
return { ok: true, data: result.data };
|
|
7877
8006
|
}
|
|
7878
8007
|
function pushPathResolution(push, resolution) {
|
|
7879
|
-
const ownDir =
|
|
8008
|
+
const ownDir = path25.dirname(resolution.ownExecutablePath);
|
|
7880
8009
|
switch (resolution.agentShim.status) {
|
|
7881
8010
|
case "ok":
|
|
7882
8011
|
push("path-resolution", "pass", `\`agent-shim\` on PATH resolves to this running executable, ${resolution.ownExecutablePath}.`, "agent-shim");
|
|
@@ -7918,7 +8047,14 @@ function pushPathResolution(push, resolution) {
|
|
|
7918
8047
|
break;
|
|
7919
8048
|
}
|
|
7920
8049
|
}
|
|
7921
|
-
function
|
|
8050
|
+
function cacheClause(cacheEnv, owner, block) {
|
|
8051
|
+
if (cacheEnv === void 0 || block.cache === void 0) {
|
|
8052
|
+
return { text: "", unreadable: false };
|
|
8053
|
+
}
|
|
8054
|
+
const state = describeCachedCredential({ port: cacheEnv.port, platform: cacheEnv.platform, owner, cache: block.cache, nowMs: cacheEnv.now() });
|
|
8055
|
+
return { text: `; ${formatCachedCredentialState(state)}`, unreadable: state.status === "unreadable" };
|
|
8056
|
+
}
|
|
8057
|
+
function pushProvider(push, entry, cacheEnv) {
|
|
7922
8058
|
if (entry.raw === void 0) {
|
|
7923
8059
|
push("provider", "fail", `${entry.path} is missing.`, entry.name);
|
|
7924
8060
|
return;
|
|
@@ -7940,18 +8076,19 @@ function pushProvider(push, entry) {
|
|
|
7940
8076
|
push("provider", "fail", new ConfigValidationError(entry.path, validated.error.issues).message, entry.name);
|
|
7941
8077
|
return;
|
|
7942
8078
|
}
|
|
7943
|
-
|
|
8079
|
+
const cache = cacheClause(cacheEnv, `provider ${entry.name}`, validated.data.credential);
|
|
8080
|
+
push("provider", cache.unreadable ? "fail" : "pass", `${entry.name} is valid (${describeProviderEndpoint(validated.data)}, credential ${describeCredential(validated.data.credential)})${cache.text}.`, entry.name);
|
|
7944
8081
|
}
|
|
7945
8082
|
function pushLegacyName(push, params) {
|
|
7946
8083
|
const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
|
|
7947
|
-
if (legacyVariables.length === 0 &&
|
|
8084
|
+
if (legacyVariables.length === 0 && path25.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
|
|
7948
8085
|
push("legacy-name", "pass", "Nothing here still uses the former `claude-use` name.");
|
|
7949
8086
|
return;
|
|
7950
8087
|
}
|
|
7951
8088
|
for (const name of legacyVariables) {
|
|
7952
8089
|
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);
|
|
7953
8090
|
}
|
|
7954
|
-
if (
|
|
8091
|
+
if (path25.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
|
|
7955
8092
|
push(
|
|
7956
8093
|
"legacy-name",
|
|
7957
8094
|
"warn",
|
|
@@ -8033,10 +8170,11 @@ function runDoctor(params) {
|
|
|
8033
8170
|
);
|
|
8034
8171
|
} else {
|
|
8035
8172
|
const credential = validated.data.credential;
|
|
8173
|
+
const cache = credential === void 0 ? { text: "", unreadable: false } : cacheClause(params.credentialCache, `identity ${entry.name}`, credential);
|
|
8036
8174
|
push(
|
|
8037
8175
|
"identity",
|
|
8038
|
-
"pass",
|
|
8039
|
-
`${entry.name} is valid and authenticates with ${credential === void 0 ? "its stored login" : `credential ${describeCredential(credential)}`}.`,
|
|
8176
|
+
cache.unreadable ? "fail" : "pass",
|
|
8177
|
+
`${entry.name} is valid and authenticates with ${credential === void 0 ? "its stored login" : `credential ${describeCredential(credential)}`}${cache.text}.`,
|
|
8040
8178
|
entry.name
|
|
8041
8179
|
);
|
|
8042
8180
|
}
|
|
@@ -8056,7 +8194,7 @@ function runDoctor(params) {
|
|
|
8056
8194
|
return poolName === void 0 ? validIdentityNames.has(selector) : poolName in pools;
|
|
8057
8195
|
};
|
|
8058
8196
|
for (const entry of params.providers) {
|
|
8059
|
-
pushProvider(push, entry);
|
|
8197
|
+
pushProvider(push, entry, params.credentialCache);
|
|
8060
8198
|
}
|
|
8061
8199
|
if (params.platform !== "darwin" || params.run === void 0) {
|
|
8062
8200
|
push("keychain", "pass", "Skipped (not macOS).");
|
|
@@ -8250,27 +8388,27 @@ function formatDoctorReport(report) {
|
|
|
8250
8388
|
}
|
|
8251
8389
|
function realpathOrSelf(target) {
|
|
8252
8390
|
try {
|
|
8253
|
-
return
|
|
8391
|
+
return fs10.realpathSync(target);
|
|
8254
8392
|
} catch {
|
|
8255
8393
|
return target;
|
|
8256
8394
|
}
|
|
8257
8395
|
}
|
|
8258
8396
|
function collectDoctorReport(params) {
|
|
8259
8397
|
const { paths } = params;
|
|
8260
|
-
const identityNames =
|
|
8398
|
+
const identityNames = fs10.existsSync(paths.identitiesDir) ? fs10.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort() : [];
|
|
8261
8399
|
const identities = identityNames.map((name) => {
|
|
8262
|
-
const farmRoot =
|
|
8263
|
-
const identityPath =
|
|
8400
|
+
const farmRoot = path25.join(paths.identitiesDir, name);
|
|
8401
|
+
const identityPath = path25.join(farmRoot, "identity.json");
|
|
8264
8402
|
return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot };
|
|
8265
8403
|
});
|
|
8266
|
-
const profileNames =
|
|
8404
|
+
const profileNames = fs10.existsSync(paths.configProfilesDir) ? fs10.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
8267
8405
|
const configProfiles = profileNames.map((name) => {
|
|
8268
|
-
const profilePath =
|
|
8406
|
+
const profilePath = path25.join(paths.configProfilesDir, `${name}.json`);
|
|
8269
8407
|
return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
|
|
8270
8408
|
});
|
|
8271
|
-
const providerNames =
|
|
8409
|
+
const providerNames = fs10.existsSync(paths.providersDir) ? fs10.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
8272
8410
|
const providers = providerNames.map((name) => {
|
|
8273
|
-
const providerPath =
|
|
8411
|
+
const providerPath = path25.join(paths.providersDir, `${name}.json`);
|
|
8274
8412
|
return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
|
|
8275
8413
|
});
|
|
8276
8414
|
const ownExecutablePath = realOwnExecutablePath();
|
|
@@ -8282,12 +8420,12 @@ function collectDoctorReport(params) {
|
|
|
8282
8420
|
binaryDiscovery = { ok: false, message: error instanceof Error ? error.message : String(error) };
|
|
8283
8421
|
}
|
|
8284
8422
|
const shimState = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
8285
|
-
const pathDirs = (params.env.PATH ?? "").split(
|
|
8423
|
+
const pathDirs = (params.env.PATH ?? "").split(path25.delimiter).filter((dir) => dir !== "");
|
|
8286
8424
|
const claudeShimShadow = shimState === void 0 ? void 0 : refinePathShadow(
|
|
8287
8425
|
findPathShadow({
|
|
8288
8426
|
pathDirs,
|
|
8289
|
-
targetDir:
|
|
8290
|
-
targetFilename:
|
|
8427
|
+
targetDir: path25.dirname(shimState.targetPath),
|
|
8428
|
+
targetFilename: path25.basename(shimState.targetPath),
|
|
8291
8429
|
findExecutableInDir
|
|
8292
8430
|
}),
|
|
8293
8431
|
shimState.targetPath,
|
|
@@ -8295,6 +8433,7 @@ function collectDoctorReport(params) {
|
|
|
8295
8433
|
);
|
|
8296
8434
|
const report = runDoctor({
|
|
8297
8435
|
env: params.env,
|
|
8436
|
+
credentialCache: realCredentialCacheEnv(paths),
|
|
8298
8437
|
identities,
|
|
8299
8438
|
configProfiles,
|
|
8300
8439
|
providers,
|
|
@@ -8303,14 +8442,14 @@ function collectDoctorReport(params) {
|
|
|
8303
8442
|
categoriesLocal: { path: paths.categoriesLocalFile, raw: realFsPort.readFileUtf8(paths.categoriesLocalFile) },
|
|
8304
8443
|
activeIdentity: { path: paths.activeIdentityFile, raw: realFsPort.readFileUtf8(paths.activeIdentityFile) },
|
|
8305
8444
|
binaryDiscovery,
|
|
8306
|
-
claudeShim: { state: shimState, targetExists: shimState !== void 0 &&
|
|
8445
|
+
claudeShim: { state: shimState, targetExists: shimState !== void 0 && fs10.existsSync(shimState.targetPath) },
|
|
8307
8446
|
rootPath: paths.root,
|
|
8308
8447
|
pathResolution: {
|
|
8309
8448
|
ownExecutablePath,
|
|
8310
8449
|
agentShim: refinePathShadow(
|
|
8311
8450
|
findPathShadow({
|
|
8312
8451
|
pathDirs,
|
|
8313
|
-
targetDir:
|
|
8452
|
+
targetDir: path25.dirname(ownExecutablePath),
|
|
8314
8453
|
targetFilename: commandFilename(ownExecutablePath, "agent-shim"),
|
|
8315
8454
|
findExecutableInDir
|
|
8316
8455
|
}),
|
|
@@ -8331,7 +8470,7 @@ function collectDoctorReport(params) {
|
|
|
8331
8470
|
|
|
8332
8471
|
// src/launcher.ts
|
|
8333
8472
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
8334
|
-
import
|
|
8473
|
+
import path27 from "node:path";
|
|
8335
8474
|
|
|
8336
8475
|
// src/launcher/argv.ts
|
|
8337
8476
|
var ConflictingIdentityError = class extends UsageError {
|
|
@@ -8583,7 +8722,7 @@ function buildCliOverride(params) {
|
|
|
8583
8722
|
}
|
|
8584
8723
|
|
|
8585
8724
|
// src/launcher/flags.ts
|
|
8586
|
-
import
|
|
8725
|
+
import path26 from "node:path";
|
|
8587
8726
|
|
|
8588
8727
|
// src/headroom/headers.ts
|
|
8589
8728
|
function mergeAnthropicCustomHeaders(existing, additions) {
|
|
@@ -8653,7 +8792,7 @@ function buildEnv(params) {
|
|
|
8653
8792
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
8654
8793
|
let providerCustomHeaders;
|
|
8655
8794
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
8656
|
-
env.CLAUDE_CONFIG_DIR =
|
|
8795
|
+
env.CLAUDE_CONFIG_DIR = path26.join(params.identitiesDir, params.resolvedIdentityName);
|
|
8657
8796
|
}
|
|
8658
8797
|
if (params.provider !== void 0) {
|
|
8659
8798
|
const providerEnv = params.provider.definition.env ?? {};
|
|
@@ -8814,7 +8953,7 @@ function prepareLaunch(params) {
|
|
|
8814
8953
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
8815
8954
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
8816
8955
|
});
|
|
8817
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(
|
|
8956
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(path27.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
8818
8957
|
log.error(
|
|
8819
8958
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
8820
8959
|
);
|
|
@@ -8987,84 +9126,6 @@ function prepareLaunch(params) {
|
|
|
8987
9126
|
import os5 from "node:os";
|
|
8988
9127
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
8989
9128
|
|
|
8990
|
-
// src/realCredentialCache.ts
|
|
8991
|
-
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
8992
|
-
import fs10 from "node:fs";
|
|
8993
|
-
import path27 from "node:path";
|
|
8994
|
-
var KEYCHAIN_CACHE_SERVICE = "agent-shim-credential-cache";
|
|
8995
|
-
var CACHE_DIR_MODE = 448;
|
|
8996
|
-
var CACHE_FILE_MODE = 384;
|
|
8997
|
-
function cacheFileNameFor(owner) {
|
|
8998
|
-
return `${owner.replace(/[^A-Za-z0-9._-]/g, "_")}.json`;
|
|
8999
|
-
}
|
|
9000
|
-
function parseEntry(raw) {
|
|
9001
|
-
let json;
|
|
9002
|
-
try {
|
|
9003
|
-
json = JSON.parse(raw);
|
|
9004
|
-
} catch {
|
|
9005
|
-
return void 0;
|
|
9006
|
-
}
|
|
9007
|
-
const parsed = CachedCredentialSchema.safeParse(json);
|
|
9008
|
-
return parsed.success ? parsed.data : void 0;
|
|
9009
|
-
}
|
|
9010
|
-
function requireKeychain() {
|
|
9011
|
-
if (process.platform !== "darwin") {
|
|
9012
|
-
throw new Error("the keychain credential store needs macOS; use --credential-cache-store file");
|
|
9013
|
-
}
|
|
9014
|
-
}
|
|
9015
|
-
function security(args, stdin) {
|
|
9016
|
-
const result = spawnSync2("security", args, { encoding: "utf8", ...stdin === void 0 ? {} : { input: stdin }, stdio: ["pipe", "pipe", "ignore"] });
|
|
9017
|
-
return { status: result.status, stdout: result.stdout };
|
|
9018
|
-
}
|
|
9019
|
-
function createRealCredentialCache(root) {
|
|
9020
|
-
const dir = path27.join(root, "credential-cache");
|
|
9021
|
-
const filePath = (owner) => path27.join(dir, cacheFileNameFor(owner));
|
|
9022
|
-
return {
|
|
9023
|
-
read(store, owner) {
|
|
9024
|
-
if (store === "file") {
|
|
9025
|
-
try {
|
|
9026
|
-
return parseEntry(fs10.readFileSync(filePath(owner), "utf8"));
|
|
9027
|
-
} catch {
|
|
9028
|
-
return void 0;
|
|
9029
|
-
}
|
|
9030
|
-
}
|
|
9031
|
-
requireKeychain();
|
|
9032
|
-
const result = security(["find-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner, "-w"]);
|
|
9033
|
-
return result.status === 0 ? parseEntry(Buffer.from(result.stdout.trim(), "base64").toString("utf8")) : void 0;
|
|
9034
|
-
},
|
|
9035
|
-
write(store, owner, entry) {
|
|
9036
|
-
const serialised = JSON.stringify(entry);
|
|
9037
|
-
if (store === "file") {
|
|
9038
|
-
fs10.mkdirSync(dir, { recursive: true, mode: CACHE_DIR_MODE });
|
|
9039
|
-
fs10.chmodSync(dir, CACHE_DIR_MODE);
|
|
9040
|
-
const target = filePath(owner);
|
|
9041
|
-
const temp = `${target}.${String(process.pid)}.tmp`;
|
|
9042
|
-
fs10.writeFileSync(temp, serialised, { mode: CACHE_FILE_MODE });
|
|
9043
|
-
fs10.renameSync(temp, target);
|
|
9044
|
-
return;
|
|
9045
|
-
}
|
|
9046
|
-
requireKeychain();
|
|
9047
|
-
const encoded = Buffer.from(serialised, "utf8").toString("base64");
|
|
9048
|
-
const result = security(["-i"], `add-generic-password -U -s ${KEYCHAIN_CACHE_SERVICE} -a ${JSON.stringify(owner)} -w ${encoded}
|
|
9049
|
-
`);
|
|
9050
|
-
if (result.status !== 0) {
|
|
9051
|
-
throw new Error(`could not write the keychain credential cache for ${owner}`);
|
|
9052
|
-
}
|
|
9053
|
-
},
|
|
9054
|
-
remove(store, owner) {
|
|
9055
|
-
if (store === "file") {
|
|
9056
|
-
fs10.rmSync(filePath(owner), { force: true });
|
|
9057
|
-
return;
|
|
9058
|
-
}
|
|
9059
|
-
requireKeychain();
|
|
9060
|
-
security(["delete-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner]);
|
|
9061
|
-
}
|
|
9062
|
-
};
|
|
9063
|
-
}
|
|
9064
|
-
function realCredentialCacheEnv(paths) {
|
|
9065
|
-
return { port: createRealCredentialCache(paths.root), platform: process.platform, now: () => Date.now() };
|
|
9066
|
-
}
|
|
9067
|
-
|
|
9068
9129
|
// src/frontdoor/realFrontDoorPort.ts
|
|
9069
9130
|
import fs11 from "node:fs";
|
|
9070
9131
|
|