agent-shim 7.13.1 → 7.14.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.
Files changed (93) hide show
  1. package/dist/cli.cjs +95 -27
  2. package/dist/index.cjs +70 -7
  3. package/dist/index.mjs +70 -7
  4. package/dist/types/index.d.ts +2789 -40
  5. package/package.json +3 -1
  6. package/dist/types/checkReport.d.ts +0 -154
  7. package/dist/types/claudeShim.d.ts +0 -114
  8. package/dist/types/cli/bool.d.ts +0 -8
  9. package/dist/types/cli/commandDeps.d.ts +0 -39
  10. package/dist/types/cli/envBool.d.ts +0 -11
  11. package/dist/types/cli/pairs.d.ts +0 -19
  12. package/dist/types/cliError.d.ts +0 -27
  13. package/dist/types/codex/http.d.ts +0 -15
  14. package/dist/types/config/classify.d.ts +0 -49
  15. package/dist/types/config/load.d.ts +0 -42
  16. package/dist/types/config/schema.d.ts +0 -746
  17. package/dist/types/config/store.d.ts +0 -46
  18. package/dist/types/configProfilesStore.d.ts +0 -61
  19. package/dist/types/configure.d.ts +0 -170
  20. package/dist/types/credential.d.ts +0 -136
  21. package/dist/types/credentialCache.d.ts +0 -46
  22. package/dist/types/directoryRulesStore.d.ts +0 -43
  23. package/dist/types/doctorReport.d.ts +0 -117
  24. package/dist/types/frontdoor/capability.d.ts +0 -19
  25. package/dist/types/frontdoor/capture.d.ts +0 -58
  26. package/dist/types/frontdoor/connect.d.ts +0 -209
  27. package/dist/types/frontdoor/connectEffects.d.ts +0 -3
  28. package/dist/types/frontdoor/custody.d.ts +0 -32
  29. package/dist/types/frontdoor/ensure.d.ts +0 -36
  30. package/dist/types/frontdoor/headroomHop.d.ts +0 -22
  31. package/dist/types/frontdoor/pipeline.d.ts +0 -109
  32. package/dist/types/frontdoor/probe.d.ts +0 -13
  33. package/dist/types/frontdoor/realFrontDoorPort.d.ts +0 -5
  34. package/dist/types/frontdoor/route.d.ts +0 -112
  35. package/dist/types/frontdoor/server.d.ts +0 -44
  36. package/dist/types/frontdoor/state.d.ts +0 -57
  37. package/dist/types/frontdoor/supervisor.d.ts +0 -48
  38. package/dist/types/frontdoor/tap.d.ts +0 -9
  39. package/dist/types/frontdoor/trust.d.ts +0 -30
  40. package/dist/types/frontdoor/x509.d.ts +0 -11
  41. package/dist/types/headroom/ensure.d.ts +0 -31
  42. package/dist/types/headroom/headers.d.ts +0 -11
  43. package/dist/types/headroom/settings.d.ts +0 -13
  44. package/dist/types/headroom/source.d.ts +0 -8
  45. package/dist/types/headroom/state.d.ts +0 -77
  46. package/dist/types/headroom/supervisor.d.ts +0 -107
  47. package/dist/types/identityStore.d.ts +0 -85
  48. package/dist/types/launchWiring.d.ts +0 -49
  49. package/dist/types/launcher/argv.d.ts +0 -42
  50. package/dist/types/launcher/cascade.d.ts +0 -42
  51. package/dist/types/launcher/cliOverride.d.ts +0 -38
  52. package/dist/types/launcher/extraFlags.d.ts +0 -6
  53. package/dist/types/launcher/farm.d.ts +0 -168
  54. package/dist/types/launcher/flags.d.ts +0 -96
  55. package/dist/types/launcher/guard.d.ts +0 -57
  56. package/dist/types/launcher/identity.d.ts +0 -95
  57. package/dist/types/launcher/lock.d.ts +0 -41
  58. package/dist/types/launcher/pool.d.ts +0 -44
  59. package/dist/types/launcher/ports.d.ts +0 -135
  60. package/dist/types/launcher/spawn.d.ts +0 -20
  61. package/dist/types/launcher.d.ts +0 -98
  62. package/dist/types/legacy.d.ts +0 -29
  63. package/dist/types/pathNorm.d.ts +0 -14
  64. package/dist/types/paths.d.ts +0 -79
  65. package/dist/types/poolPickReport.d.ts +0 -44
  66. package/dist/types/poolStore.d.ts +0 -18
  67. package/dist/types/providersStore.d.ts +0 -137
  68. package/dist/types/realCredentialCache.d.ts +0 -11
  69. package/dist/types/realPorts.d.ts +0 -109
  70. package/dist/types/resolve/conditions.d.ts +0 -37
  71. package/dist/types/resolve/decide.d.ts +0 -45
  72. package/dist/types/resolve/extends.d.ts +0 -41
  73. package/dist/types/resolve/flatten.d.ts +0 -13
  74. package/dist/types/resolve/match.d.ts +0 -58
  75. package/dist/types/resolve/pipeline.d.ts +0 -33
  76. package/dist/types/resolve/plan.d.ts +0 -57
  77. package/dist/types/resolve/projects.d.ts +0 -61
  78. package/dist/types/resolve/reconcile.d.ts +0 -80
  79. package/dist/types/resolve/types.d.ts +0 -159
  80. package/dist/types/resolve/walk.d.ts +0 -85
  81. package/dist/types/resolve/walkPolicy.d.ts +0 -15
  82. package/dist/types/usage/account.d.ts +0 -20
  83. package/dist/types/usage/middleware.d.ts +0 -17
  84. package/dist/types/usage/pick.d.ts +0 -62
  85. package/dist/types/usage/plan.d.ts +0 -18
  86. package/dist/types/usage/poolPick.d.ts +0 -31
  87. package/dist/types/usage/preflight.d.ts +0 -20
  88. package/dist/types/usage/rateLimit.d.ts +0 -25
  89. package/dist/types/usage/read.d.ts +0 -70
  90. package/dist/types/usage/scan.d.ts +0 -24
  91. package/dist/types/usage/schema.d.ts +0 -318
  92. package/dist/types/usage/store.d.ts +0 -43
  93. package/dist/types/versionDiscovery.d.ts +0 -47
