claude-use 7.4.0 → 7.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/cli.cjs +198 -90
- package/dist/index.cjs +316 -126
- package/dist/index.mjs +291 -126
- package/dist/types/config/schema.d.ts +1 -1
- package/dist/types/frontdoor/capture.d.ts +9 -0
- package/dist/types/frontdoor/connect.d.ts +14 -6
- package/dist/types/frontdoor/connectEffects.d.ts +3 -0
- package/dist/types/frontdoor/tap.d.ts +8 -0
- package/dist/types/index.d.ts +7 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -34,13 +34,35 @@ __export(index_exports, {
|
|
|
34
34
|
CONNECT_INTERCEPT_HOST: () => CONNECT_INTERCEPT_HOST,
|
|
35
35
|
CONNECT_INTERCEPT_HOSTS: () => CONNECT_INTERCEPT_HOSTS,
|
|
36
36
|
CONNECT_LIMITS: () => CONNECT_LIMITS,
|
|
37
|
+
CategoryClassificationOverlaySchema: () => CategoryClassificationOverlaySchema,
|
|
38
|
+
CategoryClassificationSchema: () => CategoryClassificationSchema,
|
|
39
|
+
CategoryMapSchema: () => CategoryMapSchema,
|
|
40
|
+
CliError: () => CliError,
|
|
41
|
+
ConfigProfileSchema: () => ConfigProfileSchema,
|
|
42
|
+
CredentialCacheSchema: () => CredentialCacheSchema,
|
|
43
|
+
CredentialSchema: () => CredentialSchema,
|
|
44
|
+
CredentialSourceSchema: () => CredentialSourceSchema,
|
|
45
|
+
DirectoryRuleSchema: () => DirectoryRuleSchema,
|
|
46
|
+
DirectoryRulesSchema: () => DirectoryRulesSchema,
|
|
47
|
+
EXIT_FAILURE: () => EXIT_FAILURE,
|
|
48
|
+
EXIT_USAGE: () => EXIT_USAGE,
|
|
49
|
+
EntryValueSchema: () => EntryValueSchema,
|
|
37
50
|
FARM_MANIFEST_FILENAME: () => FARM_MANIFEST_FILENAME,
|
|
38
51
|
FrontDoorStartError: () => FrontDoorStartError,
|
|
52
|
+
GlobalConfigSchema: () => GlobalConfigSchema,
|
|
39
53
|
HeadroomStartError: () => HeadroomStartError,
|
|
54
|
+
IdentitySchema: () => IdentitySchema,
|
|
55
|
+
PoolNameSchema: () => PoolNameSchema,
|
|
56
|
+
PoolSchema: () => PoolSchema,
|
|
57
|
+
PortableConfigSchema: () => PortableConfigSchema,
|
|
58
|
+
ProviderSchema: () => ProviderSchema,
|
|
40
59
|
ROUTED_PATH_PREFIX: () => ROUTED_PATH_PREFIX,
|
|
60
|
+
UsageError: () => UsageError,
|
|
41
61
|
UsageSnapshotError: () => UsageSnapshotError,
|
|
42
62
|
UsageSnapshotSchema: () => UsageSnapshotSchema,
|
|
63
|
+
WhenSchema: () => WhenSchema,
|
|
43
64
|
buildEntryFacts: () => buildEntryFacts,
|
|
65
|
+
buildLayoutPaths: () => buildLayoutPaths,
|
|
44
66
|
carryOver: () => carryOver,
|
|
45
67
|
createLeafCache: () => createLeafCache,
|
|
46
68
|
detectAmbientCredential: () => detectAmbientCredential,
|
|
@@ -61,7 +83,10 @@ __export(index_exports, {
|
|
|
61
83
|
realConnectEffects: () => realConnectEffects,
|
|
62
84
|
recoverFarm: () => recoverFarm,
|
|
63
85
|
recoveryDiagnostics: () => recoveryDiagnostics,
|
|
86
|
+
resolveAgentShimHome: () => resolveAgentShimHome,
|
|
87
|
+
resolveClaudeHome: () => resolveClaudeHome,
|
|
64
88
|
resolveDecisions: () => resolveDecisions,
|
|
89
|
+
resolveLayoutPaths: () => resolveLayoutPaths,
|
|
65
90
|
resolveSupervisorConfig: () => resolveSupervisorConfig,
|
|
66
91
|
resyncFarm: () => resyncFarm,
|
|
67
92
|
runFrontDoorSupervisor: () => runFrontDoorSupervisor,
|
|
@@ -323,10 +348,18 @@ var import_cosmiconfig = require("cosmiconfig");
|
|
|
323
348
|
|
|
324
349
|
// src/cliError.ts
|
|
325
350
|
var EXIT_FAILURE = 1;
|
|
351
|
+
var EXIT_USAGE = 2;
|
|
326
352
|
var CliError = class extends Error {
|
|
327
353
|
/** The process exit status this failure maps to. `EXIT_FAILURE` unless a subclass says otherwise. */
|
|
328
354
|
exitCode = EXIT_FAILURE;
|
|
329
355
|
};
|
|
356
|
+
var UsageError = class extends CliError {
|
|
357
|
+
exitCode = EXIT_USAGE;
|
|
358
|
+
constructor(message) {
|
|
359
|
+
super(message);
|
|
360
|
+
this.name = "UsageError";
|
|
361
|
+
}
|
|
362
|
+
};
|
|
330
363
|
|
|
331
364
|
// src/config/classify.ts
|
|
332
365
|
var GLOB_METACHARACTERS = /[*?[\]{}!()]/;
|
|
@@ -1287,6 +1320,8 @@ function planReconciliation(params) {
|
|
|
1287
1320
|
}
|
|
1288
1321
|
|
|
1289
1322
|
// src/legacy.ts
|
|
1323
|
+
var HOME_DIRNAME = ".agent-shim";
|
|
1324
|
+
var LEGACY_HOME_DIRNAME = ".claude-use";
|
|
1290
1325
|
var LEGACY_FARM_MANIFEST_FILENAME = ".claude-use-farm.json";
|
|
1291
1326
|
|
|
1292
1327
|
// src/launcher/lock.ts
|
|
@@ -1388,8 +1423,8 @@ var FarmManifestSchema = import_zod2.z.strictObject({
|
|
|
1388
1423
|
materialised: import_zod2.z.array(import_zod2.z.string()),
|
|
1389
1424
|
links: import_zod2.z.array(import_zod2.z.strictObject({ rel: import_zod2.z.string(), target: import_zod2.z.string() }))
|
|
1390
1425
|
});
|
|
1391
|
-
function readFarmManifest(
|
|
1392
|
-
const raw =
|
|
1426
|
+
function readFarmManifest(fs3, farmRoot) {
|
|
1427
|
+
const raw = fs3.readFileUtf8(import_node_path4.default.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs3.readFileUtf8(import_node_path4.default.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
|
|
1393
1428
|
if (raw === void 0) {
|
|
1394
1429
|
return void 0;
|
|
1395
1430
|
}
|
|
@@ -1447,9 +1482,9 @@ function buildEntryFacts(params) {
|
|
|
1447
1482
|
entries
|
|
1448
1483
|
};
|
|
1449
1484
|
}
|
|
1450
|
-
function listSubtree(
|
|
1485
|
+
function listSubtree(fs3, root, rel) {
|
|
1451
1486
|
const absolute = import_node_path4.default.join(root, rel);
|
|
1452
|
-
const stat =
|
|
1487
|
+
const stat = fs3.lstat(absolute);
|
|
1453
1488
|
if (stat === void 0) {
|
|
1454
1489
|
return [];
|
|
1455
1490
|
}
|
|
@@ -1457,10 +1492,10 @@ function listSubtree(fs2, root, rel) {
|
|
|
1457
1492
|
return [{ rel, kind: "symlink" }];
|
|
1458
1493
|
}
|
|
1459
1494
|
if (stat.kind === "dir") {
|
|
1460
|
-
const children = [...
|
|
1495
|
+
const children = [...fs3.readdir(absolute)].sort().flatMap((name) => listSubtree(fs3, root, `${rel}/${name}`));
|
|
1461
1496
|
return [{ rel, kind: "dir" }, ...children];
|
|
1462
1497
|
}
|
|
1463
|
-
const contentHash =
|
|
1498
|
+
const contentHash = fs3.hashFile(absolute);
|
|
1464
1499
|
return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
|
|
1465
1500
|
}
|
|
1466
1501
|
function topLevelScopeRoots(roots) {
|
|
@@ -1474,25 +1509,25 @@ function topLevelScopeRoots(roots) {
|
|
|
1474
1509
|
}
|
|
1475
1510
|
return kept;
|
|
1476
1511
|
}
|
|
1477
|
-
function reconciliationScope(
|
|
1512
|
+
function reconciliationScope(fs3, farmRoot, manifest) {
|
|
1478
1513
|
if (manifest !== void 0) {
|
|
1479
1514
|
return topLevelScopeRoots(manifest.materialised);
|
|
1480
1515
|
}
|
|
1481
|
-
return [...
|
|
1516
|
+
return [...fs3.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs3.lstat(import_node_path4.default.join(farmRoot, name))?.kind === "dir").sort();
|
|
1482
1517
|
}
|
|
1483
|
-
function collectFarmListing(
|
|
1484
|
-
return scopeRoots.flatMap((root) => listSubtree(
|
|
1518
|
+
function collectFarmListing(fs3, farmRoot, scopeRoots) {
|
|
1519
|
+
return scopeRoots.flatMap((root) => listSubtree(fs3, farmRoot, root));
|
|
1485
1520
|
}
|
|
1486
|
-
function collectCanonicalCounterparts(
|
|
1521
|
+
function collectCanonicalCounterparts(fs3, claudeHome, farmListing) {
|
|
1487
1522
|
const out = [];
|
|
1488
1523
|
for (const entry of farmListing) {
|
|
1489
1524
|
const absolute = import_node_path4.default.join(claudeHome, entry.rel);
|
|
1490
|
-
const stat =
|
|
1525
|
+
const stat = fs3.lstat(absolute);
|
|
1491
1526
|
if (stat === void 0) {
|
|
1492
1527
|
continue;
|
|
1493
1528
|
}
|
|
1494
1529
|
if (stat.kind === "file") {
|
|
1495
|
-
const contentHash =
|
|
1530
|
+
const contentHash = fs3.hashFile(absolute);
|
|
1496
1531
|
out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
|
|
1497
1532
|
continue;
|
|
1498
1533
|
}
|
|
@@ -1852,10 +1887,6 @@ function recoveryDiagnostics(recovery, identity) {
|
|
|
1852
1887
|
// src/frontdoor/connect.ts
|
|
1853
1888
|
var import_node_crypto3 = require("node:crypto");
|
|
1854
1889
|
var fs = __toESM(require("node:fs"), 1);
|
|
1855
|
-
var http = __toESM(require("node:http"), 1);
|
|
1856
|
-
var https = __toESM(require("node:https"), 1);
|
|
1857
|
-
var net2 = __toESM(require("node:net"), 1);
|
|
1858
|
-
var tls = __toESM(require("node:tls"), 1);
|
|
1859
1890
|
|
|
1860
1891
|
// src/frontdoor/x509.ts
|
|
1861
1892
|
var import_node_crypto2 = require("node:crypto");
|
|
@@ -2128,6 +2159,54 @@ function issueLeafCertificate(ca, names, notBefore, notAfter) {
|
|
|
2128
2159
|
return { certPem: toPem("CERTIFICATE", der), keyPem: keyPem(privateKey) };
|
|
2129
2160
|
}
|
|
2130
2161
|
|
|
2162
|
+
// src/frontdoor/tap.ts
|
|
2163
|
+
function pumpTapSession(secure, openUpstream, tap) {
|
|
2164
|
+
let upstream;
|
|
2165
|
+
let ended = false;
|
|
2166
|
+
const end = () => {
|
|
2167
|
+
if (!ended) {
|
|
2168
|
+
ended = true;
|
|
2169
|
+
tap?.onEnd();
|
|
2170
|
+
}
|
|
2171
|
+
};
|
|
2172
|
+
const drop = () => {
|
|
2173
|
+
end();
|
|
2174
|
+
secure.destroy();
|
|
2175
|
+
upstream?.destroy();
|
|
2176
|
+
};
|
|
2177
|
+
secure.once("close", () => {
|
|
2178
|
+
end();
|
|
2179
|
+
upstream?.destroy();
|
|
2180
|
+
});
|
|
2181
|
+
secure.once("error", drop);
|
|
2182
|
+
const clientAlpn = "alpnProtocol" in secure && typeof secure.alpnProtocol === "string" ? secure.alpnProtocol : void 0;
|
|
2183
|
+
void (async () => {
|
|
2184
|
+
try {
|
|
2185
|
+
upstream = await openUpstream(clientAlpn);
|
|
2186
|
+
} catch {
|
|
2187
|
+
drop();
|
|
2188
|
+
return;
|
|
2189
|
+
}
|
|
2190
|
+
if (secure.destroyed) {
|
|
2191
|
+
end();
|
|
2192
|
+
upstream.destroy();
|
|
2193
|
+
return;
|
|
2194
|
+
}
|
|
2195
|
+
if (tap !== void 0) {
|
|
2196
|
+
secure.on("data", (chunk) => {
|
|
2197
|
+
tap.onChunk("client-to-server", chunk);
|
|
2198
|
+
});
|
|
2199
|
+
upstream.on("data", (chunk) => {
|
|
2200
|
+
tap.onChunk("server-to-client", chunk);
|
|
2201
|
+
});
|
|
2202
|
+
}
|
|
2203
|
+
secure.pipe(upstream);
|
|
2204
|
+
upstream.pipe(secure);
|
|
2205
|
+
upstream.once("close", drop);
|
|
2206
|
+
upstream.once("error", drop);
|
|
2207
|
+
})();
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2131
2210
|
// src/frontdoor/capability.ts
|
|
2132
2211
|
var CONNECT_PROXY_REALM = "agent-shim front door";
|
|
2133
2212
|
var BASIC_SCHEME = "basic";
|
|
@@ -2176,10 +2255,10 @@ var FrontDoorStateSchema = import_zod3.z.strictObject({
|
|
|
2176
2255
|
/** The last fatal error, kept across shutdowns so `frontdoor status` can explain a front door that is not running. */
|
|
2177
2256
|
lastError: import_zod3.z.string().optional()
|
|
2178
2257
|
});
|
|
2179
|
-
function readFrontDoorState(
|
|
2258
|
+
function readFrontDoorState(fs3, stateFile) {
|
|
2180
2259
|
let raw;
|
|
2181
2260
|
try {
|
|
2182
|
-
raw =
|
|
2261
|
+
raw = fs3.readFileUtf8(stateFile);
|
|
2183
2262
|
} catch {
|
|
2184
2263
|
return void 0;
|
|
2185
2264
|
}
|
|
@@ -2193,28 +2272,28 @@ function readFrontDoorState(fs2, stateFile) {
|
|
|
2193
2272
|
return void 0;
|
|
2194
2273
|
}
|
|
2195
2274
|
}
|
|
2196
|
-
function writeFrontDoorState(
|
|
2197
|
-
|
|
2198
|
-
|
|
2275
|
+
function writeFrontDoorState(fs3, stateFile, state) {
|
|
2276
|
+
fs3.mkdirp(import_node_path5.default.dirname(stateFile));
|
|
2277
|
+
fs3.writeFileUtf8(stateFile, `${JSON.stringify(state, null, 2)}
|
|
2199
2278
|
`);
|
|
2200
2279
|
}
|
|
2201
2280
|
function frontDoorOrigin(state) {
|
|
2202
2281
|
const port = state?.directPort ?? state?.lastDirectPort;
|
|
2203
2282
|
return port === void 0 ? void 0 : `http://127.0.0.1:${String(port)}`;
|
|
2204
2283
|
}
|
|
2205
|
-
function writeFrontDoorSession(
|
|
2206
|
-
|
|
2207
|
-
|
|
2284
|
+
function writeFrontDoorSession(fs3, sessionsDir, session) {
|
|
2285
|
+
fs3.mkdirPrivate(sessionsDir);
|
|
2286
|
+
fs3.writeFilePrivate(import_node_path5.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
2208
2287
|
`);
|
|
2209
2288
|
}
|
|
2210
|
-
function listFrontDoorSessions(
|
|
2289
|
+
function listFrontDoorSessions(fs3, sessionsDir) {
|
|
2211
2290
|
const sessions = [];
|
|
2212
|
-
for (const name of
|
|
2291
|
+
for (const name of fs3.readdir(sessionsDir)) {
|
|
2213
2292
|
if (!name.endsWith(".json")) {
|
|
2214
2293
|
continue;
|
|
2215
2294
|
}
|
|
2216
2295
|
try {
|
|
2217
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(
|
|
2296
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs3.readFileUtf8(import_node_path5.default.join(sessionsDir, name)) ?? ""));
|
|
2218
2297
|
if (parsed.success) {
|
|
2219
2298
|
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
|
|
2220
2299
|
}
|
|
@@ -2224,14 +2303,14 @@ function listFrontDoorSessions(fs2, sessionsDir) {
|
|
|
2224
2303
|
}
|
|
2225
2304
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
2226
2305
|
}
|
|
2227
|
-
function removeFrontDoorSession(
|
|
2228
|
-
|
|
2306
|
+
function removeFrontDoorSession(fs3, sessionsDir, pid) {
|
|
2307
|
+
fs3.removeRecursive(import_node_path5.default.join(sessionsDir, `${String(pid)}.json`));
|
|
2229
2308
|
}
|
|
2230
|
-
function pruneDeadFrontDoorSessions(
|
|
2309
|
+
function pruneDeadFrontDoorSessions(fs3, sessionsDir, isRunning) {
|
|
2231
2310
|
const removed = [];
|
|
2232
|
-
for (const session of listFrontDoorSessions(
|
|
2311
|
+
for (const session of listFrontDoorSessions(fs3, sessionsDir)) {
|
|
2233
2312
|
if (!isRunning(session.pid)) {
|
|
2234
|
-
removeFrontDoorSession(
|
|
2313
|
+
removeFrontDoorSession(fs3, sessionsDir, session.pid);
|
|
2235
2314
|
removed.push(session.pid);
|
|
2236
2315
|
}
|
|
2237
2316
|
}
|
|
@@ -2243,8 +2322,8 @@ var FRONTDOOR_SUPERVISOR_STILL_RUNNING = -1;
|
|
|
2243
2322
|
var FRONTDOOR_POLL_MS = 1e3;
|
|
2244
2323
|
var MS_PER_MINUTE = 6e4;
|
|
2245
2324
|
async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {}) {
|
|
2246
|
-
const { fs:
|
|
2247
|
-
const previous = readFrontDoorState(
|
|
2325
|
+
const { fs: fs3, paths } = ports;
|
|
2326
|
+
const previous = readFrontDoorState(fs3, paths.frontdoorStateFile);
|
|
2248
2327
|
let lastPort = previous?.lastPort;
|
|
2249
2328
|
let lastConnectPort = previous?.lastConnectPort;
|
|
2250
2329
|
let lastDirectPort = previous?.lastDirectPort;
|
|
@@ -2254,12 +2333,12 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2254
2333
|
...lastDirectPort === void 0 ? {} : { lastDirectPort }
|
|
2255
2334
|
});
|
|
2256
2335
|
const fail = (message) => {
|
|
2257
|
-
writeFrontDoorState(
|
|
2258
|
-
|
|
2336
|
+
writeFrontDoorState(fs3, paths.frontdoorStateFile, { lastError: message, ...sticky() });
|
|
2337
|
+
fs3.removeRecursive(paths.frontdoorLockFile);
|
|
2259
2338
|
ports.log(`agent-shim frontdoor supervisor: ${message}`);
|
|
2260
2339
|
return 1;
|
|
2261
2340
|
};
|
|
2262
|
-
writeFrontDoorState(
|
|
2341
|
+
writeFrontDoorState(fs3, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
|
|
2263
2342
|
const previousSticky = lastPort;
|
|
2264
2343
|
let http2;
|
|
2265
2344
|
try {
|
|
@@ -2272,23 +2351,23 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2272
2351
|
}
|
|
2273
2352
|
lastPort = http2.port;
|
|
2274
2353
|
const previousStickyConnect = lastConnectPort;
|
|
2275
|
-
let
|
|
2354
|
+
let connect3;
|
|
2276
2355
|
try {
|
|
2277
|
-
|
|
2356
|
+
connect3 = await ports.startConnectListener(lastConnectPort);
|
|
2278
2357
|
} catch (error) {
|
|
2279
2358
|
await http2.close();
|
|
2280
2359
|
return fail(`could not start the CONNECT surface: ${error instanceof Error ? error.message : String(error)}`);
|
|
2281
2360
|
}
|
|
2282
|
-
if (previousStickyConnect !== void 0 &&
|
|
2283
|
-
ports.log(`agent-shim frontdoor supervisor: sticky CONNECT port ${String(previousStickyConnect)} was occupied; moving to ${String(
|
|
2361
|
+
if (previousStickyConnect !== void 0 && connect3.port !== previousStickyConnect) {
|
|
2362
|
+
ports.log(`agent-shim frontdoor supervisor: sticky CONNECT port ${String(previousStickyConnect)} was occupied; moving to ${String(connect3.port)} (OAuth sessions launched against the old port are stale until they relaunch)`);
|
|
2284
2363
|
}
|
|
2285
|
-
lastConnectPort =
|
|
2364
|
+
lastConnectPort = connect3.port;
|
|
2286
2365
|
const previousStickyDirect = lastDirectPort;
|
|
2287
2366
|
let direct;
|
|
2288
2367
|
try {
|
|
2289
2368
|
direct = await ports.startDirectListener(lastDirectPort);
|
|
2290
2369
|
} catch (error) {
|
|
2291
|
-
await
|
|
2370
|
+
await connect3.close();
|
|
2292
2371
|
await http2.close();
|
|
2293
2372
|
return fail(`could not start the direct listener: ${error instanceof Error ? error.message : String(error)}`);
|
|
2294
2373
|
}
|
|
@@ -2296,9 +2375,9 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2296
2375
|
ports.log(`agent-shim frontdoor supervisor: sticky direct port ${String(previousStickyDirect)} was occupied; moving to ${String(direct.port)} (headroom must be restarted to admit the new address)`);
|
|
2297
2376
|
}
|
|
2298
2377
|
lastDirectPort = direct.port;
|
|
2299
|
-
writeFrontDoorState(
|
|
2300
|
-
|
|
2301
|
-
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http2.port)}, CONNECT surface on 127.0.0.1:${String(
|
|
2378
|
+
writeFrontDoorState(fs3, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, port: http2.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
2379
|
+
fs3.removeRecursive(paths.frontdoorLockFile);
|
|
2380
|
+
ports.log(`agent-shim frontdoor supervisor ${String(ports.ownPid)}: front door on 127.0.0.1:${String(http2.port)}, CONNECT surface on 127.0.0.1:${String(connect3.port)}`);
|
|
2302
2381
|
let idleSince;
|
|
2303
2382
|
let ticks = 0;
|
|
2304
2383
|
for (; ; ) {
|
|
@@ -2306,15 +2385,15 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2306
2385
|
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
2307
2386
|
}
|
|
2308
2387
|
ticks += 1;
|
|
2309
|
-
pruneDeadFrontDoorSessions(
|
|
2310
|
-
if (listFrontDoorSessions(
|
|
2388
|
+
pruneDeadFrontDoorSessions(fs3, paths.frontdoorSessionsDir, ports.isRunning);
|
|
2389
|
+
if (listFrontDoorSessions(fs3, paths.frontdoorSessionsDir).length === 0) {
|
|
2311
2390
|
idleSince ??= ports.now();
|
|
2312
2391
|
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE) {
|
|
2313
2392
|
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
2314
2393
|
await direct.close();
|
|
2315
|
-
await
|
|
2394
|
+
await connect3.close();
|
|
2316
2395
|
await http2.close();
|
|
2317
|
-
writeFrontDoorState(
|
|
2396
|
+
writeFrontDoorState(fs3, paths.frontdoorStateFile, sticky());
|
|
2318
2397
|
return 0;
|
|
2319
2398
|
}
|
|
2320
2399
|
} else {
|
|
@@ -2369,8 +2448,8 @@ function parseConnectTarget(authority) {
|
|
|
2369
2448
|
function isInterceptedHost(host, interceptHosts) {
|
|
2370
2449
|
return interceptHosts.includes(host);
|
|
2371
2450
|
}
|
|
2372
|
-
function servedByPipeline(
|
|
2373
|
-
return
|
|
2451
|
+
function servedByPipeline(path9) {
|
|
2452
|
+
return path9?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
2374
2453
|
}
|
|
2375
2454
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
2376
2455
|
"connection",
|
|
@@ -2436,9 +2515,20 @@ function caParses(ca) {
|
|
|
2436
2515
|
return false;
|
|
2437
2516
|
}
|
|
2438
2517
|
}
|
|
2518
|
+
var TAP_ALPN_PROTOCOLS = ["h2", "http/1.1"];
|
|
2439
2519
|
async function startConnectServer(config, effects, preferredPort) {
|
|
2440
2520
|
const onUpgrade = config.capture === void 0 ? void 0 : (request3) => config.capture?.upgrade(request3);
|
|
2441
2521
|
const sessions = config.interceptHosts.map((host) => {
|
|
2522
|
+
if (config.tapHosts.includes(host)) {
|
|
2523
|
+
const tlsAcceptor2 = effects.createTlsAcceptor(
|
|
2524
|
+
config.leafFor(host),
|
|
2525
|
+
(secure) => {
|
|
2526
|
+
pumpTapSession(secure, async (clientAlpn) => await effects.connectTlsUpstream(host, HTTPS_PORT, clientAlpn), config.capture?.tapStream?.(host));
|
|
2527
|
+
},
|
|
2528
|
+
TAP_ALPN_PROTOCOLS
|
|
2529
|
+
);
|
|
2530
|
+
return { host, tlsAcceptor: tlsAcceptor2 };
|
|
2531
|
+
}
|
|
2442
2532
|
const handler = (request3, response) => {
|
|
2443
2533
|
if (host === config.routedHost && servedByPipeline(request3.url)) {
|
|
2444
2534
|
config.serveRouted(request3, response);
|
|
@@ -2463,7 +2553,7 @@ async function startConnectServer(config, effects, preferredPort) {
|
|
|
2463
2553
|
await listener.close();
|
|
2464
2554
|
for (const { httpSession, tlsAcceptor } of sessions) {
|
|
2465
2555
|
tlsAcceptor.close();
|
|
2466
|
-
httpSession
|
|
2556
|
+
httpSession?.close();
|
|
2467
2557
|
}
|
|
2468
2558
|
}
|
|
2469
2559
|
};
|
|
@@ -2639,6 +2729,40 @@ async function blindTunnel(socket, target, effects) {
|
|
|
2639
2729
|
socket.destroy();
|
|
2640
2730
|
});
|
|
2641
2731
|
}
|
|
2732
|
+
function isEnoent(error) {
|
|
2733
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
2734
|
+
}
|
|
2735
|
+
function realConnectCertStore(paths) {
|
|
2736
|
+
const read = (file) => {
|
|
2737
|
+
try {
|
|
2738
|
+
return fs.readFileSync(file, "utf8");
|
|
2739
|
+
} catch (error) {
|
|
2740
|
+
if (isEnoent(error)) {
|
|
2741
|
+
return void 0;
|
|
2742
|
+
}
|
|
2743
|
+
throw error;
|
|
2744
|
+
}
|
|
2745
|
+
};
|
|
2746
|
+
return {
|
|
2747
|
+
loadCa: () => {
|
|
2748
|
+
const certPem = read(paths.frontdoorCaCertFile);
|
|
2749
|
+
const keyPem2 = read(paths.frontdoorCaKeyFile);
|
|
2750
|
+
return certPem === void 0 || keyPem2 === void 0 ? void 0 : { certPem, keyPem: keyPem2 };
|
|
2751
|
+
},
|
|
2752
|
+
writeCa: (ca) => {
|
|
2753
|
+
fs.mkdirSync(paths.frontdoorCaDir, { recursive: true });
|
|
2754
|
+
fs.writeFileSync(paths.frontdoorCaCertFile, ca.certPem, "utf8");
|
|
2755
|
+
fs.writeFileSync(paths.frontdoorCaKeyFile, ca.keyPem, { encoding: "utf8", mode: CA_KEY_FILE_MODE });
|
|
2756
|
+
fs.chmodSync(paths.frontdoorCaKeyFile, CA_KEY_FILE_MODE);
|
|
2757
|
+
}
|
|
2758
|
+
};
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2761
|
+
// src/frontdoor/connectEffects.ts
|
|
2762
|
+
var http = __toESM(require("node:http"), 1);
|
|
2763
|
+
var https = __toESM(require("node:https"), 1);
|
|
2764
|
+
var net2 = __toESM(require("node:net"), 1);
|
|
2765
|
+
var tls = __toESM(require("node:tls"), 1);
|
|
2642
2766
|
function realConnectEffects() {
|
|
2643
2767
|
const plainAgent = new http.Agent({ keepAlive: true });
|
|
2644
2768
|
const tlsAgent = new https.Agent({ keepAlive: true });
|
|
@@ -2684,10 +2808,13 @@ function realConnectEffects() {
|
|
|
2684
2808
|
}
|
|
2685
2809
|
return await listenOnce(0, onSocket);
|
|
2686
2810
|
},
|
|
2687
|
-
createTlsAcceptor: (leaf, onSecure) => {
|
|
2688
|
-
const server = tls.createServer(
|
|
2689
|
-
|
|
2690
|
-
|
|
2811
|
+
createTlsAcceptor: (leaf, onSecure, alpnProtocols) => {
|
|
2812
|
+
const server = tls.createServer(
|
|
2813
|
+
{ key: leaf.keyPem, cert: leaf.certPem, ...alpnProtocols === void 0 ? {} : { ALPNProtocols: [...alpnProtocols] } },
|
|
2814
|
+
(secure) => {
|
|
2815
|
+
onSecure(secure);
|
|
2816
|
+
}
|
|
2817
|
+
);
|
|
2691
2818
|
server.on("clientError", (_error, socket) => {
|
|
2692
2819
|
socket.destroy();
|
|
2693
2820
|
});
|
|
@@ -2722,6 +2849,13 @@ function realConnectEffects() {
|
|
|
2722
2849
|
}
|
|
2723
2850
|
};
|
|
2724
2851
|
},
|
|
2852
|
+
connectTlsUpstream: async (host, port, clientAlpn) => await new Promise((resolve, reject) => {
|
|
2853
|
+
const socket = tls.connect({ host, port, servername: host, ...clientAlpn === void 0 ? {} : { ALPNProtocols: [clientAlpn] } });
|
|
2854
|
+
socket.once("secureConnect", () => {
|
|
2855
|
+
resolve(socket);
|
|
2856
|
+
});
|
|
2857
|
+
socket.once("error", reject);
|
|
2858
|
+
}),
|
|
2725
2859
|
connectTcp: async (host, port) => await new Promise((resolve, reject) => {
|
|
2726
2860
|
const socket = net2.connect({ host, port });
|
|
2727
2861
|
socket.once("connect", () => {
|
|
@@ -2785,34 +2919,6 @@ function realConnectEffects() {
|
|
|
2785
2919
|
}
|
|
2786
2920
|
};
|
|
2787
2921
|
}
|
|
2788
|
-
function isEnoent(error) {
|
|
2789
|
-
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
2790
|
-
}
|
|
2791
|
-
function realConnectCertStore(paths) {
|
|
2792
|
-
const read = (file) => {
|
|
2793
|
-
try {
|
|
2794
|
-
return fs.readFileSync(file, "utf8");
|
|
2795
|
-
} catch (error) {
|
|
2796
|
-
if (isEnoent(error)) {
|
|
2797
|
-
return void 0;
|
|
2798
|
-
}
|
|
2799
|
-
throw error;
|
|
2800
|
-
}
|
|
2801
|
-
};
|
|
2802
|
-
return {
|
|
2803
|
-
loadCa: () => {
|
|
2804
|
-
const certPem = read(paths.frontdoorCaCertFile);
|
|
2805
|
-
const keyPem2 = read(paths.frontdoorCaKeyFile);
|
|
2806
|
-
return certPem === void 0 || keyPem2 === void 0 ? void 0 : { certPem, keyPem: keyPem2 };
|
|
2807
|
-
},
|
|
2808
|
-
writeCa: (ca) => {
|
|
2809
|
-
fs.mkdirSync(paths.frontdoorCaDir, { recursive: true });
|
|
2810
|
-
fs.writeFileSync(paths.frontdoorCaCertFile, ca.certPem, "utf8");
|
|
2811
|
-
fs.writeFileSync(paths.frontdoorCaKeyFile, ca.keyPem, { encoding: "utf8", mode: CA_KEY_FILE_MODE });
|
|
2812
|
-
fs.chmodSync(paths.frontdoorCaKeyFile, CA_KEY_FILE_MODE);
|
|
2813
|
-
}
|
|
2814
|
-
};
|
|
2815
|
-
}
|
|
2816
2922
|
|
|
2817
2923
|
// src/frontdoor/ensure.ts
|
|
2818
2924
|
var import_node_crypto5 = require("node:crypto");
|
|
@@ -2853,16 +2959,16 @@ function parseJson(raw, schema) {
|
|
|
2853
2959
|
const parsed = schema.safeParse(JSON.parse(raw));
|
|
2854
2960
|
return parsed.success ? parsed.data : void 0;
|
|
2855
2961
|
}
|
|
2856
|
-
function readHeadroomState(
|
|
2962
|
+
function readHeadroomState(fs3, stateFile) {
|
|
2857
2963
|
try {
|
|
2858
|
-
return parseJson(
|
|
2964
|
+
return parseJson(fs3.readFileUtf8(stateFile), HeadroomStateSchema);
|
|
2859
2965
|
} catch {
|
|
2860
2966
|
return void 0;
|
|
2861
2967
|
}
|
|
2862
2968
|
}
|
|
2863
|
-
function writeHeadroomState(
|
|
2864
|
-
|
|
2865
|
-
|
|
2969
|
+
function writeHeadroomState(fs3, stateFile, state) {
|
|
2970
|
+
fs3.mkdirp(import_node_path6.default.dirname(stateFile));
|
|
2971
|
+
fs3.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
2866
2972
|
`);
|
|
2867
2973
|
}
|
|
2868
2974
|
function headroomAllowlist(providers) {
|
|
@@ -2882,14 +2988,14 @@ function headroomUpstreams(providers, frontDoorOrigin2) {
|
|
|
2882
2988
|
function hashAllowlist(allowlist) {
|
|
2883
2989
|
return (0, import_node_crypto4.createHash)("sha256").update(allowlist.join("\n")).digest("hex");
|
|
2884
2990
|
}
|
|
2885
|
-
function readAllProviders(
|
|
2991
|
+
function readAllProviders(fs3, providersDir) {
|
|
2886
2992
|
const result = [];
|
|
2887
|
-
for (const name of
|
|
2993
|
+
for (const name of fs3.readdir(providersDir)) {
|
|
2888
2994
|
if (!name.endsWith(".json")) {
|
|
2889
2995
|
continue;
|
|
2890
2996
|
}
|
|
2891
2997
|
try {
|
|
2892
|
-
const parsed = parseJson(
|
|
2998
|
+
const parsed = parseJson(fs3.readFileUtf8(import_node_path6.default.join(providersDir, name)), ProviderSchema);
|
|
2893
2999
|
if (parsed !== void 0) {
|
|
2894
3000
|
result.push({ name: name.slice(0, -".json".length), provider: parsed });
|
|
2895
3001
|
}
|
|
@@ -2899,22 +3005,22 @@ function readAllProviders(fs2, providersDir) {
|
|
|
2899
3005
|
}
|
|
2900
3006
|
return result;
|
|
2901
3007
|
}
|
|
2902
|
-
function writeSession(
|
|
2903
|
-
|
|
2904
|
-
|
|
3008
|
+
function writeSession(fs3, sessionsDir, session) {
|
|
3009
|
+
fs3.mkdirp(sessionsDir);
|
|
3010
|
+
fs3.writeFileUtf8(import_node_path6.default.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
2905
3011
|
`);
|
|
2906
3012
|
}
|
|
2907
|
-
function removeSession(
|
|
2908
|
-
|
|
3013
|
+
function removeSession(fs3, sessionsDir, pid) {
|
|
3014
|
+
fs3.removeRecursive(import_node_path6.default.join(sessionsDir, `${String(pid)}.json`));
|
|
2909
3015
|
}
|
|
2910
|
-
function listSessions(
|
|
3016
|
+
function listSessions(fs3, sessionsDir) {
|
|
2911
3017
|
const sessions = [];
|
|
2912
|
-
for (const name of
|
|
3018
|
+
for (const name of fs3.readdir(sessionsDir)) {
|
|
2913
3019
|
if (!name.endsWith(".json")) {
|
|
2914
3020
|
continue;
|
|
2915
3021
|
}
|
|
2916
3022
|
try {
|
|
2917
|
-
const parsed = parseJson(
|
|
3023
|
+
const parsed = parseJson(fs3.readFileUtf8(import_node_path6.default.join(sessionsDir, name)), HeadroomSessionSchema);
|
|
2918
3024
|
if (parsed !== void 0) {
|
|
2919
3025
|
sessions.push(parsed);
|
|
2920
3026
|
}
|
|
@@ -2924,22 +3030,22 @@ function listSessions(fs2, sessionsDir) {
|
|
|
2924
3030
|
}
|
|
2925
3031
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
2926
3032
|
}
|
|
2927
|
-
function sessionsForSupervisor(
|
|
2928
|
-
return listSessions(
|
|
3033
|
+
function sessionsForSupervisor(fs3, sessionsDir, supervisorPid) {
|
|
3034
|
+
return listSessions(fs3, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
|
|
2929
3035
|
}
|
|
2930
|
-
function pruneDeadSessions(
|
|
3036
|
+
function pruneDeadSessions(fs3, sessionsDir, isRunning) {
|
|
2931
3037
|
const removed = [];
|
|
2932
|
-
for (const session of listSessions(
|
|
3038
|
+
for (const session of listSessions(fs3, sessionsDir)) {
|
|
2933
3039
|
if (!isRunning(session.pid)) {
|
|
2934
|
-
removeSession(
|
|
3040
|
+
removeSession(fs3, sessionsDir, session.pid);
|
|
2935
3041
|
removed.push(session.pid);
|
|
2936
3042
|
}
|
|
2937
3043
|
}
|
|
2938
3044
|
return removed;
|
|
2939
3045
|
}
|
|
2940
|
-
function readStartLock(
|
|
3046
|
+
function readStartLock(fs3, lockFile) {
|
|
2941
3047
|
try {
|
|
2942
|
-
return parseJson(
|
|
3048
|
+
return parseJson(fs3.readFileUtf8(lockFile), HeadroomLockSchema);
|
|
2943
3049
|
} catch {
|
|
2944
3050
|
return void 0;
|
|
2945
3051
|
}
|
|
@@ -3176,9 +3282,9 @@ function snapshotPath(snapshotsDir, identity) {
|
|
|
3176
3282
|
}
|
|
3177
3283
|
return import_node_path7.default.join(snapshotsDir, `${identity}.json`);
|
|
3178
3284
|
}
|
|
3179
|
-
function readUsageSnapshot(
|
|
3285
|
+
function readUsageSnapshot(fs3, snapshotsDir, identity) {
|
|
3180
3286
|
const file = snapshotPath(snapshotsDir, identity);
|
|
3181
|
-
const raw =
|
|
3287
|
+
const raw = fs3.readFileUtf8(file);
|
|
3182
3288
|
if (raw === void 0) {
|
|
3183
3289
|
return void 0;
|
|
3184
3290
|
}
|
|
@@ -3194,8 +3300,8 @@ function readUsageSnapshot(fs2, snapshotsDir, identity) {
|
|
|
3194
3300
|
}
|
|
3195
3301
|
return snapshot.data;
|
|
3196
3302
|
}
|
|
3197
|
-
function listUsageSnapshots(
|
|
3198
|
-
return
|
|
3303
|
+
function listUsageSnapshots(fs3, snapshotsDir) {
|
|
3304
|
+
return fs3.readdir(snapshotsDir).flatMap((name) => {
|
|
3199
3305
|
if (!name.endsWith(".json")) {
|
|
3200
3306
|
return [];
|
|
3201
3307
|
}
|
|
@@ -3203,7 +3309,7 @@ function listUsageSnapshots(fs2, snapshotsDir) {
|
|
|
3203
3309
|
if (!isIdentityName(identity)) {
|
|
3204
3310
|
return [];
|
|
3205
3311
|
}
|
|
3206
|
-
const snapshot = readUsageSnapshot(
|
|
3312
|
+
const snapshot = readUsageSnapshot(fs3, snapshotsDir, identity);
|
|
3207
3313
|
return snapshot === void 0 ? [] : [snapshot];
|
|
3208
3314
|
}).sort((left, right) => left.identity.localeCompare(right.identity));
|
|
3209
3315
|
}
|
|
@@ -3370,9 +3476,9 @@ function compareVersions(a, b) {
|
|
|
3370
3476
|
}
|
|
3371
3477
|
var HEADROOM_SUPERVISOR_STILL_RUNNING = -1;
|
|
3372
3478
|
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
3373
|
-
const { fs:
|
|
3479
|
+
const { fs: fs3, paths } = ports;
|
|
3374
3480
|
let config = initialConfig;
|
|
3375
|
-
const previousState = readHeadroomState(
|
|
3481
|
+
const previousState = readHeadroomState(fs3, paths.headroomStateFile);
|
|
3376
3482
|
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
3377
3483
|
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
3378
3484
|
return 0;
|
|
@@ -3381,19 +3487,19 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3381
3487
|
let lastPort = previousState?.lastPort;
|
|
3382
3488
|
const sticky = () => lastPort === void 0 ? {} : { lastPort };
|
|
3383
3489
|
const ownsState = () => {
|
|
3384
|
-
const owner = readHeadroomState(
|
|
3490
|
+
const owner = readHeadroomState(fs3, paths.headroomStateFile)?.supervisorPid;
|
|
3385
3491
|
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
3386
3492
|
};
|
|
3387
3493
|
const writeOwnState = (state) => {
|
|
3388
3494
|
if (!ownsState()) {
|
|
3389
3495
|
return false;
|
|
3390
3496
|
}
|
|
3391
|
-
writeHeadroomState(
|
|
3497
|
+
writeHeadroomState(fs3, paths.headroomStateFile, state);
|
|
3392
3498
|
return true;
|
|
3393
3499
|
};
|
|
3394
3500
|
const fail = (message) => {
|
|
3395
3501
|
if (writeOwnState({ lastError: message, ...sticky() })) {
|
|
3396
|
-
|
|
3502
|
+
fs3.removeRecursive(paths.headroomLockFile);
|
|
3397
3503
|
}
|
|
3398
3504
|
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
3399
3505
|
return 1;
|
|
@@ -3442,7 +3548,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3442
3548
|
const settingsHash = hashSettings(config.settings);
|
|
3443
3549
|
const allowlist = allowlistOf(ports);
|
|
3444
3550
|
const allowlistHash = hashAllowlist(allowlist);
|
|
3445
|
-
pruneDeadSessions(
|
|
3551
|
+
pruneDeadSessions(fs3, paths.headroomSessionsDir, ports.isRunning);
|
|
3446
3552
|
const ownsNow = ownsState();
|
|
3447
3553
|
if (!ownsNow && !superseded) {
|
|
3448
3554
|
ports.log("agent-shim headroom supervisor: another supervisor now owns state.json; serving this daemon's own sessions until they end");
|
|
@@ -3494,7 +3600,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3494
3600
|
...sticky()
|
|
3495
3601
|
});
|
|
3496
3602
|
if (recorded) {
|
|
3497
|
-
|
|
3603
|
+
fs3.removeRecursive(paths.headroomLockFile);
|
|
3498
3604
|
}
|
|
3499
3605
|
idleSince = void 0;
|
|
3500
3606
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on 127.0.0.1:${String(port)}`);
|
|
@@ -3509,7 +3615,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3509
3615
|
}
|
|
3510
3616
|
} else {
|
|
3511
3617
|
if (runningHash !== allowlistHash || runningSettingsHash !== settingsHash || installedSource !== config.source) {
|
|
3512
|
-
if (sessionsForSupervisor(
|
|
3618
|
+
if (sessionsForSupervisor(fs3, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
3513
3619
|
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
3514
3620
|
ports.stopProcess(headroomPid);
|
|
3515
3621
|
headroomPid = void 0;
|
|
@@ -3518,7 +3624,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3518
3624
|
continue;
|
|
3519
3625
|
}
|
|
3520
3626
|
}
|
|
3521
|
-
const sessions = sessionsForSupervisor(
|
|
3627
|
+
const sessions = sessionsForSupervisor(fs3, paths.headroomSessionsDir, ports.ownPid);
|
|
3522
3628
|
if (sessions.length === 0) {
|
|
3523
3629
|
idleSince ??= ports.now();
|
|
3524
3630
|
const idleMs = ports.now() - idleSince;
|
|
@@ -3540,9 +3646,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3540
3646
|
await ports.sleep(HEADROOM_POLL_MS);
|
|
3541
3647
|
}
|
|
3542
3648
|
}
|
|
3543
|
-
function currentHeadroomAllowlist(
|
|
3544
|
-
const providers = readAllProviders(
|
|
3545
|
-
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(
|
|
3649
|
+
function currentHeadroomAllowlist(fs3, paths) {
|
|
3650
|
+
const providers = readAllProviders(fs3, paths.providersDir).map((entry) => entry.provider);
|
|
3651
|
+
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(fs3, paths.frontdoorStateFile))));
|
|
3546
3652
|
}
|
|
3547
3653
|
function allowlistOf(ports) {
|
|
3548
3654
|
return currentHeadroomAllowlist(ports.fs, ports.paths);
|
|
@@ -3606,19 +3712,100 @@ function evaluateAmbientCredentialGuard(params) {
|
|
|
3606
3712
|
message: formatAmbientCredentialGuardMessage(detected.variable, params.identityName)
|
|
3607
3713
|
};
|
|
3608
3714
|
}
|
|
3715
|
+
|
|
3716
|
+
// src/paths.ts
|
|
3717
|
+
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
3718
|
+
var import_node_os = __toESM(require("node:os"), 1);
|
|
3719
|
+
var import_node_path8 = __toESM(require("node:path"), 1);
|
|
3720
|
+
function resolveAgentShimHome(env = process.env, home = import_node_os.default.homedir(), isDirectory = isExistingDirectory) {
|
|
3721
|
+
const fromEnv = env.AGENT_SHIM_HOME;
|
|
3722
|
+
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
3723
|
+
return fromEnv;
|
|
3724
|
+
}
|
|
3725
|
+
const current = import_node_path8.default.join(home, HOME_DIRNAME);
|
|
3726
|
+
const legacy = import_node_path8.default.join(home, LEGACY_HOME_DIRNAME);
|
|
3727
|
+
return !isDirectory(current) && isDirectory(legacy) ? legacy : current;
|
|
3728
|
+
}
|
|
3729
|
+
function isExistingDirectory(candidate) {
|
|
3730
|
+
return import_node_fs.default.statSync(candidate, { throwIfNoEntry: false })?.isDirectory() ?? false;
|
|
3731
|
+
}
|
|
3732
|
+
function resolveClaudeHome() {
|
|
3733
|
+
const fromEnv = process.env.AGENT_SHIM_CLAUDE_HOME;
|
|
3734
|
+
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
3735
|
+
return fromEnv;
|
|
3736
|
+
}
|
|
3737
|
+
return import_node_path8.default.join(import_node_os.default.homedir(), ".claude");
|
|
3738
|
+
}
|
|
3739
|
+
function buildLayoutPaths(root) {
|
|
3740
|
+
return {
|
|
3741
|
+
root,
|
|
3742
|
+
identitiesDir: import_node_path8.default.join(root, "identities"),
|
|
3743
|
+
configProfilesDir: import_node_path8.default.join(root, "config-profiles"),
|
|
3744
|
+
providersDir: import_node_path8.default.join(root, "providers"),
|
|
3745
|
+
directoryRulesFile: import_node_path8.default.join(root, "directory-rules.json"),
|
|
3746
|
+
activeIdentityFile: import_node_path8.default.join(root, "active-identity"),
|
|
3747
|
+
globalConfigFile: import_node_path8.default.join(root, "config.json"),
|
|
3748
|
+
categoriesLocalFile: import_node_path8.default.join(root, "categories.local.json"),
|
|
3749
|
+
claudeShimFile: import_node_path8.default.join(root, "claude-shim.json"),
|
|
3750
|
+
headroomDir: import_node_path8.default.join(root, "headroom"),
|
|
3751
|
+
headroomStateFile: import_node_path8.default.join(root, "headroom", "state.json"),
|
|
3752
|
+
headroomLockFile: import_node_path8.default.join(root, "headroom", "start.lock"),
|
|
3753
|
+
headroomSessionsDir: import_node_path8.default.join(root, "headroom", "sessions"),
|
|
3754
|
+
logsDir: import_node_path8.default.join(root, "logs"),
|
|
3755
|
+
headroomLogPath: import_node_path8.default.join(root, "logs", "headroom.log"),
|
|
3756
|
+
frontdoorDir: import_node_path8.default.join(root, "frontdoor"),
|
|
3757
|
+
frontdoorCaDir: import_node_path8.default.join(root, "frontdoor", "ca"),
|
|
3758
|
+
frontdoorCaCertFile: import_node_path8.default.join(root, "frontdoor", "ca", "ca.pem"),
|
|
3759
|
+
frontdoorCaKeyFile: import_node_path8.default.join(root, "frontdoor", "ca", "ca.key"),
|
|
3760
|
+
frontdoorCaBundlesDir: import_node_path8.default.join(root, "frontdoor", "ca", "bundles"),
|
|
3761
|
+
frontdoorStateFile: import_node_path8.default.join(root, "frontdoor", "state.json"),
|
|
3762
|
+
frontdoorLockFile: import_node_path8.default.join(root, "frontdoor", "start.lock"),
|
|
3763
|
+
frontdoorSessionsDir: import_node_path8.default.join(root, "frontdoor", "sessions"),
|
|
3764
|
+
frontdoorLogPath: import_node_path8.default.join(root, "logs", "frontdoor.log"),
|
|
3765
|
+
usageDir: import_node_path8.default.join(root, "usage"),
|
|
3766
|
+
usageLogDir: import_node_path8.default.join(root, "usage", "log"),
|
|
3767
|
+
usageSnapshotsDir: import_node_path8.default.join(root, "usage", "snapshots"),
|
|
3768
|
+
usagePicksFile: import_node_path8.default.join(root, "usage", "picks.json")
|
|
3769
|
+
};
|
|
3770
|
+
}
|
|
3771
|
+
function resolveLayoutPaths() {
|
|
3772
|
+
return buildLayoutPaths(resolveAgentShimHome());
|
|
3773
|
+
}
|
|
3609
3774
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3610
3775
|
0 && (module.exports = {
|
|
3611
3776
|
AMBIENT_CREDENTIAL_VARS,
|
|
3612
3777
|
CONNECT_INTERCEPT_HOST,
|
|
3613
3778
|
CONNECT_INTERCEPT_HOSTS,
|
|
3614
3779
|
CONNECT_LIMITS,
|
|
3780
|
+
CategoryClassificationOverlaySchema,
|
|
3781
|
+
CategoryClassificationSchema,
|
|
3782
|
+
CategoryMapSchema,
|
|
3783
|
+
CliError,
|
|
3784
|
+
ConfigProfileSchema,
|
|
3785
|
+
CredentialCacheSchema,
|
|
3786
|
+
CredentialSchema,
|
|
3787
|
+
CredentialSourceSchema,
|
|
3788
|
+
DirectoryRuleSchema,
|
|
3789
|
+
DirectoryRulesSchema,
|
|
3790
|
+
EXIT_FAILURE,
|
|
3791
|
+
EXIT_USAGE,
|
|
3792
|
+
EntryValueSchema,
|
|
3615
3793
|
FARM_MANIFEST_FILENAME,
|
|
3616
3794
|
FrontDoorStartError,
|
|
3795
|
+
GlobalConfigSchema,
|
|
3617
3796
|
HeadroomStartError,
|
|
3797
|
+
IdentitySchema,
|
|
3798
|
+
PoolNameSchema,
|
|
3799
|
+
PoolSchema,
|
|
3800
|
+
PortableConfigSchema,
|
|
3801
|
+
ProviderSchema,
|
|
3618
3802
|
ROUTED_PATH_PREFIX,
|
|
3803
|
+
UsageError,
|
|
3619
3804
|
UsageSnapshotError,
|
|
3620
3805
|
UsageSnapshotSchema,
|
|
3806
|
+
WhenSchema,
|
|
3621
3807
|
buildEntryFacts,
|
|
3808
|
+
buildLayoutPaths,
|
|
3622
3809
|
carryOver,
|
|
3623
3810
|
createLeafCache,
|
|
3624
3811
|
detectAmbientCredential,
|
|
@@ -3639,7 +3826,10 @@ function evaluateAmbientCredentialGuard(params) {
|
|
|
3639
3826
|
realConnectEffects,
|
|
3640
3827
|
recoverFarm,
|
|
3641
3828
|
recoveryDiagnostics,
|
|
3829
|
+
resolveAgentShimHome,
|
|
3830
|
+
resolveClaudeHome,
|
|
3642
3831
|
resolveDecisions,
|
|
3832
|
+
resolveLayoutPaths,
|
|
3643
3833
|
resolveSupervisorConfig,
|
|
3644
3834
|
resyncFarm,
|
|
3645
3835
|
runFrontDoorSupervisor,
|