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