@lensmcp/cluster 1.16.31 → 1.17.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.
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BENIGN_SOCKET_ERRNOS = void 0;
4
4
  exports.buildEdgeVerifierPool = buildEdgeVerifierPool;
5
+ exports.classifyClientError = classifyClientError;
6
+ exports.createClientErrorLogGate = createClientErrorLogGate;
5
7
  exports.startGateway = startGateway;
6
8
  const tslib_1 = require("tslib");
7
9
  /**
@@ -31,6 +33,7 @@ const hooks_1 = require("./hooks");
31
33
  const handler_1 = require("./handler");
32
34
  const upgrade_1 = require("./upgrade");
33
35
  const jwks_verify_1 = require("../jwks-verify");
36
+ const types_1 = require("./types");
34
37
  /**
35
38
  * A `fetch`-shaped shim for the JWKS pull that accepts the dev gateway's OWN self-signed cert. The dev
36
39
  * IdP's JWKS is served behind the same local HTTPS front door (e.g. `https://auth.tetros.ai.local`), whose
@@ -116,6 +119,39 @@ function buildEdgeVerifierPool(getRoutes) {
116
119
  /** Client-abort errnos that are NORMAL front-door traffic (a closed tab, a sleeping laptop, a canceled
117
120
  * HMR socket) — dropped quietly. Anything else on an inbound socket is logged before the drop. */
118
121
  exports.BENIGN_SOCKET_ERRNOS = new Set(['ECONNRESET', 'EPIPE', 'ETIMEDOUT', 'ECONNABORTED', 'ECANCELED']);
