agent-shim 8.5.0 → 8.5.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/cli.cjs CHANGED
@@ -61040,7 +61040,7 @@ function registerIdentityCommand(program2, deps) {
61040
61040
  // package.json
61041
61041
  var package_default = {
61042
61042
  name: "agent-shim",
61043
- version: "8.5.0",
61043
+ version: "8.5.1",
61044
61044
  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.",
61045
61045
  license: "MIT",
61046
61046
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -64924,13 +64924,14 @@ function realConnectCertStore(paths) {
64924
64924
  }
64925
64925
 
64926
64926
  // src/frontdoor/connectEffects.ts
64927
- var dns = __toESM(require("node:dns"), 1);
64927
+ var import_node_dns = __toESM(require("node:dns"), 1);
64928
64928
  var http = __toESM(require("node:http"), 1);
64929
64929
  var https = __toESM(require("node:https"), 1);
64930
64930
  var net2 = __toESM(require("node:net"), 1);
64931
64931
  var tls = __toESM(require("node:tls"), 1);
64932
64932
  var UPSTREAM_LOCAL_PORT_START = 47900;
64933
64933
  var UPSTREAM_LOCAL_PORT_END = 47919;
64934
+ var UPSTREAM_LOCAL_PORT_COUNT = UPSTREAM_LOCAL_PORT_END - UPSTREAM_LOCAL_PORT_START + 1;
64934
64935
  var nextUpstreamLocalPort = UPSTREAM_LOCAL_PORT_START;
64935
64936
  function upstreamLocalPort() {
64936
64937
  const port = nextUpstreamLocalPort;
@@ -64942,42 +64943,93 @@ var realAddressLookup = (host, _options, callback) => {
64942
64943
  callback(null, [{ address: host, family: net2.isIP(host) }]);
64943
64944
  return;
64944
64945
  }
64945
- dns.resolve4(host, (error62, addresses) => {
64946
+ import_node_dns.default.resolve4(host, (error62, addresses) => {
64947
+ if (error62 !== null) {
64948
+ callback(error62, [{ address: "", family: 4 }]);
64949
+ return;
64950
+ }
64946
64951
  const first = addresses[0];
64947
- if (error62 !== null || first === void 0) {
64948
- callback(error62 ?? new Error(`no A record for ${host}`), [{ address: "", family: 4 }]);
64952
+ if (first === void 0) {
64953
+ callback(new Error(`no A record for ${host}`), [{ address: "", family: 4 }]);
64949
64954
  return;
64950
64955
  }
64951
64956
  callback(null, [{ address: first, family: 4 }]);
64952
64957
  });
64953
64958
  };
64954
64959
  var HTTP_PORT = 80;
64955
- function exemptDial(options, defaultPort) {
64956
- const host = typeof options.host === "string" ? options.host : "";
64957
- const port = typeof options.port === "number" ? options.port : defaultPort;
64958
- return net2.connect(net2.isIP(host) === 0 ? { host, port, localPort: upstreamLocalPort(), lookup: realAddressLookup } : { host, port });
64960
+ var HELD_PORT_ERRNOS = /* @__PURE__ */ new Set(["EADDRINUSE", "EADDRNOTAVAIL"]);
64961
+ async function dialOnce(connectOptions) {
64962
+ return await new Promise((resolve) => {
64963
+ const socket = net2.connect(connectOptions);
64964
+ socket.once("connect", () => {
64965
+ resolve({ error: null, socket });
64966
+ });
64967
+ socket.once("error", (error62) => {
64968
+ resolve({ error: error62, socket });
64969
+ });
64970
+ });
64971
+ }
64972
+ function dialTarget(options, defaultPort) {
64973
+ return { host: typeof options.host === "string" ? options.host : "", port: typeof options.port === "number" ? options.port : defaultPort };
64974
+ }
64975
+ function literalDial(target) {
64976
+ return net2.connect({ host: target.host, port: target.port });
64977
+ }
64978
+ async function reservedDial(target) {
64979
+ for (let attempt = 0; ; attempt += 1) {
64980
+ const outcome = await dialOnce({ host: target.host, port: target.port, localPort: upstreamLocalPort(), lookup: realAddressLookup });
64981
+ if (outcome.error === null) {
64982
+ return outcome;
64983
+ }
64984
+ const held = outcome.error.code !== void 0 && HELD_PORT_ERRNOS.has(outcome.error.code);
64985
+ if (!held || attempt === UPSTREAM_LOCAL_PORT_COUNT - 1) {
64986
+ return outcome;
64987
+ }
64988
+ }
64959
64989
  }
64960
64990
  function requestServername(options, fallback) {
64961
64991
  return "servername" in options && typeof options.servername === "string" && options.servername !== "" ? options.servername : fallback;
64962
64992
  }
64963
64993
  var ExemptHttpAgent = class extends http.Agent {
64964
- createConnection(options) {
64965
- return exemptDial(options, HTTP_PORT);
64994
+ // 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.
64995
+ createConnection(options, oncreate) {
64996
+ const target = dialTarget(options, HTTP_PORT);
64997
+ if (net2.isIP(target.host) !== 0) {
64998
+ return literalDial(target);
64999
+ }
65000
+ void reservedDial(target).then((outcome) => {
65001
+ oncreate?.(outcome.error, outcome.socket);
65002
+ });
65003
+ return void 0;
64966
65004
  }
64967
65005
  };
64968
65006
  var ExemptTlsAgent = class extends https.Agent {
64969
- createConnection(options) {
64970
- const host = typeof options.host === "string" ? options.host : "";
64971
- const tlsOptions = { socket: exemptDial(options, HTTPS_PORT), servername: requestServername(options, host) };
64972
- if ("ca" in options && Array.isArray(options.ca)) {
64973
- tlsOptions.ca = options.ca;
64974
- }
64975
- if ("rejectUnauthorized" in options && typeof options.rejectUnauthorized === "boolean") {
64976
- tlsOptions.rejectUnauthorized = options.rejectUnauthorized;
64977
- }
64978
- return tls.connect(tlsOptions);
65007
+ // 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.
65008
+ createConnection(options, oncreate) {
65009
+ const target = dialTarget(options, HTTPS_PORT);
65010
+ if (net2.isIP(target.host) !== 0) {
65011
+ return tls.connect({ socket: literalDial(target), servername: requestServername(options, target.host), ...tlsFacts(options) });
65012
+ }
65013
+ void reservedDial(target).then((outcome) => {
65014
+ if (outcome.error !== null) {
65015
+ oncreate?.(outcome.error, outcome.socket);
65016
+ return;
65017
+ }
65018
+ oncreate?.(null, tls.connect({ socket: outcome.socket, servername: requestServername(options, target.host), ...tlsFacts(options) }));
65019
+ });
65020
+ return void 0;
64979
65021
  }
64980
65022
  };
65023
+ function tlsFacts(options) {
65024
+ const facts = {};
65025
+ if ("ca" in options && Array.isArray(options.ca)) {
65026
+ facts.ca = options.ca;
65027
+ }
65028
+ if ("rejectUnauthorized" in options && typeof options.rejectUnauthorized === "boolean") {
65029
+ facts.rejectUnauthorized = options.rejectUnauthorized;
65030
+ }
65031
+ return facts;
65032
+ }
64981
65033
  function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
64982
65034
  const agent = new ExemptTlsAgent();
64983
65035
  return {
package/dist/index.cjs CHANGED
@@ -3248,13 +3248,14 @@ function realConnectCertStore(paths) {
3248
3248
  }
3249
3249
 
3250
3250
  // src/frontdoor/connectEffects.ts
3251
- var dns = __toESM(require("node:dns"), 1);
3251
+ var import_node_dns = __toESM(require("node:dns"), 1);
3252
3252
  var http = __toESM(require("node:http"), 1);
3253
3253
  var https = __toESM(require("node:https"), 1);
3254
3254
  var net2 = __toESM(require("node:net"), 1);
3255
3255
  var tls = __toESM(require("node:tls"), 1);
3256
3256
  var UPSTREAM_LOCAL_PORT_START = 47900;
3257
3257
  var UPSTREAM_LOCAL_PORT_END = 47919;
3258
+ var UPSTREAM_LOCAL_PORT_COUNT = UPSTREAM_LOCAL_PORT_END - UPSTREAM_LOCAL_PORT_START + 1;
3258
3259
  var nextUpstreamLocalPort = UPSTREAM_LOCAL_PORT_START;
3259
3260
  function upstreamLocalPort() {
3260
3261
  const port = nextUpstreamLocalPort;
@@ -3266,42 +3267,93 @@ var realAddressLookup = (host, _options, callback) => {
3266
3267
  callback(null, [{ address: host, family: net2.isIP(host) }]);
3267
3268
  return;
3268
3269
  }
3269
- dns.resolve4(host, (error, addresses) => {
3270
+ import_node_dns.default.resolve4(host, (error, addresses) => {
3271
+ if (error !== null) {
3272
+ callback(error, [{ address: "", family: 4 }]);
3273
+ return;
3274
+ }
3270
3275
  const first = addresses[0];
3271
- if (error !== null || first === void 0) {
3272
- callback(error ?? new Error(`no A record for ${host}`), [{ address: "", family: 4 }]);
3276
+ if (first === void 0) {
3277
+ callback(new Error(`no A record for ${host}`), [{ address: "", family: 4 }]);
3273
3278
  return;
3274
3279
  }
3275
3280
  callback(null, [{ address: first, family: 4 }]);
3276
3281
  });
3277
3282
  };
3278
3283
  var HTTP_PORT = 80;
3279
- function exemptDial(options, defaultPort) {
3280
- const host = typeof options.host === "string" ? options.host : "";
3281
- const port = typeof options.port === "number" ? options.port : defaultPort;
3282
- return net2.connect(net2.isIP(host) === 0 ? { host, port, localPort: upstreamLocalPort(), lookup: realAddressLookup } : { host, port });
3284
+ var HELD_PORT_ERRNOS = /* @__PURE__ */ new Set(["EADDRINUSE", "EADDRNOTAVAIL"]);
3285
+ async function dialOnce(connectOptions) {
3286
+ return await new Promise((resolve) => {
3287
+ const socket = net2.connect(connectOptions);
3288
+ socket.once("connect", () => {
3289
+ resolve({ error: null, socket });
3290
+ });
3291
+ socket.once("error", (error) => {
3292
+ resolve({ error, socket });
3293
+ });
3294
+ });
3295
+ }
3296
+ function dialTarget(options, defaultPort) {
3297
+ return { host: typeof options.host === "string" ? options.host : "", port: typeof options.port === "number" ? options.port : defaultPort };
3298
+ }
3299
+ function literalDial(target) {
3300
+ return net2.connect({ host: target.host, port: target.port });
3301
+ }
3302
+ async function reservedDial(target) {
3303
+ for (let attempt = 0; ; attempt += 1) {
3304
+ const outcome = await dialOnce({ host: target.host, port: target.port, localPort: upstreamLocalPort(), lookup: realAddressLookup });
3305
+ if (outcome.error === null) {
3306
+ return outcome;
3307
+ }
3308
+ const held = outcome.error.code !== void 0 && HELD_PORT_ERRNOS.has(outcome.error.code);
3309
+ if (!held || attempt === UPSTREAM_LOCAL_PORT_COUNT - 1) {
3310
+ return outcome;
3311
+ }
3312
+ }
3283
3313
  }
3284
3314
  function requestServername(options, fallback) {
3285
3315
  return "servername" in options && typeof options.servername === "string" && options.servername !== "" ? options.servername : fallback;
3286
3316
  }
3287
3317
  var ExemptHttpAgent = class extends http.Agent {
3288
- createConnection(options) {
3289
- return exemptDial(options, HTTP_PORT);
3318
+ // 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.
3319
+ createConnection(options, oncreate) {
3320
+ const target = dialTarget(options, HTTP_PORT);
3321
+ if (net2.isIP(target.host) !== 0) {
3322
+ return literalDial(target);
3323
+ }
3324
+ void reservedDial(target).then((outcome) => {
3325
+ oncreate?.(outcome.error, outcome.socket);
3326
+ });
3327
+ return void 0;
3290
3328
  }
3291
3329
  };
3292
3330
  var ExemptTlsAgent = class extends https.Agent {
3293
- createConnection(options) {
3294
- const host = typeof options.host === "string" ? options.host : "";
3295
- const tlsOptions = { socket: exemptDial(options, HTTPS_PORT), servername: requestServername(options, host) };
3296
- if ("ca" in options && Array.isArray(options.ca)) {
3297
- tlsOptions.ca = options.ca;
3298
- }
3299
- if ("rejectUnauthorized" in options && typeof options.rejectUnauthorized === "boolean") {
3300
- tlsOptions.rejectUnauthorized = options.rejectUnauthorized;
3301
- }
3302
- return tls.connect(tlsOptions);
3331
+ // 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.
3332
+ createConnection(options, oncreate) {
3333
+ const target = dialTarget(options, HTTPS_PORT);
3334
+ if (net2.isIP(target.host) !== 0) {
3335
+ return tls.connect({ socket: literalDial(target), servername: requestServername(options, target.host), ...tlsFacts(options) });
3336
+ }
3337
+ void reservedDial(target).then((outcome) => {
3338
+ if (outcome.error !== null) {
3339
+ oncreate?.(outcome.error, outcome.socket);
3340
+ return;
3341
+ }
3342
+ oncreate?.(null, tls.connect({ socket: outcome.socket, servername: requestServername(options, target.host), ...tlsFacts(options) }));
3343
+ });
3344
+ return void 0;
3303
3345
  }
3304
3346
  };
3347
+ function tlsFacts(options) {
3348
+ const facts = {};
3349
+ if ("ca" in options && Array.isArray(options.ca)) {
3350
+ facts.ca = options.ca;
3351
+ }
3352
+ if ("rejectUnauthorized" in options && typeof options.rejectUnauthorized === "boolean") {
3353
+ facts.rejectUnauthorized = options.rejectUnauthorized;
3354
+ }
3355
+ return facts;
3356
+ }
3305
3357
  function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
3306
3358
  const agent = new ExemptTlsAgent();
3307
3359
  return {
package/dist/index.mjs CHANGED
@@ -3064,13 +3064,14 @@ function realConnectCertStore(paths) {
3064
3064
  }
3065
3065
 
3066
3066
  // src/frontdoor/connectEffects.ts
3067
- import * as dns from "node:dns";
3067
+ import dns from "node:dns";
3068
3068
  import * as http from "node:http";
3069
3069
  import * as https from "node:https";
3070
3070
  import * as net2 from "node:net";
3071
3071
  import * as tls from "node:tls";
3072
3072
  var UPSTREAM_LOCAL_PORT_START = 47900;
3073
3073
  var UPSTREAM_LOCAL_PORT_END = 47919;
3074
+ var UPSTREAM_LOCAL_PORT_COUNT = UPSTREAM_LOCAL_PORT_END - UPSTREAM_LOCAL_PORT_START + 1;
3074
3075
  var nextUpstreamLocalPort = UPSTREAM_LOCAL_PORT_START;
3075
3076
  function upstreamLocalPort() {
3076
3077
  const port = nextUpstreamLocalPort;
@@ -3083,41 +3084,92 @@ var realAddressLookup = (host, _options, callback) => {
3083
3084
  return;
3084
3085
  }
3085
3086
  dns.resolve4(host, (error, addresses) => {
3087
+ if (error !== null) {
3088
+ callback(error, [{ address: "", family: 4 }]);
3089
+ return;
3090
+ }
3086
3091
  const first = addresses[0];
3087
- if (error !== null || first === void 0) {
3088
- callback(error ?? new Error(`no A record for ${host}`), [{ address: "", family: 4 }]);
3092
+ if (first === void 0) {
3093
+ callback(new Error(`no A record for ${host}`), [{ address: "", family: 4 }]);
3089
3094
  return;
3090
3095
  }
3091
3096
  callback(null, [{ address: first, family: 4 }]);
3092
3097
  });
3093
3098
  };
3094
3099
  var HTTP_PORT = 80;
3095
- function exemptDial(options, defaultPort) {
3096
- const host = typeof options.host === "string" ? options.host : "";
3097
- const port = typeof options.port === "number" ? options.port : defaultPort;
3098
- return net2.connect(net2.isIP(host) === 0 ? { host, port, localPort: upstreamLocalPort(), lookup: realAddressLookup } : { host, port });
3100
+ var HELD_PORT_ERRNOS = /* @__PURE__ */ new Set(["EADDRINUSE", "EADDRNOTAVAIL"]);
3101
+ async function dialOnce(connectOptions) {
3102
+ return await new Promise((resolve) => {
3103
+ const socket = net2.connect(connectOptions);
3104
+ socket.once("connect", () => {
3105
+ resolve({ error: null, socket });
3106
+ });
3107
+ socket.once("error", (error) => {
3108
+ resolve({ error, socket });
3109
+ });
3110
+ });
3111
+ }
3112
+ function dialTarget(options, defaultPort) {
3113
+ return { host: typeof options.host === "string" ? options.host : "", port: typeof options.port === "number" ? options.port : defaultPort };
3114
+ }
3115
+ function literalDial(target) {
3116
+ return net2.connect({ host: target.host, port: target.port });
3117
+ }
3118
+ async function reservedDial(target) {
3119
+ for (let attempt = 0; ; attempt += 1) {
3120
+ const outcome = await dialOnce({ host: target.host, port: target.port, localPort: upstreamLocalPort(), lookup: realAddressLookup });
3121
+ if (outcome.error === null) {
3122
+ return outcome;
3123
+ }
3124
+ const held = outcome.error.code !== void 0 && HELD_PORT_ERRNOS.has(outcome.error.code);
3125
+ if (!held || attempt === UPSTREAM_LOCAL_PORT_COUNT - 1) {
3126
+ return outcome;
3127
+ }
3128
+ }
3099
3129
  }
3100
3130
  function requestServername(options, fallback) {
3101
3131
  return "servername" in options && typeof options.servername === "string" && options.servername !== "" ? options.servername : fallback;
3102
3132
  }
3103
3133
  var ExemptHttpAgent = class extends http.Agent {
3104
- createConnection(options) {
3105
- return exemptDial(options, HTTP_PORT);
3134
+ // 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.
3135
+ createConnection(options, oncreate) {
3136
+ const target = dialTarget(options, HTTP_PORT);
3137
+ if (net2.isIP(target.host) !== 0) {
3138
+ return literalDial(target);
3139
+ }
3140
+ void reservedDial(target).then((outcome) => {
3141
+ oncreate?.(outcome.error, outcome.socket);
3142
+ });
3143
+ return void 0;
3106
3144
  }
3107
3145
  };
3108
3146
  var ExemptTlsAgent = class extends https.Agent {
3109
- createConnection(options) {
3110
- const host = typeof options.host === "string" ? options.host : "";
3111
- const tlsOptions = { socket: exemptDial(options, HTTPS_PORT), servername: requestServername(options, host) };
3112
- if ("ca" in options && Array.isArray(options.ca)) {
3113
- tlsOptions.ca = options.ca;
3114
- }
3115
- if ("rejectUnauthorized" in options && typeof options.rejectUnauthorized === "boolean") {
3116
- tlsOptions.rejectUnauthorized = options.rejectUnauthorized;
3117
- }
3118
- return tls.connect(tlsOptions);
3147
+ // 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.
3148
+ createConnection(options, oncreate) {
3149
+ const target = dialTarget(options, HTTPS_PORT);
3150
+ if (net2.isIP(target.host) !== 0) {
3151
+ return tls.connect({ socket: literalDial(target), servername: requestServername(options, target.host), ...tlsFacts(options) });
3152
+ }
3153
+ void reservedDial(target).then((outcome) => {
3154
+ if (outcome.error !== null) {
3155
+ oncreate?.(outcome.error, outcome.socket);
3156
+ return;
3157
+ }
3158
+ oncreate?.(null, tls.connect({ socket: outcome.socket, servername: requestServername(options, target.host), ...tlsFacts(options) }));
3159
+ });
3160
+ return void 0;
3119
3161
  }
3120
3162
  };
3163
+ function tlsFacts(options) {
3164
+ const facts = {};
3165
+ if ("ca" in options && Array.isArray(options.ca)) {
3166
+ facts.ca = options.ca;
3167
+ }
3168
+ if ("rejectUnauthorized" in options && typeof options.rejectUnauthorized === "boolean") {
3169
+ facts.rejectUnauthorized = options.rejectUnauthorized;
3170
+ }
3171
+ return facts;
3172
+ }
3121
3173
  function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
3122
3174
  const agent = new ExemptTlsAgent();
3123
3175
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-shim",
3
- "version": "8.5.0",
3
+ "version": "8.5.1",
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>",