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.cjs
CHANGED
|
@@ -1128,7 +1128,7 @@ var init_schema = __esm({
|
|
|
1128
1128
|
resumeOnLimit: import_zod3.z.boolean().optional(),
|
|
1129
1129
|
/** 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. */
|
|
1130
1130
|
compactBeforeLimit: import_zod3.z.boolean().optional(),
|
|
1131
|
-
/** 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
|
|
1131
|
+
/** 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`. */
|
|
1132
1132
|
compactAtUtilisation: CompactAtUtilisationSchema.optional()
|
|
1133
1133
|
}).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"] });
|
|
1134
1134
|
WEEKDAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
|
|
@@ -1300,7 +1300,7 @@ function parseIgnoringUnrecognisedKeys(schema, raw) {
|
|
|
1300
1300
|
return second.success ? { success: true, data: second.data, ignored } : { success: false, issues: second.error.issues };
|
|
1301
1301
|
}
|
|
1302
1302
|
function describeIgnoredKeys(filePath, ignored) {
|
|
1303
|
-
const places = ignored.map(({ path:
|
|
1303
|
+
const places = ignored.map(({ path: path45, keys }) => `${path45.length === 0 ? "" : `${path45.map(String).join(".")}.`}${keys.join(", ")}`);
|
|
1304
1304
|
return `${filePath} has settings this version of agent-shim does not know and ignores: ${places.join("; ")}. A newer release may read them.`;
|
|
1305
1305
|
}
|
|
1306
1306
|
function noteIgnoredKeys(filePath, ignored) {
|
|
@@ -1322,9 +1322,9 @@ function restoreIgnoredKeys(filePath, value) {
|
|
|
1322
1322
|
return value;
|
|
1323
1323
|
}
|
|
1324
1324
|
const restored = structuredClone(value);
|
|
1325
|
-
for (const { path:
|
|
1325
|
+
for (const { path: path45, values } of ignored) {
|
|
1326
1326
|
let holder = restored;
|
|
1327
|
-
for (const step of
|
|
1327
|
+
for (const step of path45) {
|
|
1328
1328
|
holder = isRecord(holder) ? holder[step] : void 0;
|
|
1329
1329
|
}
|
|
1330
1330
|
if (isRecord(holder)) {
|
|
@@ -1371,6 +1371,12 @@ function captureRuleEntryOrders(value) {
|
|
|
1371
1371
|
}
|
|
1372
1372
|
return rules.map((rule) => captureEntryOrder(rule));
|
|
1373
1373
|
}
|
|
1374
|
+
function unparseableFile(error, filepath) {
|
|
1375
|
+
if (error instanceof SyntaxError) {
|
|
1376
|
+
return new ConfigFileNotJsonError(filepath);
|
|
1377
|
+
}
|
|
1378
|
+
return error instanceof Error && error.name === "YAMLException" ? new ConfigFileNotJsonError(filepath, "YAML") : void 0;
|
|
1379
|
+
}
|
|
1374
1380
|
function cosmiconfigReader(explorer = createExplorer()) {
|
|
1375
1381
|
return (filepath) => {
|
|
1376
1382
|
let result;
|
|
@@ -1381,7 +1387,7 @@ function cosmiconfigReader(explorer = createExplorer()) {
|
|
|
1381
1387
|
if (code === "ENOENT") {
|
|
1382
1388
|
return void 0;
|
|
1383
1389
|
}
|
|
1384
|
-
throw error;
|
|
1390
|
+
throw unparseableFile(error, filepath) ?? error;
|
|
1385
1391
|
}
|
|
1386
1392
|
if (result === null || result.isEmpty === true) {
|
|
1387
1393
|
return void 0;
|
|
@@ -1406,7 +1412,7 @@ function loadConfigFile(filepath, schema, read = cosmiconfigReader()) {
|
|
|
1406
1412
|
ruleEntryOrders: captureRuleEntryOrders(raw)
|
|
1407
1413
|
};
|
|
1408
1414
|
}
|
|
1409
|
-
var import_cosmiconfig, ConfigValidationError;
|
|
1415
|
+
var import_cosmiconfig, ConfigValidationError, ConfigFileNotJsonError;
|
|
1410
1416
|
var init_load = __esm({
|
|
1411
1417
|
"src/config/load.ts"() {
|
|
1412
1418
|
"use strict";
|
|
@@ -1425,6 +1431,16 @@ ${detail}`);
|
|
|
1425
1431
|
filepath;
|
|
1426
1432
|
issues;
|
|
1427
1433
|
};
|
|
1434
|
+
ConfigFileNotJsonError = class extends CliError {
|
|
1435
|
+
constructor(filepath, format = "JSON") {
|
|
1436
|
+
super(`${filepath} is not valid ${format}.`);
|
|
1437
|
+
this.filepath = filepath;
|
|
1438
|
+
this.format = format;
|
|
1439
|
+
this.name = "ConfigFileNotJsonError";
|
|
1440
|
+
}
|
|
1441
|
+
filepath;
|
|
1442
|
+
format;
|
|
1443
|
+
};
|
|
1428
1444
|
}
|
|
1429
1445
|
});
|
|
1430
1446
|
|
|
@@ -1437,7 +1453,12 @@ function readJson(filePath, schema, storeFs = nodeStoreFs) {
|
|
|
1437
1453
|
if (raw === void 0) {
|
|
1438
1454
|
return void 0;
|
|
1439
1455
|
}
|
|
1440
|
-
|
|
1456
|
+
let parsed;
|
|
1457
|
+
try {
|
|
1458
|
+
parsed = JSON.parse(raw);
|
|
1459
|
+
} catch (error) {
|
|
1460
|
+
throw error instanceof SyntaxError ? new ConfigFileNotJsonError(filePath) : error;
|
|
1461
|
+
}
|
|
1441
1462
|
const result = parseIgnoringUnrecognisedKeys(schema, parsed);
|
|
1442
1463
|
if (!result.success) {
|
|
1443
1464
|
throw new ConfigValidationError(filePath, result.issues);
|
|
@@ -1729,6 +1750,24 @@ function evaluateWhen(when, context) {
|
|
|
1729
1750
|
}
|
|
1730
1751
|
return { status: "definite", passed: failed.length === 0, checked, failed };
|
|
1731
1752
|
}
|
|
1753
|
+
function referencesFact(when, key) {
|
|
1754
|
+
if (when === void 0 || !("kind" in when)) {
|
|
1755
|
+
return false;
|
|
1756
|
+
}
|
|
1757
|
+
const walk2 = (node) => {
|
|
1758
|
+
if (Array.isArray(node)) {
|
|
1759
|
+
return node.some(walk2);
|
|
1760
|
+
}
|
|
1761
|
+
if (typeof node !== "object" || node === null) {
|
|
1762
|
+
return false;
|
|
1763
|
+
}
|
|
1764
|
+
if ("kind" in node && node.kind === "reference" && "key" in node && node.key === key) {
|
|
1765
|
+
return true;
|
|
1766
|
+
}
|
|
1767
|
+
return Object.values(node).some(walk2);
|
|
1768
|
+
};
|
|
1769
|
+
return walk2(when);
|
|
1770
|
+
}
|
|
1732
1771
|
function isVacuousWhen(when) {
|
|
1733
1772
|
return when !== void 0 && !("kind" in when) && Object.keys(when).length === 0;
|
|
1734
1773
|
}
|
|
@@ -2925,6 +2964,14 @@ function acquireIdentityLock(params) {
|
|
|
2925
2964
|
return {
|
|
2926
2965
|
path: lockPath,
|
|
2927
2966
|
token,
|
|
2967
|
+
refresh: () => {
|
|
2968
|
+
const current = parseLockRecord(params.fs.readFileUtf8(lockPath));
|
|
2969
|
+
if (current?.token !== token) {
|
|
2970
|
+
throw new IdentityLockLostError(params.identity);
|
|
2971
|
+
}
|
|
2972
|
+
params.fs.writeFilePrivate(lockPath, `${JSON.stringify({ ...current, acquiredAtMs: params.nowMs() })}
|
|
2973
|
+
`);
|
|
2974
|
+
},
|
|
2928
2975
|
release: () => {
|
|
2929
2976
|
const current = parseLockRecord(params.fs.readFileUtf8(lockPath));
|
|
2930
2977
|
if (current !== void 0 && current.token !== token) {
|
|
@@ -2934,7 +2981,19 @@ function acquireIdentityLock(params) {
|
|
|
2934
2981
|
}
|
|
2935
2982
|
};
|
|
2936
2983
|
}
|
|
2937
|
-
const
|
|
2984
|
+
const raw = params.fs.readFileUtf8(lockPath);
|
|
2985
|
+
if (raw === void 0) {
|
|
2986
|
+
continue;
|
|
2987
|
+
}
|
|
2988
|
+
let existing = parseLockRecord(raw);
|
|
2989
|
+
if (existing === void 0) {
|
|
2990
|
+
params.sleep(retryDelayMs);
|
|
2991
|
+
const again = params.fs.readFileUtf8(lockPath);
|
|
2992
|
+
if (again === void 0) {
|
|
2993
|
+
continue;
|
|
2994
|
+
}
|
|
2995
|
+
existing = parseLockRecord(again);
|
|
2996
|
+
}
|
|
2938
2997
|
if (existing === void 0) {
|
|
2939
2998
|
params.fs.removeRecursive(lockPath);
|
|
2940
2999
|
continue;
|
|
@@ -2949,7 +3008,7 @@ function acquireIdentityLock(params) {
|
|
|
2949
3008
|
}
|
|
2950
3009
|
throw new IdentityLockBusyError(params.identity, lockPath, lastHolderPid);
|
|
2951
3010
|
}
|
|
2952
|
-
var import_node_crypto2, import_node_path7, DEFAULT_STALE_AFTER_MS, DEFAULT_RETRY_DELAY_MS, DEFAULT_MAX_ATTEMPTS, IdentityLockBusyError;
|
|
3011
|
+
var import_node_crypto2, import_node_path7, DEFAULT_STALE_AFTER_MS, DEFAULT_RETRY_DELAY_MS, DEFAULT_MAX_ATTEMPTS, IdentityLockLostError, IdentityLockBusyError;
|
|
2953
3012
|
var init_lock = __esm({
|
|
2954
3013
|
"src/launcher/lock.ts"() {
|
|
2955
3014
|
"use strict";
|
|
@@ -2959,6 +3018,14 @@ var init_lock = __esm({
|
|
|
2959
3018
|
DEFAULT_STALE_AFTER_MS = 12e4;
|
|
2960
3019
|
DEFAULT_RETRY_DELAY_MS = 50;
|
|
2961
3020
|
DEFAULT_MAX_ATTEMPTS = 200;
|
|
3021
|
+
IdentityLockLostError = class extends CliError {
|
|
3022
|
+
constructor(identity) {
|
|
3023
|
+
super(`The lock on identity "${identity}" was taken over by another process while it was held, so nothing it guards can be assumed unchanged.`);
|
|
3024
|
+
this.identity = identity;
|
|
3025
|
+
this.name = "IdentityLockLostError";
|
|
3026
|
+
}
|
|
3027
|
+
identity;
|
|
3028
|
+
};
|
|
2962
3029
|
IdentityLockBusyError = class extends CliError {
|
|
2963
3030
|
constructor(identity, lockPath, holderPid) {
|
|
2964
3031
|
super(
|
|
@@ -2977,8 +3044,8 @@ var init_lock = __esm({
|
|
|
2977
3044
|
});
|
|
2978
3045
|
|
|
2979
3046
|
// src/launcher/farm.ts
|
|
2980
|
-
function readFarmManifest(
|
|
2981
|
-
const raw =
|
|
3047
|
+
function readFarmManifest(fs15, farmRoot) {
|
|
3048
|
+
const raw = fs15.readFileUtf8(import_node_path8.default.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs15.readFileUtf8(import_node_path8.default.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
|
|
2982
3049
|
if (raw === void 0) {
|
|
2983
3050
|
return void 0;
|
|
2984
3051
|
}
|
|
@@ -3036,9 +3103,9 @@ function buildEntryFacts(params) {
|
|
|
3036
3103
|
entries
|
|
3037
3104
|
};
|
|
3038
3105
|
}
|
|
3039
|
-
function listSubtree(
|
|
3106
|
+
function listSubtree(fs15, root, rel) {
|
|
3040
3107
|
const absolute = import_node_path8.default.join(root, rel);
|
|
3041
|
-
const stat =
|
|
3108
|
+
const stat = fs15.lstat(absolute);
|
|
3042
3109
|
if (stat === void 0) {
|
|
3043
3110
|
return [];
|
|
3044
3111
|
}
|
|
@@ -3046,10 +3113,10 @@ function listSubtree(fs14, root, rel) {
|
|
|
3046
3113
|
return [{ rel, kind: "symlink" }];
|
|
3047
3114
|
}
|
|
3048
3115
|
if (stat.kind === "dir") {
|
|
3049
|
-
const children = [...
|
|
3116
|
+
const children = [...fs15.readdir(absolute)].sort().flatMap((name) => listSubtree(fs15, root, `${rel}/${name}`));
|
|
3050
3117
|
return [{ rel, kind: "dir" }, ...children];
|
|
3051
3118
|
}
|
|
3052
|
-
const contentHash =
|
|
3119
|
+
const contentHash = fs15.hashFile(absolute);
|
|
3053
3120
|
return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
|
|
3054
3121
|
}
|
|
3055
3122
|
function topLevelScopeRoots(roots) {
|
|
@@ -3063,25 +3130,25 @@ function topLevelScopeRoots(roots) {
|
|
|
3063
3130
|
}
|
|
3064
3131
|
return kept;
|
|
3065
3132
|
}
|
|
3066
|
-
function reconciliationScope(
|
|
3133
|
+
function reconciliationScope(fs15, farmRoot, manifest) {
|
|
3067
3134
|
if (manifest !== void 0) {
|
|
3068
3135
|
return topLevelScopeRoots(manifest.materialised);
|
|
3069
3136
|
}
|
|
3070
|
-
return [...
|
|
3137
|
+
return [...fs15.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs15.lstat(import_node_path8.default.join(farmRoot, name))?.kind === "dir").sort();
|
|
3071
3138
|
}
|
|
3072
|
-
function collectFarmListing(
|
|
3073
|
-
return scopeRoots.flatMap((root) => listSubtree(
|
|
3139
|
+
function collectFarmListing(fs15, farmRoot, scopeRoots) {
|
|
3140
|
+
return scopeRoots.flatMap((root) => listSubtree(fs15, farmRoot, root));
|
|
3074
3141
|
}
|
|
3075
|
-
function collectCanonicalCounterparts(
|
|
3142
|
+
function collectCanonicalCounterparts(fs15, claudeHome, farmListing) {
|
|
3076
3143
|
const out = [];
|
|
3077
3144
|
for (const entry of farmListing) {
|
|
3078
3145
|
const absolute = import_node_path8.default.join(claudeHome, entry.rel);
|
|
3079
|
-
const stat =
|
|
3146
|
+
const stat = fs15.lstat(absolute);
|
|
3080
3147
|
if (stat === void 0) {
|
|
3081
3148
|
continue;
|
|
3082
3149
|
}
|
|
3083
3150
|
if (stat.kind === "file") {
|
|
3084
|
-
const contentHash =
|
|
3151
|
+
const contentHash = fs15.hashFile(absolute);
|
|
3085
3152
|
out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
|
|
3086
3153
|
continue;
|
|
3087
3154
|
}
|
|
@@ -3323,6 +3390,9 @@ function resyncFarm(params) {
|
|
|
3323
3390
|
farmRoot,
|
|
3324
3391
|
classification: params.classification
|
|
3325
3392
|
});
|
|
3393
|
+
if (params.identityExists?.() === false) {
|
|
3394
|
+
throw new IdentityGoneError(params.identity);
|
|
3395
|
+
}
|
|
3326
3396
|
const previousManifest = readFarmManifest(params.fs, farmRoot);
|
|
3327
3397
|
const scope = reconciliationScope(params.fs, farmRoot, previousManifest);
|
|
3328
3398
|
const farmListing = collectFarmListing(params.fs, farmRoot, scope);
|
|
@@ -3438,7 +3508,7 @@ function recoveryDiagnostics(recovery, identity) {
|
|
|
3438
3508
|
}
|
|
3439
3509
|
];
|
|
3440
3510
|
}
|
|
3441
|
-
var import_node_path8, import_zod4, FARM_MANIFEST_FILENAME, FarmManifestSchema;
|
|
3511
|
+
var import_node_path8, import_zod4, FARM_MANIFEST_FILENAME, FarmManifestSchema, IdentityGoneError;
|
|
3442
3512
|
var init_farm = __esm({
|
|
3443
3513
|
"src/launcher/farm.ts"() {
|
|
3444
3514
|
"use strict";
|
|
@@ -3447,6 +3517,7 @@ var init_farm = __esm({
|
|
|
3447
3517
|
init_classify();
|
|
3448
3518
|
init_reconcile();
|
|
3449
3519
|
init_pipeline();
|
|
3520
|
+
init_cliError();
|
|
3450
3521
|
init_legacy();
|
|
3451
3522
|
init_lock();
|
|
3452
3523
|
FARM_MANIFEST_FILENAME = ".agent-shim-farm.json";
|
|
@@ -3460,6 +3531,14 @@ var init_farm = __esm({
|
|
|
3460
3531
|
materialised: import_zod4.z.array(import_zod4.z.string()),
|
|
3461
3532
|
links: import_zod4.z.array(import_zod4.z.strictObject({ rel: import_zod4.z.string(), target: import_zod4.z.string() }))
|
|
3462
3533
|
});
|
|
3534
|
+
IdentityGoneError = class extends CliError {
|
|
3535
|
+
constructor(identity) {
|
|
3536
|
+
super(`Identity "${identity}" no longer exists: it was renamed or removed while this launch waited for it. Launch it under its current name.`);
|
|
3537
|
+
this.identity = identity;
|
|
3538
|
+
this.name = "IdentityGoneError";
|
|
3539
|
+
}
|
|
3540
|
+
identity;
|
|
3541
|
+
};
|
|
3463
3542
|
}
|
|
3464
3543
|
});
|
|
3465
3544
|
|
|
@@ -3852,10 +3931,10 @@ var init_route = __esm({
|
|
|
3852
3931
|
});
|
|
3853
3932
|
|
|
3854
3933
|
// src/frontdoor/state.ts
|
|
3855
|
-
function readFrontDoorState(
|
|
3934
|
+
function readFrontDoorState(fs15, stateFile) {
|
|
3856
3935
|
let raw;
|
|
3857
3936
|
try {
|
|
3858
|
-
raw =
|
|
3937
|
+
raw = fs15.readFileUtf8(stateFile);
|
|
3859
3938
|
} catch {
|
|
3860
3939
|
return void 0;
|
|
3861
3940
|
}
|
|
@@ -3869,9 +3948,9 @@ function readFrontDoorState(fs14, stateFile) {
|
|
|
3869
3948
|
return void 0;
|
|
3870
3949
|
}
|
|
3871
3950
|
}
|
|
3872
|
-
function writeFrontDoorState(
|
|
3873
|
-
|
|
3874
|
-
|
|
3951
|
+
function writeFrontDoorState(fs15, stateFile, state) {
|
|
3952
|
+
fs15.mkdirp(import_node_path9.default.dirname(stateFile));
|
|
3953
|
+
fs15.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
3875
3954
|
`);
|
|
3876
3955
|
}
|
|
3877
3956
|
function directOrigin(port) {
|
|
@@ -3881,37 +3960,37 @@ function frontDoorOrigin(state) {
|
|
|
3881
3960
|
const port = state?.directPort ?? state?.lastDirectPort;
|
|
3882
3961
|
return port === void 0 ? void 0 : directOrigin(port);
|
|
3883
3962
|
}
|
|
3884
|
-
function writeFrontDoorDirectRecord(
|
|
3885
|
-
|
|
3886
|
-
|
|
3963
|
+
function writeFrontDoorDirectRecord(fs15, recordsDir, record) {
|
|
3964
|
+
fs15.mkdirp(recordsDir);
|
|
3965
|
+
fs15.writeFilePrivate(import_node_path9.default.join(recordsDir, `${String(record.pid)}.json`), `${JSON.stringify({ directPort: record.directPort })}
|
|
3887
3966
|
`);
|
|
3888
3967
|
}
|
|
3889
|
-
function removeFrontDoorDirectRecord(
|
|
3890
|
-
|
|
3968
|
+
function removeFrontDoorDirectRecord(fs15, recordsDir, pid) {
|
|
3969
|
+
fs15.removeRecursive(import_node_path9.default.join(recordsDir, `${String(pid)}.json`));
|
|
3891
3970
|
}
|
|
3892
|
-
function markFrontDoorDraining(
|
|
3893
|
-
|
|
3894
|
-
|
|
3971
|
+
function markFrontDoorDraining(fs15, markersDir, pid) {
|
|
3972
|
+
fs15.mkdirp(markersDir);
|
|
3973
|
+
fs15.writeFilePrivate(import_node_path9.default.join(markersDir, String(pid)), "\n");
|
|
3895
3974
|
}
|
|
3896
|
-
function unmarkFrontDoorDraining(
|
|
3897
|
-
|
|
3975
|
+
function unmarkFrontDoorDraining(fs15, markersDir, pid) {
|
|
3976
|
+
fs15.removeRecursive(import_node_path9.default.join(markersDir, String(pid)));
|
|
3898
3977
|
}
|
|
3899
|
-
function listDrainingFrontDoors(
|
|
3900
|
-
return
|
|
3978
|
+
function listDrainingFrontDoors(fs15, markersDir, isRunning) {
|
|
3979
|
+
return fs15.readdir(markersDir).flatMap((file) => /^[1-9]\d*$/.test(file) && Number.isSafeInteger(Number(file)) ? [Number(file)] : []).filter(isRunning).sort((a, b) => a - b);
|
|
3901
3980
|
}
|
|
3902
3981
|
function recordPid(file) {
|
|
3903
3982
|
const pidText = /^([1-9]\d*)\.json$/.exec(file)?.[1];
|
|
3904
3983
|
const pid = pidText === void 0 ? void 0 : Number(pidText);
|
|
3905
3984
|
return pid !== void 0 && Number.isSafeInteger(pid) ? pid : void 0;
|
|
3906
3985
|
}
|
|
3907
|
-
function readDirectRecordEntry(
|
|
3986
|
+
function readDirectRecordEntry(fs15, recordsDir, file) {
|
|
3908
3987
|
const pid = recordPid(file);
|
|
3909
3988
|
if (pid === void 0) {
|
|
3910
3989
|
return void 0;
|
|
3911
3990
|
}
|
|
3912
3991
|
let raw;
|
|
3913
3992
|
try {
|
|
3914
|
-
raw =
|
|
3993
|
+
raw = fs15.readFileUtf8(import_node_path9.default.join(recordsDir, file));
|
|
3915
3994
|
} catch {
|
|
3916
3995
|
return void 0;
|
|
3917
3996
|
}
|
|
@@ -3925,37 +4004,37 @@ function readDirectRecordEntry(fs14, recordsDir, file) {
|
|
|
3925
4004
|
return { malformed: true };
|
|
3926
4005
|
}
|
|
3927
4006
|
}
|
|
3928
|
-
function listFrontDoorDirectRecords(
|
|
3929
|
-
return
|
|
3930
|
-
const entry = readDirectRecordEntry(
|
|
4007
|
+
function listFrontDoorDirectRecords(fs15, recordsDir) {
|
|
4008
|
+
return fs15.readdir(recordsDir).flatMap((file) => {
|
|
4009
|
+
const entry = readDirectRecordEntry(fs15, recordsDir, file);
|
|
3931
4010
|
return entry?.record === void 0 ? [] : [entry.record];
|
|
3932
4011
|
}).sort((a, b) => a.pid - b.pid);
|
|
3933
4012
|
}
|
|
3934
|
-
function pruneMalformedFrontDoorDirectFiles(
|
|
3935
|
-
for (const file of
|
|
4013
|
+
function pruneMalformedFrontDoorDirectFiles(fs15, recordsDir, isRunning) {
|
|
4014
|
+
for (const file of fs15.readdir(recordsDir)) {
|
|
3936
4015
|
const writer = RECORD_TEMPORARY_FILE.exec(file)?.[1];
|
|
3937
4016
|
const stale = writer !== void 0 && !isRunning(Number(writer));
|
|
3938
|
-
if (stale || readDirectRecordEntry(
|
|
3939
|
-
|
|
4017
|
+
if (stale || readDirectRecordEntry(fs15, recordsDir, file)?.malformed === true) {
|
|
4018
|
+
fs15.removeRecursive(import_node_path9.default.join(recordsDir, file));
|
|
3940
4019
|
}
|
|
3941
4020
|
}
|
|
3942
4021
|
}
|
|
3943
4022
|
function liveFrontDoorDirectRecords(records, liveness) {
|
|
3944
4023
|
return records.filter((record) => liveness.doors.has(record.pid) || liveness.unknown.has(record.pid));
|
|
3945
4024
|
}
|
|
3946
|
-
function pruneDeadFrontDoorDirectRecords(
|
|
4025
|
+
function pruneDeadFrontDoorDirectRecords(fs15, recordsDir, records, liveness) {
|
|
3947
4026
|
for (const record of records) {
|
|
3948
4027
|
if (!liveness.doors.has(record.pid) && !liveness.unknown.has(record.pid)) {
|
|
3949
|
-
removeFrontDoorDirectRecord(
|
|
4028
|
+
removeFrontDoorDirectRecord(fs15, recordsDir, record.pid);
|
|
3950
4029
|
}
|
|
3951
4030
|
}
|
|
3952
4031
|
}
|
|
3953
4032
|
function recordOf(details) {
|
|
3954
4033
|
return details === void 0 ? {} : { sessionId: details.sessionId, ...details.models === void 0 ? {} : { models: details.models } };
|
|
3955
4034
|
}
|
|
3956
|
-
function writeFrontDoorSession(
|
|
3957
|
-
|
|
3958
|
-
|
|
4035
|
+
function writeFrontDoorSession(fs15, sessionsDir, session) {
|
|
4036
|
+
fs15.mkdirPrivate(sessionsDir);
|
|
4037
|
+
fs15.writeFilePrivate(import_node_path9.default.join(sessionsDir, sessionRecordName(session.pid)), `${JSON.stringify(session, null, 2)}
|
|
3959
4038
|
`);
|
|
3960
4039
|
}
|
|
3961
4040
|
function sessionRecordName(pid) {
|
|
@@ -3967,32 +4046,32 @@ function isSessionRecordName(name) {
|
|
|
3967
4046
|
function summaryOf(session) {
|
|
3968
4047
|
return { pid: session.pid, startedAt: session.startedAt, ...session.supervisorPid === void 0 ? {} : { supervisorPid: session.supervisorPid } };
|
|
3969
4048
|
}
|
|
3970
|
-
function readFrontDoorSessionRecord(
|
|
4049
|
+
function readFrontDoorSessionRecord(fs15, sessionsDir, name) {
|
|
3971
4050
|
try {
|
|
3972
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(
|
|
4051
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs15.readFileUtf8(import_node_path9.default.join(sessionsDir, name)) ?? ""));
|
|
3973
4052
|
return parsed.success ? parsed.data : void 0;
|
|
3974
4053
|
} catch {
|
|
3975
4054
|
return void 0;
|
|
3976
4055
|
}
|
|
3977
4056
|
}
|
|
3978
|
-
function listFrontDoorSessions(
|
|
4057
|
+
function listFrontDoorSessions(fs15, sessionsDir) {
|
|
3979
4058
|
const sessions = [];
|
|
3980
|
-
for (const name of
|
|
3981
|
-
const record = isSessionRecordName(name) ? readFrontDoorSessionRecord(
|
|
4059
|
+
for (const name of fs15.readdir(sessionsDir)) {
|
|
4060
|
+
const record = isSessionRecordName(name) ? readFrontDoorSessionRecord(fs15, sessionsDir, name) : void 0;
|
|
3982
4061
|
if (record !== void 0) {
|
|
3983
4062
|
sessions.push(summaryOf(record));
|
|
3984
4063
|
}
|
|
3985
4064
|
}
|
|
3986
4065
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
3987
4066
|
}
|
|
3988
|
-
function removeFrontDoorSession(
|
|
3989
|
-
|
|
4067
|
+
function removeFrontDoorSession(fs15, sessionsDir, pid) {
|
|
4068
|
+
fs15.removeRecursive(import_node_path9.default.join(sessionsDir, sessionRecordName(pid)));
|
|
3990
4069
|
}
|
|
3991
|
-
function pruneDeadFrontDoorSessions(
|
|
4070
|
+
function pruneDeadFrontDoorSessions(fs15, sessionsDir, listed, isRunning) {
|
|
3992
4071
|
const removed = [];
|
|
3993
4072
|
for (const session of listed) {
|
|
3994
4073
|
if (!isRunning(session.pid)) {
|
|
3995
|
-
removeFrontDoorSession(
|
|
4074
|
+
removeFrontDoorSession(fs15, sessionsDir, session.pid);
|
|
3996
4075
|
removed.push(session.pid);
|
|
3997
4076
|
}
|
|
3998
4077
|
}
|
|
@@ -4091,9 +4170,9 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
4091
4170
|
}
|
|
4092
4171
|
}
|
|
4093
4172
|
async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
4094
|
-
const { fs:
|
|
4173
|
+
const { fs: fs15, paths } = ports;
|
|
4095
4174
|
const servingBinary = ports.statOwnExecutable();
|
|
4096
|
-
const previous = readFrontDoorState(
|
|
4175
|
+
const previous = readFrontDoorState(fs15, paths.frontdoorStateFile);
|
|
4097
4176
|
let lastPort = previous?.lastPort;
|
|
4098
4177
|
let lastConnectPort = previous?.lastConnectPort;
|
|
4099
4178
|
let lastDirectPort = previous?.lastDirectPort;
|
|
@@ -4107,14 +4186,14 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4107
4186
|
const fail = (message) => {
|
|
4108
4187
|
ports.closeRcStreamHub();
|
|
4109
4188
|
if (predecessor === void 0) {
|
|
4110
|
-
writeFrontDoorState(
|
|
4111
|
-
|
|
4189
|
+
writeFrontDoorState(fs15, paths.frontdoorStateFile, { lastError: message, ...sticky() });
|
|
4190
|
+
fs15.removeRecursive(paths.frontdoorLockFile);
|
|
4112
4191
|
}
|
|
4113
4192
|
ports.log(`agent-shim frontdoor supervisor: ${message}`);
|
|
4114
4193
|
return 1;
|
|
4115
4194
|
};
|
|
4116
4195
|
if (predecessor === void 0) {
|
|
4117
|
-
writeFrontDoorState(
|
|
4196
|
+
writeFrontDoorState(fs15, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
|
|
4118
4197
|
}
|
|
4119
4198
|
const previousSticky = lastPort;
|
|
4120
4199
|
let http3;
|
|
@@ -4155,11 +4234,11 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4155
4234
|
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)`);
|
|
4156
4235
|
}
|
|
4157
4236
|
lastDirectPort = direct.port;
|
|
4158
|
-
writeFrontDoorDirectRecord(
|
|
4159
|
-
writeFrontDoorState(
|
|
4237
|
+
writeFrontDoorDirectRecord(fs15, paths.frontdoorDirectRecordsDir, { pid: ports.ownPid, directPort: direct.port });
|
|
4238
|
+
writeFrontDoorState(fs15, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
4160
4239
|
ports.doorHealth.generation({ providerPort: http3.port, connectPort: connect3.port, directPort: direct.port });
|
|
4161
4240
|
if (predecessor === void 0) {
|
|
4162
|
-
|
|
4241
|
+
fs15.removeRecursive(paths.frontdoorLockFile);
|
|
4163
4242
|
} else {
|
|
4164
4243
|
predecessor.serving();
|
|
4165
4244
|
}
|
|
@@ -4168,7 +4247,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4168
4247
|
let idleSince;
|
|
4169
4248
|
let ticks = 0;
|
|
4170
4249
|
const supersedingOwner = async () => {
|
|
4171
|
-
const owner = readFrontDoorState(
|
|
4250
|
+
const owner = readFrontDoorState(fs15, paths.frontdoorStateFile)?.supervisorPid;
|
|
4172
4251
|
return owner !== void 0 && owner !== ports.ownPid && (await ports.runningAmong([owner])).has(owner) ? owner : void 0;
|
|
4173
4252
|
};
|
|
4174
4253
|
let supersededBy;
|
|
@@ -4197,13 +4276,13 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4197
4276
|
ports.stopBackgroundWork?.();
|
|
4198
4277
|
const drained = [direct.drain(), connect3.drain(), http3.drain()];
|
|
4199
4278
|
if (await supersedingOwner() === void 0) {
|
|
4200
|
-
writeFrontDoorState(
|
|
4279
|
+
writeFrontDoorState(fs15, paths.frontdoorStateFile, sticky());
|
|
4201
4280
|
}
|
|
4202
|
-
markFrontDoorDraining(
|
|
4281
|
+
markFrontDoorDraining(fs15, paths.frontdoorDrainingDir, ports.ownPid);
|
|
4203
4282
|
ports.closeRcStreamHub();
|
|
4204
4283
|
await Promise.all(drained);
|
|
4205
|
-
unmarkFrontDoorDraining(
|
|
4206
|
-
removeFrontDoorDirectRecord(
|
|
4284
|
+
unmarkFrontDoorDraining(fs15, paths.frontdoorDrainingDir, ports.ownPid);
|
|
4285
|
+
removeFrontDoorDirectRecord(fs15, paths.frontdoorDirectRecordsDir, ports.ownPid);
|
|
4207
4286
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: the connections this door carried have ended; exiting`);
|
|
4208
4287
|
return 0;
|
|
4209
4288
|
};
|
|
@@ -4224,12 +4303,12 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4224
4303
|
await connect3.close();
|
|
4225
4304
|
await http3.close();
|
|
4226
4305
|
ports.closeRcStreamHub();
|
|
4227
|
-
removeFrontDoorDirectRecord(
|
|
4306
|
+
removeFrontDoorDirectRecord(fs15, paths.frontdoorDirectRecordsDir, ports.ownPid);
|
|
4228
4307
|
};
|
|
4229
4308
|
const shutdown = async () => {
|
|
4230
4309
|
await closeServing();
|
|
4231
4310
|
if (await supersedingOwner() === void 0) {
|
|
4232
|
-
writeFrontDoorState(
|
|
4311
|
+
writeFrontDoorState(fs15, paths.frontdoorStateFile, sticky());
|
|
4233
4312
|
}
|
|
4234
4313
|
return 0;
|
|
4235
4314
|
};
|
|
@@ -4248,7 +4327,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4248
4327
|
ticks += 1;
|
|
4249
4328
|
const listed = ports.registry.rescan();
|
|
4250
4329
|
const running = await ports.runningAmong(listed.map((session) => session.pid));
|
|
4251
|
-
const pruned = pruneDeadFrontDoorSessions(
|
|
4330
|
+
const pruned = pruneDeadFrontDoorSessions(fs15, paths.frontdoorSessionsDir, listed, (pid) => running.has(pid));
|
|
4252
4331
|
ports.registry.forget(pruned);
|
|
4253
4332
|
ports.observeLaunchRegistry(listed, pruned);
|
|
4254
4333
|
ports.checkQuotaExpiry();
|
|
@@ -4322,8 +4401,8 @@ function parseConnectTarget(authority) {
|
|
|
4322
4401
|
function isInterceptedHost(host, interceptHosts) {
|
|
4323
4402
|
return interceptHosts.includes(host);
|
|
4324
4403
|
}
|
|
4325
|
-
function servedByPipeline(
|
|
4326
|
-
return
|
|
4404
|
+
function servedByPipeline(path45) {
|
|
4405
|
+
return path45?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
4327
4406
|
}
|
|
4328
4407
|
function forwardableHeaders(headers) {
|
|
4329
4408
|
const connectionTokens = new Set(
|
|
@@ -4769,7 +4848,7 @@ var init_package = __esm({
|
|
|
4769
4848
|
"package.json"() {
|
|
4770
4849
|
package_default = {
|
|
4771
4850
|
name: "agent-shim",
|
|
4772
|
-
version: "11.
|
|
4851
|
+
version: "11.83.0",
|
|
4773
4852
|
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.",
|
|
4774
4853
|
license: "MIT",
|
|
4775
4854
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -4991,43 +5070,43 @@ function parseJson(raw, schema) {
|
|
|
4991
5070
|
const parsed = schema.safeParse(JSON.parse(raw));
|
|
4992
5071
|
return parsed.success ? parsed.data : void 0;
|
|
4993
5072
|
}
|
|
4994
|
-
function readHeadroomState(
|
|
5073
|
+
function readHeadroomState(fs15, stateFile) {
|
|
4995
5074
|
try {
|
|
4996
|
-
return parseJson(
|
|
5075
|
+
return parseJson(fs15.readFileUtf8(stateFile), HeadroomStateSchema);
|
|
4997
5076
|
} catch {
|
|
4998
5077
|
return void 0;
|
|
4999
5078
|
}
|
|
5000
5079
|
}
|
|
5001
|
-
function writeHeadroomState(
|
|
5002
|
-
|
|
5003
|
-
|
|
5080
|
+
function writeHeadroomState(fs15, stateFile, state) {
|
|
5081
|
+
fs15.mkdirp(import_node_path12.default.dirname(stateFile));
|
|
5082
|
+
fs15.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
5004
5083
|
`);
|
|
5005
5084
|
}
|
|
5006
|
-
function resolveServingHeadroomState(
|
|
5007
|
-
const current = readHeadroomState(
|
|
5085
|
+
function resolveServingHeadroomState(fs15, files, isRunning) {
|
|
5086
|
+
const current = readHeadroomState(fs15, files.stateFile);
|
|
5008
5087
|
if (current !== void 0) {
|
|
5009
5088
|
return { path: files.stateFile, state: current };
|
|
5010
5089
|
}
|
|
5011
|
-
const legacy = readHeadroomState(
|
|
5090
|
+
const legacy = readHeadroomState(fs15, files.legacyStateFile);
|
|
5012
5091
|
if (legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid)) {
|
|
5013
5092
|
return { path: files.legacyStateFile, state: legacy };
|
|
5014
5093
|
}
|
|
5015
5094
|
return void 0;
|
|
5016
5095
|
}
|
|
5017
|
-
function migrateHeadroomState(
|
|
5018
|
-
const legacy = readHeadroomState(
|
|
5096
|
+
function migrateHeadroomState(fs15, files, isRunning) {
|
|
5097
|
+
const legacy = readHeadroomState(fs15, files.legacyStateFile);
|
|
5019
5098
|
const legacyLive = legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid);
|
|
5020
|
-
const current = readHeadroomState(
|
|
5099
|
+
const current = readHeadroomState(fs15, files.stateFile);
|
|
5021
5100
|
if (current !== void 0 || legacyLive) {
|
|
5022
|
-
if (!legacyLive &&
|
|
5023
|
-
|
|
5101
|
+
if (!legacyLive && fs15.readFileUtf8(files.legacyStateFile) !== void 0) {
|
|
5102
|
+
fs15.removeRecursive(files.legacyStateFile);
|
|
5024
5103
|
}
|
|
5025
5104
|
return;
|
|
5026
5105
|
}
|
|
5027
5106
|
if (legacy !== void 0) {
|
|
5028
|
-
writeHeadroomState(
|
|
5107
|
+
writeHeadroomState(fs15, files.stateFile, legacy);
|
|
5029
5108
|
}
|
|
5030
|
-
|
|
5109
|
+
fs15.removeRecursive(files.legacyStateFile);
|
|
5031
5110
|
}
|
|
5032
5111
|
function hashAllowlist(allowlist) {
|
|
5033
5112
|
return (0, import_node_crypto6.createHash)("sha256").update(allowlist.join("\n")).digest("hex");
|
|
@@ -5060,27 +5139,27 @@ function isAdmissibleUrl(entry) {
|
|
|
5060
5139
|
function parseAllowlistFile(content) {
|
|
5061
5140
|
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)));
|
|
5062
5141
|
}
|
|
5063
|
-
function writeAllowlistFile(
|
|
5064
|
-
|
|
5065
|
-
|
|
5142
|
+
function writeAllowlistFile(fs15, allowlistFile, allowlist) {
|
|
5143
|
+
fs15.mkdirPrivate(import_node_path12.default.dirname(allowlistFile));
|
|
5144
|
+
fs15.writeFilePrivate(allowlistFile, formatAllowlistFile(allowlist));
|
|
5066
5145
|
}
|
|
5067
|
-
function pruneStaleAllowlistTemporaries(
|
|
5146
|
+
function pruneStaleAllowlistTemporaries(fs15, allowlistFile, isRunning) {
|
|
5068
5147
|
const prefix = `${import_node_path12.default.basename(allowlistFile)}.`;
|
|
5069
|
-
for (const name of
|
|
5148
|
+
for (const name of fs15.readdir(import_node_path12.default.dirname(allowlistFile))) {
|
|
5070
5149
|
const writer = name.startsWith(prefix) ? /^([1-9]\d*)\.tmp$/.exec(name.slice(prefix.length))?.[1] : void 0;
|
|
5071
5150
|
if (writer !== void 0 && !isRunning(Number(writer))) {
|
|
5072
|
-
|
|
5151
|
+
fs15.removeRecursive(import_node_path12.default.join(import_node_path12.default.dirname(allowlistFile), name));
|
|
5073
5152
|
}
|
|
5074
5153
|
}
|
|
5075
5154
|
}
|
|
5076
|
-
function readAllProviders(
|
|
5155
|
+
function readAllProviders(fs15, providersDir) {
|
|
5077
5156
|
const result = [];
|
|
5078
|
-
for (const name of
|
|
5157
|
+
for (const name of fs15.readdir(providersDir)) {
|
|
5079
5158
|
if (!name.endsWith(".json")) {
|
|
5080
5159
|
continue;
|
|
5081
5160
|
}
|
|
5082
5161
|
try {
|
|
5083
|
-
const parsed = parseJson(
|
|
5162
|
+
const parsed = parseJson(fs15.readFileUtf8(import_node_path12.default.join(providersDir, name)), ProviderSchema);
|
|
5084
5163
|
if (parsed !== void 0) {
|
|
5085
5164
|
result.push({ name: name.slice(0, -".json".length), provider: parsed });
|
|
5086
5165
|
}
|
|
@@ -5090,22 +5169,22 @@ function readAllProviders(fs14, providersDir) {
|
|
|
5090
5169
|
}
|
|
5091
5170
|
return result;
|
|
5092
5171
|
}
|
|
5093
|
-
function writeSession(
|
|
5094
|
-
|
|
5095
|
-
|
|
5172
|
+
function writeSession(fs15, sessionsDir, session) {
|
|
5173
|
+
fs15.mkdirp(sessionsDir);
|
|
5174
|
+
fs15.writeFileUtf8(import_node_path12.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
5096
5175
|
`);
|
|
5097
5176
|
}
|
|
5098
|
-
function removeSession(
|
|
5099
|
-
|
|
5177
|
+
function removeSession(fs15, sessionsDir, pid) {
|
|
5178
|
+
fs15.removeRecursive(import_node_path12.default.join(sessionsDir, `${String(pid)}.json`));
|
|
5100
5179
|
}
|
|
5101
|
-
function listSessions(
|
|
5180
|
+
function listSessions(fs15, sessionsDir) {
|
|
5102
5181
|
const sessions = [];
|
|
5103
|
-
for (const name of
|
|
5182
|
+
for (const name of fs15.readdir(sessionsDir)) {
|
|
5104
5183
|
if (!name.endsWith(".json")) {
|
|
5105
5184
|
continue;
|
|
5106
5185
|
}
|
|
5107
5186
|
try {
|
|
5108
|
-
const parsed = parseJson(
|
|
5187
|
+
const parsed = parseJson(fs15.readFileUtf8(import_node_path12.default.join(sessionsDir, name)), HeadroomSessionSchema);
|
|
5109
5188
|
if (parsed !== void 0) {
|
|
5110
5189
|
sessions.push(parsed);
|
|
5111
5190
|
}
|
|
@@ -5115,22 +5194,22 @@ function listSessions(fs14, sessionsDir) {
|
|
|
5115
5194
|
}
|
|
5116
5195
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
5117
5196
|
}
|
|
5118
|
-
function sessionsForSupervisor(
|
|
5119
|
-
return listSessions(
|
|
5197
|
+
function sessionsForSupervisor(fs15, sessionsDir, supervisorPid) {
|
|
5198
|
+
return listSessions(fs15, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
|
|
5120
5199
|
}
|
|
5121
|
-
function pruneDeadSessions(
|
|
5200
|
+
function pruneDeadSessions(fs15, sessionsDir, isRunning) {
|
|
5122
5201
|
const removed = [];
|
|
5123
|
-
for (const session of listSessions(
|
|
5202
|
+
for (const session of listSessions(fs15, sessionsDir)) {
|
|
5124
5203
|
if (!isRunning(session.pid)) {
|
|
5125
|
-
removeSession(
|
|
5204
|
+
removeSession(fs15, sessionsDir, session.pid);
|
|
5126
5205
|
removed.push(session.pid);
|
|
5127
5206
|
}
|
|
5128
5207
|
}
|
|
5129
5208
|
return removed;
|
|
5130
5209
|
}
|
|
5131
|
-
function readStartLock(
|
|
5210
|
+
function readStartLock(fs15, lockFile) {
|
|
5132
5211
|
try {
|
|
5133
|
-
return parseJson(
|
|
5212
|
+
return parseJson(fs15.readFileUtf8(lockFile), HeadroomLockSchema);
|
|
5134
5213
|
} catch {
|
|
5135
5214
|
return void 0;
|
|
5136
5215
|
}
|
|
@@ -5223,12 +5302,12 @@ function earlierReleaseAllowlistHash(providers, doorOrigin) {
|
|
|
5223
5302
|
}
|
|
5224
5303
|
return hashAllowlist([...entries].sort());
|
|
5225
5304
|
}
|
|
5226
|
-
function earlierReleaseDaemon(
|
|
5305
|
+
function earlierReleaseDaemon(fs15, paths, daemon) {
|
|
5227
5306
|
if (daemonIdentity(daemon.commandLine, daemon.socketPath) !== "earlier-release") {
|
|
5228
5307
|
return void 0;
|
|
5229
5308
|
}
|
|
5230
|
-
const providers = readAllProviders(
|
|
5231
|
-
const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(
|
|
5309
|
+
const providers = readAllProviders(fs15, paths.providersDir).map((entry) => entry.provider);
|
|
5310
|
+
const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(fs15, paths.frontdoorStateFile)));
|
|
5232
5311
|
return { admitsServingDoor: daemon.recordedHash === expected };
|
|
5233
5312
|
}
|
|
5234
5313
|
var EARLIER_RELEASE_ALLOWLIST, EARLIER_RELEASE_ANTHROPIC_UPSTREAM;
|
|
@@ -5253,8 +5332,8 @@ function awaitingCause(daemonPid, identity, allowlistFile) {
|
|
|
5253
5332
|
}
|
|
5254
5333
|
return `the headroom supervisor has not written an allowlist admitting this launch's upstreams to ${allowlistFile} within ${String(HEADROOM_START_TIMEOUT_MS)}ms`;
|
|
5255
5334
|
}
|
|
5256
|
-
function daemonAdmits(
|
|
5257
|
-
const content =
|
|
5335
|
+
function daemonAdmits(fs15, allowlistFile, recordedHash, required) {
|
|
5336
|
+
const content = fs15.readFileUtf8(allowlistFile);
|
|
5258
5337
|
if (content === void 0 || recordedHash === void 0) {
|
|
5259
5338
|
return false;
|
|
5260
5339
|
}
|
|
@@ -5523,7 +5602,7 @@ function verifyAllowlistFile(allowlistFile, ports) {
|
|
|
5523
5602
|
const replaceable = fileStat === void 0 || fileStat.kind === "file" || fileStat.kind === "symlink";
|
|
5524
5603
|
return { message: refusal2, repairable: replaceable };
|
|
5525
5604
|
}
|
|
5526
|
-
function prepareHeadroomSocket(
|
|
5605
|
+
function prepareHeadroomSocket(fs15, ports, paths, supervisorPid) {
|
|
5527
5606
|
const unsupported = platformRefusal(ports.platform);
|
|
5528
5607
|
if (unsupported !== void 0) {
|
|
5529
5608
|
return { refused: unsupported };
|
|
@@ -5538,18 +5617,18 @@ function prepareHeadroomSocket(fs14, ports, paths, supervisorPid) {
|
|
|
5538
5617
|
if (ports.lstat(paths.headroomSocketDir)?.kind === "symlink") {
|
|
5539
5618
|
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
5540
5619
|
}
|
|
5541
|
-
|
|
5620
|
+
fs15.mkdirPrivate(paths.headroomSocketDir);
|
|
5542
5621
|
const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
5543
5622
|
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
5544
5623
|
}
|
|
5545
|
-
function pruneStaleHeadroomSockets(
|
|
5624
|
+
function pruneStaleHeadroomSockets(fs15, paths, isRunning) {
|
|
5546
5625
|
const removed = [];
|
|
5547
|
-
for (const name of
|
|
5626
|
+
for (const name of fs15.readdir(paths.headroomSocketDir)) {
|
|
5548
5627
|
const pid = HEADROOM_SOCKET_NAME.exec(name)?.[1];
|
|
5549
5628
|
if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
|
|
5550
5629
|
continue;
|
|
5551
5630
|
}
|
|
5552
|
-
|
|
5631
|
+
fs15.removeRecursive(import_node_path13.default.join(paths.headroomSocketDir, name));
|
|
5553
5632
|
removed.push(name);
|
|
5554
5633
|
}
|
|
5555
5634
|
return removed;
|
|
@@ -5661,37 +5740,37 @@ function compareVersions2(a, b) {
|
|
|
5661
5740
|
return 0;
|
|
5662
5741
|
}
|
|
5663
5742
|
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
5664
|
-
const { fs:
|
|
5743
|
+
const { fs: fs15, paths } = ports;
|
|
5665
5744
|
let config = initialConfig;
|
|
5666
|
-
migrateHeadroomState(
|
|
5667
|
-
const previousState = resolveServingHeadroomState(
|
|
5745
|
+
migrateHeadroomState(fs15, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
|
|
5746
|
+
const previousState = resolveServingHeadroomState(fs15, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
|
|
5668
5747
|
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
5669
5748
|
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
5670
5749
|
return 0;
|
|
5671
5750
|
}
|
|
5672
5751
|
let installedSource = previousState?.installedSource;
|
|
5673
5752
|
const ownsState = () => {
|
|
5674
|
-
const owner = readHeadroomState(
|
|
5753
|
+
const owner = readHeadroomState(fs15, paths.headroomStateFile)?.supervisorPid;
|
|
5675
5754
|
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
5676
5755
|
};
|
|
5677
5756
|
const writeOwnState = (state) => {
|
|
5678
5757
|
if (!ownsState()) {
|
|
5679
5758
|
return false;
|
|
5680
5759
|
}
|
|
5681
|
-
writeHeadroomState(
|
|
5760
|
+
writeHeadroomState(fs15, paths.headroomStateFile, state);
|
|
5682
5761
|
return true;
|
|
5683
5762
|
};
|
|
5684
5763
|
const fail = (message) => {
|
|
5685
5764
|
if (writeOwnState({ lastError: message })) {
|
|
5686
|
-
|
|
5765
|
+
fs15.removeRecursive(paths.headroomLockFile);
|
|
5687
5766
|
}
|
|
5688
5767
|
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
5689
5768
|
return 1;
|
|
5690
5769
|
};
|
|
5691
5770
|
const syncAllowlistFile = (allowlist) => {
|
|
5692
5771
|
try {
|
|
5693
|
-
if (
|
|
5694
|
-
writeAllowlistFile(
|
|
5772
|
+
if (fs15.readFileUtf8(paths.headroomAllowlistFile) !== formatAllowlistFile(allowlist)) {
|
|
5773
|
+
writeAllowlistFile(fs15, paths.headroomAllowlistFile, allowlist);
|
|
5695
5774
|
ports.log(`agent-shim headroom supervisor: wrote allowlist [${allowlist.join(", ")}] to ${paths.headroomAllowlistFile}`);
|
|
5696
5775
|
}
|
|
5697
5776
|
return void 0;
|
|
@@ -5709,9 +5788,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5709
5788
|
}
|
|
5710
5789
|
ports.log(`agent-shim headroom supervisor: repairing the allowlist file: ${problem.message}`);
|
|
5711
5790
|
try {
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
writeAllowlistFile(
|
|
5791
|
+
fs15.mkdirPrivate(paths.headroomDir);
|
|
5792
|
+
fs15.mkdirPrivate(import_node_path14.default.dirname(paths.headroomAllowlistFile));
|
|
5793
|
+
writeAllowlistFile(fs15, paths.headroomAllowlistFile, allowlist);
|
|
5715
5794
|
} catch (error) {
|
|
5716
5795
|
return `could not write the headroom allowlist file ${paths.headroomAllowlistFile}: ${error instanceof Error ? error.message : String(error)}`;
|
|
5717
5796
|
}
|
|
@@ -5736,20 +5815,20 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5736
5815
|
installedSource = config.source;
|
|
5737
5816
|
return void 0;
|
|
5738
5817
|
};
|
|
5739
|
-
const socket = prepareHeadroomSocket(
|
|
5818
|
+
const socket = prepareHeadroomSocket(fs15, ports.socketTrust, paths, ports.ownPid);
|
|
5740
5819
|
if (socket.refused !== void 0) {
|
|
5741
5820
|
return fail(socket.refused);
|
|
5742
5821
|
}
|
|
5743
5822
|
const { socketPath } = socket;
|
|
5744
|
-
pruneStaleHeadroomSockets(
|
|
5745
|
-
pruneStaleAllowlistTemporaries(
|
|
5823
|
+
pruneStaleHeadroomSockets(fs15, paths, ports.isRunning);
|
|
5824
|
+
pruneStaleAllowlistTemporaries(fs15, paths.headroomAllowlistFile, ports.isRunning);
|
|
5746
5825
|
const installFailure = ensureInstalled();
|
|
5747
5826
|
if (installFailure !== void 0) {
|
|
5748
5827
|
return fail(installFailure);
|
|
5749
5828
|
}
|
|
5750
5829
|
const version = ports.headroomVersion() ?? "unknown";
|
|
5751
5830
|
writeOwnState({ supervisorPid: ports.ownPid, version, installedSource });
|
|
5752
|
-
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(
|
|
5831
|
+
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(fs15, paths, ports.frontDoorLiveness).frontDoorOrigins.join(", ")}]`);
|
|
5753
5832
|
const orphanPid = previousState?.headroomPid;
|
|
5754
5833
|
const orphanSocket = previousState?.socketPath ?? (previousState?.supervisorPid === void 0 ? void 0 : headroomSocketPath(paths, previousState.supervisorPid));
|
|
5755
5834
|
const orphanIdentity = orphanPid === void 0 || orphanSocket === void 0 || !ports.isRunning(orphanPid) ? void 0 : daemonIdentity(ports.daemonCommandLine(orphanPid), orphanSocket);
|
|
@@ -5787,12 +5866,12 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5787
5866
|
}
|
|
5788
5867
|
config = ports.readConfig();
|
|
5789
5868
|
const settingsHash = hashSettings(config.settings);
|
|
5790
|
-
const inputs = currentHeadroomAllowlistInputs(
|
|
5791
|
-
pruneDeadFrontDoorDirectRecords(
|
|
5792
|
-
pruneMalformedFrontDoorDirectFiles(
|
|
5869
|
+
const inputs = currentHeadroomAllowlistInputs(fs15, paths, ports.frontDoorLiveness);
|
|
5870
|
+
pruneDeadFrontDoorDirectRecords(fs15, paths.frontdoorDirectRecordsDir, inputs.frontDoorRecords, inputs.frontDoorLiveness);
|
|
5871
|
+
pruneMalformedFrontDoorDirectFiles(fs15, paths.frontdoorDirectRecordsDir, ports.isRunning);
|
|
5793
5872
|
const allowlist = inputs.frontDoorOrigins;
|
|
5794
5873
|
const allowlistHash = hashAllowlist(allowlist);
|
|
5795
|
-
pruneDeadSessions(
|
|
5874
|
+
pruneDeadSessions(fs15, paths.headroomSessionsDir, ports.isRunning);
|
|
5796
5875
|
const ownsNow = ownsState();
|
|
5797
5876
|
if (!ownsNow && !superseded) {
|
|
5798
5877
|
ports.log("agent-shim headroom supervisor: another supervisor now owns the state file; serving this daemon's own sessions until they end");
|
|
@@ -5839,7 +5918,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5839
5918
|
runningSettingsHash = settingsHash;
|
|
5840
5919
|
const recorded = writeOwnState(servingState(pid));
|
|
5841
5920
|
if (recorded) {
|
|
5842
|
-
|
|
5921
|
+
fs15.removeRecursive(paths.headroomLockFile);
|
|
5843
5922
|
}
|
|
5844
5923
|
idleSince = void 0;
|
|
5845
5924
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on unix socket ${socketPath}`);
|
|
@@ -5867,7 +5946,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5867
5946
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} now serves allowlist [${allowlist.join(", ")}]`);
|
|
5868
5947
|
}
|
|
5869
5948
|
if (runningSettingsHash !== settingsHash || installedSource !== config.source) {
|
|
5870
|
-
if (sessionsForSupervisor(
|
|
5949
|
+
if (sessionsForSupervisor(fs15, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
5871
5950
|
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
5872
5951
|
ports.stopProcess(headroomPid);
|
|
5873
5952
|
headroomPid = void 0;
|
|
@@ -5876,7 +5955,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5876
5955
|
continue;
|
|
5877
5956
|
}
|
|
5878
5957
|
}
|
|
5879
|
-
const sessions = sessionsForSupervisor(
|
|
5958
|
+
const sessions = sessionsForSupervisor(fs15, paths.headroomSessionsDir, ports.ownPid);
|
|
5880
5959
|
if (sessions.length === 0) {
|
|
5881
5960
|
idleSince ??= ports.now();
|
|
5882
5961
|
const idleMs = ports.now() - idleSince;
|
|
@@ -5901,9 +5980,9 @@ function undeterminedFrontDoors(inputs) {
|
|
|
5901
5980
|
return reason === void 0 ? [] : [{ pid: record.pid, origin: directOrigin(record.directPort), reason }];
|
|
5902
5981
|
});
|
|
5903
5982
|
}
|
|
5904
|
-
function currentHeadroomAllowlistInputs(
|
|
5905
|
-
const named = frontDoorOrigin(readFrontDoorState(
|
|
5906
|
-
const records = listFrontDoorDirectRecords(
|
|
5983
|
+
function currentHeadroomAllowlistInputs(fs15, paths, frontDoorLiveness) {
|
|
5984
|
+
const named = frontDoorOrigin(readFrontDoorState(fs15, paths.frontdoorStateFile));
|
|
5985
|
+
const records = listFrontDoorDirectRecords(fs15, paths.frontdoorDirectRecordsDir);
|
|
5907
5986
|
const liveness = frontDoorLiveness(records.map((record) => record.pid));
|
|
5908
5987
|
const live = liveFrontDoorDirectRecords(records, liveness).map((record) => directOrigin(record.directPort));
|
|
5909
5988
|
return {
|
|
@@ -5912,8 +5991,8 @@ function currentHeadroomAllowlistInputs(fs14, paths, frontDoorLiveness) {
|
|
|
5912
5991
|
frontDoorOrigins: [.../* @__PURE__ */ new Set([...named === void 0 ? [] : [named], ...live])].sort()
|
|
5913
5992
|
};
|
|
5914
5993
|
}
|
|
5915
|
-
function launchRequiredUpstreams(
|
|
5916
|
-
const door = frontDoorOrigin(readFrontDoorState(
|
|
5994
|
+
function launchRequiredUpstreams(fs15, paths) {
|
|
5995
|
+
const door = frontDoorOrigin(readFrontDoorState(fs15, paths.frontdoorStateFile));
|
|
5917
5996
|
return door === void 0 ? [] : [door];
|
|
5918
5997
|
}
|
|
5919
5998
|
async function waitUntilReady(ports, socketPath, pid) {
|
|
@@ -6045,6 +6124,29 @@ function isEnoent3(error) {
|
|
|
6045
6124
|
function isErrorWithCode(error, code) {
|
|
6046
6125
|
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
6047
6126
|
}
|
|
6127
|
+
function writeFileFlushed(file, contents) {
|
|
6128
|
+
const descriptor = import_node_fs2.default.openSync(file, "w", OWNER_ONLY_FILE_MODE);
|
|
6129
|
+
try {
|
|
6130
|
+
import_node_fs2.default.writeFileSync(descriptor, contents, "utf8");
|
|
6131
|
+
import_node_fs2.default.fchmodSync(descriptor, OWNER_ONLY_FILE_MODE);
|
|
6132
|
+
import_node_fs2.default.fsyncSync(descriptor);
|
|
6133
|
+
} finally {
|
|
6134
|
+
import_node_fs2.default.closeSync(descriptor);
|
|
6135
|
+
}
|
|
6136
|
+
}
|
|
6137
|
+
function flushDirectory(directory) {
|
|
6138
|
+
const descriptor = import_node_fs2.default.openSync(directory, "r");
|
|
6139
|
+
try {
|
|
6140
|
+
import_node_fs2.default.fsyncSync(descriptor);
|
|
6141
|
+
} catch (error) {
|
|
6142
|
+
const code = typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
6143
|
+
if (code === void 0 || !DIRECTORY_FLUSH_UNSUPPORTED_CODES.has(code)) {
|
|
6144
|
+
throw error;
|
|
6145
|
+
}
|
|
6146
|
+
} finally {
|
|
6147
|
+
import_node_fs2.default.closeSync(descriptor);
|
|
6148
|
+
}
|
|
6149
|
+
}
|
|
6048
6150
|
function realSleepSync(ms) {
|
|
6049
6151
|
refuseToBlockInRole("a synchronous sleep");
|
|
6050
6152
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(INT32_BYTE_LENGTH)), 0, 0, ms);
|
|
@@ -6078,9 +6180,9 @@ function realFrontDoorLiveness(pids) {
|
|
|
6078
6180
|
return { status: result.status, stdout: result.stdout, stderr: result.stderr, ...result.error === void 0 ? {} : { error: result.error } };
|
|
6079
6181
|
});
|
|
6080
6182
|
}
|
|
6081
|
-
|
|
6082
|
-
return await new Promise((resolve) => {
|
|
6083
|
-
(0, import_node_child_process3.execFile)(command, [...args], { encoding: "utf8", timeout:
|
|
6183
|
+
function realRunAsyncWithin(timeoutMs) {
|
|
6184
|
+
return async (command, args) => await new Promise((resolve) => {
|
|
6185
|
+
(0, import_node_child_process3.execFile)(command, [...args], { encoding: "utf8", timeout: timeoutMs }, (error, stdout, stderr) => {
|
|
6084
6186
|
resolve({ status: error === null ? 0 : typeof error.code === "number" ? error.code : null, stdout, stderr });
|
|
6085
6187
|
});
|
|
6086
6188
|
});
|
|
@@ -6286,7 +6388,7 @@ function realResolveClaudeBinary(isOwnBinary) {
|
|
|
6286
6388
|
function realInstalledClaudeVersions() {
|
|
6287
6389
|
return installedVersions(listVersionsDir(defaultVersionsDir()));
|
|
6288
6390
|
}
|
|
6289
|
-
var import_node_child_process3, import_node_crypto8, import_node_fs2, import_node_os2, import_node_path15, import_node_sea, 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;
|
|
6391
|
+
var import_node_child_process3, import_node_crypto8, import_node_fs2, import_node_os2, import_node_path15, import_node_sea, realFsPort, OWNER_ONLY_DIR_MODE, OWNER_ONLY_FILE_MODE, PERMISSION_BITS, DIRECTORY_FLUSH_UNSUPPORTED_CODES, realFarmFs, INT32_BYTE_LENGTH, KEY_POLL_MS, CTRL_C_BYTE, realHoldPort, PS_TIMEOUT_MS, RUN_OUTPUT_LIMIT_MIB, BYTES_PER_MIB2, RUN_OUTPUT_LIMIT_BYTES, realRunPort, ASYNC_RUN_TIMEOUT_MS, realRunAsync, MACOS_GUI_SESSION_MANAGER, realCredentialPort, SOCKET_PERMISSION_BITS, realHeadroomSocketTrust, realSpawnPort, realProcPort, realLogPort, EXECUTE_BITS_MASK, WINDOWS_DEFAULT_PATHEXT;
|
|
6290
6392
|
var init_realPorts = __esm({
|
|
6291
6393
|
"src/realPorts.ts"() {
|
|
6292
6394
|
"use strict";
|
|
@@ -6331,6 +6433,7 @@ var init_realPorts = __esm({
|
|
|
6331
6433
|
OWNER_ONLY_DIR_MODE = 448;
|
|
6332
6434
|
OWNER_ONLY_FILE_MODE = 384;
|
|
6333
6435
|
PERMISSION_BITS = 511;
|
|
6436
|
+
DIRECTORY_FLUSH_UNSUPPORTED_CODES = /* @__PURE__ */ new Set(["EINVAL", "ENOTSUP", "EOPNOTSUPP"]);
|
|
6334
6437
|
realFarmFs = {
|
|
6335
6438
|
lstat(filePath) {
|
|
6336
6439
|
let stat;
|
|
@@ -6387,12 +6490,18 @@ var init_realPorts = __esm({
|
|
|
6387
6490
|
import_node_fs2.default.mkdirSync(dirPath, { recursive: true, mode: OWNER_ONLY_DIR_MODE });
|
|
6388
6491
|
import_node_fs2.default.chmodSync(dirPath, OWNER_ONLY_DIR_MODE);
|
|
6389
6492
|
},
|
|
6390
|
-
writeFilePrivate(filePath, contents) {
|
|
6493
|
+
writeFilePrivate(filePath, contents, options) {
|
|
6391
6494
|
const temp = `${filePath}.${String(process.pid)}.tmp`;
|
|
6392
6495
|
try {
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6496
|
+
if (options?.durable === true) {
|
|
6497
|
+
writeFileFlushed(temp, contents);
|
|
6498
|
+
import_node_fs2.default.renameSync(temp, filePath);
|
|
6499
|
+
flushDirectory(import_node_path15.default.dirname(filePath));
|
|
6500
|
+
} else {
|
|
6501
|
+
import_node_fs2.default.writeFileSync(temp, contents, { encoding: "utf8", mode: OWNER_ONLY_FILE_MODE });
|
|
6502
|
+
import_node_fs2.default.chmodSync(temp, OWNER_ONLY_FILE_MODE);
|
|
6503
|
+
import_node_fs2.default.renameSync(temp, filePath);
|
|
6504
|
+
}
|
|
6396
6505
|
} catch (error) {
|
|
6397
6506
|
import_node_fs2.default.rmSync(temp, { force: true });
|
|
6398
6507
|
throw error;
|
|
@@ -6462,12 +6571,17 @@ var init_realPorts = __esm({
|
|
|
6462
6571
|
}
|
|
6463
6572
|
};
|
|
6464
6573
|
PS_TIMEOUT_MS = 2e3;
|
|
6574
|
+
RUN_OUTPUT_LIMIT_MIB = 256;
|
|
6575
|
+
BYTES_PER_MIB2 = 1048576;
|
|
6576
|
+
RUN_OUTPUT_LIMIT_BYTES = RUN_OUTPUT_LIMIT_MIB * BYTES_PER_MIB2;
|
|
6465
6577
|
realRunPort = {
|
|
6466
|
-
run(command, args) {
|
|
6467
|
-
const result = spawnSyncBlocking("an external command", command, args, { encoding: "utf8" });
|
|
6578
|
+
run(command, args, input) {
|
|
6579
|
+
const result = spawnSyncBlocking("an external command", command, args, { encoding: "utf8", maxBuffer: RUN_OUTPUT_LIMIT_BYTES, ...input === void 0 ? {} : { input } });
|
|
6468
6580
|
return { status: result.status, stdout: result.stdout, stderr: result.stderr };
|
|
6469
6581
|
}
|
|
6470
6582
|
};
|
|
6583
|
+
ASYNC_RUN_TIMEOUT_MS = 2e3;
|
|
6584
|
+
realRunAsync = realRunAsyncWithin(ASYNC_RUN_TIMEOUT_MS);
|
|
6471
6585
|
MACOS_GUI_SESSION_MANAGER = "Aqua";
|
|
6472
6586
|
realCredentialPort = {
|
|
6473
6587
|
readSecretFile(filePath) {
|
|
@@ -6659,8 +6773,8 @@ var init_cascade = __esm({
|
|
|
6659
6773
|
function poolNameOf(selector) {
|
|
6660
6774
|
return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
|
|
6661
6775
|
}
|
|
6662
|
-
function readActiveIdentity(
|
|
6663
|
-
const trimmed =
|
|
6776
|
+
function readActiveIdentity(fs15, activeIdentityFile) {
|
|
6777
|
+
const trimmed = fs15.readFileUtf8(activeIdentityFile)?.trim();
|
|
6664
6778
|
return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
|
|
6665
6779
|
}
|
|
6666
6780
|
function isNonEmpty(value) {
|
|
@@ -6710,11 +6824,11 @@ function decideConfigProfile(params) {
|
|
|
6710
6824
|
}
|
|
6711
6825
|
return { source: "none" };
|
|
6712
6826
|
}
|
|
6713
|
-
function loadIdentity(identitiesDir, name,
|
|
6827
|
+
function loadIdentity(identitiesDir, name, fs15) {
|
|
6714
6828
|
if (!isFileName(name)) {
|
|
6715
6829
|
throw new UnsafeNameError(name, "identity", FILE_NAME_RULE);
|
|
6716
6830
|
}
|
|
6717
|
-
return loadConfigFile(import_node_path18.default.join(identitiesDir, name, "identity.json"), IdentitySchema,
|
|
6831
|
+
return loadConfigFile(import_node_path18.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs15.readConfigFile);
|
|
6718
6832
|
}
|
|
6719
6833
|
var import_node_path18, IDENTITY_DECISION_SOURCES, IDENTITY_SOURCE_LABELS, CONFIG_PROFILE_DECISION_SOURCES;
|
|
6720
6834
|
var init_identity = __esm({
|
|
@@ -6968,14 +7082,14 @@ function isIdentityName(name) {
|
|
|
6968
7082
|
function claudeJsonPath(identitiesDir, identity) {
|
|
6969
7083
|
return import_node_path19.default.join(identitiesDir, identity, CLAUDE_JSON);
|
|
6970
7084
|
}
|
|
6971
|
-
function readAccountMetadata(
|
|
7085
|
+
function readAccountMetadata(fs15, identitiesDir, identity) {
|
|
6972
7086
|
if (!isIdentityName(identity)) {
|
|
6973
7087
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
6974
7088
|
}
|
|
6975
|
-
return readAccountMetadataFile(
|
|
7089
|
+
return readAccountMetadataFile(fs15, claudeJsonPath(identitiesDir, identity));
|
|
6976
7090
|
}
|
|
6977
|
-
function readAccountMetadataFile(
|
|
6978
|
-
const raw =
|
|
7091
|
+
function readAccountMetadataFile(fs15, file) {
|
|
7092
|
+
const raw = fs15.readFileUtf8(file);
|
|
6979
7093
|
if (raw === void 0) {
|
|
6980
7094
|
return void 0;
|
|
6981
7095
|
}
|
|
@@ -7005,19 +7119,19 @@ function readAccountMetadataFile(fs14, file) {
|
|
|
7005
7119
|
}
|
|
7006
7120
|
return account.data;
|
|
7007
7121
|
}
|
|
7008
|
-
function createAccountReader(
|
|
7122
|
+
function createAccountReader(fs15, identitiesDir) {
|
|
7009
7123
|
const cache = /* @__PURE__ */ new Map();
|
|
7010
7124
|
return (identity) => {
|
|
7011
7125
|
if (!isIdentityName(identity)) {
|
|
7012
7126
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
7013
7127
|
}
|
|
7014
|
-
const stat =
|
|
7128
|
+
const stat = fs15.lstat(claudeJsonPath(identitiesDir, identity));
|
|
7015
7129
|
const stamp = stat === void 0 ? "absent" : `${String(stat.mtimeMs)}:${String(stat.sizeBytes)}`;
|
|
7016
7130
|
const cached = cache.get(identity);
|
|
7017
7131
|
if (cached?.stamp === stamp) {
|
|
7018
7132
|
return cached.account;
|
|
7019
7133
|
}
|
|
7020
|
-
const account = readAccountMetadata(
|
|
7134
|
+
const account = readAccountMetadata(fs15, identitiesDir, identity);
|
|
7021
7135
|
cache.set(identity, { stamp, account });
|
|
7022
7136
|
return account;
|
|
7023
7137
|
};
|
|
@@ -7054,9 +7168,9 @@ var init_accountDescription = __esm({
|
|
|
7054
7168
|
});
|
|
7055
7169
|
|
|
7056
7170
|
// src/identityAccounts.ts
|
|
7057
|
-
function readIdentityAccount(
|
|
7171
|
+
function readIdentityAccount(fs15, identitiesDir, identity) {
|
|
7058
7172
|
try {
|
|
7059
|
-
const account = readAccountMetadata(
|
|
7173
|
+
const account = readAccountMetadata(fs15, identitiesDir, identity);
|
|
7060
7174
|
return account === void 0 ? void 0 : { account };
|
|
7061
7175
|
} catch (error) {
|
|
7062
7176
|
if (error instanceof AccountMetadataError) {
|
|
@@ -7428,10 +7542,10 @@ function billedTokensOf(record) {
|
|
|
7428
7542
|
const usage = record.usage;
|
|
7429
7543
|
return (usage?.inputTokens ?? 0) + (usage?.cacheCreationInputTokens ?? 0) + (usage?.outputTokens ?? 0);
|
|
7430
7544
|
}
|
|
7431
|
-
function utilisationPerBilledToken(records) {
|
|
7545
|
+
function utilisationPerBilledToken(records, which) {
|
|
7432
7546
|
const points = [];
|
|
7433
7547
|
for (const record of records) {
|
|
7434
|
-
const window = record.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record.rateLimitHeaders)?.
|
|
7548
|
+
const window = record.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record.rateLimitHeaders)?.[which];
|
|
7435
7549
|
if (window?.utilization !== void 0 && window.resetsAt !== void 0) {
|
|
7436
7550
|
points.push({ resetsAt: window.resetsAt, utilization: window.utilization, billed: billedTokensOf(record) });
|
|
7437
7551
|
}
|
|
@@ -7616,14 +7730,17 @@ function rankPool(input) {
|
|
|
7616
7730
|
}
|
|
7617
7731
|
const { sticky: sticky2 } = input;
|
|
7618
7732
|
const warmHere = sticky2?.identity === candidate.identity && nowMs - Date.parse(sticky2.at) <= PROMPT_CACHE_TTL_MS;
|
|
7619
|
-
|
|
7620
|
-
|
|
7733
|
+
const resumeTokens = input.resumeContextTokens;
|
|
7734
|
+
if (input.resuming && resumeTokens !== void 0 && !warmHere) {
|
|
7621
7735
|
const committed = input.committedContextTokens?.[candidate.identity] ?? 0;
|
|
7622
|
-
const
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
const
|
|
7626
|
-
|
|
7736
|
+
const alongside = committed === 0 ? "" : ` (with ${String(committed)} tokens of other conversations already moving here)`;
|
|
7737
|
+
for (const [name, label, window] of [["fiveHour", "5h", fiveHour], ["sevenDay", "7d", sevenDay]]) {
|
|
7738
|
+
const perToken = window === void 0 ? void 0 : utilisationPerBilledToken(assessment.member.records, name);
|
|
7739
|
+
const cost = perToken === void 0 ? void 0 : (resumeTokens + committed) * perToken;
|
|
7740
|
+
if (window !== void 0 && cost !== void 0 && cost > window.remaining) {
|
|
7741
|
+
dryAfterMs.push(0);
|
|
7742
|
+
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`);
|
|
7743
|
+
}
|
|
7627
7744
|
}
|
|
7628
7745
|
}
|
|
7629
7746
|
if (drySpots.length === 0) {
|
|
@@ -7691,8 +7808,8 @@ function segmentDay(epochMs) {
|
|
|
7691
7808
|
function segmentName(day, pid) {
|
|
7692
7809
|
return `${day}.${String(pid)}.jsonl`;
|
|
7693
7810
|
}
|
|
7694
|
-
function listLogSegments(
|
|
7695
|
-
return
|
|
7811
|
+
function listLogSegments(fs15, logDir) {
|
|
7812
|
+
return fs15.readdir(logDir).flatMap((name) => {
|
|
7696
7813
|
const match = SEGMENT_RE.exec(name);
|
|
7697
7814
|
const day = match?.[1];
|
|
7698
7815
|
if (day === void 0) {
|
|
@@ -7701,15 +7818,15 @@ function listLogSegments(fs14, logDir) {
|
|
|
7701
7818
|
return [{ name, day, endsAt: Date.parse(`${day}T00:00:00.000Z`) + DAY_MS }];
|
|
7702
7819
|
}).sort((left, right) => left.day.localeCompare(right.day) || left.name.localeCompare(right.name));
|
|
7703
7820
|
}
|
|
7704
|
-
function readUsageLog(
|
|
7821
|
+
function readUsageLog(fs15, logDir, options = {}) {
|
|
7705
7822
|
const { sinceMs } = options;
|
|
7706
7823
|
const records = [];
|
|
7707
7824
|
let invalidLines = 0;
|
|
7708
|
-
for (const segment of listLogSegments(
|
|
7825
|
+
for (const segment of listLogSegments(fs15, logDir)) {
|
|
7709
7826
|
if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
|
|
7710
7827
|
continue;
|
|
7711
7828
|
}
|
|
7712
|
-
const read = readSegment(
|
|
7829
|
+
const read = readSegment(fs15, logDir, segment);
|
|
7713
7830
|
if (read === void 0) {
|
|
7714
7831
|
continue;
|
|
7715
7832
|
}
|
|
@@ -7723,8 +7840,8 @@ function readUsageLog(fs14, logDir, options = {}) {
|
|
|
7723
7840
|
records.sort((left, right) => left.at.localeCompare(right.at));
|
|
7724
7841
|
return { records, invalidLines };
|
|
7725
7842
|
}
|
|
7726
|
-
function readSegment(
|
|
7727
|
-
const contents =
|
|
7843
|
+
function readSegment(fs15, logDir, segment) {
|
|
7844
|
+
const contents = fs15.readFileUtf8(import_node_path20.default.join(logDir, segment.name));
|
|
7728
7845
|
if (contents === void 0) {
|
|
7729
7846
|
return void 0;
|
|
7730
7847
|
}
|
|
@@ -7758,9 +7875,9 @@ function snapshotPath(snapshotsDir, identity) {
|
|
|
7758
7875
|
}
|
|
7759
7876
|
return import_node_path20.default.join(snapshotsDir, `${identity}.json`);
|
|
7760
7877
|
}
|
|
7761
|
-
function readUsageSnapshot(
|
|
7878
|
+
function readUsageSnapshot(fs15, snapshotsDir, identity) {
|
|
7762
7879
|
const file = snapshotPath(snapshotsDir, identity);
|
|
7763
|
-
const raw =
|
|
7880
|
+
const raw = fs15.readFileUtf8(file);
|
|
7764
7881
|
if (raw === void 0) {
|
|
7765
7882
|
return void 0;
|
|
7766
7883
|
}
|
|
@@ -7776,8 +7893,8 @@ function readUsageSnapshot(fs14, snapshotsDir, identity) {
|
|
|
7776
7893
|
}
|
|
7777
7894
|
return snapshot.data;
|
|
7778
7895
|
}
|
|
7779
|
-
function listUsageSnapshots(
|
|
7780
|
-
return
|
|
7896
|
+
function listUsageSnapshots(fs15, snapshotsDir) {
|
|
7897
|
+
return fs15.readdir(snapshotsDir).flatMap((name) => {
|
|
7781
7898
|
if (!name.endsWith(".json")) {
|
|
7782
7899
|
return [];
|
|
7783
7900
|
}
|
|
@@ -7785,7 +7902,7 @@ function listUsageSnapshots(fs14, snapshotsDir) {
|
|
|
7785
7902
|
if (!isIdentityName(identity)) {
|
|
7786
7903
|
return [];
|
|
7787
7904
|
}
|
|
7788
|
-
const snapshot = readUsageSnapshot(
|
|
7905
|
+
const snapshot = readUsageSnapshot(fs15, snapshotsDir, identity);
|
|
7789
7906
|
return snapshot === void 0 ? [] : [snapshot];
|
|
7790
7907
|
}).sort((left, right) => left.identity.localeCompare(right.identity));
|
|
7791
7908
|
}
|
|
@@ -7810,11 +7927,11 @@ var init_read = __esm({
|
|
|
7810
7927
|
});
|
|
7811
7928
|
|
|
7812
7929
|
// src/usage/store.ts
|
|
7813
|
-
function pruneUsageLog(
|
|
7930
|
+
function pruneUsageLog(fs15, logDir, nowMs) {
|
|
7814
7931
|
const cutoff = nowMs - USAGE_RETENTION_MS;
|
|
7815
|
-
for (const segment of listLogSegments(
|
|
7932
|
+
for (const segment of listLogSegments(fs15, logDir)) {
|
|
7816
7933
|
if (segment.endsAt <= cutoff) {
|
|
7817
|
-
|
|
7934
|
+
fs15.removeRecursive(import_node_path21.default.join(logDir, segment.name));
|
|
7818
7935
|
}
|
|
7819
7936
|
}
|
|
7820
7937
|
}
|
|
@@ -7843,7 +7960,7 @@ function foldProviderState(current, record) {
|
|
|
7843
7960
|
};
|
|
7844
7961
|
}
|
|
7845
7962
|
function createUsageStore(deps) {
|
|
7846
|
-
const { fs:
|
|
7963
|
+
const { fs: fs15, paths } = deps;
|
|
7847
7964
|
let prunedDay;
|
|
7848
7965
|
const rewriteSnapshot = (identity, fold) => {
|
|
7849
7966
|
if (!isIdentityName(identity)) {
|
|
@@ -7852,7 +7969,7 @@ function createUsageStore(deps) {
|
|
|
7852
7969
|
}
|
|
7853
7970
|
let current;
|
|
7854
7971
|
try {
|
|
7855
|
-
current = readUsageSnapshot(
|
|
7972
|
+
current = readUsageSnapshot(fs15, paths.usageSnapshotsDir, identity);
|
|
7856
7973
|
} catch (error) {
|
|
7857
7974
|
if (!(error instanceof UsageSnapshotError)) {
|
|
7858
7975
|
throw error;
|
|
@@ -7879,8 +7996,8 @@ function createUsageStore(deps) {
|
|
|
7879
7996
|
...account === void 0 ? {} : { account },
|
|
7880
7997
|
providers
|
|
7881
7998
|
});
|
|
7882
|
-
|
|
7883
|
-
|
|
7999
|
+
fs15.mkdirPrivate(paths.usageSnapshotsDir);
|
|
8000
|
+
fs15.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
|
|
7884
8001
|
`);
|
|
7885
8002
|
deps.publish?.(snapshot);
|
|
7886
8003
|
return true;
|
|
@@ -7889,14 +8006,14 @@ function createUsageStore(deps) {
|
|
|
7889
8006
|
record: (input) => {
|
|
7890
8007
|
const record = UsageRecordSchema.parse(input);
|
|
7891
8008
|
const nowMs = deps.now();
|
|
7892
|
-
|
|
7893
|
-
|
|
8009
|
+
fs15.mkdirPrivate(paths.usageDir);
|
|
8010
|
+
fs15.mkdirPrivate(paths.usageLogDir);
|
|
7894
8011
|
const day = segmentDay(nowMs);
|
|
7895
8012
|
if (prunedDay !== day) {
|
|
7896
|
-
pruneUsageLog(
|
|
8013
|
+
pruneUsageLog(fs15, paths.usageLogDir, nowMs);
|
|
7897
8014
|
prunedDay = day;
|
|
7898
8015
|
}
|
|
7899
|
-
|
|
8016
|
+
fs15.appendFilePrivate(import_node_path21.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
|
|
7900
8017
|
`);
|
|
7901
8018
|
deps.onRecord?.(record);
|
|
7902
8019
|
if (record.identity !== void 0) {
|
|
@@ -7939,14 +8056,14 @@ var init_store2 = __esm({
|
|
|
7939
8056
|
function errorMessage(error) {
|
|
7940
8057
|
return error instanceof Error ? error.message : String(error);
|
|
7941
8058
|
}
|
|
7942
|
-
function loadPoolMembers(
|
|
8059
|
+
function loadPoolMembers(fs15, paths, identities, nowMs) {
|
|
7943
8060
|
const windowStartMs = nowMs - FIVE_HOUR_WINDOW_MS;
|
|
7944
|
-
const log = readUsageLog(
|
|
8061
|
+
const log = readUsageLog(fs15, paths.usageLogDir, { sinceMs: windowStartMs });
|
|
7945
8062
|
return identities.map((identity) => {
|
|
7946
8063
|
const records = log.records.filter((record) => record.identity === identity && record.provider === ANTHROPIC_PROVIDER && Date.parse(record.at) >= windowStartMs);
|
|
7947
8064
|
try {
|
|
7948
|
-
const snapshot = readUsageSnapshot(
|
|
7949
|
-
const account = readAccountMetadata(
|
|
8065
|
+
const snapshot = readUsageSnapshot(fs15, paths.usageSnapshotsDir, identity);
|
|
8066
|
+
const account = readAccountMetadata(fs15, paths.identitiesDir, identity) ?? snapshot?.account;
|
|
7950
8067
|
return { identity, records, ...snapshot === void 0 ? {} : { snapshot }, ...account === void 0 ? {} : { account } };
|
|
7951
8068
|
} catch (error) {
|
|
7952
8069
|
if (error instanceof UsageSnapshotError || error instanceof AccountMetadataError) {
|
|
@@ -8065,9 +8182,9 @@ function collectPoolIdentities(pools, poolName, stack, found) {
|
|
|
8065
8182
|
collectPoolIdentities(pools, nestedName, childStack, found);
|
|
8066
8183
|
}
|
|
8067
8184
|
}
|
|
8068
|
-
function readPicksFile(
|
|
8185
|
+
function readPicksFile(fs15, file) {
|
|
8069
8186
|
const empty = { schemaVersion: SCHEMA_VERSION, picks: {} };
|
|
8070
|
-
const raw =
|
|
8187
|
+
const raw = fs15.readFileUtf8(file);
|
|
8071
8188
|
if (raw === void 0) {
|
|
8072
8189
|
return { file: empty };
|
|
8073
8190
|
}
|
|
@@ -8080,17 +8197,17 @@ function readPicksFile(fs14, file) {
|
|
|
8080
8197
|
const result = PicksFileSchema.safeParse(parsed);
|
|
8081
8198
|
return result.success ? { file: result.data } : { file: empty, problem: `${file} is not a picks file this agent-shim can read` };
|
|
8082
8199
|
}
|
|
8083
|
-
function readStickyPick(
|
|
8084
|
-
const read = readPicksFile(
|
|
8200
|
+
function readStickyPick(fs15, picksFile, directory) {
|
|
8201
|
+
const read = readPicksFile(fs15, picksFile);
|
|
8085
8202
|
const entry = read.file.picks[directory];
|
|
8086
8203
|
return { ...entry === void 0 ? {} : { sticky: entry }, ...read.problem === void 0 ? {} : { problem: read.problem } };
|
|
8087
8204
|
}
|
|
8088
|
-
function recordStickyPick(
|
|
8089
|
-
const current = readPicksFile(
|
|
8205
|
+
function recordStickyPick(fs15, picksFile, directory, identity, nowMs) {
|
|
8206
|
+
const current = readPicksFile(fs15, picksFile).file.picks;
|
|
8090
8207
|
const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
|
|
8091
8208
|
const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
|
|
8092
|
-
|
|
8093
|
-
|
|
8209
|
+
fs15.mkdirPrivate(import_node_path22.default.dirname(picksFile));
|
|
8210
|
+
fs15.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
|
|
8094
8211
|
`);
|
|
8095
8212
|
}
|
|
8096
8213
|
var import_node_path22, import_zod15, PoolGraphError, SCHEMA_VERSION, PickEntrySchema, PicksFileSchema;
|
|
@@ -8124,9 +8241,9 @@ var init_poolPick = __esm({
|
|
|
8124
8241
|
});
|
|
8125
8242
|
|
|
8126
8243
|
// src/statusline/keys.ts
|
|
8127
|
-
function valueAt(source,
|
|
8244
|
+
function valueAt(source, path45) {
|
|
8128
8245
|
let current = source;
|
|
8129
|
-
for (const part of
|
|
8246
|
+
for (const part of path45) {
|
|
8130
8247
|
if (!isPlainObject(current)) {
|
|
8131
8248
|
return void 0;
|
|
8132
8249
|
}
|
|
@@ -8134,14 +8251,14 @@ function valueAt(source, path42) {
|
|
|
8134
8251
|
}
|
|
8135
8252
|
return current;
|
|
8136
8253
|
}
|
|
8137
|
-
function acceptsNull(
|
|
8138
|
-
const layer =
|
|
8254
|
+
function acceptsNull(path45) {
|
|
8255
|
+
const layer = path45.reduceRight((inner, part) => ({ [part]: inner }), null);
|
|
8139
8256
|
return StatuslineSchema.safeParse(layer).success;
|
|
8140
8257
|
}
|
|
8141
|
-
function keyOf(
|
|
8258
|
+
function keyOf(path45, declared) {
|
|
8142
8259
|
const optional = declared instanceof import_zod16.z.ZodOptional;
|
|
8143
8260
|
const leaf = optional ? declared.unwrap() : declared;
|
|
8144
|
-
const common = { path:
|
|
8261
|
+
const common = { path: path45.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path45), optional, unsettable: acceptsNull(path45) };
|
|
8145
8262
|
if (leaf instanceof import_zod16.z.ZodNumber) {
|
|
8146
8263
|
return { ...common, kind: "integer", choices: [] };
|
|
8147
8264
|
}
|
|
@@ -8166,7 +8283,7 @@ function keyOf(path42, declared) {
|
|
|
8166
8283
|
if (leaf instanceof import_zod16.z.ZodArray && leaf.element instanceof import_zod16.z.ZodString) {
|
|
8167
8284
|
return { ...common, kind: "textList", choices: [] };
|
|
8168
8285
|
}
|
|
8169
|
-
throw new TypeError(`statusline setting ${
|
|
8286
|
+
throw new TypeError(`statusline setting ${path45.join(".")} has a kind the key listing does not describe`);
|
|
8170
8287
|
}
|
|
8171
8288
|
function walk(shape, prefix) {
|
|
8172
8289
|
return Object.entries(shape).flatMap(([name, schema]) => schema instanceof import_zod16.z.ZodObject ? walk(schema.shape, [...prefix, name]) : [keyOf([...prefix, name], schema)]);
|
|
@@ -8184,15 +8301,15 @@ var init_keys = __esm({
|
|
|
8184
8301
|
});
|
|
8185
8302
|
|
|
8186
8303
|
// src/statusline/change.ts
|
|
8187
|
-
function keyNamed(
|
|
8188
|
-
const found = statuslineKeys().find((key) => key.path ===
|
|
8304
|
+
function keyNamed(path45) {
|
|
8305
|
+
const found = statuslineKeys().find((key) => key.path === path45);
|
|
8189
8306
|
if (found === void 0) {
|
|
8190
|
-
throw new UsageError(`"${
|
|
8307
|
+
throw new UsageError(`"${path45}" is not a statusline setting; \`agent-shim statusline keys\` lists them.`);
|
|
8191
8308
|
}
|
|
8192
8309
|
return found;
|
|
8193
8310
|
}
|
|
8194
|
-
function setAt(target,
|
|
8195
|
-
const [head, ...rest] =
|
|
8311
|
+
function setAt(target, path45, value) {
|
|
8312
|
+
const [head, ...rest] = path45;
|
|
8196
8313
|
if (head === void 0) {
|
|
8197
8314
|
return;
|
|
8198
8315
|
}
|
|
@@ -8205,8 +8322,8 @@ function setAt(target, path42, value) {
|
|
|
8205
8322
|
target[head] = next;
|
|
8206
8323
|
setAt(next, rest, value);
|
|
8207
8324
|
}
|
|
8208
|
-
function removeAt(target,
|
|
8209
|
-
const [head, ...rest] =
|
|
8325
|
+
function removeAt(target, path45) {
|
|
8326
|
+
const [head, ...rest] = path45;
|
|
8210
8327
|
if (head === void 0) {
|
|
8211
8328
|
return;
|
|
8212
8329
|
}
|
|
@@ -8224,13 +8341,13 @@ function removeAt(target, path42) {
|
|
|
8224
8341
|
}
|
|
8225
8342
|
function applyStatuslineChange(existing, change) {
|
|
8226
8343
|
const draft = structuredClone(existing ?? {});
|
|
8227
|
-
for (const [
|
|
8228
|
-
keyNamed(
|
|
8229
|
-
setAt(draft,
|
|
8344
|
+
for (const [path45, value] of Object.entries(change.set ?? {})) {
|
|
8345
|
+
keyNamed(path45);
|
|
8346
|
+
setAt(draft, path45.split("."), value);
|
|
8230
8347
|
}
|
|
8231
|
-
for (const
|
|
8232
|
-
keyNamed(
|
|
8233
|
-
removeAt(draft,
|
|
8348
|
+
for (const path45 of change.unset ?? []) {
|
|
8349
|
+
keyNamed(path45);
|
|
8350
|
+
removeAt(draft, path45.split("."));
|
|
8234
8351
|
}
|
|
8235
8352
|
const result = StatuslineSchema.safeParse(draft);
|
|
8236
8353
|
if (!result.success) {
|
|
@@ -8516,6 +8633,8 @@ function buildLayoutPaths(root) {
|
|
|
8516
8633
|
usageAnchorsFile: import_node_path23.default.join(root, "usage", "anchors.json"),
|
|
8517
8634
|
usageJobsFile: import_node_path23.default.join(root, "usage", "jobs.json"),
|
|
8518
8635
|
jobLogsDir: import_node_path23.default.join(root, "logs", "jobs"),
|
|
8636
|
+
identityRenamesDir: import_node_path23.default.join(root, "identity-renames"),
|
|
8637
|
+
launchesDir: import_node_path23.default.join(root, "launches"),
|
|
8519
8638
|
superviseDir: import_node_path23.default.join(root, "supervise"),
|
|
8520
8639
|
modelMovesDir: import_node_path23.default.join(root, "model-moves"),
|
|
8521
8640
|
mcpPermissionsFile: import_node_path23.default.join(root, "mcp", "permissions.json")
|
|
@@ -9234,7 +9353,12 @@ function readProvider(paths, name) {
|
|
|
9234
9353
|
if (!import_node_fs6.default.existsSync(filePath)) {
|
|
9235
9354
|
return void 0;
|
|
9236
9355
|
}
|
|
9237
|
-
|
|
9356
|
+
let raw;
|
|
9357
|
+
try {
|
|
9358
|
+
raw = JSON.parse(import_node_fs6.default.readFileSync(filePath, "utf8"));
|
|
9359
|
+
} catch (error) {
|
|
9360
|
+
throw error instanceof SyntaxError ? new ConfigFileNotJsonError(filePath) : error;
|
|
9361
|
+
}
|
|
9238
9362
|
return parseProviderFile(filePath, raw);
|
|
9239
9363
|
}
|
|
9240
9364
|
function loadProvider(providersDir, name, port) {
|
|
@@ -9256,7 +9380,7 @@ function listProviders(paths, onInvalid = reportInvalidProvider) {
|
|
|
9256
9380
|
try {
|
|
9257
9381
|
provider = readProvider(paths, name);
|
|
9258
9382
|
} catch (error) {
|
|
9259
|
-
if (!(error instanceof ConfigValidationError || error instanceof LegacyProviderFileError || error instanceof UnsafeNameError)) {
|
|
9383
|
+
if (!(error instanceof ConfigValidationError || error instanceof LegacyProviderFileError || error instanceof ConfigFileNotJsonError || error instanceof UnsafeNameError)) {
|
|
9260
9384
|
throw error;
|
|
9261
9385
|
}
|
|
9262
9386
|
onInvalid(name, error.message);
|
|
@@ -9601,13 +9725,13 @@ function decideSignIn(facts) {
|
|
|
9601
9725
|
function credentialsFilePath(farmRoot) {
|
|
9602
9726
|
return import_node_path25.default.join(farmRoot, CREDENTIALS_FILE);
|
|
9603
9727
|
}
|
|
9604
|
-
function identitySignIn(
|
|
9728
|
+
function identitySignIn(fs15, probe, identity) {
|
|
9605
9729
|
const probing = !identity.hasCredentialBlock && identity.provider === void 0;
|
|
9606
9730
|
return decideSignIn({
|
|
9607
9731
|
hasCredentialBlock: identity.hasCredentialBlock,
|
|
9608
9732
|
provider: identity.provider,
|
|
9609
9733
|
keychainItem: probing && probe.platform === "darwin" && probe.run !== void 0 ? keychainHasItem(probe.run, identity.farmRoot) : void 0,
|
|
9610
|
-
credentialsFile: probing &&
|
|
9734
|
+
credentialsFile: probing && fs15.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
|
|
9611
9735
|
platform: probe.platform
|
|
9612
9736
|
});
|
|
9613
9737
|
}
|
|
@@ -9988,62 +10112,62 @@ var init_signatures = __esm({
|
|
|
9988
10112
|
});
|
|
9989
10113
|
|
|
9990
10114
|
// src/codex/anthropic.ts
|
|
9991
|
-
var
|
|
10115
|
+
var import_zod28, TextBlockSchema, Base64ImageSourceSchema, UrlImageSourceSchema, ImageBlockSchema, ToolUseBlockSchema, ToolResultContentBlockSchema, ToolResultBlockSchema, OtherBlockSchema, ContentBlockSchema, MessageSchema, ToolSchema, ToolChoiceSchema, SystemSchema, MessagesRequestSchema, CountTokensRequestSchema;
|
|
9992
10116
|
var init_anthropic = __esm({
|
|
9993
10117
|
"src/codex/anthropic.ts"() {
|
|
9994
10118
|
"use strict";
|
|
9995
|
-
|
|
9996
|
-
TextBlockSchema =
|
|
9997
|
-
Base64ImageSourceSchema =
|
|
9998
|
-
UrlImageSourceSchema =
|
|
9999
|
-
ImageBlockSchema =
|
|
10000
|
-
type:
|
|
10001
|
-
source:
|
|
10119
|
+
import_zod28 = require("zod");
|
|
10120
|
+
TextBlockSchema = import_zod28.z.looseObject({ type: import_zod28.z.literal("text"), text: import_zod28.z.string() });
|
|
10121
|
+
Base64ImageSourceSchema = import_zod28.z.looseObject({ type: import_zod28.z.literal("base64"), media_type: import_zod28.z.string().min(1), data: import_zod28.z.string() });
|
|
10122
|
+
UrlImageSourceSchema = import_zod28.z.looseObject({ type: import_zod28.z.literal("url"), url: import_zod28.z.string().min(1) });
|
|
10123
|
+
ImageBlockSchema = import_zod28.z.looseObject({
|
|
10124
|
+
type: import_zod28.z.literal("image"),
|
|
10125
|
+
source: import_zod28.z.union([Base64ImageSourceSchema, UrlImageSourceSchema])
|
|
10002
10126
|
});
|
|
10003
|
-
ToolUseBlockSchema =
|
|
10004
|
-
type:
|
|
10005
|
-
id:
|
|
10006
|
-
name:
|
|
10007
|
-
input:
|
|
10127
|
+
ToolUseBlockSchema = import_zod28.z.looseObject({
|
|
10128
|
+
type: import_zod28.z.literal("tool_use"),
|
|
10129
|
+
id: import_zod28.z.string().min(1),
|
|
10130
|
+
name: import_zod28.z.string().min(1),
|
|
10131
|
+
input: import_zod28.z.unknown()
|
|
10008
10132
|
});
|
|
10009
|
-
ToolResultContentBlockSchema =
|
|
10010
|
-
ToolResultBlockSchema =
|
|
10011
|
-
type:
|
|
10012
|
-
tool_use_id:
|
|
10013
|
-
content:
|
|
10133
|
+
ToolResultContentBlockSchema = import_zod28.z.union([TextBlockSchema, import_zod28.z.looseObject({ type: import_zod28.z.string() })]);
|
|
10134
|
+
ToolResultBlockSchema = import_zod28.z.looseObject({
|
|
10135
|
+
type: import_zod28.z.literal("tool_result"),
|
|
10136
|
+
tool_use_id: import_zod28.z.string().min(1),
|
|
10137
|
+
content: import_zod28.z.union([import_zod28.z.string(), import_zod28.z.array(ToolResultContentBlockSchema)]).optional()
|
|
10014
10138
|
});
|
|
10015
|
-
OtherBlockSchema =
|
|
10016
|
-
ContentBlockSchema =
|
|
10017
|
-
MessageSchema =
|
|
10018
|
-
role:
|
|
10019
|
-
content:
|
|
10139
|
+
OtherBlockSchema = import_zod28.z.looseObject({ type: import_zod28.z.string() });
|
|
10140
|
+
ContentBlockSchema = import_zod28.z.union([TextBlockSchema, ImageBlockSchema, ToolUseBlockSchema, ToolResultBlockSchema, OtherBlockSchema]);
|
|
10141
|
+
MessageSchema = import_zod28.z.looseObject({
|
|
10142
|
+
role: import_zod28.z.enum(["user", "assistant", "system"]),
|
|
10143
|
+
content: import_zod28.z.union([import_zod28.z.string(), import_zod28.z.array(ContentBlockSchema)])
|
|
10020
10144
|
});
|
|
10021
|
-
ToolSchema =
|
|
10022
|
-
name:
|
|
10023
|
-
description:
|
|
10024
|
-
input_schema:
|
|
10145
|
+
ToolSchema = import_zod28.z.looseObject({
|
|
10146
|
+
name: import_zod28.z.string().min(1),
|
|
10147
|
+
description: import_zod28.z.string().optional(),
|
|
10148
|
+
input_schema: import_zod28.z.record(import_zod28.z.string(), import_zod28.z.unknown()).optional()
|
|
10025
10149
|
});
|
|
10026
|
-
ToolChoiceSchema =
|
|
10027
|
-
|
|
10028
|
-
|
|
10150
|
+
ToolChoiceSchema = import_zod28.z.union([
|
|
10151
|
+
import_zod28.z.looseObject({ type: import_zod28.z.enum(["auto", "none", "any"]) }),
|
|
10152
|
+
import_zod28.z.looseObject({ type: import_zod28.z.literal("tool"), name: import_zod28.z.string().min(1) })
|
|
10029
10153
|
]);
|
|
10030
|
-
SystemSchema =
|
|
10031
|
-
MessagesRequestSchema =
|
|
10032
|
-
model:
|
|
10154
|
+
SystemSchema = import_zod28.z.union([import_zod28.z.string(), import_zod28.z.array(import_zod28.z.union([TextBlockSchema, OtherBlockSchema]))]);
|
|
10155
|
+
MessagesRequestSchema = import_zod28.z.looseObject({
|
|
10156
|
+
model: import_zod28.z.string().optional(),
|
|
10033
10157
|
system: SystemSchema.optional(),
|
|
10034
|
-
messages:
|
|
10035
|
-
tools:
|
|
10158
|
+
messages: import_zod28.z.array(MessageSchema),
|
|
10159
|
+
tools: import_zod28.z.array(ToolSchema).optional(),
|
|
10036
10160
|
tool_choice: ToolChoiceSchema.optional(),
|
|
10037
|
-
stream:
|
|
10161
|
+
stream: import_zod28.z.boolean().optional(),
|
|
10038
10162
|
/** `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. */
|
|
10039
|
-
metadata:
|
|
10163
|
+
metadata: import_zod28.z.looseObject({ user_id: import_zod28.z.string().optional() }).optional(),
|
|
10040
10164
|
/** Claude Code's effort setting. Any string is accepted; the translator honours only the levels the backend understands. */
|
|
10041
|
-
output_config:
|
|
10165
|
+
output_config: import_zod28.z.looseObject({ effort: import_zod28.z.string().optional() }).optional()
|
|
10042
10166
|
});
|
|
10043
|
-
CountTokensRequestSchema =
|
|
10044
|
-
system:
|
|
10045
|
-
messages:
|
|
10046
|
-
tools:
|
|
10167
|
+
CountTokensRequestSchema = import_zod28.z.looseObject({
|
|
10168
|
+
system: import_zod28.z.unknown().optional(),
|
|
10169
|
+
messages: import_zod28.z.unknown().optional(),
|
|
10170
|
+
tools: import_zod28.z.unknown().optional()
|
|
10047
10171
|
});
|
|
10048
10172
|
}
|
|
10049
10173
|
});
|
|
@@ -10145,12 +10269,12 @@ function filterCatalogue(models, catalogue) {
|
|
|
10145
10269
|
const excluded = catalogue.exclude === void 0 ? void 0 : (0, import_picomatch4.default)(catalogue.exclude, { dot: true });
|
|
10146
10270
|
return models.filter((model) => included?.(model.id) !== false && excluded?.(model.id) !== true);
|
|
10147
10271
|
}
|
|
10148
|
-
var import_picomatch4,
|
|
10272
|
+
var import_picomatch4, import_zod29, DEFAULT_CANDIDATE_URLS, MS_PER_SECOND5, SECONDS_PER_HOUR2, HOURS_PER_DAY5, MS_PER_HOUR4, HOURS_BETWEEN_RETRIES, CATALOGUE_MAX_AGE_MS, CATALOGUE_RETRY_MS, CATALOGUE_REQUEST_SECONDS, CATALOGUE_REQUEST_TIMEOUT_MS, CATALOGUE_REFRESH_TIMEOUT_MS, CatalogueModelSchema, CatalogueCacheSchema;
|
|
10149
10273
|
var init_providerCatalogue = __esm({
|
|
10150
10274
|
"src/providerCatalogue.ts"() {
|
|
10151
10275
|
"use strict";
|
|
10152
10276
|
import_picomatch4 = __toESM(require("picomatch"), 1);
|
|
10153
|
-
|
|
10277
|
+
import_zod29 = require("zod");
|
|
10154
10278
|
init_names();
|
|
10155
10279
|
DEFAULT_CANDIDATE_URLS = 2;
|
|
10156
10280
|
MS_PER_SECOND5 = 1e3;
|
|
@@ -10163,8 +10287,8 @@ var init_providerCatalogue = __esm({
|
|
|
10163
10287
|
CATALOGUE_REQUEST_SECONDS = 10;
|
|
10164
10288
|
CATALOGUE_REQUEST_TIMEOUT_MS = CATALOGUE_REQUEST_SECONDS * MS_PER_SECOND5;
|
|
10165
10289
|
CATALOGUE_REFRESH_TIMEOUT_MS = DEFAULT_CANDIDATE_URLS * CATALOGUE_REQUEST_TIMEOUT_MS;
|
|
10166
|
-
CatalogueModelSchema =
|
|
10167
|
-
CatalogueCacheSchema =
|
|
10290
|
+
CatalogueModelSchema = import_zod29.z.strictObject({ id: import_zod29.z.string().min(1), name: import_zod29.z.string().min(1).optional() });
|
|
10291
|
+
CatalogueCacheSchema = import_zod29.z.strictObject({ fetchedAt: import_zod29.z.number(), url: import_zod29.z.string().min(1), models: import_zod29.z.array(CatalogueModelSchema) });
|
|
10168
10292
|
}
|
|
10169
10293
|
});
|
|
10170
10294
|
|
|
@@ -10471,6 +10595,60 @@ var init_proxyBypass2 = __esm({
|
|
|
10471
10595
|
}
|
|
10472
10596
|
});
|
|
10473
10597
|
|
|
10598
|
+
// src/replayRun.ts
|
|
10599
|
+
function keyOf2(command, args) {
|
|
10600
|
+
return JSON.stringify([command, args]);
|
|
10601
|
+
}
|
|
10602
|
+
async function recordRuns(decide, runAsync) {
|
|
10603
|
+
const answers = /* @__PURE__ */ new Map();
|
|
10604
|
+
const replay = {
|
|
10605
|
+
run: (command, args) => {
|
|
10606
|
+
const answer = answers.get(keyOf2(command, args));
|
|
10607
|
+
if (answer === void 0) {
|
|
10608
|
+
throw new RunNeededError(command, args);
|
|
10609
|
+
}
|
|
10610
|
+
return answer;
|
|
10611
|
+
}
|
|
10612
|
+
};
|
|
10613
|
+
for (; ; ) {
|
|
10614
|
+
try {
|
|
10615
|
+
decide(replay);
|
|
10616
|
+
return replay;
|
|
10617
|
+
} catch (error) {
|
|
10618
|
+
if (!(error instanceof RunNeededError)) {
|
|
10619
|
+
throw error;
|
|
10620
|
+
}
|
|
10621
|
+
answers.set(keyOf2(error.command, error.args), await runAsync(error.command, error.args));
|
|
10622
|
+
}
|
|
10623
|
+
}
|
|
10624
|
+
}
|
|
10625
|
+
async function resolveWithAsyncRuns(decide, runAsync) {
|
|
10626
|
+
let result;
|
|
10627
|
+
await recordRuns((run) => {
|
|
10628
|
+
result = { value: decide(run) };
|
|
10629
|
+
}, runAsync);
|
|
10630
|
+
if (result === void 0) {
|
|
10631
|
+
throw new Error("the decision finished without a result");
|
|
10632
|
+
}
|
|
10633
|
+
return result.value;
|
|
10634
|
+
}
|
|
10635
|
+
var RunNeededError;
|
|
10636
|
+
var init_replayRun = __esm({
|
|
10637
|
+
"src/replayRun.ts"() {
|
|
10638
|
+
"use strict";
|
|
10639
|
+
RunNeededError = class extends Error {
|
|
10640
|
+
constructor(command, args) {
|
|
10641
|
+
super(`no recorded answer for ${command} ${args.join(" ")}`);
|
|
10642
|
+
this.command = command;
|
|
10643
|
+
this.args = args;
|
|
10644
|
+
this.name = "RunNeededError";
|
|
10645
|
+
}
|
|
10646
|
+
command;
|
|
10647
|
+
args;
|
|
10648
|
+
};
|
|
10649
|
+
}
|
|
10650
|
+
});
|
|
10651
|
+
|
|
10474
10652
|
// src/update/update.ts
|
|
10475
10653
|
function compareVersions3(left, right) {
|
|
10476
10654
|
const parse = (version) => {
|
|
@@ -10977,6 +11155,59 @@ var init_cliOverride = __esm({
|
|
|
10977
11155
|
}
|
|
10978
11156
|
});
|
|
10979
11157
|
|
|
11158
|
+
// src/launcher/launchRecords.ts
|
|
11159
|
+
function recordFile(directory, pid, identity) {
|
|
11160
|
+
return import_node_path38.default.join(directory, `${String(pid)}.${identity}${RECORD_SUFFIX}`);
|
|
11161
|
+
}
|
|
11162
|
+
function readRecord(fs15, directory, name) {
|
|
11163
|
+
if (!name.endsWith(RECORD_SUFFIX)) {
|
|
11164
|
+
return void 0;
|
|
11165
|
+
}
|
|
11166
|
+
const raw = fs15.readFileUtf8(import_node_path38.default.join(directory, name));
|
|
11167
|
+
if (raw === void 0) {
|
|
11168
|
+
return void 0;
|
|
11169
|
+
}
|
|
11170
|
+
let parsed;
|
|
11171
|
+
try {
|
|
11172
|
+
parsed = JSON.parse(raw);
|
|
11173
|
+
} catch {
|
|
11174
|
+
return void 0;
|
|
11175
|
+
}
|
|
11176
|
+
const result = LaunchRecordSchema.safeParse(parsed);
|
|
11177
|
+
return result.success ? result.data : void 0;
|
|
11178
|
+
}
|
|
11179
|
+
function registerLaunch(fs15, directory, owner, isRunning) {
|
|
11180
|
+
fs15.mkdirPrivate(directory);
|
|
11181
|
+
for (const name of fs15.readdir(directory)) {
|
|
11182
|
+
const record2 = readRecord(fs15, directory, name);
|
|
11183
|
+
if (record2 !== void 0 && !isRunning(record2.pid)) {
|
|
11184
|
+
fs15.removeRecursive(import_node_path38.default.join(directory, name));
|
|
11185
|
+
}
|
|
11186
|
+
}
|
|
11187
|
+
const file = recordFile(directory, owner.pid, owner.identity);
|
|
11188
|
+
const record = { pid: owner.pid, identity: owner.identity, startedAt: new Date(owner.startedAtMs).toISOString() };
|
|
11189
|
+
fs15.writeFilePrivate(file, `${JSON.stringify(record)}
|
|
11190
|
+
`);
|
|
11191
|
+
return () => {
|
|
11192
|
+
fs15.removeRecursive(file);
|
|
11193
|
+
};
|
|
11194
|
+
}
|
|
11195
|
+
var import_node_path38, import_zod36, LaunchRecordSchema, RECORD_SUFFIX;
|
|
11196
|
+
var init_launchRecords = __esm({
|
|
11197
|
+
"src/launcher/launchRecords.ts"() {
|
|
11198
|
+
"use strict";
|
|
11199
|
+
import_node_path38 = __toESM(require("node:path"), 1);
|
|
11200
|
+
import_zod36 = require("zod");
|
|
11201
|
+
LaunchRecordSchema = import_zod36.z.strictObject({
|
|
11202
|
+
/** The launcher's process id, which is what tells a launch in progress from a record a crashed launcher left behind. */
|
|
11203
|
+
pid: import_zod36.z.number().int().positive(),
|
|
11204
|
+
identity: import_zod36.z.string().min(1),
|
|
11205
|
+
startedAt: import_zod36.z.iso.datetime()
|
|
11206
|
+
});
|
|
11207
|
+
RECORD_SUFFIX = ".json";
|
|
11208
|
+
}
|
|
11209
|
+
});
|
|
11210
|
+
|
|
10980
11211
|
// src/headroom/headers.ts
|
|
10981
11212
|
function mergeAnthropicCustomHeaders(existing, additions) {
|
|
10982
11213
|
const merged = /* @__PURE__ */ new Map();
|
|
@@ -11100,7 +11331,7 @@ function buildEnv(params) {
|
|
|
11100
11331
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
11101
11332
|
let providerCustomHeaders;
|
|
11102
11333
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
11103
|
-
env.CLAUDE_CONFIG_DIR =
|
|
11334
|
+
env.CLAUDE_CONFIG_DIR = import_node_path39.default.join(params.identitiesDir, params.resolvedIdentityName);
|
|
11104
11335
|
}
|
|
11105
11336
|
if (params.provider !== void 0) {
|
|
11106
11337
|
const providerEnv = params.provider.definition.kind !== void 0 && params.provider.definition.kind !== "http" ? {} : params.provider.definition.env ?? {};
|
|
@@ -11154,11 +11385,11 @@ function buildEnv(params) {
|
|
|
11154
11385
|
}
|
|
11155
11386
|
return env;
|
|
11156
11387
|
}
|
|
11157
|
-
var
|
|
11388
|
+
var import_node_path39, LOOPBACK_HOSTS, PROVIDER_SESSION_PLACEHOLDER;
|
|
11158
11389
|
var init_flags = __esm({
|
|
11159
11390
|
"src/launcher/flags.ts"() {
|
|
11160
11391
|
"use strict";
|
|
11161
|
-
|
|
11392
|
+
import_node_path39 = __toESM(require("node:path"), 1);
|
|
11162
11393
|
init_envBool();
|
|
11163
11394
|
init_cliError();
|
|
11164
11395
|
init_conditions();
|
|
@@ -11243,15 +11474,15 @@ function contextTokensOfTranscript(text) {
|
|
|
11243
11474
|
}
|
|
11244
11475
|
return void 0;
|
|
11245
11476
|
}
|
|
11246
|
-
function newestTranscript(
|
|
11477
|
+
function newestTranscript(fs15, projectDir) {
|
|
11247
11478
|
let newest;
|
|
11248
11479
|
let newestMs = -Infinity;
|
|
11249
|
-
for (const name of
|
|
11480
|
+
for (const name of fs15.readdir(projectDir)) {
|
|
11250
11481
|
if (!name.endsWith(".jsonl")) {
|
|
11251
11482
|
continue;
|
|
11252
11483
|
}
|
|
11253
|
-
const candidate =
|
|
11254
|
-
const stat =
|
|
11484
|
+
const candidate = import_node_path40.default.join(projectDir, name);
|
|
11485
|
+
const stat = fs15.lstat(candidate);
|
|
11255
11486
|
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
11256
11487
|
newestMs = stat.mtimeMs;
|
|
11257
11488
|
newest = candidate;
|
|
@@ -11259,21 +11490,21 @@ function newestTranscript(fs14, projectDir) {
|
|
|
11259
11490
|
}
|
|
11260
11491
|
return newest;
|
|
11261
11492
|
}
|
|
11262
|
-
function resumedContextTokens(
|
|
11493
|
+
function resumedContextTokens(fs15, params) {
|
|
11263
11494
|
const target = resumeTargetOf(params.passthrough);
|
|
11264
11495
|
if (target === void 0) {
|
|
11265
11496
|
return void 0;
|
|
11266
11497
|
}
|
|
11267
|
-
const projectDir =
|
|
11268
|
-
const file = target.kind === "id" ?
|
|
11269
|
-
const text = file === void 0 ? void 0 :
|
|
11498
|
+
const projectDir = import_node_path40.default.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
|
|
11499
|
+
const file = target.kind === "id" ? import_node_path40.default.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs15, projectDir);
|
|
11500
|
+
const text = file === void 0 ? void 0 : fs15.readFileUtf8(file);
|
|
11270
11501
|
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
11271
11502
|
}
|
|
11272
|
-
var
|
|
11503
|
+
var import_node_path40;
|
|
11273
11504
|
var init_resumeContext = __esm({
|
|
11274
11505
|
"src/usage/resumeContext.ts"() {
|
|
11275
11506
|
"use strict";
|
|
11276
|
-
|
|
11507
|
+
import_node_path40 = __toESM(require("node:path"), 1);
|
|
11277
11508
|
}
|
|
11278
11509
|
});
|
|
11279
11510
|
|
|
@@ -11870,7 +12101,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
|
|
|
11870
12101
|
return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
11871
12102
|
}
|
|
11872
12103
|
function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
11873
|
-
const { paths, fs:
|
|
12104
|
+
const { paths, fs: fs15, proc, log } = params;
|
|
11874
12105
|
if (decided.pool === void 0) {
|
|
11875
12106
|
return { identityDecision: decided };
|
|
11876
12107
|
}
|
|
@@ -11889,7 +12120,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
11889
12120
|
selectedVia: decided.source,
|
|
11890
12121
|
pools: params.pools,
|
|
11891
12122
|
paths,
|
|
11892
|
-
fs:
|
|
12123
|
+
fs: fs15,
|
|
11893
12124
|
usageFs: farmRuntime.fs,
|
|
11894
12125
|
cwd: farmRuntime.cwd,
|
|
11895
12126
|
now: farmRuntime.now,
|
|
@@ -11913,7 +12144,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
11913
12144
|
};
|
|
11914
12145
|
}
|
|
11915
12146
|
function decideLaunch(params, readOnly) {
|
|
11916
|
-
const { paths, fs:
|
|
12147
|
+
const { paths, fs: fs15, proc, log } = params;
|
|
11917
12148
|
const { env, argv } = proc;
|
|
11918
12149
|
const parsedArgv = parseLauncherArgv(argv);
|
|
11919
12150
|
const cliOverride = buildCliOverride({
|
|
@@ -11928,7 +12159,7 @@ function decideLaunch(params, readOnly) {
|
|
|
11928
12159
|
argv0Identity: params.pickedIdentity ?? parsedArgv.identity,
|
|
11929
12160
|
directoryPinnedIdentity: params.directoryPinnedIdentity,
|
|
11930
12161
|
readActiveIdentityFile: () => {
|
|
11931
|
-
const raw =
|
|
12162
|
+
const raw = fs15.readFileUtf8(paths.activeIdentityFile);
|
|
11932
12163
|
if (raw === void 0) {
|
|
11933
12164
|
return void 0;
|
|
11934
12165
|
}
|
|
@@ -11963,7 +12194,7 @@ function decideLaunch(params, readOnly) {
|
|
|
11963
12194
|
}
|
|
11964
12195
|
let loadedIdentity;
|
|
11965
12196
|
if (identityDecision.name !== void 0) {
|
|
11966
|
-
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name,
|
|
12197
|
+
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs15);
|
|
11967
12198
|
if (loadedIdentity === void 0) {
|
|
11968
12199
|
log.error(
|
|
11969
12200
|
`agent-shim: no identity named "${identityDecision.name}" (selected via ${identityDecision.source}). Run \`agent-shim identity add ${identityDecision.name}\` first.`
|
|
@@ -11978,7 +12209,7 @@ function decideLaunch(params, readOnly) {
|
|
|
11978
12209
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
11979
12210
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
11980
12211
|
});
|
|
11981
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true &&
|
|
12212
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs15.readConfigFile(profileFilePath(paths.configProfilesDir, configProfileDecision.name, `the configuration profile selected via ${configProfileDecision.source}`)) === void 0) {
|
|
11982
12213
|
log.error(
|
|
11983
12214
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
11984
12215
|
);
|
|
@@ -11987,7 +12218,7 @@ function decideLaunch(params, readOnly) {
|
|
|
11987
12218
|
const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
|
|
11988
12219
|
const providerParams = {
|
|
11989
12220
|
paths,
|
|
11990
|
-
port:
|
|
12221
|
+
port: fs15,
|
|
11991
12222
|
...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
|
|
11992
12223
|
...farmContext === void 0 ? {} : { cascade: farmContext.cascade },
|
|
11993
12224
|
...loadedIdentity?.config.provider === void 0 ? {} : { identityProvider: loadedIdentity.config.provider }
|
|
@@ -12099,9 +12330,9 @@ function decideLaunch(params, readOnly) {
|
|
|
12099
12330
|
const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
|
|
12100
12331
|
const globalModels = loadConfigFile(paths.globalConfigFile, GlobalConfigSchema, params.fs.readConfigFile)?.config.models;
|
|
12101
12332
|
const models = launchCascade !== void 0 && params.farm !== void 0 ? cascadeModels : globalModels;
|
|
12102
|
-
const listedProviders = listProviderNames(
|
|
12333
|
+
const listedProviders = listProviderNames(fs15.readdir, paths.providersDir).flatMap((name) => {
|
|
12103
12334
|
try {
|
|
12104
|
-
const definition = loadProvider(paths.providersDir, name,
|
|
12335
|
+
const definition = loadProvider(paths.providersDir, name, fs15);
|
|
12105
12336
|
return definition === void 0 ? [] : [[name, definition, parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, name)))?.models ?? []]];
|
|
12106
12337
|
} catch {
|
|
12107
12338
|
return [];
|
|
@@ -12119,7 +12350,7 @@ function decideLaunch(params, readOnly) {
|
|
|
12119
12350
|
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
12120
12351
|
passthrough: withLauncherSettings(params.supervised === void 0 ? parsedArgv.rest : withSupervision(parsedArgv.rest, params.supervised), launcherSettings)
|
|
12121
12352
|
}) : [...parsedArgv.rest];
|
|
12122
|
-
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR :
|
|
12353
|
+
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : import_node_path41.default.join(paths.identitiesDir, identityDecision.name);
|
|
12123
12354
|
const decision = {
|
|
12124
12355
|
identitySource: identityDecision.source,
|
|
12125
12356
|
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
@@ -12157,6 +12388,19 @@ function decideLaunch(params, readOnly) {
|
|
|
12157
12388
|
};
|
|
12158
12389
|
}
|
|
12159
12390
|
function prepareLaunch(params) {
|
|
12391
|
+
const removers = [];
|
|
12392
|
+
try {
|
|
12393
|
+
return prepareRegisteredLaunch(params, (remove) => {
|
|
12394
|
+
removers.push(remove);
|
|
12395
|
+
});
|
|
12396
|
+
} catch (error) {
|
|
12397
|
+
for (const remove of removers) {
|
|
12398
|
+
remove();
|
|
12399
|
+
}
|
|
12400
|
+
throw error;
|
|
12401
|
+
}
|
|
12402
|
+
}
|
|
12403
|
+
function prepareRegisteredLaunch(params, onRecorded) {
|
|
12160
12404
|
const { paths, proc, log } = params;
|
|
12161
12405
|
const { env } = proc;
|
|
12162
12406
|
const decided = decideLaunch(params, false);
|
|
@@ -12177,14 +12421,17 @@ function prepareLaunch(params) {
|
|
|
12177
12421
|
})
|
|
12178
12422
|
];
|
|
12179
12423
|
let warnings = [];
|
|
12424
|
+
let unregisterLaunch;
|
|
12180
12425
|
const updateCheck = runLaunchUpdateCheck({
|
|
12181
12426
|
mode: params.updateMode ?? "off",
|
|
12182
|
-
checkPath:
|
|
12427
|
+
checkPath: import_node_path41.default.join(paths.root, "update.check"),
|
|
12183
12428
|
currentVersion: package_default.version,
|
|
12184
12429
|
port: params.update
|
|
12185
12430
|
});
|
|
12186
12431
|
if (decided.farmContext !== void 0) {
|
|
12187
12432
|
const { farm: resyncFarmRuntime, identity: resyncIdentity, cascade } = decided.farmContext;
|
|
12433
|
+
unregisterLaunch = registerLaunch(resyncFarmRuntime.fs, paths.launchesDir, { pid: resyncFarmRuntime.lock.pid, identity: resyncIdentity, startedAtMs: resyncFarmRuntime.now() }, resyncFarmRuntime.lock.isRunning);
|
|
12434
|
+
onRecorded(unregisterLaunch);
|
|
12188
12435
|
let result;
|
|
12189
12436
|
try {
|
|
12190
12437
|
result = resyncFarm({
|
|
@@ -12202,10 +12449,11 @@ function prepareLaunch(params) {
|
|
|
12202
12449
|
classification: resyncFarmRuntime.classification,
|
|
12203
12450
|
now: resyncFarmRuntime.now,
|
|
12204
12451
|
uniqueSuffix: resyncFarmRuntime.uniqueSuffix,
|
|
12452
|
+
identityExists: () => loadIdentity(paths.identitiesDir, resyncIdentity, params.fs) !== void 0,
|
|
12205
12453
|
lock: resyncFarmRuntime.lock
|
|
12206
12454
|
});
|
|
12207
12455
|
} catch (error) {
|
|
12208
|
-
if (error instanceof IdentityLockBusyError) {
|
|
12456
|
+
if (error instanceof IdentityLockBusyError || error instanceof IdentityGoneError) {
|
|
12209
12457
|
log.error(error.message);
|
|
12210
12458
|
proc.exit(1);
|
|
12211
12459
|
}
|
|
@@ -12265,7 +12513,7 @@ function prepareLaunch(params) {
|
|
|
12265
12513
|
proxyBypass: resolvedFlags.proxyBypass,
|
|
12266
12514
|
...resolvedFlags.statusline === void 0 ? {} : { statusline: resolvedFlags.statusline }
|
|
12267
12515
|
});
|
|
12268
|
-
const releases = [...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
|
|
12516
|
+
const releases = [...unregisterLaunch === void 0 ? [] : [unregisterLaunch], ...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
|
|
12269
12517
|
const release = () => {
|
|
12270
12518
|
for (const registered of releases) {
|
|
12271
12519
|
registered();
|
|
@@ -12326,18 +12574,19 @@ function runLaunchPlan(plan, spawn3) {
|
|
|
12326
12574
|
function runLauncher(params) {
|
|
12327
12575
|
params.proc.exit(runLaunchPlan(prepareLaunch(params), params.spawn));
|
|
12328
12576
|
}
|
|
12329
|
-
var import_node_crypto11, import_node_util2,
|
|
12577
|
+
var import_node_crypto11, import_node_util2, import_node_path41;
|
|
12330
12578
|
var init_launcher = __esm({
|
|
12331
12579
|
"src/launcher.ts"() {
|
|
12332
12580
|
"use strict";
|
|
12333
12581
|
import_node_crypto11 = require("node:crypto");
|
|
12334
12582
|
import_node_util2 = require("node:util");
|
|
12335
|
-
|
|
12583
|
+
import_node_path41 = __toESM(require("node:path"), 1);
|
|
12336
12584
|
init_package();
|
|
12337
12585
|
init_envBool();
|
|
12338
12586
|
init_argv();
|
|
12339
12587
|
init_cliOverride();
|
|
12340
12588
|
init_farm();
|
|
12589
|
+
init_launchRecords();
|
|
12341
12590
|
init_guard();
|
|
12342
12591
|
init_identity();
|
|
12343
12592
|
init_flags();
|
|
@@ -12377,13 +12626,13 @@ function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string"
|
|
|
12377
12626
|
if (distDir === void 0) {
|
|
12378
12627
|
throw new OwnCliPathUnknownError();
|
|
12379
12628
|
}
|
|
12380
|
-
return
|
|
12629
|
+
return import_node_path42.default.join(distDir, OWN_CLI_FILE_NAME);
|
|
12381
12630
|
}
|
|
12382
|
-
var
|
|
12631
|
+
var import_node_path42, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
12383
12632
|
var init_ownCli = __esm({
|
|
12384
12633
|
"src/ownCli.ts"() {
|
|
12385
12634
|
"use strict";
|
|
12386
|
-
|
|
12635
|
+
import_node_path42 = __toESM(require("node:path"), 1);
|
|
12387
12636
|
init_cliError();
|
|
12388
12637
|
OWN_CLI_FILE_NAME = "cli.cjs";
|
|
12389
12638
|
OwnCliPathUnknownError = class extends CliError {
|
|
@@ -12397,15 +12646,15 @@ var init_ownCli = __esm({
|
|
|
12397
12646
|
|
|
12398
12647
|
// src/frontdoor/doorLog.ts
|
|
12399
12648
|
function appendDoorLog(paths, line) {
|
|
12400
|
-
|
|
12401
|
-
|
|
12649
|
+
import_node_fs13.default.mkdirSync(paths.logsDir, { recursive: true });
|
|
12650
|
+
import_node_fs13.default.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
12402
12651
|
`);
|
|
12403
12652
|
}
|
|
12404
|
-
var
|
|
12653
|
+
var import_node_fs13;
|
|
12405
12654
|
var init_doorLog = __esm({
|
|
12406
12655
|
"src/frontdoor/doorLog.ts"() {
|
|
12407
12656
|
"use strict";
|
|
12408
|
-
|
|
12657
|
+
import_node_fs13 = __toESM(require("node:fs"), 1);
|
|
12409
12658
|
}
|
|
12410
12659
|
});
|
|
12411
12660
|
|
|
@@ -12425,14 +12674,14 @@ var init_selfIdentity = __esm({
|
|
|
12425
12674
|
|
|
12426
12675
|
// src/frontdoor/trust.ts
|
|
12427
12676
|
function resolveTrustBundle(params) {
|
|
12428
|
-
const { caCertFile, bundlesDir, variable, inherited, fs:
|
|
12429
|
-
if (inherited === void 0 || inherited === "" ||
|
|
12677
|
+
const { caCertFile, bundlesDir, variable, inherited, fs: fs15 } = params;
|
|
12678
|
+
if (inherited === void 0 || inherited === "" || import_node_path43.default.resolve(inherited) === import_node_path43.default.resolve(caCertFile)) {
|
|
12430
12679
|
return { path: caCertFile };
|
|
12431
12680
|
}
|
|
12432
|
-
const caPem =
|
|
12681
|
+
const caPem = fs15.readFileUtf8(caCertFile);
|
|
12433
12682
|
let inheritedPem;
|
|
12434
12683
|
try {
|
|
12435
|
-
inheritedPem =
|
|
12684
|
+
inheritedPem = fs15.readFileUtf8(inherited);
|
|
12436
12685
|
} catch (error) {
|
|
12437
12686
|
return {
|
|
12438
12687
|
path: caCertFile,
|
|
@@ -12444,19 +12693,19 @@ function resolveTrustBundle(params) {
|
|
|
12444
12693
|
}
|
|
12445
12694
|
const combined = `${inheritedPem.trimEnd()}
|
|
12446
12695
|
${caPem}`;
|
|
12447
|
-
const bundle =
|
|
12448
|
-
if (!
|
|
12449
|
-
|
|
12450
|
-
|
|
12696
|
+
const bundle = import_node_path43.default.join(bundlesDir, `${(0, import_node_crypto12.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
12697
|
+
if (!fs15.exists(bundle)) {
|
|
12698
|
+
fs15.mkdirp(bundlesDir);
|
|
12699
|
+
fs15.writeFileAtomic(bundle, combined);
|
|
12451
12700
|
}
|
|
12452
12701
|
return { path: bundle };
|
|
12453
12702
|
}
|
|
12454
|
-
var import_node_crypto12,
|
|
12703
|
+
var import_node_crypto12, import_node_path43, BUNDLE_NAME_HEX_DIGITS;
|
|
12455
12704
|
var init_trust = __esm({
|
|
12456
12705
|
"src/frontdoor/trust.ts"() {
|
|
12457
12706
|
"use strict";
|
|
12458
12707
|
import_node_crypto12 = require("node:crypto");
|
|
12459
|
-
|
|
12708
|
+
import_node_path43 = __toESM(require("node:path"), 1);
|
|
12460
12709
|
BUNDLE_NAME_HEX_DIGITS = 16;
|
|
12461
12710
|
}
|
|
12462
12711
|
});
|
|
@@ -12487,7 +12736,7 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
12487
12736
|
}
|
|
12488
12737
|
},
|
|
12489
12738
|
// 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.
|
|
12490
|
-
verifyListener: (port) => probeFrontDoorSync(port,
|
|
12739
|
+
verifyListener: (port) => probeFrontDoorSync(port, import_node_fs14.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
|
|
12491
12740
|
};
|
|
12492
12741
|
}
|
|
12493
12742
|
function realFrontDoorPort(paths, spawnDaemon) {
|
|
@@ -12508,11 +12757,11 @@ function realFrontDoorPort(paths, spawnDaemon) {
|
|
|
12508
12757
|
}
|
|
12509
12758
|
};
|
|
12510
12759
|
}
|
|
12511
|
-
var
|
|
12760
|
+
var import_node_fs14, realTrustBundleFs;
|
|
12512
12761
|
var init_realFrontDoorPort = __esm({
|
|
12513
12762
|
"src/frontdoor/realFrontDoorPort.ts"() {
|
|
12514
12763
|
"use strict";
|
|
12515
|
-
|
|
12764
|
+
import_node_fs14 = __toESM(require("node:fs"), 1);
|
|
12516
12765
|
init_realPorts();
|
|
12517
12766
|
init_doorLog();
|
|
12518
12767
|
init_ensure2();
|
|
@@ -12521,10 +12770,10 @@ var init_realFrontDoorPort = __esm({
|
|
|
12521
12770
|
init_selfIdentity();
|
|
12522
12771
|
init_trust();
|
|
12523
12772
|
realTrustBundleFs = {
|
|
12524
|
-
readFileUtf8: (file) =>
|
|
12525
|
-
exists: (file) =>
|
|
12773
|
+
readFileUtf8: (file) => import_node_fs14.default.readFileSync(file, "utf8"),
|
|
12774
|
+
exists: (file) => import_node_fs14.default.existsSync(file),
|
|
12526
12775
|
mkdirp: (dir) => {
|
|
12527
|
-
|
|
12776
|
+
import_node_fs14.default.mkdirSync(dir, { recursive: true });
|
|
12528
12777
|
},
|
|
12529
12778
|
writeFileAtomic: (file, contents) => {
|
|
12530
12779
|
realFarmFs.writeFilePrivate(file, contents);
|
|
@@ -12533,50 +12782,6 @@ var init_realFrontDoorPort = __esm({
|
|
|
12533
12782
|
}
|
|
12534
12783
|
});
|
|
12535
12784
|
|
|
12536
|
-
// src/replayRun.ts
|
|
12537
|
-
function keyOf2(command, args) {
|
|
12538
|
-
return JSON.stringify([command, args]);
|
|
12539
|
-
}
|
|
12540
|
-
async function recordRuns(decide, runAsync) {
|
|
12541
|
-
const answers = /* @__PURE__ */ new Map();
|
|
12542
|
-
const replay = {
|
|
12543
|
-
run: (command, args) => {
|
|
12544
|
-
const answer = answers.get(keyOf2(command, args));
|
|
12545
|
-
if (answer === void 0) {
|
|
12546
|
-
throw new RunNeededError(command, args);
|
|
12547
|
-
}
|
|
12548
|
-
return answer;
|
|
12549
|
-
}
|
|
12550
|
-
};
|
|
12551
|
-
for (; ; ) {
|
|
12552
|
-
try {
|
|
12553
|
-
decide(replay);
|
|
12554
|
-
return replay;
|
|
12555
|
-
} catch (error) {
|
|
12556
|
-
if (!(error instanceof RunNeededError)) {
|
|
12557
|
-
throw error;
|
|
12558
|
-
}
|
|
12559
|
-
answers.set(keyOf2(error.command, error.args), await runAsync(error.command, error.args));
|
|
12560
|
-
}
|
|
12561
|
-
}
|
|
12562
|
-
}
|
|
12563
|
-
var RunNeededError;
|
|
12564
|
-
var init_replayRun = __esm({
|
|
12565
|
-
"src/replayRun.ts"() {
|
|
12566
|
-
"use strict";
|
|
12567
|
-
RunNeededError = class extends Error {
|
|
12568
|
-
constructor(command, args) {
|
|
12569
|
-
super(`no recorded answer for ${command} ${args.join(" ")}`);
|
|
12570
|
-
this.command = command;
|
|
12571
|
-
this.args = args;
|
|
12572
|
-
this.name = "RunNeededError";
|
|
12573
|
-
}
|
|
12574
|
-
command;
|
|
12575
|
-
args;
|
|
12576
|
-
};
|
|
12577
|
-
}
|
|
12578
|
-
});
|
|
12579
|
-
|
|
12580
12785
|
// src/launchWiring.ts
|
|
12581
12786
|
function buildFarmRuntime(paths, cwd, run = realRunPort) {
|
|
12582
12787
|
const home = import_node_os7.default.homedir();
|
|
@@ -12631,7 +12836,7 @@ function realPrepareLaunchParams(paths, options) {
|
|
|
12631
12836
|
frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
|
|
12632
12837
|
credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
|
|
12633
12838
|
hold: realHoldPort,
|
|
12634
|
-
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot:
|
|
12839
|
+
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot: import_node_path44.default.join(paths.identitiesDir, identity), hasCredentialBlock: false, provider: void 0 }).state !== "signed-out",
|
|
12635
12840
|
...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
|
|
12636
12841
|
...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
|
|
12637
12842
|
...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
|
|
@@ -12690,12 +12895,12 @@ function resolveClaudeLaunch(options, run = realRunPort) {
|
|
|
12690
12895
|
};
|
|
12691
12896
|
return { resolution: resolveLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, run, farm: buildFarmRuntime(paths, options.cwd, run) })), warnings };
|
|
12692
12897
|
}
|
|
12693
|
-
var import_node_os7,
|
|
12898
|
+
var import_node_os7, import_node_path44, import_node_crypto13, LaunchRefusedError;
|
|
12694
12899
|
var init_launchWiring = __esm({
|
|
12695
12900
|
"src/launchWiring.ts"() {
|
|
12696
12901
|
"use strict";
|
|
12697
12902
|
import_node_os7 = __toESM(require("node:os"), 1);
|
|
12698
|
-
|
|
12903
|
+
import_node_path44 = __toESM(require("node:path"), 1);
|
|
12699
12904
|
import_node_crypto13 = require("node:crypto");
|
|
12700
12905
|
init_cliError();
|
|
12701
12906
|
init_claudeShim();
|
|
@@ -12919,11 +13124,11 @@ var init_identityClaude = __esm({
|
|
|
12919
13124
|
});
|
|
12920
13125
|
|
|
12921
13126
|
// src/usage/providerQuota.ts
|
|
12922
|
-
var
|
|
13127
|
+
var import_zod37, 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;
|
|
12923
13128
|
var init_providerQuota = __esm({
|
|
12924
13129
|
"src/usage/providerQuota.ts"() {
|
|
12925
13130
|
"use strict";
|
|
12926
|
-
|
|
13131
|
+
import_zod37 = require("zod");
|
|
12927
13132
|
init_cloudUpstream();
|
|
12928
13133
|
init_schema2();
|
|
12929
13134
|
MS_PER_SECOND9 = 1e3;
|
|
@@ -12938,35 +13143,35 @@ var init_providerQuota = __esm({
|
|
|
12938
13143
|
[ZAI_UNIT_HOURS, SECONDS_PER_HOUR3 * MS_PER_SECOND9],
|
|
12939
13144
|
[ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9]
|
|
12940
13145
|
]);
|
|
12941
|
-
ZaiLimitSchema =
|
|
12942
|
-
type:
|
|
12943
|
-
unit:
|
|
12944
|
-
number:
|
|
12945
|
-
percentage:
|
|
12946
|
-
nextResetTime:
|
|
12947
|
-
usage:
|
|
12948
|
-
currentValue:
|
|
12949
|
-
remaining:
|
|
13146
|
+
ZaiLimitSchema = import_zod37.z.object({
|
|
13147
|
+
type: import_zod37.z.string(),
|
|
13148
|
+
unit: import_zod37.z.number().int(),
|
|
13149
|
+
number: import_zod37.z.number().int().positive(),
|
|
13150
|
+
percentage: import_zod37.z.number().nonnegative(),
|
|
13151
|
+
nextResetTime: import_zod37.z.number().positive().optional(),
|
|
13152
|
+
usage: import_zod37.z.number().nonnegative().optional(),
|
|
13153
|
+
currentValue: import_zod37.z.number().nonnegative().optional(),
|
|
13154
|
+
remaining: import_zod37.z.number().nonnegative().optional()
|
|
12950
13155
|
});
|
|
12951
|
-
ZaiResponseSchema =
|
|
12952
|
-
success:
|
|
12953
|
-
msg:
|
|
12954
|
-
data:
|
|
13156
|
+
ZaiResponseSchema = import_zod37.z.object({
|
|
13157
|
+
success: import_zod37.z.boolean(),
|
|
13158
|
+
msg: import_zod37.z.string().optional(),
|
|
13159
|
+
data: import_zod37.z.object({ level: import_zod37.z.string().optional(), limits: import_zod37.z.array(ZaiLimitSchema) })
|
|
12955
13160
|
});
|
|
12956
13161
|
OPENROUTER_HOST = "openrouter.ai";
|
|
12957
13162
|
OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
|
|
12958
13163
|
OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
|
|
12959
13164
|
MS_PER_DAY2 = HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
|
|
12960
|
-
OpenRouterKeySchema =
|
|
12961
|
-
data:
|
|
12962
|
-
limit:
|
|
12963
|
-
limit_remaining:
|
|
12964
|
-
limit_reset:
|
|
12965
|
-
is_free_tier:
|
|
12966
|
-
free_model_daily_requests:
|
|
13165
|
+
OpenRouterKeySchema = import_zod37.z.object({
|
|
13166
|
+
data: import_zod37.z.object({
|
|
13167
|
+
limit: import_zod37.z.number().nonnegative().nullable(),
|
|
13168
|
+
limit_remaining: import_zod37.z.number().nullable(),
|
|
13169
|
+
limit_reset: import_zod37.z.string().nullable(),
|
|
13170
|
+
is_free_tier: import_zod37.z.boolean().optional(),
|
|
13171
|
+
free_model_daily_requests: import_zod37.z.object({ used: import_zod37.z.number().nonnegative(), limit: import_zod37.z.number().nonnegative(), remaining: import_zod37.z.number() }).optional()
|
|
12967
13172
|
})
|
|
12968
13173
|
});
|
|
12969
|
-
OpenRouterCreditsSchema =
|
|
13174
|
+
OpenRouterCreditsSchema = import_zod37.z.object({ data: import_zod37.z.object({ total_credits: import_zod37.z.number().nonnegative(), total_usage: import_zod37.z.number().nonnegative() }) });
|
|
12970
13175
|
ANTIGRAVITY_HOST = "daily-cloudcode-pa.googleapis.com";
|
|
12971
13176
|
ANTIGRAVITY_QUOTA_URL = `https://${ANTIGRAVITY_HOST}/v1internal:retrieveUserQuotaSummary`;
|
|
12972
13177
|
ANTIGRAVITY_USER_URL = `https://${ANTIGRAVITY_HOST}/v1internal:loadCodeAssist`;
|
|
@@ -12974,21 +13179,21 @@ var init_providerQuota = __esm({
|
|
|
12974
13179
|
DAYS_PER_WEEK2 = 7;
|
|
12975
13180
|
FIVE_HOURS_MS = FIVE_HOURS2 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
|
|
12976
13181
|
WEEK_MS = DAYS_PER_WEEK2 * HOURS_PER_DAY6 * SECONDS_PER_HOUR3 * MS_PER_SECOND9;
|
|
12977
|
-
AntigravityBucketSchema =
|
|
12978
|
-
bucketId:
|
|
12979
|
-
remainingFraction:
|
|
12980
|
-
resetTime:
|
|
13182
|
+
AntigravityBucketSchema = import_zod37.z.object({
|
|
13183
|
+
bucketId: import_zod37.z.string(),
|
|
13184
|
+
remainingFraction: import_zod37.z.number().optional(),
|
|
13185
|
+
resetTime: import_zod37.z.string().optional()
|
|
12981
13186
|
});
|
|
12982
|
-
AntigravitySummarySchema =
|
|
12983
|
-
GoogleTokenInfoSchema =
|
|
12984
|
-
email:
|
|
12985
|
-
sub:
|
|
13187
|
+
AntigravitySummarySchema = import_zod37.z.object({ groups: import_zod37.z.array(import_zod37.z.object({ buckets: import_zod37.z.array(AntigravityBucketSchema) })) });
|
|
13188
|
+
GoogleTokenInfoSchema = import_zod37.z.object({
|
|
13189
|
+
email: import_zod37.z.string().optional(),
|
|
13190
|
+
sub: import_zod37.z.string().optional()
|
|
12986
13191
|
});
|
|
12987
|
-
AntigravityUserSchema =
|
|
13192
|
+
AntigravityUserSchema = import_zod37.z.object({
|
|
12988
13193
|
/** The code-assist tier context, which defaults to the free tier for every account. */
|
|
12989
|
-
currentTier:
|
|
13194
|
+
currentTier: import_zod37.z.object({ name: import_zod37.z.string().optional(), id: import_zod37.z.string().optional() }).optional(),
|
|
12990
13195
|
/** The account's paid subscription; absent when the account has none. */
|
|
12991
|
-
paidTier:
|
|
13196
|
+
paidTier: import_zod37.z.object({ name: import_zod37.z.string().optional(), id: import_zod37.z.string().optional() }).optional()
|
|
12992
13197
|
});
|
|
12993
13198
|
}
|
|
12994
13199
|
});
|
|
@@ -13103,6 +13308,7 @@ __export(index_exports, {
|
|
|
13103
13308
|
CodexRateLimitsReadSchema: () => CodexRateLimitsReadSchema,
|
|
13104
13309
|
CodexSignInSchema: () => CodexSignInSchema,
|
|
13105
13310
|
CodexStatusOutputSchema: () => CodexStatusOutputSchema,
|
|
13311
|
+
ConfigIdentityAddInputSchema: () => ConfigIdentityAddInputSchema,
|
|
13106
13312
|
ConfigIdentityAddOutputSchema: () => ConfigIdentityAddOutputSchema,
|
|
13107
13313
|
ConfigIdentityRemoveInputSchema: () => ConfigIdentityRemoveInputSchema,
|
|
13108
13314
|
ConfigIdentityRemoveOutputSchema: () => ConfigIdentityRemoveOutputSchema,
|
|
@@ -13752,8 +13958,8 @@ function pathnameOf(url) {
|
|
|
13752
13958
|
return new URL(url ?? "/", "http://127.0.0.1").pathname;
|
|
13753
13959
|
}
|
|
13754
13960
|
function isRcSessionExchange(url) {
|
|
13755
|
-
const
|
|
13756
|
-
return
|
|
13961
|
+
const path45 = pathnameOf(url);
|
|
13962
|
+
return path45 === RC_SESSIONS_PATH_PREFIX || path45.startsWith(`${RC_SESSIONS_PATH_PREFIX}/`);
|
|
13757
13963
|
}
|
|
13758
13964
|
var RC_SESSION_ID_PREFIX = "cse_";
|
|
13759
13965
|
var RC_IDLE_EXPIRY_MS = 45e3;
|
|
@@ -14312,8 +14518,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
14312
14518
|
function isRcReadFileEncoding(value) {
|
|
14313
14519
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
14314
14520
|
}
|
|
14315
|
-
function buildRcReadFilePayload(requestId,
|
|
14316
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
14521
|
+
function buildRcReadFilePayload(requestId, path45, options) {
|
|
14522
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path45, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
14317
14523
|
}
|
|
14318
14524
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
14319
14525
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -14415,15 +14621,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
14415
14621
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
14416
14622
|
return result.ok ? { ...result, requestId } : result;
|
|
14417
14623
|
}
|
|
14418
|
-
async function readRcSessionFile(deps, sessionId,
|
|
14419
|
-
if (
|
|
14624
|
+
async function readRcSessionFile(deps, sessionId, path45, options) {
|
|
14625
|
+
if (path45 === "") {
|
|
14420
14626
|
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" };
|
|
14421
14627
|
}
|
|
14422
14628
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
14423
14629
|
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" };
|
|
14424
14630
|
}
|
|
14425
14631
|
const requestId = deps.newUuid();
|
|
14426
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
14632
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path45, options), `read ${path45} from session ${sessionId}`);
|
|
14427
14633
|
return result.ok ? { ...result, requestId } : result;
|
|
14428
14634
|
}
|
|
14429
14635
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -14592,11 +14798,11 @@ function createRcControlHandler(deps) {
|
|
|
14592
14798
|
path: "read-file",
|
|
14593
14799
|
read: (body) => {
|
|
14594
14800
|
const session = bodyString(body, "session");
|
|
14595
|
-
const
|
|
14801
|
+
const path45 = bodyString(body, "path");
|
|
14596
14802
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
14597
14803
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
14598
|
-
const refused2 = session === void 0 ||
|
|
14599
|
-
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,
|
|
14804
|
+
const refused2 = session === void 0 || path45 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
14805
|
+
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 } }) };
|
|
14600
14806
|
}
|
|
14601
14807
|
},
|
|
14602
14808
|
{
|
|
@@ -14906,9 +15112,9 @@ function requestIdOfBody(body) {
|
|
|
14906
15112
|
}
|
|
14907
15113
|
function frontDoorRcControl(transport, token) {
|
|
14908
15114
|
const headers = { authorization: `Bearer ${token}` };
|
|
14909
|
-
const listAnswerOf = async (
|
|
15115
|
+
const listAnswerOf = async (path45, what) => {
|
|
14910
15116
|
try {
|
|
14911
|
-
return await transport.request({ method: "GET", path:
|
|
15117
|
+
return await transport.request({ method: "GET", path: path45, headers });
|
|
14912
15118
|
} catch (error) {
|
|
14913
15119
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
14914
15120
|
}
|
|
@@ -14980,10 +15186,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
14980
15186
|
}
|
|
14981
15187
|
return pending;
|
|
14982
15188
|
};
|
|
14983
|
-
const writeOf = async (
|
|
15189
|
+
const writeOf = async (path45, body, describeFailure2) => {
|
|
14984
15190
|
let answer;
|
|
14985
15191
|
try {
|
|
14986
|
-
answer = await transport.request({ method: "POST", path:
|
|
15192
|
+
answer = await transport.request({ method: "POST", path: path45, headers: { ...headers, "content-type": "application/json" }, body });
|
|
14987
15193
|
} catch (error) {
|
|
14988
15194
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
14989
15195
|
}
|
|
@@ -15014,10 +15220,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
15014
15220
|
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}`),
|
|
15015
15221
|
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}`),
|
|
15016
15222
|
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}`),
|
|
15017
|
-
readFile: async (sessionId,
|
|
15223
|
+
readFile: async (sessionId, path45, options) => await writeOf(
|
|
15018
15224
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
15019
|
-
JSON.stringify({ session: sessionId, path:
|
|
15020
|
-
(status, message) => `reading ${
|
|
15225
|
+
JSON.stringify({ session: sessionId, path: path45, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
15226
|
+
(status, message) => `reading ${path45} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
15021
15227
|
),
|
|
15022
15228
|
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}`),
|
|
15023
15229
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -15176,12 +15382,12 @@ function tlsFacts(options) {
|
|
|
15176
15382
|
}
|
|
15177
15383
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
15178
15384
|
const agent = new ExemptTlsAgent();
|
|
15179
|
-
const post = async (
|
|
15385
|
+
const post = async (path45, headers, body) => await new Promise((resolve, reject) => {
|
|
15180
15386
|
const options = {
|
|
15181
15387
|
host: target.host,
|
|
15182
15388
|
port: target.port,
|
|
15183
15389
|
method: "POST",
|
|
15184
|
-
path:
|
|
15390
|
+
path: path45,
|
|
15185
15391
|
// 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.
|
|
15186
15392
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
15187
15393
|
agent
|
|
@@ -15246,12 +15452,12 @@ function lateRcStreamDial(resolve) {
|
|
|
15246
15452
|
}
|
|
15247
15453
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
15248
15454
|
const agent = new ExemptTlsAgent();
|
|
15249
|
-
const request4 = async (method,
|
|
15455
|
+
const request4 = async (method, path45, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
15250
15456
|
const options = {
|
|
15251
15457
|
host: target.host,
|
|
15252
15458
|
port: target.port,
|
|
15253
15459
|
method,
|
|
15254
|
-
path:
|
|
15460
|
+
path: path45,
|
|
15255
15461
|
// 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.
|
|
15256
15462
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
15257
15463
|
agent,
|
|
@@ -15293,9 +15499,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
15293
15499
|
return { status, body: await readAll(response) };
|
|
15294
15500
|
},
|
|
15295
15501
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
15296
|
-
const
|
|
15502
|
+
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)}`;
|
|
15297
15503
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
15298
|
-
const { status, response } = await request4("GET",
|
|
15504
|
+
const { status, response } = await request4("GET", path45, streamHeaders, void 0, signal);
|
|
15299
15505
|
if (!isSuccessful2(status)) {
|
|
15300
15506
|
await readAll(response);
|
|
15301
15507
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -15545,11 +15751,11 @@ function credentialOfJson(parsed) {
|
|
|
15545
15751
|
function sequenceNumOfJson(value) {
|
|
15546
15752
|
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
15547
15753
|
}
|
|
15548
|
-
function createRcCredentialStore(
|
|
15549
|
-
|
|
15754
|
+
function createRcCredentialStore(fs15, dir) {
|
|
15755
|
+
fs15.mkdirPrivate(dir);
|
|
15550
15756
|
const fileFor = (sessionId) => import_node_path11.default.join(dir, `${sessionId}.json`);
|
|
15551
15757
|
const readParsed = (sessionId) => {
|
|
15552
|
-
const raw =
|
|
15758
|
+
const raw = fs15.readFileUtf8(fileFor(sessionId));
|
|
15553
15759
|
if (raw === void 0) {
|
|
15554
15760
|
return void 0;
|
|
15555
15761
|
}
|
|
@@ -15574,7 +15780,7 @@ function createRcCredentialStore(fs14, dir) {
|
|
|
15574
15780
|
}
|
|
15575
15781
|
const cursor = sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
|
|
15576
15782
|
const record = { ...credential, ...cursor === void 0 ? {} : { highestSequenceNum: cursor } };
|
|
15577
|
-
|
|
15783
|
+
fs15.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
|
|
15578
15784
|
`);
|
|
15579
15785
|
},
|
|
15580
15786
|
readCursor: (sessionId) => {
|
|
@@ -15589,14 +15795,14 @@ function createRcCredentialStore(fs14, dir) {
|
|
|
15589
15795
|
}
|
|
15590
15796
|
const credential = credentialOfJson(readParsed(sessionId));
|
|
15591
15797
|
const record = credential === void 0 ? { highestSequenceNum } : { ...credential, highestSequenceNum };
|
|
15592
|
-
|
|
15798
|
+
fs15.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
|
|
15593
15799
|
`);
|
|
15594
15800
|
},
|
|
15595
15801
|
remove: (sessionId) => {
|
|
15596
15802
|
if (!isSafeSessionId(sessionId)) {
|
|
15597
15803
|
return;
|
|
15598
15804
|
}
|
|
15599
|
-
|
|
15805
|
+
fs15.removeRecursive(fileFor(sessionId));
|
|
15600
15806
|
}
|
|
15601
15807
|
};
|
|
15602
15808
|
}
|
|
@@ -16288,19 +16494,19 @@ function writePools(paths, pools) {
|
|
|
16288
16494
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
16289
16495
|
}
|
|
16290
16496
|
function poolCycleOf(pools, name) {
|
|
16291
|
-
const walk2 = (current,
|
|
16497
|
+
const walk2 = (current, path45) => {
|
|
16292
16498
|
for (const entry of pools[current]?.identities ?? []) {
|
|
16293
16499
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
16294
16500
|
if (nested === void 0) {
|
|
16295
16501
|
continue;
|
|
16296
16502
|
}
|
|
16297
16503
|
if (nested === name) {
|
|
16298
|
-
return [...
|
|
16504
|
+
return [...path45, nested];
|
|
16299
16505
|
}
|
|
16300
|
-
if (
|
|
16506
|
+
if (path45.includes(nested)) {
|
|
16301
16507
|
continue;
|
|
16302
16508
|
}
|
|
16303
|
-
const found = walk2(nested, [...
|
|
16509
|
+
const found = walk2(nested, [...path45, nested]);
|
|
16304
16510
|
if (found !== void 0) {
|
|
16305
16511
|
return found;
|
|
16306
16512
|
}
|
|
@@ -16740,7 +16946,7 @@ function loadCheckProvider(paths, name) {
|
|
|
16740
16946
|
try {
|
|
16741
16947
|
definition = readProvider(paths, name);
|
|
16742
16948
|
} catch (error) {
|
|
16743
|
-
if (error instanceof ConfigValidationError || error instanceof LegacyProviderFileError) {
|
|
16949
|
+
if (error instanceof ConfigValidationError || error instanceof LegacyProviderFileError || error instanceof ConfigFileNotJsonError) {
|
|
16744
16950
|
return { name, problem: error.message };
|
|
16745
16951
|
}
|
|
16746
16952
|
throw error;
|
|
@@ -17012,8 +17218,8 @@ var ResetRowSchema = import_zod22.z.strictObject({
|
|
|
17012
17218
|
var ResetScheduleSchema = import_zod22.z.strictObject({ resets: import_zod22.z.readonly(import_zod22.z.array(ResetRowSchema)) });
|
|
17013
17219
|
|
|
17014
17220
|
// src/frontdoor/controlSchemas.ts
|
|
17015
|
-
var
|
|
17016
|
-
var
|
|
17221
|
+
var import_node_path32 = __toESM(require("node:path"), 1);
|
|
17222
|
+
var import_zod30 = require("zod");
|
|
17017
17223
|
|
|
17018
17224
|
// src/doctorReport.ts
|
|
17019
17225
|
init_claudeShim();
|
|
@@ -17021,14 +17227,212 @@ init_names();
|
|
|
17021
17227
|
init_store();
|
|
17022
17228
|
|
|
17023
17229
|
// src/identityStore.ts
|
|
17024
|
-
var
|
|
17025
|
-
var
|
|
17230
|
+
var import_node_fs9 = __toESM(require("node:fs"), 1);
|
|
17231
|
+
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
17026
17232
|
init_load();
|
|
17233
|
+
init_names();
|
|
17027
17234
|
init_store();
|
|
17028
17235
|
init_schema();
|
|
17029
17236
|
init_cliError();
|
|
17030
17237
|
init_identity();
|
|
17031
17238
|
init_lock();
|
|
17239
|
+
|
|
17240
|
+
// src/identityRenameJournal.ts
|
|
17241
|
+
var import_node_path28 = __toESM(require("node:path"), 1);
|
|
17242
|
+
var import_zod24 = require("zod");
|
|
17243
|
+
init_cliError();
|
|
17244
|
+
var RenameJournalSchema = import_zod24.z.strictObject({
|
|
17245
|
+
version: import_zod24.z.literal(1),
|
|
17246
|
+
from: import_zod24.z.string().min(1),
|
|
17247
|
+
to: import_zod24.z.string().min(1),
|
|
17248
|
+
startedAt: import_zod24.z.iso.datetime(),
|
|
17249
|
+
/** 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. */
|
|
17250
|
+
pid: import_zod24.z.number().int().positive(),
|
|
17251
|
+
steps: import_zod24.z.array(
|
|
17252
|
+
import_zod24.z.strictObject({
|
|
17253
|
+
description: import_zod24.z.string().min(1),
|
|
17254
|
+
/** Whether the step has been applied and marked so. */
|
|
17255
|
+
done: import_zod24.z.boolean(),
|
|
17256
|
+
/** 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. */
|
|
17257
|
+
started: import_zod24.z.boolean()
|
|
17258
|
+
})
|
|
17259
|
+
)
|
|
17260
|
+
});
|
|
17261
|
+
var JOURNAL_SUFFIX = ".json";
|
|
17262
|
+
var RenameJournalUnreadableError = class extends CliError {
|
|
17263
|
+
constructor(file, detail) {
|
|
17264
|
+
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.`);
|
|
17265
|
+
this.detail = detail;
|
|
17266
|
+
this.name = "RenameJournalUnreadableError";
|
|
17267
|
+
}
|
|
17268
|
+
detail;
|
|
17269
|
+
};
|
|
17270
|
+
function readRenameJournal(fs15, file) {
|
|
17271
|
+
const raw = fs15.readFileUtf8(file);
|
|
17272
|
+
if (raw === void 0) {
|
|
17273
|
+
return void 0;
|
|
17274
|
+
}
|
|
17275
|
+
let parsed;
|
|
17276
|
+
try {
|
|
17277
|
+
parsed = JSON.parse(raw);
|
|
17278
|
+
} catch {
|
|
17279
|
+
throw new RenameJournalUnreadableError(file, "not valid JSON");
|
|
17280
|
+
}
|
|
17281
|
+
const result = RenameJournalSchema.safeParse(parsed);
|
|
17282
|
+
if (!result.success) {
|
|
17283
|
+
throw new RenameJournalUnreadableError(file, result.error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; "));
|
|
17284
|
+
}
|
|
17285
|
+
return result.data;
|
|
17286
|
+
}
|
|
17287
|
+
function listRenameJournals(fs15, directory) {
|
|
17288
|
+
const journals = [];
|
|
17289
|
+
const unreadable = [];
|
|
17290
|
+
for (const name of [...fs15.readdir(directory)].sort()) {
|
|
17291
|
+
if (!name.endsWith(JOURNAL_SUFFIX)) {
|
|
17292
|
+
continue;
|
|
17293
|
+
}
|
|
17294
|
+
const file = import_node_path28.default.join(directory, name);
|
|
17295
|
+
try {
|
|
17296
|
+
const journal = readRenameJournal(fs15, file);
|
|
17297
|
+
if (journal !== void 0) {
|
|
17298
|
+
journals.push(journal);
|
|
17299
|
+
}
|
|
17300
|
+
} catch (error) {
|
|
17301
|
+
if (!(error instanceof RenameJournalUnreadableError)) {
|
|
17302
|
+
throw error;
|
|
17303
|
+
}
|
|
17304
|
+
unreadable.push({ file, detail: error.detail });
|
|
17305
|
+
}
|
|
17306
|
+
}
|
|
17307
|
+
return { journals, unreadable };
|
|
17308
|
+
}
|
|
17309
|
+
function stepMayBeApplied(step) {
|
|
17310
|
+
return step.done || step.started;
|
|
17311
|
+
}
|
|
17312
|
+
function recordsNothingApplied(journal) {
|
|
17313
|
+
return !journal.steps.some(stepMayBeApplied);
|
|
17314
|
+
}
|
|
17315
|
+
function describeUnfinishable(bothExist) {
|
|
17316
|
+
return bothExist ? "both names are identities" : "there is no identity under either name";
|
|
17317
|
+
}
|
|
17318
|
+
function finishabilityOf(journal, exists) {
|
|
17319
|
+
const underFrom = exists(journal.from);
|
|
17320
|
+
if (underFrom === exists(journal.to)) {
|
|
17321
|
+
return { finishable: false, reason: describeUnfinishable(underFrom) };
|
|
17322
|
+
}
|
|
17323
|
+
return underFrom && recordsNothingApplied(journal) ? { finishable: true, discardable: true } : { finishable: true };
|
|
17324
|
+
}
|
|
17325
|
+
function discardJournalCommand(journal) {
|
|
17326
|
+
return `agent-shim identity rename ${journal.from} ${journal.to} --discard-journal`;
|
|
17327
|
+
}
|
|
17328
|
+
function describeUnfinishedRename(journal, finishability) {
|
|
17329
|
+
const applied = journal.steps.filter(stepMayBeApplied).length;
|
|
17330
|
+
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)`;
|
|
17331
|
+
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.`;
|
|
17332
|
+
}
|
|
17333
|
+
var NameHeldByUnfinishedRenameError = class extends CliError {
|
|
17334
|
+
constructor(action, name, journal, finishability) {
|
|
17335
|
+
super(`Cannot ${action} identity "${name}": there is ${describeUnfinishedRename(journal, finishability)}`);
|
|
17336
|
+
this.name = "NameHeldByUnfinishedRenameError";
|
|
17337
|
+
}
|
|
17338
|
+
};
|
|
17339
|
+
function requireNameFreeOfUnfinishedRename(fs15, directory, name, action, sameName, exists) {
|
|
17340
|
+
const held = listRenameJournals(fs15, directory).journals.find((journal) => [journal.from, journal.to].some((heldName) => heldName === name || sameName(name, heldName)));
|
|
17341
|
+
if (held !== void 0) {
|
|
17342
|
+
throw new NameHeldByUnfinishedRenameError(action, name, held, finishabilityOf(held, exists));
|
|
17343
|
+
}
|
|
17344
|
+
}
|
|
17345
|
+
|
|
17346
|
+
// src/keychainLogin.ts
|
|
17347
|
+
init_cliError();
|
|
17348
|
+
init_signIn();
|
|
17349
|
+
var ITEM_NOT_FOUND_STATUS = 44;
|
|
17350
|
+
var MAX_DETAIL_CHARS = 200;
|
|
17351
|
+
var CONTROL_CHARACTER = new RegExp("\\p{Cc}", "u");
|
|
17352
|
+
var KeychainLoginError = class extends CliError {
|
|
17353
|
+
constructor(message) {
|
|
17354
|
+
super(message);
|
|
17355
|
+
this.name = "KeychainLoginError";
|
|
17356
|
+
}
|
|
17357
|
+
};
|
|
17358
|
+
var KeychainLookupError = class extends KeychainLoginError {
|
|
17359
|
+
constructor(message) {
|
|
17360
|
+
super(message);
|
|
17361
|
+
this.name = "KeychainLookupError";
|
|
17362
|
+
}
|
|
17363
|
+
};
|
|
17364
|
+
function statusPhrase(status) {
|
|
17365
|
+
return status === null ? "without a status" : String(status);
|
|
17366
|
+
}
|
|
17367
|
+
function describe(stderr) {
|
|
17368
|
+
const [first] = stderr.trim().split("\n");
|
|
17369
|
+
return first === void 0 || first === "" ? "" : ` (${first.slice(0, MAX_DETAIL_CHARS)})`;
|
|
17370
|
+
}
|
|
17371
|
+
function lookup(run, service) {
|
|
17372
|
+
const result = run.run("security", ["find-generic-password", "-s", service]);
|
|
17373
|
+
if (result.status === 0) {
|
|
17374
|
+
return { found: true, attributes: result.stdout };
|
|
17375
|
+
}
|
|
17376
|
+
if (result.status === ITEM_NOT_FOUND_STATUS) {
|
|
17377
|
+
return { found: false };
|
|
17378
|
+
}
|
|
17379
|
+
throw new KeychainLookupError(`Could not look up the Keychain item ${service}: security exited ${statusPhrase(result.status)}${describe(result.stderr)}.`);
|
|
17380
|
+
}
|
|
17381
|
+
function plainAccountOf(attributes) {
|
|
17382
|
+
const line = attributes.split("\n").find((candidate) => candidate.includes('"acct"<blob>='));
|
|
17383
|
+
const value = line?.slice(line.indexOf("=") + 1).trim();
|
|
17384
|
+
const name = value === void 0 ? void 0 : /^"([^"\\]*)"$/u.exec(value)?.[1];
|
|
17385
|
+
return name === void 0 || name === "" || CONTROL_CHARACTER.test(name) ? void 0 : name;
|
|
17386
|
+
}
|
|
17387
|
+
function keychainDeleteCommand(service, account) {
|
|
17388
|
+
return `security delete-generic-password -s ${shellQuoted(service)}${account === void 0 ? "" : ` -a ${shellQuoted(account)}`}`;
|
|
17389
|
+
}
|
|
17390
|
+
function shellQuoted(value) {
|
|
17391
|
+
return `'${value.replace(/'/gu, "'\\''")}'`;
|
|
17392
|
+
}
|
|
17393
|
+
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.";
|
|
17394
|
+
function requireNoLeftoverKeychainLogin(keychain, configDir, name, keepLogin) {
|
|
17395
|
+
if (keepLogin || keychain.platform !== "darwin") {
|
|
17396
|
+
return;
|
|
17397
|
+
}
|
|
17398
|
+
const service = claudeCodeKeychainService(configDir);
|
|
17399
|
+
const found = lookup(keychain.run, service);
|
|
17400
|
+
if (!found.found) {
|
|
17401
|
+
return;
|
|
17402
|
+
}
|
|
17403
|
+
const account = plainAccountOf(found.attributes);
|
|
17404
|
+
throw new KeychainLoginError(
|
|
17405
|
+
`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.`
|
|
17406
|
+
);
|
|
17407
|
+
}
|
|
17408
|
+
|
|
17409
|
+
// src/sameDirectory.ts
|
|
17410
|
+
var import_node_fs8 = __toESM(require("node:fs"), 1);
|
|
17411
|
+
var import_node_path29 = __toESM(require("node:path"), 1);
|
|
17412
|
+
function sameDirectory(first, second) {
|
|
17413
|
+
const a = import_node_fs8.default.statSync(first, { throwIfNoEntry: false });
|
|
17414
|
+
const b = import_node_fs8.default.statSync(second, { throwIfNoEntry: false });
|
|
17415
|
+
if (a === void 0 || b === void 0) {
|
|
17416
|
+
return false;
|
|
17417
|
+
}
|
|
17418
|
+
return a.dev === b.dev && a.ino === b.ino;
|
|
17419
|
+
}
|
|
17420
|
+
function caseSwapped(name) {
|
|
17421
|
+
return name.replace(/[A-Za-z]/gu, (letter) => letter === letter.toLowerCase() ? letter.toUpperCase() : letter.toLowerCase());
|
|
17422
|
+
}
|
|
17423
|
+
function ignoresCase(directory) {
|
|
17424
|
+
if (!import_node_fs8.default.existsSync(directory)) {
|
|
17425
|
+
return false;
|
|
17426
|
+
}
|
|
17427
|
+
const probe = import_node_fs8.default.mkdtempSync(import_node_path29.default.join(directory, ".case-probe-"));
|
|
17428
|
+
try {
|
|
17429
|
+
return sameDirectory(probe, import_node_path29.default.join(directory, caseSwapped(import_node_path29.default.basename(probe))));
|
|
17430
|
+
} finally {
|
|
17431
|
+
import_node_fs8.default.rmSync(probe, { recursive: true, force: true });
|
|
17432
|
+
}
|
|
17433
|
+
}
|
|
17434
|
+
|
|
17435
|
+
// src/identityStore.ts
|
|
17032
17436
|
var IdentityNotFoundError = class extends CliError {
|
|
17033
17437
|
constructor(name) {
|
|
17034
17438
|
super(`No identity named "${name}". Run \`agent-shim identity add ${name}\` first.`);
|
|
@@ -17056,7 +17460,7 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
17056
17460
|
attemptedName;
|
|
17057
17461
|
};
|
|
17058
17462
|
function identityJsonPath(paths, name) {
|
|
17059
|
-
return
|
|
17463
|
+
return import_node_path30.default.join(paths.identitiesDir, name, "identity.json");
|
|
17060
17464
|
}
|
|
17061
17465
|
function requireIdentityNames(paths, names) {
|
|
17062
17466
|
const existing = new Set(listIdentities(paths).map((entry) => entry.name));
|
|
@@ -17067,21 +17471,23 @@ function requireIdentityNames(paths, names) {
|
|
|
17067
17471
|
}
|
|
17068
17472
|
}
|
|
17069
17473
|
function identityExists(paths, name) {
|
|
17070
|
-
return
|
|
17474
|
+
return import_node_fs9.default.existsSync(identityJsonPath(paths, name));
|
|
17071
17475
|
}
|
|
17072
17476
|
function readIdentity(paths, name) {
|
|
17073
17477
|
return readJson(identityJsonPath(paths, name), IdentitySchema);
|
|
17074
17478
|
}
|
|
17075
|
-
function
|
|
17479
|
+
function requireIdentityCreatable(paths, name) {
|
|
17480
|
+
requireNoUnfinishedRenameNaming(paths, name, "add");
|
|
17076
17481
|
if (identityExists(paths, name)) {
|
|
17077
17482
|
throw new IdentityAlreadyExistsError(name);
|
|
17078
17483
|
}
|
|
17079
|
-
|
|
17080
|
-
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
|
|
17084
|
-
|
|
17484
|
+
requireNewIdentityName(name);
|
|
17485
|
+
}
|
|
17486
|
+
function addIdentity(paths, name) {
|
|
17487
|
+
requireIdentityCreatable(paths, name);
|
|
17488
|
+
const identity = IdentitySchema.parse({ name, allowAmbientCredential: false });
|
|
17489
|
+
writeJsonAtomic(identityJsonPath(paths, name), identity);
|
|
17490
|
+
return identity;
|
|
17085
17491
|
}
|
|
17086
17492
|
function useIdentity(paths, name) {
|
|
17087
17493
|
const pool = poolNameOf(name);
|
|
@@ -17094,33 +17500,89 @@ function useIdentity(paths, name) {
|
|
|
17094
17500
|
`);
|
|
17095
17501
|
}
|
|
17096
17502
|
function readActiveIdentity2(paths) {
|
|
17097
|
-
if (!
|
|
17503
|
+
if (!import_node_fs9.default.existsSync(paths.activeIdentityFile)) {
|
|
17098
17504
|
return void 0;
|
|
17099
17505
|
}
|
|
17100
|
-
const raw =
|
|
17506
|
+
const raw = import_node_fs9.default.readFileSync(paths.activeIdentityFile, "utf8").trim();
|
|
17101
17507
|
return raw === "" ? void 0 : raw;
|
|
17102
17508
|
}
|
|
17103
17509
|
function isIdentityDirectoryName(name) {
|
|
17104
17510
|
return !name.startsWith(".");
|
|
17105
17511
|
}
|
|
17512
|
+
var UNREACHABLE_CODES = /* @__PURE__ */ new Set(["ELOOP", "EACCES", "ENOTDIR"]);
|
|
17513
|
+
function systemErrorCode(error) {
|
|
17514
|
+
return typeof error === "object" && error !== null && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
17515
|
+
}
|
|
17516
|
+
function unreachableCodeOf(error) {
|
|
17517
|
+
const code = systemErrorCode(error);
|
|
17518
|
+
if (code === "ENOENT") {
|
|
17519
|
+
return void 0;
|
|
17520
|
+
}
|
|
17521
|
+
if (code !== void 0 && UNREACHABLE_CODES.has(code)) {
|
|
17522
|
+
return code;
|
|
17523
|
+
}
|
|
17524
|
+
throw error;
|
|
17525
|
+
}
|
|
17526
|
+
function followedLink(link) {
|
|
17527
|
+
try {
|
|
17528
|
+
return import_node_fs9.default.statSync(link).isDirectory() ? "directory" : "other";
|
|
17529
|
+
} catch (error) {
|
|
17530
|
+
const code = unreachableCodeOf(error);
|
|
17531
|
+
return code === void 0 ? "other" : { code };
|
|
17532
|
+
}
|
|
17533
|
+
}
|
|
17534
|
+
function entryRefusal(directory) {
|
|
17535
|
+
try {
|
|
17536
|
+
import_node_fs9.default.accessSync(directory, import_node_fs9.default.constants.X_OK);
|
|
17537
|
+
return void 0;
|
|
17538
|
+
} catch (error) {
|
|
17539
|
+
return unreachableCodeOf(error);
|
|
17540
|
+
}
|
|
17541
|
+
}
|
|
17542
|
+
function listIdentityDirectories(paths) {
|
|
17543
|
+
const names = [];
|
|
17544
|
+
const unreachable = [];
|
|
17545
|
+
if (import_node_fs9.default.existsSync(paths.identitiesDir)) {
|
|
17546
|
+
for (const entry of import_node_fs9.default.readdirSync(paths.identitiesDir, { withFileTypes: true })) {
|
|
17547
|
+
if (!isIdentityDirectoryName(entry.name)) {
|
|
17548
|
+
continue;
|
|
17549
|
+
}
|
|
17550
|
+
const entryPath = import_node_path30.default.join(paths.identitiesDir, entry.name);
|
|
17551
|
+
const followed = entry.isDirectory() ? "directory" : entry.isSymbolicLink() ? followedLink(entryPath) : "other";
|
|
17552
|
+
if (followed === "other") {
|
|
17553
|
+
continue;
|
|
17554
|
+
}
|
|
17555
|
+
const code = followed === "directory" ? entryRefusal(entryPath) : followed.code;
|
|
17556
|
+
if (code === void 0) {
|
|
17557
|
+
names.push(entry.name);
|
|
17558
|
+
} else {
|
|
17559
|
+
unreachable.push({ name: entry.name, code });
|
|
17560
|
+
}
|
|
17561
|
+
}
|
|
17562
|
+
}
|
|
17563
|
+
return { names: names.sort(), unreachable: unreachable.sort((a, b) => a.name.localeCompare(b.name)) };
|
|
17564
|
+
}
|
|
17565
|
+
var NOT_JSON_PROBLEM = "is not valid JSON";
|
|
17106
17566
|
function readIdentityForListing(paths, name) {
|
|
17107
17567
|
try {
|
|
17108
17568
|
return readIdentity(paths, name);
|
|
17109
17569
|
} catch (error) {
|
|
17110
|
-
if (error instanceof
|
|
17570
|
+
if (error instanceof ConfigFileNotJsonError) {
|
|
17571
|
+
return { problem: NOT_JSON_PROBLEM };
|
|
17572
|
+
}
|
|
17573
|
+
if (error instanceof ConfigValidationError) {
|
|
17111
17574
|
return { problem: error.message.replace(/\s*\n\s*/g, " ") };
|
|
17112
17575
|
}
|
|
17113
17576
|
throw error;
|
|
17114
17577
|
}
|
|
17115
17578
|
}
|
|
17116
17579
|
function listIdentities(paths) {
|
|
17117
|
-
if (!
|
|
17580
|
+
if (!import_node_fs9.default.existsSync(paths.identitiesDir)) {
|
|
17118
17581
|
return [];
|
|
17119
17582
|
}
|
|
17120
17583
|
const active = readActiveIdentity2(paths);
|
|
17121
|
-
const names = import_node_fs8.default.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort();
|
|
17122
17584
|
const result = [];
|
|
17123
|
-
for (const name of names) {
|
|
17585
|
+
for (const name of listIdentityDirectories(paths).names) {
|
|
17124
17586
|
const read = readIdentityForListing(paths, name);
|
|
17125
17587
|
if (read === void 0) {
|
|
17126
17588
|
continue;
|
|
@@ -17130,6 +17592,10 @@ function listIdentities(paths) {
|
|
|
17130
17592
|
}
|
|
17131
17593
|
return result;
|
|
17132
17594
|
}
|
|
17595
|
+
function requireIdentityAddable(paths, name, keychain, keepKeychainLogin) {
|
|
17596
|
+
requireIdentityCreatable(paths, name);
|
|
17597
|
+
requireNoLeftoverKeychainLogin(keychain, import_node_path30.default.join(paths.identitiesDir, name), name, keepKeychainLogin);
|
|
17598
|
+
}
|
|
17133
17599
|
function setIdentityAnchors(paths, identityName, anchors) {
|
|
17134
17600
|
if (!identityExists(paths, identityName)) {
|
|
17135
17601
|
throw new IdentityNotFoundError(identityName);
|
|
@@ -17182,49 +17648,70 @@ function setIdentityCredential(paths, identityName, change) {
|
|
|
17182
17648
|
credential: { sources: [...sources], ...target === void 0 ? {} : { target }, ...cache === void 0 ? {} : { cache } }
|
|
17183
17649
|
});
|
|
17184
17650
|
}
|
|
17651
|
+
var UUID_PATTERN = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
|
17652
|
+
var FARM_SUFFIX_PATTERN = `\\.(?:scratch|previous)\\.\\d+\\.${UUID_PATTERN}`;
|
|
17653
|
+
function escapedForPattern(text) {
|
|
17654
|
+
return text.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
17655
|
+
}
|
|
17656
|
+
function isFarmEntry(entry, name) {
|
|
17657
|
+
return entry === name || new RegExp(`^\\.${escapedForPattern(name)}${FARM_SUFFIX_PATTERN}$`, "u").test(entry);
|
|
17658
|
+
}
|
|
17185
17659
|
function belongsToIdentity(entry, name) {
|
|
17186
|
-
return entry
|
|
17660
|
+
return isFarmEntry(entry, name) || entry === import_node_path30.default.basename(identityLockPath("", name));
|
|
17661
|
+
}
|
|
17662
|
+
function requireNewIdentityName(name) {
|
|
17663
|
+
if (!FileNameSchema.safeParse(name).success) {
|
|
17664
|
+
throw new InvalidIdentityNameError(name);
|
|
17665
|
+
}
|
|
17666
|
+
}
|
|
17667
|
+
function sameIdentityName(paths, first, second) {
|
|
17668
|
+
return sameDirectory(import_node_path30.default.join(paths.identitiesDir, first), import_node_path30.default.join(paths.identitiesDir, second)) || first.toLowerCase() === second.toLowerCase() && ignoresCase(paths.identitiesDir);
|
|
17669
|
+
}
|
|
17670
|
+
function requireNoUnfinishedRenameNaming(paths, name, action) {
|
|
17671
|
+
requireNameFreeOfUnfinishedRename({ readFileUtf8: nodeStoreFs.readFileUtf8, readdir: (directory) => import_node_fs9.default.existsSync(directory) ? import_node_fs9.default.readdirSync(directory) : [] }, paths.identityRenamesDir, name, action, (first, second) => sameIdentityName(paths, first, second), (identity) => identityExists(paths, identity));
|
|
17187
17672
|
}
|
|
17188
17673
|
function removeIdentity(paths, name) {
|
|
17674
|
+
requireNoUnfinishedRenameNaming(paths, name, "remove");
|
|
17189
17675
|
if (!identityExists(paths, name)) {
|
|
17190
17676
|
throw new IdentityNotFoundError(name);
|
|
17191
17677
|
}
|
|
17192
|
-
for (const entry of
|
|
17678
|
+
for (const entry of import_node_fs9.default.readdirSync(paths.identitiesDir)) {
|
|
17193
17679
|
if (belongsToIdentity(entry, name)) {
|
|
17194
|
-
|
|
17680
|
+
import_node_fs9.default.rmSync(import_node_path30.default.join(paths.identitiesDir, entry), { recursive: true, force: true });
|
|
17195
17681
|
}
|
|
17196
17682
|
}
|
|
17197
17683
|
if (readActiveIdentity2(paths) === name) {
|
|
17198
|
-
|
|
17684
|
+
import_node_fs9.default.rmSync(paths.activeIdentityFile);
|
|
17199
17685
|
}
|
|
17200
17686
|
}
|
|
17201
17687
|
|
|
17202
17688
|
// src/doctorReport.ts
|
|
17203
17689
|
init_realPorts();
|
|
17204
|
-
var
|
|
17205
|
-
var
|
|
17690
|
+
var import_node_fs11 = __toESM(require("node:fs"), 1);
|
|
17691
|
+
var import_node_path31 = __toESM(require("node:path"), 1);
|
|
17206
17692
|
init_signIn();
|
|
17207
17693
|
init_identityAccounts();
|
|
17694
|
+
init_read();
|
|
17208
17695
|
|
|
17209
17696
|
// src/codex/siwcStore.ts
|
|
17210
|
-
var
|
|
17697
|
+
var import_zod27 = require("zod");
|
|
17211
17698
|
|
|
17212
17699
|
// src/codex/auth.ts
|
|
17213
|
-
var
|
|
17214
|
-
var AuthFileSchema =
|
|
17215
|
-
tokens:
|
|
17216
|
-
access_token:
|
|
17217
|
-
refresh_token:
|
|
17218
|
-
id_token:
|
|
17219
|
-
account_id:
|
|
17700
|
+
var import_zod25 = require("zod");
|
|
17701
|
+
var AuthFileSchema = import_zod25.z.looseObject({
|
|
17702
|
+
tokens: import_zod25.z.looseObject({
|
|
17703
|
+
access_token: import_zod25.z.string().optional(),
|
|
17704
|
+
refresh_token: import_zod25.z.string().optional(),
|
|
17705
|
+
id_token: import_zod25.z.string().optional(),
|
|
17706
|
+
account_id: import_zod25.z.string().optional()
|
|
17220
17707
|
}).nullish(),
|
|
17221
|
-
last_refresh:
|
|
17708
|
+
last_refresh: import_zod25.z.string().optional()
|
|
17222
17709
|
});
|
|
17223
|
-
var TokenGrantSchema =
|
|
17224
|
-
access_token:
|
|
17225
|
-
refresh_token:
|
|
17226
|
-
id_token:
|
|
17227
|
-
account_id:
|
|
17710
|
+
var TokenGrantSchema = import_zod25.z.looseObject({
|
|
17711
|
+
access_token: import_zod25.z.string().min(1).optional(),
|
|
17712
|
+
refresh_token: import_zod25.z.string().min(1).optional(),
|
|
17713
|
+
id_token: import_zod25.z.string().min(1).optional(),
|
|
17714
|
+
account_id: import_zod25.z.string().min(1).optional()
|
|
17228
17715
|
});
|
|
17229
17716
|
var CodexAuthError = class extends Error {
|
|
17230
17717
|
constructor(message) {
|
|
@@ -17234,41 +17721,41 @@ var CodexAuthError = class extends Error {
|
|
|
17234
17721
|
};
|
|
17235
17722
|
|
|
17236
17723
|
// src/codex/siwc.ts
|
|
17237
|
-
var
|
|
17724
|
+
var import_zod26 = require("zod");
|
|
17238
17725
|
var SIWC_RESOURCE = "https://api.openai.com/v1";
|
|
17239
17726
|
var SIWC_RESPONSES_URL = `${SIWC_RESOURCE}/responses`;
|
|
17240
17727
|
var SIWC_PLAN_SCOPE = "chatgpt.tokens.use.direct";
|
|
17241
|
-
var TokenResponseSchema =
|
|
17242
|
-
access_token:
|
|
17243
|
-
refresh_token:
|
|
17244
|
-
id_token:
|
|
17245
|
-
expires_in:
|
|
17246
|
-
scope:
|
|
17728
|
+
var TokenResponseSchema = import_zod26.z.looseObject({
|
|
17729
|
+
access_token: import_zod26.z.string().min(1),
|
|
17730
|
+
refresh_token: import_zod26.z.string().min(1).optional(),
|
|
17731
|
+
id_token: import_zod26.z.string().min(1).optional(),
|
|
17732
|
+
expires_in: import_zod26.z.number().positive(),
|
|
17733
|
+
scope: import_zod26.z.string().optional()
|
|
17247
17734
|
});
|
|
17248
|
-
var JwtHeaderSchema =
|
|
17249
|
-
var IdTokenClaimsSchema =
|
|
17250
|
-
iss:
|
|
17251
|
-
sub:
|
|
17252
|
-
aud:
|
|
17253
|
-
exp:
|
|
17254
|
-
nonce:
|
|
17255
|
-
email:
|
|
17735
|
+
var JwtHeaderSchema = import_zod26.z.looseObject({ alg: import_zod26.z.string(), kid: import_zod26.z.string().optional() });
|
|
17736
|
+
var IdTokenClaimsSchema = import_zod26.z.looseObject({
|
|
17737
|
+
iss: import_zod26.z.string(),
|
|
17738
|
+
sub: import_zod26.z.string().min(1),
|
|
17739
|
+
aud: import_zod26.z.union([import_zod26.z.string(), import_zod26.z.array(import_zod26.z.string())]),
|
|
17740
|
+
exp: import_zod26.z.number(),
|
|
17741
|
+
nonce: import_zod26.z.string().optional(),
|
|
17742
|
+
email: import_zod26.z.string().optional()
|
|
17256
17743
|
});
|
|
17257
|
-
var JwksSchema =
|
|
17744
|
+
var JwksSchema = import_zod26.z.object({ keys: import_zod26.z.array(import_zod26.z.looseObject({ kid: import_zod26.z.string().optional(), kty: import_zod26.z.string() })) });
|
|
17258
17745
|
|
|
17259
17746
|
// src/codex/siwcStore.ts
|
|
17260
|
-
var SiwcGrantSchema =
|
|
17261
|
-
clientId:
|
|
17262
|
-
sub:
|
|
17263
|
-
email:
|
|
17264
|
-
idToken:
|
|
17265
|
-
accessToken:
|
|
17266
|
-
refreshToken:
|
|
17267
|
-
scopes:
|
|
17747
|
+
var SiwcGrantSchema = import_zod27.z.strictObject({
|
|
17748
|
+
clientId: import_zod27.z.string().min(1),
|
|
17749
|
+
sub: import_zod27.z.string().min(1),
|
|
17750
|
+
email: import_zod27.z.string().optional(),
|
|
17751
|
+
idToken: import_zod27.z.string().min(1),
|
|
17752
|
+
accessToken: import_zod27.z.string().min(1),
|
|
17753
|
+
refreshToken: import_zod27.z.string().min(1),
|
|
17754
|
+
scopes: import_zod27.z.array(import_zod27.z.string()).readonly(),
|
|
17268
17755
|
/** When the access token stops working, in milliseconds since the epoch. */
|
|
17269
|
-
expiresAt:
|
|
17756
|
+
expiresAt: import_zod27.z.number()
|
|
17270
17757
|
});
|
|
17271
|
-
var SiwcFileSchema =
|
|
17758
|
+
var SiwcFileSchema = import_zod27.z.strictObject({ registeredClientId: import_zod27.z.string().min(1).optional(), grant: SiwcGrantSchema.optional() });
|
|
17272
17759
|
function parseSiwcFile(raw, filePath) {
|
|
17273
17760
|
let json;
|
|
17274
17761
|
try {
|
|
@@ -17524,7 +18011,7 @@ function pushFrontDoorListeners(push, readings) {
|
|
|
17524
18011
|
}
|
|
17525
18012
|
|
|
17526
18013
|
// src/frontdoor/listenerReadings.ts
|
|
17527
|
-
var
|
|
18014
|
+
var import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
17528
18015
|
init_probe();
|
|
17529
18016
|
function readFrontDoorListeners(state, supervisorAlive, probes) {
|
|
17530
18017
|
if (!supervisorAlive) {
|
|
@@ -17545,7 +18032,7 @@ function readFrontDoorListeners(state, supervisorAlive, probes) {
|
|
|
17545
18032
|
}
|
|
17546
18033
|
function realFrontDoorListenerProbes(paths) {
|
|
17547
18034
|
return {
|
|
17548
|
-
authenticateProvider: (port) => probeFrontDoorSync(port,
|
|
18035
|
+
authenticateProvider: (port) => probeFrontDoorSync(port, import_node_fs10.default.readFileSync(paths.frontdoorCaCertFile, "utf8")),
|
|
17549
18036
|
connect: probeListenerAcceptSync,
|
|
17550
18037
|
now: () => performance.now()
|
|
17551
18038
|
};
|
|
@@ -17578,6 +18065,82 @@ function describeSharedLoginMembers(poolName, shared) {
|
|
|
17578
18065
|
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.`;
|
|
17579
18066
|
}
|
|
17580
18067
|
|
|
18068
|
+
// src/poolWindowReads.ts
|
|
18069
|
+
init_schema();
|
|
18070
|
+
init_identity();
|
|
18071
|
+
init_conditions();
|
|
18072
|
+
init_middleware();
|
|
18073
|
+
init_rateLimit();
|
|
18074
|
+
var WINDOW_NAMES = ["fiveHour", "sevenDay", "extraUsage"];
|
|
18075
|
+
var WINDOW_PROSE = { fiveHour: "five-hour", sevenDay: "seven-day", extraUsage: "extra-usage" };
|
|
18076
|
+
var WINDOW_FACTS = ["remaining", "utilization", "hoursUntilReset"];
|
|
18077
|
+
var DERIVED_FACTS = [{ key: "quota.burnPerHour", window: "fiveHour" }];
|
|
18078
|
+
function receivedWindows(snapshot) {
|
|
18079
|
+
const unified = snapshot?.providers[ANTHROPIC_PROVIDER]?.rateLimit?.unified;
|
|
18080
|
+
if (unified === void 0) {
|
|
18081
|
+
return void 0;
|
|
18082
|
+
}
|
|
18083
|
+
return /* @__PURE__ */ new Set([...unified.fiveHour === void 0 ? [] : ["fiveHour"], ...unified.sevenDay === void 0 ? [] : ["sevenDay"], ...soleOverageWindow(unified) === void 0 ? [] : ["extraUsage"]]);
|
|
18084
|
+
}
|
|
18085
|
+
function conditionReads(when) {
|
|
18086
|
+
const direct = WINDOW_NAMES.flatMap((window) => WINDOW_FACTS.some((fact) => referencesFact(when, `quota.${window}.${fact}`)) ? [{ window, reference: `quota.${window}` }] : []);
|
|
18087
|
+
const derived = DERIVED_FACTS.flatMap(({ key, window }) => referencesFact(when, key) ? [{ window, reference: key }] : []);
|
|
18088
|
+
return [...direct, ...derived];
|
|
18089
|
+
}
|
|
18090
|
+
function identitiesOf(selector, pools, visited = /* @__PURE__ */ new Set()) {
|
|
18091
|
+
const nested = poolNameOf(selector);
|
|
18092
|
+
if (nested === void 0) {
|
|
18093
|
+
return [selector];
|
|
18094
|
+
}
|
|
18095
|
+
const pool = pools[nested];
|
|
18096
|
+
if (pool === void 0 || visited.has(nested)) {
|
|
18097
|
+
return [];
|
|
18098
|
+
}
|
|
18099
|
+
visited.add(nested);
|
|
18100
|
+
return [...new Set(pool.identities.flatMap((member) => identitiesOf(poolMemberIdentity(member), pools, visited)))];
|
|
18101
|
+
}
|
|
18102
|
+
function poolWindowReadFindings(pools, windowsOf) {
|
|
18103
|
+
const findings = [];
|
|
18104
|
+
for (const [poolName, pool] of Object.entries(pools)) {
|
|
18105
|
+
for (const member of pool.identities) {
|
|
18106
|
+
if (typeof member === "string") {
|
|
18107
|
+
continue;
|
|
18108
|
+
}
|
|
18109
|
+
const reads = conditionReads(member.when);
|
|
18110
|
+
for (const identity of identitiesOf(member.identity, pools)) {
|
|
18111
|
+
const received = windowsOf(identity);
|
|
18112
|
+
for (const { window, reference } of reads) {
|
|
18113
|
+
if (received !== void 0 && !received.has(window)) {
|
|
18114
|
+
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.` });
|
|
18115
|
+
}
|
|
18116
|
+
}
|
|
18117
|
+
}
|
|
18118
|
+
}
|
|
18119
|
+
if (pool.compactBeforeLimit === true) {
|
|
18120
|
+
for (const identity of identitiesOf(`pool:${poolName}`, pools)) {
|
|
18121
|
+
const received = windowsOf(identity);
|
|
18122
|
+
if (received !== void 0 && !received.has("fiveHour") && !received.has("sevenDay")) {
|
|
18123
|
+
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.` });
|
|
18124
|
+
}
|
|
18125
|
+
}
|
|
18126
|
+
}
|
|
18127
|
+
}
|
|
18128
|
+
return findings;
|
|
18129
|
+
}
|
|
18130
|
+
function jobWindowReadFindings(jobs, pools, windowsOf) {
|
|
18131
|
+
return Object.entries(jobs).flatMap(([jobName, job]) => {
|
|
18132
|
+
const { trigger, target } = job;
|
|
18133
|
+
if (!("beforeReset" in trigger)) {
|
|
18134
|
+
return [];
|
|
18135
|
+
}
|
|
18136
|
+
const identities = "pool" in target ? identitiesOf(`pool:${target.pool}`, pools) : identitiesOf(target.identity, pools);
|
|
18137
|
+
return identities.flatMap((identity) => {
|
|
18138
|
+
const received = windowsOf(identity);
|
|
18139
|
+
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}.` }];
|
|
18140
|
+
});
|
|
18141
|
+
});
|
|
18142
|
+
}
|
|
18143
|
+
|
|
17581
18144
|
// src/doctorReport.ts
|
|
17582
18145
|
init_extends();
|
|
17583
18146
|
var DOCTOR_SEVERITIES = ["pass", "warn", "fail"];
|
|
@@ -17614,8 +18177,8 @@ function validateJson(schema, input) {
|
|
|
17614
18177
|
let parsed;
|
|
17615
18178
|
try {
|
|
17616
18179
|
parsed = JSON.parse(input.raw);
|
|
17617
|
-
} catch
|
|
17618
|
-
return { ok: false, message: `${input.path} is not valid JSON
|
|
18180
|
+
} catch {
|
|
18181
|
+
return { ok: false, message: `${input.path} is not valid JSON.` };
|
|
17619
18182
|
}
|
|
17620
18183
|
const result = parseIgnoringUnrecognisedKeys(schema, parsed);
|
|
17621
18184
|
if (!result.success) {
|
|
@@ -17634,7 +18197,7 @@ function tcpPortEraRecord(raw) {
|
|
|
17634
18197
|
return (has("port") || has("lastPort")) && !has("socketPath");
|
|
17635
18198
|
}
|
|
17636
18199
|
function pushPathResolution(push, resolution) {
|
|
17637
|
-
const ownDir =
|
|
18200
|
+
const ownDir = import_node_path31.default.dirname(resolution.ownExecutablePath);
|
|
17638
18201
|
switch (resolution.agentShim.status) {
|
|
17639
18202
|
case "ok":
|
|
17640
18203
|
push("path-resolution", "pass", `\`agent-shim\` on PATH resolves to this running executable, ${resolution.ownExecutablePath}.`, "agent-shim");
|
|
@@ -17721,8 +18284,8 @@ function pushProvider(push, entry, cacheEnv, signIn) {
|
|
|
17721
18284
|
let parsed;
|
|
17722
18285
|
try {
|
|
17723
18286
|
parsed = JSON.parse(entry.raw);
|
|
17724
|
-
} catch
|
|
17725
|
-
push("provider", "fail", `${entry.path} is not valid JSON
|
|
18287
|
+
} catch {
|
|
18288
|
+
push("provider", "fail", `${entry.path} is not valid JSON.`, entry.name);
|
|
17726
18289
|
return;
|
|
17727
18290
|
}
|
|
17728
18291
|
const conversion = legacyProviderConversion(parsed);
|
|
@@ -17754,14 +18317,14 @@ function pushProvider(push, entry, cacheEnv, signIn) {
|
|
|
17754
18317
|
}
|
|
17755
18318
|
function pushLegacyName(push, params) {
|
|
17756
18319
|
const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
|
|
17757
|
-
if (legacyVariables.length === 0 &&
|
|
18320
|
+
if (legacyVariables.length === 0 && import_node_path31.default.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
|
|
17758
18321
|
push("legacy-name", "pass", "Nothing here still uses the former `claude-use` name.");
|
|
17759
18322
|
return;
|
|
17760
18323
|
}
|
|
17761
18324
|
for (const name of legacyVariables) {
|
|
17762
18325
|
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);
|
|
17763
18326
|
}
|
|
17764
|
-
if (
|
|
18327
|
+
if (import_node_path31.default.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
|
|
17765
18328
|
push(
|
|
17766
18329
|
"legacy-name",
|
|
17767
18330
|
"warn",
|
|
@@ -17847,6 +18410,16 @@ function runDoctor(params) {
|
|
|
17847
18410
|
}
|
|
17848
18411
|
const validProfileNames = new Set(profileSources.keys());
|
|
17849
18412
|
const validProviderNames = /* @__PURE__ */ new Set([...params.providers.map((entry) => entry.name), ...Object.keys(params.providerAliases ?? {})]);
|
|
18413
|
+
const identityNames = new Set(params.identities.filter((entry) => entry.raw !== void 0).map((entry) => entry.name));
|
|
18414
|
+
for (const journal of params.renameJournals?.journals ?? []) {
|
|
18415
|
+
push("identity", "fail", `There is ${describeUnfinishedRename(journal, finishabilityOf(journal, (name) => identityNames.has(name)))}`, journal.from);
|
|
18416
|
+
}
|
|
18417
|
+
for (const { name, code } of params.unreachableIdentities ?? []) {
|
|
18418
|
+
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);
|
|
18419
|
+
}
|
|
18420
|
+
for (const { file, detail } of params.renameJournals?.unreadable ?? []) {
|
|
18421
|
+
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.`, import_node_path31.default.basename(file));
|
|
18422
|
+
}
|
|
17850
18423
|
const validIdentityNames = /* @__PURE__ */ new Set();
|
|
17851
18424
|
const signedInAccounts = [];
|
|
17852
18425
|
for (const entry of params.identities) {
|
|
@@ -17946,6 +18519,17 @@ function runDoctor(params) {
|
|
|
17946
18519
|
reportedCycles.add(key);
|
|
17947
18520
|
push("pool", "fail", `Pool cycle: ${chain.join(" -> ")}. A pool cannot nest itself, directly or through another pool.`, chain[0]);
|
|
17948
18521
|
}
|
|
18522
|
+
const { usageSnapshots } = params;
|
|
18523
|
+
if (usageSnapshots !== void 0) {
|
|
18524
|
+
const windowsOf = (identityName) => receivedWindows(usageSnapshots[identityName]);
|
|
18525
|
+
for (const finding of poolWindowReadFindings(pools, windowsOf)) {
|
|
18526
|
+
push("pool", "warn", finding.message, finding.subject);
|
|
18527
|
+
}
|
|
18528
|
+
const jobs = validatedGlobalConfig?.ok === true ? validatedGlobalConfig.data.jobs ?? {} : {};
|
|
18529
|
+
for (const finding of jobWindowReadFindings(jobs, pools, windowsOf)) {
|
|
18530
|
+
push("global-config", "warn", finding.message, finding.subject);
|
|
18531
|
+
}
|
|
18532
|
+
}
|
|
17949
18533
|
const selectionExists = (selector) => {
|
|
17950
18534
|
const poolName = poolNameOf(selector);
|
|
17951
18535
|
return poolName === void 0 ? validIdentityNames.has(selector) : poolName in pools;
|
|
@@ -18186,7 +18770,7 @@ function formatDoctorReport(report) {
|
|
|
18186
18770
|
}
|
|
18187
18771
|
function realpathOrSelf(target) {
|
|
18188
18772
|
try {
|
|
18189
|
-
return
|
|
18773
|
+
return import_node_fs11.default.realpathSync(target);
|
|
18190
18774
|
} catch {
|
|
18191
18775
|
return target;
|
|
18192
18776
|
}
|
|
@@ -18198,20 +18782,33 @@ function servingDoorListeners(paths) {
|
|
|
18198
18782
|
}
|
|
18199
18783
|
function collectDoctorReport(params) {
|
|
18200
18784
|
const { paths } = params;
|
|
18201
|
-
const
|
|
18785
|
+
const { names: identityNames, unreachable: unreachableIdentities } = listIdentityDirectories(paths);
|
|
18202
18786
|
const identities = identityNames.map((name) => {
|
|
18203
|
-
const farmRoot =
|
|
18204
|
-
const identityPath =
|
|
18205
|
-
return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent:
|
|
18787
|
+
const farmRoot = import_node_path31.default.join(paths.identitiesDir, name);
|
|
18788
|
+
const identityPath = import_node_path31.default.join(farmRoot, "identity.json");
|
|
18789
|
+
return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: import_node_fs11.default.existsSync(credentialsFilePath(farmRoot)), account: readIdentityAccount(realFsPort, paths.identitiesDir, name)?.account };
|
|
18206
18790
|
});
|
|
18207
|
-
const
|
|
18791
|
+
const usageSnapshots = {};
|
|
18792
|
+
for (const name of identityNames) {
|
|
18793
|
+
try {
|
|
18794
|
+
const snapshot = readUsageSnapshot(realFsPort, paths.usageSnapshotsDir, name);
|
|
18795
|
+
if (snapshot !== void 0) {
|
|
18796
|
+
usageSnapshots[name] = snapshot;
|
|
18797
|
+
}
|
|
18798
|
+
} catch (error) {
|
|
18799
|
+
if (!(error instanceof UsageSnapshotError)) {
|
|
18800
|
+
throw error;
|
|
18801
|
+
}
|
|
18802
|
+
}
|
|
18803
|
+
}
|
|
18804
|
+
const profileNames = import_node_fs11.default.existsSync(paths.configProfilesDir) ? import_node_fs11.default.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
18208
18805
|
const configProfiles = profileNames.map((name) => {
|
|
18209
|
-
const profilePath =
|
|
18806
|
+
const profilePath = import_node_path31.default.join(paths.configProfilesDir, `${name}.json`);
|
|
18210
18807
|
return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
|
|
18211
18808
|
});
|
|
18212
|
-
const providerNames =
|
|
18809
|
+
const providerNames = import_node_fs11.default.existsSync(paths.providersDir) ? import_node_fs11.default.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
18213
18810
|
const providers = providerNames.map((name) => {
|
|
18214
|
-
const providerPath =
|
|
18811
|
+
const providerPath = import_node_path31.default.join(paths.providersDir, `${name}.json`);
|
|
18215
18812
|
return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
|
|
18216
18813
|
});
|
|
18217
18814
|
const ownExecutablePath = realOwnExecutablePath();
|
|
@@ -18223,12 +18820,12 @@ function collectDoctorReport(params) {
|
|
|
18223
18820
|
binaryDiscovery = { ok: false, message: error instanceof Error ? error.message : String(error) };
|
|
18224
18821
|
}
|
|
18225
18822
|
const shimState = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
18226
|
-
const pathDirs = (params.env.PATH ?? "").split(
|
|
18823
|
+
const pathDirs = (params.env.PATH ?? "").split(import_node_path31.default.delimiter).filter((dir) => dir !== "");
|
|
18227
18824
|
const claudeShimShadow = shimState === void 0 ? void 0 : refinePathShadow(
|
|
18228
18825
|
findPathShadow({
|
|
18229
18826
|
pathDirs,
|
|
18230
|
-
targetDir:
|
|
18231
|
-
targetFilename:
|
|
18827
|
+
targetDir: import_node_path31.default.dirname(shimState.targetPath),
|
|
18828
|
+
targetFilename: import_node_path31.default.basename(shimState.targetPath),
|
|
18232
18829
|
findExecutableInDir
|
|
18233
18830
|
}),
|
|
18234
18831
|
shimState.targetPath,
|
|
@@ -18247,9 +18844,12 @@ function collectDoctorReport(params) {
|
|
|
18247
18844
|
chatgptSignIn: { path: paths.chatgptSignInFile, raw: realFsPort.readFileUtf8(paths.chatgptSignInFile) },
|
|
18248
18845
|
installedClaudeVersions: realInstalledClaudeVersions(),
|
|
18249
18846
|
identities,
|
|
18847
|
+
usageSnapshots,
|
|
18250
18848
|
configProfiles,
|
|
18251
18849
|
providers,
|
|
18252
18850
|
providerAliases: readProviderAliases(paths),
|
|
18851
|
+
renameJournals: listRenameJournals(realFarmFs, paths.identityRenamesDir),
|
|
18852
|
+
unreachableIdentities,
|
|
18253
18853
|
directoryRules: { path: paths.directoryRulesFile, raw: realFsPort.readFileUtf8(paths.directoryRulesFile) },
|
|
18254
18854
|
globalConfig: { path: paths.globalConfigFile, raw: realFsPort.readFileUtf8(paths.globalConfigFile) },
|
|
18255
18855
|
models: parsedModelsOf(paths),
|
|
@@ -18257,14 +18857,14 @@ function collectDoctorReport(params) {
|
|
|
18257
18857
|
categoriesLocal: { path: paths.categoriesLocalFile, raw: realFsPort.readFileUtf8(paths.categoriesLocalFile) },
|
|
18258
18858
|
activeIdentity: { path: paths.activeIdentityFile, raw: realFsPort.readFileUtf8(paths.activeIdentityFile) },
|
|
18259
18859
|
binaryDiscovery,
|
|
18260
|
-
claudeShim: { state: shimState, targetExists: shimState !== void 0 &&
|
|
18860
|
+
claudeShim: { state: shimState, targetExists: shimState !== void 0 && import_node_fs11.default.existsSync(shimState.targetPath) },
|
|
18261
18861
|
rootPath: paths.root,
|
|
18262
18862
|
pathResolution: {
|
|
18263
18863
|
ownExecutablePath,
|
|
18264
18864
|
agentShim: refinePathShadow(
|
|
18265
18865
|
findPathShadow({
|
|
18266
18866
|
pathDirs,
|
|
18267
|
-
targetDir:
|
|
18867
|
+
targetDir: import_node_path31.default.dirname(ownExecutablePath),
|
|
18268
18868
|
targetFilename: commandFilename(ownExecutablePath, "agent-shim"),
|
|
18269
18869
|
findExecutableInDir
|
|
18270
18870
|
}),
|
|
@@ -18305,92 +18905,92 @@ function collectDoctorReport(params) {
|
|
|
18305
18905
|
// src/frontdoor/controlSchemas.ts
|
|
18306
18906
|
init_schema2();
|
|
18307
18907
|
init_state();
|
|
18308
|
-
var UsageListOutputSchema =
|
|
18309
|
-
var UsageWindowsInputSchema =
|
|
18310
|
-
identity:
|
|
18311
|
-
provider:
|
|
18908
|
+
var UsageListOutputSchema = import_zod30.z.strictObject({ snapshots: import_zod30.z.readonly(import_zod30.z.array(UsageSnapshotSchema)) });
|
|
18909
|
+
var UsageWindowsInputSchema = import_zod30.z.strictObject({
|
|
18910
|
+
identity: import_zod30.z.string().min(1),
|
|
18911
|
+
provider: import_zod30.z.string().min(1).optional()
|
|
18312
18912
|
});
|
|
18313
|
-
var EffectiveWindowSchema =
|
|
18913
|
+
var EffectiveWindowSchema = import_zod30.z.strictObject({
|
|
18314
18914
|
/** True when the window's reset time has passed, so the recorded observation describes a window that no longer exists. */
|
|
18315
|
-
reset:
|
|
18915
|
+
reset: import_zod30.z.boolean(),
|
|
18316
18916
|
/** The fraction used: 0 for a reset window, otherwise what was last observed, absent when none was reported. */
|
|
18317
|
-
utilization:
|
|
18917
|
+
utilization: import_zod30.z.number().optional(),
|
|
18318
18918
|
/** The reset instant, for a window that has not reset yet and reported one. */
|
|
18319
|
-
resetsAtMs:
|
|
18919
|
+
resetsAtMs: import_zod30.z.number().optional(),
|
|
18320
18920
|
/** The window's own status, for a window that has not reset yet. */
|
|
18321
|
-
status:
|
|
18921
|
+
status: import_zod30.z.string().optional()
|
|
18322
18922
|
});
|
|
18323
|
-
var UsageWindowsOutputSchema =
|
|
18324
|
-
identity:
|
|
18325
|
-
provider:
|
|
18923
|
+
var UsageWindowsOutputSchema = import_zod30.z.strictObject({
|
|
18924
|
+
identity: import_zod30.z.string(),
|
|
18925
|
+
provider: import_zod30.z.string(),
|
|
18326
18926
|
/** When the rate-limit state the windows come from was observed. */
|
|
18327
|
-
observedAt:
|
|
18927
|
+
observedAt: import_zod30.z.iso.datetime().optional(),
|
|
18328
18928
|
fiveHour: EffectiveWindowSchema.optional(),
|
|
18329
18929
|
sevenDay: EffectiveWindowSchema.optional()
|
|
18330
18930
|
});
|
|
18331
|
-
var UsageLiveOutputSchema =
|
|
18931
|
+
var UsageLiveOutputSchema = import_zod30.z.strictObject({
|
|
18332
18932
|
/** 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. */
|
|
18333
18933
|
latest: RcLiveRateLimitSchema.optional(),
|
|
18334
18934
|
/** One observation per session whose stream has filed a rate_limit_event this door generation. */
|
|
18335
|
-
sessions:
|
|
18935
|
+
sessions: import_zod30.z.readonly(import_zod30.z.array(RcLiveRateLimitSchema))
|
|
18336
18936
|
});
|
|
18337
|
-
var FrontDoorSessionStatusSchema =
|
|
18338
|
-
pid:
|
|
18339
|
-
startedAt:
|
|
18340
|
-
alive:
|
|
18937
|
+
var FrontDoorSessionStatusSchema = import_zod30.z.strictObject({
|
|
18938
|
+
pid: import_zod30.z.int().positive(),
|
|
18939
|
+
startedAt: import_zod30.z.number(),
|
|
18940
|
+
alive: import_zod30.z.boolean()
|
|
18341
18941
|
});
|
|
18342
|
-
var HeadroomSocketTargetSchema =
|
|
18343
|
-
var FrontDoorStatusOutputSchema =
|
|
18942
|
+
var HeadroomSocketTargetSchema = import_zod30.z.union([import_zod30.z.strictObject({ socketPath: import_zod30.z.string() }), import_zod30.z.strictObject({ refused: import_zod30.z.string() })]);
|
|
18943
|
+
var FrontDoorStatusOutputSchema = import_zod30.z.strictObject({
|
|
18344
18944
|
state: FrontDoorStateSchema,
|
|
18345
|
-
supervisorAlive:
|
|
18945
|
+
supervisorAlive: import_zod30.z.boolean(),
|
|
18346
18946
|
/** The pids of earlier doors that released their addresses and are finishing the connections they carried: running, but not serving anything new. */
|
|
18347
|
-
draining:
|
|
18348
|
-
sessions:
|
|
18947
|
+
draining: import_zod30.z.readonly(import_zod30.z.array(import_zod30.z.number().int().positive())),
|
|
18948
|
+
sessions: import_zod30.z.readonly(import_zod30.z.array(FrontDoorSessionStatusSchema)),
|
|
18349
18949
|
headroomSocket: HeadroomSocketTargetSchema.optional(),
|
|
18350
|
-
logPath:
|
|
18351
|
-
logExists:
|
|
18950
|
+
logPath: import_zod30.z.string(),
|
|
18951
|
+
logExists: import_zod30.z.boolean()
|
|
18352
18952
|
});
|
|
18353
|
-
var FrontDoorSessionsOutputSchema =
|
|
18354
|
-
var CheckRunInputSchema =
|
|
18355
|
-
path:
|
|
18356
|
-
identity:
|
|
18357
|
-
}).refine((input) =>
|
|
18358
|
-
var PoolPickInputSchema =
|
|
18359
|
-
pool:
|
|
18360
|
-
path:
|
|
18361
|
-
}).refine((input) =>
|
|
18362
|
-
var DoctorFindingSchema =
|
|
18363
|
-
section:
|
|
18364
|
-
subject:
|
|
18365
|
-
severity:
|
|
18366
|
-
message:
|
|
18953
|
+
var FrontDoorSessionsOutputSchema = import_zod30.z.strictObject({ sessions: import_zod30.z.readonly(import_zod30.z.array(FrontDoorSessionStatusSchema)) });
|
|
18954
|
+
var CheckRunInputSchema = import_zod30.z.strictObject({
|
|
18955
|
+
path: import_zod30.z.string().min(1),
|
|
18956
|
+
identity: import_zod30.z.string().min(1).optional()
|
|
18957
|
+
}).refine((input) => import_node_path32.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
18958
|
+
var PoolPickInputSchema = import_zod30.z.strictObject({
|
|
18959
|
+
pool: import_zod30.z.string().min(1),
|
|
18960
|
+
path: import_zod30.z.string().min(1)
|
|
18961
|
+
}).refine((input) => import_node_path32.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
18962
|
+
var DoctorFindingSchema = import_zod30.z.strictObject({
|
|
18963
|
+
section: import_zod30.z.enum(DOCTOR_SECTIONS),
|
|
18964
|
+
subject: import_zod30.z.string().optional(),
|
|
18965
|
+
severity: import_zod30.z.enum(DOCTOR_SEVERITIES),
|
|
18966
|
+
message: import_zod30.z.string()
|
|
18367
18967
|
});
|
|
18368
|
-
var DoctorRunOutputSchema =
|
|
18968
|
+
var DoctorRunOutputSchema = import_zod30.z.strictObject({
|
|
18369
18969
|
/** False exactly when any finding is a `fail`; a `warn` never fails the report on its own. */
|
|
18370
|
-
ok:
|
|
18371
|
-
findings:
|
|
18970
|
+
ok: import_zod30.z.boolean(),
|
|
18971
|
+
findings: import_zod30.z.readonly(import_zod30.z.array(DoctorFindingSchema))
|
|
18372
18972
|
});
|
|
18373
|
-
var FrontDoorRestartOutputSchema =
|
|
18374
|
-
action:
|
|
18375
|
-
previousPid:
|
|
18973
|
+
var FrontDoorRestartOutputSchema = import_zod30.z.strictObject({
|
|
18974
|
+
action: import_zod30.z.literal("restarting"),
|
|
18975
|
+
previousPid: import_zod30.z.int().positive()
|
|
18376
18976
|
});
|
|
18377
|
-
var UpdateCheckOutputSchema =
|
|
18378
|
-
current:
|
|
18379
|
-
latest:
|
|
18380
|
-
action:
|
|
18977
|
+
var UpdateCheckOutputSchema = import_zod30.z.strictObject({
|
|
18978
|
+
current: import_zod30.z.string(),
|
|
18979
|
+
latest: import_zod30.z.string(),
|
|
18980
|
+
action: import_zod30.z.enum(["current", "available", "updated"])
|
|
18381
18981
|
});
|
|
18382
|
-
var CodexSignInSchema =
|
|
18383
|
-
|
|
18384
|
-
|
|
18385
|
-
|
|
18982
|
+
var CodexSignInSchema = import_zod30.z.discriminatedUnion("state", [
|
|
18983
|
+
import_zod30.z.strictObject({ state: import_zod30.z.literal("none") }),
|
|
18984
|
+
import_zod30.z.strictObject({ state: import_zod30.z.literal("signed-in"), email: import_zod30.z.string().optional(), planScope: import_zod30.z.boolean(), accessTokenExpiresAt: import_zod30.z.number() }),
|
|
18985
|
+
import_zod30.z.strictObject({ state: import_zod30.z.literal("unreadable"), message: import_zod30.z.string() })
|
|
18386
18986
|
]);
|
|
18387
|
-
var CodexStatusOutputSchema =
|
|
18987
|
+
var CodexStatusOutputSchema = import_zod30.z.strictObject({
|
|
18388
18988
|
signIn: CodexSignInSchema,
|
|
18389
|
-
codexProviders:
|
|
18989
|
+
codexProviders: import_zod30.z.readonly(import_zod30.z.array(import_zod30.z.string()))
|
|
18390
18990
|
});
|
|
18391
|
-
var CodexLogoutOutputSchema =
|
|
18392
|
-
hadGrant:
|
|
18393
|
-
revoked:
|
|
18991
|
+
var CodexLogoutOutputSchema = import_zod30.z.strictObject({
|
|
18992
|
+
hadGrant: import_zod30.z.boolean(),
|
|
18993
|
+
revoked: import_zod30.z.boolean()
|
|
18394
18994
|
});
|
|
18395
18995
|
|
|
18396
18996
|
// src/frontdoor/codexApi.ts
|
|
@@ -18545,72 +19145,74 @@ function requireRuleSelector(paths, selector) {
|
|
|
18545
19145
|
|
|
18546
19146
|
// src/frontdoor/configApi.ts
|
|
18547
19147
|
init_identity();
|
|
19148
|
+
init_replayRun();
|
|
18548
19149
|
init_providersStore();
|
|
18549
19150
|
|
|
18550
19151
|
// src/frontdoor/configSchemas.ts
|
|
18551
|
-
var
|
|
19152
|
+
var import_zod31 = require("zod");
|
|
18552
19153
|
init_schema();
|
|
18553
19154
|
init_names();
|
|
18554
19155
|
init_statusline();
|
|
18555
|
-
var RemovalConfirmationSchema =
|
|
18556
|
-
var CredentialWriteSchema = (targets) =>
|
|
18557
|
-
sources:
|
|
18558
|
-
target:
|
|
18559
|
-
cache:
|
|
19156
|
+
var RemovalConfirmationSchema = import_zod31.z.boolean();
|
|
19157
|
+
var CredentialWriteSchema = (targets) => import_zod31.z.strictObject({
|
|
19158
|
+
sources: import_zod31.z.array(RemoteCredentialSourceSchema).min(1).optional(),
|
|
19159
|
+
target: import_zod31.z.enum(targets).optional(),
|
|
19160
|
+
cache: import_zod31.z.union([import_zod31.z.literal(false), CredentialCacheSchema]).optional()
|
|
18560
19161
|
});
|
|
18561
|
-
var CredentialSummarySchema2 =
|
|
18562
|
-
target:
|
|
18563
|
-
sources:
|
|
18564
|
-
|
|
18565
|
-
|
|
18566
|
-
|
|
18567
|
-
|
|
18568
|
-
|
|
18569
|
-
|
|
18570
|
-
|
|
19162
|
+
var CredentialSummarySchema2 = import_zod31.z.strictObject({
|
|
19163
|
+
target: import_zod31.z.enum(CREDENTIAL_TARGETS),
|
|
19164
|
+
sources: import_zod31.z.readonly(import_zod31.z.array(
|
|
19165
|
+
import_zod31.z.discriminatedUnion("kind", [
|
|
19166
|
+
import_zod31.z.strictObject({ kind: import_zod31.z.literal("env"), variable: import_zod31.z.string() }),
|
|
19167
|
+
import_zod31.z.strictObject({ kind: import_zod31.z.literal("file"), path: import_zod31.z.string() }),
|
|
19168
|
+
import_zod31.z.strictObject({ kind: import_zod31.z.literal("command"), program: import_zod31.z.string() }),
|
|
19169
|
+
import_zod31.z.strictObject({ kind: import_zod31.z.literal("op"), reference: import_zod31.z.string() }),
|
|
19170
|
+
import_zod31.z.strictObject({ kind: import_zod31.z.literal("keychain"), service: import_zod31.z.string(), account: import_zod31.z.string().optional() }),
|
|
19171
|
+
import_zod31.z.strictObject({ kind: import_zod31.z.literal("literal") })
|
|
18571
19172
|
])
|
|
18572
19173
|
)),
|
|
18573
19174
|
cache: CredentialCacheSchema.optional()
|
|
18574
19175
|
});
|
|
18575
|
-
var mutationOutput = (kind, action) =>
|
|
18576
|
-
var storedMutationOutput = (kind, action, value) =>
|
|
18577
|
-
var IdentityValueSchema =
|
|
18578
|
-
name:
|
|
18579
|
-
label:
|
|
18580
|
-
defaultConfigProfile:
|
|
18581
|
-
provider:
|
|
18582
|
-
allowAmbientCredential:
|
|
19176
|
+
var mutationOutput = (kind, action) => import_zod31.z.strictObject({ action: import_zod31.z.literal(action), kind: import_zod31.z.literal(kind), name: import_zod31.z.string() });
|
|
19177
|
+
var storedMutationOutput = (kind, action, value) => import_zod31.z.strictObject({ action: import_zod31.z.literal(action), kind: import_zod31.z.literal(kind), name: import_zod31.z.string(), value });
|
|
19178
|
+
var IdentityValueSchema = import_zod31.z.strictObject({
|
|
19179
|
+
name: import_zod31.z.string(),
|
|
19180
|
+
label: import_zod31.z.string().optional(),
|
|
19181
|
+
defaultConfigProfile: import_zod31.z.string().optional(),
|
|
19182
|
+
provider: import_zod31.z.string().optional(),
|
|
19183
|
+
allowAmbientCredential: import_zod31.z.boolean(),
|
|
18583
19184
|
credential: CredentialSummarySchema2.optional(),
|
|
18584
|
-
anchors:
|
|
19185
|
+
anchors: import_zod31.z.array(AnchorSchema).optional()
|
|
18585
19186
|
});
|
|
18586
19187
|
var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
|
|
18587
|
-
var ProviderValueSchema =
|
|
18588
|
-
name:
|
|
18589
|
-
kind:
|
|
18590
|
-
displayName:
|
|
18591
|
-
baseUrl:
|
|
19188
|
+
var ProviderValueSchema = import_zod31.z.strictObject({
|
|
19189
|
+
name: import_zod31.z.string(),
|
|
19190
|
+
kind: import_zod31.z.enum(PROVIDER_KINDS),
|
|
19191
|
+
displayName: import_zod31.z.string(),
|
|
19192
|
+
baseUrl: import_zod31.z.string().optional(),
|
|
18592
19193
|
codex: CodexProviderConfigSchema.optional(),
|
|
18593
19194
|
credential: CredentialSummarySchema2.optional(),
|
|
18594
|
-
env:
|
|
19195
|
+
env: import_zod31.z.record(import_zod31.z.string(), import_zod31.z.string()).optional()
|
|
18595
19196
|
});
|
|
18596
|
-
var ConfigNameInputSchema =
|
|
19197
|
+
var ConfigNameInputSchema = import_zod31.z.strictObject({ name: import_zod31.z.string().min(1) });
|
|
19198
|
+
var ConfigIdentityAddInputSchema = import_zod31.z.strictObject({ name: import_zod31.z.string().min(1), keepKeychainLogin: import_zod31.z.boolean().optional().describe(KEEP_KEYCHAIN_LOGIN_DESCRIPTION) });
|
|
18597
19199
|
var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created", IdentityValueSchema);
|
|
18598
|
-
var ConfigIdentitySetInputSchema =
|
|
18599
|
-
name:
|
|
19200
|
+
var ConfigIdentitySetInputSchema = import_zod31.z.strictObject({
|
|
19201
|
+
name: import_zod31.z.string().min(1),
|
|
18600
19202
|
/** The identity's display label; `false` clears it. */
|
|
18601
|
-
label:
|
|
18602
|
-
defaultConfigProfile:
|
|
19203
|
+
label: import_zod31.z.union([IdentityLabelSchema, import_zod31.z.literal(false)]).optional(),
|
|
19204
|
+
defaultConfigProfile: import_zod31.z.union([import_zod31.z.string().min(1), import_zod31.z.literal(false)]).optional(),
|
|
18603
19205
|
/** The provider the identity exists for; `false` clears it. */
|
|
18604
|
-
provider:
|
|
18605
|
-
allowAmbientCredential:
|
|
18606
|
-
credential:
|
|
19206
|
+
provider: import_zod31.z.union([import_zod31.z.string().min(1), import_zod31.z.literal(false)]).optional(),
|
|
19207
|
+
allowAmbientCredential: import_zod31.z.boolean().optional(),
|
|
19208
|
+
credential: import_zod31.z.union([import_zod31.z.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional(),
|
|
18607
19209
|
/** `false` removes the anchors; a list replaces them. */
|
|
18608
|
-
anchors:
|
|
19210
|
+
anchors: import_zod31.z.union([import_zod31.z.literal(false), import_zod31.z.array(AnchorSchema).min(1)]).optional()
|
|
18609
19211
|
});
|
|
18610
19212
|
var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
|
|
18611
|
-
var ConfigIdentityRemoveInputSchema =
|
|
19213
|
+
var ConfigIdentityRemoveInputSchema = import_zod31.z.strictObject({ name: import_zod31.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18612
19214
|
var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
|
|
18613
|
-
var ConfigStatuslineSetSchema =
|
|
19215
|
+
var ConfigStatuslineSetSchema = import_zod31.z.record(import_zod31.z.string(), import_zod31.z.unknown()).superRefine((settings, context) => {
|
|
18614
19216
|
for (const key of Object.keys(settings)) {
|
|
18615
19217
|
if (key === STATUSLINE_EXTRA_GROUP || key.startsWith(`${STATUSLINE_EXTRA_GROUP}.`)) {
|
|
18616
19218
|
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` });
|
|
@@ -18618,102 +19220,105 @@ var ConfigStatuslineSetSchema = import_zod30.z.record(import_zod30.z.string(), i
|
|
|
18618
19220
|
}
|
|
18619
19221
|
});
|
|
18620
19222
|
var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
|
|
18621
|
-
var ConfigProfileAddInputSchema =
|
|
18622
|
-
name:
|
|
18623
|
-
extends:
|
|
18624
|
-
description:
|
|
19223
|
+
var ConfigProfileAddInputSchema = import_zod31.z.strictObject({
|
|
19224
|
+
name: import_zod31.z.string().min(1),
|
|
19225
|
+
extends: import_zod31.z.array(import_zod31.z.string().min(1)).optional(),
|
|
19226
|
+
description: import_zod31.z.string().optional()
|
|
18625
19227
|
});
|
|
18626
19228
|
var ConfigProfileAddOutputSchema = storedMutationOutput("profile", "created", ProfileValueSchema);
|
|
18627
|
-
var ConfigProfileSetInputSchema =
|
|
18628
|
-
name:
|
|
18629
|
-
category:
|
|
18630
|
-
entry:
|
|
18631
|
-
extends:
|
|
18632
|
-
description:
|
|
18633
|
-
launch:
|
|
18634
|
-
skipPermissions:
|
|
18635
|
-
remoteControl:
|
|
18636
|
-
headroom:
|
|
18637
|
-
trackUsage:
|
|
18638
|
-
provider:
|
|
18639
|
-
claudeVersion:
|
|
18640
|
-
delay:
|
|
18641
|
-
pause:
|
|
18642
|
-
explain:
|
|
18643
|
-
proxyBypass:
|
|
18644
|
-
statusline:
|
|
19229
|
+
var ConfigProfileSetInputSchema = import_zod31.z.strictObject({
|
|
19230
|
+
name: import_zod31.z.string().min(1),
|
|
19231
|
+
category: import_zod31.z.record(import_zod31.z.string(), import_zod31.z.boolean()).optional(),
|
|
19232
|
+
entry: import_zod31.z.record(import_zod31.z.string(), import_zod31.z.boolean()).optional(),
|
|
19233
|
+
extends: import_zod31.z.union([import_zod31.z.array(import_zod31.z.string().min(1)), import_zod31.z.literal(false)]).optional(),
|
|
19234
|
+
description: import_zod31.z.union([import_zod31.z.string(), import_zod31.z.literal(false)]).optional(),
|
|
19235
|
+
launch: import_zod31.z.strictObject({
|
|
19236
|
+
skipPermissions: import_zod31.z.boolean().optional(),
|
|
19237
|
+
remoteControl: import_zod31.z.boolean().optional(),
|
|
19238
|
+
headroom: import_zod31.z.boolean().optional(),
|
|
19239
|
+
trackUsage: import_zod31.z.boolean().optional(),
|
|
19240
|
+
provider: import_zod31.z.union([import_zod31.z.string().min(1), import_zod31.z.literal(false)]).optional(),
|
|
19241
|
+
claudeVersion: import_zod31.z.union([import_zod31.z.string().min(1), import_zod31.z.literal(false)]).optional(),
|
|
19242
|
+
delay: import_zod31.z.union([import_zod31.z.string().regex(DURATION_RE), import_zod31.z.literal(false)]).optional(),
|
|
19243
|
+
pause: import_zod31.z.boolean().optional(),
|
|
19244
|
+
explain: import_zod31.z.boolean().optional(),
|
|
19245
|
+
proxyBypass: import_zod31.z.union([import_zod31.z.array(import_zod31.z.string().min(1)), import_zod31.z.literal(false)]).optional(),
|
|
19246
|
+
statusline: import_zod31.z.strictObject({
|
|
18645
19247
|
set: ConfigStatuslineSetSchema.optional(),
|
|
18646
|
-
unset:
|
|
19248
|
+
unset: import_zod31.z.array(import_zod31.z.string()).optional()
|
|
18647
19249
|
}).optional()
|
|
18648
19250
|
}).optional()
|
|
18649
19251
|
});
|
|
18650
19252
|
var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
|
|
18651
|
-
var ConfigProfileRemoveInputSchema =
|
|
19253
|
+
var ConfigProfileRemoveInputSchema = import_zod31.z.strictObject({ name: import_zod31.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18652
19254
|
var ConfigProfileRemoveOutputSchema = mutationOutput("profile", "removed");
|
|
18653
19255
|
var ConfigProfileUseOutputSchema = mutationOutput("profile", "selected");
|
|
18654
|
-
var PoolMembersInputSchema =
|
|
18655
|
-
var ConfigPoolAddInputSchema =
|
|
18656
|
-
name:
|
|
19256
|
+
var PoolMembersInputSchema = import_zod31.z.array(import_zod31.z.string().min(1)).min(1);
|
|
19257
|
+
var ConfigPoolAddInputSchema = import_zod31.z.strictObject({
|
|
19258
|
+
name: import_zod31.z.string().min(1),
|
|
18657
19259
|
identities: PoolMembersInputSchema,
|
|
18658
|
-
preference:
|
|
18659
|
-
resumeOnLimit:
|
|
18660
|
-
compactBeforeLimit:
|
|
19260
|
+
preference: import_zod31.z.enum(POOL_PREFERENCES).optional(),
|
|
19261
|
+
resumeOnLimit: import_zod31.z.boolean().optional(),
|
|
19262
|
+
compactBeforeLimit: import_zod31.z.boolean().optional(),
|
|
18661
19263
|
compactAtUtilisation: CompactAtUtilisationSchema.optional()
|
|
18662
19264
|
});
|
|
18663
19265
|
var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
|
|
18664
|
-
var ConfigPoolSetInputSchema =
|
|
18665
|
-
name:
|
|
19266
|
+
var ConfigPoolSetInputSchema = import_zod31.z.strictObject({
|
|
19267
|
+
name: import_zod31.z.string().min(1),
|
|
18666
19268
|
identities: PoolMembersInputSchema.optional(),
|
|
18667
|
-
preference:
|
|
18668
|
-
resumeOnLimit:
|
|
18669
|
-
compactBeforeLimit:
|
|
18670
|
-
compactAtUtilisation:
|
|
19269
|
+
preference: import_zod31.z.union([import_zod31.z.enum(POOL_PREFERENCES), import_zod31.z.literal(false)]).optional(),
|
|
19270
|
+
resumeOnLimit: import_zod31.z.boolean().optional(),
|
|
19271
|
+
compactBeforeLimit: import_zod31.z.boolean().optional(),
|
|
19272
|
+
compactAtUtilisation: import_zod31.z.union([CompactAtUtilisationSchema, import_zod31.z.literal(false)]).optional()
|
|
18671
19273
|
});
|
|
18672
19274
|
var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
|
|
18673
|
-
var ConfigPoolRemoveInputSchema =
|
|
19275
|
+
var ConfigPoolRemoveInputSchema = import_zod31.z.strictObject({ name: import_zod31.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18674
19276
|
var ConfigPoolRemoveOutputSchema = mutationOutput("pool", "removed");
|
|
18675
19277
|
var ConfigPoolUseOutputSchema = mutationOutput("pool", "selected");
|
|
18676
|
-
var ConfigProviderAddInputSchema =
|
|
18677
|
-
name:
|
|
18678
|
-
kind:
|
|
18679
|
-
displayName:
|
|
18680
|
-
baseUrl:
|
|
19278
|
+
var ConfigProviderAddInputSchema = import_zod31.z.strictObject({
|
|
19279
|
+
name: import_zod31.z.string().min(1),
|
|
19280
|
+
kind: import_zod31.z.enum(PROVIDER_KINDS).optional(),
|
|
19281
|
+
displayName: import_zod31.z.string().min(1),
|
|
19282
|
+
baseUrl: import_zod31.z.string().min(1).optional(),
|
|
18681
19283
|
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).required({ sources: true }),
|
|
18682
19284
|
codex: CodexProviderConfigSchema.optional()
|
|
18683
19285
|
});
|
|
18684
19286
|
var ConfigProviderAddOutputSchema = storedMutationOutput("provider", "created", ProviderValueSchema);
|
|
18685
|
-
var ConfigProviderSetInputSchema =
|
|
18686
|
-
name:
|
|
18687
|
-
displayName:
|
|
18688
|
-
baseUrl:
|
|
19287
|
+
var ConfigProviderSetInputSchema = import_zod31.z.strictObject({
|
|
19288
|
+
name: import_zod31.z.string().min(1),
|
|
19289
|
+
displayName: import_zod31.z.string().min(1).optional(),
|
|
19290
|
+
baseUrl: import_zod31.z.string().min(1).optional(),
|
|
18689
19291
|
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).optional(),
|
|
18690
19292
|
codex: CodexProviderConfigSchema.optional()
|
|
18691
19293
|
});
|
|
18692
19294
|
var ConfigProviderSetOutputSchema = storedMutationOutput("provider", "updated", ProviderValueSchema);
|
|
18693
|
-
var ConfigProviderRemoveInputSchema =
|
|
19295
|
+
var ConfigProviderRemoveInputSchema = import_zod31.z.strictObject({ name: import_zod31.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18694
19296
|
var ConfigProviderRemoveOutputSchema = mutationOutput("provider", "removed");
|
|
18695
|
-
var ConfigRuleAddInputSchema =
|
|
18696
|
-
path:
|
|
18697
|
-
configProfile:
|
|
18698
|
-
identity:
|
|
19297
|
+
var ConfigRuleAddInputSchema = import_zod31.z.strictObject({
|
|
19298
|
+
path: import_zod31.z.string().min(1),
|
|
19299
|
+
configProfile: import_zod31.z.string().min(1).optional(),
|
|
19300
|
+
identity: import_zod31.z.string().min(1).optional()
|
|
18699
19301
|
});
|
|
18700
19302
|
var ConfigRuleAddOutputSchema = storedMutationOutput("rule", "created", DirectoryRuleSchema);
|
|
18701
|
-
var ConfigRuleSetInputSchema =
|
|
18702
|
-
path:
|
|
18703
|
-
configProfile:
|
|
18704
|
-
identity:
|
|
19303
|
+
var ConfigRuleSetInputSchema = import_zod31.z.strictObject({
|
|
19304
|
+
path: import_zod31.z.string().min(1),
|
|
19305
|
+
configProfile: import_zod31.z.union([import_zod31.z.string().min(1), import_zod31.z.literal(false)]).optional(),
|
|
19306
|
+
identity: import_zod31.z.union([import_zod31.z.string().min(1), import_zod31.z.literal(false)]).optional()
|
|
18705
19307
|
});
|
|
18706
19308
|
var ConfigRuleSetOutputSchema = storedMutationOutput("rule", "updated", DirectoryRuleSchema);
|
|
18707
|
-
var ConfigRuleRemoveInputSchema =
|
|
19309
|
+
var ConfigRuleRemoveInputSchema = import_zod31.z.strictObject({ path: import_zod31.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18708
19310
|
var ConfigRuleRemoveOutputSchema = mutationOutput("rule", "removed");
|
|
18709
19311
|
|
|
18710
19312
|
// src/frontdoor/configApi.ts
|
|
18711
19313
|
var CONFIG_API_TAG = "config";
|
|
18712
19314
|
function refusal(error) {
|
|
19315
|
+
if (error instanceof KeychainLookupError) {
|
|
19316
|
+
throw new import_client2.ORPCError("SERVICE_UNAVAILABLE", { message: error.message });
|
|
19317
|
+
}
|
|
18713
19318
|
if (error instanceof IdentityNotFoundError || error instanceof ProfileNotFoundError || error instanceof PoolNotFoundError || error instanceof ProviderNotFoundError || error instanceof DirectoryRuleNotFoundError) {
|
|
18714
19319
|
throw new import_client2.ORPCError("NOT_FOUND", { message: error.message });
|
|
18715
19320
|
}
|
|
18716
|
-
if (error instanceof IdentityAlreadyExistsError || error instanceof ProfileAlreadyExistsError || error instanceof PoolAlreadyExistsError || error instanceof ProviderAlreadyExistsError || error instanceof DirectoryRuleAlreadyExistsError) {
|
|
19321
|
+
if (error instanceof IdentityAlreadyExistsError || error instanceof ProfileAlreadyExistsError || error instanceof PoolAlreadyExistsError || error instanceof ProviderAlreadyExistsError || error instanceof DirectoryRuleAlreadyExistsError || error instanceof KeychainLoginError) {
|
|
18717
19322
|
throw new import_client2.ORPCError("CONFLICT", { message: error.message });
|
|
18718
19323
|
}
|
|
18719
19324
|
if (error instanceof CliError) {
|
|
@@ -18721,6 +19326,13 @@ function refusal(error) {
|
|
|
18721
19326
|
}
|
|
18722
19327
|
throw error;
|
|
18723
19328
|
}
|
|
19329
|
+
async function guardedAsync(write) {
|
|
19330
|
+
try {
|
|
19331
|
+
await write();
|
|
19332
|
+
} catch (error) {
|
|
19333
|
+
refusal(error);
|
|
19334
|
+
}
|
|
19335
|
+
}
|
|
18724
19336
|
function guarded(write) {
|
|
18725
19337
|
try {
|
|
18726
19338
|
return write();
|
|
@@ -18770,16 +19382,21 @@ function profileValue(name, paths) {
|
|
|
18770
19382
|
function createConfigApiRouter(deps) {
|
|
18771
19383
|
const authed = doorApiAuth(deps.expectedToken);
|
|
18772
19384
|
const { paths } = deps;
|
|
18773
|
-
const route = (
|
|
19385
|
+
const route = (path45, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path45, summary, tags: [CONFIG_API_TAG] }));
|
|
18774
19386
|
return {
|
|
18775
19387
|
config: {
|
|
18776
19388
|
identity: {
|
|
18777
|
-
add: route("/rest/config/identity/add", "Create an identity").input(
|
|
18778
|
-
(
|
|
19389
|
+
add: route("/rest/config/identity/add", "Create an identity").input(ConfigIdentityAddInputSchema).output(ConfigIdentityAddOutputSchema).handler(async ({ input }) => {
|
|
19390
|
+
await guardedAsync(async () => {
|
|
19391
|
+
await resolveWithAsyncRuns((run) => {
|
|
19392
|
+
requireIdentityAddable(paths, input.name, { run, platform: deps.keychain.platform }, input.keepKeychainLogin === true);
|
|
19393
|
+
}, deps.keychain.runAsync);
|
|
19394
|
+
});
|
|
19395
|
+
return guarded(() => {
|
|
18779
19396
|
addIdentity(paths, input.name);
|
|
18780
19397
|
return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
|
|
18781
|
-
})
|
|
18782
|
-
),
|
|
19398
|
+
});
|
|
19399
|
+
}),
|
|
18783
19400
|
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(
|
|
18784
19401
|
({ input }) => guarded(() => {
|
|
18785
19402
|
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");
|
|
@@ -19028,43 +19645,43 @@ var import_openapi4 = require("@orpc/openapi");
|
|
|
19028
19645
|
var import_server3 = require("@orpc/server");
|
|
19029
19646
|
|
|
19030
19647
|
// src/frontdoor/eventSchemas.ts
|
|
19031
|
-
var
|
|
19648
|
+
var import_zod32 = require("zod");
|
|
19032
19649
|
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
19033
19650
|
var LAUNCH_EVENT_SOURCE = "launch";
|
|
19034
19651
|
var USAGE_EVENT_SOURCE = "usage";
|
|
19035
19652
|
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
19036
19653
|
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
19037
|
-
var DoorEventSchema =
|
|
19038
|
-
source:
|
|
19654
|
+
var DoorEventSchema = import_zod32.z.strictObject({
|
|
19655
|
+
source: import_zod32.z.string().min(1),
|
|
19039
19656
|
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
19040
|
-
sequence:
|
|
19041
|
-
payload:
|
|
19657
|
+
sequence: import_zod32.z.number().int().positive(),
|
|
19658
|
+
payload: import_zod32.z.unknown()
|
|
19042
19659
|
});
|
|
19043
|
-
var DoorEventSourceQuerySchema =
|
|
19044
|
-
sources:
|
|
19660
|
+
var DoorEventSourceQuerySchema = import_zod32.z.strictObject({
|
|
19661
|
+
sources: import_zod32.z.array(import_zod32.z.string().min(1)).min(1).optional()
|
|
19045
19662
|
});
|
|
19046
|
-
var LaunchLifecycleEventSchema =
|
|
19047
|
-
kind:
|
|
19048
|
-
pid:
|
|
19049
|
-
startedAt:
|
|
19050
|
-
observedAt:
|
|
19663
|
+
var LaunchLifecycleEventSchema = import_zod32.z.strictObject({
|
|
19664
|
+
kind: import_zod32.z.enum(["registered", "pruned", "ended"]),
|
|
19665
|
+
pid: import_zod32.z.number().int().positive(),
|
|
19666
|
+
startedAt: import_zod32.z.number(),
|
|
19667
|
+
observedAt: import_zod32.z.number()
|
|
19051
19668
|
});
|
|
19052
|
-
var DoorHealthEventSchema =
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
|
|
19056
|
-
|
|
19057
|
-
|
|
19058
|
-
|
|
19669
|
+
var DoorHealthEventSchema = import_zod32.z.discriminatedUnion("kind", [
|
|
19670
|
+
import_zod32.z.strictObject({ kind: import_zod32.z.literal("generation"), pid: import_zod32.z.number().int().positive(), providerPort: import_zod32.z.number().int().positive(), connectPort: import_zod32.z.number().int().positive(), directPort: import_zod32.z.number().int().positive(), observedAt: import_zod32.z.number() }),
|
|
19671
|
+
import_zod32.z.strictObject({ kind: import_zod32.z.literal("listenerFailed"), pid: import_zod32.z.number().int().positive(), listener: import_zod32.z.enum(["provider", "connect", "direct"]), message: import_zod32.z.string(), observedAt: import_zod32.z.number() }),
|
|
19672
|
+
import_zod32.z.strictObject({ kind: import_zod32.z.literal("binaryTurnover"), pid: import_zod32.z.number().int().positive(), observedAt: import_zod32.z.number() }),
|
|
19673
|
+
import_zod32.z.strictObject({ kind: import_zod32.z.literal("idleShutdown"), pid: import_zod32.z.number().int().positive(), observedAt: import_zod32.z.number() }),
|
|
19674
|
+
import_zod32.z.strictObject({ kind: import_zod32.z.literal("superseded"), pid: import_zod32.z.number().int().positive(), ownerPid: import_zod32.z.number().int().positive(), observedAt: import_zod32.z.number() }),
|
|
19675
|
+
import_zod32.z.strictObject({ kind: import_zod32.z.literal("drained"), pid: import_zod32.z.number().int().positive(), observedAt: import_zod32.z.number() })
|
|
19059
19676
|
]);
|
|
19060
|
-
var QuotaExpiringEventSchema =
|
|
19061
|
-
identity:
|
|
19062
|
-
provider:
|
|
19063
|
-
window:
|
|
19677
|
+
var QuotaExpiringEventSchema = import_zod32.z.strictObject({
|
|
19678
|
+
identity: import_zod32.z.string().min(1),
|
|
19679
|
+
provider: import_zod32.z.string().min(1),
|
|
19680
|
+
window: import_zod32.z.enum(["fiveHour", "sevenDay"]),
|
|
19064
19681
|
/** 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. */
|
|
19065
|
-
utilization:
|
|
19066
|
-
resetsAt:
|
|
19067
|
-
observedAt:
|
|
19682
|
+
utilization: import_zod32.z.number().min(0).max(1),
|
|
19683
|
+
resetsAt: import_zod32.z.iso.datetime(),
|
|
19684
|
+
observedAt: import_zod32.z.number()
|
|
19068
19685
|
});
|
|
19069
19686
|
|
|
19070
19687
|
// src/frontdoor/eventsApi.ts
|
|
@@ -19147,61 +19764,61 @@ var import_openapi6 = require("@orpc/openapi");
|
|
|
19147
19764
|
init_cliError();
|
|
19148
19765
|
|
|
19149
19766
|
// src/frontdoor/launchSchemas.ts
|
|
19150
|
-
var
|
|
19151
|
-
var
|
|
19767
|
+
var import_node_path33 = __toESM(require("node:path"), 1);
|
|
19768
|
+
var import_zod33 = require("zod");
|
|
19152
19769
|
init_statusline();
|
|
19153
19770
|
init_claudeVersion();
|
|
19154
19771
|
init_identity();
|
|
19155
|
-
var LaunchResolveInputSchema =
|
|
19156
|
-
path:
|
|
19772
|
+
var LaunchResolveInputSchema = import_zod33.z.strictObject({
|
|
19773
|
+
path: import_zod33.z.string().min(1),
|
|
19157
19774
|
/** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
|
|
19158
|
-
argv:
|
|
19775
|
+
argv: import_zod33.z.readonly(import_zod33.z.array(import_zod33.z.string())).optional(),
|
|
19159
19776
|
/** 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. */
|
|
19160
|
-
env:
|
|
19161
|
-
}).refine((input) =>
|
|
19162
|
-
var LaunchPoolDecisionSchema =
|
|
19163
|
-
name:
|
|
19164
|
-
reasons:
|
|
19165
|
-
movedOff:
|
|
19777
|
+
env: import_zod33.z.record(import_zod33.z.string(), import_zod33.z.string()).optional()
|
|
19778
|
+
}).refine((input) => import_node_path33.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
19779
|
+
var LaunchPoolDecisionSchema = import_zod33.z.strictObject({
|
|
19780
|
+
name: import_zod33.z.string(),
|
|
19781
|
+
reasons: import_zod33.z.readonly(import_zod33.z.array(import_zod33.z.string())),
|
|
19782
|
+
movedOff: import_zod33.z.strictObject({ identity: import_zod33.z.string(), reason: import_zod33.z.string() }).optional()
|
|
19166
19783
|
});
|
|
19167
|
-
var LaunchDecisionSchema =
|
|
19168
|
-
identity:
|
|
19169
|
-
identitySource:
|
|
19784
|
+
var LaunchDecisionSchema = import_zod33.z.strictObject({
|
|
19785
|
+
identity: import_zod33.z.string().optional(),
|
|
19786
|
+
identitySource: import_zod33.z.enum(IDENTITY_DECISION_SOURCES),
|
|
19170
19787
|
pool: LaunchPoolDecisionSchema.optional(),
|
|
19171
|
-
configDirEscapeHatch:
|
|
19172
|
-
configDir:
|
|
19173
|
-
configProfile:
|
|
19174
|
-
configProfileSource:
|
|
19175
|
-
provider:
|
|
19788
|
+
configDirEscapeHatch: import_zod33.z.boolean(),
|
|
19789
|
+
configDir: import_zod33.z.string().optional(),
|
|
19790
|
+
configProfile: import_zod33.z.string().optional(),
|
|
19791
|
+
configProfileSource: import_zod33.z.enum(CONFIG_PROFILE_DECISION_SOURCES),
|
|
19792
|
+
provider: import_zod33.z.string().optional()
|
|
19176
19793
|
});
|
|
19177
|
-
var LaunchFlagsSchema =
|
|
19178
|
-
skipPermissions:
|
|
19179
|
-
remoteControl:
|
|
19180
|
-
headroom:
|
|
19181
|
-
trackUsage:
|
|
19182
|
-
pause:
|
|
19183
|
-
explain:
|
|
19794
|
+
var LaunchFlagsSchema = import_zod33.z.strictObject({
|
|
19795
|
+
skipPermissions: import_zod33.z.boolean(),
|
|
19796
|
+
remoteControl: import_zod33.z.boolean(),
|
|
19797
|
+
headroom: import_zod33.z.boolean(),
|
|
19798
|
+
trackUsage: import_zod33.z.boolean(),
|
|
19799
|
+
pause: import_zod33.z.boolean(),
|
|
19800
|
+
explain: import_zod33.z.boolean(),
|
|
19184
19801
|
/** How long the launch waits after its own output before it starts claude, in milliseconds. */
|
|
19185
|
-
delayMs:
|
|
19802
|
+
delayMs: import_zod33.z.number(),
|
|
19186
19803
|
/** The hosts the launch keeps off the front door by adding them to the child's `NO_PROXY`. */
|
|
19187
|
-
proxyBypass:
|
|
19804
|
+
proxyBypass: import_zod33.z.array(import_zod33.z.string()).readonly(),
|
|
19188
19805
|
/** How the session's built-in statusline looks, when the launch configures any of it. */
|
|
19189
19806
|
statusline: StatuslineSchema.optional()
|
|
19190
19807
|
});
|
|
19191
|
-
var LaunchResolveOutputSchema =
|
|
19808
|
+
var LaunchResolveOutputSchema = import_zod33.z.strictObject({
|
|
19192
19809
|
decision: LaunchDecisionSchema,
|
|
19193
19810
|
flags: LaunchFlagsSchema,
|
|
19194
|
-
claudeVersion:
|
|
19811
|
+
claudeVersion: import_zod33.z.strictObject({ version: import_zod33.z.string(), source: import_zod33.z.enum(CLAUDE_VERSION_SOURCES) }).optional(),
|
|
19195
19812
|
/** The real `claude` binary the launch would spawn, on the door's host. */
|
|
19196
|
-
bin:
|
|
19813
|
+
bin: import_zod33.z.string(),
|
|
19197
19814
|
/** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
|
|
19198
|
-
args:
|
|
19815
|
+
args: import_zod33.z.readonly(import_zod33.z.array(import_zod33.z.string())),
|
|
19199
19816
|
/** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
|
|
19200
|
-
credential:
|
|
19201
|
-
routing:
|
|
19817
|
+
credential: import_zod33.z.strictObject({ subject: import_zod33.z.enum(["provider", "identity"]), name: import_zod33.z.string(), summary: CredentialSummarySchema }).optional(),
|
|
19818
|
+
routing: import_zod33.z.strictObject({ frontDoor: import_zod33.z.boolean(), headroom: import_zod33.z.boolean() }),
|
|
19202
19819
|
/** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
|
|
19203
|
-
environment:
|
|
19204
|
-
warnings:
|
|
19820
|
+
environment: import_zod33.z.readonly(import_zod33.z.array(import_zod33.z.string())),
|
|
19821
|
+
warnings: import_zod33.z.readonly(import_zod33.z.array(import_zod33.z.string()))
|
|
19205
19822
|
});
|
|
19206
19823
|
|
|
19207
19824
|
// src/frontdoor/launchApi.ts
|
|
@@ -19237,22 +19854,22 @@ function createLaunchApiRouter(deps) {
|
|
|
19237
19854
|
// src/frontdoor/agentTreesApi.ts
|
|
19238
19855
|
var import_client6 = require("@orpc/client");
|
|
19239
19856
|
var import_openapi7 = require("@orpc/openapi");
|
|
19240
|
-
var
|
|
19857
|
+
var import_zod34 = require("zod");
|
|
19241
19858
|
init_cliError();
|
|
19242
|
-
var AgentTreesListInputSchema =
|
|
19859
|
+
var AgentTreesListInputSchema = import_zod34.z.strictObject({
|
|
19243
19860
|
/** Only this identity's sessions. */
|
|
19244
|
-
identity:
|
|
19861
|
+
identity: import_zod34.z.string().optional(),
|
|
19245
19862
|
/** Include sessions that spawned no agent and ran no workflow. */
|
|
19246
|
-
all:
|
|
19863
|
+
all: import_zod34.z.boolean().optional()
|
|
19247
19864
|
});
|
|
19248
|
-
var AgentTreesListOutputSchema =
|
|
19249
|
-
var AgentTreesShowInputSchema =
|
|
19865
|
+
var AgentTreesListOutputSchema = import_zod34.z.array(SessionSummarySchema);
|
|
19866
|
+
var AgentTreesShowInputSchema = import_zod34.z.strictObject({
|
|
19250
19867
|
/** A session id, or an unambiguous prefix of one. */
|
|
19251
|
-
session:
|
|
19868
|
+
session: import_zod34.z.string().min(1),
|
|
19252
19869
|
/** Look only in this identity. */
|
|
19253
|
-
identity:
|
|
19870
|
+
identity: import_zod34.z.string().optional()
|
|
19254
19871
|
});
|
|
19255
|
-
var AgentTreesShowOutputSchema =
|
|
19872
|
+
var AgentTreesShowOutputSchema = import_zod34.z.strictObject({ identities: import_zod34.z.array(import_zod34.z.string()), ...MergedAgentTreeSchema.shape });
|
|
19256
19873
|
function asBadRequest(error) {
|
|
19257
19874
|
if (error instanceof CliError) {
|
|
19258
19875
|
throw new import_client6.ORPCError("BAD_REQUEST", { message: error.message });
|
|
@@ -21338,7 +21955,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
21338
21955
|
}
|
|
21339
21956
|
|
|
21340
21957
|
// src/frontdoor/rcSelfHostMint.ts
|
|
21341
|
-
var
|
|
21958
|
+
var import_node_path34 = __toESM(require("node:path"), 1);
|
|
21342
21959
|
init_account();
|
|
21343
21960
|
var CREDENTIALS_FILE2 = ".credentials.json";
|
|
21344
21961
|
var CLAUDE_JSON2 = ".claude.json";
|
|
@@ -21349,8 +21966,8 @@ var SELF_HOST_SUBSCRIPTION_TYPE = "max";
|
|
|
21349
21966
|
function isRecord14(value) {
|
|
21350
21967
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21351
21968
|
}
|
|
21352
|
-
function readJsonObject(
|
|
21353
|
-
const raw =
|
|
21969
|
+
function readJsonObject(fs15, file) {
|
|
21970
|
+
const raw = fs15.readFileUtf8(file);
|
|
21354
21971
|
if (raw === void 0) {
|
|
21355
21972
|
return void 0;
|
|
21356
21973
|
}
|
|
@@ -21362,8 +21979,8 @@ function readJsonObject(fs14, file) {
|
|
|
21362
21979
|
}
|
|
21363
21980
|
return isRecord14(parsed) ? parsed : void 0;
|
|
21364
21981
|
}
|
|
21365
|
-
function readRcSelfHostRecord(
|
|
21366
|
-
const parsed = readJsonObject(
|
|
21982
|
+
function readRcSelfHostRecord(fs15, frontdoorDir) {
|
|
21983
|
+
const parsed = readJsonObject(fs15, import_node_path34.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
21367
21984
|
if (parsed === void 0) {
|
|
21368
21985
|
return void 0;
|
|
21369
21986
|
}
|
|
@@ -21377,11 +21994,11 @@ function mintRcSelfHostCredential(deps) {
|
|
|
21377
21994
|
if (!isIdentityName(deps.identity)) {
|
|
21378
21995
|
throw new Error(`"${deps.identity}" is not a valid identity name.`);
|
|
21379
21996
|
}
|
|
21380
|
-
const identityDir =
|
|
21381
|
-
const credentialsFile =
|
|
21382
|
-
const claudeJsonFile =
|
|
21383
|
-
const recordDir =
|
|
21384
|
-
const
|
|
21997
|
+
const identityDir = import_node_path34.default.join(deps.identitiesDir, deps.identity);
|
|
21998
|
+
const credentialsFile = import_node_path34.default.join(identityDir, CREDENTIALS_FILE2);
|
|
21999
|
+
const claudeJsonFile = import_node_path34.default.join(identityDir, CLAUDE_JSON2);
|
|
22000
|
+
const recordDir = import_node_path34.default.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
|
|
22001
|
+
const recordFile2 = import_node_path34.default.join(recordDir, RC_SELF_HOST_RECORD_FILE);
|
|
21385
22002
|
const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
|
|
21386
22003
|
const existingCredentials = readJsonObject(deps.fs, credentialsFile);
|
|
21387
22004
|
const existingOauth = isRecord14(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
|
|
@@ -21397,7 +22014,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
21397
22014
|
const organizationUuid = deps.newUuid();
|
|
21398
22015
|
const accountUuid = deps.newUuid();
|
|
21399
22016
|
const mintedAt = new Date(deps.now()).toISOString();
|
|
21400
|
-
deps.fs.mkdirPrivate(
|
|
22017
|
+
deps.fs.mkdirPrivate(import_node_path34.default.dirname(credentialsFile));
|
|
21401
22018
|
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)}
|
|
21402
22019
|
`);
|
|
21403
22020
|
const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
|
|
@@ -21424,36 +22041,36 @@ function mintRcSelfHostCredential(deps) {
|
|
|
21424
22041
|
}, null, 2)}
|
|
21425
22042
|
`);
|
|
21426
22043
|
deps.fs.mkdirPrivate(recordDir);
|
|
21427
|
-
deps.fs.writeFilePrivate(
|
|
22044
|
+
deps.fs.writeFilePrivate(recordFile2, `${JSON.stringify({ accessToken, refreshToken, organizationUuid, accountUuid }, null, 2)}
|
|
21428
22045
|
`);
|
|
21429
|
-
return { identity: deps.identity, organizationUuid, credentialsFile, claudeJsonFile, recordFile, replaced: existingIsOwn };
|
|
22046
|
+
return { identity: deps.identity, organizationUuid, credentialsFile, claudeJsonFile, recordFile: recordFile2, replaced: existingIsOwn };
|
|
21430
22047
|
}
|
|
21431
22048
|
|
|
21432
22049
|
// src/index.ts
|
|
21433
22050
|
init_ensure2();
|
|
21434
22051
|
|
|
21435
22052
|
// src/frontdoor/liveSessionRegistry.ts
|
|
21436
|
-
var
|
|
22053
|
+
var import_node_path35 = __toESM(require("node:path"), 1);
|
|
21437
22054
|
init_capability();
|
|
21438
22055
|
init_state();
|
|
21439
22056
|
function sameStat(recorded, current) {
|
|
21440
22057
|
return recorded?.mtimeMs === current.mtimeMs && recorded.sizeBytes === current.sizeBytes;
|
|
21441
22058
|
}
|
|
21442
22059
|
function createLiveSessionRegistry(ports) {
|
|
21443
|
-
const { fs:
|
|
22060
|
+
const { fs: fs15, sessionsDir } = ports;
|
|
21444
22061
|
const known = /* @__PURE__ */ new Map();
|
|
21445
22062
|
let tokens = /* @__PURE__ */ new Set();
|
|
21446
22063
|
let bySessionId = /* @__PURE__ */ new Map();
|
|
21447
|
-
const recordNames = () =>
|
|
22064
|
+
const recordNames = () => fs15.readdir(sessionsDir).filter(isSessionRecordName);
|
|
21448
22065
|
const rebuildIndexes = () => {
|
|
21449
22066
|
const records = [...known.values()].flatMap(({ record }) => record === void 0 ? [] : [record]);
|
|
21450
22067
|
tokens = new Set(records.map((record) => record.token));
|
|
21451
22068
|
bySessionId = new Map(records.flatMap((record) => record.sessionId === void 0 ? [] : [[record.sessionId, record]]));
|
|
21452
22069
|
};
|
|
21453
22070
|
const load = (name, stat) => {
|
|
21454
|
-
known.set(name, { stat: { mtimeMs: stat.mtimeMs, sizeBytes: stat.sizeBytes }, record: readFrontDoorSessionRecord(
|
|
22071
|
+
known.set(name, { stat: { mtimeMs: stat.mtimeMs, sizeBytes: stat.sizeBytes }, record: readFrontDoorSessionRecord(fs15, sessionsDir, name) });
|
|
21455
22072
|
};
|
|
21456
|
-
const statOf = (name) =>
|
|
22073
|
+
const statOf = (name) => fs15.lstat(import_node_path35.default.join(sessionsDir, name));
|
|
21457
22074
|
const reconcile = () => {
|
|
21458
22075
|
const names = new Set(recordNames());
|
|
21459
22076
|
let changed = false;
|
|
@@ -21520,8 +22137,8 @@ init_plan2();
|
|
|
21520
22137
|
init_poolPick();
|
|
21521
22138
|
|
|
21522
22139
|
// src/agents/read.ts
|
|
21523
|
-
var
|
|
21524
|
-
var
|
|
22140
|
+
var import_node_path36 = __toESM(require("node:path"), 1);
|
|
22141
|
+
var import_zod35 = require("zod");
|
|
21525
22142
|
var PROJECTS_DIR = "projects";
|
|
21526
22143
|
var TASKS_DIR = "tasks";
|
|
21527
22144
|
var SUBAGENTS_DIR = "subagents";
|
|
@@ -21544,17 +22161,17 @@ function parseEntry2(project, entry) {
|
|
|
21544
22161
|
const base = match?.[1];
|
|
21545
22162
|
return base === void 0 ? { project, sessionId: entry, superseded: false, entry } : { project, sessionId: base, superseded: true, entry };
|
|
21546
22163
|
}
|
|
21547
|
-
function listSessions2(
|
|
22164
|
+
function listSessions2(fs15, configDir) {
|
|
21548
22165
|
const found = [];
|
|
21549
|
-
for (const project of
|
|
21550
|
-
const projectDir =
|
|
22166
|
+
for (const project of fs15.readdir(import_node_path36.default.join(configDir, PROJECTS_DIR))) {
|
|
22167
|
+
const projectDir = import_node_path36.default.join(configDir, PROJECTS_DIR, project);
|
|
21551
22168
|
const entries = /* @__PURE__ */ new Set();
|
|
21552
|
-
for (const name of
|
|
22169
|
+
for (const name of fs15.readdir(projectDir)) {
|
|
21553
22170
|
if (name.endsWith(TRANSCRIPT_SUFFIX)) {
|
|
21554
22171
|
entries.add(name.slice(0, -TRANSCRIPT_SUFFIX.length));
|
|
21555
22172
|
continue;
|
|
21556
22173
|
}
|
|
21557
|
-
const children =
|
|
22174
|
+
const children = fs15.readdir(import_node_path36.default.join(projectDir, name));
|
|
21558
22175
|
if (children.includes(SUBAGENTS_DIR) || children.includes(WORKFLOWS_DIR)) {
|
|
21559
22176
|
entries.add(name);
|
|
21560
22177
|
}
|
|
@@ -21565,17 +22182,17 @@ function listSessions2(fs14, configDir) {
|
|
|
21565
22182
|
}
|
|
21566
22183
|
return found.sort((left, right) => left.project.localeCompare(right.project) || left.entry.localeCompare(right.entry));
|
|
21567
22184
|
}
|
|
21568
|
-
function locateAgents(
|
|
22185
|
+
function locateAgents(fs15, configDir, relativeDir, workflowRunId, report) {
|
|
21569
22186
|
const located = [];
|
|
21570
|
-
for (const name of listDirOrReport(
|
|
22187
|
+
for (const name of listDirOrReport(fs15, configDir, relativeDir, report)) {
|
|
21571
22188
|
if (!name.startsWith(AGENT_FILE_PREFIX) || !name.endsWith(META_SUFFIX)) {
|
|
21572
22189
|
continue;
|
|
21573
22190
|
}
|
|
21574
22191
|
const id = name.slice(AGENT_FILE_PREFIX.length, -META_SUFFIX.length);
|
|
21575
22192
|
located.push({
|
|
21576
22193
|
id,
|
|
21577
|
-
metaPath:
|
|
21578
|
-
transcriptPath:
|
|
22194
|
+
metaPath: import_node_path36.default.join(relativeDir, name),
|
|
22195
|
+
transcriptPath: import_node_path36.default.join(relativeDir, `${AGENT_FILE_PREFIX}${id}${TRANSCRIPT_SUFFIX}`),
|
|
21579
22196
|
workflowRunId
|
|
21580
22197
|
});
|
|
21581
22198
|
}
|
|
@@ -21616,17 +22233,17 @@ function toNode(read, children) {
|
|
|
21616
22233
|
function describeFailure(error) {
|
|
21617
22234
|
return error instanceof Error ? error.message : String(error);
|
|
21618
22235
|
}
|
|
21619
|
-
function readFileOrReport(
|
|
22236
|
+
function readFileOrReport(fs15, configDir, relative, report) {
|
|
21620
22237
|
try {
|
|
21621
|
-
return
|
|
22238
|
+
return fs15.readFileUtf8(import_node_path36.default.join(configDir, relative));
|
|
21622
22239
|
} catch (error) {
|
|
21623
22240
|
report({ path: relative, reason: `could not be read: ${describeFailure(error)}` });
|
|
21624
22241
|
return void 0;
|
|
21625
22242
|
}
|
|
21626
22243
|
}
|
|
21627
|
-
function listDirOrReport(
|
|
22244
|
+
function listDirOrReport(fs15, configDir, relative, report) {
|
|
21628
22245
|
try {
|
|
21629
|
-
return
|
|
22246
|
+
return fs15.readdir(import_node_path36.default.join(configDir, relative));
|
|
21630
22247
|
} catch (error) {
|
|
21631
22248
|
report({ path: relative, reason: `could not be listed: ${describeFailure(error)}` });
|
|
21632
22249
|
return [];
|
|
@@ -21640,47 +22257,47 @@ function parseJson2(text) {
|
|
|
21640
22257
|
return void 0;
|
|
21641
22258
|
}
|
|
21642
22259
|
}
|
|
21643
|
-
var TaskFileSchema =
|
|
21644
|
-
var WorkflowRunFileSchema =
|
|
21645
|
-
runId:
|
|
21646
|
-
workflowName:
|
|
21647
|
-
status:
|
|
21648
|
-
startTime:
|
|
21649
|
-
phases:
|
|
21650
|
-
summary:
|
|
22260
|
+
var TaskFileSchema = import_zod35.z.object({ ...TaskItemSchema.omit({ taskList: true }).shape, blocks: import_zod35.z.array(import_zod35.z.string()).default([]), blockedBy: import_zod35.z.array(import_zod35.z.string()).default([]) });
|
|
22261
|
+
var WorkflowRunFileSchema = import_zod35.z.object({
|
|
22262
|
+
runId: import_zod35.z.string(),
|
|
22263
|
+
workflowName: import_zod35.z.string().optional(),
|
|
22264
|
+
status: import_zod35.z.string().optional(),
|
|
22265
|
+
startTime: import_zod35.z.number().optional(),
|
|
22266
|
+
phases: import_zod35.z.array(import_zod35.z.object({ title: import_zod35.z.string() })).default([]),
|
|
22267
|
+
summary: import_zod35.z.string().optional()
|
|
21651
22268
|
});
|
|
21652
|
-
function summariseSession(
|
|
21653
|
-
const sessionRelative =
|
|
21654
|
-
const subagentsRelative =
|
|
21655
|
-
const workflowsUnderSubagents =
|
|
22269
|
+
function summariseSession(fs15, configDir, ref) {
|
|
22270
|
+
const sessionRelative = import_node_path36.default.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
22271
|
+
const subagentsRelative = import_node_path36.default.join(sessionRelative, SUBAGENTS_DIR);
|
|
22272
|
+
const workflowsUnderSubagents = import_node_path36.default.join(subagentsRelative, WORKFLOWS_DIR);
|
|
21656
22273
|
const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
|
|
21657
|
-
let agentCount =
|
|
21658
|
-
for (const runDir of
|
|
22274
|
+
let agentCount = fs15.readdir(import_node_path36.default.join(configDir, subagentsRelative)).filter(isMeta).length;
|
|
22275
|
+
for (const runDir of fs15.readdir(import_node_path36.default.join(configDir, workflowsUnderSubagents))) {
|
|
21659
22276
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
21660
|
-
agentCount +=
|
|
22277
|
+
agentCount += fs15.readdir(import_node_path36.default.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
|
|
21661
22278
|
}
|
|
21662
22279
|
}
|
|
21663
|
-
const workflowRunCount =
|
|
21664
|
-
const transcript =
|
|
22280
|
+
const workflowRunCount = fs15.readdir(import_node_path36.default.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
|
|
22281
|
+
const transcript = fs15.lstat(import_node_path36.default.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
|
|
21665
22282
|
return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
|
|
21666
22283
|
}
|
|
21667
|
-
function readSessionAgentTree(
|
|
22284
|
+
function readSessionAgentTree(fs15, configDir, ref, options = {}) {
|
|
21668
22285
|
const problems = [];
|
|
21669
22286
|
const report = (problem) => {
|
|
21670
22287
|
problems.push(problem);
|
|
21671
22288
|
};
|
|
21672
|
-
const sessionRelative =
|
|
21673
|
-
const subagentsRelative =
|
|
21674
|
-
const workflowsUnderSubagents =
|
|
21675
|
-
const located = locateAgents(
|
|
21676
|
-
for (const runDir of listDirOrReport(
|
|
22289
|
+
const sessionRelative = import_node_path36.default.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
22290
|
+
const subagentsRelative = import_node_path36.default.join(sessionRelative, SUBAGENTS_DIR);
|
|
22291
|
+
const workflowsUnderSubagents = import_node_path36.default.join(subagentsRelative, WORKFLOWS_DIR);
|
|
22292
|
+
const located = locateAgents(fs15, configDir, subagentsRelative, void 0, report);
|
|
22293
|
+
for (const runDir of listDirOrReport(fs15, configDir, workflowsUnderSubagents, report)) {
|
|
21677
22294
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
21678
|
-
located.push(...locateAgents(
|
|
22295
|
+
located.push(...locateAgents(fs15, configDir, import_node_path36.default.join(workflowsUnderSubagents, runDir), runDir, report));
|
|
21679
22296
|
}
|
|
21680
22297
|
}
|
|
21681
22298
|
const agents = /* @__PURE__ */ new Map();
|
|
21682
22299
|
for (const candidate of located) {
|
|
21683
|
-
const text = readFileOrReport(
|
|
22300
|
+
const text = readFileOrReport(fs15, configDir, candidate.metaPath, report);
|
|
21684
22301
|
if (text === void 0) {
|
|
21685
22302
|
continue;
|
|
21686
22303
|
}
|
|
@@ -21692,7 +22309,7 @@ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
|
21692
22309
|
agents.set(candidate.id, { located: candidate, meta: parsed.data });
|
|
21693
22310
|
}
|
|
21694
22311
|
const teamNames = [...new Set([...agents.values()].flatMap((agent) => agent.meta.teamName === void 0 ? [] : [agent.meta.teamName]))].sort();
|
|
21695
|
-
const parentOf3 = resolveParents(
|
|
22312
|
+
const parentOf3 = resolveParents(fs15, configDir, agents, report);
|
|
21696
22313
|
const childrenOf = /* @__PURE__ */ new Map();
|
|
21697
22314
|
const roots = [];
|
|
21698
22315
|
for (const id of agents.keys()) {
|
|
@@ -21715,12 +22332,12 @@ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
|
21715
22332
|
sessionId: ref.sessionId,
|
|
21716
22333
|
superseded: ref.superseded,
|
|
21717
22334
|
agents: roots.sort().map(build),
|
|
21718
|
-
tasks: readTasks(
|
|
21719
|
-
workflowRuns: readWorkflowRuns(
|
|
22335
|
+
tasks: readTasks(fs15, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
|
|
22336
|
+
workflowRuns: readWorkflowRuns(fs15, configDir, import_node_path36.default.join(sessionRelative, WORKFLOWS_DIR), report),
|
|
21720
22337
|
problems
|
|
21721
22338
|
};
|
|
21722
22339
|
}
|
|
21723
|
-
function resolveParents(
|
|
22340
|
+
function resolveParents(fs15, configDir, agents, report) {
|
|
21724
22341
|
const parentOf3 = /* @__PURE__ */ new Map();
|
|
21725
22342
|
const transcriptCache = /* @__PURE__ */ new Map();
|
|
21726
22343
|
const transcriptOf = (agent) => {
|
|
@@ -21728,7 +22345,7 @@ function resolveParents(fs14, configDir, agents, report) {
|
|
|
21728
22345
|
if (cached !== void 0) {
|
|
21729
22346
|
return cached;
|
|
21730
22347
|
}
|
|
21731
|
-
const text = readFileOrReport(
|
|
22348
|
+
const text = readFileOrReport(fs15, configDir, agent.located.transcriptPath, report) ?? "";
|
|
21732
22349
|
transcriptCache.set(agent.located.id, text);
|
|
21733
22350
|
return text;
|
|
21734
22351
|
};
|
|
@@ -21778,16 +22395,16 @@ function resolveParents(fs14, configDir, agents, report) {
|
|
|
21778
22395
|
function ownTaskLists(sessionId) {
|
|
21779
22396
|
return [sessionId, `${SHORT_SESSION_LIST_PREFIX}${sessionId.slice(0, SHORT_SESSION_ID_LENGTH)}`];
|
|
21780
22397
|
}
|
|
21781
|
-
function readTasks(
|
|
22398
|
+
function readTasks(fs15, configDir, ownLists, sharedLists, report) {
|
|
21782
22399
|
const tasks = [];
|
|
21783
22400
|
[...ownLists, ...sharedLists].forEach((scope, index) => {
|
|
21784
|
-
const relativeDir =
|
|
21785
|
-
for (const name of [...listDirOrReport(
|
|
22401
|
+
const relativeDir = import_node_path36.default.join(TASKS_DIR, scope);
|
|
22402
|
+
for (const name of [...listDirOrReport(fs15, configDir, relativeDir, report)].sort()) {
|
|
21786
22403
|
if (name.startsWith(".") || !name.endsWith(JSON_SUFFIX)) {
|
|
21787
22404
|
continue;
|
|
21788
22405
|
}
|
|
21789
|
-
const relative =
|
|
21790
|
-
const text = readFileOrReport(
|
|
22406
|
+
const relative = import_node_path36.default.join(relativeDir, name);
|
|
22407
|
+
const text = readFileOrReport(fs15, configDir, relative, report);
|
|
21791
22408
|
const parsed = TaskFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
21792
22409
|
if (parsed.success) {
|
|
21793
22410
|
tasks.push(index < ownLists.length ? parsed.data : { ...parsed.data, taskList: scope });
|
|
@@ -21798,14 +22415,14 @@ function readTasks(fs14, configDir, ownLists, sharedLists, report) {
|
|
|
21798
22415
|
});
|
|
21799
22416
|
return tasks;
|
|
21800
22417
|
}
|
|
21801
|
-
function readWorkflowRuns(
|
|
22418
|
+
function readWorkflowRuns(fs15, configDir, relativeDir, report) {
|
|
21802
22419
|
const runs = [];
|
|
21803
|
-
for (const name of [...listDirOrReport(
|
|
22420
|
+
for (const name of [...listDirOrReport(fs15, configDir, relativeDir, report)].sort()) {
|
|
21804
22421
|
if (!name.startsWith(WORKFLOW_RUN_PREFIX) || !name.endsWith(JSON_SUFFIX)) {
|
|
21805
22422
|
continue;
|
|
21806
22423
|
}
|
|
21807
|
-
const relative =
|
|
21808
|
-
const text = readFileOrReport(
|
|
22424
|
+
const relative = import_node_path36.default.join(relativeDir, name);
|
|
22425
|
+
const text = readFileOrReport(fs15, configDir, relative, report);
|
|
21809
22426
|
const parsed = WorkflowRunFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
21810
22427
|
if (!parsed.success) {
|
|
21811
22428
|
if (text !== void 0) {
|
|
@@ -21820,7 +22437,7 @@ function readWorkflowRuns(fs14, configDir, relativeDir, report) {
|
|
|
21820
22437
|
}
|
|
21821
22438
|
|
|
21822
22439
|
// src/agents/sessions.ts
|
|
21823
|
-
var
|
|
22440
|
+
var import_node_path37 = __toESM(require("node:path"), 1);
|
|
21824
22441
|
init_cliError();
|
|
21825
22442
|
var SessionLookupError = class extends CliError {
|
|
21826
22443
|
constructor(message) {
|
|
@@ -21829,13 +22446,13 @@ var SessionLookupError = class extends CliError {
|
|
|
21829
22446
|
}
|
|
21830
22447
|
};
|
|
21831
22448
|
function identityConfigDir(identitiesDir, identity) {
|
|
21832
|
-
return
|
|
22449
|
+
return import_node_path37.default.join(identitiesDir, identity);
|
|
21833
22450
|
}
|
|
21834
|
-
function historyStores(
|
|
22451
|
+
function historyStores(fs15, identitiesDir, identities) {
|
|
21835
22452
|
const byRealPath = /* @__PURE__ */ new Map();
|
|
21836
22453
|
for (const identity of identities) {
|
|
21837
22454
|
const configDir = identityConfigDir(identitiesDir, identity);
|
|
21838
|
-
const real =
|
|
22455
|
+
const real = fs15.realpath(import_node_path37.default.join(configDir, "projects"));
|
|
21839
22456
|
if (real === void 0) {
|
|
21840
22457
|
continue;
|
|
21841
22458
|
}
|
|
@@ -21848,15 +22465,15 @@ function historyStores(fs14, identitiesDir, identities) {
|
|
|
21848
22465
|
}
|
|
21849
22466
|
return [...byRealPath.values()];
|
|
21850
22467
|
}
|
|
21851
|
-
function collectSessionList(
|
|
22468
|
+
function collectSessionList(fs15, identitiesDir, identities, filters) {
|
|
21852
22469
|
const names = filters.identity === void 0 ? identities : identities.filter((name) => name === filters.identity);
|
|
21853
22470
|
if (filters.identity !== void 0 && names.length === 0) {
|
|
21854
22471
|
throw new SessionLookupError(`no identity named "${filters.identity}"`);
|
|
21855
22472
|
}
|
|
21856
22473
|
const sessions = [];
|
|
21857
|
-
for (const store of historyStores(
|
|
21858
|
-
for (const ref of listSessions2(
|
|
21859
|
-
const summary = summariseSession(
|
|
22474
|
+
for (const store of historyStores(fs15, identitiesDir, names)) {
|
|
22475
|
+
for (const ref of listSessions2(fs15, store.configDir)) {
|
|
22476
|
+
const summary = summariseSession(fs15, store.configDir, ref);
|
|
21860
22477
|
if (filters.all === true || summary.agentCount > 0 || summary.workflowRunCount > 0) {
|
|
21861
22478
|
sessions.push({ ...summary, identities: store.identities });
|
|
21862
22479
|
}
|
|
@@ -21864,14 +22481,14 @@ function collectSessionList(fs14, identitiesDir, identities, filters) {
|
|
|
21864
22481
|
}
|
|
21865
22482
|
return sessions.sort((left, right) => (right.updatedAt ?? "").localeCompare(left.updatedAt ?? "") || left.sessionId.localeCompare(right.sessionId));
|
|
21866
22483
|
}
|
|
21867
|
-
function locateSession(
|
|
22484
|
+
function locateSession(fs15, identitiesDir, identities, query, onlyIdentity) {
|
|
21868
22485
|
const names = onlyIdentity === void 0 ? identities : identities.filter((name) => name === onlyIdentity);
|
|
21869
22486
|
if (onlyIdentity !== void 0 && names.length === 0) {
|
|
21870
22487
|
throw new SessionLookupError(`no identity named "${onlyIdentity}"`);
|
|
21871
22488
|
}
|
|
21872
22489
|
const matches = [];
|
|
21873
|
-
for (const store of historyStores(
|
|
21874
|
-
for (const ref of listSessions2(
|
|
22490
|
+
for (const store of historyStores(fs15, identitiesDir, names)) {
|
|
22491
|
+
for (const ref of listSessions2(fs15, store.configDir)) {
|
|
21875
22492
|
if (ref.sessionId.startsWith(query)) {
|
|
21876
22493
|
matches.push({ identities: store.identities, configDir: store.configDir, ref });
|
|
21877
22494
|
}
|
|
@@ -21888,19 +22505,19 @@ function locateSession(fs14, identitiesDir, identities, query, onlyIdentity) {
|
|
|
21888
22505
|
}
|
|
21889
22506
|
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`);
|
|
21890
22507
|
}
|
|
21891
|
-
function showSession(
|
|
21892
|
-
const located = locateSession(
|
|
21893
|
-
return { identities: located.identities, tree: readSessionAgentTree(
|
|
22508
|
+
function showSession(fs15, identitiesDir, identities, query, onlyIdentity) {
|
|
22509
|
+
const located = locateSession(fs15, identitiesDir, identities, query, onlyIdentity);
|
|
22510
|
+
return { identities: located.identities, tree: readSessionAgentTree(fs15, located.configDir, located.ref) };
|
|
21894
22511
|
}
|
|
21895
22512
|
|
|
21896
22513
|
// src/agents/realFs.ts
|
|
21897
|
-
var
|
|
22514
|
+
var import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
21898
22515
|
init_realPorts();
|
|
21899
22516
|
var realSessionFs = {
|
|
21900
22517
|
...realFarmFs,
|
|
21901
22518
|
realpath: (candidate) => {
|
|
21902
22519
|
try {
|
|
21903
|
-
return
|
|
22520
|
+
return import_node_fs12.default.realpathSync(candidate);
|
|
21904
22521
|
} catch {
|
|
21905
22522
|
return void 0;
|
|
21906
22523
|
}
|
|
@@ -22046,6 +22663,7 @@ init_ownCli();
|
|
|
22046
22663
|
CodexRateLimitsReadSchema,
|
|
22047
22664
|
CodexSignInSchema,
|
|
22048
22665
|
CodexStatusOutputSchema,
|
|
22666
|
+
ConfigIdentityAddInputSchema,
|
|
22049
22667
|
ConfigIdentityAddOutputSchema,
|
|
22050
22668
|
ConfigIdentityRemoveInputSchema,
|
|
22051
22669
|
ConfigIdentityRemoveOutputSchema,
|