122
+ function classifyClientError(code, message) {
123
+ if (code && exports.BENIGN_SOCKET_ERRNOS.has(code))
124
+ return { status: null, report: false, cause: 'client-abort' };
125
+ // Peer half-closed mid-message: nobody is waiting for a 400, and writing one is the spurious-400 vector.
126
+ if (code === 'HPE_INVALID_EOF_STATE')
127
+ return { status: null, report: false, cause: 'truncated-at-eof' };
128
+ if (code === 'ERR_HTTP_REQUEST_TIMEOUT')
129
+ return { status: 408, report: true, cause: 'request-timeout' };
130
+ if (code === 'HPE_HEADER_OVERFLOW')
131
+ return { status: 431, report: true, cause: 'header-overflow' };
132
+ if (code?.startsWith('HPE_'))
133
+ return { status: 400, report: true, cause: 'parse-error' };
134
+ return { status: 400, report: true, cause: code ?? message ?? 'unknown' };
135
+ }
136
+ const CLIENT_ERROR_REASON = {
137
+ 400: 'Bad Request',
138
+ 408: 'Request Timeout',
139
+ 431: 'Request Header Fields Too Large',
140
+ };
141
+ /** Per-cause log throttle for `clientError`: a desynced client or a port scanner can produce these in a
142
+ * tight loop, and the point is a dev NOTICING one — not drowning in thousands. One line per cause per
143
+ * window; the suppressed count rides the next admitted line. Exported for the unit test. */
144
+ function createClientErrorLogGate(windowMs = 10_000) {
145
+ const lastAt = new Map();
146
+ return (cause) => {
147
+ const now = Date.now();
148
+ const prev = lastAt.get(cause) ?? 0;
149
+ if (now - prev < windowMs)
150
+ return false;
151
+ lastAt.set(cause, now);
152
+ return true;
153
+ };
154
+ }
119
155
  /** Attach the inbound-socket error guard. EVERY socket the front door accepts gets an 'error' listener
120
156
  * the moment it exists — both the raw TCP socket ('connection') and the post-handshake TLSSocket
121
157
  * ('secureConnection', a DIFFERENT emitter). A client abort is routine, but with NO listener Node turns
@@ -193,10 +229,17 @@ async function startGateway(options, context) {
193
229
  sweepMs,
194
230
  trafficFlushMs,
195
231
  https,
232
+ // Absolute project root per project name — the scanner narrows each child's staleness scope with it
233
+ // (`sourceScopeDirs`), so a `server/**` file add stops recycling every `web/**` vite. Absent (a bare
234
+ // context with no projectsConfigurations) ⇒ the workspace-wide clock, i.e. previous behavior.
235
+ projectRoots: Object.fromEntries(Object.entries(context.projectsConfigurations?.projects ?? {})
236
+ .map(([name, cfg]) => [name, path.resolve(context.root, cfg.root)])),
196
237
  stopped: () => stopped,
197
238
  };
198
239
  // --- layers -----------------------------------------------------------------
199
240
  const obs = (0, observability_1.createObservability)(eventFile, { trafficFlushMs });
241
+ // One gate for every front-door port — a desynced client must not get N log lines because we bound N ports.
242
+ const admitClientErrorLog = createClientErrorLogGate();
200
243
  const svcLayer = (0, lifecycle_1.createServiceLayer)(rt, obs);
201
244
  const lens = (0, lens_children_1.createLensChildren)(rt, obs, options);
202
245
  // The daemon CONTROL PLANE (loopback ~/.lensmcp/control.sock): a second workspace's `gateway start`
@@ -329,11 +372,42 @@ async function startGateway(options, context) {
329
372
  server.on('connection', guardInboundSocket);
330
373
  server.on('secureConnection', guardInboundSocket); // never fires on a plain-http server — harmless
331
374
  server.on('tlsClientError', (_err, tlsSocket) => tlsSocket.destroy());
332
- server.on('clientError', (err, socket) => {
333
- if (err.code !== 'ECONNRESET' && socket.writable)
334
- socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
375
+ server.on('clientError', (rawErr, socket) => {
376
+ // Node adds `bytesParsed`/`rawPacket` on an HTTP parse error (not on the base ErrnoException type):
377
+ // `bytesParsed` is the single most useful field for telling a truncated reuse race (0 / very low) from
378
+ // a genuinely malformed request, which is exactly what the old handler discarded.
379
+ const err = rawErr;
380
+ const v = classifyClientError(err.code, err.message);
381
+ // OBSERVABILITY (this used to be silent — the whole reason a gateway-invented 400 looked like an app
382
+ // bug). Rate-limited per cause so a port scanner or a desynced client cannot flood the log; the bus
383
+ // `emit` is separately flood-guarded by its fingerprint.
384
+ if (v.report && admitClientErrorLog(v.cause)) {
385
+ const peer = socket.remoteAddress ?? 'unknown';
386
+ const answer = v.status === null ? 'dropped' : String(v.status);
387
+ console.warn(`[gateway] inbound H1 clientError from ${peer}: ${v.cause} (${err.code ?? err.message}${err.bytesParsed !== undefined ? `, bytesParsed=${err.bytesParsed}` : ''}) → ${answer}. This status is the GATEWAY's, not the upstream service's.`);
388
+ obs.emit('warning', `inbound clientError: ${v.cause} → ${answer}`, `gateway-client-error:${v.cause}`, {
389
+ kind: 'gateway-client-error', cause: v.cause, code: err.code ?? null, status: v.status, peer,
390
+ bytesParsed: err.bytesParsed ?? null,
391
+ });
392
+ }
393
+ // Preserved intent: a best-effort status on a still-writable socket, then destroy.
394
+ if (v.status !== null && socket.writable)
395
+ socket.end(`HTTP/1.1 ${v.status} ${CLIENT_ERROR_REASON[v.status]}\r\n\r\n`);
335
396
  socket.destroy();
336
397
  });
398
+ // KEEP-ALIVE REUSE RACE. Node's server default `keepAliveTimeout` is 5s — and a Node HTTP client's
399
+ // pooled agent (Node 19+ `globalAgent` is keepAlive:true; vite's dev proxy uses it) idles on ~the same
400
+ // 5s. Both sides then race the SAME deadline: the client writes a request onto a socket the server is
401
+ // simultaneously closing, the server reads a truncated message, and the front door answers a bare
402
+ // `400` that the dev proxy forwards to the browser verbatim — a 400 on a request the service would
403
+ // have served 200. The documented fix is for the server's idle window to EXCEED every client's, so the
404
+ // server never closes first and the client always controls socket reuse. `headersTimeout` must stay
405
+ // above `keepAliveTimeout` (it bounds a request that has started arriving), and `requestTimeout` keeps
406
+ // its Node default. Dev-only front door, a handful of clients → holding idle sockets longer is free.
407
+ server.keepAliveTimeout = types_1.GATEWAY_KEEPALIVE_TIMEOUT_MS;
408
+ if (server.headersTimeout < types_1.GATEWAY_KEEPALIVE_TIMEOUT_MS + 5_000) {
409
+ server.headersTimeout = types_1.GATEWAY_KEEPALIVE_TIMEOUT_MS + 5_000;
410
+ }
337
411
  // h2 SESSION resilience: without a `sessionError` handler ANY session-level
338
412
  // fault (a client GOAWAY mid-burst, a flood-protection trip, a decode error)
339
413
  // is unhandled → Node tears the session down, failing EVERY sibling stream at
@@ -213,6 +213,61 @@ export declare const POD_STALE_SCAN_MS: number;
213
213
  /** Per-service cooldown between staleness recycles — stops a source-churn burst (codegen) thrash-recycling
214
214
  * the same pod. Override `LENSMCP_POD_STALE_RECYCLE_COOLDOWN_MS`. Default 60s. */
