claude-use 6.2.2 → 7.1.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/README.md +90 -79
- package/dist/cli.cjs +716 -621
- package/dist/index.cjs +56 -41
- package/dist/index.mjs +56 -41
- package/dist/types/cliError.d.ts +1 -1
- package/dist/types/config/classify.d.ts +3 -3
- package/dist/types/config/schema.d.ts +13 -13
- package/dist/types/frontdoor/capability.d.ts +3 -3
- package/dist/types/frontdoor/connect.d.ts +2 -2
- package/dist/types/frontdoor/ensure.d.ts +2 -2
- package/dist/types/frontdoor/probe.d.ts +1 -1
- package/dist/types/frontdoor/supervisor.d.ts +1 -1
- package/dist/types/frontdoor/x509.d.ts +1 -1
- package/dist/types/headroom/source.d.ts +8 -0
- package/dist/types/headroom/state.d.ts +1 -1
- package/dist/types/headroom/supervisor.d.ts +2 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/launcher/farm.d.ts +5 -5
- package/dist/types/launcher/guard.d.ts +3 -3
- package/dist/types/launcher/lock.d.ts +1 -1
- package/dist/types/launcher/ports.d.ts +3 -3
- package/dist/types/legacy.d.ts +24 -0
- package/dist/types/paths.d.ts +12 -10
- package/dist/types/resolve/conditions.d.ts +1 -1
- package/dist/types/resolve/match.d.ts +1 -1
- package/dist/types/resolve/reconcile.d.ts +1 -1
- package/dist/types/resolve/types.d.ts +3 -3
- package/dist/types/resolve/walk.d.ts +6 -6
- package/dist/types/usage/read.d.ts +1 -1
- package/dist/types/usage/schema.d.ts +2 -2
- package/package.json +5 -4
package/dist/cli.cjs
CHANGED
|
@@ -3248,42 +3248,42 @@ var require_defaults = __commonJS({
|
|
|
3248
3248
|
var require_env_paths = __commonJS({
|
|
3249
3249
|
"node_modules/.pnpm/env-paths@2.2.1/node_modules/env-paths/index.js"(exports2, module2) {
|
|
3250
3250
|
"use strict";
|
|
3251
|
-
var
|
|
3251
|
+
var path36 = require("path");
|
|
3252
3252
|
var os9 = require("os");
|
|
3253
3253
|
var homedir = os9.homedir();
|
|
3254
3254
|
var tmpdir = os9.tmpdir();
|
|
3255
3255
|
var { env } = process;
|
|
3256
3256
|
var macos = (name) => {
|
|
3257
|
-
const library =
|
|
3257
|
+
const library = path36.join(homedir, "Library");
|
|
3258
3258
|
return {
|
|
3259
|
-
data:
|
|
3260
|
-
config:
|
|
3261
|
-
cache:
|
|
3262
|
-
log:
|
|
3263
|
-
temp:
|
|
3259
|
+
data: path36.join(library, "Application Support", name),
|
|
3260
|
+
config: path36.join(library, "Preferences", name),
|
|
3261
|
+
cache: path36.join(library, "Caches", name),
|
|
3262
|
+
log: path36.join(library, "Logs", name),
|
|
3263
|
+
temp: path36.join(tmpdir, name)
|
|
3264
3264
|
};
|
|
3265
3265
|
};
|
|
3266
3266
|
var windows = (name) => {
|
|
3267
|
-
const appData = env.APPDATA ||
|
|
3268
|
-
const localAppData = env.LOCALAPPDATA ||
|
|
3267
|
+
const appData = env.APPDATA || path36.join(homedir, "AppData", "Roaming");
|
|
3268
|
+
const localAppData = env.LOCALAPPDATA || path36.join(homedir, "AppData", "Local");
|
|
3269
3269
|
return {
|
|
3270
3270
|
// Data/config/cache/log are invented by me as Windows isn't opinionated about this
|
|
3271
|
-
data:
|
|
3272
|
-
config:
|
|
3273
|
-
cache:
|
|
3274
|
-
log:
|
|
3275
|
-
temp:
|
|
3271
|
+
data: path36.join(localAppData, name, "Data"),
|
|
3272
|
+
config: path36.join(appData, name, "Config"),
|
|
3273
|
+
cache: path36.join(localAppData, name, "Cache"),
|
|
3274
|
+
log: path36.join(localAppData, name, "Log"),
|
|
3275
|
+
temp: path36.join(tmpdir, name)
|
|
3276
3276
|
};
|
|
3277
3277
|
};
|
|
3278
3278
|
var linux = (name) => {
|
|
3279
|
-
const username =
|
|
3279
|
+
const username = path36.basename(homedir);
|
|
3280
3280
|
return {
|
|
3281
|
-
data:
|
|
3282
|
-
config:
|
|
3283
|
-
cache:
|
|
3281
|
+
data: path36.join(env.XDG_DATA_HOME || path36.join(homedir, ".local", "share"), name),
|
|
3282
|
+
config: path36.join(env.XDG_CONFIG_HOME || path36.join(homedir, ".config"), name),
|
|
3283
|
+
cache: path36.join(env.XDG_CACHE_HOME || path36.join(homedir, ".cache"), name),
|
|
3284
3284
|
// https://wiki.debian.org/XDGBaseDirectorySpecification#state
|
|
3285
|
-
log:
|
|
3286
|
-
temp:
|
|
3285
|
+
log: path36.join(env.XDG_STATE_HOME || path36.join(homedir, ".local", "state"), name),
|
|
3286
|
+
temp: path36.join(tmpdir, username, name)
|
|
3287
3287
|
};
|
|
3288
3288
|
};
|
|
3289
3289
|
var envPaths = (name, options) => {
|
|
@@ -3351,11 +3351,11 @@ var require_util = __commonJS({
|
|
|
3351
3351
|
return result;
|
|
3352
3352
|
}
|
|
3353
3353
|
exports2.emplace = emplace;
|
|
3354
|
-
function getPropertyByPath(source,
|
|
3355
|
-
if (typeof
|
|
3356
|
-
return source[
|
|
3354
|
+
function getPropertyByPath(source, path36) {
|
|
3355
|
+
if (typeof path36 === "string" && Object.prototype.hasOwnProperty.call(source, path36)) {
|
|
3356
|
+
return source[path36];
|
|
3357
3357
|
}
|
|
3358
|
-
const parsedPath = typeof
|
|
3358
|
+
const parsedPath = typeof path36 === "string" ? path36.split(".") : path36;
|
|
3359
3359
|
return parsedPath.reduce((previous, key) => {
|
|
3360
3360
|
if (previous === void 0) {
|
|
3361
3361
|
return previous;
|
|
@@ -3378,9 +3378,9 @@ var require_util = __commonJS({
|
|
|
3378
3378
|
return Object.fromEntries(Object.entries(options).filter(([, value]) => value !== void 0));
|
|
3379
3379
|
}
|
|
3380
3380
|
exports2.removeUndefinedValuesFromObject = removeUndefinedValuesFromObject;
|
|
3381
|
-
async function isDirectory(
|
|
3381
|
+
async function isDirectory(path36) {
|
|
3382
3382
|
try {
|
|
3383
|
-
const stat = await fs_1.promises.stat(
|
|
3383
|
+
const stat = await fs_1.promises.stat(path36);
|
|
3384
3384
|
return stat.isDirectory();
|
|
3385
3385
|
} catch (e) {
|
|
3386
3386
|
if (e.code === "ENOENT") {
|
|
@@ -3390,9 +3390,9 @@ var require_util = __commonJS({
|
|
|
3390
3390
|
}
|
|
3391
3391
|
}
|
|
3392
3392
|
exports2.isDirectory = isDirectory;
|
|
3393
|
-
function isDirectorySync(
|
|
3393
|
+
function isDirectorySync(path36) {
|
|
3394
3394
|
try {
|
|
3395
|
-
const stat = fs_1.default.statSync(
|
|
3395
|
+
const stat = fs_1.default.statSync(path36);
|
|
3396
3396
|
return stat.isDirectory();
|
|
3397
3397
|
} catch (e) {
|
|
3398
3398
|
if (e.code === "ENOENT") {
|
|
@@ -3490,7 +3490,7 @@ var require_ExplorerBase = __commonJS({
|
|
|
3490
3490
|
const idx = importStack.indexOf(fullPath);
|
|
3491
3491
|
if (idx !== -1) {
|
|
3492
3492
|
throw new Error(`Circular import detected:
|
|
3493
|
-
${[...importStack, fullPath].map((
|
|
3493
|
+
${[...importStack, fullPath].map((path36, i2) => `${i2 + 1}. ${path36}`).join("\n")} (same as ${idx + 1}.)`);
|
|
3494
3494
|
}
|
|
3495
3495
|
}
|
|
3496
3496
|
}
|
|
@@ -3678,9 +3678,9 @@ var require_Explorer = __commonJS({
|
|
|
3678
3678
|
throw error62;
|
|
3679
3679
|
}
|
|
3680
3680
|
}
|
|
3681
|
-
async #fileExists(
|
|
3681
|
+
async #fileExists(path36) {
|
|
3682
3682
|
try {
|
|
3683
|
-
await promises_1.default.stat(
|
|
3683
|
+
await promises_1.default.stat(path36);
|
|
3684
3684
|
return true;
|
|
3685
3685
|
} catch (e) {
|
|
3686
3686
|
return false;
|
|
@@ -3840,9 +3840,9 @@ var require_ExplorerSync = __commonJS({
|
|
|
3840
3840
|
throw error62;
|
|
3841
3841
|
}
|
|
3842
3842
|
}
|
|
3843
|
-
#fileExists(
|
|
3843
|
+
#fileExists(path36) {
|
|
3844
3844
|
try {
|
|
3845
|
-
fs_1.default.statSync(
|
|
3845
|
+
fs_1.default.statSync(path36);
|
|
3846
3846
|
return true;
|
|
3847
3847
|
} catch (e) {
|
|
3848
3848
|
return false;
|
|
@@ -3966,7 +3966,7 @@ var require_dist = __commonJS({
|
|
|
3966
3966
|
};
|
|
3967
3967
|
}
|
|
3968
3968
|
function getResolvedSearchPlaces(moduleName, toolDefinedSearchPlaces, userConfiguredOptions) {
|
|
3969
|
-
const userConfiguredSearchPlaces = userConfiguredOptions.searchPlaces?.map((
|
|
3969
|
+
const userConfiguredSearchPlaces = userConfiguredOptions.searchPlaces?.map((path36) => path36.replace("{name}", moduleName));
|
|
3970
3970
|
if (userConfiguredOptions.mergeSearchPlaces) {
|
|
3971
3971
|
return [...userConfiguredSearchPlaces ?? [], ...toolDefinedSearchPlaces];
|
|
3972
3972
|
}
|
|
@@ -4374,8 +4374,8 @@ var require_utils = __commonJS({
|
|
|
4374
4374
|
}
|
|
4375
4375
|
return output2;
|
|
4376
4376
|
};
|
|
4377
|
-
exports2.basename = (
|
|
4378
|
-
const segs =
|
|
4377
|
+
exports2.basename = (path36, { windows } = {}) => {
|
|
4378
|
+
const segs = path36.split(windows ? /[\\/]/ : "/");
|
|
4379
4379
|
const last = segs[segs.length - 1];
|
|
4380
4380
|
if (last === "") {
|
|
4381
4381
|
return segs[segs.length - 2];
|
|
@@ -7003,14 +7003,14 @@ var require_util2 = __commonJS({
|
|
|
7003
7003
|
}
|
|
7004
7004
|
const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
|
|
7005
7005
|
let origin = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
|
|
7006
|
-
let
|
|
7006
|
+
let path36 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
|
|
7007
7007
|
if (origin[origin.length - 1] === "/") {
|
|
7008
7008
|
origin = origin.slice(0, origin.length - 1);
|
|
7009
7009
|
}
|
|
7010
|
-
if (
|
|
7011
|
-
|
|
7010
|
+
if (path36 && path36[0] !== "/") {
|
|
7011
|
+
path36 = `/${path36}`;
|
|
7012
7012
|
}
|
|
7013
|
-
return new URL(`${origin}${
|
|
7013
|
+
return new URL(`${origin}${path36}`);
|
|
7014
7014
|
}
|
|
7015
7015
|
if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
|
|
7016
7016
|
throw new InvalidArgumentError2("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -7831,9 +7831,9 @@ var require_diagnostics = __commonJS({
|
|
|
7831
7831
|
"undici:client:sendHeaders",
|
|
7832
7832
|
(evt) => {
|
|
7833
7833
|
const {
|
|
7834
|
-
request: { method, path:
|
|
7834
|
+
request: { method, path: path36, origin }
|
|
7835
7835
|
} = evt;
|
|
7836
|
-
debugLog("sending request to %s %s%s", method, origin,
|
|
7836
|
+
debugLog("sending request to %s %s%s", method, origin, path36);
|
|
7837
7837
|
}
|
|
7838
7838
|
);
|
|
7839
7839
|
}
|
|
@@ -7851,14 +7851,14 @@ var require_diagnostics = __commonJS({
|
|
|
7851
7851
|
"undici:request:headers",
|
|
7852
7852
|
(evt) => {
|
|
7853
7853
|
const {
|
|
7854
|
-
request: { method, path:
|
|
7854
|
+
request: { method, path: path36, origin },
|
|
7855
7855
|
response: { statusCode }
|
|
7856
7856
|
} = evt;
|
|
7857
7857
|
debugLog(
|
|
7858
7858
|
"received response to %s %s%s - HTTP %d",
|
|
7859
7859
|
method,
|
|
7860
7860
|
origin,
|
|
7861
|
-
|
|
7861
|
+
path36,
|
|
7862
7862
|
statusCode
|
|
7863
7863
|
);
|
|
7864
7864
|
}
|
|
@@ -7867,23 +7867,23 @@ var require_diagnostics = __commonJS({
|
|
|
7867
7867
|
"undici:request:trailers",
|
|
7868
7868
|
(evt) => {
|
|
7869
7869
|
const {
|
|
7870
|
-
request: { method, path:
|
|
7870
|
+
request: { method, path: path36, origin }
|
|
7871
7871
|
} = evt;
|
|
7872
|
-
debugLog("trailers received from %s %s%s", method, origin,
|
|
7872
|
+
debugLog("trailers received from %s %s%s", method, origin, path36);
|
|
7873
7873
|
}
|
|
7874
7874
|
);
|
|
7875
7875
|
diagnosticsChannel.subscribe(
|
|
7876
7876
|
"undici:request:error",
|
|
7877
7877
|
(evt) => {
|
|
7878
7878
|
const {
|
|
7879
|
-
request: { method, path:
|
|
7879
|
+
request: { method, path: path36, origin },
|
|
7880
7880
|
error: error62
|
|
7881
7881
|
} = evt;
|
|
7882
7882
|
debugLog(
|
|
7883
7883
|
"request to %s %s%s errored - %s",
|
|
7884
7884
|
method,
|
|
7885
7885
|
origin,
|
|
7886
|
-
|
|
7886
|
+
path36,
|
|
7887
7887
|
error62.message
|
|
7888
7888
|
);
|
|
7889
7889
|
}
|
|
@@ -7998,7 +7998,7 @@ var require_request = __commonJS({
|
|
|
7998
7998
|
var kHandler = /* @__PURE__ */ Symbol("handler");
|
|
7999
7999
|
var Request = class {
|
|
8000
8000
|
constructor(origin, {
|
|
8001
|
-
path:
|
|
8001
|
+
path: path36,
|
|
8002
8002
|
method,
|
|
8003
8003
|
body,
|
|
8004
8004
|
headers,
|
|
@@ -8015,11 +8015,11 @@ var require_request = __commonJS({
|
|
|
8015
8015
|
maxRedirections,
|
|
8016
8016
|
typeOfService
|
|
8017
8017
|
}, handler) {
|
|
8018
|
-
if (typeof
|
|
8018
|
+
if (typeof path36 !== "string") {
|
|
8019
8019
|
throw new InvalidArgumentError2("path must be a string");
|
|
8020
|
-
} else if (
|
|
8020
|
+
} else if (path36[0] !== "/" && !(path36.startsWith("http://") || path36.startsWith("https://")) && method !== "CONNECT") {
|
|
8021
8021
|
throw new InvalidArgumentError2("path must be an absolute URL or start with a slash");
|
|
8022
|
-
} else if (invalidPathRegex.test(
|
|
8022
|
+
} else if (invalidPathRegex.test(path36)) {
|
|
8023
8023
|
throw new InvalidArgumentError2("invalid request path");
|
|
8024
8024
|
}
|
|
8025
8025
|
if (typeof method !== "string") {
|
|
@@ -8094,7 +8094,7 @@ var require_request = __commonJS({
|
|
|
8094
8094
|
this.completed = false;
|
|
8095
8095
|
this.aborted = false;
|
|
8096
8096
|
this.upgrade = upgrade || null;
|
|
8097
|
-
this.path = query ? serializePathWithQuery(
|
|
8097
|
+
this.path = query ? serializePathWithQuery(path36, query) : path36;
|
|
8098
8098
|
this.origin = origin;
|
|
8099
8099
|
this.protocol = getProtocolFromUrlString(origin);
|
|
8100
8100
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
@@ -13276,7 +13276,7 @@ var require_client_h1 = __commonJS({
|
|
|
13276
13276
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
13277
13277
|
}
|
|
13278
13278
|
function writeH1(client, request6) {
|
|
13279
|
-
const { method, path:
|
|
13279
|
+
const { method, path: path36, host, upgrade, blocking, reset } = request6;
|
|
13280
13280
|
let { body, headers, contentLength } = request6;
|
|
13281
13281
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
13282
13282
|
if (util.isFormDataLike(body)) {
|
|
@@ -13354,7 +13354,7 @@ var require_client_h1 = __commonJS({
|
|
|
13354
13354
|
if (socket.setTypeOfService) {
|
|
13355
13355
|
socket.setTypeOfService(request6.typeOfService);
|
|
13356
13356
|
}
|
|
13357
|
-
let header = `${method} ${
|
|
13357
|
+
let header = `${method} ${path36} HTTP/1.1\r
|
|
13358
13358
|
`;
|
|
13359
13359
|
if (typeof host === "string") {
|
|
13360
13360
|
header += `host: ${host}\r
|
|
@@ -14033,7 +14033,7 @@ var require_client_h2 = __commonJS({
|
|
|
14033
14033
|
const headersTimeout = request6.headersTimeout ?? client[kHeadersTimeout];
|
|
14034
14034
|
const bodyTimeout = request6.bodyTimeout ?? client[kBodyTimeout];
|
|
14035
14035
|
const session = client[kHTTP2Session];
|
|
14036
|
-
const { method, path:
|
|
14036
|
+
const { method, path: path36, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request6;
|
|
14037
14037
|
let { body } = request6;
|
|
14038
14038
|
if (upgrade != null && upgrade !== "websocket") {
|
|
14039
14039
|
util.errorRequest(client, request6, new InvalidArgumentError2(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
@@ -14102,7 +14102,7 @@ var require_client_h2 = __commonJS({
|
|
|
14102
14102
|
}
|
|
14103
14103
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
14104
14104
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
14105
|
-
headers[HTTP2_HEADER_PATH] =
|
|
14105
|
+
headers[HTTP2_HEADER_PATH] = path36;
|
|
14106
14106
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
14107
14107
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
14108
14108
|
} else {
|
|
@@ -14144,7 +14144,7 @@ var require_client_h2 = __commonJS({
|
|
|
14144
14144
|
stream.setTimeout(headersTimeout);
|
|
14145
14145
|
return true;
|
|
14146
14146
|
}
|
|
14147
|
-
headers[HTTP2_HEADER_PATH] =
|
|
14147
|
+
headers[HTTP2_HEADER_PATH] = path36;
|
|
14148
14148
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
14149
14149
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
14150
14150
|
if (body && typeof body.read === "function") {
|
|
@@ -16496,10 +16496,10 @@ var require_proxy_agent = __commonJS({
|
|
|
16496
16496
|
};
|
|
16497
16497
|
const {
|
|
16498
16498
|
origin,
|
|
16499
|
-
path:
|
|
16499
|
+
path: path36 = "/",
|
|
16500
16500
|
headers = {}
|
|
16501
16501
|
} = opts;
|
|
16502
|
-
opts.path = origin +
|
|
16502
|
+
opts.path = origin + path36;
|
|
16503
16503
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
16504
16504
|
const { host } = new URL(origin);
|
|
16505
16505
|
headers.host = host;
|
|
@@ -18608,20 +18608,20 @@ var require_mock_utils = __commonJS({
|
|
|
18608
18608
|
}
|
|
18609
18609
|
return normalizedQp;
|
|
18610
18610
|
}
|
|
18611
|
-
function safeUrl(
|
|
18612
|
-
if (typeof
|
|
18613
|
-
return
|
|
18611
|
+
function safeUrl(path36) {
|
|
18612
|
+
if (typeof path36 !== "string") {
|
|
18613
|
+
return path36;
|
|
18614
18614
|
}
|
|
18615
|
-
const pathSegments =
|
|
18615
|
+
const pathSegments = path36.split("?", 3);
|
|
18616
18616
|
if (pathSegments.length !== 2) {
|
|
18617
|
-
return
|
|
18617
|
+
return path36;
|
|
18618
18618
|
}
|
|
18619
18619
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
18620
18620
|
qp.sort();
|
|
18621
18621
|
return [...pathSegments, qp.toString()].join("?");
|
|
18622
18622
|
}
|
|
18623
|
-
function matchKey(mockDispatch2, { path:
|
|
18624
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
18623
|
+
function matchKey(mockDispatch2, { path: path36, method, body, headers }) {
|
|
18624
|
+
const pathMatch = matchValue(mockDispatch2.path, path36);
|
|
18625
18625
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
18626
18626
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
18627
18627
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -18646,8 +18646,8 @@ var require_mock_utils = __commonJS({
|
|
|
18646
18646
|
const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
|
|
18647
18647
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
18648
18648
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
18649
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
18650
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(
|
|
18649
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path36, ignoreTrailingSlash }) => {
|
|
18650
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path36)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path36), resolvedPath);
|
|
18651
18651
|
});
|
|
18652
18652
|
if (matchedMockDispatches.length === 0) {
|
|
18653
18653
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -18686,19 +18686,19 @@ var require_mock_utils = __commonJS({
|
|
|
18686
18686
|
mockDispatches.splice(index, 1);
|
|
18687
18687
|
}
|
|
18688
18688
|
}
|
|
18689
|
-
function removeTrailingSlash(
|
|
18690
|
-
while (
|
|
18691
|
-
|
|
18689
|
+
function removeTrailingSlash(path36) {
|
|
18690
|
+
while (path36.endsWith("/")) {
|
|
18691
|
+
path36 = path36.slice(0, -1);
|
|
18692
18692
|
}
|
|
18693
|
-
if (
|
|
18694
|
-
|
|
18693
|
+
if (path36.length === 0) {
|
|
18694
|
+
path36 = "/";
|
|
18695
18695
|
}
|
|
18696
|
-
return
|
|
18696
|
+
return path36;
|
|
18697
18697
|
}
|
|
18698
18698
|
function buildKey(opts) {
|
|
18699
|
-
const { path:
|
|
18699
|
+
const { path: path36, method, body, headers, query } = opts;
|
|
18700
18700
|
return {
|
|
18701
|
-
path:
|
|
18701
|
+
path: path36,
|
|
18702
18702
|
method,
|
|
18703
18703
|
body,
|
|
18704
18704
|
headers,
|
|
@@ -19388,10 +19388,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
19388
19388
|
}
|
|
19389
19389
|
format(pendingInterceptors) {
|
|
19390
19390
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
19391
|
-
({ method, path:
|
|
19391
|
+
({ method, path: path36, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
19392
19392
|
Method: method,
|
|
19393
19393
|
Origin: origin,
|
|
19394
|
-
Path:
|
|
19394
|
+
Path: path36,
|
|
19395
19395
|
"Status code": statusCode,
|
|
19396
19396
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
19397
19397
|
Invocations: timesInvoked,
|
|
@@ -19473,9 +19473,9 @@ var require_mock_agent = __commonJS({
|
|
|
19473
19473
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
19474
19474
|
const dispatchOpts = { ...opts };
|
|
19475
19475
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
19476
|
-
const [
|
|
19476
|
+
const [path36, searchParams] = dispatchOpts.path.split("?");
|
|
19477
19477
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
19478
|
-
dispatchOpts.path = `${
|
|
19478
|
+
dispatchOpts.path = `${path36}?${normalizedSearchParams}`;
|
|
19479
19479
|
}
|
|
19480
19480
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
19481
19481
|
}
|
|
@@ -19876,12 +19876,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
19876
19876
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
19877
19877
|
*/
|
|
19878
19878
|
async loadSnapshots(filePath) {
|
|
19879
|
-
const
|
|
19880
|
-
if (!
|
|
19879
|
+
const path36 = filePath || this.#snapshotPath;
|
|
19880
|
+
if (!path36) {
|
|
19881
19881
|
throw new InvalidArgumentError2("Snapshot path is required");
|
|
19882
19882
|
}
|
|
19883
19883
|
try {
|
|
19884
|
-
const data = await readFile(resolve(
|
|
19884
|
+
const data = await readFile(resolve(path36), "utf8");
|
|
19885
19885
|
const parsed = JSON.parse(data);
|
|
19886
19886
|
if (Array.isArray(parsed)) {
|
|
19887
19887
|
this.#snapshots.clear();
|
|
@@ -19895,7 +19895,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
19895
19895
|
if (error62.code === "ENOENT") {
|
|
19896
19896
|
this.#snapshots.clear();
|
|
19897
19897
|
} else {
|
|
19898
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
19898
|
+
throw new UndiciError(`Failed to load snapshots from ${path36}`, { cause: error62 });
|
|
19899
19899
|
}
|
|
19900
19900
|
}
|
|
19901
19901
|
}
|
|
@@ -19906,11 +19906,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
19906
19906
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
19907
19907
|
*/
|
|
19908
19908
|
async saveSnapshots(filePath) {
|
|
19909
|
-
const
|
|
19910
|
-
if (!
|
|
19909
|
+
const path36 = filePath || this.#snapshotPath;
|
|
19910
|
+
if (!path36) {
|
|
19911
19911
|
throw new InvalidArgumentError2("Snapshot path is required");
|
|
19912
19912
|
}
|
|
19913
|
-
const resolvedPath = resolve(
|
|
19913
|
+
const resolvedPath = resolve(path36);
|
|
19914
19914
|
await mkdir(dirname(resolvedPath), { recursive: true });
|
|
19915
19915
|
const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
|
|
19916
19916
|
hash: hash2,
|
|
@@ -20542,15 +20542,15 @@ var require_redirect_handler = __commonJS({
|
|
|
20542
20542
|
return;
|
|
20543
20543
|
}
|
|
20544
20544
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
20545
|
-
const
|
|
20546
|
-
const redirectUrlString = `${origin}${
|
|
20545
|
+
const path36 = search ? `${pathname}${search}` : pathname;
|
|
20546
|
+
const redirectUrlString = `${origin}${path36}`;
|
|
20547
20547
|
for (const historyUrl of this.history) {
|
|
20548
20548
|
if (historyUrl.toString() === redirectUrlString) {
|
|
20549
20549
|
throw new InvalidArgumentError2(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
|
|
20550
20550
|
}
|
|
20551
20551
|
}
|
|
20552
20552
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
20553
|
-
this.opts.path =
|
|
20553
|
+
this.opts.path = path36;
|
|
20554
20554
|
this.opts.origin = origin;
|
|
20555
20555
|
this.opts.query = null;
|
|
20556
20556
|
}
|
|
@@ -22310,10 +22310,10 @@ var require_cache_handler = __commonJS({
|
|
|
22310
22310
|
}
|
|
22311
22311
|
return locationUrl.pathname + locationUrl.search;
|
|
22312
22312
|
}
|
|
22313
|
-
function deleteCachedUri(store, cacheKey,
|
|
22313
|
+
function deleteCachedUri(store, cacheKey, path36) {
|
|
22314
22314
|
deleteCachedValue(store, {
|
|
22315
22315
|
...cacheKey,
|
|
22316
|
-
path:
|
|
22316
|
+
path: path36
|
|
22317
22317
|
});
|
|
22318
22318
|
for (let i2 = 0; i2 < util.safeHTTPMethods.length; i2++) {
|
|
22319
22319
|
const method = util.safeHTTPMethods[i2];
|
|
@@ -22321,7 +22321,7 @@ var require_cache_handler = __commonJS({
|
|
|
22321
22321
|
deleteCachedValue(store, {
|
|
22322
22322
|
...cacheKey,
|
|
22323
22323
|
method,
|
|
22324
|
-
path:
|
|
22324
|
+
path: path36
|
|
22325
22325
|
});
|
|
22326
22326
|
}
|
|
22327
22327
|
}
|
|
@@ -22332,9 +22332,9 @@ var require_cache_handler = __commonJS({
|
|
|
22332
22332
|
}
|
|
22333
22333
|
const values = Array.isArray(headerValue2) ? headerValue2 : [headerValue2];
|
|
22334
22334
|
for (let i2 = 0; i2 < values.length; i2++) {
|
|
22335
|
-
const
|
|
22336
|
-
if (
|
|
22337
|
-
deleteCachedUri(store, cacheKey,
|
|
22335
|
+
const path36 = getSameOriginPath(cacheKey, values[i2]);
|
|
22336
|
+
if (path36 !== void 0) {
|
|
22337
|
+
deleteCachedUri(store, cacheKey, path36);
|
|
22338
22338
|
}
|
|
22339
22339
|
}
|
|
22340
22340
|
}
|
|
@@ -27334,11 +27334,11 @@ var require_fetch = __commonJS({
|
|
|
27334
27334
|
function dispatch({ body }) {
|
|
27335
27335
|
const url2 = requestCurrentURL(request6);
|
|
27336
27336
|
const agent = fetchParams.controller.dispatcher;
|
|
27337
|
-
const
|
|
27337
|
+
const path36 = url2.pathname + url2.search;
|
|
27338
27338
|
const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
|
|
27339
27339
|
return new Promise((resolve, reject) => agent.dispatch(
|
|
27340
27340
|
{
|
|
27341
|
-
path: hasTrailingQuestionMark ? `${
|
|
27341
|
+
path: hasTrailingQuestionMark ? `${path36}?` : path36,
|
|
27342
27342
|
origin: url2.origin,
|
|
27343
27343
|
method: request6.method,
|
|
27344
27344
|
body: agent.isMockActive ? request6.body && (request6.body.source || request6.body.stream) : body,
|
|
@@ -28285,9 +28285,9 @@ var require_util5 = __commonJS({
|
|
|
28285
28285
|
}
|
|
28286
28286
|
}
|
|
28287
28287
|
}
|
|
28288
|
-
function validateCookiePath(
|
|
28289
|
-
for (let i2 = 0; i2 <
|
|
28290
|
-
const code =
|
|
28288
|
+
function validateCookiePath(path36) {
|
|
28289
|
+
for (let i2 = 0; i2 < path36.length; ++i2) {
|
|
28290
|
+
const code = path36.charCodeAt(i2);
|
|
28291
28291
|
if (code < 32 || // exclude CTLs (0-31)
|
|
28292
28292
|
code > 126 || // exclude DEL and non-ascii
|
|
28293
28293
|
code === 59) {
|
|
@@ -31635,11 +31635,11 @@ var require_undici = __commonJS({
|
|
|
31635
31635
|
if (typeof opts.path !== "string") {
|
|
31636
31636
|
throw new InvalidArgumentError2("invalid opts.path");
|
|
31637
31637
|
}
|
|
31638
|
-
let
|
|
31638
|
+
let path36 = opts.path;
|
|
31639
31639
|
if (!opts.path.startsWith("/")) {
|
|
31640
|
-
|
|
31640
|
+
path36 = `/${path36}`;
|
|
31641
31641
|
}
|
|
31642
|
-
url2 = new URL(util.parseOrigin(url2).origin +
|
|
31642
|
+
url2 = new URL(util.parseOrigin(url2).origin + path36);
|
|
31643
31643
|
} else {
|
|
31644
31644
|
if (!opts) {
|
|
31645
31645
|
opts = typeof url2 === "object" ? url2 : {};
|
|
@@ -31749,7 +31749,7 @@ ${captureLines}` : capture.stack;
|
|
|
31749
31749
|
});
|
|
31750
31750
|
|
|
31751
31751
|
// src/cli.ts
|
|
31752
|
-
var
|
|
31752
|
+
var import_node_path35 = __toESM(require("node:path"), 1);
|
|
31753
31753
|
|
|
31754
31754
|
// node_modules/.pnpm/commander@15.0.0/node_modules/commander/lib/error.js
|
|
31755
31755
|
var CommanderError = class extends Error {
|
|
@@ -34862,9 +34862,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
34862
34862
|
* @param {string} [path]
|
|
34863
34863
|
* @return {(string|null|Command)}
|
|
34864
34864
|
*/
|
|
34865
|
-
executableDir(
|
|
34866
|
-
if (
|
|
34867
|
-
this._executableDir =
|
|
34865
|
+
executableDir(path36) {
|
|
34866
|
+
if (path36 === void 0) return this._executableDir;
|
|
34867
|
+
this._executableDir = path36;
|
|
34868
34868
|
return this;
|
|
34869
34869
|
}
|
|
34870
34870
|
/**
|
|
@@ -35168,18 +35168,18 @@ function reportFatalError(error62, io) {
|
|
|
35168
35168
|
return error62.exitCode === 0 ? 0 : EXIT_USAGE;
|
|
35169
35169
|
}
|
|
35170
35170
|
if (error62 instanceof CliError) {
|
|
35171
|
-
io.writeErr(`
|
|
35171
|
+
io.writeErr(`agent-shim: ${error62.message}`);
|
|
35172
35172
|
return error62.exitCode;
|
|
35173
35173
|
}
|
|
35174
35174
|
const message = error62 instanceof Error ? error62.message : String(error62);
|
|
35175
|
-
io.writeErr(`
|
|
35175
|
+
io.writeErr(`agent-shim: ${message}`);
|
|
35176
35176
|
if (error62 instanceof Error && error62.stack !== void 0 && debugEnabled(io.env)) {
|
|
35177
35177
|
io.writeErr(error62.stack);
|
|
35178
35178
|
}
|
|
35179
35179
|
return EXIT_FAILURE;
|
|
35180
35180
|
}
|
|
35181
35181
|
function debugEnabled(env) {
|
|
35182
|
-
return env.
|
|
35182
|
+
return env.AGENT_SHIM_DEBUG !== void 0 && parseBoolWord(env.AGENT_SHIM_DEBUG) === true;
|
|
35183
35183
|
}
|
|
35184
35184
|
|
|
35185
35185
|
// src/claudeShim.ts
|
|
@@ -36002,10 +36002,10 @@ function mergeDefs(...defs) {
|
|
|
36002
36002
|
function cloneDef(schema) {
|
|
36003
36003
|
return mergeDefs(schema._zod.def);
|
|
36004
36004
|
}
|
|
36005
|
-
function getElementAtPath(obj,
|
|
36006
|
-
if (!
|
|
36005
|
+
function getElementAtPath(obj, path36) {
|
|
36006
|
+
if (!path36)
|
|
36007
36007
|
return obj;
|
|
36008
|
-
return
|
|
36008
|
+
return path36.reduce((acc, key) => acc?.[key], obj);
|
|
36009
36009
|
}
|
|
36010
36010
|
function promiseAllObject(promisesObj) {
|
|
36011
36011
|
const keys = Object.keys(promisesObj);
|
|
@@ -36345,11 +36345,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
36345
36345
|
}
|
|
36346
36346
|
return false;
|
|
36347
36347
|
}
|
|
36348
|
-
function prefixIssues(
|
|
36348
|
+
function prefixIssues(path36, issues) {
|
|
36349
36349
|
return issues.map((iss) => {
|
|
36350
36350
|
var _a3;
|
|
36351
36351
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
36352
|
-
iss.path.unshift(
|
|
36352
|
+
iss.path.unshift(path36);
|
|
36353
36353
|
return iss;
|
|
36354
36354
|
});
|
|
36355
36355
|
}
|
|
@@ -36799,16 +36799,16 @@ function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
|
36799
36799
|
}
|
|
36800
36800
|
function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
36801
36801
|
const fieldErrors = { _errors: [] };
|
|
36802
|
-
const processError = (error63,
|
|
36802
|
+
const processError = (error63, path36 = []) => {
|
|
36803
36803
|
for (const issue2 of error63.issues) {
|
|
36804
36804
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
36805
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
36805
|
+
issue2.errors.map((issues) => processError({ issues }, [...path36, ...issue2.path]));
|
|
36806
36806
|
} else if (issue2.code === "invalid_key") {
|
|
36807
|
-
processError({ issues: issue2.issues }, [...
|
|
36807
|
+
processError({ issues: issue2.issues }, [...path36, ...issue2.path]);
|
|
36808
36808
|
} else if (issue2.code === "invalid_element") {
|
|
36809
|
-
processError({ issues: issue2.issues }, [...
|
|
36809
|
+
processError({ issues: issue2.issues }, [...path36, ...issue2.path]);
|
|
36810
36810
|
} else {
|
|
36811
|
-
const fullpath = [...
|
|
36811
|
+
const fullpath = [...path36, ...issue2.path];
|
|
36812
36812
|
if (fullpath.length === 0) {
|
|
36813
36813
|
fieldErrors._errors.push(mapper(issue2));
|
|
36814
36814
|
} else {
|
|
@@ -36847,17 +36847,17 @@ function formatError(error62, mapper = (issue2) => issue2.message) {
|
|
|
36847
36847
|
}
|
|
36848
36848
|
function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
36849
36849
|
const result = { errors: [] };
|
|
36850
|
-
const processError = (error63,
|
|
36850
|
+
const processError = (error63, path36 = []) => {
|
|
36851
36851
|
var _a3;
|
|
36852
36852
|
for (const issue2 of error63.issues) {
|
|
36853
36853
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
36854
|
-
issue2.errors.map((issues) => processError({ issues }, [...
|
|
36854
|
+
issue2.errors.map((issues) => processError({ issues }, [...path36, ...issue2.path]));
|
|
36855
36855
|
} else if (issue2.code === "invalid_key") {
|
|
36856
|
-
processError({ issues: issue2.issues }, [...
|
|
36856
|
+
processError({ issues: issue2.issues }, [...path36, ...issue2.path]);
|
|
36857
36857
|
} else if (issue2.code === "invalid_element") {
|
|
36858
|
-
processError({ issues: issue2.issues }, [...
|
|
36858
|
+
processError({ issues: issue2.issues }, [...path36, ...issue2.path]);
|
|
36859
36859
|
} else {
|
|
36860
|
-
const fullpath = [...
|
|
36860
|
+
const fullpath = [...path36, ...issue2.path];
|
|
36861
36861
|
if (fullpath.length === 0) {
|
|
36862
36862
|
result.errors.push(mapper(issue2));
|
|
36863
36863
|
continue;
|
|
@@ -36896,8 +36896,8 @@ function treeifyError(error62, mapper = (issue2) => issue2.message) {
|
|
|
36896
36896
|
}
|
|
36897
36897
|
function toDotPath(_path) {
|
|
36898
36898
|
const segs = [];
|
|
36899
|
-
const
|
|
36900
|
-
for (const seg of
|
|
36899
|
+
const path36 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
36900
|
+
for (const seg of path36) {
|
|
36901
36901
|
if (typeof seg === "number")
|
|
36902
36902
|
segs.push(`[${seg}]`);
|
|
36903
36903
|
else if (typeof seg === "symbol")
|
|
@@ -53999,13 +53999,13 @@ function resolveRef(ref, ctx) {
|
|
|
53999
53999
|
if (!ref.startsWith("#")) {
|
|
54000
54000
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
54001
54001
|
}
|
|
54002
|
-
const
|
|
54003
|
-
if (
|
|
54002
|
+
const path36 = ref.slice(1).split("/").filter(Boolean);
|
|
54003
|
+
if (path36.length === 0) {
|
|
54004
54004
|
return ctx.rootSchema;
|
|
54005
54005
|
}
|
|
54006
54006
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
54007
|
-
if (
|
|
54008
|
-
const key =
|
|
54007
|
+
if (path36[0] === defsKey) {
|
|
54008
|
+
const key = path36[1] === void 0 ? void 0 : decodeJSONPointerSegment(path36[1]);
|
|
54009
54009
|
if (!key || !ctx.defs[key]) {
|
|
54010
54010
|
throw new Error(`Reference not found: ${ref}`);
|
|
54011
54011
|
}
|
|
@@ -54890,7 +54890,7 @@ var import_node_crypto = require("node:crypto");
|
|
|
54890
54890
|
|
|
54891
54891
|
// src/config/load.ts
|
|
54892
54892
|
var import_cosmiconfig = __toESM(require_dist(), 1);
|
|
54893
|
-
function createExplorer(moduleName = "
|
|
54893
|
+
function createExplorer(moduleName = "agent-shim") {
|
|
54894
54894
|
return (0, import_cosmiconfig.cosmiconfigSync)(moduleName, { searchPlaces: [] });
|
|
54895
54895
|
}
|
|
54896
54896
|
function isRecord(value) {
|
|
@@ -55135,7 +55135,7 @@ function expandAllCategoryKey(pairs) {
|
|
|
55135
55135
|
if (all === void 0) {
|
|
55136
55136
|
return { ...rest };
|
|
55137
55137
|
}
|
|
55138
|
-
const expanded = Object.fromEntries(OVERRIDABLE_CATEGORIES.map((category) => [category, all]));
|
|
55138
|
+
const expanded = Object.fromEntries(OVERRIDABLE_CATEGORIES.filter((category) => !all || category !== "runtime").map((category) => [category, all]));
|
|
55139
55139
|
return { ...expanded, ...rest };
|
|
55140
55140
|
}
|
|
55141
55141
|
var CategoryMapSchema = external_exports.strictObject({
|
|
@@ -55209,7 +55209,7 @@ var CredentialSchema = external_exports.strictObject({
|
|
|
55209
55209
|
var ProviderCredentialSchema = CredentialSchema.extend({ target: external_exports.enum(PROVIDER_CREDENTIAL_TARGETS).optional() });
|
|
55210
55210
|
var RESERVED_PROVIDER_ENV_KEYS = Object.values(CREDENTIAL_TARGET_VARS);
|
|
55211
55211
|
var ProviderEnvSchema = external_exports.record(external_exports.string().min(1), external_exports.string()).refine((env) => !Object.keys(env).some((key) => RESERVED_PROVIDER_ENV_KEYS.includes(key)), {
|
|
55212
|
-
message: `env may not set ${RESERVED_PROVIDER_ENV_KEYS.join(", ")}: the credential block's target sets one and
|
|
55212
|
+
message: `env may not set ${RESERVED_PROVIDER_ENV_KEYS.join(", ")}: the credential block's target sets one and agent-shim removes the others`
|
|
55213
55213
|
});
|
|
55214
55214
|
var PROVIDER_KINDS = ["http", "codex"];
|
|
55215
55215
|
var CODEX_TIERS = ["fable", "opus", "sonnet", "haiku"];
|
|
@@ -55399,16 +55399,16 @@ function parseJson(raw, schema) {
|
|
|
55399
55399
|
const parsed = schema.safeParse(JSON.parse(raw));
|
|
55400
55400
|
return parsed.success ? parsed.data : void 0;
|
|
55401
55401
|
}
|
|
55402
|
-
function readHeadroomState(
|
|
55402
|
+
function readHeadroomState(fs17, stateFile) {
|
|
55403
55403
|
try {
|
|
55404
|
-
return parseJson(
|
|
55404
|
+
return parseJson(fs17.readFileUtf8(stateFile), HeadroomStateSchema);
|
|
55405
55405
|
} catch {
|
|
55406
55406
|
return void 0;
|
|
55407
55407
|
}
|
|
55408
55408
|
}
|
|
55409
|
-
function writeHeadroomState(
|
|
55410
|
-
|
|
55411
|
-
|
|
55409
|
+
function writeHeadroomState(fs17, stateFile, state) {
|
|
55410
|
+
fs17.mkdirp(import_node_path5.default.dirname(stateFile));
|
|
55411
|
+
fs17.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
55412
55412
|
`);
|
|
55413
55413
|
}
|
|
55414
55414
|
function headroomAllowlist(providers) {
|
|
@@ -55428,14 +55428,14 @@ function headroomUpstreams(providers, frontDoorOrigin2) {
|
|
|
55428
55428
|
function hashAllowlist(allowlist) {
|
|
55429
55429
|
return (0, import_node_crypto2.createHash)("sha256").update(allowlist.join("\n")).digest("hex");
|
|
55430
55430
|
}
|
|
55431
|
-
function readAllProviders(
|
|
55431
|
+
function readAllProviders(fs17, providersDir) {
|
|
55432
55432
|
const result = [];
|
|
55433
|
-
for (const name of
|
|
55433
|
+
for (const name of fs17.readdir(providersDir)) {
|
|
55434
55434
|
if (!name.endsWith(".json")) {
|
|
55435
55435
|
continue;
|
|
55436
55436
|
}
|
|
55437
55437
|
try {
|
|
55438
|
-
const parsed = parseJson(
|
|
55438
|
+
const parsed = parseJson(fs17.readFileUtf8(import_node_path5.default.join(providersDir, name)), ProviderSchema);
|
|
55439
55439
|
if (parsed !== void 0) {
|
|
55440
55440
|
result.push({ name: name.slice(0, -".json".length), provider: parsed });
|
|
55441
55441
|
}
|
|
@@ -55445,22 +55445,22 @@ function readAllProviders(fs16, providersDir) {
|
|
|
55445
55445
|
}
|
|
55446
55446
|
return result;
|
|
55447
55447
|
}
|
|
55448
|
-
function writeSession(
|
|
55449
|
-
|
|
55450
|
-
|
|
55448
|
+
function writeSession(fs17, sessionsDir, session) {
|
|
55449
|
+
fs17.mkdirp(sessionsDir);
|
|
55450
|
+
fs17.writeFileUtf8(import_node_path5.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
55451
55451
|
`);
|
|
55452
55452
|
}
|
|
55453
|
-
function removeSession(
|
|
55454
|
-
|
|
55453
|
+
function removeSession(fs17, sessionsDir, pid) {
|
|
55454
|
+
fs17.removeRecursive(import_node_path5.default.join(sessionsDir, `${String(pid)}.json`));
|
|
55455
55455
|
}
|
|
55456
|
-
function listSessions(
|
|
55456
|
+
function listSessions(fs17, sessionsDir) {
|
|
55457
55457
|
const sessions = [];
|
|
55458
|
-
for (const name of
|
|
55458
|
+
for (const name of fs17.readdir(sessionsDir)) {
|
|
55459
55459
|
if (!name.endsWith(".json")) {
|
|
55460
55460
|
continue;
|
|
55461
55461
|
}
|
|
55462
55462
|
try {
|
|
55463
|
-
const parsed = parseJson(
|
|
55463
|
+
const parsed = parseJson(fs17.readFileUtf8(import_node_path5.default.join(sessionsDir, name)), HeadroomSessionSchema);
|
|
55464
55464
|
if (parsed !== void 0) {
|
|
55465
55465
|
sessions.push(parsed);
|
|
55466
55466
|
}
|
|
@@ -55470,22 +55470,22 @@ function listSessions(fs16, sessionsDir) {
|
|
|
55470
55470
|
}
|
|
55471
55471
|
return sessions.sort((a2, b) => a2.pid - b.pid);
|
|
55472
55472
|
}
|
|
55473
|
-
function sessionsForSupervisor(
|
|
55474
|
-
return listSessions(
|
|
55473
|
+
function sessionsForSupervisor(fs17, sessionsDir, supervisorPid) {
|
|
55474
|
+
return listSessions(fs17, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
|
|
55475
55475
|
}
|
|
55476
|
-
function pruneDeadSessions(
|
|
55476
|
+
function pruneDeadSessions(fs17, sessionsDir, isRunning) {
|
|
55477
55477
|
const removed = [];
|
|
55478
|
-
for (const session of listSessions(
|
|
55478
|
+
for (const session of listSessions(fs17, sessionsDir)) {
|
|
55479
55479
|
if (!isRunning(session.pid)) {
|
|
55480
|
-
removeSession(
|
|
55480
|
+
removeSession(fs17, sessionsDir, session.pid);
|
|
55481
55481
|
removed.push(session.pid);
|
|
55482
55482
|
}
|
|
55483
55483
|
}
|
|
55484
55484
|
return removed;
|
|
55485
55485
|
}
|
|
55486
|
-
function readStartLock(
|
|
55486
|
+
function readStartLock(fs17, lockFile) {
|
|
55487
55487
|
try {
|
|
55488
|
-
return parseJson(
|
|
55488
|
+
return parseJson(fs17.readFileUtf8(lockFile), HeadroomLockSchema);
|
|
55489
55489
|
} catch {
|
|
55490
55490
|
return void 0;
|
|
55491
55491
|
}
|
|
@@ -55514,7 +55514,7 @@ function ensureHeadroom(params) {
|
|
|
55514
55514
|
}
|
|
55515
55515
|
if (state.lastError !== void 0) {
|
|
55516
55516
|
throw new HeadroomStartError(
|
|
55517
|
-
`
|
|
55517
|
+
`agent-shim: the headroom daemon reported a fatal error and is not serving: ${state.lastError} (daemon log: ${paths.headroomLogPath})`
|
|
55518
55518
|
);
|
|
55519
55519
|
}
|
|
55520
55520
|
} else if (!spawnedSupervisor) {
|
|
@@ -55538,7 +55538,7 @@ function ensureHeadroom(params) {
|
|
|
55538
55538
|
if (ports.now() >= deadline) {
|
|
55539
55539
|
const lastError = state?.lastError;
|
|
55540
55540
|
throw new HeadroomStartError(
|
|
55541
|
-
`
|
|
55541
|
+
`agent-shim: the headroom daemon did not become ready within ${String(HEADROOM_START_TIMEOUT_MS)}ms` + (lastError === void 0 ? "" : ` (last error: ${lastError})`) + `. Daemon log: ${paths.headroomLogPath}`
|
|
55542
55542
|
);
|
|
55543
55543
|
}
|
|
55544
55544
|
ports.sleep(HEADROOM_LAUNCHER_POLL_MS);
|
|
@@ -55780,7 +55780,7 @@ function spawnDetachedSupervisor(paths, subcommand, logPath) {
|
|
|
55780
55780
|
const logFd = import_node_fs3.default.openSync(logPath, "a");
|
|
55781
55781
|
try {
|
|
55782
55782
|
const invocation = selfInvocation([subcommand]);
|
|
55783
|
-
const child = (0, import_node_child_process2.spawn)(invocation.command, invocation.args, detachedDaemonSpawnOptions(logFd, { ...process.env,
|
|
55783
|
+
const child = (0, import_node_child_process2.spawn)(invocation.command, invocation.args, detachedDaemonSpawnOptions(logFd, { ...process.env, AGENT_SHIM_HOME: paths.root }));
|
|
55784
55784
|
child.unref();
|
|
55785
55785
|
if (child.pid === void 0) {
|
|
55786
55786
|
throw new Error(`spawning ${subcommand} returned no pid`);
|
|
@@ -55974,7 +55974,7 @@ var ClaudeShimStateSchema = external_exports.strictObject({
|
|
|
55974
55974
|
var ForeignClaudeEntryError = class extends CliError {
|
|
55975
55975
|
constructor(targetPath, action) {
|
|
55976
55976
|
super(
|
|
55977
|
-
`${targetPath} already exists and does not look like something
|
|
55977
|
+
`${targetPath} already exists and does not look like something agent-shim created. Refusing to ${action === "enable" ? "overwrite" : "remove"} it automatically \u2014 inspect it yourself, or pass --force if you're sure.`
|
|
55978
55978
|
);
|
|
55979
55979
|
this.targetPath = targetPath;
|
|
55980
55980
|
this.action = action;
|
|
@@ -55986,7 +55986,7 @@ var ForeignClaudeEntryError = class extends CliError {
|
|
|
55986
55986
|
var UnsupportedShimSourceError = class extends CliError {
|
|
55987
55987
|
constructor(contentSourcePath) {
|
|
55988
55988
|
super(
|
|
55989
|
-
`Cannot create a working \`claude\` command from ${contentSourcePath} on Windows: an npm-installed
|
|
55989
|
+
`Cannot create a working \`claude\` command from ${contentSourcePath} on Windows: an npm-installed agent-shim running under Node.js has no .exe to hardlink/copy, and Windows has no shebang-based dispatch the way POSIX does. Install agent-shim via Scoop instead (see README), which ships a real agent-shim.exe this command can link from.`
|
|
55990
55990
|
);
|
|
55991
55991
|
this.contentSourcePath = contentSourcePath;
|
|
55992
55992
|
this.name = "UnsupportedShimSourceError";
|
|
@@ -56100,11 +56100,11 @@ function registerShimCommand(program2, deps) {
|
|
|
56100
56100
|
const { paths } = deps;
|
|
56101
56101
|
const shim = withExamples(
|
|
56102
56102
|
program2.command("shim").description(
|
|
56103
|
-
"Manage the `claude` command shim: an optional, explicit way to also invoke this launcher as `claude` instead of `
|
|
56103
|
+
"Manage the `claude` command shim: an optional, explicit way to also invoke this launcher as `claude` instead of `agent-shim run`. Off by default; every installer ships only `agent-shim`."
|
|
56104
56104
|
),
|
|
56105
|
-
["
|
|
56105
|
+
["agent-shim shim enable", "agent-shim shim disable"]
|
|
56106
56106
|
);
|
|
56107
|
-
const enable = shim.command("enable").description("Create a `claude`-named copy of this same executable, alongside
|
|
56107
|
+
const enable = shim.command("enable").description("Create a `claude`-named copy of this same executable, alongside agent-shim by default.").option("--dir <path>", "Enable into this directory instead of alongside the running agent-shim executable.").option("--force", "Overwrite the target even if it doesn't look like agent-shim's own doing.").action((options) => {
|
|
56108
56108
|
const ownExecutablePath = realOwnExecutablePath();
|
|
56109
56109
|
const contentSourcePath = realContentSourcePath();
|
|
56110
56110
|
const result = enableClaudeShim({
|
|
@@ -56123,15 +56123,15 @@ function registerShimCommand(program2, deps) {
|
|
|
56123
56123
|
findExecutableInDir
|
|
56124
56124
|
});
|
|
56125
56125
|
if (shadow.status === "not-on-path") {
|
|
56126
|
-
console.warn(`warning: ${import_node_path7.default.dirname(result.targetPath)} is not on PATH \u2014 add it, or use \`
|
|
56126
|
+
console.warn(`warning: ${import_node_path7.default.dirname(result.targetPath)} is not on PATH \u2014 add it, or use \`agent-shim run\` instead.`);
|
|
56127
56127
|
} else if (shadow.status === "shadowed") {
|
|
56128
56128
|
console.warn(
|
|
56129
56129
|
`warning: 'claude' on PATH currently resolves to ${shadow.by}, not ${result.targetPath}. Put ${import_node_path7.default.dirname(result.targetPath)} ahead of it on PATH.`
|
|
56130
56130
|
);
|
|
56131
56131
|
}
|
|
56132
56132
|
});
|
|
56133
|
-
withExamples(enable, ["
|
|
56134
|
-
const disable = shim.command("disable").description("Remove the `claude` command shim `shim enable` previously created. A no-op, not an error, if none is enabled.").option("--dir <path>", "Look in this directory instead of trusting the recorded location.").option("--force", "Remove the target even if it doesn't look like
|
|
56133
|
+
withExamples(enable, ["agent-shim shim enable", "agent-shim shim enable --dir ~/bin"]);
|
|
56134
|
+
const disable = shim.command("disable").description("Remove the `claude` command shim `shim enable` previously created. A no-op, not an error, if none is enabled.").option("--dir <path>", "Look in this directory instead of trusting the recorded location.").option("--force", "Remove the target even if it doesn't look like agent-shim's own doing.").action((options) => {
|
|
56135
56135
|
const ownExecutablePath = realOwnExecutablePath();
|
|
56136
56136
|
const contentSourcePath = realContentSourcePath();
|
|
56137
56137
|
const result = disableClaudeShim({
|
|
@@ -56145,11 +56145,37 @@ function registerShimCommand(program2, deps) {
|
|
|
56145
56145
|
result.action === "disabled" ? `Removed \`claude\` at ${result.targetPath}.` : `No \`claude\` command enabled at ${result.targetPath}; nothing to do.`
|
|
56146
56146
|
);
|
|
56147
56147
|
});
|
|
56148
|
-
withExamples(disable, ["
|
|
56148
|
+
withExamples(disable, ["agent-shim shim disable"]);
|
|
56149
|
+
}
|
|
56150
|
+
|
|
56151
|
+
// src/legacy.ts
|
|
56152
|
+
var ENV_PREFIX = "AGENT_SHIM_";
|
|
56153
|
+
var LEGACY_ENV_PREFIX = "CLAUDE_USE_";
|
|
56154
|
+
var HOME_DIRNAME = ".agent-shim";
|
|
56155
|
+
var LEGACY_HOME_DIRNAME = ".claude-use";
|
|
56156
|
+
var LEGACY_PORTABLE_CONFIG_FILENAME = ".claude-use.json";
|
|
56157
|
+
var LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME = ".claude-use.local.json";
|
|
56158
|
+
var LEGACY_FARM_MANIFEST_FILENAME = ".claude-use-farm.json";
|
|
56159
|
+
var LEGACY_COMMAND_NAME = "claude-use";
|
|
56160
|
+
function aliasLegacyEnv(env) {
|
|
56161
|
+
const aliased = [];
|
|
56162
|
+
for (const name of Object.keys(env).sort()) {
|
|
56163
|
+
if (!name.startsWith(LEGACY_ENV_PREFIX)) {
|
|
56164
|
+
continue;
|
|
56165
|
+
}
|
|
56166
|
+
const value = env[name];
|
|
56167
|
+
const current = `${ENV_PREFIX}${name.slice(LEGACY_ENV_PREFIX.length)}`;
|
|
56168
|
+
if (value === void 0 || env[current] !== void 0) {
|
|
56169
|
+
continue;
|
|
56170
|
+
}
|
|
56171
|
+
env[current] = value;
|
|
56172
|
+
aliased.push(name);
|
|
56173
|
+
}
|
|
56174
|
+
return aliased;
|
|
56149
56175
|
}
|
|
56150
56176
|
|
|
56151
56177
|
// src/configure.ts
|
|
56152
|
-
var
|
|
56178
|
+
var import_node_fs8 = __toESM(require("node:fs"), 1);
|
|
56153
56179
|
var import_node_os4 = __toESM(require("node:os"), 1);
|
|
56154
56180
|
var import_node_path19 = __toESM(require("node:path"), 1);
|
|
56155
56181
|
|
|
@@ -57469,7 +57495,7 @@ function collectCredentialSource(value, previous = []) {
|
|
|
57469
57495
|
}
|
|
57470
57496
|
function addCredentialCacheOptions(command) {
|
|
57471
57497
|
return command.option("--credential-cache-ttl <ttl>", "Keep the resolved credential for this long (a whole number and s, m, h or d, for example 12h) so a launch need not re-run a source that needs a person. Enables caching.").addOption(
|
|
57472
|
-
new Option("--credential-cache-store <store>", "Where the cached credential is kept: keychain (macOS login Keychain, the default there) or file (mode 0600 under the
|
|
57498
|
+
new Option("--credential-cache-store <store>", "Where the cached credential is kept: keychain (macOS login Keychain, the default there) or file (mode 0600 under the agent-shim home, the default elsewhere). Enables caching.").choices(
|
|
57473
57499
|
CREDENTIAL_CACHE_STORES
|
|
57474
57500
|
)
|
|
57475
57501
|
).option("--credential-cache", "Cache this credential in the default store with no expiry (add --credential-cache-ttl for one).").option("--no-credential-cache", "Stop caching this credential. Run `credential forget` first to drop the stored copy.");
|
|
@@ -57646,7 +57672,7 @@ function trySource(source, params) {
|
|
|
57646
57672
|
}
|
|
57647
57673
|
function warmCommandFor(subject) {
|
|
57648
57674
|
const [kind, name] = subject.split(" ");
|
|
57649
|
-
return kind === "provider" ? `
|
|
57675
|
+
return kind === "provider" ? `agent-shim credential warm --provider ${name ?? ""}` : `agent-shim credential warm ${name ?? ""}`;
|
|
57650
57676
|
}
|
|
57651
57677
|
function resolveCredential(params) {
|
|
57652
57678
|
const target = params.credential.target ?? "bearer";
|
|
@@ -57672,11 +57698,11 @@ function resolveCredential(params) {
|
|
|
57672
57698
|
const line = `${describeSource(source)} ${outcome.reason}`;
|
|
57673
57699
|
attempts.push(line);
|
|
57674
57700
|
if (outcome.warn) {
|
|
57675
|
-
warnings.push(`
|
|
57701
|
+
warnings.push(`agent-shim: ${params.subject}: skipped ${line}`);
|
|
57676
57702
|
}
|
|
57677
57703
|
}
|
|
57678
57704
|
const hint = cacheBlock === void 0 ? "" : `; fill the cache from a terminal with \`${warmCommandFor(params.subject)}\``;
|
|
57679
|
-
return { ok: false, message: `
|
|
57705
|
+
return { ok: false, message: `agent-shim: ${params.subject} has no usable credential: ${attempts.join("; ")}${hint}` };
|
|
57680
57706
|
}
|
|
57681
57707
|
function credentialVariables(target, token) {
|
|
57682
57708
|
return {
|
|
@@ -58248,7 +58274,7 @@ function resolveEntry(relPath, params) {
|
|
|
58248
58274
|
diagnostics.push({
|
|
58249
58275
|
code: "UNCLASSIFIED_ENTRY",
|
|
58250
58276
|
severity: "warning",
|
|
58251
|
-
message: `"${head}" is not in the category map, so it is excluded. Run \`
|
|
58277
|
+
message: `"${head}" is not in the category map, so it is excluded. Run \`agent-shim configure\` to classify it, which records the answer in the local overlay without touching the shipped default map.`,
|
|
58252
58278
|
subject: head
|
|
58253
58279
|
});
|
|
58254
58280
|
return { decision: { relPath, shared: false, via: "unclassified", category }, diagnostics };
|
|
@@ -58664,7 +58690,7 @@ var DEFAULT_MAX_ATTEMPTS = 200;
|
|
|
58664
58690
|
var IdentityLockBusyError = class extends CliError {
|
|
58665
58691
|
constructor(identity, lockPath, holderPid) {
|
|
58666
58692
|
super(
|
|
58667
|
-
`Another
|
|
58693
|
+
`Another agent-shim resync is already running for identity "${identity}"` + (holderPid === void 0 ? "" : ` (pid ${String(holderPid)})`) + `. Its lock at ${lockPath} was still held after the full retry budget; nothing was changed.`
|
|
58668
58694
|
);
|
|
58669
58695
|
this.identity = identity;
|
|
58670
58696
|
this.lockPath = lockPath;
|
|
@@ -58743,7 +58769,7 @@ function acquireIdentityLock(params) {
|
|
|
58743
58769
|
}
|
|
58744
58770
|
|
|
58745
58771
|
// src/launcher/farm.ts
|
|
58746
|
-
var FARM_MANIFEST_FILENAME = ".
|
|
58772
|
+
var FARM_MANIFEST_FILENAME = ".agent-shim-farm.json";
|
|
58747
58773
|
var FarmManifestSchema = external_exports.strictObject({
|
|
58748
58774
|
version: external_exports.literal(1),
|
|
58749
58775
|
builtAtMs: external_exports.number(),
|
|
@@ -58754,8 +58780,8 @@ var FarmManifestSchema = external_exports.strictObject({
|
|
|
58754
58780
|
materialised: external_exports.array(external_exports.string()),
|
|
58755
58781
|
links: external_exports.array(external_exports.strictObject({ rel: external_exports.string(), target: external_exports.string() }))
|
|
58756
58782
|
});
|
|
58757
|
-
function readFarmManifest(
|
|
58758
|
-
const raw =
|
|
58783
|
+
function readFarmManifest(fs17, farmRoot) {
|
|
58784
|
+
const raw = fs17.readFileUtf8(import_node_path11.default.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs17.readFileUtf8(import_node_path11.default.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
|
|
58759
58785
|
if (raw === void 0) {
|
|
58760
58786
|
return void 0;
|
|
58761
58787
|
}
|
|
@@ -58813,9 +58839,9 @@ function buildEntryFacts(params) {
|
|
|
58813
58839
|
entries
|
|
58814
58840
|
};
|
|
58815
58841
|
}
|
|
58816
|
-
function listSubtree(
|
|
58842
|
+
function listSubtree(fs17, root, rel) {
|
|
58817
58843
|
const absolute = import_node_path11.default.join(root, rel);
|
|
58818
|
-
const stat =
|
|
58844
|
+
const stat = fs17.lstat(absolute);
|
|
58819
58845
|
if (stat === void 0) {
|
|
58820
58846
|
return [];
|
|
58821
58847
|
}
|
|
@@ -58823,10 +58849,10 @@ function listSubtree(fs16, root, rel) {
|
|
|
58823
58849
|
return [{ rel, kind: "symlink" }];
|
|
58824
58850
|
}
|
|
58825
58851
|
if (stat.kind === "dir") {
|
|
58826
|
-
const children = [...
|
|
58852
|
+
const children = [...fs17.readdir(absolute)].sort().flatMap((name) => listSubtree(fs17, root, `${rel}/${name}`));
|
|
58827
58853
|
return [{ rel, kind: "dir" }, ...children];
|
|
58828
58854
|
}
|
|
58829
|
-
const contentHash =
|
|
58855
|
+
const contentHash = fs17.hashFile(absolute);
|
|
58830
58856
|
return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
|
|
58831
58857
|
}
|
|
58832
58858
|
function topLevelScopeRoots(roots) {
|
|
@@ -58840,25 +58866,25 @@ function topLevelScopeRoots(roots) {
|
|
|
58840
58866
|
}
|
|
58841
58867
|
return kept;
|
|
58842
58868
|
}
|
|
58843
|
-
function reconciliationScope(
|
|
58869
|
+
function reconciliationScope(fs17, farmRoot, manifest) {
|
|
58844
58870
|
if (manifest !== void 0) {
|
|
58845
58871
|
return topLevelScopeRoots(manifest.materialised);
|
|
58846
58872
|
}
|
|
58847
|
-
return [...
|
|
58873
|
+
return [...fs17.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs17.lstat(import_node_path11.default.join(farmRoot, name))?.kind === "dir").sort();
|
|
58848
58874
|
}
|
|
58849
|
-
function collectFarmListing(
|
|
58850
|
-
return scopeRoots.flatMap((root) => listSubtree(
|
|
58875
|
+
function collectFarmListing(fs17, farmRoot, scopeRoots) {
|
|
58876
|
+
return scopeRoots.flatMap((root) => listSubtree(fs17, farmRoot, root));
|
|
58851
58877
|
}
|
|
58852
|
-
function collectCanonicalCounterparts(
|
|
58878
|
+
function collectCanonicalCounterparts(fs17, claudeHome, farmListing) {
|
|
58853
58879
|
const out = [];
|
|
58854
58880
|
for (const entry of farmListing) {
|
|
58855
58881
|
const absolute = import_node_path11.default.join(claudeHome, entry.rel);
|
|
58856
|
-
const stat =
|
|
58882
|
+
const stat = fs17.lstat(absolute);
|
|
58857
58883
|
if (stat === void 0) {
|
|
58858
58884
|
continue;
|
|
58859
58885
|
}
|
|
58860
58886
|
if (stat.kind === "file") {
|
|
58861
|
-
const contentHash =
|
|
58887
|
+
const contentHash = fs17.hashFile(absolute);
|
|
58862
58888
|
out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
|
|
58863
58889
|
continue;
|
|
58864
58890
|
}
|
|
@@ -58868,7 +58894,7 @@ function collectCanonicalCounterparts(fs16, claudeHome, farmListing) {
|
|
|
58868
58894
|
}
|
|
58869
58895
|
function carryOver(params) {
|
|
58870
58896
|
const manifest = readFarmManifest(params.fs, params.previousRoot);
|
|
58871
|
-
const accounted = /* @__PURE__ */ new Set([FARM_MANIFEST_FILENAME]);
|
|
58897
|
+
const accounted = /* @__PURE__ */ new Set([FARM_MANIFEST_FILENAME, LEGACY_FARM_MANIFEST_FILENAME]);
|
|
58872
58898
|
for (const rel of manifest?.materialised ?? []) {
|
|
58873
58899
|
const head = rel.split("/")[0];
|
|
58874
58900
|
if (head !== void 0 && head !== "") {
|
|
@@ -59166,7 +59192,7 @@ function resyncFarm(params) {
|
|
|
59166
59192
|
diagnostics.push({
|
|
59167
59193
|
code: "FARM_PREVIOUS_RETAINED",
|
|
59168
59194
|
severity: "warning",
|
|
59169
|
-
message: `The superseded farm was left at ${swap.retainedPrevious} because it still holds ${swap.collided.join(", ")}, which the new farm has its own entry for. Nothing was overwritten in either direction; run \`
|
|
59195
|
+
message: `The superseded farm was left at ${swap.retainedPrevious} because it still holds ${swap.collided.join(", ")}, which the new farm has its own entry for. Nothing was overwritten in either direction; run \`agent-shim identity resolve-conflicts ${params.identity}\` to resolve it interactively.`,
|
|
59170
59196
|
subject: swap.retainedPrevious
|
|
59171
59197
|
});
|
|
59172
59198
|
}
|
|
@@ -59203,7 +59229,7 @@ function recoveryDiagnostics(recovery, identity) {
|
|
|
59203
59229
|
}
|
|
59204
59230
|
if (recovery.retained.length > 0) {
|
|
59205
59231
|
parts.push(
|
|
59206
|
-
`kept ${recovery.retained.join(", ")}, which still holds data the current farm also has an entry for \u2014 run \`
|
|
59232
|
+
`kept ${recovery.retained.join(", ")}, which still holds data the current farm also has an entry for \u2014 run \`agent-shim identity resolve-conflicts ${identity}\` to resolve it interactively`
|
|
59207
59233
|
);
|
|
59208
59234
|
}
|
|
59209
59235
|
return [
|
|
@@ -59348,7 +59374,7 @@ function parseDurationOption(value) {
|
|
|
59348
59374
|
// src/configProfiles.ts
|
|
59349
59375
|
var ProfileNotFoundError = class extends CliError {
|
|
59350
59376
|
constructor(profileName) {
|
|
59351
|
-
super(`No configuration profile named "${profileName}". Run \`
|
|
59377
|
+
super(`No configuration profile named "${profileName}". Run \`agent-shim profile add ${profileName}\` first.`);
|
|
59352
59378
|
this.profileName = profileName;
|
|
59353
59379
|
this.name = "ProfileNotFoundError";
|
|
59354
59380
|
}
|
|
@@ -59535,7 +59561,7 @@ function registerProfileCommand(program2, deps) {
|
|
|
59535
59561
|
const { paths } = deps;
|
|
59536
59562
|
const profile = withExamples(
|
|
59537
59563
|
program2.command("profile").description("Manage configuration profiles: named, reusable rules for what an identity shares with ~/.claude."),
|
|
59538
|
-
["
|
|
59564
|
+
["agent-shim profile add client-acme", "agent-shim profile list"]
|
|
59539
59565
|
);
|
|
59540
59566
|
withExamples(
|
|
59541
59567
|
profile.command("add [name]").description(
|
|
@@ -59556,7 +59582,7 @@ function registerProfileCommand(program2, deps) {
|
|
|
59556
59582
|
createProfile(paths, name, options.extends, options.description);
|
|
59557
59583
|
console.log(`Created configuration profile "${name}".`);
|
|
59558
59584
|
}),
|
|
59559
|
-
["
|
|
59585
|
+
["agent-shim profile add client-acme", "agent-shim profile add client-acme --extends work-default --extends strict"]
|
|
59560
59586
|
);
|
|
59561
59587
|
withExamples(
|
|
59562
59588
|
profile.command("set <name>").description(
|
|
@@ -59578,9 +59604,9 @@ function registerProfileCommand(program2, deps) {
|
|
|
59578
59604
|
console.log(`Updated configuration profile "${name}".`);
|
|
59579
59605
|
}),
|
|
59580
59606
|
[
|
|
59581
|
-
"
|
|
59582
|
-
'
|
|
59583
|
-
"
|
|
59607
|
+
"agent-shim profile set client-acme --category history=false --category knowledge=true",
|
|
59608
|
+
'agent-shim profile set client-acme --entry "knowledge/skills/commit=false"',
|
|
59609
|
+
"agent-shim profile set client-acme --launch-headroom --launch-provider z"
|
|
59584
59610
|
]
|
|
59585
59611
|
);
|
|
59586
59612
|
withExamples(
|
|
@@ -59592,7 +59618,7 @@ function registerProfileCommand(program2, deps) {
|
|
|
59592
59618
|
return;
|
|
59593
59619
|
}
|
|
59594
59620
|
if (entries.length === 0) {
|
|
59595
|
-
console.log("No configuration profiles yet. Run `
|
|
59621
|
+
console.log("No configuration profiles yet. Run `agent-shim profile add <name>` to create one.");
|
|
59596
59622
|
return;
|
|
59597
59623
|
}
|
|
59598
59624
|
for (const entry of entries) {
|
|
@@ -59601,7 +59627,7 @@ function registerProfileCommand(program2, deps) {
|
|
|
59601
59627
|
console.log(`${marker}${entry.name}${extendsSuffix}`);
|
|
59602
59628
|
}
|
|
59603
59629
|
}),
|
|
59604
|
-
["
|
|
59630
|
+
["agent-shim profile list", "agent-shim profile list --json"]
|
|
59605
59631
|
);
|
|
59606
59632
|
withExamples(
|
|
59607
59633
|
profile.command("show <name>").description("Show one configuration profile's contents.").option("--json", "Print the profile as JSON.").action((name, options) => {
|
|
@@ -59628,16 +59654,16 @@ function registerProfileCommand(program2, deps) {
|
|
|
59628
59654
|
console.log(`${label}: ${pairs.length === 0 ? "(none)" : pairs.map(([key, setting]) => `${key}=${JSON.stringify(setting)}`).join(", ")}`);
|
|
59629
59655
|
}
|
|
59630
59656
|
}),
|
|
59631
|
-
["
|
|
59657
|
+
["agent-shim profile show client-acme", "agent-shim profile show client-acme --json"]
|
|
59632
59658
|
);
|
|
59633
59659
|
withExamples(
|
|
59634
|
-
profile.command("remove <name>").description("Delete a configuration profile's file. References to it by name are left for `
|
|
59660
|
+
profile.command("remove <name>").description("Delete a configuration profile's file. References to it by name are left for `agent-shim doctor` to report.").option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").action(async (name, options) => {
|
|
59635
59661
|
requireProfileExists(paths, name);
|
|
59636
59662
|
await confirmRemoval(deps, options.yes, `configuration profile "${name}"`);
|
|
59637
59663
|
removeProfile(paths, name);
|
|
59638
59664
|
console.log(`Removed configuration profile "${name}".`);
|
|
59639
59665
|
}),
|
|
59640
|
-
["
|
|
59666
|
+
["agent-shim profile remove client-acme --yes"]
|
|
59641
59667
|
);
|
|
59642
59668
|
withExamples(
|
|
59643
59669
|
profile.command("use <name>").description("Make a configuration profile the global default, used when no directory rule or identity selects one.").action(async (name) => {
|
|
@@ -59645,7 +59671,7 @@ function registerProfileCommand(program2, deps) {
|
|
|
59645
59671
|
setGlobalDefaultProfile(paths, name);
|
|
59646
59672
|
console.log(`Global default configuration profile is now "${name}".`);
|
|
59647
59673
|
}),
|
|
59648
|
-
["
|
|
59674
|
+
["agent-shim profile use work-default"]
|
|
59649
59675
|
);
|
|
59650
59676
|
}
|
|
59651
59677
|
|
|
@@ -59668,8 +59694,8 @@ function decideIdentity(params) {
|
|
|
59668
59694
|
if (isNonEmpty(params.argv0Identity)) {
|
|
59669
59695
|
return selected(params.argv0Identity, "argv");
|
|
59670
59696
|
}
|
|
59671
|
-
if (isNonEmpty(params.env.
|
|
59672
|
-
return selected(params.env.
|
|
59697
|
+
if (isNonEmpty(params.env.AGENT_SHIM_IDENTITY)) {
|
|
59698
|
+
return selected(params.env.AGENT_SHIM_IDENTITY, "env");
|
|
59673
59699
|
}
|
|
59674
59700
|
if (isNonEmpty(params.directoryPinnedIdentity)) {
|
|
59675
59701
|
return selected(params.directoryPinnedIdentity, "directory-pin");
|
|
@@ -59684,8 +59710,8 @@ function decideConfigProfile(params) {
|
|
|
59684
59710
|
if (isNonEmpty(params.cliFlagConfigProfile)) {
|
|
59685
59711
|
return { name: params.cliFlagConfigProfile, source: "cli-flag" };
|
|
59686
59712
|
}
|
|
59687
|
-
if (isNonEmpty(params.env.
|
|
59688
|
-
return { name: params.env.
|
|
59713
|
+
if (isNonEmpty(params.env.AGENT_SHIM_CONFIG_PROFILE)) {
|
|
59714
|
+
return { name: params.env.AGENT_SHIM_CONFIG_PROFILE, source: "env" };
|
|
59689
59715
|
}
|
|
59690
59716
|
if (isNonEmpty(params.directoryRuleConfigProfile)) {
|
|
59691
59717
|
return { name: params.directoryRuleConfigProfile, source: "directory-rule" };
|
|
@@ -59698,14 +59724,14 @@ function decideConfigProfile(params) {
|
|
|
59698
59724
|
}
|
|
59699
59725
|
return { source: "none" };
|
|
59700
59726
|
}
|
|
59701
|
-
function loadIdentity(identitiesDir, name,
|
|
59702
|
-
return loadConfigFile(import_node_path14.default.join(identitiesDir, name, "identity.json"), IdentitySchema,
|
|
59727
|
+
function loadIdentity(identitiesDir, name, fs17) {
|
|
59728
|
+
return loadConfigFile(import_node_path14.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs17.readConfigFile);
|
|
59703
59729
|
}
|
|
59704
59730
|
|
|
59705
59731
|
// src/poolStore.ts
|
|
59706
59732
|
var PoolNotFoundError = class extends CliError {
|
|
59707
59733
|
constructor(poolName) {
|
|
59708
|
-
super(`No pool named "${poolName}". Run \`
|
|
59734
|
+
super(`No pool named "${poolName}". Run \`agent-shim pool add ${poolName} --identity <name>...\` first.`);
|
|
59709
59735
|
this.poolName = poolName;
|
|
59710
59736
|
this.name = "PoolNotFoundError";
|
|
59711
59737
|
}
|
|
@@ -59713,7 +59739,7 @@ var PoolNotFoundError = class extends CliError {
|
|
|
59713
59739
|
};
|
|
59714
59740
|
var PoolAlreadyExistsError = class extends CliError {
|
|
59715
59741
|
constructor(poolName) {
|
|
59716
|
-
super(`A pool named "${poolName}" already exists. Use \`
|
|
59742
|
+
super(`A pool named "${poolName}" already exists. Use \`agent-shim pool set ${poolName}\` to change its members.`);
|
|
59717
59743
|
this.poolName = poolName;
|
|
59718
59744
|
this.name = "PoolAlreadyExistsError";
|
|
59719
59745
|
}
|
|
@@ -59767,7 +59793,7 @@ function removePool(paths, name) {
|
|
|
59767
59793
|
// src/identityManager.ts
|
|
59768
59794
|
var IdentityNotFoundError = class extends CliError {
|
|
59769
59795
|
constructor(name) {
|
|
59770
|
-
super(`No identity named "${name}". Run \`
|
|
59796
|
+
super(`No identity named "${name}". Run \`agent-shim identity add ${name}\` first.`);
|
|
59771
59797
|
this.name = name;
|
|
59772
59798
|
this.name = "IdentityNotFoundError";
|
|
59773
59799
|
}
|
|
@@ -59995,14 +60021,14 @@ function registerIdentityCommand(program2, deps) {
|
|
|
59995
60021
|
const { paths } = deps;
|
|
59996
60022
|
const identity = withExamples(
|
|
59997
60023
|
program2.command("identity").description("Manage identities: each one is a separate Claude Code login with its own credentials."),
|
|
59998
|
-
["
|
|
60024
|
+
["agent-shim identity add work", "agent-shim identity list"]
|
|
59999
60025
|
);
|
|
60000
60026
|
withExamples(
|
|
60001
60027
|
identity.command("add <name>").description("Create a new identity. Fails if one with this name already exists.").action((name) => {
|
|
60002
60028
|
addIdentity(paths, name);
|
|
60003
60029
|
console.log(`Created identity "${name}".`);
|
|
60004
60030
|
}),
|
|
60005
|
-
["
|
|
60031
|
+
["agent-shim identity add work"]
|
|
60006
60032
|
);
|
|
60007
60033
|
withExamples(
|
|
60008
60034
|
identity.command("list").description("List every identity, marking the active one with *.").option("--json", "Print the identities as JSON.").action((options) => {
|
|
@@ -60012,17 +60038,17 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60012
60038
|
return;
|
|
60013
60039
|
}
|
|
60014
60040
|
if (entries.length === 0) {
|
|
60015
|
-
console.log("No identities yet. Run `
|
|
60041
|
+
console.log("No identities yet. Run `agent-shim identity add <name>` to create one.");
|
|
60016
60042
|
return;
|
|
60017
60043
|
}
|
|
60018
60044
|
for (const entry of entries) {
|
|
60019
60045
|
console.log(formatIdentityLine(entry));
|
|
60020
60046
|
}
|
|
60021
60047
|
if (entries.some((entry) => entry.problem !== void 0)) {
|
|
60022
|
-
console.log("\nRun `
|
|
60048
|
+
console.log("\nRun `agent-shim doctor` for the full detail on every unreadable entry.");
|
|
60023
60049
|
}
|
|
60024
60050
|
}),
|
|
60025
|
-
["
|
|
60051
|
+
["agent-shim identity list", "agent-shim identity list --json"]
|
|
60026
60052
|
);
|
|
60027
60053
|
withExamples(
|
|
60028
60054
|
identity.command("show <name>").description("Show one identity's settings and directory.").option("--json", "Print the identity as JSON.").action((name, options) => {
|
|
@@ -60045,7 +60071,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60045
60071
|
console.log(`Allows ambient credential: ${view.allowAmbientCredential === true ? "yes" : "no"}`);
|
|
60046
60072
|
console.log(`Credential: ${entry.identity?.credential === void 0 ? "(none; uses its stored login)" : describeCredential(entry.identity.credential)}`);
|
|
60047
60073
|
}),
|
|
60048
|
-
["
|
|
60074
|
+
["agent-shim identity show work", "agent-shim identity show work --json"]
|
|
60049
60075
|
);
|
|
60050
60076
|
const identitySet = identity.command("set <name>").description("Update an identity's settings.").option("--default-profile <profile>", "Configuration profile this identity uses when nothing more specific selects one.").option("--no-default-profile", "Clear this identity's default configuration profile.").option("--allow-ambient-credential", "Allow this identity to launch even with an ambient credential env var set.").option("--no-allow-ambient-credential", "Disallow ambient credential env vars for this identity (the default).").option(
|
|
60051
60077
|
"--credential <source>",
|
|
@@ -60100,10 +60126,10 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60100
60126
|
}
|
|
60101
60127
|
}),
|
|
60102
60128
|
[
|
|
60103
|
-
"
|
|
60104
|
-
"
|
|
60105
|
-
"
|
|
60106
|
-
"
|
|
60129
|
+
"agent-shim identity set work --default-profile client-acme",
|
|
60130
|
+
"agent-shim identity set work --allow-ambient-credential",
|
|
60131
|
+
"agent-shim identity set work --credential-target oauthToken --credential op:op://vault/claude-work/token",
|
|
60132
|
+
"agent-shim identity set work --no-credential"
|
|
60107
60133
|
]
|
|
60108
60134
|
);
|
|
60109
60135
|
withExamples(
|
|
@@ -60117,13 +60143,13 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60117
60143
|
removeIdentity(paths, name);
|
|
60118
60144
|
console.log(`Removed identity "${name}".`);
|
|
60119
60145
|
}),
|
|
60120
|
-
["
|
|
60146
|
+
["agent-shim identity remove old-client --yes"]
|
|
60121
60147
|
);
|
|
60122
60148
|
withExamples(
|
|
60123
60149
|
identity.command("use <name>").description("Select the active identity, used by every launch that names none. Offers to create it on a terminal if it does not exist.").action(async (name) => {
|
|
60124
60150
|
await selectIdentity(deps, name);
|
|
60125
60151
|
}),
|
|
60126
|
-
["
|
|
60152
|
+
["agent-shim identity use work", "agent-shim @work"]
|
|
60127
60153
|
);
|
|
60128
60154
|
withExamples(
|
|
60129
60155
|
identity.command("resolve-conflicts <name>").description("Interactively resolve data a superseded farm left behind when it collides with the current farm's copy.").action(async (name) => {
|
|
@@ -60162,7 +60188,7 @@ function registerIdentityCommand(program2, deps) {
|
|
|
60162
60188
|
`Resolved ${String(result.resolved.length)} conflict(s): ${String(result.removed.length)} superseded director(ies) fully cleared, ${String(result.retained.length)} still retained pending a skipped conflict.`
|
|
60163
60189
|
);
|
|
60164
60190
|
}),
|
|
60165
|
-
["
|
|
60191
|
+
["agent-shim identity resolve-conflicts work"]
|
|
60166
60192
|
);
|
|
60167
60193
|
}
|
|
60168
60194
|
|
|
@@ -60183,7 +60209,7 @@ var DirectoryRuleMissingTargetError = class extends CliError {
|
|
|
60183
60209
|
};
|
|
60184
60210
|
var DirectoryRuleAlreadyExistsError = class extends CliError {
|
|
60185
60211
|
constructor(rulePath) {
|
|
60186
|
-
super(`A directory rule for path "${rulePath}" already exists. Use \`
|
|
60212
|
+
super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
|
|
60187
60213
|
this.rulePath = rulePath;
|
|
60188
60214
|
this.name = "DirectoryRuleAlreadyExistsError";
|
|
60189
60215
|
}
|
|
@@ -60271,7 +60297,7 @@ function registerRuleCommand(program2, deps) {
|
|
|
60271
60297
|
const { paths } = deps;
|
|
60272
60298
|
const rule = withExamples(
|
|
60273
60299
|
program2.command("rule").description("Manage directory rules: pin an identity or configuration profile to every launch under a path."),
|
|
60274
|
-
["
|
|
60300
|
+
["agent-shim rule add ~/work/acme --config-profile client-acme", "agent-shim rule list"]
|
|
60275
60301
|
);
|
|
60276
60302
|
withExamples(
|
|
60277
60303
|
rule.command("add <path>").description("Add a directory rule for a path. Fails if a rule for that exact path already exists.").option("--config-profile <profile>", "Configuration profile to select under this path.").option("--identity <identity>", "Identity to pin under this path.").action(async (rulePath, options) => {
|
|
@@ -60279,7 +60305,7 @@ function registerRuleCommand(program2, deps) {
|
|
|
60279
60305
|
addDirectoryRule(paths, rulePath, options);
|
|
60280
60306
|
console.log(`Added directory rule for "${rulePath}".`);
|
|
60281
60307
|
}),
|
|
60282
|
-
["
|
|
60308
|
+
["agent-shim rule add ~/work/acme --config-profile client-acme", "agent-shim rule add ~/personal --identity personal"]
|
|
60283
60309
|
);
|
|
60284
60310
|
withExamples(
|
|
60285
60311
|
rule.command("set <path>").description("Update the directory rule for a path.").option("--config-profile <profile>", "Configuration profile to select under this path.").option("--no-config-profile", "Stop selecting a configuration profile under this path.").option("--identity <identity>", "Identity to pin under this path.").option("--no-identity", "Stop pinning an identity under this path.").action(async (rulePath, options) => {
|
|
@@ -60290,7 +60316,7 @@ function registerRuleCommand(program2, deps) {
|
|
|
60290
60316
|
updateDirectoryRule(paths, rulePath, options);
|
|
60291
60317
|
console.log(`Updated directory rule for "${rulePath}".`);
|
|
60292
60318
|
}),
|
|
60293
|
-
["
|
|
60319
|
+
["agent-shim rule set ~/work/acme --identity work", "agent-shim rule set ~/work/acme --no-config-profile"]
|
|
60294
60320
|
);
|
|
60295
60321
|
withExamples(
|
|
60296
60322
|
rule.command("list").description("List every directory rule, in file order.").option("--json", "Print the rules as JSON.").action((options) => {
|
|
@@ -60300,14 +60326,14 @@ function registerRuleCommand(program2, deps) {
|
|
|
60300
60326
|
return;
|
|
60301
60327
|
}
|
|
60302
60328
|
if (entries.length === 0) {
|
|
60303
|
-
console.log("No directory rules yet. Run `
|
|
60329
|
+
console.log("No directory rules yet. Run `agent-shim rule add <path>` to create one.");
|
|
60304
60330
|
return;
|
|
60305
60331
|
}
|
|
60306
60332
|
for (const entry of entries) {
|
|
60307
60333
|
console.log(` ${entry.path} (${describeRule(entry)})`);
|
|
60308
60334
|
}
|
|
60309
60335
|
}),
|
|
60310
|
-
["
|
|
60336
|
+
["agent-shim rule list", "agent-shim rule list --json"]
|
|
60311
60337
|
);
|
|
60312
60338
|
withExamples(
|
|
60313
60339
|
rule.command("show <path>").description("Show the directory rule for a path, matched exactly as it was written.").option("--json", "Print the rule as JSON.").action((rulePath, options) => {
|
|
@@ -60322,7 +60348,7 @@ function registerRuleCommand(program2, deps) {
|
|
|
60322
60348
|
console.log(`Directory rule: ${found.path}`);
|
|
60323
60349
|
console.log(`Settings: ${describeRule(found)}`);
|
|
60324
60350
|
}),
|
|
60325
|
-
["
|
|
60351
|
+
["agent-shim rule show ~/work/acme"]
|
|
60326
60352
|
);
|
|
60327
60353
|
withExamples(
|
|
60328
60354
|
rule.command("remove <path>").description("Remove the directory rule for a path.").option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").action(async (rulePath, options) => {
|
|
@@ -60333,7 +60359,7 @@ function registerRuleCommand(program2, deps) {
|
|
|
60333
60359
|
removeDirectoryRule(paths, rulePath);
|
|
60334
60360
|
console.log(`Removed directory rule for "${rulePath}".`);
|
|
60335
60361
|
}),
|
|
60336
|
-
["
|
|
60362
|
+
["agent-shim rule remove ~/work/acme --yes"]
|
|
60337
60363
|
);
|
|
60338
60364
|
}
|
|
60339
60365
|
|
|
@@ -60363,8 +60389,8 @@ function isAncestorOrSelf(ancestor, descendant) {
|
|
|
60363
60389
|
}
|
|
60364
60390
|
|
|
60365
60391
|
// src/launcher/cascade.ts
|
|
60366
|
-
var PORTABLE_CONFIG_FILENAME = ".
|
|
60367
|
-
var PORTABLE_LOCAL_CONFIG_FILENAME = ".
|
|
60392
|
+
var PORTABLE_CONFIG_FILENAME = ".agent-shim.json";
|
|
60393
|
+
var PORTABLE_LOCAL_CONFIG_FILENAME = ".agent-shim.local.json";
|
|
60368
60394
|
function loadCascadeInput(params) {
|
|
60369
60395
|
const globalConfig2 = loadConfigFile(params.paths.globalConfigFile, GlobalConfigSchema, params.read);
|
|
60370
60396
|
const directoryRules = loadConfigFile(params.paths.directoryRulesFile, DirectoryRulesSchema, params.read);
|
|
@@ -60384,8 +60410,8 @@ function loadCascadeInput(params) {
|
|
|
60384
60410
|
});
|
|
60385
60411
|
const levels = [];
|
|
60386
60412
|
for (const dir of dirs) {
|
|
60387
|
-
const portable = loadConfigFile(import_node_path17.default.join(dir, PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read);
|
|
60388
|
-
const portableLocal = loadConfigFile(import_node_path17.default.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read);
|
|
60413
|
+
const portable = loadConfigFile(import_node_path17.default.join(dir, PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(import_node_path17.default.join(dir, LEGACY_PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read);
|
|
60414
|
+
const portableLocal = loadConfigFile(import_node_path17.default.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(import_node_path17.default.join(dir, LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read);
|
|
60389
60415
|
const rules = (directoryRules?.config.rules ?? []).map((rule, index) => ({ rule, index })).filter(({ rule }) => normaliseRulePath(rule.path, params.home) === dir).map(({ rule, index }) => {
|
|
60390
60416
|
const entryOrder = directoryRules?.ruleEntryOrders[index];
|
|
60391
60417
|
return {
|
|
@@ -60434,17 +60460,23 @@ function readDirectorySelections(loaded) {
|
|
|
60434
60460
|
}
|
|
60435
60461
|
|
|
60436
60462
|
// src/paths.ts
|
|
60463
|
+
var import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
60437
60464
|
var import_node_os3 = __toESM(require("node:os"), 1);
|
|
60438
60465
|
var import_node_path18 = __toESM(require("node:path"), 1);
|
|
60439
|
-
function
|
|
60440
|
-
const fromEnv =
|
|
60466
|
+
function resolveAgentShimHome(env = process.env, home = import_node_os3.default.homedir(), isDirectory = isExistingDirectory) {
|
|
60467
|
+
const fromEnv = env.AGENT_SHIM_HOME;
|
|
60441
60468
|
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
60442
60469
|
return fromEnv;
|
|
60443
60470
|
}
|
|
60444
|
-
|
|
60471
|
+
const current = import_node_path18.default.join(home, HOME_DIRNAME);
|
|
60472
|
+
const legacy = import_node_path18.default.join(home, LEGACY_HOME_DIRNAME);
|
|
60473
|
+
return !isDirectory(current) && isDirectory(legacy) ? legacy : current;
|
|
60474
|
+
}
|
|
60475
|
+
function isExistingDirectory(candidate) {
|
|
60476
|
+
return import_node_fs7.default.statSync(candidate, { throwIfNoEntry: false })?.isDirectory() ?? false;
|
|
60445
60477
|
}
|
|
60446
60478
|
function resolveClaudeHome() {
|
|
60447
|
-
const fromEnv = process.env.
|
|
60479
|
+
const fromEnv = process.env.AGENT_SHIM_CLAUDE_HOME;
|
|
60448
60480
|
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
60449
60481
|
return fromEnv;
|
|
60450
60482
|
}
|
|
@@ -60483,14 +60515,14 @@ function buildLayoutPaths(root) {
|
|
|
60483
60515
|
};
|
|
60484
60516
|
}
|
|
60485
60517
|
function resolveLayoutPaths() {
|
|
60486
|
-
return buildLayoutPaths(
|
|
60518
|
+
return buildLayoutPaths(resolveAgentShimHome());
|
|
60487
60519
|
}
|
|
60488
60520
|
|
|
60489
60521
|
// src/configure.ts
|
|
60490
60522
|
var NoConfigProfileResolvedError = class extends CliError {
|
|
60491
60523
|
constructor(identityName, cwd) {
|
|
60492
60524
|
super(
|
|
60493
|
-
`No configuration profile resolves for identity "${identityName}" at "${cwd}". Create one with \`
|
|
60525
|
+
`No configuration profile resolves for identity "${identityName}" at "${cwd}". Create one with \`agent-shim profile add <name>\` and make it this identity's default with \`agent-shim identity set ${identityName} --default-profile <name>\` before running \`configure\`.`
|
|
60494
60526
|
);
|
|
60495
60527
|
this.identityName = identityName;
|
|
60496
60528
|
this.cwd = cwd;
|
|
@@ -60501,13 +60533,13 @@ var NoConfigProfileResolvedError = class extends CliError {
|
|
|
60501
60533
|
};
|
|
60502
60534
|
var ConfigureNeedsTerminalError = class extends UsageError {
|
|
60503
60535
|
constructor() {
|
|
60504
|
-
super("`
|
|
60536
|
+
super("`agent-shim configure` is interactive and needs a terminal. From a script, use `agent-shim profile set` or edit the files it writes.");
|
|
60505
60537
|
this.name = "ConfigureNeedsTerminalError";
|
|
60506
60538
|
}
|
|
60507
60539
|
};
|
|
60508
60540
|
var NoIdentityResolvedError = class extends UsageError {
|
|
60509
60541
|
constructor(cwd) {
|
|
60510
|
-
super(`No identity resolves in "${cwd}": pass --identity <name>, or select one with \`
|
|
60542
|
+
super(`No identity resolves in "${cwd}": pass --identity <name>, or select one with \`agent-shim identity use <name>\`.`);
|
|
60511
60543
|
this.cwd = cwd;
|
|
60512
60544
|
this.name = "NoIdentityResolvedError";
|
|
60513
60545
|
}
|
|
@@ -60561,7 +60593,7 @@ function chooseWriteTarget(params) {
|
|
|
60561
60593
|
for (let index = params.levels.length - 1; index >= 0; index -= 1) {
|
|
60562
60594
|
const level = params.levels[index];
|
|
60563
60595
|
if (level !== void 0 && (level.hasPortable || level.hasPortableLocal)) {
|
|
60564
|
-
return { tier: "portable-local", localConfigPath: import_node_path19.default.join(level.dir,
|
|
60596
|
+
return { tier: "portable-local", localConfigPath: import_node_path19.default.join(level.dir, level.portableLocalFilename) };
|
|
60565
60597
|
}
|
|
60566
60598
|
}
|
|
60567
60599
|
const normalisedCwd = normaliseRulePath(params.cwd, params.home);
|
|
@@ -60653,11 +60685,16 @@ function parentOf3(relPath) {
|
|
|
60653
60685
|
function buildWriteTargetLevels(cwd, home, walkUpLimit) {
|
|
60654
60686
|
const limit = walkUpLimit === void 0 ? void 0 : expandTilde(walkUpLimit, home);
|
|
60655
60687
|
const dirs = walkDirectoryAncestors(cwd, { home, ...limit === void 0 ? {} : { limit } });
|
|
60656
|
-
return dirs.map((dir) =>
|
|
60657
|
-
dir,
|
|
60658
|
-
|
|
60659
|
-
|
|
60660
|
-
|
|
60688
|
+
return dirs.map((dir) => {
|
|
60689
|
+
const hasLocal = import_node_fs8.default.existsSync(import_node_path19.default.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME));
|
|
60690
|
+
const hasLegacyLocal = import_node_fs8.default.existsSync(import_node_path19.default.join(dir, LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME));
|
|
60691
|
+
return {
|
|
60692
|
+
dir,
|
|
60693
|
+
hasPortable: import_node_fs8.default.existsSync(import_node_path19.default.join(dir, PORTABLE_CONFIG_FILENAME)) || import_node_fs8.default.existsSync(import_node_path19.default.join(dir, LEGACY_PORTABLE_CONFIG_FILENAME)),
|
|
60694
|
+
hasPortableLocal: hasLocal || hasLegacyLocal,
|
|
60695
|
+
portableLocalFilename: !hasLocal && hasLegacyLocal ? LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME : PORTABLE_LOCAL_CONFIG_FILENAME
|
|
60696
|
+
};
|
|
60697
|
+
});
|
|
60661
60698
|
}
|
|
60662
60699
|
function resolveWriteTarget(context) {
|
|
60663
60700
|
return chooseWriteTarget({
|
|
@@ -60821,7 +60858,7 @@ async function runProfileDirectMode(context) {
|
|
|
60821
60858
|
const { deps } = context;
|
|
60822
60859
|
const profiles = listProfiles(deps.paths);
|
|
60823
60860
|
if (profiles.length === 0) {
|
|
60824
|
-
deps.log.info("No configuration profiles exist yet. Run `
|
|
60861
|
+
deps.log.info("No configuration profiles exist yet. Run `agent-shim profile add <name>` first.");
|
|
60825
60862
|
return;
|
|
60826
60863
|
}
|
|
60827
60864
|
const chosen = await deps.prompts.select({
|
|
@@ -60979,7 +61016,7 @@ function registerConfigureCommand(program2, deps) {
|
|
|
60979
61016
|
}
|
|
60980
61017
|
);
|
|
60981
61018
|
});
|
|
60982
|
-
withExamples(command, ["
|
|
61019
|
+
withExamples(command, ["agent-shim configure", "agent-shim configure --identity work", "agent-shim configure projects --identity work"]);
|
|
60983
61020
|
}
|
|
60984
61021
|
function resolveLaunchIdentity(paths, cwd) {
|
|
60985
61022
|
const loaded = loadCascadeInput({ paths, home: import_node_os4.default.homedir(), cwd, read: cosmiconfigReader() });
|
|
@@ -60997,16 +61034,16 @@ function resolveLaunchIdentity(paths, cwd) {
|
|
|
60997
61034
|
// package.json
|
|
60998
61035
|
var package_default = {
|
|
60999
61036
|
name: "claude-use",
|
|
61000
|
-
version: "
|
|
61037
|
+
version: "7.1.0",
|
|
61001
61038
|
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.",
|
|
61002
61039
|
license: "Apache-2.0",
|
|
61003
61040
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
61004
61041
|
repository: {
|
|
61005
61042
|
type: "git",
|
|
61006
|
-
url: "git+https://github.com/ExaDev/
|
|
61043
|
+
url: "git+https://github.com/ExaDev/agent-shim.git"
|
|
61007
61044
|
},
|
|
61008
|
-
homepage: "https://github.com/ExaDev/
|
|
61009
|
-
bugs: "https://github.com/ExaDev/
|
|
61045
|
+
homepage: "https://github.com/ExaDev/agent-shim#readme",
|
|
61046
|
+
bugs: "https://github.com/ExaDev/agent-shim/issues",
|
|
61010
61047
|
keywords: [
|
|
61011
61048
|
"claude-code",
|
|
61012
61049
|
"claude",
|
|
@@ -61018,6 +61055,7 @@ var package_default = {
|
|
|
61018
61055
|
node: "^22.18 || >=24"
|
|
61019
61056
|
},
|
|
61020
61057
|
bin: {
|
|
61058
|
+
"agent-shim": "dist/cli.cjs",
|
|
61021
61059
|
"claude-use": "dist/cli.cjs"
|
|
61022
61060
|
},
|
|
61023
61061
|
files: [
|
|
@@ -61116,12 +61154,12 @@ function detectAmbientCredential(env, injected) {
|
|
|
61116
61154
|
return void 0;
|
|
61117
61155
|
}
|
|
61118
61156
|
function formatAmbientCredentialGuardMessage(variable, identityName) {
|
|
61119
|
-
const identitySetCommand = identityName === void 0 ? "
|
|
61157
|
+
const identitySetCommand = identityName === void 0 ? "agent-shim identity set <name> --allow-ambient-credential" : `agent-shim identity set ${identityName} --allow-ambient-credential`;
|
|
61120
61158
|
return [
|
|
61121
61159
|
`error: ${variable} is set in the environment. This identity's isolated`,
|
|
61122
61160
|
"credential would be bypassed \u2014 every identity authenticates as this same key",
|
|
61123
61161
|
"while it's set. Unset it, or if this is deliberate, opt in per-launch with",
|
|
61124
|
-
"
|
|
61162
|
+
"AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL=1, or persistently for this identity with",
|
|
61125
61163
|
`\`${identitySetCommand}\`.`
|
|
61126
61164
|
].join("\n");
|
|
61127
61165
|
}
|
|
@@ -61184,7 +61222,7 @@ function quotaWarnings(snapshot, provider, nowMs) {
|
|
|
61184
61222
|
}
|
|
61185
61223
|
const reset = window.resetsAt === void 0 ? "" : `, resets ${window.resetsAt}`;
|
|
61186
61224
|
const verdict = effective.status === "rejected" ? "exhausted" : "nearly used";
|
|
61187
|
-
return [`
|
|
61225
|
+
return [`agent-shim: identity ${snapshot.identity}: the ${name} quota is ${verdict}${reset} (last seen ${age} ago)`];
|
|
61188
61226
|
});
|
|
61189
61227
|
}
|
|
61190
61228
|
|
|
@@ -61363,12 +61401,12 @@ function isIdentityName(name) {
|
|
|
61363
61401
|
function claudeJsonPath(identitiesDir, identity) {
|
|
61364
61402
|
return import_node_path20.default.join(identitiesDir, identity, CLAUDE_JSON);
|
|
61365
61403
|
}
|
|
61366
|
-
function readAccountMetadata(
|
|
61404
|
+
function readAccountMetadata(fs17, identitiesDir, identity) {
|
|
61367
61405
|
if (!isIdentityName(identity)) {
|
|
61368
61406
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
61369
61407
|
}
|
|
61370
61408
|
const file2 = claudeJsonPath(identitiesDir, identity);
|
|
61371
|
-
const raw =
|
|
61409
|
+
const raw = fs17.readFileUtf8(file2);
|
|
61372
61410
|
if (raw === void 0) {
|
|
61373
61411
|
return void 0;
|
|
61374
61412
|
}
|
|
@@ -61398,19 +61436,19 @@ function readAccountMetadata(fs16, identitiesDir, identity) {
|
|
|
61398
61436
|
}
|
|
61399
61437
|
return account.data;
|
|
61400
61438
|
}
|
|
61401
|
-
function createAccountReader(
|
|
61439
|
+
function createAccountReader(fs17, identitiesDir) {
|
|
61402
61440
|
const cache = /* @__PURE__ */ new Map();
|
|
61403
61441
|
return (identity) => {
|
|
61404
61442
|
if (!isIdentityName(identity)) {
|
|
61405
61443
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
61406
61444
|
}
|
|
61407
|
-
const stat =
|
|
61445
|
+
const stat = fs17.lstat(claudeJsonPath(identitiesDir, identity));
|
|
61408
61446
|
const stamp = stat === void 0 ? "absent" : `${String(stat.mtimeMs)}:${String(stat.sizeBytes)}`;
|
|
61409
61447
|
const cached2 = cache.get(identity);
|
|
61410
61448
|
if (cached2?.stamp === stamp) {
|
|
61411
61449
|
return cached2.account;
|
|
61412
61450
|
}
|
|
61413
|
-
const account = readAccountMetadata(
|
|
61451
|
+
const account = readAccountMetadata(fs17, identitiesDir, identity);
|
|
61414
61452
|
cache.set(identity, { stamp, account });
|
|
61415
61453
|
return account;
|
|
61416
61454
|
};
|
|
@@ -61441,23 +61479,23 @@ var zlib = __toESM(require("node:zlib"), 1);
|
|
|
61441
61479
|
|
|
61442
61480
|
// src/frontdoor/route.ts
|
|
61443
61481
|
var INTERNAL_HEADER_NAMES = [
|
|
61444
|
-
"x-
|
|
61445
|
-
"x-
|
|
61446
|
-
"x-
|
|
61447
|
-
"x-
|
|
61448
|
-
"x-
|
|
61449
|
-
"x-
|
|
61482
|
+
"x-agent-shim-identity",
|
|
61483
|
+
"x-agent-shim-session",
|
|
61484
|
+
"x-agent-shim-headroom",
|
|
61485
|
+
"x-agent-shim-auth",
|
|
61486
|
+
"x-agent-shim-hop",
|
|
61487
|
+
"x-agent-shim-hop-id",
|
|
61450
61488
|
"x-headroom-project-id",
|
|
61451
61489
|
"x-headroom-base-url"
|
|
61452
61490
|
];
|
|
61453
|
-
var IDENTITY_HEADER = "x-
|
|
61454
|
-
var SESSION_HEADER = "x-
|
|
61455
|
-
var HEADROOM_FLAG_HEADER = "x-
|
|
61491
|
+
var IDENTITY_HEADER = "x-agent-shim-identity";
|
|
61492
|
+
var SESSION_HEADER = "x-agent-shim-session";
|
|
61493
|
+
var HEADROOM_FLAG_HEADER = "x-agent-shim-headroom";
|
|
61456
61494
|
var PROJECT_ID_HEADER = "x-headroom-project-id";
|
|
61457
61495
|
var HEADROOM_BASE_URL_HEADER = "x-headroom-base-url";
|
|
61458
|
-
var AUTH_HEADER = "x-
|
|
61459
|
-
var HOP_SECRET_HEADER = "x-
|
|
61460
|
-
var HOP_ID_HEADER = "x-
|
|
61496
|
+
var AUTH_HEADER = "x-agent-shim-auth";
|
|
61497
|
+
var HOP_SECRET_HEADER = "x-agent-shim-hop";
|
|
61498
|
+
var HOP_ID_HEADER = "x-agent-shim-hop-id";
|
|
61461
61499
|
function singleHeaderValue(value) {
|
|
61462
61500
|
if (typeof value === "string") {
|
|
61463
61501
|
return value;
|
|
@@ -61500,11 +61538,11 @@ function providerBaseUrl(port, provider) {
|
|
|
61500
61538
|
function directOrigin(port) {
|
|
61501
61539
|
return `http://127.0.0.1:${String(port)}`;
|
|
61502
61540
|
}
|
|
61503
|
-
function parseProviderPath(
|
|
61504
|
-
if (!
|
|
61541
|
+
function parseProviderPath(path36) {
|
|
61542
|
+
if (!path36.startsWith(PROVIDER_PATH_PREFIX)) {
|
|
61505
61543
|
return void 0;
|
|
61506
61544
|
}
|
|
61507
|
-
const tail =
|
|
61545
|
+
const tail = path36.slice(PROVIDER_PATH_PREFIX.length);
|
|
61508
61546
|
const slash = tail.indexOf("/");
|
|
61509
61547
|
if (slash <= 0) {
|
|
61510
61548
|
return void 0;
|
|
@@ -61904,9 +61942,9 @@ function decoderFor(encoding) {
|
|
|
61904
61942
|
return void 0;
|
|
61905
61943
|
}
|
|
61906
61944
|
}
|
|
61907
|
-
function destinationOf(
|
|
61908
|
-
const scoped = parseProviderPath(
|
|
61909
|
-
return scoped === void 0 ? { provider: ANTHROPIC_PROVIDER, endpoint:
|
|
61945
|
+
function destinationOf(path36) {
|
|
61946
|
+
const scoped = parseProviderPath(path36);
|
|
61947
|
+
return scoped === void 0 ? { provider: ANTHROPIC_PROVIDER, endpoint: path36 } : { provider: scoped.provider, endpoint: scoped.rest };
|
|
61910
61948
|
}
|
|
61911
61949
|
function buildRecord(event, context) {
|
|
61912
61950
|
const { scan } = context;
|
|
@@ -62178,8 +62216,8 @@ function segmentDay(epochMs) {
|
|
|
62178
62216
|
function segmentName(day, pid) {
|
|
62179
62217
|
return `${day}.${String(pid)}.jsonl`;
|
|
62180
62218
|
}
|
|
62181
|
-
function listLogSegments(
|
|
62182
|
-
return
|
|
62219
|
+
function listLogSegments(fs17, logDir) {
|
|
62220
|
+
return fs17.readdir(logDir).flatMap((name) => {
|
|
62183
62221
|
const match = SEGMENT_RE.exec(name);
|
|
62184
62222
|
const day = match?.[1];
|
|
62185
62223
|
if (day === void 0) {
|
|
@@ -62188,15 +62226,15 @@ function listLogSegments(fs16, logDir) {
|
|
|
62188
62226
|
return [{ name, day, endsAt: Date.parse(`${day}T00:00:00.000Z`) + DAY_MS }];
|
|
62189
62227
|
}).sort((left, right) => left.day.localeCompare(right.day) || left.name.localeCompare(right.name));
|
|
62190
62228
|
}
|
|
62191
|
-
function readUsageLog(
|
|
62229
|
+
function readUsageLog(fs17, logDir, options = {}) {
|
|
62192
62230
|
const { sinceMs } = options;
|
|
62193
62231
|
const records = [];
|
|
62194
62232
|
let invalidLines = 0;
|
|
62195
|
-
for (const segment of listLogSegments(
|
|
62233
|
+
for (const segment of listLogSegments(fs17, logDir)) {
|
|
62196
62234
|
if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
|
|
62197
62235
|
continue;
|
|
62198
62236
|
}
|
|
62199
|
-
const contents =
|
|
62237
|
+
const contents = fs17.readFileUtf8(import_node_path21.default.join(logDir, segment.name));
|
|
62200
62238
|
if (contents === void 0) {
|
|
62201
62239
|
continue;
|
|
62202
62240
|
}
|
|
@@ -62228,7 +62266,7 @@ function readUsageLog(fs16, logDir, options = {}) {
|
|
|
62228
62266
|
}
|
|
62229
62267
|
var UsageSnapshotError = class extends Error {
|
|
62230
62268
|
constructor(file2, detail) {
|
|
62231
|
-
super(`${file2} is not a usage snapshot this
|
|
62269
|
+
super(`${file2} is not a usage snapshot this agent-shim can read (schema version ${String(USAGE_SCHEMA_VERSION)}): ${detail}`);
|
|
62232
62270
|
this.file = file2;
|
|
62233
62271
|
this.name = "UsageSnapshotError";
|
|
62234
62272
|
}
|
|
@@ -62240,9 +62278,9 @@ function snapshotPath(snapshotsDir, identity) {
|
|
|
62240
62278
|
}
|
|
62241
62279
|
return import_node_path21.default.join(snapshotsDir, `${identity}.json`);
|
|
62242
62280
|
}
|
|
62243
|
-
function readUsageSnapshot(
|
|
62281
|
+
function readUsageSnapshot(fs17, snapshotsDir, identity) {
|
|
62244
62282
|
const file2 = snapshotPath(snapshotsDir, identity);
|
|
62245
|
-
const raw =
|
|
62283
|
+
const raw = fs17.readFileUtf8(file2);
|
|
62246
62284
|
if (raw === void 0) {
|
|
62247
62285
|
return void 0;
|
|
62248
62286
|
}
|
|
@@ -62258,8 +62296,8 @@ function readUsageSnapshot(fs16, snapshotsDir, identity) {
|
|
|
62258
62296
|
}
|
|
62259
62297
|
return snapshot.data;
|
|
62260
62298
|
}
|
|
62261
|
-
function listUsageSnapshots(
|
|
62262
|
-
return
|
|
62299
|
+
function listUsageSnapshots(fs17, snapshotsDir) {
|
|
62300
|
+
return fs17.readdir(snapshotsDir).flatMap((name) => {
|
|
62263
62301
|
if (!name.endsWith(".json")) {
|
|
62264
62302
|
return [];
|
|
62265
62303
|
}
|
|
@@ -62267,7 +62305,7 @@ function listUsageSnapshots(fs16, snapshotsDir) {
|
|
|
62267
62305
|
if (!isIdentityName(identity)) {
|
|
62268
62306
|
return [];
|
|
62269
62307
|
}
|
|
62270
|
-
const snapshot = readUsageSnapshot(
|
|
62308
|
+
const snapshot = readUsageSnapshot(fs17, snapshotsDir, identity);
|
|
62271
62309
|
return snapshot === void 0 ? [] : [snapshot];
|
|
62272
62310
|
}).sort((left, right) => left.identity.localeCompare(right.identity));
|
|
62273
62311
|
}
|
|
@@ -62326,11 +62364,11 @@ var import_node_path22 = __toESM(require("node:path"), 1);
|
|
|
62326
62364
|
var DAY_MS2 = 864e5;
|
|
62327
62365
|
var DAYS_IN_WEEK = 7;
|
|
62328
62366
|
var USAGE_RETENTION_MS = DAYS_IN_WEEK * DAY_MS2;
|
|
62329
|
-
function pruneUsageLog(
|
|
62367
|
+
function pruneUsageLog(fs17, logDir, nowMs) {
|
|
62330
62368
|
const cutoff = nowMs - USAGE_RETENTION_MS;
|
|
62331
|
-
for (const segment of listLogSegments(
|
|
62369
|
+
for (const segment of listLogSegments(fs17, logDir)) {
|
|
62332
62370
|
if (segment.endsAt <= cutoff) {
|
|
62333
|
-
|
|
62371
|
+
fs17.removeRecursive(import_node_path22.default.join(logDir, segment.name));
|
|
62334
62372
|
}
|
|
62335
62373
|
}
|
|
62336
62374
|
}
|
|
@@ -62359,7 +62397,7 @@ function foldProviderState(current, record2) {
|
|
|
62359
62397
|
};
|
|
62360
62398
|
}
|
|
62361
62399
|
function createUsageStore(deps) {
|
|
62362
|
-
const { fs:
|
|
62400
|
+
const { fs: fs17, paths } = deps;
|
|
62363
62401
|
let prunedDay;
|
|
62364
62402
|
const rewriteSnapshot = (identity, fold) => {
|
|
62365
62403
|
if (!isIdentityName(identity)) {
|
|
@@ -62368,7 +62406,7 @@ function createUsageStore(deps) {
|
|
|
62368
62406
|
}
|
|
62369
62407
|
let current;
|
|
62370
62408
|
try {
|
|
62371
|
-
current = readUsageSnapshot(
|
|
62409
|
+
current = readUsageSnapshot(fs17, paths.usageSnapshotsDir, identity);
|
|
62372
62410
|
} catch (error62) {
|
|
62373
62411
|
if (!(error62 instanceof UsageSnapshotError)) {
|
|
62374
62412
|
throw error62;
|
|
@@ -62395,8 +62433,8 @@ function createUsageStore(deps) {
|
|
|
62395
62433
|
...account === void 0 ? {} : { account },
|
|
62396
62434
|
providers
|
|
62397
62435
|
});
|
|
62398
|
-
|
|
62399
|
-
|
|
62436
|
+
fs17.mkdirPrivate(paths.usageSnapshotsDir);
|
|
62437
|
+
fs17.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
|
|
62400
62438
|
`);
|
|
62401
62439
|
return true;
|
|
62402
62440
|
};
|
|
@@ -62404,14 +62442,14 @@ function createUsageStore(deps) {
|
|
|
62404
62442
|
record: (input2) => {
|
|
62405
62443
|
const record2 = UsageRecordSchema.parse(input2);
|
|
62406
62444
|
const nowMs = deps.now();
|
|
62407
|
-
|
|
62408
|
-
|
|
62445
|
+
fs17.mkdirPrivate(paths.usageDir);
|
|
62446
|
+
fs17.mkdirPrivate(paths.usageLogDir);
|
|
62409
62447
|
const day = segmentDay(nowMs);
|
|
62410
62448
|
if (prunedDay !== day) {
|
|
62411
|
-
pruneUsageLog(
|
|
62449
|
+
pruneUsageLog(fs17, paths.usageLogDir, nowMs);
|
|
62412
62450
|
prunedDay = day;
|
|
62413
62451
|
}
|
|
62414
|
-
|
|
62452
|
+
fs17.appendFilePrivate(import_node_path22.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record2)}
|
|
62415
62453
|
`);
|
|
62416
62454
|
if (record2.identity !== void 0) {
|
|
62417
62455
|
rewriteSnapshot(record2.identity, (current) => ({ ...current?.providers, [record2.provider]: foldProviderState(current?.providers[record2.provider], record2) }));
|
|
@@ -62438,14 +62476,14 @@ var PicksFileSchema = external_exports.strictObject({
|
|
|
62438
62476
|
function errorMessage(error62) {
|
|
62439
62477
|
return error62 instanceof Error ? error62.message : String(error62);
|
|
62440
62478
|
}
|
|
62441
|
-
function loadPoolMembers(
|
|
62479
|
+
function loadPoolMembers(fs17, paths, identities, nowMs) {
|
|
62442
62480
|
const windowStartMs = nowMs - FIVE_HOUR_WINDOW_MS;
|
|
62443
|
-
const log = readUsageLog(
|
|
62481
|
+
const log = readUsageLog(fs17, paths.usageLogDir, { sinceMs: windowStartMs });
|
|
62444
62482
|
return identities.map((identity) => {
|
|
62445
62483
|
const records = log.records.filter((record2) => record2.identity === identity && record2.provider === ANTHROPIC_PROVIDER && Date.parse(record2.at) >= windowStartMs);
|
|
62446
62484
|
try {
|
|
62447
|
-
const snapshot = readUsageSnapshot(
|
|
62448
|
-
const account = readAccountMetadata(
|
|
62485
|
+
const snapshot = readUsageSnapshot(fs17, paths.usageSnapshotsDir, identity);
|
|
62486
|
+
const account = readAccountMetadata(fs17, paths.identitiesDir, identity) ?? snapshot?.account;
|
|
62449
62487
|
return { identity, records, ...snapshot === void 0 ? {} : { snapshot }, ...account === void 0 ? {} : { account } };
|
|
62450
62488
|
} catch (error62) {
|
|
62451
62489
|
if (error62 instanceof UsageSnapshotError || error62 instanceof AccountMetadataError) {
|
|
@@ -62463,9 +62501,9 @@ function rankPoolFromStore(params) {
|
|
|
62463
62501
|
...params.sticky === void 0 ? {} : { sticky: params.sticky }
|
|
62464
62502
|
});
|
|
62465
62503
|
}
|
|
62466
|
-
function readPicksFile(
|
|
62504
|
+
function readPicksFile(fs17, file2) {
|
|
62467
62505
|
const empty = { schemaVersion: SCHEMA_VERSION, picks: {} };
|
|
62468
|
-
const raw =
|
|
62506
|
+
const raw = fs17.readFileUtf8(file2);
|
|
62469
62507
|
if (raw === void 0) {
|
|
62470
62508
|
return { file: empty };
|
|
62471
62509
|
}
|
|
@@ -62476,19 +62514,19 @@ function readPicksFile(fs16, file2) {
|
|
|
62476
62514
|
return { file: empty, problem: `${file2} is not valid JSON` };
|
|
62477
62515
|
}
|
|
62478
62516
|
const result = PicksFileSchema.safeParse(parsed);
|
|
62479
|
-
return result.success ? { file: result.data } : { file: empty, problem: `${file2} is not a picks file this
|
|
62517
|
+
return result.success ? { file: result.data } : { file: empty, problem: `${file2} is not a picks file this agent-shim can read` };
|
|
62480
62518
|
}
|
|
62481
|
-
function readStickyPick(
|
|
62482
|
-
const read = readPicksFile(
|
|
62519
|
+
function readStickyPick(fs17, picksFile, directory) {
|
|
62520
|
+
const read = readPicksFile(fs17, picksFile);
|
|
62483
62521
|
const entry = read.file.picks[directory];
|
|
62484
62522
|
return { ...entry === void 0 ? {} : { sticky: entry }, ...read.problem === void 0 ? {} : { problem: read.problem } };
|
|
62485
62523
|
}
|
|
62486
|
-
function recordStickyPick(
|
|
62487
|
-
const current = readPicksFile(
|
|
62524
|
+
function recordStickyPick(fs17, picksFile, directory, identity, nowMs) {
|
|
62525
|
+
const current = readPicksFile(fs17, picksFile).file.picks;
|
|
62488
62526
|
const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
|
|
62489
62527
|
const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
|
|
62490
|
-
|
|
62491
|
-
|
|
62528
|
+
fs17.mkdirPrivate(import_node_path23.default.dirname(picksFile));
|
|
62529
|
+
fs17.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
|
|
62492
62530
|
`);
|
|
62493
62531
|
}
|
|
62494
62532
|
|
|
@@ -62496,8 +62534,8 @@ function recordStickyPick(fs16, picksFile, directory, identity, nowMs) {
|
|
|
62496
62534
|
var RESUME_FLAGS = /* @__PURE__ */ new Set(["--continue", "-c", "--resume", "-r"]);
|
|
62497
62535
|
var TERMINATOR = "--";
|
|
62498
62536
|
var REASONS_LOGGED = 3;
|
|
62499
|
-
function splitMembers(pool, paths,
|
|
62500
|
-
const exists = (name) => loadIdentity(paths.identitiesDir, name,
|
|
62537
|
+
function splitMembers(pool, paths, fs17) {
|
|
62538
|
+
const exists = (name) => loadIdentity(paths.identitiesDir, name, fs17) !== void 0;
|
|
62501
62539
|
return { present: pool.identities.filter(exists), missing: pool.identities.filter((name) => !exists(name)) };
|
|
62502
62540
|
}
|
|
62503
62541
|
function isResuming(passthrough) {
|
|
@@ -62508,19 +62546,19 @@ function resolvePoolLaunch(params) {
|
|
|
62508
62546
|
const { poolName, log } = params;
|
|
62509
62547
|
const pool = params.pools?.[poolName];
|
|
62510
62548
|
if (pool === void 0) {
|
|
62511
|
-
return { ok: false, message: `
|
|
62549
|
+
return { ok: false, message: `agent-shim: no pool named "${poolName}" (selected via ${params.selectedVia}). Run \`agent-shim pool add ${poolName} --identity <name>...\` first.` };
|
|
62512
62550
|
}
|
|
62513
62551
|
const { present: identities, missing } = splitMembers(pool, params.paths, params.fs);
|
|
62514
62552
|
for (const name of missing) {
|
|
62515
|
-
log.warn(`
|
|
62553
|
+
log.warn(`agent-shim: pool "${poolName}" names identity "${name}", which does not exist; skipping it`);
|
|
62516
62554
|
}
|
|
62517
62555
|
if (identities.length === 0) {
|
|
62518
|
-
return { ok: false, message: `
|
|
62556
|
+
return { ok: false, message: `agent-shim: no member of pool "${poolName}" is an existing identity.` };
|
|
62519
62557
|
}
|
|
62520
62558
|
const resuming = isResuming(params.passthrough);
|
|
62521
62559
|
const stickyRead = readStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd);
|
|
62522
62560
|
if (stickyRead.problem !== void 0) {
|
|
62523
|
-
log.warn(`
|
|
62561
|
+
log.warn(`agent-shim: ${stickyRead.problem}; ignoring the last-pick record`);
|
|
62524
62562
|
}
|
|
62525
62563
|
for (; ; ) {
|
|
62526
62564
|
const nowMs = params.now();
|
|
@@ -62531,16 +62569,16 @@ function resolvePoolLaunch(params) {
|
|
|
62531
62569
|
return { ok: true, identity: pick2.identity, explanation: `pool ${poolName}: ${pick2.reasons.slice(0, REASONS_LOGGED).join("; ")}` };
|
|
62532
62570
|
}
|
|
62533
62571
|
if (earliestReturn === void 0) {
|
|
62534
|
-
return { ok: false, message: `
|
|
62572
|
+
return { ok: false, message: `agent-shim: no member of pool "${poolName}" can be picked.` };
|
|
62535
62573
|
}
|
|
62536
62574
|
const until = new Date(earliestReturn.atMs).toISOString();
|
|
62537
62575
|
if (!params.wait) {
|
|
62538
62576
|
return {
|
|
62539
62577
|
ok: false,
|
|
62540
|
-
message: `
|
|
62578
|
+
message: `agent-shim: every member of pool "${poolName}" is refused right now; the earliest, ${earliestReturn.identity}, returns at ${until} (in ${formatAge(earliestReturn.atMs - nowMs)}). Pass --wait to sleep until then.`
|
|
62541
62579
|
};
|
|
62542
62580
|
}
|
|
62543
|
-
log.info(`
|
|
62581
|
+
log.info(`agent-shim: every member of pool "${poolName}" is refused; waiting until ${until} for ${earliestReturn.identity}`);
|
|
62544
62582
|
params.sleep(Math.max(earliestReturn.atMs - nowMs, 0));
|
|
62545
62583
|
}
|
|
62546
62584
|
}
|
|
@@ -62606,7 +62644,7 @@ function registerPoolCommand(program2, deps) {
|
|
|
62606
62644
|
const { paths } = deps;
|
|
62607
62645
|
const pool = withExamples(
|
|
62608
62646
|
program2.command("pool").description("Manage pools: named sets of identities that a launch picks one member of, by remaining quota, with `claude @pool:<name>`."),
|
|
62609
|
-
["
|
|
62647
|
+
["agent-shim pool add subs --identity work --identity personal", "agent-shim pool pick subs"]
|
|
62610
62648
|
);
|
|
62611
62649
|
withExamples(
|
|
62612
62650
|
pool.command("add <name>").description("Define a pool. Fails if one with this name already exists.").option("--identity <name>", "A member identity (repeatable).", collectRepeated).action((name, options) => {
|
|
@@ -62615,7 +62653,7 @@ function registerPoolCommand(program2, deps) {
|
|
|
62615
62653
|
addPool(paths, name, members2);
|
|
62616
62654
|
console.log(`Created pool "${name}" with ${members2.join(", ")}.`);
|
|
62617
62655
|
}),
|
|
62618
|
-
["
|
|
62656
|
+
["agent-shim pool add subs --identity work --identity personal"]
|
|
62619
62657
|
);
|
|
62620
62658
|
withExamples(
|
|
62621
62659
|
pool.command("set <name>").description("Replace a pool's members.").option("--identity <name>", "A member identity (repeatable); the full new list.", collectRepeated).action((name, options) => {
|
|
@@ -62624,7 +62662,7 @@ function registerPoolCommand(program2, deps) {
|
|
|
62624
62662
|
setPool(paths, name, members2);
|
|
62625
62663
|
console.log(`Pool "${name}" now has ${members2.join(", ")}.`);
|
|
62626
62664
|
}),
|
|
62627
|
-
["
|
|
62665
|
+
["agent-shim pool set subs --identity work --identity personal --identity spare"]
|
|
62628
62666
|
);
|
|
62629
62667
|
withExamples(
|
|
62630
62668
|
pool.command("list").description("List every pool and its members, marking the active selection with *.").option("--json", "Print the pools as JSON.").action((options) => {
|
|
@@ -62636,14 +62674,14 @@ function registerPoolCommand(program2, deps) {
|
|
|
62636
62674
|
}
|
|
62637
62675
|
const names = Object.keys(pools).sort();
|
|
62638
62676
|
if (names.length === 0) {
|
|
62639
|
-
console.log("No pools yet. Run `
|
|
62677
|
+
console.log("No pools yet. Run `agent-shim pool add <name> --identity <name>...` to create one.");
|
|
62640
62678
|
return;
|
|
62641
62679
|
}
|
|
62642
62680
|
for (const name of names) {
|
|
62643
62681
|
console.log(`${active === `${POOL_SELECTOR_PREFIX}${name}` ? "*" : " "} ${name}: ${(pools[name]?.identities ?? []).join(", ")}`);
|
|
62644
62682
|
}
|
|
62645
62683
|
}),
|
|
62646
|
-
["
|
|
62684
|
+
["agent-shim pool list", "agent-shim pool list --json"]
|
|
62647
62685
|
);
|
|
62648
62686
|
withExamples(
|
|
62649
62687
|
pool.command("show <name>").description("Show one pool's members.").option("--json", "Print the pool as JSON.").action((name, options) => {
|
|
@@ -62655,7 +62693,7 @@ function registerPoolCommand(program2, deps) {
|
|
|
62655
62693
|
console.log(`Pool: ${name}`);
|
|
62656
62694
|
console.log(`Members: ${entry.identities.join(", ")}`);
|
|
62657
62695
|
}),
|
|
62658
|
-
["
|
|
62696
|
+
["agent-shim pool show subs"]
|
|
62659
62697
|
);
|
|
62660
62698
|
withExamples(
|
|
62661
62699
|
pool.command("remove <name>").description("Delete a pool. Its member identities are untouched.").option("--yes", "Skip the confirmation prompt.").action(async (name, options) => {
|
|
@@ -62664,14 +62702,14 @@ function registerPoolCommand(program2, deps) {
|
|
|
62664
62702
|
removePool(paths, name);
|
|
62665
62703
|
console.log(`Removed pool "${name}".`);
|
|
62666
62704
|
}),
|
|
62667
|
-
["
|
|
62705
|
+
["agent-shim pool remove subs --yes"]
|
|
62668
62706
|
);
|
|
62669
62707
|
withExamples(
|
|
62670
62708
|
pool.command("use <name>").description("Make launches with no other selection pick a member of this pool.").action((name) => {
|
|
62671
62709
|
useIdentity(paths, `${POOL_SELECTOR_PREFIX}${name}`);
|
|
62672
62710
|
console.log(`Active selection is now pool "${name}".`);
|
|
62673
62711
|
}),
|
|
62674
|
-
["
|
|
62712
|
+
["agent-shim pool use subs"]
|
|
62675
62713
|
);
|
|
62676
62714
|
withExamples(
|
|
62677
62715
|
pool.command("pick <name>").description("Show how a launch from this directory would rank the pool's members right now, and which it would run as. Read-only: it records nothing.").option("--json", "Print the ranking as JSON.").action((name, options) => {
|
|
@@ -62685,12 +62723,12 @@ function registerPoolCommand(program2, deps) {
|
|
|
62685
62723
|
console.log(line);
|
|
62686
62724
|
}
|
|
62687
62725
|
}),
|
|
62688
|
-
["
|
|
62726
|
+
["agent-shim pool pick subs", "agent-shim pool pick subs --json"]
|
|
62689
62727
|
);
|
|
62690
62728
|
}
|
|
62691
62729
|
|
|
62692
62730
|
// src/providers.ts
|
|
62693
|
-
var
|
|
62731
|
+
var import_node_fs9 = __toESM(require("node:fs"), 1);
|
|
62694
62732
|
var import_node_path24 = __toESM(require("node:path"), 1);
|
|
62695
62733
|
|
|
62696
62734
|
// src/codex/translate.ts
|
|
@@ -62933,7 +62971,7 @@ function translateRequest(body, config2) {
|
|
|
62933
62971
|
// src/providers.ts
|
|
62934
62972
|
var ProviderNotFoundError = class extends CliError {
|
|
62935
62973
|
constructor(name) {
|
|
62936
|
-
super(`No provider named "${name}". Run \`
|
|
62974
|
+
super(`No provider named "${name}". Run \`agent-shim provider add ${name}\` first.`);
|
|
62937
62975
|
this.name = name;
|
|
62938
62976
|
this.name = "ProviderNotFoundError";
|
|
62939
62977
|
}
|
|
@@ -62962,7 +63000,7 @@ function providerJsonPath(paths, name) {
|
|
|
62962
63000
|
return import_node_path24.default.join(paths.providersDir, `${name}.json`);
|
|
62963
63001
|
}
|
|
62964
63002
|
function providerExists(paths, name) {
|
|
62965
|
-
return
|
|
63003
|
+
return import_node_fs9.default.existsSync(providerJsonPath(paths, name));
|
|
62966
63004
|
}
|
|
62967
63005
|
var LEGACY_PROVIDER_FIELDS = ["tokenEnv", "tokenCommand", "authScheme"];
|
|
62968
63006
|
var LEGACY_ENV_CREDENTIAL_KEYS = Object.values(CREDENTIAL_TARGET_VARS);
|
|
@@ -63028,10 +63066,10 @@ function parseProviderFile(filePath, raw) {
|
|
|
63028
63066
|
}
|
|
63029
63067
|
function readProvider(paths, name) {
|
|
63030
63068
|
const filePath = providerJsonPath(paths, name);
|
|
63031
|
-
if (!
|
|
63069
|
+
if (!import_node_fs9.default.existsSync(filePath)) {
|
|
63032
63070
|
return void 0;
|
|
63033
63071
|
}
|
|
63034
|
-
const raw = JSON.parse(
|
|
63072
|
+
const raw = JSON.parse(import_node_fs9.default.readFileSync(filePath, "utf8"));
|
|
63035
63073
|
return parseProviderFile(filePath, raw);
|
|
63036
63074
|
}
|
|
63037
63075
|
function loadProvider(providersDir, name, port) {
|
|
@@ -63041,7 +63079,7 @@ function loadProvider(providersDir, name, port) {
|
|
|
63041
63079
|
}
|
|
63042
63080
|
function listProviders(paths) {
|
|
63043
63081
|
const names = listProviderNames(
|
|
63044
|
-
(dir) =>
|
|
63082
|
+
(dir) => import_node_fs9.default.readdirSync(dir),
|
|
63045
63083
|
paths.providersDir
|
|
63046
63084
|
);
|
|
63047
63085
|
const result = [];
|
|
@@ -63053,7 +63091,7 @@ function listProviders(paths) {
|
|
|
63053
63091
|
if (!(error62 instanceof ConfigValidationError || error62 instanceof LegacyProviderFileError)) {
|
|
63054
63092
|
throw error62;
|
|
63055
63093
|
}
|
|
63056
|
-
console.error(`
|
|
63094
|
+
console.error(`agent-shim: providers/${name}.json is invalid and was skipped: ${error62.message}`);
|
|
63057
63095
|
continue;
|
|
63058
63096
|
}
|
|
63059
63097
|
if (provider !== void 0) {
|
|
@@ -63160,7 +63198,7 @@ function removeProvider(paths, name) {
|
|
|
63160
63198
|
if (!providerExists(paths, name)) {
|
|
63161
63199
|
throw new ProviderNotFoundError(name);
|
|
63162
63200
|
}
|
|
63163
|
-
|
|
63201
|
+
import_node_fs9.default.rmSync(providerJsonPath(paths, name));
|
|
63164
63202
|
}
|
|
63165
63203
|
function cascadeProviderName(cascade) {
|
|
63166
63204
|
let name;
|
|
@@ -63183,11 +63221,11 @@ function resolveProvider(params) {
|
|
|
63183
63221
|
return {
|
|
63184
63222
|
ok: false,
|
|
63185
63223
|
status: 1,
|
|
63186
|
-
message: `
|
|
63224
|
+
message: `agent-shim: no provider named "${name}". ` + (known.length > 0 ? `Known providers: ${known.join(", ")}.` : "No providers are defined yet; run `agent-shim provider add`.")
|
|
63187
63225
|
};
|
|
63188
63226
|
}
|
|
63189
63227
|
if (params.credentials === void 0) {
|
|
63190
|
-
return { ok: false, status: 1, message: `
|
|
63228
|
+
return { ok: false, status: 1, message: `agent-shim: provider ${name} needs its credential resolved, but this launcher has no credential port wired` };
|
|
63191
63229
|
}
|
|
63192
63230
|
const resolution = resolveCredential({ credential: definition.credential, env: params.env, port: params.credentials, subject: `provider ${name}` });
|
|
63193
63231
|
if (!resolution.ok) {
|
|
@@ -63224,10 +63262,10 @@ function registerProviderCommand(program2, deps) {
|
|
|
63224
63262
|
const { paths } = deps;
|
|
63225
63263
|
const provider = withExamples(
|
|
63226
63264
|
program2.command("provider").description("Manage API providers: Anthropic-compatible endpoints a launch can route through with --provider."),
|
|
63227
|
-
["
|
|
63265
|
+
["agent-shim provider add z --display-name z.ai --base-url https://api.z.ai/api/anthropic --credential env:Z_API_TOKEN", "agent-shim provider list"]
|
|
63228
63266
|
);
|
|
63229
63267
|
withExamples(
|
|
63230
|
-
provider.command("add <name>").description("Create a new API provider definition. Fails if one with this name already exists.").addOption(new Option("--kind <kind>", "http (default): an Anthropic-compatible endpoint at --base-url; codex: ChatGPT's Codex backend through the front-door daemon.").choices(PROVIDER_KINDS)).requiredOption("--display-name <name>", "Human-readable name, exported to the child as
|
|
63268
|
+
provider.command("add <name>").description("Create a new API provider definition. Fails if one with this name already exists.").addOption(new Option("--kind <kind>", "http (default): an Anthropic-compatible endpoint at --base-url; codex: ChatGPT's Codex backend through the front-door daemon.").choices(PROVIDER_KINDS)).requiredOption("--display-name <name>", "Human-readable name, exported to the child as AGENT_SHIM_PROVIDER.").option("--base-url <url>", "Anthropic-compatible base URL the child's requests are sent to (http providers only, and required for them).").requiredOption(
|
|
63231
63269
|
"--credential <source>",
|
|
63232
63270
|
`Where the provider's token comes from (repeatable; tried in the order given until one yields a token): ${CREDENTIAL_SOURCE_SYNTAX}. Never the token itself.`,
|
|
63233
63271
|
collectCredentialSource
|
|
@@ -63249,12 +63287,12 @@ function registerProviderCommand(program2, deps) {
|
|
|
63249
63287
|
console.log(`Created provider "${name}" (${describeProviderEndpoint(created)}, credential ${describeCredential(created.credential)}).`);
|
|
63250
63288
|
}),
|
|
63251
63289
|
[
|
|
63252
|
-
"
|
|
63253
|
-
"
|
|
63254
|
-
"
|
|
63255
|
-
"
|
|
63256
|
-
"
|
|
63257
|
-
"
|
|
63290
|
+
"agent-shim provider add z --display-name z.ai --base-url https://api.z.ai/api/anthropic --credential env:Z_API_TOKEN",
|
|
63291
|
+
"agent-shim provider add z --display-name z.ai --base-url https://api.z.ai/api/anthropic --credential env:Z_API_TOKEN --credential op:op://vault/z/credential",
|
|
63292
|
+
"agent-shim provider add anthropic-api --display-name Anthropic --base-url https://api.anthropic.com --credential-target apiKey --credential keychain:anthropic-api-key",
|
|
63293
|
+
"agent-shim provider add local --display-name Local --base-url http://127.0.0.1:4000 --credential literal:dummy",
|
|
63294
|
+
"agent-shim provider add codex --kind codex --display-name Codex --credential literal:codex",
|
|
63295
|
+
"agent-shim provider add codex --kind codex --display-name Codex --credential literal:codex --codex-model sonnet=gpt-5.6-sol --codex-effort medium"
|
|
63258
63296
|
]
|
|
63259
63297
|
);
|
|
63260
63298
|
const providerSet = provider.command("set <name>").description("Update an existing API provider definition.").option("--display-name <name>", "Replace the human-readable name.").option("--base-url <url>", "Replace the base URL (http providers only).").option(
|
|
@@ -63289,11 +63327,11 @@ function registerProviderCommand(program2, deps) {
|
|
|
63289
63327
|
console.log(`Updated provider "${name}" (${describeProviderEndpoint(updated)}, credential ${describeCredential(updated.credential)}).`);
|
|
63290
63328
|
}),
|
|
63291
63329
|
[
|
|
63292
|
-
"
|
|
63293
|
-
"
|
|
63294
|
-
"
|
|
63295
|
-
"
|
|
63296
|
-
"
|
|
63330
|
+
"agent-shim provider set z --base-url https://api.z.ai/api/anthropic",
|
|
63331
|
+
"agent-shim provider set z --env API_TIMEOUT_MS=600000",
|
|
63332
|
+
"agent-shim provider set z --credential op:op://vault/z/credential --credential-cache-ttl 12h",
|
|
63333
|
+
"agent-shim provider set anthropic-api --credential-target apiKey",
|
|
63334
|
+
"agent-shim provider set codex --codex-model haiku=gpt-5.6-terra"
|
|
63297
63335
|
]
|
|
63298
63336
|
);
|
|
63299
63337
|
withExamples(
|
|
@@ -63304,14 +63342,14 @@ function registerProviderCommand(program2, deps) {
|
|
|
63304
63342
|
return;
|
|
63305
63343
|
}
|
|
63306
63344
|
if (entries.length === 0) {
|
|
63307
|
-
console.log("No providers yet. Run `
|
|
63345
|
+
console.log("No providers yet. Run `agent-shim provider add <name>` to create one.");
|
|
63308
63346
|
return;
|
|
63309
63347
|
}
|
|
63310
63348
|
for (const entry of entries) {
|
|
63311
63349
|
console.log(` ${entry.name} (${entry.provider.displayName}, ${describeProviderEndpoint(entry.provider)})`);
|
|
63312
63350
|
}
|
|
63313
63351
|
}),
|
|
63314
|
-
["
|
|
63352
|
+
["agent-shim provider list", "agent-shim provider list --json"]
|
|
63315
63353
|
);
|
|
63316
63354
|
withExamples(
|
|
63317
63355
|
provider.command("show <name>").description("Show one provider's definition. Credentials are described by source, never printed.").option("--json", "Print the provider as JSON.").action((name, options) => {
|
|
@@ -63337,7 +63375,7 @@ function registerProviderCommand(program2, deps) {
|
|
|
63337
63375
|
const env = Object.entries(found.env ?? {});
|
|
63338
63376
|
console.log(`Environment: ${env.length === 0 ? "(none)" : env.map(([key, value]) => `${key}=${value}`).join(", ")}`);
|
|
63339
63377
|
}),
|
|
63340
|
-
["
|
|
63378
|
+
["agent-shim provider show z", "agent-shim provider show z --json"]
|
|
63341
63379
|
);
|
|
63342
63380
|
withExamples(
|
|
63343
63381
|
provider.command("remove <name>").description("Delete a provider definition.").option("--yes", "Remove without asking for confirmation (required when standard input is not a terminal).").action(async (name, options) => {
|
|
@@ -63348,7 +63386,7 @@ function registerProviderCommand(program2, deps) {
|
|
|
63348
63386
|
removeProvider(paths, name);
|
|
63349
63387
|
console.log(`Removed provider "${name}".`);
|
|
63350
63388
|
}),
|
|
63351
|
-
["
|
|
63389
|
+
["agent-shim provider remove z --yes"]
|
|
63352
63390
|
);
|
|
63353
63391
|
}
|
|
63354
63392
|
|
|
@@ -63510,7 +63548,7 @@ function runCheck(params) {
|
|
|
63510
63548
|
const ambientCredential = evaluateAmbientCredentialGuard({
|
|
63511
63549
|
env: params.env,
|
|
63512
63550
|
allowAmbientCredential: params.identity?.allowAmbientCredential ?? false,
|
|
63513
|
-
allowAmbientCredentialOverride: parseEnvBool("
|
|
63551
|
+
allowAmbientCredentialOverride: parseEnvBool("AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL", params.env.AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL) === true,
|
|
63514
63552
|
...params.identityName === void 0 ? {} : { identityName: params.identityName }
|
|
63515
63553
|
});
|
|
63516
63554
|
const settingsShared = resolved.flattened.categories.get("settings") ?? SHIPPED_CATEGORY_DEFAULTS.settings;
|
|
@@ -63723,12 +63761,12 @@ function registerCheckCommand(program2, deps) {
|
|
|
63723
63761
|
process.exitCode = 1;
|
|
63724
63762
|
}
|
|
63725
63763
|
});
|
|
63726
|
-
withExamples(command, ["
|
|
63764
|
+
withExamples(command, ["agent-shim check", "agent-shim check ~/work/acme --identity work --json", "agent-shim check --strict"]);
|
|
63727
63765
|
}
|
|
63728
63766
|
|
|
63729
63767
|
// src/codex/commands.ts
|
|
63730
63768
|
var import_node_crypto7 = require("node:crypto");
|
|
63731
|
-
var
|
|
63769
|
+
var import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
63732
63770
|
var import_node_os6 = __toESM(require("node:os"), 1);
|
|
63733
63771
|
var import_node_path27 = __toESM(require("node:path"), 1);
|
|
63734
63772
|
|
|
@@ -63761,10 +63799,10 @@ var FrontDoorStateSchema = external_exports.strictObject({
|
|
|
63761
63799
|
/** The last fatal error, kept across shutdowns so `frontdoor status` can explain a front door that is not running. */
|
|
63762
63800
|
lastError: external_exports.string().optional()
|
|
63763
63801
|
});
|
|
63764
|
-
function readFrontDoorState(
|
|
63802
|
+
function readFrontDoorState(fs17, stateFile) {
|
|
63765
63803
|
let raw;
|
|
63766
63804
|
try {
|
|
63767
|
-
raw =
|
|
63805
|
+
raw = fs17.readFileUtf8(stateFile);
|
|
63768
63806
|
} catch {
|
|
63769
63807
|
return void 0;
|
|
63770
63808
|
}
|
|
@@ -63778,28 +63816,28 @@ function readFrontDoorState(fs16, stateFile) {
|
|
|
63778
63816
|
return void 0;
|
|
63779
63817
|
}
|
|
63780
63818
|
}
|
|
63781
|
-
function writeFrontDoorState(
|
|
63782
|
-
|
|
63783
|
-
|
|
63819
|
+
function writeFrontDoorState(fs17, stateFile, state) {
|
|
63820
|
+
fs17.mkdirp(import_node_path26.default.dirname(stateFile));
|
|
63821
|
+
fs17.writeFileUtf8(stateFile, `${JSON.stringify(state, null, 2)}
|
|
63784
63822
|
`);
|
|
63785
63823
|
}
|
|
63786
63824
|
function frontDoorOrigin(state) {
|
|
63787
63825
|
const port = state?.directPort ?? state?.lastDirectPort;
|
|
63788
63826
|
return port === void 0 ? void 0 : `http://127.0.0.1:${String(port)}`;
|
|
63789
63827
|
}
|
|
63790
|
-
function writeFrontDoorSession(
|
|
63791
|
-
|
|
63792
|
-
|
|
63828
|
+
function writeFrontDoorSession(fs17, sessionsDir, session) {
|
|
63829
|
+
fs17.mkdirPrivate(sessionsDir);
|
|
63830
|
+
fs17.writeFilePrivate(import_node_path26.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
63793
63831
|
`);
|
|
63794
63832
|
}
|
|
63795
|
-
function listFrontDoorSessions(
|
|
63833
|
+
function listFrontDoorSessions(fs17, sessionsDir) {
|
|
63796
63834
|
const sessions = [];
|
|
63797
|
-
for (const name of
|
|
63835
|
+
for (const name of fs17.readdir(sessionsDir)) {
|
|
63798
63836
|
if (!name.endsWith(".json")) {
|
|
63799
63837
|
continue;
|
|
63800
63838
|
}
|
|
63801
63839
|
try {
|
|
63802
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(
|
|
63840
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs17.readFileUtf8(import_node_path26.default.join(sessionsDir, name)) ?? ""));
|
|
63803
63841
|
if (parsed.success) {
|
|
63804
63842
|
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
|
|
63805
63843
|
}
|
|
@@ -63809,27 +63847,27 @@ function listFrontDoorSessions(fs16, sessionsDir) {
|
|
|
63809
63847
|
}
|
|
63810
63848
|
return sessions.sort((a2, b) => a2.pid - b.pid);
|
|
63811
63849
|
}
|
|
63812
|
-
function removeFrontDoorSession(
|
|
63813
|
-
|
|
63850
|
+
function removeFrontDoorSession(fs17, sessionsDir, pid) {
|
|
63851
|
+
fs17.removeRecursive(import_node_path26.default.join(sessionsDir, `${String(pid)}.json`));
|
|
63814
63852
|
}
|
|
63815
|
-
function pruneDeadFrontDoorSessions(
|
|
63853
|
+
function pruneDeadFrontDoorSessions(fs17, sessionsDir, isRunning) {
|
|
63816
63854
|
const removed = [];
|
|
63817
|
-
for (const session of listFrontDoorSessions(
|
|
63855
|
+
for (const session of listFrontDoorSessions(fs17, sessionsDir)) {
|
|
63818
63856
|
if (!isRunning(session.pid)) {
|
|
63819
|
-
removeFrontDoorSession(
|
|
63857
|
+
removeFrontDoorSession(fs17, sessionsDir, session.pid);
|
|
63820
63858
|
removed.push(session.pid);
|
|
63821
63859
|
}
|
|
63822
63860
|
}
|
|
63823
63861
|
return removed;
|
|
63824
63862
|
}
|
|
63825
|
-
function liveSessionTokens(
|
|
63863
|
+
function liveSessionTokens(fs17, sessionsDir) {
|
|
63826
63864
|
const tokens = /* @__PURE__ */ new Set();
|
|
63827
|
-
for (const name of
|
|
63865
|
+
for (const name of fs17.readdir(sessionsDir)) {
|
|
63828
63866
|
if (!name.endsWith(".json")) {
|
|
63829
63867
|
continue;
|
|
63830
63868
|
}
|
|
63831
63869
|
try {
|
|
63832
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(
|
|
63870
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs17.readFileUtf8(import_node_path26.default.join(sessionsDir, name)) ?? ""));
|
|
63833
63871
|
if (parsed.success) {
|
|
63834
63872
|
tokens.add(parsed.data.token);
|
|
63835
63873
|
}
|
|
@@ -64041,7 +64079,7 @@ function sessionIdFor(userId, randomId) {
|
|
|
64041
64079
|
if (userId === void 0 || userId === "") {
|
|
64042
64080
|
return randomId();
|
|
64043
64081
|
}
|
|
64044
|
-
const hex3 = (0, import_node_crypto6.createHash)("sha256").update(`
|
|
64082
|
+
const hex3 = (0, import_node_crypto6.createHash)("sha256").update(`agent-shim codex session
|
|
64045
64083
|
${userId}`).digest("hex");
|
|
64046
64084
|
let next = 0;
|
|
64047
64085
|
return UUID_TEMPLATE.replace(/x/g, () => hex3.charAt(next++));
|
|
@@ -64089,7 +64127,7 @@ var PRIVATE_FILE_MODE = 384;
|
|
|
64089
64127
|
var realCodexAuthFs = {
|
|
64090
64128
|
read: (filePath) => {
|
|
64091
64129
|
try {
|
|
64092
|
-
return
|
|
64130
|
+
return import_node_fs10.default.readFileSync(filePath, "utf8");
|
|
64093
64131
|
} catch (error62) {
|
|
64094
64132
|
if (isEnoent4(error62)) {
|
|
64095
64133
|
return void 0;
|
|
@@ -64098,21 +64136,21 @@ var realCodexAuthFs = {
|
|
|
64098
64136
|
}
|
|
64099
64137
|
},
|
|
64100
64138
|
writePrivate: (filePath, contents) => {
|
|
64101
|
-
|
|
64102
|
-
|
|
64139
|
+
import_node_fs10.default.writeFileSync(filePath, contents, { encoding: "utf8", mode: PRIVATE_FILE_MODE });
|
|
64140
|
+
import_node_fs10.default.chmodSync(filePath, PRIVATE_FILE_MODE);
|
|
64103
64141
|
},
|
|
64104
64142
|
rename: (from, to) => {
|
|
64105
|
-
|
|
64143
|
+
import_node_fs10.default.renameSync(from, to);
|
|
64106
64144
|
}
|
|
64107
64145
|
};
|
|
64108
64146
|
function writeUsageSnapshot(log, snapshot) {
|
|
64109
64147
|
const target = codexUsageSnapshotPath();
|
|
64110
64148
|
const temp = `${target}.${String(process.pid)}.tmp`;
|
|
64111
64149
|
try {
|
|
64112
|
-
|
|
64113
|
-
|
|
64150
|
+
import_node_fs10.default.mkdirSync(import_node_path27.default.dirname(target), { recursive: true });
|
|
64151
|
+
import_node_fs10.default.writeFileSync(temp, `${JSON.stringify(snapshot, null, 2)}
|
|
64114
64152
|
`);
|
|
64115
|
-
|
|
64153
|
+
import_node_fs10.default.renameSync(temp, target);
|
|
64116
64154
|
} catch (error62) {
|
|
64117
64155
|
log(`usage snapshot write failed: ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
64118
64156
|
}
|
|
@@ -64177,7 +64215,7 @@ function formatCodexStatus(status) {
|
|
|
64177
64215
|
}
|
|
64178
64216
|
function registerCodexCommand(program2, deps) {
|
|
64179
64217
|
const { paths } = deps;
|
|
64180
|
-
const codex = withExamples(program2.command("codex").description("Inspect the codex translation the front-door daemon serves for codex providers."), ["
|
|
64218
|
+
const codex = withExamples(program2.command("codex").description("Inspect the codex translation the front-door daemon serves for codex providers."), ["agent-shim codex status"]);
|
|
64181
64219
|
withExamples(
|
|
64182
64220
|
codex.command("status").description("Report the front door serving codex providers, its sessions, and the usage snapshot. Read-only.").option("--json", "Print the status as JSON.").action((options) => {
|
|
64183
64221
|
const status = collectCodexStatus(realFarmFs, paths, realIsProcessRunning);
|
|
@@ -64189,17 +64227,17 @@ function registerCodexCommand(program2, deps) {
|
|
|
64189
64227
|
console.log(line);
|
|
64190
64228
|
}
|
|
64191
64229
|
}),
|
|
64192
|
-
["
|
|
64230
|
+
["agent-shim codex status", "agent-shim codex status --json"]
|
|
64193
64231
|
);
|
|
64194
64232
|
}
|
|
64195
64233
|
|
|
64196
64234
|
// src/frontdoor/commands.ts
|
|
64197
64235
|
var import_node_crypto13 = require("node:crypto");
|
|
64198
|
-
var
|
|
64236
|
+
var import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
64199
64237
|
|
|
64200
64238
|
// src/frontdoor/custody.ts
|
|
64201
64239
|
var CREDENTIAL_HEADERS = ["authorization", "x-api-key"];
|
|
64202
|
-
var SEQUESTERED_CREDENTIAL = "
|
|
64240
|
+
var SEQUESTERED_CREDENTIAL = "agent-shim-sequestered";
|
|
64203
64241
|
function placeholderFor(name, value) {
|
|
64204
64242
|
const first = typeof value === "string" ? value : value[0] ?? "";
|
|
64205
64243
|
if (name === "authorization") {
|
|
@@ -64259,19 +64297,19 @@ function singleValue(value) {
|
|
|
64259
64297
|
function admitLaunch(isLiveToken) {
|
|
64260
64298
|
return (request6) => {
|
|
64261
64299
|
const token = singleValue(request6.headers[AUTH_HEADER]);
|
|
64262
|
-
return token !== void 0 && isLiveToken(token) ? { ok: true, headers: { ...request6.forwardable } } : { ok: false, message: "
|
|
64300
|
+
return token !== void 0 && isLiveToken(token) ? { ok: true, headers: { ...request6.forwardable } } : { ok: false, message: "agent-shim front door: this request carries no capability from a live agent-shim launch" };
|
|
64263
64301
|
};
|
|
64264
64302
|
}
|
|
64265
64303
|
function admitHop(hopSecret, custody) {
|
|
64266
64304
|
return (request6) => {
|
|
64267
64305
|
if (singleValue(request6.headers[HOP_SECRET_HEADER]) !== hopSecret) {
|
|
64268
|
-
return { ok: false, message: "
|
|
64306
|
+
return { ok: false, message: "agent-shim front door: the direct listener serves only this door's own headroom hop" };
|
|
64269
64307
|
}
|
|
64270
64308
|
const hopId = singleValue(request6.headers[HOP_ID_HEADER]);
|
|
64271
64309
|
const provider = parseProviderPath(new URL(request6.url, "http://127.0.0.1").pathname)?.provider;
|
|
64272
64310
|
const credentials = hopId === void 0 || provider === void 0 ? void 0 : custody.redeem(hopId, provider);
|
|
64273
64311
|
if (credentials === void 0) {
|
|
64274
|
-
return { ok: false, message: "
|
|
64312
|
+
return { ok: false, message: "agent-shim front door: this request names no live headroom hop for its provider" };
|
|
64275
64313
|
}
|
|
64276
64314
|
return { ok: true, headers: restoreCredentials(request6.forwardable, credentials) };
|
|
64277
64315
|
};
|
|
@@ -64299,8 +64337,8 @@ function createDoorPipelines(deps) {
|
|
|
64299
64337
|
|
|
64300
64338
|
// src/frontdoor/capability.ts
|
|
64301
64339
|
var import_node_crypto8 = require("node:crypto");
|
|
64302
|
-
var CONNECT_PROXY_USER = "
|
|
64303
|
-
var CONNECT_PROXY_REALM = "
|
|
64340
|
+
var CONNECT_PROXY_USER = "agent-shim";
|
|
64341
|
+
var CONNECT_PROXY_REALM = "agent-shim front door";
|
|
64304
64342
|
var BASIC_SCHEME = "basic";
|
|
64305
64343
|
function connectProxyUrl(port, token) {
|
|
64306
64344
|
return `http://${encodeURIComponent(CONNECT_PROXY_USER)}:${encodeURIComponent(token)}@127.0.0.1:${String(port)}`;
|
|
@@ -64334,7 +64372,7 @@ function isLiveCapability(presented, live) {
|
|
|
64334
64372
|
|
|
64335
64373
|
// src/frontdoor/connect.ts
|
|
64336
64374
|
var import_node_crypto10 = require("node:crypto");
|
|
64337
|
-
var
|
|
64375
|
+
var fs11 = __toESM(require("node:fs"), 1);
|
|
64338
64376
|
var http = __toESM(require("node:http"), 1);
|
|
64339
64377
|
var https = __toESM(require("node:https"), 1);
|
|
64340
64378
|
var net3 = __toESM(require("node:net"), 1);
|
|
@@ -64616,8 +64654,8 @@ var FRONTDOOR_SUPERVISOR_STILL_RUNNING = -1;
|
|
|
64616
64654
|
var FRONTDOOR_POLL_MS = 1e3;
|
|
64617
64655
|
var MS_PER_MINUTE = 6e4;
|
|
64618
64656
|
async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {}) {
|
|
64619
|
-
const { fs:
|
|
64620
|
-
const previous = readFrontDoorState(
|
|
64657
|
+
const { fs: fs17, paths } = ports;
|
|
64658
|
+
const previous = readFrontDoorState(fs17, paths.frontdoorStateFile);
|
|
64621
64659
|
let lastPort = previous?.lastPort;
|
|
64622
64660
|
let lastConnectPort = previous?.lastConnectPort;
|
|
64623
64661
|
let lastDirectPort = previous?.lastDirectPort;
|
|
@@ -64627,12 +64665,12 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
64627
64665
|
...lastDirectPort === void 0 ? {} : { lastDirectPort }
|
|
64628
64666
|
});
|
|
64629
64667
|
const fail = (message) => {
|
|
64630
|
-
writeFrontDoorState(
|
|
64631
|
-
|
|
64632
|
-
ports.log(`
|
|
64668
|
+
writeFrontDoorState(fs17, paths.frontdoorStateFile, { lastError: message, ...sticky() });
|
|
64669
|
+
fs17.removeRecursive(paths.frontdoorLockFile);
|
|
64670
|
+
ports.log(`agent-shim frontdoor supervisor: ${message}`);
|
|
64633
64671
|
return 1;
|
|
64634
64672
|
};
|
|
64635
|
-
writeFrontDoorState(
|
|
64673
|
+
writeFrontDoorState(fs17, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
|
|
64636
64674
|
const previousSticky = lastPort;
|
|
64637
64675
|
let http5;
|
|
64638
64676
|
try {
|
|
@@ -64641,7 +64679,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
64641
64679
|
return fail(`could not start the provider listener: ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
64642
64680
|
}
|
|
64643
64681
|
if (previousSticky !== void 0 && http5.port !== previousSticky) {
|
|
64644
|
-
ports.log(`
|
|
64682
|
+
ports.log(`agent-shim frontdoor supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(http5.port)} (sessions launched against the old port are stale until they relaunch)`);
|
|
64645
64683
|
}
|
|
64646
64684
|
lastPort = http5.port;
|
|
64647
64685
|
const previousStickyConnect = lastConnectPort;
|
|
@@ -64653,7 +64691,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
64653
64691
|
return fail(`could not start the CONNECT surface: ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
64654
64692
|
}
|
|
64655
64693
|
if (previousStickyConnect !== void 0 && connect2.port !== previousStickyConnect) {
|
|
64656
|
-
ports.log(`
|
|
64694
|
+
ports.log(`agent-shim frontdoor supervisor: sticky CONNECT port ${String(previousStickyConnect)} was occupied; moving to ${String(connect2.port)} (OAuth sessions launched against the old port are stale until they relaunch)`);
|
|
64657
64695
|
}
|
|
64658
64696
|
lastConnectPort = connect2.port;
|
|
64659
64697
|
const previousStickyDirect = lastDirectPort;
|
|
@@ -64666,12 +64704,12 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
64666
64704
|
return fail(`could not start the direct listener: ${error62 instanceof Error ? error62.message : String(error62)}`);
|
|
64667
64705
|
}
|
|
64668
64706
|
if (previousStickyDirect !== void 0 && direct.port !== previousStickyDirect) {
|
|
64669
|
-
ports.log(`
|
|
64707
|
+
ports.log(`agent-shim frontdoor supervisor: sticky direct port ${String(previousStickyDirect)} was occupied; moving to ${String(direct.port)} (headroom must be restarted to admit the new address)`);
|
|
64670
64708
|
}
|
|
64671
64709
|
lastDirectPort = direct.port;
|
|
64672
|
-
writeFrontDoorState(
|
|
64673
|
-
|
|
64674
|
-
ports.log(`
|
|
64710
|
+
writeFrontDoorState(fs17, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, port: http5.port, connectPort: connect2.port, directPort: direct.port, ...sticky() });
|
|
64711
|
+
fs17.removeRecursive(paths.frontdoorLockFile);
|
|
64712
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http5.port)}, CONNECT surface on 127.0.0.1:${String(connect2.port)}`);
|
|
64675
64713
|
let idleSince;
|
|
64676
64714
|
let ticks = 0;
|
|
64677
64715
|
for (; ; ) {
|
|
@@ -64679,15 +64717,15 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
64679
64717
|
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
64680
64718
|
}
|
|
64681
64719
|
ticks += 1;
|
|
64682
|
-
pruneDeadFrontDoorSessions(
|
|
64683
|
-
if (listFrontDoorSessions(
|
|
64720
|
+
pruneDeadFrontDoorSessions(fs17, paths.frontdoorSessionsDir, ports.isRunning);
|
|
64721
|
+
if (listFrontDoorSessions(fs17, paths.frontdoorSessionsDir).length === 0) {
|
|
64684
64722
|
idleSince ??= ports.now();
|
|
64685
64723
|
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE) {
|
|
64686
|
-
ports.log(`
|
|
64724
|
+
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
64687
64725
|
await direct.close();
|
|
64688
64726
|
await connect2.close();
|
|
64689
64727
|
await http5.close();
|
|
64690
|
-
writeFrontDoorState(
|
|
64728
|
+
writeFrontDoorState(fs17, paths.frontdoorStateFile, sticky());
|
|
64691
64729
|
return 0;
|
|
64692
64730
|
}
|
|
64693
64731
|
} else {
|
|
@@ -64723,7 +64761,7 @@ var CONNECT_LIMITS = {
|
|
|
64723
64761
|
};
|
|
64724
64762
|
var CA_VALIDITY_DAYS = 3650;
|
|
64725
64763
|
var LEAF_VALIDITY_DAYS = 397;
|
|
64726
|
-
var CA_SUBJECT_COMMON_NAME = "
|
|
64764
|
+
var CA_SUBJECT_COMMON_NAME = "agent-shim front door CA";
|
|
64727
64765
|
var MS_PER_DAY = 864e5;
|
|
64728
64766
|
function parseConnectTarget(authority) {
|
|
64729
64767
|
const colon = authority.lastIndexOf(":");
|
|
@@ -64741,8 +64779,8 @@ function parseConnectTarget(authority) {
|
|
|
64741
64779
|
function isInterceptedHost(host, interceptHost) {
|
|
64742
64780
|
return host === interceptHost;
|
|
64743
64781
|
}
|
|
64744
|
-
function servedByPipeline(
|
|
64745
|
-
return
|
|
64782
|
+
function servedByPipeline(path36) {
|
|
64783
|
+
return path36?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
64746
64784
|
}
|
|
64747
64785
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
64748
64786
|
"connection",
|
|
@@ -65118,7 +65156,7 @@ function realConnectEffects() {
|
|
|
65118
65156
|
response.destroy(error62);
|
|
65119
65157
|
return;
|
|
65120
65158
|
}
|
|
65121
|
-
const body = `
|
|
65159
|
+
const body = `agent-shim headroom: upstream unreachable (${error62.message})`;
|
|
65122
65160
|
response.writeHead(HTTP_BAD_GATEWAY, { "content-type": "text/plain", "content-length": String(body.length) });
|
|
65123
65161
|
response.end(body);
|
|
65124
65162
|
});
|
|
@@ -65136,7 +65174,7 @@ function isEnoent5(error62) {
|
|
|
65136
65174
|
function realConnectCertStore(paths) {
|
|
65137
65175
|
const read = (file2) => {
|
|
65138
65176
|
try {
|
|
65139
|
-
return
|
|
65177
|
+
return fs11.readFileSync(file2, "utf8");
|
|
65140
65178
|
} catch (error62) {
|
|
65141
65179
|
if (isEnoent5(error62)) {
|
|
65142
65180
|
return void 0;
|
|
@@ -65151,10 +65189,10 @@ function realConnectCertStore(paths) {
|
|
|
65151
65189
|
return certPem === void 0 || keyPem2 === void 0 ? void 0 : { certPem, keyPem: keyPem2 };
|
|
65152
65190
|
},
|
|
65153
65191
|
writeCa: (ca) => {
|
|
65154
|
-
|
|
65155
|
-
|
|
65156
|
-
|
|
65157
|
-
|
|
65192
|
+
fs11.mkdirSync(paths.frontdoorCaDir, { recursive: true });
|
|
65193
|
+
fs11.writeFileSync(paths.frontdoorCaCertFile, ca.certPem, "utf8");
|
|
65194
|
+
fs11.writeFileSync(paths.frontdoorCaKeyFile, ca.keyPem, { encoding: "utf8", mode: CA_KEY_FILE_MODE });
|
|
65195
|
+
fs11.chmodSync(paths.frontdoorCaKeyFile, CA_KEY_FILE_MODE);
|
|
65158
65196
|
}
|
|
65159
65197
|
};
|
|
65160
65198
|
}
|
|
@@ -65188,13 +65226,13 @@ function ensureFrontDoor(params) {
|
|
|
65188
65226
|
}
|
|
65189
65227
|
lastRejection = `the listener on 127.0.0.1:${String(state.port)} (recorded for pid ${String(supervisorPid)}) failed authentication: ${verdict.reason}`;
|
|
65190
65228
|
if (spawned) {
|
|
65191
|
-
throw new FrontDoorStartError(`
|
|
65229
|
+
throw new FrontDoorStartError(`agent-shim: ${lastRejection}; refusing to send this session's credentials to it. Daemon log: ${paths.frontdoorLogPath}`);
|
|
65192
65230
|
}
|
|
65193
65231
|
distrusted.add(supervisorPid);
|
|
65194
65232
|
continue;
|
|
65195
65233
|
}
|
|
65196
65234
|
if (state?.lastError !== void 0) {
|
|
65197
|
-
throw new FrontDoorStartError(`
|
|
65235
|
+
throw new FrontDoorStartError(`agent-shim: the front door reported a fatal error and is not serving: ${state.lastError} (daemon log: ${paths.frontdoorLogPath})`);
|
|
65198
65236
|
}
|
|
65199
65237
|
} else if (!spawned) {
|
|
65200
65238
|
ports.fs.mkdirp(paths.frontdoorDir);
|
|
@@ -65214,7 +65252,7 @@ function ensureFrontDoor(params) {
|
|
|
65214
65252
|
if (ports.now() >= deadline) {
|
|
65215
65253
|
const lastError = state?.lastError;
|
|
65216
65254
|
throw new FrontDoorStartError(
|
|
65217
|
-
`
|
|
65255
|
+
`agent-shim: the front door did not become ready within ${String(FRONTDOOR_START_TIMEOUT_MS)}ms` + (lastError === void 0 ? "" : ` (last error: ${lastError})`) + (lastRejection === void 0 ? "" : ` (${lastRejection})`) + `. Daemon log: ${paths.frontdoorLogPath}`
|
|
65218
65256
|
);
|
|
65219
65257
|
}
|
|
65220
65258
|
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
@@ -65253,7 +65291,7 @@ function createFrontDoorServer(pipeline, log, tls2) {
|
|
|
65253
65291
|
log(`request ${request6.method ?? "?"} ${request6.url ?? "?"} failed: ${error62 instanceof Error ? `${error62.name}: ${error62.message}` : String(error62)}`);
|
|
65254
65292
|
if (!response.headersSent) {
|
|
65255
65293
|
response.writeHead(HTTP_STATUS.internalServerError, { "Content-Type": "application/json" });
|
|
65256
|
-
response.end(JSON.stringify({ type: "error", error: { type: "api_error", message: "internal error in the
|
|
65294
|
+
response.end(JSON.stringify({ type: "error", error: { type: "api_error", message: "internal error in the agent-shim front door" } }));
|
|
65257
65295
|
} else {
|
|
65258
65296
|
response.destroy();
|
|
65259
65297
|
}
|
|
@@ -65368,7 +65406,7 @@ async function applyHeadroomHop(request6, response, upstream, deps) {
|
|
|
65368
65406
|
const port = deps.headroomPort();
|
|
65369
65407
|
if (port === void 0) {
|
|
65370
65408
|
response.start(HTTP_BAD_GATEWAY2, { "Content-Type": "application/json" });
|
|
65371
|
-
await response.write(JSON.stringify({ type: "error", error: { type: "api_error", message: "
|
|
65409
|
+
await response.write(JSON.stringify({ type: "error", error: { type: "api_error", message: "agent-shim front door: the headroom daemon is restarting" } }));
|
|
65372
65410
|
response.end();
|
|
65373
65411
|
return;
|
|
65374
65412
|
}
|
|
@@ -65426,7 +65464,7 @@ async function forwardThroughHeadroom(request6, response, target) {
|
|
|
65426
65464
|
target.log(`front door: headroom hop to 127.0.0.1:${String(port)} failed: ${error62.message}`);
|
|
65427
65465
|
if (!response.headersSent) {
|
|
65428
65466
|
response.start(HTTP_BAD_GATEWAY2, { "Content-Type": "application/json" });
|
|
65429
|
-
void response.write(JSON.stringify({ type: "error", error: { type: "api_error", message: `
|
|
65467
|
+
void response.write(JSON.stringify({ type: "error", error: { type: "api_error", message: `agent-shim front door: the headroom daemon is unreachable (${error62.message})` } })).then(() => {
|
|
65430
65468
|
response.end();
|
|
65431
65469
|
});
|
|
65432
65470
|
} else {
|
|
@@ -65599,7 +65637,7 @@ async function serveRouted(request6, deps) {
|
|
|
65599
65637
|
deps.log(`front door: route ${resolution.route.name} failed: ${error62 instanceof Error ? `${error62.name}: ${error62.message}` : String(error62)}`);
|
|
65600
65638
|
if (!response.headersSent) {
|
|
65601
65639
|
response.start(HTTP_STATUS.internalServerError, { "Content-Type": "application/json" });
|
|
65602
|
-
await response.write(errorBody(HTTP_STATUS.internalServerError, "internal error in the
|
|
65640
|
+
await response.write(errorBody(HTTP_STATUS.internalServerError, "internal error in the agent-shim front door"));
|
|
65603
65641
|
response.end();
|
|
65604
65642
|
return;
|
|
65605
65643
|
}
|
|
@@ -66241,8 +66279,8 @@ function createCodexRouteMount(ports, upstreamBase, provider) {
|
|
|
66241
66279
|
request6.body.resume();
|
|
66242
66280
|
return;
|
|
66243
66281
|
}
|
|
66244
|
-
const
|
|
66245
|
-
const translated = { method: request6.method, path:
|
|
66282
|
+
const path36 = new URL(request6.url, "http://127.0.0.1").pathname;
|
|
66283
|
+
const translated = { method: request6.method, path: path36, body, signal: request6.signal };
|
|
66246
66284
|
const routed = await route(translated);
|
|
66247
66285
|
if (request6.signal.aborted) {
|
|
66248
66286
|
return;
|
|
@@ -66275,7 +66313,7 @@ function createPassthroughRoute(name, target) {
|
|
|
66275
66313
|
headroomUpstream: target.headroomUpstream,
|
|
66276
66314
|
serve: async (request6, response) => {
|
|
66277
66315
|
const incoming = new URL(request6.url, "http://127.0.0.1");
|
|
66278
|
-
const
|
|
66316
|
+
const path36 = target.stripPrefix !== void 0 && incoming.pathname.startsWith(target.stripPrefix) ? incoming.pathname.slice(target.stripPrefix.length) : incoming.pathname;
|
|
66279
66317
|
const headers = forwardableHeaders(request6.headers);
|
|
66280
66318
|
delete headers.host;
|
|
66281
66319
|
await new Promise((resolve) => {
|
|
@@ -66283,7 +66321,7 @@ function createPassthroughRoute(name, target) {
|
|
|
66283
66321
|
host: base.hostname,
|
|
66284
66322
|
port: base.port === "" ? void 0 : Number(base.port),
|
|
66285
66323
|
method: request6.method,
|
|
66286
|
-
path: `${
|
|
66324
|
+
path: `${path36}${incoming.search}`,
|
|
66287
66325
|
headers,
|
|
66288
66326
|
agent
|
|
66289
66327
|
};
|
|
@@ -66345,10 +66383,10 @@ function createProviderRouteResolver(deps) {
|
|
|
66345
66383
|
return route;
|
|
66346
66384
|
};
|
|
66347
66385
|
const resolve = (request6) => {
|
|
66348
|
-
const
|
|
66349
|
-
const scoped = parseProviderPath(
|
|
66386
|
+
const path36 = new URL(request6.url, "http://127.0.0.1").pathname;
|
|
66387
|
+
const scoped = parseProviderPath(path36);
|
|
66350
66388
|
if (scoped === void 0) {
|
|
66351
|
-
return
|
|
66389
|
+
return path36.startsWith("/v1/") ? { ok: true, route: oauthRoute } : { ok: false, status: HTTP_STATUS.notFound, message: `no such endpoint: ${path36}` };
|
|
66352
66390
|
}
|
|
66353
66391
|
const { provider } = scoped;
|
|
66354
66392
|
let definition;
|
|
@@ -66392,18 +66430,18 @@ var import_node_crypto12 = require("node:crypto");
|
|
|
66392
66430
|
var import_node_path28 = __toESM(require("node:path"), 1);
|
|
66393
66431
|
var BUNDLE_NAME_HEX_DIGITS = 16;
|
|
66394
66432
|
function resolveTrustBundle(params) {
|
|
66395
|
-
const { caCertFile, bundlesDir, inherited, fs:
|
|
66433
|
+
const { caCertFile, bundlesDir, inherited, fs: fs17 } = params;
|
|
66396
66434
|
if (inherited === void 0 || inherited === "" || import_node_path28.default.resolve(inherited) === import_node_path28.default.resolve(caCertFile)) {
|
|
66397
66435
|
return { path: caCertFile };
|
|
66398
66436
|
}
|
|
66399
|
-
const caPem =
|
|
66437
|
+
const caPem = fs17.readFileUtf8(caCertFile);
|
|
66400
66438
|
let inheritedPem;
|
|
66401
66439
|
try {
|
|
66402
|
-
inheritedPem =
|
|
66440
|
+
inheritedPem = fs17.readFileUtf8(inherited);
|
|
66403
66441
|
} catch (error62) {
|
|
66404
66442
|
return {
|
|
66405
66443
|
path: caCertFile,
|
|
66406
|
-
warning: `
|
|
66444
|
+
warning: `agent-shim: NODE_EXTRA_CA_CERTS names ${inherited}, which could not be read (${error62 instanceof Error ? error62.message : String(error62)}); the child trusts agent-shim's front-door CA on top of the system store, and nothing from that file`
|
|
66407
66445
|
};
|
|
66408
66446
|
}
|
|
66409
66447
|
if (inheritedPem.includes(caPem.trim())) {
|
|
@@ -66412,9 +66450,9 @@ function resolveTrustBundle(params) {
|
|
|
66412
66450
|
const combined = `${inheritedPem.trimEnd()}
|
|
66413
66451
|
${caPem}`;
|
|
66414
66452
|
const bundle = import_node_path28.default.join(bundlesDir, `${(0, import_node_crypto12.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
66415
|
-
if (!
|
|
66416
|
-
|
|
66417
|
-
|
|
66453
|
+
if (!fs17.exists(bundle)) {
|
|
66454
|
+
fs17.mkdirp(bundlesDir);
|
|
66455
|
+
fs17.writeFileAtomic(bundle, combined);
|
|
66418
66456
|
}
|
|
66419
66457
|
return { path: bundle };
|
|
66420
66458
|
}
|
|
@@ -66702,8 +66740,8 @@ function createRealQuotaRefresher(params) {
|
|
|
66702
66740
|
|
|
66703
66741
|
// src/frontdoor/commands.ts
|
|
66704
66742
|
function appendLog(paths, line) {
|
|
66705
|
-
|
|
66706
|
-
|
|
66743
|
+
import_node_fs11.default.mkdirSync(paths.logsDir, { recursive: true });
|
|
66744
|
+
import_node_fs11.default.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
66707
66745
|
`);
|
|
66708
66746
|
}
|
|
66709
66747
|
function liveHeadroomPort(paths) {
|
|
@@ -66794,7 +66832,7 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
66794
66832
|
log(`connect request ${request6.method ?? "?"} ${request6.url ?? "?"} failed: ${error62 instanceof Error ? `${error62.name}: ${error62.message}` : String(error62)}`);
|
|
66795
66833
|
if (!response.headersSent) {
|
|
66796
66834
|
response.writeHead(HTTP_STATUS.badGateway, { "Content-Type": "application/json" });
|
|
66797
|
-
response.end(JSON.stringify({ type: "error", error: { type: "api_error", message: "internal error in the
|
|
66835
|
+
response.end(JSON.stringify({ type: "error", error: { type: "api_error", message: "internal error in the agent-shim front door" } }));
|
|
66798
66836
|
return;
|
|
66799
66837
|
}
|
|
66800
66838
|
response.destroy();
|
|
@@ -66830,10 +66868,10 @@ function realFrontDoorSupervisorPorts(paths) {
|
|
|
66830
66868
|
};
|
|
66831
66869
|
}
|
|
66832
66870
|
var realTrustBundleFs = {
|
|
66833
|
-
readFileUtf8: (file2) =>
|
|
66834
|
-
exists: (file2) =>
|
|
66871
|
+
readFileUtf8: (file2) => import_node_fs11.default.readFileSync(file2, "utf8"),
|
|
66872
|
+
exists: (file2) => import_node_fs11.default.existsSync(file2),
|
|
66835
66873
|
mkdirp: (dir) => {
|
|
66836
|
-
|
|
66874
|
+
import_node_fs11.default.mkdirSync(dir, { recursive: true });
|
|
66837
66875
|
},
|
|
66838
66876
|
writeFileAtomic: (file2, contents) => {
|
|
66839
66877
|
realFarmFs.writeFilePrivate(file2, contents);
|
|
@@ -66852,7 +66890,7 @@ function realFrontDoorPort(paths) {
|
|
|
66852
66890
|
sleep: realSleepSync,
|
|
66853
66891
|
spawnSupervisor: (layout) => spawnDetachedSupervisor(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
|
|
66854
66892
|
// Read fresh for each probe: a replacement supervisor may have regenerated an unparseable CA, and the probe must trust exactly what the serving door's leaf chains to.
|
|
66855
|
-
verifyListener: (port) => probeFrontDoorSync(port,
|
|
66893
|
+
verifyListener: (port) => probeFrontDoorSync(port, import_node_fs11.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
|
|
66856
66894
|
}
|
|
66857
66895
|
});
|
|
66858
66896
|
const trust = resolveTrustBundle({ caCertFile: paths.frontdoorCaCertFile, bundlesDir: paths.frontdoorCaBundlesDir, inherited: inheritedExtraCaCerts, fs: realTrustBundleFs });
|
|
@@ -66914,8 +66952,8 @@ function formatFrontDoorStatus(status, caCertPath) {
|
|
|
66914
66952
|
}
|
|
66915
66953
|
function registerFrontDoorCommand(program2, deps) {
|
|
66916
66954
|
const { paths } = deps;
|
|
66917
|
-
const frontdoor = withExamples(program2.command("frontdoor").description("Inspect the front-door daemon that routes every
|
|
66918
|
-
"
|
|
66955
|
+
const frontdoor = withExamples(program2.command("frontdoor").description("Inspect the front-door daemon that routes every agent-shim session."), [
|
|
66956
|
+
"agent-shim frontdoor status"
|
|
66919
66957
|
]);
|
|
66920
66958
|
withExamples(
|
|
66921
66959
|
frontdoor.command("status").description("Report the front door's supervisor, listeners, sessions, and last error. Read-only.").option("--json", "Print the status as JSON.").action((options) => {
|
|
@@ -66928,7 +66966,7 @@ function registerFrontDoorCommand(program2, deps) {
|
|
|
66928
66966
|
console.log(line);
|
|
66929
66967
|
}
|
|
66930
66968
|
}),
|
|
66931
|
-
["
|
|
66969
|
+
["agent-shim frontdoor status", "agent-shim frontdoor status --json"]
|
|
66932
66970
|
);
|
|
66933
66971
|
program2.command("__frontdoor-supervisor", { hidden: true }).description("Internal: serve the front-door routing listeners. Started by the launcher; never run by hand.").allowUnknownOption().action(async () => {
|
|
66934
66972
|
const idleShutdownMinutes = readGlobalConfig(paths)?.frontdoor?.idleShutdownMinutes ?? FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES;
|
|
@@ -67087,7 +67125,7 @@ function collectNodes(program2) {
|
|
|
67087
67125
|
const visit2 = (command, id) => {
|
|
67088
67126
|
const subcommands = help.visibleCommands(command).filter((sub) => sub.name() !== "help");
|
|
67089
67127
|
const children = new Map(subcommands.map((sub) => [sub.name(), `${id}/${sub.name()}`]));
|
|
67090
|
-
const optionWords = command.name() === "run" && id !== "root" ? LAUNCHER_FLAG_NAMES.map((flag) => ({ word: flag, description: "
|
|
67128
|
+
const optionWords = command.name() === "run" && id !== "root" ? LAUNCHER_FLAG_NAMES.map((flag) => ({ word: flag, description: "agent-shim launch flag" })) : help.visibleOptions(command).flatMap((option) => option.long === void 0 ? [] : [{ word: option.long, description: firstSentence(option.description) }]);
|
|
67091
67129
|
nodes.push({
|
|
67092
67130
|
id,
|
|
67093
67131
|
words: [...subcommands.map((sub) => ({ word: sub.name(), description: firstSentence(sub.description()) })), ...optionWords],
|
|
@@ -67111,8 +67149,8 @@ function transitionArms(nodes, indent) {
|
|
|
67111
67149
|
}
|
|
67112
67150
|
function bashScript(nodes) {
|
|
67113
67151
|
const arms = nodes.map((node2) => ` ${singleQuote(node2.id)}) candidates=${singleQuote(node2.words.map((word) => word.word).join(" "))} ;;`).join("\n");
|
|
67114
|
-
return `#
|
|
67115
|
-
|
|
67152
|
+
return `# agent-shim bash completion. Load with: source <(agent-shim completion bash)
|
|
67153
|
+
_agent_shim() {
|
|
67116
67154
|
local cur="\${COMP_WORDS[COMP_CWORD]}" node=root candidates="" i
|
|
67117
67155
|
for ((i = 1; i < COMP_CWORD; i++)); do
|
|
67118
67156
|
case "\${node}:\${COMP_WORDS[i]}" in
|
|
@@ -67124,7 +67162,7 @@ ${arms}
|
|
|
67124
67162
|
esac
|
|
67125
67163
|
COMPREPLY=($(compgen -W "\${candidates}" -- "\${cur}"))
|
|
67126
67164
|
}
|
|
67127
|
-
complete -o default -F
|
|
67165
|
+
complete -o default -F _agent_shim agent-shim ${LEGACY_COMMAND_NAME}
|
|
67128
67166
|
`;
|
|
67129
67167
|
}
|
|
67130
67168
|
function zshScript(nodes) {
|
|
@@ -67132,9 +67170,9 @@ function zshScript(nodes) {
|
|
|
67132
67170
|
const entries = node2.words.map((word) => singleQuote(`${word.word}:${word.description.replaceAll(":", "\\:")}`)).join(" ");
|
|
67133
67171
|
return ` ${singleQuote(node2.id)}) candidates=(${entries}) ;;`;
|
|
67134
67172
|
}).join("\n");
|
|
67135
|
-
return `#compdef
|
|
67136
|
-
#
|
|
67137
|
-
|
|
67173
|
+
return `#compdef agent-shim ${LEGACY_COMMAND_NAME}
|
|
67174
|
+
# agent-shim zsh completion. Load with: source <(agent-shim completion zsh), after compinit.
|
|
67175
|
+
_agent_shim() {
|
|
67138
67176
|
local node=root word
|
|
67139
67177
|
local -a candidates
|
|
67140
67178
|
for word in "\${(@)words[2,CURRENT-1]}"; do
|
|
@@ -67145,12 +67183,12 @@ ${transitionArms(nodes, " ")}
|
|
|
67145
67183
|
case "\${node}" in
|
|
67146
67184
|
${arms}
|
|
67147
67185
|
esac
|
|
67148
|
-
_describe -t commands '
|
|
67186
|
+
_describe -t commands 'agent-shim' candidates
|
|
67149
67187
|
}
|
|
67150
|
-
if [ "\${funcstack[1]}" = "
|
|
67151
|
-
|
|
67188
|
+
if [ "\${funcstack[1]}" = "_agent_shim" ]; then
|
|
67189
|
+
_agent_shim "$@"
|
|
67152
67190
|
else
|
|
67153
|
-
compdef
|
|
67191
|
+
compdef _agent_shim agent-shim ${LEGACY_COMMAND_NAME}
|
|
67154
67192
|
fi
|
|
67155
67193
|
`;
|
|
67156
67194
|
}
|
|
@@ -67161,13 +67199,13 @@ function fishScript(nodes) {
|
|
|
67161
67199
|
).join("\n");
|
|
67162
67200
|
const completions = nodes.flatMap(
|
|
67163
67201
|
(node2) => node2.words.map((word) => {
|
|
67164
|
-
const condition = fishQuote(`test (
|
|
67202
|
+
const condition = fishQuote(`test (__agent_shim_node) = ${node2.id}`);
|
|
67165
67203
|
const target = word.word.startsWith("--") ? `-l ${fishQuote(word.word.slice(2))}` : `-a ${fishQuote(word.word)}`;
|
|
67166
|
-
return `complete -c
|
|
67204
|
+
return ["agent-shim", LEGACY_COMMAND_NAME].map((command) => `complete -c ${command} -n ${condition} ${target} -d ${fishQuote(word.description)}`).join("\n");
|
|
67167
67205
|
})
|
|
67168
67206
|
).join("\n");
|
|
67169
|
-
return `#
|
|
67170
|
-
function
|
|
67207
|
+
return `# agent-shim fish completion. Load with: agent-shim completion fish | source
|
|
67208
|
+
function __agent_shim_node
|
|
67171
67209
|
set -l node root
|
|
67172
67210
|
for word in (commandline -opc)[2..-1]
|
|
67173
67211
|
switch "$node:$word"
|
|
@@ -67176,7 +67214,7 @@ ${transitions}
|
|
|
67176
67214
|
end
|
|
67177
67215
|
echo $node
|
|
67178
67216
|
end
|
|
67179
|
-
complete -c
|
|
67217
|
+
complete -c agent-shim -f
|
|
67180
67218
|
${completions}
|
|
67181
67219
|
`;
|
|
67182
67220
|
}
|
|
@@ -67212,7 +67250,7 @@ function registerCompletionCommand(program2) {
|
|
|
67212
67250
|
process.stdout.write(generateCompletion(program2, shell));
|
|
67213
67251
|
}).addHelpText(
|
|
67214
67252
|
"after",
|
|
67215
|
-
"\nExamples:\n $ source <(
|
|
67253
|
+
"\nExamples:\n $ source <(agent-shim completion bash) # in ~/.bashrc\n $ source <(agent-shim completion zsh) # in ~/.zshrc, after compinit\n $ agent-shim completion fish | source # in ~/.config/fish/config.fish"
|
|
67216
67254
|
);
|
|
67217
67255
|
}
|
|
67218
67256
|
|
|
@@ -67220,7 +67258,7 @@ function registerCompletionCommand(program2) {
|
|
|
67220
67258
|
var import_node_child_process4 = require("node:child_process");
|
|
67221
67259
|
|
|
67222
67260
|
// src/identityToken.ts
|
|
67223
|
-
var
|
|
67261
|
+
var import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
67224
67262
|
var import_node_path29 = __toESM(require("node:path"), 1);
|
|
67225
67263
|
var TOKEN_FILE_MODE = 384;
|
|
67226
67264
|
var TOKEN_DIR_MODE = 448;
|
|
@@ -67237,21 +67275,21 @@ function storeIdentityToken(paths, identityName, raw) {
|
|
|
67237
67275
|
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.");
|
|
67238
67276
|
}
|
|
67239
67277
|
const dir = identityTokenDir(paths);
|
|
67240
|
-
|
|
67241
|
-
|
|
67278
|
+
import_node_fs12.default.mkdirSync(dir, { recursive: true, mode: TOKEN_DIR_MODE });
|
|
67279
|
+
import_node_fs12.default.chmodSync(dir, TOKEN_DIR_MODE);
|
|
67242
67280
|
const target = identityTokenPath(paths, identityName);
|
|
67243
67281
|
const temp = import_node_path29.default.join(dir, `.${identityName}.${String(process.pid)}.tmp`);
|
|
67244
|
-
|
|
67282
|
+
import_node_fs12.default.writeFileSync(temp, `${token}
|
|
67245
67283
|
`, { mode: TOKEN_FILE_MODE });
|
|
67246
|
-
|
|
67284
|
+
import_node_fs12.default.renameSync(temp, target);
|
|
67247
67285
|
return target;
|
|
67248
67286
|
}
|
|
67249
67287
|
|
|
67250
67288
|
// src/realCredentialCache.ts
|
|
67251
67289
|
var import_node_child_process3 = require("node:child_process");
|
|
67252
|
-
var
|
|
67290
|
+
var import_node_fs13 = __toESM(require("node:fs"), 1);
|
|
67253
67291
|
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
67254
|
-
var KEYCHAIN_CACHE_SERVICE = "
|
|
67292
|
+
var KEYCHAIN_CACHE_SERVICE = "agent-shim-credential-cache";
|
|
67255
67293
|
var CACHE_DIR_MODE = 448;
|
|
67256
67294
|
var CACHE_FILE_MODE = 384;
|
|
67257
67295
|
function cacheFileNameFor(owner) {
|
|
@@ -67283,7 +67321,7 @@ function createRealCredentialCache(root) {
|
|
|
67283
67321
|
read(store, owner) {
|
|
67284
67322
|
if (store === "file") {
|
|
67285
67323
|
try {
|
|
67286
|
-
return parseEntry(
|
|
67324
|
+
return parseEntry(import_node_fs13.default.readFileSync(filePath(owner), "utf8"));
|
|
67287
67325
|
} catch {
|
|
67288
67326
|
return void 0;
|
|
67289
67327
|
}
|
|
@@ -67295,12 +67333,12 @@ function createRealCredentialCache(root) {
|
|
|
67295
67333
|
write(store, owner, entry) {
|
|
67296
67334
|
const serialised = JSON.stringify(entry);
|
|
67297
67335
|
if (store === "file") {
|
|
67298
|
-
|
|
67299
|
-
|
|
67336
|
+
import_node_fs13.default.mkdirSync(dir, { recursive: true, mode: CACHE_DIR_MODE });
|
|
67337
|
+
import_node_fs13.default.chmodSync(dir, CACHE_DIR_MODE);
|
|
67300
67338
|
const target = filePath(owner);
|
|
67301
67339
|
const temp = `${target}.${String(process.pid)}.tmp`;
|
|
67302
|
-
|
|
67303
|
-
|
|
67340
|
+
import_node_fs13.default.writeFileSync(temp, serialised, { mode: CACHE_FILE_MODE });
|
|
67341
|
+
import_node_fs13.default.renameSync(temp, target);
|
|
67304
67342
|
return;
|
|
67305
67343
|
}
|
|
67306
67344
|
requireKeychain();
|
|
@@ -67313,7 +67351,7 @@ function createRealCredentialCache(root) {
|
|
|
67313
67351
|
},
|
|
67314
67352
|
remove(store, owner) {
|
|
67315
67353
|
if (store === "file") {
|
|
67316
|
-
|
|
67354
|
+
import_node_fs13.default.rmSync(filePath(owner), { force: true });
|
|
67317
67355
|
return;
|
|
67318
67356
|
}
|
|
67319
67357
|
requireKeychain();
|
|
@@ -67350,6 +67388,7 @@ function realCommandPorts(deps) {
|
|
|
67350
67388
|
ssh: (host, remoteCommand, input2) => (0, import_node_child_process4.spawnSync)("ssh", ["--", host, remoteCommand], { input: input2, stdio: ["pipe", "inherit", "inherit"] }).status
|
|
67351
67389
|
};
|
|
67352
67390
|
}
|
|
67391
|
+
var REMOTE_ROOT_SCRIPT = 'root="${AGENT_SHIM_HOME:-${CLAUDE_USE_HOME:-}}"; if [ -z "$root" ]; then if [ ! -d "$HOME/.agent-shim" ] && [ -d "$HOME/.claude-use" ]; then root="$HOME/.claude-use"; else root="$HOME/.agent-shim"; fi; fi';
|
|
67353
67392
|
var SSH_HOST_RE = /^[A-Za-z0-9._@:][A-Za-z0-9._@:-]*$/;
|
|
67354
67393
|
function credentialSubject(deps, name, asProvider) {
|
|
67355
67394
|
if (asProvider) {
|
|
@@ -67364,7 +67403,7 @@ function credentialSubject(deps, name, asProvider) {
|
|
|
67364
67403
|
throw new IdentityNotFoundError(name);
|
|
67365
67404
|
}
|
|
67366
67405
|
if (identity.credential === void 0) {
|
|
67367
|
-
throw new CredentialCommandError(`Identity "${name}" has no credential block to cache; it uses its stored login. Give it one with \`
|
|
67406
|
+
throw new CredentialCommandError(`Identity "${name}" has no credential block to cache; it uses its stored login. Give it one with \`agent-shim identity set ${name} --credential ...\`.`);
|
|
67368
67407
|
}
|
|
67369
67408
|
return { name, subject: `identity ${name}`, credential: identity.credential };
|
|
67370
67409
|
}
|
|
@@ -67372,14 +67411,14 @@ function requireCaching(subject) {
|
|
|
67372
67411
|
const cache = subject.credential.cache;
|
|
67373
67412
|
if (cache === void 0) {
|
|
67374
67413
|
const flag = subject.subject.startsWith("provider") ? `provider set ${subject.name}` : `identity set ${subject.name}`;
|
|
67375
|
-
throw new CredentialCommandError(`The credential for ${subject.subject} is not cached. Turn caching on with \`
|
|
67414
|
+
throw new CredentialCommandError(`The credential for ${subject.subject} is not cached. Turn caching on with \`agent-shim ${flag} --credential-cache-ttl 12h\` (or --credential-cache for no expiry).`);
|
|
67376
67415
|
}
|
|
67377
67416
|
return cache;
|
|
67378
67417
|
}
|
|
67379
67418
|
function registerCredentialCommand(program2, deps, ports = realCommandPorts(deps)) {
|
|
67380
67419
|
const credential = withExamples(program2.command("credential").description("Manage the credentials identities authenticate with."), [
|
|
67381
|
-
"
|
|
67382
|
-
"
|
|
67420
|
+
"agent-shim credential store work < token.txt",
|
|
67421
|
+
"agent-shim credential warm work"
|
|
67383
67422
|
]);
|
|
67384
67423
|
withExamples(
|
|
67385
67424
|
credential.command("store <identity>").description("Store a `claude setup-token` token for an identity and make it that identity's credential. The token is read from standard input and never printed.").action(async (name) => {
|
|
@@ -67395,7 +67434,7 @@ function registerCredentialCommand(program2, deps, ports = realCommandPorts(deps
|
|
|
67395
67434
|
console.log(`Identity "${name}" now authenticates with credential ${describeCredential(updated.credential)}.`);
|
|
67396
67435
|
}
|
|
67397
67436
|
}),
|
|
67398
|
-
["pbpaste |
|
|
67437
|
+
["pbpaste | agent-shim credential store work", "agent-shim credential store work < token.txt"]
|
|
67399
67438
|
);
|
|
67400
67439
|
withExamples(
|
|
67401
67440
|
credential.command("warm [identity]").description("Fetch an identity's or provider's credential from its sources now, prompting if a source needs a person, and fill its cache so later launches need no prompt. Never prints the token.").option("--provider <name>", "Warm a provider's credential instead of an identity's.").action((name, options) => {
|
|
@@ -67410,7 +67449,7 @@ function registerCredentialCommand(program2, deps, ports = realCommandPorts(deps
|
|
|
67410
67449
|
`Cached the credential for ${subject.subject} in the ${effectiveStore(block2, ports.platform)} store (${limit === void 0 ? "no expiry" : `expires after ${block2.ttl ?? ""}`}).`
|
|
67411
67450
|
);
|
|
67412
67451
|
}),
|
|
67413
|
-
["
|
|
67452
|
+
["agent-shim credential warm work", "agent-shim credential warm --provider z"]
|
|
67414
67453
|
);
|
|
67415
67454
|
withExamples(
|
|
67416
67455
|
credential.command("forget [identity]").description("Remove an identity's or provider's cached credential from every store. The next launch fetches from the sources again.").option("--provider <name>", "Forget a provider's credential instead of an identity's.").action((name, options) => {
|
|
@@ -67421,7 +67460,7 @@ function registerCredentialCommand(program2, deps, ports = realCommandPorts(deps
|
|
|
67421
67460
|
}
|
|
67422
67461
|
console.log(`Removed the cached credential for ${subject.subject}.`);
|
|
67423
67462
|
}),
|
|
67424
|
-
["
|
|
67463
|
+
["agent-shim credential forget work", "agent-shim credential forget --provider z"]
|
|
67425
67464
|
);
|
|
67426
67465
|
withExamples(
|
|
67427
67466
|
credential.command("push <identity> <host>").description("Read an identity's credential here and write it to the credential cache on another host over SSH (mode 0600, token on standard input), so that host needs no 1Password. The identity must cache with the file store on that host.").option("--provider <name>", "Push a provider's credential instead; <identity> is then ignored.").action((name, host, options) => {
|
|
@@ -67435,15 +67474,15 @@ function registerCredentialCommand(program2, deps, ports = realCommandPorts(deps
|
|
|
67435
67474
|
throw new CredentialCommandError(resolution.message, CREDENTIAL_UNAVAILABLE_EXIT);
|
|
67436
67475
|
}
|
|
67437
67476
|
const entry = JSON.stringify({ token: resolution.credential.token, fetchedAt: resolution.credential.cachedAt ?? ports.now(), source: resolution.credential.source });
|
|
67438
|
-
const remoteFile = `"
|
|
67439
|
-
const remoteDir =
|
|
67440
|
-
const status = ports.ssh(host,
|
|
67477
|
+
const remoteFile = `"$root/credential-cache/${cacheFileNameFor(subject.subject)}"`;
|
|
67478
|
+
const remoteDir = '"$root/credential-cache"';
|
|
67479
|
+
const status = ports.ssh(host, `${REMOTE_ROOT_SCRIPT} && umask 077 && mkdir -p ${remoteDir} && cat > ${remoteFile}`, entry);
|
|
67441
67480
|
if (status !== 0) {
|
|
67442
67481
|
throw new CredentialCommandError(`Could not write the credential cache for ${subject.subject} on ${host} (ssh exited ${status === null ? "without a status" : String(status)}).`);
|
|
67443
67482
|
}
|
|
67444
|
-
console.log(`Wrote the credential for ${subject.subject} to ${host}. There, set the credential's cache store to file: \`
|
|
67483
|
+
console.log(`Wrote the credential for ${subject.subject} to ${host}. There, set the credential's cache store to file: \`agent-shim ${subject.subject.startsWith("provider") ? "provider" : "identity"} set ${subject.name} --credential-cache-store file\`.`);
|
|
67445
67484
|
}),
|
|
67446
|
-
["
|
|
67485
|
+
["agent-shim credential push work build-host", "agent-shim credential push x build-host --provider z"]
|
|
67447
67486
|
);
|
|
67448
67487
|
}
|
|
67449
67488
|
function subjectName(positional, provider) {
|
|
@@ -67455,12 +67494,13 @@ function subjectName(positional, provider) {
|
|
|
67455
67494
|
}
|
|
67456
67495
|
|
|
67457
67496
|
// src/doctor.ts
|
|
67458
|
-
var
|
|
67497
|
+
var import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
67459
67498
|
var import_node_path31 = __toESM(require("node:path"), 1);
|
|
67460
67499
|
|
|
67461
67500
|
// src/headroom/source.ts
|
|
67462
67501
|
var GIT_SPEC_RE = /git\+[^@\s]+(?:@([^\s#]+))?/;
|
|
67463
67502
|
var COMMIT_SHA_RE = /^[0-9a-f]{40}$/i;
|
|
67503
|
+
var DirectUrlSchema = external_exports.object({ vcs_info: external_exports.object({ commit_id: external_exports.string() }) });
|
|
67464
67504
|
function isMovingGitSource(spec) {
|
|
67465
67505
|
const match = GIT_SPEC_RE.exec(spec);
|
|
67466
67506
|
if (match === null) {
|
|
@@ -67469,6 +67509,18 @@ function isMovingGitSource(spec) {
|
|
|
67469
67509
|
const ref = match[1];
|
|
67470
67510
|
return ref === void 0 || !COMMIT_SHA_RE.test(ref);
|
|
67471
67511
|
}
|
|
67512
|
+
function pinnedGitCommit(spec) {
|
|
67513
|
+
const ref = GIT_SPEC_RE.exec(spec)?.[1];
|
|
67514
|
+
return ref !== void 0 && COMMIT_SHA_RE.test(ref) ? ref.toLowerCase() : void 0;
|
|
67515
|
+
}
|
|
67516
|
+
function parseInstalledCommit(directUrlJson) {
|
|
67517
|
+
try {
|
|
67518
|
+
const parsed = DirectUrlSchema.safeParse(JSON.parse(directUrlJson));
|
|
67519
|
+
return parsed.success ? parsed.data.vcs_info.commit_id.toLowerCase() : void 0;
|
|
67520
|
+
} catch {
|
|
67521
|
+
return void 0;
|
|
67522
|
+
}
|
|
67523
|
+
}
|
|
67472
67524
|
|
|
67473
67525
|
// src/doctor.ts
|
|
67474
67526
|
function refinePathShadow(status, ownExecutablePath, realpath) {
|
|
@@ -67495,24 +67547,24 @@ function validateJson(schema, input2) {
|
|
|
67495
67547
|
}
|
|
67496
67548
|
function pushPathResolution(push, resolution) {
|
|
67497
67549
|
const ownDir = import_node_path31.default.dirname(resolution.ownExecutablePath);
|
|
67498
|
-
switch (resolution.
|
|
67550
|
+
switch (resolution.agentShim.status) {
|
|
67499
67551
|
case "ok":
|
|
67500
|
-
push("path-resolution", "pass", `\`
|
|
67552
|
+
push("path-resolution", "pass", `\`agent-shim\` on PATH resolves to this running executable, ${resolution.ownExecutablePath}.`, "agent-shim");
|
|
67501
67553
|
break;
|
|
67502
67554
|
case "not-on-path":
|
|
67503
67555
|
push(
|
|
67504
67556
|
"path-resolution",
|
|
67505
67557
|
"warn",
|
|
67506
|
-
`${ownDir} is not on PATH, so a bare \`
|
|
67507
|
-
"
|
|
67558
|
+
`${ownDir} is not on PATH, so a bare \`agent-shim\` does not reach ${resolution.ownExecutablePath}. Add it to PATH, or keep invoking this executable by its full path.`,
|
|
67559
|
+
"agent-shim"
|
|
67508
67560
|
);
|
|
67509
67561
|
break;
|
|
67510
67562
|
case "shadowed":
|
|
67511
67563
|
push(
|
|
67512
67564
|
"path-resolution",
|
|
67513
67565
|
"fail",
|
|
67514
|
-
`\`
|
|
67515
|
-
"
|
|
67566
|
+
`\`agent-shim\` on PATH resolves to ${resolution.agentShim.by}, not this running executable, ${resolution.ownExecutablePath}. Every command you type runs that one instead, at whatever version it happens to be \u2014 including the checks in this report, which describe this executable. Remove ${resolution.agentShim.by}, repoint it at ${resolution.ownExecutablePath}, or put ${ownDir} ahead of it on PATH.`,
|
|
67567
|
+
"agent-shim"
|
|
67516
67568
|
);
|
|
67517
67569
|
break;
|
|
67518
67570
|
}
|
|
@@ -67524,13 +67576,13 @@ function pushPathResolution(push, resolution) {
|
|
|
67524
67576
|
push("path-resolution", "pass", "`claude` on PATH resolves to the enabled shim.", "claude");
|
|
67525
67577
|
break;
|
|
67526
67578
|
case "not-on-path":
|
|
67527
|
-
push("path-resolution", "warn", "The enabled `claude` shim's directory is not on PATH \u2014 add it, or use `
|
|
67579
|
+
push("path-resolution", "warn", "The enabled `claude` shim's directory is not on PATH \u2014 add it, or use `agent-shim run` instead.", "claude");
|
|
67528
67580
|
break;
|
|
67529
67581
|
case "shadowed":
|
|
67530
67582
|
push(
|
|
67531
67583
|
"path-resolution",
|
|
67532
67584
|
"warn",
|
|
67533
|
-
`\`claude\` on PATH resolves to ${resolution.claude.by}, not the enabled shim. Put the shim's directory ahead of it on PATH, or run \`
|
|
67585
|
+
`\`claude\` on PATH resolves to ${resolution.claude.by}, not the enabled shim. Put the shim's directory ahead of it on PATH, or run \`agent-shim shim disable\` if you meant to launch that one directly.`,
|
|
67534
67586
|
"claude"
|
|
67535
67587
|
);
|
|
67536
67588
|
break;
|
|
@@ -67560,6 +67612,23 @@ function pushProvider(push, entry) {
|
|
|
67560
67612
|
}
|
|
67561
67613
|
push("provider", "pass", `${entry.name} is valid (${describeProviderEndpoint(validated.data)}, credential ${describeCredential(validated.data.credential)}).`, entry.name);
|
|
67562
67614
|
}
|
|
67615
|
+
function pushLegacyName(push, params) {
|
|
67616
|
+
const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
|
|
67617
|
+
if (legacyVariables.length === 0 && import_node_path31.default.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
|
|
67618
|
+
push("legacy-name", "pass", "Nothing here still uses the former `claude-use` name.");
|
|
67619
|
+
return;
|
|
67620
|
+
}
|
|
67621
|
+
for (const name of legacyVariables) {
|
|
67622
|
+
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);
|
|
67623
|
+
}
|
|
67624
|
+
if (import_node_path31.default.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
|
|
67625
|
+
push(
|
|
67626
|
+
"legacy-name",
|
|
67627
|
+
"warn",
|
|
67628
|
+
`The state root is the former ${params.rootPath}, used in place. Leave it where it is: macOS Claude Code keys each identity's Keychain login on its exact configuration directory path, so moving it signs every identity out.`
|
|
67629
|
+
);
|
|
67630
|
+
}
|
|
67631
|
+
}
|
|
67563
67632
|
function runDoctor(params) {
|
|
67564
67633
|
const findings = [];
|
|
67565
67634
|
const push = (section, severity, message, subject) => {
|
|
@@ -67579,21 +67648,22 @@ function runDoctor(params) {
|
|
|
67579
67648
|
push("binary-discovery", "fail", params.binaryDiscovery.message);
|
|
67580
67649
|
}
|
|
67581
67650
|
if (params.claudeShim.state === void 0) {
|
|
67582
|
-
push("claude-shim", "pass", "No `claude` command shim enabled (the default). Run `
|
|
67651
|
+
push("claude-shim", "pass", "No `claude` command shim enabled (the default). Run `agent-shim shim enable` to add one.");
|
|
67583
67652
|
} else if (!params.claudeShim.targetExists) {
|
|
67584
67653
|
push(
|
|
67585
67654
|
"claude-shim",
|
|
67586
67655
|
"warn",
|
|
67587
|
-
`claude-shim.json records a \`claude\` shim at ${params.claudeShim.state.targetPath}, but nothing is there. Run \`
|
|
67656
|
+
`claude-shim.json records a \`claude\` shim at ${params.claudeShim.state.targetPath}, but nothing is there. Run \`agent-shim shim enable\` again, or \`agent-shim shim disable\` to clear the stale record.`
|
|
67588
67657
|
);
|
|
67589
67658
|
} else {
|
|
67590
67659
|
push(
|
|
67591
67660
|
"claude-shim",
|
|
67592
67661
|
"pass",
|
|
67593
|
-
`\`claude\` is enabled at ${params.claudeShim.state.targetPath} (${params.claudeShim.state.method}). If you've upgraded
|
|
67662
|
+
`\`claude\` is enabled at ${params.claudeShim.state.targetPath} (${params.claudeShim.state.method}). If you've upgraded agent-shim since, re-run \`agent-shim shim enable\` to refresh it.`
|
|
67594
67663
|
);
|
|
67595
67664
|
}
|
|
67596
67665
|
pushPathResolution(push, params.pathResolution);
|
|
67666
|
+
pushLegacyName(push, params);
|
|
67597
67667
|
const profileSources = /* @__PURE__ */ new Map();
|
|
67598
67668
|
for (const entry of params.configProfiles) {
|
|
67599
67669
|
const validated = validateJson(ConfigProfileSchema, entry);
|
|
@@ -67791,6 +67861,7 @@ var SECTION_TITLES = {
|
|
|
67791
67861
|
"binary-discovery": "Claude Code binary discovery",
|
|
67792
67862
|
"claude-shim": "`claude` command shim",
|
|
67793
67863
|
"path-resolution": "PATH resolution",
|
|
67864
|
+
"legacy-name": "Former `claude-use` name",
|
|
67794
67865
|
"config-profile": "Configuration profiles",
|
|
67795
67866
|
identity: "Identities",
|
|
67796
67867
|
pool: "Pools",
|
|
@@ -67849,7 +67920,7 @@ function formatDoctorReport(report) {
|
|
|
67849
67920
|
}
|
|
67850
67921
|
function realpathOrSelf(target) {
|
|
67851
67922
|
try {
|
|
67852
|
-
return
|
|
67923
|
+
return import_node_fs14.default.realpathSync(target);
|
|
67853
67924
|
} catch {
|
|
67854
67925
|
return target;
|
|
67855
67926
|
}
|
|
@@ -67857,20 +67928,20 @@ function realpathOrSelf(target) {
|
|
|
67857
67928
|
function registerDoctorCommand(program2, deps) {
|
|
67858
67929
|
const { paths } = deps;
|
|
67859
67930
|
const command = program2.command("doctor").description(
|
|
67860
|
-
"Audit the whole ~/.
|
|
67931
|
+
"Audit the whole ~/.agent-shim config graph: every identity, every configuration profile's extends chain, every provider, directory-rules.json, config.json, categories.local.json, active-identity, and real Claude Code binary discoverability. Identity/directory-agnostic, unlike `check`. Exits 1 when any check fails."
|
|
67861
67932
|
).option("--json", "Print the report as JSON.").action((options) => {
|
|
67862
|
-
const identityNames =
|
|
67933
|
+
const identityNames = import_node_fs14.default.existsSync(paths.identitiesDir) ? import_node_fs14.default.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort() : [];
|
|
67863
67934
|
const identities = identityNames.map((name) => {
|
|
67864
67935
|
const farmRoot = import_node_path31.default.join(paths.identitiesDir, name);
|
|
67865
67936
|
const identityPath = import_node_path31.default.join(farmRoot, "identity.json");
|
|
67866
67937
|
return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot };
|
|
67867
67938
|
});
|
|
67868
|
-
const profileNames =
|
|
67939
|
+
const profileNames = import_node_fs14.default.existsSync(paths.configProfilesDir) ? import_node_fs14.default.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
67869
67940
|
const configProfiles = profileNames.map((name) => {
|
|
67870
67941
|
const profilePath = import_node_path31.default.join(paths.configProfilesDir, `${name}.json`);
|
|
67871
67942
|
return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
|
|
67872
67943
|
});
|
|
67873
|
-
const providerNames =
|
|
67944
|
+
const providerNames = import_node_fs14.default.existsSync(paths.providersDir) ? import_node_fs14.default.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
67874
67945
|
const providers = providerNames.map((name) => {
|
|
67875
67946
|
const providerPath = import_node_path31.default.join(paths.providersDir, `${name}.json`);
|
|
67876
67947
|
return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
|
|
@@ -67905,14 +67976,15 @@ function registerDoctorCommand(program2, deps) {
|
|
|
67905
67976
|
categoriesLocal: { path: paths.categoriesLocalFile, raw: realFsPort.readFileUtf8(paths.categoriesLocalFile) },
|
|
67906
67977
|
activeIdentity: { path: paths.activeIdentityFile, raw: realFsPort.readFileUtf8(paths.activeIdentityFile) },
|
|
67907
67978
|
binaryDiscovery,
|
|
67908
|
-
claudeShim: { state: shimState, targetExists: shimState !== void 0 &&
|
|
67979
|
+
claudeShim: { state: shimState, targetExists: shimState !== void 0 && import_node_fs14.default.existsSync(shimState.targetPath) },
|
|
67980
|
+
rootPath: paths.root,
|
|
67909
67981
|
pathResolution: {
|
|
67910
67982
|
ownExecutablePath,
|
|
67911
|
-
|
|
67983
|
+
agentShim: refinePathShadow(
|
|
67912
67984
|
findPathShadow({
|
|
67913
67985
|
pathDirs,
|
|
67914
67986
|
targetDir: import_node_path31.default.dirname(ownExecutablePath),
|
|
67915
|
-
targetFilename: commandFilename(ownExecutablePath, "
|
|
67987
|
+
targetFilename: commandFilename(ownExecutablePath, "agent-shim"),
|
|
67916
67988
|
findExecutableInDir
|
|
67917
67989
|
}),
|
|
67918
67990
|
ownExecutablePath,
|
|
@@ -67938,12 +68010,13 @@ function registerDoctorCommand(program2, deps) {
|
|
|
67938
68010
|
process.exitCode = 1;
|
|
67939
68011
|
}
|
|
67940
68012
|
});
|
|
67941
|
-
withExamples(command, ["
|
|
68013
|
+
withExamples(command, ["agent-shim doctor", "agent-shim doctor --json"]);
|
|
67942
68014
|
}
|
|
67943
68015
|
|
|
67944
68016
|
// src/headroom/commands.ts
|
|
67945
|
-
var
|
|
68017
|
+
var import_node_fs15 = __toESM(require("node:fs"), 1);
|
|
67946
68018
|
var import_node_net3 = __toESM(require("node:net"), 1);
|
|
68019
|
+
var import_node_path32 = __toESM(require("node:path"), 1);
|
|
67947
68020
|
var import_node_child_process5 = require("node:child_process");
|
|
67948
68021
|
|
|
67949
68022
|
// src/headroom/settings.ts
|
|
@@ -68074,42 +68147,44 @@ function compareVersions2(a2, b) {
|
|
|
68074
68147
|
}
|
|
68075
68148
|
var HEADROOM_SUPERVISOR_STILL_RUNNING = -1;
|
|
68076
68149
|
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
68077
|
-
const { fs:
|
|
68150
|
+
const { fs: fs17, paths } = ports;
|
|
68078
68151
|
let config2 = initialConfig;
|
|
68079
|
-
const previousState = readHeadroomState(
|
|
68152
|
+
const previousState = readHeadroomState(fs17, paths.headroomStateFile);
|
|
68080
68153
|
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
68081
|
-
ports.log(`
|
|
68154
|
+
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
68082
68155
|
return 0;
|
|
68083
68156
|
}
|
|
68084
68157
|
let installedSource = previousState?.installedSource;
|
|
68085
68158
|
let lastPort = previousState?.lastPort;
|
|
68086
68159
|
const sticky = () => lastPort === void 0 ? {} : { lastPort };
|
|
68087
68160
|
const ownsState = () => {
|
|
68088
|
-
const owner = readHeadroomState(
|
|
68161
|
+
const owner = readHeadroomState(fs17, paths.headroomStateFile)?.supervisorPid;
|
|
68089
68162
|
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
68090
68163
|
};
|
|
68091
68164
|
const writeOwnState = (state) => {
|
|
68092
68165
|
if (!ownsState()) {
|
|
68093
68166
|
return false;
|
|
68094
68167
|
}
|
|
68095
|
-
writeHeadroomState(
|
|
68168
|
+
writeHeadroomState(fs17, paths.headroomStateFile, state);
|
|
68096
68169
|
return true;
|
|
68097
68170
|
};
|
|
68098
68171
|
const fail = (message) => {
|
|
68099
68172
|
if (writeOwnState({ lastError: message, ...sticky() })) {
|
|
68100
|
-
|
|
68173
|
+
fs17.removeRecursive(paths.headroomLockFile);
|
|
68101
68174
|
}
|
|
68102
|
-
ports.log(`
|
|
68175
|
+
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
68103
68176
|
return 1;
|
|
68104
68177
|
};
|
|
68105
68178
|
const ensureInstalled = () => {
|
|
68106
68179
|
const version3 = ports.headroomVersion();
|
|
68107
68180
|
const versionOk = version3 !== void 0 && versionSatisfies(version3, config2.source);
|
|
68108
|
-
|
|
68181
|
+
const pinned = pinnedGitCommit(config2.source);
|
|
68182
|
+
const commitOk = pinned === void 0 || ports.installedCommit() === pinned;
|
|
68183
|
+
if (versionOk && commitOk && (installedSource === void 0 || installedSource === config2.source)) {
|
|
68109
68184
|
installedSource = config2.source;
|
|
68110
68185
|
return true;
|
|
68111
68186
|
}
|
|
68112
|
-
ports.log(`
|
|
68187
|
+
ports.log(`agent-shim headroom supervisor: installing headroom from ${config2.source}`);
|
|
68113
68188
|
const result = ports.install(config2.source);
|
|
68114
68189
|
if (!result.ok) {
|
|
68115
68190
|
return false;
|
|
@@ -68122,10 +68197,10 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
68122
68197
|
}
|
|
68123
68198
|
const version2 = ports.headroomVersion() ?? "unknown";
|
|
68124
68199
|
writeOwnState({ supervisorPid: ports.ownPid, version: version2, installedSource, ...sticky() });
|
|
68125
|
-
ports.log(`
|
|
68200
|
+
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${allowlistOf(ports).join(", ")}]`);
|
|
68126
68201
|
const orphanPid = previousState?.headroomPid;
|
|
68127
68202
|
if (orphanPid !== void 0 && ports.isRunning(orphanPid)) {
|
|
68128
|
-
ports.log(`
|
|
68203
|
+
ports.log(`agent-shim headroom supervisor: stopping daemon pid ${String(orphanPid)} left behind by the previous supervisor`);
|
|
68129
68204
|
ports.stopProcess(orphanPid);
|
|
68130
68205
|
}
|
|
68131
68206
|
let headroomPid;
|
|
@@ -68144,16 +68219,16 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
68144
68219
|
const settingsHash = hashSettings(config2.settings);
|
|
68145
68220
|
const allowlist = allowlistOf(ports);
|
|
68146
68221
|
const allowlistHash = hashAllowlist(allowlist);
|
|
68147
|
-
pruneDeadSessions(
|
|
68222
|
+
pruneDeadSessions(fs17, paths.headroomSessionsDir, ports.isRunning);
|
|
68148
68223
|
const ownsNow = ownsState();
|
|
68149
68224
|
if (!ownsNow && !superseded) {
|
|
68150
|
-
ports.log("
|
|
68225
|
+
ports.log("agent-shim headroom supervisor: another supervisor now owns state.json; serving this daemon's own sessions until they end");
|
|
68151
68226
|
}
|
|
68152
68227
|
superseded = !ownsNow;
|
|
68153
68228
|
const crashed = headroomPid !== void 0 && !ports.isRunning(headroomPid);
|
|
68154
68229
|
if (headroomPid === void 0 || crashed) {
|
|
68155
68230
|
if (crashed) {
|
|
68156
|
-
ports.log(`
|
|
68231
|
+
ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} died`);
|
|
68157
68232
|
headroomPid = void 0;
|
|
68158
68233
|
runningHash = void 0;
|
|
68159
68234
|
runningSettingsHash = void 0;
|
|
@@ -68182,7 +68257,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
68182
68257
|
lastPort = port;
|
|
68183
68258
|
if (previousSticky !== void 0 && port !== previousSticky) {
|
|
68184
68259
|
ports.log(
|
|
68185
|
-
`
|
|
68260
|
+
`agent-shim headroom supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(port)} (sessions launched against the old port are stale until they relaunch)`
|
|
68186
68261
|
);
|
|
68187
68262
|
}
|
|
68188
68263
|
const recorded = writeOwnState({
|
|
@@ -68196,23 +68271,23 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
68196
68271
|
...sticky()
|
|
68197
68272
|
});
|
|
68198
68273
|
if (recorded) {
|
|
68199
|
-
|
|
68274
|
+
fs17.removeRecursive(paths.headroomLockFile);
|
|
68200
68275
|
}
|
|
68201
68276
|
idleSince = void 0;
|
|
68202
|
-
ports.log(`
|
|
68277
|
+
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on 127.0.0.1:${String(port)}`);
|
|
68203
68278
|
} else {
|
|
68204
68279
|
ports.stopProcess(pid);
|
|
68205
68280
|
consecutiveFailures += 1;
|
|
68206
68281
|
ports.log(
|
|
68207
|
-
`
|
|
68282
|
+
`agent-shim headroom supervisor: headroom did not become ready on port ${String(port)} (attempt ${String(consecutiveFailures)} of ${String(HEADROOM_START_RETRY_BUDGET)})`
|
|
68208
68283
|
);
|
|
68209
68284
|
await ports.sleep(backoffForAttempt(consecutiveFailures));
|
|
68210
68285
|
continue;
|
|
68211
68286
|
}
|
|
68212
68287
|
} else {
|
|
68213
68288
|
if (runningHash !== allowlistHash || runningSettingsHash !== settingsHash || installedSource !== config2.source) {
|
|
68214
|
-
if (sessionsForSupervisor(
|
|
68215
|
-
ports.log("
|
|
68289
|
+
if (sessionsForSupervisor(fs17, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
68290
|
+
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
68216
68291
|
ports.stopProcess(headroomPid);
|
|
68217
68292
|
headroomPid = void 0;
|
|
68218
68293
|
runningHash = void 0;
|
|
@@ -68220,13 +68295,13 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
68220
68295
|
continue;
|
|
68221
68296
|
}
|
|
68222
68297
|
}
|
|
68223
|
-
const sessions = sessionsForSupervisor(
|
|
68298
|
+
const sessions = sessionsForSupervisor(fs17, paths.headroomSessionsDir, ports.ownPid);
|
|
68224
68299
|
if (sessions.length === 0) {
|
|
68225
68300
|
idleSince ??= ports.now();
|
|
68226
68301
|
const idleMs = ports.now() - idleSince;
|
|
68227
68302
|
if (idleMs >= config2.idleShutdownMinutes * MS_PER_MINUTE2) {
|
|
68228
68303
|
ports.log(
|
|
68229
|
-
`
|
|
68304
|
+
`agent-shim headroom supervisor: no sessions for ${String(config2.idleShutdownMinutes)} minute(s); stopping headroom and exiting`
|
|
68230
68305
|
);
|
|
68231
68306
|
ports.stopProcess(headroomPid);
|
|
68232
68307
|
writeOwnState({
|
|
@@ -68242,9 +68317,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
68242
68317
|
await ports.sleep(HEADROOM_POLL_MS);
|
|
68243
68318
|
}
|
|
68244
68319
|
}
|
|
68245
|
-
function currentHeadroomAllowlist(
|
|
68246
|
-
const providers = readAllProviders(
|
|
68247
|
-
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(
|
|
68320
|
+
function currentHeadroomAllowlist(fs17, paths) {
|
|
68321
|
+
const providers = readAllProviders(fs17, paths.providersDir).map((entry) => entry.provider);
|
|
68322
|
+
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(fs17, paths.frontdoorStateFile))));
|
|
68248
68323
|
}
|
|
68249
68324
|
function allowlistOf(ports) {
|
|
68250
68325
|
return currentHeadroomAllowlist(ports.fs, ports.paths);
|
|
@@ -68350,6 +68425,24 @@ function headroomSpawnEnv(parentEnv, allowlist, settings2) {
|
|
|
68350
68425
|
...settingsEnv(settings2)
|
|
68351
68426
|
};
|
|
68352
68427
|
}
|
|
68428
|
+
var HEADROOM_TOOL_NAME = "headroom-ai";
|
|
68429
|
+
function readInstalledHeadroomCommit() {
|
|
68430
|
+
const toolDir = (0, import_node_child_process5.spawnSync)("uv", ["tool", "dir"], { encoding: "utf8" });
|
|
68431
|
+
if (toolDir.status !== 0) {
|
|
68432
|
+
return void 0;
|
|
68433
|
+
}
|
|
68434
|
+
const libDir = import_node_path32.default.join(toolDir.stdout.trim(), HEADROOM_TOOL_NAME, "lib");
|
|
68435
|
+
for (const python of realFarmFs.readdir(libDir)) {
|
|
68436
|
+
const sitePackages = import_node_path32.default.join(libDir, python, "site-packages");
|
|
68437
|
+
for (const entry of realFarmFs.readdir(sitePackages)) {
|
|
68438
|
+
if (entry.startsWith("headroom_ai-") && entry.endsWith(".dist-info")) {
|
|
68439
|
+
const directUrl = realFarmFs.readFileUtf8(import_node_path32.default.join(sitePackages, entry, "direct_url.json"));
|
|
68440
|
+
return directUrl === void 0 ? void 0 : parseInstalledCommit(directUrl);
|
|
68441
|
+
}
|
|
68442
|
+
}
|
|
68443
|
+
}
|
|
68444
|
+
return void 0;
|
|
68445
|
+
}
|
|
68353
68446
|
function realSupervisorPorts(paths) {
|
|
68354
68447
|
return {
|
|
68355
68448
|
fs: realFarmFs,
|
|
@@ -68367,8 +68460,8 @@ function realSupervisorPorts(paths) {
|
|
|
68367
68460
|
isPortFree: realIsPortFree,
|
|
68368
68461
|
readConfig: () => resolveSupervisorConfig(readGlobalConfig(paths)?.headroom ?? {}),
|
|
68369
68462
|
spawnHeadroom: (port, allowlist, settings2) => {
|
|
68370
|
-
|
|
68371
|
-
const logFd =
|
|
68463
|
+
import_node_fs15.default.mkdirSync(paths.logsDir, { recursive: true });
|
|
68464
|
+
const logFd = import_node_fs15.default.openSync(paths.headroomLogPath, "a");
|
|
68372
68465
|
try {
|
|
68373
68466
|
const child = (0, import_node_child_process5.spawn)("headroom", ["proxy", "--host", "127.0.0.1", "--port", String(port), ...settingsArgs(settings2)], {
|
|
68374
68467
|
detached: true,
|
|
@@ -68383,12 +68476,12 @@ function realSupervisorPorts(paths) {
|
|
|
68383
68476
|
child.once("exit", (code, signal) => {
|
|
68384
68477
|
ownedHeadroom.delete(pid);
|
|
68385
68478
|
exitedHeadroom.add(pid);
|
|
68386
|
-
|
|
68479
|
+
import_node_fs15.default.appendFileSync(paths.headroomLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} agent-shim headroom supervisor: headroom exited (${signal ?? `code ${String(code)}`})
|
|
68387
68480
|
`);
|
|
68388
68481
|
});
|
|
68389
68482
|
return pid;
|
|
68390
68483
|
} finally {
|
|
68391
|
-
|
|
68484
|
+
import_node_fs15.default.closeSync(logFd);
|
|
68392
68485
|
}
|
|
68393
68486
|
},
|
|
68394
68487
|
stopProcess: (pid) => {
|
|
@@ -68401,9 +68494,9 @@ function realSupervisorPorts(paths) {
|
|
|
68401
68494
|
now: () => Date.now()
|
|
68402
68495
|
});
|
|
68403
68496
|
if (outcome === "still-running") {
|
|
68404
|
-
|
|
68497
|
+
import_node_fs15.default.appendFileSync(
|
|
68405
68498
|
paths.headroomLogPath,
|
|
68406
|
-
`${(/* @__PURE__ */ new Date()).toISOString()}
|
|
68499
|
+
`${(/* @__PURE__ */ new Date()).toISOString()} agent-shim headroom supervisor: pid ${String(pid)} survived SIGKILL within its grace; it is stuck uninterruptibly
|
|
68407
68500
|
`
|
|
68408
68501
|
);
|
|
68409
68502
|
}
|
|
@@ -68422,10 +68515,10 @@ function realSupervisorPorts(paths) {
|
|
|
68422
68515
|
return { ok: false, error: `uv is not installed or not on PATH (${result.error.message})` };
|
|
68423
68516
|
}
|
|
68424
68517
|
if (result.stdout !== "") {
|
|
68425
|
-
|
|
68518
|
+
import_node_fs15.default.appendFileSync(paths.headroomLogPath, result.stdout);
|
|
68426
68519
|
}
|
|
68427
68520
|
if (result.stderr !== "") {
|
|
68428
|
-
|
|
68521
|
+
import_node_fs15.default.appendFileSync(paths.headroomLogPath, result.stderr);
|
|
68429
68522
|
}
|
|
68430
68523
|
return result.status === 0 ? { ok: true } : { ok: false, error: `uv tool install exited ${String(result.status)}` };
|
|
68431
68524
|
},
|
|
@@ -68433,9 +68526,10 @@ function realSupervisorPorts(paths) {
|
|
|
68433
68526
|
const result = (0, import_node_child_process5.spawnSync)("headroom", ["--version"], { encoding: "utf8" });
|
|
68434
68527
|
return result.status === 0 ? result.stdout.trim() : void 0;
|
|
68435
68528
|
},
|
|
68529
|
+
installedCommit: readInstalledHeadroomCommit,
|
|
68436
68530
|
log: (line) => {
|
|
68437
|
-
|
|
68438
|
-
|
|
68531
|
+
import_node_fs15.default.mkdirSync(paths.logsDir, { recursive: true });
|
|
68532
|
+
import_node_fs15.default.appendFileSync(paths.headroomLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
68439
68533
|
`);
|
|
68440
68534
|
}
|
|
68441
68535
|
};
|
|
@@ -68443,7 +68537,7 @@ function realSupervisorPorts(paths) {
|
|
|
68443
68537
|
function registerHeadroomCommand(program2, deps) {
|
|
68444
68538
|
const { paths } = deps;
|
|
68445
68539
|
const headroom = withExamples(program2.command("headroom").description("Inspect the headroom routing daemon."), [
|
|
68446
|
-
"
|
|
68540
|
+
"agent-shim headroom status"
|
|
68447
68541
|
]);
|
|
68448
68542
|
withExamples(
|
|
68449
68543
|
headroom.command("status").description("Report the headroom daemon's supervisor, process, port, sessions, and last error. Read-only.").option("--json", "Print the status as JSON.").action((options) => {
|
|
@@ -68456,7 +68550,7 @@ function registerHeadroomCommand(program2, deps) {
|
|
|
68456
68550
|
console.log(line);
|
|
68457
68551
|
}
|
|
68458
68552
|
}),
|
|
68459
|
-
["
|
|
68553
|
+
["agent-shim headroom status", "agent-shim headroom status --json"]
|
|
68460
68554
|
);
|
|
68461
68555
|
program2.command("__headroom-supervisor", { hidden: true }).description("Internal: supervise the headroom daemon. Started by the launcher; never run by hand.").allowUnknownOption().action(async () => {
|
|
68462
68556
|
const globalConfig2 = readGlobalConfig(paths);
|
|
@@ -68483,7 +68577,7 @@ function registerHeadroomCommand(program2, deps) {
|
|
|
68483
68577
|
// src/runCommand.ts
|
|
68484
68578
|
function registerRunCommand(program2, handler) {
|
|
68485
68579
|
program2.command("run").description(
|
|
68486
|
-
"Launch Claude Code under an identity, without needing a `claude`-named binary on PATH. Launch flags (see `
|
|
68580
|
+
"Launch Claude Code under an identity, without needing a `claude`-named binary on PATH. Launch flags (see `agent-shim --help`) are consumed first; every other argument is forwarded exactly as `claude` would receive it."
|
|
68487
68581
|
).allowUnknownOption().passThroughOptions().helpOption(false).argument("[args...]", "Arguments to forward, e.g. @<name>, --config-profile <name>, or any Claude Code flag.").action(async (args) => {
|
|
68488
68582
|
await handler(args);
|
|
68489
68583
|
});
|
|
@@ -68496,14 +68590,14 @@ function requireIdentity(paths, name) {
|
|
|
68496
68590
|
throw new IdentityNotFoundError(name);
|
|
68497
68591
|
}
|
|
68498
68592
|
}
|
|
68499
|
-
function collectUsageReport(
|
|
68593
|
+
function collectUsageReport(fs17, paths, filters) {
|
|
68500
68594
|
const { identity, provider, sinceMs } = filters;
|
|
68501
68595
|
if (identity !== void 0) {
|
|
68502
68596
|
requireIdentity(paths, identity);
|
|
68503
68597
|
}
|
|
68504
|
-
const log = readUsageLog(
|
|
68598
|
+
const log = readUsageLog(fs17, paths.usageLogDir, sinceMs === void 0 ? {} : { sinceMs });
|
|
68505
68599
|
const records = log.records.filter((record2) => (identity === void 0 || record2.identity === identity) && (provider === void 0 || record2.provider === provider));
|
|
68506
|
-
const snapshots = (identity === void 0 ? listUsageSnapshots(
|
|
68600
|
+
const snapshots = (identity === void 0 ? listUsageSnapshots(fs17, paths.usageSnapshotsDir) : [readUsageSnapshot(fs17, paths.usageSnapshotsDir, identity)].flatMap((snapshot) => snapshot === void 0 ? [] : [snapshot])).map((snapshot) => provider === void 0 ? snapshot : { ...snapshot, providers: Object.fromEntries(Object.entries(snapshot.providers).filter(([name]) => name === provider)) }).filter((snapshot) => Object.keys(snapshot.providers).length > 0);
|
|
68507
68601
|
return {
|
|
68508
68602
|
since: sinceMs === void 0 ? void 0 : new Date(sinceMs).toISOString(),
|
|
68509
68603
|
logDir: paths.usageLogDir,
|
|
@@ -68599,15 +68693,15 @@ function formatUsageReport(report) {
|
|
|
68599
68693
|
}
|
|
68600
68694
|
return lines;
|
|
68601
68695
|
}
|
|
68602
|
-
function collectAccounts(
|
|
68696
|
+
function collectAccounts(fs17, paths, identity) {
|
|
68603
68697
|
if (identity !== void 0) {
|
|
68604
68698
|
requireIdentity(paths, identity);
|
|
68605
68699
|
}
|
|
68606
68700
|
const names = identity === void 0 ? listIdentities(paths).map((entry) => entry.name) : [identity];
|
|
68607
68701
|
return names.map((name) => ({
|
|
68608
68702
|
identity: name,
|
|
68609
|
-
account: readAccountMetadata(
|
|
68610
|
-
usage: readUsageSnapshot(
|
|
68703
|
+
account: readAccountMetadata(fs17, paths.identitiesDir, name),
|
|
68704
|
+
usage: readUsageSnapshot(fs17, paths.usageSnapshotsDir, name)
|
|
68611
68705
|
}));
|
|
68612
68706
|
}
|
|
68613
68707
|
function formatAccounts(views) {
|
|
@@ -68687,10 +68781,10 @@ function registerUsageCommands(program2, deps) {
|
|
|
68687
68781
|
console.log(line);
|
|
68688
68782
|
}
|
|
68689
68783
|
}),
|
|
68690
|
-
["
|
|
68784
|
+
["agent-shim usage", "agent-shim usage --identity work --since 5h", "agent-shim usage --provider z --refresh --json"]
|
|
68691
68785
|
);
|
|
68692
68786
|
const account = withExamples(program2.command("account").description("Inspect the Claude account behind each identity: plan, tier and latest quota."), [
|
|
68693
|
-
"
|
|
68787
|
+
"agent-shim account show work"
|
|
68694
68788
|
]);
|
|
68695
68789
|
withExamples(
|
|
68696
68790
|
account.command("show [identity]").description("Show an identity's account metadata (read live from its stored login) and its latest recorded quota; every identity when none is named. Read-only.").option("--refresh", "First fetch the quota of providers that report it through their own usage endpoint (z.ai), regardless of how fresh the stored one is.").option("--json", "Print the accounts as JSON.").action(async (identity, options) => {
|
|
@@ -68708,21 +68802,21 @@ function registerUsageCommands(program2, deps) {
|
|
|
68708
68802
|
console.log(line);
|
|
68709
68803
|
}
|
|
68710
68804
|
}),
|
|
68711
|
-
["
|
|
68805
|
+
["agent-shim account show", "agent-shim account show work", "agent-shim account show work --json"]
|
|
68712
68806
|
);
|
|
68713
68807
|
}
|
|
68714
68808
|
|
|
68715
68809
|
// src/program.ts
|
|
68716
68810
|
var ROOT_HELP_AFTER = `
|
|
68717
68811
|
Grammar:
|
|
68718
|
-
|
|
68812
|
+
agent-shim <noun> <verb> [name] [options], where the nouns are identity, profile,
|
|
68719
68813
|
provider and rule, and the verbs are add, set, list, show, remove and use.
|
|
68720
68814
|
credential is the exception: it acts on the credentials identities use (store).
|
|
68721
68815
|
|
|
68722
68816
|
Launching:
|
|
68723
|
-
|
|
68724
|
-
Everything after run is forwarded to Claude Code, so \`
|
|
68725
|
-
claude's own help.
|
|
68817
|
+
agent-shim run [@<identity>] [launch flags] [claude arguments]
|
|
68818
|
+
Everything after run is forwarded to Claude Code, so \`agent-shim run --help\` shows
|
|
68819
|
+
claude's own help. agent-shim consumes these launch flags first, and only before a
|
|
68726
68820
|
\`--\` terminator (everything from \`--\` on is forwarded untouched):
|
|
68727
68821
|
--identity <name> the identity (same as a leading @<name>)
|
|
68728
68822
|
--config-profile <name> the configuration profile for this launch
|
|
@@ -68733,22 +68827,22 @@ Launching:
|
|
|
68733
68827
|
--[no-]wait with @pool:<name>, sleep until the earliest member returns when all are refused
|
|
68734
68828
|
|
|
68735
68829
|
Environment:
|
|
68736
|
-
|
|
68737
|
-
|
|
68738
|
-
|
|
68739
|
-
|
|
68830
|
+
AGENT_SHIM_IDENTITY, AGENT_SHIM_CONFIG_PROFILE, AGENT_SHIM_SKIP_PERMISSIONS,
|
|
68831
|
+
AGENT_SHIM_REMOTE_CONTROL, AGENT_SHIM_HEADROOM, AGENT_SHIM_TRACK_USAGE, AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL,
|
|
68832
|
+
AGENT_SHIM_CATEGORY_OVERRIDE, AGENT_SHIM_ENTRY_OVERRIDE, AGENT_SHIM_HOME,
|
|
68833
|
+
AGENT_SHIM_DEBUG (print stack traces), NO_COLOR. Booleans are true, false, 1 or 0.
|
|
68740
68834
|
|
|
68741
68835
|
Exit status:
|
|
68742
68836
|
0 success, 1 failure, 2 usage error, 64 a selected provider's or identity's credential
|
|
68743
68837
|
yields no token.
|
|
68744
68838
|
|
|
68745
68839
|
Examples:
|
|
68746
|
-
$
|
|
68747
|
-
$
|
|
68748
|
-
$
|
|
68840
|
+
$ agent-shim identity add work
|
|
68841
|
+
$ agent-shim run @work
|
|
68842
|
+
$ agent-shim run --identity work --provider z -p "hello"`;
|
|
68749
68843
|
function buildProgram(deps) {
|
|
68750
68844
|
const program2 = new Command();
|
|
68751
|
-
program2.name("
|
|
68845
|
+
program2.name("agent-shim").description("Run Claude Code under several logins from one machine, controlling what each one shares with ~/.claude.").version(package_default.version).exitOverride().enablePositionalOptions().addHelpText("after", ROOT_HELP_AFTER);
|
|
68752
68846
|
registerIdentityCommand(program2, deps);
|
|
68753
68847
|
registerProfileCommand(program2, deps);
|
|
68754
68848
|
registerPoolCommand(program2, deps);
|
|
@@ -68774,7 +68868,7 @@ var import_node_crypto16 = require("node:crypto");
|
|
|
68774
68868
|
|
|
68775
68869
|
// src/launcher.ts
|
|
68776
68870
|
var import_node_crypto15 = require("node:crypto");
|
|
68777
|
-
var
|
|
68871
|
+
var import_node_path34 = __toESM(require("node:path"), 1);
|
|
68778
68872
|
|
|
68779
68873
|
// src/launcher/cliOverride.ts
|
|
68780
68874
|
var InvalidCliCategoryError = class extends CliError {
|
|
@@ -68824,8 +68918,8 @@ function parseOverride(source, raw, parse3) {
|
|
|
68824
68918
|
}
|
|
68825
68919
|
function buildCliOverride(params) {
|
|
68826
68920
|
let categoryPairs = {};
|
|
68827
|
-
if (params.env.
|
|
68828
|
-
categoryPairs = parseOverride("
|
|
68921
|
+
if (params.env.AGENT_SHIM_CATEGORY_OVERRIDE !== void 0 && params.env.AGENT_SHIM_CATEGORY_OVERRIDE !== "") {
|
|
68922
|
+
categoryPairs = parseOverride("AGENT_SHIM_CATEGORY_OVERRIDE", params.env.AGENT_SHIM_CATEGORY_OVERRIDE, parseBoolPairList);
|
|
68829
68923
|
}
|
|
68830
68924
|
for (const flagValue of params.categoryFlags) {
|
|
68831
68925
|
const pair = parseOverride("--category", flagValue, (raw) => {
|
|
@@ -68835,8 +68929,8 @@ function buildCliOverride(params) {
|
|
|
68835
68929
|
categoryPairs[pair.key] = pair.value;
|
|
68836
68930
|
}
|
|
68837
68931
|
let entryPairs = {};
|
|
68838
|
-
if (params.env.
|
|
68839
|
-
entryPairs = parseOverride("
|
|
68932
|
+
if (params.env.AGENT_SHIM_ENTRY_OVERRIDE !== void 0 && params.env.AGENT_SHIM_ENTRY_OVERRIDE !== "") {
|
|
68933
|
+
entryPairs = parseOverride("AGENT_SHIM_ENTRY_OVERRIDE", params.env.AGENT_SHIM_ENTRY_OVERRIDE, parseBoolPairList);
|
|
68840
68934
|
}
|
|
68841
68935
|
for (const entryPath of params.shareFlags) {
|
|
68842
68936
|
entryPairs[entryPath] = true;
|
|
@@ -68858,7 +68952,7 @@ function buildCliOverride(params) {
|
|
|
68858
68952
|
}
|
|
68859
68953
|
|
|
68860
68954
|
// src/launcher/flags.ts
|
|
68861
|
-
var
|
|
68955
|
+
var import_node_path33 = __toESM(require("node:path"), 1);
|
|
68862
68956
|
|
|
68863
68957
|
// src/headroom/headers.ts
|
|
68864
68958
|
function mergeAnthropicCustomHeaders(existing, additions) {
|
|
@@ -68895,10 +68989,10 @@ function parseCustomHeaderLine(line) {
|
|
|
68895
68989
|
// src/launcher/flags.ts
|
|
68896
68990
|
function resolveLaunchFlags(params) {
|
|
68897
68991
|
return {
|
|
68898
|
-
skipPermissions: params.flags?.skipPermissions ?? parseEnvBool("
|
|
68899
|
-
remoteControl: params.flags?.remoteControl ?? parseEnvBool("
|
|
68900
|
-
headroom: params.flags?.headroom ?? parseEnvBool("
|
|
68901
|
-
trackUsage: params.flags?.trackUsage ?? parseEnvBool("
|
|
68992
|
+
skipPermissions: params.flags?.skipPermissions ?? parseEnvBool("AGENT_SHIM_SKIP_PERMISSIONS", params.env.AGENT_SHIM_SKIP_PERMISSIONS) ?? params.cascade?.skipPermissions ?? false,
|
|
68993
|
+
remoteControl: params.flags?.remoteControl ?? parseEnvBool("AGENT_SHIM_REMOTE_CONTROL", params.env.AGENT_SHIM_REMOTE_CONTROL) ?? params.cascade?.remoteControl ?? false,
|
|
68994
|
+
headroom: params.flags?.headroom ?? parseEnvBool("AGENT_SHIM_HEADROOM", params.env.AGENT_SHIM_HEADROOM) ?? params.cascade?.headroom ?? false,
|
|
68995
|
+
trackUsage: params.flags?.trackUsage ?? parseEnvBool("AGENT_SHIM_TRACK_USAGE", params.env.AGENT_SHIM_TRACK_USAGE) ?? params.cascade?.trackUsage ?? params.trackUsageDefault ?? false
|
|
68902
68996
|
};
|
|
68903
68997
|
}
|
|
68904
68998
|
function buildFlagArgs(flags) {
|
|
@@ -68928,7 +69022,7 @@ function buildEnv(params) {
|
|
|
68928
69022
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
68929
69023
|
let providerCustomHeaders;
|
|
68930
69024
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
68931
|
-
env.CLAUDE_CONFIG_DIR =
|
|
69025
|
+
env.CLAUDE_CONFIG_DIR = import_node_path33.default.join(params.identitiesDir, params.resolvedIdentityName);
|
|
68932
69026
|
}
|
|
68933
69027
|
if (params.provider !== void 0) {
|
|
68934
69028
|
const providerEnv = params.provider.definition.env ?? {};
|
|
@@ -68938,7 +69032,7 @@ function buildEnv(params) {
|
|
|
68938
69032
|
env.NO_PROXY = withLoopbackHosts(params.baseEnv.NO_PROXY);
|
|
68939
69033
|
env.no_proxy = withLoopbackHosts(params.baseEnv.no_proxy);
|
|
68940
69034
|
}
|
|
68941
|
-
env.
|
|
69035
|
+
env.AGENT_SHIM_PROVIDER = params.provider.definition.displayName;
|
|
68942
69036
|
for (const [key, value] of Object.entries(providerEnv)) {
|
|
68943
69037
|
env[key] = value;
|
|
68944
69038
|
}
|
|
@@ -69014,19 +69108,19 @@ function spawnClaude(params) {
|
|
|
69014
69108
|
// src/launcher.ts
|
|
69015
69109
|
function resolveIdentityCredential(identity, credential, env, port) {
|
|
69016
69110
|
if (port === void 0) {
|
|
69017
|
-
return { ok: false, status: 1, message: `
|
|
69111
|
+
return { ok: false, status: 1, message: `agent-shim: identity ${identity} needs its credential resolved, but this launcher has no credential port wired` };
|
|
69018
69112
|
}
|
|
69019
69113
|
const resolution = resolveCredential({ credential, env, port, subject: `identity ${identity}` });
|
|
69020
69114
|
return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
69021
69115
|
}
|
|
69022
69116
|
function pickFromPool(decided, params, parsedArgv) {
|
|
69023
|
-
const { paths, fs:
|
|
69117
|
+
const { paths, fs: fs17, proc, log } = params;
|
|
69024
69118
|
if (decided.pool === void 0) {
|
|
69025
69119
|
return { identityDecision: decided };
|
|
69026
69120
|
}
|
|
69027
69121
|
const farmRuntime = params.farm;
|
|
69028
69122
|
if (farmRuntime === void 0) {
|
|
69029
|
-
log.error(`
|
|
69123
|
+
log.error(`agent-shim: pool "${decided.pool}" was selected, but this launcher has no farm wired to read usage and pick a member with.`);
|
|
69030
69124
|
return proc.exit(1);
|
|
69031
69125
|
}
|
|
69032
69126
|
const resolution = resolvePoolLaunch({
|
|
@@ -69034,7 +69128,7 @@ function pickFromPool(decided, params, parsedArgv) {
|
|
|
69034
69128
|
selectedVia: decided.source,
|
|
69035
69129
|
pools: params.pools,
|
|
69036
69130
|
paths,
|
|
69037
|
-
fs:
|
|
69131
|
+
fs: fs17,
|
|
69038
69132
|
usageFs: farmRuntime.fs,
|
|
69039
69133
|
cwd: farmRuntime.cwd,
|
|
69040
69134
|
now: farmRuntime.now,
|
|
@@ -69050,7 +69144,7 @@ function pickFromPool(decided, params, parsedArgv) {
|
|
|
69050
69144
|
return { identityDecision: { ...decided, name: resolution.identity }, poolExplanation: resolution.explanation };
|
|
69051
69145
|
}
|
|
69052
69146
|
function runLauncher(params) {
|
|
69053
|
-
const { paths, fs:
|
|
69147
|
+
const { paths, fs: fs17, spawn: spawn3, proc, log } = params;
|
|
69054
69148
|
const { env, argv } = proc;
|
|
69055
69149
|
const parsedArgv = parseLauncherArgv(argv);
|
|
69056
69150
|
const cliOverride = buildCliOverride({
|
|
@@ -69065,7 +69159,7 @@ function runLauncher(params) {
|
|
|
69065
69159
|
argv0Identity: parsedArgv.identity,
|
|
69066
69160
|
directoryPinnedIdentity: params.directoryPinnedIdentity,
|
|
69067
69161
|
readActiveIdentityFile: () => {
|
|
69068
|
-
const raw =
|
|
69162
|
+
const raw = fs17.readFileUtf8(paths.activeIdentityFile);
|
|
69069
69163
|
if (raw === void 0) {
|
|
69070
69164
|
return void 0;
|
|
69071
69165
|
}
|
|
@@ -69095,15 +69189,15 @@ function runLauncher(params) {
|
|
|
69095
69189
|
throw error62;
|
|
69096
69190
|
}
|
|
69097
69191
|
for (const diagnostic of recoveryDiagnostics(recovery, farmIdentity)) {
|
|
69098
|
-
log.warn(`
|
|
69192
|
+
log.warn(`agent-shim: ${diagnostic.code}: ${diagnostic.message}`);
|
|
69099
69193
|
}
|
|
69100
69194
|
}
|
|
69101
69195
|
let loadedIdentity;
|
|
69102
69196
|
if (identityDecision.name !== void 0) {
|
|
69103
|
-
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name,
|
|
69197
|
+
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs17);
|
|
69104
69198
|
if (loadedIdentity === void 0) {
|
|
69105
69199
|
log.error(
|
|
69106
|
-
`
|
|
69200
|
+
`agent-shim: no identity named "${identityDecision.name}" (selected via ${identityDecision.source}). Run \`agent-shim identity add ${identityDecision.name}\` first.`
|
|
69107
69201
|
);
|
|
69108
69202
|
proc.exit(1);
|
|
69109
69203
|
}
|
|
@@ -69115,16 +69209,16 @@ function runLauncher(params) {
|
|
|
69115
69209
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
69116
69210
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
69117
69211
|
});
|
|
69118
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true &&
|
|
69212
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs17.readConfigFile(import_node_path34.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
69119
69213
|
log.error(
|
|
69120
|
-
`
|
|
69214
|
+
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
69121
69215
|
);
|
|
69122
69216
|
proc.exit(1);
|
|
69123
69217
|
}
|
|
69124
69218
|
const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
|
|
69125
69219
|
const provider = parsedArgv.provider === false ? void 0 : resolveProvider({
|
|
69126
69220
|
paths,
|
|
69127
|
-
port:
|
|
69221
|
+
port: fs17,
|
|
69128
69222
|
env,
|
|
69129
69223
|
...params.credentials === void 0 ? {} : { credentials: params.credentials },
|
|
69130
69224
|
...parsedArgv.provider === void 0 ? {} : { cliProvider: parsedArgv.provider },
|
|
@@ -69148,7 +69242,7 @@ function runLauncher(params) {
|
|
|
69148
69242
|
if (!(error62 instanceof UsageSnapshotError)) {
|
|
69149
69243
|
throw error62;
|
|
69150
69244
|
}
|
|
69151
|
-
log.warn(`
|
|
69245
|
+
log.warn(`agent-shim: ${error62.message}`);
|
|
69152
69246
|
}
|
|
69153
69247
|
}
|
|
69154
69248
|
const identityCredentialBlock = loadedIdentity?.config.credential;
|
|
@@ -69164,7 +69258,7 @@ function runLauncher(params) {
|
|
|
69164
69258
|
const guardResult = evaluateAmbientCredentialGuard({
|
|
69165
69259
|
env,
|
|
69166
69260
|
allowAmbientCredential: loadedIdentity?.config.allowAmbientCredential ?? false,
|
|
69167
|
-
allowAmbientCredentialOverride: parseEnvBool("
|
|
69261
|
+
allowAmbientCredentialOverride: parseEnvBool("AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL", env.AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL) === true,
|
|
69168
69262
|
identityName: identityDecision.name,
|
|
69169
69263
|
providerSelected: resolvedProvider !== void 0,
|
|
69170
69264
|
...identityCredential === void 0 ? {} : { injectedCredential: { variable: CREDENTIAL_TARGET_VARS[identityCredential.target], token: identityCredential.token } }
|
|
@@ -69174,7 +69268,7 @@ function runLauncher(params) {
|
|
|
69174
69268
|
proc.exit(1);
|
|
69175
69269
|
}
|
|
69176
69270
|
log.info(
|
|
69177
|
-
`
|
|
69271
|
+
`agent-shim: identity ${identityDecision.name ?? "(none)"} (${identityDecision.source}${poolExplanation === void 0 ? "" : `, ${poolExplanation}`}), config profile ${configProfileDecision.name ?? "(none)"} (${configProfileDecision.source})` + (resolvedProvider === void 0 ? "" : `, provider ${resolvedProvider.name} (credential ${resolvedProvider.credential.target} from ${describeSource(resolvedProvider.credential.source)})`) + (identityCredential === void 0 ? "" : `, identity credential ${identityCredential.target} from ${describeSource(identityCredential.source)}`)
|
|
69178
69272
|
);
|
|
69179
69273
|
let cascadeLaunch;
|
|
69180
69274
|
if (farmContext !== void 0) {
|
|
@@ -69207,13 +69301,13 @@ function runLauncher(params) {
|
|
|
69207
69301
|
}
|
|
69208
69302
|
for (const diagnostic of result.diagnostics) {
|
|
69209
69303
|
if (diagnostic.severity === "error") {
|
|
69210
|
-
log.error(`
|
|
69304
|
+
log.error(`agent-shim: ${diagnostic.code}: ${diagnostic.message}`);
|
|
69211
69305
|
} else if (diagnostic.severity === "warning") {
|
|
69212
|
-
log.warn(`
|
|
69306
|
+
log.warn(`agent-shim: ${diagnostic.code}: ${diagnostic.message}`);
|
|
69213
69307
|
}
|
|
69214
69308
|
}
|
|
69215
69309
|
log.info(
|
|
69216
|
-
result.noOp ? `
|
|
69310
|
+
result.noOp ? `agent-shim: farm at ${result.farmRoot} already matches the resolved cascade` : `agent-shim: farm at ${result.farmRoot} resynced (${String(result.manifest.links.length)} link(s), ${String(result.manifest.materialised.length)} built director(ies)${result.adopted.length === 0 ? "" : `, ${String(result.adopted.length)} adopted into ${resyncFarmRuntime.claudeHome}`})`
|
|
69217
69311
|
);
|
|
69218
69312
|
cascadeLaunch = result.resolved.flattened.launch;
|
|
69219
69313
|
} else if (params.farm !== void 0) {
|
|
@@ -69235,7 +69329,7 @@ function runLauncher(params) {
|
|
|
69235
69329
|
const frontDoorPort = params.frontdoor;
|
|
69236
69330
|
const frontDoorEngaged = resolvedProvider !== void 0 || resolvedFlags.headroom || resolvedFlags.trackUsage;
|
|
69237
69331
|
if (frontDoorEngaged && frontDoorPort === void 0) {
|
|
69238
|
-
log.error("
|
|
69332
|
+
log.error("agent-shim: this launch routes through the front-door daemon, but this launcher has no front-door port wired; refusing to launch without it.");
|
|
69239
69333
|
proc.exit(1);
|
|
69240
69334
|
}
|
|
69241
69335
|
const frontDoor = frontDoorEngaged && frontDoorPort !== void 0 ? frontDoorPort.ensure(env.NODE_EXTRA_CA_CERTS) : void 0;
|
|
@@ -69251,12 +69345,12 @@ function runLauncher(params) {
|
|
|
69251
69345
|
if (resolvedFlags.headroom && headroomPort !== void 0) {
|
|
69252
69346
|
headroom = headroomPort.ensure();
|
|
69253
69347
|
const via = resolvedProvider === void 0 ? `OAuth via the door's CONNECT surface on 127.0.0.1:${String(frontDoor?.connectPort ?? 0)}` : `provider ${resolvedProvider.name}`;
|
|
69254
|
-
log.info(`
|
|
69348
|
+
log.info(`agent-shim: routing through the front door on 127.0.0.1:${String(frontDoor?.port ?? 0)} with headroom on 127.0.0.1:${String(headroom.port)} (${via}, project ${headroom.projectId})`);
|
|
69255
69349
|
} else if (resolvedFlags.headroom) {
|
|
69256
|
-
log.error("
|
|
69350
|
+
log.error("agent-shim: headroom routing was requested but this launcher has no headroom port wired; refusing to launch without it.");
|
|
69257
69351
|
proc.exit(1);
|
|
69258
69352
|
} else if (frontDoor !== void 0) {
|
|
69259
|
-
log.info(`
|
|
69353
|
+
log.info(`agent-shim: routing through the front door on 127.0.0.1:${String(frontDoor.port)}${resolvedProvider === void 0 ? ` (OAuth via the door's CONNECT surface on 127.0.0.1:${String(frontDoor.connectPort)}, usage recorded)` : ` (provider ${resolvedProvider.name})`}`);
|
|
69260
69354
|
}
|
|
69261
69355
|
const frontDoorRelease = frontDoor === void 0 ? void 0 : frontDoorPort?.release;
|
|
69262
69356
|
const finalArgv = buildArgv({
|
|
@@ -69407,7 +69501,8 @@ async function runClaude(argvOverride) {
|
|
|
69407
69501
|
|
|
69408
69502
|
// src/cli.ts
|
|
69409
69503
|
async function main() {
|
|
69410
|
-
|
|
69504
|
+
aliasLegacyEnv(process.env);
|
|
69505
|
+
const invokedName = import_node_path35.default.basename(process.argv[1] ?? "agent-shim");
|
|
69411
69506
|
if (isInvokedAsClaude(invokedName)) {
|
|
69412
69507
|
await runClaude();
|
|
69413
69508
|
return;
|