agent-shim 8.10.0 → 8.11.1

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
@@ -2815,8 +2815,8 @@ function parseConnectTarget(authority) {
2815
2815
  function isInterceptedHost(host, interceptHosts) {
2816
2816
  return interceptHosts.includes(host);
2817
2817
  }
2818
- function servedByPipeline(path29) {
2819
- return path29?.startsWith(ROUTED_PATH_PREFIX) === true;
2818
+ function servedByPipeline(path30) {
2819
+ return path30?.startsWith(ROUTED_PATH_PREFIX) === true;
2820
2820
  }
2821
2821
  var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
2822
2822
  "connection",
@@ -3340,13 +3340,18 @@ function createRcSessionTracker(deps) {
3340
3340
  entries.set(id, record);
3341
3341
  return record;
3342
3342
  };
3343
+ const persistCredential = (entry) => {
3344
+ if (entry.oauthAuthorization !== void 0) {
3345
+ deps.credentialStore?.write(entry.id, { authorization: entry.oauthAuthorization, anthropicVersion: entry.anthropicVersion, anthropicClientPlatform: entry.anthropicClientPlatform });
3346
+ }
3347
+ };
3343
3348
  const observeExchange = (request4) => {
3344
3349
  const method = (request4.method ?? "").toUpperCase();
3345
- const path29 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
3346
- if (!path29.startsWith(RC_SESSIONS_PATH_PREFIX)) {
3350
+ const path30 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
3351
+ if (!path30.startsWith(RC_SESSIONS_PATH_PREFIX)) {
3347
3352
  return void 0;
3348
3353
  }
3349
- const tail = path29.slice(RC_SESSIONS_PATH_PREFIX.length);
3354
+ const tail = path30.slice(RC_SESSIONS_PATH_PREFIX.length);
3350
3355
  const facts = {
3351
3356
  oauthAuthorization: oauthAuthorizationOf(request4.headers),
3352
3357
  anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
@@ -3379,7 +3384,7 @@ function createRcSessionTracker(deps) {
3379
3384
  if (id2 === void 0) {
3380
3385
  return;
3381
3386
  }
3382
- birth(id2, facts);
3387
+ persistCredential(birth(id2, facts));
3383
3388
  }
3384
3389
  };
3385
3390
  }
@@ -3393,6 +3398,7 @@ function createRcSessionTracker(deps) {
3393
3398
  entry.oauthAuthorization = facts.oauthAuthorization ?? entry.oauthAuthorization;
3394
3399
  entry.anthropicVersion = facts.anthropicVersion ?? entry.anthropicVersion;
3395
3400
  entry.anthropicClientPlatform = facts.anthropicClientPlatform ?? entry.anthropicClientPlatform;
3401
+ persistCredential(entry);
3396
3402
  const bodyKind = method === "POST" && rest === `${id}/worker/events` ? "worker-events" : method === "POST" && rest === `${id}/events` ? "client-events" : method === "POST" && rest === `${id}/worker/heartbeat` ? "heartbeat" : method === "PUT" && rest === `${id}/worker` ? "worker-registration" : void 0;
3397
3403
  let chunks = [];
3398
3404
  let buffered = 0;
@@ -3446,6 +3452,7 @@ function createRcSessionTracker(deps) {
3446
3452
  },
3447
3453
  onResponse: (status, headers) => {
3448
3454
  if (singleHeader(headers, CONFLICT_REASON_HEADER) !== void 0 || archiving && isSuccessful(status)) {
3455
+ deps.credentialStore?.remove(id);
3449
3456
  expire(id);
3450
3457
  return;
3451
3458
  }
@@ -3478,7 +3485,18 @@ function createRcSessionTracker(deps) {
3478
3485
  },
3479
3486
  credentialOf: (sessionId) => {
3480
3487
  const entry = entries.get(sessionId);
3481
- return entry === void 0 ? void 0 : { authorization: entry.oauthAuthorization, anthropicVersion: entry.anthropicVersion, anthropicClientPlatform: entry.anthropicClientPlatform };
3488
+ if (entry === void 0) {
3489
+ return void 0;
3490
+ }
3491
+ if (entry.oauthAuthorization === void 0 && deps.credentialStore !== void 0) {
3492
+ const persisted = deps.credentialStore.read(sessionId);
3493
+ if (persisted?.authorization !== void 0) {
3494
+ entry.oauthAuthorization = persisted.authorization;
3495
+ entry.anthropicVersion = entry.anthropicVersion ?? persisted.anthropicVersion;
3496
+ entry.anthropicClientPlatform = entry.anthropicClientPlatform ?? persisted.anthropicClientPlatform;
3497
+ }
3498
+ }
3499
+ return { authorization: entry.oauthAuthorization, anthropicVersion: entry.anthropicVersion, anthropicClientPlatform: entry.anthropicClientPlatform };
3482
3500
  },
3483
3501
  noteSequenceNums: (sessionId, sequenceNums) => {
3484
3502
  const entry = entries.get(sessionId);
@@ -4094,9 +4112,9 @@ function sequenceNumsOfBody(body) {
4094
4112
  }
4095
4113
  function frontDoorRcControl(transport, token) {
4096
4114
  const headers = { authorization: `Bearer ${token}` };
4097
- const listAnswerOf = async (path29, what) => {
4115
+ const listAnswerOf = async (path30, what) => {
4098
4116
  try {
4099
- return await transport.request({ method: "GET", path: path29, headers });
4117
+ return await transport.request({ method: "GET", path: path30, headers });
4100
4118
  } catch (error) {
4101
4119
  throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
4102
4120
  }
@@ -4168,10 +4186,10 @@ function frontDoorRcControl(transport, token) {
4168
4186
  }
4169
4187
  return pending;
4170
4188
  };
4171
- const writeOf = async (path29, body, describeFailure) => {
4189
+ const writeOf = async (path30, body, describeFailure) => {
4172
4190
  let answer;
4173
4191
  try {
4174
- answer = await transport.request({ method: "POST", path: path29, headers: { ...headers, "content-type": "application/json" }, body });
4192
+ answer = await transport.request({ method: "POST", path: path30, headers: { ...headers, "content-type": "application/json" }, body });
4175
4193
  } catch (error) {
4176
4194
  return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
4177
4195
  }
@@ -4219,15 +4237,27 @@ var SUCCESS_STATUS_MAX_EXCLUSIVE2 = 300;
4219
4237
  function isSuccessful2(status) {
4220
4238
  return status >= HTTP_STATUS.ok && status < SUCCESS_STATUS_MAX_EXCLUSIVE2;
4221
4239
  }
4222
- var UPSTREAM_LOCAL_PORT_START = 47900;
4223
- var UPSTREAM_LOCAL_PORT_END = 47919;
4224
- var UPSTREAM_LOCAL_PORT_COUNT = UPSTREAM_LOCAL_PORT_END - UPSTREAM_LOCAL_PORT_START + 1;
4225
- var nextUpstreamLocalPort = UPSTREAM_LOCAL_PORT_START;
4226
- function upstreamLocalPort() {
4227
- const port = nextUpstreamLocalPort;
4228
- nextUpstreamLocalPort = nextUpstreamLocalPort === UPSTREAM_LOCAL_PORT_END ? UPSTREAM_LOCAL_PORT_START : nextUpstreamLocalPort + 1;
4229
- return port;
4230
- }
4240
+ var SourcePortRange = class {
4241
+ constructor(start, end) {
4242
+ this.start = start;
4243
+ this.end = end;
4244
+ this.count = end - start + 1;
4245
+ this.next = start;
4246
+ }
4247
+ start;
4248
+ end;
4249
+ count;
4250
+ next;
4251
+ /** The next port in rotation, wrapping from the end back to the start. */
4252
+ take() {
4253
+ const port = this.next;
4254
+ this.next = this.next === this.end ? this.start : this.next + 1;
4255
+ return port;
4256
+ }
4257
+ };
4258
+ var DOOR_SOURCE_PORT_START = 47900;
4259
+ var DOOR_SOURCE_PORT_END = 47919;
4260
+ var DOOR_SOURCE_PORTS = new SourcePortRange(DOOR_SOURCE_PORT_START, DOOR_SOURCE_PORT_END);
4231
4261
  var realAddressLookup = (host, _options, callback) => {
4232
4262
  if (net2.isIP(host) !== 0) {
4233
4263
  callback(null, [{ address: host, family: net2.isIP(host) }]);
@@ -4265,14 +4295,14 @@ function dialTarget(options, defaultPort) {
4265
4295
  function literalDial(target) {
4266
4296
  return net2.connect({ host: target.host, port: target.port });
4267
4297
  }
4268
- async function reservedDial(target) {
4298
+ async function reservedDial(target, ports) {
4269
4299
  for (let attempt = 0; ; attempt += 1) {
4270
- const outcome = await dialOnce({ host: target.host, port: target.port, localPort: upstreamLocalPort(), lookup: realAddressLookup });
4300
+ const outcome = await dialOnce({ host: target.host, port: target.port, localPort: ports.take(), lookup: realAddressLookup });
4271
4301
  if (outcome.error === null) {
4272
4302
  return outcome;
4273
4303
  }
4274
4304
  const held = outcome.error.code !== void 0 && HELD_PORT_ERRNOS.has(outcome.error.code);
4275
- if (!held || attempt === UPSTREAM_LOCAL_PORT_COUNT - 1) {
4305
+ if (!held || attempt === ports.count - 1) {
4276
4306
  return outcome;
4277
4307
  }
4278
4308
  }
@@ -4281,26 +4311,36 @@ function requestServername(options, fallback) {
4281
4311
  return "servername" in options && typeof options.servername === "string" && options.servername !== "" ? options.servername : fallback;
4282
4312
  }
4283
4313
  var ExemptHttpAgent = class extends http.Agent {
4314
+ constructor(ports = DOOR_SOURCE_PORTS) {
4315
+ super();
4316
+ this.ports = ports;
4317
+ }
4318
+ ports;
4284
4319
  // A reserved-port dial that has to retry cannot produce its socket synchronously, so it settles first and arrives through the callback (node's documented asynchronous createConnection form); a literal dial has nothing to retry and keeps node's own synchronous shape.
4285
4320
  createConnection(options, oncreate) {
4286
4321
  const target = dialTarget(options, HTTP_PORT);
4287
4322
  if (net2.isIP(target.host) !== 0) {
4288
4323
  return literalDial(target);
4289
4324
  }
4290
- void reservedDial(target).then((outcome) => {
4325
+ void reservedDial(target, this.ports).then((outcome) => {
4291
4326
  oncreate?.(outcome.error, outcome.socket);
4292
4327
  });
4293
4328
  return void 0;
4294
4329
  }
4295
4330
  };
4296
4331
  var ExemptTlsAgent = class extends https2.Agent {
4332
+ constructor(ports = DOOR_SOURCE_PORTS) {
4333
+ super();
4334
+ this.ports = ports;
4335
+ }
4336
+ ports;
4297
4337
  // The same split as the plain sibling: a literal dial wraps TLS around the socket node's own agent would have returned, a reserved dial settles (retries included) first and arrives through the callback, which is exactly where node's own agent wraps its own dials.
4298
4338
  createConnection(options, oncreate) {
4299
4339
  const target = dialTarget(options, HTTPS_PORT);
4300
4340
  if (net2.isIP(target.host) !== 0) {
4301
4341
  return tls.connect({ socket: literalDial(target), servername: requestServername(options, target.host), ...tlsFacts(options) });
4302
4342
  }
4303
- void reservedDial(target).then((outcome) => {
4343
+ void reservedDial(target, this.ports).then((outcome) => {
4304
4344
  if (outcome.error !== null) {
4305
4345
  oncreate?.(outcome.error, outcome.socket);
4306
4346
  return;
@@ -4361,12 +4401,12 @@ var NO_CHUNKS = {
4361
4401
  };
4362
4402
  function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
4363
4403
  const agent = new ExemptTlsAgent();
4364
- const request4 = async (method, path29, headers, body, signal) => await new Promise((resolve, reject) => {
4404
+ const request4 = async (method, path30, headers, body, signal) => await new Promise((resolve, reject) => {
4365
4405
  const options = {
4366
4406
  host: target.host,
4367
4407
  port: target.port,
4368
4408
  method,
4369
- path: path29,
4409
+ path: path30,
4370
4410
  // The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
4371
4411
  headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
4372
4412
  agent,
@@ -4403,9 +4443,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
4403
4443
  return { status, body: await readAll(response) };
4404
4444
  },
4405
4445
  openStream: async (sessionId, headers, resume, signal) => {
4406
- const path29 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
4446
+ const path30 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
4407
4447
  const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
4408
- const { status, response } = await request4("GET", path29, streamHeaders, void 0, signal);
4448
+ const { status, response } = await request4("GET", path30, streamHeaders, void 0, signal);
4409
4449
  if (!isSuccessful2(status)) {
4410
4450
  await readAll(response);
4411
4451
  return { status, chunks: NO_CHUNKS };
@@ -4414,9 +4454,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
4414
4454
  }
4415
4455
  };
4416
4456
  }
4417
- function realConnectEffects() {
4418
- const plainAgent = new ExemptHttpAgent();
4419
- const tlsAgent = new ExemptTlsAgent();
4457
+ function realConnectEffects(ports = DOOR_SOURCE_PORTS) {
4458
+ const plainAgent = new ExemptHttpAgent(ports);
4459
+ const tlsAgent = new ExemptTlsAgent(ports);
4420
4460
  const listenOnce = async (port, onSocket) => await new Promise((resolve, reject) => {
4421
4461
  const accepted = /* @__PURE__ */ new Set();
4422
4462
  const server = net2.createServer((socket) => {
@@ -4534,7 +4574,7 @@ function realConnectEffects() {
4534
4574
  };
4535
4575
  },
4536
4576
  connectTlsUpstream: async (host, port, clientAlpn) => {
4537
- const dialled = await reservedDial({ host, port });
4577
+ const dialled = await reservedDial({ host, port }, ports);
4538
4578
  if (dialled.error !== null) {
4539
4579
  throw dialled.error;
4540
4580
  }
@@ -4616,6 +4656,64 @@ function realConnectEffects() {
4616
4656
  };
4617
4657
  }
4618
4658
 
4659
+ // src/frontdoor/rcCredentialStore.ts
4660
+ import path9 from "node:path";
4661
+ function isSafeSessionId(sessionId) {
4662
+ return /^[A-Za-z0-9_-]+$/.test(sessionId);
4663
+ }
4664
+ function isRecord3(value) {
4665
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4666
+ }
4667
+ function credentialOfJson(parsed) {
4668
+ if (!isRecord3(parsed)) {
4669
+ return void 0;
4670
+ }
4671
+ const { authorization, anthropicVersion, anthropicClientPlatform } = parsed;
4672
+ if (typeof authorization !== "string" || authorization === "") {
4673
+ return void 0;
4674
+ }
4675
+ return {
4676
+ authorization,
4677
+ anthropicVersion: typeof anthropicVersion === "string" ? anthropicVersion : void 0,
4678
+ anthropicClientPlatform: typeof anthropicClientPlatform === "string" ? anthropicClientPlatform : void 0
4679
+ };
4680
+ }
4681
+ function createRcCredentialStore(fs12, dir) {
4682
+ fs12.mkdirPrivate(dir);
4683
+ const fileFor = (sessionId) => path9.join(dir, `${sessionId}.json`);
4684
+ return {
4685
+ read: (sessionId) => {
4686
+ if (!isSafeSessionId(sessionId)) {
4687
+ return void 0;
4688
+ }
4689
+ const raw = fs12.readFileUtf8(fileFor(sessionId));
4690
+ if (raw === void 0) {
4691
+ return void 0;
4692
+ }
4693
+ let parsed;
4694
+ try {
4695
+ parsed = JSON.parse(raw);
4696
+ } catch {
4697
+ return void 0;
4698
+ }
4699
+ return credentialOfJson(parsed);
4700
+ },
4701
+ write: (sessionId, credential) => {
4702
+ if (!isSafeSessionId(sessionId)) {
4703
+ return;
4704
+ }
4705
+ fs12.writeFilePrivate(fileFor(sessionId), `${JSON.stringify(credential, null, 2)}
4706
+ `);
4707
+ },
4708
+ remove: (sessionId) => {
4709
+ if (!isSafeSessionId(sessionId)) {
4710
+ return;
4711
+ }
4712
+ fs12.removeRecursive(fileFor(sessionId));
4713
+ }
4714
+ };
4715
+ }
4716
+
4619
4717
  // src/frontdoor/rcApi.ts
4620
4718
  import { createORPCClient, ORPCError } from "@orpc/client";
4621
4719
  import { RPCLink } from "@orpc/client/fetch";
@@ -4873,7 +4971,7 @@ function createSseParser() {
4873
4971
  }
4874
4972
  };
4875
4973
  }
4876
- function isRecord3(value) {
4974
+ function isRecord4(value) {
4877
4975
  return typeof value === "object" && value !== null && !Array.isArray(value);
4878
4976
  }
4879
4977
  function sequenceNumOf(value) {
@@ -4895,7 +4993,7 @@ function parseRcStreamEnvelope(parsed) {
4895
4993
  } catch {
4896
4994
  return void 0;
4897
4995
  }
4898
- if (!isRecord3(data)) {
4996
+ if (!isRecord4(data)) {
4899
4997
  return void 0;
4900
4998
  }
4901
4999
  const eventType = data.event_type;
@@ -4984,6 +5082,7 @@ function createRcStreamHub(deps) {
4984
5082
  if (!isSuccessful3(answer.status)) {
4985
5083
  throw new Error(`the client read stream answered HTTP ${String(answer.status)}`);
4986
5084
  }
5085
+ deps.log?.(`rc stream ${attachment.sessionId}: attached as client ${attachment.clientId}${resume === void 0 ? ", reading from the stream's own head" : `, resuming after sequence number ${String(resume.fromSequenceNum)}`}`);
4987
5086
  const parser = createSseParser();
4988
5087
  for await (const chunk of answer.chunks) {
4989
5088
  attachment.controller.signal.throwIfAborted();
@@ -5007,6 +5106,7 @@ function createRcStreamHub(deps) {
5007
5106
  const live = deps.trackedSessions().includes(attachment.sessionId);
5008
5107
  const credential = deps.credentialOf(attachment.sessionId);
5009
5108
  if (!live || credential?.authorization === void 0) {
5109
+ deps.log?.(`rc stream ${attachment.sessionId}: the attachment ended (${live ? "the session's client credential is no longer known" : "the tracker gave up on the session"})`);
5010
5110
  if (attachments.get(attachment.sessionId) === attachment) {
5011
5111
  attachments.delete(attachment.sessionId);
5012
5112
  }
@@ -5028,6 +5128,7 @@ function createRcStreamHub(deps) {
5028
5128
  return;
5029
5129
  }
5030
5130
  if (outcome === "dropped") {
5131
+ deps.log?.(`rc stream ${attachment.sessionId}: the stream ended of its own accord, reconnecting`);
5031
5132
  retriedUnauthorized = false;
5032
5133
  continue;
5033
5134
  }
@@ -5077,7 +5178,7 @@ import { randomUUID as randomUUID3 } from "node:crypto";
5077
5178
 
5078
5179
  // src/headroom/state.ts
5079
5180
  import { createHash as createHash3 } from "node:crypto";
5080
- import path9 from "node:path";
5181
+ import path10 from "node:path";
5081
5182
  import { z as z5 } from "zod";
5082
5183
  var HEADROOM_ANTHROPIC_UPSTREAM = "https://api.anthropic.com";
5083
5184
  var HEADROOM_STATE_SCHEMA_VERSION = 2;
@@ -5118,7 +5219,7 @@ function readHeadroomState(fs12, stateFile) {
5118
5219
  }
5119
5220
  }
5120
5221
  function writeHeadroomState(fs12, stateFile, state) {
5121
- fs12.mkdirp(path9.dirname(stateFile));
5222
+ fs12.mkdirp(path10.dirname(stateFile));
5122
5223
  fs12.writeFilePrivate(stateFile, `${JSON.stringify(state, null, 2)}
5123
5224
  `);
5124
5225
  }
@@ -5146,7 +5247,7 @@ function readAllProviders(fs12, providersDir) {
5146
5247
  continue;
5147
5248
  }
5148
5249
  try {
5149
- const parsed = parseJson(fs12.readFileUtf8(path9.join(providersDir, name)), ProviderSchema);
5250
+ const parsed = parseJson(fs12.readFileUtf8(path10.join(providersDir, name)), ProviderSchema);
5150
5251
  if (parsed !== void 0) {
5151
5252
  result.push({ name: name.slice(0, -".json".length), provider: parsed });
5152
5253
  }
@@ -5158,11 +5259,11 @@ function readAllProviders(fs12, providersDir) {
5158
5259
  }
5159
5260
  function writeSession(fs12, sessionsDir, session) {
5160
5261
  fs12.mkdirp(sessionsDir);
5161
- fs12.writeFileUtf8(path9.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
5262
+ fs12.writeFileUtf8(path10.join(sessionsDir, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
5162
5263
  `);
5163
5264
  }
5164
5265
  function removeSession(fs12, sessionsDir, pid) {
5165
- fs12.removeRecursive(path9.join(sessionsDir, `${String(pid)}.json`));
5266
+ fs12.removeRecursive(path10.join(sessionsDir, `${String(pid)}.json`));
5166
5267
  }
5167
5268
  function listSessions(fs12, sessionsDir) {
5168
5269
  const sessions = [];
@@ -5171,7 +5272,7 @@ function listSessions(fs12, sessionsDir) {
5171
5272
  continue;
5172
5273
  }
5173
5274
  try {
5174
- const parsed = parseJson(fs12.readFileUtf8(path9.join(sessionsDir, name)), HeadroomSessionSchema);
5275
+ const parsed = parseJson(fs12.readFileUtf8(path10.join(sessionsDir, name)), HeadroomSessionSchema);
5175
5276
  if (parsed !== void 0) {
5176
5277
  sessions.push(parsed);
5177
5278
  }
@@ -5276,10 +5377,10 @@ function ensureFrontDoor(params) {
5276
5377
  }
5277
5378
 
5278
5379
  // src/usage/read.ts
5279
- import path11 from "node:path";
5380
+ import path12 from "node:path";
5280
5381
 
5281
5382
  // src/usage/account.ts
5282
- import path10 from "node:path";
5383
+ import path11 from "node:path";
5283
5384
 
5284
5385
  // src/usage/schema.ts
5285
5386
  import { z as z6 } from "zod";
@@ -5445,7 +5546,7 @@ function isIdentityName(name) {
5445
5546
  return IdentitySchema.shape.name.safeParse(name).success;
5446
5547
  }
5447
5548
  function claudeJsonPath(identitiesDir, identity) {
5448
- return path10.join(identitiesDir, identity, CLAUDE_JSON);
5549
+ return path11.join(identitiesDir, identity, CLAUDE_JSON);
5449
5550
  }
5450
5551
  function readAccountMetadata(fs12, identitiesDir, identity) {
5451
5552
  if (!isIdentityName(identity)) {
@@ -5504,7 +5605,7 @@ function readUsageLog(fs12, logDir, options = {}) {
5504
5605
  if (sinceMs !== void 0 && segment.endsAt <= sinceMs) {
5505
5606
  continue;
5506
5607
  }
5507
- const contents = fs12.readFileUtf8(path11.join(logDir, segment.name));
5608
+ const contents = fs12.readFileUtf8(path12.join(logDir, segment.name));
5508
5609
  if (contents === void 0) {
5509
5610
  continue;
5510
5611
  }
@@ -5546,7 +5647,7 @@ function snapshotPath(snapshotsDir, identity) {
5546
5647
  if (!isIdentityName(identity)) {
5547
5648
  throw new Error(`"${identity}" is not a valid identity name.`);
5548
5649
  }
5549
- return path11.join(snapshotsDir, `${identity}.json`);
5650
+ return path12.join(snapshotsDir, `${identity}.json`);
5550
5651
  }
5551
5652
  function readUsageSnapshot(fs12, snapshotsDir, identity) {
5552
5653
  const file = snapshotPath(snapshotsDir, identity);
@@ -5880,7 +5981,7 @@ function rankPool(input) {
5880
5981
  }
5881
5982
 
5882
5983
  // src/usage/poolPick.ts
5883
- import path12 from "node:path";
5984
+ import path13 from "node:path";
5884
5985
  import { z as z9 } from "zod";
5885
5986
 
5886
5987
  // src/usage/store.ts
@@ -5947,13 +6048,13 @@ function recordStickyPick(fs12, picksFile, directory, identity, nowMs) {
5947
6048
  const current = readPicksFile(fs12, picksFile).file.picks;
5948
6049
  const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
5949
6050
  const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
5950
- fs12.mkdirPrivate(path12.dirname(picksFile));
6051
+ fs12.mkdirPrivate(path13.dirname(picksFile));
5951
6052
  fs12.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
5952
6053
  `);
5953
6054
  }
5954
6055
 
5955
6056
  // src/launcher/identity.ts
5956
- import path13 from "node:path";
6057
+ import path14 from "node:path";
5957
6058
  function poolNameOf(selector) {
5958
6059
  return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
5959
6060
  }
@@ -6002,7 +6103,7 @@ function decideConfigProfile(params) {
6002
6103
  return { source: "none" };
6003
6104
  }
6004
6105
  function loadIdentity(identitiesDir, name, fs12) {
6005
- return loadConfigFile(path13.join(identitiesDir, name, "identity.json"), IdentitySchema, fs12.readConfigFile);
6106
+ return loadConfigFile(path14.join(identitiesDir, name, "identity.json"), IdentitySchema, fs12.readConfigFile);
6006
6107
  }
6007
6108
 
6008
6109
  // src/launcher/pool.ts
@@ -6217,7 +6318,7 @@ function hashSettings(settings) {
6217
6318
  }
6218
6319
 
6219
6320
  // src/headroom/socket.ts
6220
- import path14 from "node:path";
6321
+ import path15 from "node:path";
6221
6322
  var GROUP_OR_OTHER_BITS = 63;
6222
6323
  var OCTAL_RADIX = 8;
6223
6324
  var MODE_DIGITS = 4;
@@ -6226,7 +6327,7 @@ var HEADROOM_SOCKET_NAME = /^(\d+)\.sock$/;
6226
6327
  var UNIX_SOCKET_PATH_MAX_BYTES = 103;
6227
6328
  var PLATFORMS_WITHOUT_UNIX_SOCKETS = ["win32"];
6228
6329
  function headroomSocketPath(paths, supervisorPid) {
6229
- return path14.join(paths.headroomSocketDir, `${String(supervisorPid)}${HEADROOM_SOCKET_SUFFIX}`);
6330
+ return path15.join(paths.headroomSocketDir, `${String(supervisorPid)}${HEADROOM_SOCKET_SUFFIX}`);
6230
6331
  }
6231
6332
  function platformRefusal(platform) {
6232
6333
  return PLATFORMS_WITHOUT_UNIX_SOCKETS.includes(platform) ? `headroom routing needs a unix domain socket, which headroom cannot serve on ${platform}; agent-shim never falls back to a TCP port for this hop` : void 0;
@@ -6275,7 +6376,7 @@ function pruneStaleHeadroomSockets(fs12, paths, isRunning) {
6275
6376
  if (pid === void 0 || isRunning(Number.parseInt(pid, 10))) {
6276
6377
  continue;
6277
6378
  }
6278
- fs12.removeRecursive(path14.join(paths.headroomSocketDir, name));
6379
+ fs12.removeRecursive(path15.join(paths.headroomSocketDir, name));
6279
6380
  removed.push(name);
6280
6381
  }
6281
6382
  return removed;
@@ -6599,14 +6700,14 @@ function evaluateAmbientCredentialGuard(params) {
6599
6700
  // src/paths.ts
6600
6701
  import fs3 from "node:fs";
6601
6702
  import os3 from "node:os";
6602
- import path15 from "node:path";
6703
+ import path16 from "node:path";
6603
6704
  function resolveAgentShimHome(env = process.env, home = os3.homedir(), isDirectory = isExistingDirectory) {
6604
6705
  const fromEnv = env.AGENT_SHIM_HOME;
6605
6706
  if (fromEnv !== void 0 && fromEnv !== "") {
6606
6707
  return fromEnv;
6607
6708
  }
6608
- const current = path15.join(home, HOME_DIRNAME);
6609
- const legacy = path15.join(home, LEGACY_HOME_DIRNAME);
6709
+ const current = path16.join(home, HOME_DIRNAME);
6710
+ const legacy = path16.join(home, LEGACY_HOME_DIRNAME);
6610
6711
  return !isDirectory(current) && isDirectory(legacy) ? legacy : current;
6611
6712
  }
6612
6713
  function isExistingDirectory(candidate) {
@@ -6617,40 +6718,41 @@ function resolveClaudeHome() {
6617
6718
  if (fromEnv !== void 0 && fromEnv !== "") {
6618
6719
  return fromEnv;
6619
6720
  }
6620
- return path15.join(os3.homedir(), ".claude");
6721
+ return path16.join(os3.homedir(), ".claude");
6621
6722
  }
6622
6723
  function buildLayoutPaths(root) {
6623
6724
  return {
6624
6725
  root,
6625
- identitiesDir: path15.join(root, "identities"),
6626
- configProfilesDir: path15.join(root, "config-profiles"),
6627
- providersDir: path15.join(root, "providers"),
6628
- directoryRulesFile: path15.join(root, "directory-rules.json"),
6629
- activeIdentityFile: path15.join(root, "active-identity"),
6630
- globalConfigFile: path15.join(root, "config.json"),
6631
- categoriesLocalFile: path15.join(root, "categories.local.json"),
6632
- claudeShimFile: path15.join(root, "claude-shim.json"),
6633
- headroomDir: path15.join(root, "headroom"),
6634
- headroomStateFile: path15.join(root, "headroom", `state.v${String(HEADROOM_STATE_SCHEMA_VERSION)}.json`),
6635
- headroomSocketDir: path15.join(root, "headroom", "run"),
6636
- headroomLockFile: path15.join(root, "headroom", "start.lock"),
6637
- headroomSessionsDir: path15.join(root, "headroom", "sessions"),
6638
- logsDir: path15.join(root, "logs"),
6639
- headroomLogPath: path15.join(root, "logs", "headroom.log"),
6640
- frontdoorDir: path15.join(root, "frontdoor"),
6641
- frontdoorCaDir: path15.join(root, "frontdoor", "ca"),
6642
- frontdoorCaCertFile: path15.join(root, "frontdoor", "ca", "ca.pem"),
6643
- frontdoorCaKeyFile: path15.join(root, "frontdoor", "ca", "ca.key"),
6644
- frontdoorCaBundlesDir: path15.join(root, "frontdoor", "ca", "bundles"),
6645
- frontdoorStateFile: path15.join(root, "frontdoor", "state.json"),
6646
- frontdoorLockFile: path15.join(root, "frontdoor", "start.lock"),
6647
- frontdoorControlTokenFile: path15.join(root, "frontdoor", "control-token"),
6648
- frontdoorSessionsDir: path15.join(root, "frontdoor", "sessions"),
6649
- frontdoorLogPath: path15.join(root, "logs", "frontdoor.log"),
6650
- usageDir: path15.join(root, "usage"),
6651
- usageLogDir: path15.join(root, "usage", "log"),
6652
- usageSnapshotsDir: path15.join(root, "usage", "snapshots"),
6653
- usagePicksFile: path15.join(root, "usage", "picks.json")
6726
+ identitiesDir: path16.join(root, "identities"),
6727
+ configProfilesDir: path16.join(root, "config-profiles"),
6728
+ providersDir: path16.join(root, "providers"),
6729
+ directoryRulesFile: path16.join(root, "directory-rules.json"),
6730
+ activeIdentityFile: path16.join(root, "active-identity"),
6731
+ globalConfigFile: path16.join(root, "config.json"),
6732
+ categoriesLocalFile: path16.join(root, "categories.local.json"),
6733
+ claudeShimFile: path16.join(root, "claude-shim.json"),
6734
+ headroomDir: path16.join(root, "headroom"),
6735
+ headroomStateFile: path16.join(root, "headroom", `state.v${String(HEADROOM_STATE_SCHEMA_VERSION)}.json`),
6736
+ headroomSocketDir: path16.join(root, "headroom", "run"),
6737
+ headroomLockFile: path16.join(root, "headroom", "start.lock"),
6738
+ headroomSessionsDir: path16.join(root, "headroom", "sessions"),
6739
+ logsDir: path16.join(root, "logs"),
6740
+ headroomLogPath: path16.join(root, "logs", "headroom.log"),
6741
+ frontdoorDir: path16.join(root, "frontdoor"),
6742
+ frontdoorCaDir: path16.join(root, "frontdoor", "ca"),
6743
+ frontdoorCaCertFile: path16.join(root, "frontdoor", "ca", "ca.pem"),
6744
+ frontdoorCaKeyFile: path16.join(root, "frontdoor", "ca", "ca.key"),
6745
+ frontdoorCaBundlesDir: path16.join(root, "frontdoor", "ca", "bundles"),
6746
+ frontdoorStateFile: path16.join(root, "frontdoor", "state.json"),
6747
+ frontdoorLockFile: path16.join(root, "frontdoor", "start.lock"),
6748
+ frontdoorControlTokenFile: path16.join(root, "frontdoor", "control-token"),
6749
+ frontdoorSessionsDir: path16.join(root, "frontdoor", "sessions"),
6750
+ frontdoorRcCredentialsDir: path16.join(root, "frontdoor", "rc-credentials"),
6751
+ frontdoorLogPath: path16.join(root, "logs", "frontdoor.log"),
6752
+ usageDir: path16.join(root, "usage"),
6753
+ usageLogDir: path16.join(root, "usage", "log"),
6754
+ usageSnapshotsDir: path16.join(root, "usage", "snapshots"),
6755
+ usagePicksFile: path16.join(root, "usage", "picks.json")
6654
6756
  };
6655
6757
  }
6656
6758
  function resolveLayoutPaths() {
@@ -6659,11 +6761,11 @@ function resolveLayoutPaths() {
6659
6761
 
6660
6762
  // src/identityStore.ts
6661
6763
  import fs5 from "node:fs";
6662
- import path17 from "node:path";
6764
+ import path18 from "node:path";
6663
6765
 
6664
6766
  // src/configProfilesStore.ts
6665
6767
  import fs4 from "node:fs";
6666
- import path16 from "node:path";
6768
+ import path17 from "node:path";
6667
6769
  var ProfileNotFoundError = class extends CliError {
6668
6770
  constructor(profileName) {
6669
6771
  super(`No configuration profile named "${profileName}". Run \`agent-shim profile add ${profileName}\` first.`);
@@ -6689,7 +6791,7 @@ var InvalidCategoryNameError = class extends CliError {
6689
6791
  categoryName;
6690
6792
  };
6691
6793
  function profileJsonPath(paths, name) {
6692
- return path16.join(paths.configProfilesDir, `${name}.json`);
6794
+ return path17.join(paths.configProfilesDir, `${name}.json`);
6693
6795
  }
6694
6796
  function profileExists(paths, name) {
6695
6797
  return fs4.existsSync(profileJsonPath(paths, name));
@@ -6877,7 +6979,7 @@ var InvalidIdentityNameError = class extends CliError {
6877
6979
  attemptedName;
6878
6980
  };
6879
6981
  function identityJsonPath(paths, name) {
6880
- return path17.join(paths.identitiesDir, name, "identity.json");
6982
+ return path18.join(paths.identitiesDir, name, "identity.json");
6881
6983
  }
6882
6984
  function identityExists(paths, name) {
6883
6985
  return fs5.existsSync(identityJsonPath(paths, name));
@@ -6978,7 +7080,7 @@ function setIdentityCredential(paths, identityName, change) {
6978
7080
  });
6979
7081
  }
6980
7082
  function belongsToIdentity(entry, name) {
6981
- return entry === name || entry === path17.basename(identityLockPath("", name)) || entry.startsWith(`.${name}.scratch.`) || entry.startsWith(`.${name}.previous.`);
7083
+ return entry === name || entry === path18.basename(identityLockPath("", name)) || entry.startsWith(`.${name}.scratch.`) || entry.startsWith(`.${name}.previous.`);
6982
7084
  }
6983
7085
  function removeIdentity(paths, name) {
6984
7086
  if (!identityExists(paths, name)) {
@@ -6986,7 +7088,7 @@ function removeIdentity(paths, name) {
6986
7088
  }
6987
7089
  for (const entry of fs5.readdirSync(paths.identitiesDir)) {
6988
7090
  if (belongsToIdentity(entry, name)) {
6989
- fs5.rmSync(path17.join(paths.identitiesDir, entry), { recursive: true, force: true });
7091
+ fs5.rmSync(path18.join(paths.identitiesDir, entry), { recursive: true, force: true });
6990
7092
  }
6991
7093
  }
6992
7094
  if (readActiveIdentity(paths) === name) {
@@ -6996,7 +7098,7 @@ function removeIdentity(paths, name) {
6996
7098
 
6997
7099
  // src/providersStore.ts
6998
7100
  import fs6 from "node:fs";
6999
- import path18 from "node:path";
7101
+ import path19 from "node:path";
7000
7102
 
7001
7103
  // src/credentialCache.ts
7002
7104
  import { z as z12 } from "zod";
@@ -7261,7 +7363,7 @@ var InvalidProviderNameError = class extends CliError {
7261
7363
  };
7262
7364
  var PROVIDER_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._@-]*$/;
7263
7365
  function providerJsonPath(paths, name) {
7264
- return path18.join(paths.providersDir, `${name}.json`);
7366
+ return path19.join(paths.providersDir, `${name}.json`);
7265
7367
  }
7266
7368
  function providerExists(paths, name) {
7267
7369
  return fs6.existsSync(providerJsonPath(paths, name));
@@ -7269,14 +7371,14 @@ function providerExists(paths, name) {
7269
7371
  var LEGACY_PROVIDER_FIELDS = ["tokenEnv", "tokenCommand", "authScheme"];
7270
7372
  var LEGACY_ENV_CREDENTIAL_KEYS = Object.values(CREDENTIAL_TARGET_VARS);
7271
7373
  var LEGACY_LITERAL_PLACEHOLDER = "<the value of env.ANTHROPIC_AUTH_TOKEN>";
7272
- function isRecord4(value) {
7374
+ function isRecord5(value) {
7273
7375
  return typeof value === "object" && value !== null && !Array.isArray(value);
7274
7376
  }
7275
7377
  function legacyProviderConversion(raw) {
7276
- if (!isRecord4(raw) || "credential" in raw) {
7378
+ if (!isRecord5(raw) || "credential" in raw) {
7277
7379
  return void 0;
7278
7380
  }
7279
- const env = isRecord4(raw.env) ? raw.env : void 0;
7381
+ const env = isRecord5(raw.env) ? raw.env : void 0;
7280
7382
  const legacyEnvKeys = env === void 0 ? [] : Object.keys(env).filter((key) => LEGACY_ENV_CREDENTIAL_KEYS.includes(key));
7281
7383
  const fields = [...LEGACY_PROVIDER_FIELDS.filter((field) => field in raw), ...legacyEnvKeys.map((key) => `env.${key}`)];
7282
7384
  if (fields.length === 0) {
@@ -7337,7 +7439,7 @@ function readProvider(paths, name) {
7337
7439
  return parseProviderFile(filePath, raw);
7338
7440
  }
7339
7441
  function loadProvider(providersDir, name, port) {
7340
- const filePath = path18.join(providersDir, `${name}.json`);
7442
+ const filePath = path19.join(providersDir, `${name}.json`);
7341
7443
  const raw = port.readConfigFile(filePath);
7342
7444
  return raw === void 0 ? void 0 : parseProviderFile(filePath, raw);
7343
7445
  }
@@ -7592,21 +7694,21 @@ function removeDirectoryRule(paths, rulePath) {
7592
7694
  import os5 from "node:os";
7593
7695
 
7594
7696
  // src/launcher/cascade.ts
7595
- import path20 from "node:path";
7697
+ import path21 from "node:path";
7596
7698
 
7597
7699
  // src/pathNorm.ts
7598
- import path19 from "node:path";
7700
+ import path20 from "node:path";
7599
7701
  function expandTilde(value, home) {
7600
7702
  if (value === "~") {
7601
7703
  return home;
7602
7704
  }
7603
7705
  if (value.startsWith("~/")) {
7604
- return path19.join(home, value.slice(2));
7706
+ return path20.join(home, value.slice(2));
7605
7707
  }
7606
7708
  return value;
7607
7709
  }
7608
7710
  function normaliseRulePath(rulePath, home) {
7609
- return path19.resolve(expandTilde(rulePath, home));
7711
+ return path20.resolve(expandTilde(rulePath, home));
7610
7712
  }
7611
7713
 
7612
7714
  // src/launcher/cascade.ts
@@ -7616,7 +7718,7 @@ function loadCascadeInput(params) {
7616
7718
  const globalConfig = loadConfigFile(params.paths.globalConfigFile, GlobalConfigSchema, params.read);
7617
7719
  const directoryRules = loadConfigFile(params.paths.directoryRulesFile, DirectoryRulesSchema, params.read);
7618
7720
  const loadProfile = (name) => {
7619
- const filepath = path20.join(params.paths.configProfilesDir, `${name}.json`);
7721
+ const filepath = path21.join(params.paths.configProfilesDir, `${name}.json`);
7620
7722
  const loaded = loadConfigFile(filepath, ConfigProfileSchema, params.read);
7621
7723
  if (loaded === void 0) {
7622
7724
  return void 0;
@@ -7631,8 +7733,8 @@ function loadCascadeInput(params) {
7631
7733
  });
7632
7734
  const levels = [];
7633
7735
  for (const dir of dirs) {
7634
- const portable = loadConfigFile(path20.join(dir, PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(path20.join(dir, LEGACY_PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read);
7635
- const portableLocal = loadConfigFile(path20.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(path20.join(dir, LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read);
7736
+ const portable = loadConfigFile(path21.join(dir, PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(path21.join(dir, LEGACY_PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read);
7737
+ const portableLocal = loadConfigFile(path21.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(path21.join(dir, LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read);
7636
7738
  const rules = (directoryRules?.config.rules ?? []).map((rule, index) => ({ rule, index })).filter(({ rule }) => normaliseRulePath(rule.path, params.home) === dir).map(({ rule, index }) => {
7637
7739
  const entryOrder = directoryRules?.ruleEntryOrders[index];
7638
7740
  return {
@@ -7683,7 +7785,7 @@ function readDirectorySelections(loaded) {
7683
7785
  // src/realCredentialCache.ts
7684
7786
  import { spawnSync } from "node:child_process";
7685
7787
  import fs7 from "node:fs";
7686
- import path21 from "node:path";
7788
+ import path22 from "node:path";
7687
7789
  var KEYCHAIN_CACHE_SERVICE = "agent-shim-credential-cache";
7688
7790
  var CACHE_DIR_MODE = 448;
7689
7791
  var CACHE_FILE_MODE = 384;
@@ -7710,8 +7812,8 @@ function security(args, stdin) {
7710
7812
  return { status: result.status, stdout: result.stdout };
7711
7813
  }
7712
7814
  function createRealCredentialCache(root) {
7713
- const dir = path21.join(root, "credential-cache");
7714
- const filePath = (owner) => path21.join(dir, cacheFileNameFor(owner));
7815
+ const dir = path22.join(root, "credential-cache");
7816
+ const filePath = (owner) => path22.join(dir, cacheFileNameFor(owner));
7715
7817
  return {
7716
7818
  read(store, owner) {
7717
7819
  if (store === "file") {
@@ -7763,7 +7865,7 @@ import { spawn, spawnSync as spawnSync2 } from "node:child_process";
7763
7865
  import { createHash as createHash5 } from "node:crypto";
7764
7866
  import fs8 from "node:fs";
7765
7867
  import os4 from "node:os";
7766
- import path22 from "node:path";
7868
+ import path23 from "node:path";
7767
7869
  import { isSea } from "node:sea";
7768
7870
  function isEnoent3(error) {
7769
7871
  return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
@@ -7922,7 +8024,7 @@ var realRunPort = {
7922
8024
  }
7923
8025
  };
7924
8026
  function expandHome2(filePath) {
7925
- return filePath.startsWith("~/") ? path22.join(os4.homedir(), filePath.slice(1)) : filePath;
8027
+ return filePath.startsWith("~/") ? path23.join(os4.homedir(), filePath.slice(1)) : filePath;
7926
8028
  }
7927
8029
  var MACOS_GUI_SESSION_MANAGER = "Aqua";
7928
8030
  function hasDesktopSession() {
@@ -7995,7 +8097,7 @@ function spawnDaemonThrough(executable) {
7995
8097
  return (paths, subcommand, logPath) => spawnDetachedDaemon({ command: executable, args: [subcommand] }, paths, subcommand, logPath);
7996
8098
  }
7997
8099
  function spawnDetachedDaemon(invocation, paths, subcommand, logPath) {
7998
- fs8.mkdirSync(path22.dirname(logPath), { recursive: true });
8100
+ fs8.mkdirSync(path23.dirname(logPath), { recursive: true });
7999
8101
  const logFd = fs8.openSync(logPath, "a");
8000
8102
  try {
8001
8103
  const child = spawn(invocation.command, invocation.args, detachedDaemonSpawnOptions(logFd, { ...process.env, AGENT_SHIM_HOME: paths.root }));
@@ -8077,7 +8179,7 @@ function listVersionsDir(dir) {
8077
8179
  throw error;
8078
8180
  }
8079
8181
  return entries.filter((entry) => entry.isFile()).map((entry) => {
8080
- const fullPath = path22.join(dir, entry.name);
8182
+ const fullPath = path23.join(dir, entry.name);
8081
8183
  const stat = fs8.statSync(fullPath);
8082
8184
  return {
8083
8185
  name: entry.name,
@@ -8092,7 +8194,7 @@ function windowsPathExtensions(pathext) {
8092
8194
  return (pathext ?? WINDOWS_DEFAULT_PATHEXT).split(";").map((ext) => ext.trim()).filter((ext) => ext.length > 0);
8093
8195
  }
8094
8196
  function resolveExecutableCandidate(dir, name, env) {
8095
- const candidate = path22.join(dir, name);
8197
+ const candidate = path23.join(dir, name);
8096
8198
  if (env.platform === "win32") {
8097
8199
  const extensions = windowsPathExtensions(env.pathext);
8098
8200
  const alreadyHasRecognisedExtension = extensions.some((ext) => candidate.toLowerCase().endsWith(ext.toLowerCase()));
@@ -8141,13 +8243,13 @@ function resolveOwnExecutablePath(env) {
8141
8243
  if (env.argv1 !== void 0 && !env.argv1.includes("/") && !env.argv1.includes("\\")) {
8142
8244
  return searchPathForExecutable(env.pathDirs, env.argv1, env.findExecutableInDir) ?? env.execPath;
8143
8245
  }
8144
- const candidate = env.argv1 === void 0 ? env.execPath : path22.resolve(env.cwd, env.argv1);
8145
- const candidateDir = path22.dirname(candidate);
8146
- const candidateDirOnPath = env.pathDirs.some((dir) => path22.resolve(dir) === candidateDir);
8246
+ const candidate = env.argv1 === void 0 ? env.execPath : path23.resolve(env.cwd, env.argv1);
8247
+ const candidateDir = path23.dirname(candidate);
8248
+ const candidateDirOnPath = env.pathDirs.some((dir) => path23.resolve(dir) === candidateDir);
8147
8249
  if (candidateDirOnPath) {
8148
8250
  return candidate;
8149
8251
  }
8150
- const viaPath = searchPathForExecutable(env.pathDirs, path22.basename(candidate), env.findExecutableInDir);
8252
+ const viaPath = searchPathForExecutable(env.pathDirs, path23.basename(candidate), env.findExecutableInDir);
8151
8253
  return viaPath ?? candidate;
8152
8254
  }
8153
8255
  function realOwnExecutablePath() {
@@ -8155,7 +8257,7 @@ function realOwnExecutablePath() {
8155
8257
  argv1: process.argv[1],
8156
8258
  execPath: process.execPath,
8157
8259
  cwd: process.cwd(),
8158
- pathDirs: (process.env.PATH ?? "").split(path22.delimiter).filter((dir) => dir !== ""),
8260
+ pathDirs: (process.env.PATH ?? "").split(path23.delimiter).filter((dir) => dir !== ""),
8159
8261
  findExecutableInDir
8160
8262
  });
8161
8263
  }
@@ -8168,7 +8270,7 @@ function realContentSourcePath() {
8168
8270
  function realResolveClaudeBinary(isOwnBinary) {
8169
8271
  return (request4) => discoverClaudeBinary({
8170
8272
  listVersionsDir,
8171
- pathDirs: (process.env.PATH ?? "").split(path22.delimiter).filter((dir) => dir !== ""),
8273
+ pathDirs: (process.env.PATH ?? "").split(path23.delimiter).filter((dir) => dir !== ""),
8172
8274
  findExecutableInDir,
8173
8275
  isOwnBinary,
8174
8276
  ...request4?.version === void 0 ? {} : { version: request4.version }
@@ -8179,7 +8281,7 @@ function realInstalledClaudeVersions() {
8179
8281
  }
8180
8282
 
8181
8283
  // src/checkReport.ts
8182
- import path23 from "node:path";
8284
+ import path24 from "node:path";
8183
8285
  import { z as z13 } from "zod";
8184
8286
 
8185
8287
  // src/cli/bool.ts
@@ -8611,10 +8713,10 @@ function collectCheckReport(params) {
8611
8713
  }).input;
8612
8714
  const providerName = cascadeProviderName(cascade);
8613
8715
  const provider = providerName === void 0 ? void 0 : loadCheckProvider(paths, providerName);
8614
- const farmRoot = identityDecision.name === void 0 ? void 0 : path23.join(paths.identitiesDir, identityDecision.name);
8716
+ const farmRoot = identityDecision.name === void 0 ? void 0 : path24.join(paths.identitiesDir, identityDecision.name);
8615
8717
  const settingsFiles = {
8616
- "settings.json": realFsPort.readFileUtf8(path23.join(claudeHome, "settings.json")),
8617
- "settings.local.json": realFsPort.readFileUtf8(path23.join(claudeHome, "settings.local.json"))
8718
+ "settings.json": realFsPort.readFileUtf8(path24.join(claudeHome, "settings.json")),
8719
+ "settings.local.json": realFsPort.readFileUtf8(path24.join(claudeHome, "settings.local.json"))
8618
8720
  };
8619
8721
  const report = runCheck({
8620
8722
  cwd,
@@ -8646,7 +8748,7 @@ function collectCheckReport(params) {
8646
8748
 
8647
8749
  // src/claudeShim.ts
8648
8750
  import fs9 from "node:fs";
8649
- import path24 from "node:path";
8751
+ import path25 from "node:path";
8650
8752
  import { z as z14 } from "zod";
8651
8753
  var ClaudeShimStateSchema = z14.strictObject({
8652
8754
  targetPath: z14.string().min(1),
@@ -8658,10 +8760,10 @@ function commandFilename(ownExecutablePath, commandName) {
8658
8760
  }
8659
8761
  function resolveOwnBinaryCheck(paths, contentSourcePath) {
8660
8762
  const state = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
8661
- const recordedTarget = state === void 0 ? void 0 : path24.resolve(state.targetPath);
8763
+ const recordedTarget = state === void 0 ? void 0 : path25.resolve(state.targetPath);
8662
8764
  let ownStat;
8663
8765
  return (candidate) => {
8664
- if (recordedTarget !== void 0 && path24.resolve(candidate) === recordedTarget) {
8766
+ if (recordedTarget !== void 0 && path25.resolve(candidate) === recordedTarget) {
8665
8767
  return true;
8666
8768
  }
8667
8769
  ownStat ??= statOrUndefined(contentSourcePath);
@@ -8685,20 +8787,20 @@ function statOrUndefined(target) {
8685
8787
  }
8686
8788
  var nodeLinkFs = { link: fs9.linkSync, copyFile: fs9.copyFileSync, chmod: fs9.chmodSync };
8687
8789
  function findPathShadow(params) {
8688
- const resolvedTargetDir = path24.resolve(params.targetDir);
8790
+ const resolvedTargetDir = path25.resolve(params.targetDir);
8689
8791
  for (const dir of params.pathDirs) {
8690
8792
  const found = params.findExecutableInDir(dir, params.targetFilename);
8691
8793
  if (found === void 0) {
8692
8794
  continue;
8693
8795
  }
8694
- return path24.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
8796
+ return path25.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
8695
8797
  }
8696
- return params.pathDirs.some((dir) => path24.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
8798
+ return params.pathDirs.some((dir) => path25.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
8697
8799
  }
8698
8800
 
8699
8801
  // src/doctorReport.ts
8700
8802
  import fs10 from "node:fs";
8701
- import path25 from "node:path";
8803
+ import path26 from "node:path";
8702
8804
  function refinePathShadow(status, ownExecutablePath, realpath) {
8703
8805
  if (status.status !== "shadowed") {
8704
8806
  return status;
@@ -8722,7 +8824,7 @@ function validateJson(schema, input) {
8722
8824
  return { ok: true, data: result.data };
8723
8825
  }
8724
8826
  function pushPathResolution(push, resolution) {
8725
- const ownDir = path25.dirname(resolution.ownExecutablePath);
8827
+ const ownDir = path26.dirname(resolution.ownExecutablePath);
8726
8828
  switch (resolution.agentShim.status) {
8727
8829
  case "ok":
8728
8830
  push("path-resolution", "pass", `\`agent-shim\` on PATH resolves to this running executable, ${resolution.ownExecutablePath}.`, "agent-shim");
@@ -8798,14 +8900,14 @@ function pushProvider(push, entry, cacheEnv) {
8798
8900
  }
8799
8901
  function pushLegacyName(push, params) {
8800
8902
  const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
8801
- if (legacyVariables.length === 0 && path25.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
8903
+ if (legacyVariables.length === 0 && path26.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
8802
8904
  push("legacy-name", "pass", "Nothing here still uses the former `claude-use` name.");
8803
8905
  return;
8804
8906
  }
8805
8907
  for (const name of legacyVariables) {
8806
8908
  push("legacy-name", "warn", `${name} is the former name of ${name.replace(LEGACY_ENV_PREFIX, ENV_PREFIX)}. Rename it; the old name still works but is only a fallback.`, name);
8807
8909
  }
8808
- if (path25.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
8910
+ if (path26.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
8809
8911
  push(
8810
8912
  "legacy-name",
8811
8913
  "warn",
@@ -9124,18 +9226,18 @@ function collectDoctorReport(params) {
9124
9226
  const { paths } = params;
9125
9227
  const identityNames = fs10.existsSync(paths.identitiesDir) ? fs10.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort() : [];
9126
9228
  const identities = identityNames.map((name) => {
9127
- const farmRoot = path25.join(paths.identitiesDir, name);
9128
- const identityPath = path25.join(farmRoot, "identity.json");
9229
+ const farmRoot = path26.join(paths.identitiesDir, name);
9230
+ const identityPath = path26.join(farmRoot, "identity.json");
9129
9231
  return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot };
9130
9232
  });
9131
9233
  const profileNames = fs10.existsSync(paths.configProfilesDir) ? fs10.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
9132
9234
  const configProfiles = profileNames.map((name) => {
9133
- const profilePath = path25.join(paths.configProfilesDir, `${name}.json`);
9235
+ const profilePath = path26.join(paths.configProfilesDir, `${name}.json`);
9134
9236
  return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
9135
9237
  });
9136
9238
  const providerNames = fs10.existsSync(paths.providersDir) ? fs10.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
9137
9239
  const providers = providerNames.map((name) => {
9138
- const providerPath = path25.join(paths.providersDir, `${name}.json`);
9240
+ const providerPath = path26.join(paths.providersDir, `${name}.json`);
9139
9241
  return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
9140
9242
  });
9141
9243
  const ownExecutablePath = realOwnExecutablePath();
@@ -9147,12 +9249,12 @@ function collectDoctorReport(params) {
9147
9249
  binaryDiscovery = { ok: false, message: error instanceof Error ? error.message : String(error) };
9148
9250
  }
9149
9251
  const shimState = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
9150
- const pathDirs = (params.env.PATH ?? "").split(path25.delimiter).filter((dir) => dir !== "");
9252
+ const pathDirs = (params.env.PATH ?? "").split(path26.delimiter).filter((dir) => dir !== "");
9151
9253
  const claudeShimShadow = shimState === void 0 ? void 0 : refinePathShadow(
9152
9254
  findPathShadow({
9153
9255
  pathDirs,
9154
- targetDir: path25.dirname(shimState.targetPath),
9155
- targetFilename: path25.basename(shimState.targetPath),
9256
+ targetDir: path26.dirname(shimState.targetPath),
9257
+ targetFilename: path26.basename(shimState.targetPath),
9156
9258
  findExecutableInDir
9157
9259
  }),
9158
9260
  shimState.targetPath,
@@ -9177,7 +9279,7 @@ function collectDoctorReport(params) {
9177
9279
  agentShim: refinePathShadow(
9178
9280
  findPathShadow({
9179
9281
  pathDirs,
9180
- targetDir: path25.dirname(ownExecutablePath),
9282
+ targetDir: path26.dirname(ownExecutablePath),
9181
9283
  targetFilename: commandFilename(ownExecutablePath, "agent-shim"),
9182
9284
  findExecutableInDir
9183
9285
  }),
@@ -9198,7 +9300,7 @@ function collectDoctorReport(params) {
9198
9300
 
9199
9301
  // src/launcher.ts
9200
9302
  import { randomUUID as randomUUID4 } from "node:crypto";
9201
- import path27 from "node:path";
9303
+ import path28 from "node:path";
9202
9304
 
9203
9305
  // src/launcher/argv.ts
9204
9306
  var ConflictingIdentityError = class extends UsageError {
@@ -9463,7 +9565,7 @@ function buildCliOverride(params) {
9463
9565
  }
9464
9566
 
9465
9567
  // src/launcher/flags.ts
9466
- import path26 from "node:path";
9568
+ import path27 from "node:path";
9467
9569
 
9468
9570
  // src/headroom/headers.ts
9469
9571
  function mergeAnthropicCustomHeaders(existing, additions) {
@@ -9533,7 +9635,7 @@ function buildEnv(params) {
9533
9635
  const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
9534
9636
  let providerCustomHeaders;
9535
9637
  if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
9536
- env.CLAUDE_CONFIG_DIR = path26.join(params.identitiesDir, params.resolvedIdentityName);
9638
+ env.CLAUDE_CONFIG_DIR = path27.join(params.identitiesDir, params.resolvedIdentityName);
9537
9639
  }
9538
9640
  if (params.provider !== void 0) {
9539
9641
  const providerEnv = params.provider.definition.env ?? {};
@@ -9694,7 +9796,7 @@ function prepareLaunch(params) {
9694
9796
  identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
9695
9797
  globalDefaultConfigProfile: params.globalDefaultConfigProfile
9696
9798
  });
9697
- if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(path27.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
9799
+ if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(path28.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
9698
9800
  log.error(
9699
9801
  `agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
9700
9802
  );
@@ -9940,11 +10042,11 @@ function probeFrontDoorSync(port, caPem) {
9940
10042
 
9941
10043
  // src/frontdoor/trust.ts
9942
10044
  import { createHash as createHash6 } from "node:crypto";
9943
- import path28 from "node:path";
10045
+ import path29 from "node:path";
9944
10046
  var BUNDLE_NAME_HEX_DIGITS = 16;
9945
10047
  function resolveTrustBundle(params) {
9946
10048
  const { caCertFile, bundlesDir, variable, inherited, fs: fs12 } = params;
9947
- if (inherited === void 0 || inherited === "" || path28.resolve(inherited) === path28.resolve(caCertFile)) {
10049
+ if (inherited === void 0 || inherited === "" || path29.resolve(inherited) === path29.resolve(caCertFile)) {
9948
10050
  return { path: caCertFile };
9949
10051
  }
9950
10052
  const caPem = fs12.readFileUtf8(caCertFile);
@@ -9962,7 +10064,7 @@ function resolveTrustBundle(params) {
9962
10064
  }
9963
10065
  const combined = `${inheritedPem.trimEnd()}
9964
10066
  ${caPem}`;
9965
- const bundle = path28.join(bundlesDir, `${createHash6("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
10067
+ const bundle = path29.join(bundlesDir, `${createHash6("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
9966
10068
  if (!fs12.exists(bundle)) {
9967
10069
  fs12.mkdirp(bundlesDir);
9968
10070
  fs12.writeFileAtomic(bundle, combined);
@@ -10189,6 +10291,7 @@ export {
10189
10291
  createRcApiNodeHandler,
10190
10292
  createRcApiRouter,
10191
10293
  createRcControlHandler,
10294
+ createRcCredentialStore,
10192
10295
  createRcEventFanout,
10193
10296
  createRcSessionTracker,
10194
10297
  createRcStreamHub,