claude-use 11.6.2 → 11.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.cjs +492 -310
- package/dist/index.cjs +423 -336
- package/dist/index.mjs +420 -333
- package/dist/types/index.d.ts +34 -8
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2021,8 +2021,8 @@ var init_lock = __esm({
|
|
|
2021
2021
|
// src/launcher/farm.ts
|
|
2022
2022
|
import path7 from "node:path";
|
|
2023
2023
|
import { z as z2 } from "zod";
|
|
2024
|
-
function readFarmManifest(
|
|
2025
|
-
const raw =
|
|
2024
|
+
function readFarmManifest(fs13, farmRoot) {
|
|
2025
|
+
const raw = fs13.readFileUtf8(path7.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs13.readFileUtf8(path7.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
|
|
2026
2026
|
if (raw === void 0) {
|
|
2027
2027
|
return void 0;
|
|
2028
2028
|
}
|
|
@@ -2080,9 +2080,9 @@ function buildEntryFacts(params) {
|
|
|
2080
2080
|
entries
|
|
2081
2081
|
};
|
|
2082
2082
|
}
|
|
2083
|
-
function listSubtree(
|
|
2083
|
+
function listSubtree(fs13, root, rel) {
|
|
2084
2084
|
const absolute = path7.join(root, rel);
|
|
2085
|
-
const stat =
|
|
2085
|
+
const stat = fs13.lstat(absolute);
|
|
2086
2086
|
if (stat === void 0) {
|
|
2087
2087
|
return [];
|
|
2088
2088
|
}
|
|
@@ -2090,10 +2090,10 @@ function listSubtree(fs12, root, rel) {
|
|
|
2090
2090
|
return [{ rel, kind: "symlink" }];
|
|
2091
2091
|
}
|
|
2092
2092
|
if (stat.kind === "dir") {
|
|
2093
|
-
const children = [...
|
|
2093
|
+
const children = [...fs13.readdir(absolute)].sort().flatMap((name) => listSubtree(fs13, root, `${rel}/${name}`));
|
|
2094
2094
|
return [{ rel, kind: "dir" }, ...children];
|
|
2095
2095
|
}
|
|
2096
|
-
const contentHash =
|
|
2096
|
+
const contentHash = fs13.hashFile(absolute);
|
|
2097
2097
|
return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
|
|
2098
2098
|
}
|
|
2099
2099
|
function topLevelScopeRoots(roots) {
|
|
@@ -2107,25 +2107,25 @@ function topLevelScopeRoots(roots) {
|
|
|
2107
2107
|
}
|
|
2108
2108
|
return kept;
|
|
2109
2109
|
}
|
|
2110
|
-
function reconciliationScope(
|
|
2110
|
+
function reconciliationScope(fs13, farmRoot, manifest) {
|
|
2111
2111
|
if (manifest !== void 0) {
|
|
2112
2112
|
return topLevelScopeRoots(manifest.materialised);
|
|
2113
2113
|
}
|
|
2114
|
-
return [...
|
|
2114
|
+
return [...fs13.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs13.lstat(path7.join(farmRoot, name))?.kind === "dir").sort();
|
|
2115
2115
|
}
|
|
2116
|
-
function collectFarmListing(
|
|
2117
|
-
return scopeRoots.flatMap((root) => listSubtree(
|
|
2116
|
+
function collectFarmListing(fs13, farmRoot, scopeRoots) {
|
|
2117
|
+
return scopeRoots.flatMap((root) => listSubtree(fs13, farmRoot, root));
|
|
2118
2118
|
}
|
|
2119
|
-
function collectCanonicalCounterparts(
|
|
2119
|
+
function collectCanonicalCounterparts(fs13, claudeHome, farmListing) {
|
|
2120
2120
|
const out = [];
|
|
2121
2121
|
for (const entry of farmListing) {
|
|
2122
2122
|
const absolute = path7.join(claudeHome, entry.rel);
|
|
2123
|
-
const stat =
|
|
2123
|
+
const stat = fs13.lstat(absolute);
|
|
2124
2124
|
if (stat === void 0) {
|
|
2125
2125
|
continue;
|
|
2126
2126
|
}
|
|
2127
2127
|
if (stat.kind === "file") {
|
|
2128
|
-
const contentHash =
|
|
2128
|
+
const contentHash = fs13.hashFile(absolute);
|
|
2129
2129
|
out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
|
|
2130
2130
|
continue;
|
|
2131
2131
|
}
|
|
@@ -2563,10 +2563,10 @@ var init_route = __esm({
|
|
|
2563
2563
|
// src/frontdoor/state.ts
|
|
2564
2564
|
import path8 from "node:path";
|
|
2565
2565
|
import { z as z3 } from "zod";
|
|
2566
|
-
function readFrontDoorState(
|
|
2566
|
+
function readFrontDoorState(fs13, stateFile) {
|
|
2567
2567
|
let raw;
|
|
2568
2568
|
try {
|
|
2569
|
-
raw =
|
|
2569
|
+
raw = fs13.readFileUtf8(stateFile);
|
|
2570
2570
|
} catch {
|
|
2571
2571
|
return void 0;
|
|
2572
2572
|
}
|
|
@@ -2580,9 +2580,9 @@ function readFrontDoorState(fs12, stateFile) {
|
|
|
2580
2580
|
return void 0;
|
|
2581
2581
|
}
|
|
2582
2582
|
}
|
|
2583
|
-
function writeFrontDoorState(
|
|
2584
|
-
|
|
2585
|
-
|
|
2583
|
+
function writeFrontDoorState(fs13, stateFile, state) {
|
|
2584
|
+
fs13.mkdirp(path8.dirname(stateFile));
|
|
2585
|
+
fs13.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
2586
2586
|
`);
|
|
2587
2587
|
}
|
|
2588
2588
|
function directOrigin(port) {
|
|
@@ -2592,27 +2592,27 @@ function frontDoorOrigin(state) {
|
|
|
2592
2592
|
const port = state?.directPort ?? state?.lastDirectPort;
|
|
2593
2593
|
return port === void 0 ? void 0 : directOrigin(port);
|
|
2594
2594
|
}
|
|
2595
|
-
function writeFrontDoorDirectRecord(
|
|
2596
|
-
|
|
2597
|
-
|
|
2595
|
+
function writeFrontDoorDirectRecord(fs13, recordsDir, record) {
|
|
2596
|
+
fs13.mkdirp(recordsDir);
|
|
2597
|
+
fs13.writeFilePrivate(path8.join(recordsDir, `${String(record.pid)}.json`), `${JSON.stringify({ directPort: record.directPort })}
|
|
2598
2598
|
`);
|
|
2599
2599
|
}
|
|
2600
|
-
function removeFrontDoorDirectRecord(
|
|
2601
|
-
|
|
2600
|
+
function removeFrontDoorDirectRecord(fs13, recordsDir, pid) {
|
|
2601
|
+
fs13.removeRecursive(path8.join(recordsDir, `${String(pid)}.json`));
|
|
2602
2602
|
}
|
|
2603
2603
|
function recordPid(file) {
|
|
2604
2604
|
const pidText = /^([1-9]\d*)\.json$/.exec(file)?.[1];
|
|
2605
2605
|
const pid = pidText === void 0 ? void 0 : Number(pidText);
|
|
2606
2606
|
return pid !== void 0 && Number.isSafeInteger(pid) ? pid : void 0;
|
|
2607
2607
|
}
|
|
2608
|
-
function readDirectRecordEntry(
|
|
2608
|
+
function readDirectRecordEntry(fs13, recordsDir, file) {
|
|
2609
2609
|
const pid = recordPid(file);
|
|
2610
2610
|
if (pid === void 0) {
|
|
2611
2611
|
return void 0;
|
|
2612
2612
|
}
|
|
2613
2613
|
let raw;
|
|
2614
2614
|
try {
|
|
2615
|
-
raw =
|
|
2615
|
+
raw = fs13.readFileUtf8(path8.join(recordsDir, file));
|
|
2616
2616
|
} catch {
|
|
2617
2617
|
return void 0;
|
|
2618
2618
|
}
|
|
@@ -2626,44 +2626,44 @@ function readDirectRecordEntry(fs12, recordsDir, file) {
|
|
|
2626
2626
|
return { malformed: true };
|
|
2627
2627
|
}
|
|
2628
2628
|
}
|
|
2629
|
-
function listFrontDoorDirectRecords(
|
|
2630
|
-
return
|
|
2631
|
-
const entry = readDirectRecordEntry(
|
|
2629
|
+
function listFrontDoorDirectRecords(fs13, recordsDir) {
|
|
2630
|
+
return fs13.readdir(recordsDir).flatMap((file) => {
|
|
2631
|
+
const entry = readDirectRecordEntry(fs13, recordsDir, file);
|
|
2632
2632
|
return entry?.record === void 0 ? [] : [entry.record];
|
|
2633
2633
|
}).sort((a, b) => a.pid - b.pid);
|
|
2634
2634
|
}
|
|
2635
|
-
function pruneMalformedFrontDoorDirectFiles(
|
|
2636
|
-
for (const file of
|
|
2635
|
+
function pruneMalformedFrontDoorDirectFiles(fs13, recordsDir, isRunning) {
|
|
2636
|
+
for (const file of fs13.readdir(recordsDir)) {
|
|
2637
2637
|
const writer = RECORD_TEMPORARY_FILE.exec(file)?.[1];
|
|
2638
2638
|
const stale = writer !== void 0 && !isRunning(Number(writer));
|
|
2639
|
-
if (stale || readDirectRecordEntry(
|
|
2640
|
-
|
|
2639
|
+
if (stale || readDirectRecordEntry(fs13, recordsDir, file)?.malformed === true) {
|
|
2640
|
+
fs13.removeRecursive(path8.join(recordsDir, file));
|
|
2641
2641
|
}
|
|
2642
2642
|
}
|
|
2643
2643
|
}
|
|
2644
2644
|
function liveFrontDoorDirectRecords(records, liveness) {
|
|
2645
2645
|
return records.filter((record) => liveness.doors.has(record.pid) || liveness.unknown.has(record.pid));
|
|
2646
2646
|
}
|
|
2647
|
-
function pruneDeadFrontDoorDirectRecords(
|
|
2647
|
+
function pruneDeadFrontDoorDirectRecords(fs13, recordsDir, records, liveness) {
|
|
2648
2648
|
for (const record of records) {
|
|
2649
2649
|
if (!liveness.doors.has(record.pid) && !liveness.unknown.has(record.pid)) {
|
|
2650
|
-
removeFrontDoorDirectRecord(
|
|
2650
|
+
removeFrontDoorDirectRecord(fs13, recordsDir, record.pid);
|
|
2651
2651
|
}
|
|
2652
2652
|
}
|
|
2653
2653
|
}
|
|
2654
|
-
function writeFrontDoorSession(
|
|
2655
|
-
|
|
2656
|
-
|
|
2654
|
+
function writeFrontDoorSession(fs13, sessionsDir, session) {
|
|
2655
|
+
fs13.mkdirPrivate(sessionsDir);
|
|
2656
|
+
fs13.writeFilePrivate(path8.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
2657
2657
|
`);
|
|
2658
2658
|
}
|
|
2659
|
-
function listFrontDoorSessions(
|
|
2659
|
+
function listFrontDoorSessions(fs13, sessionsDir) {
|
|
2660
2660
|
const sessions = [];
|
|
2661
|
-
for (const name of
|
|
2661
|
+
for (const name of fs13.readdir(sessionsDir)) {
|
|
2662
2662
|
if (!name.endsWith(".json")) {
|
|
2663
2663
|
continue;
|
|
2664
2664
|
}
|
|
2665
2665
|
try {
|
|
2666
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(
|
|
2666
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs13.readFileUtf8(path8.join(sessionsDir, name)) ?? ""));
|
|
2667
2667
|
if (parsed.success) {
|
|
2668
2668
|
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
|
|
2669
2669
|
}
|
|
@@ -2673,14 +2673,14 @@ function listFrontDoorSessions(fs12, sessionsDir) {
|
|
|
2673
2673
|
}
|
|
2674
2674
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
2675
2675
|
}
|
|
2676
|
-
function removeFrontDoorSession(
|
|
2677
|
-
|
|
2676
|
+
function removeFrontDoorSession(fs13, sessionsDir, pid) {
|
|
2677
|
+
fs13.removeRecursive(path8.join(sessionsDir, `${String(pid)}.json`));
|
|
2678
2678
|
}
|
|
2679
|
-
function pruneDeadFrontDoorSessions(
|
|
2679
|
+
function pruneDeadFrontDoorSessions(fs13, sessionsDir, isRunning) {
|
|
2680
2680
|
const removed = [];
|
|
2681
|
-
for (const session of listFrontDoorSessions(
|
|
2681
|
+
for (const session of listFrontDoorSessions(fs13, sessionsDir)) {
|
|
2682
2682
|
if (!isRunning(session.pid)) {
|
|
2683
|
-
removeFrontDoorSession(
|
|
2683
|
+
removeFrontDoorSession(fs13, sessionsDir, session.pid);
|
|
2684
2684
|
removed.push(session.pid);
|
|
2685
2685
|
}
|
|
2686
2686
|
}
|
|
@@ -2763,7 +2763,7 @@ var init_package = __esm({
|
|
|
2763
2763
|
"package.json"() {
|
|
2764
2764
|
package_default = {
|
|
2765
2765
|
name: "claude-use",
|
|
2766
|
-
version: "11.
|
|
2766
|
+
version: "11.8.0",
|
|
2767
2767
|
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.",
|
|
2768
2768
|
license: "MIT",
|
|
2769
2769
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -2971,43 +2971,43 @@ function parseJson(raw, schema) {
|
|
|
2971
2971
|
const parsed = schema.safeParse(JSON.parse(raw));
|
|
2972
2972
|
return parsed.success ? parsed.data : void 0;
|
|
2973
2973
|
}
|
|
2974
|
-
function readHeadroomState(
|
|
2974
|
+
function readHeadroomState(fs13, stateFile) {
|
|
2975
2975
|
try {
|
|
2976
|
-
return parseJson(
|
|
2976
|
+
return parseJson(fs13.readFileUtf8(stateFile), HeadroomStateSchema);
|
|
2977
2977
|
} catch {
|
|
2978
2978
|
return void 0;
|
|
2979
2979
|
}
|
|
2980
2980
|
}
|
|
2981
|
-
function writeHeadroomState(
|
|
2982
|
-
|
|
2983
|
-
|
|
2981
|
+
function writeHeadroomState(fs13, stateFile, state) {
|
|
2982
|
+
fs13.mkdirp(path11.dirname(stateFile));
|
|
2983
|
+
fs13.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
2984
2984
|
`);
|
|
2985
2985
|
}
|
|
2986
|
-
function resolveServingHeadroomState(
|
|
2987
|
-
const current = readHeadroomState(
|
|
2986
|
+
function resolveServingHeadroomState(fs13, files, isRunning) {
|
|
2987
|
+
const current = readHeadroomState(fs13, files.stateFile);
|
|
2988
2988
|
if (current !== void 0) {
|
|
2989
2989
|
return { path: files.stateFile, state: current };
|
|
2990
2990
|
}
|
|
2991
|
-
const legacy = readHeadroomState(
|
|
2991
|
+
const legacy = readHeadroomState(fs13, files.legacyStateFile);
|
|
2992
2992
|
if (legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid)) {
|
|
2993
2993
|
return { path: files.legacyStateFile, state: legacy };
|
|
2994
2994
|
}
|
|
2995
2995
|
return void 0;
|
|
2996
2996
|
}
|
|
2997
|
-
function migrateHeadroomState(
|
|
2998
|
-
const legacy = readHeadroomState(
|
|
2997
|
+
function migrateHeadroomState(fs13, files, isRunning) {
|
|
2998
|
+
const legacy = readHeadroomState(fs13, files.legacyStateFile);
|
|
2999
2999
|
const legacyLive = legacy?.supervisorPid !== void 0 && isRunning(legacy.supervisorPid);
|
|
3000
|
-
const current = readHeadroomState(
|
|
3000
|
+
const current = readHeadroomState(fs13, files.stateFile);
|
|
3001
3001
|
if (current !== void 0 || legacyLive) {
|
|
3002
|
-
if (!legacyLive &&
|
|
3003
|
-
|
|
3002
|
+
if (!legacyLive && fs13.readFileUtf8(files.legacyStateFile) !== void 0) {
|
|
3003
|
+
fs13.removeRecursive(files.legacyStateFile);
|
|
3004
3004
|
}
|
|
3005
3005
|
return;
|
|
3006
3006
|
}
|
|
3007
3007
|
if (legacy !== void 0) {
|
|
3008
|
-
writeHeadroomState(
|
|
3008
|
+
writeHeadroomState(fs13, files.stateFile, legacy);
|
|
3009
3009
|
}
|
|
3010
|
-
|
|
3010
|
+
fs13.removeRecursive(files.legacyStateFile);
|
|
3011
3011
|
}
|
|
3012
3012
|
function hashAllowlist(allowlist) {
|
|
3013
3013
|
return createHash3("sha256").update(allowlist.join("\n")).digest("hex");
|
|
@@ -3040,27 +3040,27 @@ function isAdmissibleUrl(entry) {
|
|
|
3040
3040
|
function parseAllowlistFile(content) {
|
|
3041
3041
|
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)));
|
|
3042
3042
|
}
|
|
3043
|
-
function writeAllowlistFile(
|
|
3044
|
-
|
|
3045
|
-
|
|
3043
|
+
function writeAllowlistFile(fs13, allowlistFile, allowlist) {
|
|
3044
|
+
fs13.mkdirPrivate(path11.dirname(allowlistFile));
|
|
3045
|
+
fs13.writeFilePrivate(allowlistFile, formatAllowlistFile(allowlist));
|
|
3046
3046
|
}
|
|
3047
|
-
function pruneStaleAllowlistTemporaries(
|
|
3047
|
+
function pruneStaleAllowlistTemporaries(fs13, allowlistFile, isRunning) {
|
|
3048
3048
|
const prefix = `${path11.basename(allowlistFile)}.`;
|
|
3049
|
-
for (const name of
|
|
3049
|
+
for (const name of fs13.readdir(path11.dirname(allowlistFile))) {
|
|
3050
3050
|
const writer = name.startsWith(prefix) ? /^([1-9]\d*)\.tmp$/.exec(name.slice(prefix.length))?.[1] : void 0;
|
|
3051
3051
|
if (writer !== void 0 && !isRunning(Number(writer))) {
|
|
3052
|
-
|
|
3052
|
+
fs13.removeRecursive(path11.join(path11.dirname(allowlistFile), name));
|
|
3053
3053
|
}
|
|
3054
3054
|
}
|
|
3055
3055
|
}
|
|
3056
|
-
function readAllProviders(
|
|
3056
|
+
function readAllProviders(fs13, providersDir) {
|
|
3057
3057
|
const result = [];
|
|
3058
|
-
for (const name of
|
|
3058
|
+
for (const name of fs13.readdir(providersDir)) {
|
|
3059
3059
|
if (!name.endsWith(".json")) {
|
|
3060
3060
|
continue;
|
|
3061
3061
|
}
|
|
3062
3062
|
try {
|
|
3063
|
-
const parsed = parseJson(
|
|
3063
|
+
const parsed = parseJson(fs13.readFileUtf8(path11.join(providersDir, name)), ProviderSchema);
|
|
3064
3064
|
if (parsed !== void 0) {
|
|
3065
3065
|
result.push({ name: name.slice(0, -".json".length), provider: parsed });
|
|
3066
3066
|
}
|
|
@@ -3070,22 +3070,22 @@ function readAllProviders(fs12, providersDir) {
|
|
|
3070
3070
|
}
|
|
3071
3071
|
return result;
|
|
3072
3072
|
}
|
|
3073
|
-
function writeSession(
|
|
3074
|
-
|
|
3075
|
-
|
|
3073
|
+
function writeSession(fs13, sessionsDir, session) {
|
|
3074
|
+
fs13.mkdirp(sessionsDir);
|
|
3075
|
+
fs13.writeFileUtf8(path11.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
3076
3076
|
`);
|
|
3077
3077
|
}
|
|
3078
|
-
function removeSession(
|
|
3079
|
-
|
|
3078
|
+
function removeSession(fs13, sessionsDir, pid) {
|
|
3079
|
+
fs13.removeRecursive(path11.join(sessionsDir, `${String(pid)}.json`));
|
|
3080
3080
|
}
|
|
3081
|
-
function listSessions(
|
|
3081
|
+
function listSessions(fs13, sessionsDir) {
|
|
3082
3082
|
const sessions = [];
|
|
3083
|
-
for (const name of
|
|
3083
|
+
for (const name of fs13.readdir(sessionsDir)) {
|
|
3084
3084
|
if (!name.endsWith(".json")) {
|
|
3085
3085
|
continue;
|
|
3086
3086
|
}
|
|
3087
3087
|
try {
|
|
3088
|
-
const parsed = parseJson(
|
|
3088
|
+
const parsed = parseJson(fs13.readFileUtf8(path11.join(sessionsDir, name)), HeadroomSessionSchema);
|
|
3089
3089
|
if (parsed !== void 0) {
|
|
3090
3090
|
sessions.push(parsed);
|
|
3091
3091
|
}
|
|
@@ -3095,22 +3095,22 @@ function listSessions(fs12, sessionsDir) {
|
|
|
3095
3095
|
}
|
|
3096
3096
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
3097
3097
|
}
|
|
3098
|
-
function sessionsForSupervisor(
|
|
3099
|
-
return listSessions(
|
|
3098
|
+
function sessionsForSupervisor(fs13, sessionsDir, supervisorPid) {
|
|
3099
|
+
return listSessions(fs13, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
|
|
3100
3100
|
}
|
|
3101
|
-
function pruneDeadSessions(
|
|
3101
|
+
function pruneDeadSessions(fs13, sessionsDir, isRunning) {
|
|
3102
3102
|
const removed = [];
|
|
3103
|
-
for (const session of listSessions(
|
|
3103
|
+
for (const session of listSessions(fs13, sessionsDir)) {
|
|
3104
3104
|
if (!isRunning(session.pid)) {
|
|
3105
|
-
removeSession(
|
|
3105
|
+
removeSession(fs13, sessionsDir, session.pid);
|
|
3106
3106
|
removed.push(session.pid);
|
|
3107
3107
|
}
|
|
3108
3108
|
}
|
|
3109
3109
|
return removed;
|
|
3110
3110
|
}
|
|
3111
|
-
function readStartLock(
|
|
3111
|
+
function readStartLock(fs13, lockFile) {
|
|
3112
3112
|
try {
|
|
3113
|
-
return parseJson(
|
|
3113
|
+
return parseJson(fs13.readFileUtf8(lockFile), HeadroomLockSchema);
|
|
3114
3114
|
} catch {
|
|
3115
3115
|
return void 0;
|
|
3116
3116
|
}
|
|
@@ -3200,12 +3200,12 @@ function earlierReleaseAllowlistHash(providers, doorOrigin) {
|
|
|
3200
3200
|
}
|
|
3201
3201
|
return hashAllowlist([...entries].sort());
|
|
3202
3202
|
}
|
|
3203
|
-
function earlierReleaseDaemon(
|
|
3203
|
+
function earlierReleaseDaemon(fs13, paths, daemon) {
|
|
3204
3204
|
if (daemonIdentity(daemon.commandLine, daemon.socketPath) !== "earlier-release") {
|
|
3205
3205
|
return void 0;
|
|
3206
3206
|
}
|
|
3207
|
-
const providers = readAllProviders(
|
|
3208
|
-
const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(
|
|
3207
|
+
const providers = readAllProviders(fs13, paths.providersDir).map((entry) => entry.provider);
|
|
3208
|
+
const expected = earlierReleaseAllowlistHash(providers, frontDoorOrigin(readFrontDoorState(fs13, paths.frontdoorStateFile)));
|
|
3209
3209
|
return { admitsServingDoor: daemon.recordedHash === expected };
|
|
3210
3210
|
}
|
|
3211
3211
|
var EARLIER_RELEASE_ALLOWLIST, EARLIER_RELEASE_ANTHROPIC_UPSTREAM;
|
|
@@ -3230,8 +3230,8 @@ function awaitingCause(daemonPid, identity, allowlistFile) {
|
|
|
3230
3230
|
}
|
|
3231
3231
|
return `the headroom supervisor has not written an allowlist admitting this launch's upstreams to ${allowlistFile} within ${String(HEADROOM_START_TIMEOUT_MS)}ms`;
|
|
3232
3232
|
}
|
|
3233
|
-
function daemonAdmits(
|
|
3234
|
-
const content =
|
|
3233
|
+
function daemonAdmits(fs13, allowlistFile, recordedHash, required) {
|
|
3234
|
+
const content = fs13.readFileUtf8(allowlistFile);
|
|
3235
3235
|
if (content === void 0 || recordedHash === void 0) {
|
|
3236
3236
|
return false;
|
|
3237
3237
|
}
|
|
@@ -3494,7 +3494,7 @@ function verifyAllowlistFile(allowlistFile, ports) {
|
|
|
3494
3494
|
const replaceable = fileStat === void 0 || fileStat.kind === "file" || fileStat.kind === "symlink";
|
|
3495
3495
|
return { message: refusal2, repairable: replaceable };
|
|
3496
3496
|
}
|
|
3497
|
-
function prepareHeadroomSocket(
|
|
3497
|
+
function prepareHeadroomSocket(fs13, ports, paths, supervisorPid) {
|
|
3498
3498
|
const unsupported = platformRefusal(ports.platform);
|
|
3499
3499
|
if (unsupported !== void 0) {
|
|
3500
3500
|
return { refused: unsupported };
|
|
@@ -3509,18 +3509,18 @@ function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
|
|
|
3509
3509
|
if (ports.lstat(paths.headroomSocketDir)?.kind === "symlink") {
|
|
3510
3510
|
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
3511
3511
|
}
|
|
3512
|
-
|
|
3512
|
+
fs13.mkdirPrivate(paths.headroomSocketDir);
|
|
3513
3513
|
const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
3514
3514
|
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
3515
3515
|
}
|
|
3516
|
-
function pruneStaleHeadroomSockets(
|
|
3516
|
+
function pruneStaleHeadroomSockets(fs13, paths, isRunning) {
|
|
3517
3517
|
const removed = [];
|
|
3518
|
-
for (const name of
|
|
3518
|
+
for (const name of fs13.readdir(paths.headroomSocketDir)) {
|
|
3519
3519
|
const pid = HEADROOM_SOCKET_NAME.exec(name)?.[1];
|
|
3520
3520
|
if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
|
|
3521
3521
|
continue;
|
|
3522
3522
|
}
|
|
3523
|
-
|
|
3523
|
+
fs13.removeRecursive(path12.join(paths.headroomSocketDir, name));
|
|
3524
3524
|
removed.push(name);
|
|
3525
3525
|
}
|
|
3526
3526
|
return removed;
|
|
@@ -3632,37 +3632,37 @@ function compareVersions2(a, b) {
|
|
|
3632
3632
|
return 0;
|
|
3633
3633
|
}
|
|
3634
3634
|
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
3635
|
-
const { fs:
|
|
3635
|
+
const { fs: fs13, paths } = ports;
|
|
3636
3636
|
let config = initialConfig;
|
|
3637
|
-
migrateHeadroomState(
|
|
3638
|
-
const previousState = resolveServingHeadroomState(
|
|
3637
|
+
migrateHeadroomState(fs13, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning);
|
|
3638
|
+
const previousState = resolveServingHeadroomState(fs13, { stateFile: paths.headroomStateFile, legacyStateFile: paths.headroomLegacyStateFile }, ports.isRunning)?.state;
|
|
3639
3639
|
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
3640
3640
|
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
3641
3641
|
return 0;
|
|
3642
3642
|
}
|
|
3643
3643
|
let installedSource = previousState?.installedSource;
|
|
3644
3644
|
const ownsState = () => {
|
|
3645
|
-
const owner = readHeadroomState(
|
|
3645
|
+
const owner = readHeadroomState(fs13, paths.headroomStateFile)?.supervisorPid;
|
|
3646
3646
|
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
3647
3647
|
};
|
|
3648
3648
|
const writeOwnState = (state) => {
|
|
3649
3649
|
if (!ownsState()) {
|
|
3650
3650
|
return false;
|
|
3651
3651
|
}
|
|
3652
|
-
writeHeadroomState(
|
|
3652
|
+
writeHeadroomState(fs13, paths.headroomStateFile, state);
|
|
3653
3653
|
return true;
|
|
3654
3654
|
};
|
|
3655
3655
|
const fail = (message) => {
|
|
3656
3656
|
if (writeOwnState({ lastError: message })) {
|
|
3657
|
-
|
|
3657
|
+
fs13.removeRecursive(paths.headroomLockFile);
|
|
3658
3658
|
}
|
|
3659
3659
|
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
3660
3660
|
return 1;
|
|
3661
3661
|
};
|
|
3662
3662
|
const syncAllowlistFile = (allowlist) => {
|
|
3663
3663
|
try {
|
|
3664
|
-
if (
|
|
3665
|
-
writeAllowlistFile(
|
|
3664
|
+
if (fs13.readFileUtf8(paths.headroomAllowlistFile) !== formatAllowlistFile(allowlist)) {
|
|
3665
|
+
writeAllowlistFile(fs13, paths.headroomAllowlistFile, allowlist);
|
|
3666
3666
|
ports.log(`agent-shim headroom supervisor: wrote allowlist [${allowlist.join(", ")}] to ${paths.headroomAllowlistFile}`);
|
|
3667
3667
|
}
|
|
3668
3668
|
return void 0;
|
|
@@ -3680,9 +3680,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3680
3680
|
}
|
|
3681
3681
|
ports.log(`agent-shim headroom supervisor: repairing the allowlist file: ${problem.message}`);
|
|
3682
3682
|
try {
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
writeAllowlistFile(
|
|
3683
|
+
fs13.mkdirPrivate(paths.headroomDir);
|
|
3684
|
+
fs13.mkdirPrivate(path13.dirname(paths.headroomAllowlistFile));
|
|
3685
|
+
writeAllowlistFile(fs13, paths.headroomAllowlistFile, allowlist);
|
|
3686
3686
|
} catch (error) {
|
|
3687
3687
|
return `could not write the headroom allowlist file ${paths.headroomAllowlistFile}: ${error instanceof Error ? error.message : String(error)}`;
|
|
3688
3688
|
}
|
|
@@ -3707,20 +3707,20 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3707
3707
|
installedSource = config.source;
|
|
3708
3708
|
return void 0;
|
|
3709
3709
|
};
|
|
3710
|
-
const socket = prepareHeadroomSocket(
|
|
3710
|
+
const socket = prepareHeadroomSocket(fs13, ports.socketTrust, paths, ports.ownPid);
|
|
3711
3711
|
if (socket.refused !== void 0) {
|
|
3712
3712
|
return fail(socket.refused);
|
|
3713
3713
|
}
|
|
3714
3714
|
const { socketPath } = socket;
|
|
3715
|
-
pruneStaleHeadroomSockets(
|
|
3716
|
-
pruneStaleAllowlistTemporaries(
|
|
3715
|
+
pruneStaleHeadroomSockets(fs13, paths, ports.isRunning);
|
|
3716
|
+
pruneStaleAllowlistTemporaries(fs13, paths.headroomAllowlistFile, ports.isRunning);
|
|
3717
3717
|
const installFailure = ensureInstalled();
|
|
3718
3718
|
if (installFailure !== void 0) {
|
|
3719
3719
|
return fail(installFailure);
|
|
3720
3720
|
}
|
|
3721
3721
|
const version = ports.headroomVersion() ?? "unknown";
|
|
3722
3722
|
writeOwnState({ supervisorPid: ports.ownPid, version, installedSource });
|
|
3723
|
-
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(
|
|
3723
|
+
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${currentHeadroomAllowlistInputs(fs13, paths, ports.frontDoorLiveness).frontDoorOrigins.join(", ")}]`);
|
|
3724
3724
|
const orphanPid = previousState?.headroomPid;
|
|
3725
3725
|
const orphanSocket = previousState?.socketPath ?? (previousState?.supervisorPid === void 0 ? void 0 : headroomSocketPath(paths, previousState.supervisorPid));
|
|
3726
3726
|
const orphanIdentity = orphanPid === void 0 || orphanSocket === void 0 || !ports.isRunning(orphanPid) ? void 0 : daemonIdentity(ports.daemonCommandLine(orphanPid), orphanSocket);
|
|
@@ -3755,12 +3755,12 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3755
3755
|
ticks += 1;
|
|
3756
3756
|
config = ports.readConfig();
|
|
3757
3757
|
const settingsHash = hashSettings(config.settings);
|
|
3758
|
-
const inputs = currentHeadroomAllowlistInputs(
|
|
3759
|
-
pruneDeadFrontDoorDirectRecords(
|
|
3760
|
-
pruneMalformedFrontDoorDirectFiles(
|
|
3758
|
+
const inputs = currentHeadroomAllowlistInputs(fs13, paths, ports.frontDoorLiveness);
|
|
3759
|
+
pruneDeadFrontDoorDirectRecords(fs13, paths.frontdoorDirectRecordsDir, inputs.frontDoorRecords, inputs.frontDoorLiveness);
|
|
3760
|
+
pruneMalformedFrontDoorDirectFiles(fs13, paths.frontdoorDirectRecordsDir, ports.isRunning);
|
|
3761
3761
|
const allowlist = inputs.frontDoorOrigins;
|
|
3762
3762
|
const allowlistHash = hashAllowlist(allowlist);
|
|
3763
|
-
pruneDeadSessions(
|
|
3763
|
+
pruneDeadSessions(fs13, paths.headroomSessionsDir, ports.isRunning);
|
|
3764
3764
|
const ownsNow = ownsState();
|
|
3765
3765
|
if (!ownsNow && !superseded) {
|
|
3766
3766
|
ports.log("agent-shim headroom supervisor: another supervisor now owns the state file; serving this daemon's own sessions until they end");
|
|
@@ -3807,7 +3807,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3807
3807
|
runningSettingsHash = settingsHash;
|
|
3808
3808
|
const recorded = writeOwnState(servingState(pid));
|
|
3809
3809
|
if (recorded) {
|
|
3810
|
-
|
|
3810
|
+
fs13.removeRecursive(paths.headroomLockFile);
|
|
3811
3811
|
}
|
|
3812
3812
|
idleSince = void 0;
|
|
3813
3813
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on unix socket ${socketPath}`);
|
|
@@ -3835,7 +3835,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3835
3835
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} now serves allowlist [${allowlist.join(", ")}]`);
|
|
3836
3836
|
}
|
|
3837
3837
|
if (runningSettingsHash !== settingsHash || installedSource !== config.source) {
|
|
3838
|
-
if (sessionsForSupervisor(
|
|
3838
|
+
if (sessionsForSupervisor(fs13, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
3839
3839
|
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
3840
3840
|
ports.stopProcess(headroomPid);
|
|
3841
3841
|
headroomPid = void 0;
|
|
@@ -3844,7 +3844,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3844
3844
|
continue;
|
|
3845
3845
|
}
|
|
3846
3846
|
}
|
|
3847
|
-
const sessions = sessionsForSupervisor(
|
|
3847
|
+
const sessions = sessionsForSupervisor(fs13, paths.headroomSessionsDir, ports.ownPid);
|
|
3848
3848
|
if (sessions.length === 0) {
|
|
3849
3849
|
idleSince ??= ports.now();
|
|
3850
3850
|
const idleMs = ports.now() - idleSince;
|
|
@@ -3869,9 +3869,9 @@ function undeterminedFrontDoors(inputs) {
|
|
|
3869
3869
|
return reason === void 0 ? [] : [{ pid: record.pid, origin: directOrigin(record.directPort), reason }];
|
|
3870
3870
|
});
|
|
3871
3871
|
}
|
|
3872
|
-
function currentHeadroomAllowlistInputs(
|
|
3873
|
-
const named = frontDoorOrigin(readFrontDoorState(
|
|
3874
|
-
const records = listFrontDoorDirectRecords(
|
|
3872
|
+
function currentHeadroomAllowlistInputs(fs13, paths, frontDoorLiveness) {
|
|
3873
|
+
const named = frontDoorOrigin(readFrontDoorState(fs13, paths.frontdoorStateFile));
|
|
3874
|
+
const records = listFrontDoorDirectRecords(fs13, paths.frontdoorDirectRecordsDir);
|
|
3875
3875
|
const liveness = frontDoorLiveness(records.map((record) => record.pid));
|
|
3876
3876
|
const live = liveFrontDoorDirectRecords(records, liveness).map((record) => directOrigin(record.directPort));
|
|
3877
3877
|
return {
|
|
@@ -3880,8 +3880,8 @@ function currentHeadroomAllowlistInputs(fs12, paths, frontDoorLiveness) {
|
|
|
3880
3880
|
frontDoorOrigins: [.../* @__PURE__ */ new Set([...named === void 0 ? [] : [named], ...live])].sort()
|
|
3881
3881
|
};
|
|
3882
3882
|
}
|
|
3883
|
-
function launchRequiredUpstreams(
|
|
3884
|
-
const door = frontDoorOrigin(readFrontDoorState(
|
|
3883
|
+
function launchRequiredUpstreams(fs13, paths) {
|
|
3884
|
+
const door = frontDoorOrigin(readFrontDoorState(fs13, paths.frontdoorStateFile));
|
|
3885
3885
|
return door === void 0 ? [] : [door];
|
|
3886
3886
|
}
|
|
3887
3887
|
async function waitUntilReady(ports, socketPath, pid) {
|
|
@@ -4501,8 +4501,8 @@ import path17 from "node:path";
|
|
|
4501
4501
|
function poolNameOf(selector) {
|
|
4502
4502
|
return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
|
|
4503
4503
|
}
|
|
4504
|
-
function readActiveIdentity(
|
|
4505
|
-
const trimmed =
|
|
4504
|
+
function readActiveIdentity(fs13, activeIdentityFile) {
|
|
4505
|
+
const trimmed = fs13.readFileUtf8(activeIdentityFile)?.trim();
|
|
4506
4506
|
return trimmed === void 0 || trimmed === "" ? void 0 : trimmed;
|
|
4507
4507
|
}
|
|
4508
4508
|
function isNonEmpty(value) {
|
|
@@ -4549,8 +4549,8 @@ function decideConfigProfile(params) {
|
|
|
4549
4549
|
}
|
|
4550
4550
|
return { source: "none" };
|
|
4551
4551
|
}
|
|
4552
|
-
function loadIdentity(identitiesDir, name,
|
|
4553
|
-
return loadConfigFile(path17.join(identitiesDir, name, "identity.json"), IdentitySchema,
|
|
4552
|
+
function loadIdentity(identitiesDir, name, fs13) {
|
|
4553
|
+
return loadConfigFile(path17.join(identitiesDir, name, "identity.json"), IdentitySchema, fs13.readConfigFile);
|
|
4554
4554
|
}
|
|
4555
4555
|
var IDENTITY_DECISION_SOURCES, CONFIG_PROFILE_DECISION_SOURCES;
|
|
4556
4556
|
var init_identity = __esm({
|
|
@@ -4782,12 +4782,12 @@ function isIdentityName(name) {
|
|
|
4782
4782
|
function claudeJsonPath(identitiesDir, identity) {
|
|
4783
4783
|
return path18.join(identitiesDir, identity, CLAUDE_JSON);
|
|
4784
4784
|
}
|
|
4785
|
-
function readAccountMetadata(
|
|
4785
|
+
function readAccountMetadata(fs13, identitiesDir, identity) {
|
|
4786
4786
|
if (!isIdentityName(identity)) {
|
|
4787
4787
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
4788
4788
|
}
|
|
4789
4789
|
const file = claudeJsonPath(identitiesDir, identity);
|
|
4790
|
-
const raw =
|
|
4790
|
+
const raw = fs13.readFileUtf8(file);
|
|
4791
4791
|
if (raw === void 0) {
|
|
4792
4792
|
return void 0;
|
|
4793
4793
|
}
|
|
@@ -4817,19 +4817,19 @@ function readAccountMetadata(fs12, identitiesDir, identity) {
|
|
|
4817
4817
|
}
|
|
4818
4818
|
return account.data;
|
|
4819
4819
|
}
|
|
4820
|
-
function createAccountReader(
|
|
4820
|
+
function createAccountReader(fs13, identitiesDir) {
|
|
4821
4821
|
const cache = /* @__PURE__ */ new Map();
|
|
4822
4822
|
return (identity) => {
|
|
4823
4823
|
if (!isIdentityName(identity)) {
|
|
4824
4824
|
throw new Error(`"${identity}" is not a valid identity name.`);
|
|
4825
4825
|
}
|
|
4826
|
-
const stat =
|
|
4826
|
+
const stat = fs13.lstat(claudeJsonPath(identitiesDir, identity));
|
|
4827
4827
|
const stamp = stat === void 0 ? "absent" : `${String(stat.mtimeMs)}:${String(stat.sizeBytes)}`;
|
|
4828
4828
|
const cached = cache.get(identity);
|
|
4829
4829
|
if (cached?.stamp === stamp) {
|
|
4830
4830
|
return cached.account;
|
|
4831
4831
|
}
|
|
4832
|
-
const account = readAccountMetadata(
|
|
4832
|
+
const account = readAccountMetadata(fs13, identitiesDir, identity);
|
|
4833
4833
|
cache.set(identity, { stamp, account });
|
|
4834
4834
|
return account;
|
|
4835
4835
|
};
|
|
@@ -5411,8 +5411,8 @@ function segmentDay(epochMs) {
|
|
|
5411
5411
|
function segmentName(day, pid) {
|
|
5412
5412
|
return `${day}.${String(pid)}.jsonl`;
|
|
5413
5413
|
}
|
|
5414
|
-
function listLogSegments(
|
|
5415
|
-
return
|
|
5414
|
+
function listLogSegments(fs13, logDir) {
|
|
5415
|
+
return fs13.readdir(logDir).flatMap((name) => {
|
|
5416
5416
|
const match = SEGMENT_RE.exec(name);
|
|
5417
5417
|
const day = match?.[1];
|
|
5418
5418
|
if (day === void 0) {
|
|
@@ -5421,15 +5421,15 @@ function listLogSegments(fs12, logDir) {
|
|
|
5421
5421
|
return [{ name, day, endsAt: Date.parse(`${day}T00:00:00.000Z`) + DAY_MS }];
|
|
5422
5422
|
}).sort((left, right) => left.day.localeCompare(right.day) || left.name.localeCompare(right.name));
|
|
5423
5423
|
}
|
|
5424
|
-
function readUsageLog(
|
|
5424
|
+
function readUsageLog(fs13, logDir, options = {}) {
|
|
5425
5425
|
const { sinceMs } = options;
|
|
5426
5426
|
const records = [];
|
|
5427
5427
|
let invalidLines = 0;
|
|
5428
|
-
for (const segment of listLogSegments(
|
|
5428
|
+
for (const segment of listLogSegments(fs13, logDir)) {
|
|
5429
5429
|
if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
|
|
5430
5430
|
continue;
|
|
5431
5431
|
}
|
|
5432
|
-
const contents =
|
|
5432
|
+
const contents = fs13.readFileUtf8(path19.join(logDir, segment.name));
|
|
5433
5433
|
if (contents === void 0) {
|
|
5434
5434
|
continue;
|
|
5435
5435
|
}
|
|
@@ -5465,9 +5465,9 @@ function snapshotPath(snapshotsDir, identity) {
|
|
|
5465
5465
|
}
|
|
5466
5466
|
return path19.join(snapshotsDir, `${identity}.json`);
|
|
5467
5467
|
}
|
|
5468
|
-
function readUsageSnapshot(
|
|
5468
|
+
function readUsageSnapshot(fs13, snapshotsDir, identity) {
|
|
5469
5469
|
const file = snapshotPath(snapshotsDir, identity);
|
|
5470
|
-
const raw =
|
|
5470
|
+
const raw = fs13.readFileUtf8(file);
|
|
5471
5471
|
if (raw === void 0) {
|
|
5472
5472
|
return void 0;
|
|
5473
5473
|
}
|
|
@@ -5483,8 +5483,8 @@ function readUsageSnapshot(fs12, snapshotsDir, identity) {
|
|
|
5483
5483
|
}
|
|
5484
5484
|
return snapshot.data;
|
|
5485
5485
|
}
|
|
5486
|
-
function listUsageSnapshots(
|
|
5487
|
-
return
|
|
5486
|
+
function listUsageSnapshots(fs13, snapshotsDir) {
|
|
5487
|
+
return fs13.readdir(snapshotsDir).flatMap((name) => {
|
|
5488
5488
|
if (!name.endsWith(".json")) {
|
|
5489
5489
|
return [];
|
|
5490
5490
|
}
|
|
@@ -5492,7 +5492,7 @@ function listUsageSnapshots(fs12, snapshotsDir) {
|
|
|
5492
5492
|
if (!isIdentityName(identity)) {
|
|
5493
5493
|
return [];
|
|
5494
5494
|
}
|
|
5495
|
-
const snapshot = readUsageSnapshot(
|
|
5495
|
+
const snapshot = readUsageSnapshot(fs13, snapshotsDir, identity);
|
|
5496
5496
|
return snapshot === void 0 ? [] : [snapshot];
|
|
5497
5497
|
}).sort((left, right) => left.identity.localeCompare(right.identity));
|
|
5498
5498
|
}
|
|
@@ -5517,11 +5517,11 @@ var init_read = __esm({
|
|
|
5517
5517
|
|
|
5518
5518
|
// src/usage/store.ts
|
|
5519
5519
|
import path20 from "node:path";
|
|
5520
|
-
function pruneUsageLog(
|
|
5520
|
+
function pruneUsageLog(fs13, logDir, nowMs) {
|
|
5521
5521
|
const cutoff = nowMs - USAGE_RETENTION_MS;
|
|
5522
|
-
for (const segment of listLogSegments(
|
|
5522
|
+
for (const segment of listLogSegments(fs13, logDir)) {
|
|
5523
5523
|
if (segment.endsAt <= cutoff) {
|
|
5524
|
-
|
|
5524
|
+
fs13.removeRecursive(path20.join(logDir, segment.name));
|
|
5525
5525
|
}
|
|
5526
5526
|
}
|
|
5527
5527
|
}
|
|
@@ -5550,7 +5550,7 @@ function foldProviderState(current, record) {
|
|
|
5550
5550
|
};
|
|
5551
5551
|
}
|
|
5552
5552
|
function createUsageStore(deps) {
|
|
5553
|
-
const { fs:
|
|
5553
|
+
const { fs: fs13, paths } = deps;
|
|
5554
5554
|
let prunedDay;
|
|
5555
5555
|
const rewriteSnapshot = (identity, fold) => {
|
|
5556
5556
|
if (!isIdentityName(identity)) {
|
|
@@ -5559,7 +5559,7 @@ function createUsageStore(deps) {
|
|
|
5559
5559
|
}
|
|
5560
5560
|
let current;
|
|
5561
5561
|
try {
|
|
5562
|
-
current = readUsageSnapshot(
|
|
5562
|
+
current = readUsageSnapshot(fs13, paths.usageSnapshotsDir, identity);
|
|
5563
5563
|
} catch (error) {
|
|
5564
5564
|
if (!(error instanceof UsageSnapshotError)) {
|
|
5565
5565
|
throw error;
|
|
@@ -5586,8 +5586,8 @@ function createUsageStore(deps) {
|
|
|
5586
5586
|
...account === void 0 ? {} : { account },
|
|
5587
5587
|
providers
|
|
5588
5588
|
});
|
|
5589
|
-
|
|
5590
|
-
|
|
5589
|
+
fs13.mkdirPrivate(paths.usageSnapshotsDir);
|
|
5590
|
+
fs13.writeFilePrivate(snapshotPath(paths.usageSnapshotsDir, identity), `${JSON.stringify(snapshot, null, 2)}
|
|
5591
5591
|
`);
|
|
5592
5592
|
deps.publish?.(snapshot);
|
|
5593
5593
|
return true;
|
|
@@ -5596,14 +5596,14 @@ function createUsageStore(deps) {
|
|
|
5596
5596
|
record: (input) => {
|
|
5597
5597
|
const record = UsageRecordSchema.parse(input);
|
|
5598
5598
|
const nowMs = deps.now();
|
|
5599
|
-
|
|
5600
|
-
|
|
5599
|
+
fs13.mkdirPrivate(paths.usageDir);
|
|
5600
|
+
fs13.mkdirPrivate(paths.usageLogDir);
|
|
5601
5601
|
const day = segmentDay(nowMs);
|
|
5602
5602
|
if (prunedDay !== day) {
|
|
5603
|
-
pruneUsageLog(
|
|
5603
|
+
pruneUsageLog(fs13, paths.usageLogDir, nowMs);
|
|
5604
5604
|
prunedDay = day;
|
|
5605
5605
|
}
|
|
5606
|
-
|
|
5606
|
+
fs13.appendFilePrivate(path20.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
|
|
5607
5607
|
`);
|
|
5608
5608
|
if (record.identity !== void 0) {
|
|
5609
5609
|
rewriteSnapshot(record.identity, (current) => ({ ...current?.providers, [record.provider]: foldProviderState(current?.providers[record.provider], record) }));
|
|
@@ -5646,14 +5646,14 @@ import { z as z13 } from "zod";
|
|
|
5646
5646
|
function errorMessage(error) {
|
|
5647
5647
|
return error instanceof Error ? error.message : String(error);
|
|
5648
5648
|
}
|
|
5649
|
-
function loadPoolMembers(
|
|
5649
|
+
function loadPoolMembers(fs13, paths, identities, nowMs) {
|
|
5650
5650
|
const windowStartMs = nowMs - FIVE_HOUR_WINDOW_MS;
|
|
5651
|
-
const log = readUsageLog(
|
|
5651
|
+
const log = readUsageLog(fs13, paths.usageLogDir, { sinceMs: windowStartMs });
|
|
5652
5652
|
return identities.map((identity) => {
|
|
5653
5653
|
const records = log.records.filter((record) => record.identity === identity && record.provider === ANTHROPIC_PROVIDER && Date.parse(record.at) >= windowStartMs);
|
|
5654
5654
|
try {
|
|
5655
|
-
const snapshot = readUsageSnapshot(
|
|
5656
|
-
const account = readAccountMetadata(
|
|
5655
|
+
const snapshot = readUsageSnapshot(fs13, paths.usageSnapshotsDir, identity);
|
|
5656
|
+
const account = readAccountMetadata(fs13, paths.identitiesDir, identity) ?? snapshot?.account;
|
|
5657
5657
|
return { identity, records, ...snapshot === void 0 ? {} : { snapshot }, ...account === void 0 ? {} : { account } };
|
|
5658
5658
|
} catch (error) {
|
|
5659
5659
|
if (error instanceof UsageSnapshotError || error instanceof AccountMetadataError) {
|
|
@@ -5746,9 +5746,9 @@ function collectPoolIdentities(pools, poolName, stack, found) {
|
|
|
5746
5746
|
collectPoolIdentities(pools, nestedName, childStack, found);
|
|
5747
5747
|
}
|
|
5748
5748
|
}
|
|
5749
|
-
function readPicksFile(
|
|
5749
|
+
function readPicksFile(fs13, file) {
|
|
5750
5750
|
const empty = { schemaVersion: SCHEMA_VERSION, picks: {} };
|
|
5751
|
-
const raw =
|
|
5751
|
+
const raw = fs13.readFileUtf8(file);
|
|
5752
5752
|
if (raw === void 0) {
|
|
5753
5753
|
return { file: empty };
|
|
5754
5754
|
}
|
|
@@ -5761,17 +5761,17 @@ function readPicksFile(fs12, file) {
|
|
|
5761
5761
|
const result = PicksFileSchema.safeParse(parsed);
|
|
5762
5762
|
return result.success ? { file: result.data } : { file: empty, problem: `${file} is not a picks file this agent-shim can read` };
|
|
5763
5763
|
}
|
|
5764
|
-
function readStickyPick(
|
|
5765
|
-
const read = readPicksFile(
|
|
5764
|
+
function readStickyPick(fs13, picksFile, directory) {
|
|
5765
|
+
const read = readPicksFile(fs13, picksFile);
|
|
5766
5766
|
const entry = read.file.picks[directory];
|
|
5767
5767
|
return { ...entry === void 0 ? {} : { sticky: entry }, ...read.problem === void 0 ? {} : { problem: read.problem } };
|
|
5768
5768
|
}
|
|
5769
|
-
function recordStickyPick(
|
|
5770
|
-
const current = readPicksFile(
|
|
5769
|
+
function recordStickyPick(fs13, picksFile, directory, identity, nowMs) {
|
|
5770
|
+
const current = readPicksFile(fs13, picksFile).file.picks;
|
|
5771
5771
|
const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
|
|
5772
5772
|
const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
|
|
5773
|
-
|
|
5774
|
-
|
|
5773
|
+
fs13.mkdirPrivate(path21.dirname(picksFile));
|
|
5774
|
+
fs13.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
|
|
5775
5775
|
`);
|
|
5776
5776
|
}
|
|
5777
5777
|
var PoolGraphError, SCHEMA_VERSION, PickEntrySchema, PicksFileSchema;
|
|
@@ -6709,6 +6709,106 @@ var init_claudeShim = __esm({
|
|
|
6709
6709
|
}
|
|
6710
6710
|
});
|
|
6711
6711
|
|
|
6712
|
+
// src/frontdoor/probe.ts
|
|
6713
|
+
import { Worker } from "node:worker_threads";
|
|
6714
|
+
function probeFrontDoorSync(port, caPem) {
|
|
6715
|
+
refuseToBlockInRole("a synchronous probe of the front door");
|
|
6716
|
+
return runProbeWorker(PROBE_SOURCE, { port, ca: caPem });
|
|
6717
|
+
}
|
|
6718
|
+
function probeListenerAcceptSync(port) {
|
|
6719
|
+
refuseToBlockInRole("a synchronous probe of a front door listener");
|
|
6720
|
+
return runProbeWorker(ACCEPT_PROBE_SOURCE, { port });
|
|
6721
|
+
}
|
|
6722
|
+
function runProbeWorker(source, data) {
|
|
6723
|
+
const shared = new SharedArrayBuffer(HEADER_SLOTS * INT32_BYTES + REASON_BYTES);
|
|
6724
|
+
const header = new Int32Array(shared, 0, HEADER_SLOTS);
|
|
6725
|
+
const worker = new Worker(source, {
|
|
6726
|
+
eval: true,
|
|
6727
|
+
workerData: { ...data, timeoutMs: PROBE_TIMEOUT_MS, shared, ok: VERDICT_OK, failed: VERDICT_FAILED, headerSlots: HEADER_SLOTS }
|
|
6728
|
+
});
|
|
6729
|
+
worker.unref();
|
|
6730
|
+
try {
|
|
6731
|
+
const waited = Atomics.wait(header, 0, VERDICT_PENDING, PROBE_TIMEOUT_MS + PROBE_WAIT_MARGIN_MS);
|
|
6732
|
+
const verdict = Atomics.load(header, 0);
|
|
6733
|
+
if (waited === "timed-out" || verdict === VERDICT_PENDING) {
|
|
6734
|
+
return { ok: false, reason: `the probe did not finish within ${String(PROBE_TIMEOUT_MS + PROBE_WAIT_MARGIN_MS)}ms` };
|
|
6735
|
+
}
|
|
6736
|
+
if (verdict === VERDICT_OK) {
|
|
6737
|
+
return { ok: true };
|
|
6738
|
+
}
|
|
6739
|
+
const length = Atomics.load(header, 1);
|
|
6740
|
+
return { ok: false, reason: Buffer.from(new Uint8Array(shared, HEADER_SLOTS * INT32_BYTES, length)).toString("utf8") };
|
|
6741
|
+
} finally {
|
|
6742
|
+
void worker.terminate();
|
|
6743
|
+
}
|
|
6744
|
+
}
|
|
6745
|
+
var PROBE_TIMEOUT_MS, PROBE_WAIT_MARGIN_MS, REASON_BYTES, HEADER_SLOTS, INT32_BYTES, VERDICT_PENDING, VERDICT_OK, VERDICT_FAILED, PROBE_SOURCE, ACCEPT_PROBE_SOURCE;
|
|
6746
|
+
var init_probe = __esm({
|
|
6747
|
+
"src/frontdoor/probe.ts"() {
|
|
6748
|
+
"use strict";
|
|
6749
|
+
init_processRole();
|
|
6750
|
+
PROBE_TIMEOUT_MS = 2e3;
|
|
6751
|
+
PROBE_WAIT_MARGIN_MS = 1e3;
|
|
6752
|
+
REASON_BYTES = 1024;
|
|
6753
|
+
HEADER_SLOTS = 2;
|
|
6754
|
+
INT32_BYTES = 4;
|
|
6755
|
+
VERDICT_PENDING = 0;
|
|
6756
|
+
VERDICT_OK = 1;
|
|
6757
|
+
VERDICT_FAILED = 2;
|
|
6758
|
+
PROBE_SOURCE = `
|
|
6759
|
+
const { workerData } = require("node:worker_threads");
|
|
6760
|
+
const https = require("node:https");
|
|
6761
|
+
const { port, ca, timeoutMs, shared, ok, failed, headerSlots } = workerData;
|
|
6762
|
+
const header = new Int32Array(shared, 0, headerSlots);
|
|
6763
|
+
const reason = new Uint8Array(shared, headerSlots * 4);
|
|
6764
|
+
let done = false;
|
|
6765
|
+
const finish = (verdict, message) => {
|
|
6766
|
+
if (done) return;
|
|
6767
|
+
done = true;
|
|
6768
|
+
const bytes = Buffer.from(String(message), "utf8").subarray(0, reason.length);
|
|
6769
|
+
reason.set(bytes);
|
|
6770
|
+
Atomics.store(header, 1, bytes.length);
|
|
6771
|
+
Atomics.store(header, 0, verdict);
|
|
6772
|
+
Atomics.notify(header, 0);
|
|
6773
|
+
};
|
|
6774
|
+
const request = https.get({ host: "127.0.0.1", port, path: "/healthz", ca: [ca], agent: false }, (response) => {
|
|
6775
|
+
let body = "";
|
|
6776
|
+
response.setEncoding("utf8");
|
|
6777
|
+
response.on("data", (chunk) => { body += chunk; });
|
|
6778
|
+
response.on("end", () => {
|
|
6779
|
+
if (response.statusCode === 200 && body === "ok") finish(ok, "");
|
|
6780
|
+
else finish(failed, "the listener answered its health probe with HTTP " + String(response.statusCode));
|
|
6781
|
+
});
|
|
6782
|
+
response.on("error", (error) => finish(failed, error.message));
|
|
6783
|
+
});
|
|
6784
|
+
// A hard deadline over the whole exchange, handshake included: a listener that accepts the connection and then says nothing must still fail the probe.
|
|
6785
|
+
setTimeout(() => { request.destroy(new Error("no answer within " + String(timeoutMs) + "ms")); }, timeoutMs);
|
|
6786
|
+
request.on("error", (error) => finish(failed, (error.code ? error.code + ": " : "") + error.message));
|
|
6787
|
+
`;
|
|
6788
|
+
ACCEPT_PROBE_SOURCE = `
|
|
6789
|
+
const { workerData } = require("node:worker_threads");
|
|
6790
|
+
const net = require("node:net");
|
|
6791
|
+
const { port, timeoutMs, shared, ok, failed, headerSlots } = workerData;
|
|
6792
|
+
const header = new Int32Array(shared, 0, headerSlots);
|
|
6793
|
+
const reason = new Uint8Array(shared, headerSlots * 4);
|
|
6794
|
+
let done = false;
|
|
6795
|
+
const finish = (verdict, message) => {
|
|
6796
|
+
if (done) return;
|
|
6797
|
+
done = true;
|
|
6798
|
+
const bytes = Buffer.from(String(message), "utf8").subarray(0, reason.length);
|
|
6799
|
+
reason.set(bytes);
|
|
6800
|
+
Atomics.store(header, 1, bytes.length);
|
|
6801
|
+
Atomics.store(header, 0, verdict);
|
|
6802
|
+
Atomics.notify(header, 0);
|
|
6803
|
+
};
|
|
6804
|
+
const socket = net.connect({ host: "127.0.0.1", port });
|
|
6805
|
+
socket.once("connect", () => { socket.destroy(); finish(ok, ""); });
|
|
6806
|
+
socket.once("error", (error) => finish(failed, (error.code ? error.code + ": " : "") + error.message));
|
|
6807
|
+
setTimeout(() => { socket.destroy(); finish(failed, "no connection accepted within " + String(timeoutMs) + "ms"); }, timeoutMs);
|
|
6808
|
+
`;
|
|
6809
|
+
}
|
|
6810
|
+
});
|
|
6811
|
+
|
|
6712
6812
|
// src/update/update.ts
|
|
6713
6813
|
function compareVersions3(left, right) {
|
|
6714
6814
|
const parse = (version) => {
|
|
@@ -7461,7 +7561,7 @@ function contextTokensOfTranscript(text) {
|
|
|
7461
7561
|
}
|
|
7462
7562
|
return void 0;
|
|
7463
7563
|
}
|
|
7464
|
-
function resumedContextTokens(
|
|
7564
|
+
function resumedContextTokens(fs13, params) {
|
|
7465
7565
|
const target = resumeTargetOf(params.passthrough);
|
|
7466
7566
|
if (target === void 0) {
|
|
7467
7567
|
return void 0;
|
|
@@ -7472,19 +7572,19 @@ function resumedContextTokens(fs12, params) {
|
|
|
7472
7572
|
file = path37.join(projectDir, `${target.id}.jsonl`);
|
|
7473
7573
|
} else {
|
|
7474
7574
|
let newestMs = -Infinity;
|
|
7475
|
-
for (const name of
|
|
7575
|
+
for (const name of fs13.readdir(projectDir)) {
|
|
7476
7576
|
if (!name.endsWith(".jsonl")) {
|
|
7477
7577
|
continue;
|
|
7478
7578
|
}
|
|
7479
7579
|
const candidate = path37.join(projectDir, name);
|
|
7480
|
-
const stat =
|
|
7580
|
+
const stat = fs13.lstat(candidate);
|
|
7481
7581
|
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
7482
7582
|
newestMs = stat.mtimeMs;
|
|
7483
7583
|
file = candidate;
|
|
7484
7584
|
}
|
|
7485
7585
|
}
|
|
7486
7586
|
}
|
|
7487
|
-
const text = file === void 0 ? void 0 :
|
|
7587
|
+
const text = file === void 0 ? void 0 : fs13.readFileUtf8(file);
|
|
7488
7588
|
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
7489
7589
|
}
|
|
7490
7590
|
var init_resumeContext = __esm({
|
|
@@ -7602,7 +7702,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
|
|
|
7602
7702
|
return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
7603
7703
|
}
|
|
7604
7704
|
function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
7605
|
-
const { paths, fs:
|
|
7705
|
+
const { paths, fs: fs13, proc, log } = params;
|
|
7606
7706
|
if (decided.pool === void 0) {
|
|
7607
7707
|
return { identityDecision: decided };
|
|
7608
7708
|
}
|
|
@@ -7617,7 +7717,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
7617
7717
|
selectedVia: decided.source,
|
|
7618
7718
|
pools: params.pools,
|
|
7619
7719
|
paths,
|
|
7620
|
-
fs:
|
|
7720
|
+
fs: fs13,
|
|
7621
7721
|
usageFs: farmRuntime.fs,
|
|
7622
7722
|
cwd: farmRuntime.cwd,
|
|
7623
7723
|
now: farmRuntime.now,
|
|
@@ -7640,7 +7740,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
7640
7740
|
};
|
|
7641
7741
|
}
|
|
7642
7742
|
function decideLaunch(params, readOnly) {
|
|
7643
|
-
const { paths, fs:
|
|
7743
|
+
const { paths, fs: fs13, proc, log } = params;
|
|
7644
7744
|
const { env, argv } = proc;
|
|
7645
7745
|
const parsedArgv = parseLauncherArgv(argv);
|
|
7646
7746
|
const cliOverride = buildCliOverride({
|
|
@@ -7655,7 +7755,7 @@ function decideLaunch(params, readOnly) {
|
|
|
7655
7755
|
argv0Identity: parsedArgv.identity,
|
|
7656
7756
|
directoryPinnedIdentity: params.directoryPinnedIdentity,
|
|
7657
7757
|
readActiveIdentityFile: () => {
|
|
7658
|
-
const raw =
|
|
7758
|
+
const raw = fs13.readFileUtf8(paths.activeIdentityFile);
|
|
7659
7759
|
if (raw === void 0) {
|
|
7660
7760
|
return void 0;
|
|
7661
7761
|
}
|
|
@@ -7690,7 +7790,7 @@ function decideLaunch(params, readOnly) {
|
|
|
7690
7790
|
}
|
|
7691
7791
|
let loadedIdentity;
|
|
7692
7792
|
if (identityDecision.name !== void 0) {
|
|
7693
|
-
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name,
|
|
7793
|
+
loadedIdentity = loadIdentity(paths.identitiesDir, identityDecision.name, fs13);
|
|
7694
7794
|
if (loadedIdentity === void 0) {
|
|
7695
7795
|
log.error(
|
|
7696
7796
|
`agent-shim: no identity named "${identityDecision.name}" (selected via ${identityDecision.source}). Run \`agent-shim identity add ${identityDecision.name}\` first.`
|
|
@@ -7705,7 +7805,7 @@ function decideLaunch(params, readOnly) {
|
|
|
7705
7805
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
7706
7806
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
7707
7807
|
});
|
|
7708
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true &&
|
|
7808
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs13.readConfigFile(path38.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
7709
7809
|
log.error(
|
|
7710
7810
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
7711
7811
|
);
|
|
@@ -7714,7 +7814,7 @@ function decideLaunch(params, readOnly) {
|
|
|
7714
7814
|
const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
|
|
7715
7815
|
const providerParams = {
|
|
7716
7816
|
paths,
|
|
7717
|
-
port:
|
|
7817
|
+
port: fs13,
|
|
7718
7818
|
...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
|
|
7719
7819
|
...farmContext === void 0 ? {} : { cascade: farmContext.cascade }
|
|
7720
7820
|
};
|
|
@@ -8039,78 +8139,6 @@ var init_ownCli = __esm({
|
|
|
8039
8139
|
}
|
|
8040
8140
|
});
|
|
8041
8141
|
|
|
8042
|
-
// src/frontdoor/probe.ts
|
|
8043
|
-
import { Worker } from "node:worker_threads";
|
|
8044
|
-
function probeFrontDoorSync(port, caPem) {
|
|
8045
|
-
refuseToBlockInRole("a synchronous probe of the front door");
|
|
8046
|
-
const shared = new SharedArrayBuffer(HEADER_SLOTS * INT32_BYTES + REASON_BYTES);
|
|
8047
|
-
const header = new Int32Array(shared, 0, HEADER_SLOTS);
|
|
8048
|
-
const worker = new Worker(PROBE_SOURCE, {
|
|
8049
|
-
eval: true,
|
|
8050
|
-
workerData: { port, ca: caPem, timeoutMs: PROBE_TIMEOUT_MS, shared, ok: VERDICT_OK, failed: VERDICT_FAILED, headerSlots: HEADER_SLOTS }
|
|
8051
|
-
});
|
|
8052
|
-
worker.unref();
|
|
8053
|
-
try {
|
|
8054
|
-
const waited = Atomics.wait(header, 0, VERDICT_PENDING, PROBE_TIMEOUT_MS + PROBE_WAIT_MARGIN_MS);
|
|
8055
|
-
const verdict = Atomics.load(header, 0);
|
|
8056
|
-
if (waited === "timed-out" || verdict === VERDICT_PENDING) {
|
|
8057
|
-
return { ok: false, reason: `the probe did not finish within ${String(PROBE_TIMEOUT_MS + PROBE_WAIT_MARGIN_MS)}ms` };
|
|
8058
|
-
}
|
|
8059
|
-
if (verdict === VERDICT_OK) {
|
|
8060
|
-
return { ok: true };
|
|
8061
|
-
}
|
|
8062
|
-
const length = Atomics.load(header, 1);
|
|
8063
|
-
return { ok: false, reason: Buffer.from(new Uint8Array(shared, HEADER_SLOTS * INT32_BYTES, length)).toString("utf8") };
|
|
8064
|
-
} finally {
|
|
8065
|
-
void worker.terminate();
|
|
8066
|
-
}
|
|
8067
|
-
}
|
|
8068
|
-
var PROBE_TIMEOUT_MS, PROBE_WAIT_MARGIN_MS, REASON_BYTES, HEADER_SLOTS, INT32_BYTES, VERDICT_PENDING, VERDICT_OK, VERDICT_FAILED, PROBE_SOURCE;
|
|
8069
|
-
var init_probe = __esm({
|
|
8070
|
-
"src/frontdoor/probe.ts"() {
|
|
8071
|
-
"use strict";
|
|
8072
|
-
init_processRole();
|
|
8073
|
-
PROBE_TIMEOUT_MS = 2e3;
|
|
8074
|
-
PROBE_WAIT_MARGIN_MS = 1e3;
|
|
8075
|
-
REASON_BYTES = 1024;
|
|
8076
|
-
HEADER_SLOTS = 2;
|
|
8077
|
-
INT32_BYTES = 4;
|
|
8078
|
-
VERDICT_PENDING = 0;
|
|
8079
|
-
VERDICT_OK = 1;
|
|
8080
|
-
VERDICT_FAILED = 2;
|
|
8081
|
-
PROBE_SOURCE = `
|
|
8082
|
-
const { workerData } = require("node:worker_threads");
|
|
8083
|
-
const https = require("node:https");
|
|
8084
|
-
const { port, ca, timeoutMs, shared, ok, failed, headerSlots } = workerData;
|
|
8085
|
-
const header = new Int32Array(shared, 0, headerSlots);
|
|
8086
|
-
const reason = new Uint8Array(shared, headerSlots * 4);
|
|
8087
|
-
let done = false;
|
|
8088
|
-
const finish = (verdict, message) => {
|
|
8089
|
-
if (done) return;
|
|
8090
|
-
done = true;
|
|
8091
|
-
const bytes = Buffer.from(String(message), "utf8").subarray(0, reason.length);
|
|
8092
|
-
reason.set(bytes);
|
|
8093
|
-
Atomics.store(header, 1, bytes.length);
|
|
8094
|
-
Atomics.store(header, 0, verdict);
|
|
8095
|
-
Atomics.notify(header, 0);
|
|
8096
|
-
};
|
|
8097
|
-
const request = https.get({ host: "127.0.0.1", port, path: "/healthz", ca: [ca], agent: false }, (response) => {
|
|
8098
|
-
let body = "";
|
|
8099
|
-
response.setEncoding("utf8");
|
|
8100
|
-
response.on("data", (chunk) => { body += chunk; });
|
|
8101
|
-
response.on("end", () => {
|
|
8102
|
-
if (response.statusCode === 200 && body === "ok") finish(ok, "");
|
|
8103
|
-
else finish(failed, "the listener answered its health probe with HTTP " + String(response.statusCode));
|
|
8104
|
-
});
|
|
8105
|
-
response.on("error", (error) => finish(failed, error.message));
|
|
8106
|
-
});
|
|
8107
|
-
// A hard deadline over the whole exchange, handshake included: a listener that accepts the connection and then says nothing must still fail the probe.
|
|
8108
|
-
setTimeout(() => { request.destroy(new Error("no answer within " + String(timeoutMs) + "ms")); }, timeoutMs);
|
|
8109
|
-
request.on("error", (error) => finish(failed, (error.code ? error.code + ": " : "") + error.message));
|
|
8110
|
-
`;
|
|
8111
|
-
}
|
|
8112
|
-
});
|
|
8113
|
-
|
|
8114
8142
|
// src/frontdoor/selfIdentity.ts
|
|
8115
8143
|
function isFrontDoorSupervisorPid(pid, identify) {
|
|
8116
8144
|
return declaredPid !== void 0 && pid === declaredPid && pid === process.pid || identify(pid);
|
|
@@ -8126,14 +8154,14 @@ var init_selfIdentity = __esm({
|
|
|
8126
8154
|
import { createHash as createHash6 } from "node:crypto";
|
|
8127
8155
|
import path40 from "node:path";
|
|
8128
8156
|
function resolveTrustBundle(params) {
|
|
8129
|
-
const { caCertFile, bundlesDir, variable, inherited, fs:
|
|
8157
|
+
const { caCertFile, bundlesDir, variable, inherited, fs: fs13 } = params;
|
|
8130
8158
|
if (inherited === void 0 || inherited === "" || path40.resolve(inherited) === path40.resolve(caCertFile)) {
|
|
8131
8159
|
return { path: caCertFile };
|
|
8132
8160
|
}
|
|
8133
|
-
const caPem =
|
|
8161
|
+
const caPem = fs13.readFileUtf8(caCertFile);
|
|
8134
8162
|
let inheritedPem;
|
|
8135
8163
|
try {
|
|
8136
|
-
inheritedPem =
|
|
8164
|
+
inheritedPem = fs13.readFileUtf8(inherited);
|
|
8137
8165
|
} catch (error) {
|
|
8138
8166
|
return {
|
|
8139
8167
|
path: caCertFile,
|
|
@@ -8146,9 +8174,9 @@ function resolveTrustBundle(params) {
|
|
|
8146
8174
|
const combined = `${inheritedPem.trimEnd()}
|
|
8147
8175
|
${caPem}`;
|
|
8148
8176
|
const bundle = path40.join(bundlesDir, `${createHash6("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
8149
|
-
if (!
|
|
8150
|
-
|
|
8151
|
-
|
|
8177
|
+
if (!fs13.exists(bundle)) {
|
|
8178
|
+
fs13.mkdirp(bundlesDir);
|
|
8179
|
+
fs13.writeFileAtomic(bundle, combined);
|
|
8152
8180
|
}
|
|
8153
8181
|
return { path: bundle };
|
|
8154
8182
|
}
|
|
@@ -8161,7 +8189,7 @@ var init_trust = __esm({
|
|
|
8161
8189
|
});
|
|
8162
8190
|
|
|
8163
8191
|
// src/frontdoor/realFrontDoorPort.ts
|
|
8164
|
-
import
|
|
8192
|
+
import fs12 from "node:fs";
|
|
8165
8193
|
function realEnsurePorts(paths, spawnDaemon) {
|
|
8166
8194
|
return {
|
|
8167
8195
|
fs: realFarmFs,
|
|
@@ -8177,7 +8205,7 @@ function realEnsurePorts(paths, spawnDaemon) {
|
|
|
8177
8205
|
process.kill(pid, "SIGKILL");
|
|
8178
8206
|
},
|
|
8179
8207
|
// 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.
|
|
8180
|
-
verifyListener: (port) => probeFrontDoorSync(port,
|
|
8208
|
+
verifyListener: (port) => probeFrontDoorSync(port, fs12.readFileSync(paths.frontdoorCaCertFile, "utf8"))
|
|
8181
8209
|
};
|
|
8182
8210
|
}
|
|
8183
8211
|
function realFrontDoorPort(paths, spawnDaemon) {
|
|
@@ -8209,10 +8237,10 @@ var init_realFrontDoorPort = __esm({
|
|
|
8209
8237
|
init_selfIdentity();
|
|
8210
8238
|
init_trust();
|
|
8211
8239
|
realTrustBundleFs = {
|
|
8212
|
-
readFileUtf8: (file) =>
|
|
8213
|
-
exists: (file) =>
|
|
8240
|
+
readFileUtf8: (file) => fs12.readFileSync(file, "utf8"),
|
|
8241
|
+
exists: (file) => fs12.existsSync(file),
|
|
8214
8242
|
mkdirp: (dir) => {
|
|
8215
|
-
|
|
8243
|
+
fs12.mkdirSync(dir, { recursive: true });
|
|
8216
8244
|
},
|
|
8217
8245
|
writeFileAtomic: (file, contents) => {
|
|
8218
8246
|
realFarmFs.writeFilePrivate(file, contents);
|
|
@@ -9036,9 +9064,9 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
9036
9064
|
}
|
|
9037
9065
|
}
|
|
9038
9066
|
async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
9039
|
-
const { fs:
|
|
9067
|
+
const { fs: fs13, paths } = ports;
|
|
9040
9068
|
const servingBinary = ports.statOwnExecutable();
|
|
9041
|
-
const previous = readFrontDoorState(
|
|
9069
|
+
const previous = readFrontDoorState(fs13, paths.frontdoorStateFile);
|
|
9042
9070
|
let lastPort = previous?.lastPort;
|
|
9043
9071
|
let lastConnectPort = previous?.lastConnectPort;
|
|
9044
9072
|
let lastDirectPort = previous?.lastDirectPort;
|
|
@@ -9049,12 +9077,12 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
9049
9077
|
});
|
|
9050
9078
|
const fail = (message) => {
|
|
9051
9079
|
ports.closeRcStreamHub();
|
|
9052
|
-
writeFrontDoorState(
|
|
9053
|
-
|
|
9080
|
+
writeFrontDoorState(fs13, paths.frontdoorStateFile, { lastError: message, ...sticky() });
|
|
9081
|
+
fs13.removeRecursive(paths.frontdoorLockFile);
|
|
9054
9082
|
ports.log(`agent-shim frontdoor supervisor: ${message}`);
|
|
9055
9083
|
return 1;
|
|
9056
9084
|
};
|
|
9057
|
-
writeFrontDoorState(
|
|
9085
|
+
writeFrontDoorState(fs13, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
|
|
9058
9086
|
const previousSticky = lastPort;
|
|
9059
9087
|
let http3;
|
|
9060
9088
|
try {
|
|
@@ -9094,15 +9122,16 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
9094
9122
|
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)`);
|
|
9095
9123
|
}
|
|
9096
9124
|
lastDirectPort = direct.port;
|
|
9097
|
-
writeFrontDoorDirectRecord(
|
|
9098
|
-
writeFrontDoorState(
|
|
9125
|
+
writeFrontDoorDirectRecord(fs13, paths.frontdoorDirectRecordsDir, { pid: ports.ownPid, directPort: direct.port });
|
|
9126
|
+
writeFrontDoorState(fs13, paths.frontdoorStateFile, { protocol: FRONT_DOOR_PROTOCOL, supervisorPid: ports.ownPid, port: http3.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
9099
9127
|
ports.doorHealth.generation({ providerPort: http3.port, connectPort: connect3.port, directPort: direct.port });
|
|
9100
|
-
|
|
9128
|
+
fs13.removeRecursive(paths.frontdoorLockFile);
|
|
9101
9129
|
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)}`);
|
|
9130
|
+
const watchdog = ports.startWatchdog?.();
|
|
9102
9131
|
let idleSince;
|
|
9103
9132
|
let ticks = 0;
|
|
9104
9133
|
const supersedingOwner = () => {
|
|
9105
|
-
const owner = readFrontDoorState(
|
|
9134
|
+
const owner = readFrontDoorState(fs13, paths.frontdoorStateFile)?.supervisorPid;
|
|
9106
9135
|
return owner !== void 0 && owner !== ports.ownPid && ports.isRunning(owner) ? owner : void 0;
|
|
9107
9136
|
};
|
|
9108
9137
|
let supersededBy;
|
|
@@ -9112,26 +9141,29 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
9112
9141
|
return current !== void 0 && servingBinary !== void 0 && (current.dev !== servingBinary.dev || current.ino !== servingBinary.ino || current.size !== servingBinary.size || current.mtimeMs !== servingBinary.mtimeMs);
|
|
9113
9142
|
};
|
|
9114
9143
|
const closeServing = async () => {
|
|
9144
|
+
watchdog?.stop();
|
|
9115
9145
|
await direct.close();
|
|
9116
9146
|
await connect3.close();
|
|
9117
9147
|
await http3.close();
|
|
9118
9148
|
ports.closeRcStreamHub();
|
|
9119
|
-
removeFrontDoorDirectRecord(
|
|
9149
|
+
removeFrontDoorDirectRecord(fs13, paths.frontdoorDirectRecordsDir, ports.ownPid);
|
|
9120
9150
|
};
|
|
9121
9151
|
const shutdown = async () => {
|
|
9122
9152
|
await closeServing();
|
|
9123
9153
|
if (supersedingOwner() === void 0) {
|
|
9124
|
-
writeFrontDoorState(
|
|
9154
|
+
writeFrontDoorState(fs13, paths.frontdoorStateFile, sticky());
|
|
9125
9155
|
}
|
|
9126
9156
|
return 0;
|
|
9127
9157
|
};
|
|
9128
9158
|
for (; ; ) {
|
|
9159
|
+
watchdog?.beat();
|
|
9129
9160
|
if (options.tickLimit !== void 0 && ticks >= options.tickLimit) {
|
|
9161
|
+
watchdog?.stop();
|
|
9130
9162
|
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
9131
9163
|
}
|
|
9132
9164
|
ticks += 1;
|
|
9133
|
-
const listed = listFrontDoorSessions(
|
|
9134
|
-
const pruned = pruneDeadFrontDoorSessions(
|
|
9165
|
+
const listed = listFrontDoorSessions(fs13, paths.frontdoorSessionsDir);
|
|
9166
|
+
const pruned = pruneDeadFrontDoorSessions(fs13, paths.frontdoorSessionsDir, ports.isRunning);
|
|
9135
9167
|
ports.observeLaunchRegistry(listed, pruned);
|
|
9136
9168
|
ports.checkQuotaExpiry();
|
|
9137
9169
|
const prunedPids = new Set(pruned);
|
|
@@ -11627,11 +11659,11 @@ function credentialOfJson(parsed) {
|
|
|
11627
11659
|
function sequenceNumOfJson(value) {
|
|
11628
11660
|
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? value : void 0;
|
|
11629
11661
|
}
|
|
11630
|
-
function createRcCredentialStore(
|
|
11631
|
-
|
|
11662
|
+
function createRcCredentialStore(fs13, dir) {
|
|
11663
|
+
fs13.mkdirPrivate(dir);
|
|
11632
11664
|
const fileFor = (sessionId) => path10.join(dir, `${sessionId}.json`);
|
|
11633
11665
|
const readParsed = (sessionId) => {
|
|
11634
|
-
const raw =
|
|
11666
|
+
const raw = fs13.readFileUtf8(fileFor(sessionId));
|
|
11635
11667
|
if (raw === void 0) {
|
|
11636
11668
|
return void 0;
|
|
11637
11669
|
}
|
|
@@ -11656,7 +11688,7 @@ function createRcCredentialStore(fs12, dir) {
|
|
|
11656
11688
|
}
|
|
11657
11689
|
const cursor = sequenceNumOfJson(readParsed(sessionId)?.highestSequenceNum);
|
|
11658
11690
|
const record = { ...credential, ...cursor === void 0 ? {} : { highestSequenceNum: cursor } };
|
|
11659
|
-
|
|
11691
|
+
fs13.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
|
|
11660
11692
|
`);
|
|
11661
11693
|
},
|
|
11662
11694
|
readCursor: (sessionId) => {
|
|
@@ -11671,14 +11703,14 @@ function createRcCredentialStore(fs12, dir) {
|
|
|
11671
11703
|
}
|
|
11672
11704
|
const credential = credentialOfJson(readParsed(sessionId));
|
|
11673
11705
|
const record = credential === void 0 ? { highestSequenceNum } : { ...credential, highestSequenceNum };
|
|
11674
|
-
|
|
11706
|
+
fs13.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(record, null, 2)}
|
|
11675
11707
|
`);
|
|
11676
11708
|
},
|
|
11677
11709
|
remove: (sessionId) => {
|
|
11678
11710
|
if (!isSafeSessionId(sessionId)) {
|
|
11679
11711
|
return;
|
|
11680
11712
|
}
|
|
11681
|
-
|
|
11713
|
+
fs13.removeRecursive(fileFor(sessionId));
|
|
11682
11714
|
}
|
|
11683
11715
|
};
|
|
11684
11716
|
}
|
|
@@ -13474,7 +13506,7 @@ function removeIdentity(paths, name) {
|
|
|
13474
13506
|
|
|
13475
13507
|
// src/doctorReport.ts
|
|
13476
13508
|
init_realPorts();
|
|
13477
|
-
import
|
|
13509
|
+
import fs11 from "node:fs";
|
|
13478
13510
|
import path30 from "node:path";
|
|
13479
13511
|
|
|
13480
13512
|
// src/usage/signIn.ts
|
|
@@ -13697,6 +13729,53 @@ function pushFrontDoor(push, supervisors, registeredPid, liveSessions) {
|
|
|
13697
13729
|
);
|
|
13698
13730
|
}
|
|
13699
13731
|
}
|
|
13732
|
+
var LISTENER_ROUTES = {
|
|
13733
|
+
provider: "provider sessions (`z`, `m` and the like)",
|
|
13734
|
+
connect: "every plain OAuth session, which reaches Anthropic through it"
|
|
13735
|
+
};
|
|
13736
|
+
function pushFrontDoorListeners(push, readings) {
|
|
13737
|
+
for (const reading of readings) {
|
|
13738
|
+
const where = `127.0.0.1:${String(reading.port)}`;
|
|
13739
|
+
if (reading.ok) {
|
|
13740
|
+
push("frontdoor", "pass", `The front door's ${reading.listener} listener on ${where} accepted a probe in ${String(Math.round(reading.elapsedMs))} ms.`, reading.listener);
|
|
13741
|
+
continue;
|
|
13742
|
+
}
|
|
13743
|
+
push(
|
|
13744
|
+
"frontdoor",
|
|
13745
|
+
"fail",
|
|
13746
|
+
`The front door's ${reading.listener} listener on ${where} did not accept a probe${reading.reason === void 0 ? "" : ` (${reading.reason})`}, so ${LISTENER_ROUTES[reading.listener]} cannot get through while it stays like this. The supervisor is alive but is not serving: \`agent-shim frontdoor restart\` replaces it.`,
|
|
13747
|
+
reading.listener
|
|
13748
|
+
);
|
|
13749
|
+
}
|
|
13750
|
+
}
|
|
13751
|
+
|
|
13752
|
+
// src/frontdoor/listenerReadings.ts
|
|
13753
|
+
init_probe();
|
|
13754
|
+
import fs10 from "node:fs";
|
|
13755
|
+
function readFrontDoorListeners(state, supervisorAlive, probes) {
|
|
13756
|
+
if (!supervisorAlive) {
|
|
13757
|
+
return [];
|
|
13758
|
+
}
|
|
13759
|
+
const readings = [];
|
|
13760
|
+
const take = (listener, port, probe) => {
|
|
13761
|
+
if (port === void 0) {
|
|
13762
|
+
return;
|
|
13763
|
+
}
|
|
13764
|
+
const started = probes.now();
|
|
13765
|
+
const verdict = probe(port);
|
|
13766
|
+
readings.push({ listener, port, ok: verdict.ok, ...verdict.ok ? {} : { reason: verdict.reason }, elapsedMs: Math.max(0, probes.now() - started) });
|
|
13767
|
+
};
|
|
13768
|
+
take("provider", state.port, probes.authenticateProvider);
|
|
13769
|
+
take("connect", state.connectPort, probes.connect);
|
|
13770
|
+
return readings;
|
|
13771
|
+
}
|
|
13772
|
+
function realFrontDoorListenerProbes(paths) {
|
|
13773
|
+
return {
|
|
13774
|
+
authenticateProvider: (port) => probeFrontDoorSync(port, fs10.readFileSync(paths.frontdoorCaCertFile, "utf8")),
|
|
13775
|
+
connect: probeListenerAcceptSync,
|
|
13776
|
+
now: () => performance.now()
|
|
13777
|
+
};
|
|
13778
|
+
}
|
|
13700
13779
|
|
|
13701
13780
|
// src/doctorReport.ts
|
|
13702
13781
|
init_supervisorProcesses();
|
|
@@ -14141,6 +14220,9 @@ function runDoctor(params) {
|
|
|
14141
14220
|
if (params.frontDoor !== void 0) {
|
|
14142
14221
|
const validated3 = params.frontDoor.state.raw === void 0 ? void 0 : validateJson(FrontDoorStateSchema, params.frontDoor.state);
|
|
14143
14222
|
pushFrontDoor(push, params.frontDoor.supervisors, validated3?.ok === true ? validated3.data.supervisorPid : void 0, params.frontDoor.liveSessions);
|
|
14223
|
+
if (params.frontDoor.listeners !== void 0) {
|
|
14224
|
+
pushFrontDoorListeners(push, params.frontDoor.listeners);
|
|
14225
|
+
}
|
|
14144
14226
|
}
|
|
14145
14227
|
if (params.activeIdentity.raw === void 0) {
|
|
14146
14228
|
push("active-identity", "pass", "No active identity set.");
|
|
@@ -14224,25 +14306,30 @@ function formatDoctorReport(report) {
|
|
|
14224
14306
|
}
|
|
14225
14307
|
function realpathOrSelf(target) {
|
|
14226
14308
|
try {
|
|
14227
|
-
return
|
|
14309
|
+
return fs11.realpathSync(target);
|
|
14228
14310
|
} catch {
|
|
14229
14311
|
return target;
|
|
14230
14312
|
}
|
|
14231
14313
|
}
|
|
14314
|
+
function servingDoorListeners(paths) {
|
|
14315
|
+
const state = readFrontDoorState(realFarmFs, paths.frontdoorStateFile) ?? {};
|
|
14316
|
+
const alive = state.supervisorPid !== void 0 && realIsProcessRunning(state.supervisorPid);
|
|
14317
|
+
return readFrontDoorListeners(state, alive, realFrontDoorListenerProbes(paths));
|
|
14318
|
+
}
|
|
14232
14319
|
function collectDoctorReport(params) {
|
|
14233
14320
|
const { paths } = params;
|
|
14234
|
-
const identityNames =
|
|
14321
|
+
const identityNames = fs11.existsSync(paths.identitiesDir) ? fs11.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort() : [];
|
|
14235
14322
|
const identities = identityNames.map((name) => {
|
|
14236
14323
|
const farmRoot = path30.join(paths.identitiesDir, name);
|
|
14237
14324
|
const identityPath = path30.join(farmRoot, "identity.json");
|
|
14238
|
-
return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent:
|
|
14325
|
+
return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: fs11.existsSync(credentialsFilePath(farmRoot)) };
|
|
14239
14326
|
});
|
|
14240
|
-
const profileNames =
|
|
14327
|
+
const profileNames = fs11.existsSync(paths.configProfilesDir) ? fs11.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
14241
14328
|
const configProfiles = profileNames.map((name) => {
|
|
14242
14329
|
const profilePath = path30.join(paths.configProfilesDir, `${name}.json`);
|
|
14243
14330
|
return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
|
|
14244
14331
|
});
|
|
14245
|
-
const providerNames =
|
|
14332
|
+
const providerNames = fs11.existsSync(paths.providersDir) ? fs11.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
14246
14333
|
const providers = providerNames.map((name) => {
|
|
14247
14334
|
const providerPath = path30.join(paths.providersDir, `${name}.json`);
|
|
14248
14335
|
return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
|
|
@@ -14287,7 +14374,7 @@ function collectDoctorReport(params) {
|
|
|
14287
14374
|
categoriesLocal: { path: paths.categoriesLocalFile, raw: realFsPort.readFileUtf8(paths.categoriesLocalFile) },
|
|
14288
14375
|
activeIdentity: { path: paths.activeIdentityFile, raw: realFsPort.readFileUtf8(paths.activeIdentityFile) },
|
|
14289
14376
|
binaryDiscovery,
|
|
14290
|
-
claudeShim: { state: shimState, targetExists: shimState !== void 0 &&
|
|
14377
|
+
claudeShim: { state: shimState, targetExists: shimState !== void 0 && fs11.existsSync(shimState.targetPath) },
|
|
14291
14378
|
rootPath: paths.root,
|
|
14292
14379
|
pathResolution: {
|
|
14293
14380
|
ownExecutablePath,
|
|
@@ -14327,7 +14414,7 @@ function collectDoctorReport(params) {
|
|
|
14327
14414
|
logPath: paths.headroomLogPath
|
|
14328
14415
|
}
|
|
14329
14416
|
},
|
|
14330
|
-
...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)) } }
|
|
14417
|
+
...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) } }
|
|
14331
14418
|
});
|
|
14332
14419
|
return report;
|
|
14333
14420
|
}
|
|
@@ -17318,8 +17405,8 @@ var SELF_HOST_SUBSCRIPTION_TYPE = "max";
|
|
|
17318
17405
|
function isRecord12(value) {
|
|
17319
17406
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17320
17407
|
}
|
|
17321
|
-
function readJsonObject(
|
|
17322
|
-
const raw =
|
|
17408
|
+
function readJsonObject(fs13, file) {
|
|
17409
|
+
const raw = fs13.readFileUtf8(file);
|
|
17323
17410
|
if (raw === void 0) {
|
|
17324
17411
|
return void 0;
|
|
17325
17412
|
}
|
|
@@ -17331,8 +17418,8 @@ function readJsonObject(fs12, file) {
|
|
|
17331
17418
|
}
|
|
17332
17419
|
return isRecord12(parsed) ? parsed : void 0;
|
|
17333
17420
|
}
|
|
17334
|
-
function readRcSelfHostRecord(
|
|
17335
|
-
const parsed = readJsonObject(
|
|
17421
|
+
function readRcSelfHostRecord(fs13, frontdoorDir) {
|
|
17422
|
+
const parsed = readJsonObject(fs13, path33.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
17336
17423
|
if (parsed === void 0) {
|
|
17337
17424
|
return void 0;
|
|
17338
17425
|
}
|
|
@@ -17432,17 +17519,17 @@ function parseEntry2(project, entry) {
|
|
|
17432
17519
|
const base = match?.[1];
|
|
17433
17520
|
return base === void 0 ? { project, sessionId: entry, superseded: false, entry } : { project, sessionId: base, superseded: true, entry };
|
|
17434
17521
|
}
|
|
17435
|
-
function listSessions2(
|
|
17522
|
+
function listSessions2(fs13, configDir) {
|
|
17436
17523
|
const found = [];
|
|
17437
|
-
for (const project of
|
|
17524
|
+
for (const project of fs13.readdir(path34.join(configDir, PROJECTS_DIR))) {
|
|
17438
17525
|
const projectDir = path34.join(configDir, PROJECTS_DIR, project);
|
|
17439
17526
|
const entries = /* @__PURE__ */ new Set();
|
|
17440
|
-
for (const name of
|
|
17527
|
+
for (const name of fs13.readdir(projectDir)) {
|
|
17441
17528
|
if (name.endsWith(TRANSCRIPT_SUFFIX)) {
|
|
17442
17529
|
entries.add(name.slice(0, -TRANSCRIPT_SUFFIX.length));
|
|
17443
17530
|
continue;
|
|
17444
17531
|
}
|
|
17445
|
-
const children =
|
|
17532
|
+
const children = fs13.readdir(path34.join(projectDir, name));
|
|
17446
17533
|
if (children.includes(SUBAGENTS_DIR) || children.includes(WORKFLOWS_DIR)) {
|
|
17447
17534
|
entries.add(name);
|
|
17448
17535
|
}
|
|
@@ -17453,9 +17540,9 @@ function listSessions2(fs12, configDir) {
|
|
|
17453
17540
|
}
|
|
17454
17541
|
return found.sort((left, right) => left.project.localeCompare(right.project) || left.entry.localeCompare(right.entry));
|
|
17455
17542
|
}
|
|
17456
|
-
function locateAgents(
|
|
17543
|
+
function locateAgents(fs13, configDir, relativeDir, workflowRunId, report) {
|
|
17457
17544
|
const located = [];
|
|
17458
|
-
for (const name of listDirOrReport(
|
|
17545
|
+
for (const name of listDirOrReport(fs13, configDir, relativeDir, report)) {
|
|
17459
17546
|
if (!name.startsWith(AGENT_FILE_PREFIX) || !name.endsWith(META_SUFFIX)) {
|
|
17460
17547
|
continue;
|
|
17461
17548
|
}
|
|
@@ -17504,17 +17591,17 @@ function toNode(read, children) {
|
|
|
17504
17591
|
function describeFailure(error) {
|
|
17505
17592
|
return error instanceof Error ? error.message : String(error);
|
|
17506
17593
|
}
|
|
17507
|
-
function readFileOrReport(
|
|
17594
|
+
function readFileOrReport(fs13, configDir, relative, report) {
|
|
17508
17595
|
try {
|
|
17509
|
-
return
|
|
17596
|
+
return fs13.readFileUtf8(path34.join(configDir, relative));
|
|
17510
17597
|
} catch (error) {
|
|
17511
17598
|
report({ path: relative, reason: `could not be read: ${describeFailure(error)}` });
|
|
17512
17599
|
return void 0;
|
|
17513
17600
|
}
|
|
17514
17601
|
}
|
|
17515
|
-
function listDirOrReport(
|
|
17602
|
+
function listDirOrReport(fs13, configDir, relative, report) {
|
|
17516
17603
|
try {
|
|
17517
|
-
return
|
|
17604
|
+
return fs13.readdir(path34.join(configDir, relative));
|
|
17518
17605
|
} catch (error) {
|
|
17519
17606
|
report({ path: relative, reason: `could not be listed: ${describeFailure(error)}` });
|
|
17520
17607
|
return [];
|
|
@@ -17537,22 +17624,22 @@ var WorkflowRunFileSchema = z28.object({
|
|
|
17537
17624
|
phases: z28.array(z28.object({ title: z28.string() })).default([]),
|
|
17538
17625
|
summary: z28.string().optional()
|
|
17539
17626
|
});
|
|
17540
|
-
function summariseSession(
|
|
17627
|
+
function summariseSession(fs13, configDir, ref) {
|
|
17541
17628
|
const sessionRelative = path34.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
17542
17629
|
const subagentsRelative = path34.join(sessionRelative, SUBAGENTS_DIR);
|
|
17543
17630
|
const workflowsUnderSubagents = path34.join(subagentsRelative, WORKFLOWS_DIR);
|
|
17544
17631
|
const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
|
|
17545
|
-
let agentCount =
|
|
17546
|
-
for (const runDir of
|
|
17632
|
+
let agentCount = fs13.readdir(path34.join(configDir, subagentsRelative)).filter(isMeta).length;
|
|
17633
|
+
for (const runDir of fs13.readdir(path34.join(configDir, workflowsUnderSubagents))) {
|
|
17547
17634
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
17548
|
-
agentCount +=
|
|
17635
|
+
agentCount += fs13.readdir(path34.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
|
|
17549
17636
|
}
|
|
17550
17637
|
}
|
|
17551
|
-
const workflowRunCount =
|
|
17552
|
-
const transcript =
|
|
17638
|
+
const workflowRunCount = fs13.readdir(path34.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
|
|
17639
|
+
const transcript = fs13.lstat(path34.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
|
|
17553
17640
|
return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
|
|
17554
17641
|
}
|
|
17555
|
-
function readSessionAgentTree(
|
|
17642
|
+
function readSessionAgentTree(fs13, configDir, ref, options = {}) {
|
|
17556
17643
|
const problems = [];
|
|
17557
17644
|
const report = (problem) => {
|
|
17558
17645
|
problems.push(problem);
|
|
@@ -17560,15 +17647,15 @@ function readSessionAgentTree(fs12, configDir, ref, options = {}) {
|
|
|
17560
17647
|
const sessionRelative = path34.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
17561
17648
|
const subagentsRelative = path34.join(sessionRelative, SUBAGENTS_DIR);
|
|
17562
17649
|
const workflowsUnderSubagents = path34.join(subagentsRelative, WORKFLOWS_DIR);
|
|
17563
|
-
const located = locateAgents(
|
|
17564
|
-
for (const runDir of listDirOrReport(
|
|
17650
|
+
const located = locateAgents(fs13, configDir, subagentsRelative, void 0, report);
|
|
17651
|
+
for (const runDir of listDirOrReport(fs13, configDir, workflowsUnderSubagents, report)) {
|
|
17565
17652
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
17566
|
-
located.push(...locateAgents(
|
|
17653
|
+
located.push(...locateAgents(fs13, configDir, path34.join(workflowsUnderSubagents, runDir), runDir, report));
|
|
17567
17654
|
}
|
|
17568
17655
|
}
|
|
17569
17656
|
const agents = /* @__PURE__ */ new Map();
|
|
17570
17657
|
for (const candidate of located) {
|
|
17571
|
-
const text = readFileOrReport(
|
|
17658
|
+
const text = readFileOrReport(fs13, configDir, candidate.metaPath, report);
|
|
17572
17659
|
if (text === void 0) {
|
|
17573
17660
|
continue;
|
|
17574
17661
|
}
|
|
@@ -17580,7 +17667,7 @@ function readSessionAgentTree(fs12, configDir, ref, options = {}) {
|
|
|
17580
17667
|
agents.set(candidate.id, { located: candidate, meta: parsed.data });
|
|
17581
17668
|
}
|
|
17582
17669
|
const teamNames = [...new Set([...agents.values()].flatMap((agent) => agent.meta.teamName === void 0 ? [] : [agent.meta.teamName]))].sort();
|
|
17583
|
-
const parentOf3 = resolveParents(
|
|
17670
|
+
const parentOf3 = resolveParents(fs13, configDir, agents, report);
|
|
17584
17671
|
const childrenOf = /* @__PURE__ */ new Map();
|
|
17585
17672
|
const roots = [];
|
|
17586
17673
|
for (const id of agents.keys()) {
|
|
@@ -17603,12 +17690,12 @@ function readSessionAgentTree(fs12, configDir, ref, options = {}) {
|
|
|
17603
17690
|
sessionId: ref.sessionId,
|
|
17604
17691
|
superseded: ref.superseded,
|
|
17605
17692
|
agents: roots.sort().map(build),
|
|
17606
|
-
tasks: readTasks(
|
|
17607
|
-
workflowRuns: readWorkflowRuns(
|
|
17693
|
+
tasks: readTasks(fs13, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
|
|
17694
|
+
workflowRuns: readWorkflowRuns(fs13, configDir, path34.join(sessionRelative, WORKFLOWS_DIR), report),
|
|
17608
17695
|
problems
|
|
17609
17696
|
};
|
|
17610
17697
|
}
|
|
17611
|
-
function resolveParents(
|
|
17698
|
+
function resolveParents(fs13, configDir, agents, report) {
|
|
17612
17699
|
const parentOf3 = /* @__PURE__ */ new Map();
|
|
17613
17700
|
const transcriptCache = /* @__PURE__ */ new Map();
|
|
17614
17701
|
const transcriptOf = (agent) => {
|
|
@@ -17616,7 +17703,7 @@ function resolveParents(fs12, configDir, agents, report) {
|
|
|
17616
17703
|
if (cached !== void 0) {
|
|
17617
17704
|
return cached;
|
|
17618
17705
|
}
|
|
17619
|
-
const text = readFileOrReport(
|
|
17706
|
+
const text = readFileOrReport(fs13, configDir, agent.located.transcriptPath, report) ?? "";
|
|
17620
17707
|
transcriptCache.set(agent.located.id, text);
|
|
17621
17708
|
return text;
|
|
17622
17709
|
};
|
|
@@ -17666,16 +17753,16 @@ function resolveParents(fs12, configDir, agents, report) {
|
|
|
17666
17753
|
function ownTaskLists(sessionId) {
|
|
17667
17754
|
return [sessionId, `${SHORT_SESSION_LIST_PREFIX}${sessionId.slice(0, SHORT_SESSION_ID_LENGTH)}`];
|
|
17668
17755
|
}
|
|
17669
|
-
function readTasks(
|
|
17756
|
+
function readTasks(fs13, configDir, ownLists, sharedLists, report) {
|
|
17670
17757
|
const tasks = [];
|
|
17671
17758
|
[...ownLists, ...sharedLists].forEach((scope, index) => {
|
|
17672
17759
|
const relativeDir = path34.join(TASKS_DIR, scope);
|
|
17673
|
-
for (const name of [...listDirOrReport(
|
|
17760
|
+
for (const name of [...listDirOrReport(fs13, configDir, relativeDir, report)].sort()) {
|
|
17674
17761
|
if (name.startsWith(".") || !name.endsWith(JSON_SUFFIX)) {
|
|
17675
17762
|
continue;
|
|
17676
17763
|
}
|
|
17677
17764
|
const relative = path34.join(relativeDir, name);
|
|
17678
|
-
const text = readFileOrReport(
|
|
17765
|
+
const text = readFileOrReport(fs13, configDir, relative, report);
|
|
17679
17766
|
const parsed = TaskFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
17680
17767
|
if (parsed.success) {
|
|
17681
17768
|
tasks.push(index < ownLists.length ? parsed.data : { ...parsed.data, taskList: scope });
|
|
@@ -17686,14 +17773,14 @@ function readTasks(fs12, configDir, ownLists, sharedLists, report) {
|
|
|
17686
17773
|
});
|
|
17687
17774
|
return tasks;
|
|
17688
17775
|
}
|
|
17689
|
-
function readWorkflowRuns(
|
|
17776
|
+
function readWorkflowRuns(fs13, configDir, relativeDir, report) {
|
|
17690
17777
|
const runs = [];
|
|
17691
|
-
for (const name of [...listDirOrReport(
|
|
17778
|
+
for (const name of [...listDirOrReport(fs13, configDir, relativeDir, report)].sort()) {
|
|
17692
17779
|
if (!name.startsWith(WORKFLOW_RUN_PREFIX) || !name.endsWith(JSON_SUFFIX)) {
|
|
17693
17780
|
continue;
|
|
17694
17781
|
}
|
|
17695
17782
|
const relative = path34.join(relativeDir, name);
|
|
17696
|
-
const text = readFileOrReport(
|
|
17783
|
+
const text = readFileOrReport(fs13, configDir, relative, report);
|
|
17697
17784
|
const parsed = WorkflowRunFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
17698
17785
|
if (!parsed.success) {
|
|
17699
17786
|
if (text !== void 0) {
|
|
@@ -17719,11 +17806,11 @@ var SessionLookupError = class extends CliError {
|
|
|
17719
17806
|
function identityConfigDir(identitiesDir, identity) {
|
|
17720
17807
|
return path35.join(identitiesDir, identity);
|
|
17721
17808
|
}
|
|
17722
|
-
function historyStores(
|
|
17809
|
+
function historyStores(fs13, identitiesDir, identities) {
|
|
17723
17810
|
const byRealPath = /* @__PURE__ */ new Map();
|
|
17724
17811
|
for (const identity of identities) {
|
|
17725
17812
|
const configDir = identityConfigDir(identitiesDir, identity);
|
|
17726
|
-
const real =
|
|
17813
|
+
const real = fs13.realpath(path35.join(configDir, "projects"));
|
|
17727
17814
|
if (real === void 0) {
|
|
17728
17815
|
continue;
|
|
17729
17816
|
}
|
|
@@ -17736,15 +17823,15 @@ function historyStores(fs12, identitiesDir, identities) {
|
|
|
17736
17823
|
}
|
|
17737
17824
|
return [...byRealPath.values()];
|
|
17738
17825
|
}
|
|
17739
|
-
function collectSessionList(
|
|
17826
|
+
function collectSessionList(fs13, identitiesDir, identities, filters) {
|
|
17740
17827
|
const names = filters.identity === void 0 ? identities : identities.filter((name) => name === filters.identity);
|
|
17741
17828
|
if (filters.identity !== void 0 && names.length === 0) {
|
|
17742
17829
|
throw new SessionLookupError(`no identity named "${filters.identity}"`);
|
|
17743
17830
|
}
|
|
17744
17831
|
const sessions = [];
|
|
17745
|
-
for (const store of historyStores(
|
|
17746
|
-
for (const ref of listSessions2(
|
|
17747
|
-
const summary = summariseSession(
|
|
17832
|
+
for (const store of historyStores(fs13, identitiesDir, names)) {
|
|
17833
|
+
for (const ref of listSessions2(fs13, store.configDir)) {
|
|
17834
|
+
const summary = summariseSession(fs13, store.configDir, ref);
|
|
17748
17835
|
if (filters.all === true || summary.agentCount > 0 || summary.workflowRunCount > 0) {
|
|
17749
17836
|
sessions.push({ ...summary, identities: store.identities });
|
|
17750
17837
|
}
|
|
@@ -17752,14 +17839,14 @@ function collectSessionList(fs12, identitiesDir, identities, filters) {
|
|
|
17752
17839
|
}
|
|
17753
17840
|
return sessions.sort((left, right) => (right.updatedAt ?? "").localeCompare(left.updatedAt ?? "") || left.sessionId.localeCompare(right.sessionId));
|
|
17754
17841
|
}
|
|
17755
|
-
function locateSession(
|
|
17842
|
+
function locateSession(fs13, identitiesDir, identities, query, onlyIdentity) {
|
|
17756
17843
|
const names = onlyIdentity === void 0 ? identities : identities.filter((name) => name === onlyIdentity);
|
|
17757
17844
|
if (onlyIdentity !== void 0 && names.length === 0) {
|
|
17758
17845
|
throw new SessionLookupError(`no identity named "${onlyIdentity}"`);
|
|
17759
17846
|
}
|
|
17760
17847
|
const matches = [];
|
|
17761
|
-
for (const store of historyStores(
|
|
17762
|
-
for (const ref of listSessions2(
|
|
17848
|
+
for (const store of historyStores(fs13, identitiesDir, names)) {
|
|
17849
|
+
for (const ref of listSessions2(fs13, store.configDir)) {
|
|
17763
17850
|
if (ref.sessionId.startsWith(query)) {
|
|
17764
17851
|
matches.push({ identities: store.identities, configDir: store.configDir, ref });
|
|
17765
17852
|
}
|
|
@@ -17776,9 +17863,9 @@ function locateSession(fs12, identitiesDir, identities, query, onlyIdentity) {
|
|
|
17776
17863
|
}
|
|
17777
17864
|
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`);
|
|
17778
17865
|
}
|
|
17779
|
-
function showSession(
|
|
17780
|
-
const located = locateSession(
|
|
17781
|
-
return { identities: located.identities, tree: readSessionAgentTree(
|
|
17866
|
+
function showSession(fs13, identitiesDir, identities, query, onlyIdentity) {
|
|
17867
|
+
const located = locateSession(fs13, identitiesDir, identities, query, onlyIdentity);
|
|
17868
|
+
return { identities: located.identities, tree: readSessionAgentTree(fs13, located.configDir, located.ref) };
|
|
17782
17869
|
}
|
|
17783
17870
|
|
|
17784
17871
|
// src/agents/realFs.ts
|