package/dist/cli.cjs CHANGED
@@ -15625,7 +15625,7 @@ var require_agent = __commonJS({
15625
15625
  function defaultFactory(origin, opts) {
15626
15626
  return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts);
15627
15627
  }
15628
- var Agent7 = class extends DispatcherBase {
15628
+ var Agent5 = class extends DispatcherBase {
15629
15629
  constructor({ factory = defaultFactory, maxOrigins = Infinity, connect: connect3, ...options } = {}) {
15630
15630
  if (typeof factory !== "function") {
15631
15631
  throw new InvalidArgumentError2("factory must be a function.");
@@ -15734,7 +15734,7 @@ var require_agent = __commonJS({
15734
15734
  return allClientStats;
15735
15735
  }
15736
15736
  };
15737
- module2.exports = Agent7;
15737
+ module2.exports = Agent5;
15738
15738
  }
15739
15739
  });
15740
15740
 
@@ -16440,7 +16440,7 @@ var require_proxy_agent = __commonJS({
16440
16440
  "node_modules/.pnpm/undici@7.29.1/node_modules/undici/lib/dispatcher/proxy-agent.js"(exports2, module2) {
16441
16441
  "use strict";
16442
16442
  var { kProxy, kClose, kDestroy, kDispatch } = require_symbols();
16443
- var Agent7 = require_agent();
16443
+ var Agent5 = require_agent();
16444
16444
  var Pool = require_pool();
16445
16445
  var DispatcherBase = require_dispatcher_base();
16446
16446
  var { InvalidArgumentError: InvalidArgumentError2, RequestAbortedError, SecureProxyConnectionError } = require_errors();
@@ -16571,7 +16571,7 @@ var require_proxy_agent = __commonJS({
16571
16571
  } else {
16572
16572
  this[kClient] = clientFactory(url2, { connect: connect3 });
16573
16573
  }
16574
- this[kAgent] = new Agent7({
16574
+ this[kAgent] = new Agent5({
16575
16575
  ...opts,
16576
16576
  factory,
16577
16577
  connect: async (opts2, callback) => {
@@ -16699,7 +16699,7 @@ var require_env_http_proxy_agent = __commonJS({
16699
16699
  var DispatcherBase = require_dispatcher_base();
16700
16700
  var { kClose, kDestroy, kClosed, kDestroyed, kDispatch, kNoProxyAgent, kHttpProxyAgent, kHttpsProxyAgent } = require_symbols();
16701
16701
  var ProxyAgent = require_proxy_agent();
16702
- var Agent7 = require_agent();
16702
+ var Agent5 = require_agent();
16703
16703
  var DEFAULT_PORTS = {
16704
16704
  "http:": 80,
16705
16705
  "https:": 443
@@ -16712,7 +16712,7 @@ var require_env_http_proxy_agent = __commonJS({
16712
16712
  super();
16713
16713
  this.#opts = opts;
16714
16714
  const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts;
16715
- this[kNoProxyAgent] = new Agent7(agentOpts);
16715
+ this[kNoProxyAgent] = new Agent5(agentOpts);
16716
16716
  const HTTP_PROXY = httpProxy ?? process.env.http_proxy ?? process.env.HTTP_PROXY;
16717
16717
  if (HTTP_PROXY) {
16718
16718
  this[kHttpProxyAgent] = new ProxyAgent({ ...agentOpts, uri: HTTP_PROXY });
@@ -19410,7 +19410,7 @@ var require_mock_agent = __commonJS({
19410
19410
  "node_modules/.pnpm/undici@7.29.1/node_modules/undici/lib/mock/mock-agent.js"(exports2, module2) {
19411
19411
  "use strict";
19412
19412
  var { kClients } = require_symbols();
19413
- var Agent7 = require_agent();
19413
+ var Agent5 = require_agent();
19414
19414
  var {
19415
19415
  kAgent,
19416
19416
  kMockAgentSet,
@@ -19448,7 +19448,7 @@ var require_mock_agent = __commonJS({
19448
19448
  if (opts?.agent && typeof opts.agent.dispatch !== "function") {
19449
19449
  throw new InvalidArgumentError2("Argument opts.agent must implement Agent");
19450
19450
  }
19451
- const agent = opts?.agent ? opts.agent : new Agent7(opts);
19451
+ const agent = opts?.agent ? opts.agent : new Agent5(opts);
19452
19452
  this[kAgent] = agent;
19453
19453
  this[kClients] = agent[kClients];
19454
19454
  this[kOptions] = mockOptions;
@@ -20055,7 +20055,7 @@ var require_snapshot_recorder = __commonJS({
20055
20055
  var require_snapshot_agent = __commonJS({
20056
20056
  "node_modules/.pnpm/undici@7.29.1/node_modules/undici/lib/mock/snapshot-agent.js"(exports2, module2) {
20057
20057
  "use strict";
20058
- var Agent7 = require_agent();
20058
+ var Agent5 = require_agent();
20059
20059
  var MockAgent = require_mock_agent();
20060
20060
  var { SnapshotRecorder } = require_snapshot_recorder();
20061
20061
  var WrapHandler = require_wrap_handler();
@@ -20106,7 +20106,7 @@ var require_snapshot_agent = __commonJS({
20106
20106
  });
20107
20107
  this[kSnapshotLoaded] = false;
20108
20108
  if (this[kSnapshotMode] === "record" || this[kSnapshotMode] === "update" || this[kSnapshotMode] === "playback" && opts.excludeUrls && opts.excludeUrls.length > 0) {
20109
- this[kRealAgent] = new Agent7(opts);
20109
+ this[kRealAgent] = new Agent5(opts);
20110
20110
  }
20111
20111
  if ((this[kSnapshotMode] === "playback" || this[kSnapshotMode] === "update") && this[kSnapshotPath]) {
20112
20112
  this.loadSnapshots().catch(() => {
@@ -20345,9 +20345,9 @@ var require_global2 = __commonJS({
20345
20345
  var globalDispatcher = /* @__PURE__ */ Symbol.for("undici.globalDispatcher.2");
20346
20346
  var legacyGlobalDispatcher = /* @__PURE__ */ Symbol.for("undici.globalDispatcher.1");
20347
20347
  var { InvalidArgumentError: InvalidArgumentError2 } = require_errors();
20348
- var Agent7 = require_agent();
20348
+ var Agent5 = require_agent();
20349
20349
  if (getGlobalDispatcher() === void 0) {
20350
- setGlobalDispatcher(new Agent7());
20350
+ setGlobalDispatcher(new Agent5());
20351
20351
  }
20352
20352
  function setGlobalDispatcher(agent) {
20353
20353
  if (!agent || typeof agent.dispatch !== "function") {
@@ -20817,7 +20817,7 @@ var require_dump = __commonJS({
20817
20817
  var require_dns = __commonJS({
20818
20818
  "node_modules/.pnpm/undici@7.29.1/node_modules/undici/lib/interceptor/dns.js"(exports2, module2) {
20819
20819
  "use strict";
20820
- var { isIP } = require("node:net");
20820
+ var { isIP: isIP2 } = require("node:net");
20821
20821
  var { lookup } = require("node:dns");
20822
20822
  var DecoratorHandler = require_decorator_handler();
20823
20823
  var { InvalidArgumentError: InvalidArgumentError2, InformationalError } = require_errors();
@@ -21223,7 +21223,7 @@ var require_dns = __commonJS({
21223
21223
  return (dispatch) => {
21224
21224
  return function dnsInterceptor(origDispatchOpts, handler) {
21225
21225
  const origin = origDispatchOpts.origin.constructor === URL ? origDispatchOpts.origin : new URL(origDispatchOpts.origin);
21226
- if (isIP(origin.hostname) !== 0) {
21226
+ if (isIP2(origin.hostname) !== 0) {
21227
21227
  return dispatch(origDispatchOpts, handler);
21228
21228
  }
21229
21229
  instance.runLookup(origin, origDispatchOpts, (err, newOrigin) => {
@@ -31562,7 +31562,7 @@ var require_undici = __commonJS({
31562
31562
  var Pool = require_pool();
31563
31563
  var BalancedPool = require_balanced_pool();
31564
31564
  var RoundRobinPool = require_round_robin_pool();
31565
- var Agent7 = require_agent();
31565
+ var Agent5 = require_agent();
31566
31566
  var ProxyAgent = require_proxy_agent();
31567
31567
  var Socks5ProxyAgent = require_socks5_proxy_agent();
31568
31568
  var EnvHttpProxyAgent = require_env_http_proxy_agent();
@@ -31589,7 +31589,7 @@ var require_undici = __commonJS({
31589
31589
  module2.exports.Pool = Pool;
31590
31590
  module2.exports.BalancedPool = BalancedPool;
31591
31591
  module2.exports.RoundRobinPool = RoundRobinPool;
31592
- module2.exports.Agent = Agent7;
31592
+ module2.exports.Agent = Agent5;
31593
31593
  module2.exports.ProxyAgent = ProxyAgent;
31594
31594
  module2.exports.Socks5ProxyAgent = Socks5ProxyAgent;
31595
31595
  module2.exports.EnvHttpProxyAgent = EnvHttpProxyAgent;
@@ -61032,7 +61032,7 @@ function registerIdentityCommand(program2, deps) {
61032
61032
  // package.json
61033
61033
  var package_default = {
61034
61034
  name: "agent-shim",
61035
- version: "7.13.1",
61035
+ version: "7.14.0",
61036
61036
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
61037
61037
  license: "MIT",
61038
61038
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -61106,6 +61106,8 @@ var package_default = {
61106
61106
  jiti: "^2.7.0",
61107
61107
  knip: "^6.35.1",
61108
61108
  "lint-staged": "^17.5.0",
61109
+ rollup: "4.64.0",
61110
+ "rollup-plugin-dts": "6.5.1",
61109
61111
  "semantic-release": "^25.0.9",
61110
61112
  turbo: "^2.10.12",
61111
61113
  typescript: "^6.0.3",
@@ -64831,13 +64833,63 @@ function realConnectCertStore(paths) {
64831
64833
  }
64832
64834
 
64833
64835
  // src/frontdoor/connectEffects.ts
64836
+ var dns = __toESM(require("node:dns"), 1);
64834
64837
  var http = __toESM(require("node:http"), 1);
64835
64838
  var https = __toESM(require("node:https"), 1);
64836
64839
  var net3 = __toESM(require("node:net"), 1);
64837
64840
  var tls = __toESM(require("node:tls"), 1);
64841
+ var UPSTREAM_LOCAL_PORT_START = 47900;
64842
+ var UPSTREAM_LOCAL_PORT_END = 47919;
64843
+ var nextUpstreamLocalPort = UPSTREAM_LOCAL_PORT_START;
64844
+ function upstreamLocalPort() {
64845
+ const port = nextUpstreamLocalPort;
64846
+ nextUpstreamLocalPort = nextUpstreamLocalPort === UPSTREAM_LOCAL_PORT_END ? UPSTREAM_LOCAL_PORT_START : nextUpstreamLocalPort + 1;
64847
+ return port;
64848
+ }
64849
+ var realAddressLookup = (host, _options, callback) => {
64850
+ if (net3.isIP(host) !== 0) {
64851
+ callback(null, [{ address: host, family: net3.isIP(host) }]);
64852
+ return;
64853
+ }
64854
+ dns.resolve4(host, (error62, addresses) => {
64855
+ const first = addresses[0];
64856
+ if (error62 !== null || first === void 0) {
64857
+ callback(error62 ?? new Error(`no A record for ${host}`), [{ address: "", family: 4 }]);
64858
+ return;
64859
+ }
64860
+ callback(null, [{ address: first, family: 4 }]);
64861
+ });
64862
+ };
64863
+ var HTTP_PORT = 80;
64864
+ function exemptDial(options, defaultPort) {
64865
+ const host = typeof options.host === "string" ? options.host : "";
64866
+ const port = typeof options.port === "number" ? options.port : defaultPort;
64867
+ return net3.connect(net3.isIP(host) === 0 ? { host, port, localPort: upstreamLocalPort(), lookup: realAddressLookup } : { host, port });
64868
+ }
64869
+ function requestServername(options, fallback) {
64870
+ return "servername" in options && typeof options.servername === "string" && options.servername !== "" ? options.servername : fallback;
64871
+ }
64872
+ var ExemptHttpAgent = class extends http.Agent {
64873
+ createConnection(options) {
64874
+ return exemptDial(options, HTTP_PORT);
64875
+ }
64876
+ };
64877
+ var ExemptTlsAgent = class extends https.Agent {
64878
+ createConnection(options) {
64879
+ const host = typeof options.host === "string" ? options.host : "";
64880
+ const tlsOptions = { socket: exemptDial(options, HTTPS_PORT), servername: requestServername(options, host) };
64881
+ if ("ca" in options && Array.isArray(options.ca)) {
64882
+ tlsOptions.ca = options.ca;
64883
+ }
64884
+ if ("rejectUnauthorized" in options && typeof options.rejectUnauthorized === "boolean") {
64885
+ tlsOptions.rejectUnauthorized = options.rejectUnauthorized;
64886
+ }
64887
+ return tls.connect(tlsOptions);
64888
+ }
64889
+ };
64838
64890
  function realConnectEffects() {
64839
- const plainAgent = new http.Agent({ keepAlive: true });
64840
- const tlsAgent = new https.Agent({ keepAlive: true });
64891
+ const plainAgent = new ExemptHttpAgent();
64892
+ const tlsAgent = new ExemptTlsAgent();
64841
64893
  const listenOnce = async (port, onSocket) => await new Promise((resolve, reject) => {
64842
64894
  const accepted = /* @__PURE__ */ new Set();
64843
64895
  const server = net3.createServer((socket) => {
@@ -64923,11 +64975,23 @@ function realConnectEffects() {
64923
64975
  };
64924
64976
  },
64925
64977
  connectTlsUpstream: async (host, port, clientAlpn) => await new Promise((resolve, reject) => {
64926
- const socket = tls.connect({ host, port, servername: host, ...clientAlpn === void 0 ? {} : { ALPNProtocols: [clientAlpn] } });
64927
- socket.once("secureConnect", () => {
64928
- resolve(socket);
64929
- });
64930
- socket.once("error", reject);
64978
+ const dial = (localPort) => {
64979
+ const raw = net3.connect({ host, port, localPort, lookup: realAddressLookup });
64980
+ return tls.connect({ socket: raw, servername: host, ...clientAlpn === void 0 ? {} : { ALPNProtocols: [clientAlpn] } });
64981
+ };
64982
+ const settle2 = (candidate) => {
64983
+ candidate.once("secureConnect", () => {
64984
+ resolve(candidate);
64985
+ });
64986
+ candidate.once("error", (error62) => {
64987
+ if ("code" in error62 && error62.code === "EADDRINUSE") {
64988
+ settle2(dial(upstreamLocalPort()));
64989
+ return;
64990
+ }
64991
+ reject(error62);
64992
+ });
64993
+ };
64994
+ settle2(dial(upstreamLocalPort()));
64931
64995
  }),
64932
64996
  connectTcp: async (host, port) => await new Promise((resolve, reject) => {
64933
64997
  const socket = net3.connect({ host, port });
@@ -64941,6 +65005,7 @@ function realConnectEffects() {
64941
65005
  const options = {
64942
65006
  host: target.host,
64943
65007
  port: target.port,
65008
+ lookup: realAddressLookup,
64944
65009
  method: request6.method,
64945
65010
  path: request6.url,
64946
65011
  headers,
@@ -66220,7 +66285,7 @@ function createPassthroughRoute(name, target) {
66220
66285
  const base = new URL(target.baseUrl);
66221
66286
  const tls2 = base.protocol === "https:";
66222
66287
  const basePath = base.pathname.replace(/\/+$/, "");
66223
- const agent = tls2 ? new https3.Agent({ keepAlive: true }) : new http4.Agent({ keepAlive: true });
66288
+ const agent = tls2 ? new ExemptTlsAgent() : new ExemptHttpAgent();
66224
66289
  return {
66225
66290
  name,
66226
66291
  headroomEligible: true,
@@ -68279,11 +68344,13 @@ var READY_FETCH_TIMEOUT_MS = 2e3;
68279
68344
  function headroomPidRunning(pid) {
68280
68345
  return !exitedHeadroom.has(pid) && realIsProcessRunning(pid);
68281
68346
  }
68282
- function headroomSpawnEnv(parentEnv, allowlist, settings2) {
68347
+ function headroomSpawnEnv(parentEnv, allowlist, settings2, caBundle) {
68283
68348
  return {
68284
68349
  ...parentEnv,
68285
68350
  HEADROOM_ALLOWED_BASE_URLS: allowlist.join(","),
68286
68351
  HEADROOM_HTTP2: parentEnv.HEADROOM_HTTP2 ?? "0",
68352
+ // A transparent-interception deployment redirects the API host's address machine-wide, so headroom's own Python dials reach the front door's leaf instead of the origin's public certificate, and Python trusts only the system store: point its two trust variables (urllib3/httpx read both) at the door's combined bundle, which carries the system-equivalent anchors alongside the door's CA. An explicit value in the parent environment always wins, exactly like HEADROOM_HTTP2.
68353
+ ...caBundle === void 0 || parentEnv.REQUESTS_CA_BUNDLE !== void 0 || parentEnv.SSL_CERT_FILE !== void 0 ? {} : { REQUESTS_CA_BUNDLE: caBundle, SSL_CERT_FILE: caBundle },
68287
68354
  ...settingsEnv(settings2)
68288
68355
  };
68289
68356
  }
@@ -68322,13 +68389,14 @@ function realSupervisorPorts(paths) {
68322
68389
  isPortFree: realIsPortFree,
68323
68390
  readConfig: () => resolveSupervisorConfig(readGlobalConfig(paths)?.headroom ?? {}),
68324
68391
  spawnHeadroom: (port, allowlist, settings2) => {
68392
+ const caBundle = import_node_fs15.default.existsSync(paths.frontdoorCaCertFile) ? import_node_fs15.default.readFileSync(paths.frontdoorCaCertFile, "utf8") : void 0;
68325
68393
  import_node_fs15.default.mkdirSync(paths.logsDir, { recursive: true });
68326
68394
  const logFd = import_node_fs15.default.openSync(paths.headroomLogPath, "a");
68327
68395
  try {
68328
68396
  const child = (0, import_node_child_process5.spawn)("headroom", ["proxy", "--host", "127.0.0.1", "--port", String(port), ...settingsArgs(settings2)], {
68329
68397
  detached: true,
68330
68398
  stdio: ["ignore", logFd, logFd],
68331
- env: headroomSpawnEnv(process.env, allowlist, settings2)
68399
+ env: headroomSpawnEnv(process.env, allowlist, settings2, caBundle)
68332
68400
  });
68333
68401
  if (child.pid === void 0) {
68334
68402
  throw new Error("spawning headroom returned no pid");
package/dist/index.cjs CHANGED
@@ -3209,13 +3209,63 @@ function realConnectCertStore(paths) {
3209
3209
  }
3210
3210
 
3211
3211
  // src/frontdoor/connectEffects.ts
3212
+ var dns = __toESM(require("node:dns"), 1);
3212
3213
  var http = __toESM(require("node:http"), 1);
3213
3214
  var https = __toESM(require("node:https"), 1);
3214
3215
  var net2 = __toESM(require("node:net"), 1);
3215
3216
  var tls = __toESM(require("node:tls"), 1);
3217
+ var UPSTREAM_LOCAL_PORT_START = 47900;
3218
+ var UPSTREAM_LOCAL_PORT_END = 47919;
3219
+ var nextUpstreamLocalPort = UPSTREAM_LOCAL_PORT_START;
3220
+ function upstreamLocalPort() {
3221
+ const port = nextUpstreamLocalPort;
3222
+ nextUpstreamLocalPort = nextUpstreamLocalPort === UPSTREAM_LOCAL_PORT_END ? UPSTREAM_LOCAL_PORT_START : nextUpstreamLocalPort + 1;
3223
+ return port;
3224
+ }
3225
+ var realAddressLookup = (host, _options, callback) => {
3226
+ if (net2.isIP(host) !== 0) {
3227
+ callback(null, [{ address: host, family: net2.isIP(host) }]);
3228
+ return;
3229
+ }
3230
+ dns.resolve4(host, (error, addresses) => {
3231
+ const first = addresses[0];
3232
+ if (error !== null || first === void 0) {
3233
+ callback(error ?? new Error(`no A record for ${host}`), [{ address: "", family: 4 }]);
3234
+ return;
3235
+ }
3236
+ callback(null, [{ address: first, family: 4 }]);
3237
+ });
3238
+ };
3239
+ var HTTP_PORT = 80;
3240
+ function exemptDial(options, defaultPort) {
3241
+ const host = typeof options.host === "string" ? options.host : "";
3242
+ const port = typeof options.port === "number" ? options.port : defaultPort;
3243
+ return net2.connect(net2.isIP(host) === 0 ? { host, port, localPort: upstreamLocalPort(), lookup: realAddressLookup } : { host, port });
3244
+ }
3245
+ function requestServername(options, fallback) {
3246
+ return "servername" in options && typeof options.servername === "string" && options.servername !== "" ? options.servername : fallback;
3247
+ }
3248
+ var ExemptHttpAgent = class extends http.Agent {
3249
+ createConnection(options) {
3250
+ return exemptDial(options, HTTP_PORT);
3251
+ }
3252
+ };
3253
+ var ExemptTlsAgent = class extends https.Agent {
3254
+ createConnection(options) {
3255
+ const host = typeof options.host === "string" ? options.host : "";
3256
+ const tlsOptions = { socket: exemptDial(options, HTTPS_PORT), servername: requestServername(options, host) };
3257
+ if ("ca" in options && Array.isArray(options.ca)) {
3258
+ tlsOptions.ca = options.ca;
3259
+ }
3260
+ if ("rejectUnauthorized" in options && typeof options.rejectUnauthorized === "boolean") {
3261
+ tlsOptions.rejectUnauthorized = options.rejectUnauthorized;
3262
+ }
3263
+ return tls.connect(tlsOptions);
3264
+ }
3265
+ };
3216
3266
  function realConnectEffects() {
3217
- const plainAgent = new http.Agent({ keepAlive: true });
3218
- const tlsAgent = new https.Agent({ keepAlive: true });
3267
+ const plainAgent = new ExemptHttpAgent();
3268
+ const tlsAgent = new ExemptTlsAgent();
3219
3269
  const listenOnce = async (port, onSocket) => await new Promise((resolve, reject) => {
3220
3270
  const accepted = /* @__PURE__ */ new Set();
3221
3271
  const server = net2.createServer((socket) => {
@@ -3301,11 +3351,23 @@ function realConnectEffects() {
3301
3351
  };
3302
3352
  },
3303
3353
  connectTlsUpstream: async (host, port, clientAlpn) => await new Promise((resolve, reject) => {
3304
- const socket = tls.connect({ host, port, servername: host, ...clientAlpn === void 0 ? {} : { ALPNProtocols: [clientAlpn] } });
3305
- socket.once("secureConnect", () => {
3306
- resolve(socket);
3307
- });
3308
- socket.once("error", reject);
3354
+ const dial = (localPort) => {
3355
+ const raw = net2.connect({ host, port, localPort, lookup: realAddressLookup });
3356
+ return tls.connect({ socket: raw, servername: host, ...clientAlpn === void 0 ? {} : { ALPNProtocols: [clientAlpn] } });
3357
+ };
3358
+ const settle = (candidate) => {
3359
+ candidate.once("secureConnect", () => {
3360
+ resolve(candidate);
3361
+ });
3362
+ candidate.once("error", (error) => {
3363
+ if ("code" in error && error.code === "EADDRINUSE") {
3364
+ settle(dial(upstreamLocalPort()));
3365
+ return;
3366
+ }
3367
+ reject(error);
3368
+ });
3369
+ };
3370
+ settle(dial(upstreamLocalPort()));
3309
3371
  }),
3310
3372
  connectTcp: async (host, port) => await new Promise((resolve, reject) => {
3311
3373
  const socket = net2.connect({ host, port });
@@ -3319,6 +3381,7 @@ function realConnectEffects() {
3319
3381
  const options = {
3320
3382
  host: target.host,
3321
3383
  port: target.port,
3384
+ lookup: realAddressLookup,
3322
3385
  method: request3.method,
3323
3386
  path: request3.url,
3324
3387
  headers,
package/dist/index.mjs CHANGED
@@ -3043,13 +3043,63 @@ function realConnectCertStore(paths) {
3043
3043
  }
3044
3044
 
3045
3045
  // src/frontdoor/connectEffects.ts
3046
+ import * as dns from "node:dns";
3046
3047
  import * as http from "node:http";
3047
3048
  import * as https from "node:https";
3048
3049
  import * as net2 from "node:net";
3049
3050
  import * as tls from "node:tls";
3051
+ var UPSTREAM_LOCAL_PORT_START = 47900;
3052
+ var UPSTREAM_LOCAL_PORT_END = 47919;
3053
+ var nextUpstreamLocalPort = UPSTREAM_LOCAL_PORT_START;
3054
+ function upstreamLocalPort() {
3055
+ const port = nextUpstreamLocalPort;
3056
+ nextUpstreamLocalPort = nextUpstreamLocalPort === UPSTREAM_LOCAL_PORT_END ? UPSTREAM_LOCAL_PORT_START : nextUpstreamLocalPort + 1;
3057
+ return port;
3058
+ }
3059
+ var realAddressLookup = (host, _options, callback) => {
3060
+ if (net2.isIP(host) !== 0) {
3061
+ callback(null, [{ address: host, family: net2.isIP(host) }]);
3062
+ return;
3063
+ }
3064
+ dns.resolve4(host, (error, addresses) => {
3065
+ const first = addresses[0];
3066
+ if (error !== null || first === void 0) {
3067
+ callback(error ?? new Error(`no A record for ${host}`), [{ address: "", family: 4 }]);
3068
+ return;
3069
+ }
3070
+ callback(null, [{ address: first, family: 4 }]);
3071
+ });
3072
+ };
3073
+ var HTTP_PORT = 80;
3074
+ function exemptDial(options, defaultPort) {
3075
+ const host = typeof options.host === "string" ? options.host : "";
3076
+ const port = typeof options.port === "number" ? options.port : defaultPort;
3077
+ return net2.connect(net2.isIP(host) === 0 ? { host, port, localPort: upstreamLocalPort(), lookup: realAddressLookup } : { host, port });
3078
+ }
3079
+ function requestServername(options, fallback) {
3080
+ return "servername" in options && typeof options.servername === "string" && options.servername !== "" ? options.servername : fallback;
3081
+ }
3082
+ var ExemptHttpAgent = class extends http.Agent {
3083
+ createConnection(options) {
3084
+ return exemptDial(options, HTTP_PORT);
3085
+ }
3086
+ };
3087
+ var ExemptTlsAgent = class extends https.Agent {
3088
+ createConnection(options) {
3089
+ const host = typeof options.host === "string" ? options.host : "";
3090
+ const tlsOptions = { socket: exemptDial(options, HTTPS_PORT), servername: requestServername(options, host) };
3091
+ if ("ca" in options && Array.isArray(options.ca)) {
3092
+ tlsOptions.ca = options.ca;
3093
+ }
3094
+ if ("rejectUnauthorized" in options && typeof options.rejectUnauthorized === "boolean") {
3095
+ tlsOptions.rejectUnauthorized = options.rejectUnauthorized;
3096
+ }
3097
+ return tls.connect(tlsOptions);
3098
+ }
3099
+ };
3050
3100
  function realConnectEffects() {
3051
- const plainAgent = new http.Agent({ keepAlive: true });
3052
- const tlsAgent = new https.Agent({ keepAlive: true });
3101
+ const plainAgent = new ExemptHttpAgent();
3102
+ const tlsAgent = new ExemptTlsAgent();
3053
3103
  const listenOnce = async (port, onSocket) => await new Promise((resolve, reject) => {
3054
3104
  const accepted = /* @__PURE__ */ new Set();
3055
3105
  const server = net2.createServer((socket) => {
@@ -3135,11 +3185,23 @@ function realConnectEffects() {
3135
3185
  };
3136
3186
  },
3137
3187
  connectTlsUpstream: async (host, port, clientAlpn) => await new Promise((resolve, reject) => {
3138
- const socket = tls.connect({ host, port, servername: host, ...clientAlpn === void 0 ? {} : { ALPNProtocols: [clientAlpn] } });
3139
- socket.once("secureConnect", () => {
3140
- resolve(socket);
3141
- });
3142
- socket.once("error", reject);
3188
+ const dial = (localPort) => {
3189
+ const raw = net2.connect({ host, port, localPort, lookup: realAddressLookup });
3190
+ return tls.connect({ socket: raw, servername: host, ...clientAlpn === void 0 ? {} : { ALPNProtocols: [clientAlpn] } });
3191
+ };
3192
+ const settle = (candidate) => {
3193
+ candidate.once("secureConnect", () => {
3194
+ resolve(candidate);
3195
+ });
3196
+ candidate.once("error", (error) => {
3197
+ if ("code" in error && error.code === "EADDRINUSE") {
3198
+ settle(dial(upstreamLocalPort()));
3199
+ return;
3200
+ }
3201
+ reject(error);
3202
+ });
3203
+ };
3204
+ settle(dial(upstreamLocalPort()));
3143
3205
  }),
3144
3206
  connectTcp: async (host, port) => await new Promise((resolve, reject) => {
3145
3207
  const socket = net2.connect({ host, port });
@@ -3153,6 +3215,7 @@ function realConnectEffects() {
3153
3215
  const options = {
3154
3216
  host: target.host,
3155
3217
  port: target.port,
3218
+ lookup: realAddressLookup,
3156
3219
  method: request3.method,
3157
3220
  path: request3.url,
3158
3221
  headers,