215
215
  export declare const POD_STALE_RECYCLE_COOLDOWN_MS: number;
216
+ /**
217
+ * LENS-CHILD LIVENESS PROBE (dev only). The FOURTH failure mode, and the one that wedges an app in a
218
+ * PERMANENT 502 with nothing in the log: a gateway-spawned vite that is ALIVE but NOT LISTENING. Child
219
+ * health was modelled ONLY as "has the process exited", so a vite whose HTTP listener closes/faults while
220
+ * its event loop stays held open (by the lensmcp plugin's WS server + the bridge connections) is INVISIBLE:
221
+ * `viteChildren` still holds it as live, no `lens child vite exited` line is ever logged, and the
222
+ * exit-driven auto-heal never fires. Worked failure (foodguard, 2026-07-29): two 43-minute-old vite children
223
+ * (pids 89518/89519) that had both printed `VITE ready in 1005 ms` + `Local: http://localhost:4200/`, yet
224
+ * `lsof -nP -p 89519` showed ZERO LISTEN sockets and `lsof -iTCP:4200 -sTCP:LISTEN` was empty —
225
+ * `https://app.foodguard.local` 502'd indefinitely until the pids were hand-killed (the exit handler then
226
+ * respawned them and the app returned 200 within 8s). So the sweeper now TCP-probes each live child's pinned
227
+ * port and SIGKILLs a confirmed wedge, letting the proven exit→auto-heal path do the rest.
228
+ */
229
+ /** Master switch for the liveness probe. Deliberately INDEPENDENT of {@link POD_RECYCLE_ENABLED}: a user who
230
+ * sets `LENSMCP_POD_RECYCLE=0` to stop staleness churn still wants a wedged 502 healed. Set
231
+ * `LENSMCP_LENS_PROBE=0` to disable. Default ON (dev). */
232
+ export declare const LENS_PROBE_ENABLED: boolean;
233
+ /** Spawn grace: a child is never probed (and so never recycled) until it has had this long to BIND its port
234
+ * — a cold vite/nx boot in a big monorepo takes many seconds, and killing a still-booting dev server would
235
+ * be a self-inflicted outage. Override `LENSMCP_LENS_PROBE_GRACE_MS`. Default 45s. */
236
+ export declare const LENS_PROBE_GRACE_MS: number;
237
+ /** CONSECUTIVE probe failures required before a recycle — one blip (a momentary accept backlog, a laptop
238
+ * sleep-wake, a GC pause) must never recycle a healthy dev server. Floored at 2 by
239
+ * {@link lensChildWedged}. Override `LENSMCP_LENS_PROBE_FAILS`. Default 2. */
240
+ export declare const LENS_PROBE_FAILS: number;
241
+ /** Per-probe TCP connect timeout. Short: a listening socket accepts a loopback connect in microseconds, so
242
+ * anything slower is indistinguishable from absent. Override `LENSMCP_LENS_PROBE_TIMEOUT_MS`. Default 1s. */
243
+ export declare const LENS_PROBE_TIMEOUT_MS: number;
244
+ /**
245
+ * RESPAWN-INTO-A-HELD-PORT (the EADDRINUSE self-inflicted crash). The auto-heal respawned after a FIXED
246
+ * backoff while the previous child still held the pinned port — vite's `--strictPort` then exits code=1 on
247
+ * bind, burning a heal attempt and EXTENDING the 502 window. Observed in the gateway log:
248
+ * `Error: listen EADDRINUSE: address already in use 127.0.0.1:50059` immediately followed by
249
+ * `lens child vite exited (code=1 sig=null); auto-healing in 3s (attempt 2).` (3 such events in one log).
250
+ * Two fixes: WAIT for the port to become bindable before spawning, and classify a bind-race exit as
251
+ * RETRYABLE so it does not consume the crash-loop budget a real code fault does.
252
+ */
253
+ /** How long a respawn polls for its pinned port to become bindable before spawning anyway (past the budget
254
+ * the normal heal backoff takes over). Override `LENSMCP_PORT_FREE_WAIT_MS`. Default 10s. */
255
+ export declare const PORT_FREE_WAIT_MS: number;
256
+ /** Poll interval while waiting for a port to free. Override `LENSMCP_PORT_FREE_POLL_MS`. Default 250ms. */
257
+ export declare const PORT_FREE_POLL_MS: number;
258
+ /** A non-zero exit sooner than this is a START failure (it never bound); later means the child RAN and so
259
+ * had the port, which cannot be a bind race. Override `LENSMCP_CHILD_START_FAIL_MS`. Default 10s. */
260
+ export declare const CHILD_START_FAIL_MS: number;
261
+ /** Ultimate backstop: after this many CONSECUTIVE bind-race exits for one label, stop forgiving them and
262
+ * fall back to the normal exponential backoff (so a permanently-squatted port can't 10s-loop forever).
263
+ * Override `LENSMCP_MAX_PORT_CONFLICT_RETRIES`. Default 5. */
264
+ export declare const MAX_PORT_CONFLICT_RETRIES: number;
265
+ /** Inbound keep-alive idle window for the front door. MUST exceed every client's pooled-socket idle timeout
266
+ * so the SERVER never closes a keep-alive socket a client is about to reuse — otherwise both sides race the
267
+ * same deadline and the truncated request surfaces as a spurious front-door `400` (see
268
+ * `classifyClientError`). Node's server default is 5s and a Node client agent's is ~5s, i.e. exactly tied.
269
+ * Override `LENSMCP_KEEPALIVE_TIMEOUT_MS`. Default 76s. */
270
+ export declare const GATEWAY_KEEPALIVE_TIMEOUT_MS: number;
216
271
  /** Test-tunable knobs on top of the user-facing schema. */
