@lensmcp/cluster 1.17.3 → 1.17.4

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.
@@ -13,7 +13,7 @@
13
13
  export { hostMatches } from './manifest';
14
14
  export { startGateway } from './runtime/server';
15
15
  export { verifyDevJwt, stampIdentity } from './runtime/dev-auth';
16
- export { baseDomainOf, readLensScope } from './runtime/scope';
16
+ export { baseDomainOf, deriveMcpHttpPort, readLensScope, type LensScope } from './runtime/scope';
17
17
  export { pickSock, discoverRoutes } from './runtime/discovery';
18
18
  export type { GatewayContext, ClusterProjectDecl, SockPool, Route, LensFrontend, ServiceCtl, GatewayRuntimeOptions, GatewayHandle, GatewayHooks, GatewayPhase, HookHandler, HookContext, } from './runtime/types';
19
19
  //# sourceMappingURL=gateway.lib.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gateway.lib.d.ts","sourceRoot":"","sources":["../../../../../libs/cluster/src/executors/gateway/gateway.lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE/D,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,QAAQ,EACR,KAAK,EACL,YAAY,EACZ,UAAU,EACV,qBAAqB,EACrB,aAAa,EAEb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,GACZ,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"gateway.lib.d.ts","sourceRoot":"","sources":["../../../../../libs/cluster/src/executors/gateway/gateway.lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE/D,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,QAAQ,EACR,KAAK,EACL,YAAY,EACZ,UAAU,EACV,qBAAqB,EACrB,aAAa,EAEb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,GACZ,MAAM,iBAAiB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.discoverRoutes = exports.pickSock = exports.readLensScope = exports.baseDomainOf = exports.stampIdentity = exports.verifyDevJwt = exports.startGateway = exports.hostMatches = void 0;
3
+ exports.discoverRoutes = exports.pickSock = exports.readLensScope = exports.deriveMcpHttpPort = exports.baseDomainOf = exports.stampIdentity = exports.verifyDevJwt = exports.startGateway = exports.hostMatches = void 0;
4
4
  /**
5
5
  * Public facade for the dev gateway runtime.
6
6
  *
@@ -22,6 +22,7 @@ Object.defineProperty(exports, "verifyDevJwt", { enumerable: true, get: function
22
22
  Object.defineProperty(exports, "stampIdentity", { enumerable: true, get: function () { return dev_auth_1.stampIdentity; } });
23
23
  var scope_1 = require("./runtime/scope");
24
24
  Object.defineProperty(exports, "baseDomainOf", { enumerable: true, get: function () { return scope_1.baseDomainOf; } });
25
+ Object.defineProperty(exports, "deriveMcpHttpPort", { enumerable: true, get: function () { return scope_1.deriveMcpHttpPort; } });
25
26
  Object.defineProperty(exports, "readLensScope", { enumerable: true, get: function () { return scope_1.readLensScope; } });
26
27
  var discovery_1 = require("./runtime/discovery");
27
28
  Object.defineProperty(exports, "pickSock", { enumerable: true, get: function () { return discovery_1.pickSock; } });
@@ -1 +1 @@
1
- {"version":3,"file":"lens-children.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/lens-children.ts"],"names":[],"mappings":"AASA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,kCAAkC,CAAC;AAI1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAuB,MAAM,SAAS,CAAC;AAiB1F,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA0B7E,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAalE;AAyBD;;;;;;mDAMmD;AACnD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAG1F;AAMD;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GAClF,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED;;;iFAGiF;AACjF,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAQvE;AAED,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,UAAU,CAAC;IAC9B;;gFAE4E;IAC5E,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC;;6GAEyG;IACzG,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IACvF;;yGAEqG;IACrG,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IACpE;gHAC4G;IAC5G,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,qBAAqB,EAE9B,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,GACzD,YAAY,CAmbd"}
1
+ {"version":3,"file":"lens-children.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/lens-children.ts"],"names":[],"mappings":"AASA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,kCAAkC,CAAC;AAI1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAuB,MAAM,SAAS,CAAC;AAiB1F,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA0B7E,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAalE;AAyBD;;;;;;mDAMmD;AACnD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAG1F;AAMD;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GAClF,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED;;;iFAGiF;AACjF,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAQvE;AAED,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,UAAU,CAAC;IAC9B;;gFAE4E;IAC5E,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC;;6GAEyG;IACzG,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;IACvF;;yGAEqG;IACrG,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;IACpE;gHAC4G;IAC5G,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAChC,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,qBAAqB,EAE9B,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,GACzD,YAAY,CA4bd"}
@@ -399,11 +399,20 @@ deps) {
399
399
  console.warn("[gateway] MCP server bundle not found — skipping (lens apps will still publish to the bus; an external `lensmcp mcp` can read it). Install: `npm i -D lensmcp`.");
400
400
  }
401
401
  else {
402
- console.log(`[gateway] starting lens MCP server (${mcpBundle})`);
402
+ // The workspace's OWN port, not a shared default. This used to be a
403
+ // hardcoded 3000 for EVERY workspace: with two gateways (or one daemon
404
+ // hosting two workspaces) whichever bound first served the other's
405
+ // sessions too — one project's agent reading another project's events.
406
+ // The port is also the contract the MCP shim resolves from
407
+ // `.lensmcp/config.json`, so it must not be stepped up on collision:
408
+ // a shim pointed at 4543 cannot find a server that quietly moved to 4544.
409
+ const scope = (0, scope_1.readLensScope)(rt.root);
410
+ const mcpPort = Number(process.env['LENSMCP_PORT'] ?? scope.mcpHttpPort);
411
+ console.log(`[gateway] starting lens MCP server on 127.0.0.1:${mcpPort} (${mcpBundle})`);
403
412
  spawnManagedChild('lens-mcp', process.execPath, [mcpBundle], {
404
413
  LENSMCP_EVENT_FILE: rt.eventFile,
405
414
  LENSMCP_TRANSPORT: process.env['LENSMCP_TRANSPORT'] ?? 'http',
406
- LENSMCP_PORT: process.env['LENSMCP_PORT'] ?? '3000',
415
+ LENSMCP_PORT: String(mcpPort),
407
416
  });
408
417
  }
409
418
  }
@@ -3,14 +3,26 @@
3
3
  * 'tetros.ai.local'] → 'tetros.ai.local'). Falls back to the first host, then
4
4
  * to 'lens.local' if no host is declared. */
