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.mjs
CHANGED
|
@@ -2430,8 +2430,8 @@ var init_lock = __esm({
|
|
|
2430
2430
|
// src/launcher/farm.ts
|
|
2431
2431
|
import path7 from "node:path";
|
|
2432
2432
|
import { z as z2 } from "zod";
|
|
2433
|
-
function readFarmManifest(
|
|
2434
|
-
const raw =
|
|
2433
|
+
function readFarmManifest(fs14, farmRoot) {
|
|
2434
|
+
const raw = fs14.readFileUtf8(path7.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs14.readFileUtf8(path7.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
|
|
2435
2435
|
if (raw === void 0) {
|
|
2436
2436
|
return void 0;
|
|
2437
2437
|
}
|
|
@@ -2489,9 +2489,9 @@ function buildEntryFacts(params) {
|
|
|
2489
2489
|
entries
|
|
2490
2490
|
};
|
|
2491
2491
|
}
|
|
2492
|
-
function listSubtree(
|
|
2492
|
+
function listSubtree(fs14, root, rel) {
|
|
2493
2493
|
const absolute = path7.join(root, rel);
|
|
2494
|
-
const stat =
|
|
2494
|
+
const stat = fs14.lstat(absolute);
|
|
2495
2495
|
if (stat === void 0) {
|
|
2496
2496
|
return [];
|
|
2497
2497
|
}
|
|
@@ -2499,10 +2499,10 @@ function listSubtree(fs13, root, rel) {
|
|
|
2499
2499
|
return [{ rel, kind: "symlink" }];
|
|
2500
2500
|
}
|
|
2501
2501
|
if (stat.kind === "dir") {
|
|
2502
|
-
const children = [...
|
|
2502
|
+
const children = [...fs14.readdir(absolute)].sort().flatMap((name) => listSubtree(fs14, root, `${rel}/${name}`));
|
|
2503
2503
|
return [{ rel, kind: "dir" }, ...children];
|
|
2504
2504
|
}
|
|
2505
|
-
const contentHash =
|
|
2505
|
+
const contentHash = fs14.hashFile(absolute);
|
|
2506
2506
|
return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
|
|
2507
2507
|
}
|
|
2508
2508
|
function topLevelScopeRoots(roots) {
|
|
@@ -2516,25 +2516,25 @@ function topLevelScopeRoots(roots) {
|
|
|
2516
2516
|
}
|
|
2517
2517
|
return kept;
|
|
2518
2518
|
}
|
|
2519
|
-
function reconciliationScope(
|
|
2519
|
+
function reconciliationScope(fs14, farmRoot, manifest) {
|
|
2520
2520
|
if (manifest !== void 0) {
|
|
2521
2521
|
return topLevelScopeRoots(manifest.materialised);
|
|
2522
2522
|
}
|
|
2523
|
-
return [...
|
|
2523
|
+
return [...fs14.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs14.lstat(path7.join(farmRoot, name))?.kind === "dir").sort();
|
|
2524
2524
|
}
|
|
2525
|
-
function collectFarmListing(
|
|
2526
|
-
return scopeRoots.flatMap((root) => listSubtree(
|
|
2525
|
+
function collectFarmListing(fs14, farmRoot, scopeRoots) {
|
|
2526
|
+
return scopeRoots.flatMap((root) => listSubtree(fs14, farmRoot, root));
|
|
2527
2527
|
}
|
|
2528
|
-
function collectCanonicalCounterparts(
|
|
2528
|
+
function collectCanonicalCounterparts(fs14, claudeHome, farmListing) {
|
|
2529
2529
|
const out = [];
|
|
2530
2530
|
for (const entry of farmListing) {
|
|
2531
2531
|
const absolute = path7.join(claudeHome, entry.rel);
|
|
2532
|
-
const stat =
|
|
2532
|
+
const stat = fs14.lstat(absolute);
|
|
2533
2533
|
if (stat === void 0) {
|
|
2534
2534
|
continue;
|
|
2535
2535
|
}
|
|
2536
2536
|
if (stat.kind === "file") {
|
|
2537
|
-
const contentHash =
|
|
2537
|
+
const contentHash = fs14.hashFile(absolute);
|
|
2538
2538
|
out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
|
|
2539
2539
|
continue;
|
|
2540
2540
|
}
|
|
@@ -3305,10 +3305,10 @@ var init_route = __esm({
|
|
|
3305
3305
|
// src/frontdoor/state.ts
|
|
3306
3306
|
import path8 from "node:path";
|
|
3307
3307
|
import { z as z3 } from "zod";
|
|
3308
|
-
function readFrontDoorState(
|
|
3308
|
+
function readFrontDoorState(fs14, stateFile) {
|
|
3309
3309
|
let raw;
|
|
3310
3310
|
try {
|
|
3311
|
-
raw =
|
|
3311
|
+
raw = fs14.readFileUtf8(stateFile);
|
|
3312
3312
|
} catch {
|
|
3313
3313
|
return void 0;
|
|
3314
3314
|
}
|
|
@@ -3322,9 +3322,9 @@ function readFrontDoorState(fs13, stateFile) {
|
|
|
3322
3322
|
return void 0;
|
|
3323
3323
|
}
|
|
3324
3324
|
}
|
|
3325
|
-
function writeFrontDoorState(
|
|
3326
|
-
|
|
3327
|
-
|
|
3325
|
+
function writeFrontDoorState(fs14, stateFile, state) {
|
|
3326
|
+
fs14.mkdirp(path8.dirname(stateFile));
|
|
3327
|
+
fs14.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
3328
3328
|
`);
|
|
3329
3329
|
}
|
|
3330
3330
|
function directOrigin(port) {
|
|
@@ -3334,27 +3334,37 @@ function frontDoorOrigin(state) {
|
|
|
3334
3334
|
const port = state?.directPort ?? state?.lastDirectPort;
|
|
3335
3335
|
return port === void 0 ? void 0 : directOrigin(port);
|
|
3336
3336
|
}
|
|
3337
|
-
function writeFrontDoorDirectRecord(
|
|
3338
|
-
|
|
3339
|
-
|
|
3337
|
+
function writeFrontDoorDirectRecord(fs14, recordsDir, record) {
|
|
3338
|
+
fs14.mkdirp(recordsDir);
|
|
3339
|
+
fs14.writeFilePrivate(path8.join(recordsDir, `${String(record.pid)}.json`), `${JSON.stringify({ directPort: record.directPort })}
|
|
3340
3340
|
`);
|
|
3341
3341
|
}
|
|
3342
|
-
function removeFrontDoorDirectRecord(
|
|
3343
|
-
|
|
3342
|
+
function removeFrontDoorDirectRecord(fs14, recordsDir, pid) {
|
|
3343
|
+
fs14.removeRecursive(path8.join(recordsDir, `${String(pid)}.json`));
|
|
3344
|
+
}
|
|
3345
|
+
function markFrontDoorDraining(fs14, markersDir, pid) {
|
|
3346
|
+
fs14.mkdirp(markersDir);
|
|
3347
|
+
fs14.writeFilePrivate(path8.join(markersDir, String(pid)), "\n");
|
|
3348
|
+
}
|
|
3349
|
+
function unmarkFrontDoorDraining(fs14, markersDir, pid) {
|
|
3350
|
+
fs14.removeRecursive(path8.join(markersDir, String(pid)));
|
|
3351
|
+
}
|
|
3352
|
+
function listDrainingFrontDoors(fs14, markersDir, isRunning) {
|
|
3353
|
+
return fs14.readdir(markersDir).flatMap((file) => /^[1-9]\d*$/.test(file) && Number.isSafeInteger(Number(file)) ? [Number(file)] : []).filter(isRunning).sort((a, b) => a - b);
|
|
3344
3354
|
}
|
|
3345
3355
|
function recordPid(file) {
|
|
3346
3356
|
const pidText = /^([1-9]\d*)\.json$/.exec(file)?.[1];
|
|
3347
3357
|
const pid = pidText === void 0 ? void 0 : Number(pidText);
|
|
3348
3358
|
return pid !== void 0 && Number.isSafeInteger(pid) ? pid : void 0;
|
|
3349
3359
|
}
|
|
3350
|
-
function readDirectRecordEntry(
|
|
3360
|
+
function readDirectRecordEntry(fs14, recordsDir, file) {
|
|
3351
3361
|
const pid = recordPid(file);
|
|
3352
3362
|
if (pid === void 0) {
|
|
3353
3363
|
return void 0;
|
|
3354
3364
|
}
|
|
3355
3365
|
let raw;
|
|
3356
3366
|
try {
|
|
3357
|
-
raw =
|
|
3367
|
+
raw = fs14.readFileUtf8(path8.join(recordsDir, file));
|
|
3358
3368
|
} catch {
|
|
3359
3369
|
return void 0;
|
|
3360
3370
|
}
|
|
@@ -3368,47 +3378,47 @@ function readDirectRecordEntry(fs13, recordsDir, file) {
|
|
|
3368
3378
|
return { malformed: true };
|
|
3369
3379
|
}
|
|
3370
3380
|
}
|
|
3371
|
-
function listFrontDoorDirectRecords(
|
|
3372
|
-
return
|
|
3373
|
-
const entry = readDirectRecordEntry(
|
|
3381
|
+
function listFrontDoorDirectRecords(fs14, recordsDir) {
|
|
3382
|
+
return fs14.readdir(recordsDir).flatMap((file) => {
|
|
3383
|
+
const entry = readDirectRecordEntry(fs14, recordsDir, file);
|
|
3374
3384
|
return entry?.record === void 0 ? [] : [entry.record];
|
|
3375
3385
|
}).sort((a, b) => a.pid - b.pid);
|
|
3376
3386
|
}
|
|
3377
|
-
function pruneMalformedFrontDoorDirectFiles(
|
|
3378
|
-
for (const file of
|
|
3387
|
+
function pruneMalformedFrontDoorDirectFiles(fs14, recordsDir, isRunning) {
|
|
3388
|
+
for (const file of fs14.readdir(recordsDir)) {
|
|
3379
3389
|
const writer = RECORD_TEMPORARY_FILE.exec(file)?.[1];
|
|
3380
3390
|
const stale = writer !== void 0 && !isRunning(Number(writer));
|
|
3381
|
-
if (stale || readDirectRecordEntry(
|
|
3382
|
-
|
|
3391
|
+
if (stale || readDirectRecordEntry(fs14, recordsDir, file)?.malformed === true) {
|
|
3392
|
+
fs14.removeRecursive(path8.join(recordsDir, file));
|
|
3383
3393
|
}
|
|
3384
3394
|
}
|
|
3385
3395
|
}
|
|
3386
3396
|
function liveFrontDoorDirectRecords(records, liveness) {
|
|
3387
3397
|
return records.filter((record) => liveness.doors.has(record.pid) || liveness.unknown.has(record.pid));
|
|
3388
3398
|
}
|
|
3389
|
-
function pruneDeadFrontDoorDirectRecords(
|
|
3399
|
+
function pruneDeadFrontDoorDirectRecords(fs14, recordsDir, records, liveness) {
|
|
3390
3400
|
for (const record of records) {
|
|
3391
3401
|
if (!liveness.doors.has(record.pid) && !liveness.unknown.has(record.pid)) {
|
|
3392
|
-
removeFrontDoorDirectRecord(
|
|
3402
|
+
removeFrontDoorDirectRecord(fs14, recordsDir, record.pid);
|
|
3393
3403
|
}
|
|
3394
3404
|
}
|
|
3395
3405
|
}
|
|
3396
3406
|
function recordOf(details) {
|
|
3397
3407
|
return details === void 0 ? {} : { sessionId: details.sessionId, ...details.models === void 0 ? {} : { models: details.models } };
|
|
3398
3408
|
}
|
|
3399
|
-
function writeFrontDoorSession(
|
|
3400
|
-
|
|
3401
|
-
|
|
3409
|
+
function writeFrontDoorSession(fs14, sessionsDir, session) {
|
|
3410
|
+
fs14.mkdirPrivate(sessionsDir);
|
|
3411
|
+
fs14.writeFilePrivate(path8.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
3402
3412
|
`);
|
|
3403
3413
|
}
|
|
3404
|
-
function listFrontDoorSessions(
|
|
3414
|
+
function listFrontDoorSessions(fs14, sessionsDir) {
|
|
3405
3415
|
const sessions = [];
|
|
3406
|
-
for (const name of
|
|
3416
|
+
for (const name of fs14.readdir(sessionsDir)) {
|
|
3407
3417
|
if (!name.endsWith(".json")) {
|
|
3408
3418
|
continue;
|
|
3409
3419
|
}
|
|
3410
3420
|
try {
|
|
3411
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(
|
|
3421
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs14.readFileUtf8(path8.join(sessionsDir, name)) ?? ""));
|
|
3412
3422
|
if (parsed.success) {
|
|
3413
3423
|
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
|
|
3414
3424
|
}
|
|
@@ -3418,14 +3428,14 @@ function listFrontDoorSessions(fs13, sessionsDir) {
|
|
|
3418
3428
|
}
|
|
3419
3429
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
3420
3430
|
}
|
|
3421
|
-
function removeFrontDoorSession(
|
|
3422
|
-
|
|
3431
|
+
function removeFrontDoorSession(fs14, sessionsDir, pid) {
|
|
3432
|
+
fs14.removeRecursive(path8.join(sessionsDir, `${String(pid)}.json`));
|
|
3423
3433
|
}
|
|
3424
|
-
function pruneDeadFrontDoorSessions(
|
|
3434
|
+
function pruneDeadFrontDoorSessions(fs14, sessionsDir, isRunning) {
|
|
3425
3435
|
const removed = [];
|
|
3426
|
-
for (const session of listFrontDoorSessions(
|
|
3436
|
+
for (const session of listFrontDoorSessions(fs14, sessionsDir)) {
|
|
3427
3437
|
if (!isRunning(session.pid)) {
|
|
3428
|
-
removeFrontDoorSession(
|
|
3438
|
+
removeFrontDoorSession(fs14, sessionsDir, session.pid);
|
|
3429
3439
|
removed.push(session.pid);
|
|
3430
3440
|
}
|
|
3431
3441
|
}
|
|
@@ -3522,9 +3532,9 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
3522
3532
|
}
|
|
3523
3533
|
}
|
|
3524
3534
|
async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
3525
|
-
const { fs:
|
|
3535
|
+
const { fs: fs14, paths } = ports;
|
|
3526
3536
|
const servingBinary = ports.statOwnExecutable();
|
|
3527
|
-
const previous = readFrontDoorState(
|
|
3537
|
+
const previous = readFrontDoorState(fs14, paths.frontdoorStateFile);
|
|
3528
3538
|
let lastPort = previous?.lastPort;
|
|
3529
3539
|
let lastConnectPort = previous?.lastConnectPort;
|
|
3530
3540
|
let lastDirectPort = previous?.lastDirectPort;
|
|
@@ -3535,12 +3545,12 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3535
3545
|
});
|
|
3536
3546
|
const fail = (message) => {
|
|
3537
3547
|
ports.closeRcStreamHub();
|
|
3538
|
-
writeFrontDoorState(
|
|
3539
|
-
|
|
3548
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, { lastError: message, ...sticky() });
|
|
3549
|
+
fs14.removeRecursive(paths.frontdoorLockFile);
|
|
3540
3550
|
ports.log(`agent-shim frontdoor supervisor: ${message}`);
|
|
3541
3551
|
return 1;
|
|
3542
3552
|
};
|
|
3543
|
-
writeFrontDoorState(
|
|
3553
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
|
|
3544
3554
|
const previousSticky = lastPort;
|
|
3545
3555
|
let http3;
|
|
3546
3556
|
try {
|
|
@@ -3580,16 +3590,16 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3580
3590
|
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)`);
|
|
3581
3591
|
}
|
|
3582
3592
|
lastDirectPort = direct.port;
|
|
3583
|
-
writeFrontDoorDirectRecord(
|
|
3584
|
-
writeFrontDoorState(
|
|
3593
|
+
writeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, { pid: ports.ownPid, directPort: direct.port });
|
|
3594
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
3585
3595
|
ports.doorHealth.generation({ providerPort: http3.port, connectPort: connect3.port, directPort: direct.port });
|
|
3586
|
-
|
|
3596
|
+
fs14.removeRecursive(paths.frontdoorLockFile);
|
|
3587
3597
|
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)}`);
|
|
3588
3598
|
const watchdog = ports.startWatchdog?.();
|
|
3589
3599
|
let idleSince;
|
|
3590
3600
|
let ticks = 0;
|
|
3591
3601
|
const supersedingOwner = () => {
|
|
3592
|
-
const owner = readFrontDoorState(
|
|
3602
|
+
const owner = readFrontDoorState(fs14, paths.frontdoorStateFile)?.supervisorPid;
|
|
3593
3603
|
return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
|
|
3594
3604
|
};
|
|
3595
3605
|
let supersededBy;
|
|
@@ -3598,30 +3608,61 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3598
3608
|
const current = ports.statOwnExecutable();
|
|
3599
3609
|
return current !== void 0 && servingBinary !== void 0 && (current.dev !== servingBinary.dev || current.ino !== servingBinary.ino || current.size !== servingBinary.size || current.mtimeMs !== servingBinary.mtimeMs);
|
|
3600
3610
|
};
|
|
3611
|
+
const pause = async () => {
|
|
3612
|
+
await new Promise((resolve) => {
|
|
3613
|
+
const wake = () => {
|
|
3614
|
+
resolve();
|
|
3615
|
+
};
|
|
3616
|
+
ports.retire?.addEventListener("abort", wake, { once: true });
|
|
3617
|
+
void ports.sleep(FRONTDOOR_POLL_MS).then(() => {
|
|
3618
|
+
ports.retire?.removeEventListener("abort", wake);
|
|
3619
|
+
resolve();
|
|
3620
|
+
});
|
|
3621
|
+
});
|
|
3622
|
+
};
|
|
3623
|
+
const retireByDrain = async () => {
|
|
3624
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: asked to exit; releasing the front door's addresses and finishing the connections it carries`);
|
|
3625
|
+
watchdog?.stop();
|
|
3626
|
+
ports.stopBackgroundWork?.();
|
|
3627
|
+
const drained = [direct.drain(), connect3.drain(), http3.drain()];
|
|
3628
|
+
if (supersedingOwner() === void 0) {
|
|
3629
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
|
|
3630
|
+
}
|
|
3631
|
+
markFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
|
|
3632
|
+
ports.closeRcStreamHub();
|
|
3633
|
+
await Promise.all(drained);
|
|
3634
|
+
unmarkFrontDoorDraining(fs14, paths.frontdoorDrainingDir, ports.ownPid);
|
|
3635
|
+
removeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, ports.ownPid);
|
|
3636
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: the connections this door carried have ended; exiting`);
|
|
3637
|
+
return 0;
|
|
3638
|
+
};
|
|
3601
3639
|
const closeServing = async () => {
|
|
3602
3640
|
watchdog?.stop();
|
|
3603
3641
|
await direct.close();
|
|
3604
3642
|
await connect3.close();
|
|
3605
3643
|
await http3.close();
|
|
3606
3644
|
ports.closeRcStreamHub();
|
|
3607
|
-
removeFrontDoorDirectRecord(
|
|
3645
|
+
removeFrontDoorDirectRecord(fs14, paths.frontdoorDirectRecordsDir, ports.ownPid);
|
|
3608
3646
|
};
|
|
3609
3647
|
const shutdown = async () => {
|
|
3610
3648
|
await closeServing();
|
|
3611
3649
|
if (supersedingOwner() === void 0) {
|
|
3612
|
-
writeFrontDoorState(
|
|
3650
|
+
writeFrontDoorState(fs14, paths.frontdoorStateFile, sticky());
|
|
3613
3651
|
}
|
|
3614
3652
|
return 0;
|
|
3615
3653
|
};
|
|
3616
3654
|
for (; ; ) {
|
|
3617
3655
|
watchdog?.beat();
|
|
3656
|
+
if (ports.retire?.aborted === true) {
|
|
3657
|
+
return await retireByDrain();
|
|
3658
|
+
}
|
|
3618
3659
|
if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
|
|
3619
3660
|
watchdog?.stop();
|
|
3620
3661
|
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
3621
3662
|
}
|
|
3622
3663
|
ticks += 1;
|
|
3623
|
-
const listed = listFrontDoorSessions(
|
|
3624
|
-
const pruned = pruneDeadFrontDoorSessions(
|
|
3664
|
+
const listed = listFrontDoorSessions(fs14, paths.frontdoorSessionsDir);
|
|
3665
|
+
const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, ports.isRunning);
|
|
3625
3666
|
ports.observeLaunchRegistry(listed, pruned);
|
|
3626
3667
|
ports.checkQuotaExpiry();
|
|
3627
3668
|
const prunedPids = new Set(pruned);
|
|
@@ -3631,7 +3672,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3631
3672
|
if (supersededBy !== void 0) {
|
|
3632
3673
|
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`);
|
|
3633
3674
|
ports.doorHealth.superseded(supersededBy);
|
|
3634
|
-
await
|
|
3675
|
+
await pause();
|
|
3635
3676
|
continue;
|
|
3636
3677
|
}
|
|
3637
3678
|
} else {
|
|
@@ -3643,7 +3684,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3643
3684
|
await closeServing();
|
|
3644
3685
|
return 0;
|
|
3645
3686
|
}
|
|
3646
|
-
await
|
|
3687
|
+
await pause();
|
|
3647
3688
|
continue;
|
|
3648
3689
|
}
|
|
3649
3690
|
if (live.length === 0) {
|
|
@@ -3661,7 +3702,7 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
3661
3702
|
} else {
|
|
3662
3703
|
idleSince = void 0;
|
|
3663
3704
|
}
|
|
3664
|
-
await
|
|
3705
|
+
await pause();
|
|
3665
3706
|
}
|
|
3666
3707
|
}
|
|
3667
3708
|
var FRONTDOOR_SUPERVISOR_STILL_RUNNING, FRONTDOOR_POLL_MS, MS_PER_MINUTE;
|
|
@@ -3815,25 +3856,35 @@ ${request4.rawHeaders.reduce((accumulated, value, index) => index % 2 === 0 ? `$
|
|
|
3815
3856
|
const transparent = config.transparentPort === void 0 || apiSession === void 0 ? void 0 : await effects.listenLoopback(config.transparentPort, (socket) => {
|
|
3816
3857
|
sniAcceptor.accept(socket);
|
|
3817
3858
|
});
|
|
3859
|
+
const closeSurface = async () => {
|
|
3860
|
+
ledger.close();
|
|
3861
|
+
await listener.close();
|
|
3862
|
+
await transparent?.close();
|
|
3863
|
+
sniAcceptor.close();
|
|
3864
|
+
for (const { httpSession, tlsAcceptor } of sessions) {
|
|
3865
|
+
tlsAcceptor.close();
|
|
3866
|
+
httpSession?.close();
|
|
3867
|
+
}
|
|
3868
|
+
};
|
|
3818
3869
|
return {
|
|
3819
3870
|
port: listener.port,
|
|
3820
3871
|
...transparent === void 0 ? {} : { transparentPort: transparent.port },
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3872
|
+
openTunnels: ledger.openTunnels,
|
|
3873
|
+
drain: async () => {
|
|
3874
|
+
listener.stopAccepting();
|
|
3824
3875
|
await transparent?.close();
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
}
|
|
3830
|
-
}
|
|
3876
|
+
await ledger.retire();
|
|
3877
|
+
await closeSurface();
|
|
3878
|
+
},
|
|
3879
|
+
close: closeSurface
|
|
3831
3880
|
};
|
|
3832
3881
|
}
|
|
3833
3882
|
function createConnectionLedger(limits, isLiveCapability2) {
|
|
3834
3883
|
const pending = /* @__PURE__ */ new Map();
|
|
3835
3884
|
const authenticated = /* @__PURE__ */ new Map();
|
|
3836
3885
|
let tunnels = 0;
|
|
3886
|
+
const blind = /* @__PURE__ */ new Set();
|
|
3887
|
+
let onNoBlindTunnels;
|
|
3837
3888
|
const leavePending = (socket) => {
|
|
3838
3889
|
const deadline = pending.get(socket);
|
|
3839
3890
|
if (deadline !== void 0) {
|
|
@@ -3870,16 +3921,45 @@ function createConnectionLedger(limits, isLiveCapability2) {
|
|
|
3870
3921
|
});
|
|
3871
3922
|
},
|
|
3872
3923
|
headReceived: leavePending,
|
|
3873
|
-
|
|
3924
|
+
openTunnels: () => tunnels,
|
|
3925
|
+
retire: async () => {
|
|
3926
|
+
for (const socket of pending.keys()) {
|
|
3927
|
+
socket.destroy();
|
|
3928
|
+
}
|
|
3929
|
+
for (const deadline of pending.values()) {
|
|
3930
|
+
clearTimeout(deadline);
|
|
3931
|
+
}
|
|
3932
|
+
pending.clear();
|
|
3933
|
+
for (const sockets of authenticated.values()) {
|
|
3934
|
+
for (const socket of sockets) {
|
|
3935
|
+
if (!blind.has(socket)) {
|
|
3936
|
+
socket.destroy();
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
if (blind.size > 0) {
|
|
3941
|
+
await new Promise((resolve) => {
|
|
3942
|
+
onNoBlindTunnels = resolve;
|
|
3943
|
+
});
|
|
3944
|
+
}
|
|
3945
|
+
},
|
|
3946
|
+
establish: (socket, capability, kind) => {
|
|
3874
3947
|
if (tunnels >= limits.maxTunnels) {
|
|
3875
3948
|
return false;
|
|
3876
3949
|
}
|
|
3877
3950
|
tunnels += 1;
|
|
3951
|
+
if (kind === "blind") {
|
|
3952
|
+
blind.add(socket);
|
|
3953
|
+
}
|
|
3878
3954
|
const sockets = authenticated.get(capability) ?? /* @__PURE__ */ new Set();
|
|
3879
3955
|
sockets.add(socket);
|
|
3880
3956
|
authenticated.set(capability, sockets);
|
|
3881
3957
|
socket.once("close", () => {
|
|
3882
3958
|
tunnels -= 1;
|
|
3959
|
+
blind.delete(socket);
|
|
3960
|
+
if (blind.size === 0) {
|
|
3961
|
+
onNoBlindTunnels?.();
|
|
3962
|
+
}
|
|
3883
3963
|
sockets.delete(socket);
|
|
3884
3964
|
if (sockets.size === 0 && authenticated.get(capability) === sockets) {
|
|
3885
3965
|
authenticated.delete(capability);
|
|
@@ -3961,11 +4041,11 @@ function routeConnect(socket, head, context) {
|
|
|
3961
4041
|
refuse(socket, REFUSAL.badRequest);
|
|
3962
4042
|
return;
|
|
3963
4043
|
}
|
|
3964
|
-
|
|
4044
|
+
const session = sessions.find((entry) => entry.host === target.host);
|
|
4045
|
+
if (!ledger.establish(socket, capability, session === void 0 ? "blind" : "terminated")) {
|
|
3965
4046
|
refuse(socket, REFUSAL.serviceUnavailable);
|
|
3966
4047
|
return;
|
|
3967
4048
|
}
|
|
3968
|
-
const session = sessions.find((entry) => entry.host === target.host);
|
|
3969
4049
|
config.capture?.connect(target, session !== void 0);
|
|
3970
4050
|
socket.write(CONNECT_ESTABLISHED);
|
|
3971
4051
|
if (session !== void 0) {
|
|
@@ -4087,7 +4167,7 @@ var init_package = __esm({
|
|
|
4087
4167
|
"package.json"() {
|
|
4088
4168
|
package_default = {
|
|
4089
4169
|
name: "claude-use",
|
|
4090
|
-
version: "11.
|
|
4170
|
+
version: "11.49.0",
|
|
4091
4171
|
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.",
|
|
4092
4172
|
license: "MIT",
|
|
4093
4173
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -4295,43 +4375,43 @@ function parseJson(raw, schema) {
|
|
|
4295
4375
|
const parsed = schema.safeParse(JSON.parse(raw));
|
|
4296
4376
|
return parsed.success ? parsed.data : void 0;
|
|
4297
4377
|
}
|
|
4298
|
-
function readHeadroomState(
|
|
4378
|
+
function readHeadroomState(fs14, stateFile) {
|
|
4299
4379
|
try {
|
|
4300
|
-
return parseJson(
|
|
4380
|
+
return parseJson(fs14.readFileUtf8(stateFile), HeadroomStateSchema);
|
|
4301
4381
|
} catch {
|
|
4302
4382
|
return void 0;
|
|
4303
4383
|
}
|
|
4304
4384
|
}
|
|
4305
|
-
function writeHeadroomState(
|
|
4306
|
-
|
|
4307
|
-
|
|
4385
|
+
function writeHeadroomState(fs14, stateFile, state) {
|
|
4386
|
+
fs14.mkdirp(path11.dirname(stateFile));
|
|
4387
|
+
fs14.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
4308
4388
|
`);
|
|
4309
4389
|
}
|
|
4310
|
-
function resolveServingHeadroomState(
|
|
4311
|
-
const current = readHeadroomState(
|
|
4390
|
+
function resolveServingHeadroomState(fs14, files, isRunning) {
|
|
4391
|
+
const current = readHeadroomState(fs14, files.stateFile);
|
|
4312
4392
|
if (current !== void 0) {
|
|
4313
4393
|
return { path: files.stateFile, state: current };
|
|
4314
4394
|
}
|
|
4315
|
-
const legacy = readHeadroomState(
|
|
4395
|
+
const legacy = readHeadroomState(fs14, files.legacyStateFile);
|
|
4316
4396
|
if (legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid)) {
|
|
4317
4397
|
return { path: files.legacyStateFile, state: legacy };
|
|
4318
4398
|
}
|
|
4319
4399
|
return void 0;
|
|
4320
4400
|
}
|
|
4321
|
-
function migrateHeadroomState(
|
|
4322
|
-
const legacy = readHeadroomState(
|
|
4401
|
+
function migrateHeadroomState(fs14, files, isRunning) {
|
|
4402
|
+
const legacy = readHeadroomState(fs14, files.legacyStateFile);
|
|
4323
4403
|
const legacyLive = legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid);
|
|
4324
|
-
const current = readHeadroomState(
|
|
4404
|
+
const current = readHeadroomState(fs14, files.stateFile);
|
|
4325
4405
|
if (current !== void 0 || legacyLive) {
|
|
4326
|
-
if (!legacyLive &&
|
|
4327
|
-
|
|
4406
|
+
if (!legacyLive && fs14.readFileUtf8(files.legacyStateFile) !== void 0) {
|
|
4407
|
+
fs14.removeRecursive(files.legacyStateFile);
|
|
4328
4408
|
}
|
|
4329
4409
|
return;
|
|
4330
4410
|
}
|
|
4331
4411
|
if (legacy !== void 0) {
|
|
4332
|
-
writeHeadroomState(
|
|
4412
|
+
writeHeadroomState(fs14, files.stateFile, legacy);
|
|
4333
4413
|
}
|
|
4334
|
-
|
|
4414
|
+
fs14.removeRecursive(files.legacyStateFile);
|
|
4335
4415
|
}
|
|
4336
4416
|
function hashAllowlist(allowlist) {
|
|
4337
4417
|
return createHash3("sha256").update(allowlist.join("\n")).digest("hex");
|
|
@@ -4364,27 +4444,27 @@ function isAdmissibleUrl(entry) {
|
|
|
4364
4444
|
function parseAllowlistFile(content) {
|
|
4365
4445
|
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)));
|
|
4366
4446
|
}
|
|
4367
|
-
function writeAllowlistFile(
|
|
4368
|
-
|
|
4369
|
-
|
|
4447
|
+
function writeAllowlistFile(fs14, allowlistFile, allowlist) {
|
|
4448
|
+
fs14.mkdirPrivate(path11.dirname(allowlistFile));
|
|
4449
|
+
fs14.writeFilePrivate(allowlistFile, formatAllowlistFile(allowlist));
|
|
4370
4450
|
}
|
|
4371
|
-
function pruneStaleAllowlistTemporaries(
|
|
4451
|
+
function pruneStaleAllowlistTemporaries(fs14, allowlistFile, isRunning) {
|
|
4372
4452
|
const prefix = `${path11.basename(allowlistFile)}.`;
|
|
4373
|
-
for (const name of
|
|
4453
|
+
for (const name of fs14.readdir(path11.dirname(allowlistFile))) {
|
|
4374
4454
|
const writer = name.startsWith(prefix) ? /^([1-9]\d*)\.tmp$/.exec(name.slice(prefix.length))?.[1] : void 0;
|
|
4375
4455
|
if (writer !== void 0 && !isRunning(Number(writer))) {
|
|
4376
|
-
|
|
4456
|
+
fs14.removeRecursive(path11.join(path11.dirname(allowlistFile), name));
|
|
4377
4457
|
}
|
|
4378
4458
|
}
|
|
4379
4459
|
}
|
|
4380
|
-
function readAllProviders(
|
|
4460
|
+
function readAllProviders(fs14, providersDir) {
|
|
4381
4461
|
const result = [];
|
|
4382
|
-
for (const name of
|
|
4462
|
+
for (const name of fs14.readdir(providersDir)) {
|
|
4383
4463
|
if (!name.endsWith(".json")) {
|
|
4384
4464
|
continue;
|
|
4385
4465
|
}
|
|
4386
4466
|
try {
|
|
4387
|
-
const parsed = parseJson(
|
|
4467
|
+
const parsed = parseJson(fs14.readFileUtf8(path11.join(providersDir, name)), ProviderSchema);
|
|
4388
4468
|
if (parsed !== void 0) {
|
|
4389
4469
|
result.push({ name: name.slice(0, -".json".length), provider: parsed });
|
|
4390
4470
|
}
|
|
@@ -4394,22 +4474,22 @@ function readAllProviders(fs13, providersDir) {
|
|
|
4394
4474
|
}
|
|
4395
4475
|
return result;
|
|
4396
4476
|
}
|
|
4397
|
-
function writeSession(
|
|
4398
|
-
|
|
4399
|
-
|
|
4477
|
+
function writeSession(fs14, sessionsDir, session) {
|
|
4478
|
+
fs14.mkdirp(sessionsDir);
|
|
4479
|
+
fs14.writeFileUtf8(path11.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
4400
4480
|
`);
|
|
4401
4481
|
}
|
|
4402
|
-
function removeSession(
|
|
4403
|
-
|
|
4482
|
+
function removeSession(fs14, sessionsDir, pid) {
|
|
4483
|
+
fs14.removeRecursive(path11.join(sessionsDir, `${String(pid)}.json`));
|
|
4404
4484
|
}
|
|
4405
|
-
function listSessions(
|
|
4485
|
+
function listSessions(fs14, sessionsDir) {
|
|
4406
4486
|
const sessions = [];
|
|
4407
|
-
for (const name of
|
|
4487
|
+
for (const name of fs14.readdir(sessionsDir)) {
|
|
4408
4488
|
if (!name.endsWith(".json")) {
|
|
4409
4489
|
continue;
|
|
4410
4490
|
}
|
|
4411
4491
|
try {
|
|
4412
|
-
const parsed = parseJson(
|
|
4492
|
+
const parsed = parseJson(fs14.readFileUtf8(path11.join(sessionsDir, name)), HeadroomSessionSchema);
|
|
4413
4493
|
if (parsed !== void 0) {
|
|
4414
4494
|
sessions.push(parsed);
|
|
4415
4495
|
}
|
|
@@ -4419,22 +4499,22 @@ function listSessions(fs13, sessionsDir) {
|
|
|
4419
4499
|
}
|
|
4420
4500
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
4421
4501
|
}
|
|
4422
|
-
function sessionsForSupervisor(
|
|
4423
|
-
return listSessions(
|
|
4502
|
+
function sessionsForSupervisor(fs14, sessionsDir, supervisorPid) {
|
|
4503
|
+
return listSessions(fs14, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
|
|
4424
4504
|
}
|
|
4425
|
-
function pruneDeadSessions(
|
|
4505
|
+
function pruneDeadSessions(fs14, sessionsDir, isRunning) {
|
|
4426
4506
|
const removed = [];
|
|
4427
|
-
for (const session of listSessions(
|
|
4507
|
+
for (const session of listSessions(fs14, sessionsDir)) {
|
|
4428
4508
|
if (!isRunning(session.pid)) {
|
|
4429
|
-
removeSession(
|
|
4509
|
+
removeSession(fs14, sessionsDir, session.pid);
|
|
4430
4510
|
removed.push(session.pid);
|
|
4431
4511
|
}
|
|
4432
4512
|
}
|
|
4433
4513
|
return removed;
|
|
4434
4514
|
}
|
|
4435
|
-
function readStartLock(
|
|
4515
|
+
function readStartLock(fs14, lockFile) {
|
|
4436
4516
|
try {
|
|
4437
|
-
return parseJson(
|
|
4517
|
+
return parseJson(fs14.readFileUtf8(lockFile), HeadroomLockSchema);
|
|
4438
4518
|
} catch {
|
|
4439
4519
|
return void 0;
|
|
4440
4520
|
}
|
|
@@ -4524,12 +4604,12 @@ function earlierReleaseAllowlistHash(providers, doorOrigin) {
|
|
|
4524
4604
|
}
|
|
4525
4605
|
return hashAllowlist([...entries].sort());
|
|
4526
4606
|
}
|
|
4527
|
-
function earlierReleaseDaemon(
|
|
4607
|
+
function earlierReleaseDaemon(fs14, paths, daemon) {
|
|
4528
4608
|
if (daemonIdentity(daemon.commandLine, daemon.socketPath) !== "earlier-release") {
|
|
4529
4609
|
return void 0;
|
|
4530
4610
|
}
|
|
4531
|
-
const providers = readAllProviders(
|
|
4532
|
-
const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(
|
|
4611
|
+
const providers = readAllProviders(fs14, paths.providersDir).map((entry) => entry.provider);
|
|
4612
|
+
const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile)));
|
|
4533
4613
|
return { admitsServingDoor: daemon.recordedHash === expected };
|
|
4534
4614
|
}
|
|
4535
4615
|
var EARLIER_RELEASE_ALLOWLIST, EARLIER_RELEASE_ANTHROPIC_UPSTREAM;
|
|
@@ -4554,8 +4634,8 @@ function awaitingCause(daemonPid, identity, allowlistFile) {
|
|
|
4554
4634
|
}
|
|
4555
4635
|
return `the headroom supervisor has not written an allowlist admitting this launch's upstreams to ${allowlistFile} within ${String(HEADROOM_START_TIMEOUT_MS)}ms`;
|
|
4556
4636
|
}
|
|
4557
|
-
function daemonAdmits(
|
|
4558
|
-
const content =
|
|
4637
|
+
function daemonAdmits(fs14, allowlistFile, recordedHash, required) {
|
|
4638
|
+
const content = fs14.readFileUtf8(allowlistFile);
|
|
4559
4639
|
if (content === void 0 || recordedHash === void 0) {
|
|
4560
4640
|
return false;
|
|
4561
4641
|
}
|
|
@@ -4818,7 +4898,7 @@ function verifyAllowlistFile(allowlistFile, ports) {
|
|
|
4818
4898
|
const replaceable = fileStat === void 0 || fileStat.kind === "file" || fileStat.kind === "symlink";
|
|
4819
4899
|
return { message: refusal2, repairable: replaceable };
|
|
4820
4900
|
}
|
|
4821
|
-
function prepareHeadroomSocket(
|
|
4901
|
+
function prepareHeadroomSocket(fs14, ports, paths, supervisorPid) {
|
|
4822
4902
|
const unsupported = platformRefusal(ports.platform);
|
|
4823
4903
|
if (unsupported !== void 0) {
|
|
4824
4904
|
return { refused: unsupported };
|
|
@@ -4833,18 +4913,18 @@ function prepareHeadroomSocket(fs13, ports, paths, supervisorPid) {
|
|
|
4833
4913
|
if (ports.lstat(paths.headroomSocketDir)?.kind === "symlink") {
|
|
4834
4914
|
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
4835
4915
|
}
|
|
4836
|
-
|
|
4916
|
+
fs14.mkdirPrivate(paths.headroomSocketDir);
|
|
4837
4917
|
const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
4838
4918
|
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
4839
4919
|
}
|
|
4840
|
-
function pruneStaleHeadroomSockets(
|
|
4920
|
+
function pruneStaleHeadroomSockets(fs14, paths, isRunning) {
|
|
4841
4921
|
const removed = [];
|
|
4842
|
-
for (const name of
|
|
4922
|
+
for (const name of fs14.readdir(paths.headroomSocketDir)) {
|
|
4843
4923
|
const pid = HEADROOM_SOCKET_NAME.exec(name)?.[1];
|
|
4844
4924
|
if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
|
|
4845
4925
|
continue;
|
|
4846
4926
|
}
|
|
4847
|
-
|
|
4927
|
+
fs14.removeRecursive(path12.join(paths.headroomSocketDir, name));
|
|
4848
4928
|
removed.push(name);
|
|
4849
4929
|
}
|
|
4850
4930
|
return removed;
|
|
@@ -4956,37 +5036,37 @@ function compareVersions2(a, b) {
|
|
|
4956
5036
|
return 0;
|
|
4957
5037
|
}
|
|
4958
5038
|
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
4959
|
-
const { fs:
|
|
5039
|
+
const { fs: fs14, paths } = ports;
|
|
4960
5040
|
let config = initialConfig;
|
|
4961
|
-
migrateHeadroomState(
|
|
4962
|
-
const previousState = resolveServingHeadroomState(
|
|
5041
|
+
migrateHeadroomState(fs14, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
|
|
5042
|
+
const previousState = resolveServingHeadroomState(fs14, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
|
|
4963
5043
|
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
4964
5044
|
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
4965
5045
|
return 0;
|
|
4966
5046
|
}
|
|
4967
5047
|
let installedSource = previousState?.installedSource;
|
|
4968
5048
|
const ownsState = () => {
|
|
4969
|
-
const owner = readHeadroomState(
|
|
5049
|
+
const owner = readHeadroomState(fs14, paths.headroomStateFile)?.supervisorPid;
|
|
4970
5050
|
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
4971
5051
|
};
|
|
4972
5052
|
const writeOwnState = (state) => {
|
|
4973
5053
|
if (!ownsState()) {
|
|
4974
5054
|
return false;
|
|
4975
5055
|
}
|
|
4976
|
-
writeHeadroomState(
|
|
5056
|
+
writeHeadroomState(fs14, paths.headroomStateFile, state);
|
|
4977
5057
|
return true;
|
|
4978
5058
|
};
|
|
4979
5059
|
const fail = (message) => {
|
|
4980
5060
|
if (writeOwnState({ lastError: message })) {
|
|
4981
|
-
|
|
5061
|
+
fs14.removeRecursive(paths.headroomLockFile);
|
|
4982
5062
|
}
|
|
4983
5063
|
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
4984
5064
|
return 1;
|
|
4985
5065
|
};
|
|
4986
5066
|
const syncAllowlistFile = (allowlist) => {
|
|
4987
5067
|
try {
|
|
4988
|
-
if (
|
|
4989
|
-
writeAllowlistFile(
|
|
5068
|
+
if (fs14.readFileUtf8(paths.headroomAllowlistFile) !== formatAllowlistFile(allowlist)) {
|
|
5069
|
+
writeAllowlistFile(fs14, paths.headroomAllowlistFile, allowlist);
|
|
4990
5070
|
ports.log(`agent-shim headroom supervisor: wrote allowlist [${allowlist.join(", ")}] to ${paths.headroomAllowlistFile}`);
|
|
4991
5071
|
}
|
|
4992
5072
|
return void 0;
|
|
@@ -5004,9 +5084,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5004
5084
|
}
|
|
5005
5085
|
ports.log(`agent-shim headroom supervisor: repairing the allowlist file: ${problem.message}`);
|
|
5006
5086
|
try {
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
writeAllowlistFile(
|
|
5087
|
+
fs14.mkdirPrivate(paths.headroomDir);
|
|
5088
|
+
fs14.mkdirPrivate(path13.dirname(paths.headroomAllowlistFile));
|
|
5089
|
+
writeAllowlistFile(fs14, paths.headroomAllowlistFile, allowlist);
|
|
5010
5090
|
} catch (error) {
|
|
5011
5091
|
return `could not write the headroom allowlist file ${paths.headroomAllowlistFile}: ${error instanceof Error ? error.message : String(error)}`;
|
|
5012
5092
|
}
|
|
@@ -5031,20 +5111,20 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5031
5111
|
installedSource = config.source;
|
|
5032
5112
|
return void 0;
|
|
5033
5113
|
};
|
|
5034
|
-
const socket = prepareHeadroomSocket(
|
|
5114
|
+
const socket = prepareHeadroomSocket(fs14, ports.socketTrust, paths, ports.ownPid);
|
|
5035
5115
|
if (socket.refused !== void 0) {
|
|
5036
5116
|
return fail(socket.refused);
|
|
5037
5117
|
}
|
|
5038
5118
|
const { socketPath } = socket;
|
|
5039
|
-
pruneStaleHeadroomSockets(
|
|
5040
|
-
pruneStaleAllowlistTemporaries(
|
|
5119
|
+
pruneStaleHeadroomSockets(fs14, paths, ports.isRunning);
|
|
5120
|
+
pruneStaleAllowlistTemporaries(fs14, paths.headroomAllowlistFile, ports.isRunning);
|
|
5041
5121
|
const installFailure = ensureInstalled();
|
|
5042
5122
|
if (installFailure !== void 0) {
|
|
5043
5123
|
return fail(installFailure);
|
|
5044
5124
|
}
|
|
5045
5125
|
const version = ports.headroomVersion() ?? "unknown";
|
|
5046
5126
|
writeOwnState({ supervisorPid: ports.ownPid, version, installedSource });
|
|
5047
|
-
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(
|
|
5127
|
+
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(fs14, paths, ports.frontDoorLiveness).frontDoorOrigins.join(", ")}]`);
|
|
5048
5128
|
const orphanPid = previousState?.headroomPid;
|
|
5049
5129
|
const orphanSocket = previousState?.socketPath ?? (previousState?.supervisorPid === void 0 ? void 0 : headroomSocketPath(paths, previousState.supervisorPid));
|
|
5050
5130
|
const orphanIdentity = orphanPid === void 0 || orphanSocket === void 0 || !ports.isRunning(orphanPid) ? void 0 : daemonIdentity(ports.daemonCommandLine(orphanPid), orphanSocket);
|
|
@@ -5079,12 +5159,12 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5079
5159
|
ticks += 1;
|
|
5080
5160
|
config = ports.readConfig();
|
|
5081
5161
|
const settingsHash = hashSettings(config.settings);
|
|
5082
|
-
const inputs = currentHeadroomAllowlistInputs(
|
|
5083
|
-
pruneDeadFrontDoorDirectRecords(
|
|
5084
|
-
pruneMalformedFrontDoorDirectFiles(
|
|
5162
|
+
const inputs = currentHeadroomAllowlistInputs(fs14, paths, ports.frontDoorLiveness);
|
|
5163
|
+
pruneDeadFrontDoorDirectRecords(fs14, paths.frontdoorDirectRecordsDir, inputs.frontDoorRecords, inputs.frontDoorLiveness);
|
|
5164
|
+
pruneMalformedFrontDoorDirectFiles(fs14, paths.frontdoorDirectRecordsDir, ports.isRunning);
|
|
5085
5165
|
const allowlist = inputs.frontDoorOrigins;
|
|
5086
5166
|
const allowlistHash = hashAllowlist(allowlist);
|
|
5087
|
-
pruneDeadSessions(
|
|
5167
|
+
pruneDeadSessions(fs14, paths.headroomSessionsDir, ports.isRunning);
|
|
5088
5168
|
const ownsNow = ownsState();
|
|
5089
5169
|
if (!ownsNow && !superseded) {
|
|
5090
5170
|
ports.log("agent-shim headroom supervisor: another supervisor now owns the state file; serving this daemon's own sessions until they end");
|
|
@@ -5131,7 +5211,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5131
5211
|
runningSettingsHash = settingsHash;
|
|
5132
5212
|
const recorded = writeOwnState(servingState(pid));
|
|
5133
5213
|
if (recorded) {
|
|
5134
|
-
|
|
5214
|
+
fs14.removeRecursive(paths.headroomLockFile);
|
|
5135
5215
|
}
|
|
5136
5216
|
idleSince = void 0;
|
|
5137
5217
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on unix socket ${socketPath}`);
|
|
@@ -5159,7 +5239,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5159
5239
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} now serves allowlist [${allowlist.join(", ")}]`);
|
|
5160
5240
|
}
|
|
5161
5241
|
if (runningSettingsHash !== settingsHash || installedSource !== config.source) {
|
|
5162
|
-
if (sessionsForSupervisor(
|
|
5242
|
+
if (sessionsForSupervisor(fs14, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
5163
5243
|
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
5164
5244
|
ports.stopProcess(headroomPid);
|
|
5165
5245
|
headroomPid = void 0;
|
|
@@ -5168,7 +5248,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
5168
5248
|
continue;
|
|
5169
5249
|
}
|
|
5170
5250
|
}
|
|
5171
|
-
const sessions = sessionsForSupervisor(
|
|
5251
|
+
const sessions = sessionsForSupervisor(fs14, paths.headroomSessionsDir, ports.ownPid);
|
|
5172
5252
|
if (sessions.length === 0) {
|
|
5173
5253
|
idleSince ??= ports.now();
|
|
5174
5254
|
const idleMs = ports.now() - idleSince;
|
|
@@ -5193,9 +5273,9 @@ function undeterminedFrontDoors(inputs) {
|
|
|
5193
5273
|
return reason === void 0 ? [] : [{ pid: record.pid, origin: directOrigin(record.directPort), reason }];
|
|
5194
5274
|
});
|
|
5195
5275
|
}
|
|
5196
|
-
function currentHeadroomAllowlistInputs(
|
|
5197
|
-
const named = frontDoorOrigin(readFrontDoorState(
|
|
5198
|
-
const records = listFrontDoorDirectRecords(
|
|
5276
|
+
function currentHeadroomAllowlistInputs(fs14, paths, frontDoorLiveness) {
|
|
5277
|
+
const named = frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile));
|
|
5278
|
+
const records = listFrontDoorDirectRecords(fs14, paths.frontdoorDirectRecordsDir);
|
|
5199
5279
|
const liveness = frontDoorLiveness(records.map((record) => record.pid));
|
|
5200
5280
|
const live = liveFrontDoorDirectRecords(records, liveness).map((record) => directOrigin(record.directPort));
|
|
5201
5281
|
return {
|
|
@@ -5204,8 +5284,8 @@ function currentHeadroomAllowlistInputs(fs13, paths, frontDoorLiveness) {
|
|
|
5204
5284
|
frontDoorOrigins: [.../* @__PURE__ */ new Set([...named === void 0 ? [] : [named], ...live])].sort()
|
|
5205
5285
|
};
|
|
5206
5286
|
}
|
|
5207
|
-
function launchRequiredUpstreams(
|
|
5208
|
-
const door = frontDoorOrigin(readFrontDoorState(
|
|
5287
|
+
function launchRequiredUpstreams(fs14, paths) {
|
|
5288
|
+
const door = frontDoorOrigin(readFrontDoorState(fs14, paths.frontdoorStateFile));
|
|
5209
5289
|
return door === void 0 ? [] : [door];
|
|
5210
5290
|
}
|
|
5211
5291
|
async function waitUntilReady(ports, socketPath, pid) {
|
|
@@ -5929,8 +6009,8 @@ import path17 from "node:path";
|
|
|
5929
6009
|
function poolNameOf(selector) {
|
|
5930
6010
|
return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
|
|
5931
6011
|
}
|
|
5932
|
-
function readActiveIdentity(
|
|
5933
|
-
const trimmed =
|
|
6012
|
+
function readActiveIdentity(fs14, activeIdentityFile) {
|
|
6013
|
+
const trimmed = fs14.readFileUtf8(activeIdentityFile)?.trim();
|
|
5934
6014
|
return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
|
|
5935
6015
|
}
|
|
5936
6016
|
function isNonEmpty(value) {
|
|
@@ -5977,8 +6057,8 @@ function decideConfigProfile(params) {
|
|
|
5977
6057
|
}
|
|
5978
6058
|
return { source: "none" };
|
|
5979
6059
|
}
|
|
5980
|
-
function loadIdentity(identitiesDir, name,
|
|
5981
|
-
return loadConfigFile(path17.join(identitiesDir, name, "identity.json"), IdentitySchema,
|
|
6060
|
+
function loadIdentity(identitiesDir, name, fs14) {
|
|
6061
|
+
return loadConfigFile(path17.join(identitiesDir, name, "identity.json"), IdentitySchema, fs14.readConfigFile);
|
|
5982
6062
|
}
|
|
5983
6063
|
var IDENTITY_DECISION_SOURCES, CONFIG_PROFILE_DECISION_SOURCES;
|
|
5984
6064
|
var init_identity = __esm({
|
|
@@ -6220,14 +6300,14 @@ function isIdentityName(name) {
|
|
|
6220
6300
|
function claudeJsonPath(identitiesDir, identity) {
|
|
6221
6301
|
return path18.join(identitiesDir, identity, CLAUDE_JSON);
|
|
6222
6302
|
}
|
|
6223
|
-
function readAccountMetadata(
|
|
6303
|
+
function readAccountMetadata(fs14, identitiesDir, identity) {
|
|
6224
6304
|
if (!isIdentityName(identity)) {
|
|
6225
6305
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
6226
6306
|
}
|
|
6227
|
-
return readAccountMetadataFile(
|
|
6307
|
+
return readAccountMetadataFile(fs14, claudeJsonPath(identitiesDir, identity));
|
|
6228
6308
|
}
|
|
6229
|
-
function readAccountMetadataFile(
|
|
6230
|
-
const raw =
|
|
6309
|
+
function readAccountMetadataFile(fs14, file) {
|
|
6310
|
+
const raw = fs14.readFileUtf8(file);
|
|
6231
6311
|
if (raw === void 0) {
|
|
6232
6312
|
return void 0;
|
|
6233
6313
|
}
|
|
@@ -6257,19 +6337,19 @@ function readAccountMetadataFile(fs13, file) {
|
|
|
6257
6337
|
}
|
|
6258
6338
|
return account.data;
|
|
6259
6339
|
}
|
|
6260
|
-
function createAccountReader(
|
|
6340
|
+
function createAccountReader(fs14, identitiesDir) {
|
|
6261
6341
|
const cache = /* @__PURE__ */ new Map();
|
|
6262
6342
|
return (identity) => {
|
|
6263
6343
|
if (!isIdentityName(identity)) {
|
|
6264
6344
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
6265
6345
|
}
|
|
6266
|
-
const stat =
|
|
6346
|
+
const stat = fs14.lstat(claudeJsonPath(identitiesDir, identity));
|
|
6267
6347
|
const stamp = stat === void 0 ? "absent" : `${String(stat.mtimeMs)}:${String(stat.sizeBytes)}`;
|
|
6268
6348
|
const cached = cache.get(identity);
|
|
6269
6349
|
if (cached?.stamp === stamp) {
|
|
6270
6350
|
return cached.account;
|
|
6271
6351
|
}
|
|
6272
|
-
const account = readAccountMetadata(
|
|
6352
|
+
const account = readAccountMetadata(fs14, identitiesDir, identity);
|
|
6273
6353
|
cache.set(identity, { stamp, account });
|
|
6274
6354
|
return account;
|
|
6275
6355
|
};
|
|
@@ -6853,8 +6933,8 @@ function segmentDay(epochMs) {
|
|
|
6853
6933
|
function segmentName(day, pid) {
|
|
6854
6934
|
return `${day}.${String(pid)}.jsonl`;
|
|
6855
6935
|
}
|
|
6856
|
-
function listLogSegments(
|
|
6857
|
-
return
|
|
6936
|
+
function listLogSegments(fs14, logDir) {
|
|
6937
|
+
return fs14.readdir(logDir).flatMap((name) => {
|
|
6858
6938
|
const match = SEGMENT_RE.exec(name);
|
|
6859
6939
|
const day = match?.[1];
|
|
6860
6940
|
if (day === void 0) {
|
|
@@ -6863,15 +6943,15 @@ function listLogSegments(fs13, logDir) {
|
|
|
6863
6943
|
return [{ name, day, endsAt: Date.parse(`${day}T00:00:00.000Z`) + DAY_MS }];
|
|
6864
6944
|
}).sort((left, right) => left.day.localeCompare(right.day) || left.name.localeCompare(right.name));
|
|
6865
6945
|
}
|
|
6866
|
-
function readUsageLog(
|
|
6946
|
+
function readUsageLog(fs14, logDir, options = {}) {
|
|
6867
6947
|
const { sinceMs } = options;
|
|
6868
6948
|
const records = [];
|
|
6869
6949
|
let invalidLines = 0;
|
|
6870
|
-
for (const segment of listLogSegments(
|
|
6950
|
+
for (const segment of listLogSegments(fs14, logDir)) {
|
|
6871
6951
|
if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
|
|
6872
6952
|
continue;
|
|
6873
6953
|
}
|
|
6874
|
-
const contents =
|
|
6954
|
+
const contents = fs14.readFileUtf8(path19.join(logDir, segment.name));
|
|
6875
6955
|
if (contents === void 0) {
|
|
6876
6956
|
continue;
|
|
6877
6957
|
}
|
|
@@ -6907,9 +6987,9 @@ function snapshotPath(snapshotsDir, identity) {
|
|
|
6907
6987
|
}
|
|
6908
6988
|
return path19.join(snapshotsDir, `${identity}.json`);
|
|
6909
6989
|
}
|
|
6910
|
-
function readUsageSnapshot(
|
|
6990
|
+
function readUsageSnapshot(fs14, snapshotsDir, identity) {
|
|
6911
6991
|
const file = snapshotPath(snapshotsDir, identity);
|
|
6912
|
-
const raw =
|
|
6992
|
+
const raw = fs14.readFileUtf8(file);
|
|
6913
6993
|
if (raw === void 0) {
|
|
6914
6994
|
return void 0;
|
|
6915
6995
|
}
|
|
@@ -6925,8 +7005,8 @@ function readUsageSnapshot(fs13, snapshotsDir, identity) {
|
|
|
6925
7005
|
}
|
|
6926
7006
|
return snapshot.data;
|
|
6927
7007
|
}
|
|
6928
|
-
function listUsageSnapshots(
|
|
6929
|
-
return
|
|
7008
|
+
function listUsageSnapshots(fs14, snapshotsDir) {
|
|
7009
|
+
return fs14.readdir(snapshotsDir).flatMap((name) => {
|
|
6930
7010
|
if (!name.endsWith(".json")) {
|
|
6931
7011
|
return [];
|
|
6932
7012
|
}
|
|
@@ -6934,7 +7014,7 @@ function listUsageSnapshots(fs13, snapshotsDir) {
|
|
|
6934
7014
|
if (!isIdentityName(identity)) {
|
|
6935
7015
|
return [];
|
|
6936
7016
|
}
|
|
6937
|
-
const snapshot = readUsageSnapshot(
|
|
7017
|
+
const snapshot = readUsageSnapshot(fs14, snapshotsDir, identity);
|
|
6938
7018
|
return snapshot === void 0 ? [] : [snapshot];
|
|
6939
7019
|
}).sort((left, right) => left.identity.localeCompare(right.identity));
|
|
6940
7020
|
}
|
|
@@ -6959,11 +7039,11 @@ var init_read = __esm({
|
|
|
6959
7039
|
|
|
6960
7040
|
// src/usage/store.ts
|
|
6961
7041
|
import path20 from "node:path";
|
|
6962
|
-
function pruneUsageLog(
|
|
7042
|
+
function pruneUsageLog(fs14, logDir, nowMs) {
|
|
6963
7043
|
const cutoff = nowMs - USAGE_RETENTION_MS;
|
|
6964
|
-
for (const segment of listLogSegments(
|
|
7044
|
+
for (const segment of listLogSegments(fs14, logDir)) {
|
|
6965
7045
|
if (segment.endsAt <= cutoff) {
|
|
6966
|
-
|
|
7046
|
+
fs14.removeRecursive(path20.join(logDir, segment.name));
|
|
6967
7047
|
}
|
|
6968
7048
|
}
|
|
6969
7049
|
}
|
|
@@ -6992,7 +7072,7 @@ function foldProviderState(current, record) {
|
|
|
6992
7072
|
};
|
|
6993
7073
|
}
|
|
6994
7074
|
function createUsageStore(deps) {
|
|
6995
|
-
const { fs:
|
|
7075
|
+
const { fs: fs14, paths } = deps;
|
|
6996
7076
|
let prunedDay;
|
|
6997
7077
|
const rewriteSnapshot = (identity, fold) => {
|
|
6998
7078
|
if (!isIdentityName(identity)) {
|
|
@@ -7001,7 +7081,7 @@ function createUsageStore(deps) {
|
|
|
7001
7081
|
}
|
|
7002
7082
|
let current;
|
|
7003
7083
|
try {
|
|
7004
|
-
current = readUsageSnapshot(
|
|
7084
|
+
current = readUsageSnapshot(fs14, paths.usageSnapshotsDir, identity);
|
|
7005
7085
|
} catch (error) {
|
|
7006
7086
|
if (!(error instanceof UsageSnapshotError)) {
|
|
7007
7087
|
throw error;
|
|
@@ -7028,8 +7108,8 @@ function createUsageStore(deps) {
|
|
|
7028
7108
|
...account === void 0 ? {} : { account },
|
|
7029
7109
|
providers
|
|
7030
7110
|
});
|
|
7031
|
-
|
|
7032
|
-
|
|
7111
|
+
fs14.mkdirPrivate(paths.usageSnapshotsDir);
|
|
7112
|
+
fs14.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
|
|
7033
7113
|
`);
|
|
7034
7114
|
deps.publish?.(snapshot);
|
|
7035
7115
|
return true;
|
|
@@ -7038,14 +7118,14 @@ function createUsageStore(deps) {
|
|
|
7038
7118
|
record: (input) => {
|
|
7039
7119
|
const record = UsageRecordSchema.parse(input);
|
|
7040
7120
|
const nowMs = deps.now();
|
|
7041
|
-
|
|
7042
|
-
|
|
7121
|
+
fs14.mkdirPrivate(paths.usageDir);
|
|
7122
|
+
fs14.mkdirPrivate(paths.usageLogDir);
|
|
7043
7123
|
const day = segmentDay(nowMs);
|
|
7044
7124
|
if (prunedDay !== day) {
|
|
7045
|
-
pruneUsageLog(
|
|
7125
|
+
pruneUsageLog(fs14, paths.usageLogDir, nowMs);
|
|
7046
7126
|
prunedDay = day;
|
|
7047
7127
|
}
|
|
7048
|
-
|
|
7128
|
+
fs14.appendFilePrivate(path20.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
|
|
7049
7129
|
`);
|
|
7050
7130
|
deps.onRecord?.(record);
|
|
7051
7131
|
if (record.identity !== void 0) {
|
|
@@ -7089,14 +7169,14 @@ import { z as z13 } from "zod";
|
|
|
7089
7169
|
function errorMessage(error) {
|
|
7090
7170
|
return error instanceof Error ? error.message : String(error);
|
|
7091
7171
|
}
|
|
7092
|
-
function loadPoolMembers(
|
|
7172
|
+
function loadPoolMembers(fs14, paths, identities, nowMs) {
|
|
7093
7173
|
const windowStartMs = nowMs - FIVE_HOUR_WINDOW_MS;
|
|
7094
|
-
const log = readUsageLog(
|
|
7174
|
+
const log = readUsageLog(fs14, paths.usageLogDir, { sinceMs: windowStartMs });
|
|
7095
7175
|
return identities.map((identity) => {
|
|
7096
7176
|
const records = log.records.filter((record) => record.identity === identity && record.provider === ANTHROPIC_PROVIDER && Date.parse(record.at) >= windowStartMs);
|
|
7097
7177
|
try {
|
|
7098
|
-
const snapshot = readUsageSnapshot(
|
|
7099
|
-
const account = readAccountMetadata(
|
|
7178
|
+
const snapshot = readUsageSnapshot(fs14, paths.usageSnapshotsDir, identity);
|
|
7179
|
+
const account = readAccountMetadata(fs14, paths.identitiesDir, identity) ?? snapshot?.account;
|
|
7100
7180
|
return { identity, records, ...snapshot === void 0 ? {} : { snapshot }, ...account === void 0 ? {} : { account } };
|
|
7101
7181
|
} catch (error) {
|
|
7102
7182
|
if (error instanceof UsageSnapshotError || error instanceof AccountMetadataError) {
|
|
@@ -7190,9 +7270,9 @@ function collectPoolIdentities(pools, poolName, stack, found) {
|
|
|
7190
7270
|
collectPoolIdentities(pools, nestedName, childStack, found);
|
|
7191
7271
|
}
|
|
7192
7272
|
}
|
|
7193
|
-
function readPicksFile(
|
|
7273
|
+
function readPicksFile(fs14, file) {
|
|
7194
7274
|
const empty = { schemaVersion: SCHEMA_VERSION, picks: {} };
|
|
7195
|
-
const raw =
|
|
7275
|
+
const raw = fs14.readFileUtf8(file);
|
|
7196
7276
|
if (raw === void 0) {
|
|
7197
7277
|
return { file: empty };
|
|
7198
7278
|
}
|
|
@@ -7205,17 +7285,17 @@ function readPicksFile(fs13, file) {
|
|
|
7205
7285
|
const result = PicksFileSchema.safeParse(parsed);
|
|
7206
7286
|
return result.success ? { file: result.data } : { file: empty, problem: `${file} is not a picks file this agent-shim can read` };
|
|
7207
7287
|
}
|
|
7208
|
-
function readStickyPick(
|
|
7209
|
-
const read = readPicksFile(
|
|
7288
|
+
function readStickyPick(fs14, picksFile, directory) {
|
|
7289
|
+
const read = readPicksFile(fs14, picksFile);
|
|
7210
7290
|
const entry = read.file.picks[directory];
|
|
7211
7291
|
return { ...entry === void 0 ? {} : { sticky: entry }, ...read.problem === void 0 ? {} : { problem: read.problem } };
|
|
7212
7292
|
}
|
|
7213
|
-
function recordStickyPick(
|
|
7214
|
-
const current = readPicksFile(
|
|
7293
|
+
function recordStickyPick(fs14, picksFile, directory, identity, nowMs) {
|
|
7294
|
+
const current = readPicksFile(fs14, picksFile).file.picks;
|
|
7215
7295
|
const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
|
|
7216
7296
|
const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
|
|
7217
|
-
|
|
7218
|
-
|
|
7297
|
+
fs14.mkdirPrivate(path21.dirname(picksFile));
|
|
7298
|
+
fs14.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
|
|
7219
7299
|
`);
|
|
7220
7300
|
}
|
|
7221
7301
|
var PoolGraphError, SCHEMA_VERSION, PickEntrySchema, PicksFileSchema;
|
|
@@ -7491,6 +7571,7 @@ function buildLayoutPaths(root) {
|
|
|
7491
7571
|
frontdoorControlTokenFile: path23.join(root, "frontdoor", "control-token"),
|
|
7492
7572
|
frontdoorSessionsDir: path23.join(root, "frontdoor", "sessions"),
|
|
7493
7573
|
frontdoorDirectRecordsDir: path23.join(root, "frontdoor", "direct"),
|
|
7574
|
+
frontdoorDrainingDir: path23.join(root, "frontdoor", "draining"),
|
|
7494
7575
|
frontdoorRcCredentialsDir: path23.join(root, "frontdoor", "rc-credentials"),
|
|
7495
7576
|
frontdoorLogPath: path23.join(root, "logs", "frontdoor.log"),
|
|
7496
7577
|
usageDir: path23.join(root, "usage"),
|
|
@@ -8565,12 +8646,12 @@ function decideSignIn(facts) {
|
|
|
8565
8646
|
function credentialsFilePath(farmRoot) {
|
|
8566
8647
|
return path26.join(farmRoot, CREDENTIALS_FILE);
|
|
8567
8648
|
}
|
|
8568
|
-
function identitySignIn(
|
|
8649
|
+
function identitySignIn(fs14, probe, identity) {
|
|
8569
8650
|
const probing = !identity.hasCredentialBlock;
|
|
8570
8651
|
return decideSignIn({
|
|
8571
8652
|
hasCredentialBlock: identity.hasCredentialBlock,
|
|
8572
8653
|
keychainItem: probing && probe.platform === "darwin" && probe.run !== void 0 ? keychainHasItem(probe.run, identity.farmRoot) : void 0,
|
|
8573
|
-
credentialsFile: probing &&
|
|
8654
|
+
credentialsFile: probing && fs14.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
|
|
8574
8655
|
platform: probe.platform
|
|
8575
8656
|
});
|
|
8576
8657
|
}
|
|
@@ -9411,6 +9492,16 @@ var init_update = __esm({
|
|
|
9411
9492
|
}
|
|
9412
9493
|
});
|
|
9413
9494
|
|
|
9495
|
+
// src/frontdoor/replacement.ts
|
|
9496
|
+
function replacementLine(facts) {
|
|
9497
|
+
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)}`;
|
|
9498
|
+
}
|
|
9499
|
+
var init_replacement = __esm({
|
|
9500
|
+
"src/frontdoor/replacement.ts"() {
|
|
9501
|
+
"use strict";
|
|
9502
|
+
}
|
|
9503
|
+
});
|
|
9504
|
+
|
|
9414
9505
|
// src/frontdoor/ensure.ts
|
|
9415
9506
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
9416
9507
|
function ensureFrontDoor(params) {
|
|
@@ -9422,7 +9513,7 @@ function ensureFrontDoor(params) {
|
|
|
9422
9513
|
let lastRejection;
|
|
9423
9514
|
let busyDoor;
|
|
9424
9515
|
const liveSessionsOn = (doorPid) => listFrontDoorSessions(ports.fs, paths.frontdoorSessionsDir).filter(
|
|
9425
|
-
(session) => session.pid !== params.launcherPid && ports.isRunning(session.pid) && (session.supervisorPid === void 0 || session.supervisorPid === doorPid)
|
|
9516
|
+
(session) => session.pid !== params.launcherPid && ports.isRunning(session.pid) && (session.supervisorPid === void 0 || session.supervisorPid === doorPid || !ports.isRunning(session.supervisorPid))
|
|
9426
9517
|
).length;
|
|
9427
9518
|
const verifyWithRetry = (port) => {
|
|
9428
9519
|
let verdict = ports.verifyListener(port);
|
|
@@ -9432,12 +9523,20 @@ function ensureFrontDoor(params) {
|
|
|
9432
9523
|
}
|
|
9433
9524
|
return verdict;
|
|
9434
9525
|
};
|
|
9435
|
-
const
|
|
9526
|
+
const recordReplacement = (doorPid, doorProtocol, reason, signal) => {
|
|
9527
|
+
ports.recordReplacement(
|
|
9528
|
+
replacementLine({ reason, signal, launcherPid: params.launcherPid, launcherProtocol: FRONT_DOOR_PROTOCOL, doorPid, doorProtocol, liveSessions: liveSessionsOn(doorPid) })
|
|
9529
|
+
);
|
|
9530
|
+
};
|
|
9531
|
+
const stopAndAwaitExit = (supervisorPid, doorProtocol, reason, failure) => {
|
|
9532
|
+
recordReplacement(supervisorPid, doorProtocol, reason, "SIGTERM");
|
|
9436
9533
|
ports.stopSupervisor(supervisorPid);
|
|
9437
9534
|
const graceEnds = ports.now() + FRONTDOOR_EXIT_GRACE_MS;
|
|
9438
9535
|
let killed = false;
|
|
9439
|
-
|
|
9536
|
+
const holdsAddresses = () => ports.isRunning(supervisorPid) && readFrontDoorState(ports.fs, paths.frontdoorStateFile)?.supervisorPid === supervisorPid;
|
|
9537
|
+
while (holdsAddresses()) {
|
|
9440
9538
|
if (!killed && ports.now() >= graceEnds) {
|
|
9539
|
+
recordReplacement(supervisorPid, doorProtocol, reason, "SIGKILL");
|
|
9441
9540
|
ports.killSupervisor(supervisorPid);
|
|
9442
9541
|
killed = true;
|
|
9443
9542
|
}
|
|
@@ -9452,16 +9551,19 @@ function ensureFrontDoor(params) {
|
|
|
9452
9551
|
const supervisorPid = state?.supervisorPid;
|
|
9453
9552
|
if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
|
|
9454
9553
|
if (state?.port !== void 0 && state.connectPort !== void 0) {
|
|
9455
|
-
if (supervisorPid === params.launcherPid && params.replace
|
|
9554
|
+
if (supervisorPid === params.launcherPid && params.replace === void 0 && ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
9456
9555
|
const token = randomUUID3();
|
|
9457
9556
|
writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid, ...recordOf(params.session) });
|
|
9458
9557
|
return { port: state.port, connectPort: state.connectPort, token };
|
|
9459
9558
|
}
|
|
9460
9559
|
const verdict = verifyWithRetry(state.port);
|
|
9461
|
-
|
|
9560
|
+
const doorProtocol = state.protocol ?? 0;
|
|
9561
|
+
if (verdict.ok && !replaced && !spawned && (params.replace !== void 0 || doorProtocol < FRONT_DOOR_PROTOCOL)) {
|
|
9462
9562
|
stopAndAwaitExit(
|
|
9463
9563
|
supervisorPid,
|
|
9464
|
-
|
|
9564
|
+
doorProtocol,
|
|
9565
|
+
params.replace ?? "protocol-older",
|
|
9566
|
+
`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`
|
|
9465
9567
|
);
|
|
9466
9568
|
replaced = true;
|
|
9467
9569
|
continue;
|
|
@@ -9477,15 +9579,15 @@ function ensureFrontDoor(params) {
|
|
|
9477
9579
|
}
|
|
9478
9580
|
if (ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
9479
9581
|
const stranded = liveSessionsOn(supervisorPid);
|
|
9480
|
-
if (params.replace
|
|
9481
|
-
stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
9582
|
+
if (params.replace !== void 0 && !replaced) {
|
|
9583
|
+
stopAndAwaitExit(supervisorPid, doorProtocol, "probe-failed-restart", `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
9482
9584
|
replaced = true;
|
|
9483
9585
|
continue;
|
|
9484
9586
|
}
|
|
9485
9587
|
if (stranded > 0) {
|
|
9486
9588
|
busyDoor = { pid: supervisorPid, sessions: stranded };
|
|
9487
9589
|
} else {
|
|
9488
|
-
stopAndAwaitExit(supervisorPid, `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
9590
|
+
stopAndAwaitExit(supervisorPid, doorProtocol, "probe-failed-idle", `the front door (pid ${String(supervisorPid)}) stopped answering and did not exit when asked to`);
|
|
9489
9591
|
continue;
|
|
9490
9592
|
}
|
|
9491
9593
|
} else {
|
|
@@ -9526,6 +9628,7 @@ var init_ensure2 = __esm({
|
|
|
9526
9628
|
"use strict";
|
|
9527
9629
|
init_cliError();
|
|
9528
9630
|
init_state2();
|
|
9631
|
+
init_replacement();
|
|
9529
9632
|
init_state();
|
|
9530
9633
|
FRONTDOOR_START_TIMEOUT_MS = 3e4;
|
|
9531
9634
|
FRONTDOOR_LAUNCHER_POLL_MS = 100;
|
|
@@ -10054,15 +10157,15 @@ function contextTokensOfTranscript(text) {
|
|
|
10054
10157
|
}
|
|
10055
10158
|
return void 0;
|
|
10056
10159
|
}
|
|
10057
|
-
function newestTranscript(
|
|
10160
|
+
function newestTranscript(fs14, projectDir) {
|
|
10058
10161
|
let newest;
|
|
10059
10162
|
let newestMs = -Infinity;
|
|
10060
|
-
for (const name of
|
|
10163
|
+
for (const name of fs14.readdir(projectDir)) {
|
|
10061
10164
|
if (!name.endsWith(".jsonl")) {
|
|
10062
10165
|
continue;
|
|
10063
10166
|
}
|
|
10064
10167
|
const candidate = path38.join(projectDir, name);
|
|
10065
|
-
const stat =
|
|
10168
|
+
const stat = fs14.lstat(candidate);
|
|
10066
10169
|
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
10067
10170
|
newestMs = stat.mtimeMs;
|
|
10068
10171
|
newest = candidate;
|
|
@@ -10070,14 +10173,14 @@ function newestTranscript(fs13, projectDir) {
|
|
|
10070
10173
|
}
|
|
10071
10174
|
return newest;
|
|
10072
10175
|
}
|
|
10073
|
-
function resumedContextTokens(
|
|
10176
|
+
function resumedContextTokens(fs14, params) {
|
|
10074
10177
|
const target = resumeTargetOf(params.passthrough);
|
|
10075
10178
|
if (target === void 0) {
|
|
10076
10179
|
return void 0;
|
|
10077
10180
|
}
|
|
10078
10181
|
const projectDir = path38.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
|
|
10079
|
-
const file = target.kind === "id" ? path38.join(projectDir, `${target.id}.jsonl`) : newestTranscript(
|
|
10080
|
-
const text = file === void 0 ? void 0 :
|
|
10182
|
+
const file = target.kind === "id" ? path38.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs14, projectDir);
|
|
10183
|
+
const text = file === void 0 ? void 0 : fs14.readFileUtf8(file);
|
|
10081
10184
|
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
10082
10185
|
}
|
|
10083
10186
|
var init_resumeContext = __esm({
|
|
@@ -10530,7 +10633,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
|
|
|
10530
10633
|
return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
10531
10634
|
}
|
|
10532
10635
|
function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
10533
|
-
const { paths, fs:
|
|
10636
|
+
const { paths, fs: fs14, proc, log } = params;
|
|
10534
10637
|
if (decided.pool === void 0) {
|
|
10535
10638
|
return { identityDecision: decided };
|
|
10536
10639
|
}
|
|
@@ -10549,7 +10652,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
10549
10652
|
selectedVia: decided.source,
|
|
10550
10653
|
pools: params.pools,
|
|
10551
10654
|
paths,
|
|
10552
|
-
fs:
|
|
10655
|
+
fs: fs14,
|
|
10553
10656
|
usageFs: farmRuntime.fs,
|
|
10554
10657
|
cwd: farmRuntime.cwd,
|
|
10555
10658
|
now: farmRuntime.now,
|
|
@@ -10572,7 +10675,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
10572
10675
|
};
|
|
10573
10676
|
}
|
|
10574
10677
|
function decideLaunch(params, readOnly) {
|
|
10575
|
-
const { paths, fs:
|
|
10678
|
+
const { paths, fs: fs14, proc, log } = params;
|
|
10576
10679
|
const { env, argv } = proc;
|
|
10577
10680
|
const parsedArgv = parseLauncherArgv(argv);
|
|
10578
10681
|
const cliOverride = buildCliOverride({
|
|
@@ -10587,7 +10690,7 @@ function decideLaunch(params, readOnly) {
|
|
|
10587
10690
|
argv0Identity: parsedArgv.identity,
|
|
10588
10691
|
directoryPinnedIdentity: params.directoryPinnedIdentity,
|
|
10589
10692
|
readActiveIdentityFile: () => {
|
|
10590
|
-
const raw =
|
|
10693
|
+
const raw = fs14.readFileUtf8(paths.activeIdentityFile);
|
|
10591
10694
|
if (raw === void 0) {
|
|
10592
10695
|
return void 0;
|
|
10593
10696
|
}
|
|
@@ -10622,7 +10725,7 @@ function decideLaunch(params, readOnly) {
|
|
|
10622
10725
|
}
|
|
10623
10726
|
let loadedIdentity;
|
|
10624
10727
|
if (identityDecision.name !== void 0) {
|
|
10625
|
-
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name,
|
|
10728
|
+
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs14);
|
|
10626
10729
|
if (loadedIdentity === void 0) {
|
|
10627
10730
|
log.error(
|
|
10628
10731
|
`agent-shim: no identity named "${identityDecision.name}" (selected via ${identityDecision.source}). Run \`agent-shim identity add ${identityDecision.name}\` first.`
|
|
@@ -10637,7 +10740,7 @@ function decideLaunch(params, readOnly) {
|
|
|
10637
10740
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
10638
10741
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
10639
10742
|
});
|
|
10640
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true &&
|
|
10743
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs14.readConfigFile(path39.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
10641
10744
|
log.error(
|
|
10642
10745
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
10643
10746
|
);
|
|
@@ -10646,7 +10749,7 @@ function decideLaunch(params, readOnly) {
|
|
|
10646
10749
|
const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
|
|
10647
10750
|
const providerParams = {
|
|
10648
10751
|
paths,
|
|
10649
|
-
port:
|
|
10752
|
+
port: fs14,
|
|
10650
10753
|
...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
|
|
10651
10754
|
...farmContext === void 0 ? {} : { cascade: farmContext.cascade }
|
|
10652
10755
|
};
|
|
@@ -10745,9 +10848,9 @@ function decideLaunch(params, readOnly) {
|
|
|
10745
10848
|
const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
|
|
10746
10849
|
const globalModels = loadConfigFile(paths.globalConfigFile, GlobalConfigSchema, params.fs.readConfigFile)?.config.models;
|
|
10747
10850
|
const models = launchCascade !== void 0 && params.farm !== void 0 ? cascadeModels : globalModels;
|
|
10748
|
-
const listedProviders = listProviderNames(
|
|
10851
|
+
const listedProviders = listProviderNames(fs14.readdir, paths.providersDir).flatMap((name) => {
|
|
10749
10852
|
try {
|
|
10750
|
-
const definition = loadProvider(paths.providersDir, name,
|
|
10853
|
+
const definition = loadProvider(paths.providersDir, name, fs14);
|
|
10751
10854
|
return definition === void 0 ? [] : [[name, definition, parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, name)))?.models ?? []]];
|
|
10752
10855
|
} catch {
|
|
10753
10856
|
return [];
|
|
@@ -11024,6 +11127,19 @@ var init_ownCli = __esm({
|
|
|
11024
11127
|
}
|
|
11025
11128
|
});
|
|
11026
11129
|
|
|
11130
|
+
// src/frontdoor/doorLog.ts
|
|
11131
|
+
import fs12 from "node:fs";
|
|
11132
|
+
function appendDoorLog(paths, line) {
|
|
11133
|
+
fs12.mkdirSync(paths.logsDir, { recursive: true });
|
|
11134
|
+
fs12.appendFileSync(paths.frontdoorLogPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}
|
|
11135
|
+
`);
|
|
11136
|
+
}
|
|
11137
|
+
var init_doorLog = __esm({
|
|
11138
|
+
"src/frontdoor/doorLog.ts"() {
|
|
11139
|
+
"use strict";
|
|
11140
|
+
}
|
|
11141
|
+
});
|
|
11142
|
+
|
|
11027
11143
|
// src/frontdoor/selfIdentity.ts
|
|
11028
11144
|
function isFrontDoorSupervisorPid(pid, identify) {
|
|
11029
11145
|
return declaredPid !== void 0 && pid === declaredPid && pid === process.pid || identify(pid);
|
|
@@ -11039,14 +11155,14 @@ var init_selfIdentity = __esm({
|
|
|
11039
11155
|
import { createHash as createHash7 } from "node:crypto";
|
|
11040
11156
|
import path41 from "node:path";
|
|
11041
11157
|
function resolveTrustBundle(params) {
|
|
11042
|
-
const { caCertFile, bundlesDir, variable, inherited, fs:
|
|
11158
|
+
const { caCertFile, bundlesDir, variable, inherited, fs: fs14 } = params;
|
|
11043
11159
|
if (inherited === void 0 || inherited === "" || path41.resolve(inherited) === path41.resolve(caCertFile)) {
|
|
11044
11160
|
return { path: caCertFile };
|
|
11045
11161
|
}
|
|
11046
|
-
const caPem =
|
|
11162
|
+
const caPem = fs14.readFileUtf8(caCertFile);
|
|
11047
11163
|
let inheritedPem;
|
|
11048
11164
|
try {
|
|
11049
|
-
inheritedPem =
|
|
11165
|
+
inheritedPem = fs14.readFileUtf8(inherited);
|
|
11050
11166
|
} catch (error) {
|
|
11051
11167
|
return {
|
|
11052
11168
|
path: caCertFile,
|
|
@@ -11059,9 +11175,9 @@ function resolveTrustBundle(params) {
|
|
|
11059
11175
|
const combined = `${inheritedPem.trimEnd()}
|
|
11060
11176
|
${caPem}`;
|
|
11061
11177
|
const bundle = path41.join(bundlesDir, `${createHash7("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
11062
|
-
if (!
|
|
11063
|
-
|
|
11064
|
-
|
|
11178
|
+
if (!fs14.exists(bundle)) {
|
|
11179
|
+
fs14.mkdirp(bundlesDir);
|
|
11180
|
+
fs14.writeFileAtomic(bundle, combined);
|
|
11065
11181
|
}
|
|
11066
11182
|
return { path: bundle };
|
|
11067
11183
|
}
|
|
@@ -11074,7 +11190,7 @@ var init_trust = __esm({
|
|
|
11074
11190
|
});
|
|
11075
11191
|
|
|
11076
11192
|
// src/frontdoor/realFrontDoorPort.ts
|
|
11077
|
-
import
|
|
11193
|
+
import fs13 from "node:fs";
|
|
11078
11194
|
function realEnsurePorts(paths, spawnDaemon) {
|
|
11079
11195
|
return {
|
|
11080
11196
|
fs: realFarmFs,
|
|
@@ -11083,6 +11199,9 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
11083
11199
|
sleep: realSleepSync,
|
|
11084
11200
|
spawnSupervisor: (layout) => spawnDaemon(layout, "__frontdoor-supervisor", layout.frontdoorLogPath),
|
|
11085
11201
|
isFrontDoorSupervisor: (pid) => isFrontDoorSupervisorPid(pid, realIsFrontDoorSupervisor),
|
|
11202
|
+
recordReplacement: (line) => {
|
|
11203
|
+
appendDoorLog(paths, line);
|
|
11204
|
+
},
|
|
11086
11205
|
stopSupervisor: (pid) => {
|
|
11087
11206
|
process.kill(pid, "SIGTERM");
|
|
11088
11207
|
},
|
|
@@ -11090,7 +11209,7 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
11090
11209
|
process.kill(pid, "SIGKILL");
|
|
11091
11210
|
},
|
|
11092
11211
|
// 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.
|
|
11093
|
-
verifyListener: (port) => probeFrontDoorSync(port,
|
|
11212
|
+
verifyListener: (port) => probeFrontDoorSync(port, fs13.readFileSync(paths.frontdoorCaCertFile, "utf8"))
|
|
11094
11213
|
};
|
|
11095
11214
|
}
|
|
11096
11215
|
function realFrontDoorPort(paths, spawnDaemon) {
|
|
@@ -11116,16 +11235,17 @@ var init_realFrontDoorPort = __esm({
|
|
|
11116
11235
|
"src/frontdoor/realFrontDoorPort.ts"() {
|
|
11117
11236
|
"use strict";
|
|
11118
11237
|
init_realPorts();
|
|
11238
|
+
init_doorLog();
|
|
11119
11239
|
init_ensure2();
|
|
11120
11240
|
init_state();
|
|
11121
11241
|
init_probe();
|
|
11122
11242
|
init_selfIdentity();
|
|
11123
11243
|
init_trust();
|
|
11124
11244
|
realTrustBundleFs = {
|
|
11125
|
-
readFileUtf8: (file) =>
|
|
11126
|
-
exists: (file) =>
|
|
11245
|
+
readFileUtf8: (file) => fs13.readFileSync(file, "utf8"),
|
|
11246
|
+
exists: (file) => fs13.existsSync(file),
|
|
11127
11247
|
mkdirp: (dir) => {
|
|
11128
|
-
|
|
11248
|
+
fs13.mkdirSync(dir, { recursive: true });
|
|
11129
11249
|
},
|
|
11130
11250
|
writeFileAtomic: (file, contents) => {
|
|
11131
11251
|
realFarmFs.writeFilePrivate(file, contents);
|
|
@@ -13485,6 +13605,10 @@ function realConnectEffects(ports = DOOR_SOURCE_PORTS) {
|
|
|
13485
13605
|
}
|
|
13486
13606
|
resolve({
|
|
13487
13607
|
port: bound,
|
|
13608
|
+
// 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.
|
|
13609
|
+
stopAccepting: () => {
|
|
13610
|
+
server.close();
|
|
13611
|
+
},
|
|
13488
13612
|
close: async () => {
|
|
13489
13613
|
await new Promise((closeResolve) => {
|
|
13490
13614
|
server.close(() => {
|
|
@@ -13690,11 +13814,11 @@ function credentialOfJson(parsed) {
|
|
|
13690
13814
|
function sequenceNumOfJson(value) {
|
|
13691
13815
|
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
13692
13816
|
}
|
|
13693
|
-
function createRcCredentialStore(
|
|
13694
|
-
|
|
13817
|
+
function createRcCredentialStore(fs14, dir) {
|
|
13818
|
+
fs14.mkdirPrivate(dir);
|
|
13695
13819
|
const fileFor = (sessionId) => path10.join(dir, `${sessionId}.json`);
|
|
13696
13820
|
const readParsed = (sessionId) => {
|
|
13697
|
-
const raw =
|
|
13821
|
+
const raw = fs14.readFileUtf8(fileFor(sessionId));
|
|
13698
13822
|
if (raw === void 0) {
|
|
13699
13823
|
return void 0;
|
|
13700
13824
|
}
|
|
@@ -13719,7 +13843,7 @@ function createRcCredentialStore(fs13, dir) {
|
|
|
13719
13843
|
}
|
|
13720
13844
|
const cursor = sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
|
|
13721
13845
|
const record = { ...credential, ...cursor === void 0 ? {} : { highestSequenceNum: cursor } };
|
|
13722
|
-
|
|
13846
|
+
fs14.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
|
|
13723
13847
|
`);
|
|
13724
13848
|
},
|
|
13725
13849
|
readCursor: (sessionId) => {
|
|
@@ -13734,14 +13858,14 @@ function createRcCredentialStore(fs13, dir) {
|
|
|
13734
13858
|
}
|
|
13735
13859
|
const credential = credentialOfJson(readParsed(sessionId));
|
|
13736
13860
|
const record = credential === void 0 ? { highestSequenceNum } : { ...credential, highestSequenceNum };
|
|
13737
|
-
|
|
13861
|
+
fs14.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
|
|
13738
13862
|
`);
|
|
13739
13863
|
},
|
|
13740
13864
|
remove: (sessionId) => {
|
|
13741
13865
|
if (!isSafeSessionId(sessionId)) {
|
|
13742
13866
|
return;
|
|
13743
13867
|
}
|
|
13744
|
-
|
|
13868
|
+
fs14.removeRecursive(fileFor(sessionId));
|
|
13745
13869
|
}
|
|
13746
13870
|
};
|
|
13747
13871
|
}
|
|
@@ -15644,14 +15768,18 @@ init_supervisor2();
|
|
|
15644
15768
|
init_state();
|
|
15645
15769
|
|
|
15646
15770
|
// src/doctorFrontDoor.ts
|
|
15647
|
-
function pushFrontDoor(push, supervisors, registeredPid, liveSessions) {
|
|
15771
|
+
function pushFrontDoor(push, supervisors, registeredPid, liveSessions, draining) {
|
|
15648
15772
|
if (!supervisors.ok) {
|
|
15649
15773
|
push("frontdoor", "warn", `Could not list processes to look for duplicate front door supervisors: ${supervisors.message}.`);
|
|
15650
15774
|
return;
|
|
15651
15775
|
}
|
|
15652
|
-
const
|
|
15776
|
+
const drainingPids = supervisors.pids.filter((pid) => draining.includes(pid));
|
|
15777
|
+
for (const pid of drainingPids) {
|
|
15778
|
+
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));
|
|
15779
|
+
}
|
|
15780
|
+
const pids = supervisors.pids.filter((pid) => !draining.includes(pid));
|
|
15653
15781
|
if (pids.length === 0) {
|
|
15654
|
-
push("frontdoor", "pass", "No front door supervisor is running.");
|
|
15782
|
+
push("frontdoor", "pass", drainingPids.length === 0 ? "No front door supervisor is running." : "No front door supervisor is serving.");
|
|
15655
15783
|
return;
|
|
15656
15784
|
}
|
|
15657
15785
|
const [only, ...rest] = pids;
|
|
@@ -16201,7 +16329,7 @@ function runDoctor(params) {
|
|
|
16201
16329
|
}
|
|
16202
16330
|
if (params.frontDoor !== void 0) {
|
|
16203
16331
|
const validated3 = params.frontDoor.state.raw === void 0 ? void 0 : validateJson(FrontDoorStateSchema, params.frontDoor.state);
|
|
16204
|
-
pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0, params.frontDoor.liveSessions);
|
|
16332
|
+
pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0, params.frontDoor.liveSessions, params.frontDoor.draining ?? []);
|
|
16205
16333
|
if (params.frontDoor.listeners !== void 0) {
|
|
16206
16334
|
pushFrontDoorListeners(push, params.frontDoor.listeners);
|
|
16207
16335
|
}
|
|
@@ -16400,7 +16528,7 @@ function collectDoctorReport(params) {
|
|
|
16400
16528
|
logPath: paths.headroomLogPath
|
|
16401
16529
|
}
|
|
16402
16530
|
},
|
|
16403
|
-
...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) } }
|
|
16531
|
+
...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) } }
|
|
16404
16532
|
});
|
|
16405
16533
|
return report;
|
|
16406
16534
|
}
|
|
@@ -16446,6 +16574,8 @@ var HeadroomSocketTargetSchema = z26.union([z26.strictObject({ socketPath: z26.s
|
|
|
16446
16574
|
var FrontDoorStatusOutputSchema = z26.strictObject({
|
|
16447
16575
|
state: FrontDoorStateSchema,
|
|
16448
16576
|
supervisorAlive: z26.boolean(),
|
|
16577
|
+
/** The pids of earlier doors that released their addresses and are finishing the connections they carried: running, but not serving anything new. */
|
|
16578
|
+
draining: z26.readonly(z26.array(z26.number().int().positive())),
|
|
16449
16579
|
sessions: z26.readonly(z26.array(FrontDoorSessionStatusSchema)),
|
|
16450
16580
|
headroomSocket: HeadroomSocketTargetSchema.optional(),
|
|
16451
16581
|
logPath: z26.string(),
|
|
@@ -17490,6 +17620,7 @@ function collectFrontDoorStatus(fsPort, socketTrust, paths, isRunning) {
|
|
|
17490
17620
|
return {
|
|
17491
17621
|
state,
|
|
17492
17622
|
supervisorAlive: state.supervisorPid !== void 0 && isRunning(state.supervisorPid),
|
|
17623
|
+
draining: listDrainingFrontDoors(fsPort, paths.frontdoorDrainingDir, isRunning),
|
|
17493
17624
|
sessions: listFrontDoorSessions(fsPort, paths.frontdoorSessionsDir).map((session) => ({ ...session, alive: isRunning(session.pid) })),
|
|
17494
17625
|
headroomSocket: headroomSocketTarget(fsPort, socketTrust, paths),
|
|
17495
17626
|
logPath: paths.frontdoorLogPath,
|
|
@@ -17513,6 +17644,9 @@ function formatFrontDoorStatus(status, caCertPath) {
|
|
|
17513
17644
|
} else {
|
|
17514
17645
|
lines.push(`connect surface: listening on 127.0.0.1:${String(status.state.connectPort)}, CA ${caCertPath}`);
|
|
17515
17646
|
}
|
|
17647
|
+
if (status.draining.length > 0) {
|
|
17648
|
+
lines.push(`draining: ${status.draining.map(String).join(", ")} (finishing connections opened before the last restart; each exits when they have ended)`);
|
|
17649
|
+
}
|
|
17516
17650
|
if (status.headroomSocket === void 0) {
|
|
17517
17651
|
lines.push("headroom hop: the daemon is not serving (sessions asking for headroom fail until it is up)");
|
|
17518
17652
|
} else if (status.headroomSocket.refused === void 0) {
|
|
@@ -17927,6 +18061,7 @@ function createRcEventFanout() {
|
|
|
17927
18061
|
}
|
|
17928
18062
|
function createRcStreamHub(deps) {
|
|
17929
18063
|
const attachments = /* @__PURE__ */ new Map();
|
|
18064
|
+
let closed = false;
|
|
17930
18065
|
const lastSavedSequenceNums = /* @__PURE__ */ new Map();
|
|
17931
18066
|
const persistCursor = (sessionId) => {
|
|
17932
18067
|
if (deps.saveSequenceNum === void 0) {
|
|
@@ -18085,6 +18220,9 @@ function createRcStreamHub(deps) {
|
|
|
18085
18220
|
};
|
|
18086
18221
|
return {
|
|
18087
18222
|
reconcile: () => {
|
|
18223
|
+
if (closed) {
|
|
18224
|
+
return;
|
|
18225
|
+
}
|
|
18088
18226
|
const live = new Set(deps.trackedSessions());
|
|
18089
18227
|
for (const [sessionId, attachment] of attachments) {
|
|
18090
18228
|
if (!live.has(sessionId)) {
|
|
@@ -18107,6 +18245,7 @@ function createRcStreamHub(deps) {
|
|
|
18107
18245
|
}
|
|
18108
18246
|
},
|
|
18109
18247
|
close: () => {
|
|
18248
|
+
closed = true;
|
|
18110
18249
|
for (const attachment of attachments.values()) {
|
|
18111
18250
|
persistCursor(attachment.sessionId);
|
|
18112
18251
|
const credential = deps.credentialOf(attachment.sessionId);
|
|
@@ -19411,8 +19550,8 @@ var SELF_HOST_SUBSCRIPTION_TYPE = "max";
|
|
|
19411
19550
|
function isRecord14(value) {
|
|
19412
19551
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19413
19552
|
}
|
|
19414
|
-
function readJsonObject(
|
|
19415
|
-
const raw =
|
|
19553
|
+
function readJsonObject(fs14, file) {
|
|
19554
|
+
const raw = fs14.readFileUtf8(file);
|
|
19416
19555
|
if (raw === void 0) {
|
|
19417
19556
|
return void 0;
|
|
19418
19557
|
}
|
|
@@ -19424,8 +19563,8 @@ function readJsonObject(fs13, file) {
|
|
|
19424
19563
|
}
|
|
19425
19564
|
return isRecord14(parsed) ? parsed : void 0;
|
|
19426
19565
|
}
|
|
19427
|
-
function readRcSelfHostRecord(
|
|
19428
|
-
const parsed = readJsonObject(
|
|
19566
|
+
function readRcSelfHostRecord(fs14, frontdoorDir) {
|
|
19567
|
+
const parsed = readJsonObject(fs14, path34.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
19429
19568
|
if (parsed === void 0) {
|
|
19430
19569
|
return void 0;
|
|
19431
19570
|
}
|
|
@@ -19526,17 +19665,17 @@ function parseEntry2(project, entry) {
|
|
|
19526
19665
|
const base = match?.[1];
|
|
19527
19666
|
return base === void 0 ? { project, sessionId: entry, superseded: false, entry } : { project, sessionId: base, superseded: true, entry };
|
|
19528
19667
|
}
|
|
19529
|
-
function listSessions2(
|
|
19668
|
+
function listSessions2(fs14, configDir) {
|
|
19530
19669
|
const found = [];
|
|
19531
|
-
for (const project of
|
|
19670
|
+
for (const project of fs14.readdir(path35.join(configDir, PROJECTS_DIR))) {
|
|
19532
19671
|
const projectDir = path35.join(configDir, PROJECTS_DIR, project);
|
|
19533
19672
|
const entries = /* @__PURE__ */ new Set();
|
|
19534
|
-
for (const name of
|
|
19673
|
+
for (const name of fs14.readdir(projectDir)) {
|
|
19535
19674
|
if (name.endsWith(TRANSCRIPT_SUFFIX)) {
|
|
19536
19675
|
entries.add(name.slice(0, -TRANSCRIPT_SUFFIX.length));
|
|
19537
19676
|
continue;
|
|
19538
19677
|
}
|
|
19539
|
-
const children =
|
|
19678
|
+
const children = fs14.readdir(path35.join(projectDir, name));
|
|
19540
19679
|
if (children.includes(SUBAGENTS_DIR) || children.includes(WORKFLOWS_DIR)) {
|
|
19541
19680
|
entries.add(name);
|
|
19542
19681
|
}
|
|
@@ -19547,9 +19686,9 @@ function listSessions2(fs13, configDir) {
|
|
|
19547
19686
|
}
|
|
19548
19687
|
return found.sort((left, right) => left.project.localeCompare(right.project) || left.entry.localeCompare(right.entry));
|
|
19549
19688
|
}
|
|
19550
|
-
function locateAgents(
|
|
19689
|
+
function locateAgents(fs14, configDir, relativeDir, workflowRunId, report) {
|
|
19551
19690
|
const located = [];
|
|
19552
|
-
for (const name of listDirOrReport(
|
|
19691
|
+
for (const name of listDirOrReport(fs14, configDir, relativeDir, report)) {
|
|
19553
19692
|
if (!name.startsWith(AGENT_FILE_PREFIX) || !name.endsWith(META_SUFFIX)) {
|
|
19554
19693
|
continue;
|
|
19555
19694
|
}
|
|
@@ -19598,17 +19737,17 @@ function toNode(read, children) {
|
|
|
19598
19737
|
function describeFailure(error) {
|
|
19599
19738
|
return error instanceof Error ? error.message : String(error);
|
|
19600
19739
|
}
|
|
19601
|
-
function readFileOrReport(
|
|
19740
|
+
function readFileOrReport(fs14, configDir, relative, report) {
|
|
19602
19741
|
try {
|
|
19603
|
-
return
|
|
19742
|
+
return fs14.readFileUtf8(path35.join(configDir, relative));
|
|
19604
19743
|
} catch (error) {
|
|
19605
19744
|
report({ path: relative, reason: `could not be read: ${describeFailure(error)}` });
|
|
19606
19745
|
return void 0;
|
|
19607
19746
|
}
|
|
19608
19747
|
}
|
|
19609
|
-
function listDirOrReport(
|
|
19748
|
+
function listDirOrReport(fs14, configDir, relative, report) {
|
|
19610
19749
|
try {
|
|
19611
|
-
return
|
|
19750
|
+
return fs14.readdir(path35.join(configDir, relative));
|
|
19612
19751
|
} catch (error) {
|
|
19613
19752
|
report({ path: relative, reason: `could not be listed: ${describeFailure(error)}` });
|
|
19614
19753
|
return [];
|
|
@@ -19631,22 +19770,22 @@ var WorkflowRunFileSchema = z31.object({
|
|
|
19631
19770
|
phases: z31.array(z31.object({ title: z31.string() })).default([]),
|
|
19632
19771
|
summary: z31.string().optional()
|
|
19633
19772
|
});
|
|
19634
|
-
function summariseSession(
|
|
19773
|
+
function summariseSession(fs14, configDir, ref) {
|
|
19635
19774
|
const sessionRelative = path35.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
19636
19775
|
const subagentsRelative = path35.join(sessionRelative, SUBAGENTS_DIR);
|
|
19637
19776
|
const workflowsUnderSubagents = path35.join(subagentsRelative, WORKFLOWS_DIR);
|
|
19638
19777
|
const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
|
|
19639
|
-
let agentCount =
|
|
19640
|
-
for (const runDir of
|
|
19778
|
+
let agentCount = fs14.readdir(path35.join(configDir, subagentsRelative)).filter(isMeta).length;
|
|
19779
|
+
for (const runDir of fs14.readdir(path35.join(configDir, workflowsUnderSubagents))) {
|
|
19641
19780
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
19642
|
-
agentCount +=
|
|
19781
|
+
agentCount += fs14.readdir(path35.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
|
|
19643
19782
|
}
|
|
19644
19783
|
}
|
|
19645
|
-
const workflowRunCount =
|
|
19646
|
-
const transcript =
|
|
19784
|
+
const workflowRunCount = fs14.readdir(path35.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
|
|
19785
|
+
const transcript = fs14.lstat(path35.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
|
|
19647
19786
|
return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
|
|
19648
19787
|
}
|
|
19649
|
-
function readSessionAgentTree(
|
|
19788
|
+
function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
19650
19789
|
const problems = [];
|
|
19651
19790
|
const report = (problem) => {
|
|
19652
19791
|
problems.push(problem);
|
|
@@ -19654,15 +19793,15 @@ function readSessionAgentTree(fs13, configDir, ref, options = {}) {
|
|
|
19654
19793
|
const sessionRelative = path35.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
19655
19794
|
const subagentsRelative = path35.join(sessionRelative, SUBAGENTS_DIR);
|
|
19656
19795
|
const workflowsUnderSubagents = path35.join(subagentsRelative, WORKFLOWS_DIR);
|
|
19657
|
-
const located = locateAgents(
|
|
19658
|
-
for (const runDir of listDirOrReport(
|
|
19796
|
+
const located = locateAgents(fs14, configDir, subagentsRelative, void 0, report);
|
|
19797
|
+
for (const runDir of listDirOrReport(fs14, configDir, workflowsUnderSubagents, report)) {
|
|
19659
19798
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
19660
|
-
located.push(...locateAgents(
|
|
19799
|
+
located.push(...locateAgents(fs14, configDir, path35.join(workflowsUnderSubagents, runDir), runDir, report));
|
|
19661
19800
|
}
|
|
19662
19801
|
}
|
|
19663
19802
|
const agents = /* @__PURE__ */ new Map();
|
|
19664
19803
|
for (const candidate of located) {
|
|
19665
|
-
const text = readFileOrReport(
|
|
19804
|
+
const text = readFileOrReport(fs14, configDir, candidate.metaPath, report);
|
|
19666
19805
|
if (text === void 0) {
|
|
19667
19806
|
continue;
|
|
19668
19807
|
}
|
|
@@ -19674,7 +19813,7 @@ function readSessionAgentTree(fs13, configDir, ref, options = {}) {
|
|
|
19674
19813
|
agents.set(candidate.id, { located: candidate, meta: parsed.data });
|
|
19675
19814
|
}
|
|
19676
19815
|
const teamNames = [...new Set([...agents.values()].flatMap((agent) => agent.meta.teamName === void 0 ? [] : [agent.meta.teamName]))].sort();
|
|
19677
|
-
const parentOf3 = resolveParents(
|
|
19816
|
+
const parentOf3 = resolveParents(fs14, configDir, agents, report);
|
|
19678
19817
|
const childrenOf = /* @__PURE__ */ new Map();
|
|
19679
19818
|
const roots = [];
|
|
19680
19819
|
for (const id of agents.keys()) {
|
|
@@ -19697,12 +19836,12 @@ function readSessionAgentTree(fs13, configDir, ref, options = {}) {
|
|
|
19697
19836
|
sessionId: ref.sessionId,
|
|
19698
19837
|
superseded: ref.superseded,
|
|
19699
19838
|
agents: roots.sort().map(build),
|
|
19700
|
-
tasks: readTasks(
|
|
19701
|
-
workflowRuns: readWorkflowRuns(
|
|
19839
|
+
tasks: readTasks(fs14, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
|
|
19840
|
+
workflowRuns: readWorkflowRuns(fs14, configDir, path35.join(sessionRelative, WORKFLOWS_DIR), report),
|
|
19702
19841
|
problems
|
|
19703
19842
|
};
|
|
19704
19843
|
}
|
|
19705
|
-
function resolveParents(
|
|
19844
|
+
function resolveParents(fs14, configDir, agents, report) {
|
|
19706
19845
|
const parentOf3 = /* @__PURE__ */ new Map();
|
|
19707
19846
|
const transcriptCache = /* @__PURE__ */ new Map();
|
|
19708
19847
|
const transcriptOf = (agent) => {
|
|
@@ -19710,7 +19849,7 @@ function resolveParents(fs13, configDir, agents, report) {
|
|
|
19710
19849
|
if (cached !== void 0) {
|
|
19711
19850
|
return cached;
|
|
19712
19851
|
}
|
|
19713
|
-
const text = readFileOrReport(
|
|
19852
|
+
const text = readFileOrReport(fs14, configDir, agent.located.transcriptPath, report) ?? "";
|
|
19714
19853
|
transcriptCache.set(agent.located.id, text);
|
|
19715
19854
|
return text;
|
|
19716
19855
|
};
|
|
@@ -19760,16 +19899,16 @@ function resolveParents(fs13, configDir, agents, report) {
|
|
|
19760
19899
|
function ownTaskLists(sessionId) {
|
|
19761
19900
|
return [sessionId, `${SHORT_SESSION_LIST_PREFIX}${sessionId.slice(0, SHORT_SESSION_ID_LENGTH)}`];
|
|
19762
19901
|
}
|
|
19763
|
-
function readTasks(
|
|
19902
|
+
function readTasks(fs14, configDir, ownLists, sharedLists, report) {
|
|
19764
19903
|
const tasks = [];
|
|
19765
19904
|
[...ownLists, ...sharedLists].forEach((scope, index) => {
|
|
19766
19905
|
const relativeDir = path35.join(TASKS_DIR, scope);
|
|
19767
|
-
for (const name of [...listDirOrReport(
|
|
19906
|
+
for (const name of [...listDirOrReport(fs14, configDir, relativeDir, report)].sort()) {
|
|
19768
19907
|
if (name.startsWith(".") || !name.endsWith(JSON_SUFFIX)) {
|
|
19769
19908
|
continue;
|
|
19770
19909
|
}
|
|
19771
19910
|
const relative = path35.join(relativeDir, name);
|
|
19772
|
-
const text = readFileOrReport(
|
|
19911
|
+
const text = readFileOrReport(fs14, configDir, relative, report);
|
|
19773
19912
|
const parsed = TaskFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
19774
19913
|
if (parsed.success) {
|
|
19775
19914
|
tasks.push(index < ownLists.length ? parsed.data : { ...parsed.data, taskList: scope });
|
|
@@ -19780,14 +19919,14 @@ function readTasks(fs13, configDir, ownLists, sharedLists, report) {
|
|
|
19780
19919
|
});
|
|
19781
19920
|
return tasks;
|
|
19782
19921
|
}
|
|
19783
|
-
function readWorkflowRuns(
|
|
19922
|
+
function readWorkflowRuns(fs14, configDir, relativeDir, report) {
|
|
19784
19923
|
const runs = [];
|
|
19785
|
-
for (const name of [...listDirOrReport(
|
|
19924
|
+
for (const name of [...listDirOrReport(fs14, configDir, relativeDir, report)].sort()) {
|
|
19786
19925
|
if (!name.startsWith(WORKFLOW_RUN_PREFIX) || !name.endsWith(JSON_SUFFIX)) {
|
|
19787
19926
|
continue;
|
|
19788
19927
|
}
|
|
19789
19928
|
const relative = path35.join(relativeDir, name);
|
|
19790
|
-
const text = readFileOrReport(
|
|
19929
|
+
const text = readFileOrReport(fs14, configDir, relative, report);
|
|
19791
19930
|
const parsed = WorkflowRunFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
19792
19931
|
if (!parsed.success) {
|
|
19793
19932
|
if (text !== void 0) {
|
|
@@ -19813,11 +19952,11 @@ var SessionLookupError = class extends CliError {
|
|
|
19813
19952
|
function identityConfigDir(identitiesDir, identity) {
|
|
19814
19953
|
return path36.join(identitiesDir, identity);
|
|
19815
19954
|
}
|
|
19816
|
-
function historyStores(
|
|
19955
|
+
function historyStores(fs14, identitiesDir, identities) {
|
|
19817
19956
|
const byRealPath = /* @__PURE__ */ new Map();
|
|
19818
19957
|
for (const identity of identities) {
|
|
19819
19958
|
const configDir = identityConfigDir(identitiesDir, identity);
|
|
19820
|
-
const real =
|
|
19959
|
+
const real = fs14.realpath(path36.join(configDir, "projects"));
|
|
19821
19960
|
if (real === void 0) {
|
|
19822
19961
|
continue;
|
|
19823
19962
|
}
|
|
@@ -19830,15 +19969,15 @@ function historyStores(fs13, identitiesDir, identities) {
|
|
|
19830
19969
|
}
|
|
19831
19970
|
return [...byRealPath.values()];
|
|
19832
19971
|
}
|
|
19833
|
-
function collectSessionList(
|
|
19972
|
+
function collectSessionList(fs14, identitiesDir, identities, filters) {
|
|
19834
19973
|
const names = filters.identity === void 0 ? identities : identities.filter((name) => name === filters.identity);
|
|
19835
19974
|
if (filters.identity !== void 0 && names.length === 0) {
|
|
19836
19975
|
throw new SessionLookupError(`no identity named "${filters.identity}"`);
|
|
19837
19976
|
}
|
|
19838
19977
|
const sessions = [];
|
|
19839
|
-
for (const store of historyStores(
|
|
19840
|
-
for (const ref of listSessions2(
|
|
19841
|
-
const summary = summariseSession(
|
|
19978
|
+
for (const store of historyStores(fs14, identitiesDir, names)) {
|
|
19979
|
+
for (const ref of listSessions2(fs14, store.configDir)) {
|
|
19980
|
+
const summary = summariseSession(fs14, store.configDir, ref);
|
|
19842
19981
|
if (filters.all === true || summary.agentCount > 0 || summary.workflowRunCount > 0) {
|
|
19843
19982
|
sessions.push({ ...summary, identities: store.identities });
|
|
19844
19983
|
}
|
|
@@ -19846,14 +19985,14 @@ function collectSessionList(fs13, identitiesDir, identities, filters) {
|
|
|
19846
19985
|
}
|
|
19847
19986
|
return sessions.sort((left, right) => (right.updatedAt ?? "").localeCompare(left.updatedAt ?? "") || left.sessionId.localeCompare(right.sessionId));
|
|
19848
19987
|
}
|
|
19849
|
-
function locateSession(
|
|
19988
|
+
function locateSession(fs14, identitiesDir, identities, query, onlyIdentity) {
|
|
19850
19989
|
const names = onlyIdentity === void 0 ? identities : identities.filter((name) => name === onlyIdentity);
|
|
19851
19990
|
if (onlyIdentity !== void 0 && names.length === 0) {
|
|
19852
19991
|
throw new SessionLookupError(`no identity named "${onlyIdentity}"`);
|
|
19853
19992
|
}
|
|
19854
19993
|
const matches = [];
|
|
19855
|
-
for (const store of historyStores(
|
|
19856
|
-
for (const ref of listSessions2(
|
|
19994
|
+
for (const store of historyStores(fs14, identitiesDir, names)) {
|
|
19995
|
+
for (const ref of listSessions2(fs14, store.configDir)) {
|
|
19857
19996
|
if (ref.sessionId.startsWith(query)) {
|
|
19858
19997
|
matches.push({ identities: store.identities, configDir: store.configDir, ref });
|
|
19859
19998
|
}
|
|
@@ -19870,9 +20009,9 @@ function locateSession(fs13, identitiesDir, identities, query, onlyIdentity) {
|
|
|
19870
20009
|
}
|
|
19871
20010
|
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`);
|
|
19872
20011
|
}
|
|
19873
|
-
function showSession(
|
|
19874
|
-
const located = locateSession(
|
|
19875
|
-
return { identities: located.identities, tree: readSessionAgentTree(
|
|
20012
|
+
function showSession(fs14, identitiesDir, identities, query, onlyIdentity) {
|
|
20013
|
+
const located = locateSession(fs14, identitiesDir, identities, query, onlyIdentity);
|
|
20014
|
+
return { identities: located.identities, tree: readSessionAgentTree(fs14, located.configDir, located.ref) };
|
|
19876
20015
|
}
|
|
19877
20016
|
|
|
19878
20017
|
// src/agents/realFs.ts
|