217
272
  export interface GatewayRuntimeOptions extends GatewayExecutorSchema {
218
273
  /** Traffic-edge flush period (ms). Default 5000. */
@@ -279,6 +334,16 @@ export interface GatewayRuntime {
279
334
  * lens-frontend sweeper (lens-children) — recycle any child that spawned before it. `0`/undefined until
280
335
  * the first change is observed. Mutable (the one non-readonly runtime field, written only by the scanner). */
281
336
  sourceSetChangedAt?: number;
337
+ /** Per-PROJECT scoped twin of {@link sourceSetChangedAt}: the last time the file set changed *within the
338
+ * subtrees that project could actually resolve* (`sourceScopeDirs`). The workspace-wide clock above
339
+ * recycles every child for an add ANYWHERE — so a backend-only `.ts` restarted every frontend vite. A
340
+ * consumer prefers its own entry and falls back to the wide clock when absent (project root unknown, or
341
+ * the scan not yet warmed). Mutable, written only by the scanner. */
342
+ sourceSetChangedFor?: Map<string, number>;
343
+ /** Absolute project root per project name (from `projectsConfigurations`) — lets the scanner derive each
344
+ * child's watch scope, and tells it which top-level buckets are OWNED by a managed project. Absent ⇒
345
+ * every consumer falls back to the workspace-wide clock (previous behavior). */
346
+ readonly projectRoots?: Readonly<Record<string, string>>;
282
347
  /** Teardown flag — a GETTER, never a captured boolean, so every layer reads
283
348
  * the LIVE value (an in-flight cold start / auto-heal must not act after stop). */
284
349
  stopped(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/types.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.POD_STALE_RECYCLE_COOLDOWN_MS = exports.POD_STALE_SCAN_MS = exports.POD_RECYCLE_SETTLE_MS = exports.POD_STALE_GRACE_MS = exports.POD_MAX_AGE_MS = exports.POD_RECYCLE_ENABLED = exports.WEDGE_RECYCLE_GRACE_MS = exports.POD_RESPONSE_TIMEOUT_MS = exports.UPSTREAM_HEAL_STEP_MS = exports.UPSTREAM_HEAL_WINDOW_MS = exports.SERVICE_RESTART_WINDOW_MS = exports.SERVICE_MAX_RESTARTS = exports.SERVICE_ERROR_THROTTLE_MS = void 0;
3
+ exports.GATEWAY_KEEPALIVE_TIMEOUT_MS = exports.MAX_PORT_CONFLICT_RETRIES = exports.CHILD_START_FAIL_MS = exports.PORT_FREE_POLL_MS = exports.PORT_FREE_WAIT_MS = exports.LENS_PROBE_TIMEOUT_MS = exports.LENS_PROBE_FAILS = exports.LENS_PROBE_GRACE_MS = exports.LENS_PROBE_ENABLED = exports.POD_STALE_RECYCLE_COOLDOWN_MS = exports.POD_STALE_SCAN_MS = exports.POD_RECYCLE_SETTLE_MS = exports.POD_STALE_GRACE_MS = exports.POD_MAX_AGE_MS = exports.POD_RECYCLE_ENABLED = exports.WEDGE_RECYCLE_GRACE_MS = exports.POD_RESPONSE_TIMEOUT_MS = exports.UPSTREAM_HEAL_STEP_MS = exports.UPSTREAM_HEAL_WINDOW_MS = exports.SERVICE_RESTART_WINDOW_MS = exports.SERVICE_MAX_RESTARTS = exports.SERVICE_ERROR_THROTTLE_MS = void 0;
4
4
  /** Parse a positive-integer env override; fall back to `def` on missing/NaN/negative. `allowZero` lets a
5
5
  * `0` through (used as a "disable" sentinel, e.g. {@link POD_MAX_AGE_MS}); otherwise `0` also falls back. */
6
6
  function envInt(name, def, allowZero = false) {
@@ -77,3 +77,58 @@ exports.POD_STALE_SCAN_MS = envInt('LENSMCP_POD_STALE_SCAN_MS', 30_000);
77
77
  /** Per-service cooldown between staleness recycles — stops a source-churn burst (codegen) thrash-recycling
78
78
  * the same pod. Override `LENSMCP_POD_STALE_RECYCLE_COOLDOWN_MS`. Default 60s. */
79
79
  exports.POD_STALE_RECYCLE_COOLDOWN_MS = envInt('LENSMCP_POD_STALE_RECYCLE_COOLDOWN_MS', 60_000);
80
+ /**
81
+ * LENS-CHILD LIVENESS PROBE (dev only). The FOURTH failure mode, and the one that wedges an app in a
82
+ * PERMANENT 502 with nothing in the log: a gateway-spawned vite that is ALIVE but NOT LISTENING. Child
83
+ * health was modelled ONLY as "has the process exited", so a vite whose HTTP listener closes/faults while
84
+ * its event loop stays held open (by the lensmcp plugin's WS server + the bridge connections) is INVISIBLE:
85
+ * `viteChildren` still holds it as live, no `lens child vite exited` line is ever logged, and the
86
+ * exit-driven auto-heal never fires. Worked failure (foodguard, 2026-07-29): two 43-minute-old vite children
87
+ * (pids 89518/89519) that had both printed `VITE ready in 1005 ms` + `Local: http://localhost:4200/`, yet
88
+ * `lsof -nP -p 89519` showed ZERO LISTEN sockets and `lsof -iTCP:4200 -sTCP:LISTEN` was empty —
89
+ * `https://app.foodguard.local` 502'd indefinitely until the pids were hand-killed (the exit handler then
90
+ * respawned them and the app returned 200 within 8s). So the sweeper now TCP-probes each live child's pinned
91
+ * port and SIGKILLs a confirmed wedge, letting the proven exit→auto-heal path do the rest.
92
+ */
93
+ /** Master switch for the liveness probe. Deliberately INDEPENDENT of {@link POD_RECYCLE_ENABLED}: a user who
94
+ * sets `LENSMCP_POD_RECYCLE=0` to stop staleness churn still wants a wedged 502 healed. Set
95
+ * `LENSMCP_LENS_PROBE=0` to disable. Default ON (dev). */
96
+ exports.LENS_PROBE_ENABLED = process.env['LENSMCP_LENS_PROBE'] !== '0';
97
+ /** Spawn grace: a child is never probed (and so never recycled) until it has had this long to BIND its port
98
+ * — a cold vite/nx boot in a big monorepo takes many seconds, and killing a still-booting dev server would
99
+ * be a self-inflicted outage. Override `LENSMCP_LENS_PROBE_GRACE_MS`. Default 45s. */
100
+ exports.LENS_PROBE_GRACE_MS = envInt('LENSMCP_LENS_PROBE_GRACE_MS', 45_000);
101
+ /** CONSECUTIVE probe failures required before a recycle — one blip (a momentary accept backlog, a laptop
102
+ * sleep-wake, a GC pause) must never recycle a healthy dev server. Floored at 2 by
103
+ * {@link lensChildWedged}. Override `LENSMCP_LENS_PROBE_FAILS`. Default 2. */
104
+ exports.LENS_PROBE_FAILS = envInt('LENSMCP_LENS_PROBE_FAILS', 2);
105
+ /** Per-probe TCP connect timeout. Short: a listening socket accepts a loopback connect in microseconds, so
106
+ * anything slower is indistinguishable from absent. Override `LENSMCP_LENS_PROBE_TIMEOUT_MS`. Default 1s. */
107
+ exports.LENS_PROBE_TIMEOUT_MS = envInt('LENSMCP_LENS_PROBE_TIMEOUT_MS', 1_000);
108
+ /**
109
+ * RESPAWN-INTO-A-HELD-PORT (the EADDRINUSE self-inflicted crash). The auto-heal respawned after a FIXED
110
+ * backoff while the previous child still held the pinned port — vite's `--strictPort` then exits code=1 on
111
+ * bind, burning a heal attempt and EXTENDING the 502 window. Observed in the gateway log:
112
+ * `Error: listen EADDRINUSE: address already in use 127.0.0.1:50059` immediately followed by
113
+ * `lens child vite exited (code=1 sig=null); auto-healing in 3s (attempt 2).` (3 such events in one log).
114
+ * Two fixes: WAIT for the port to become bindable before spawning, and classify a bind-race exit as
115
+ * RETRYABLE so it does not consume the crash-loop budget a real code fault does.
116
+ */
117
+ /** How long a respawn polls for its pinned port to become bindable before spawning anyway (past the budget
118
+ * the normal heal backoff takes over). Override `LENSMCP_PORT_FREE_WAIT_MS`. Default 10s. */
119
+ exports.PORT_FREE_WAIT_MS = envInt('LENSMCP_PORT_FREE_WAIT_MS', 10_000);
120
+ /** Poll interval while waiting for a port to free. Override `LENSMCP_PORT_FREE_POLL_MS`. Default 250ms. */
121
+ exports.PORT_FREE_POLL_MS = envInt('LENSMCP_PORT_FREE_POLL_MS', 250);
122
+ /** A non-zero exit sooner than this is a START failure (it never bound); later means the child RAN and so
123
+ * had the port, which cannot be a bind race. Override `LENSMCP_CHILD_START_FAIL_MS`. Default 10s. */
124
+ exports.CHILD_START_FAIL_MS = envInt('LENSMCP_CHILD_START_FAIL_MS', 10_000);
125
+ /** Ultimate backstop: after this many CONSECUTIVE bind-race exits for one label, stop forgiving them and
126
+ * fall back to the normal exponential backoff (so a permanently-squatted port can't 10s-loop forever).
127
+ * Override `LENSMCP_MAX_PORT_CONFLICT_RETRIES`. Default 5. */
128
+ exports.MAX_PORT_CONFLICT_RETRIES = envInt('LENSMCP_MAX_PORT_CONFLICT_RETRIES', 5);
129
+ /** Inbound keep-alive idle window for the front door. MUST exceed every client's pooled-socket idle timeout
130
+ * so the SERVER never closes a keep-alive socket a client is about to reuse — otherwise both sides race the
131
+ * same deadline and the truncated request surfaces as a spurious front-door `400` (see
132
+ * `classifyClientError`). Node's server default is 5s and a Node client agent's is ~5s, i.e. exactly tied.
133
+ * Override `LENSMCP_KEEPALIVE_TIMEOUT_MS`. Default 76s. */
134
+ exports.GATEWAY_KEEPALIVE_TIMEOUT_MS = envInt('LENSMCP_KEEPALIVE_TIMEOUT_MS', 76_000);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/cluster",
3
- "version": "1.16.31",
3
+ "version": "1.17.0",
4
4
  "description": "Run your Nx workspace as a local production cluster: pods on unix sockets with true HMR, one https gateway with per-project domains, scale-from-zero, autoscale, idle-kill, local-CA TLS — observed by the LensMCP lens.",
5
5
  "main": "./index.js",
6
6
  "types": "./index.d.ts",
@@ -65,8 +65,8 @@
65
65
  }
66
66
  },
67
67
  "dependencies": {
68
- "@lensmcp/node-instrumentation": "1.16.31",
69
- "@lensmcp/nx-plugin": "1.16.31",
68
+ "@lensmcp/node-instrumentation": "1.17.0",
69
+ "@lensmcp/nx-plugin": "1.17.0",
70
70
  "fork-ts-checker-webpack-plugin": "^9.0.0",
71
71
  "glob": "^11.0.0",
72
72
  "http-proxy": "^1.18.0",