5
5
  export declare function baseDomainOf(hosts: string[]): string;
6
- /** Per-workspace lens scope (key + dashboard port + mount path). Prefers the
7
- * CLI-written `.lensmcp/config.json` (so the gateway agrees with `lensmcp gateway`
8
- * / `lensmcp dashboard`); falls back to deriving from the workspace. */
9
- export declare function readLensScope(root: string): {
6
+ export interface LensScope {
10
7
  key: string;
11
8
  dashboardPort: number;
9
+ /**
10
+ * The MCP server's HTTP port for THIS workspace.
11
+ *
12
+ * This is the ISOLATION BOUNDARY for the shared MCP server. One daemon hosts
13
+ * several workspaces; if their MCP children shared a port, a session in one
14
+ * workspace would read the other's observability data. It used to be the
15
+ * hardcoded `3000` for every workspace — see `lens-children.ts`.
16
+ */
17
+ mcpHttpPort: number;
12
18
  basePath: string;
13
- };
19
+ }
20
+ /** Per-workspace lens scope (key + ports + mount path). Prefers the
21
+ * CLI-written `.lensmcp/config.json` (so the gateway agrees with `lensmcp gateway`
22
+ * / `lensmcp dashboard` / the MCP shim); falls back to deriving from the workspace. */
23
+ export declare function readLensScope(root: string): LensScope;
24
+ /** The workspace's MCP HTTP port, derived from its key. In lock-step with the CLI. */
25
+ export declare function deriveMcpHttpPort(key: string): number;
14
26
  /**
15
27
  * Per-workspace extra SOURCE-SET excludes (`.lensmcp/config.json` →
16
28
  * `sourceSet.exclude: string[]`) — top-level dir names the staleness scanner
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/scope.ts"],"names":[],"mappings":"AAOA;;;8CAG8C;AAC9C,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAUpD;AAED;;yEAEyE;AACzE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAmBpG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAa9D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQhD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ9C"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/scope.ts"],"names":[],"mappings":"AAOA;;;8CAG8C;AAC9C,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAUpD;AAeD,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;wFAEwF;AACxF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CA2BrD;AAED,sFAAsF;AACtF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAa9D;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQhD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ9C"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.baseDomainOf = baseDomainOf;
4
4
  exports.readLensScope = readLensScope;
5
+ exports.deriveMcpHttpPort = deriveMcpHttpPort;
5
6
  exports.readSourceSetExclude = readSourceSetExclude;
6
7
  exports.lensKeyFrom = lensKeyFrom;
7
8
  exports.lensSlug = lensSlug;
@@ -29,16 +30,30 @@ function baseDomainOf(hosts) {
29
30
  const parts = shortest.split('.');
30
31
  return parts.slice(-Math.min(parts.length, 3)).join('.');
31
32
  }
32
- /** Per-workspace lens scope (key + dashboard port + mount path). Prefers the
33
+ /** Lens-infra port bases must equal `BASE_PORTS` in the CLI's workspace-scope. */
34
+ const BASE_PORTS = { dashboard: 4321, mcpHttp: 4500 };
35
+ /** FNV-1a → 0..(range-1). Same derivation as the CLI's `hashToRange`. */
36
+ function hashToRange(s, range) {
37
+ let h = 0x811c9dc5;
38
+ for (let i = 0; i < s.length; i++) {
39
+ h ^= s.charCodeAt(i);
40
+ h = Math.imul(h, 0x01000193);
41
+ }
42
+ return Math.abs(h | 0) % range;
43
+ }
44
+ /** Per-workspace lens scope (key + ports + mount path). Prefers the
33
45
  * CLI-written `.lensmcp/config.json` (so the gateway agrees with `lensmcp gateway`
34
- * / `lensmcp dashboard`); falls back to deriving from the workspace. */
46
+ * / `lensmcp dashboard` / the MCP shim); falls back to deriving from the workspace. */
35
47
  function readLensScope(root) {
36
48
  try {
37
49
  const cfg = JSON.parse(fs.readFileSync(path.join(root, '.lensmcp', 'config.json'), 'utf8'));
38
50
  if (cfg && typeof cfg.key === 'string') {
39
51
  return {
40
52
  key: cfg.key,
41
- dashboardPort: cfg.ports?.dashboard ?? 4321,
53
+ dashboardPort: cfg.ports?.dashboard ?? BASE_PORTS.dashboard,
54
+ // Derive rather than fall back to a constant: a constant would put two
55
+ // config-less workspaces on ONE port, which is the cross-feed bug.
56
+ mcpHttpPort: cfg.ports?.mcpHttp ?? deriveMcpHttpPort(cfg.key),
42
57
  basePath: cfg.dashboardBasePath ?? '/' + cfg.key,
43
58
  };
44
59
  }
@@ -47,7 +62,16 @@ function readLensScope(root) {
47
62
  /* no config yet — derive below */
48
63
  }
49
64
  const key = lensKeyFrom(root);
50
- return { key, dashboardPort: 4321, basePath: '/' + key };
65
+ return {
66
+ key,
67
+ dashboardPort: BASE_PORTS.dashboard,
68
+ mcpHttpPort: deriveMcpHttpPort(key),
69
+ basePath: '/' + key,
70
+ };
71
+ }
72
+ /** The workspace's MCP HTTP port, derived from its key. In lock-step with the CLI. */
73
+ function deriveMcpHttpPort(key) {
74
+ return BASE_PORTS.mcpHttp + hashToRange(key, 200);
51
75
  }
52
76
  /**
53
77
  * Per-workspace extra SOURCE-SET excludes (`.lensmcp/config.json` →
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/cluster",
3
- "version": "1.17.3",
3
+ "version": "1.17.4",
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.17.3",
69
- "@lensmcp/nx-plugin": "1.17.3",
68
+ "@lensmcp/node-instrumentation": "1.17.4",
69
+ "@lensmcp/nx-plugin": "1.17.4",
70
70
  "@typescript/native-preview": "^7.0.0-dev.20260707.2",
71
71
  "fork-ts-checker-webpack-plugin": "^9.0.0",
72
72
  "glob": "^11.0.0",