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/dist/index.mjs CHANGED
@@ -17,7 +17,7 @@ function expandAllCategoryKey(pairs) {
17
17
  if (all === void 0) {
18
18
  return { ...rest };
19
19
  }
20
- const expanded = Object.fromEntries(OVERRIDABLE_CATEGORIES.map((category) => [category, all]));
20
+ const expanded = Object.fromEntries(OVERRIDABLE_CATEGORIES.filter((category) => !all || category !== "runtime").map((category) => [category, all]));
21
21
  return { ...expanded, ...rest };
22
22
  }
23
23
  var CategoryMapSchema = z.strictObject({
@@ -91,7 +91,7 @@ var CredentialSchema = z.strictObject({
91
91
  var ProviderCredentialSchema = CredentialSchema.extend({ target: z.enum(PROVIDER_CREDENTIAL_TARGETS).optional() });
92
92
  var RESERVED_PROVIDER_ENV_KEYS = Object.values(CREDENTIAL_TARGET_VARS);
93
93
  var ProviderEnvSchema = z.record(z.string().min(1), z.string()).refine((env) => !Object.keys(env).some((key) => RESERVED_PROVIDER_ENV_KEYS.includes(key)), {
94
- message: `env may not set ${RESERVED_PROVIDER_ENV_KEYS.join(", ")}: the credential block's target sets one and claude-use removes the others`
94
+ message: `env may not set ${RESERVED_PROVIDER_ENV_KEYS.join(", ")}: the credential block's target sets one and agent-shim removes the others`
95
95
  });
96
96
  var CODEX_EFFORTS = ["none", "low", "medium", "high"];
97
97
  var CODEX_DEFAULT_TIER_MODELS = Object.freeze({
@@ -734,7 +734,7 @@ function resolveEntry(relPath, params) {
734
734
  diagnostics.push({
735
735
  code: "UNCLASSIFIED_ENTRY",
736
736
  severity: "warning",
737
- message: `"${head}" is not in the category map, so it is excluded. Run \`claude-use configure\` to classify it, which records the answer in the local overlay without touching the shipped default map.`,
737
+ 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.`,
738
738
  subject: head
739
739
  });
740
740
  return { decision: { relPath, shared: false, via: "unclassified", category }, diagnostics };
@@ -1211,6 +1211,9 @@ function planReconciliation(params) {
1211
1211
  return { actions, diagnostics, conservative };
1212
1212
  }
1213
1213
 
1214
+ // src/legacy.ts
1215
+ var LEGACY_FARM_MANIFEST_FILENAME = ".claude-use-farm.json";
1216
+
1214
1217
  // src/launcher/lock.ts
1215
1218
  import { randomUUID } from "node:crypto";
1216
1219
  import path3 from "node:path";
@@ -1220,7 +1223,7 @@ var DEFAULT_MAX_ATTEMPTS = 200;
1220
1223
  var IdentityLockBusyError = class extends CliError {
1221
1224
  constructor(identity, lockPath, holderPid) {
1222
1225
  super(
1223
- `Another claude-use 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.`
1226
+ `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.`
1224
1227
  );
1225
1228
  this.identity = identity;
1226
1229
  this.lockPath = lockPath;
@@ -1299,7 +1302,7 @@ function acquireIdentityLock(params) {
1299
1302
  }
1300
1303
 
1301
1304
  // src/launcher/farm.ts
1302
- var FARM_MANIFEST_FILENAME = ".claude-use-farm.json";
1305
+ var FARM_MANIFEST_FILENAME = ".agent-shim-farm.json";
1303
1306
  var FarmManifestSchema = z2.strictObject({
1304
1307
  version: z2.literal(1),
1305
1308
  builtAtMs: z2.number(),
@@ -1311,7 +1314,7 @@ var FarmManifestSchema = z2.strictObject({
1311
1314
  links: z2.array(z2.strictObject({ rel: z2.string(), target: z2.string() }))
1312
1315
  });
1313
1316
  function readFarmManifest(fs2, farmRoot) {
1314
- const raw = fs2.readFileUtf8(path4.join(farmRoot, FARM_MANIFEST_FILENAME));
1317
+ const raw = fs2.readFileUtf8(path4.join(farmRoot, FARM_MANIFEST_FILENAME)) ?? fs2.readFileUtf8(path4.join(farmRoot, LEGACY_FARM_MANIFEST_FILENAME));
1315
1318
  if (raw === void 0) {
1316
1319
  return void 0;
1317
1320
  }
@@ -1400,7 +1403,7 @@ function reconciliationScope(fs2, farmRoot, manifest) {
1400
1403
  if (manifest !== void 0) {
1401
1404
  return topLevelScopeRoots(manifest.materialised);
1402
1405
  }
1403
- return [...fs2.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && fs2.lstat(path4.join(farmRoot, name))?.kind === "dir").sort();
1406
+ return [...fs2.readdir(farmRoot)].filter((name) => name !== FARM_MANIFEST_FILENAME && name !== LEGACY_FARM_MANIFEST_FILENAME && fs2.lstat(path4.join(farmRoot, name))?.kind === "dir").sort();
1404
1407
  }
1405
1408
  function collectFarmListing(fs2, farmRoot, scopeRoots) {
1406
1409
  return scopeRoots.flatMap((root) => listSubtree(fs2, farmRoot, root));
@@ -1424,7 +1427,7 @@ function collectCanonicalCounterparts(fs2, claudeHome, farmListing) {
1424
1427
  }
1425
1428
  function carryOver(params) {
1426
1429
  const manifest = readFarmManifest(params.fs, params.previousRoot);
1427
- const accounted = /* @__PURE__ */ new Set([FARM_MANIFEST_FILENAME]);
1430
+ const accounted = /* @__PURE__ */ new Set([FARM_MANIFEST_FILENAME, LEGACY_FARM_MANIFEST_FILENAME]);
1428
1431
  for (const rel of manifest?.materialised ?? []) {
1429
1432
  const head = rel.split("/")[0];
1430
1433
  if (head !== void 0 && head !== "") {
@@ -1722,7 +1725,7 @@ function resyncFarm(params) {
1722
1725
  diagnostics.push({
1723
1726
  code: "FARM_PREVIOUS_RETAINED",
1724
1727
  severity: "warning",
1725
- 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 \`claude-use identity resolve-conflicts ${params.identity}\` to resolve it interactively.`,
1728
+ 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.`,
1726
1729
  subject: swap.retainedPrevious
1727
1730
  });
1728
1731
  }
@@ -1759,7 +1762,7 @@ function recoveryDiagnostics(recovery, identity) {
1759
1762
  }
1760
1763
  if (recovery.retained.length > 0) {
1761
1764
  parts.push(
1762
- `kept ${recovery.retained.join(", ")}, which still holds data the current farm also has an entry for \u2014 run \`claude-use identity resolve-conflicts ${identity}\` to resolve it interactively`
1765
+ `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`
1763
1766
  );
1764
1767
  }
1765
1768
  return [
@@ -2051,7 +2054,7 @@ function issueLeafCertificate(ca, names, notBefore, notAfter) {
2051
2054
  }
2052
2055
 
2053
2056
  // src/frontdoor/capability.ts
2054
- var CONNECT_PROXY_REALM = "claude-use front door";
2057
+ var CONNECT_PROXY_REALM = "agent-shim front door";
2055
2058
  var BASIC_SCHEME = "basic";
2056
2059
  function capabilityFromProxyAuthorization(value) {
2057
2060
  const trimmed = value.trim();
@@ -2178,7 +2181,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
2178
2181
  const fail = (message) => {
2179
2182
  writeFrontDoorState(fs2, paths.frontdoorStateFile, { lastError: message, ...sticky() });
2180
2183
  fs2.removeRecursive(paths.frontdoorLockFile);
2181
- ports.log(`claude-use frontdoor supervisor: ${message}`);
2184
+ ports.log(`agent-shim frontdoor supervisor: ${message}`);
2182
2185
  return 1;
2183
2186
  };
2184
2187
  writeFrontDoorState(fs2, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, ...sticky() });
@@ -2190,7 +2193,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
2190
2193
  return fail(`could not start the provider listener: ${error instanceof Error ? error.message : String(error)}`);
2191
2194
  }
2192
2195
  if (previousSticky !== void 0 && http2.port !== previousSticky) {
2193
- ports.log(`claude-use frontdoor supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(http2.port)} (sessions launched against the old port are stale until they relaunch)`);
2196
+ 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)`);
2194
2197
  }
2195
2198
  lastPort = http2.port;
2196
2199
  const previousStickyConnect = lastConnectPort;
@@ -2202,7 +2205,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
2202
2205
  return fail(`could not start the CONNECT surface: ${error instanceof Error ? error.message : String(error)}`);
2203
2206
  }
2204
2207
  if (previousStickyConnect !== void 0 && connect2.port !== previousStickyConnect) {
2205
- ports.log(`claude-use 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)`);
2208
+ 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)`);
2206
2209
  }
2207
2210
  lastConnectPort = connect2.port;
2208
2211
  const previousStickyDirect = lastDirectPort;
@@ -2215,12 +2218,12 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
2215
2218
  return fail(`could not start the direct listener: ${error instanceof Error ? error.message : String(error)}`);
2216
2219
  }
2217
2220
  if (previousStickyDirect !== void 0 && direct.port !== previousStickyDirect) {
2218
- ports.log(`claude-use frontdoor supervisor: sticky direct port ${String(previousStickyDirect)} was occupied; moving to ${String(direct.port)} (headroom must be restarted to admit the new address)`);
2221
+ 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)`);
2219
2222
  }
2220
2223
  lastDirectPort = direct.port;
2221
2224
  writeFrontDoorState(fs2, paths.frontdoorStateFile, { supervisorPid: ports.ownPid, port: http2.port, connectPort: connect2.port, directPort: direct.port, ...sticky() });
2222
2225
  fs2.removeRecursive(paths.frontdoorLockFile);
2223
- ports.log(`claude-use 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)}`);
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(connect2.port)}`);
2224
2227
  let idleSince;
