agent-shim 7.13.2 → 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.
- package/dist/cli.cjs +93 -27
- package/dist/index.cjs +70 -7
- package/dist/index.mjs +70 -7
- package/dist/types/index.d.ts +0 -1
- package/package.json +1 -1
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
20348
|
+
var Agent5 = require_agent();
|
|
20349
20349
|
if (getGlobalDispatcher() === void 0) {
|
|
20350
|
-
setGlobalDispatcher(new
|
|
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 (
|
|
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
|
|
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 =
|
|
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.
|
|
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>",
|
|
@@ -64833,13 +64833,63 @@ function realConnectCertStore(paths) {
|
|
|
64833
64833
|
}
|
|
64834
64834
|
|
|
64835
64835
|
// src/frontdoor/connectEffects.ts
|
|
64836
|
+
var dns = __toESM(require("node:dns"), 1);
|
|
64836
64837
|
var http = __toESM(require("node:http"), 1);
|
|
64837
64838
|
var https = __toESM(require("node:https"), 1);
|
|
64838
64839
|
var net3 = __toESM(require("node:net"), 1);
|
|
64839
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
|
+
};
|
|
64840
64890
|
function realConnectEffects() {
|
|
64841
|
-
const plainAgent = new
|
|
64842
|
-
const tlsAgent = new
|
|
64891
|
+
const plainAgent = new ExemptHttpAgent();
|
|
64892
|
+
const tlsAgent = new ExemptTlsAgent();
|
|
64843
64893
|
const listenOnce = async (port, onSocket) => await new Promise((resolve, reject) => {
|
|
64844
64894
|
const accepted = /* @__PURE__ */ new Set();
|
|
64845
64895
|
const server = net3.createServer((socket) => {
|
|
@@ -64925,11 +64975,23 @@ function realConnectEffects() {
|
|
|
64925
64975
|
};
|
|
64926
64976
|
},
|
|
64927
64977
|
connectTlsUpstream: async (host, port, clientAlpn) => await new Promise((resolve, reject) => {
|
|
64928
|
-
const
|
|
64929
|
-
|
|
64930
|
-
|
|
64931
|
-
}
|
|
64932
|
-
|
|
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()));
|
|
64933
64995
|
}),
|
|
64934
64996
|
connectTcp: async (host, port) => await new Promise((resolve, reject) => {
|
|
64935
64997
|
const socket = net3.connect({ host, port });
|
|
@@ -64943,6 +65005,7 @@ function realConnectEffects() {
|
|
|
64943
65005
|
const options = {
|
|
64944
65006
|
host: target.host,
|
|
64945
65007
|
port: target.port,
|
|
65008
|
+
lookup: realAddressLookup,
|
|
64946
65009
|
method: request6.method,
|
|
64947
65010
|
path: request6.url,
|
|
64948
65011
|
headers,
|
|
@@ -66222,7 +66285,7 @@ function createPassthroughRoute(name, target) {
|
|
|
66222
66285
|
const base = new URL(target.baseUrl);
|
|
66223
66286
|
const tls2 = base.protocol === "https:";
|
|
66224
66287
|
const basePath = base.pathname.replace(/\/+$/, "");
|
|
66225
|
-
const agent = tls2 ? new
|
|
66288
|
+
const agent = tls2 ? new ExemptTlsAgent() : new ExemptHttpAgent();
|
|
66226
66289
|
return {
|
|
66227
66290
|
name,
|
|
66228
66291
|
headroomEligible: true,
|
|
@@ -68281,11 +68344,13 @@ var READY_FETCH_TIMEOUT_MS = 2e3;
|
|
|
68281
68344
|
function headroomPidRunning(pid) {
|
|
68282
68345
|
return !exitedHeadroom.has(pid) && realIsProcessRunning(pid);
|
|
68283
68346
|
}
|
|
68284
|
-
function headroomSpawnEnv(parentEnv, allowlist, settings2) {
|
|
68347
|
+
function headroomSpawnEnv(parentEnv, allowlist, settings2, caBundle) {
|
|
68285
68348
|
return {
|
|
68286
68349
|
...parentEnv,
|
|
68287
68350
|
HEADROOM_ALLOWED_BASE_URLS: allowlist.join(","),
|
|
68288
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 },
|
|
68289
68354
|
...settingsEnv(settings2)
|
|
68290
68355
|
};
|
|
68291
68356
|
}
|
|
@@ -68324,13 +68389,14 @@ function realSupervisorPorts(paths) {
|
|
|
68324
68389
|
isPortFree: realIsPortFree,
|
|
68325
68390
|
readConfig: () => resolveSupervisorConfig(readGlobalConfig(paths)?.headroom ?? {}),
|
|
68326
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;
|
|
68327
68393
|
import_node_fs15.default.mkdirSync(paths.logsDir, { recursive: true });
|
|
68328
68394
|
const logFd = import_node_fs15.default.openSync(paths.headroomLogPath, "a");
|
|
68329
68395
|
try {
|
|
68330
68396
|
const child = (0, import_node_child_process5.spawn)("headroom", ["proxy", "--host", "127.0.0.1", "--port", String(port), ...settingsArgs(settings2)], {
|
|
68331
68397
|
detached: true,
|
|
68332
68398
|
stdio: ["ignore", logFd, logFd],
|
|
68333
|
-
env: headroomSpawnEnv(process.env, allowlist, settings2)
|
|
68399
|
+
env: headroomSpawnEnv(process.env, allowlist, settings2, caBundle)
|
|
68334
68400
|
});
|
|
68335
68401
|
if (child.pid === void 0) {
|
|
68336
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
|
|
3218
|
-
const tlsAgent = new
|
|
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
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
}
|
|
3308
|
-
|
|
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
|
|
3052
|
-
const tlsAgent = new
|
|
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
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
}
|
|
3142
|
-
|
|
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,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1583,7 +1583,6 @@ declare function realConnectCertStore(paths: {
|
|
|
1583
1583
|
readonly frontdoorCaKeyFile: string;
|
|
1584
1584
|
}): ConnectCertStore;
|
|
1585
1585
|
|
|
1586
|
-
/** The real `ConnectEffects` over node's own net, tls, and http. `connectTcp` opens real connections to the CONNECTed host, so tests that want a blind tunnel redirect it. */
|
|
1587
1586
|
declare function realConnectEffects(): ConnectEffects;
|
|
1588
1587
|
|
|
1589
1588
|
/** The filesystem operations headroom coordination needs: the same shape as `FarmFs`, injected so every decision over state, sessions, and the start lock runs against an in-memory fake in tests. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-shim",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.14.0",
|
|
4
4
|
"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.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Joseph Mearman <joseph@mearman.co.uk>",
|