@lensmcp/cluster 1.16.13 → 1.16.14

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.
@@ -1 +1 @@
1
- {"version":3,"file":"basic-ssl.d.ts","sourceRoot":"","sources":["../../../libs/cluster/src/basic-ssl.ts"],"names":[],"mappings":"AA6BA,eAAO,MAAM,YAAY,yBAAyB,CAAC;AAKnD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,SAAgB,EAAE,OAAO,GAAE,MAAM,EAAO,GAAG,MAAM,CAoCzG;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMrD"}
1
+ {"version":3,"file":"basic-ssl.d.ts","sourceRoot":"","sources":["../../../libs/cluster/src/basic-ssl.ts"],"names":[],"mappings":"AA6BA,eAAO,MAAM,YAAY,yBAAyB,CAAC;AAKnD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,SAAgB,EAAE,OAAO,GAAE,MAAM,EAAO,GAAG,MAAM,CA0CzG;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMrD"}
package/basic-ssl.js CHANGED
@@ -35,6 +35,15 @@ exports.CA_CERT_FILE = 'lensmcp-local-ca.crt';
35
35
  const LEGACY_CA_CERT_FILE = 'davnx-local-ca.crt';
36
36
  const CA_KEY_FILE = '_ca-key.pem';
37
37
  function getCertificateSync(cacheDir, name = 'lensmcp.dev', domains = []) {
38
+ // Resolve the CA FIRST: loadOrCreateCa mints a fresh CA (and sweeps every OLD-CA leaf) whenever the CA
39
+ // cert is missing/expired — e.g. after a rebrand renamed the CA file. Doing this BEFORE the leaf-cache read
40
+ // is what makes a CA change actually take effect: otherwise a stale, old-CA-signed leaf short-circuits the
41
+ // mint and the rebrand never applies (the bug that needed a manual cache clear). On a normal run the CA is
42
+ // unchanged, nothing is swept, and the SAN-keyed leaf cache below still fast-paths.
43
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
44
+ const forge = require('node-forge');
45
+ fs.mkdirSync(cacheDir, { recursive: true });
46
+ const ca = loadOrCreateCa(cacheDir, forge);
38
47
  // The SAN set is part of the cache key: adding a gateway hostname must
39
48
  // mint a fresh leaf, not serve a cached one that lacks the new SAN.
40
49
  const sanKey = crypto
@@ -46,16 +55,12 @@ function getCertificateSync(cacheDir, name = 'lensmcp.dev', domains = []) {
46
55
  try {
47
56
  const stat = fs.statSync(leafPath);
48
57
  if (Date.now() - stat.ctimeMs < LEAF_MAX_AGE_MS) {
49
- return fs.readFileSync(leafPath, 'utf8');
58
+ return fs.readFileSync(leafPath, 'utf8'); // reached only when the CA was NOT just re-minted (a mint sweeps leaves)
50
59
  }
51
60
  }
52
61
  catch {
53
62
  /* no cache yet */
54
63
  }
55
- // eslint-disable-next-line @typescript-eslint/no-require-imports
56
- const forge = require('node-forge');
57
- fs.mkdirSync(cacheDir, { recursive: true });
58
- const ca = loadOrCreateCa(cacheDir, forge);
59
64
  const pem = createLeafCertificate(forge, ca, name, domains);
60
65
  fs.writeFileSync(leafPath, pem);
61
66
  // Stale leaves and the pre-1.3.4 self-signed cache just rot here — sweep
@@ -1 +1 @@
1
- {"version":3,"file":"lens-children.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/lens-children.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAgB,MAAM,SAAS,CAAC;AAQnF,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAM7E,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,UAAU,CAAC;IAC9B;iFAC6E;IAC7E,qBAAqB,IAAI,IAAI,CAAC;IAC9B;;6GAEyG;IACzG,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9E,wDAAwD;IACxD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,qBAAqB,GAAG,YAAY,CA8MvH"}
1
+ {"version":3,"file":"lens-children.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/lens-children.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAgB,MAAM,SAAS,CAAC;AAQnF,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAM7E,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,UAAU,CAAC;IAC9B;iFAC6E;IAC7E,qBAAqB,IAAI,IAAI,CAAC;IAC9B;;6GAEyG;IACzG,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAC9E,wDAAwD;IACxD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,qBAAqB,GAAG,YAAY,CAkNvH"}
@@ -206,6 +206,9 @@ function createLensChildren(rt, obs, options) {
206
206
  const eventFile = path.join(fragment.root, '.lensmcp', 'events.jsonl'); // the registered workspace's OWN bus
207
207
  removedLabels.delete(label); // a fresh registration after a prior unregister → allow auto-heal again
208
208
  rt.registry.appendRoutes(fragment.wsKey, [{ host: lensHost, prefix: lensBase, project: observability_1.LENS_DASHBOARD_PROJECT, target: `http://localhost:${port}` }]);
209
+ // Publish the hosted workspace to the GLOBAL chooser registry (keyed on the DAEMON's pid — the daemon is
210
+ // what keeps it live), so `lensmcp.local/` lists it. Reaped on unregister below.
211
+ (0, workspace_registry_1.registerWorkspace)({ key: fragment.wsKey, root: fragment.root, base: lensBase, pid: process.pid, updatedAt: new Date().toISOString() });
209
212
  console.log(`[gateway] hosting dashboard for workspace '${fragment.wsKey}' → http://localhost:${port} (routed at https://${lensHost}${lensBase}/)`);
210
213
  emit('info', `lens dashboard up: ${lensHost}${lensBase} → :${port}`, 'cluster-lens-dashboard', { kind: 'lens-dashboard-up', host: lensHost, port, base: lensBase });
211
214
  spawnManagedChild(label, process.execPath, [bundle], {
@@ -216,6 +219,7 @@ function createLensChildren(rt, obs, options) {
216
219
  return () => {
217
220
  removedLabels.add(label); // stop auto-heal from resurrecting it
218
221
  usedDashboardPorts.delete(port);
222
+ (0, workspace_registry_1.unregisterWorkspace)(fragment.wsKey); // drop it from the chooser registry
219
223
  try {
220
224
  labeledChildren.get(label)?.kill('SIGTERM');
221
225
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/lifecycle.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAapE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA4CrD;;sGAEsG;AACtG,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBtE;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,oBAAoB,CAAC,EACpG,GAAG,EAAE,MAAM,EACX,kBAAkB,EAAE,MAAM,EAC1B,GAAG,EAAE,gBAAgB,GACpB,kBAAkB,GAAG,SAAS,GAAG,IAAI,CAQvC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,MAAM,EAC1B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC7D,OAAO,CAMT;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAChC,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,2EAA2E;IAC3E,YAAY,IAAI,MAAM,CAAC,OAAO,CAAC;CAChC;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,GAAG,YAAY,CA+PvF"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/lifecycle.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAapE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA4CrD;;sGAEsG;AACtG,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBtE;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,oBAAoB,CAAC,EACpG,GAAG,EAAE,MAAM,EACX,kBAAkB,EAAE,MAAM,EAC1B,GAAG,EAAE,gBAAgB,GACpB,kBAAkB,GAAG,SAAS,GAAG,IAAI,CAQvC;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,MAAM,EAC1B,GAAG,EAAE,MAAM,EACX,GAAG,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAC7D,OAAO,CAMT;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAChC,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,WAAW,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,2EAA2E;IAC3E,YAAY,IAAI,MAAM,CAAC,OAAO,CAAC;CAChC;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,GAAG,YAAY,CAwQvF"}
@@ -166,7 +166,16 @@ function createServiceLayer(rt, obs) {
166
166
  // means env vars DO reach the pod, so the east-west key + CA propagate.
167
167
  // LENSMCP_WS_KEY (the SERVICE's owning workspace) namespaces its pod sock dir
168
168
  // ($TMPDIR/<wsKey>/<service>-devserver) — the namespaced pool the daemon scans for this fragment.
169
- env: { ...process.env, NX_DAEMON: 'false', ...(svc.wsKey ? { LENSMCP_WS_KEY: svc.wsKey } : {}), ...eastWestEnv(rt, svc.project) },
169
+ // LENSMCP_EVENT_FILE points a REGISTERED workspace's pods at ITS OWN bus (<root>/.lensmcp/events.jsonl),
170
+ // so its dashboard shows its live traces, not the daemon's. The daemon's own services keep rt.eventFile
171
+ // exactly (svc.root === rt.root), so single-workspace behavior is unchanged.
172
+ env: {
173
+ ...process.env,
174
+ NX_DAEMON: 'false',
175
+ ...(svc.wsKey ? { LENSMCP_WS_KEY: svc.wsKey } : {}),
176
+ LENSMCP_EVENT_FILE: svc.wsKey === rt.wsKey ? rt.eventFile : path.join(svc.root, '.lensmcp', 'events.jsonl'),
177
+ ...eastWestEnv(rt, svc.project),
178
+ },
170
179
  stdio: ['ignore', 'pipe', 'pipe'],
171
180
  });
172
181
  svc.lastErrors = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/cluster",
3
- "version": "1.16.13",
3
+ "version": "1.16.14",
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.13",
69
- "@lensmcp/nx-plugin": "1.16.13",
68
+ "@lensmcp/node-instrumentation": "1.16.14",
69
+ "@lensmcp/nx-plugin": "1.16.14",
70
70
  "fork-ts-checker-webpack-plugin": "^9.0.0",
71
71
  "glob": "^11.0.0",
72
72
  "http-proxy": "^1.18.0",