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.mjs
CHANGED
|
@@ -248,10 +248,18 @@ import { cosmiconfigSync } from "cosmiconfig";
|
|
|
248
248
|
|
|
249
249
|
// src/cliError.ts
|
|
250
250
|
var EXIT_FAILURE = 1;
|
|
251
|
+
var EXIT_USAGE = 2;
|
|
251
252
|
var CliError = class extends Error {
|
|
252
253
|
/** The process exit status this failure maps to. `EXIT_FAILURE` unless a subclass says otherwise. */
|
|
253
254
|
exitCode = EXIT_FAILURE;
|
|
254
255
|
};
|
|
256
|
+
var UsageError = class extends CliError {
|
|
257
|
+
exitCode = EXIT_USAGE;
|
|
258
|
+
constructor(message) {
|
|
259
|
+
super(message);
|
|
260
|
+
this.name = "UsageError";
|
|
261
|
+
}
|
|
262
|
+
};
|
|
255
263
|
|
|
256
264
|
// src/config/classify.ts
|
|
257
265
|
var GLOB_METACHARACTERS = /[*?[\]{}!()]/;
|
|
@@ -1212,6 +1220,8 @@ function planReconciliation(params) {
|
|
|
1212
1220
|
}
|
|
1213
1221
|
|
|
1214
1222
|
// src/legacy.ts
|
|
1223
|
+
var HOME_DIRNAME = ".agent-shim";
|
|
1224
|
+
var LEGACY_HOME_DIRNAME = ".claude-use";
|
|
1215
1225
|
var LEGACY_FARM_MANIFEST_FILENAME = ".claude-use-farm.json";
|
|
1216
1226
|
|
|
1217
1227
|
// src/launcher/lock.ts
|
|
@@ -1313,8 +1323,8 @@ var FarmManifestSchema = z2.strictObject({
|
|
|
1313
1323
|
materialised: z2.array(z2.string()),
|
|
1314
1324
|
links: z2.array(z2.strictObject({ rel: z2.string(), target: z2.string() }))
|
|
1315
1325
|
});
|
|
1316
|
-
function readFarmManifest(
|
|
1317
|
-
const raw =
|
|
1326
|
+
function readFarmManifest(fs3, farmRoot) {
|
|
1327
|
+
const raw = fs3.readFileUtf8(path4.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs3.readFileUtf8(path4.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
|
|
1318
1328
|
if (raw === void 0) {
|
|
1319
1329
|
return void 0;
|
|
1320
1330
|
}
|
|
@@ -1372,9 +1382,9 @@ function buildEntryFacts(params) {
|
|
|
1372
1382
|
entries
|
|
1373
1383
|
};
|
|
1374
1384
|
}
|
|
1375
|
-
function listSubtree(
|
|
1385
|
+
function listSubtree(fs3, root, rel) {
|
|
1376
1386
|
const absolute = path4.join(root, rel);
|
|
1377
|
-
const stat =
|
|
1387
|
+
const stat = fs3.lstat(absolute);
|
|
1378
1388
|
if (stat === void 0) {
|
|
1379
1389
|
return [];
|
|
1380
1390
|
}
|
|
@@ -1382,10 +1392,10 @@ function listSubtree(fs2, root, rel) {
|
|
|
1382
1392
|
return [{ rel, kind: "symlink" }];
|
|
1383
1393
|
}
|
|
1384
1394
|
if (stat.kind === "dir") {
|
|
1385
|
-
const children = [...
|
|
1395
|
+
const children = [...fs3.readdir(absolute)].sort().flatMap((name) => listSubtree(fs3, root, `${rel}/${name}`));
|
|
1386
1396
|
return [{ rel, kind: "dir" }, ...children];
|
|
1387
1397
|
}
|
|
1388
|
-
const contentHash =
|
|
1398
|
+
const contentHash = fs3.hashFile(absolute);
|
|
1389
1399
|
return [{ rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } }];
|
|
1390
1400
|
}
|
|
1391
1401
|
function topLevelScopeRoots(roots) {
|
|
@@ -1399,25 +1409,25 @@ function topLevelScopeRoots(roots) {
|
|
|
1399
1409
|
}
|
|
1400
1410
|
return kept;
|
|
1401
1411
|
}
|
|
1402
|
-
function reconciliationScope(
|
|
1412
|
+
function reconciliationScope(fs3, farmRoot, manifest) {
|
|
1403
1413
|
if (manifest !== void 0) {
|
|
1404
1414
|
return topLevelScopeRoots(manifest.materialised);
|
|
1405
1415
|
}
|
|
1406
|
-
return [...
|
|
1416
|
+
return [...fs3.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs3.lstat(path4.join(farmRoot, name))?.kind === "dir").sort();
|
|
1407
1417
|
}
|
|
1408
|
-
function collectFarmListing(
|
|
1409
|
-
return scopeRoots.flatMap((root) => listSubtree(
|
|
1418
|
+
function collectFarmListing(fs3, farmRoot, scopeRoots) {
|
|
1419
|
+
return scopeRoots.flatMap((root) => listSubtree(fs3, farmRoot, root));
|
|
1410
1420
|
}
|
|
1411
|
-
function collectCanonicalCounterparts(
|
|
1421
|
+
function collectCanonicalCounterparts(fs3, claudeHome, farmListing) {
|
|
1412
1422
|
const out = [];
|
|
1413
1423
|
for (const entry of farmListing) {
|
|
1414
1424
|
const absolute = path4.join(claudeHome, entry.rel);
|
|
1415
|
-
const stat =
|
|
1425
|
+
const stat = fs3.lstat(absolute);
|
|
1416
1426
|
if (stat === void 0) {
|
|
1417
1427
|
continue;
|
|
1418
1428
|
}
|
|
1419
1429
|
if (stat.kind === "file") {
|
|
1420
|
-
const contentHash =
|
|
1430
|
+
const contentHash = fs3.hashFile(absolute);
|
|
1421
1431
|
out.push({ rel: entry.rel, kind: "file", ...contentHash === void 0 ? {} : { contentHash } });
|
|
1422
1432
|
continue;
|
|
1423
1433
|
}
|
|
@@ -1777,10 +1787,6 @@ function recoveryDiagnostics(recovery, identity) {
|
|
|
1777
1787
|
// src/frontdoor/connect.ts
|
|
1778
1788
|
import { X509Certificate as X509Certificate2, createPrivateKey as createPrivateKey2 } from "node:crypto";
|
|
1779
1789
|
import * as fs from "node:fs";
|
|
1780
|
-
import * as http from "node:http";
|
|
1781
|
-
import * as https from "node:https";
|
|
1782
|
-
import * as net2 from "node:net";
|
|
1783
|
-
import * as tls from "node:tls";
|
|
1784
1790
|
|
|
1785
1791
|
// src/frontdoor/x509.ts
|
|
1786
1792
|
import { createHash, createPrivateKey, generateKeyPairSync, randomBytes, sign, X509Certificate } from "node:crypto";
|
|
@@ -2053,6 +2059,54 @@ function issueLeafCertificate(ca, names, notBefore, notAfter) {
|
|
|
2053
2059
|
return { certPem: toPem("CERTIFICATE", der), keyPem: keyPem(privateKey) };
|
|
2054
2060
|
}
|
|
2055
2061
|
|
|
2062
|
+
// src/frontdoor/tap.ts
|
|
2063
|
+
function pumpTapSession(secure, openUpstream, tap) {
|
|
2064
|
+
let upstream;
|
|
2065
|
+
let ended = false;
|
|
2066
|
+
const end = () => {
|
|
2067
|
+
if (!ended) {
|
|
2068
|
+
ended = true;
|
|
2069
|
+
tap?.onEnd();
|
|
2070
|
+
}
|
|
2071
|
+
};
|
|
2072
|
+
const drop = () => {
|
|
2073
|
+
end();
|
|
2074
|
+
secure.destroy();
|
|
2075
|
+
upstream?.destroy();
|
|
2076
|
+
};
|
|
2077
|
+
secure.once("close", () => {
|
|
2078
|
+
end();
|
|
2079
|
+
upstream?.destroy();
|
|
2080
|
+
});
|
|
2081
|
+
secure.once("error", drop);
|
|
2082
|
+
const clientAlpn = "alpnProtocol" in secure && typeof secure.alpnProtocol === "string" ? secure.alpnProtocol : void 0;
|
|
2083
|
+
void (async () => {
|
|
2084
|
+
try {
|
|
2085
|
+
upstream = await openUpstream(clientAlpn);
|
|
2086
|
+
} catch {
|
|
2087
|
+
drop();
|
|
2088
|
+
return;
|
|
2089
|
+
}
|
|
2090
|
+
if (secure.destroyed) {
|
|
2091
|
+
end();
|
|
2092
|
+
upstream.destroy();
|
|
2093
|
+
return;
|
|
2094
|
+
}
|
|
2095
|
+
if (tap !== void 0) {
|
|
2096
|
+
secure.on("data", (chunk) => {
|
|
2097
|
+
tap.onChunk("client-to-server", chunk);
|
|
2098
|
+
});
|
|
2099
|
+
upstream.on("data", (chunk) => {
|
|
2100
|
+
tap.onChunk("server-to-client", chunk);
|
|
2101
|
+
});
|
|
2102
|
+
}
|
|
2103
|
+
secure.pipe(upstream);
|
|
2104
|
+
upstream.pipe(secure);
|
|
2105
|
+
upstream.once("close", drop);
|
|
2106
|
+
upstream.once("error", drop);
|
|
2107
|
+
})();
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2056
2110
|
// src/frontdoor/capability.ts
|
|
2057
2111
|
var CONNECT_PROXY_REALM = "agent-shim front door";
|
|
2058
2112
|
var BASIC_SCHEME = "basic";
|
|
@@ -2101,10 +2155,10 @@ var FrontDoorStateSchema = z3.strictObject({
|
|
|
2101
2155
|
/** The last fatal error, kept across shutdowns so `frontdoor status` can explain a front door that is not running. */
|
|
2102
2156
|
lastError: z3.string().optional()
|
|
2103
2157
|
});
|
|
2104
|
-
function readFrontDoorState(
|
|
2158
|
+
function readFrontDoorState(fs3, stateFile) {
|
|
2105
2159
|
let raw;
|
|
2106
2160
|
try {
|
|
2107
|
-
raw =
|
|
2161
|
+
raw = fs3.readFileUtf8(stateFile);
|
|
2108
2162
|
} catch {
|
|
2109
2163
|
return void 0;
|
|
2110
2164
|
}
|
|
@@ -2118,28 +2172,28 @@ function readFrontDoorState(fs2, stateFile) {
|
|
|
2118
2172
|
return void 0;
|
|
2119
2173
|
}
|
|
2120
2174
|
}
|
|
2121
|
-
function writeFrontDoorState(
|
|
2122
|
-
|
|
2123
|
-
|
|
2175
|
+
function writeFrontDoorState(fs3, stateFile, state) {
|
|
2176
|
+
fs3.mkdirp(path5.dirname(stateFile));
|
|
2177
|
+
fs3.writeFileUtf8(stateFile, `${JSON.stringify(state, null, 2)}
|
|
2124
2178
|
`);
|
|
2125
2179
|
}
|
|
2126
2180
|
function frontDoorOrigin(state) {
|
|
2127
2181
|
const port = state?.directPort ?? state?.lastDirectPort;
|
|
2128
2182
|
return port === void 0 ? void 0 : `http://127.0.0.1:${String(port)}`;
|
|
2129
2183
|
}
|
|
2130
|
-
function writeFrontDoorSession(
|
|
2131
|
-
|
|
2132
|
-
|
|
2184
|
+
function writeFrontDoorSession(fs3, sessionsDir, session) {
|
|
2185
|
+
fs3.mkdirPrivate(sessionsDir);
|
|
2186
|
+
fs3.writeFilePrivate(path5.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
2133
2187
|
`);
|
|
2134
2188
|
}
|
|
2135
|
-
function listFrontDoorSessions(
|
|
2189
|
+
function listFrontDoorSessions(fs3, sessionsDir) {
|
|
2136
2190
|
const sessions = [];
|
|
2137
|
-
for (const name of
|
|
2191
|
+
for (const name of fs3.readdir(sessionsDir)) {
|
|
2138
2192
|
if (!name.endsWith(".json")) {
|
|
2139
2193
|
continue;
|
|
2140
2194
|
}
|
|
2141
2195
|
try {
|
|
2142
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(
|
|
2196
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs3.readFileUtf8(path5.join(sessionsDir, name)) ?? ""));
|
|
2143
2197
|
if (parsed.success) {
|
|
2144
2198
|
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt });
|
|
2145
2199
|
}
|
|
@@ -2149,14 +2203,14 @@ function listFrontDoorSessions(fs2, sessionsDir) {
|
|
|
2149
2203
|
}
|
|
2150
2204
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
2151
2205
|
}
|
|
2152
|
-
function removeFrontDoorSession(
|
|
2153
|
-
|
|
2206
|
+
function removeFrontDoorSession(fs3, sessionsDir, pid) {
|
|
2207
|
+
fs3.removeRecursive(path5.join(sessionsDir, `${String(pid)}.json`));
|
|
2154
2208
|
}
|
|
2155
|
-
function pruneDeadFrontDoorSessions(
|
|
2209
|
+
function pruneDeadFrontDoorSessions(fs3, sessionsDir, isRunning) {
|
|
2156
2210
|
const removed = [];
|
|
2157
|
-
for (const session of listFrontDoorSessions(
|
|
2211
|
+
for (const session of listFrontDoorSessions(fs3, sessionsDir)) {
|
|
2158
2212
|
if (!isRunning(session.pid)) {
|
|
2159
|
-
removeFrontDoorSession(
|
|
2213
|
+
removeFrontDoorSession(fs3, sessionsDir, session.pid);
|
|
2160
2214
|
removed.push(session.pid);
|
|
2161
2215
|
}
|
|
2162
2216
|
}
|
|
@@ -2168,8 +2222,8 @@ var FRONTDOOR_SUPERVISOR_STILL_RUNNING = -1;
|
|
|
2168
2222
|
var FRONTDOOR_POLL_MS = 1e3;
|
|
2169
2223
|
var MS_PER_MINUTE = 6e4;
|
|
2170
2224
|
async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {}) {
|
|
2171
|
-
const { fs:
|
|
2172
|
-
const previous = readFrontDoorState(
|
|
2225
|
+
const { fs: fs3, paths } = ports;
|
|
2226
|
+
const previous = readFrontDoorState(fs3, paths.frontdoorStateFile);
|
|
2173
2227
|
let lastPort = previous?.lastPort;
|
|
2174
2228
|
let lastConnectPort = previous?.lastConnectPort;
|
|
2175
2229
|
let lastDirectPort = previous?.lastDirectPort;
|
|
@@ -2179,12 +2233,12 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2179
2233
|
...lastDirectPort === void 0 ? {} : { lastDirectPort }
|
|
2180
2234
|
});
|
|
2181
2235
|
const fail = (message) => {
|
|
2182
|
-
writeFrontDoorState(
|
|
2183
|
-
|
|
2236
|
+
writeFrontDoorState(fs3, paths.frontdoorStateFile, { lastError: message, ...sticky() });
|
|
2237
|
+
fs3.removeRecursive(paths.frontdoorLockFile);
|
|
2184
2238
|
ports.log(`agent-shim frontdoor supervisor: ${message}`);
|
|
2185
2239
|
return 1;
|
|
2186
2240
|
};
|
|
2187
|
-
writeFrontDoorState(
|
|
2241
|
+
writeFrontDoorState(fs3, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
|
|
2188
2242
|
const previousSticky = lastPort;
|
|
2189
2243
|
let http2;
|
|
2190
2244
|
try {
|
|
@@ -2197,23 +2251,23 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2197
2251
|
}
|
|
2198
2252
|
lastPort = http2.port;
|
|
2199
2253
|
const previousStickyConnect = lastConnectPort;
|
|
2200
|
-
let
|
|
2254
|
+
let connect3;
|
|
2201
2255
|
try {
|
|
2202
|
-
|
|
2256
|
+
connect3 = await ports.startConnectListener(lastConnectPort);
|
|
2203
2257
|
} catch (error) {
|
|
2204
2258
|
await http2.close();
|
|
2205
2259
|
return fail(`could not start the CONNECT surface: ${error instanceof Error ? error.message : String(error)}`);
|
|
2206
2260
|
}
|
|
2207
|
-
if (previousStickyConnect !== void 0 &&
|
|
2208
|
-
ports.log(`agent-shim frontdoor supervisor: sticky CONNECT port ${String(previousStickyConnect)} was occupied; moving to ${String(
|
|
2261
|
+
if (previousStickyConnect !== void 0 && connect3.port !== previousStickyConnect) {
|
|
2262
|
+
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)`);
|
|
2209
2263
|
}
|
|
2210
|
-
lastConnectPort =
|
|
2264
|
+
lastConnectPort = connect3.port;
|
|
2211
2265
|
const previousStickyDirect = lastDirectPort;
|
|
2212
2266
|
let direct;
|
|
2213
2267
|
try {
|
|
2214
2268
|
direct = await ports.startDirectListener(lastDirectPort);
|
|
2215
2269
|
} catch (error) {
|
|
2216
|
-
await
|
|
2270
|
+
await connect3.close();
|
|
2217
2271
|
await http2.close();
|
|
2218
2272
|
return fail(`could not start the direct listener: ${error instanceof Error ? error.message : String(error)}`);
|
|
2219
2273
|
}
|
|
@@ -2221,9 +2275,9 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2221
2275
|
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)`);
|
|
2222
2276
|
}
|
|
2223
2277
|
lastDirectPort = direct.port;
|
|
2224
|
-
writeFrontDoorState(
|
|
2225
|
-
|
|
2226
|
-
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(
|
|
2278
|
+
writeFrontDoorState(fs3, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, port: http2.port, connectPort: connect3.port, directPort: direct.port, ...sticky() });
|
|
2279
|
+
fs3.removeRecursive(paths.frontdoorLockFile);
|
|
2280
|
+
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)}`);
|
|
2227
2281
|
let idleSince;
|
|
2228
2282
|
let ticks = 0;
|
|
2229
2283
|
for (; ; ) {
|
|
@@ -2231,15 +2285,15 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2231
2285
|
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
2232
2286
|
}
|
|
2233
2287
|
ticks += 1;
|
|
2234
|
-
pruneDeadFrontDoorSessions(
|
|
2235
|
-
if (listFrontDoorSessions(
|
|
2288
|
+
pruneDeadFrontDoorSessions(fs3, paths.frontdoorSessionsDir, ports.isRunning);
|
|
2289
|
+
if (listFrontDoorSessions(fs3, paths.frontdoorSessionsDir).length === 0) {
|
|
2236
2290
|
idleSince ??= ports.now();
|
|
2237
2291
|
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE) {
|
|
2238
2292
|
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
2239
2293
|
await direct.close();
|
|
2240
|
-
await
|
|
2294
|
+
await connect3.close();
|
|
2241
2295
|
await http2.close();
|
|
2242
|
-
writeFrontDoorState(
|
|
2296
|
+
writeFrontDoorState(fs3, paths.frontdoorStateFile, sticky());
|
|
2243
2297
|
return 0;
|
|
2244
2298
|
}
|
|
2245
2299
|
} else {
|
|
@@ -2294,8 +2348,8 @@ function parseConnectTarget(authority) {
|
|
|
2294
2348
|
function isInterceptedHost(host, interceptHosts) {
|
|
2295
2349
|
return interceptHosts.includes(host);
|
|
2296
2350
|
}
|
|
2297
|
-
function servedByPipeline(
|
|
2298
|
-
return
|
|
2351
|
+
function servedByPipeline(path9) {
|
|
2352
|
+
return path9?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
2299
2353
|
}
|
|
2300
2354
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
2301
2355
|
"connection",
|
|
@@ -2361,9 +2415,20 @@ function caParses(ca) {
|
|
|
2361
2415
|
return false;
|
|
2362
2416
|
}
|
|
2363
2417
|
}
|
|
2418
|
+
var TAP_ALPN_PROTOCOLS = ["h2", "http/1.1"];
|
|
2364
2419
|
async function startConnectServer(config, effects, preferredPort) {
|
|
2365
2420
|
const onUpgrade = config.capture === void 0 ? void 0 : (request3) => config.capture?.upgrade(request3);
|
|
2366
2421
|
const sessions = config.interceptHosts.map((host) => {
|
|
2422
|
+
if (config.tapHosts.includes(host)) {
|
|
2423
|
+
const tlsAcceptor2 = effects.createTlsAcceptor(
|
|
2424
|
+
config.leafFor(host),
|
|
2425
|
+
(secure) => {
|
|
2426
|
+
pumpTapSession(secure, async (clientAlpn) => await effects.connectTlsUpstream(host, HTTPS_PORT, clientAlpn), config.capture?.tapStream?.(host));
|
|
2427
|
+
},
|
|
2428
|
+
TAP_ALPN_PROTOCOLS
|
|
2429
|
+
);
|
|
2430
|
+
return { host, tlsAcceptor: tlsAcceptor2 };
|
|
2431
|
+
}
|
|
2367
2432
|
const handler = (request3, response) => {
|
|
2368
2433
|
if (host === config.routedHost && servedByPipeline(request3.url)) {
|
|
2369
2434
|
config.serveRouted(request3, response);
|
|
@@ -2388,7 +2453,7 @@ async function startConnectServer(config, effects, preferredPort) {
|
|
|
2388
2453
|
await listener.close();
|
|
2389
2454
|
for (const { httpSession, tlsAcceptor } of sessions) {
|
|
2390
2455
|
tlsAcceptor.close();
|
|
2391
|
-
httpSession
|
|
2456
|
+
httpSession?.close();
|
|
2392
2457
|
}
|
|
2393
2458
|
}
|
|
2394
2459
|
};
|
|
@@ -2564,6 +2629,40 @@ async function blindTunnel(socket, target, effects) {
|
|
|
2564
2629
|
socket.destroy();
|
|
2565
2630
|
});
|
|
2566
2631
|
}
|
|
2632
|
+
function isEnoent(error) {
|
|
2633
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
2634
|
+
}
|
|
2635
|
+
function realConnectCertStore(paths) {
|
|
2636
|
+
const read = (file) => {
|
|
2637
|
+
try {
|
|
2638
|
+
return fs.readFileSync(file, "utf8");
|
|
2639
|
+
} catch (error) {
|
|
2640
|
+
if (isEnoent(error)) {
|
|
2641
|
+
return void 0;
|
|
2642
|
+
}
|
|
2643
|
+
throw error;
|
|
2644
|
+
}
|
|
2645
|
+
};
|
|
2646
|
+
return {
|
|
2647
|
+
loadCa: () => {
|
|
2648
|
+
const certPem = read(paths.frontdoorCaCertFile);
|
|
2649
|
+
const keyPem2 = read(paths.frontdoorCaKeyFile);
|
|
2650
|
+
return certPem === void 0 || keyPem2 === void 0 ? void 0 : { certPem, keyPem: keyPem2 };
|
|
2651
|
+
},
|
|
2652
|
+
writeCa: (ca) => {
|
|
2653
|
+
fs.mkdirSync(paths.frontdoorCaDir, { recursive: true });
|
|
2654
|
+
fs.writeFileSync(paths.frontdoorCaCertFile, ca.certPem, "utf8");
|
|
2655
|
+
fs.writeFileSync(paths.frontdoorCaKeyFile, ca.keyPem, { encoding: "utf8", mode: CA_KEY_FILE_MODE });
|
|
2656
|
+
fs.chmodSync(paths.frontdoorCaKeyFile, CA_KEY_FILE_MODE);
|
|
2657
|
+
}
|
|
2658
|
+
};
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2661
|
+
// src/frontdoor/connectEffects.ts
|
|
2662
|
+
import * as http from "node:http";
|
|
2663
|
+
import * as https from "node:https";
|
|
2664
|
+
import * as net2 from "node:net";
|
|
2665
|
+
import * as tls from "node:tls";
|
|
2567
2666
|
function realConnectEffects() {
|
|
2568
2667
|
const plainAgent = new http.Agent({ keepAlive: true });
|
|
2569
2668
|
const tlsAgent = new https.Agent({ keepAlive: true });
|
|
@@ -2609,10 +2708,13 @@ function realConnectEffects() {
|
|
|
2609
2708
|
}
|
|
2610
2709
|
return await listenOnce(0, onSocket);
|
|
2611
2710
|
},
|
|
2612
|
-
createTlsAcceptor: (leaf, onSecure) => {
|
|
2613
|
-
const server = tls.createServer(
|
|
2614
|
-
|
|
2615
|
-
|
|
2711
|
+
createTlsAcceptor: (leaf, onSecure, alpnProtocols) => {
|
|
2712
|
+
const server = tls.createServer(
|
|
2713
|
+
{ key: leaf.keyPem, cert: leaf.certPem, ...alpnProtocols === void 0 ? {} : { ALPNProtocols: [...alpnProtocols] } },
|
|
2714
|
+
(secure) => {
|
|
2715
|
+
onSecure(secure);
|
|
2716
|
+
}
|
|
2717
|
+
);
|
|
2616
2718
|
server.on("clientError", (_error, socket) => {
|
|
2617
2719
|
socket.destroy();
|
|
2618
2720
|
});
|
|
@@ -2647,6 +2749,13 @@ function realConnectEffects() {
|
|
|
2647
2749
|
}
|
|
2648
2750
|
};
|
|
2649
2751
|
},
|
|
2752
|
+
connectTlsUpstream: async (host, port, clientAlpn) => await new Promise((resolve, reject) => {
|
|
2753
|
+
const socket = tls.connect({ host, port, servername: host, ...clientAlpn === void 0 ? {} : { ALPNProtocols: [clientAlpn] } });
|
|
2754
|
+
socket.once("secureConnect", () => {
|
|
2755
|
+
resolve(socket);
|
|
2756
|
+
});
|
|
2757
|
+
socket.once("error", reject);
|
|
2758
|
+
}),
|
|
2650
2759
|
connectTcp: async (host, port) => await new Promise((resolve, reject) => {
|
|
2651
2760
|
const socket = net2.connect({ host, port });
|
|
2652
2761
|
socket.once("connect", () => {
|
|
@@ -2710,34 +2819,6 @@ function realConnectEffects() {
|
|
|
2710
2819
|
}
|
|
2711
2820
|
};
|
|
2712
2821
|
}
|
|
2713
|
-
function isEnoent(error) {
|
|
2714
|
-
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
2715
|
-
}
|
|
2716
|
-
function realConnectCertStore(paths) {
|
|
2717
|
-
const read = (file) => {
|
|
2718
|
-
try {
|
|
2719
|
-
return fs.readFileSync(file, "utf8");
|
|
2720
|
-
} catch (error) {
|
|
2721
|
-
if (isEnoent(error)) {
|
|
2722
|
-
return void 0;
|
|
2723
|
-
}
|
|
2724
|
-
throw error;
|
|
2725
|
-
}
|
|
2726
|
-
};
|
|
2727
|
-
return {
|
|
2728
|
-
loadCa: () => {
|
|
2729
|
-
const certPem = read(paths.frontdoorCaCertFile);
|
|
2730
|
-
const keyPem2 = read(paths.frontdoorCaKeyFile);
|
|
2731
|
-
return certPem === void 0 || keyPem2 === void 0 ? void 0 : { certPem, keyPem: keyPem2 };
|
|
2732
|
-
},
|
|
2733
|
-
writeCa: (ca) => {
|
|
2734
|
-
fs.mkdirSync(paths.frontdoorCaDir, { recursive: true });
|
|
2735
|
-
fs.writeFileSync(paths.frontdoorCaCertFile, ca.certPem, "utf8");
|
|
2736
|
-
fs.writeFileSync(paths.frontdoorCaKeyFile, ca.keyPem, { encoding: "utf8", mode: CA_KEY_FILE_MODE });
|
|
2737
|
-
fs.chmodSync(paths.frontdoorCaKeyFile, CA_KEY_FILE_MODE);
|
|
2738
|
-
}
|
|
2739
|
-
};
|
|
2740
|
-
}
|
|
2741
2822
|
|
|
2742
2823
|
// src/frontdoor/ensure.ts
|
|
2743
2824
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
@@ -2778,16 +2859,16 @@ function parseJson(raw, schema) {
|
|
|
2778
2859
|
const parsed = schema.safeParse(JSON.parse(raw));
|
|
2779
2860
|
return parsed.success ? parsed.data : void 0;
|
|
2780
2861
|
}
|
|
2781
|
-
function readHeadroomState(
|
|
2862
|
+
function readHeadroomState(fs3, stateFile) {
|
|
2782
2863
|
try {
|
|
2783
|
-
return parseJson(
|
|
2864
|
+
return parseJson(fs3.readFileUtf8(stateFile), HeadroomStateSchema);
|
|
2784
2865
|
} catch {
|
|
2785
2866
|
return void 0;
|
|
2786
2867
|
}
|
|
2787
2868
|
}
|
|
2788
|
-
function writeHeadroomState(
|
|
2789
|
-
|
|
2790
|
-
|
|
2869
|
+
function writeHeadroomState(fs3, stateFile, state) {
|
|
2870
|
+
fs3.mkdirp(path6.dirname(stateFile));
|
|
2871
|
+
fs3.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
2791
2872
|
`);
|
|
2792
2873
|
}
|
|
2793
2874
|
function headroomAllowlist(providers) {
|
|
@@ -2807,14 +2888,14 @@ function headroomUpstreams(providers, frontDoorOrigin2) {
|
|
|
2807
2888
|
function hashAllowlist(allowlist) {
|
|
2808
2889
|
return createHash2("sha256").update(allowlist.join("\n")).digest("hex");
|
|
2809
2890
|
}
|
|
2810
|
-
function readAllProviders(
|
|
2891
|
+
function readAllProviders(fs3, providersDir) {
|
|
2811
2892
|
const result = [];
|
|
2812
|
-
for (const name of
|
|
2893
|
+
for (const name of fs3.readdir(providersDir)) {
|
|
2813
2894
|
if (!name.endsWith(".json")) {
|
|
2814
2895
|
continue;
|
|
2815
2896
|
}
|
|
2816
2897
|
try {
|
|
2817
|
-
const parsed = parseJson(
|
|
2898
|
+
const parsed = parseJson(fs3.readFileUtf8(path6.join(providersDir, name)), ProviderSchema);
|
|
2818
2899
|
if (parsed !== void 0) {
|
|
2819
2900
|
result.push({ name: name.slice(0, -".json".length), provider: parsed });
|
|
2820
2901
|
}
|
|
@@ -2824,22 +2905,22 @@ function readAllProviders(fs2, providersDir) {
|
|
|
2824
2905
|
}
|
|
2825
2906
|
return result;
|
|
2826
2907
|
}
|
|
2827
|
-
function writeSession(
|
|
2828
|
-
|
|
2829
|
-
|
|
2908
|
+
function writeSession(fs3, sessionsDir, session) {
|
|
2909
|
+
fs3.mkdirp(sessionsDir);
|
|
2910
|
+
fs3.writeFileUtf8(path6.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
|
|
2830
2911
|
`);
|
|
2831
2912
|
}
|
|
2832
|
-
function removeSession(
|
|
2833
|
-
|
|
2913
|
+
function removeSession(fs3, sessionsDir, pid) {
|
|
2914
|
+
fs3.removeRecursive(path6.join(sessionsDir, `${String(pid)}.json`));
|
|
2834
2915
|
}
|
|
2835
|
-
function listSessions(
|
|
2916
|
+
function listSessions(fs3, sessionsDir) {
|
|
2836
2917
|
const sessions = [];
|
|
2837
|
-
for (const name of
|
|
2918
|
+
for (const name of fs3.readdir(sessionsDir)) {
|
|
2838
2919
|
if (!name.endsWith(".json")) {
|
|
2839
2920
|
continue;
|
|
2840
2921
|
}
|
|
2841
2922
|
try {
|
|
2842
|
-
const parsed = parseJson(
|
|
2923
|
+
const parsed = parseJson(fs3.readFileUtf8(path6.join(sessionsDir, name)), HeadroomSessionSchema);
|
|
2843
2924
|
if (parsed !== void 0) {
|
|
2844
2925
|
sessions.push(parsed);
|
|
2845
2926
|
}
|
|
@@ -2849,22 +2930,22 @@ function listSessions(fs2, sessionsDir) {
|
|
|
2849
2930
|
}
|
|
2850
2931
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
2851
2932
|
}
|
|
2852
|
-
function sessionsForSupervisor(
|
|
2853
|
-
return listSessions(
|
|
2933
|
+
function sessionsForSupervisor(fs3, sessionsDir, supervisorPid) {
|
|
2934
|
+
return listSessions(fs3, sessionsDir).filter((session) => session.supervisorPid === supervisorPid);
|
|
2854
2935
|
}
|
|
2855
|
-
function pruneDeadSessions(
|
|
2936
|
+
function pruneDeadSessions(fs3, sessionsDir, isRunning) {
|
|
2856
2937
|
const removed = [];
|
|
2857
|
-
for (const session of listSessions(
|
|
2938
|
+
for (const session of listSessions(fs3, sessionsDir)) {
|
|
2858
2939
|
if (!isRunning(session.pid)) {
|
|
2859
|
-
removeSession(
|
|
2940
|
+
removeSession(fs3, sessionsDir, session.pid);
|
|
2860
2941
|
removed.push(session.pid);
|
|
2861
2942
|
}
|
|
2862
2943
|
}
|
|
2863
2944
|
return removed;
|
|
2864
2945
|
}
|
|
2865
|
-
function readStartLock(
|
|
2946
|
+
function readStartLock(fs3, lockFile) {
|
|
2866
2947
|
try {
|
|
2867
|
-
return parseJson(
|
|
2948
|
+
return parseJson(fs3.readFileUtf8(lockFile), HeadroomLockSchema);
|
|
2868
2949
|
} catch {
|
|
2869
2950
|
return void 0;
|
|
2870
2951
|
}
|
|
@@ -3101,9 +3182,9 @@ function snapshotPath(snapshotsDir, identity) {
|
|
|
3101
3182
|
}
|
|
3102
3183
|
return path7.join(snapshotsDir, `${identity}.json`);
|
|
3103
3184
|
}
|
|
3104
|
-
function readUsageSnapshot(
|
|
3185
|
+
function readUsageSnapshot(fs3, snapshotsDir, identity) {
|
|
3105
3186
|
const file = snapshotPath(snapshotsDir, identity);
|
|
3106
|
-
const raw =
|
|
3187
|
+
const raw = fs3.readFileUtf8(file);
|
|
3107
3188
|
if (raw === void 0) {
|
|
3108
3189
|
return void 0;
|
|
3109
3190
|
}
|
|
@@ -3119,8 +3200,8 @@ function readUsageSnapshot(fs2, snapshotsDir, identity) {
|
|
|
3119
3200
|
}
|
|
3120
3201
|
return snapshot.data;
|
|
3121
3202
|
}
|
|
3122
|
-
function listUsageSnapshots(
|
|
3123
|
-
return
|
|
3203
|
+
function listUsageSnapshots(fs3, snapshotsDir) {
|
|
3204
|
+
return fs3.readdir(snapshotsDir).flatMap((name) => {
|
|
3124
3205
|
if (!name.endsWith(".json")) {
|
|
3125
3206
|
return [];
|
|
3126
3207
|
}
|
|
@@ -3128,7 +3209,7 @@ function listUsageSnapshots(fs2, snapshotsDir) {
|
|
|
3128
3209
|
if (!isIdentityName(identity)) {
|
|
3129
3210
|
return [];
|
|
3130
3211
|
}
|
|
3131
|
-
const snapshot = readUsageSnapshot(
|
|
3212
|
+
const snapshot = readUsageSnapshot(fs3, snapshotsDir, identity);
|
|
3132
3213
|
return snapshot === void 0 ? [] : [snapshot];
|
|
3133
3214
|
}).sort((left, right) => left.identity.localeCompare(right.identity));
|
|
3134
3215
|
}
|
|
@@ -3295,9 +3376,9 @@ function compareVersions(a, b) {
|
|
|
3295
3376
|
}
|
|
3296
3377
|
var HEADROOM_SUPERVISOR_STILL_RUNNING = -1;
|
|
3297
3378
|
async function runSupervisor(initialConfig, ports, options = {}) {
|
|
3298
|
-
const { fs:
|
|
3379
|
+
const { fs: fs3, paths } = ports;
|
|
3299
3380
|
let config = initialConfig;
|
|
3300
|
-
const previousState = readHeadroomState(
|
|
3381
|
+
const previousState = readHeadroomState(fs3, paths.headroomStateFile);
|
|
3301
3382
|
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
3302
3383
|
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
3303
3384
|
return 0;
|
|
@@ -3306,19 +3387,19 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3306
3387
|
let lastPort = previousState?.lastPort;
|
|
3307
3388
|
const sticky = () => lastPort === void 0 ? {} : { lastPort };
|
|
3308
3389
|
const ownsState = () => {
|
|
3309
|
-
const owner = readHeadroomState(
|
|
3390
|
+
const owner = readHeadroomState(fs3, paths.headroomStateFile)?.supervisorPid;
|
|
3310
3391
|
return owner === void 0 || owner === ports.ownPid || !ports.isRunning(owner);
|
|
3311
3392
|
};
|
|
3312
3393
|
const writeOwnState = (state) => {
|
|
3313
3394
|
if (!ownsState()) {
|
|
3314
3395
|
return false;
|
|
3315
3396
|
}
|
|
3316
|
-
writeHeadroomState(
|
|
3397
|
+
writeHeadroomState(fs3, paths.headroomStateFile, state);
|
|
3317
3398
|
return true;
|
|
3318
3399
|
};
|
|
3319
3400
|
const fail = (message) => {
|
|
3320
3401
|
if (writeOwnState({ lastError: message, ...sticky() })) {
|
|
3321
|
-
|
|
3402
|
+
fs3.removeRecursive(paths.headroomLockFile);
|
|
3322
3403
|
}
|
|
3323
3404
|
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
3324
3405
|
return 1;
|
|
@@ -3367,7 +3448,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3367
3448
|
const settingsHash = hashSettings(config.settings);
|
|
3368
3449
|
const allowlist = allowlistOf(ports);
|
|
3369
3450
|
const allowlistHash = hashAllowlist(allowlist);
|
|
3370
|
-
pruneDeadSessions(
|
|
3451
|
+
pruneDeadSessions(fs3, paths.headroomSessionsDir, ports.isRunning);
|
|
3371
3452
|
const ownsNow = ownsState();
|
|
3372
3453
|
if (!ownsNow && !superseded) {
|
|
3373
3454
|
ports.log("agent-shim headroom supervisor: another supervisor now owns state.json; serving this daemon's own sessions until they end");
|
|
@@ -3419,7 +3500,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3419
3500
|
...sticky()
|
|
3420
3501
|
});
|
|
3421
3502
|
if (recorded) {
|
|
3422
|
-
|
|
3503
|
+
fs3.removeRecursive(paths.headroomLockFile);
|
|
3423
3504
|
}
|
|
3424
3505
|
idleSince = void 0;
|
|
3425
3506
|
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on 127.0.0.1:${String(port)}`);
|
|
@@ -3434,7 +3515,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3434
3515
|
}
|
|
3435
3516
|
} else {
|
|
3436
3517
|
if (runningHash !== allowlistHash || runningSettingsHash !== settingsHash || installedSource !== config.source) {
|
|
3437
|
-
if (sessionsForSupervisor(
|
|
3518
|
+
if (sessionsForSupervisor(fs3, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
3438
3519
|
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
3439
3520
|
ports.stopProcess(headroomPid);
|
|
3440
3521
|
headroomPid = void 0;
|
|
@@ -3443,7 +3524,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3443
3524
|
continue;
|
|
3444
3525
|
}
|
|
3445
3526
|
}
|
|
3446
|
-
const sessions = sessionsForSupervisor(
|
|
3527
|
+
const sessions = sessionsForSupervisor(fs3, paths.headroomSessionsDir, ports.ownPid);
|
|
3447
3528
|
if (sessions.length === 0) {
|
|
3448
3529
|
idleSince ??= ports.now();
|
|
3449
3530
|
const idleMs = ports.now() - idleSince;
|
|
@@ -3465,9 +3546,9 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3465
3546
|
await ports.sleep(HEADROOM_POLL_MS);
|
|
3466
3547
|
}
|
|
3467
3548
|
}
|
|
3468
|
-
function currentHeadroomAllowlist(
|
|
3469
|
-
const providers = readAllProviders(
|
|
3470
|
-
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(
|
|
3549
|
+
function currentHeadroomAllowlist(fs3, paths) {
|
|
3550
|
+
const providers = readAllProviders(fs3, paths.providersDir).map((entry) => entry.provider);
|
|
3551
|
+
return headroomAllowlist(headroomUpstreams(providers, frontDoorOrigin(readFrontDoorState(fs3, paths.frontdoorStateFile))));
|
|
3471
3552
|
}
|
|
3472
3553
|
function allowlistOf(ports) {
|
|
3473
3554
|
return currentHeadroomAllowlist(ports.fs, ports.paths);
|
|
@@ -3531,18 +3612,99 @@ function evaluateAmbientCredentialGuard(params) {
|
|
|
3531
3612
|
message: formatAmbientCredentialGuardMessage(detected.variable, params.identityName)
|
|
3532
3613
|
};
|
|
3533
3614
|
}
|
|
3615
|
+
|
|
3616
|
+
// src/paths.ts
|
|
3617
|
+
import fs2 from "node:fs";
|
|
3618
|
+
import os from "node:os";
|
|
3619
|
+
import path8 from "node:path";
|
|
3620
|
+
function resolveAgentShimHome(env = process.env, home = os.homedir(), isDirectory = isExistingDirectory) {
|
|
3621
|
+
const fromEnv = env.AGENT_SHIM_HOME;
|
|
3622
|
+
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
3623
|
+
return fromEnv;
|
|
3624
|
+
}
|
|
3625
|
+
const current = path8.join(home, HOME_DIRNAME);
|
|
3626
|
+
const legacy = path8.join(home, LEGACY_HOME_DIRNAME);
|
|
3627
|
+
return !isDirectory(current) && isDirectory(legacy) ? legacy : current;
|
|
3628
|
+
}
|
|
3629
|
+
function isExistingDirectory(candidate) {
|
|
3630
|
+
return fs2.statSync(candidate, { throwIfNoEntry: false })?.isDirectory() ?? false;
|
|
3631
|
+
}
|
|
3632
|
+
function resolveClaudeHome() {
|
|
3633
|
+
const fromEnv = process.env.AGENT_SHIM_CLAUDE_HOME;
|
|
3634
|
+
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
3635
|
+
return fromEnv;
|
|
3636
|
+
}
|
|
3637
|
+
return path8.join(os.homedir(), ".claude");
|
|
3638
|
+
}
|
|
3639
|
+
function buildLayoutPaths(root) {
|
|
3640
|
+
return {
|
|
3641
|
+
root,
|
|
3642
|
+
identitiesDir: path8.join(root, "identities"),
|
|
3643
|
+
configProfilesDir: path8.join(root, "config-profiles"),
|
|
3644
|
+
providersDir: path8.join(root, "providers"),
|
|
3645
|
+
directoryRulesFile: path8.join(root, "directory-rules.json"),
|
|
3646
|
+
activeIdentityFile: path8.join(root, "active-identity"),
|
|
3647
|
+
globalConfigFile: path8.join(root, "config.json"),
|
|
3648
|
+
categoriesLocalFile: path8.join(root, "categories.local.json"),
|
|
3649
|
+
claudeShimFile: path8.join(root, "claude-shim.json"),
|
|
3650
|
+
headroomDir: path8.join(root, "headroom"),
|
|
3651
|
+
headroomStateFile: path8.join(root, "headroom", "state.json"),
|
|
3652
|
+
headroomLockFile: path8.join(root, "headroom", "start.lock"),
|
|
3653
|
+
headroomSessionsDir: path8.join(root, "headroom", "sessions"),
|
|
3654
|
+
logsDir: path8.join(root, "logs"),
|
|
3655
|
+
headroomLogPath: path8.join(root, "logs", "headroom.log"),
|
|
3656
|
+
frontdoorDir: path8.join(root, "frontdoor"),
|
|
3657
|
+
frontdoorCaDir: path8.join(root, "frontdoor", "ca"),
|
|
3658
|
+
frontdoorCaCertFile: path8.join(root, "frontdoor", "ca", "ca.pem"),
|
|
3659
|
+
frontdoorCaKeyFile: path8.join(root, "frontdoor", "ca", "ca.key"),
|
|
3660
|
+
frontdoorCaBundlesDir: path8.join(root, "frontdoor", "ca", "bundles"),
|
|
3661
|
+
frontdoorStateFile: path8.join(root, "frontdoor", "state.json"),
|
|
3662
|
+
frontdoorLockFile: path8.join(root, "frontdoor", "start.lock"),
|
|
3663
|
+
frontdoorSessionsDir: path8.join(root, "frontdoor", "sessions"),
|
|
3664
|
+
frontdoorLogPath: path8.join(root, "logs", "frontdoor.log"),
|
|
3665
|
+
usageDir: path8.join(root, "usage"),
|
|
3666
|
+
usageLogDir: path8.join(root, "usage", "log"),
|
|
3667
|
+
usageSnapshotsDir: path8.join(root, "usage", "snapshots"),
|
|
3668
|
+
usagePicksFile: path8.join(root, "usage", "picks.json")
|
|
3669
|
+
};
|
|
3670
|
+
}
|
|
3671
|
+
function resolveLayoutPaths() {
|
|
3672
|
+
return buildLayoutPaths(resolveAgentShimHome());
|
|
3673
|
+
}
|
|
3534
3674
|
export {
|
|
3535
3675
|
AMBIENT_CREDENTIAL_VARS,
|
|
3536
3676
|
CONNECT_INTERCEPT_HOST,
|
|
3537
3677
|
CONNECT_INTERCEPT_HOSTS,
|
|
3538
3678
|
CONNECT_LIMITS,
|
|
3679
|
+
CategoryClassificationOverlaySchema,
|
|
3680
|
+
CategoryClassificationSchema,
|
|
3681
|
+
CategoryMapSchema,
|
|
3682
|
+
CliError,
|
|
3683
|
+
ConfigProfileSchema,
|
|
3684
|
+
CredentialCacheSchema,
|
|
3685
|
+
CredentialSchema,
|
|
3686
|
+
CredentialSourceSchema,
|
|
3687
|
+
DirectoryRuleSchema,
|
|
3688
|
+
DirectoryRulesSchema,
|
|
3689
|
+
EXIT_FAILURE,
|
|
3690
|
+
EXIT_USAGE,
|
|
3691
|
+
EntryValueSchema,
|
|
3539
3692
|
FARM_MANIFEST_FILENAME,
|
|
3540
3693
|
FrontDoorStartError,
|
|
3694
|
+
GlobalConfigSchema,
|
|
3541
3695
|
HeadroomStartError,
|
|
3696
|
+
IdentitySchema,
|
|
3697
|
+
PoolNameSchema,
|
|
3698
|
+
PoolSchema,
|
|
3699
|
+
PortableConfigSchema,
|
|
3700
|
+
ProviderSchema,
|
|
3542
3701
|
ROUTED_PATH_PREFIX,
|
|
3702
|
+
UsageError,
|
|
3543
3703
|
UsageSnapshotError,
|
|
3544
3704
|
UsageSnapshotSchema,
|
|
3705
|
+
WhenSchema,
|
|
3545
3706
|
buildEntryFacts,
|
|
3707
|
+
buildLayoutPaths,
|
|
3546
3708
|
carryOver,
|
|
3547
3709
|
createLeafCache,
|
|
3548
3710
|
detectAmbientCredential,
|
|
@@ -3563,7 +3725,10 @@ export {
|
|
|
3563
3725
|
realConnectEffects,
|
|
3564
3726
|
recoverFarm,
|
|
3565
3727
|
recoveryDiagnostics,
|
|
3728
|
+
resolveAgentShimHome,
|
|
3729
|
+
resolveClaudeHome,
|
|
3566
3730
|
resolveDecisions,
|
|
3731
|
+
resolveLayoutPaths,
|
|
3567
3732
|
resolveSupervisorConfig,
|
|
3568
3733
|
resyncFarm,
|
|
3569
3734
|
runFrontDoorSupervisor,
|