@lensmcp/cluster 1.16.9 → 1.16.11

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.
@@ -156,6 +156,10 @@ export interface Route {
156
156
  prependPrefix?: string;
157
157
  internal?: boolean;
158
158
  default?: boolean;
159
+ /** For a host-less `default` catch-all: the apex (base domain) it belongs to — set when a shared
160
+ * multi-workspace gateway merges several workspaces' fragments, so an unclaimed host routes to the
161
+ * default of ITS apex, not another workspace's. Undefined = a truly-global catch-all. */
162
+ apex?: string;
159
163
  /** Direct TCP upstream (app/vite/prod-direct) — bypasses pod resolution. */
160
164
  upstream?: string;
161
165
  /** Resolved auth for the route root (overrides refine per-path at match). */
@@ -181,6 +185,7 @@ export declare function hostMatches(pattern: string, host: string): boolean;
181
185
  export declare function matchRoute<R extends {
182
186
  host?: string;
183
187
  prefix?: string;
188
+ apex?: string;
184
189
  }>(routes: readonly R[], host: string, url: string): R | undefined;
185
190
  /** Specificity sort: host+path beats host-only beats catch-all. Mutates+returns. */
186
191
  export declare function sortBySpecificity<R extends {
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../../../libs/cluster/src/executors/gateway/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../../../libs/cluster/src/executors/gateway/manifest.ts"],"names":[],"mappings":"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"}
@@ -81,11 +81,28 @@ function hostMatches(pattern, host) {
81
81
  */
82
82
  function matchRoute(routes, host, url) {
83
83
  const claimed = routes.some((r) => r.host && hostMatches(r.host, host));
84
- let candidates = claimed
85
- ? routes.filter((r) => r.host && hostMatches(r.host, host))
86
- : routes.filter((r) => !r.host);
87
- if (candidates.some((r) => r.host === host)) {
88
- candidates = candidates.filter((r) => r.host === host);
84
+ let candidates;
85
+ if (claimed) {
86
+ candidates = routes.filter((r) => r.host && hostMatches(r.host, host));
87
+ if (candidates.some((r) => r.host === host)) {
88
+ candidates = candidates.filter((r) => r.host === host);
89
+ }
90
+ }
91
+ else {
92
+ // UNCLAIMED host → the host-less default catch-all(s). ONE default (a single workspace) → today's
93
+ // behavior, apex ignored. MULTIPLE defaults (a shared multi-workspace gateway that merged several
94
+ // workspaces' fragments) → route by APEX: the default whose apex the request host belongs to, longest
95
+ // apex first; a foreign host matching no apex falls to an apex-less GLOBAL default (else nothing → 404).
96
+ const defaults = routes.filter((r) => !r.host);
97
+ if (defaults.length <= 1) {
98
+ candidates = defaults;
99
+ }
100
+ else {
101
+ const apexHit = defaults
102
+ .filter((r) => r.apex && (host === r.apex || host.endsWith('.' + r.apex)))
103
+ .sort((a, b) => b.apex.length - a.apex.length);
104
+ candidates = apexHit.length > 0 ? apexHit : defaults.filter((r) => !r.apex);
105
+ }
89
106
  }
90
107
  return candidates.find((r) => !r.prefix || url.startsWith(r.prefix));
91
108
  }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The multi-workspace LANDING page — served at `lensmcp.local/` (the dashboard host root, which otherwise
3
+ * 404s because the dashboard itself mounts at `/<key>`). It lists every workspace in the global registry
4
+ * (`workspace-registry.ts`), marks which are LIVE (their gateway process is alive) and which one is running
5
+ * HERE, and links each live one to its dashboard. The visible half of the shared multi-workspace gateway
6
+ * (planning/multi-workspace-gateway.md).
7
+ */
8
+ import type * as http from 'node:http';
9
+ import { type WorkspaceEntry } from './workspace-registry';
10
+ /** Render the chooser HTML from the registry entries (+ which key is running in THIS gateway). */
11
+ export declare function renderChooserPage(entries: WorkspaceEntry[], currentKey: string): string;
12
+ /** Serve the chooser at the dashboard-host root. Reads the registry fresh so live status is current. */
13
+ export declare function serveChooser(res: http.ServerResponse, currentKey: string): void;
14
+ //# sourceMappingURL=chooser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chooser.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/chooser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AACvC,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAK5F,kGAAkG;AAClG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAyEvF;AAED,wGAAwG;AACxG,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAI/E"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderChooserPage = renderChooserPage;
4
+ exports.serveChooser = serveChooser;
5
+ const workspace_registry_1 = require("./workspace-registry");
6
+ const esc = (s) => s.replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[c]);
7
+ /** Render the chooser HTML from the registry entries (+ which key is running in THIS gateway). */
8
+ function renderChooserPage(entries, currentKey) {
9
+ const rows = entries
10
+ .map((e) => ({ ...e, live: e.key === currentKey || (0, workspace_registry_1.isWorkspaceLive)(e) }))
11
+ .sort((a, b) => Number(b.live) - Number(a.live) || a.key.localeCompare(b.key));
12
+ const cards = rows.length === 0
13
+ ? `<p class="empty">No workspaces registered yet. Start a gateway in a workspace (<code>lensmcp gateway start</code>) and it will appear here.</p>`
14
+ : rows
15
+ .map((e) => {
16
+ const here = e.key === currentKey;
17
+ const badge = here
18
+ ? `<span class="badge here">running here</span>`
19
+ : e.live
20
+ ? `<span class="badge live">live</span>`
21
+ : `<span class="badge off">offline</span>`;
22
+ // The whole card is the anchor for a live workspace (no nested <a>); a `<div>` when offline.
23
+ const action = e.live
24
+ ? `<span class="open">Open dashboard →</span>`
25
+ : `<span class="hint">start its gateway to open</span>`;
26
+ const inner = `<div class="card-main">
27
+ <div class="key">${esc(e.key)} ${badge}</div>
28
+ <div class="root">${esc(e.root)}</div>
29
+ </div>
30
+ <div class="card-action">${action}</div>`;
31
+ return e.live
32
+ ? `<a class="card is-live" href="${esc(e.base)}/">\n ${inner}\n </a>`
33
+ : `<div class="card is-off">\n ${inner}\n </div>`;
34
+ })
35
+ .join('\n');
36
+ return `<!doctype html>
37
+ <html lang="en"><head>
38
+ <meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
39
+ <title>LensMCP · workspaces</title>
40
+ <style>
41
+ :root { color-scheme: dark; }
42
+ * { box-sizing: border-box; }
43
+ body { margin: 0; min-height: 100vh; font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
44
+ color: #e6e8ec; background: radial-gradient(1200px 600px at 50% -10%, #1b2233 0%, #0d1017 60%); padding: 48px 20px; }
45
+ .wrap { max-width: 640px; margin: 0 auto; }
46
+ header { margin-bottom: 28px; }
47
+ h1 { font-size: 22px; font-weight: 700; margin: 0 0 4px; letter-spacing: -0.01em; }
48
+ .sub { color: #8b93a3; font-size: 13.5px; margin: 0; }
49
+ .list { display: flex; flex-direction: column; gap: 10px; }
50
+ .card { display: flex; align-items: center; justify-content: space-between; gap: 16px; text-decoration: none; color: inherit;
51
+ padding: 16px 18px; border: 1px solid #232a3a; border-radius: 12px; background: #141926;
52
+ transition: transform .12s ease, border-color .12s ease, background .12s ease; }
53
+ .card.is-live:hover { border-color: #3355ff; background: #171d2e; transform: translateY(-1px); }
54
+ .card.is-off { opacity: .62; cursor: default; }
55
+ .key { font-weight: 650; font-size: 15.5px; display: flex; align-items: center; gap: 9px; }
56
+ .root { color: #79808f; font-size: 12.5px; margin-top: 3px; font-variant-numeric: tabular-nums; word-break: break-all; }
57
+ .badge { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; letter-spacing: .02em; }
58
+ .badge.here { background: rgba(51,85,255,.16); color: #8aa8ff; }
59
+ .badge.live { background: rgba(38,190,120,.15); color: #4fd699; }
60
+ .badge.off { background: rgba(139,147,163,.14); color: #9aa1b0; }
61
+ .card-action { flex-shrink: 0; }
62
+ .open { color: #8aa8ff; font-weight: 600; font-size: 13.5px; text-decoration: none; }
63
+ .hint { color: #6b7280; font-size: 12.5px; }
64
+ .empty { color: #8b93a3; }
65
+ code { background: #1c2333; padding: 1px 6px; border-radius: 5px; font-size: 12.5px; }
66
+ footer { margin-top: 24px; color: #5b6270; font-size: 12px; }
67
+ </style></head>
68
+ <body><div class="wrap">
69
+ <header>
70
+ <h1>LensMCP workspaces</h1>
71
+ <p class="sub">Pick a workspace to open its dashboard. ${rows.filter((r) => r.live).length} live · ${rows.length} known.</p>
72
+ </header>
73
+ <div class="list">
74
+ ${cards}
75
+ </div>
76
+ <footer>Served by the gateway on <code>lensmcp.local</code>. This list updates as gateways start and stop.</footer>
77
+ </div></body></html>`;
78
+ }
79
+ /** Serve the chooser at the dashboard-host root. Reads the registry fresh so live status is current. */
80
+ function serveChooser(res, currentKey) {
81
+ const html = renderChooserPage((0, workspace_registry_1.readWorkspaces)(), currentKey);
82
+ res.writeHead(200, { 'content-type': 'text/html; charset=utf-8', 'cache-control': 'no-store' });
83
+ res.end(html);
84
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/discovery.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAoC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE7F,uFAAuF;AACvF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,SAAO,GAAG,MAAM,GAAG,SAAS,CAa7E;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI1E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAC1C,WAAW,SAAc,EAIzB,KAAK,SAAK,GACT;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,QAAQ,EAAE,UAAU,EAAE,CAAA;CAAE,CA2D7C"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/discovery.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAoC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE7F,uFAAuF;AACvF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,SAAO,GAAG,MAAM,GAAG,SAAS,CAa7E;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI1E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAC1C,WAAW,SAAc,EAIzB,KAAK,SAAK,GACT;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,QAAQ,EAAE,UAAU,EAAE,CAAA;CAAE,CAkE7C"}
@@ -12,6 +12,7 @@ const fs = tslib_1.__importStar(require("node:fs"));
12
12
  const os = tslib_1.__importStar(require("node:os"));
13
13
  const path = tslib_1.__importStar(require("node:path"));
14
14
  const manifest_1 = require("../manifest");
15
+ const scope_1 = require("./scope");
15
16
  /** Round-robin over the pool's sockets, rescanning the dir when the cache ages out. */
16
17
  function pickSock(pool, scanTtlMs = 1500) {
17
18
  const now = Date.now();
@@ -51,6 +52,7 @@ wsKey = '') {
51
52
  const sockDirFor = (service) => wsKey ? path.join(sockBaseDir, wsKey, `${service}-devserver`) : path.join(sockBaseDir, `${service}-devserver`);
52
53
  const routes = [];
53
54
  const services = [];
55
+ const hosts = []; // every declared host — the default's apex is derived from these
54
56
  let defaultRoute;
55
57
  for (const [name, p] of Object.entries(projects)) {
56
58
  let decl;
@@ -94,6 +96,7 @@ wsKey = '') {
94
96
  const base = { project: name, prependPrefix: decl.prependPrefix, target, pool, svc, prefix: decl.path, auth: decl.auth, lens };
95
97
  if (decl.host) {
96
98
  routes.push({ ...base, host: decl.host });
99
+ hosts.push(decl.host);
97
100
  // internal.<host>: east-west traffic, same pods, NO middleware.
98
101
  if (pool && decl.internalHost !== false) {
99
102
  routes.push({
@@ -106,8 +109,12 @@ wsKey = '') {
106
109
  if (decl.default)
107
110
  defaultRoute = { ...base, prefix: undefined };
108
111
  }
109
- if (defaultRoute)
112
+ if (defaultRoute) {
113
+ // Stamp the apex so a shared multi-workspace gateway routes an unclaimed host to THIS workspace's
114
+ // default (see matchRoute). Harmless for a single workspace — one default ignores its apex.
115
+ defaultRoute.apex = (0, scope_1.baseDomainOf)(hosts);
110
116
  routes.push(defaultRoute);
117
+ }
111
118
  // specificity sort (shared with prod): host+path beats host-only beats
112
119
  // catch-all — so a path-mounted service (api.x/channels) wins over the
113
120
  // host's owner (api.x → api).
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import type * as http from 'node:http';
11
11
  import type { GatewayRuntime } from './types';
12
- import type { Observability } from './observability';
12
+ import { type Observability } from './observability';
13
13
  import type { EdgeAuth } from './auth';
14
14
  import type { ProxyLayer } from './proxy';
15
15
  import type { HooksLayer } from './hooks';
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAWvC,OAAO,KAAK,EAAE,cAAc,EAAW,MAAM,SAAS,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,cAAc,CAAC;IACnB,GAAG,EAAE,aAAa,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC,eAAe,CAoJrE"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAWvC,OAAO,KAAK,EAAE,cAAc,EAAW,MAAM,SAAS,CAAC;AACvD,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,cAAc,CAAC;IACnB,GAAG,EAAE,aAAa,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC,eAAe,CA6JrE"}
@@ -5,6 +5,8 @@ const manifest_1 = require("../manifest");
5
5
  const gateway_errors_1 = require("../gateway-errors");
6
6
  const discovery_1 = require("./discovery");
7
7
  const edge_1 = require("./edge");
8
+ const observability_1 = require("./observability");
9
+ const chooser_1 = require("./chooser");
8
10
  function createHandler(deps) {
9
11
  const { rt, obs, auth, proxy, hooks } = deps;
10
12
  const match = (req) => (0, manifest_1.matchRoute)(rt.routes, (req.headers.host || '').split(':')[0], req.url ?? '/');
@@ -27,6 +29,13 @@ function createHandler(deps) {
27
29
  const host = (req.headers.host || '').split(':')[0];
28
30
  const mounted = rt.routes.filter((r) => r.host && (0, manifest_1.hostMatches)(r.host, host) && r.prefix);
29
31
  const url = (req.url ?? '/').split('?')[0];
32
+ // The lens dashboard HOST ROOT → the multi-workspace chooser. The dashboard itself mounts at `/<key>`,
33
+ // so the bare `/` is unrouted and lands here; serve the landing page listing every known workspace.
34
+ if ((url === '/' || url === '/index.html' || url === '') &&
35
+ rt.routes.some((r) => r.host && (0, manifest_1.hostMatches)(r.host, host) && r.project === observability_1.LENS_DASHBOARD_PROJECT)) {
36
+ (0, chooser_1.serveChooser)(res, rt.wsKey);
37
+ return;
38
+ }
30
39
  if (mounted.length > 0 && (url === '/health' || url === '/healthz')) {
31
40
  const services = mounted.map((r) => ({
32
41
  project: r.project,
@@ -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,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,wDAAwD;IACxD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,qBAAqB,GAAG,YAAY,CAiKvH"}
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;AAI1C,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,wDAAwD;IACxD,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,qBAAqB,GAAG,YAAY,CAoKvH"}
@@ -11,6 +11,7 @@ const node_child_process_1 = require("node:child_process");
11
11
  const manifest_1 = require("../manifest");
12
12
  const lens_frontend_1 = require("@lensmcp/nx-plugin/lens-frontend");
13
13
  const scope_1 = require("./scope");
14
+ const workspace_registry_1 = require("./workspace-registry");
14
15
  const lifecycle_1 = require("./lifecycle");
15
16
  const types_1 = require("./types");
16
17
  const observability_1 = require("./observability");
@@ -121,6 +122,9 @@ function createLensChildren(rt, obs, options) {
121
122
  // auto-joins the TLS SANs. Run `gateway:trust` to add it to /etc/hosts.
122
123
  rt.routes.push({ host: lensHost, prefix: lensBase, project: observability_1.LENS_DASHBOARD_PROJECT, target: `http://localhost:${dashboardPort}` });
123
124
  (0, manifest_1.sortBySpecificity)(rt.routes);
125
+ // Publish this workspace to the GLOBAL registry so the root chooser at `${lensHost}/` lists it
126
+ // (and marks it live while this gateway runs). Best-effort — a registry write never blocks serving.
127
+ (0, workspace_registry_1.registerWorkspace)({ key: scope.key, root: rt.root, base: lensBase, pid: process.pid, updatedAt: new Date().toISOString() });
124
128
  console.log(`[gateway] starting lens dashboard → http://localhost:${dashboardPort} (routed at https://${lensHost}${lensBase}/)`);
125
129
  emit('info', `lens dashboard up: ${lensHost}${lensBase} → :${dashboardPort}`, 'cluster-lens-dashboard', { kind: 'lens-dashboard-up', host: lensHost, port: dashboardPort, base: lensBase });
126
130
  spawnManagedChild('lens-dashboard', process.execPath, [dashboardBundle], {
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/server.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAkB,qBAAqB,EAAsB,MAAM,SAAS,CAAC;AAkDxH,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAgLxB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/server.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAkB,qBAAqB,EAAsB,MAAM,SAAS,CAAC;AAkDxH,wBAAsB,YAAY,CAChC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,CAAC,CAiLxB"}
@@ -16,6 +16,7 @@ const http = tslib_1.__importStar(require("node:http"));
16
16
  const path = tslib_1.__importStar(require("node:path"));
17
17
  const discovery_1 = require("./discovery");
18
18
  const scope_1 = require("./scope");
19
+ const workspace_registry_1 = require("./workspace-registry");
19
20
  const service_keys_1 = require("./service-keys");
20
21
  const observability_1 = require("./observability");
21
22
  const lifecycle_1 = require("./lifecycle");
@@ -234,6 +235,7 @@ async function startGateway(options, context) {
234
235
  clearInterval(sweeper);
235
236
  obs.emit('info', 'gateway down', 'cluster-gateway', { kind: 'gateway-down' });
236
237
  jwtVerifier?.stop(); // clear the JWKS periodic-refresh timer
238
+ (0, workspace_registry_1.unregisterWorkspace)(wsKey); // drop this workspace from the global chooser registry (graceful stop)
237
239
  for (const svc of services)
238
240
  svcLayer.killSpawned(svc, 'gateway shutdown');
239
241
  // Reap the lens-mode managed children (dashboard + MCP singletons + each
@@ -81,6 +81,9 @@ export interface SockPool {
81
81
  export interface Route {
82
82
  host?: string;
83
83
  prefix?: string;
84
+ /** For a host-less `default` catch-all: the apex it belongs to — so a shared multi-workspace gateway
85
+ * routes an unclaimed host to ITS workspace's default, not another's. Read by `matchRoute`. */
86
+ apex?: string;
84
87
  project: string;
85
88
  prependPrefix?: string;
86
89
  target?: string;
@@ -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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"}
@@ -0,0 +1,22 @@
1
+ export interface WorkspaceEntry {
2
+ /** The workspace key (`readLensScope(root).key`) — the `/<key>` the dashboard mounts at. */
3
+ key: string;
4
+ /** Absolute workspace root. */
5
+ root: string;
6
+ /** The dashboard base path under `lensmcp.local` (e.g. `/tetros`). */
7
+ base: string;
8
+ /** The gateway process that registered this workspace (owns :443 for it). Liveness is checked via this. */
9
+ pid: number;
10
+ /** ISO timestamp of the last register. */
11
+ updatedAt: string;
12
+ }
13
+ /** `~/.lensmcp/workspaces.json` — override the home dir via `LENSMCP_HOME` (tests). */
14
+ export declare function registryPath(): string;
15
+ export declare function readWorkspaces(file?: string): WorkspaceEntry[];
16
+ /** Upsert this workspace (keyed by `key`) — called on gateway start. */
17
+ export declare function registerWorkspace(entry: WorkspaceEntry, file?: string): void;
18
+ /** Drop this workspace — called on a graceful gateway stop. */
19
+ export declare function unregisterWorkspace(key: string, file?: string): void;
20
+ /** Is the gateway that registered this workspace still alive? `process.kill(pid, 0)` throws ESRCH if not. */
21
+ export declare function isWorkspaceLive(entry: Pick<WorkspaceEntry, 'pid'>): boolean;
22
+ //# sourceMappingURL=workspace-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-registry.d.ts","sourceRoot":"","sources":["../../../../../../libs/cluster/src/executors/gateway/runtime/workspace-registry.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,cAAc;IAC7B,4FAA4F;IAC5F,GAAG,EAAE,MAAM,CAAC;IACZ,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,2GAA2G;IAC3G,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,uFAAuF;AACvF,wBAAgB,YAAY,IAAI,MAAM,CAGrC;AAED,wBAAgB,cAAc,CAAC,IAAI,SAAiB,GAAG,cAAc,EAAE,CAYtE;AAWD,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,SAAiB,GAAG,IAAI,CAKpF;AAED,+DAA+D;AAC/D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAiB,GAAG,IAAI,CAK5E;AAED,6GAA6G;AAC7G,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,CAAC,GAAG,OAAO,CAQ3E"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registryPath = registryPath;
4
+ exports.readWorkspaces = readWorkspaces;
5
+ exports.registerWorkspace = registerWorkspace;
6
+ exports.unregisterWorkspace = unregisterWorkspace;
7
+ exports.isWorkspaceLive = isWorkspaceLive;
8
+ const tslib_1 = require("tslib");
9
+ /**
10
+ * The GLOBAL workspace registry — `~/.lensmcp/workspaces.json`. Each gateway upserts its own workspace
11
+ * on start and drops it on a graceful stop, so the shared landing page at `lensmcp.local/` can list EVERY
12
+ * workspace LensMCP knows about (not just the one whose gateway currently owns :443). It's the persistence
13
+ * seam the multi-workspace daemon (planning/multi-workspace-gateway.md) builds on: today it powers the
14
+ * root chooser; the daemon will read the same file to decide which workspaces to host.
15
+ *
16
+ * Concurrency: read-modify-write, best-effort. Writes are rare (start/stop only) and the file is tiny, so
17
+ * a lost update at most drops one entry from the listing until the next start — never a correctness issue.
18
+ */
19
+ const fs = tslib_1.__importStar(require("node:fs"));
20
+ const os = tslib_1.__importStar(require("node:os"));
21
+ const path = tslib_1.__importStar(require("node:path"));
22
+ /** `~/.lensmcp/workspaces.json` — override the home dir via `LENSMCP_HOME` (tests). */
23
+ function registryPath() {
24
+ const home = process.env['LENSMCP_HOME'] || os.homedir();
25
+ return path.join(home, '.lensmcp', 'workspaces.json');
26
+ }
27
+ function readWorkspaces(file = registryPath()) {
28
+ try {
29
+ const raw = JSON.parse(fs.readFileSync(file, 'utf8'));
30
+ if (!Array.isArray(raw))
31
+ return [];
32
+ // tolerate partial/corrupt entries — keep only well-formed ones.
33
+ return raw.filter((e) => !!e && typeof e.key === 'string' && typeof e.base === 'string');
34
+ }
35
+ catch {
36
+ return [];
37
+ }
38
+ }
39
+ function writeWorkspaces(list, file = registryPath()) {
40
+ try {
41
+ fs.mkdirSync(path.dirname(file), { recursive: true });
42
+ fs.writeFileSync(file, JSON.stringify(list, null, 2));
43
+ }
44
+ catch {
45
+ /* best-effort — a read-only home or a race must never crash the gateway */
46
+ }
47
+ }
48
+ /** Upsert this workspace (keyed by `key`) — called on gateway start. */
49
+ function registerWorkspace(entry, file = registryPath()) {
50
+ const list = readWorkspaces(file).filter((e) => e.key !== entry.key);
51
+ list.push(entry);
52
+ list.sort((a, b) => a.key.localeCompare(b.key));
53
+ writeWorkspaces(list, file);
54
+ }
55
+ /** Drop this workspace — called on a graceful gateway stop. */
56
+ function unregisterWorkspace(key, file = registryPath()) {
57
+ writeWorkspaces(readWorkspaces(file).filter((e) => e.key !== key), file);
58
+ }
59
+ /** Is the gateway that registered this workspace still alive? `process.kill(pid, 0)` throws ESRCH if not. */
60
+ function isWorkspaceLive(entry) {
61
+ if (!entry.pid || entry.pid <= 0)
62
+ return false;
63
+ try {
64
+ process.kill(entry.pid, 0);
65
+ return true; // alive (or EPERM below — exists but not ours)
66
+ }
67
+ catch (e) {
68
+ return e.code === 'EPERM'; // EPERM = exists but not signalable; ESRCH = gone
69
+ }
70
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/cluster",
3
- "version": "1.16.9",
3
+ "version": "1.16.11",
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.9",
69
- "@lensmcp/nx-plugin": "1.16.9",
68
+ "@lensmcp/node-instrumentation": "1.16.11",
69
+ "@lensmcp/nx-plugin": "1.16.11",
70
70
  "fork-ts-checker-webpack-plugin": "^9.0.0",
71
71
  "glob": "^11.0.0",
72
72
  "http-proxy": "^1.18.0",