claude-use 6.2.2 → 7.1.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 +90 -79
- package/dist/cli.cjs +716 -621
- package/dist/index.cjs +56 -41
- package/dist/index.mjs +56 -41
- package/dist/types/cliError.d.ts +1 -1
- package/dist/types/config/classify.d.ts +3 -3
- package/dist/types/config/schema.d.ts +13 -13
- package/dist/types/frontdoor/capability.d.ts +3 -3
- package/dist/types/frontdoor/connect.d.ts +2 -2
- package/dist/types/frontdoor/ensure.d.ts +2 -2
- package/dist/types/frontdoor/probe.d.ts +1 -1
- package/dist/types/frontdoor/supervisor.d.ts +1 -1
- package/dist/types/frontdoor/x509.d.ts +1 -1
- package/dist/types/headroom/source.d.ts +8 -0
- package/dist/types/headroom/state.d.ts +1 -1
- package/dist/types/headroom/supervisor.d.ts +2 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/launcher/farm.d.ts +5 -5
- package/dist/types/launcher/guard.d.ts +3 -3
- package/dist/types/launcher/lock.d.ts +1 -1
- package/dist/types/launcher/ports.d.ts +3 -3
- package/dist/types/legacy.d.ts +24 -0
- package/dist/types/paths.d.ts +12 -10
- package/dist/types/resolve/conditions.d.ts +1 -1
- package/dist/types/resolve/match.d.ts +1 -1
- package/dist/types/resolve/reconcile.d.ts +1 -1
- package/dist/types/resolve/types.d.ts +3 -3
- package/dist/types/resolve/walk.d.ts +6 -6
- package/dist/types/usage/read.d.ts +1 -1
- package/dist/types/usage/schema.d.ts +2 -2
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -91,7 +91,7 @@ function expandAllCategoryKey(pairs) {
|
|
|
91
91
|
if (all === void 0) {
|
|
92
92
|
return { ...rest };
|
|
93
93
|
}
|
|
94
|
-
const expanded = Object.fromEntries(OVERRIDABLE_CATEGORIES.map((category) => [category, all]));
|
|
94
|
+
const expanded = Object.fromEntries(OVERRIDABLE_CATEGORIES.filter((category) => !all || category !== "runtime").map((category) => [category, all]));
|
|
95
95
|
return { ...expanded, ...rest };
|
|
96
96
|
}
|
|
97
97
|
var CategoryMapSchema = import_zod.z.strictObject({
|
|
@@ -165,7 +165,7 @@ var CredentialSchema = import_zod.z.strictObject({
|
|
|
165
165
|
var ProviderCredentialSchema = CredentialSchema.extend({ target: import_zod.z.enum(PROVIDER_CREDENTIAL_TARGETS).optional() });
|
|
166
166
|
var RESERVED_PROVIDER_ENV_KEYS = Object.values(CREDENTIAL_TARGET_VARS);
|
|
167
167
|
var ProviderEnvSchema = import_zod.z.record(import_zod.z.string().min(1), import_zod.z.string()).refine((env) => !Object.keys(env).some((key) => RESERVED_PROVIDER_ENV_KEYS.includes(key)), {
|
|
168
|
-
message: `env may not set ${RESERVED_PROVIDER_ENV_KEYS.join(", ")}: the credential block's target sets one and
|
|
168
|
+
message: `env may not set ${RESERVED_PROVIDER_ENV_KEYS.join(", ")}: the credential block's target sets one and agent-shim removes the others`
|
|
169
169
|
});
|
|
170
170
|
var CODEX_EFFORTS = ["none", "low", "medium", "high"];
|
|
171
171
|
var CODEX_DEFAULT_TIER_MODELS = Object.freeze({
|
|
@@ -808,7 +808,7 @@ function resolveEntry(relPath, params) {
|
|
|
808
808
|
diagnostics.push({
|
|
809
809
|
code: "UNCLASSIFIED_ENTRY",
|
|
810
810
|
severity: "warning",
|
|
811
|
-
message: `"${head}" is not in the category map, so it is excluded. Run \`
|
|
811
|
+
message: `"${head}" is not in the category map, so it is excluded. Run \`agent-shim configure\` to classify it, which records the answer in the local overlay without touching the shipped default map.`,
|
|
812
812
|
subject: head
|
|
813
813
|
});
|
|
814
814
|
return { decision: { relPath, shared: false, via: "unclassified", category }, diagnostics };
|
|
@@ -1285,6 +1285,9 @@ function planReconciliation(params) {
|
|
|
1285
1285
|
return { actions, diagnostics, conservative };
|
|
1286
1286
|
}
|
|
1287
1287
|
|
|
1288
|
+
// src/legacy.ts
|
|
1289
|
+
var LEGACY_FARM_MANIFEST_FILENAME = ".claude-use-farm.json";
|
|
1290
|
+
|
|
1288
1291
|
// src/launcher/lock.ts
|
|
1289
1292
|
var import_node_crypto = require("node:crypto");
|
|
1290
1293
|
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
@@ -1294,7 +1297,7 @@ var DEFAULT_MAX_ATTEMPTS = 200;
|
|
|
1294
1297
|
var IdentityLockBusyError = class extends CliError {
|
|
1295
1298
|
constructor(identity, lockPath, holderPid) {
|
|
1296
1299
|
super(
|
|
1297
|
-
`Another
|
|
1300
|
+
`Another agent-shim resync is already running for identity "${identity}"` + (holderPid === void 0 ? "" : ` (pid ${String(holderPid)})`) + `. Its lock at ${lockPath} was still held after the full retry budget; nothing was changed.`
|
|
1298
1301
|
);
|
|
1299
1302
|
this.identity = identity;
|
|
1300
1303
|
this.lockPath = lockPath;
|
|
@@ -1373,7 +1376,7 @@ function acquireIdentityLock(params) {
|
|
|
1373
1376
|
}
|
|
1374
1377
|
|
|
1375
1378
|
// src/launcher/farm.ts
|
|
1376
|
-
var FARM_MANIFEST_FILENAME = ".
|
|
1379
|
+
var FARM_MANIFEST_FILENAME = ".agent-shim-farm.json";
|
|
1377
1380
|
var FarmManifestSchema = import_zod2.z.strictObject({
|
|
1378
1381
|
version: import_zod2.z.literal(1),
|
|
1379
1382
|
builtAtMs: import_zod2.z.number(),
|
|
@@ -1385,7 +1388,7 @@ var FarmManifestSchema = import_zod2.z.strictObject({
|
|
|
1385
1388
|
links: import_zod2.z.array(import_zod2.z.strictObject({ rel: import_zod2.z.string(), target: import_zod2.z.string() }))
|
|
1386
1389
|
});
|
|
1387
1390
|
function readFarmManifest(fs2, farmRoot) {
|
|
1388
|
-
const raw = fs2.readFileUtf8(import_node_path4.default.join(farmRoot, FARM_MANIFEST_FILENAME));
|
|
1391
|
+
const raw = fs2.readFileUtf8(import_node_path4.default.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs2.readFileUtf8(import_node_path4.default.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
|
|
1389
1392
|
if (raw === void 0) {
|
|
1390
1393
|
return void 0;
|
|
1391
1394
|
}
|
|
@@ -1474,7 +1477,7 @@ function reconciliationScope(fs2, farmRoot, manifest) {
|
|
|
1474
1477
|
if (manifest !== void 0) {
|
|
1475
1478
|
return topLevelScopeRoots(manifest.materialised);
|
|
1476
1479
|
}
|
|
1477
|
-
return [...fs2.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && fs2.lstat(import_node_path4.default.join(farmRoot, name))?.kind === "dir").sort();
|
|
1480
|
+
return [...fs2.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs2.lstat(import_node_path4.default.join(farmRoot, name))?.kind === "dir").sort();
|
|
1478
1481
|
}
|
|
1479
1482
|
function collectFarmListing(fs2, farmRoot, scopeRoots) {
|
|
1480
1483
|
return scopeRoots.flatMap((root) => listSubtree(fs2, farmRoot, root));
|
|
@@ -1498,7 +1501,7 @@ function collectCanonicalCounterparts(fs2, claudeHome, farmListing) {
|
|
|
1498
1501
|
}
|
|
1499
1502
|
function carryOver(params) {
|
|
1500
1503
|
const manifest = readFarmManifest(params.fs, params.previousRoot);
|
|
1501
|
-
const accounted = /* @__PURE__ */ new Set([FARM_MANIFEST_FILENAME]);
|
|
1504
|
+
const accounted = /* @__PURE__ */ new Set([FARM_MANIFEST_FILENAME, LEGACY_FARM_MANIFEST_FILENAME]);
|
|
1502
1505
|
for (const rel of manifest?.materialised ?? []) {
|
|
1503
1506
|
const head = rel.split("/")[0];
|
|
1504
1507
|
if (head !== void 0 && head !== "") {
|
|
@@ -1796,7 +1799,7 @@ function resyncFarm(params) {
|
|
|
1796
1799
|
diagnostics.push({
|
|
1797
1800
|
code: "FARM_PREVIOUS_RETAINED",
|
|
1798
1801
|
severity: "warning",
|
|
1799
|
-
message: `The superseded farm was left at ${swap.retainedPrevious} because it still holds ${swap.collided.join(", ")}, which the new farm has its own entry for. Nothing was overwritten in either direction; run \`
|
|
1802
|
+
message: `The superseded farm was left at ${swap.retainedPrevious} because it still holds ${swap.collided.join(", ")}, which the new farm has its own entry for. Nothing was overwritten in either direction; run \`agent-shim identity resolve-conflicts ${params.identity}\` to resolve it interactively.`,
|
|
1800
1803
|
subject: swap.retainedPrevious
|
|
1801
1804
|
});
|
|
1802
1805
|
}
|
|
@@ -1833,7 +1836,7 @@ function recoveryDiagnostics(recovery, identity) {
|
|
|
1833
1836
|
}
|
|
1834
1837
|
if (recovery.retained.length > 0) {
|
|
1835
1838
|
parts.push(
|
|
1836
|
-
`kept ${recovery.retained.join(", ")}, which still holds data the current farm also has an entry for \u2014 run \`
|
|
1839
|
+
`kept ${recovery.retained.join(", ")}, which still holds data the current farm also has an entry for \u2014 run \`agent-shim identity resolve-conflicts ${identity}\` to resolve it interactively`
|
|
1837
1840
|
);
|
|
1838
1841
|
}
|
|
1839
1842
|
return [
|
|
@@ -2125,7 +2128,7 @@ function issueLeafCertificate(ca, names, notBefore, notAfter) {
|
|
|
2125
2128
|
}
|
|
2126
2129
|
|
|
2127
2130
|
// src/frontdoor/capability.ts
|
|
2128
|
-
var CONNECT_PROXY_REALM = "
|
|
2131
|
+
var CONNECT_PROXY_REALM = "agent-shim front door";
|
|
2129
2132
|
var BASIC_SCHEME = "basic";
|
|
2130
2133
|
function capabilityFromProxyAuthorization(value) {
|
|
2131
2134
|
const trimmed = value.trim();
|
|
@@ -2252,7 +2255,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2252
2255
|
const fail = (message) => {
|
|
2253
2256
|
writeFrontDoorState(fs2, paths.frontdoorStateFile, { lastError: message, ...sticky() });
|
|
2254
2257
|
fs2.removeRecursive(paths.frontdoorLockFile);
|
|
2255
|
-
ports.log(`
|
|
2258
|
+
ports.log(`agent-shim frontdoor supervisor: ${message}`);
|
|
2256
2259
|
return 1;
|
|
2257
2260
|
};
|
|
2258
2261
|
writeFrontDoorState(fs2, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
|
|
@@ -2264,7 +2267,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2264
2267
|
return fail(`could not start the provider listener: ${error instanceof Error ? error.message : String(error)}`);
|
|
2265
2268
|
}
|
|
2266
2269
|
if (previousSticky !== void 0 && http2.port !== previousSticky) {
|
|
2267
|
-
ports.log(`
|
|
2270
|
+
ports.log(`agent-shim frontdoor supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(http2.port)} (sessions launched against the old port are stale until they relaunch)`);
|
|
2268
2271
|
}
|
|
2269
2272
|
lastPort = http2.port;
|
|
2270
2273
|
const previousStickyConnect = lastConnectPort;
|
|
@@ -2276,7 +2279,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2276
2279
|
return fail(`could not start the CONNECT surface: ${error instanceof Error ? error.message : String(error)}`);
|
|
2277
2280
|
}
|
|
2278
2281
|
if (previousStickyConnect !== void 0 && connect2.port !== previousStickyConnect) {
|
|
2279
|
-
ports.log(`
|
|
2282
|
+
ports.log(`agent-shim frontdoor supervisor: sticky CONNECT port ${String(previousStickyConnect)} was occupied; moving to ${String(connect2.port)} (OAuth sessions launched against the old port are stale until they relaunch)`);
|
|
2280
2283
|
}
|
|
2281
2284
|
lastConnectPort = connect2.port;
|
|
2282
2285
|
const previousStickyDirect = lastDirectPort;
|
|
@@ -2289,12 +2292,12 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2289
2292
|
return fail(`could not start the direct listener: ${error instanceof Error ? error.message : String(error)}`);
|
|
2290
2293
|
}
|
|
2291
2294
|
if (previousStickyDirect !== void 0 && direct.port !== previousStickyDirect) {
|
|
2292
|
-
ports.log(`
|
|
2295
|
+
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)`);
|
|
2293
2296
|
}
|
|
2294
2297
|
lastDirectPort = direct.port;
|
|
2295
2298
|
writeFrontDoorState(fs2, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, port: http2.port, connectPort: connect2.port, directPort: direct.port, ...sticky() });
|
|
2296
2299
|
fs2.removeRecursive(paths.frontdoorLockFile);
|
|
2297
|
-
ports.log(`
|
|
2300
|
+
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(connect2.port)}`);
|
|
2298
2301
|
let idleSince;
|
|
2299
2302
|
let ticks = 0;
|
|
2300
2303
|
for (; ; ) {
|
|
@@ -2306,7 +2309,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
|
|
|
2306
2309
|
if (listFrontDoorSessions(fs2, paths.frontdoorSessionsDir).length === 0) {
|
|
2307
2310
|
idleSince ??= ports.now();
|
|
2308
2311
|
if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE) {
|
|
2309
|
-
ports.log(`
|
|
2312
|
+
ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
|
|
2310
2313
|
await direct.close();
|
|
2311
2314
|
await connect2.close();
|
|
2312
2315
|
await http2.close();
|
|
@@ -2346,7 +2349,7 @@ var CONNECT_LIMITS = {
|
|
|
2346
2349
|
};
|
|
2347
2350
|
var CA_VALIDITY_DAYS = 3650;
|
|
2348
2351
|
var LEAF_VALIDITY_DAYS = 397;
|
|
2349
|
-
var CA_SUBJECT_COMMON_NAME = "
|
|
2352
|
+
var CA_SUBJECT_COMMON_NAME = "agent-shim front door CA";
|
|
2350
2353
|
var MS_PER_DAY = 864e5;
|
|
2351
2354
|
function parseConnectTarget(authority) {
|
|
2352
2355
|
const colon = authority.lastIndexOf(":");
|
|
@@ -2740,7 +2743,7 @@ function realConnectEffects() {
|
|
|
2740
2743
|
response.destroy(error);
|
|
2741
2744
|
return;
|
|
2742
2745
|
}
|
|
2743
|
-
const body = `
|
|
2746
|
+
const body = `agent-shim headroom: upstream unreachable (${error.message})`;
|
|
2744
2747
|
response.writeHead(HTTP_BAD_GATEWAY, { "content-type": "text/plain", "content-length": String(body.length) });
|
|
2745
2748
|
response.end(body);
|
|
2746
2749
|
});
|
|
@@ -2829,7 +2832,7 @@ function readHeadroomState(fs2, stateFile) {
|
|
|
2829
2832
|
}
|
|
2830
2833
|
function writeHeadroomState(fs2, stateFile, state) {
|
|
2831
2834
|
fs2.mkdirp(import_node_path6.default.dirname(stateFile));
|
|
2832
|
-
fs2.
|
|
2835
|
+
fs2.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
|
|
2833
2836
|
`);
|
|
2834
2837
|
}
|
|
2835
2838
|
function headroomAllowlist(providers) {
|
|
@@ -2940,13 +2943,13 @@ function ensureFrontDoor(params) {
|
|
|
2940
2943
|
}
|
|
2941
2944
|
lastRejection = `the listener on 127.0.0.1:${String(state.port)} (recorded for pid ${String(supervisorPid)}) failed authentication: ${verdict.reason}`;
|
|
2942
2945
|
if (spawned) {
|
|
2943
|
-
throw new FrontDoorStartError(`
|
|
2946
|
+
throw new FrontDoorStartError(`agent-shim: ${lastRejection}; refusing to send this session's credentials to it. Daemon log: ${paths.frontdoorLogPath}`);
|
|
2944
2947
|
}
|
|
2945
2948
|
distrusted.add(supervisorPid);
|
|
2946
2949
|
continue;
|
|
2947
2950
|
}
|
|
2948
2951
|
if (state?.lastError !== void 0) {
|
|
2949
|
-
throw new FrontDoorStartError(`
|
|
2952
|
+
throw new FrontDoorStartError(`agent-shim: the front door reported a fatal error and is not serving: ${state.lastError} (daemon log: ${paths.frontdoorLogPath})`);
|
|
2950
2953
|
}
|
|
2951
2954
|
} else if (!spawned) {
|
|
2952
2955
|
ports.fs.mkdirp(paths.frontdoorDir);
|
|
@@ -2966,7 +2969,7 @@ function ensureFrontDoor(params) {
|
|
|
2966
2969
|
if (ports.now() >= deadline) {
|
|
2967
2970
|
const lastError = state?.lastError;
|
|
2968
2971
|
throw new FrontDoorStartError(
|
|
2969
|
-
`
|
|
2972
|
+
`agent-shim: the front door did not become ready within ${String(FRONTDOOR_START_TIMEOUT_MS)}ms` + (lastError === void 0 ? "" : ` (last error: ${lastError})`) + (lastRejection === void 0 ? "" : ` (${lastRejection})`) + `. Daemon log: ${paths.frontdoorLogPath}`
|
|
2970
2973
|
);
|
|
2971
2974
|
}
|
|
2972
2975
|
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
@@ -3131,7 +3134,7 @@ function isIdentityName(name) {
|
|
|
3131
3134
|
// src/usage/read.ts
|
|
3132
3135
|
var UsageSnapshotError = class extends Error {
|
|
3133
3136
|
constructor(file, detail) {
|
|
3134
|
-
super(`${file} is not a usage snapshot this
|
|
3137
|
+
super(`${file} is not a usage snapshot this agent-shim can read (schema version ${String(USAGE_SCHEMA_VERSION)}): ${detail}`);
|
|
3135
3138
|
this.file = file;
|
|
3136
3139
|
this.name = "UsageSnapshotError";
|
|
3137
3140
|
}
|
|
@@ -3198,7 +3201,7 @@ function ensureHeadroom(params) {
|
|
|
3198
3201
|
}
|
|
3199
3202
|
if (state.lastError !== void 0) {
|
|
3200
3203
|
throw new HeadroomStartError(
|
|
3201
|
-
`
|
|
3204
|
+
`agent-shim: the headroom daemon reported a fatal error and is not serving: ${state.lastError} (daemon log: ${paths.headroomLogPath})`
|
|
3202
3205
|
);
|
|
3203
3206
|
}
|
|
3204
3207
|
} else if (!spawnedSupervisor) {
|
|
@@ -3222,7 +3225,7 @@ function ensureHeadroom(params) {
|
|
|
3222
3225
|
if (ports.now() >= deadline) {
|
|
3223
3226
|
const lastError = state?.lastError;
|
|
3224
3227
|
throw new HeadroomStartError(
|
|
3225
|
-
`
|
|
3228
|
+
`agent-shim: the headroom daemon did not become ready within ${String(HEADROOM_START_TIMEOUT_MS)}ms` + (lastError === void 0 ? "" : ` (last error: ${lastError})`) + `. Daemon log: ${paths.headroomLogPath}`
|
|
3226
3229
|
);
|
|
3227
3230
|
}
|
|
3228
3231
|
ports.sleep(HEADROOM_LAUNCHER_POLL_MS);
|
|
@@ -3258,6 +3261,16 @@ function hashSettings(settings) {
|
|
|
3258
3261
|
return (0, import_node_crypto6.createHash)("sha256").update(JSON.stringify([...settingsArgs(settings), JSON.stringify(settingsEnv(settings))])).digest("hex");
|
|
3259
3262
|
}
|
|
3260
3263
|
|
|
3264
|
+
// src/headroom/source.ts
|
|
3265
|
+
var import_zod6 = require("zod");
|
|
3266
|
+
var GIT_SPEC_RE = /git\+[^@\s]+(?:@([^\s#]+))?/;
|
|
3267
|
+
var COMMIT_SHA_RE = /^[0-9a-f]{40}$/i;
|
|
3268
|
+
var DirectUrlSchema = import_zod6.z.object({ vcs_info: import_zod6.z.object({ commit_id: import_zod6.z.string() }) });
|
|
3269
|
+
function pinnedGitCommit(spec) {
|
|
3270
|
+
const ref = GIT_SPEC_RE.exec(spec)?.[1];
|
|
3271
|
+
return ref !== void 0 && COMMIT_SHA_RE.test(ref) ? ref.toLowerCase() : void 0;
|
|
3272
|
+
}
|
|
3273
|
+
|
|
3261
3274
|
// src/headroom/supervisor.ts
|
|
3262
3275
|
function resolveSupervisorConfig(configured) {
|
|
3263
3276
|
return {
|
|
@@ -3331,7 +3344,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3331
3344
|
let config = initialConfig;
|
|
3332
3345
|
const previousState = readHeadroomState(fs2, paths.headroomStateFile);
|
|
3333
3346
|
if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
|
|
3334
|
-
ports.log(`
|
|
3347
|
+
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
|
|
3335
3348
|
return 0;
|
|
3336
3349
|
}
|
|
3337
3350
|
let installedSource = previousState?.installedSource;
|
|
@@ -3352,17 +3365,19 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3352
3365
|
if (writeOwnState({ lastError: message, ...sticky() })) {
|
|
3353
3366
|
fs2.removeRecursive(paths.headroomLockFile);
|
|
3354
3367
|
}
|
|
3355
|
-
ports.log(`
|
|
3368
|
+
ports.log(`agent-shim headroom supervisor: ${message}`);
|
|
3356
3369
|
return 1;
|
|
3357
3370
|
};
|
|
3358
3371
|
const ensureInstalled = () => {
|
|
3359
3372
|
const version2 = ports.headroomVersion();
|
|
3360
3373
|
const versionOk = version2 !== void 0 && versionSatisfies(version2, config.source);
|
|
3361
|
-
|
|
3374
|
+
const pinned = pinnedGitCommit(config.source);
|
|
3375
|
+
const commitOk = pinned === void 0 || ports.installedCommit() === pinned;
|
|
3376
|
+
if (versionOk && commitOk && (installedSource === void 0 || installedSource === config.source)) {
|
|
3362
3377
|
installedSource = config.source;
|
|
3363
3378
|
return true;
|
|
3364
3379
|
}
|
|
3365
|
-
ports.log(`
|
|
3380
|
+
ports.log(`agent-shim headroom supervisor: installing headroom from ${config.source}`);
|
|
3366
3381
|
const result = ports.install(config.source);
|
|
3367
3382
|
if (!result.ok) {
|
|
3368
3383
|
return false;
|
|
@@ -3375,10 +3390,10 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3375
3390
|
}
|
|
3376
3391
|
const version = ports.headroomVersion() ?? "unknown";
|
|
3377
3392
|
writeOwnState({ supervisorPid: ports.ownPid, version, installedSource, ...sticky() });
|
|
3378
|
-
ports.log(`
|
|
3393
|
+
ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${allowlistOf(ports).join(", ")}]`);
|
|
3379
3394
|
const orphanPid = previousState?.headroomPid;
|
|
3380
3395
|
if (orphanPid !== void 0 && ports.isRunning(orphanPid)) {
|
|
3381
|
-
ports.log(`
|
|
3396
|
+
ports.log(`agent-shim headroom supervisor: stopping daemon pid ${String(orphanPid)} left behind by the previous supervisor`);
|
|
3382
3397
|
ports.stopProcess(orphanPid);
|
|
3383
3398
|
}
|
|
3384
3399
|
let headroomPid;
|
|
@@ -3400,13 +3415,13 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3400
3415
|
pruneDeadSessions(fs2, paths.headroomSessionsDir, ports.isRunning);
|
|
3401
3416
|
const ownsNow = ownsState();
|
|
3402
3417
|
if (!ownsNow && !superseded) {
|
|
3403
|
-
ports.log("
|
|
3418
|
+
ports.log("agent-shim headroom supervisor: another supervisor now owns state.json; serving this daemon's own sessions until they end");
|
|
3404
3419
|
}
|
|
3405
3420
|
superseded = !ownsNow;
|
|
3406
3421
|
const crashed = headroomPid !== void 0 && !ports.isRunning(headroomPid);
|
|
3407
3422
|
if (headroomPid === void 0 || crashed) {
|
|
3408
3423
|
if (crashed) {
|
|
3409
|
-
ports.log(`
|
|
3424
|
+
ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} died`);
|
|
3410
3425
|
headroomPid = void 0;
|
|
3411
3426
|
runningHash = void 0;
|
|
3412
3427
|
runningSettingsHash = void 0;
|
|
@@ -3435,7 +3450,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3435
3450
|
lastPort = port;
|
|
3436
3451
|
if (previousSticky !== void 0 && port !== previousSticky) {
|
|
3437
3452
|
ports.log(
|
|
3438
|
-
`
|
|
3453
|
+
`agent-shim headroom supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(port)} (sessions launched against the old port are stale until they relaunch)`
|
|
3439
3454
|
);
|
|
3440
3455
|
}
|
|
3441
3456
|
const recorded = writeOwnState({
|
|
@@ -3452,12 +3467,12 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3452
3467
|
fs2.removeRecursive(paths.headroomLockFile);
|
|
3453
3468
|
}
|
|
3454
3469
|
idleSince = void 0;
|
|
3455
|
-
ports.log(`
|
|
3470
|
+
ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on 127.0.0.1:${String(port)}`);
|
|
3456
3471
|
} else {
|
|
3457
3472
|
ports.stopProcess(pid);
|
|
3458
3473
|
consecutiveFailures += 1;
|
|
3459
3474
|
ports.log(
|
|
3460
|
-
`
|
|
3475
|
+
`agent-shim headroom supervisor: headroom did not become ready on port ${String(port)} (attempt ${String(consecutiveFailures)} of ${String(HEADROOM_START_RETRY_BUDGET)})`
|
|
3461
3476
|
);
|
|
3462
3477
|
await ports.sleep(backoffForAttempt(consecutiveFailures));
|
|
3463
3478
|
continue;
|
|
@@ -3465,7 +3480,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3465
3480
|
} else {
|
|
3466
3481
|
if (runningHash !== allowlistHash || runningSettingsHash !== settingsHash || installedSource !== config.source) {
|
|
3467
3482
|
if (sessionsForSupervisor(fs2, paths.headroomSessionsDir, ports.ownPid).length === 0) {
|
|
3468
|
-
ports.log("
|
|
3483
|
+
ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
|
|
3469
3484
|
ports.stopProcess(headroomPid);
|
|
3470
3485
|
headroomPid = void 0;
|
|
3471
3486
|
runningHash = void 0;
|
|
@@ -3479,7 +3494,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
|
|
|
3479
3494
|
const idleMs = ports.now() - idleSince;
|
|
3480
3495
|
if (idleMs >= config.idleShutdownMinutes * MS_PER_MINUTE2) {
|
|
3481
3496
|
ports.log(
|
|
3482
|
-
`
|
|
3497
|
+
`agent-shim headroom supervisor: no sessions for ${String(config.idleShutdownMinutes)} minute(s); stopping headroom and exiting`
|
|
3483
3498
|
);
|
|
3484
3499
|
ports.stopProcess(headroomPid);
|
|
3485
3500
|
writeOwnState({
|
|
@@ -3538,12 +3553,12 @@ function detectAmbientCredential(env, injected) {
|
|
|
3538
3553
|
return void 0;
|
|
3539
3554
|
}
|
|
3540
3555
|
function formatAmbientCredentialGuardMessage(variable, identityName) {
|
|
3541
|
-
const identitySetCommand = identityName === void 0 ? "
|
|
3556
|
+
const identitySetCommand = identityName === void 0 ? "agent-shim identity set <name> --allow-ambient-credential" : `agent-shim identity set ${identityName} --allow-ambient-credential`;
|
|
3542
3557
|
return [
|
|
3543
3558
|
`error: ${variable} is set in the environment. This identity's isolated`,
|
|
3544
3559
|
"credential would be bypassed \u2014 every identity authenticates as this same key",
|
|
3545
3560
|
"while it's set. Unset it, or if this is deliberate, opt in per-launch with",
|
|
3546
|
-
"
|
|
3561
|
+
"AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL=1, or persistently for this identity with",
|
|
3547
3562
|
`\`${identitySetCommand}\`.`
|
|
3548
3563
|
].join("\n");
|
|
3549
3564
|
}
|