claude-use 11.48.0 → 11.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +663 -454
- package/dist/index.cjs +431 -291
- package/dist/index.mjs +429 -290
- package/dist/types/index.d.ts +41 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2452,8 +2452,8 @@ var init_lock = __esm({
|
|
|
2452
2452
|
});
|
|
2453
2453
|
|
|
2454
2454
|
// src/launcher/farm.ts
|
|
2455
|
-
function readFarmManifest(
|
|
2456
|
-
const raw =
|
|
2455
|
+
function readFarmManifest(fs14, farmRoot) {
|
|
2456
|
+
const raw = fs14.readFileUtf8(import_node_path7.default.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs14.readFileUtf8(import_node_path7.default.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
|
|
2457
2457
|
if (raw === void 0) {
|
|
2458
2458
|
return void 0;
|
|
2459
2459
|
}
|
|
@@ -2511,9 +2511,9 @@ function buildEntryFacts(params) {
|
|
|
2511
2511
|
entries
|
|
2512
2512
|
};
|
|
2513
2513
|
}
|
|
2514
|
-
function listSubtree(
|
|
2514
|
+
function listSubtree(fs14, root, rel) {
|
|
2515
2515
|
const absolute = import_node_path7.default.join(root, rel);
|
|
2516
|
-
const stat =
|
|
2516
|
+
const stat = fs14.lstat(absolute);
|
|
2517
2517
|
if (stat === void 0) {
|
|
2518
2518
|
return [];
|
|
2519
2519
|
}
|
|
@@ -2521,10 +2521,10 @@ function listSubtree(fs13, root, rel) {
|
|
|
2521
2521
|
return [{ rel, kind: "symlink" }];
|
|
2522
2522
|
}
|
|
2523
2523
|
if (stat.kind === "dir") {
|
|
2524
|
-
const children = [...
|
|
2524
|
+
const children = [...fs14.readdir(absolute)].sort().flatMap((name) => listSubtree(fs14, root, `${rel}/${name}`));
|
|
2525
2525
|
return [{ rel, kind: "dir" }, ...children];
|
|
2526
2526
|
}
|
|
2527
|
-
const contentHash =
|
|
2527
|
+
const contentHash = fs14.hashFile(absolute);
|
|
2528
2528
|
return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
|
|
2529
2529
|
}
|
|
2530
2530
|
function topLevelScopeRoots(roots) {
|
|
@@ -2538,25 +2538,25 @@ function topLevelScopeRoots(roots) {
|
|
|
2538
2538
|
}
|
|
2539
2539
|
return kept;
|
|
2540
2540
|
}
|
|
2541
|
-
function reconciliationScope(
|
|
2541
|
+
function reconciliationScope(fs14, farmRoot, manifest) {
|
|
2542
2542
|
if (manifest !== void 0) {
|
|
2543
2543
|
return topLevelScopeRoots(manifest.materialised);
|
|
2544
2544
|
}
|
|
2545
|
-
return [...
|
|
2545
|
+
return [...fs14.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs14.lstat(import_node_path7.default.join(farmRoot, name))?.kind === "dir").sort();
|
|
2546
2546
|
}
|
|
2547
|
-
function collectFarmListing(
|
|
2548
|
-
return scopeRoots.flatMap((root) => listSubtree(
|
|
2547
|
+
function collectFarmListing(fs14, farmRoot, scopeRoots) {
|
|
2548
|
+
return scopeRoots.flatMap((root) => listSubtree(fs14, farmRoot, root));
|
|
2549
2549
|
}
|
|
2550
|
-
function collectCanonicalCounterparts(
|
|
2550
|
+
function collectCanonicalCounterparts(fs14, claudeHome, farmListing) {
|
|
2551
2551
|
const out = [];
|
|
2552
2552
|
for (const entry of farmListing) {
|
|
2553
2553
|
const absolute = import_node_path7.default.join(claudeHome, entry.rel);
|
|
2554
|
-
const stat =
|
|
2554
|
+
const stat = fs14.lstat(absolute);
|
|
2555
2555
|
if (stat === void 0) {
|
|
2556
2556
|
continue;
|
|
2557
2557
|
}
|
|
2558
2558
|
if (stat.kind === "file") {
|
|
2559
|
-
const contentHash =
|
|
2559
|
+
const contentHash = fs14.hashFile(absolute);
|
|
2560
2560
|
out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
|
|
2561
2561
|
continue;
|
|
2562
2562
|
}
|
|
@@ -3327,10 +3327,10 @@ var init_route = __esm({
|
|
|
3327
3327
|
});
|
|
3328
3328
|
|
|
3329
3329
|
// src/frontdoor/state.ts
|
|
3330
|
-
function readFrontDoorState(
|
|
3330
|
+
function readFrontDoorState(fs14, stateFile) {
|
|
3331
3331
|
let raw;
|
|
3332
3332
|
try {
|
|
3333
|
-
raw =
|
|
3333
|
+
raw = fs14.readFileUtf8(stateFile);
|
|
3334
3334
|
} catch {
|
|
3335
3335
|
return void 0;
|
|
3336
3336
|
}
|
|
@@ -3344,9 +3344,9 @@ function readFrontDoorState(fs13, stateFile) {
|
|
|
3344
3344
|
return void 0;
|
|
3345
3345
|
}
|
|
3346
3346
|
}
|
|
3347
|
-
function writeFrontDoorState(
|
|
3348
|
-
|
|
3349
|
-
|
|
3347
|
+
function writeFrontDoorState(fs14, stateFile, state) {
|
|
3348
|
+
fs14.mkdirp(import_node_path8.default.dirname(stateFile));
|
|
3349
|
+
fs14.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
3350
3350
|
`);
|
|
3351
3351
|
}
|
|
3352
3352
|
function directOrigin(port) {
|
|
@@ -3356,27 +3356,37 @@ function frontDoorOrigin(state) {
|
|
|
3356
3356
|
const port = state?.directPort ?? state?.lastDirectPort;
|
|
3357
3357
|
return port === void 0 ? void 0 : directOrigin(port);
|
|
3358
3358
|
}
|
|
3359
|
-
function writeFrontDoorDirectRecord(
|
|
3360
|
-
|
|
3361
|
-
|
|
3359
|
+
function writeFrontDoorDirectRecord(fs14, recordsDir, record) {
|
|
3360
|
+
fs14.mkdirp(recordsDir);
|
|
3361
|
+
fs14.writeFilePrivate(import_node_path8.default.join(recordsDir, `${String(record.pid)}.json`), `${JSON.stringify({ directPort: record.directPort })}
|
|
3362
3362
|
`);
|
|
3363
3363
|
}
|
|
3364
|
-
function removeFrontDoorDirectRecord(
|
|
3365
|
-
|
|
3364
|
+
function removeFrontDoorDirectRecord(fs14, recordsDir, pid) {
|
|
3365
|
+
fs14.removeRecursive(import_node_path8.default.join(recordsDir, `${String(pid)}.json`));
|
|
3366
|
+
}
|
|
3367
|
+
function markFrontDoorDraining(fs14, markersDir, pid) {
|
|
3368
|
+
fs14.mkdirp(markersDir);
|
|
3369
|
+
fs14.writeFilePrivate(import_node_path8.default.join(markersDir, String(pid)), "\n");
|
|
3370
|
+
}
|
|
3371
|
+
function unmarkFrontDoorDraining(fs14, markersDir, pid) {
|
|
3372
|
+
fs14.removeRecursive(import_node_path8.default.join(markersDir, String(pid)));
|
|
3373
|
+
}
|
|
3374
|
+
function listDrainingFrontDoors(fs14, markersDir, isRunning) {
|
|
3375
|
+
return fs14.readdir(markersDir).flatMap((file) => /^[1-9]\d*$/.test(file) && Number.isSafeInteger(Number(file)) ? [Number(file)] : []).filter(isRunning).sort((a, b) => a - b);
|
|
3366
3376
|
}
|
|
3367
3377
|
function recordPid(file) {
|
|
3368
3378
|
const pidText = /^([1-9]\d*)\.json$/.exec(file)?.[1];
|
|
3369
3379
|
const pid = pidText === void 0 ? void 0 : Number(pidText);
|
|
3370
3380
|
return pid !== void 0 && Number.isSafeInteger(pid) ? pid : void 0;
|
|
3371
3381
|
}
|
|
3372
|
-
function readDirectRecordEntry(
|
|
3382
|
+
function readDirectRecordEntry(fs14, recordsDir, file) {
|
|
3373
3383
|
const pid = recordPid(file);
|
|
3374
3384
|
if (pid === void 0) {
|
|
3375
3385
|
return void 0;
|
|
3376
3386
|
}
|
|
3377
3387
|
let raw;
|
|
3378
3388
|
try {
|
|
3379
|
-
raw =
|
|
3389
|
+
raw = fs14.readFileUtf8(import_node_path8.default.join(recordsDir, file));
|
|
3380
3390
|
} catch {
|
|
3381
3391
|
return void 0;
|
|
3382
3392
|
}
|
|
@@ -3390,47 +3400,47 @@ function readDirectRecordEntry(fs13, recordsDir, file) {
|
|
|
3390
3400
|
return { malformed: true };
|
|
3391
3401
|
}
|
|
3392
3402
|
}
|
|
3393
|
-
function listFrontDoorDirectRecords(
|
|
3394
|
-
return
|
|
3395
|
-
const entry = readDirectRecordEntry(
|
|
3403
|
+
function listFrontDoorDirectRecords(fs14, recordsDir) {
|
|
3404
|
+
return fs14.readdir(recordsDir).flatMap((file) => {
|
|
3405
|
+
const entry = readDirectRecordEntry(fs14, recordsDir, file);
|
|
3396
3406
|
return entry?.record === void 0 ? [] : [entry.record];
|
|
3397
3407
|
}).sort((a, b) => a.pid - b.pid);
|
|
3398
3408
|
}
|
|
3399
|
-
function pruneMalformedFrontDoorDirectFiles(
|
|
3400
|
-
for (const file of
|
|
3409
|
+
function pruneMalformedFrontDoorDirectFiles(fs14, recordsDir, isRunning) {
|
|
3410
|
+
for (const file of fs14.readdir(recordsDir)) {
|
|
3401
3411
|
const writer = RECORD_TEMPORARY_FILE.exec(file)?.[1];
|
|
3402
3412
|
const stale = writer !== void 0 && !isRunning(Number(writer));
|
|
3403
|
-
if (stale || readDirectRecordEntry(
|
|
3404
|
-
|
|
3413
|
+
if (stale || readDirectRecordEntry(fs14, recordsDir, file)?.malformed === true) {
|
|
3414
|
+
fs14.removeRecursive(import_node_path8.default.join(recordsDir, file));
|
|
3405
3415
|
}
|
|
3406
3416
|
}
|
|
3407
3417
|
}
|
|
3408
3418
|
function liveFrontDoorDirectRecords(records, liveness) {
|
|
3409
3419
|
return records.filter((record) => liveness.doors.has(record.pid) || liveness.unknown.has(record.pid));
|
|
3410
3420
|
}
|
|
3411
|
-
function pruneDeadFrontDoorDirectRecords(
|
|
3421
|
+
function pruneDeadFrontDoorDirectRecords(fs14, recordsDir, records, liveness) {
|
|
3412
3422
|
for (const record of records) {
|
|
3413
3423
|
if (!liveness.doors.has(record.pid) && !liveness.unknown.has(record.pid)) {
|
|
3414
|
-
removeFrontDoorDirectRecord(
|
|
3424
|
+
removeFrontDoorDirectRecord(fs14, recordsDir, record.pid);
|
|
3415
3425
|
}
|
|
3416
3426
|
}
|
|
3417
3427
|
}
|
|
3418
3428
|
function recordOf(details) {
|
|
3419
3429
|
return details === void 0 ? {} : { sessionId: details.sessionId, ...details.models === void 0 ? {} : { models: details.models } };
|
|
3420
3430
|
}
|
|
3421
|
-
function writeFrontDoorSession(
|
|
3422
|
-
|
|
3423
|
-
|
|
3431
|
+
function writeFrontDoorSession(fs14, sessionsDir, session) {
|
|
3432
|
+
fs14.mkdirPrivate(sessionsDir);
|
|
3433
|
+
fs14.writeFilePrivate(import_node_path8.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
3424
3434
|
`);
|
|
3425
3435
|
}
|
|
3426
|
-
function listFrontDoorSessions(
|
|
3436
|
+
function listFrontDoorSessions(fs14, sessionsDir) {
|
|
3427
3437
|
const sessions = [];
|
|
3428
|
-
for (const name of
|
|
3438
|
+
for (const name of fs14.readdir(sessionsDir)) {
|
|
3429
3439
|
if (!name.endsWith(".json")) {
|
|
3430
3440
|
continue;
|
|
3431
3441
|
}
|
|
3432
3442
|
try {
|
|
3433
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(
|
|
3443
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs14.readFileUtf8(import_node_path8.default.join(sessionsDir, name)) ?? ""));
|
|
3434
3444
|
if (parsed.success) {
|
|
3435
3445
|
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
|
|
3436
3446
|
}
|
|
@@ -3440,14 +3450,14 @@ function listFrontDoorSessions(fs13, sessionsDir) {
|
|
|
3440
3450
|
}
|
|
3441
3451
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
3442
3452
|
}
|
|
3443
|
-
function removeFrontDoorSession(
|
|
3444
|
-
|
|
3453
|
+
function removeFrontDoorSession(fs14, sessionsDir, pid) {
|
|
3454
|
+
fs14.removeRecursive(import_node_path8.default.join(sessionsDir, `${String(pid)}.json`));
|
|
3445
3455
|
}
|
|
3446
|
-
function pruneDeadFrontDoorSessions(
|
|
3456
|
+
function pruneDeadFrontDoorSessions(fs14, sessionsDir, isRunning) {
|
|
3447
3457
|
const removed = [];
|
|
3448
|
-
for (const session of listFrontDoorSessions(
|
|
3458
|
+
for (const session of listFrontDoorSessions(fs14, sessionsDir)) {
|
|
3449
3459
|
if (!isRunning(session.pid)) {
|
|
3450
|
-
removeFrontDoorSession(
|
|
3460
|
+
removeFrontDoorSession(fs14, sessionsDir, session.pid);
|
|
3451
3461
|
removed.push(session.pid);
|
|
3452
3462
|
}
|
|
3453
3463
|
}
|
|
@@ -3545,9 +3555,9 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
3545
3555
|
}
|
|
3546
3556
|
}
|
|
3547
3557
|
async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
3548
|
-
const { fs:
|
|
3558
|
+
const { fs: fs14, paths } = ports;
|
|
3549
3559
|
const servingBinary = ports.statOwnExecutable();
|
|
3550
|
-
const previous = readFrontDoorState(
|
|
3560
|
+
const previous = readFrontDoorState(fs14, paths.frontdoorStateFile);
|
|
3551
3561
|
let lastPort = previous?.lastPort;
|
|
3552
3562
|
let lastConnectPort = previous?.lastConnectPort;
|
|
3553
3563
|
let lastDirectPort = previous?.lastDirectPort;
|
|
@@ -3558,12 +3568,12 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3558
3568
|
});
|
|
3559
3569
|
const fail = (message) => {
|
|
3560
3570
|
ports.closeRcStreamHub();
|
|
3561
|
-
writeFrontDoorState(
|
|
3562
|
-
|
|
3571
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, { lastError: message, ...sticky() });
|
|
3572
|
+
fs14.removeRecursive(paths.frontdoorLockFile);
|
|
3563
3573
|
ports.log(`agent-shim frontdoor supervisor: ${message}`);
|
|
3564
3574
|
return 1;
|
|
3565
3575
|
};
|
|
3566
|
-
writeFrontDoorState(
|
|
3576
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
|
|
3567
3577
|
const previousSticky = lastPort;
|
|
3568
3578
|
let http3;
|
|
3569
3579
|
try {
|
|
@@ -3603,16 +3613,16 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3603
3613
|
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)`);
|
|
3604
3614
|
}
|
|
3605
3615
|
lastDirectPort = direct.port;
|
|
3606
|
-
writeFrontDoorDirectRecord(
|
|
3607
|
-
writeFrontDoorState(
|
|
3616
|
+
writeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, { pid: ports.ownPid, directPort: direct.port });
|
|
3617
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
3608
3618
|
ports.doorHealth.generation({ providerPort: http3.port, connectPort: connect3.port, directPort: direct.port });
|
|
3609
|
-
|
|
3619
|
+
fs14.removeRecursive(paths.frontdoorLockFile);
|
|
3610
3620
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http3.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
|
|
3611
3621
|
const watchdog = ports.startWatchdog?.();
|
|
3612
3622
|
let idleSince;
|
|
3613
3623
|
let ticks = 0;
|
|
3614
3624
|
const supersedingOwner = () => {
|
|
3615
|
-
const owner = readFrontDoorState(
|
|
3625
|
+
const owner = readFrontDoorState(fs14, paths.frontdoorStateFile)?.supervisorPid;
|
|
3616
3626
|
return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
|
|
3617
3627
|
};
|
|
3618
3628
|
let supersededBy;
|
|
@@ -3621,30 +3631,61 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3621
3631
|
const current = ports.statOwnExecutable();
|
|
3622
3632
|
return current !== void 0 && servingBinary !== void 0 && (current.dev !== servingBinary.dev || current.ino !== servingBinary.ino || current.size !== servingBinary.size || current.mtimeMs !== servingBinary.mtimeMs);
|
|
3623
3633
|
};
|
|
3634
|
+
const pause = async () => {
|
|
3635
|
+
await new Promise((resolve) => {
|
|
3636
|
+
const wake = () => {
|
|
3637
|
+
resolve();
|
|
3638
|
+
};
|
|
3639
|
+
ports.retire?.addEventListener("abort", wake, { once: true });
|
|
3640
|
+
void ports.sleep(FRONTDOOR_POLL_MS).then(() => {
|
|
3641
|
+
ports.retire?.removeEventListener("abort", wake);
|
|
3642
|
+
resolve();
|
|
3643
|
+
});
|
|
3644
|
+
});
|
|
3645
|
+
};
|
|
3646
|
+
const retireByDrain = async () => {
|
|
3647
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: asked to exit; releasing the front door's addresses and finishing the connections it carries`);
|
|
3648
|
+
watchdog?.stop();
|
|
3649
|
+
ports.stopBackgroundWork?.();
|
|
3650
|
+
const drained = [direct.drain(), connect3.drain(), http3.drain()];
|
|
3651
|
+
if (supersedingOwner() === void 0) {
|
|
3652
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
|
|
3653
|
+
}
|
|
3654
|
+
markFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
|
|
3655
|
+
ports.closeRcStreamHub();
|
|
3656
|
+
await Promise.all(drained);
|
|
3657
|
+
unmarkFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
|
|
3658
|
+
removeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, ports.ownPid);
|
|
3659
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: the connections this door carried have ended; exiting`);
|
|
3660
|
+
return 0;
|
|
3661
|
+
};
|
|
3624
3662
|
const closeServing = async () => {
|
|
3625
3663
|
watchdog?.stop();
|
|
3626
3664
|
await direct.close();
|
|
3627
3665
|
await connect3.close();
|
|
3628
3666
|
await http3.close();
|
|
3629
3667
|
ports.closeRcStreamHub();
|
|
3630
|
-
removeFrontDoorDirectRecord(
|
|
3668
|
+
removeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, ports.ownPid);
|
|
3631
3669
|
};
|
|
3632
3670
|
const shutdown = async () => {
|
|
3633
3671
|
await closeServing();
|
|
3634
3672
|
if (supersedingOwner() === void 0) {
|
|
3635
|
-
writeFrontDoorState(
|
|
3673
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
|
|
3636
3674
|
}
|
|
3637
3675
|
return 0;
|
|
3638
3676
|
};
|
|
3639
3677
|
for (; ; ) {
|
|
3640
3678
|
watchdog?.beat();
|
|
3679
|
+
if (ports.retire?.aborted === true) {
|
|
3680
|
+
return await retireByDrain();
|
|
3681
|
+
}
|
|
3641
3682
|
if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
|
|
3642
3683
|
watchdog?.stop();
|
|
3643
3684
|
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
3644
3685
|
}
|
|
3645
3686
|
ticks += 1;
|
|
3646
|
-
const listed = listFrontDoorSessions(
|
|
3647
|
-
const pruned = pruneDeadFrontDoorSessions(
|
|
3687
|
+
const listed = listFrontDoorSessions(fs14, paths.frontdoorSessionsDir);
|
|
3688
|
+
const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, ports.isRunning);
|
|
3648
3689
|
ports.observeLaunchRegistry(listed, pruned);
|
|
3649
3690
|
ports.checkQuotaExpiry();
|
|
3650
3691
|
const prunedPids = new Set(pruned);
|
|
@@ -3654,7 +3695,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3654
3695
|
if (supersededBy !== void 0) {
|
|
3655
3696
|
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: supervisor ${String(supersededBy)} now owns the front door; taking no new sessions and exiting once the sessions this door serves have ended`);
|
|
3656
3697
|
ports.doorHealth.superseded(supersededBy);
|
|
3657
|
-
await
|
|
3698
|
+
await pause();
|
|
3658
3699
|
continue;
|
|
3659
3700
|
}
|
|
3660
3701
|
} else {
|
|
@@ -3666,7 +3707,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3666
3707
|
await closeServing();
|
|
3667
3708
|
return 0;
|
|
3668
3709
|
}
|
|
3669
|
-
await
|
|
3710
|
+
await pause();
|
|
3670
3711
|
continue;
|
|
3671
3712
|
}
|
|
3672
3713
|
if (live.length === 0) {
|
|
@@ -3684,7 +3725,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3684
3725
|
} else {
|
|
3685
3726
|
idleSince = void 0;
|
|
3686
3727
|
}
|
|
3687
|
-
await
|
|
3728
|
+
await pause();
|
|
3688
3729
|
}
|
|
3689
3730
|
}
|
|
3690
3731
|
var import_node_path9, FRONTDOOR_SUPERVISOR_STILL_RUNNING, FRONTDOOR_POLL_MS, MS_PER_MINUTE;
|
|
@@ -3837,25 +3878,35 @@ ${request4.rawHeaders.reduce((accumulated, value, index) => index % 2 === 0 ? `$
|
|
|
3837
3878
|
const transparent = config.transparentPort === void 0 || apiSession === void 0 ? void 0 : await effects.listenLoopback(config.transparentPort, (socket) => {
|
|
3838
3879
|
sniAcceptor.accept(socket);
|
|
3839
3880
|
});
|
|
3881
|
+
const closeSurface = async () => {
|
|
3882
|
+
ledger.close();
|
|
3883
|
+
await listener.close();
|
|
3884
|
+
await transparent?.close();
|
|
3885
|
+
sniAcceptor.close();
|
|
3886
|
+
for (const { httpSession, tlsAcceptor } of sessions) {
|
|
3887
|
+
tlsAcceptor.close();
|
|
3888
|
+
httpSession?.close();
|
|
3889
|
+
}
|
|
3890
|
+
};
|
|
3840
3891
|
return {
|
|
3841
3892
|
port: listener.port,
|
|
3842
3893
|
...transparent === void 0 ? {} : { transparentPort: transparent.port },
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3894
|
+
openTunnels: ledger.openTunnels,
|
|
3895
|
+
drain: async () => {
|
|
3896
|
+
listener.stopAccepting();
|
|
3846
3897
|
await transparent?.close();
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
}
|
|
3852
|
-
}
|
|
3898
|
+
await ledger.retire();
|
|
3899
|
+
await closeSurface();
|
|
3900
|
+
},
|
|
3901
|
+
close: closeSurface
|
|
3853
3902
|
};
|
|
3854
3903
|
}
|
|
3855
3904
|
function createConnectionLedger(limits, isLiveCapability2) {
|
|
3856
3905
|
const pending = /* @__PURE__ */ new Map();
|
|
3857
3906
|
const authenticated = /* @__PURE__ */ new Map();
|
|
3858
3907
|
let tunnels = 0;
|
|
3908
|
+
const blind = /* @__PURE__ */ new Set();
|
|
3909
|
+
let onNoBlindTunnels;
|
|
3859
3910
|
const leavePending = (socket) => {
|
|
3860
3911
|
const deadline = pending.get(socket);
|
|
3861
3912
|
if (deadline !== void 0) {
|
|
@@ -3892,16 +3943,45 @@ function createConnectionLedger(limits, isLiveCapability2) {
|
|
|
3892
3943
|
});
|
|
3893
3944
|
},
|
|
3894
3945
|
headReceived: leavePending,
|
|
3895
|
-
|
|
3946
|
+
openTunnels: () => tunnels,
|
|
3947
|
+
retire: async () => {
|
|
3948
|
+
for (const socket of pending.keys()) {
|
|
3949
|
+
socket.destroy();
|
|
3950
|
+
}
|
|
3951
|
+
for (const deadline of pending.values()) {
|
|
3952
|
+
clearTimeout(deadline);
|
|
3953
|
+
}
|
|
3954
|
+
pending.clear();
|
|
3955
|
+
for (const sockets of authenticated.values()) {
|
|
3956
|
+
for (const socket of sockets) {
|
|
3957
|
+
if (!blind.has(socket)) {
|
|
3958
|
+
socket.destroy();
|
|
3959
|
+
}
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3962
|
+
if (blind.size > 0) {
|
|
3963
|
+
await new Promise((resolve) => {
|
|
3964
|
+
onNoBlindTunnels = resolve;
|
|
3965
|
+
});
|
|
3966
|
+
}
|
|
3967
|
+
},
|
|
3968
|
+
establish: (socket, capability, kind) => {
|
|
3896
3969
|
if (tunnels >= limits.maxTunnels) {
|
|
3897
3970
|
return false;
|
|
3898
3971
|
}
|
|
3899
3972
|
tunnels += 1;
|
|
3973
|
+
if (kind === "blind") {
|
|
3974
|
+
blind.add(socket);
|
|
3975
|
+
}
|
|
3900
3976
|
const sockets = authenticated.get(capability) ?? /* @__PURE__ */ new Set();
|
|
3901
3977
|
sockets.add(socket);
|
|
3902
3978
|
authenticated.set(capability, sockets);
|
|
3903
3979
|
socket.once("close", () => {
|
|
3904
3980
|
tunnels -= 1;
|
|
3981
|
+
blind.delete(socket);
|
|
3982
|
+
if (blind.size === 0) {
|
|
3983
|
+
onNoBlindTunnels?.();
|
|
3984
|
+
}
|
|
3905
3985
|
sockets.delete(socket);
|
|
3906
3986
|
if (sockets.size === 0 && authenticated.get(capability) === sockets) {
|
|
3907
3987
|
authenticated.delete(capability);
|
|
@@ -3983,11 +4063,11 @@ function routeConnect(socket, head, context) {
|
|
|
3983
4063
|
refuse(socket, REFUSAL.badRequest);
|
|
3984
4064
|
return;
|
|
3985
4065
|
}
|
|
3986
|
-
|
|
4066
|
+
const session = sessions.find((entry) => entry.host === target.host);
|
|
4067
|
+
if (!ledger.establish(socket, capability, session === void 0 ? "blind" : "terminated")) {
|
|
3987
4068
|
refuse(socket, REFUSAL.serviceUnavailable);
|
|
3988
4069
|
return;
|
|
3989
4070
|
}
|
|
3990
|
-
const session = sessions.find((entry) => entry.host === target.host);
|
|
3991
4071
|
config.capture?.connect(target, session !== void 0);
|
|
3992
4072
|
socket.write(CONNECT_ESTABLISHED);
|
|
3993
4073
|
if (session !== void 0) {
|
|
@@ -4111,7 +4191,7 @@ var init_package = __esm({
|
|
|
4111
4191
|
"package.json"() {
|
|
4112
4192
|
package_default = {
|
|
4113
4193
|
name: "claude-use",
|
|
4114
|
-
version: "11.
|
|
4194
|
+
version: "11.49.0",
|
|
4115
4195
|
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.",
|
|
4116
4196
|
license: "MIT",
|
|
4117
4197
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -4316,43 +4396,43 @@ function parseJson(raw, schema) {
|
|
|
4316
4396
|
const parsed = schema.safeParse(JSON.parse(raw));
|
|
4317
4397
|
return parsed.success ? parsed.data : void 0;
|
|
4318
4398
|
}
|
|
4319
|
-
function readHeadroomState(
|
|
4399
|
+
function readHeadroomState(fs14, stateFile) {
|
|
4320
4400
|
try {
|
|
4321
|
-
return parseJson(
|
|
4401
|
+
return parseJson(fs14.readFileUtf8(stateFile), HeadroomStateSchema);
|
|
4322
4402
|
} catch {
|
|
4323
4403
|
return void 0;
|
|
4324
4404
|
}
|
|
4325
4405
|
}
|
|
4326
|
-
function writeHeadroomState(
|
|
4327
|
-
|
|
4328
|
-
|
|
4406
|
+
function writeHeadroomState(fs14, stateFile, state) {
|
|
4407
|
+
fs14.mkdirp(import_node_path11.default.dirname(stateFile));
|
|
4408
|
+
fs14.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
4329
4409
|
`);
|
|
4330
4410
|
}
|
|
4331
|
-
function resolveServingHeadroomState(
|
|
4332
|
-
const current = readHeadroomState(
|
|
4411
|
+
function resolveServingHeadroomState(fs14, files, isRunning) {
|
|
4412
|
+
const current = readHeadroomState(fs14, files.stateFile);
|
|
4333
4413
|
if (current !== void 0) {
|
|
4334
4414
|
return { path: files.stateFile, state: current };
|
|
4335
4415
|
}
|
|
4336
|
-
const legacy = readHeadroomState(
|
|
4416
|
+
const legacy = readHeadroomState(fs14, files.legacyStateFile);
|
|
4337
4417
|
if (legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid)) {
|
|
4338
4418
|
return { path: files.legacyStateFile, state: legacy };
|
|
4339
4419
|
}
|
|
4340
4420
|
return void 0;
|
|
4341
4421
|
}
|
|
4342
|
-
function migrateHeadroomState(
|
|
4343
|
-
const legacy = readHeadroomState(
|
|
4422
|
+
function migrateHeadroomState(fs14, files, isRunning) {
|
|
4423
|
+
const legacy = readHeadroomState(fs14, files.legacyStateFile);
|
|
4344
4424
|
const legacyLive = legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid);
|
|
4345
|
-
const current = readHeadroomState(
|
|
4425
|
+
const current = readHeadroomState(fs14, files.stateFile);
|
|
4346
4426
|
if (current !== void 0 || legacyLive) {
|
|
4347
|
-
if (!legacyLive &&
|
|
4348
|
-
|
|
4427
|
+
if (!legacyLive && fs14.readFileUtf8(files.legacyStateFile) !== void 0) {
|
|
4428
|
+
fs14.removeRecursive(files.legacyStateFile);
|
|
4349
4429
|
}
|
|
4350
4430
|
return;
|
|
4351
4431
|
}
|
|
4352
4432
|
if (legacy !== void 0) {
|
|
4353
|
-
writeHeadroomState(
|
|
4433
|
+
writeHeadroomState(fs14, files.stateFile, legacy);
|
|
4354
4434
|
}
|
|
4355
|
-
|
|
4435
|
+
fs14.removeRecursive(files.legacyStateFile);
|
|
4356
4436
|
}
|
|
4357
4437
|
function hashAllowlist(allowlist) {
|
|
4358
4438
|
return (0, import_node_crypto6.createHash)("sha256").update(allowlist.join("\n")).digest("hex");
|
|
@@ -4385,27 +4465,27 @@ function isAdmissibleUrl(entry) {
|
|
|
4385
4465
|
function parseAllowlistFile(content) {
|
|
4386
4466
|
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)));
|
|
4387
4467
|
}
|
|
4388
|
-
function writeAllowlistFile(
|
|
4389
|
-
|
|
4390
|
-
|
|
4468
|
+
function writeAllowlistFile(fs14, allowlistFile, allowlist) {
|
|
4469
|
+
fs14.mkdirPrivate(import_node_path11.default.dirname(allowlistFile));
|
|
4470
|
+
fs14.writeFilePrivate(allowlistFile, formatAllowlistFile(allowlist));
|
|
4391
4471
|
}
|
|
4392
|
-
function pruneStaleAllowlistTemporaries(
|
|
4472
|
+
function pruneStaleAllowlistTemporaries(fs14, allowlistFile, isRunning) {
|
|
4393
4473
|
const prefix = `${import_node_path11.default.basename(allowlistFile)}.`;
|
|
4394
|
-
for (const name of
|
|
4474
|
+
for (const name of fs14.readdir(import_node_path11.default.dirname(allowlistFile))) {
|
|
4395
4475
|
const writer = name.startsWith(prefix) ? /^([1-9]\d*)\.tmp$/.exec(name.slice(prefix.length))?.[1] : void 0;
|
|
4396
4476
|
if (writer !== void 0 && !isRunning(Number(writer))) {
|
|
4397
|
-
|
|
4477
|
+
fs14.removeRecursive(import_node_path11.default.join(import_node_path11.default.dirname(allowlistFile), name));
|
|
4398
4478
|
}
|
|
4399
4479
|
}
|
|
4400
4480
|
}
|
|
4401
|
-
function readAllProviders(
|
|
4481
|
+
function readAllProviders(fs14, providersDir) {
|
|
4402
4482
|
const result = [];
|
|
4403
|
-
for (const name of
|
|
4483
|
+
for (const name of fs14.readdir(providersDir)) {
|
|
4404
4484
|
if (!name.endsWith(".json")) {
|
|
4405
4485
|
continue;
|
|
4406
4486
|
}
|
|
4407
4487
|
try {
|
|
4408
|
-
const parsed = parseJson(
|
|
4488
|
+
const parsed = parseJson(fs14.readFileUtf8(import_node_path11.default.join(providersDir, name)), ProviderSchema);
|
|
4409
4489
|
if (parsed !== void 0) {
|
|
4410
4490
|
result.push({ name: name.slice(0, -".json".length), provider: parsed });
|
|
4411
4491
|
}
|
|
@@ -4415,22 +4495,22 @@ function readAllProviders(fs13, providersDir) {
|
|
|
4415
4495
|
}
|
|
4416
4496
|
return result;
|
|
4417
4497
|
}
|
|
4418
|
-
function writeSession(
|
|
4419
|
-
|
|
4420
|
-
|
|
4498
|
+
function writeSession(fs14, sessionsDir, session) {
|
|
4499
|
+
fs14.mkdirp(sessionsDir);
|
|
4500
|
+
fs14.writeFileUtf8(import_node_path11.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
4421
4501
|
`);
|
|
4422
4502
|
}
|
|
4423
|
-
function removeSession(
|
|
4424
|
-
|
|
4503
|
+
function removeSession(fs14, sessionsDir, pid) {
|
|
4504
|
+
fs14.removeRecursive(import_node_path11.default.join(sessionsDir, `${String(pid)}.json`));
|
|
4425
4505
|
}
|
|
4426
|
-
function listSessions(
|
|
4506
|
+
function listSessions(fs14, sessionsDir) {
|
|
4427
4507
|
const sessions = [];
|
|
4428
|
-
for (const name of
|
|
4508
|
+
for (const name of fs14.readdir(sessionsDir)) {
|
|
4429
4509
|
if (!name.endsWith(".json")) {
|
|
4430
4510
|
continue;
|
|
4431
4511
|
}
|
|
4432
4512
|
try {
|
|
4433
|
-
const parsed = parseJson(
|
|
4513
|
+
const parsed = parseJson(fs14.readFileUtf8(import_node_path11.default.join(sessionsDir, name)), HeadroomSessionSchema);
|
|
4434
4514
|
if (parsed !== void 0) {
|
|
4435
4515
|
sessions.push(parsed);
|
|
4436
4516
|
}
|
|
@@ -4440,22 +4520,22 @@ function listSessions(fs13, sessionsDir) {
|
|
|
4440
4520
|
}
|
|
4441
4521
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
4442
4522
|
}
|
|
4443
|
-
function sessionsForSupervisor(
|
|
4444
|
-
return listSessions(
|
|
4523
|
+
function sessionsForSupervisor(fs14, sessionsDir, supervisorPid) {
|
|
4524
|
+
return listSessions(fs14, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
|
|
4445
4525
|
}
|
|
4446
|
-
function pruneDeadSessions(
|
|
4526
|
+
function pruneDeadSessions(fs14, sessionsDir, isRunning) {
|
|
4447
4527
|
const removed = [];
|
|
4448
|
-
for (const session of listSessions(
|
|
4528
|
+
for (const session of listSessions(fs14, sessionsDir)) {
|
|
4449
4529
|
if (!isRunning(session.pid)) {
|
|
4450
|
-
removeSession(
|
|
4530
|
+
removeSession(fs14, sessionsDir, session.pid);
|
|
4451
4531
|
removed.push(session.pid);
|
|
4452
4532
|
}
|
|
4453
4533
|
}
|
|
4454
4534
|
return removed;
|
|
4455
4535
|
}
|
|
4456
|
-
function readStartLock(
|
|
4536
|
+
function readStartLock(fs14, lockFile) {
|
|
4457
4537
|
try {
|
|
4458
|
-
return parseJson(
|
|
4538
|
+
return parseJson(fs14.readFileUtf8(lockFile), HeadroomLockSchema);
|
|
4459
4539
|
} catch {
|
|
4460
4540
|
return void 0;
|
|
4461
4541
|
}
|
|
@@ -4548,12 +4628,12 @@ function earlierReleaseAllowlistHash(providers, doorOrigin) {
|
|
|
4548
4628
|
}
|
|
4549
4629
|
return hashAllowlist([...entries].sort());
|
|
4550
4630
|
}
|
|
4551
|
-
function earlierReleaseDaemon(
|
|
4631
|
+
function earlierReleaseDaemon(fs14, paths, daemon) {
|
|
4552
4632
|
if (daemonIdentity(daemon.commandLine, daemon.socketPath) !== "earlier-release") {
|
|
4553
4633
|
return void 0;
|
|
4554
4634
|
}
|
|
4555
|
-
const providers = readAllProviders(
|
|
4556
|
-
const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(
|
|
4635
|
+
const providers = readAllProviders(fs14, paths.providersDir).map((entry) => entry.provider);
|
|
4636
|
+
const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile)));
|
|
4557
4637
|
return { admitsServingDoor: daemon.recordedHash === expected };
|
|
4558
4638
|
}
|
|
4559
4639
|
var EARLIER_RELEASE_ALLOWLIST, EARLIER_RELEASE_ANTHROPIC_UPSTREAM;
|
|
@@ -4578,8 +4658,8 @@ function awaitingCause(daemonPid, identity, allowlistFile) {
|
|
|
4578
4658
|
}
|
|
4579
4659
|
return `the headroom supervisor has not written an allowlist admitting this launch's upstreams to ${allowlistFile} within ${String(HEADROOM_START_TIMEOUT_MS)}ms`;
|
|
4580
4660
|
}
|
|
4581
|
-
function daemonAdmits(
|
|
4582
|
-
const content =
|
|
4661
|
+
function daemonAdmits(fs14, allowlistFile, recordedHash, required) {
|
|
4662
|
+
const content = fs14.readFileUtf8(allowlistFile);
|
|
4583
4663
|
if (content === void 0 || recordedHash === void 0) {
|
|
4584
4664
|
return false;
|
|
4585
4665
|
}
|
|
@@ -4842,7 +4922,7 @@ function verifyAllowlistFile(allowlistFile, ports) {
|
|
|
4842
4922
|
const replaceable = fileStat === void 0 || fileStat.kind === "file" || fileStat.kind === "symlink";
|
|
4843
4923
|
return { message: refusal2, repairable: replaceable };
|
|
4844
4924
|
}
|
|
4845
|
-
function prepareHeadroomSocket(
|
|
4925
|
+
function prepareHeadroomSocket(fs14, ports, paths, supervisorPid) {
|
|
4846
4926
|
const unsupported = platformRefusal(ports.platform);
|
|
4847
4927
|
if (unsupported !== void 0) {
|
|
4848
4928
|
return { refused: unsupported };
|
|
@@ -4857,18 +4937,18 @@ function prepareHeadroomSocket(fs13, ports, paths, supervisorPid) {
|
|
|
4857
4937
|
if (ports.lstat(paths.headroomSocketDir)?.kind === "symlink") {
|
|
4858
4938
|
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
4859
4939
|
}
|
|
4860
|
-
|
|
4940
|
+
fs14.mkdirPrivate(paths.headroomSocketDir);
|
|
4861
4941
|
const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
4862
4942
|
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
4863
4943
|
}
|
|
4864
|
-
function pruneStaleHeadroomSockets(
|
|
4944
|
+
function pruneStaleHeadroomSockets(fs14, paths, isRunning) {
|
|
4865
4945
|
const removed = [];
|
|
4866
|
-
for (const name of
|
|
4946
|
+
for (const name of fs14.readdir(paths.headroomSocketDir)) {
|
|
4867
4947
|
const pid = HEADROOM_SOCKET_NAME.exec(name)?.[1];
|
|
4868
4948
|
if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
|
|
4869
4949
|
continue;
|
|
4870
4950
|
}
|
|
4871
|
-
|
|
4951
|
+
fs14.removeRecursive(import_node_path12.default.join(paths.headroomSocketDir, name));
|
|
4872
4952
|
removed.push(name);
|
|
4873
4953
|
}
|
|
4874
4954
|
return removed;
|
|
@@ -4980,37 +5060,37 @@ function compareVersions2(a, b) {
|
|
|
4980
5060
|
return 0;
|
|
4981
5061
|
}
|
|
4982
5062
|
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
4983
|
-
const { fs:
|
|
5063
|
+
const { fs: fs14, paths } = ports;
|
|
4984
5064
|
let config = initialConfig;
|
|
4985
|
-
migrateHeadroomState(
|
|
4986
|
-
const previousState = resolveServingHeadroomState(
|
|
5065
|
+
migrateHeadroomState(fs14, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
|
|
5066
|
+
const previousState = resolveServingHeadroomState(fs14, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
|
|
4987
5067
|
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
4988
5068
|
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
4989
5069
|
return 0;
|
|
4990
5070
|
}
|
|
4991
5071
|
let installedSource = previousState?.installedSource;
|
|
4992
5072
|
const ownsState = () => {
|
|
4993
|
-
const owner = readHeadroomState(
|
|
5073
|
+
const owner = readHeadroomState(fs14, paths.headroomStateFile)?.supervisorPid;
|
|
4994
5074
|
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
4995
5075
|
};
|
|
4996
5076
|
const writeOwnState = (state) => {
|
|
4997
5077
|
if (!ownsState()) {
|
|
4998
5078
|
return false;
|
|
4999
5079
|
}
|
|
5000
|
-
writeHeadroomState(
|
|
5080
|
+
writeHeadroomState(fs14, paths.headroomStateFile, state);
|
|
5001
5081
|
return true;
|
|
5002
5082
|
};
|
|
5003
5083
|
const fail = (message) => {
|
|
5004
5084
|
if (writeOwnState({ lastError: message })) {
|
|
5005
|
-
|
|
5085
|
+
fs14.removeRecursive(paths.headroomLockFile);
|
|
5006
5086
|
}
|
|
5007
5087
|
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
5008
5088
|
return 1;
|
|
5009
5089
|
};
|
|
5010
5090
|
const syncAllowlistFile = (allowlist) => {
|
|
5011
5091
|
try {
|
|
5012
|
-
if (
|
|
5013
|
-
writeAllowlistFile(
|
|
5092
|
+
if (fs14.readFileUtf8(paths.headroomAllowlistFile) !== formatAllowlistFile(allowlist)) {
|
|
5093
|
+
writeAllowlistFile(fs14, paths.headroomAllowlistFile, allowlist);
|
|
5014
5094
|
ports.log(`agent-shim headroom supervisor: wrote allowlist [${allowlist.join(", ")}] to ${paths.headroomAllowlistFile}`);
|
|
5015
5095
|
}
|
|
5016
5096
|
return void 0;
|
|
@@ -5028,9 +5108,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5028
5108
|
}
|
|
5029
5109
|
ports.log(`agent-shim headroom supervisor: repairing the allowlist file: ${problem.message}`);
|
|
5030
5110
|
try {
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
writeAllowlistFile(
|
|
5111
|
+
fs14.mkdirPrivate(paths.headroomDir);
|
|
5112
|
+
fs14.mkdirPrivate(import_node_path13.default.dirname(paths.headroomAllowlistFile));
|
|
5113
|
+
writeAllowlistFile(fs14, paths.headroomAllowlistFile, allowlist);
|
|
5034
5114
|
} catch (error) {
|
|
5035
5115
|
return `could not write the headroom allowlist file ${paths.headroomAllowlistFile}: ${error instanceof Error ? error.message : String(error)}`;
|
|
5036
5116
|
}
|
|
@@ -5055,20 +5135,20 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5055
5135
|
installedSource = config.source;
|
|
5056
5136
|
return void 0;
|
|
5057
5137
|
};
|
|
5058
|
-
const socket = prepareHeadroomSocket(
|
|
5138
|
+
const socket = prepareHeadroomSocket(fs14, ports.socketTrust, paths, ports.ownPid);
|
|
5059
5139
|
if (socket.refused !== void 0) {
|
|
5060
5140
|
return fail(socket.refused);
|
|
5061
5141
|
}
|
|
5062
5142
|
const { socketPath } = socket;
|
|
5063
|
-
pruneStaleHeadroomSockets(
|
|
5064
|
-
pruneStaleAllowlistTemporaries(
|
|
5143
|
+
pruneStaleHeadroomSockets(fs14, paths, ports.isRunning);
|
|
5144
|
+
pruneStaleAllowlistTemporaries(fs14, paths.headroomAllowlistFile, ports.isRunning);
|
|
5065
5145
|
const installFailure = ensureInstalled();
|
|
5066
5146
|
if (installFailure !== void 0) {
|
|
5067
5147
|
return fail(installFailure);
|
|
5068
5148
|
}
|
|
5069
5149
|
const version = ports.headroomVersion() ?? "unknown";
|
|
5070
5150
|
writeOwnState({ supervisorPid: ports.ownPid, version, installedSource });
|
|
5071
|
-
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(
|
|
5151
|
+
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(fs14, paths, ports.frontDoorLiveness).frontDoorOrigins.join(", ")}]`);
|
|
5072
5152
|
const orphanPid = previousState?.headroomPid;
|
|
5073
5153
|
const orphanSocket = previousState?.socketPath ?? (previousState?.supervisorPid === void 0 ? void 0 : headroomSocketPath(paths, previousState.supervisorPid));
|
|
5074
5154
|
const orphanIdentity = orphanPid === void 0 || orphanSocket === void 0 || !ports.isRunning(orphanPid) ? void 0 : daemonIdentity(ports.daemonCommandLine(orphanPid), orphanSocket);
|
|
@@ -5103,12 +5183,12 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5103
5183
|
ticks += 1;
|
|
5104
5184
|
config = ports.readConfig();
|
|
5105
5185
|
const settingsHash = hashSettings(config.settings);
|
|
5106
|
-
const inputs = currentHeadroomAllowlistInputs(
|
|
5107
|
-
pruneDeadFrontDoorDirectRecords(
|
|
5108
|
-
pruneMalformedFrontDoorDirectFiles(
|
|
5186
|
+
const inputs = currentHeadroomAllowlistInputs(fs14, paths, ports.frontDoorLiveness);
|
|
5187
|
+
pruneDeadFrontDoorDirectRecords(fs14, paths.frontdoorDirectRecordsDir, inputs.frontDoorRecords, inputs.frontDoorLiveness);
|
|
5188
|
+
pruneMalformedFrontDoorDirectFiles(fs14, paths.frontdoorDirectRecordsDir, ports.isRunning);
|
|
5109
5189
|
const allowlist = inputs.frontDoorOrigins;
|
|
5110
5190
|
const allowlistHash = hashAllowlist(allowlist);
|
|
5111
|
-
pruneDeadSessions(
|
|
5191
|
+
pruneDeadSessions(fs14, paths.headroomSessionsDir, ports.isRunning);
|
|
5112
5192
|
const ownsNow = ownsState();
|
|
5113
5193
|
if (!ownsNow && !superseded) {
|
|
5114
5194
|
ports.log("agent-shim headroom supervisor: another supervisor now owns the state file; serving this daemon's own sessions until they end");
|
|
@@ -5155,7 +5235,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5155
5235
|
runningSettingsHash = settingsHash;
|
|
5156
5236
|
const recorded = writeOwnState(servingState(pid));
|
|
5157
5237
|
if (recorded) {
|
|
5158
|
-
|
|
5238
|
+
fs14.removeRecursive(paths.headroomLockFile);
|
|
5159
5239
|
}
|
|
5160
5240
|
idleSince = void 0;
|
|
5161
5241
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on unix socket ${socketPath}`);
|
|
@@ -5183,7 +5263,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5183
5263
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} now serves allowlist [${allowlist.join(", ")}]`);
|
|
5184
5264
|
}
|
|
5185
5265
|
if (runningSettingsHash !== settingsHash || installedSource !== config.source) {
|
|
5186
|
-
if (sessionsForSupervisor(
|
|
5266
|
+
if (sessionsForSupervisor(fs14, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
5187
5267
|
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
5188
5268
|
ports.stopProcess(headroomPid);
|
|
5189
5269
|
headroomPid = void 0;
|
|
@@ -5192,7 +5272,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5192
5272
|
continue;
|
|
5193
5273
|
}
|
|
5194
5274
|
}
|
|
5195
|
-
const sessions = sessionsForSupervisor(
|
|
5275
|
+
const sessions = sessionsForSupervisor(fs14, paths.headroomSessionsDir, ports.ownPid);
|
|
5196
5276
|
if (sessions.length === 0) {
|
|
5197
5277
|
idleSince ??= ports.now();
|
|
5198
5278
|
const idleMs = ports.now() - idleSince;
|
|
@@ -5217,9 +5297,9 @@ function undeterminedFrontDoors(inputs) {
|
|
|
5217
5297
|
return reason === void 0 ? [] : [{ pid: record.pid, origin: directOrigin(record.directPort), reason }];
|
|
5218
5298
|
});
|
|
5219
5299
|
}
|
|
5220
|
-
function currentHeadroomAllowlistInputs(
|
|
5221
|
-
const named = frontDoorOrigin(readFrontDoorState(
|
|
5222
|
-
const records = listFrontDoorDirectRecords(
|
|
5300
|
+
function currentHeadroomAllowlistInputs(fs14, paths, frontDoorLiveness) {
|
|
5301
|
+
const named = frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile));
|
|
5302
|
+
const records = listFrontDoorDirectRecords(fs14, paths.frontdoorDirectRecordsDir);
|
|
5223
5303
|
const liveness = frontDoorLiveness(records.map((record) => record.pid));
|
|
5224
5304
|
const live = liveFrontDoorDirectRecords(records, liveness).map((record) => directOrigin(record.directPort));
|
|
5225
5305
|
return {
|
|
@@ -5228,8 +5308,8 @@ function currentHeadroomAllowlistInputs(fs13, paths, frontDoorLiveness) {
|
|
|
5228
5308
|
frontDoorOrigins: [.../* @__PURE__ */ new Set([...named === void 0 ? [] : [named], ...live])].sort()
|
|
5229
5309
|
};
|
|
5230
5310
|
}
|
|
5231
|
-
function launchRequiredUpstreams(
|
|
5232
|
-
const door = frontDoorOrigin(readFrontDoorState(
|
|
5311
|
+
function launchRequiredUpstreams(fs14, paths) {
|
|
5312
|
+
const door = frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile));
|
|
5233
5313
|
return door === void 0 ? [] : [door];
|
|
5234
5314
|
}
|
|
5235
5315
|
async function waitUntilReady(ports, socketPath, pid) {
|
|
@@ -5954,8 +6034,8 @@ var init_cascade = __esm({
|
|
|
5954
6034
|
function poolNameOf(selector) {
|
|
5955
6035
|
return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
|
|
5956
6036
|
}
|
|
5957
|
-
function readActiveIdentity(
|
|
5958
|
-
const trimmed =
|
|
6037
|
+
function readActiveIdentity(fs14, activeIdentityFile) {
|
|
6038
|
+
const trimmed = fs14.readFileUtf8(activeIdentityFile)?.trim();
|
|
5959
6039
|
return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
|
|
5960
6040
|
}
|
|
5961
6041
|
function isNonEmpty(value) {
|
|
@@ -6002,8 +6082,8 @@ function decideConfigProfile(params) {
|
|
|
6002
6082
|
}
|
|
6003
6083
|
return { source: "none" };
|
|
6004
6084
|
}
|
|
6005
|
-
function loadIdentity(identitiesDir, name,
|
|
6006
|
-
return loadConfigFile(import_node_path17.default.join(identitiesDir, name, "identity.json"), IdentitySchema,
|
|
6085
|
+
function loadIdentity(identitiesDir, name, fs14) {
|
|
6086
|
+
return loadConfigFile(import_node_path17.default.join(identitiesDir, name, "identity.json"), IdentitySchema, fs14.readConfigFile);
|
|
6007
6087
|
}
|
|
6008
6088
|
var import_node_path17, IDENTITY_DECISION_SOURCES, CONFIG_PROFILE_DECISION_SOURCES;
|
|
6009
6089
|
var init_identity = __esm({
|
|
@@ -6245,14 +6325,14 @@ function isIdentityName(name) {
|
|
|
6245
6325
|
function claudeJsonPath(identitiesDir, identity) {
|
|
6246
6326
|
return import_node_path18.default.join(identitiesDir, identity, CLAUDE_JSON);
|
|
6247
6327
|
}
|
|
6248
|
-
function readAccountMetadata(
|
|
6328
|
+
function readAccountMetadata(fs14, identitiesDir, identity) {
|
|
6249
6329
|
if (!isIdentityName(identity)) {
|
|
6250
6330
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
6251
6331
|
}
|
|
6252
|
-
return readAccountMetadataFile(
|
|
6332
|
+
return readAccountMetadataFile(fs14, claudeJsonPath(identitiesDir, identity));
|
|
6253
6333
|
}
|
|
6254
|
-
function readAccountMetadataFile(
|
|
6255
|
-
const raw =
|
|
6334
|
+
function readAccountMetadataFile(fs14, file) {
|
|
6335
|
+
const raw = fs14.readFileUtf8(file);
|
|
6256
6336
|
if (raw === void 0) {
|
|
6257
6337
|
return void 0;
|
|
6258
6338
|
}
|
|
@@ -6282,19 +6362,19 @@ function readAccountMetadataFile(fs13, file) {
|
|
|
6282
6362
|
}
|
|
6283
6363
|
return account.data;
|
|
6284
6364
|
}
|
|
6285
|
-
function createAccountReader(
|
|
6365
|
+
function createAccountReader(fs14, identitiesDir) {
|
|
6286
6366
|
const cache = /* @__PURE__ */ new Map();
|
|
6287
6367
|
return (identity) => {
|
|
6288
6368
|
if (!isIdentityName(identity)) {
|
|
6289
6369
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
6290
6370
|
}
|
|
6291
|
-
const stat =
|
|
6371
|
+
const stat = fs14.lstat(claudeJsonPath(identitiesDir, identity));
|
|
6292
6372
|
const stamp = stat === void 0 ? "absent" : `${String(stat.mtimeMs)}:${String(stat.sizeBytes)}`;
|
|
6293
6373
|
const cached = cache.get(identity);
|
|
6294
6374
|
if (cached?.stamp === stamp) {
|
|
6295
6375
|
return cached.account;
|
|
6296
6376
|
}
|
|
6297
|
-
const account = readAccountMetadata(
|
|
6377
|
+
const account = readAccountMetadata(fs14, identitiesDir, identity);
|
|
6298
6378
|
cache.set(identity, { stamp, account });
|
|
6299
6379
|
return account;
|
|
6300
6380
|
};
|
|
@@ -6878,8 +6958,8 @@ function segmentDay(epochMs) {
|
|
|
6878
6958
|
function segmentName(day, pid) {
|
|
6879
6959
|
return `${day}.${String(pid)}.jsonl`;
|
|
6880
6960
|
}
|
|
6881
|
-
function listLogSegments(
|
|
6882
|
-
return
|
|
6961
|
+
function listLogSegments(fs14, logDir) {
|
|
6962
|
+
return fs14.readdir(logDir).flatMap((name) => {
|
|
6883
6963
|
const match = SEGMENT_RE.exec(name);
|
|
6884
6964
|
const day = match?.[1];
|
|
6885
6965
|
if (day === void 0) {
|
|
@@ -6888,15 +6968,15 @@ function listLogSegments(fs13, logDir) {
|
|
|
6888
6968
|
return [{ name, day, endsAt: Date.parse(`${day}T00:00:00.000Z`) + DAY_MS }];
|
|
6889
6969
|
}).sort((left, right) => left.day.localeCompare(right.day) || left.name.localeCompare(right.name));
|
|
6890
6970
|
}
|
|
6891
|
-
function readUsageLog(
|
|
6971
|
+
function readUsageLog(fs14, logDir, options = {}) {
|
|
6892
6972
|
const { sinceMs } = options;
|
|
6893
6973
|
const records = [];
|
|
6894
6974
|
let invalidLines = 0;
|
|
6895
|
-
for (const segment of listLogSegments(
|
|
6975
|
+
for (const segment of listLogSegments(fs14, logDir)) {
|
|
6896
6976
|
if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
|
|
6897
6977
|
continue;
|
|
6898
6978
|
}
|
|
6899
|
-
const contents =
|
|
6979
|
+
const contents = fs14.readFileUtf8(import_node_path19.default.join(logDir, segment.name));
|
|
6900
6980
|
if (contents === void 0) {
|
|
6901
6981
|
continue;
|
|
6902
6982
|
}
|
|
@@ -6932,9 +7012,9 @@ function snapshotPath(snapshotsDir, identity) {
|
|
|
6932
7012
|
}
|
|
6933
7013
|
return import_node_path19.default.join(snapshotsDir, `${identity}.json`);
|
|
6934
7014
|
}
|
|
6935
|
-
function readUsageSnapshot(
|
|
7015
|
+
function readUsageSnapshot(fs14, snapshotsDir, identity) {
|
|
6936
7016
|
const file = snapshotPath(snapshotsDir, identity);
|
|
6937
|
-
const raw =
|
|
7017
|
+
const raw = fs14.readFileUtf8(file);
|
|
6938
7018
|
if (raw === void 0) {
|
|
6939
7019
|
return void 0;
|
|
6940
7020
|
}
|
|
@@ -6950,8 +7030,8 @@ function readUsageSnapshot(fs13, snapshotsDir, identity) {
|
|
|
6950
7030
|
}
|
|
6951
7031
|
return snapshot.data;
|
|
6952
7032
|
}
|
|
6953
|
-
function listUsageSnapshots(
|
|
6954
|
-
return
|
|
7033
|
+
function listUsageSnapshots(fs14, snapshotsDir) {
|
|
7034
|
+
return fs14.readdir(snapshotsDir).flatMap((name) => {
|
|
6955
7035
|
if (!name.endsWith(".json")) {
|
|
6956
7036
|
return [];
|
|
6957
7037
|
}
|
|
@@ -6959,7 +7039,7 @@ function listUsageSnapshots(fs13, snapshotsDir) {
|
|
|
6959
7039
|
if (!isIdentityName(identity)) {
|
|
6960
7040
|
return [];
|
|
6961
7041
|
}
|
|
6962
|
-
const snapshot = readUsageSnapshot(
|
|
7042
|
+
const snapshot = readUsageSnapshot(fs14, snapshotsDir, identity);
|
|
6963
7043
|
return snapshot === void 0 ? [] : [snapshot];
|
|
6964
7044
|
}).sort((left, right) => left.identity.localeCompare(right.identity));
|
|
6965
7045
|
}
|
|
@@ -6984,11 +7064,11 @@ var init_read = __esm({
|
|
|
6984
7064
|
});
|
|
6985
7065
|
|
|
6986
7066
|
// src/usage/store.ts
|
|
6987
|
-
function pruneUsageLog(
|
|
7067
|
+
function pruneUsageLog(fs14, logDir, nowMs) {
|
|
6988
7068
|
const cutoff = nowMs - USAGE_RETENTION_MS;
|
|
6989
|
-
for (const segment of listLogSegments(
|
|
7069
|
+
for (const segment of listLogSegments(fs14, logDir)) {
|
|
6990
7070
|
if (segment.endsAt <= cutoff) {
|
|
6991
|
-
|
|
7071
|
+
fs14.removeRecursive(import_node_path20.default.join(logDir, segment.name));
|
|
6992
7072
|
}
|
|
6993
7073
|
}
|
|
6994
7074
|
}
|
|
@@ -7017,7 +7097,7 @@ function foldProviderState(current, record) {
|
|
|
7017
7097
|
};
|
|
7018
7098
|
}
|
|
7019
7099
|
function createUsageStore(deps) {
|
|
7020
|
-
const { fs:
|
|
7100
|
+
const { fs: fs14, paths } = deps;
|
|
7021
7101
|
let prunedDay;
|
|
7022
7102
|
const rewriteSnapshot = (identity, fold) => {
|
|
7023
7103
|
if (!isIdentityName(identity)) {
|
|
@@ -7026,7 +7106,7 @@ function createUsageStore(deps) {
|
|
|
7026
7106
|
}
|
|
7027
7107
|
let current;
|
|
7028
7108
|
try {
|
|
7029
|
-
current = readUsageSnapshot(
|
|
7109
|
+
current = readUsageSnapshot(fs14, paths.usageSnapshotsDir, identity);
|
|
7030
7110
|
} catch (error) {
|
|
7031
7111
|
if (!(error instanceof UsageSnapshotError)) {
|
|
7032
7112
|
throw error;
|
|
@@ -7053,8 +7133,8 @@ function createUsageStore(deps) {
|
|
|
7053
7133
|
...account === void 0 ? {} : { account },
|
|
7054
7134
|
providers
|
|
7055
7135
|
});
|
|
7056
|
-
|
|
7057
|
-
|
|
7136
|
+
fs14.mkdirPrivate(paths.usageSnapshotsDir);
|
|
7137
|
+
fs14.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
|
|
7058
7138
|
`);
|
|
7059
7139
|
deps.publish?.(snapshot);
|
|
7060
7140
|
return true;
|
|
@@ -7063,14 +7143,14 @@ function createUsageStore(deps) {
|
|
|
7063
7143
|
record: (input) => {
|
|
7064
7144
|
const record = UsageRecordSchema.parse(input);
|
|
7065
7145
|
const nowMs = deps.now();
|
|
7066
|
-
|
|
7067
|
-
|
|
7146
|
+
fs14.mkdirPrivate(paths.usageDir);
|
|
7147
|
+
fs14.mkdirPrivate(paths.usageLogDir);
|
|
7068
7148
|
const day = segmentDay(nowMs);
|
|
7069
7149
|
if (prunedDay !== day) {
|
|
7070
|
-
pruneUsageLog(
|
|
7150
|
+
pruneUsageLog(fs14, paths.usageLogDir, nowMs);
|
|
7071
7151
|
prunedDay = day;
|
|
7072
7152
|
}
|
|
7073
|
-
|
|
7153
|
+
fs14.appendFilePrivate(import_node_path20.default.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
|
|
7074
7154
|
`);
|
|
7075
7155
|
deps.onRecord?.(record);
|
|
7076
7156
|
if (record.identity !== void 0) {
|
|
@@ -7113,14 +7193,14 @@ var init_store2 = __esm({
|
|
|
7113
7193
|
function errorMessage(error) {
|
|
7114
7194
|
return error instanceof Error ? error.message : String(error);
|
|
7115
7195
|
}
|
|
7116
|
-
function loadPoolMembers(
|
|
7196
|
+
function loadPoolMembers(fs14, paths, identities, nowMs) {
|
|
7117
7197
|
const windowStartMs = nowMs - FIVE_HOUR_WINDOW_MS;
|
|
7118
|
-
const log = readUsageLog(
|
|
7198
|
+
const log = readUsageLog(fs14, paths.usageLogDir, { sinceMs: windowStartMs });
|
|
7119
7199
|
return identities.map((identity) => {
|
|
7120
7200
|
const records = log.records.filter((record) => record.identity === identity && record.provider === ANTHROPIC_PROVIDER && Date.parse(record.at) >= windowStartMs);
|
|
7121
7201
|
try {
|
|
7122
|
-
const snapshot = readUsageSnapshot(
|
|
7123
|
-
const account = readAccountMetadata(
|
|
7202
|
+
const snapshot = readUsageSnapshot(fs14, paths.usageSnapshotsDir, identity);
|
|
7203
|
+
const account = readAccountMetadata(fs14, paths.identitiesDir, identity) ?? snapshot?.account;
|
|
7124
7204
|
return { identity, records, ...snapshot === void 0 ? {} : { snapshot }, ...account === void 0 ? {} : { account } };
|
|
7125
7205
|
} catch (error) {
|
|
7126
7206
|
if (error instanceof UsageSnapshotError || error instanceof AccountMetadataError) {
|
|
@@ -7214,9 +7294,9 @@ function collectPoolIdentities(pools, poolName, stack, found) {
|
|
|
7214
7294
|
collectPoolIdentities(pools, nestedName, childStack, found);
|
|
7215
7295
|
}
|
|
7216
7296
|
}
|
|
7217
|
-
function readPicksFile(
|
|
7297
|
+
function readPicksFile(fs14, file) {
|
|
7218
7298
|
const empty = { schemaVersion: SCHEMA_VERSION, picks: {} };
|
|
7219
|
-
const raw =
|
|
7299
|
+
const raw = fs14.readFileUtf8(file);
|
|
7220
7300
|
if (raw === void 0) {
|
|
7221
7301
|
return { file: empty };
|
|
7222
7302
|
}
|
|
@@ -7229,17 +7309,17 @@ function readPicksFile(fs13, file) {
|
|
|
7229
7309
|
const result = PicksFileSchema.safeParse(parsed);
|
|
7230
7310
|
return result.success ? { file: result.data } : { file: empty, problem: `${file} is not a picks file this agent-shim can read` };
|
|
7231
7311
|
}
|
|
7232
|
-
function readStickyPick(
|
|
7233
|
-
const read = readPicksFile(
|
|
7312
|
+
function readStickyPick(fs14, picksFile, directory) {
|
|
7313
|
+
const read = readPicksFile(fs14, picksFile);
|
|
7234
7314
|
const entry = read.file.picks[directory];
|
|
7235
7315
|
return { ...entry === void 0 ? {} : { sticky: entry }, ...read.problem === void 0 ? {} : { problem: read.problem } };
|
|
7236
7316
|
}
|
|
7237
|
-
function recordStickyPick(
|
|
7238
|
-
const current = readPicksFile(
|
|
7317
|
+
function recordStickyPick(fs14, picksFile, directory, identity, nowMs) {
|
|
7318
|
+
const current = readPicksFile(fs14, picksFile).file.picks;
|
|
7239
7319
|
const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
|
|
7240
7320
|
const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
|
|
7241
|
-
|
|
7242
|
-
|
|
7321
|
+
fs14.mkdirPrivate(import_node_path21.default.dirname(picksFile));
|
|
7322
|
+
fs14.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
|
|
7243
7323
|
`);
|
|
7244
7324
|
}
|
|
7245
7325
|
var import_node_path21, import_zod13, PoolGraphError, SCHEMA_VERSION, PickEntrySchema, PicksFileSchema;
|
|
@@ -7514,6 +7594,7 @@ function buildLayoutPaths(root) {
|
|
|
7514
7594
|
frontdoorControlTokenFile: import_node_path23.default.join(root, "frontdoor", "control-token"),
|
|
7515
7595
|
frontdoorSessionsDir: import_node_path23.default.join(root, "frontdoor", "sessions"),
|
|
7516
7596
|
frontdoorDirectRecordsDir: import_node_path23.default.join(root, "frontdoor", "direct"),
|
|
7597
|
+
frontdoorDrainingDir: import_node_path23.default.join(root, "frontdoor", "draining"),
|
|
7517
7598
|
frontdoorRcCredentialsDir: import_node_path23.default.join(root, "frontdoor", "rc-credentials"),
|
|
7518
7599
|
frontdoorLogPath: import_node_path23.default.join(root, "logs", "frontdoor.log"),
|
|
7519
7600
|
usageDir: import_node_path23.default.join(root, "usage"),
|
|
@@ -8590,12 +8671,12 @@ function decideSignIn(facts) {
|
|
|
8590
8671
|
function credentialsFilePath(farmRoot) {
|
|
8591
8672
|
return import_node_path26.default.join(farmRoot, CREDENTIALS_FILE);
|
|
8592
8673
|
}
|
|
8593
|
-
function identitySignIn(
|
|
8674
|
+
function identitySignIn(fs14, probe, identity) {
|
|
8594
8675
|
const probing = !identity.hasCredentialBlock;
|
|
8595
8676
|
return decideSignIn({
|
|
8596
8677
|
hasCredentialBlock: identity.hasCredentialBlock,
|
|
8597
8678
|
keychainItem: probing && probe.platform === "darwin" && probe.run !== void 0 ? keychainHasItem(probe.run, identity.farmRoot) : void 0,
|
|
8598
|
-
credentialsFile: probing &&
|
|
8679
|
+
credentialsFile: probing && fs14.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
|
|
8599
8680
|
platform: probe.platform
|
|
8600
8681
|
});
|
|
8601
8682
|
}
|
|
@@ -9438,6 +9519,16 @@ var init_update = __esm({
|
|
|
9438
9519
|
}
|
|
9439
9520
|
});
|
|
9440
9521
|
|
|
9522
|
+
// src/frontdoor/replacement.ts
|
|
9523
|
+
function replacementLine(facts) {
|
|
9524
|
+
return `launcher ${String(facts.launcherPid)}: replacing front door; reason=${facts.reason} signal=${facts.signal} door=${String(facts.doorPid)} doorProtocol=${String(facts.doorProtocol)} launcherProtocol=${String(facts.launcherProtocol)} liveSessions=${String(facts.liveSessions)}`;
|
|
9525
|
+
}
|
|
9526
|
+
var init_replacement = __esm({
|
|
9527
|
+
"src/frontdoor/replacement.ts"() {
|
|
9528
|
+
"use strict";
|
|
9529
|
+
}
|
|
9530
|
+
});
|
|
9531
|
+
|
|
9441
9532
|
// src/frontdoor/ensure.ts
|
|
9442
9533
|
function ensureFrontDoor(params) {
|
|
9443
9534
|
const { paths, ports } = params;
|
|
@@ -9448,7 +9539,7 @@ function ensureFrontDoor(params) {
|
|
|
9448
9539
|
let lastRejection;
|
|
9449
9540
|
let busyDoor;
|
|
9450
9541
|
const liveSessionsOn = (doorPid) => listFrontDoorSessions(ports.fs, paths.frontdoorSessionsDir).filter(
|
|
9451
|
-
(session) => session.pid !== params.launcherPid && ports.isRunning(session.pid) && (session.supervisorPid === void 0 || session.supervisorPid === doorPid)
|
|
9542
|
+
(session) => session.pid !== params.launcherPid && ports.isRunning(session.pid) && (session.supervisorPid === void 0 || session.supervisorPid === doorPid || !ports.isRunning(session.supervisorPid))
|
|
9452
9543
|
).length;
|
|
9453
9544
|
const verifyWithRetry = (port) => {
|
|
9454
9545
|
let verdict = ports.verifyListener(port);
|
|
@@ -9458,12 +9549,20 @@ function ensureFrontDoor(params) {
|
|
|
9458
9549
|
}
|
|
9459
9550
|
return verdict;
|
|
9460
9551
|
};
|
|
9461
|
-
const
|
|
9552
|
+
const recordReplacement = (doorPid, doorProtocol, reason, signal) => {
|
|
9553
|
+
ports.recordReplacement(
|
|
9554
|
+
replacementLine({ reason, signal, launcherPid: params.launcherPid, launcherProtocol: FRONT_DOOR_PROTOCOL, doorPid, doorProtocol, liveSessions: liveSessionsOn(doorPid) })
|
|
9555
|
+
);
|
|
9556
|
+
};
|
|
9557
|
+
const stopAndAwaitExit = (supervisorPid, doorProtocol, reason, failure) => {
|
|
9558
|
+
recordReplacement(supervisorPid, doorProtocol, reason, "SIGTERM");
|
|
9462
9559
|
ports.stopSupervisor(supervisorPid);
|
|
9463
9560
|
const graceEnds = ports.now() + FRONTDOOR_EXIT_GRACE_MS;
|
|
9464
9561
|
let killed = false;
|
|
9465
|
-
|
|
9562
|
+
const holdsAddresses = () => ports.isRunning(supervisorPid) && readFrontDoorState(ports.fs, paths.frontdoorStateFile)?.supervisorPid === supervisorPid;
|
|
9563
|
+
while (holdsAddresses()) {
|
|
9466
9564
|
if (!killed && ports.now() >= graceEnds) {
|
|
9565
|
+
recordReplacement(supervisorPid, doorProtocol, reason, "SIGKILL");
|
|
9467
9566
|
ports.killSupervisor(supervisorPid);
|
|
9468
9567
|
killed = true;
|
|
9469
9568
|
}
|
|
@@ -9478,16 +9577,19 @@ function ensureFrontDoor(params) {
|
|
|
9478
9577
|
const supervisorPid = state?.supervisorPid;
|
|
9479
9578
|
if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
|
|
9480
9579
|
if (state?.port !== void 0 && state.connectPort !== void 0) {
|
|
9481
|
-
if (supervisorPid === params.launcherPid && params.replace
|
|
9580
|
+
if (supervisorPid === params.launcherPid && params.replace === void 0 && ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
9482
9581
|
const token = (0, import_node_crypto10.randomUUID)();
|
|
9483
9582
|
writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid, ...recordOf(params.session) });
|
|
9484
9583
|
return { port: state.port, connectPort: state.connectPort, token };
|
|
9485
9584
|
}
|
|
9486
9585
|
const verdict = verifyWithRetry(state.port);
|
|
9487
|
-
|
|
9586
|
+
const doorProtocol = state.protocol ?? 0;
|
|
9587
|
+
if (verdict.ok && !replaced && !spawned && (params.replace !== void 0 || doorProtocol < FRONT_DOOR_PROTOCOL)) {
|
|
9488
9588
|
stopAndAwaitExit(
|
|
9489
9589
|
supervisorPid,
|
|
9490
|
-
|
|
9590
|
+
doorProtocol,
|
|
9591
|
+
params.replace ?? "protocol-older",
|
|
9592
|
+
`the front door (pid ${String(supervisorPid)}, protocol ${String(doorProtocol)}; this launcher speaks protocol ${String(FRONT_DOOR_PROTOCOL)}) was asked to be replaced and did not exit`
|
|
9491
9593
|
);
|
|
9492
9594
|
replaced = true;
|
|
9493
9595
|
continue;
|
|
@@ -9503,15 +9605,15 @@ function ensureFrontDoor(params) {
|
|
|
9503
9605
|
}
|
|
9504
9606
|
if (ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
9505
9607
|
const stranded = liveSessionsOn(supervisorPid);
|
|
9506
|
-
if (params.replace
|
|
9507
|
-
stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
9608
|
+
if (params.replace !== void 0 && !replaced) {
|
|
9609
|
+
stopAndAwaitExit(supervisorPid, doorProtocol, "probe-failed-restart", `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
9508
9610
|
replaced = true;
|
|
9509
9611
|
continue;
|
|
9510
9612
|
}
|
|
9511
9613
|
if (stranded > 0) {
|
|
9512
9614
|
busyDoor = { pid: supervisorPid, sessions: stranded };
|
|
9513
9615
|
} else {
|
|
9514
|
-
stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
9616
|
+
stopAndAwaitExit(supervisorPid, doorProtocol, "probe-failed-idle", `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
9515
9617
|
continue;
|
|
9516
9618
|
}
|
|
9517
9619
|
} else {
|
|
@@ -9553,6 +9655,7 @@ var init_ensure2 = __esm({
|
|
|
9553
9655
|
import_node_crypto10 = require("node:crypto");
|
|
9554
9656
|
init_cliError();
|
|
9555
9657
|
init_state2();
|
|
9658
|
+
init_replacement();
|
|
9556
9659
|
init_state();
|
|
9557
9660
|
FRONTDOOR_START_TIMEOUT_MS = 3e4;
|
|
9558
9661
|
FRONTDOOR_LAUNCHER_POLL_MS = 100;
|
|
@@ -10080,15 +10183,15 @@ function contextTokensOfTranscript(text) {
|
|
|
10080
10183
|
}
|
|
10081
10184
|
return void 0;
|
|
10082
10185
|
}
|
|
10083
|
-
function newestTranscript(
|
|
10186
|
+
function newestTranscript(fs14, projectDir) {
|
|
10084
10187
|
let newest;
|
|
10085
10188
|
let newestMs = -Infinity;
|
|
10086
|
-
for (const name of
|
|
10189
|
+
for (const name of fs14.readdir(projectDir)) {
|
|
10087
10190
|
if (!name.endsWith(".jsonl")) {
|
|
10088
10191
|
continue;
|
|
10089
10192
|
}
|
|
10090
10193
|
const candidate = import_node_path38.default.join(projectDir, name);
|
|
10091
|
-
const stat =
|
|
10194
|
+
const stat = fs14.lstat(candidate);
|
|
10092
10195
|
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
10093
10196
|
newestMs = stat.mtimeMs;
|
|
10094
10197
|
newest = candidate;
|
|
@@ -10096,14 +10199,14 @@ function newestTranscript(fs13, projectDir) {
|
|
|
10096
10199
|
}
|
|
10097
10200
|
return newest;
|
|
10098
10201
|
}
|
|
10099
|
-
function resumedContextTokens(
|
|
10202
|
+
function resumedContextTokens(fs14, params) {
|
|
10100
10203
|
const target = resumeTargetOf(params.passthrough);
|
|
10101
10204
|
if (target === void 0) {
|
|
10102
10205
|
return void 0;
|
|
10103
10206
|
}
|
|
10104
10207
|
const projectDir = import_node_path38.default.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
|
|
10105
|
-
const file = target.kind === "id" ? import_node_path38.default.join(projectDir, `${target.id}.jsonl`) : newestTranscript(
|
|
10106
|
-
const text = file === void 0 ? void 0 :
|
|
10208
|
+
const file = target.kind === "id" ? import_node_path38.default.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs14, projectDir);
|
|
10209
|
+
const text = file === void 0 ? void 0 : fs14.readFileUtf8(file);
|
|
10107
10210
|
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
10108
10211
|
}
|
|
10109
10212
|
var import_node_path38;
|
|
@@ -10555,7 +10658,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
|
|
|
10555
10658
|
return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
10556
10659
|
}
|
|
10557
10660
|
function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
10558
|
-
const { paths, fs:
|
|
10661
|
+
const { paths, fs: fs14, proc, log } = params;
|
|
10559
10662
|
if (decided.pool === void 0) {
|
|
10560
10663
|
return { identityDecision: decided };
|
|
10561
10664
|
}
|
|
@@ -10574,7 +10677,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
10574
10677
|
selectedVia: decided.source,
|
|
10575
10678
|
pools: params.pools,
|
|
10576
10679
|
paths,
|
|
10577
|
-
fs:
|
|
10680
|
+
fs: fs14,
|
|
10578
10681
|
usageFs: farmRuntime.fs,
|
|
10579
10682
|
cwd: farmRuntime.cwd,
|
|
10580
10683
|
now: farmRuntime.now,
|
|
@@ -10597,7 +10700,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
10597
10700
|
};
|
|
10598
10701
|
}
|
|
10599
10702
|
function decideLaunch(params, readOnly) {
|
|
10600
|
-
const { paths, fs:
|
|
10703
|
+
const { paths, fs: fs14, proc, log } = params;
|
|
10601
10704
|
const { env, argv } = proc;
|
|
10602
10705
|
const parsedArgv = parseLauncherArgv(argv);
|
|
10603
10706
|
const cliOverride = buildCliOverride({
|
|
@@ -10612,7 +10715,7 @@ function decideLaunch(params, readOnly) {
|
|
|
10612
10715
|
argv0Identity: parsedArgv.identity,
|
|
10613
10716
|
directoryPinnedIdentity: params.directoryPinnedIdentity,
|
|
10614
10717
|
readActiveIdentityFile: () => {
|
|
10615
|
-
const raw =
|
|
10718
|
+
const raw = fs14.readFileUtf8(paths.activeIdentityFile);
|
|
10616
10719
|
if (raw === void 0) {
|
|
10617
10720
|
return void 0;
|
|
10618
10721
|
}
|
|
@@ -10647,7 +10750,7 @@ function decideLaunch(params, readOnly) {
|
|
|
10647
10750
|
}
|
|
10648
10751
|
let loadedIdentity;
|
|
10649
10752
|
if (identityDecision.name !== void 0) {
|
|
10650
|
-
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name,
|
|
10753
|
+
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs14);
|
|
10651
10754
|
if (loadedIdentity === void 0) {
|
|
10652
10755
|
log.error(
|
|
10653
10756
|
`agent-shim: no identity named "${identityDecision.name}" (selected via ${identityDecision.source}). Run \`agent-shim identity add ${identityDecision.name}\` first.`
|
|
@@ -10662,7 +10765,7 @@ function decideLaunch(params, readOnly) {
|
|
|
10662
10765
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
10663
10766
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
10664
10767
|
});
|
|
10665
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true &&
|
|
10768
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs14.readConfigFile(import_node_path39.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
10666
10769
|
log.error(
|
|
10667
10770
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
10668
10771
|
);
|
|
@@ -10671,7 +10774,7 @@ function decideLaunch(params, readOnly) {
|
|
|
10671
10774
|
const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
|
|
10672
10775
|
const providerParams = {
|
|
10673
10776
|
paths,
|
|
10674
|
-
port:
|
|
10777
|
+
port: fs14,
|
|
10675
10778
|
...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
|
|
10676
10779
|
...farmContext === void 0 ? {} : { cascade: farmContext.cascade }
|
|
10677
10780
|
};
|
|
@@ -10770,9 +10873,9 @@ function decideLaunch(params, readOnly) {
|
|
|
10770
10873
|
const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
|
|
10771
10874
|
const globalModels = loadConfigFile(paths.globalConfigFile, GlobalConfigSchema, params.fs.readConfigFile)?.config.models;
|
|
10772
10875
|
const models = launchCascade !== void 0 && params.farm !== void 0 ? cascadeModels : globalModels;
|
|
10773
|
-
const listedProviders = listProviderNames(
|
|
10876
|
+
const listedProviders = listProviderNames(fs14.readdir, paths.providersDir).flatMap((name) => {
|
|
10774
10877
|
try {
|
|
10775
|
-
const definition = loadProvider(paths.providersDir, name,
|
|
10878
|
+
const definition = loadProvider(paths.providersDir, name, fs14);
|
|
10776
10879
|
return definition === void 0 ? [] : [[name, definition, parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, name)))?.models ?? []]];
|
|
10777
10880
|
} catch {
|
|
10778
10881
|
return [];
|
|
@@ -11053,6 +11156,20 @@ var init_ownCli = __esm({
|
|
|
11053
11156
|
}
|
|
11054
11157
|
});
|
|
11055
11158
|
|
|
11159
|
+
// src/frontdoor/doorLog.ts
|
|
11160
|
+
function appendDoorLog(paths, line) {
|
|
11161
|
+
import_node_fs12.default.mkdirSync(paths.logsDir, { recursive: true });
|
|
11162
|
+
import_node_fs12.default.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
11163
|
+
`);
|
|
11164
|
+
}
|
|
11165
|
+
var import_node_fs12;
|
|
11166
|
+
var init_doorLog = __esm({
|
|
11167
|
+
"src/frontdoor/doorLog.ts"() {
|
|
11168
|
+
"use strict";
|
|
11169
|
+
import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
11170
|
+
}
|
|
11171
|
+
});
|
|
11172
|
+
|
|
11056
11173
|
// src/frontdoor/selfIdentity.ts
|
|
11057
11174
|
function isFrontDoorSupervisorPid(pid, identify) {
|
|
11058
11175
|
return declaredPid !== void 0 && pid === declaredPid && pid === process.pid || identify(pid);
|
|
@@ -11066,14 +11183,14 @@ var init_selfIdentity = __esm({
|
|
|
11066
11183
|
|
|
11067
11184
|
// src/frontdoor/trust.ts
|
|
11068
11185
|
function resolveTrustBundle(params) {
|
|
11069
|
-
const { caCertFile, bundlesDir, variable, inherited, fs:
|
|
11186
|
+
const { caCertFile, bundlesDir, variable, inherited, fs: fs14 } = params;
|
|
11070
11187
|
if (inherited === void 0 || inherited === "" || import_node_path41.default.resolve(inherited) === import_node_path41.default.resolve(caCertFile)) {
|
|
11071
11188
|
return { path: caCertFile };
|
|
11072
11189
|
}
|
|
11073
|
-
const caPem =
|
|
11190
|
+
const caPem = fs14.readFileUtf8(caCertFile);
|
|
11074
11191
|
let inheritedPem;
|
|
11075
11192
|
try {
|
|
11076
|
-
inheritedPem =
|
|
11193
|
+
inheritedPem = fs14.readFileUtf8(inherited);
|
|
11077
11194
|
} catch (error) {
|
|
11078
11195
|
return {
|
|
11079
11196
|
path: caCertFile,
|
|
@@ -11086,9 +11203,9 @@ function resolveTrustBundle(params) {
|
|
|
11086
11203
|
const combined = `${inheritedPem.trimEnd()}
|
|
11087
11204
|
${caPem}`;
|
|
11088
11205
|
const bundle = import_node_path41.default.join(bundlesDir, `${(0, import_node_crypto12.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
11089
|
-
if (!
|
|
11090
|
-
|
|
11091
|
-
|
|
11206
|
+
if (!fs14.exists(bundle)) {
|
|
11207
|
+
fs14.mkdirp(bundlesDir);
|
|
11208
|
+
fs14.writeFileAtomic(bundle, combined);
|
|
11092
11209
|
}
|
|
11093
11210
|
return { path: bundle };
|
|
11094
11211
|
}
|
|
@@ -11111,6 +11228,9 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
11111
11228
|
sleep: realSleepSync,
|
|
11112
11229
|
spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
|
|
11113
11230
|
isFrontDoorSupervisor: (pid) => isFrontDoorSupervisorPid(pid, realIsFrontDoorSupervisor),
|
|
11231
|
+
recordReplacement: (line) => {
|
|
11232
|
+
appendDoorLog(paths, line);
|
|
11233
|
+
},
|
|
11114
11234
|
stopSupervisor: (pid) => {
|
|
11115
11235
|
process.kill(pid, "SIGTERM");
|
|
11116
11236
|
},
|
|
@@ -11118,7 +11238,7 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
11118
11238
|
process.kill(pid, "SIGKILL");
|
|
11119
11239
|
},
|
|
11120
11240
|
// 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.
|
|
11121
|
-
verifyListener: (port) => probeFrontDoorSync(port,
|
|
11241
|
+
verifyListener: (port) => probeFrontDoorSync(port, import_node_fs13.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
|
|
11122
11242
|
};
|
|
11123
11243
|
}
|
|
11124
11244
|
function realFrontDoorPort(paths, spawnDaemon) {
|
|
@@ -11139,22 +11259,23 @@ function realFrontDoorPort(paths, spawnDaemon) {
|
|
|
11139
11259
|
}
|
|
11140
11260
|
};
|
|
11141
11261
|
}
|
|
11142
|
-
var
|
|
11262
|
+
var import_node_fs13, realTrustBundleFs;
|
|
11143
11263
|
var init_realFrontDoorPort = __esm({
|
|
11144
11264
|
"src/frontdoor/realFrontDoorPort.ts"() {
|
|
11145
11265
|
"use strict";
|
|
11146
|
-
|
|
11266
|
+
import_node_fs13 = __toESM(require("node:fs"), 1);
|
|
11147
11267
|
init_realPorts();
|
|
11268
|
+
init_doorLog();
|
|
11148
11269
|
init_ensure2();
|
|
11149
11270
|
init_state();
|
|
11150
11271
|
init_probe();
|
|
11151
11272
|
init_selfIdentity();
|
|
11152
11273
|
init_trust();
|
|
11153
11274
|
realTrustBundleFs = {
|
|
11154
|
-
readFileUtf8: (file) =>
|
|
11155
|
-
exists: (file) =>
|
|
11275
|
+
readFileUtf8: (file) => import_node_fs13.default.readFileSync(file, "utf8"),
|
|
11276
|
+
exists: (file) => import_node_fs13.default.existsSync(file),
|
|
11156
11277
|
mkdirp: (dir) => {
|
|
11157
|
-
|
|
11278
|
+
import_node_fs13.default.mkdirSync(dir, { recursive: true });
|
|
11158
11279
|
},
|
|
11159
11280
|
writeFileAtomic: (file, contents) => {
|
|
11160
11281
|
realFarmFs.writeFilePrivate(file, contents);
|
|
@@ -13898,6 +14019,10 @@ function realConnectEffects(ports = DOOR_SOURCE_PORTS) {
|
|
|
13898
14019
|
}
|
|
13899
14020
|
resolve({
|
|
13900
14021
|
port: bound,
|
|
14022
|
+
// The listening socket is released by `close` at once; the connections already accepted are untouched and keep the server's `close` callback pending until they end.
|
|
14023
|
+
stopAccepting: () => {
|
|
14024
|
+
server.close();
|
|
14025
|
+
},
|
|
13901
14026
|
close: async () => {
|
|
13902
14027
|
await new Promise((closeResolve) => {
|
|
13903
14028
|
server.close(() => {
|
|
@@ -14103,11 +14228,11 @@ function credentialOfJson(parsed) {
|
|
|
14103
14228
|
function sequenceNumOfJson(value) {
|
|
14104
14229
|
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
14105
14230
|
}
|
|
14106
|
-
function createRcCredentialStore(
|
|
14107
|
-
|
|
14231
|
+
function createRcCredentialStore(fs14, dir) {
|
|
14232
|
+
fs14.mkdirPrivate(dir);
|
|
14108
14233
|
const fileFor = (sessionId) => import_node_path10.default.join(dir, `${sessionId}.json`);
|
|
14109
14234
|
const readParsed = (sessionId) => {
|
|
14110
|
-
const raw =
|
|
14235
|
+
const raw = fs14.readFileUtf8(fileFor(sessionId));
|
|
14111
14236
|
if (raw === void 0) {
|
|
14112
14237
|
return void 0;
|
|
14113
14238
|
}
|
|
@@ -14132,7 +14257,7 @@ function createRcCredentialStore(fs13, dir) {
|
|
|
14132
14257
|
}
|
|
14133
14258
|
const cursor = sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
|
|
14134
14259
|
const record = { ...credential, ...cursor === void 0 ? {} : { highestSequenceNum: cursor } };
|
|
14135
|
-
|
|
14260
|
+
fs14.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
|
|
14136
14261
|
`);
|
|
14137
14262
|
},
|
|
14138
14263
|
readCursor: (sessionId) => {
|
|
@@ -14147,14 +14272,14 @@ function createRcCredentialStore(fs13, dir) {
|
|
|
14147
14272
|
}
|
|
14148
14273
|
const credential = credentialOfJson(readParsed(sessionId));
|
|
14149
14274
|
const record = credential === void 0 ? { highestSequenceNum } : { ...credential, highestSequenceNum };
|
|
14150
|
-
|
|
14275
|
+
fs14.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
|
|
14151
14276
|
`);
|
|
14152
14277
|
},
|
|
14153
14278
|
remove: (sessionId) => {
|
|
14154
14279
|
if (!isSafeSessionId(sessionId)) {
|
|
14155
14280
|
return;
|
|
14156
14281
|
}
|
|
14157
|
-
|
|
14282
|
+
fs14.removeRecursive(fileFor(sessionId));
|
|
14158
14283
|
}
|
|
14159
14284
|
};
|
|
14160
14285
|
}
|
|
@@ -16057,14 +16182,18 @@ init_supervisor2();
|
|
|
16057
16182
|
init_state();
|
|
16058
16183
|
|
|
16059
16184
|
// src/doctorFrontDoor.ts
|
|
16060
|
-
function pushFrontDoor(push, supervisors, registeredPid, liveSessions) {
|
|
16185
|
+
function pushFrontDoor(push, supervisors, registeredPid, liveSessions, draining) {
|
|
16061
16186
|
if (!supervisors.ok) {
|
|
16062
16187
|
push("frontdoor", "warn", `Could not list processes to look for duplicate front door supervisors: ${supervisors.message}.`);
|
|
16063
16188
|
return;
|
|
16064
16189
|
}
|
|
16065
|
-
const
|
|
16190
|
+
const drainingPids = supervisors.pids.filter((pid) => draining.includes(pid));
|
|
16191
|
+
for (const pid of drainingPids) {
|
|
16192
|
+
push("frontdoor", "warn", `Front door supervisor pid ${String(pid)} is draining: it has released its addresses and exits once the connections it carried have ended.`, String(pid));
|
|
16193
|
+
}
|
|
16194
|
+
const pids = supervisors.pids.filter((pid) => !draining.includes(pid));
|
|
16066
16195
|
if (pids.length === 0) {
|
|
16067
|
-
push("frontdoor", "pass", "No front door supervisor is running.");
|
|
16196
|
+
push("frontdoor", "pass", drainingPids.length === 0 ? "No front door supervisor is running." : "No front door supervisor is serving.");
|
|
16068
16197
|
return;
|
|
16069
16198
|
}
|
|
16070
16199
|
const [only, ...rest] = pids;
|
|
@@ -16614,7 +16743,7 @@ function runDoctor(params) {
|
|
|
16614
16743
|
}
|
|
16615
16744
|
if (params.frontDoor !== void 0) {
|
|
16616
16745
|
const validated3 = params.frontDoor.state.raw === void 0 ? void 0 : validateJson(FrontDoorStateSchema, params.frontDoor.state);
|
|
16617
|
-
pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0, params.frontDoor.liveSessions);
|
|
16746
|
+
pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0, params.frontDoor.liveSessions, params.frontDoor.draining ?? []);
|
|
16618
16747
|
if (params.frontDoor.listeners !== void 0) {
|
|
16619
16748
|
pushFrontDoorListeners(push, params.frontDoor.listeners);
|
|
16620
16749
|
}
|
|
@@ -16813,7 +16942,7 @@ function collectDoctorReport(params) {
|
|
|
16813
16942
|
logPath: paths.headroomLogPath
|
|
16814
16943
|
}
|
|
16815
16944
|
},
|
|
16816
|
-
...uid === void 0 ? {} : { frontDoor: { state: { path: paths.frontdoorStateFile, raw: realFsPort.readFileUtf8(paths.frontdoorStateFile) }, supervisors: listFrontDoorSupervisors(realRunPort, uid), liveSessions: listFrontDoorSessions(realFarmFs, paths.frontdoorSessionsDir).filter((session) => realIsProcessRunning(session.pid)), listeners: servingDoorListeners(paths) } }
|
|
16945
|
+
...uid === void 0 ? {} : { frontDoor: { state: { path: paths.frontdoorStateFile, raw: realFsPort.readFileUtf8(paths.frontdoorStateFile) }, supervisors: listFrontDoorSupervisors(realRunPort, uid), liveSessions: listFrontDoorSessions(realFarmFs, paths.frontdoorSessionsDir).filter((session) => realIsProcessRunning(session.pid)), draining: listDrainingFrontDoors(realFarmFs, paths.frontdoorDrainingDir, realIsProcessRunning), listeners: servingDoorListeners(paths) } }
|
|
16817
16946
|
});
|
|
16818
16947
|
return report;
|
|
16819
16948
|
}
|
|
@@ -16859,6 +16988,8 @@ var HeadroomSocketTargetSchema = import_zod26.z.union([import_zod26.z.strictObje
|
|
|
16859
16988
|
var FrontDoorStatusOutputSchema = import_zod26.z.strictObject({
|
|
16860
16989
|
state: FrontDoorStateSchema,
|
|
16861
16990
|
supervisorAlive: import_zod26.z.boolean(),
|
|
16991
|
+
/** The pids of earlier doors that released their addresses and are finishing the connections they carried: running, but not serving anything new. */
|
|
16992
|
+
draining: import_zod26.z.readonly(import_zod26.z.array(import_zod26.z.number().int().positive())),
|
|
16862
16993
|
sessions: import_zod26.z.readonly(import_zod26.z.array(FrontDoorSessionStatusSchema)),
|
|
16863
16994
|
headroomSocket: HeadroomSocketTargetSchema.optional(),
|
|
16864
16995
|
logPath: import_zod26.z.string(),
|
|
@@ -17903,6 +18034,7 @@ function collectFrontDoorStatus(fsPort, socketTrust, paths, isRunning) {
|
|
|
17903
18034
|
return {
|
|
17904
18035
|
state,
|
|
17905
18036
|
supervisorAlive: state.supervisorPid !== void 0 && isRunning(state.supervisorPid),
|
|
18037
|
+
draining: listDrainingFrontDoors(fsPort, paths.frontdoorDrainingDir, isRunning),
|
|
17906
18038
|
sessions: listFrontDoorSessions(fsPort, paths.frontdoorSessionsDir).map((session) => ({ ...session, alive: isRunning(session.pid) })),
|
|
17907
18039
|
headroomSocket: headroomSocketTarget(fsPort, socketTrust, paths),
|
|
17908
18040
|
logPath: paths.frontdoorLogPath,
|
|
@@ -17926,6 +18058,9 @@ function formatFrontDoorStatus(status, caCertPath) {
|
|
|
17926
18058
|
} else {
|
|
17927
18059
|
lines.push(`connect surface: listening on 127.0.0.1:${String(status.state.connectPort)}, CA ${caCertPath}`);
|
|
17928
18060
|
}
|
|
18061
|
+
if (status.draining.length > 0) {
|
|
18062
|
+
lines.push(`draining: ${status.draining.map(String).join(", ")} (finishing connections opened before the last restart; each exits when they have ended)`);
|
|
18063
|
+
}
|
|
17929
18064
|
if (status.headroomSocket === void 0) {
|
|
17930
18065
|
lines.push("headroom hop: the daemon is not serving (sessions asking for headroom fail until it is up)");
|
|
17931
18066
|
} else if (status.headroomSocket.refused === void 0) {
|
|
@@ -18340,6 +18475,7 @@ function createRcEventFanout() {
|
|
|
18340
18475
|
}
|
|
18341
18476
|
function createRcStreamHub(deps) {
|
|
18342
18477
|
const attachments = /* @__PURE__ */ new Map();
|
|
18478
|
+
let closed = false;
|
|
18343
18479
|
const lastSavedSequenceNums = /* @__PURE__ */ new Map();
|
|
18344
18480
|
const persistCursor = (sessionId) => {
|
|
18345
18481
|
if (deps.saveSequenceNum === void 0) {
|
|
@@ -18498,6 +18634,9 @@ function createRcStreamHub(deps) {
|
|
|
18498
18634
|
};
|
|
18499
18635
|
return {
|
|
18500
18636
|
reconcile: () => {
|
|
18637
|
+
if (closed) {
|
|
18638
|
+
return;
|
|
18639
|
+
}
|
|
18501
18640
|
const live = new Set(deps.trackedSessions());
|
|
18502
18641
|
for (const [sessionId, attachment] of attachments) {
|
|
18503
18642
|
if (!live.has(sessionId)) {
|
|
@@ -18520,6 +18659,7 @@ function createRcStreamHub(deps) {
|
|
|
18520
18659
|
}
|
|
18521
18660
|
},
|
|
18522
18661
|
close: () => {
|
|
18662
|
+
closed = true;
|
|
18523
18663
|
for (const attachment of attachments.values()) {
|
|
18524
18664
|
persistCursor(attachment.sessionId);
|
|
18525
18665
|
const credential = deps.credentialOf(attachment.sessionId);
|
|
@@ -19824,8 +19964,8 @@ var SELF_HOST_SUBSCRIPTION_TYPE = "max";
|
|
|
19824
19964
|
function isRecord14(value) {
|
|
19825
19965
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19826
19966
|
}
|
|
19827
|
-
function readJsonObject(
|
|
19828
|
-
const raw =
|
|
19967
|
+
function readJsonObject(fs14, file) {
|
|
19968
|
+
const raw = fs14.readFileUtf8(file);
|
|
19829
19969
|
if (raw === void 0) {
|
|
19830
19970
|
return void 0;
|
|
19831
19971
|
}
|
|
@@ -19837,8 +19977,8 @@ function readJsonObject(fs13, file) {
|
|
|
19837
19977
|
}
|
|
19838
19978
|
return isRecord14(parsed) ? parsed : void 0;
|
|
19839
19979
|
}
|
|
19840
|
-
function readRcSelfHostRecord(
|
|
19841
|
-
const parsed = readJsonObject(
|
|
19980
|
+
function readRcSelfHostRecord(fs14, frontdoorDir) {
|
|
19981
|
+
const parsed = readJsonObject(fs14, import_node_path34.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
19842
19982
|
if (parsed === void 0) {
|
|
19843
19983
|
return void 0;
|
|
19844
19984
|
}
|
|
@@ -19939,17 +20079,17 @@ function parseEntry2(project, entry) {
|
|
|
19939
20079
|
const base = match?.[1];
|
|
19940
20080
|
return base === void 0 ? { project, sessionId: entry, superseded: false, entry } : { project, sessionId: base, superseded: true, entry };
|
|
19941
20081
|
}
|
|
19942
|
-
function listSessions2(
|
|
20082
|
+
function listSessions2(fs14, configDir) {
|
|
19943
20083
|
const found = [];
|
|
19944
|
-
for (const project of
|
|
20084
|
+
for (const project of fs14.readdir(import_node_path35.default.join(configDir, PROJECTS_DIR))) {
|
|
19945
20085
|
const projectDir = import_node_path35.default.join(configDir, PROJECTS_DIR, project);
|
|
19946
20086
|
const entries = /* @__PURE__ */ new Set();
|
|
19947
|
-
for (const name of
|
|
20087
|
+
for (const name of fs14.readdir(projectDir)) {
|
|
19948
20088
|
if (name.endsWith(TRANSCRIPT_SUFFIX)) {
|
|
19949
20089
|
entries.add(name.slice(0, -TRANSCRIPT_SUFFIX.length));
|
|
19950
20090
|
continue;
|
|
19951
20091
|
}
|
|
19952
|
-
const children =
|
|
20092
|
+
const children = fs14.readdir(import_node_path35.default.join(projectDir, name));
|
|
19953
20093
|
if (children.includes(SUBAGENTS_DIR) || children.includes(WORKFLOWS_DIR)) {
|
|
19954
20094
|
entries.add(name);
|
|
19955
20095
|
}
|
|
@@ -19960,9 +20100,9 @@ function listSessions2(fs13, configDir) {
|
|
|
19960
20100
|
}
|
|
19961
20101
|
return found.sort((left, right) => left.project.localeCompare(right.project) || left.entry.localeCompare(right.entry));
|
|
19962
20102
|
}
|
|
19963
|
-
function locateAgents(
|
|
20103
|
+
function locateAgents(fs14, configDir, relativeDir, workflowRunId, report) {
|
|
19964
20104
|
const located = [];
|
|
19965
|
-
for (const name of listDirOrReport(
|
|
20105
|
+
for (const name of listDirOrReport(fs14, configDir, relativeDir, report)) {
|
|
19966
20106
|
if (!name.startsWith(AGENT_FILE_PREFIX) || !name.endsWith(META_SUFFIX)) {
|
|
19967
20107
|
continue;
|
|
19968
20108
|
}
|
|
@@ -20011,17 +20151,17 @@ function toNode(read, children) {
|
|
|
20011
20151
|
function describeFailure(error) {
|
|
20012
20152
|
return error instanceof Error ? error.message : String(error);
|
|
20013
20153
|
}
|
|
20014
|
-
function readFileOrReport(
|
|
20154
|
+
function readFileOrReport(fs14, configDir, relative, report) {
|
|
20015
20155
|
try {
|
|
20016
|
-
return
|
|
20156
|
+
return fs14.readFileUtf8(import_node_path35.default.join(configDir, relative));
|
|
20017
20157
|
} catch (error) {
|
|
20018
20158
|
report({ path: relative, reason: `could not be read: ${describeFailure(error)}` });
|
|
20019
20159
|
return void 0;
|
|
20020
20160
|
}
|
|
20021
20161
|
}
|
|
20022
|
-
function listDirOrReport(
|
|
20162
|
+
function listDirOrReport(fs14, configDir, relative, report) {
|
|
20023
20163
|
try {
|
|
20024
|
-
return
|
|
20164
|
+
return fs14.readdir(import_node_path35.default.join(configDir, relative));
|
|
20025
20165
|
} catch (error) {
|
|
20026
20166
|
report({ path: relative, reason: `could not be listed: ${describeFailure(error)}` });
|
|
20027
20167
|
return [];
|
|
@@ -20044,22 +20184,22 @@ var WorkflowRunFileSchema = import_zod31.z.object({
|
|
|
20044
20184
|
phases: import_zod31.z.array(import_zod31.z.object({ title: import_zod31.z.string() })).default([]),
|
|
20045
20185
|
summary: import_zod31.z.string().optional()
|
|
20046
20186
|
});
|
|
20047
|
-
function summariseSession(
|
|
20187
|
+
function summariseSession(fs14, configDir, ref) {
|
|
20048
20188
|
const sessionRelative = import_node_path35.default.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
20049
20189
|
const subagentsRelative = import_node_path35.default.join(sessionRelative, SUBAGENTS_DIR);
|
|
20050
20190
|
const workflowsUnderSubagents = import_node_path35.default.join(subagentsRelative, WORKFLOWS_DIR);
|
|
20051
20191
|
const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
|
|
20052
|
-
let agentCount =
|
|
20053
|
-
for (const runDir of
|
|
20192
|
+
let agentCount = fs14.readdir(import_node_path35.default.join(configDir, subagentsRelative)).filter(isMeta).length;
|
|
20193
|
+
for (const runDir of fs14.readdir(import_node_path35.default.join(configDir, workflowsUnderSubagents))) {
|
|
20054
20194
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
20055
|
-
agentCount +=
|
|
20195
|
+
agentCount += fs14.readdir(import_node_path35.default.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
|
|
20056
20196
|
}
|
|
20057
20197
|
}
|
|
20058
|
-
const workflowRunCount =
|
|
20059
|
-
const transcript =
|
|
20198
|
+
const workflowRunCount = fs14.readdir(import_node_path35.default.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
|
|
20199
|
+
const transcript = fs14.lstat(import_node_path35.default.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
|
|
20060
20200
|
return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
|
|
20061
20201
|
}
|
|
20062
|
-
function readSessionAgentTree(
|
|
20202
|
+
function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
20063
20203
|
const problems = [];
|
|
20064
20204
|
const report = (problem) => {
|
|
20065
20205
|
problems.push(problem);
|
|
@@ -20067,15 +20207,15 @@ function readSessionAgentTree(fs13, configDir, ref, options = {}) {
|
|
|
20067
20207
|
const sessionRelative = import_node_path35.default.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
20068
20208
|
const subagentsRelative = import_node_path35.default.join(sessionRelative, SUBAGENTS_DIR);
|
|
20069
20209
|
const workflowsUnderSubagents = import_node_path35.default.join(subagentsRelative, WORKFLOWS_DIR);
|
|
20070
|
-
const located = locateAgents(
|
|
20071
|
-
for (const runDir of listDirOrReport(
|
|
20210
|
+
const located = locateAgents(fs14, configDir, subagentsRelative, void 0, report);
|
|
20211
|
+
for (const runDir of listDirOrReport(fs14, configDir, workflowsUnderSubagents, report)) {
|
|
20072
20212
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
20073
|
-
located.push(...locateAgents(
|
|
20213
|
+
located.push(...locateAgents(fs14, configDir, import_node_path35.default.join(workflowsUnderSubagents, runDir), runDir, report));
|
|
20074
20214
|
}
|
|
20075
20215
|
}
|
|
20076
20216
|
const agents = /* @__PURE__ */ new Map();
|
|
20077
20217
|
for (const candidate of located) {
|
|
20078
|
-
const text = readFileOrReport(
|
|
20218
|
+
const text = readFileOrReport(fs14, configDir, candidate.metaPath, report);
|
|
20079
20219
|
if (text === void 0) {
|
|
20080
20220
|
continue;
|
|
20081
20221
|
}
|
|
@@ -20087,7 +20227,7 @@ function readSessionAgentTree(fs13, configDir, ref, options = {}) {
|
|
|
20087
20227
|
agents.set(candidate.id, { located: candidate, meta: parsed.data });
|
|
20088
20228
|
}
|
|
20089
20229
|
const teamNames = [...new Set([...agents.values()].flatMap((agent) => agent.meta.teamName === void 0 ? [] : [agent.meta.teamName]))].sort();
|
|
20090
|
-
const parentOf3 = resolveParents(
|
|
20230
|
+
const parentOf3 = resolveParents(fs14, configDir, agents, report);
|
|
20091
20231
|
const childrenOf = /* @__PURE__ */ new Map();
|
|
20092
20232
|
const roots = [];
|
|
20093
20233
|
for (const id of agents.keys()) {
|
|
@@ -20110,12 +20250,12 @@ function readSessionAgentTree(fs13, configDir, ref, options = {}) {
|
|
|
20110
20250
|
sessionId: ref.sessionId,
|
|
20111
20251
|
superseded: ref.superseded,
|
|
20112
20252
|
agents: roots.sort().map(build),
|
|
20113
|
-
tasks: readTasks(
|
|
20114
|
-
workflowRuns: readWorkflowRuns(
|
|
20253
|
+
tasks: readTasks(fs14, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
|
|
20254
|
+
workflowRuns: readWorkflowRuns(fs14, configDir, import_node_path35.default.join(sessionRelative, WORKFLOWS_DIR), report),
|
|
20115
20255
|
problems
|
|
20116
20256
|
};
|
|
20117
20257
|
}
|
|
20118
|
-
function resolveParents(
|
|
20258
|
+
function resolveParents(fs14, configDir, agents, report) {
|
|
20119
20259
|
const parentOf3 = /* @__PURE__ */ new Map();
|
|
20120
20260
|
const transcriptCache = /* @__PURE__ */ new Map();
|
|
20121
20261
|
const transcriptOf = (agent) => {
|
|
@@ -20123,7 +20263,7 @@ function resolveParents(fs13, configDir, agents, report) {
|
|
|
20123
20263
|
if (cached !== void 0) {
|
|
20124
20264
|
return cached;
|
|
20125
20265
|
}
|
|
20126
|
-
const text = readFileOrReport(
|
|
20266
|
+
const text = readFileOrReport(fs14, configDir, agent.located.transcriptPath, report) ?? "";
|
|
20127
20267
|
transcriptCache.set(agent.located.id, text);
|
|
20128
20268
|
return text;
|
|
20129
20269
|
};
|
|
@@ -20173,16 +20313,16 @@ function resolveParents(fs13, configDir, agents, report) {
|
|
|
20173
20313
|
function ownTaskLists(sessionId) {
|
|
20174
20314
|
return [sessionId, `${SHORT_SESSION_LIST_PREFIX}${sessionId.slice(0, SHORT_SESSION_ID_LENGTH)}`];
|
|
20175
20315
|
}
|
|
20176
|
-
function readTasks(
|
|
20316
|
+
function readTasks(fs14, configDir, ownLists, sharedLists, report) {
|
|
20177
20317
|
const tasks = [];
|
|
20178
20318
|
[...ownLists, ...sharedLists].forEach((scope, index) => {
|
|
20179
20319
|
const relativeDir = import_node_path35.default.join(TASKS_DIR, scope);
|
|
20180
|
-
for (const name of [...listDirOrReport(
|
|
20320
|
+
for (const name of [...listDirOrReport(fs14, configDir, relativeDir, report)].sort()) {
|
|
20181
20321
|
if (name.startsWith(".") || !name.endsWith(JSON_SUFFIX)) {
|
|
20182
20322
|
continue;
|
|
20183
20323
|
}
|
|
20184
20324
|
const relative = import_node_path35.default.join(relativeDir, name);
|
|
20185
|
-
const text = readFileOrReport(
|
|
20325
|
+
const text = readFileOrReport(fs14, configDir, relative, report);
|
|
20186
20326
|
const parsed = TaskFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
20187
20327
|
if (parsed.success) {
|
|
20188
20328
|
tasks.push(index < ownLists.length ? parsed.data : { ...parsed.data, taskList: scope });
|
|
@@ -20193,14 +20333,14 @@ function readTasks(fs13, configDir, ownLists, sharedLists, report) {
|
|
|
20193
20333
|
});
|
|
20194
20334
|
return tasks;
|
|
20195
20335
|
}
|
|
20196
|
-
function readWorkflowRuns(
|
|
20336
|
+
function readWorkflowRuns(fs14, configDir, relativeDir, report) {
|
|
20197
20337
|
const runs = [];
|
|
20198
|
-
for (const name of [...listDirOrReport(
|
|
20338
|
+
for (const name of [...listDirOrReport(fs14, configDir, relativeDir, report)].sort()) {
|
|
20199
20339
|
if (!name.startsWith(WORKFLOW_RUN_PREFIX) || !name.endsWith(JSON_SUFFIX)) {
|
|
20200
20340
|
continue;
|
|
20201
20341
|
}
|
|
20202
20342
|
const relative = import_node_path35.default.join(relativeDir, name);
|
|
20203
|
-
const text = readFileOrReport(
|
|
20343
|
+
const text = readFileOrReport(fs14, configDir, relative, report);
|
|
20204
20344
|
const parsed = WorkflowRunFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
20205
20345
|
if (!parsed.success) {
|
|
20206
20346
|
if (text !== void 0) {
|
|
@@ -20226,11 +20366,11 @@ var SessionLookupError = class extends CliError {
|
|
|
20226
20366
|
function identityConfigDir(identitiesDir, identity) {
|
|
20227
20367
|
return import_node_path36.default.join(identitiesDir, identity);
|
|
20228
20368
|
}
|
|
20229
|
-
function historyStores(
|
|
20369
|
+
function historyStores(fs14, identitiesDir, identities) {
|
|
20230
20370
|
const byRealPath = /* @__PURE__ */ new Map();
|
|
20231
20371
|
for (const identity of identities) {
|
|
20232
20372
|
const configDir = identityConfigDir(identitiesDir, identity);
|
|
20233
|
-
const real =
|
|
20373
|
+
const real = fs14.realpath(import_node_path36.default.join(configDir, "projects"));
|
|
20234
20374
|
if (real === void 0) {
|
|
20235
20375
|
continue;
|
|
20236
20376
|
}
|
|
@@ -20243,15 +20383,15 @@ function historyStores(fs13, identitiesDir, identities) {
|
|
|
20243
20383
|
}
|
|
20244
20384
|
return [...byRealPath.values()];
|
|
20245
20385
|
}
|
|
20246
|
-
function collectSessionList(
|
|
20386
|
+
function collectSessionList(fs14, identitiesDir, identities, filters) {
|
|
20247
20387
|
const names = filters.identity === void 0 ? identities : identities.filter((name) => name === filters.identity);
|
|
20248
20388
|
if (filters.identity !== void 0 && names.length === 0) {
|
|
20249
20389
|
throw new SessionLookupError(`no identity named "${filters.identity}"`);
|
|
20250
20390
|
}
|
|
20251
20391
|
const sessions = [];
|
|
20252
|
-
for (const store of historyStores(
|
|
20253
|
-
for (const ref of listSessions2(
|
|
20254
|
-
const summary = summariseSession(
|
|
20392
|
+
for (const store of historyStores(fs14, identitiesDir, names)) {
|
|
20393
|
+
for (const ref of listSessions2(fs14, store.configDir)) {
|
|
20394
|
+
const summary = summariseSession(fs14, store.configDir, ref);
|
|
20255
20395
|
if (filters.all === true || summary.agentCount > 0 || summary.workflowRunCount > 0) {
|
|
20256
20396
|
sessions.push({ ...summary, identities: store.identities });
|
|
20257
20397
|
}
|
|
@@ -20259,14 +20399,14 @@ function collectSessionList(fs13, identitiesDir, identities, filters) {
|
|
|
20259
20399
|
}
|
|
20260
20400
|
return sessions.sort((left, right) => (right.updatedAt ?? "").localeCompare(left.updatedAt ?? "") || left.sessionId.localeCompare(right.sessionId));
|
|
20261
20401
|
}
|
|
20262
|
-
function locateSession(
|
|
20402
|
+
function locateSession(fs14, identitiesDir, identities, query, onlyIdentity) {
|
|
20263
20403
|
const names = onlyIdentity === void 0 ? identities : identities.filter((name) => name === onlyIdentity);
|
|
20264
20404
|
if (onlyIdentity !== void 0 && names.length === 0) {
|
|
20265
20405
|
throw new SessionLookupError(`no identity named "${onlyIdentity}"`);
|
|
20266
20406
|
}
|
|
20267
20407
|
const matches = [];
|
|
20268
|
-
for (const store of historyStores(
|
|
20269
|
-
for (const ref of listSessions2(
|
|
20408
|
+
for (const store of historyStores(fs14, identitiesDir, names)) {
|
|
20409
|
+
for (const ref of listSessions2(fs14, store.configDir)) {
|
|
20270
20410
|
if (ref.sessionId.startsWith(query)) {
|
|
20271
20411
|
matches.push({ identities: store.identities, configDir: store.configDir, ref });
|
|
20272
20412
|
}
|
|
@@ -20283,9 +20423,9 @@ function locateSession(fs13, identitiesDir, identities, query, onlyIdentity) {
|
|
|
20283
20423
|
}
|
|
20284
20424
|
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`);
|
|
20285
20425
|
}
|
|
20286
|
-
function showSession(
|
|
20287
|
-
const located = locateSession(
|
|
20288
|
-
return { identities: located.identities, tree: readSessionAgentTree(
|
|
20426
|
+
function showSession(fs14, identitiesDir, identities, query, onlyIdentity) {
|
|
20427
|
+
const located = locateSession(fs14, identitiesDir, identities, query, onlyIdentity);
|
|
20428
|
+
return { identities: located.identities, tree: readSessionAgentTree(fs14, located.configDir, located.ref) };
|
|
20289
20429
|
}
|
|
20290
20430
|
|
|
20291
20431
|
// src/agents/realFs.ts
|