agent-shim 11.81.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 +3686 -1827
- package/dist/index.cjs +1489 -871
- package/dist/index.mjs +1475 -858
- package/dist/types/index.d.ts +170 -99
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1106,7 +1106,7 @@ var init_schema = __esm({
|
|
|
1106
1106
|
resumeOnLimit: z3.boolean().optional(),
|
|
1107
1107
|
/** Whether a supervised session's context is compacted before its identity's quota is spent, so the resume on the next member writes a small context instead of a large one. Needs `resumeOnLimit`. Absent means false. */
|
|
1108
1108
|
compactBeforeLimit: z3.boolean().optional(),
|
|
1109
|
-
/** The share of a quota window, in whole percent, at which sessions are compacted. Absent means the launcher decides from what compacting every session on the member would cost against what its
|
|
1109
|
+
/** The share of a quota window, in whole percent, at which sessions are compacted. Absent means the launcher decides from what compacting every session on the member would cost against what its tightest quota window has left. Needs `compactBeforeLimit`. */
|
|
1110
1110
|
compactAtUtilisation: CompactAtUtilisationSchema.optional()
|
|
1111
1111
|
}).refine((pool) => pool.compactBeforeLimit !== true || pool.resumeOnLimit === true, { message: "compactBeforeLimit needs resumeOnLimit, since a session that is not moved has no cold cache to avoid", path: ["compactBeforeLimit"] }).refine((pool) => pool.compactAtUtilisation === void 0 || pool.compactBeforeLimit === true, { message: "compactAtUtilisation needs compactBeforeLimit", path: ["compactAtUtilisation"] });
|
|
1112
1112
|
WEEKDAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
|
|
@@ -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);
|
|
@@ -1709,6 +1730,24 @@ function evaluateWhen(when, context) {
|
|
|
1709
1730
|
}
|
|
1710
1731
|
return { status: "definite", passed: failed.length === 0, checked, failed };
|
|
1711
1732
|
}
|
|
1733
|
+
function referencesFact(when, key) {
|
|
1734
|
+
if (when === void 0 || !("kind" in when)) {
|
|
1735
|
+
return false;
|
|
1736
|
+
}
|
|
1737
|
+
const walk2 = (node) => {
|
|
1738
|
+
if (Array.isArray(node)) {
|
|
1739
|
+
return node.some(walk2);
|
|
1740
|
+
}
|
|
1741
|
+
if (typeof node !== "object" || node === null) {
|
|
1742
|
+
return false;
|
|
1743
|
+
}
|
|
1744
|
+
if ("kind" in node && node.kind === "reference" && "key" in node && node.key === key) {
|
|
1745
|
+
return true;
|
|
1746
|
+
}
|
|
1747
|
+
return Object.values(node).some(walk2);
|
|
1748
|
+
};
|
|
1749
|
+
return walk2(when);
|
|
1750
|
+
}
|
|
1712
1751
|
function isVacuousWhen(when) {
|
|
1713
1752
|
return when !== void 0 && !("kind" in when) && Object.keys(when).length === 0;
|
|
1714
1753
|
}
|
|
@@ -2903,6 +2942,14 @@ function acquireIdentityLock(params) {
|
|
|
2903
2942
|
return {
|
|
2904
2943
|
path: lockPath,
|
|
2905
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
|
+
},
|
|
2906
2953
|
release: () => {
|
|
2907
2954
|
const current = parseLockRecord(params.fs.readFileUtf8(lockPath));
|
|
2908
2955
|
if (current !== void 0 && current.token !== token) {
|
|
@@ -2912,7 +2959,19 @@ function acquireIdentityLock(params) {
|
|
|
2912
2959
|
}
|
|
2913
2960
|
};
|
|
2914
2961
|
}
|
|
2915
|
-
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
|
+
}
|
|
2916
2975
|
if (existing === void 0) {
|
|
2917
2976
|
params.fs.removeRecursive(lockPath);
|
|
2918
2977
|
continue;
|
|
@@ -2927,7 +2986,7 @@ function acquireIdentityLock(params) {
|
|
|
2927
2986
|
}
|
|
2928
2987
|
throw new IdentityLockBusyError(params.identity, lockPath, lastHolderPid);
|
|
2929
2988
|
}
|
|
2930
|
-
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;
|
|
2931
2990
|
var init_lock = __esm({
|
|
2932
2991
|
"src/launcher/lock.ts"() {
|
|
2933
2992
|
"use strict";
|
|
@@ -2935,6 +2994,14 @@ var init_lock = __esm({
|
|
|
2935
2994
|
DEFAULT_STALE_AFTER_MS = 12e4;
|
|
2936
2995
|
DEFAULT_RETRY_DELAY_MS = 50;
|
|
2937
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
|
+
};
|
|
2938
3005
|
IdentityLockBusyError = class extends CliError {
|
|
2939
3006
|
constructor(identity, lockPath, holderPid) {
|
|
2940
3007
|
super(
|
|
@@ -2955,8 +3022,8 @@ var init_lock = __esm({
|
|
|
2955
3022
|
// src/launcher/farm.ts
|
|
2956
3023
|
import path8 from "node:path";
|
|
2957
3024
|
import { z as z4 } from "zod";
|
|
2958
|
-
function readFarmManifest(
|
|
2959
|
-
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));
|
|
2960
3027
|
if (raw === void 0) {
|
|
2961
3028
|
return void 0;
|
|
2962
3029
|
}
|
|
@@ -3014,9 +3081,9 @@ function buildEntryFacts(params) {
|
|
|
3014
3081
|
entries
|
|
3015
3082
|
};
|
|
3016
3083
|
}
|
|
3017
|
-
function listSubtree(
|
|
3084
|
+
function listSubtree(fs15, root, rel) {
|
|
3018
3085
|
const absolute = path8.join(root, rel);
|
|
3019
|
-
const stat =
|
|
3086
|
+
const stat = fs15.lstat(absolute);
|
|
3020
3087
|
if (stat === void 0) {
|
|
3021
3088
|
return [];
|
|
3022
3089
|
}
|
|
@@ -3024,10 +3091,10 @@ function listSubtree(fs14, root, rel) {
|
|
|
3024
3091
|
return [{ rel, kind: "symlink" }];
|
|
3025
3092
|
}
|
|
3026
3093
|
if (stat.kind === "dir") {
|
|
3027
|
-
const children = [...
|
|
3094
|
+
const children = [...fs15.readdir(absolute)].sort().flatMap((name) => listSubtree(fs15, root, `${rel}/${name}`));
|
|
3028
3095
|
return [{ rel, kind: "dir" }, ...children];
|
|
3029
3096
|
}
|
|
3030
|
-
const contentHash =
|
|
3097
|
+
const contentHash = fs15.hashFile(absolute);
|
|
3031
3098
|
return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
|
|
3032
3099
|
}
|
|
3033
3100
|
function topLevelScopeRoots(roots) {
|
|
@@ -3041,25 +3108,25 @@ function topLevelScopeRoots(roots) {
|
|
|
3041
3108
|
}
|
|
3042
3109
|
return kept;
|
|
3043
3110
|
}
|
|
3044
|
-
function reconciliationScope(
|
|
3111
|
+
function reconciliationScope(fs15, farmRoot, manifest) {
|
|
3045
3112
|
if (manifest !== void 0) {
|
|
3046
3113
|
return topLevelScopeRoots(manifest.materialised);
|
|
3047
3114
|
}
|
|
3048
|
-
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();
|
|
3049
3116
|
}
|
|
3050
|
-
function collectFarmListing(
|
|
3051
|
-
return scopeRoots.flatMap((root) => listSubtree(
|
|
3117
|
+
function collectFarmListing(fs15, farmRoot, scopeRoots) {
|
|
3118
|
+
return scopeRoots.flatMap((root) => listSubtree(fs15, farmRoot, root));
|
|
3052
3119
|
}
|
|
3053
|
-
function collectCanonicalCounterparts(
|
|
3120
|
+
function collectCanonicalCounterparts(fs15, claudeHome, farmListing) {
|
|
3054
3121
|
const out = [];
|
|
3055
3122
|
for (const entry of farmListing) {
|
|
3056
3123
|
const absolute = path8.join(claudeHome, entry.rel);
|
|
3057
|
-
const stat =
|
|
3124
|
+
const stat = fs15.lstat(absolute);
|
|
3058
3125
|
if (stat === void 0) {
|
|
3059
3126
|
continue;
|
|
3060
3127
|
}
|
|
3061
3128
|
if (stat.kind === "file") {
|
|
3062
|
-
const contentHash =
|
|
3129
|
+
const contentHash = fs15.hashFile(absolute);
|
|
3063
3130
|
out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
|
|
3064
3131
|
continue;
|
|
3065
3132
|
}
|
|
@@ -3301,6 +3368,9 @@ function resyncFarm(params) {
|
|
|
3301
3368
|
farmRoot,
|
|
3302
3369
|
classification: params.classification
|
|
3303
3370
|
});
|
|
3371
|
+
if (params.identityExists?.() === false) {
|
|
3372
|
+
throw new IdentityGoneError(params.identity);
|
|
3373
|
+
}
|
|
3304
3374
|
const previousManifest = readFarmManifest(params.fs, farmRoot);
|
|
3305
3375
|
const scope = reconciliationScope(params.fs, farmRoot, previousManifest);
|
|
3306
3376
|
const farmListing = collectFarmListing(params.fs, farmRoot, scope);
|
|
@@ -3416,13 +3486,14 @@ function recoveryDiagnostics(recovery, identity) {
|
|
|
3416
3486
|
}
|
|
3417
3487
|
];
|
|
3418
3488
|
}
|
|
3419
|
-
var FARM_MANIFEST_FILENAME, FarmManifestSchema;
|
|
3489
|
+
var FARM_MANIFEST_FILENAME, FarmManifestSchema, IdentityGoneError;
|
|
3420
3490
|
var init_farm = __esm({
|
|
3421
3491
|
"src/launcher/farm.ts"() {
|
|
3422
3492
|
"use strict";
|
|
3423
3493
|
init_classify();
|
|
3424
3494
|
init_reconcile();
|
|
3425
3495
|
init_pipeline();
|
|
3496
|
+
init_cliError();
|
|
3426
3497
|
init_legacy();
|
|
3427
3498
|
init_lock();
|
|
3428
3499
|
FARM_MANIFEST_FILENAME = ".agent-shim-farm.json";
|
|
@@ -3436,6 +3507,14 @@ var init_farm = __esm({
|
|
|
3436
3507
|
materialised: z4.array(z4.string()),
|
|
3437
3508
|
links: z4.array(z4.strictObject({ rel: z4.string(), target: z4.string() }))
|
|
3438
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
|
+
};
|
|
3439
3518
|
}
|
|
3440
3519
|
});
|
|
3441
3520
|
|
|
@@ -3830,10 +3909,10 @@ var init_route = __esm({
|
|
|
3830
3909
|
// src/frontdoor/state.ts
|
|
3831
3910
|
import path9 from "node:path";
|
|
3832
3911
|
import { z as z5 } from "zod";
|
|
3833
|
-
function readFrontDoorState(
|
|
3912
|
+
function readFrontDoorState(fs15, stateFile) {
|
|
3834
3913
|
let raw;
|
|
3835
3914
|
try {
|
|
3836
|
-
raw =
|
|
3915
|
+
raw = fs15.readFileUtf8(stateFile);
|
|
3837
3916
|
} catch {
|
|
3838
3917
|
return void 0;
|
|
3839
3918
|
}
|
|
@@ -3847,9 +3926,9 @@ function readFrontDoorState(fs14, stateFile) {
|
|
|
3847
3926
|
return void 0;
|
|
3848
3927
|
}
|
|
3849
3928
|
}
|
|
3850
|
-
function writeFrontDoorState(
|
|
3851
|
-
|
|
3852
|
-
|
|
3929
|
+
function writeFrontDoorState(fs15, stateFile, state) {
|
|
3930
|
+
fs15.mkdirp(path9.dirname(stateFile));
|
|
3931
|
+
fs15.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
3853
3932
|
`);
|
|
3854
3933
|
}
|
|
3855
3934
|
function directOrigin(port) {
|
|
@@ -3859,37 +3938,37 @@ function frontDoorOrigin(state) {
|
|
|
3859
3938
|
const port = state?.directPort ?? state?.lastDirectPort;
|
|
3860
3939
|
return port === void 0 ? void 0 : directOrigin(port);
|
|
3861
3940
|
}
|
|
3862
|
-
function writeFrontDoorDirectRecord(
|
|
3863
|
-
|
|
3864
|
-
|
|
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 })}
|
|
3865
3944
|
`);
|
|
3866
3945
|
}
|
|
3867
|
-
function removeFrontDoorDirectRecord(
|
|
3868
|
-
|
|
3946
|
+
function removeFrontDoorDirectRecord(fs15, recordsDir, pid) {
|
|
3947
|
+
fs15.removeRecursive(path9.join(recordsDir, `${String(pid)}.json`));
|
|
3869
3948
|
}
|
|
3870
|
-
function markFrontDoorDraining(
|
|
3871
|
-
|
|
3872
|
-
|
|
3949
|
+
function markFrontDoorDraining(fs15, markersDir, pid) {
|
|
3950
|
+
fs15.mkdirp(markersDir);
|
|
3951
|
+
fs15.writeFilePrivate(path9.join(markersDir, String(pid)), "\n");
|
|
3873
3952
|
}
|
|
3874
|
-
function unmarkFrontDoorDraining(
|
|
3875
|
-
|
|
3953
|
+
function unmarkFrontDoorDraining(fs15, markersDir, pid) {
|
|
3954
|
+
fs15.removeRecursive(path9.join(markersDir, String(pid)));
|
|
3876
3955
|
}
|
|
3877
|
-
function listDrainingFrontDoors(
|
|
3878
|
-
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);
|
|
3879
3958
|
}
|
|
3880
3959
|
function recordPid(file) {
|
|
3881
3960
|
const pidText = /^([1-9]\d*)\.json$/.exec(file)?.[1];
|
|
3882
3961
|
const pid = pidText === void 0 ? void 0 : Number(pidText);
|
|
3883
3962
|
return pid !== void 0 && Number.isSafeInteger(pid) ? pid : void 0;
|
|
3884
3963
|
}
|
|
3885
|
-
function readDirectRecordEntry(
|
|
3964
|
+
function readDirectRecordEntry(fs15, recordsDir, file) {
|
|
3886
3965
|
const pid = recordPid(file);
|
|
3887
3966
|
if (pid === void 0) {
|
|
3888
3967
|
return void 0;
|
|
3889
3968
|
}
|
|
3890
3969
|
let raw;
|
|
3891
3970
|
try {
|
|
3892
|
-
raw =
|
|
3971
|
+
raw = fs15.readFileUtf8(path9.join(recordsDir, file));
|
|
3893
3972
|
} catch {
|
|
3894
3973
|
return void 0;
|
|
3895
3974
|
}
|
|
@@ -3903,37 +3982,37 @@ function readDirectRecordEntry(fs14, recordsDir, file) {
|
|
|
3903
3982
|
return { malformed: true };
|
|
3904
3983
|
}
|
|
3905
3984
|
}
|
|
3906
|
-
function listFrontDoorDirectRecords(
|
|
3907
|
-
return
|
|
3908
|
-
const entry = readDirectRecordEntry(
|
|
3985
|
+
function listFrontDoorDirectRecords(fs15, recordsDir) {
|
|
3986
|
+
return fs15.readdir(recordsDir).flatMap((file) => {
|
|
3987
|
+
const entry = readDirectRecordEntry(fs15, recordsDir, file);
|
|
3909
3988
|
return entry?.record === void 0 ? [] : [entry.record];
|
|
3910
3989
|
}).sort((a, b) => a.pid - b.pid);
|
|
3911
3990
|
}
|
|
3912
|
-
function pruneMalformedFrontDoorDirectFiles(
|
|
3913
|
-
for (const file of
|
|
3991
|
+
function pruneMalformedFrontDoorDirectFiles(fs15, recordsDir, isRunning) {
|
|
3992
|
+
for (const file of fs15.readdir(recordsDir)) {
|
|
3914
3993
|
const writer = RECORD_TEMPORARY_FILE.exec(file)?.[1];
|
|
3915
3994
|
const stale = writer !== void 0 && !isRunning(Number(writer));
|
|
3916
|
-
if (stale || readDirectRecordEntry(
|
|
3917
|
-
|
|
3995
|
+
if (stale || readDirectRecordEntry(fs15, recordsDir, file)?.malformed === true) {
|
|
3996
|
+
fs15.removeRecursive(path9.join(recordsDir, file));
|
|
3918
3997
|
}
|
|
3919
3998
|
}
|
|
3920
3999
|
}
|
|
3921
4000
|
function liveFrontDoorDirectRecords(records, liveness) {
|
|
3922
4001
|
return records.filter((record) => liveness.doors.has(record.pid) || liveness.unknown.has(record.pid));
|
|
3923
4002
|
}
|
|
3924
|
-
function pruneDeadFrontDoorDirectRecords(
|
|
4003
|
+
function pruneDeadFrontDoorDirectRecords(fs15, recordsDir, records, liveness) {
|
|
3925
4004
|
for (const record of records) {
|
|
3926
4005
|
if (!liveness.doors.has(record.pid) && !liveness.unknown.has(record.pid)) {
|
|
3927
|
-
removeFrontDoorDirectRecord(
|
|
4006
|
+
removeFrontDoorDirectRecord(fs15, recordsDir, record.pid);
|
|
3928
4007
|
}
|
|
3929
4008
|
}
|
|
3930
4009
|
}
|
|
3931
4010
|
function recordOf(details) {
|
|
3932
4011
|
return details === void 0 ? {} : { sessionId: details.sessionId, ...details.models === void 0 ? {} : { models: details.models } };
|
|
3933
4012
|
}
|
|
3934
|
-
function writeFrontDoorSession(
|
|
3935
|
-
|
|
3936
|
-
|
|
4013
|
+
function writeFrontDoorSession(fs15, sessionsDir, session) {
|
|
4014
|
+
fs15.mkdirPrivate(sessionsDir);
|
|
4015
|
+
fs15.writeFilePrivate(path9.join(sessionsDir, sessionRecordName(session.pid)), `${JSON.stringify(session, null, 2)}
|
|
3937
4016
|
`);
|
|
3938
4017
|
}
|
|
3939
4018
|
function sessionRecordName(pid) {
|
|
@@ -3945,32 +4024,32 @@ function isSessionRecordName(name) {
|
|
|
3945
4024
|
function summaryOf(session) {
|
|
3946
4025
|
return { pid: session.pid, startedAt: session.startedAt, ...session.supervisorPid === void 0 ? {} : { supervisorPid: session.supervisorPid } };
|
|
3947
4026
|
}
|
|
3948
|
-
function readFrontDoorSessionRecord(
|
|
4027
|
+
function readFrontDoorSessionRecord(fs15, sessionsDir, name) {
|
|
3949
4028
|
try {
|
|
3950
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(
|
|
4029
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs15.readFileUtf8(path9.join(sessionsDir, name)) ?? ""));
|
|
3951
4030
|
return parsed.success ? parsed.data : void 0;
|
|
3952
4031
|
} catch {
|
|
3953
4032
|
return void 0;
|
|
3954
4033
|
}
|
|
3955
4034
|
}
|
|
3956
|
-
function listFrontDoorSessions(
|
|
4035
|
+
function listFrontDoorSessions(fs15, sessionsDir) {
|
|
3957
4036
|
const sessions = [];
|
|
3958
|
-
for (const name of
|
|
3959
|
-
const record = isSessionRecordName(name) ? readFrontDoorSessionRecord(
|
|
4037
|
+
for (const name of fs15.readdir(sessionsDir)) {
|
|
4038
|
+
const record = isSessionRecordName(name) ? readFrontDoorSessionRecord(fs15, sessionsDir, name) : void 0;
|
|
3960
4039
|
if (record !== void 0) {
|
|
3961
4040
|
sessions.push(summaryOf(record));
|
|
3962
4041
|
}
|
|
3963
4042
|
}
|
|
3964
4043
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
3965
4044
|
}
|
|
3966
|
-
function removeFrontDoorSession(
|
|
3967
|
-
|
|
4045
|
+
function removeFrontDoorSession(fs15, sessionsDir, pid) {
|
|
4046
|
+
fs15.removeRecursive(path9.join(sessionsDir, sessionRecordName(pid)));
|
|
3968
4047
|
}
|
|
3969
|
-
function pruneDeadFrontDoorSessions(
|
|
4048
|
+
function pruneDeadFrontDoorSessions(fs15, sessionsDir, listed, isRunning) {
|
|
3970
4049
|
const removed = [];
|
|
3971
4050
|
for (const session of listed) {
|
|
3972
4051
|
if (!isRunning(session.pid)) {
|
|
3973
|
-
removeFrontDoorSession(
|
|
4052
|
+
removeFrontDoorSession(fs15, sessionsDir, session.pid);
|
|
3974
4053
|
removed.push(session.pid);
|
|
3975
4054
|
}
|
|
3976
4055
|
}
|
|
@@ -4068,9 +4147,9 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
4068
4147
|
}
|
|
4069
4148
|
}
|
|
4070
4149
|
async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
4071
|
-
const { fs:
|
|
4150
|
+
const { fs: fs15, paths } = ports;
|
|
4072
4151
|
const servingBinary = ports.statOwnExecutable();
|
|
4073
|
-
const previous = readFrontDoorState(
|
|
4152
|
+
const previous = readFrontDoorState(fs15, paths.frontdoorStateFile);
|
|
4074
4153
|
let lastPort = previous?.lastPort;
|
|
4075
4154
|
let lastConnectPort = previous?.lastConnectPort;
|
|
4076
4155
|
let lastDirectPort = previous?.lastDirectPort;
|
|
@@ -4084,14 +4163,14 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4084
4163
|
const fail = (message) => {
|
|
4085
4164
|
ports.closeRcStreamHub();
|
|
4086
4165
|
if (predecessor === void 0) {
|
|
4087
|
-
writeFrontDoorState(
|
|
4088
|
-
|
|
4166
|
+
writeFrontDoorState(fs15, paths.frontdoorStateFile, { lastError: message, ...sticky() });
|
|
4167
|
+
fs15.removeRecursive(paths.frontdoorLockFile);
|
|
4089
4168
|
}
|
|
4090
4169
|
ports.log(`agent-shim frontdoor supervisor: ${message}`);
|
|
4091
4170
|
return 1;
|
|
4092
4171
|
};
|
|
4093
4172
|
if (predecessor === void 0) {
|
|
4094
|
-
writeFrontDoorState(
|
|
4173
|
+
writeFrontDoorState(fs15, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
|
|
4095
4174
|
}
|
|
4096
4175
|
const previousSticky = lastPort;
|
|
4097
4176
|
let http3;
|
|
@@ -4132,11 +4211,11 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4132
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)`);
|
|
4133
4212
|
}
|
|
4134
4213
|
lastDirectPort = direct.port;
|
|
4135
|
-
writeFrontDoorDirectRecord(
|
|
4136
|
-
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() });
|
|
4137
4216
|
ports.doorHealth.generation({ providerPort: http3.port, connectPort: connect3.port, directPort: direct.port });
|
|
4138
4217
|
if (predecessor === void 0) {
|
|
4139
|
-
|
|
4218
|
+
fs15.removeRecursive(paths.frontdoorLockFile);
|
|
4140
4219
|
} else {
|
|
4141
4220
|
predecessor.serving();
|
|
4142
4221
|
}
|
|
@@ -4145,7 +4224,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4145
4224
|
let idleSince;
|
|
4146
4225
|
let ticks = 0;
|
|
4147
4226
|
const supersedingOwner = async () => {
|
|
4148
|
-
const owner = readFrontDoorState(
|
|
4227
|
+
const owner = readFrontDoorState(fs15, paths.frontdoorStateFile)?.supervisorPid;
|
|
4149
4228
|
return owner !== void 0 && owner !== ports.ownPid && (await ports.runningAmong([owner])).has(owner) ? owner : void 0;
|
|
4150
4229
|
};
|
|
4151
4230
|
let supersededBy;
|
|
@@ -4174,13 +4253,13 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4174
4253
|
ports.stopBackgroundWork?.();
|
|
4175
4254
|
const drained = [direct.drain(), connect3.drain(), http3.drain()];
|
|
4176
4255
|
if (await supersedingOwner() === void 0) {
|
|
4177
|
-
writeFrontDoorState(
|
|
4256
|
+
writeFrontDoorState(fs15, paths.frontdoorStateFile, sticky());
|
|
4178
4257
|
}
|
|
4179
|
-
markFrontDoorDraining(
|
|
4258
|
+
markFrontDoorDraining(fs15, paths.frontdoorDrainingDir, ports.ownPid);
|
|
4180
4259
|
ports.closeRcStreamHub();
|
|
4181
4260
|
await Promise.all(drained);
|
|
4182
|
-
unmarkFrontDoorDraining(
|
|
4183
|
-
removeFrontDoorDirectRecord(
|
|
4261
|
+
unmarkFrontDoorDraining(fs15, paths.frontdoorDrainingDir, ports.ownPid);
|
|
4262
|
+
removeFrontDoorDirectRecord(fs15, paths.frontdoorDirectRecordsDir, ports.ownPid);
|
|
4184
4263
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: the connections this door carried have ended; exiting`);
|
|
4185
4264
|
return 0;
|
|
4186
4265
|
};
|
|
@@ -4201,12 +4280,12 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4201
4280
|
await connect3.close();
|
|
4202
4281
|
await http3.close();
|
|
4203
4282
|
ports.closeRcStreamHub();
|
|
4204
|
-
removeFrontDoorDirectRecord(
|
|
4283
|
+
removeFrontDoorDirectRecord(fs15, paths.frontdoorDirectRecordsDir, ports.ownPid);
|
|
4205
4284
|
};
|
|
4206
4285
|
const shutdown = async () => {
|
|
4207
4286
|
await closeServing();
|
|
4208
4287
|
if (await supersedingOwner() === void 0) {
|
|
4209
|
-
writeFrontDoorState(
|
|
4288
|
+
writeFrontDoorState(fs15, paths.frontdoorStateFile, sticky());
|
|
4210
4289
|
}
|
|
4211
4290
|
return 0;
|
|
4212
4291
|
};
|
|
@@ -4225,7 +4304,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4225
4304
|
ticks += 1;
|
|
4226
4305
|
const listed = ports.registry.rescan();
|
|
4227
4306
|
const running = await ports.runningAmong(listed.map((session) => session.pid));
|
|
4228
|
-
const pruned = pruneDeadFrontDoorSessions(
|
|
4307
|
+
const pruned = pruneDeadFrontDoorSessions(fs15, paths.frontdoorSessionsDir, listed, (pid) => running.has(pid));
|
|
4229
4308
|
ports.registry.forget(pruned);
|
|
4230
4309
|
ports.observeLaunchRegistry(listed, pruned);
|
|
4231
4310
|
ports.checkQuotaExpiry();
|
|
@@ -4300,8 +4379,8 @@ function parseConnectTarget(authority) {
|
|
|
4300
4379
|
function isInterceptedHost(host, interceptHosts) {
|
|
4301
4380
|
return interceptHosts.includes(host);
|
|
4302
4381
|
}
|
|
4303
|
-
function servedByPipeline(
|
|
4304
|
-
return
|
|
4382
|
+
function servedByPipeline(path45) {
|
|
4383
|
+
return path45?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
4305
4384
|
}
|
|
4306
4385
|
function forwardableHeaders(headers) {
|
|
4307
4386
|
const connectionTokens = new Set(
|
|
@@ -4745,7 +4824,7 @@ var init_package = __esm({
|
|
|
4745
4824
|
"package.json"() {
|
|
4746
4825
|
package_default = {
|
|
4747
4826
|
name: "agent-shim",
|
|
4748
|
-
version: "11.
|
|
4827
|
+
version: "11.83.0",
|
|
4749
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.",
|
|
4750
4829
|
license: "MIT",
|
|
4751
4830
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -4971,43 +5050,43 @@ function parseJson(raw, schema) {
|
|
|
4971
5050
|
const parsed = schema.safeParse(JSON.parse(raw));
|
|
4972
5051
|
return parsed.success ? parsed.data : void 0;
|
|
4973
5052
|
}
|
|
4974
|
-
function readHeadroomState(
|
|
5053
|
+
function readHeadroomState(fs15, stateFile) {
|
|
4975
5054
|
try {
|
|
4976
|
-
return parseJson(
|
|
5055
|
+
return parseJson(fs15.readFileUtf8(stateFile), HeadroomStateSchema);
|
|
4977
5056
|
} catch {
|
|
4978
5057
|
return void 0;
|
|
4979
5058
|
}
|
|
4980
5059
|
}
|
|
4981
|
-
function writeHeadroomState(
|
|
4982
|
-
|
|
4983
|
-
|
|
5060
|
+
function writeHeadroomState(fs15, stateFile, state) {
|
|
5061
|
+
fs15.mkdirp(path12.dirname(stateFile));
|
|
5062
|
+
fs15.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
4984
5063
|
`);
|
|
4985
5064
|
}
|
|
4986
|
-
function resolveServingHeadroomState(
|
|
4987
|
-
const current = readHeadroomState(
|
|
5065
|
+
function resolveServingHeadroomState(fs15, files, isRunning) {
|
|
5066
|
+
const current = readHeadroomState(fs15, files.stateFile);
|
|
4988
5067
|
if (current !== void 0) {
|
|
4989
5068
|
return { path: files.stateFile, state: current };
|
|
4990
5069
|
}
|
|
4991
|
-
const legacy = readHeadroomState(
|
|
5070
|
+
const legacy = readHeadroomState(fs15, files.legacyStateFile);
|
|
4992
5071
|
if (legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid)) {
|
|
4993
5072
|
return { path: files.legacyStateFile, state: legacy };
|
|
4994
5073
|
}
|
|
4995
5074
|
return void 0;
|
|
4996
5075
|
}
|
|
4997
|
-
function migrateHeadroomState(
|
|
4998
|
-
const legacy = readHeadroomState(
|
|
5076
|
+
function migrateHeadroomState(fs15, files, isRunning) {
|
|
5077
|
+
const legacy = readHeadroomState(fs15, files.legacyStateFile);
|
|
4999
5078
|
const legacyLive = legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid);
|
|
5000
|
-
const current = readHeadroomState(
|
|
5079
|
+
const current = readHeadroomState(fs15, files.stateFile);
|
|
5001
5080
|
if (current !== void 0 || legacyLive) {
|
|
5002
|
-
if (!legacyLive &&
|
|
5003
|
-
|
|
5081
|
+
if (!legacyLive && fs15.readFileUtf8(files.legacyStateFile) !== void 0) {
|
|
5082
|
+
fs15.removeRecursive(files.legacyStateFile);
|
|
5004
5083
|
}
|
|
5005
5084
|
return;
|
|
5006
5085
|
}
|
|
5007
5086
|
if (legacy !== void 0) {
|
|
5008
|
-
writeHeadroomState(
|
|
5087
|
+
writeHeadroomState(fs15, files.stateFile, legacy);
|
|
5009
5088
|
}
|
|
5010
|
-
|
|
5089
|
+
fs15.removeRecursive(files.legacyStateFile);
|
|
5011
5090
|
}
|
|
5012
5091
|
function hashAllowlist(allowlist) {
|
|
5013
5092
|
return createHash3("sha256").update(allowlist.join("\n")).digest("hex");
|
|
@@ -5040,27 +5119,27 @@ function isAdmissibleUrl(entry) {
|
|
|
5040
5119
|
function parseAllowlistFile(content) {
|
|
5041
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)));
|
|
5042
5121
|
}
|
|
5043
|
-
function writeAllowlistFile(
|
|
5044
|
-
|
|
5045
|
-
|
|
5122
|
+
function writeAllowlistFile(fs15, allowlistFile, allowlist) {
|
|
5123
|
+
fs15.mkdirPrivate(path12.dirname(allowlistFile));
|
|
5124
|
+
fs15.writeFilePrivate(allowlistFile, formatAllowlistFile(allowlist));
|
|
5046
5125
|
}
|
|
5047
|
-
function pruneStaleAllowlistTemporaries(
|
|
5126
|
+
function pruneStaleAllowlistTemporaries(fs15, allowlistFile, isRunning) {
|
|
5048
5127
|
const prefix = `${path12.basename(allowlistFile)}.`;
|
|
5049
|
-
for (const name of
|
|
5128
|
+
for (const name of fs15.readdir(path12.dirname(allowlistFile))) {
|
|
5050
5129
|
const writer = name.startsWith(prefix) ? /^([1-9]\d*)\.tmp$/.exec(name.slice(prefix.length))?.[1] : void 0;
|
|
5051
5130
|
if (writer !== void 0 && !isRunning(Number(writer))) {
|
|
5052
|
-
|
|
5131
|
+
fs15.removeRecursive(path12.join(path12.dirname(allowlistFile), name));
|
|
5053
5132
|
}
|
|
5054
5133
|
}
|
|
5055
5134
|
}
|
|
5056
|
-
function readAllProviders(
|
|
5135
|
+
function readAllProviders(fs15, providersDir) {
|
|
5057
5136
|
const result = [];
|
|
5058
|
-
for (const name of
|
|
5137
|
+
for (const name of fs15.readdir(providersDir)) {
|
|
5059
5138
|
if (!name.endsWith(".json")) {
|
|
5060
5139
|
continue;
|
|
5061
5140
|
}
|
|
5062
5141
|
try {
|
|
5063
|
-
const parsed = parseJson(
|
|
5142
|
+
const parsed = parseJson(fs15.readFileUtf8(path12.join(providersDir, name)), ProviderSchema);
|
|
5064
5143
|
if (parsed !== void 0) {
|
|
5065
5144
|
result.push({ name: name.slice(0, -".json".length), provider: parsed });
|
|
5066
5145
|
}
|
|
@@ -5070,22 +5149,22 @@ function readAllProviders(fs14, providersDir) {
|
|
|
5070
5149
|
}
|
|
5071
5150
|
return result;
|
|
5072
5151
|
}
|
|
5073
|
-
function writeSession(
|
|
5074
|
-
|
|
5075
|
-
|
|
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)}
|
|
5076
5155
|
`);
|
|
5077
5156
|
}
|
|
5078
|
-
function removeSession(
|
|
5079
|
-
|
|
5157
|
+
function removeSession(fs15, sessionsDir, pid) {
|
|
5158
|
+
fs15.removeRecursive(path12.join(sessionsDir, `${String(pid)}.json`));
|
|
5080
5159
|
}
|
|
5081
|
-
function listSessions(
|
|
5160
|
+
function listSessions(fs15, sessionsDir) {
|
|
5082
5161
|
const sessions = [];
|
|
5083
|
-
for (const name of
|
|
5162
|
+
for (const name of fs15.readdir(sessionsDir)) {
|
|
5084
5163
|
if (!name.endsWith(".json")) {
|
|
5085
5164
|
continue;
|
|
5086
5165
|
}
|
|
5087
5166
|
try {
|
|
5088
|
-
const parsed = parseJson(
|
|
5167
|
+
const parsed = parseJson(fs15.readFileUtf8(path12.join(sessionsDir, name)), HeadroomSessionSchema);
|
|
5089
5168
|
if (parsed !== void 0) {
|
|
5090
5169
|
sessions.push(parsed);
|
|
5091
5170
|
}
|
|
@@ -5095,22 +5174,22 @@ function listSessions(fs14, sessionsDir) {
|
|
|
5095
5174
|
}
|
|
5096
5175
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
5097
5176
|
}
|
|
5098
|
-
function sessionsForSupervisor(
|
|
5099
|
-
return listSessions(
|
|
5177
|
+
function sessionsForSupervisor(fs15, sessionsDir, supervisorPid) {
|
|
5178
|
+
return listSessions(fs15, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
|
|
5100
5179
|
}
|
|
5101
|
-
function pruneDeadSessions(
|
|
5180
|
+
function pruneDeadSessions(fs15, sessionsDir, isRunning) {
|
|
5102
5181
|
const removed = [];
|
|
5103
|
-
for (const session of listSessions(
|
|
5182
|
+
for (const session of listSessions(fs15, sessionsDir)) {
|
|
5104
5183
|
if (!isRunning(session.pid)) {
|
|
5105
|
-
removeSession(
|
|
5184
|
+
removeSession(fs15, sessionsDir, session.pid);
|
|
5106
5185
|
removed.push(session.pid);
|
|
5107
5186
|
}
|
|
5108
5187
|
}
|
|
5109
5188
|
return removed;
|
|
5110
5189
|
}
|
|
5111
|
-
function readStartLock(
|
|
5190
|
+
function readStartLock(fs15, lockFile) {
|
|
5112
5191
|
try {
|
|
5113
|
-
return parseJson(
|
|
5192
|
+
return parseJson(fs15.readFileUtf8(lockFile), HeadroomLockSchema);
|
|
5114
5193
|
} catch {
|
|
5115
5194
|
return void 0;
|
|
5116
5195
|
}
|
|
@@ -5200,12 +5279,12 @@ function earlierReleaseAllowlistHash(providers, doorOrigin) {
|
|
|
5200
5279
|
}
|
|
5201
5280
|
return hashAllowlist([...entries].sort());
|
|
5202
5281
|
}
|
|
5203
|
-
function earlierReleaseDaemon(
|
|
5282
|
+
function earlierReleaseDaemon(fs15, paths, daemon) {
|
|
5204
5283
|
if (daemonIdentity(daemon.commandLine, daemon.socketPath) !== "earlier-release") {
|
|
5205
5284
|
return void 0;
|
|
5206
5285
|
}
|
|
5207
|
-
const providers = readAllProviders(
|
|
5208
|
-
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)));
|
|
5209
5288
|
return { admitsServingDoor: daemon.recordedHash === expected };
|
|
5210
5289
|
}
|
|
5211
5290
|
var EARLIER_RELEASE_ALLOWLIST, EARLIER_RELEASE_ANTHROPIC_UPSTREAM;
|
|
@@ -5230,8 +5309,8 @@ function awaitingCause(daemonPid, identity, allowlistFile) {
|
|
|
5230
5309
|
}
|
|
5231
5310
|
return `the headroom supervisor has not written an allowlist admitting this launch's upstreams to ${allowlistFile} within ${String(HEADROOM_START_TIMEOUT_MS)}ms`;
|
|
5232
5311
|
}
|
|
5233
|
-
function daemonAdmits(
|
|
5234
|
-
const content =
|
|
5312
|
+
function daemonAdmits(fs15, allowlistFile, recordedHash, required) {
|
|
5313
|
+
const content = fs15.readFileUtf8(allowlistFile);
|
|
5235
5314
|
if (content === void 0 || recordedHash === void 0) {
|
|
5236
5315
|
return false;
|
|
5237
5316
|
}
|
|
@@ -5500,7 +5579,7 @@ function verifyAllowlistFile(allowlistFile, ports) {
|
|
|
5500
5579
|
const replaceable = fileStat === void 0 || fileStat.kind === "file" || fileStat.kind === "symlink";
|
|
5501
5580
|
return { message: refusal2, repairable: replaceable };
|
|
5502
5581
|
}
|
|
5503
|
-
function prepareHeadroomSocket(
|
|
5582
|
+
function prepareHeadroomSocket(fs15, ports, paths, supervisorPid) {
|
|
5504
5583
|
const unsupported = platformRefusal(ports.platform);
|
|
5505
5584
|
if (unsupported !== void 0) {
|
|
5506
5585
|
return { refused: unsupported };
|
|
@@ -5515,18 +5594,18 @@ function prepareHeadroomSocket(fs14, ports, paths, supervisorPid) {
|
|
|
5515
5594
|
if (ports.lstat(paths.headroomSocketDir)?.kind === "symlink") {
|
|
5516
5595
|
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
5517
5596
|
}
|
|
5518
|
-
|
|
5597
|
+
fs15.mkdirPrivate(paths.headroomSocketDir);
|
|
5519
5598
|
const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
5520
5599
|
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
5521
5600
|
}
|
|
5522
|
-
function pruneStaleHeadroomSockets(
|
|
5601
|
+
function pruneStaleHeadroomSockets(fs15, paths, isRunning) {
|
|
5523
5602
|
const removed = [];
|
|
5524
|
-
for (const name of
|
|
5603
|
+
for (const name of fs15.readdir(paths.headroomSocketDir)) {
|
|
5525
5604
|
const pid = HEADROOM_SOCKET_NAME.exec(name)?.[1];
|
|
5526
5605
|
if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
|
|
5527
5606
|
continue;
|
|
5528
5607
|
}
|
|
5529
|
-
|
|
5608
|
+
fs15.removeRecursive(path13.join(paths.headroomSocketDir, name));
|
|
5530
5609
|
removed.push(name);
|
|
5531
5610
|
}
|
|
5532
5611
|
return removed;
|
|
@@ -5638,37 +5717,37 @@ function compareVersions2(a, b) {
|
|
|
5638
5717
|
return 0;
|
|
5639
5718
|
}
|
|
5640
5719
|
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
5641
|
-
const { fs:
|
|
5720
|
+
const { fs: fs15, paths } = ports;
|
|
5642
5721
|
let config = initialConfig;
|
|
5643
|
-
migrateHeadroomState(
|
|
5644
|
-
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;
|
|
5645
5724
|
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
5646
5725
|
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
5647
5726
|
return 0;
|
|
5648
5727
|
}
|
|
5649
5728
|
let installedSource = previousState?.installedSource;
|
|
5650
5729
|
const ownsState = () => {
|
|
5651
|
-
const owner = readHeadroomState(
|
|
5730
|
+
const owner = readHeadroomState(fs15, paths.headroomStateFile)?.supervisorPid;
|
|
5652
5731
|
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
5653
5732
|
};
|
|
5654
5733
|
const writeOwnState = (state) => {
|
|
5655
5734
|
if (!ownsState()) {
|
|
5656
5735
|
return false;
|
|
5657
5736
|
}
|
|
5658
|
-
writeHeadroomState(
|
|
5737
|
+
writeHeadroomState(fs15, paths.headroomStateFile, state);
|
|
5659
5738
|
return true;
|
|
5660
5739
|
};
|
|
5661
5740
|
const fail = (message) => {
|
|
5662
5741
|
if (writeOwnState({ lastError: message })) {
|
|
5663
|
-
|
|
5742
|
+
fs15.removeRecursive(paths.headroomLockFile);
|
|
5664
5743
|
}
|
|
5665
5744
|
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
5666
5745
|
return 1;
|
|
5667
5746
|
};
|
|
5668
5747
|
const syncAllowlistFile = (allowlist) => {
|
|
5669
5748
|
try {
|
|
5670
|
-
if (
|
|
5671
|
-
writeAllowlistFile(
|
|
5749
|
+
if (fs15.readFileUtf8(paths.headroomAllowlistFile) !== formatAllowlistFile(allowlist)) {
|
|
5750
|
+
writeAllowlistFile(fs15, paths.headroomAllowlistFile, allowlist);
|
|
5672
5751
|
ports.log(`agent-shim headroom supervisor: wrote allowlist [${allowlist.join(", ")}] to ${paths.headroomAllowlistFile}`);
|
|
5673
5752
|
}
|
|
5674
5753
|
return void 0;
|
|
@@ -5686,9 +5765,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5686
5765
|
}
|
|
5687
5766
|
ports.log(`agent-shim headroom supervisor: repairing the allowlist file: ${problem.message}`);
|
|
5688
5767
|
try {
|
|
5689
|
-
|
|
5690
|
-
|
|
5691
|
-
writeAllowlistFile(
|
|
5768
|
+
fs15.mkdirPrivate(paths.headroomDir);
|
|
5769
|
+
fs15.mkdirPrivate(path14.dirname(paths.headroomAllowlistFile));
|
|
5770
|
+
writeAllowlistFile(fs15, paths.headroomAllowlistFile, allowlist);
|
|
5692
5771
|
} catch (error) {
|
|
5693
5772
|
return `could not write the headroom allowlist file ${paths.headroomAllowlistFile}: ${error instanceof Error ? error.message : String(error)}`;
|
|
5694
5773
|
}
|
|
@@ -5713,20 +5792,20 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5713
5792
|
installedSource = config.source;
|
|
5714
5793
|
return void 0;
|
|
5715
5794
|
};
|
|
5716
|
-
const socket = prepareHeadroomSocket(
|
|
5795
|
+
const socket = prepareHeadroomSocket(fs15, ports.socketTrust, paths, ports.ownPid);
|
|
5717
5796
|
if (socket.refused !== void 0) {
|
|
5718
5797
|
return fail(socket.refused);
|
|
5719
5798
|
}
|
|
5720
5799
|
const { socketPath } = socket;
|
|
5721
|
-
pruneStaleHeadroomSockets(
|
|
5722
|
-
pruneStaleAllowlistTemporaries(
|
|
5800
|
+
pruneStaleHeadroomSockets(fs15, paths, ports.isRunning);
|
|
5801
|
+
pruneStaleAllowlistTemporaries(fs15, paths.headroomAllowlistFile, ports.isRunning);
|
|
5723
5802
|
const installFailure = ensureInstalled();
|
|
5724
5803
|
if (installFailure !== void 0) {
|
|
5725
5804
|
return fail(installFailure);
|
|
5726
5805
|
}
|
|
5727
5806
|
const version = ports.headroomVersion() ?? "unknown";
|
|
5728
5807
|
writeOwnState({ supervisorPid: ports.ownPid, version, installedSource });
|
|
5729
|
-
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(", ")}]`);
|
|
5730
5809
|
const orphanPid = previousState?.headroomPid;
|
|
5731
5810
|
const orphanSocket = previousState?.socketPath ?? (previousState?.supervisorPid === void 0 ? void 0 : headroomSocketPath(paths, previousState.supervisorPid));
|
|
5732
5811
|
const orphanIdentity = orphanPid === void 0 || orphanSocket === void 0 || !ports.isRunning(orphanPid) ? void 0 : daemonIdentity(ports.daemonCommandLine(orphanPid), orphanSocket);
|
|
@@ -5764,12 +5843,12 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5764
5843
|
}
|
|
5765
5844
|
config = ports.readConfig();
|
|
5766
5845
|
const settingsHash = hashSettings(config.settings);
|
|
5767
|
-
const inputs = currentHeadroomAllowlistInputs(
|
|
5768
|
-
pruneDeadFrontDoorDirectRecords(
|
|
5769
|
-
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);
|
|
5770
5849
|
const allowlist = inputs.frontDoorOrigins;
|
|
5771
5850
|
const allowlistHash = hashAllowlist(allowlist);
|
|
5772
|
-
pruneDeadSessions(
|
|
5851
|
+
pruneDeadSessions(fs15, paths.headroomSessionsDir, ports.isRunning);
|
|
5773
5852
|
const ownsNow = ownsState();
|
|
5774
5853
|
if (!ownsNow && !superseded) {
|
|
5775
5854
|
ports.log("agent-shim headroom supervisor: another supervisor now owns the state file; serving this daemon's own sessions until they end");
|
|
@@ -5816,7 +5895,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5816
5895
|
runningSettingsHash = settingsHash;
|
|
5817
5896
|
const recorded = writeOwnState(servingState(pid));
|
|
5818
5897
|
if (recorded) {
|
|
5819
|
-
|
|
5898
|
+
fs15.removeRecursive(paths.headroomLockFile);
|
|
5820
5899
|
}
|
|
5821
5900
|
idleSince = void 0;
|
|
5822
5901
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on unix socket ${socketPath}`);
|
|
@@ -5844,7 +5923,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5844
5923
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} now serves allowlist [${allowlist.join(", ")}]`);
|
|
5845
5924
|
}
|
|
5846
5925
|
if (runningSettingsHash !== settingsHash || installedSource !== config.source) {
|
|
5847
|
-
if (sessionsForSupervisor(
|
|
5926
|
+
if (sessionsForSupervisor(fs15, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
5848
5927
|
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
5849
5928
|
ports.stopProcess(headroomPid);
|
|
5850
5929
|
headroomPid = void 0;
|
|
@@ -5853,7 +5932,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5853
5932
|
continue;
|
|
5854
5933
|
}
|
|
5855
5934
|
}
|
|
5856
|
-
const sessions = sessionsForSupervisor(
|
|
5935
|
+
const sessions = sessionsForSupervisor(fs15, paths.headroomSessionsDir, ports.ownPid);
|
|
5857
5936
|
if (sessions.length === 0) {
|
|
5858
5937
|
idleSince ??= ports.now();
|
|
5859
5938
|
const idleMs = ports.now() - idleSince;
|
|
@@ -5878,9 +5957,9 @@ function undeterminedFrontDoors(inputs) {
|
|
|
5878
5957
|
return reason === void 0 ? [] : [{ pid: record.pid, origin: directOrigin(record.directPort), reason }];
|
|
5879
5958
|
});
|
|
5880
5959
|
}
|
|
5881
|
-
function currentHeadroomAllowlistInputs(
|
|
5882
|
-
const named = frontDoorOrigin(readFrontDoorState(
|
|
5883
|
-
const records = listFrontDoorDirectRecords(
|
|
5960
|
+
function currentHeadroomAllowlistInputs(fs15, paths, frontDoorLiveness) {
|
|
5961
|
+
const named = frontDoorOrigin(readFrontDoorState(fs15, paths.frontdoorStateFile));
|
|
5962
|
+
const records = listFrontDoorDirectRecords(fs15, paths.frontdoorDirectRecordsDir);
|
|
5884
5963
|
const liveness = frontDoorLiveness(records.map((record) => record.pid));
|
|
5885
5964
|
const live = liveFrontDoorDirectRecords(records, liveness).map((record) => directOrigin(record.directPort));
|
|
5886
5965
|
return {
|
|
@@ -5889,8 +5968,8 @@ function currentHeadroomAllowlistInputs(fs14, paths, frontDoorLiveness) {
|
|
|
5889
5968
|
frontDoorOrigins: [.../* @__PURE__ */ new Set([...named === void 0 ? [] : [named], ...live])].sort()
|
|
5890
5969
|
};
|
|
5891
5970
|
}
|
|
5892
|
-
function launchRequiredUpstreams(
|
|
5893
|
-
const door = frontDoorOrigin(readFrontDoorState(
|
|
5971
|
+
function launchRequiredUpstreams(fs15, paths) {
|
|
5972
|
+
const door = frontDoorOrigin(readFrontDoorState(fs15, paths.frontdoorStateFile));
|
|
5894
5973
|
return door === void 0 ? [] : [door];
|
|
5895
5974
|
}
|
|
5896
5975
|
async function waitUntilReady(ports, socketPath, pid) {
|
|
@@ -6027,6 +6106,29 @@ function isEnoent3(error) {
|
|
|
6027
6106
|
function isErrorWithCode(error, code) {
|
|
6028
6107
|
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
6029
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
|
+
}
|
|
6030
6132
|
function realSleepSync(ms) {
|
|
6031
6133
|
refuseToBlockInRole("a synchronous sleep");
|
|
6032
6134
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(INT32_BYTE_LENGTH)), 0, 0, ms);
|
|
@@ -6060,9 +6162,9 @@ function realFrontDoorLiveness(pids) {
|
|
|
6060
6162
|
return { status: result.status, stdout: result.stdout, stderr: result.stderr, ...result.error === void 0 ? {} : { error: result.error } };
|
|
6061
6163
|
});
|
|
6062
6164
|
}
|
|
6063
|
-
|
|
6064
|
-
return await new Promise((resolve) => {
|
|
6065
|
-
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) => {
|
|
6066
6168
|
resolve({ status: error === null ? 0 : typeof error.code === "number" ? error.code : null, stdout, stderr });
|
|
6067
6169
|
});
|
|
6068
6170
|
});
|
|
@@ -6268,7 +6370,7 @@ function realResolveClaudeBinary(isOwnBinary) {
|
|
|
6268
6370
|
function realInstalledClaudeVersions() {
|
|
6269
6371
|
return installedVersions(listVersionsDir(defaultVersionsDir()));
|
|
6270
6372
|
}
|
|
6271
|
-
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;
|
|
6272
6374
|
var init_realPorts = __esm({
|
|
6273
6375
|
"src/realPorts.ts"() {
|
|
6274
6376
|
"use strict";
|
|
@@ -6307,6 +6409,7 @@ var init_realPorts = __esm({
|
|
|
6307
6409
|
OWNER_ONLY_DIR_MODE = 448;
|
|
6308
6410
|
OWNER_ONLY_FILE_MODE = 384;
|
|
6309
6411
|
PERMISSION_BITS = 511;
|
|
6412
|
+
DIRECTORY_FLUSH_UNSUPPORTED_CODES = /* @__PURE__ */ new Set(["EINVAL", "ENOTSUP", "EOPNOTSUPP"]);
|
|
6310
6413
|
realFarmFs = {
|
|
6311
6414
|
lstat(filePath) {
|
|
6312
6415
|
let stat;
|
|
@@ -6363,12 +6466,18 @@ var init_realPorts = __esm({
|
|
|
6363
6466
|
fs3.mkdirSync(dirPath, { recursive: true, mode: OWNER_ONLY_DIR_MODE });
|
|
6364
6467
|
fs3.chmodSync(dirPath, OWNER_ONLY_DIR_MODE);
|
|
6365
6468
|
},
|
|
6366
|
-
writeFilePrivate(filePath, contents) {
|
|
6469
|
+
writeFilePrivate(filePath, contents, options) {
|
|
6367
6470
|
const temp = `${filePath}.${String(process.pid)}.tmp`;
|
|
6368
6471
|
try {
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
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
|
+
}
|
|
6372
6481
|
} catch (error) {
|
|
6373
6482
|
fs3.rmSync(temp, { force: true });
|
|
6374
6483
|
throw error;
|
|
@@ -6438,12 +6547,17 @@ var init_realPorts = __esm({
|
|
|
6438
6547
|
}
|
|
6439
6548
|
};
|
|
6440
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;
|
|
6441
6553
|
realRunPort = {
|
|
6442
|
-
run(command, args) {
|
|
6443
|
-
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 } });
|
|
6444
6556
|
return { status: result.status, stdout: result.stdout, stderr: result.stderr };
|
|
6445
6557
|
}
|
|
6446
6558
|
};
|
|
6559
|
+
ASYNC_RUN_TIMEOUT_MS = 2e3;
|
|
6560
|
+
realRunAsync = realRunAsyncWithin(ASYNC_RUN_TIMEOUT_MS);
|
|
6447
6561
|
MACOS_GUI_SESSION_MANAGER = "Aqua";
|
|
6448
6562
|
realCredentialPort = {
|
|
6449
6563
|
readSecretFile(filePath) {
|
|
@@ -6635,8 +6749,8 @@ import path18 from "node:path";
|
|
|
6635
6749
|
function poolNameOf(selector) {
|
|
6636
6750
|
return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
|
|
6637
6751
|
}
|
|
6638
|
-
function readActiveIdentity(
|
|
6639
|
-
const trimmed =
|
|
6752
|
+
function readActiveIdentity(fs15, activeIdentityFile) {
|
|
6753
|
+
const trimmed = fs15.readFileUtf8(activeIdentityFile)?.trim();
|
|
6640
6754
|
return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
|
|
6641
6755
|
}
|
|
6642
6756
|
function isNonEmpty(value) {
|
|
@@ -6686,11 +6800,11 @@ function decideConfigProfile(params) {
|
|
|
6686
6800
|
}
|
|
6687
6801
|
return { source: "none" };
|
|
6688
6802
|
}
|
|
6689
|
-
function loadIdentity(identitiesDir, name,
|
|
6803
|
+
function loadIdentity(identitiesDir, name, fs15) {
|
|
6690
6804
|
if (!isFileName(name)) {
|
|
6691
6805
|
throw new UnsafeNameError(name, "identity", FILE_NAME_RULE);
|
|
6692
6806
|
}
|
|
6693
|
-
return loadConfigFile(path18.join(identitiesDir, name, "identity.json"), IdentitySchema,
|
|
6807
|
+
return loadConfigFile(path18.join(identitiesDir, name, "identity.json"), IdentitySchema, fs15.readConfigFile);
|
|
6694
6808
|
}
|
|
6695
6809
|
var IDENTITY_DECISION_SOURCES, IDENTITY_SOURCE_LABELS, CONFIG_PROFILE_DECISION_SOURCES;
|
|
6696
6810
|
var init_identity = __esm({
|
|
@@ -6944,14 +7058,14 @@ function isIdentityName(name) {
|
|
|
6944
7058
|
function claudeJsonPath(identitiesDir, identity) {
|
|
6945
7059
|
return path19.join(identitiesDir, identity, CLAUDE_JSON);
|
|
6946
7060
|
}
|
|
6947
|
-
function readAccountMetadata(
|
|
7061
|
+
function readAccountMetadata(fs15, identitiesDir, identity) {
|
|
6948
7062
|
if (!isIdentityName(identity)) {
|
|
6949
7063
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
6950
7064
|
}
|
|
6951
|
-
return readAccountMetadataFile(
|
|
7065
|
+
return readAccountMetadataFile(fs15, claudeJsonPath(identitiesDir, identity));
|
|
6952
7066
|
}
|
|
6953
|
-
function readAccountMetadataFile(
|
|
6954
|
-
const raw =
|
|
7067
|
+
function readAccountMetadataFile(fs15, file) {
|
|
7068
|
+
const raw = fs15.readFileUtf8(file);
|
|
6955
7069
|
if (raw === void 0) {
|
|
6956
7070
|
return void 0;
|
|
6957
7071
|
}
|
|
@@ -6981,19 +7095,19 @@ function readAccountMetadataFile(fs14, file) {
|
|
|
6981
7095
|
}
|
|
6982
7096
|
return account.data;
|
|
6983
7097
|
}
|
|
6984
|
-
function createAccountReader(
|
|
7098
|
+
function createAccountReader(fs15, identitiesDir) {
|
|
6985
7099
|
const cache = /* @__PURE__ */ new Map();
|
|
6986
7100
|
return (identity) => {
|
|
6987
7101
|
if (!isIdentityName(identity)) {
|
|
6988
7102
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
6989
7103
|
}
|
|
6990
|
-
const stat =
|
|
7104
|
+
const stat = fs15.lstat(claudeJsonPath(identitiesDir, identity));
|
|
6991
7105
|
const stamp = stat === void 0 ? "absent" : `${String(stat.mtimeMs)}:${String(stat.sizeBytes)}`;
|
|
6992
7106
|
const cached = cache.get(identity);
|
|
6993
7107
|
if (cached?.stamp === stamp) {
|
|
6994
7108
|
return cached.account;
|
|
6995
7109
|
}
|
|
6996
|
-
const account = readAccountMetadata(
|
|
7110
|
+
const account = readAccountMetadata(fs15, identitiesDir, identity);
|
|
6997
7111
|
cache.set(identity, { stamp, account });
|
|
6998
7112
|
return account;
|
|
6999
7113
|
};
|
|
@@ -7029,9 +7143,9 @@ var init_accountDescription = __esm({
|
|
|
7029
7143
|
});
|
|
7030
7144
|
|
|
7031
7145
|
// src/identityAccounts.ts
|
|
7032
|
-
function readIdentityAccount(
|
|
7146
|
+
function readIdentityAccount(fs15, identitiesDir, identity) {
|
|
7033
7147
|
try {
|
|
7034
|
-
const account = readAccountMetadata(
|
|
7148
|
+
const account = readAccountMetadata(fs15, identitiesDir, identity);
|
|
7035
7149
|
return account === void 0 ? void 0 : { account };
|
|
7036
7150
|
} catch (error) {
|
|
7037
7151
|
if (error instanceof AccountMetadataError) {
|
|
@@ -7403,10 +7517,10 @@ function billedTokensOf(record) {
|
|
|
7403
7517
|
const usage = record.usage;
|
|
7404
7518
|
return (usage?.inputTokens ?? 0) + (usage?.cacheCreationInputTokens ?? 0) + (usage?.outputTokens ?? 0);
|
|
7405
7519
|
}
|
|
7406
|
-
function utilisationPerBilledToken(records) {
|
|
7520
|
+
function utilisationPerBilledToken(records, which) {
|
|
7407
7521
|
const points = [];
|
|
7408
7522
|
for (const record of records) {
|
|
7409
|
-
const window = record.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record.rateLimitHeaders)?.
|
|
7523
|
+
const window = record.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record.rateLimitHeaders)?.[which];
|
|
7410
7524
|
if (window?.utilization !== void 0 && window.resetsAt !== void 0) {
|
|
7411
7525
|
points.push({ resetsAt: window.resetsAt, utilization: window.utilization, billed: billedTokensOf(record) });
|
|
7412
7526
|
}
|
|
@@ -7591,14 +7705,17 @@ function rankPool(input) {
|
|
|
7591
7705
|
}
|
|
7592
7706
|
const { sticky: sticky2 } = input;
|
|
7593
7707
|
const warmHere = sticky2?.identity === candidate.identity && nowMs - Date.parse(sticky2.at) <= PROMPT_CACHE_TTL_MS;
|
|
7594
|
-
|
|
7595
|
-
|
|
7708
|
+
const resumeTokens = input.resumeContextTokens;
|
|
7709
|
+
if (input.resuming && resumeTokens !== void 0 && !warmHere) {
|
|
7596
7710
|
const committed = input.committedContextTokens?.[candidate.identity] ?? 0;
|
|
7597
|
-
const
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
const
|
|
7601
|
-
|
|
7711
|
+
const alongside = committed === 0 ? "" : ` (with ${String(committed)} tokens of other conversations already moving here)`;
|
|
7712
|
+
for (const [name, label, window] of [["fiveHour", "5h", fiveHour], ["sevenDay", "7d", sevenDay]]) {
|
|
7713
|
+
const perToken = window === void 0 ? void 0 : utilisationPerBilledToken(assessment.member.records, name);
|
|
7714
|
+
const cost = perToken === void 0 ? void 0 : (resumeTokens + committed) * perToken;
|
|
7715
|
+
if (window !== void 0 && cost !== void 0 && cost > window.remaining) {
|
|
7716
|
+
dryAfterMs.push(0);
|
|
7717
|
+
drySpots.push(`resuming a ${String(resumeTokens)}-token conversation here${alongside} would cost about ${percent(cost)} of the ${label} window, which has ${percent(window.remaining)} left`);
|
|
7718
|
+
}
|
|
7602
7719
|
}
|
|
7603
7720
|
}
|
|
7604
7721
|
if (drySpots.length === 0) {
|
|
@@ -7667,8 +7784,8 @@ function segmentDay(epochMs) {
|
|
|
7667
7784
|
function segmentName(day, pid) {
|
|
7668
7785
|
return `${day}.${String(pid)}.jsonl`;
|
|
7669
7786
|
}
|
|
7670
|
-
function listLogSegments(
|
|
7671
|
-
return
|
|
7787
|
+
function listLogSegments(fs15, logDir) {
|
|
7788
|
+
return fs15.readdir(logDir).flatMap((name) => {
|
|
7672
7789
|
const match = SEGMENT_RE.exec(name);
|
|
7673
7790
|
const day = match?.[1];
|
|
7674
7791
|
if (day === void 0) {
|
|
@@ -7677,15 +7794,15 @@ function listLogSegments(fs14, logDir) {
|
|
|
7677
7794
|
return [{ name, day, endsAt: Date.parse(`${day}T00:00:00.000Z`) + DAY_MS }];
|
|
7678
7795
|
}).sort((left, right) => left.day.localeCompare(right.day) || left.name.localeCompare(right.name));
|
|
7679
7796
|
}
|
|
7680
|
-
function readUsageLog(
|
|
7797
|
+
function readUsageLog(fs15, logDir, options = {}) {
|
|
7681
7798
|
const { sinceMs } = options;
|
|
7682
7799
|
const records = [];
|
|
7683
7800
|
let invalidLines = 0;
|
|
7684
|
-
for (const segment of listLogSegments(
|
|
7801
|
+
for (const segment of listLogSegments(fs15, logDir)) {
|
|
7685
7802
|
if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
|
|
7686
7803
|
continue;
|
|
7687
7804
|
}
|
|
7688
|
-
const read = readSegment(
|
|
7805
|
+
const read = readSegment(fs15, logDir, segment);
|
|
7689
7806
|
if (read === void 0) {
|
|
7690
7807
|
continue;
|
|
7691
7808
|
}
|
|
@@ -7699,8 +7816,8 @@ function readUsageLog(fs14, logDir, options = {}) {
|
|
|
7699
7816
|
records.sort((left, right) => left.at.localeCompare(right.at));
|
|
7700
7817
|
return { records, invalidLines };
|
|
7701
7818
|
}
|
|
7702
|
-
function readSegment(
|
|
7703
|
-
const contents =
|
|
7819
|
+
function readSegment(fs15, logDir, segment) {
|
|
7820
|
+
const contents = fs15.readFileUtf8(path20.join(logDir, segment.name));
|
|
7704
7821
|
if (contents === void 0) {
|
|
7705
7822
|
return void 0;
|
|
7706
7823
|
}
|
|
@@ -7734,9 +7851,9 @@ function snapshotPath(snapshotsDir, identity) {
|
|
|
7734
7851
|
}
|
|
7735
7852
|
return path20.join(snapshotsDir, `${identity}.json`);
|
|
7736
7853
|
}
|
|
7737
|
-
function readUsageSnapshot(
|
|
7854
|
+
function readUsageSnapshot(fs15, snapshotsDir, identity) {
|
|
7738
7855
|
const file = snapshotPath(snapshotsDir, identity);
|
|
7739
|
-
const raw =
|
|
7856
|
+
const raw = fs15.readFileUtf8(file);
|
|
7740
7857
|
if (raw === void 0) {
|
|
7741
7858
|
return void 0;
|
|
7742
7859
|
}
|
|
@@ -7752,8 +7869,8 @@ function readUsageSnapshot(fs14, snapshotsDir, identity) {
|
|
|
7752
7869
|
}
|
|
7753
7870
|
return snapshot.data;
|
|
7754
7871
|
}
|
|
7755
|
-
function listUsageSnapshots(
|
|
7756
|
-
return
|
|
7872
|
+
function listUsageSnapshots(fs15, snapshotsDir) {
|
|
7873
|
+
return fs15.readdir(snapshotsDir).flatMap((name) => {
|
|
7757
7874
|
if (!name.endsWith(".json")) {
|
|
7758
7875
|
return [];
|
|
7759
7876
|
}
|
|
@@ -7761,7 +7878,7 @@ function listUsageSnapshots(fs14, snapshotsDir) {
|
|
|
7761
7878
|
if (!isIdentityName(identity)) {
|
|
7762
7879
|
return [];
|
|
7763
7880
|
}
|
|
7764
|
-
const snapshot = readUsageSnapshot(
|
|
7881
|
+
const snapshot = readUsageSnapshot(fs15, snapshotsDir, identity);
|
|
7765
7882
|
return snapshot === void 0 ? [] : [snapshot];
|
|
7766
7883
|
}).sort((left, right) => left.identity.localeCompare(right.identity));
|
|
7767
7884
|
}
|
|
@@ -7786,11 +7903,11 @@ var init_read = __esm({
|
|
|
7786
7903
|
|
|
7787
7904
|
// src/usage/store.ts
|
|
7788
7905
|
import path21 from "node:path";
|
|
7789
|
-
function pruneUsageLog(
|
|
7906
|
+
function pruneUsageLog(fs15, logDir, nowMs) {
|
|
7790
7907
|
const cutoff = nowMs - USAGE_RETENTION_MS;
|
|
7791
|
-
for (const segment of listLogSegments(
|
|
7908
|
+
for (const segment of listLogSegments(fs15, logDir)) {
|
|
7792
7909
|
if (segment.endsAt <= cutoff) {
|
|
7793
|
-
|
|
7910
|
+
fs15.removeRecursive(path21.join(logDir, segment.name));
|
|
7794
7911
|
}
|
|
7795
7912
|
}
|
|
7796
7913
|
}
|
|
@@ -7819,7 +7936,7 @@ function foldProviderState(current, record) {
|
|
|
7819
7936
|
};
|
|
7820
7937
|
}
|
|
7821
7938
|
function createUsageStore(deps) {
|
|
7822
|
-
const { fs:
|
|
7939
|
+
const { fs: fs15, paths } = deps;
|
|
7823
7940
|
let prunedDay;
|
|
7824
7941
|
const rewriteSnapshot = (identity, fold) => {
|
|
7825
7942
|
if (!isIdentityName(identity)) {
|
|
@@ -7828,7 +7945,7 @@ function createUsageStore(deps) {
|
|
|
7828
7945
|
}
|
|
7829
7946
|
let current;
|
|
7830
7947
|
try {
|
|
7831
|
-
current = readUsageSnapshot(
|
|
7948
|
+
current = readUsageSnapshot(fs15, paths.usageSnapshotsDir, identity);
|
|
7832
7949
|
} catch (error) {
|
|
7833
7950
|
if (!(error instanceof UsageSnapshotError)) {
|
|
7834
7951
|
throw error;
|
|
@@ -7855,8 +7972,8 @@ function createUsageStore(deps) {
|
|
|
7855
7972
|
...account === void 0 ? {} : { account },
|
|
7856
7973
|
providers
|
|
7857
7974
|
});
|
|
7858
|
-
|
|
7859
|
-
|
|
7975
|
+
fs15.mkdirPrivate(paths.usageSnapshotsDir);
|
|
7976
|
+
fs15.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
|
|
7860
7977
|
`);
|
|
7861
7978
|
deps.publish?.(snapshot);
|
|
7862
7979
|
return true;
|
|
@@ -7865,14 +7982,14 @@ function createUsageStore(deps) {
|
|
|
7865
7982
|
record: (input) => {
|
|
7866
7983
|
const record = UsageRecordSchema.parse(input);
|
|
7867
7984
|
const nowMs = deps.now();
|
|
7868
|
-
|
|
7869
|
-
|
|
7985
|
+
fs15.mkdirPrivate(paths.usageDir);
|
|
7986
|
+
fs15.mkdirPrivate(paths.usageLogDir);
|
|
7870
7987
|
const day = segmentDay(nowMs);
|
|
7871
7988
|
if (prunedDay !== day) {
|
|
7872
|
-
pruneUsageLog(
|
|
7989
|
+
pruneUsageLog(fs15, paths.usageLogDir, nowMs);
|
|
7873
7990
|
prunedDay = day;
|
|
7874
7991
|
}
|
|
7875
|
-
|
|
7992
|
+
fs15.appendFilePrivate(path21.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
|
|
7876
7993
|
`);
|
|
7877
7994
|
deps.onRecord?.(record);
|
|
7878
7995
|
if (record.identity !== void 0) {
|
|
@@ -7916,14 +8033,14 @@ import { z as z15 } from "zod";
|
|
|
7916
8033
|
function errorMessage(error) {
|
|
7917
8034
|
return error instanceof Error ? error.message : String(error);
|
|
7918
8035
|
}
|
|
7919
|
-
function loadPoolMembers(
|
|
8036
|
+
function loadPoolMembers(fs15, paths, identities, nowMs) {
|
|
7920
8037
|
const windowStartMs = nowMs - FIVE_HOUR_WINDOW_MS;
|
|
7921
|
-
const log = readUsageLog(
|
|
8038
|
+
const log = readUsageLog(fs15, paths.usageLogDir, { sinceMs: windowStartMs });
|
|
7922
8039
|
return identities.map((identity) => {
|
|
7923
8040
|
const records = log.records.filter((record) => record.identity === identity && record.provider === ANTHROPIC_PROVIDER && Date.parse(record.at) >= windowStartMs);
|
|
7924
8041
|
try {
|
|
7925
|
-
const snapshot = readUsageSnapshot(
|
|
7926
|
-
const account = readAccountMetadata(
|
|
8042
|
+
const snapshot = readUsageSnapshot(fs15, paths.usageSnapshotsDir, identity);
|
|
8043
|
+
const account = readAccountMetadata(fs15, paths.identitiesDir, identity) ?? snapshot?.account;
|
|
7927
8044
|
return { identity, records, ...snapshot === void 0 ? {} : { snapshot }, ...account === void 0 ? {} : { account } };
|
|
7928
8045
|
} catch (error) {
|
|
7929
8046
|
if (error instanceof UsageSnapshotError || error instanceof AccountMetadataError) {
|
|
@@ -8042,9 +8159,9 @@ function collectPoolIdentities(pools, poolName, stack, found) {
|
|
|
8042
8159
|
collectPoolIdentities(pools, nestedName, childStack, found);
|
|
8043
8160
|
}
|
|
8044
8161
|
}
|
|
8045
|
-
function readPicksFile(
|
|
8162
|
+
function readPicksFile(fs15, file) {
|
|
8046
8163
|
const empty = { schemaVersion: SCHEMA_VERSION, picks: {} };
|
|
8047
|
-
const raw =
|
|
8164
|
+
const raw = fs15.readFileUtf8(file);
|
|
8048
8165
|
if (raw === void 0) {
|
|
8049
8166
|
return { file: empty };
|
|
8050
8167
|
}
|
|
@@ -8057,17 +8174,17 @@ function readPicksFile(fs14, file) {
|
|
|
8057
8174
|
const result = PicksFileSchema.safeParse(parsed);
|
|
8058
8175
|
return result.success ? { file: result.data } : { file: empty, problem: `${file} is not a picks file this agent-shim can read` };
|
|
8059
8176
|
}
|
|
8060
|
-
function readStickyPick(
|
|
8061
|
-
const read = readPicksFile(
|
|
8177
|
+
function readStickyPick(fs15, picksFile, directory) {
|
|
8178
|
+
const read = readPicksFile(fs15, picksFile);
|
|
8062
8179
|
const entry = read.file.picks[directory];
|
|
8063
8180
|
return { ...entry === void 0 ? {} : { sticky: entry }, ...read.problem === void 0 ? {} : { problem: read.problem } };
|
|
8064
8181
|
}
|
|
8065
|
-
function recordStickyPick(
|
|
8066
|
-
const current = readPicksFile(
|
|
8182
|
+
function recordStickyPick(fs15, picksFile, directory, identity, nowMs) {
|
|
8183
|
+
const current = readPicksFile(fs15, picksFile).file.picks;
|
|
8067
8184
|
const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
|
|
8068
8185
|
const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
|
|
8069
|
-
|
|
8070
|
-
|
|
8186
|
+
fs15.mkdirPrivate(path22.dirname(picksFile));
|
|
8187
|
+
fs15.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
|
|
8071
8188
|
`);
|
|
8072
8189
|
}
|
|
8073
8190
|
var PoolGraphError, SCHEMA_VERSION, PickEntrySchema, PicksFileSchema;
|
|
@@ -8100,9 +8217,9 @@ var init_poolPick = __esm({
|
|
|
8100
8217
|
|
|
8101
8218
|
// src/statusline/keys.ts
|
|
8102
8219
|
import { z as z16 } from "zod";
|
|
8103
|
-
function valueAt(source,
|
|
8220
|
+
function valueAt(source, path45) {
|
|
8104
8221
|
let current = source;
|
|
8105
|
-
for (const part of
|
|
8222
|
+
for (const part of path45) {
|
|
8106
8223
|
if (!isPlainObject(current)) {
|
|
8107
8224
|
return void 0;
|
|
8108
8225
|
}
|
|
@@ -8110,14 +8227,14 @@ function valueAt(source, path42) {
|
|
|
8110
8227
|
}
|
|
8111
8228
|
return current;
|
|
8112
8229
|
}
|
|
8113
|
-
function acceptsNull(
|
|
8114
|
-
const layer =
|
|
8230
|
+
function acceptsNull(path45) {
|
|
8231
|
+
const layer = path45.reduceRight((inner, part) => ({ [part]: inner }), null);
|
|
8115
8232
|
return StatuslineSchema.safeParse(layer).success;
|
|
8116
8233
|
}
|
|
8117
|
-
function keyOf(
|
|
8234
|
+
function keyOf(path45, declared) {
|
|
8118
8235
|
const optional = declared instanceof z16.ZodOptional;
|
|
8119
8236
|
const leaf = optional ? declared.unwrap() : declared;
|
|
8120
|
-
const common = { path:
|
|
8237
|
+
const common = { path: path45.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path45), optional, unsettable: acceptsNull(path45) };
|
|
8121
8238
|
if (leaf instanceof z16.ZodNumber) {
|
|
8122
8239
|
return { ...common, kind: "integer", choices: [] };
|
|
8123
8240
|
}
|
|
@@ -8142,7 +8259,7 @@ function keyOf(path42, declared) {
|
|
|
8142
8259
|
if (leaf instanceof z16.ZodArray && leaf.element instanceof z16.ZodString) {
|
|
8143
8260
|
return { ...common, kind: "textList", choices: [] };
|
|
8144
8261
|
}
|
|
8145
|
-
throw new TypeError(`statusline setting ${
|
|
8262
|
+
throw new TypeError(`statusline setting ${path45.join(".")} has a kind the key listing does not describe`);
|
|
8146
8263
|
}
|
|
8147
8264
|
function walk(shape, prefix) {
|
|
8148
8265
|
return Object.entries(shape).flatMap(([name, schema]) => schema instanceof z16.ZodObject ? walk(schema.shape, [...prefix, name]) : [keyOf([...prefix, name], schema)]);
|
|
@@ -8158,15 +8275,15 @@ var init_keys = __esm({
|
|
|
8158
8275
|
});
|
|
8159
8276
|
|
|
8160
8277
|
// src/statusline/change.ts
|
|
8161
|
-
function keyNamed(
|
|
8162
|
-
const found = statuslineKeys().find((key) => key.path ===
|
|
8278
|
+
function keyNamed(path45) {
|
|
8279
|
+
const found = statuslineKeys().find((key) => key.path === path45);
|
|
8163
8280
|
if (found === void 0) {
|
|
8164
|
-
throw new UsageError(`"${
|
|
8281
|
+
throw new UsageError(`"${path45}" is not a statusline setting; \`agent-shim statusline keys\` lists them.`);
|
|
8165
8282
|
}
|
|
8166
8283
|
return found;
|
|
8167
8284
|
}
|
|
8168
|
-
function setAt(target,
|
|
8169
|
-
const [head, ...rest] =
|
|
8285
|
+
function setAt(target, path45, value) {
|
|
8286
|
+
const [head, ...rest] = path45;
|
|
8170
8287
|
if (head === void 0) {
|
|
8171
8288
|
return;
|
|
8172
8289
|
}
|
|
@@ -8179,8 +8296,8 @@ function setAt(target, path42, value) {
|
|
|
8179
8296
|
target[head] = next;
|
|
8180
8297
|
setAt(next, rest, value);
|
|
8181
8298
|
}
|
|
8182
|
-
function removeAt(target,
|
|
8183
|
-
const [head, ...rest] =
|
|
8299
|
+
function removeAt(target, path45) {
|
|
8300
|
+
const [head, ...rest] = path45;
|
|
8184
8301
|
if (head === void 0) {
|
|
8185
8302
|
return;
|
|
8186
8303
|
}
|
|
@@ -8198,13 +8315,13 @@ function removeAt(target, path42) {
|
|
|
8198
8315
|
}
|
|
8199
8316
|
function applyStatuslineChange(existing, change) {
|
|
8200
8317
|
const draft = structuredClone(existing ?? {});
|
|
8201
|
-
for (const [
|
|
8202
|
-
keyNamed(
|
|
8203
|
-
setAt(draft,
|
|
8318
|
+
for (const [path45, value] of Object.entries(change.set ?? {})) {
|
|
8319
|
+
keyNamed(path45);
|
|
8320
|
+
setAt(draft, path45.split("."), value);
|
|
8204
8321
|
}
|
|
8205
|
-
for (const
|
|
8206
|
-
keyNamed(
|
|
8207
|
-
removeAt(draft,
|
|
8322
|
+
for (const path45 of change.unset ?? []) {
|
|
8323
|
+
keyNamed(path45);
|
|
8324
|
+
removeAt(draft, path45.split("."));
|
|
8208
8325
|
}
|
|
8209
8326
|
const result = StatuslineSchema.safeParse(draft);
|
|
8210
8327
|
if (!result.success) {
|
|
@@ -8493,6 +8610,8 @@ function buildLayoutPaths(root) {
|
|
|
8493
8610
|
usageAnchorsFile: path23.join(root, "usage", "anchors.json"),
|
|
8494
8611
|
usageJobsFile: path23.join(root, "usage", "jobs.json"),
|
|
8495
8612
|
jobLogsDir: path23.join(root, "logs", "jobs"),
|
|
8613
|
+
identityRenamesDir: path23.join(root, "identity-renames"),
|
|
8614
|
+
launchesDir: path23.join(root, "launches"),
|
|
8496
8615
|
superviseDir: path23.join(root, "supervise"),
|
|
8497
8616
|
modelMovesDir: path23.join(root, "model-moves"),
|
|
8498
8617
|
mcpPermissionsFile: path23.join(root, "mcp", "permissions.json")
|
|
@@ -9208,7 +9327,12 @@ function readProvider(paths, name) {
|
|
|
9208
9327
|
if (!fs7.existsSync(filePath)) {
|
|
9209
9328
|
return void 0;
|
|
9210
9329
|
}
|
|
9211
|
-
|
|
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
|
+
}
|
|
9212
9336
|
return parseProviderFile(filePath, raw);
|
|
9213
9337
|
}
|
|
9214
9338
|
function loadProvider(providersDir, name, port) {
|
|
@@ -9230,7 +9354,7 @@ function listProviders(paths, onInvalid = reportInvalidProvider) {
|
|
|
9230
9354
|
try {
|
|
9231
9355
|
provider = readProvider(paths, name);
|
|
9232
9356
|
} catch (error) {
|
|
9233
|
-
if (!(error instanceof ConfigValidationError || error instanceof LegacyProviderFileError || error instanceof UnsafeNameError)) {
|
|
9357
|
+
if (!(error instanceof ConfigValidationError || error instanceof LegacyProviderFileError || error instanceof ConfigFileNotJsonError || error instanceof UnsafeNameError)) {
|
|
9234
9358
|
throw error;
|
|
9235
9359
|
}
|
|
9236
9360
|
onInvalid(name, error.message);
|
|
@@ -9576,13 +9700,13 @@ function decideSignIn(facts) {
|
|
|
9576
9700
|
function credentialsFilePath(farmRoot) {
|
|
9577
9701
|
return path25.join(farmRoot, CREDENTIALS_FILE);
|
|
9578
9702
|
}
|
|
9579
|
-
function identitySignIn(
|
|
9703
|
+
function identitySignIn(fs15, probe, identity) {
|
|
9580
9704
|
const probing = !identity.hasCredentialBlock && identity.provider === void 0;
|
|
9581
9705
|
return decideSignIn({
|
|
9582
9706
|
hasCredentialBlock: identity.hasCredentialBlock,
|
|
9583
9707
|
provider: identity.provider,
|
|
9584
9708
|
keychainItem: probing && probe.platform === "darwin" && probe.run !== void 0 ? keychainHasItem(probe.run, identity.farmRoot) : void 0,
|
|
9585
|
-
credentialsFile: probing &&
|
|
9709
|
+
credentialsFile: probing && fs15.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
|
|
9586
9710
|
platform: probe.platform
|
|
9587
9711
|
});
|
|
9588
9712
|
}
|
|
@@ -9961,62 +10085,62 @@ var init_signatures = __esm({
|
|
|
9961
10085
|
});
|
|
9962
10086
|
|
|
9963
10087
|
// src/codex/anthropic.ts
|
|
9964
|
-
import { z as
|
|
10088
|
+
import { z as z28 } from "zod";
|
|
9965
10089
|
var TextBlockSchema, Base64ImageSourceSchema, UrlImageSourceSchema, ImageBlockSchema, ToolUseBlockSchema, ToolResultContentBlockSchema, ToolResultBlockSchema, OtherBlockSchema, ContentBlockSchema, MessageSchema, ToolSchema, ToolChoiceSchema, SystemSchema, MessagesRequestSchema, CountTokensRequestSchema;
|
|
9966
10090
|
var init_anthropic = __esm({
|
|
9967
10091
|
"src/codex/anthropic.ts"() {
|
|
9968
10092
|
"use strict";
|
|
9969
|
-
TextBlockSchema =
|
|
9970
|
-
Base64ImageSourceSchema =
|
|
9971
|
-
UrlImageSourceSchema =
|
|
9972
|
-
ImageBlockSchema =
|
|
9973
|
-
type:
|
|
9974
|
-
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])
|
|
9975
10099
|
});
|
|
9976
|
-
ToolUseBlockSchema =
|
|
9977
|
-
type:
|
|
9978
|
-
id:
|
|
9979
|
-
name:
|
|
9980
|
-
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()
|
|
9981
10105
|
});
|
|
9982
|
-
ToolResultContentBlockSchema =
|
|
9983
|
-
ToolResultBlockSchema =
|
|
9984
|
-
type:
|
|
9985
|
-
tool_use_id:
|
|
9986
|
-
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()
|
|
9987
10111
|
});
|
|
9988
|
-
OtherBlockSchema =
|
|
9989
|
-
ContentBlockSchema =
|
|
9990
|
-
MessageSchema =
|
|
9991
|
-
role:
|
|
9992
|
-
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)])
|
|
9993
10117
|
});
|
|
9994
|
-
ToolSchema =
|
|
9995
|
-
name:
|
|
9996
|
-
description:
|
|
9997
|
-
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()
|
|
9998
10122
|
});
|
|
9999
|
-
ToolChoiceSchema =
|
|
10000
|
-
|
|
10001
|
-
|
|
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) })
|
|
10002
10126
|
]);
|
|
10003
|
-
SystemSchema =
|
|
10004
|
-
MessagesRequestSchema =
|
|
10005
|
-
model:
|
|
10127
|
+
SystemSchema = z28.union([z28.string(), z28.array(z28.union([TextBlockSchema, OtherBlockSchema]))]);
|
|
10128
|
+
MessagesRequestSchema = z28.looseObject({
|
|
10129
|
+
model: z28.string().optional(),
|
|
10006
10130
|
system: SystemSchema.optional(),
|
|
10007
|
-
messages:
|
|
10008
|
-
tools:
|
|
10131
|
+
messages: z28.array(MessageSchema),
|
|
10132
|
+
tools: z28.array(ToolSchema).optional(),
|
|
10009
10133
|
tool_choice: ToolChoiceSchema.optional(),
|
|
10010
|
-
stream:
|
|
10134
|
+
stream: z28.boolean().optional(),
|
|
10011
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. */
|
|
10012
|
-
metadata:
|
|
10136
|
+
metadata: z28.looseObject({ user_id: z28.string().optional() }).optional(),
|
|
10013
10137
|
/** Claude Code's effort setting. Any string is accepted; the translator honours only the levels the backend understands. */
|
|
10014
|
-
output_config:
|
|
10138
|
+
output_config: z28.looseObject({ effort: z28.string().optional() }).optional()
|
|
10015
10139
|
});
|
|
10016
|
-
CountTokensRequestSchema =
|
|
10017
|
-
system:
|
|
10018
|
-
messages:
|
|
10019
|
-
tools:
|
|
10140
|
+
CountTokensRequestSchema = z28.looseObject({
|
|
10141
|
+
system: z28.unknown().optional(),
|
|
10142
|
+
messages: z28.unknown().optional(),
|
|
10143
|
+
tools: z28.unknown().optional()
|
|
10020
10144
|
});
|
|
10021
10145
|
}
|
|
10022
10146
|
});
|
|
@@ -10100,7 +10224,7 @@ var init_translate2 = __esm({
|
|
|
10100
10224
|
|
|
10101
10225
|
// src/providerCatalogue.ts
|
|
10102
10226
|
import picomatch4 from "picomatch";
|
|
10103
|
-
import { z as
|
|
10227
|
+
import { z as z29 } from "zod";
|
|
10104
10228
|
function catalogueCachePath(paths, name) {
|
|
10105
10229
|
return providerFilePath(paths.catalogueDir, name);
|
|
10106
10230
|
}
|
|
@@ -10136,8 +10260,8 @@ var init_providerCatalogue = __esm({
|
|
|
10136
10260
|
CATALOGUE_REQUEST_SECONDS = 10;
|
|
10137
10261
|
CATALOGUE_REQUEST_TIMEOUT_MS = CATALOGUE_REQUEST_SECONDS * MS_PER_SECOND5;
|
|
10138
10262
|
CATALOGUE_REFRESH_TIMEOUT_MS = DEFAULT_CANDIDATE_URLS * CATALOGUE_REQUEST_TIMEOUT_MS;
|
|
10139
|
-
CatalogueModelSchema =
|
|
10140
|
-
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) });
|
|
10141
10265
|
}
|
|
10142
10266
|
});
|
|
10143
10267
|
|
|
@@ -10444,6 +10568,60 @@ var init_proxyBypass2 = __esm({
|
|
|
10444
10568
|
}
|
|
10445
10569
|
});
|
|
10446
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
|
+
|
|
10447
10625
|
// src/update/update.ts
|
|
10448
10626
|
function compareVersions3(left, right) {
|
|
10449
10627
|
const parse = (version) => {
|
|
@@ -10950,6 +11128,59 @@ var init_cliOverride = __esm({
|
|
|
10950
11128
|
}
|
|
10951
11129
|
});
|
|
10952
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
|
+
|
|
10953
11184
|
// src/headroom/headers.ts
|
|
10954
11185
|
function mergeAnthropicCustomHeaders(existing, additions) {
|
|
10955
11186
|
const merged = /* @__PURE__ */ new Map();
|
|
@@ -11018,7 +11249,7 @@ var init_settings2 = __esm({
|
|
|
11018
11249
|
});
|
|
11019
11250
|
|
|
11020
11251
|
// src/launcher/flags.ts
|
|
11021
|
-
import
|
|
11252
|
+
import path39 from "node:path";
|
|
11022
11253
|
function resolveLaunchFlags(params) {
|
|
11023
11254
|
const statusline = resolveStatuslineSettings(params);
|
|
11024
11255
|
return {
|
|
@@ -11074,7 +11305,7 @@ function buildEnv(params) {
|
|
|
11074
11305
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
11075
11306
|
let providerCustomHeaders;
|
|
11076
11307
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
11077
|
-
env.CLAUDE_CONFIG_DIR =
|
|
11308
|
+
env.CLAUDE_CONFIG_DIR = path39.join(params.identitiesDir, params.resolvedIdentityName);
|
|
11078
11309
|
}
|
|
11079
11310
|
if (params.provider !== void 0) {
|
|
11080
11311
|
const providerEnv = params.provider.definition.kind !== void 0 && params.provider.definition.kind !== "http" ? {} : params.provider.definition.env ?? {};
|
|
@@ -11166,7 +11397,7 @@ var init_extraFlags = __esm({
|
|
|
11166
11397
|
});
|
|
11167
11398
|
|
|
11168
11399
|
// src/usage/resumeContext.ts
|
|
11169
|
-
import
|
|
11400
|
+
import path40 from "node:path";
|
|
11170
11401
|
function projectDirNameOf(cwd) {
|
|
11171
11402
|
return cwd.replace(/[^A-Za-z0-9]/g, "-");
|
|
11172
11403
|
}
|
|
@@ -11217,15 +11448,15 @@ function contextTokensOfTranscript(text) {
|
|
|
11217
11448
|
}
|
|
11218
11449
|
return void 0;
|
|
11219
11450
|
}
|
|
11220
|
-
function newestTranscript(
|
|
11451
|
+
function newestTranscript(fs15, projectDir) {
|
|
11221
11452
|
let newest;
|
|
11222
11453
|
let newestMs = -Infinity;
|
|
11223
|
-
for (const name of
|
|
11454
|
+
for (const name of fs15.readdir(projectDir)) {
|
|
11224
11455
|
if (!name.endsWith(".jsonl")) {
|
|
11225
11456
|
continue;
|
|
11226
11457
|
}
|
|
11227
|
-
const candidate =
|
|
11228
|
-
const stat =
|
|
11458
|
+
const candidate = path40.join(projectDir, name);
|
|
11459
|
+
const stat = fs15.lstat(candidate);
|
|
11229
11460
|
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
11230
11461
|
newestMs = stat.mtimeMs;
|
|
11231
11462
|
newest = candidate;
|
|
@@ -11233,14 +11464,14 @@ function newestTranscript(fs14, projectDir) {
|
|
|
11233
11464
|
}
|
|
11234
11465
|
return newest;
|
|
11235
11466
|
}
|
|
11236
|
-
function resumedContextTokens(
|
|
11467
|
+
function resumedContextTokens(fs15, params) {
|
|
11237
11468
|
const target = resumeTargetOf(params.passthrough);
|
|
11238
11469
|
if (target === void 0) {
|
|
11239
11470
|
return void 0;
|
|
11240
11471
|
}
|
|
11241
|
-
const projectDir =
|
|
11242
|
-
const file = target.kind === "id" ?
|
|
11243
|
-
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);
|
|
11244
11475
|
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
11245
11476
|
}
|
|
11246
11477
|
var init_resumeContext = __esm({
|
|
@@ -11836,7 +12067,7 @@ var init_launchHook = __esm({
|
|
|
11836
12067
|
// src/launcher.ts
|
|
11837
12068
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
11838
12069
|
import { isDeepStrictEqual } from "node:util";
|
|
11839
|
-
import
|
|
12070
|
+
import path41 from "node:path";
|
|
11840
12071
|
function resolveIdentityCredential(identity, credential, env, port) {
|
|
11841
12072
|
if (port === void 0) {
|
|
11842
12073
|
return { ok: false, status: 1, message: `agent-shim: identity ${identity} needs its credential resolved, but this launcher has no credential port wired` };
|
|
@@ -11845,7 +12076,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
|
|
|
11845
12076
|
return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
11846
12077
|
}
|
|
11847
12078
|
function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
11848
|
-
const { paths, fs:
|
|
12079
|
+
const { paths, fs: fs15, proc, log } = params;
|
|
11849
12080
|
if (decided.pool === void 0) {
|
|
11850
12081
|
return { identityDecision: decided };
|
|
11851
12082
|
}
|
|
@@ -11864,7 +12095,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
11864
12095
|
selectedVia: decided.source,
|
|
11865
12096
|
pools: params.pools,
|
|
11866
12097
|
paths,
|
|
11867
|
-
fs:
|
|
12098
|
+
fs: fs15,
|
|
11868
12099
|
usageFs: farmRuntime.fs,
|
|
11869
12100
|
cwd: farmRuntime.cwd,
|
|
11870
12101
|
now: farmRuntime.now,
|
|
@@ -11888,7 +12119,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
11888
12119
|
};
|
|
11889
12120
|
}
|
|
11890
12121
|
function decideLaunch(params, readOnly) {
|
|
11891
|
-
const { paths, fs:
|
|
12122
|
+
const { paths, fs: fs15, proc, log } = params;
|
|
11892
12123
|
const { env, argv } = proc;
|
|
11893
12124
|
const parsedArgv = parseLauncherArgv(argv);
|
|
11894
12125
|
const cliOverride = buildCliOverride({
|
|
@@ -11903,7 +12134,7 @@ function decideLaunch(params, readOnly) {
|
|
|
11903
12134
|
argv0Identity: params.pickedIdentity ?? parsedArgv.identity,
|
|
11904
12135
|
directoryPinnedIdentity: params.directoryPinnedIdentity,
|
|
11905
12136
|
readActiveIdentityFile: () => {
|
|
11906
|
-
const raw =
|
|
12137
|
+
const raw = fs15.readFileUtf8(paths.activeIdentityFile);
|
|
11907
12138
|
if (raw === void 0) {
|
|
11908
12139
|
return void 0;
|
|
11909
12140
|
}
|
|
@@ -11938,7 +12169,7 @@ function decideLaunch(params, readOnly) {
|
|
|
11938
12169
|
}
|
|
11939
12170
|
let loadedIdentity;
|
|
11940
12171
|
if (identityDecision.name !== void 0) {
|
|
11941
|
-
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name,
|
|
12172
|
+
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs15);
|
|
11942
12173
|
if (loadedIdentity === void 0) {
|
|
11943
12174
|
log.error(
|
|
11944
12175
|
`agent-shim: no identity named "${identityDecision.name}" (selected via ${identityDecision.source}). Run \`agent-shim identity add ${identityDecision.name}\` first.`
|
|
@@ -11953,7 +12184,7 @@ function decideLaunch(params, readOnly) {
|
|
|
11953
12184
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
11954
12185
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
11955
12186
|
});
|
|
11956
|
-
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) {
|
|
11957
12188
|
log.error(
|
|
11958
12189
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
11959
12190
|
);
|
|
@@ -11962,7 +12193,7 @@ function decideLaunch(params, readOnly) {
|
|
|
11962
12193
|
const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
|
|
11963
12194
|
const providerParams = {
|
|
11964
12195
|
paths,
|
|
11965
|
-
port:
|
|
12196
|
+
port: fs15,
|
|
11966
12197
|
...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
|
|
11967
12198
|
...farmContext === void 0 ? {} : { cascade: farmContext.cascade },
|
|
11968
12199
|
...loadedIdentity?.config.provider === void 0 ? {} : { identityProvider: loadedIdentity.config.provider }
|
|
@@ -12074,9 +12305,9 @@ function decideLaunch(params, readOnly) {
|
|
|
12074
12305
|
const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
|
|
12075
12306
|
const globalModels = loadConfigFile(paths.globalConfigFile, GlobalConfigSchema, params.fs.readConfigFile)?.config.models;
|
|
12076
12307
|
const models = launchCascade !== void 0 && params.farm !== void 0 ? cascadeModels : globalModels;
|
|
12077
|
-
const listedProviders = listProviderNames(
|
|
12308
|
+
const listedProviders = listProviderNames(fs15.readdir, paths.providersDir).flatMap((name) => {
|
|
12078
12309
|
try {
|
|
12079
|
-
const definition = loadProvider(paths.providersDir, name,
|
|
12310
|
+
const definition = loadProvider(paths.providersDir, name, fs15);
|
|
12080
12311
|
return definition === void 0 ? [] : [[name, definition, parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, name)))?.models ?? []]];
|
|
12081
12312
|
} catch {
|
|
12082
12313
|
return [];
|
|
@@ -12094,7 +12325,7 @@ function decideLaunch(params, readOnly) {
|
|
|
12094
12325
|
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
12095
12326
|
passthrough: withLauncherSettings(params.supervised === void 0 ? parsedArgv.rest : withSupervision(parsedArgv.rest, params.supervised), launcherSettings)
|
|
12096
12327
|
}) : [...parsedArgv.rest];
|
|
12097
|
-
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);
|
|
12098
12329
|
const decision = {
|
|
12099
12330
|
identitySource: identityDecision.source,
|
|
12100
12331
|
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
@@ -12132,6 +12363,19 @@ function decideLaunch(params, readOnly) {
|
|
|
12132
12363
|
};
|
|
12133
12364
|
}
|
|
12134
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) {
|
|
12135
12379
|
const { paths, proc, log } = params;
|
|
12136
12380
|
const { env } = proc;
|
|
12137
12381
|
const decided = decideLaunch(params, false);
|
|
@@ -12152,14 +12396,17 @@ function prepareLaunch(params) {
|
|
|
12152
12396
|
})
|
|
12153
12397
|
];
|
|
12154
12398
|
let warnings = [];
|
|
12399
|
+
let unregisterLaunch;
|
|
12155
12400
|
const updateCheck = runLaunchUpdateCheck({
|
|
12156
12401
|
mode: params.updateMode ?? "off",
|
|
12157
|
-
checkPath:
|
|
12402
|
+
checkPath: path41.join(paths.root, "update.check"),
|
|
12158
12403
|
currentVersion: package_default.version,
|
|
12159
12404
|
port: params.update
|
|
12160
12405
|
});
|
|
12161
12406
|
if (decided.farmContext !== void 0) {
|
|
12162
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);
|
|
12163
12410
|
let result;
|
|
12164
12411
|
try {
|
|
12165
12412
|
result = resyncFarm({
|
|
@@ -12177,10 +12424,11 @@ function prepareLaunch(params) {
|
|
|
12177
12424
|
classification: resyncFarmRuntime.classification,
|
|
12178
12425
|
now: resyncFarmRuntime.now,
|
|
12179
12426
|
uniqueSuffix: resyncFarmRuntime.uniqueSuffix,
|
|
12427
|
+
identityExists: () => loadIdentity(paths.identitiesDir, resyncIdentity, params.fs) !== void 0,
|
|
12180
12428
|
lock: resyncFarmRuntime.lock
|
|
12181
12429
|
});
|
|
12182
12430
|
} catch (error) {
|
|
12183
|
-
if (error instanceof IdentityLockBusyError) {
|
|
12431
|
+
if (error instanceof IdentityLockBusyError || error instanceof IdentityGoneError) {
|
|
12184
12432
|
log.error(error.message);
|
|
12185
12433
|
proc.exit(1);
|
|
12186
12434
|
}
|
|
@@ -12240,7 +12488,7 @@ function prepareLaunch(params) {
|
|
|
12240
12488
|
proxyBypass: resolvedFlags.proxyBypass,
|
|
12241
12489
|
...resolvedFlags.statusline === void 0 ? {} : { statusline: resolvedFlags.statusline }
|
|
12242
12490
|
});
|
|
12243
|
-
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]];
|
|
12244
12492
|
const release = () => {
|
|
12245
12493
|
for (const registered of releases) {
|
|
12246
12494
|
registered();
|
|
@@ -12309,6 +12557,7 @@ var init_launcher = __esm({
|
|
|
12309
12557
|
init_argv();
|
|
12310
12558
|
init_cliOverride();
|
|
12311
12559
|
init_farm();
|
|
12560
|
+
init_launchRecords();
|
|
12312
12561
|
init_guard();
|
|
12313
12562
|
init_identity();
|
|
12314
12563
|
init_flags();
|
|
@@ -12344,12 +12593,12 @@ var init_launcher = __esm({
|
|
|
12344
12593
|
});
|
|
12345
12594
|
|
|
12346
12595
|
// src/ownCli.ts
|
|
12347
|
-
import
|
|
12596
|
+
import path42 from "node:path";
|
|
12348
12597
|
function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string" ? __AGENT_SHIM_DIST_DIR__ : void 0) {
|
|
12349
12598
|
if (distDir === void 0) {
|
|
12350
12599
|
throw new OwnCliPathUnknownError();
|
|
12351
12600
|
}
|
|
12352
|
-
return
|
|
12601
|
+
return path42.join(distDir, OWN_CLI_FILE_NAME);
|
|
12353
12602
|
}
|
|
12354
12603
|
var OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
12355
12604
|
var init_ownCli = __esm({
|
|
@@ -12367,10 +12616,10 @@ var init_ownCli = __esm({
|
|
|
12367
12616
|
});
|
|
12368
12617
|
|
|
12369
12618
|
// src/frontdoor/doorLog.ts
|
|
12370
|
-
import
|
|
12619
|
+
import fs13 from "node:fs";
|
|
12371
12620
|
function appendDoorLog(paths, line) {
|
|
12372
|
-
|
|
12373
|
-
|
|
12621
|
+
fs13.mkdirSync(paths.logsDir, { recursive: true });
|
|
12622
|
+
fs13.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
12374
12623
|
`);
|
|
12375
12624
|
}
|
|
12376
12625
|
var init_doorLog = __esm({
|
|
@@ -12395,16 +12644,16 @@ var init_selfIdentity = __esm({
|
|
|
12395
12644
|
|
|
12396
12645
|
// src/frontdoor/trust.ts
|
|
12397
12646
|
import { createHash as createHash7 } from "node:crypto";
|
|
12398
|
-
import
|
|
12647
|
+
import path43 from "node:path";
|
|
12399
12648
|
function resolveTrustBundle(params) {
|
|
12400
|
-
const { caCertFile, bundlesDir, variable, inherited, fs:
|
|
12401
|
-
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)) {
|
|
12402
12651
|
return { path: caCertFile };
|
|
12403
12652
|
}
|
|
12404
|
-
const caPem =
|
|
12653
|
+
const caPem = fs15.readFileUtf8(caCertFile);
|
|
12405
12654
|
let inheritedPem;
|
|
12406
12655
|
try {
|
|
12407
|
-
inheritedPem =
|
|
12656
|
+
inheritedPem = fs15.readFileUtf8(inherited);
|
|
12408
12657
|
} catch (error) {
|
|
12409
12658
|
return {
|
|
12410
12659
|
path: caCertFile,
|
|
@@ -12416,10 +12665,10 @@ function resolveTrustBundle(params) {
|
|
|
12416
12665
|
}
|
|
12417
12666
|
const combined = `${inheritedPem.trimEnd()}
|
|
12418
12667
|
${caPem}`;
|
|
12419
|
-
const bundle =
|
|
12420
|
-
if (!
|
|
12421
|
-
|
|
12422
|
-
|
|
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);
|
|
12423
12672
|
}
|
|
12424
12673
|
return { path: bundle };
|
|
12425
12674
|
}
|
|
@@ -12432,7 +12681,7 @@ var init_trust = __esm({
|
|
|
12432
12681
|
});
|
|
12433
12682
|
|
|
12434
12683
|
// src/frontdoor/realFrontDoorPort.ts
|
|
12435
|
-
import
|
|
12684
|
+
import fs14 from "node:fs";
|
|
12436
12685
|
function realEnsurePorts(paths, spawnDaemon) {
|
|
12437
12686
|
return {
|
|
12438
12687
|
fs: realFarmFs,
|
|
@@ -12458,7 +12707,7 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
12458
12707
|
}
|
|
12459
12708
|
},
|
|
12460
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.
|
|
12461
|
-
verifyListener: (port) => probeFrontDoorSync(port,
|
|
12710
|
+
verifyListener: (port) => probeFrontDoorSync(port, fs14.readFileSync(paths.frontdoorCaCertFile, "utf8"))
|
|
12462
12711
|
};
|
|
12463
12712
|
}
|
|
12464
12713
|
function realFrontDoorPort(paths, spawnDaemon) {
|
|
@@ -12491,10 +12740,10 @@ var init_realFrontDoorPort = __esm({
|
|
|
12491
12740
|
init_selfIdentity();
|
|
12492
12741
|
init_trust();
|
|
12493
12742
|
realTrustBundleFs = {
|
|
12494
|
-
readFileUtf8: (file) =>
|
|
12495
|
-
exists: (file) =>
|
|
12743
|
+
readFileUtf8: (file) => fs14.readFileSync(file, "utf8"),
|
|
12744
|
+
exists: (file) => fs14.existsSync(file),
|
|
12496
12745
|
mkdirp: (dir) => {
|
|
12497
|
-
|
|
12746
|
+
fs14.mkdirSync(dir, { recursive: true });
|
|
12498
12747
|
},
|
|
12499
12748
|
writeFileAtomic: (file, contents) => {
|
|
12500
12749
|
realFarmFs.writeFilePrivate(file, contents);
|
|
@@ -12503,53 +12752,9 @@ var init_realFrontDoorPort = __esm({
|
|
|
12503
12752
|
}
|
|
12504
12753
|
});
|
|
12505
12754
|
|
|
12506
|
-
// src/replayRun.ts
|
|
12507
|
-
function keyOf2(command, args) {
|
|
12508
|
-
return JSON.stringify([command, args]);
|
|
12509
|
-
}
|
|
12510
|
-
async function recordRuns(decide, runAsync) {
|
|
12511
|
-
const answers = /* @__PURE__ */ new Map();
|
|
12512
|
-
const replay = {
|
|
12513
|
-
run: (command, args) => {
|
|
12514
|
-
const answer = answers.get(keyOf2(command, args));
|
|
12515
|
-
if (answer === void 0) {
|
|
12516
|
-
throw new RunNeededError(command, args);
|
|
12517
|
-
}
|
|
12518
|
-
return answer;
|
|
12519
|
-
}
|
|
12520
|
-
};
|
|
12521
|
-
for (; ; ) {
|
|
12522
|
-
try {
|
|
12523
|
-
decide(replay);
|
|
12524
|
-
return replay;
|
|
12525
|
-
} catch (error) {
|
|
12526
|
-
if (!(error instanceof RunNeededError)) {
|
|
12527
|
-
throw error;
|
|
12528
|
-
}
|
|
12529
|
-
answers.set(keyOf2(error.command, error.args), await runAsync(error.command, error.args));
|
|
12530
|
-
}
|
|
12531
|
-
}
|
|
12532
|
-
}
|
|
12533
|
-
var RunNeededError;
|
|
12534
|
-
var init_replayRun = __esm({
|
|
12535
|
-
"src/replayRun.ts"() {
|
|
12536
|
-
"use strict";
|
|
12537
|
-
RunNeededError = class extends Error {
|
|
12538
|
-
constructor(command, args) {
|
|
12539
|
-
super(`no recorded answer for ${command} ${args.join(" ")}`);
|
|
12540
|
-
this.command = command;
|
|
12541
|
-
this.args = args;
|
|
12542
|
-
this.name = "RunNeededError";
|
|
12543
|
-
}
|
|
12544
|
-
command;
|
|
12545
|
-
args;
|
|
12546
|
-
};
|
|
12547
|
-
}
|
|
12548
|
-
});
|
|
12549
|
-
|
|
12550
12755
|
// src/launchWiring.ts
|
|
12551
12756
|
import os8 from "node:os";
|
|
12552
|
-
import
|
|
12757
|
+
import path44 from "node:path";
|
|
12553
12758
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
12554
12759
|
function buildFarmRuntime(paths, cwd, run = realRunPort) {
|
|
12555
12760
|
const home = os8.homedir();
|
|
@@ -12604,7 +12809,7 @@ function realPrepareLaunchParams(paths, options) {
|
|
|
12604
12809
|
frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
|
|
12605
12810
|
credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
|
|
12606
12811
|
hold: realHoldPort,
|
|
12607
|
-
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",
|
|
12608
12813
|
...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
|
|
12609
12814
|
...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
|
|
12610
12815
|
...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
|
|
@@ -12889,7 +13094,7 @@ var init_identityClaude = __esm({
|
|
|
12889
13094
|
});
|
|
12890
13095
|
|
|
12891
13096
|
// src/usage/providerQuota.ts
|
|
12892
|
-
import { z as
|
|
13097
|
+
import { z as z37 } from "zod";
|
|
12893
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;
|
|
12894
13099
|
var init_providerQuota = __esm({
|
|
12895
13100
|
"src/usage/providerQuota.ts"() {
|
|
@@ -12908,35 +13113,35 @@ var init_providerQuota = __esm({
|
|
|
12908
13113
|
[ZAI_UNIT_HOURS, SECONDS_PER_HOUR3 * MS_PER_SECOND9],
|
|
12909
13114
|
[ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9]
|
|
12910
13115
|
]);
|
|
12911
|
-
ZaiLimitSchema =
|
|
12912
|
-
type:
|
|
12913
|
-
unit:
|
|
12914
|
-
number:
|
|
12915
|
-
percentage:
|
|
12916
|
-
nextResetTime:
|
|
12917
|
-
usage:
|
|
12918
|
-
currentValue:
|
|
12919
|
-
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()
|
|
12920
13125
|
});
|
|
12921
|
-
ZaiResponseSchema =
|
|
12922
|
-
success:
|
|
12923
|
-
msg:
|
|
12924
|
-
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) })
|
|
12925
13130
|
});
|
|
12926
13131
|
OPENROUTER_HOST = "openrouter.ai";
|
|
12927
13132
|
OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
|
|
12928
13133
|
OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
|
|
12929
13134
|
MS_PER_DAY2 = HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
|
|
12930
|
-
OpenRouterKeySchema =
|
|
12931
|
-
data:
|
|
12932
|
-
limit:
|
|
12933
|
-
limit_remaining:
|
|
12934
|
-
limit_reset:
|
|
12935
|
-
is_free_tier:
|
|
12936
|
-
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()
|
|
12937
13142
|
})
|
|
12938
13143
|
});
|
|
12939
|
-
OpenRouterCreditsSchema =
|
|
13144
|
+
OpenRouterCreditsSchema = z37.object({ data: z37.object({ total_credits: z37.number().nonnegative(), total_usage: z37.number().nonnegative() }) });
|
|
12940
13145
|
ANTIGRAVITY_HOST = "daily-cloudcode-pa.googleapis.com";
|
|
12941
13146
|
ANTIGRAVITY_QUOTA_URL = `https://${ANTIGRAVITY_HOST}/v1internal:retrieveUserQuotaSummary`;
|
|
12942
13147
|
ANTIGRAVITY_USER_URL = `https://${ANTIGRAVITY_HOST}/v1internal:loadCodeAssist`;
|
|
@@ -12944,21 +13149,21 @@ var init_providerQuota = __esm({
|
|
|
12944
13149
|
DAYS_PER_WEEK2 = 7;
|
|
12945
13150
|
FIVE_HOURS_MS = FIVE_HOURS2 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
|
|
12946
13151
|
WEEK_MS = DAYS_PER_WEEK2 * HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
|
|
12947
|
-
AntigravityBucketSchema =
|
|
12948
|
-
bucketId:
|
|
12949
|
-
remainingFraction:
|
|
12950
|
-
resetTime:
|
|
13152
|
+
AntigravityBucketSchema = z37.object({
|
|
13153
|
+
bucketId: z37.string(),
|
|
13154
|
+
remainingFraction: z37.number().optional(),
|
|
13155
|
+
resetTime: z37.string().optional()
|
|
12951
13156
|
});
|
|
12952
|
-
AntigravitySummarySchema =
|
|
12953
|
-
GoogleTokenInfoSchema =
|
|
12954
|
-
email:
|
|
12955
|
-
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()
|
|
12956
13161
|
});
|
|
12957
|
-
AntigravityUserSchema =
|
|
13162
|
+
AntigravityUserSchema = z37.object({
|
|
12958
13163
|
/** The code-assist tier context, which defaults to the free tier for every account. */
|
|
12959
|
-
currentTier:
|
|
13164
|
+
currentTier: z37.object({ name: z37.string().optional(), id: z37.string().optional() }).optional(),
|
|
12960
13165
|
/** The account's paid subscription; absent when the account has none. */
|
|
12961
|
-
paidTier:
|
|
13166
|
+
paidTier: z37.object({ name: z37.string().optional(), id: z37.string().optional() }).optional()
|
|
12962
13167
|
});
|
|
12963
13168
|
}
|
|
12964
13169
|
});
|
|
@@ -13337,8 +13542,8 @@ function pathnameOf(url) {
|
|
|
13337
13542
|
return new URL(url ?? "/", "http://127.0.0.1").pathname;
|
|
13338
13543
|
}
|
|
13339
13544
|
function isRcSessionExchange(url) {
|
|
13340
|
-
const
|
|
13341
|
-
return
|
|
13545
|
+
const path45 = pathnameOf(url);
|
|
13546
|
+
return path45 === RC_SESSIONS_PATH_PREFIX || path45.startsWith(`${RC_SESSIONS_PATH_PREFIX}/`);
|
|
13342
13547
|
}
|
|
13343
13548
|
var RC_SESSION_ID_PREFIX = "cse_";
|
|
13344
13549
|
var RC_IDLE_EXPIRY_MS = 45e3;
|
|
@@ -13897,8 +14102,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
13897
14102
|
function isRcReadFileEncoding(value) {
|
|
13898
14103
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
13899
14104
|
}
|
|
13900
|
-
function buildRcReadFilePayload(requestId,
|
|
13901
|
-
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 } });
|
|
13902
14107
|
}
|
|
13903
14108
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
13904
14109
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -14000,15 +14205,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
14000
14205
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
14001
14206
|
return result.ok ? { ...result, requestId } : result;
|
|
14002
14207
|
}
|
|
14003
|
-
async function readRcSessionFile(deps, sessionId,
|
|
14004
|
-
if (
|
|
14208
|
+
async function readRcSessionFile(deps, sessionId, path45, options) {
|
|
14209
|
+
if (path45 === "") {
|
|
14005
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" };
|
|
14006
14211
|
}
|
|
14007
14212
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
14008
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" };
|
|
14009
14214
|
}
|
|
14010
14215
|
const requestId = deps.newUuid();
|
|
14011
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
14216
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path45, options), `read ${path45} from session ${sessionId}`);
|
|
14012
14217
|
return result.ok ? { ...result, requestId } : result;
|
|
14013
14218
|
}
|
|
14014
14219
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -14177,11 +14382,11 @@ function createRcControlHandler(deps) {
|
|
|
14177
14382
|
path: "read-file",
|
|
14178
14383
|
read: (body) => {
|
|
14179
14384
|
const session = bodyString(body, "session");
|
|
14180
|
-
const
|
|
14385
|
+
const path45 = bodyString(body, "path");
|
|
14181
14386
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
14182
14387
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
14183
|
-
const refused2 = session === void 0 ||
|
|
14184
|
-
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 } }) };
|
|
14185
14390
|
}
|
|
14186
14391
|
},
|
|
14187
14392
|
{
|
|
@@ -14491,9 +14696,9 @@ function requestIdOfBody(body) {
|
|
|
14491
14696
|
}
|
|
14492
14697
|
function frontDoorRcControl(transport, token) {
|
|
14493
14698
|
const headers = { authorization: `Bearer ${token}` };
|
|
14494
|
-
const listAnswerOf = async (
|
|
14699
|
+
const listAnswerOf = async (path45, what) => {
|
|
14495
14700
|
try {
|
|
14496
|
-
return await transport.request({ method: "GET", path:
|
|
14701
|
+
return await transport.request({ method: "GET", path: path45, headers });
|
|
14497
14702
|
} catch (error) {
|
|
14498
14703
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
14499
14704
|
}
|
|
@@ -14565,10 +14770,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
14565
14770
|
}
|
|
14566
14771
|
return pending;
|
|
14567
14772
|
};
|
|
14568
|
-
const writeOf = async (
|
|
14773
|
+
const writeOf = async (path45, body, describeFailure2) => {
|
|
14569
14774
|
let answer;
|
|
14570
14775
|
try {
|
|
14571
|
-
answer = await transport.request({ method: "POST", path:
|
|
14776
|
+
answer = await transport.request({ method: "POST", path: path45, headers: { ...headers, "content-type": "application/json" }, body });
|
|
14572
14777
|
} catch (error) {
|
|
14573
14778
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
14574
14779
|
}
|
|
@@ -14599,10 +14804,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
14599
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}`),
|
|
14600
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}`),
|
|
14601
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}`),
|
|
14602
|
-
readFile: async (sessionId,
|
|
14807
|
+
readFile: async (sessionId, path45, options) => await writeOf(
|
|
14603
14808
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
14604
|
-
JSON.stringify({ session: sessionId, path:
|
|
14605
|
-
(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}`
|
|
14606
14811
|
),
|
|
14607
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}`),
|
|
14608
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}`),
|
|
@@ -14761,12 +14966,12 @@ function tlsFacts(options) {
|
|
|
14761
14966
|
}
|
|
14762
14967
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
14763
14968
|
const agent = new ExemptTlsAgent();
|
|
14764
|
-
const post = async (
|
|
14969
|
+
const post = async (path45, headers, body) => await new Promise((resolve, reject) => {
|
|
14765
14970
|
const options = {
|
|
14766
14971
|
host: target.host,
|
|
14767
14972
|
port: target.port,
|
|
14768
14973
|
method: "POST",
|
|
14769
|
-
path:
|
|
14974
|
+
path: path45,
|
|
14770
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.
|
|
14771
14976
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
14772
14977
|
agent
|
|
@@ -14831,12 +15036,12 @@ function lateRcStreamDial(resolve) {
|
|
|
14831
15036
|
}
|
|
14832
15037
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
14833
15038
|
const agent = new ExemptTlsAgent();
|
|
14834
|
-
const request4 = async (method,
|
|
15039
|
+
const request4 = async (method, path45, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
14835
15040
|
const options = {
|
|
14836
15041
|
host: target.host,
|
|
14837
15042
|
port: target.port,
|
|
14838
15043
|
method,
|
|
14839
|
-
path:
|
|
15044
|
+
path: path45,
|
|
14840
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.
|
|
14841
15046
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
14842
15047
|
agent,
|
|
@@ -14878,9 +15083,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
14878
15083
|
return { status, body: await readAll(response) };
|
|
14879
15084
|
},
|
|
14880
15085
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
14881
|
-
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)}`;
|
|
14882
15087
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
14883
|
-
const { status, response } = await request4("GET",
|
|
15088
|
+
const { status, response } = await request4("GET", path45, streamHeaders, void 0, signal);
|
|
14884
15089
|
if (!isSuccessful2(status)) {
|
|
14885
15090
|
await readAll(response);
|
|
14886
15091
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -15130,11 +15335,11 @@ function credentialOfJson(parsed) {
|
|
|
15130
15335
|
function sequenceNumOfJson(value) {
|
|
15131
15336
|
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
15132
15337
|
}
|
|
15133
|
-
function createRcCredentialStore(
|
|
15134
|
-
|
|
15338
|
+
function createRcCredentialStore(fs15, dir) {
|
|
15339
|
+
fs15.mkdirPrivate(dir);
|
|
15135
15340
|
const fileFor = (sessionId) => path11.join(dir, `${sessionId}.json`);
|
|
15136
15341
|
const readParsed = (sessionId) => {
|
|
15137
|
-
const raw =
|
|
15342
|
+
const raw = fs15.readFileUtf8(fileFor(sessionId));
|
|
15138
15343
|
if (raw === void 0) {
|
|
15139
15344
|
return void 0;
|
|
15140
15345
|
}
|
|
@@ -15159,7 +15364,7 @@ function createRcCredentialStore(fs14, dir) {
|
|
|
15159
15364
|
}
|
|
15160
15365
|
const cursor = sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
|
|
15161
15366
|
const record = { ...credential, ...cursor === void 0 ? {} : { highestSequenceNum: cursor } };
|
|
15162
|
-
|
|
15367
|
+
fs15.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
|
|
15163
15368
|
`);
|
|
15164
15369
|
},
|
|
15165
15370
|
readCursor: (sessionId) => {
|
|
@@ -15174,14 +15379,14 @@ function createRcCredentialStore(fs14, dir) {
|
|
|
15174
15379
|
}
|
|
15175
15380
|
const credential = credentialOfJson(readParsed(sessionId));
|
|
15176
15381
|
const record = credential === void 0 ? { highestSequenceNum } : { ...credential, highestSequenceNum };
|
|
15177
|
-
|
|
15382
|
+
fs15.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
|
|
15178
15383
|
`);
|
|
15179
15384
|
},
|
|
15180
15385
|
remove: (sessionId) => {
|
|
15181
15386
|
if (!isSafeSessionId(sessionId)) {
|
|
15182
15387
|
return;
|
|
15183
15388
|
}
|
|
15184
|
-
|
|
15389
|
+
fs15.removeRecursive(fileFor(sessionId));
|
|
15185
15390
|
}
|
|
15186
15391
|
};
|
|
15187
15392
|
}
|
|
@@ -15873,19 +16078,19 @@ function writePools(paths, pools) {
|
|
|
15873
16078
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
15874
16079
|
}
|
|
15875
16080
|
function poolCycleOf(pools, name) {
|
|
15876
|
-
const walk2 = (current,
|
|
16081
|
+
const walk2 = (current, path45) => {
|
|
15877
16082
|
for (const entry of pools[current]?.identities ?? []) {
|
|
15878
16083
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
15879
16084
|
if (nested === void 0) {
|
|
15880
16085
|
continue;
|
|
15881
16086
|
}
|
|
15882
16087
|
if (nested === name) {
|
|
15883
|
-
return [...
|
|
16088
|
+
return [...path45, nested];
|
|
15884
16089
|
}
|
|
15885
|
-
if (
|
|
16090
|
+
if (path45.includes(nested)) {
|
|
15886
16091
|
continue;
|
|
15887
16092
|
}
|
|
15888
|
-
const found = walk2(nested, [...
|
|
16093
|
+
const found = walk2(nested, [...path45, nested]);
|
|
15889
16094
|
if (found !== void 0) {
|
|
15890
16095
|
return found;
|
|
15891
16096
|
}
|
|
@@ -16325,7 +16530,7 @@ function loadCheckProvider(paths, name) {
|
|
|
16325
16530
|
try {
|
|
16326
16531
|
definition = readProvider(paths, name);
|
|
16327
16532
|
} catch (error) {
|
|
16328
|
-
if (error instanceof ConfigValidationError || error instanceof LegacyProviderFileError) {
|
|
16533
|
+
if (error instanceof ConfigValidationError || error instanceof LegacyProviderFileError || error instanceof ConfigFileNotJsonError) {
|
|
16329
16534
|
return { name, problem: error.message };
|
|
16330
16535
|
}
|
|
16331
16536
|
throw error;
|
|
@@ -16597,8 +16802,8 @@ var ResetRowSchema = z22.strictObject({
|
|
|
16597
16802
|
var ResetScheduleSchema = z22.strictObject({ resets: z22.readonly(z22.array(ResetRowSchema)) });
|
|
16598
16803
|
|
|
16599
16804
|
// src/frontdoor/controlSchemas.ts
|
|
16600
|
-
import
|
|
16601
|
-
import { z as
|
|
16805
|
+
import path32 from "node:path";
|
|
16806
|
+
import { z as z30 } from "zod";
|
|
16602
16807
|
|
|
16603
16808
|
// src/doctorReport.ts
|
|
16604
16809
|
init_claudeShim();
|
|
@@ -16607,13 +16812,211 @@ init_store();
|
|
|
16607
16812
|
|
|
16608
16813
|
// src/identityStore.ts
|
|
16609
16814
|
init_load();
|
|
16815
|
+
init_names();
|
|
16610
16816
|
init_store();
|
|
16611
16817
|
init_schema();
|
|
16612
16818
|
init_cliError();
|
|
16613
16819
|
init_identity();
|
|
16614
|
-
import
|
|
16615
|
-
import
|
|
16820
|
+
import fs10 from "node:fs";
|
|
16821
|
+
import path30 from "node:path";
|
|
16616
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
|
|
16617
17020
|
var IdentityNotFoundError = class extends CliError {
|
|
16618
17021
|
constructor(name) {
|
|
16619
17022
|
super(`No identity named "${name}". Run \`agent-shim identity add ${name}\` first.`);
|
|
@@ -16641,7 +17044,7 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
16641
17044
|
attemptedName;
|
|
16642
17045
|
};
|
|
16643
17046
|
function identityJsonPath(paths, name) {
|
|
16644
|
-
return
|
|
17047
|
+
return path30.join(paths.identitiesDir, name, "identity.json");
|
|
16645
17048
|
}
|
|
16646
17049
|
function requireIdentityNames(paths, names) {
|
|
16647
17050
|
const existing = new Set(listIdentities(paths).map((entry) => entry.name));
|
|
@@ -16652,21 +17055,23 @@ function requireIdentityNames(paths, names) {
|
|
|
16652
17055
|
}
|
|
16653
17056
|
}
|
|
16654
17057
|
function identityExists(paths, name) {
|
|
16655
|
-
return
|
|
17058
|
+
return fs10.existsSync(identityJsonPath(paths, name));
|
|
16656
17059
|
}
|
|
16657
17060
|
function readIdentity(paths, name) {
|
|
16658
17061
|
return readJson(identityJsonPath(paths, name), IdentitySchema);
|
|
16659
17062
|
}
|
|
16660
|
-
function
|
|
17063
|
+
function requireIdentityCreatable(paths, name) {
|
|
17064
|
+
requireNoUnfinishedRenameNaming(paths, name, "add");
|
|
16661
17065
|
if (identityExists(paths, name)) {
|
|
16662
17066
|
throw new IdentityAlreadyExistsError(name);
|
|
16663
17067
|
}
|
|
16664
|
-
|
|
16665
|
-
|
|
16666
|
-
|
|
16667
|
-
|
|
16668
|
-
|
|
16669
|
-
|
|
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;
|
|
16670
17075
|
}
|
|
16671
17076
|
function useIdentity(paths, name) {
|
|
16672
17077
|
const pool = poolNameOf(name);
|
|
@@ -16679,33 +17084,89 @@ function useIdentity(paths, name) {
|
|
|
16679
17084
|
`);
|
|
16680
17085
|
}
|
|
16681
17086
|
function readActiveIdentity2(paths) {
|
|
16682
|
-
if (!
|
|
17087
|
+
if (!fs10.existsSync(paths.activeIdentityFile)) {
|
|
16683
17088
|
return void 0;
|
|
16684
17089
|
}
|
|
16685
|
-
const raw =
|
|
17090
|
+
const raw = fs10.readFileSync(paths.activeIdentityFile, "utf8").trim();
|
|
16686
17091
|
return raw === "" ? void 0 : raw;
|
|
16687
17092
|
}
|
|
16688
17093
|
function isIdentityDirectoryName(name) {
|
|
16689
17094
|
return !name.startsWith(".");
|
|
16690
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";
|
|
16691
17150
|
function readIdentityForListing(paths, name) {
|
|
16692
17151
|
try {
|
|
16693
17152
|
return readIdentity(paths, name);
|
|
16694
17153
|
} catch (error) {
|
|
16695
|
-
if (error instanceof
|
|
17154
|
+
if (error instanceof ConfigFileNotJsonError) {
|
|
17155
|
+
return { problem: NOT_JSON_PROBLEM };
|
|
17156
|
+
}
|
|
17157
|
+
if (error instanceof ConfigValidationError) {
|
|
16696
17158
|
return { problem: error.message.replace(/\s*\n\s*/g, " ") };
|
|
16697
17159
|
}
|
|
16698
17160
|
throw error;
|
|
16699
17161
|
}
|
|
16700
17162
|
}
|
|
16701
17163
|
function listIdentities(paths) {
|
|
16702
|
-
if (!
|
|
17164
|
+
if (!fs10.existsSync(paths.identitiesDir)) {
|
|
16703
17165
|
return [];
|
|
16704
17166
|
}
|
|
16705
17167
|
const active = readActiveIdentity2(paths);
|
|
16706
|
-
const names = fs9.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort();
|
|
16707
17168
|
const result = [];
|
|
16708
|
-
for (const name of names) {
|
|
17169
|
+
for (const name of listIdentityDirectories(paths).names) {
|
|
16709
17170
|
const read = readIdentityForListing(paths, name);
|
|
16710
17171
|
if (read === void 0) {
|
|
16711
17172
|
continue;
|
|
@@ -16715,6 +17176,10 @@ function listIdentities(paths) {
|
|
|
16715
17176
|
}
|
|
16716
17177
|
return result;
|
|
16717
17178
|
}
|
|
17179
|
+
function requireIdentityAddable(paths, name, keychain, keepKeychainLogin) {
|
|
17180
|
+
requireIdentityCreatable(paths, name);
|
|
17181
|
+
requireNoLeftoverKeychainLogin(keychain, path30.join(paths.identitiesDir, name), name, keepKeychainLogin);
|
|
17182
|
+
}
|
|
16718
17183
|
function setIdentityAnchors(paths, identityName, anchors) {
|
|
16719
17184
|
if (!identityExists(paths, identityName)) {
|
|
16720
17185
|
throw new IdentityNotFoundError(identityName);
|
|
@@ -16767,49 +17232,70 @@ function setIdentityCredential(paths, identityName, change) {
|
|
|
16767
17232
|
credential: { sources: [...sources], ...target === void 0 ? {} : { target }, ...cache === void 0 ? {} : { cache } }
|
|
16768
17233
|
});
|
|
16769
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
|
+
}
|
|
16770
17243
|
function belongsToIdentity(entry, name) {
|
|
16771
|
-
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));
|
|
16772
17256
|
}
|
|
16773
17257
|
function removeIdentity(paths, name) {
|
|
17258
|
+
requireNoUnfinishedRenameNaming(paths, name, "remove");
|
|
16774
17259
|
if (!identityExists(paths, name)) {
|
|
16775
17260
|
throw new IdentityNotFoundError(name);
|
|
16776
17261
|
}
|
|
16777
|
-
for (const entry of
|
|
17262
|
+
for (const entry of fs10.readdirSync(paths.identitiesDir)) {
|
|
16778
17263
|
if (belongsToIdentity(entry, name)) {
|
|
16779
|
-
|
|
17264
|
+
fs10.rmSync(path30.join(paths.identitiesDir, entry), { recursive: true, force: true });
|
|
16780
17265
|
}
|
|
16781
17266
|
}
|
|
16782
17267
|
if (readActiveIdentity2(paths) === name) {
|
|
16783
|
-
|
|
17268
|
+
fs10.rmSync(paths.activeIdentityFile);
|
|
16784
17269
|
}
|
|
16785
17270
|
}
|
|
16786
17271
|
|
|
16787
17272
|
// src/doctorReport.ts
|
|
16788
17273
|
init_realPorts();
|
|
16789
|
-
import
|
|
16790
|
-
import
|
|
17274
|
+
import fs12 from "node:fs";
|
|
17275
|
+
import path31 from "node:path";
|
|
16791
17276
|
init_signIn();
|
|
16792
17277
|
init_identityAccounts();
|
|
17278
|
+
init_read();
|
|
16793
17279
|
|
|
16794
17280
|
// src/codex/siwcStore.ts
|
|
16795
|
-
import { z as
|
|
17281
|
+
import { z as z27 } from "zod";
|
|
16796
17282
|
|
|
16797
17283
|
// src/codex/auth.ts
|
|
16798
|
-
import { z as
|
|
16799
|
-
var AuthFileSchema =
|
|
16800
|
-
tokens:
|
|
16801
|
-
access_token:
|
|
16802
|
-
refresh_token:
|
|
16803
|
-
id_token:
|
|
16804
|
-
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()
|
|
16805
17291
|
}).nullish(),
|
|
16806
|
-
last_refresh:
|
|
17292
|
+
last_refresh: z25.string().optional()
|
|
16807
17293
|
});
|
|
16808
|
-
var TokenGrantSchema =
|
|
16809
|
-
access_token:
|
|
16810
|
-
refresh_token:
|
|
16811
|
-
id_token:
|
|
16812
|
-
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()
|
|
16813
17299
|
});
|
|
16814
17300
|
var CodexAuthError = class extends Error {
|
|
16815
17301
|
constructor(message) {
|
|
@@ -16819,41 +17305,41 @@ var CodexAuthError = class extends Error {
|
|
|
16819
17305
|
};
|
|
16820
17306
|
|
|
16821
17307
|
// src/codex/siwc.ts
|
|
16822
|
-
import { z as
|
|
17308
|
+
import { z as z26 } from "zod";
|
|
16823
17309
|
var SIWC_RESOURCE = "https://api.openai.com/v1";
|
|
16824
17310
|
var SIWC_RESPONSES_URL = `${SIWC_RESOURCE}/responses`;
|
|
16825
17311
|
var SIWC_PLAN_SCOPE = "chatgpt.tokens.use.direct";
|
|
16826
|
-
var TokenResponseSchema =
|
|
16827
|
-
access_token:
|
|
16828
|
-
refresh_token:
|
|
16829
|
-
id_token:
|
|
16830
|
-
expires_in:
|
|
16831
|
-
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()
|
|
16832
17318
|
});
|
|
16833
|
-
var JwtHeaderSchema =
|
|
16834
|
-
var IdTokenClaimsSchema =
|
|
16835
|
-
iss:
|
|
16836
|
-
sub:
|
|
16837
|
-
aud:
|
|
16838
|
-
exp:
|
|
16839
|
-
nonce:
|
|
16840
|
-
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()
|
|
16841
17327
|
});
|
|
16842
|
-
var JwksSchema =
|
|
17328
|
+
var JwksSchema = z26.object({ keys: z26.array(z26.looseObject({ kid: z26.string().optional(), kty: z26.string() })) });
|
|
16843
17329
|
|
|
16844
17330
|
// src/codex/siwcStore.ts
|
|
16845
|
-
var SiwcGrantSchema =
|
|
16846
|
-
clientId:
|
|
16847
|
-
sub:
|
|
16848
|
-
email:
|
|
16849
|
-
idToken:
|
|
16850
|
-
accessToken:
|
|
16851
|
-
refreshToken:
|
|
16852
|
-
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(),
|
|
16853
17339
|
/** When the access token stops working, in milliseconds since the epoch. */
|
|
16854
|
-
expiresAt:
|
|
17340
|
+
expiresAt: z27.number()
|
|
16855
17341
|
});
|
|
16856
|
-
var SiwcFileSchema =
|
|
17342
|
+
var SiwcFileSchema = z27.strictObject({ registeredClientId: z27.string().min(1).optional(), grant: SiwcGrantSchema.optional() });
|
|
16857
17343
|
function parseSiwcFile(raw, filePath) {
|
|
16858
17344
|
let json;
|
|
16859
17345
|
try {
|
|
@@ -17110,7 +17596,7 @@ function pushFrontDoorListeners(push, readings) {
|
|
|
17110
17596
|
|
|
17111
17597
|
// src/frontdoor/listenerReadings.ts
|
|
17112
17598
|
init_probe();
|
|
17113
|
-
import
|
|
17599
|
+
import fs11 from "node:fs";
|
|
17114
17600
|
function readFrontDoorListeners(state, supervisorAlive, probes) {
|
|
17115
17601
|
if (!supervisorAlive) {
|
|
17116
17602
|
return [];
|
|
@@ -17130,7 +17616,7 @@ function readFrontDoorListeners(state, supervisorAlive, probes) {
|
|
|
17130
17616
|
}
|
|
17131
17617
|
function realFrontDoorListenerProbes(paths) {
|
|
17132
17618
|
return {
|
|
17133
|
-
authenticateProvider: (port) => probeFrontDoorSync(port,
|
|
17619
|
+
authenticateProvider: (port) => probeFrontDoorSync(port, fs11.readFileSync(paths.frontdoorCaCertFile, "utf8")),
|
|
17134
17620
|
connect: probeListenerAcceptSync,
|
|
17135
17621
|
now: () => performance.now()
|
|
17136
17622
|
};
|
|
@@ -17163,6 +17649,82 @@ function describeSharedLoginMembers(poolName, shared) {
|
|
|
17163
17649
|
return `Pool "${poolName}" lists ${joinNames(shared.members)}, which hold the same login${holder === void 0 ? "" : ` (${holder})`}, so they share one quota window. A launch ranks them as one candidate and never fails over from one to another; keep one of them in the pool.`;
|
|
17164
17650
|
}
|
|
17165
17651
|
|
|
17652
|
+
// src/poolWindowReads.ts
|
|
17653
|
+
init_schema();
|
|
17654
|
+
init_identity();
|
|
17655
|
+
init_conditions();
|
|
17656
|
+
init_middleware();
|
|
17657
|
+
init_rateLimit();
|
|
17658
|
+
var WINDOW_NAMES = ["fiveHour", "sevenDay", "extraUsage"];
|
|
17659
|
+
var WINDOW_PROSE = { fiveHour: "five-hour", sevenDay: "seven-day", extraUsage: "extra-usage" };
|
|
17660
|
+
var WINDOW_FACTS = ["remaining", "utilization", "hoursUntilReset"];
|
|
17661
|
+
var DERIVED_FACTS = [{ key: "quota.burnPerHour", window: "fiveHour" }];
|
|
17662
|
+
function receivedWindows(snapshot) {
|
|
17663
|
+
const unified = snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified;
|
|
17664
|
+
if (unified === void 0) {
|
|
17665
|
+
return void 0;
|
|
17666
|
+
}
|
|
17667
|
+
return /* @__PURE__ */ new Set([...unified.fiveHour === void 0 ? [] : ["fiveHour"], ...unified.sevenDay === void 0 ? [] : ["sevenDay"], ...soleOverageWindow(unified) === void 0 ? [] : ["extraUsage"]]);
|
|
17668
|
+
}
|
|
17669
|
+
function conditionReads(when) {
|
|
17670
|
+
const direct = WINDOW_NAMES.flatMap((window) => WINDOW_FACTS.some((fact) => referencesFact(when, `quota.${window}.${fact}`)) ? [{ window, reference: `quota.${window}` }] : []);
|
|
17671
|
+
const derived = DERIVED_FACTS.flatMap(({ key, window }) => referencesFact(when, key) ? [{ window, reference: key }] : []);
|
|
17672
|
+
return [...direct, ...derived];
|
|
17673
|
+
}
|
|
17674
|
+
function identitiesOf(selector, pools, visited = /* @__PURE__ */ new Set()) {
|
|
17675
|
+
const nested = poolNameOf(selector);
|
|
17676
|
+
if (nested === void 0) {
|
|
17677
|
+
return [selector];
|
|
17678
|
+
}
|
|
17679
|
+
const pool = pools[nested];
|
|
17680
|
+
if (pool === void 0 || visited.has(nested)) {
|
|
17681
|
+
return [];
|
|
17682
|
+
}
|
|
17683
|
+
visited.add(nested);
|
|
17684
|
+
return [...new Set(pool.identities.flatMap((member) => identitiesOf(poolMemberIdentity(member), pools, visited)))];
|
|
17685
|
+
}
|
|
17686
|
+
function poolWindowReadFindings(pools, windowsOf) {
|
|
17687
|
+
const findings = [];
|
|
17688
|
+
for (const [poolName, pool] of Object.entries(pools)) {
|
|
17689
|
+
for (const member of pool.identities) {
|
|
17690
|
+
if (typeof member === "string") {
|
|
17691
|
+
continue;
|
|
17692
|
+
}
|
|
17693
|
+
const reads = conditionReads(member.when);
|
|
17694
|
+
for (const identity of identitiesOf(member.identity, pools)) {
|
|
17695
|
+
const received = windowsOf(identity);
|
|
17696
|
+
for (const { window, reference } of reads) {
|
|
17697
|
+
if (received !== void 0 && !received.has(window)) {
|
|
17698
|
+
findings.push({ subject: poolName, message: `Pool "${poolName}" guards ${member.identity} with a condition that reads ${reference}, but ${identity} reports no ${WINDOW_PROSE[window]} window, so the condition is undecided for it and it always ranks last within its class.` });
|
|
17699
|
+
}
|
|
17700
|
+
}
|
|
17701
|
+
}
|
|
17702
|
+
}
|
|
17703
|
+
if (pool.compactBeforeLimit === true) {
|
|
17704
|
+
for (const identity of identitiesOf(`pool:${poolName}`, pools)) {
|
|
17705
|
+
const received = windowsOf(identity);
|
|
17706
|
+
if (received !== void 0 && !received.has("fiveHour") && !received.has("sevenDay")) {
|
|
17707
|
+
findings.push({ subject: poolName, message: `Pool "${poolName}" compacts before the limit, but ${identity} reports no five-hour or seven-day window, so its sessions are never compacted before the limit.` });
|
|
17708
|
+
}
|
|
17709
|
+
}
|
|
17710
|
+
}
|
|
17711
|
+
}
|
|
17712
|
+
return findings;
|
|
17713
|
+
}
|
|
17714
|
+
function jobWindowReadFindings(jobs, pools, windowsOf) {
|
|
17715
|
+
return Object.entries(jobs).flatMap(([jobName, job]) => {
|
|
17716
|
+
const { trigger, target } = job;
|
|
17717
|
+
if (!("beforeReset" in trigger)) {
|
|
17718
|
+
return [];
|
|
17719
|
+
}
|
|
17720
|
+
const identities = "pool" in target ? identitiesOf(`pool:${target.pool}`, pools) : identitiesOf(target.identity, pools);
|
|
17721
|
+
return identities.flatMap((identity) => {
|
|
17722
|
+
const received = windowsOf(identity);
|
|
17723
|
+
return received === void 0 || received.has(trigger.beforeReset) ? [] : [{ subject: jobName, message: `Job "${jobName}" runs before the ${WINDOW_PROSE[trigger.beforeReset]} window resets, but ${identity} reports no ${WINDOW_PROSE[trigger.beforeReset]} window, so the job is skipped whenever it runs as ${identity}.` }];
|
|
17724
|
+
});
|
|
17725
|
+
});
|
|
17726
|
+
}
|
|
17727
|
+
|
|
17166
17728
|
// src/doctorReport.ts
|
|
17167
17729
|
init_extends();
|
|
17168
17730
|
var DOCTOR_SEVERITIES = ["pass", "warn", "fail"];
|
|
@@ -17199,8 +17761,8 @@ function validateJson(schema, input) {
|
|
|
17199
17761
|
let parsed;
|
|
17200
17762
|
try {
|
|
17201
17763
|
parsed = JSON.parse(input.raw);
|
|
17202
|
-
} catch
|
|
17203
|
-
return { ok: false, message: `${input.path} is not valid JSON
|
|
17764
|
+
} catch {
|
|
17765
|
+
return { ok: false, message: `${input.path} is not valid JSON.` };
|
|
17204
17766
|
}
|
|
17205
17767
|
const result = parseIgnoringUnrecognisedKeys(schema, parsed);
|
|
17206
17768
|
if (!result.success) {
|
|
@@ -17219,7 +17781,7 @@ function tcpPortEraRecord(raw) {
|
|
|
17219
17781
|
return (has("port") || has("lastPort")) && !has("socketPath");
|
|
17220
17782
|
}
|
|
17221
17783
|
function pushPathResolution(push, resolution) {
|
|
17222
|
-
const ownDir =
|
|
17784
|
+
const ownDir = path31.dirname(resolution.ownExecutablePath);
|
|
17223
17785
|
switch (resolution.agentShim.status) {
|
|
17224
17786
|
case "ok":
|
|
17225
17787
|
push("path-resolution", "pass", `\`agent-shim\` on PATH resolves to this running executable, ${resolution.ownExecutablePath}.`, "agent-shim");
|
|
@@ -17306,8 +17868,8 @@ function pushProvider(push, entry, cacheEnv, signIn) {
|
|
|
17306
17868
|
let parsed;
|
|
17307
17869
|
try {
|
|
17308
17870
|
parsed = JSON.parse(entry.raw);
|
|
17309
|
-
} catch
|
|
17310
|
-
push("provider", "fail", `${entry.path} is not valid JSON
|
|
17871
|
+
} catch {
|
|
17872
|
+
push("provider", "fail", `${entry.path} is not valid JSON.`, entry.name);
|
|
17311
17873
|
return;
|
|
17312
17874
|
}
|
|
17313
17875
|
const conversion = legacyProviderConversion(parsed);
|
|
@@ -17339,14 +17901,14 @@ function pushProvider(push, entry, cacheEnv, signIn) {
|
|
|
17339
17901
|
}
|
|
17340
17902
|
function pushLegacyName(push, params) {
|
|
17341
17903
|
const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
|
|
17342
|
-
if (legacyVariables.length === 0 &&
|
|
17904
|
+
if (legacyVariables.length === 0 && path31.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
|
|
17343
17905
|
push("legacy-name", "pass", "Nothing here still uses the former `claude-use` name.");
|
|
17344
17906
|
return;
|
|
17345
17907
|
}
|
|
17346
17908
|
for (const name of legacyVariables) {
|
|
17347
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);
|
|
17348
17910
|
}
|
|
17349
|
-
if (
|
|
17911
|
+
if (path31.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
|
|
17350
17912
|
push(
|
|
17351
17913
|
"legacy-name",
|
|
17352
17914
|
"warn",
|
|
@@ -17432,6 +17994,16 @@ function runDoctor(params) {
|
|
|
17432
17994
|
}
|
|
17433
17995
|
const validProfileNames = new Set(profileSources.keys());
|
|
17434
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
|
+
}
|
|
17435
18007
|
const validIdentityNames = /* @__PURE__ */ new Set();
|
|
17436
18008
|
const signedInAccounts = [];
|
|
17437
18009
|
for (const entry of params.identities) {
|
|
@@ -17531,6 +18103,17 @@ function runDoctor(params) {
|
|
|
17531
18103
|
reportedCycles.add(key);
|
|
17532
18104
|
push("pool", "fail", `Pool cycle: ${chain.join(" -> ")}. A pool cannot nest itself, directly or through another pool.`, chain[0]);
|
|
17533
18105
|
}
|
|
18106
|
+
const { usageSnapshots } = params;
|
|
18107
|
+
if (usageSnapshots !== void 0) {
|
|
18108
|
+
const windowsOf = (identityName) => receivedWindows(usageSnapshots[identityName]);
|
|
18109
|
+
for (const finding of poolWindowReadFindings(pools, windowsOf)) {
|
|
18110
|
+
push("pool", "warn", finding.message, finding.subject);
|
|
18111
|
+
}
|
|
18112
|
+
const jobs = validatedGlobalConfig?.ok === true ? validatedGlobalConfig.data.jobs ?? {} : {};
|
|
18113
|
+
for (const finding of jobWindowReadFindings(jobs, pools, windowsOf)) {
|
|
18114
|
+
push("global-config", "warn", finding.message, finding.subject);
|
|
18115
|
+
}
|
|
18116
|
+
}
|
|
17534
18117
|
const selectionExists = (selector) => {
|
|
17535
18118
|
const poolName = poolNameOf(selector);
|
|
17536
18119
|
return poolName === void 0 ? validIdentityNames.has(selector) : poolName in pools;
|
|
@@ -17771,7 +18354,7 @@ function formatDoctorReport(report) {
|
|
|
17771
18354
|
}
|
|
17772
18355
|
function realpathOrSelf(target) {
|
|
17773
18356
|
try {
|
|
17774
|
-
return
|
|
18357
|
+
return fs12.realpathSync(target);
|
|
17775
18358
|
} catch {
|
|
17776
18359
|
return target;
|
|
17777
18360
|
}
|
|
@@ -17783,20 +18366,33 @@ function servingDoorListeners(paths) {
|
|
|
17783
18366
|
}
|
|
17784
18367
|
function collectDoctorReport(params) {
|
|
17785
18368
|
const { paths } = params;
|
|
17786
|
-
const
|
|
18369
|
+
const { names: identityNames, unreachable: unreachableIdentities } = listIdentityDirectories(paths);
|
|
17787
18370
|
const identities = identityNames.map((name) => {
|
|
17788
|
-
const farmRoot =
|
|
17789
|
-
const identityPath =
|
|
17790
|
-
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 };
|
|
17791
18374
|
});
|
|
17792
|
-
const
|
|
18375
|
+
const usageSnapshots = {};
|
|
18376
|
+
for (const name of identityNames) {
|
|
18377
|
+
try {
|
|
18378
|
+
const snapshot = readUsageSnapshot(realFsPort, paths.usageSnapshotsDir, name);
|
|
18379
|
+
if (snapshot !== void 0) {
|
|
18380
|
+
usageSnapshots[name] = snapshot;
|
|
18381
|
+
}
|
|
18382
|
+
} catch (error) {
|
|
18383
|
+
if (!(error instanceof UsageSnapshotError)) {
|
|
18384
|
+
throw error;
|
|
18385
|
+
}
|
|
18386
|
+
}
|
|
18387
|
+
}
|
|
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() : [];
|
|
17793
18389
|
const configProfiles = profileNames.map((name) => {
|
|
17794
|
-
const profilePath =
|
|
18390
|
+
const profilePath = path31.join(paths.configProfilesDir, `${name}.json`);
|
|
17795
18391
|
return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
|
|
17796
18392
|
});
|
|
17797
|
-
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() : [];
|
|
17798
18394
|
const providers = providerNames.map((name) => {
|
|
17799
|
-
const providerPath =
|
|
18395
|
+
const providerPath = path31.join(paths.providersDir, `${name}.json`);
|
|
17800
18396
|
return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
|
|
17801
18397
|
});
|
|
17802
18398
|
const ownExecutablePath = realOwnExecutablePath();
|
|
@@ -17808,12 +18404,12 @@ function collectDoctorReport(params) {
|
|
|
17808
18404
|
binaryDiscovery = { ok: false, message: error instanceof Error ? error.message : String(error) };
|
|
17809
18405
|
}
|
|
17810
18406
|
const shimState = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
17811
|
-
const pathDirs = (params.env.PATH ?? "").split(
|
|
18407
|
+
const pathDirs = (params.env.PATH ?? "").split(path31.delimiter).filter((dir) => dir !== "");
|
|
17812
18408
|
const claudeShimShadow = shimState === void 0 ? void 0 : refinePathShadow(
|
|
17813
18409
|
findPathShadow({
|
|
17814
18410
|
pathDirs,
|
|
17815
|
-
targetDir:
|
|
17816
|
-
targetFilename:
|
|
18411
|
+
targetDir: path31.dirname(shimState.targetPath),
|
|
18412
|
+
targetFilename: path31.basename(shimState.targetPath),
|
|
17817
18413
|
findExecutableInDir
|
|
17818
18414
|
}),
|
|
17819
18415
|
shimState.targetPath,
|
|
@@ -17832,9 +18428,12 @@ function collectDoctorReport(params) {
|
|
|
17832
18428
|
chatgptSignIn: { path: paths.chatgptSignInFile, raw: realFsPort.readFileUtf8(paths.chatgptSignInFile) },
|
|
17833
18429
|
installedClaudeVersions: realInstalledClaudeVersions(),
|
|
17834
18430
|
identities,
|
|
18431
|
+
usageSnapshots,
|
|
17835
18432
|
configProfiles,
|
|
17836
18433
|
providers,
|
|
17837
18434
|
providerAliases: readProviderAliases(paths),
|
|
18435
|
+
renameJournals: listRenameJournals(realFarmFs, paths.identityRenamesDir),
|
|
18436
|
+
unreachableIdentities,
|
|
17838
18437
|
directoryRules: { path: paths.directoryRulesFile, raw: realFsPort.readFileUtf8(paths.directoryRulesFile) },
|
|
17839
18438
|
globalConfig: { path: paths.globalConfigFile, raw: realFsPort.readFileUtf8(paths.globalConfigFile) },
|
|
17840
18439
|
models: parsedModelsOf(paths),
|
|
@@ -17842,14 +18441,14 @@ function collectDoctorReport(params) {
|
|
|
17842
18441
|
categoriesLocal: { path: paths.categoriesLocalFile, raw: realFsPort.readFileUtf8(paths.categoriesLocalFile) },
|
|
17843
18442
|
activeIdentity: { path: paths.activeIdentityFile, raw: realFsPort.readFileUtf8(paths.activeIdentityFile) },
|
|
17844
18443
|
binaryDiscovery,
|
|
17845
|
-
claudeShim: { state: shimState, targetExists: shimState !== void 0 &&
|
|
18444
|
+
claudeShim: { state: shimState, targetExists: shimState !== void 0 && fs12.existsSync(shimState.targetPath) },
|
|
17846
18445
|
rootPath: paths.root,
|
|
17847
18446
|
pathResolution: {
|
|
17848
18447
|
ownExecutablePath,
|
|
17849
18448
|
agentShim: refinePathShadow(
|
|
17850
18449
|
findPathShadow({
|
|
17851
18450
|
pathDirs,
|
|
17852
|
-
targetDir:
|
|
18451
|
+
targetDir: path31.dirname(ownExecutablePath),
|
|
17853
18452
|
targetFilename: commandFilename(ownExecutablePath, "agent-shim"),
|
|
17854
18453
|
findExecutableInDir
|
|
17855
18454
|
}),
|
|
@@ -17890,92 +18489,92 @@ function collectDoctorReport(params) {
|
|
|
17890
18489
|
// src/frontdoor/controlSchemas.ts
|
|
17891
18490
|
init_schema2();
|
|
17892
18491
|
init_state();
|
|
17893
|
-
var UsageListOutputSchema =
|
|
17894
|
-
var UsageWindowsInputSchema =
|
|
17895
|
-
identity:
|
|
17896
|
-
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()
|
|
17897
18496
|
});
|
|
17898
|
-
var EffectiveWindowSchema =
|
|
18497
|
+
var EffectiveWindowSchema = z30.strictObject({
|
|
17899
18498
|
/** True when the window's reset time has passed, so the recorded observation describes a window that no longer exists. */
|
|
17900
|
-
reset:
|
|
18499
|
+
reset: z30.boolean(),
|
|
17901
18500
|
/** The fraction used: 0 for a reset window, otherwise what was last observed, absent when none was reported. */
|
|
17902
|
-
utilization:
|
|
18501
|
+
utilization: z30.number().optional(),
|
|
17903
18502
|
/** The reset instant, for a window that has not reset yet and reported one. */
|
|
17904
|
-
resetsAtMs:
|
|
18503
|
+
resetsAtMs: z30.number().optional(),
|
|
17905
18504
|
/** The window's own status, for a window that has not reset yet. */
|
|
17906
|
-
status:
|
|
18505
|
+
status: z30.string().optional()
|
|
17907
18506
|
});
|
|
17908
|
-
var UsageWindowsOutputSchema =
|
|
17909
|
-
identity:
|
|
17910
|
-
provider:
|
|
18507
|
+
var UsageWindowsOutputSchema = z30.strictObject({
|
|
18508
|
+
identity: z30.string(),
|
|
18509
|
+
provider: z30.string(),
|
|
17911
18510
|
/** When the rate-limit state the windows come from was observed. */
|
|
17912
|
-
observedAt:
|
|
18511
|
+
observedAt: z30.iso.datetime().optional(),
|
|
17913
18512
|
fiveHour: EffectiveWindowSchema.optional(),
|
|
17914
18513
|
sevenDay: EffectiveWindowSchema.optional()
|
|
17915
18514
|
});
|
|
17916
|
-
var UsageLiveOutputSchema =
|
|
18515
|
+
var UsageLiveOutputSchema = z30.strictObject({
|
|
17917
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. */
|
|
17918
18517
|
latest: RcLiveRateLimitSchema.optional(),
|
|
17919
18518
|
/** One observation per session whose stream has filed a rate_limit_event this door generation. */
|
|
17920
|
-
sessions:
|
|
18519
|
+
sessions: z30.readonly(z30.array(RcLiveRateLimitSchema))
|
|
17921
18520
|
});
|
|
17922
|
-
var FrontDoorSessionStatusSchema =
|
|
17923
|
-
pid:
|
|
17924
|
-
startedAt:
|
|
17925
|
-
alive:
|
|
18521
|
+
var FrontDoorSessionStatusSchema = z30.strictObject({
|
|
18522
|
+
pid: z30.int().positive(),
|
|
18523
|
+
startedAt: z30.number(),
|
|
18524
|
+
alive: z30.boolean()
|
|
17926
18525
|
});
|
|
17927
|
-
var HeadroomSocketTargetSchema =
|
|
17928
|
-
var FrontDoorStatusOutputSchema =
|
|
18526
|
+
var HeadroomSocketTargetSchema = z30.union([z30.strictObject({ socketPath: z30.string() }), z30.strictObject({ refused: z30.string() })]);
|
|
18527
|
+
var FrontDoorStatusOutputSchema = z30.strictObject({
|
|
17929
18528
|
state: FrontDoorStateSchema,
|
|
17930
|
-
supervisorAlive:
|
|
18529
|
+
supervisorAlive: z30.boolean(),
|
|
17931
18530
|
/** The pids of earlier doors that released their addresses and are finishing the connections they carried: running, but not serving anything new. */
|
|
17932
|
-
draining:
|
|
17933
|
-
sessions:
|
|
18531
|
+
draining: z30.readonly(z30.array(z30.number().int().positive())),
|
|
18532
|
+
sessions: z30.readonly(z30.array(FrontDoorSessionStatusSchema)),
|
|
17934
18533
|
headroomSocket: HeadroomSocketTargetSchema.optional(),
|
|
17935
|
-
logPath:
|
|
17936
|
-
logExists:
|
|
18534
|
+
logPath: z30.string(),
|
|
18535
|
+
logExists: z30.boolean()
|
|
17937
18536
|
});
|
|
17938
|
-
var FrontDoorSessionsOutputSchema =
|
|
17939
|
-
var CheckRunInputSchema =
|
|
17940
|
-
path:
|
|
17941
|
-
identity:
|
|
17942
|
-
}).refine((input) =>
|
|
17943
|
-
var PoolPickInputSchema =
|
|
17944
|
-
pool:
|
|
17945
|
-
path:
|
|
17946
|
-
}).refine((input) =>
|
|
17947
|
-
var DoctorFindingSchema =
|
|
17948
|
-
section:
|
|
17949
|
-
subject:
|
|
17950
|
-
severity:
|
|
17951
|
-
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()
|
|
17952
18551
|
});
|
|
17953
|
-
var DoctorRunOutputSchema =
|
|
18552
|
+
var DoctorRunOutputSchema = z30.strictObject({
|
|
17954
18553
|
/** False exactly when any finding is a `fail`; a `warn` never fails the report on its own. */
|
|
17955
|
-
ok:
|
|
17956
|
-
findings:
|
|
18554
|
+
ok: z30.boolean(),
|
|
18555
|
+
findings: z30.readonly(z30.array(DoctorFindingSchema))
|
|
17957
18556
|
});
|
|
17958
|
-
var FrontDoorRestartOutputSchema =
|
|
17959
|
-
action:
|
|
17960
|
-
previousPid:
|
|
18557
|
+
var FrontDoorRestartOutputSchema = z30.strictObject({
|
|
18558
|
+
action: z30.literal("restarting"),
|
|
18559
|
+
previousPid: z30.int().positive()
|
|
17961
18560
|
});
|
|
17962
|
-
var UpdateCheckOutputSchema =
|
|
17963
|
-
current:
|
|
17964
|
-
latest:
|
|
17965
|
-
action:
|
|
18561
|
+
var UpdateCheckOutputSchema = z30.strictObject({
|
|
18562
|
+
current: z30.string(),
|
|
18563
|
+
latest: z30.string(),
|
|
18564
|
+
action: z30.enum(["current", "available", "updated"])
|
|
17966
18565
|
});
|
|
17967
|
-
var CodexSignInSchema =
|
|
17968
|
-
|
|
17969
|
-
|
|
17970
|
-
|
|
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() })
|
|
17971
18570
|
]);
|
|
17972
|
-
var CodexStatusOutputSchema =
|
|
18571
|
+
var CodexStatusOutputSchema = z30.strictObject({
|
|
17973
18572
|
signIn: CodexSignInSchema,
|
|
17974
|
-
codexProviders:
|
|
18573
|
+
codexProviders: z30.readonly(z30.array(z30.string()))
|
|
17975
18574
|
});
|
|
17976
|
-
var CodexLogoutOutputSchema =
|
|
17977
|
-
hadGrant:
|
|
17978
|
-
revoked:
|
|
18575
|
+
var CodexLogoutOutputSchema = z30.strictObject({
|
|
18576
|
+
hadGrant: z30.boolean(),
|
|
18577
|
+
revoked: z30.boolean()
|
|
17979
18578
|
});
|
|
17980
18579
|
|
|
17981
18580
|
// src/frontdoor/codexApi.ts
|
|
@@ -18130,72 +18729,74 @@ function requireRuleSelector(paths, selector) {
|
|
|
18130
18729
|
|
|
18131
18730
|
// src/frontdoor/configApi.ts
|
|
18132
18731
|
init_identity();
|
|
18732
|
+
init_replayRun();
|
|
18133
18733
|
init_providersStore();
|
|
18134
18734
|
|
|
18135
18735
|
// src/frontdoor/configSchemas.ts
|
|
18136
18736
|
init_schema();
|
|
18137
18737
|
init_names();
|
|
18738
|
+
import { z as z31 } from "zod";
|
|
18138
18739
|
init_statusline();
|
|
18139
|
-
|
|
18140
|
-
var
|
|
18141
|
-
|
|
18142
|
-
|
|
18143
|
-
|
|
18144
|
-
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()
|
|
18145
18745
|
});
|
|
18146
|
-
var CredentialSummarySchema2 =
|
|
18147
|
-
target:
|
|
18148
|
-
sources:
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
|
|
18152
|
-
|
|
18153
|
-
|
|
18154
|
-
|
|
18155
|
-
|
|
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") })
|
|
18156
18756
|
])
|
|
18157
18757
|
)),
|
|
18158
18758
|
cache: CredentialCacheSchema.optional()
|
|
18159
18759
|
});
|
|
18160
|
-
var mutationOutput = (kind, action) =>
|
|
18161
|
-
var storedMutationOutput = (kind, action, value) =>
|
|
18162
|
-
var IdentityValueSchema =
|
|
18163
|
-
name:
|
|
18164
|
-
label:
|
|
18165
|
-
defaultConfigProfile:
|
|
18166
|
-
provider:
|
|
18167
|
-
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(),
|
|
18168
18768
|
credential: CredentialSummarySchema2.optional(),
|
|
18169
|
-
anchors:
|
|
18769
|
+
anchors: z31.array(AnchorSchema).optional()
|
|
18170
18770
|
});
|
|
18171
18771
|
var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
|
|
18172
|
-
var ProviderValueSchema =
|
|
18173
|
-
name:
|
|
18174
|
-
kind:
|
|
18175
|
-
displayName:
|
|
18176
|
-
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(),
|
|
18177
18777
|
codex: CodexProviderConfigSchema.optional(),
|
|
18178
18778
|
credential: CredentialSummarySchema2.optional(),
|
|
18179
|
-
env:
|
|
18779
|
+
env: z31.record(z31.string(), z31.string()).optional()
|
|
18180
18780
|
});
|
|
18181
|
-
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) });
|
|
18182
18783
|
var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created", IdentityValueSchema);
|
|
18183
|
-
var ConfigIdentitySetInputSchema =
|
|
18184
|
-
name:
|
|
18784
|
+
var ConfigIdentitySetInputSchema = z31.strictObject({
|
|
18785
|
+
name: z31.string().min(1),
|
|
18185
18786
|
/** The identity's display label; `false` clears it. */
|
|
18186
|
-
label:
|
|
18187
|
-
defaultConfigProfile:
|
|
18787
|
+
label: z31.union([IdentityLabelSchema, z31.literal(false)]).optional(),
|
|
18788
|
+
defaultConfigProfile: z31.union([z31.string().min(1), z31.literal(false)]).optional(),
|
|
18188
18789
|
/** The provider the identity exists for; `false` clears it. */
|
|
18189
|
-
provider:
|
|
18190
|
-
allowAmbientCredential:
|
|
18191
|
-
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(),
|
|
18192
18793
|
/** `false` removes the anchors; a list replaces them. */
|
|
18193
|
-
anchors:
|
|
18794
|
+
anchors: z31.union([z31.literal(false), z31.array(AnchorSchema).min(1)]).optional()
|
|
18194
18795
|
});
|
|
18195
18796
|
var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
|
|
18196
|
-
var ConfigIdentityRemoveInputSchema =
|
|
18797
|
+
var ConfigIdentityRemoveInputSchema = z31.strictObject({ name: z31.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18197
18798
|
var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
|
|
18198
|
-
var ConfigStatuslineSetSchema =
|
|
18799
|
+
var ConfigStatuslineSetSchema = z31.record(z31.string(), z31.unknown()).superRefine((settings, context) => {
|
|
18199
18800
|
for (const key of Object.keys(settings)) {
|
|
18200
18801
|
if (key === STATUSLINE_EXTRA_GROUP || key.startsWith(`${STATUSLINE_EXTRA_GROUP}.`)) {
|
|
18201
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` });
|
|
@@ -18203,102 +18804,105 @@ var ConfigStatuslineSetSchema = z30.record(z30.string(), z30.unknown()).superRef
|
|
|
18203
18804
|
}
|
|
18204
18805
|
});
|
|
18205
18806
|
var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
|
|
18206
|
-
var ConfigProfileAddInputSchema =
|
|
18207
|
-
name:
|
|
18208
|
-
extends:
|
|
18209
|
-
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()
|
|
18210
18811
|
});
|
|
18211
18812
|
var ConfigProfileAddOutputSchema = storedMutationOutput("profile", "created", ProfileValueSchema);
|
|
18212
|
-
var ConfigProfileSetInputSchema =
|
|
18213
|
-
name:
|
|
18214
|
-
category:
|
|
18215
|
-
entry:
|
|
18216
|
-
extends:
|
|
18217
|
-
description:
|
|
18218
|
-
launch:
|
|
18219
|
-
skipPermissions:
|
|
18220
|
-
remoteControl:
|
|
18221
|
-
headroom:
|
|
18222
|
-
trackUsage:
|
|
18223
|
-
provider:
|
|
18224
|
-
claudeVersion:
|
|
18225
|
-
delay:
|
|
18226
|
-
pause:
|
|
18227
|
-
explain:
|
|
18228
|
-
proxyBypass:
|
|
18229
|
-
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({
|
|
18230
18831
|
set: ConfigStatuslineSetSchema.optional(),
|
|
18231
|
-
unset:
|
|
18832
|
+
unset: z31.array(z31.string()).optional()
|
|
18232
18833
|
}).optional()
|
|
18233
18834
|
}).optional()
|
|
18234
18835
|
});
|
|
18235
18836
|
var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
|
|
18236
|
-
var ConfigProfileRemoveInputSchema =
|
|
18837
|
+
var ConfigProfileRemoveInputSchema = z31.strictObject({ name: z31.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18237
18838
|
var ConfigProfileRemoveOutputSchema = mutationOutput("profile", "removed");
|
|
18238
18839
|
var ConfigProfileUseOutputSchema = mutationOutput("profile", "selected");
|
|
18239
|
-
var PoolMembersInputSchema =
|
|
18240
|
-
var ConfigPoolAddInputSchema =
|
|
18241
|
-
name:
|
|
18840
|
+
var PoolMembersInputSchema = z31.array(z31.string().min(1)).min(1);
|
|
18841
|
+
var ConfigPoolAddInputSchema = z31.strictObject({
|
|
18842
|
+
name: z31.string().min(1),
|
|
18242
18843
|
identities: PoolMembersInputSchema,
|
|
18243
|
-
preference:
|
|
18244
|
-
resumeOnLimit:
|
|
18245
|
-
compactBeforeLimit:
|
|
18844
|
+
preference: z31.enum(POOL_PREFERENCES).optional(),
|
|
18845
|
+
resumeOnLimit: z31.boolean().optional(),
|
|
18846
|
+
compactBeforeLimit: z31.boolean().optional(),
|
|
18246
18847
|
compactAtUtilisation: CompactAtUtilisationSchema.optional()
|
|
18247
18848
|
});
|
|
18248
18849
|
var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
|
|
18249
|
-
var ConfigPoolSetInputSchema =
|
|
18250
|
-
name:
|
|
18850
|
+
var ConfigPoolSetInputSchema = z31.strictObject({
|
|
18851
|
+
name: z31.string().min(1),
|
|
18251
18852
|
identities: PoolMembersInputSchema.optional(),
|
|
18252
|
-
preference:
|
|
18253
|
-
resumeOnLimit:
|
|
18254
|
-
compactBeforeLimit:
|
|
18255
|
-
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()
|
|
18256
18857
|
});
|
|
18257
18858
|
var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
|
|
18258
|
-
var ConfigPoolRemoveInputSchema =
|
|
18859
|
+
var ConfigPoolRemoveInputSchema = z31.strictObject({ name: z31.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18259
18860
|
var ConfigPoolRemoveOutputSchema = mutationOutput("pool", "removed");
|
|
18260
18861
|
var ConfigPoolUseOutputSchema = mutationOutput("pool", "selected");
|
|
18261
|
-
var ConfigProviderAddInputSchema =
|
|
18262
|
-
name:
|
|
18263
|
-
kind:
|
|
18264
|
-
displayName:
|
|
18265
|
-
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(),
|
|
18266
18867
|
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).required({ sources: true }),
|
|
18267
18868
|
codex: CodexProviderConfigSchema.optional()
|
|
18268
18869
|
});
|
|
18269
18870
|
var ConfigProviderAddOutputSchema = storedMutationOutput("provider", "created", ProviderValueSchema);
|
|
18270
|
-
var ConfigProviderSetInputSchema =
|
|
18271
|
-
name:
|
|
18272
|
-
displayName:
|
|
18273
|
-
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(),
|
|
18274
18875
|
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).optional(),
|
|
18275
18876
|
codex: CodexProviderConfigSchema.optional()
|
|
18276
18877
|
});
|
|
18277
18878
|
var ConfigProviderSetOutputSchema = storedMutationOutput("provider", "updated", ProviderValueSchema);
|
|
18278
|
-
var ConfigProviderRemoveInputSchema =
|
|
18879
|
+
var ConfigProviderRemoveInputSchema = z31.strictObject({ name: z31.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18279
18880
|
var ConfigProviderRemoveOutputSchema = mutationOutput("provider", "removed");
|
|
18280
|
-
var ConfigRuleAddInputSchema =
|
|
18281
|
-
path:
|
|
18282
|
-
configProfile:
|
|
18283
|
-
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()
|
|
18284
18885
|
});
|
|
18285
18886
|
var ConfigRuleAddOutputSchema = storedMutationOutput("rule", "created", DirectoryRuleSchema);
|
|
18286
|
-
var ConfigRuleSetInputSchema =
|
|
18287
|
-
path:
|
|
18288
|
-
configProfile:
|
|
18289
|
-
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()
|
|
18290
18891
|
});
|
|
18291
18892
|
var ConfigRuleSetOutputSchema = storedMutationOutput("rule", "updated", DirectoryRuleSchema);
|
|
18292
|
-
var ConfigRuleRemoveInputSchema =
|
|
18893
|
+
var ConfigRuleRemoveInputSchema = z31.strictObject({ path: z31.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18293
18894
|
var ConfigRuleRemoveOutputSchema = mutationOutput("rule", "removed");
|
|
18294
18895
|
|
|
18295
18896
|
// src/frontdoor/configApi.ts
|
|
18296
18897
|
var CONFIG_API_TAG = "config";
|
|
18297
18898
|
function refusal(error) {
|
|
18899
|
+
if (error instanceof KeychainLookupError) {
|
|
18900
|
+
throw new ORPCError2("SERVICE_UNAVAILABLE", { message: error.message });
|
|
18901
|
+
}
|
|
18298
18902
|
if (error instanceof IdentityNotFoundError || error instanceof ProfileNotFoundError || error instanceof PoolNotFoundError || error instanceof ProviderNotFoundError || error instanceof DirectoryRuleNotFoundError) {
|
|
18299
18903
|
throw new ORPCError2("NOT_FOUND", { message: error.message });
|
|
18300
18904
|
}
|
|
18301
|
-
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) {
|
|
18302
18906
|
throw new ORPCError2("CONFLICT", { message: error.message });
|
|
18303
18907
|
}
|
|
18304
18908
|
if (error instanceof CliError) {
|
|
@@ -18306,6 +18910,13 @@ function refusal(error) {
|
|
|
18306
18910
|
}
|
|
18307
18911
|
throw error;
|
|
18308
18912
|
}
|
|
18913
|
+
async function guardedAsync(write) {
|
|
18914
|
+
try {
|
|
18915
|
+
await write();
|
|
18916
|
+
} catch (error) {
|
|
18917
|
+
refusal(error);
|
|
18918
|
+
}
|
|
18919
|
+
}
|
|
18309
18920
|
function guarded(write) {
|
|
18310
18921
|
try {
|
|
18311
18922
|
return write();
|
|
@@ -18355,16 +18966,21 @@ function profileValue(name, paths) {
|
|
|
18355
18966
|
function createConfigApiRouter(deps) {
|
|
18356
18967
|
const authed = doorApiAuth(deps.expectedToken);
|
|
18357
18968
|
const { paths } = deps;
|
|
18358
|
-
const route = (
|
|
18969
|
+
const route = (path45, summary) => authed.meta(openapi3({ method: "POST", path: path45, summary, tags: [CONFIG_API_TAG] }));
|
|
18359
18970
|
return {
|
|
18360
18971
|
config: {
|
|
18361
18972
|
identity: {
|
|
18362
|
-
add: route("/rest/config/identity/add", "Create an identity").input(
|
|
18363
|
-
(
|
|
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(() => {
|
|
18364
18980
|
addIdentity(paths, input.name);
|
|
18365
18981
|
return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
|
|
18366
|
-
})
|
|
18367
|
-
),
|
|
18982
|
+
});
|
|
18983
|
+
}),
|
|
18368
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(
|
|
18369
18985
|
({ input }) => guarded(() => {
|
|
18370
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");
|
|
@@ -18613,43 +19229,43 @@ import { openapi as openapi4 } from "@orpc/openapi";
|
|
|
18613
19229
|
import { eventIterator as eventIterator2, withEventMeta as withEventMeta2 } from "@orpc/server";
|
|
18614
19230
|
|
|
18615
19231
|
// src/frontdoor/eventSchemas.ts
|
|
18616
|
-
import { z as
|
|
19232
|
+
import { z as z32 } from "zod";
|
|
18617
19233
|
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
18618
19234
|
var LAUNCH_EVENT_SOURCE = "launch";
|
|
18619
19235
|
var USAGE_EVENT_SOURCE = "usage";
|
|
18620
19236
|
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
18621
19237
|
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
18622
|
-
var DoorEventSchema =
|
|
18623
|
-
source:
|
|
19238
|
+
var DoorEventSchema = z32.strictObject({
|
|
19239
|
+
source: z32.string().min(1),
|
|
18624
19240
|
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
18625
|
-
sequence:
|
|
18626
|
-
payload:
|
|
19241
|
+
sequence: z32.number().int().positive(),
|
|
19242
|
+
payload: z32.unknown()
|
|
18627
19243
|
});
|
|
18628
|
-
var DoorEventSourceQuerySchema =
|
|
18629
|
-
sources:
|
|
19244
|
+
var DoorEventSourceQuerySchema = z32.strictObject({
|
|
19245
|
+
sources: z32.array(z32.string().min(1)).min(1).optional()
|
|
18630
19246
|
});
|
|
18631
|
-
var LaunchLifecycleEventSchema =
|
|
18632
|
-
kind:
|
|
18633
|
-
pid:
|
|
18634
|
-
startedAt:
|
|
18635
|
-
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()
|
|
18636
19252
|
});
|
|
18637
|
-
var DoorHealthEventSchema =
|
|
18638
|
-
|
|
18639
|
-
|
|
18640
|
-
|
|
18641
|
-
|
|
18642
|
-
|
|
18643
|
-
|
|
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() })
|
|
18644
19260
|
]);
|
|
18645
|
-
var QuotaExpiringEventSchema =
|
|
18646
|
-
identity:
|
|
18647
|
-
provider:
|
|
18648
|
-
window:
|
|
19261
|
+
var QuotaExpiringEventSchema = z32.strictObject({
|
|
19262
|
+
identity: z32.string().min(1),
|
|
19263
|
+
provider: z32.string().min(1),
|
|
19264
|
+
window: z32.enum(["fiveHour", "sevenDay"]),
|
|
18649
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. */
|
|
18650
|
-
utilization:
|
|
18651
|
-
resetsAt:
|
|
18652
|
-
observedAt:
|
|
19266
|
+
utilization: z32.number().min(0).max(1),
|
|
19267
|
+
resetsAt: z32.iso.datetime(),
|
|
19268
|
+
observedAt: z32.number()
|
|
18653
19269
|
});
|
|
18654
19270
|
|
|
18655
19271
|
// src/frontdoor/eventsApi.ts
|
|
@@ -18732,61 +19348,61 @@ import { ORPCError as ORPCError5 } from "@orpc/client";
|
|
|
18732
19348
|
import { openapi as openapi6 } from "@orpc/openapi";
|
|
18733
19349
|
|
|
18734
19350
|
// src/frontdoor/launchSchemas.ts
|
|
18735
|
-
import
|
|
18736
|
-
import { z as
|
|
19351
|
+
import path33 from "node:path";
|
|
19352
|
+
import { z as z33 } from "zod";
|
|
18737
19353
|
init_statusline();
|
|
18738
19354
|
init_claudeVersion();
|
|
18739
19355
|
init_identity();
|
|
18740
|
-
var LaunchResolveInputSchema =
|
|
18741
|
-
path:
|
|
19356
|
+
var LaunchResolveInputSchema = z33.strictObject({
|
|
19357
|
+
path: z33.string().min(1),
|
|
18742
19358
|
/** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
|
|
18743
|
-
argv:
|
|
19359
|
+
argv: z33.readonly(z33.array(z33.string())).optional(),
|
|
18744
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. */
|
|
18745
|
-
env:
|
|
18746
|
-
}).refine((input) =>
|
|
18747
|
-
var LaunchPoolDecisionSchema =
|
|
18748
|
-
name:
|
|
18749
|
-
reasons:
|
|
18750
|
-
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()
|
|
18751
19367
|
});
|
|
18752
|
-
var LaunchDecisionSchema =
|
|
18753
|
-
identity:
|
|
18754
|
-
identitySource:
|
|
19368
|
+
var LaunchDecisionSchema = z33.strictObject({
|
|
19369
|
+
identity: z33.string().optional(),
|
|
19370
|
+
identitySource: z33.enum(IDENTITY_DECISION_SOURCES),
|
|
18755
19371
|
pool: LaunchPoolDecisionSchema.optional(),
|
|
18756
|
-
configDirEscapeHatch:
|
|
18757
|
-
configDir:
|
|
18758
|
-
configProfile:
|
|
18759
|
-
configProfileSource:
|
|
18760
|
-
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()
|
|
18761
19377
|
});
|
|
18762
|
-
var LaunchFlagsSchema =
|
|
18763
|
-
skipPermissions:
|
|
18764
|
-
remoteControl:
|
|
18765
|
-
headroom:
|
|
18766
|
-
trackUsage:
|
|
18767
|
-
pause:
|
|
18768
|
-
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(),
|
|
18769
19385
|
/** How long the launch waits after its own output before it starts claude, in milliseconds. */
|
|
18770
|
-
delayMs:
|
|
19386
|
+
delayMs: z33.number(),
|
|
18771
19387
|
/** The hosts the launch keeps off the front door by adding them to the child's `NO_PROXY`. */
|
|
18772
|
-
proxyBypass:
|
|
19388
|
+
proxyBypass: z33.array(z33.string()).readonly(),
|
|
18773
19389
|
/** How the session's built-in statusline looks, when the launch configures any of it. */
|
|
18774
19390
|
statusline: StatuslineSchema.optional()
|
|
18775
19391
|
});
|
|
18776
|
-
var LaunchResolveOutputSchema =
|
|
19392
|
+
var LaunchResolveOutputSchema = z33.strictObject({
|
|
18777
19393
|
decision: LaunchDecisionSchema,
|
|
18778
19394
|
flags: LaunchFlagsSchema,
|
|
18779
|
-
claudeVersion:
|
|
19395
|
+
claudeVersion: z33.strictObject({ version: z33.string(), source: z33.enum(CLAUDE_VERSION_SOURCES) }).optional(),
|
|
18780
19396
|
/** The real `claude` binary the launch would spawn, on the door's host. */
|
|
18781
|
-
bin:
|
|
19397
|
+
bin: z33.string(),
|
|
18782
19398
|
/** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
|
|
18783
|
-
args:
|
|
19399
|
+
args: z33.readonly(z33.array(z33.string())),
|
|
18784
19400
|
/** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
|
|
18785
|
-
credential:
|
|
18786
|
-
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() }),
|
|
18787
19403
|
/** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
|
|
18788
|
-
environment:
|
|
18789
|
-
warnings:
|
|
19404
|
+
environment: z33.readonly(z33.array(z33.string())),
|
|
19405
|
+
warnings: z33.readonly(z33.array(z33.string()))
|
|
18790
19406
|
});
|
|
18791
19407
|
|
|
18792
19408
|
// src/frontdoor/launchApi.ts
|
|
@@ -18822,22 +19438,22 @@ function createLaunchApiRouter(deps) {
|
|
|
18822
19438
|
// src/frontdoor/agentTreesApi.ts
|
|
18823
19439
|
import { ORPCError as ORPCError6 } from "@orpc/client";
|
|
18824
19440
|
import { openapi as openapi7 } from "@orpc/openapi";
|
|
18825
|
-
import { z as
|
|
19441
|
+
import { z as z34 } from "zod";
|
|
18826
19442
|
init_cliError();
|
|
18827
|
-
var AgentTreesListInputSchema =
|
|
19443
|
+
var AgentTreesListInputSchema = z34.strictObject({
|
|
18828
19444
|
/** Only this identity's sessions. */
|
|
18829
|
-
identity:
|
|
19445
|
+
identity: z34.string().optional(),
|
|
18830
19446
|
/** Include sessions that spawned no agent and ran no workflow. */
|
|
18831
|
-
all:
|
|
19447
|
+
all: z34.boolean().optional()
|
|
18832
19448
|
});
|
|
18833
|
-
var AgentTreesListOutputSchema =
|
|
18834
|
-
var AgentTreesShowInputSchema =
|
|
19449
|
+
var AgentTreesListOutputSchema = z34.array(SessionSummarySchema);
|
|
19450
|
+
var AgentTreesShowInputSchema = z34.strictObject({
|
|
18835
19451
|
/** A session id, or an unambiguous prefix of one. */
|
|
18836
|
-
session:
|
|
19452
|
+
session: z34.string().min(1),
|
|
18837
19453
|
/** Look only in this identity. */
|
|
18838
|
-
identity:
|
|
19454
|
+
identity: z34.string().optional()
|
|
18839
19455
|
});
|
|
18840
|
-
var AgentTreesShowOutputSchema =
|
|
19456
|
+
var AgentTreesShowOutputSchema = z34.strictObject({ identities: z34.array(z34.string()), ...MergedAgentTreeSchema.shape });
|
|
18841
19457
|
function asBadRequest(error) {
|
|
18842
19458
|
if (error instanceof CliError) {
|
|
18843
19459
|
throw new ORPCError6("BAD_REQUEST", { message: error.message });
|
|
@@ -20924,7 +21540,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
20924
21540
|
|
|
20925
21541
|
// src/frontdoor/rcSelfHostMint.ts
|
|
20926
21542
|
init_account();
|
|
20927
|
-
import
|
|
21543
|
+
import path34 from "node:path";
|
|
20928
21544
|
var CREDENTIALS_FILE2 = ".credentials.json";
|
|
20929
21545
|
var CLAUDE_JSON2 = ".claude.json";
|
|
20930
21546
|
var RC_SELF_HOST_RECORD_DIR = "rc-selfhost";
|
|
@@ -20934,8 +21550,8 @@ var SELF_HOST_SUBSCRIPTION_TYPE = "max";
|
|
|
20934
21550
|
function isRecord14(value) {
|
|
20935
21551
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20936
21552
|
}
|
|
20937
|
-
function readJsonObject(
|
|
20938
|
-
const raw =
|
|
21553
|
+
function readJsonObject(fs15, file) {
|
|
21554
|
+
const raw = fs15.readFileUtf8(file);
|
|
20939
21555
|
if (raw === void 0) {
|
|
20940
21556
|
return void 0;
|
|
20941
21557
|
}
|
|
@@ -20947,8 +21563,8 @@ function readJsonObject(fs14, file) {
|
|
|
20947
21563
|
}
|
|
20948
21564
|
return isRecord14(parsed) ? parsed : void 0;
|
|
20949
21565
|
}
|
|
20950
|
-
function readRcSelfHostRecord(
|
|
20951
|
-
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));
|
|
20952
21568
|
if (parsed === void 0) {
|
|
20953
21569
|
return void 0;
|
|
20954
21570
|
}
|
|
@@ -20962,11 +21578,11 @@ function mintRcSelfHostCredential(deps) {
|
|
|
20962
21578
|
if (!isIdentityName(deps.identity)) {
|
|
20963
21579
|
throw new Error(`"${deps.identity}" is not a valid identity name.`);
|
|
20964
21580
|
}
|
|
20965
|
-
const identityDir =
|
|
20966
|
-
const credentialsFile =
|
|
20967
|
-
const claudeJsonFile =
|
|
20968
|
-
const recordDir =
|
|
20969
|
-
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);
|
|
20970
21586
|
const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
|
|
20971
21587
|
const existingCredentials = readJsonObject(deps.fs, credentialsFile);
|
|
20972
21588
|
const existingOauth = isRecord14(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
|
|
@@ -20982,7 +21598,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
20982
21598
|
const organizationUuid = deps.newUuid();
|
|
20983
21599
|
const accountUuid = deps.newUuid();
|
|
20984
21600
|
const mintedAt = new Date(deps.now()).toISOString();
|
|
20985
|
-
deps.fs.mkdirPrivate(
|
|
21601
|
+
deps.fs.mkdirPrivate(path34.dirname(credentialsFile));
|
|
20986
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)}
|
|
20987
21603
|
`);
|
|
20988
21604
|
const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
|
|
@@ -21009,9 +21625,9 @@ function mintRcSelfHostCredential(deps) {
|
|
|
21009
21625
|
}, null, 2)}
|
|
21010
21626
|
`);
|
|
21011
21627
|
deps.fs.mkdirPrivate(recordDir);
|
|
21012
|
-
deps.fs.writeFilePrivate(
|
|
21628
|
+
deps.fs.writeFilePrivate(recordFile2, `${JSON.stringify({ accessToken, refreshToken, organizationUuid, accountUuid }, null, 2)}
|
|
21013
21629
|
`);
|
|
21014
|
-
return { identity: deps.identity, organizationUuid, credentialsFile, claudeJsonFile, recordFile, replaced: existingIsOwn };
|
|
21630
|
+
return { identity: deps.identity, organizationUuid, credentialsFile, claudeJsonFile, recordFile: recordFile2, replaced: existingIsOwn };
|
|
21015
21631
|
}
|
|
21016
21632
|
|
|
21017
21633
|
// src/index.ts
|
|
@@ -21020,25 +21636,25 @@ init_ensure2();
|
|
|
21020
21636
|
// src/frontdoor/liveSessionRegistry.ts
|
|
21021
21637
|
init_capability();
|
|
21022
21638
|
init_state();
|
|
21023
|
-
import
|
|
21639
|
+
import path35 from "node:path";
|
|
21024
21640
|
function sameStat(recorded, current) {
|
|
21025
21641
|
return recorded?.mtimeMs === current.mtimeMs && recorded.sizeBytes === current.sizeBytes;
|
|
21026
21642
|
}
|
|
21027
21643
|
function createLiveSessionRegistry(ports) {
|
|
21028
|
-
const { fs:
|
|
21644
|
+
const { fs: fs15, sessionsDir } = ports;
|
|
21029
21645
|
const known = /* @__PURE__ */ new Map();
|
|
21030
21646
|
let tokens = /* @__PURE__ */ new Set();
|
|
21031
21647
|
let bySessionId = /* @__PURE__ */ new Map();
|
|
21032
|
-
const recordNames = () =>
|
|
21648
|
+
const recordNames = () => fs15.readdir(sessionsDir).filter(isSessionRecordName);
|
|
21033
21649
|
const rebuildIndexes = () => {
|
|
21034
21650
|
const records = [...known.values()].flatMap(({ record }) => record === void 0 ? [] : [record]);
|
|
21035
21651
|
tokens = new Set(records.map((record) => record.token));
|
|
21036
21652
|
bySessionId = new Map(records.flatMap((record) => record.sessionId === void 0 ? [] : [[record.sessionId, record]]));
|
|
21037
21653
|
};
|
|
21038
21654
|
const load = (name, stat) => {
|
|
21039
|
-
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) });
|
|
21040
21656
|
};
|
|
21041
|
-
const statOf = (name) =>
|
|
21657
|
+
const statOf = (name) => fs15.lstat(path35.join(sessionsDir, name));
|
|
21042
21658
|
const reconcile = () => {
|
|
21043
21659
|
const names = new Set(recordNames());
|
|
21044
21660
|
let changed = false;
|
|
@@ -21105,8 +21721,8 @@ init_plan2();
|
|
|
21105
21721
|
init_poolPick();
|
|
21106
21722
|
|
|
21107
21723
|
// src/agents/read.ts
|
|
21108
|
-
import
|
|
21109
|
-
import { z as
|
|
21724
|
+
import path36 from "node:path";
|
|
21725
|
+
import { z as z35 } from "zod";
|
|
21110
21726
|
var PROJECTS_DIR = "projects";
|
|
21111
21727
|
var TASKS_DIR = "tasks";
|
|
21112
21728
|
var SUBAGENTS_DIR = "subagents";
|
|
@@ -21129,17 +21745,17 @@ function parseEntry2(project, entry) {
|
|
|
21129
21745
|
const base = match?.[1];
|
|
21130
21746
|
return base === void 0 ? { project, sessionId: entry, superseded: false, entry } : { project, sessionId: base, superseded: true, entry };
|
|
21131
21747
|
}
|
|
21132
|
-
function listSessions2(
|
|
21748
|
+
function listSessions2(fs15, configDir) {
|
|
21133
21749
|
const found = [];
|
|
21134
|
-
for (const project of
|
|
21135
|
-
const projectDir =
|
|
21750
|
+
for (const project of fs15.readdir(path36.join(configDir, PROJECTS_DIR))) {
|
|
21751
|
+
const projectDir = path36.join(configDir, PROJECTS_DIR, project);
|
|
21136
21752
|
const entries = /* @__PURE__ */ new Set();
|
|
21137
|
-
for (const name of
|
|
21753
|
+
for (const name of fs15.readdir(projectDir)) {
|
|
21138
21754
|
if (name.endsWith(TRANSCRIPT_SUFFIX)) {
|
|
21139
21755
|
entries.add(name.slice(0, -TRANSCRIPT_SUFFIX.length));
|
|
21140
21756
|
continue;
|
|
21141
21757
|
}
|
|
21142
|
-
const children =
|
|
21758
|
+
const children = fs15.readdir(path36.join(projectDir, name));
|
|
21143
21759
|
if (children.includes(SUBAGENTS_DIR) || children.includes(WORKFLOWS_DIR)) {
|
|
21144
21760
|
entries.add(name);
|
|
21145
21761
|
}
|
|
@@ -21150,17 +21766,17 @@ function listSessions2(fs14, configDir) {
|
|
|
21150
21766
|
}
|
|
21151
21767
|
return found.sort((left, right) => left.project.localeCompare(right.project) || left.entry.localeCompare(right.entry));
|
|
21152
21768
|
}
|
|
21153
|
-
function locateAgents(
|
|
21769
|
+
function locateAgents(fs15, configDir, relativeDir, workflowRunId, report) {
|
|
21154
21770
|
const located = [];
|
|
21155
|
-
for (const name of listDirOrReport(
|
|
21771
|
+
for (const name of listDirOrReport(fs15, configDir, relativeDir, report)) {
|
|
21156
21772
|
if (!name.startsWith(AGENT_FILE_PREFIX) || !name.endsWith(META_SUFFIX)) {
|
|
21157
21773
|
continue;
|
|
21158
21774
|
}
|
|
21159
21775
|
const id = name.slice(AGENT_FILE_PREFIX.length, -META_SUFFIX.length);
|
|
21160
21776
|
located.push({
|
|
21161
21777
|
id,
|
|
21162
|
-
metaPath:
|
|
21163
|
-
transcriptPath:
|
|
21778
|
+
metaPath: path36.join(relativeDir, name),
|
|
21779
|
+
transcriptPath: path36.join(relativeDir, `${AGENT_FILE_PREFIX}${id}${TRANSCRIPT_SUFFIX}`),
|
|
21164
21780
|
workflowRunId
|
|
21165
21781
|
});
|
|
21166
21782
|
}
|
|
@@ -21201,17 +21817,17 @@ function toNode(read, children) {
|
|
|
21201
21817
|
function describeFailure(error) {
|
|
21202
21818
|
return error instanceof Error ? error.message : String(error);
|
|
21203
21819
|
}
|
|
21204
|
-
function readFileOrReport(
|
|
21820
|
+
function readFileOrReport(fs15, configDir, relative, report) {
|
|
21205
21821
|
try {
|
|
21206
|
-
return
|
|
21822
|
+
return fs15.readFileUtf8(path36.join(configDir, relative));
|
|
21207
21823
|
} catch (error) {
|
|
21208
21824
|
report({ path: relative, reason: `could not be read: ${describeFailure(error)}` });
|
|
21209
21825
|
return void 0;
|
|
21210
21826
|
}
|
|
21211
21827
|
}
|
|
21212
|
-
function listDirOrReport(
|
|
21828
|
+
function listDirOrReport(fs15, configDir, relative, report) {
|
|
21213
21829
|
try {
|
|
21214
|
-
return
|
|
21830
|
+
return fs15.readdir(path36.join(configDir, relative));
|
|
21215
21831
|
} catch (error) {
|
|
21216
21832
|
report({ path: relative, reason: `could not be listed: ${describeFailure(error)}` });
|
|
21217
21833
|
return [];
|
|
@@ -21225,47 +21841,47 @@ function parseJson2(text) {
|
|
|
21225
21841
|
return void 0;
|
|
21226
21842
|
}
|
|
21227
21843
|
}
|
|
21228
|
-
var TaskFileSchema =
|
|
21229
|
-
var WorkflowRunFileSchema =
|
|
21230
|
-
runId:
|
|
21231
|
-
workflowName:
|
|
21232
|
-
status:
|
|
21233
|
-
startTime:
|
|
21234
|
-
phases:
|
|
21235
|
-
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()
|
|
21236
21852
|
});
|
|
21237
|
-
function summariseSession(
|
|
21238
|
-
const sessionRelative =
|
|
21239
|
-
const subagentsRelative =
|
|
21240
|
-
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);
|
|
21241
21857
|
const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
|
|
21242
|
-
let agentCount =
|
|
21243
|
-
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))) {
|
|
21244
21860
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
21245
|
-
agentCount +=
|
|
21861
|
+
agentCount += fs15.readdir(path36.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
|
|
21246
21862
|
}
|
|
21247
21863
|
}
|
|
21248
|
-
const workflowRunCount =
|
|
21249
|
-
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}`));
|
|
21250
21866
|
return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
|
|
21251
21867
|
}
|
|
21252
|
-
function readSessionAgentTree(
|
|
21868
|
+
function readSessionAgentTree(fs15, configDir, ref, options = {}) {
|
|
21253
21869
|
const problems = [];
|
|
21254
21870
|
const report = (problem) => {
|
|
21255
21871
|
problems.push(problem);
|
|
21256
21872
|
};
|
|
21257
|
-
const sessionRelative =
|
|
21258
|
-
const subagentsRelative =
|
|
21259
|
-
const workflowsUnderSubagents =
|
|
21260
|
-
const located = locateAgents(
|
|
21261
|
-
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)) {
|
|
21262
21878
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
21263
|
-
located.push(...locateAgents(
|
|
21879
|
+
located.push(...locateAgents(fs15, configDir, path36.join(workflowsUnderSubagents, runDir), runDir, report));
|
|
21264
21880
|
}
|
|
21265
21881
|
}
|
|
21266
21882
|
const agents = /* @__PURE__ */ new Map();
|
|
21267
21883
|
for (const candidate of located) {
|
|
21268
|
-
const text = readFileOrReport(
|
|
21884
|
+
const text = readFileOrReport(fs15, configDir, candidate.metaPath, report);
|
|
21269
21885
|
if (text === void 0) {
|
|
21270
21886
|
continue;
|
|
21271
21887
|
}
|
|
@@ -21277,7 +21893,7 @@ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
|
21277
21893
|
agents.set(candidate.id, { located: candidate, meta: parsed.data });
|
|
21278
21894
|
}
|
|
21279
21895
|
const teamNames = [...new Set([...agents.values()].flatMap((agent) => agent.meta.teamName === void 0 ? [] : [agent.meta.teamName]))].sort();
|
|
21280
|
-
const parentOf3 = resolveParents(
|
|
21896
|
+
const parentOf3 = resolveParents(fs15, configDir, agents, report);
|
|
21281
21897
|
const childrenOf = /* @__PURE__ */ new Map();
|
|
21282
21898
|
const roots = [];
|
|
21283
21899
|
for (const id of agents.keys()) {
|
|
@@ -21300,12 +21916,12 @@ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
|
21300
21916
|
sessionId: ref.sessionId,
|
|
21301
21917
|
superseded: ref.superseded,
|
|
21302
21918
|
agents: roots.sort().map(build),
|
|
21303
|
-
tasks: readTasks(
|
|
21304
|
-
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),
|
|
21305
21921
|
problems
|
|
21306
21922
|
};
|
|
21307
21923
|
}
|
|
21308
|
-
function resolveParents(
|
|
21924
|
+
function resolveParents(fs15, configDir, agents, report) {
|
|
21309
21925
|
const parentOf3 = /* @__PURE__ */ new Map();
|
|
21310
21926
|
const transcriptCache = /* @__PURE__ */ new Map();
|
|
21311
21927
|
const transcriptOf = (agent) => {
|
|
@@ -21313,7 +21929,7 @@ function resolveParents(fs14, configDir, agents, report) {
|
|
|
21313
21929
|
if (cached !== void 0) {
|
|
21314
21930
|
return cached;
|
|
21315
21931
|
}
|
|
21316
|
-
const text = readFileOrReport(
|
|
21932
|
+
const text = readFileOrReport(fs15, configDir, agent.located.transcriptPath, report) ?? "";
|
|
21317
21933
|
transcriptCache.set(agent.located.id, text);
|
|
21318
21934
|
return text;
|
|
21319
21935
|
};
|
|
@@ -21363,16 +21979,16 @@ function resolveParents(fs14, configDir, agents, report) {
|
|
|
21363
21979
|
function ownTaskLists(sessionId) {
|
|
21364
21980
|
return [sessionId, `${SHORT_SESSION_LIST_PREFIX}${sessionId.slice(0, SHORT_SESSION_ID_LENGTH)}`];
|
|
21365
21981
|
}
|
|
21366
|
-
function readTasks(
|
|
21982
|
+
function readTasks(fs15, configDir, ownLists, sharedLists, report) {
|
|
21367
21983
|
const tasks = [];
|
|
21368
21984
|
[...ownLists, ...sharedLists].forEach((scope, index) => {
|
|
21369
|
-
const relativeDir =
|
|
21370
|
-
for (const name of [...listDirOrReport(
|
|
21985
|
+
const relativeDir = path36.join(TASKS_DIR, scope);
|
|
21986
|
+
for (const name of [...listDirOrReport(fs15, configDir, relativeDir, report)].sort()) {
|
|
21371
21987
|
if (name.startsWith(".") || !name.endsWith(JSON_SUFFIX)) {
|
|
21372
21988
|
continue;
|
|
21373
21989
|
}
|
|
21374
|
-
const relative =
|
|
21375
|
-
const text = readFileOrReport(
|
|
21990
|
+
const relative = path36.join(relativeDir, name);
|
|
21991
|
+
const text = readFileOrReport(fs15, configDir, relative, report);
|
|
21376
21992
|
const parsed = TaskFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
21377
21993
|
if (parsed.success) {
|
|
21378
21994
|
tasks.push(index < ownLists.length ? parsed.data : { ...parsed.data, taskList: scope });
|
|
@@ -21383,14 +21999,14 @@ function readTasks(fs14, configDir, ownLists, sharedLists, report) {
|
|
|
21383
21999
|
});
|
|
21384
22000
|
return tasks;
|
|
21385
22001
|
}
|
|
21386
|
-
function readWorkflowRuns(
|
|
22002
|
+
function readWorkflowRuns(fs15, configDir, relativeDir, report) {
|
|
21387
22003
|
const runs = [];
|
|
21388
|
-
for (const name of [...listDirOrReport(
|
|
22004
|
+
for (const name of [...listDirOrReport(fs15, configDir, relativeDir, report)].sort()) {
|
|
21389
22005
|
if (!name.startsWith(WORKFLOW_RUN_PREFIX) || !name.endsWith(JSON_SUFFIX)) {
|
|
21390
22006
|
continue;
|
|
21391
22007
|
}
|
|
21392
|
-
const relative =
|
|
21393
|
-
const text = readFileOrReport(
|
|
22008
|
+
const relative = path36.join(relativeDir, name);
|
|
22009
|
+
const text = readFileOrReport(fs15, configDir, relative, report);
|
|
21394
22010
|
const parsed = WorkflowRunFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
21395
22011
|
if (!parsed.success) {
|
|
21396
22012
|
if (text !== void 0) {
|
|
@@ -21406,7 +22022,7 @@ function readWorkflowRuns(fs14, configDir, relativeDir, report) {
|
|
|
21406
22022
|
|
|
21407
22023
|
// src/agents/sessions.ts
|
|
21408
22024
|
init_cliError();
|
|
21409
|
-
import
|
|
22025
|
+
import path37 from "node:path";
|
|
21410
22026
|
var SessionLookupError = class extends CliError {
|
|
21411
22027
|
constructor(message) {
|
|
21412
22028
|
super(message);
|
|
@@ -21414,13 +22030,13 @@ var SessionLookupError = class extends CliError {
|
|
|
21414
22030
|
}
|
|
21415
22031
|
};
|
|
21416
22032
|
function identityConfigDir(identitiesDir, identity) {
|
|
21417
|
-
return
|
|
22033
|
+
return path37.join(identitiesDir, identity);
|
|
21418
22034
|
}
|
|
21419
|
-
function historyStores(
|
|
22035
|
+
function historyStores(fs15, identitiesDir, identities) {
|
|
21420
22036
|
const byRealPath = /* @__PURE__ */ new Map();
|
|
21421
22037
|
for (const identity of identities) {
|
|
21422
22038
|
const configDir = identityConfigDir(identitiesDir, identity);
|
|
21423
|
-
const real =
|
|
22039
|
+
const real = fs15.realpath(path37.join(configDir, "projects"));
|
|
21424
22040
|
if (real === void 0) {
|
|
21425
22041
|
continue;
|
|
21426
22042
|
}
|
|
@@ -21433,15 +22049,15 @@ function historyStores(fs14, identitiesDir, identities) {
|
|
|
21433
22049
|
}
|
|
21434
22050
|
return [...byRealPath.values()];
|
|
21435
22051
|
}
|
|
21436
|
-
function collectSessionList(
|
|
22052
|
+
function collectSessionList(fs15, identitiesDir, identities, filters) {
|
|
21437
22053
|
const names = filters.identity === void 0 ? identities : identities.filter((name) => name === filters.identity);
|
|
21438
22054
|
if (filters.identity !== void 0 && names.length === 0) {
|
|
21439
22055
|
throw new SessionLookupError(`no identity named "${filters.identity}"`);
|
|
21440
22056
|
}
|
|
21441
22057
|
const sessions = [];
|
|
21442
|
-
for (const store of historyStores(
|
|
21443
|
-
for (const ref of listSessions2(
|
|
21444
|
-
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);
|
|
21445
22061
|
if (filters.all === true || summary.agentCount > 0 || summary.workflowRunCount > 0) {
|
|
21446
22062
|
sessions.push({ ...summary, identities: store.identities });
|
|
21447
22063
|
}
|
|
@@ -21449,14 +22065,14 @@ function collectSessionList(fs14, identitiesDir, identities, filters) {
|
|
|
21449
22065
|
}
|
|
21450
22066
|
return sessions.sort((left, right) => (right.updatedAt ?? "").localeCompare(left.updatedAt ?? "") || left.sessionId.localeCompare(right.sessionId));
|
|
21451
22067
|
}
|
|
21452
|
-
function locateSession(
|
|
22068
|
+
function locateSession(fs15, identitiesDir, identities, query, onlyIdentity) {
|
|
21453
22069
|
const names = onlyIdentity === void 0 ? identities : identities.filter((name) => name === onlyIdentity);
|
|
21454
22070
|
if (onlyIdentity !== void 0 && names.length === 0) {
|
|
21455
22071
|
throw new SessionLookupError(`no identity named "${onlyIdentity}"`);
|
|
21456
22072
|
}
|
|
21457
22073
|
const matches = [];
|
|
21458
|
-
for (const store of historyStores(
|
|
21459
|
-
for (const ref of listSessions2(
|
|
22074
|
+
for (const store of historyStores(fs15, identitiesDir, names)) {
|
|
22075
|
+
for (const ref of listSessions2(fs15, store.configDir)) {
|
|
21460
22076
|
if (ref.sessionId.startsWith(query)) {
|
|
21461
22077
|
matches.push({ identities: store.identities, configDir: store.configDir, ref });
|
|
21462
22078
|
}
|
|
@@ -21473,9 +22089,9 @@ function locateSession(fs14, identitiesDir, identities, query, onlyIdentity) {
|
|
|
21473
22089
|
}
|
|
21474
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`);
|
|
21475
22091
|
}
|
|
21476
|
-
function showSession(
|
|
21477
|
-
const located = locateSession(
|
|
21478
|
-
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) };
|
|
21479
22095
|
}
|
|
21480
22096
|
|
|
21481
22097
|
// src/agents/realFs.ts
|
|
@@ -21630,6 +22246,7 @@ export {
|
|
|
21630
22246
|
CodexRateLimitsReadSchema,
|
|
21631
22247
|
CodexSignInSchema,
|
|
21632
22248
|
CodexStatusOutputSchema,
|
|
22249
|
+
ConfigIdentityAddInputSchema,
|
|
21633
22250
|
ConfigIdentityAddOutputSchema,
|
|
21634
22251
|
ConfigIdentityRemoveInputSchema,
|
|
21635
22252
|
ConfigIdentityRemoveOutputSchema,
|