2225
2228
  let ticks = 0;
2226
2229
  for (; ; ) {
@@ -2232,7 +2235,7 @@ async function runFrontDoorSupervisor(idleShutdownMinutes, ports, options = {})
2232
2235
  if (listFrontDoorSessions(fs2, paths.frontdoorSessionsDir).length === 0) {
2233
2236
  idleSince ??= ports.now();
2234
2237
  if (ports.now() - idleSince >= idleShutdownMinutes * MS_PER_MINUTE) {
2235
- ports.log(`claude-use frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
2238
+ ports.log(`agent-shim frontdoor supervisor: no sessions for ${String(idleShutdownMinutes)} minute(s); closing the front door and exiting`);
2236
2239
  await direct.close();
2237
2240
  await connect2.close();
2238
2241
  await http2.close();
@@ -2272,7 +2275,7 @@ var CONNECT_LIMITS = {
2272
2275
  };
2273
2276
  var CA_VALIDITY_DAYS = 3650;
2274
2277
  var LEAF_VALIDITY_DAYS = 397;
2275
- var CA_SUBJECT_COMMON_NAME = "claude-use front door CA";
2278
+ var CA_SUBJECT_COMMON_NAME = "agent-shim front door CA";
2276
2279
  var MS_PER_DAY = 864e5;
2277
2280
  function parseConnectTarget(authority) {
2278
2281
  const colon = authority.lastIndexOf(":");
@@ -2666,7 +2669,7 @@ function realConnectEffects() {
2666
2669
  response.destroy(error);
2667
2670
  return;
2668
2671
  }
2669
- const body = `claude-use headroom: upstream unreachable (${error.message})`;
2672
+ const body = `agent-shim headroom: upstream unreachable (${error.message})`;
2670
2673
  response.writeHead(HTTP_BAD_GATEWAY, { "content-type": "text/plain", "content-length": String(body.length) });
2671
2674
  response.end(body);
2672
2675
  });
@@ -2755,7 +2758,7 @@ function readHeadroomState(fs2, stateFile) {
2755
2758
  }
2756
2759
  function writeHeadroomState(fs2, stateFile, state) {
2757
2760
  fs2.mkdirp(path6.dirname(stateFile));
2758
- fs2.writeFileUtf8(stateFile, `${JSON.stringify(state, null, 2)}
2761
+ fs2.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
2759
2762
  `);
2760
2763
  }
2761
2764
  function headroomAllowlist(providers) {
@@ -2866,13 +2869,13 @@ function ensureFrontDoor(params) {
2866
2869
  }
2867
2870
  lastRejection = `the listener on 127.0.0.1:${String(state.port)} (recorded for pid ${String(supervisorPid)}) failed authentication: ${verdict.reason}`;
2868
2871
  if (spawned) {
2869
- throw new FrontDoorStartError(`claude-use: ${lastRejection}; refusing to send this session's credentials to it. Daemon log: ${paths.frontdoorLogPath}`);
2872
+ throw new FrontDoorStartError(`agent-shim: ${lastRejection}; refusing to send this session's credentials to it. Daemon log: ${paths.frontdoorLogPath}`);
2870
2873
  }
2871
2874
  distrusted.add(supervisorPid);
2872
2875
  continue;
2873
2876
  }
2874
2877
  if (state?.lastError !== void 0) {
2875
- throw new FrontDoorStartError(`claude-use: the front door reported a fatal error and is not serving: ${state.lastError} (daemon log: ${paths.frontdoorLogPath})`);
2878
+ throw new FrontDoorStartError(`agent-shim: the front door reported a fatal error and is not serving: ${state.lastError} (daemon log: ${paths.frontdoorLogPath})`);
2876
2879
  }
2877
2880
  } else if (!spawned) {
2878
2881
  ports.fs.mkdirp(paths.frontdoorDir);
@@ -2892,7 +2895,7 @@ function ensureFrontDoor(params) {
2892
2895
  if (ports.now() >= deadline) {
2893
2896
  const lastError = state?.lastError;
2894
2897
  throw new FrontDoorStartError(
2895
- `claude-use: 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}`
2898
+ `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}`
2896
2899
  );
2897
2900
  }
2898
2901
  ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
@@ -3057,7 +3060,7 @@ function isIdentityName(name) {
3057
3060
  // src/usage/read.ts
3058
3061
  var UsageSnapshotError = class extends Error {
3059
3062
  constructor(file, detail) {
3060
- super(`${file} is not a usage snapshot this claude-use can read (schema version ${String(USAGE_SCHEMA_VERSION)}): ${detail}`);
3063
+ super(`${file} is not a usage snapshot this agent-shim can read (schema version ${String(USAGE_SCHEMA_VERSION)}): ${detail}`);
3061
3064
  this.file = file;
3062
3065
  this.name = "UsageSnapshotError";
3063
3066
  }
@@ -3124,7 +3127,7 @@ function ensureHeadroom(params) {
3124
3127
  }
3125
3128
  if (state.lastError !== void 0) {
3126
3129
  throw new HeadroomStartError(
3127
- `claude-use: the headroom daemon reported a fatal error and is not serving: ${state.lastError} (daemon log: ${paths.headroomLogPath})`
3130
+ `agent-shim: the headroom daemon reported a fatal error and is not serving: ${state.lastError} (daemon log: ${paths.headroomLogPath})`
3128
3131
  );
3129
3132
  }
3130
3133
  } else if (!spawnedSupervisor) {
@@ -3148,7 +3151,7 @@ function ensureHeadroom(params) {
3148
3151
  if (ports.now() >= deadline) {
3149
3152
  const lastError = state?.lastError;
3150
3153
  throw new HeadroomStartError(
3151
- `claude-use: the headroom daemon did not become ready within ${String(HEADROOM_START_TIMEOUT_MS)}ms` + (lastError === void 0 ? "" : ` (last error: ${lastError})`) + `. Daemon log: ${paths.headroomLogPath}`
3154
+ `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}`
3152
3155
  );
3153
3156
  }
3154
3157
  ports.sleep(HEADROOM_LAUNCHER_POLL_MS);
@@ -3184,6 +3187,16 @@ function hashSettings(settings) {
3184
3187
  return createHash3("sha256").update(JSON.stringify([...settingsArgs(settings), JSON.stringify(settingsEnv(settings))])).digest("hex");
3185
3188
  }
3186
3189
 
3190
+ // src/headroom/source.ts
3191
+ import { z as z6 } from "zod";
3192
+ var GIT_SPEC_RE = /git\+[^@\s]+(?:@([^\s#]+))?/;
3193
+ var COMMIT_SHA_RE = /^[0-9a-f]{40}$/i;
3194
+ var DirectUrlSchema = z6.object({ vcs_info: z6.object({ commit_id: z6.string() }) });
3195
+ function pinnedGitCommit(spec) {
3196
+ const ref = GIT_SPEC_RE.exec(spec)?.[1];
3197
+ return ref !== void 0 && COMMIT_SHA_RE.test(ref) ? ref.toLowerCase() : void 0;
3198
+ }
3199
+
3187
3200
  // src/headroom/supervisor.ts
3188
3201
  function resolveSupervisorConfig(configured) {
3189
3202
  return {
@@ -3257,7 +3270,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3257
3270
  let config = initialConfig;
3258
3271
  const previousState = readHeadroomState(fs2, paths.headroomStateFile);
3259
3272
  if (previousState?.supervisorPid !== void 0 && previousState.supervisorPid !== ports.ownPid && ports.isRunning(previousState.supervisorPid)) {
3260
- ports.log(`claude-use headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
3273
+ ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: supervisor ${String(previousState.supervisorPid)} already owns the daemon; exiting`);
3261
3274
  return 0;
3262
3275
  }
3263
3276
  let installedSource = previousState?.installedSource;
@@ -3278,17 +3291,19 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3278
3291
  if (writeOwnState({ lastError: message, ...sticky() })) {
3279
3292
  fs2.removeRecursive(paths.headroomLockFile);
3280
3293
  }
3281
- ports.log(`claude-use headroom supervisor: ${message}`);
3294
+ ports.log(`agent-shim headroom supervisor: ${message}`);
3282
3295
  return 1;
3283
3296
  };
3284
3297
  const ensureInstalled = () => {
3285
3298
  const version2 = ports.headroomVersion();
3286
3299
  const versionOk = version2 !== void 0 && versionSatisfies(version2, config.source);
3287
- if (versionOk && (installedSource === void 0 || installedSource === config.source)) {
3300
+ const pinned = pinnedGitCommit(config.source);
3301
+ const commitOk = pinned === void 0 || ports.installedCommit() === pinned;
3302
+ if (versionOk && commitOk && (installedSource === void 0 || installedSource === config.source)) {
3288
3303
  installedSource = config.source;
3289
3304
  return true;
3290
3305
  }
3291
- ports.log(`claude-use headroom supervisor: installing headroom from ${config.source}`);
3306
+ ports.log(`agent-shim headroom supervisor: installing headroom from ${config.source}`);
3292
3307
  const result = ports.install(config.source);
3293
3308
  if (!result.ok) {
3294
3309
  return false;
@@ -3301,10 +3316,10 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3301
3316
  }
3302
3317
  const version = ports.headroomVersion() ?? "unknown";
3303
3318
  writeOwnState({ supervisorPid: ports.ownPid, version, installedSource, ...sticky() });
3304
- ports.log(`claude-use headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${allowlistOf(ports).join(", ")}]`);
3319
+ ports.log(`agent-shim headroom supervisor ${String(ports.ownPid)}: managing headroom on allowlist [${allowlistOf(ports).join(", ")}]`);
3305
3320
  const orphanPid = previousState?.headroomPid;
3306
3321
  if (orphanPid !== void 0 && ports.isRunning(orphanPid)) {
3307
- ports.log(`claude-use headroom supervisor: stopping daemon pid ${String(orphanPid)} left behind by the previous supervisor`);
3322
+ ports.log(`agent-shim headroom supervisor: stopping daemon pid ${String(orphanPid)} left behind by the previous supervisor`);
3308
3323
  ports.stopProcess(orphanPid);
3309
3324
  }
3310
3325
  let headroomPid;
@@ -3326,13 +3341,13 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3326
3341
  pruneDeadSessions(fs2, paths.headroomSessionsDir, ports.isRunning);
3327
3342
  const ownsNow = ownsState();
3328
3343
  if (!ownsNow && !superseded) {
3329
- ports.log("claude-use headroom supervisor: another supervisor now owns state.json; serving this daemon's own sessions until they end");
3344
+ ports.log("agent-shim headroom supervisor: another supervisor now owns state.json; serving this daemon's own sessions until they end");
3330
3345
  }
3331
3346
  superseded = !ownsNow;
3332
3347
  const crashed = headroomPid !== void 0 && !ports.isRunning(headroomPid);
3333
3348
  if (headroomPid === void 0 || crashed) {
3334
3349
  if (crashed) {
3335
- ports.log(`claude-use headroom supervisor: headroom pid ${String(headroomPid)} died`);
3350
+ ports.log(`agent-shim headroom supervisor: headroom pid ${String(headroomPid)} died`);
3336
3351
  headroomPid = void 0;
3337
3352
  runningHash = void 0;
3338
3353
  runningSettingsHash = void 0;
@@ -3361,7 +3376,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3361
3376
  lastPort = port;
3362
3377
  if (previousSticky !== void 0 && port !== previousSticky) {
3363
3378
  ports.log(
3364
- `claude-use headroom supervisor: sticky port ${String(previousSticky)} was occupied; moving to ${String(port)} (sessions launched against the old port are stale until they relaunch)`
3379
+ `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)`
3365
3380
  );
3366
3381
  }
3367
3382
  const recorded = writeOwnState({
@@ -3378,12 +3393,12 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3378
3393
  fs2.removeRecursive(paths.headroomLockFile);
3379
3394
  }
3380
3395
  idleSince = void 0;
3381
- ports.log(`claude-use headroom supervisor: headroom pid ${String(pid)} ready on 127.0.0.1:${String(port)}`);
3396
+ ports.log(`agent-shim headroom supervisor: headroom pid ${String(pid)} ready on 127.0.0.1:${String(port)}`);
3382
3397
  } else {
3383
3398
  ports.stopProcess(pid);
3384
3399
  consecutiveFailures += 1;
3385
3400
  ports.log(
3386
- `claude-use headroom supervisor: headroom did not become ready on port ${String(port)} (attempt ${String(consecutiveFailures)} of ${String(HEADROOM_START_RETRY_BUDGET)})`
3401
+ `agent-shim headroom supervisor: headroom did not become ready on port ${String(port)} (attempt ${String(consecutiveFailures)} of ${String(HEADROOM_START_RETRY_BUDGET)})`
3387
3402
  );
3388
3403
  await ports.sleep(backoffForAttempt(consecutiveFailures));
3389
3404
  continue;
@@ -3391,7 +3406,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3391
3406
  } else {
3392
3407
  if (runningHash !== allowlistHash || runningSettingsHash !== settingsHash || installedSource !== config.source) {
3393
3408
  if (sessionsForSupervisor(fs2, paths.headroomSessionsDir, ports.ownPid).length === 0) {
3394
- ports.log("claude-use headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
3409
+ ports.log("agent-shim headroom supervisor: configuration drifted and no sessions are live; restarting headroom");
3395
3410
  ports.stopProcess(headroomPid);
3396
3411
  headroomPid = void 0;
3397
3412
  runningHash = void 0;
@@ -3405,7 +3420,7 @@ async function runSupervisor(initialConfig, ports, options = {}) {
3405
3420
  const idleMs = ports.now() - idleSince;
3406
3421
  if (idleMs >= config.idleShutdownMinutes * MS_PER_MINUTE2) {
3407
3422
  ports.log(
3408
- `claude-use headroom supervisor: no sessions for ${String(config.idleShutdownMinutes)} minute(s); stopping headroom and exiting`
3423
+ `agent-shim headroom supervisor: no sessions for ${String(config.idleShutdownMinutes)} minute(s); stopping headroom and exiting`
3409
3424
  );
3410
3425
  ports.stopProcess(headroomPid);
3411
3426
  writeOwnState({
@@ -3464,12 +3479,12 @@ function detectAmbientCredential(env, injected) {
3464
3479
  return void 0;
3465
3480
  }
3466
3481
  function formatAmbientCredentialGuardMessage(variable, identityName) {
3467
- const identitySetCommand = identityName === void 0 ? "claude-use identity set <name> --allow-ambient-credential" : `claude-use identity set ${identityName} --allow-ambient-credential`;
3482
+ const identitySetCommand = identityName === void 0 ? "agent-shim identity set <name> --allow-ambient-credential" : `agent-shim identity set ${identityName} --allow-ambient-credential`;
3468
3483
  return [
3469
3484
  `error: ${variable} is set in the environment. This identity's isolated`,
3470
3485
  "credential would be bypassed \u2014 every identity authenticates as this same key",
3471
3486
  "while it's set. Unset it, or if this is deliberate, opt in per-launch with",
3472
- "CLAUDE_USE_ALLOW_AMBIENT_CREDENTIAL=1, or persistently for this identity with",
3487
+ "AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL=1, or persistently for this identity with",
3473
3488
  `\`${identitySetCommand}\`.`
3474
3489
  ].join("\n");
3475
3490
  }
@@ -3,7 +3,7 @@ export declare const EXIT_FAILURE = 1;
3
3
  /** Exit status for a usage error: an unknown command or option, a malformed flag value, or required input missing with no terminal to prompt on. */
4
4
  export declare const EXIT_USAGE = 2;
5
5
  /**
6
- * Base class for every error this CLI throws to represent an expected, user-facing failure: bad input, a missing identity/profile/rule, a malformed config file. `reportFatalError` prints this class as `claude-use: <message>` with no stack trace and exits with `exitCode`; anything that does not extend it is an unexpected bug, reported by message alone unless `CLAUDE_USE_DEBUG` asks for the stack.
6
+ * Base class for every error this CLI throws to represent an expected, user-facing failure: bad input, a missing identity/profile/rule, a malformed config file. `reportFatalError` prints this class as `agent-shim: <message>` with no stack trace and exits with `exitCode`; anything that does not extend it is an unexpected bug, reported by message alone unless `AGENT_SHIM_DEBUG` asks for the stack.
7
7
  */
8
8
  export declare abstract class CliError extends Error {
9
9
  /** The process exit status this failure maps to. `EXIT_FAILURE` unless a subclass says otherwise. */
@@ -17,9 +17,9 @@ export interface ClassificationPattern {
17
17
  export interface ClassifyResult {
18
18
  /** Every input name mapped to its category, or to null when nothing in either map recognises it. */
19
19
  readonly classification: ReadonlyMap<string, CategoryName | null>;
20
- /** The input names that nothing recognised, in input order. These are the names `claude-use configure` prompts about. */
20
+ /** The input names that nothing recognised, in input order. These are the names `agent-shim configure` prompts about. */
21
21
  readonly unclassified: readonly string[];
22
- /** For each classified name, the pattern that decided it — used by `claude-use check` to explain a classification. */
22
+ /** For each classified name, the pattern that decided it — used by `agent-shim check` to explain a classification. */
23
23
  readonly decidedBy: ReadonlyMap<string, ClassificationPattern>;
24
24
  }
25
25
  /** True when `pattern` contains no glob metacharacter, so it matches exactly one literal name. */
@@ -40,7 +40,7 @@ export declare function loadClassification(paths: LayoutPaths): LoadedClassifica
40
40
  /**
41
41
  * Classifies a list of real top-level `~/.claude` entry names against the shipped category map plus an optional local overlay.
42
42
  *
43
- * An unrecognised name maps to `null` rather than being silently assumed safe or silently dropped: the resolver treats it as not-shared and reports it, and `claude-use configure` prompts for an answer that is then written to the local overlay.
43
+ * An unrecognised name maps to `null` rather than being silently assumed safe or silently dropped: the resolver treats it as not-shared and reports it, and `agent-shim configure` prompts for an answer that is then written to the local overlay.
44
44
  */
45
45
  export declare function classifyEntries(names: readonly string[], options: {
46
46
  defaults: CategoryClassification;
@@ -16,13 +16,13 @@ export declare function isCategoryName(name: string): name is CategoryName;
16
16
  */
17
17
  export type CategoryMap = Partial<Record<OverridableCategory, boolean>>;
18
18
  /**
19
- * Expands the `all` pseudo-category key into every overridable category set to that same value, dropping `all` itself from the result. An explicit named category always wins over the `all` expansion regardless of where it appears relative to `all` in the input — `{ all: true, runtime: false }` means "share everything except runtime", not "runtime is false, then immediately overwritten back to true by all's own expansion". Built from `OVERRIDABLE_CATEGORIES` rather than the four names spelled out again, so a future addition to that list is covered by `all` with no change needed here.
19
+ * Expands the `all` pseudo-category key, dropping `all` itself from the result. `all: true` opens every category meant to be shared across identities, which is every overridable category except `runtime`: `runtime` holds live per-process and per-machine state (daemon locks and auth status, PIDs, IDE and shell snapshots) that must never be pooled across running identities, so it opens only when named explicitly. `all: false` closes every overridable category, `runtime` included, so it also closes a `runtime` an earlier layer opened. An explicit named category always wins over the `all` expansion regardless of where it appears relative to `all` in the input: `{ all: true, runtime: true }` opens `runtime` too, and `{ all: true, history: false }` means "share everything except history", not "history is false, then immediately overwritten back to true".
20
20
  *
21
- * This is the one shared implementation `CategoryMapSchema`'s own transform, `launcher/cliOverride.ts`'s `--category`/`CLAUDE_USE_CATEGORY_OVERRIDE` handling, and `configProfiles.ts`'s `claude-use profile set --category` all call — so `all` means the same thing regardless of which of those three input paths it arrived through.
21
+ * This is the one shared implementation `CategoryMapSchema`'s own transform, `launcher/cliOverride.ts`'s `--category`/`AGENT_SHIM_CATEGORY_OVERRIDE` handling, and `configProfiles.ts`'s `agent-shim profile set --category` all call, so `all` means the same thing regardless of which of those three input paths it arrived through.
22
22
  */
23
23
  export declare function expandAllCategoryKey(pairs: Readonly<Record<string, boolean>>): Record<string, boolean>;
24
24
  /**
25
- * The category toggle map as written by hand: the four overridable categories, plus `all` as shorthand for "every overridable category at once" (expanded by `expandAllCategoryKey` above). `secret` is omitted from the shape entirely, so `{ "categories": { "secret": true } }` is rejected at parse time rather than relying solely on the resolver's runtime floor check. The closed shape is also what lets the published JSON Schema offer real key-name autocomplete, which an open record type cannot.
25
+ * The category toggle map as written by hand: the four overridable categories, plus `all` as shorthand for "every shareable category at once" (expanded by `expandAllCategoryKey` above). `secret` is omitted from the shape entirely, so `{ "categories": { "secret": true } }` is rejected at parse time rather than relying solely on the resolver's runtime floor check. The closed shape is also what lets the published JSON Schema offer real key-name autocomplete, which an open record type cannot.
26
26
  */
27
27
  export declare const CategoryMapSchema: z.ZodPipe<z.ZodObject<{
28
28
  all: z.ZodOptional<z.ZodBoolean>;
@@ -40,7 +40,7 @@ export declare const CategoryMapSchema: z.ZodPipe<z.ZodObject<{
40
40
  /** A duration literal: a positive integer count followed by a unit. Used by `newerThan`/`olderThan`. */
41
41
  export declare const DURATION_RE: RegExp;
42
42
  /**
43
- * A conditional guard on an entries value or a whole directory rule. Every field present within one `when` object must hold (AND logic). An empty object is vacuously true — `claude-use check` warns about it, it is never an error.
43
+ * A conditional guard on an entries value or a whole directory rule. Every field present within one `when` object must hold (AND logic). An empty object is vacuously true — `agent-shim check` warns about it, it is never an error.
44
44
  */
45
45
  export declare const WhenSchema: z.ZodObject<{
46
46
  newerThan: z.ZodOptional<z.ZodString>;
@@ -93,7 +93,7 @@ export declare const CREDENTIAL_TARGETS: readonly ["bearer", "apiKey", "oauthTok
93
93
  export type CredentialTarget = (typeof CREDENTIAL_TARGETS)[number];
94
94
  /** The targets a provider's credential may use: every target except `oauthToken`, which only an identity can carry. */
95
95
  export declare const PROVIDER_CREDENTIAL_TARGETS: readonly ["bearer", "apiKey"];
96
- /** The environment variable each credential target exports the token as. These are also the variables no provider `env` block may set, since claude-use sets and clears them itself. */
96
+ /** The environment variable each credential target exports the token as. These are also the variables no provider `env` block may set, since agent-shim sets and clears them itself. */
97
97
  export declare const CREDENTIAL_TARGET_VARS: {
98
98
  readonly bearer: "ANTHROPIC_AUTH_TOKEN";
99
99
  readonly apiKey: "ANTHROPIC_API_KEY";
@@ -133,7 +133,7 @@ export declare const CredentialSourceSchema: z.ZodUnion<readonly [z.ZodObject<{
133
133
  literal: z.ZodString;
134
134
  }, z.core.$strict>]>;
135
135
  export type CredentialSource = z.infer<typeof CredentialSourceSchema>;
136
- /** Where a cached credential is kept: the macOS login Keychain, or a mode-0600 file under the claude-use home. */
136
+ /** Where a cached credential is kept: the macOS login Keychain, or a mode-0600 file under the agent-shim home. */
137
137
  export declare const CREDENTIAL_CACHE_STORES: readonly ["keychain", "file"];
138
138
  export type CredentialCacheStore = (typeof CREDENTIAL_CACHE_STORES)[number];
139
139
  /**
@@ -187,7 +187,7 @@ export declare const CredentialSchema: z.ZodObject<{
187
187
  }, z.core.$strict>>;
188
188
  }, z.core.$strict>;
189
189
  export type Credential = z.infer<typeof CredentialSchema>;
190
- /** The kinds of provider: `http` is an Anthropic Messages endpoint at a fixed `baseUrl` (the default when `kind` is absent), and `codex` is ChatGPT's Codex backend reached through claude-use's own supervised translation daemon. */
190
+ /** The kinds of provider: `http` is an Anthropic Messages endpoint at a fixed `baseUrl` (the default when `kind` is absent), and `codex` is ChatGPT's Codex backend reached through agent-shim's own supervised translation daemon. */
191
191
  export declare const PROVIDER_KINDS: readonly ["http", "codex"];
192
192
  /**
193
193
  * The Claude model tiers the codex translator maps, in the order they are matched: the first tier whose name is a substring of the requested model (case-insensitive) decides the codex model. `fable` comes before `opus` because a fable model name is the most specific.
@@ -382,7 +382,7 @@ export type Provider = z.infer<typeof ProviderSchema>;
382
382
  /** True when `provider` is a codex provider. `kind` is the tag, since a codex provider's own distinguishing block is optional. */
383
383
  export declare function isCodexProvider(provider: Provider): provider is CodexProvider;
384
384
  /**
385
- * A named, reusable configuration profile at `~/.claude-use/config-profiles/<name>.json`.
385
+ * A named, reusable configuration profile at `~/.agent-shim/config-profiles/<name>.json`.
386
386
  *
387
387
  * `extends` is a flat array of other profiles' *names*, deliberately not a self-referential `z.lazy()` schema: nothing in this shape points back at a profile object, so each file validates in isolation and the extends graph is walked at resolve time. That also means Zod cannot detect a circular `extends` definition — the walker in `src/resolve/extends.ts` carries its own cycle guard.
388
388
  */
@@ -431,7 +431,7 @@ declare const PoolSchema: z.ZodObject<{
431
431
  identities: z.ZodArray<z.ZodString>;
432
432
  }, z.core.$strict>;
433
433
  export type Pool = z.infer<typeof PoolSchema>;
434
- /** One directory rule in `~/.claude-use/directory-rules.json`, scoped to an explicit absolute (or `~`-rooted) path. */
434
+ /** One directory rule in `~/.agent-shim/directory-rules.json`, scoped to an explicit absolute (or `~`-rooted) path. */
435
435
  export declare const DirectoryRuleSchema: z.ZodObject<{
436
436
  entries: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
437
437
  value: z.ZodBoolean;
@@ -477,7 +477,7 @@ export declare const DirectoryRuleSchema: z.ZodObject<{
477
477
  }, z.core.$strict>>;
478
478
  }, z.core.$strict>;
479
479
  export type DirectoryRule = z.infer<typeof DirectoryRuleSchema>;
480
- /** The `~/.claude-use/directory-rules.json` file. */
480
+ /** The `~/.agent-shim/directory-rules.json` file. */
481
481
  export declare const DirectoryRulesSchema: z.ZodObject<{
482
482
  $schema: z.ZodOptional<z.ZodString>;
483
483
  rules: z.ZodArray<z.ZodObject<{
@@ -527,7 +527,7 @@ export declare const DirectoryRulesSchema: z.ZodObject<{
527
527
  }, z.core.$strict>;
528
528
  export type DirectoryRules = z.infer<typeof DirectoryRulesSchema>;
529
529
  /**
530
- * A committed `.claude-use.json` (or its gitignored `.claude-use.local.json` sibling). Structurally a directory rule without the `path` field: its scope is implicit — wherever the file lives, and everything below it — which is exactly what makes it portable across clone locations.
530
+ * A committed `.agent-shim.json` (or its gitignored `.agent-shim.local.json` sibling). Structurally a directory rule without the `path` field: its scope is implicit — wherever the file lives, and everything below it — which is exactly what makes it portable across clone locations.
531
531
  */
532
532
  export declare const PortableConfigSchema: z.ZodObject<{
533
533
  entries: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodBoolean, z.ZodObject<{
@@ -607,7 +607,7 @@ export declare const HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES = 15;
607
607
  * The default `frontdoor.idleShutdownMinutes`, the same trade-off as headroom's: warm through a break, gone the same working day once abandoned.
608
608
  */
609
609
  export declare const FRONTDOOR_DEFAULT_IDLE_SHUTDOWN_MINUTES = 15;
610
- /** The user-global `~/.claude-use/config.json`. */
610
+ /** The user-global `~/.agent-shim/config.json`. */
611
611
  export declare const GlobalConfigSchema: z.ZodObject<{
612
612
  $schema: z.ZodOptional<z.ZodString>;
613
613
  defaultConfigProfile: z.ZodOptional<z.ZodString>;
@@ -729,7 +729,7 @@ export declare const CategoryClassificationSchema: z.ZodObject<{
729
729
  settings: z.ZodArray<z.ZodString>;
730
730
  }, z.core.$strict>;
731
731
  export type CategoryClassification = z.infer<typeof CategoryClassificationSchema>;
732
- /** The gitignored `~/.claude-use/categories.local.json` overlay: any subset of the classification lists, answering "what category is this new entry?" without editing the shipped default map. */
732
+ /** The gitignored `~/.agent-shim/categories.local.json` overlay: any subset of the classification lists, answering "what category is this new entry?" without editing the shipped default map. */
733
733
  export declare const CategoryClassificationOverlaySchema: z.ZodObject<{
734
734
  $schema: z.ZodOptional<z.ZodString>;
735
735
  secret: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -1,10 +1,10 @@
1
1
  /**
2
- * How a launch's capability token is presented and checked. The token reaches the child twice: as the `x-claude-use-auth` header on every request it sends (see `AUTH_HEADER`), and as the password in the `HTTPS_PROXY` URL an OAuth launch gets, which every proxy-aware client turns into `Proxy-Authorization: Basic ...` on its CONNECT request. Both are checked against the same live registry with the same constant-time comparison.
2
+ * How a launch's capability token is presented and checked. The token reaches the child twice: as the `x-agent-shim-auth` header on every request it sends (see `AUTH_HEADER`), and as the password in the `HTTPS_PROXY` URL an OAuth launch gets, which every proxy-aware client turns into `Proxy-Authorization: Basic ...` on its CONNECT request. Both are checked against the same live registry with the same constant-time comparison.
3
3
  */
4
4
  /** The user name in the proxy URL. A label only: the surface checks the password, which is the capability, and ignores the user name, so nothing depends on how a client spells it. */
5
- export declare const CONNECT_PROXY_USER = "claude-use";
5
+ export declare const CONNECT_PROXY_USER = "agent-shim";
6
6
  /** The realm the CONNECT surface's 407 challenge names, so a client that waits for a challenge before sending credentials knows which ones to send. */
7
- export declare const CONNECT_PROXY_REALM = "claude-use front door";
7
+ export declare const CONNECT_PROXY_REALM = "agent-shim front door";
8
8
  /**
9
9
  * The `HTTPS_PROXY` value for a launch: the CONNECT surface's loopback address with the capability as the URL's password. Both userinfo halves are percent-encoded, because a client percent-decodes userinfo before it builds the `Proxy-Authorization` value, so the surface receives exactly the token whatever characters it holds.
10
10
  */
@@ -1,7 +1,7 @@
1
1
  import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "node:http";
2
2
  import * as net from "node:net";
3
3
  /**
4
- * The front door's CONNECT surface, so an OAuth session can have claude-use's routing AND Claude Code's Remote Control at once: Remote Control refuses any `ANTHROPIC_BASE_URL` other than the real API, but happily honours `HTTPS_PROXY`, so OAuth launches route at the proxy layer instead.
4
+ * The front door's CONNECT surface, so an OAuth session can have agent-shim's routing AND Claude Code's Remote Control at once: Remote Control refuses any `ANTHROPIC_BASE_URL` other than the real API, but happily honours `HTTPS_PROXY`, so OAuth launches route at the proxy layer instead.
5
5
  *
6
6
  * Nothing is tunnelled or intercepted for a client that has not authenticated: every CONNECT request must present a live launch's capability as its proxy credential (`Proxy-Authorization: Basic`, which clients derive from the credential in the `HTTPS_PROXY` URL the launcher sets), or it is answered 407 before any target is dialled, so the port is no open proxy for other local processes. Pending and authenticated connections are bounded by `ConnectLimits`.
7
7
  *
@@ -69,7 +69,7 @@ export interface LeafCert {
69
69
  readonly certPem: string;
70
70
  readonly keyPem: string;
71
71
  }
72
- /** Generates the local CA: one RSA keypair, self-signed, CA-only by basicConstraints and keyUsage, with a random serial. Built on `node:crypto` alone (see `x509.ts`), no openssl, so the same code works on every platform claude-use ships to. */
72
+ /** Generates the local CA: one RSA keypair, self-signed, CA-only by basicConstraints and keyUsage, with a random serial. Built on `node:crypto` alone (see `x509.ts`), no openssl, so the same code works on every platform agent-shim ships to. */
73
73
  export declare function generateCa(now: Readonly<Date>): CaMaterial;
74
74
  /** The names the front door's provider listener answers to: the loopback address every provider session's base URL names, plus the loopback hostname for a client that spells it that way. */
75
75
  export declare const LOOPBACK_LEAF_NAMES: readonly string[];
@@ -15,13 +15,13 @@ export interface EnsureFrontDoorPorts {
15
15
  readonly sleep: (ms: number) => void;
16
16
  /** Spawns the detached front-door supervisor, returning its pid. */
17
17
  readonly spawnSupervisor: (paths: LayoutPaths) => number;
18
- /** Authenticates the provider listener on `port`: a TLS handshake chaining to claude-use's CA and a healthy answer, with no capability sent (see `probeFrontDoorSync`). */
18
+ /** Authenticates the provider listener on `port`: a TLS handshake chaining to agent-shim's CA and a healthy answer, with no capability sent (see `probeFrontDoorSync`). */
19
19
  readonly verifyListener: (port: number) => ListenerVerdict;
20
20
  }
21
21
  /**
22
22
  * Brings the front door up for this launch, or finds it serving, and registers this launcher pid in its session registry: the fact that keeps the door from idling out while this session lives, and the record that holds this launch's capability token. The same lock-and-poll coordination as headroom's and the old codex daemon's ensure: the exclusive-create start lock decides which of several concurrent launches spawns the one supervisor, everyone waits on state.json, and a lock whose holder died is removed and retried. Ready means state names a live supervisor and both listeners' ports, which the supervisor writes only after both have bound (and the provider listener has answered its own health probe).
23
23
  *
24
- * A live pid in state proves nothing about who holds the port it names: the door may have crashed and left the port to anyone, or the pid may have been reused by an unrelated process. So before anything is registered or returned, the provider listener is authenticated over TLS against claude-use's CA. A listener that fails (wrong certificate, nothing answering, a bad answer) is treated as a stale or hostile owner: its pid is distrusted for the rest of this call and a replacement supervisor is spawned, which binds a free port when the sticky one is held and is then verified in turn. If a supervisor this call spawned also fails verification, the launch is refused naming the reason and the daemon log; no capability is written and no address is handed to the child.
24
+ * A live pid in state proves nothing about who holds the port it names: the door may have crashed and left the port to anyone, or the pid may have been reused by an unrelated process. So before anything is registered or returned, the provider listener is authenticated over TLS against agent-shim's CA. A listener that fails (wrong certificate, nothing answering, a bad answer) is treated as a stale or hostile owner: its pid is distrusted for the rest of this call and a replacement supervisor is spawned, which binds a free port when the sticky one is held and is then verified in turn. If a supervisor this call spawned also fails verification, the launch is refused naming the reason and the daemon log; no capability is written and no address is handed to the child.
25
25
  */
26
26
  export declare function ensureFrontDoor(params: {
27
27
  readonly paths: LayoutPaths;
@@ -6,7 +6,7 @@ export type ListenerVerdict = {
6
6
  readonly reason: string;
7
7
  };
8
8
  /**
9
- * Authenticates the front door's provider listener before a launch trusts it: a TLS handshake that must chain to claude-use's CA (whose key only this user can read) for 127.0.0.1, then a healthy answer. A process that merely holds the port (a stale state file's port re-bound by someone else, or a reused pid's listener) cannot complete that handshake, so it fails here and the launch never hands its child that address.
9
+ * Authenticates the front door's provider listener before a launch trusts it: a TLS handshake that must chain to agent-shim's CA (whose key only this user can read) for 127.0.0.1, then a healthy answer. A process that merely holds the port (a stale state file's port re-bound by someone else, or a reused pid's listener) cannot complete that handshake, so it fails here and the launch never hands its child that address.
10
10
  *
11
11
  * Synchronous because the launcher is synchronous right through to `spawnSync`: the HTTPS request runs on a worker thread and this thread blocks on a shared buffer until the worker posts its verdict.
12
12
  */
@@ -17,7 +17,7 @@ export interface FrontDoorSupervisorPorts {
17
17
  /** Zombie-aware liveness, the notion every coordination decision in this project uses. */
18
18
  readonly isRunning: (pid: number) => boolean;
19
19
  /**
20
- * Starts the provider listener in this process on `preferredPort` (falling back to any free port when the sticky one is taken, decided at bind time rather than by a racy check-then-bind probe) and resolves once it has bound and answered its own health probe over TLS. This is the HTTPS listener every provider session's base URL points at, serving a loopback leaf signed by claude-use's CA.
20
+ * Starts the provider listener in this process on `preferredPort` (falling back to any free port when the sticky one is taken, decided at bind time rather than by a racy check-then-bind probe) and resolves once it has bound and answered its own health probe over TLS. This is the HTTPS listener every provider session's base URL points at, serving a loopback leaf signed by agent-shim's CA.
21
21
  */
22
22
  readonly startProviderListener: (preferredPort: number | undefined) => Promise<FrontDoorListenerHandle>;
23
23
  /**
@@ -1,6 +1,6 @@
1
1
  /** An IP address as the 4 or 16 octets an iPAddress GeneralName carries. */
2
2
  export declare function ipBytes(address: string): Buffer;
3
- /** A key pair in the PEM forms claude-use persists. */
3
+ /** A key pair in the PEM forms agent-shim persists. */
4
4
  export interface PemKeyPair {
5
5
  readonly certPem: string;
6
6
  readonly keyPem: string;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Whether an install spec resolves through a git ref that can move underneath it. A full commit SHA never moves; a branch name, a tag a maintainer can re-point, or no ref at all (the remote's default branch) can, and a rebased, renamed or deleted branch changes or breaks every fresh install. A registry requirement is not a git source.
3
+ */
4
+ export declare function isMovingGitSource(spec: string): boolean;
5
+ /** The full commit SHA an install spec pins, lowercased, or undefined when the spec is a registry requirement or follows a moving ref. */
6
+ export declare function pinnedGitCommit(spec: string): string | undefined;
7
+ /** The commit an install was built from, read from the text of its `direct_url.json`, or undefined when the file records no VCS commit (a registry install) or is not valid JSON. */
8
+ export declare function parseInstalledCommit(directUrlJson: string): string | undefined;
@@ -38,7 +38,7 @@ export type HeadroomLock = z.infer<typeof HeadroomLockSchema>;
38
38
  /** Reads state.json, or undefined when absent. A malformed file is treated as absent: the lock-and-spawn flow below overwrites it with a fresh supervisor's state rather than crashing every future launch over one bad write. */
39
39
  export declare function readHeadroomState(fs: HeadroomFs, stateFile: string): HeadroomState | undefined;
40
40
  /**
41
- * Writes state.json. A plain write rather than the write-then-rename most config files get: state.json is advisory coordination, read tolerantly (`readHeadroomState` treats a malformed file as absent) and rewritten constantly by the supervisor, and the exclusive-create start lock below, not this file, is the actual mutual exclusion.
41
+ * Writes state.json atomically (a temporary sibling renamed into place), so a concurrent reader never sees a partial file. A reader treats a malformed file as absent, and a launcher that finds no supervisor in state spawns one, so a torn write read mid-flight started a redundant supervisor and daemon.
42
42
  */
43
43
  export declare function writeHeadroomState(fs: HeadroomFs, stateFile: string, state: Readonly<HeadroomState>): void;
44
44
  /** The allowlist the daemon is started with: every provider's base URL plus Claude Code's own API, so a session with no provider selected reaches the real Anthropic upstream through the same proxy. */