@lensmcp/cluster 1.19.0 → 1.20.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.
- package/basic-ssl.js +1 -1
- package/build-scope-patterns.js +1 -1
- package/create-webpack-dev.js +1 -1
- package/create-webpack-prod.js +1 -1
- package/executors/build/build.impl.js +1 -1
- package/executors/gateway/gateway-errors.d.ts +2 -2
- package/executors/gateway/gateway-errors.js +1 -1
- package/executors/gateway/gateway.impl.js +1 -1
- package/executors/gateway/gateway.lib.d.ts +1 -1
- package/executors/gateway/gateway.lib.js +1 -1
- package/executors/gateway/health-check.js +1 -1
- package/executors/gateway/jwks-verify.js +1 -1
- package/executors/gateway/main.prod-gateway.js +2 -2
- package/executors/gateway/main.rollout.js +4 -4
- package/executors/gateway/manifest.js +1 -1
- package/executors/gateway/metrics.js +1 -1
- package/executors/gateway/otel-tracing.js +1 -1
- package/executors/gateway/prod-gateway.lib.js +1 -1
- package/executors/gateway/prod-runtime/access-log.js +1 -1
- package/executors/gateway/prod-runtime/app.js +1 -1
- package/executors/gateway/prod-runtime/auth.js +1 -1
- package/executors/gateway/prod-runtime/cors.js +1 -1
- package/executors/gateway/prod-runtime/edge.js +1 -1
- package/executors/gateway/prod-runtime/handler.js +1 -1
- package/executors/gateway/prod-runtime/hooks.js +1 -1
- package/executors/gateway/prod-runtime/observability.js +1 -1
- package/executors/gateway/prod-runtime/rollout.js +1 -1
- package/executors/gateway/prod-runtime/routing.js +1 -1
- package/executors/gateway/prod-runtime/server.js +1 -1
- package/executors/gateway/prod-runtime/trust.js +1 -1
- package/executors/gateway/prod-runtime/upgrade.js +2 -2
- package/executors/gateway/prod-runtime/upstream.js +1 -1
- package/executors/gateway/providers-prod.js +1 -1
- package/executors/gateway/rate-limit.js +2 -2
- package/executors/gateway/registry-source.js +1 -1
- package/executors/gateway/rollout-ops.js +2 -2
- package/executors/gateway/runtime/auth.js +1 -1
- package/executors/gateway/runtime/chooser.js +7 -7
- package/executors/gateway/runtime/control.js +1 -1
- package/executors/gateway/runtime/dev-auth.js +1 -1
- package/executors/gateway/runtime/discovery.d.ts +5 -1
- package/executors/gateway/runtime/discovery.js +1 -1
- package/executors/gateway/runtime/edge.d.ts +1 -1
- package/executors/gateway/runtime/edge.js +1 -1
- package/executors/gateway/runtime/handler.js +1 -1
- package/executors/gateway/runtime/hmr-reload.d.ts +2 -2
- package/executors/gateway/runtime/hmr-reload.js +1 -1
- package/executors/gateway/runtime/hooks.js +1 -1
- package/executors/gateway/runtime/lens-children.d.ts +3 -7
- package/executors/gateway/runtime/lens-children.js +1 -1
- package/executors/gateway/runtime/lifecycle.d.ts +11 -3
- package/executors/gateway/runtime/lifecycle.js +3 -3
- package/executors/gateway/runtime/observability.js +2 -2
- package/executors/gateway/runtime/pod-env.js +2 -2
- package/executors/gateway/runtime/proxy.js +1 -1
- package/executors/gateway/runtime/route-registry.js +1 -1
- package/executors/gateway/runtime/scope.js +1 -1
- package/executors/gateway/runtime/server.js +2 -2
- package/executors/gateway/runtime/service-keys.js +1 -1
- package/executors/gateway/runtime/types.d.ts +57 -1
- package/executors/gateway/runtime/types.js +1 -1
- package/executors/gateway/runtime/upgrade.js +1 -1
- package/executors/gateway/runtime/workspace-registry.js +1 -1
- package/executors/gateway/ssrf-guard.js +1 -1
- package/executors/serve/serve.impl.js +1 -1
- package/executors/trust/trust.impl.js +3 -3
- package/gateway.js +1 -1
- package/index.js +1 -1
- package/main.devserver.js +5 -5
- package/package.json +4 -4
- package/tsgo-check-plugin.js +4 -4
- package/typecheck-bus.js +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var X=Object.defineProperty;var l=(e,t)=>X(e,"name",{value:t,configurable:!0});var Y=Object.defineProperty,a=l((e,t)=>Y(e,"name",{value:t,configurable:!0}),"a"),J=Object.defineProperty,c=a((e,t)=>J(e,"name",{value:t,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0});const tslib_1=require("tslib"),path=tslib_1.__importStar(require("node:path")),fs=tslib_1.__importStar(require("node:fs")),node_child_process_1=require("node:child_process"),yaml=tslib_1.__importStar(require("js-yaml")),create_webpack_dev_1=require("../../create-webpack-dev"),webpack=require("webpack");async function*serveExecutor(e,t){process.env.NODE_ENV="development";const L=t.projectsConfigurations.projects[t.projectName],n=t.root,g=path.join(n,L.root),k=e.outputPath?path.join(n,e.outputPath):path.join(n,"dist",L.root),O=e.configEnv||"development",_=path.join(n,"config",`config.${O}.yaml`),y=3050;let i=y,p=t.projectName,h={};fs.existsSync(_)?(h=yaml.load(fs.readFileSync(_,"utf8")),i=Number(h.port)||i,p=h.serviceName||p):console.warn(`[serve] ${t.projectName}: no config file at ${_} \u2014 public devserver port defaults to ${y}. If another service also lacks its config, both bind ${y} \u2192 EADDRINUSE. Add config/config.${O}.yaml with a distinct \`port:\` (matching this project's cluster.port).`),e.serviceName&&(p=e.serviceName);const b=e.servePrefix??"",m=e.debugPort??(Number(process.env.LENSMCP_DEBUG_PORT)||void 0),u=e.logFile?path.resolve(n,e.logFile):process.env.LENSMCP_LOG_FILE||void 0;u&&(fs.mkdirSync(path.dirname(u),{recursive:!0}),fs.writeFileSync(u,""));let N,P;e.gateway?.middleware&&(N=path.resolve(g,e.gateway.middleware),P=JSON.stringify(h));const $=e.entryFile||"./src/deployments/service/main.ts",F=e.tsConfigFile||"./tsconfig.app.json",G=path.resolve(g,$),M=path.resolve(g,F),W=(e.workers||[]).map(r=>({entryName:r.name,entryPath:path.resolve(g,r.entryPath)})),R=(0,create_webpack_dev_1.createDevWebpackConfig)({appName:t.projectName,appRoot:g,outputDir:k,main:G,tsConfig:M,assets:e.assets||[],additionalEntryPoints:W,port:i,serviceName:p,memoryLimit:e.memoryLimit||8192,buildLibsFromSource:e.buildLibsFromSource!==!1,workspaceRoot:n,orgScopes:e.orgScopes||[],bundlePackages:e.bundlePackages||[],nodeExternalsConfig:e.nodeExternalsConfig,webpackConfigPath:e.webpackConfigPath,httpsReload:e.gateway?.https===!0});let s=null,w=!1;const x=path.join(__dirname,"../../main.devserver.js"),D=path.join(__dirname,"../../main.devserver.ts"),I=!fs.existsSync(x)&&fs.existsSync(D),T=I?D:x,U=path.join(k,"main.js");function d(){s&&!s.killed&&(s.kill("SIGTERM"),s=null)}l(d,"v"),a(d,"f"),c(d,"cleanup");const q=["SIGINT","SIGTERM","SIGHUP","SIGQUIT"].map(r=>{const o=c(()=>d(),"handler");return process.on(r,o),{sig:r,handler:o}});process.on("exit",d);function v(){if(!fs.existsSync(T)){console.error(`[serve] devserver script not found at ${T}`);return}const r=["--enable-source-maps"];I&&r.unshift("--require","@swc-node/register"),s=(0,node_child_process_1.fork)(T,{cwd:n,env:{...process.env,PORT:String(i),SERVICE_NAME:p,SERVE_PREFIX:b,LENSMCP_PROJECT:process.env.LENSMCP_PROJECT||t.projectName||p,LENSMCP_EVENT_FILE:process.env.LENSMCP_EVENT_FILE||path.join(n,".lensmcp","events.jsonl"),CHILD_COUNT:String(e.childCount||process.env.CHILD_COUNT||1),BUNDLE_PATH:U,...N&&{GATEWAY_MIDDLEWARE:N},...P&&{GATEWAY_CONFIG:P},...e.gateway?.routes?.length&&{GATEWAY_ROUTES:JSON.stringify(e.gateway.routes)},...e.gateway?.https&&{GATEWAY_HTTPS:"1"},...e.gateway?.extraPorts?.length&&{GATEWAY_EXTRA_PORTS:JSON.stringify(e.gateway.extraPorts)},...e.internalPort&&{INTERNAL_PORT:String(e.internalPort)},...m&&{LENSMCP_DEBUG_PORT:String(m)},...u&&{LENSMCP_LOG_FILE:u},...e.workers?.length&&{WORKERS:JSON.stringify(e.workers.map(o=>o.name))}},stdio:["inherit","inherit","inherit","ipc"],execArgv:r}),s.on("exit",(o,S)=>{s=null,!S&&(console.error(`[serve] devserver exited unexpectedly (code=${o}, signal=${S}) \u2014 respawning in 1.5s`),setTimeout(()=>{!s&&w&&v()},1500).unref?.())}),console.log(`[serve] Devserver started on port ${i} (service: ${p}${b?`, prefix: /${b}`:""})`),console.log(m?`[serve] Debug: pod inspectors on 127.0.0.1:${m}+ \u2014 click the "Debugger listening" link in the console, or attach WebStorm (Attach to Node.js/Chrome) to port ${m}`:`[serve] Debug on demand: POST http://localhost:${i}/webpack/debug (optionally ?port=<base>) opens pod inspectors without a restart`),u&&console.log(`[serve] Logs teed to ${u} \u2014 tail it in WebStorm via Run/Debug configuration \u2192 Logs tab`)}l(v,"g"),a(v,"v"),c(v,"startDevServer");function A(){if(!s||s.killed){console.log("[serve] Devserver not running, restarting..."),v();return}fetch(`http://localhost:${i}/webpack/reload`,{method:"POST",headers:{"content-type":"application/json"},body:"{}"}).then(()=>console.log("[serve] Notified devserver to reload")).catch(r=>{console.warn("[serve] Failed to notify devserver, restarting...",r.message),d(),v()})}l(A,"U"),a(A,"B"),c(A,"_notifyDevServerReload");const{watch:K,...H}=R,V=webpack(H);let E=null;const j=[];function f(r){if(E){const o=E;E=null,o(r)}else j.push(r)}l(f,"h"),a(f,"b"),c(f,"pushResult");function C(){return j.length>0?Promise.resolve(j.shift()):new Promise(r=>{E=r})}l(C,"D"),a(C,"W"),c(C,"waitForNext");const B=V.watch(R.watchOptions||{},(r,o)=>{if(r){console.error("[serve] Webpack error:",r),f({success:!1});return}const S=o.hasErrors();if(console.info(o.toString({colors:!0,chunks:!1,assets:!0})),S){f({success:!1});return}(!w||!s)&&(w=!0,v()),f({success:!0,baseUrl:`http://localhost:${i}`})});try{for(;;)yield await C()}finally{B.close(()=>{}),d(),q.forEach(({sig:r,handler:o})=>process.removeListener(r,o))}}l(serveExecutor,"serveExecutor"),a(serveExecutor,"serveExecutor"),c(serveExecutor,"serveExecutor"),exports.default=serveExecutor,module.exports=serveExecutor,module.exports.default=serveExecutor;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`).some(
|
|
1
|
+
"use strict";var w=Object.defineProperty;var h=(e,t)=>w(e,"name",{value:t,configurable:!0});var v=Object.defineProperty,p=h((e,t)=>v(e,"name",{value:t,configurable:!0}),"p"),m=Object.defineProperty,d=p((e,t)=>m(e,"name",{value:t,configurable:!0}),"d");Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=trustExecutor,exports.collectHosts=collectHosts;const tslib_1=require("tslib"),node_child_process_1=require("node:child_process"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path")),basic_ssl_1=require("../../basic-ssl");async function trustExecutor(e,t){const o=path.join(t.root,"node_modules",".cache","davnx-webpack"),n=(0,basic_ssl_1.ensureCaSync)(o),u=process.env.LENSMCP_TRUST_HOSTS_ONLY==="1",a=collectHosts(e,t);if(a.length===0&&console.log("[trust] no concrete hostnames found (only wildcards?) \u2014 keychain step only."),process.platform!=="darwin"){console.log("[trust] non-macOS platform \u2014 do these manually:"),console.log(` \u2022 trust ${n} in your OS/browser store (Linux: update-ca-certificates / certutil)`);for(const s of a)console.log(` \u2022 /etc/hosts: "127.0.0.1 ${s}" and "::1 ${s}"`);return{success:!0}}const r=caSha256Fingerprint(n),f=u||r!==void 0&&(0,node_child_process_1.spawnSync)("security",["find-certificate","-a","-c","lensmcp local dev CA","-Z","/Library/Keychains/System.keychain"],{encoding:"utf8"}).stdout?.includes(r)===!0;if(u)console.log("[trust] hosts-only: a shared daemon serves TLS with its own CA \u2014 skipping the keychain step.");else if(f)console.log("[trust] CA already in the System keychain \u2014 skipping.");else{if(console.log(`[trust] adding CA to the System keychain (sudo will prompt): ${n}`),(0,node_child_process_1.spawnSync)("sudo",["security","add-trusted-cert","-d","-r","trustRoot","-k","/Library/Keychains/System.keychain",n],{stdio:"inherit"}).status!==0)return console.error("[trust] add-trusted-cert failed \u2014 rerun in a terminal so sudo can prompt."),{success:!1};console.log("[trust] CA trusted. Restart your browser once (it caches certificate verdicts).")}const c=fs.readFileSync("/etc/hosts","utf8"),i=d((s,y)=>c.split(`
|
|
2
|
+
`).some(b=>{const g=b.trim();if(g.startsWith("#"))return!1;const S=g.split(/\s+/);return S[0]===s&&S.slice(1).includes(y)}),"hasEntry"),l=[];for(const s of a)i("127.0.0.1",s)||l.push(`127.0.0.1 ${s}`),i("::1",s)||l.push(`::1 ${s}`);if(l.length===0)console.log("[trust] /etc/hosts already complete (both families for every hostname).");else{console.log(`[trust] appending to /etc/hosts (sudo):
|
|
3
3
|
${l.join(`
|
|
4
|
-
`)}`);const s=`printf '%s\\n' ${l.map(
|
|
4
|
+
`)}`);const s=`printf '%s\\n' ${l.map(y=>`'${y}'`).join(" ")} >> /etc/hosts`;if((0,node_child_process_1.spawnSync)("sudo",["sh","-c",s],{stdio:"inherit"}).status!==0)return console.error("[trust] /etc/hosts update failed."),{success:!1};(0,node_child_process_1.spawnSync)("sudo",["sh","-c","dscacheutil -flushcache; killall -HUP mDNSResponder"],{stdio:"inherit"})}if(!u){const s=(0,node_child_process_1.spawnSync)("security",["verify-cert","-c",n,"-p","basic"],{stdio:"ignore"});console.log(`[trust] CA trust check: ${s.status===0?"OK":"NOT TRUSTED YET (browser restart may be needed)"}`)}for(const s of a)console.log(`[trust] ${s} \u2192 https ready (hosts + cert SAN ride the gateway config)`);return{success:!0}}h(trustExecutor,"trustExecutor"),p(trustExecutor,"trustExecutor"),d(trustExecutor,"trustExecutor");function caSha256Fingerprint(e){const t=(0,node_child_process_1.spawnSync)("openssl",["x509","-in",e,"-noout","-fingerprint","-sha256"],{encoding:"utf8"});if(t.status!==0||!t.stdout)return;const o=t.stdout.split("=")[1]?.replaceAll(":","").trim().toUpperCase();return o&&/^[0-9A-F]{64}$/.test(o)?o:void 0}h(caSha256Fingerprint,"caSha256Fingerprint"),p(caSha256Fingerprint,"caSha256Fingerprint"),d(caSha256Fingerprint,"caSha256Fingerprint");function collectHosts(e,t){const o=[],n=t.projectName?t.projectsConfigurations?.projects[t.projectName]:void 0,u=e.serveTarget??"serve-hmr",a=n?.targets?.[u]?.options?.gateway?.routes??[];for(const r of a)r.host&&!r.host.includes("*")&&o.push(r.host);for(const r of Object.values(t.projectsConfigurations?.projects??{}))try{const f=JSON.parse(fs.readFileSync(path.join(t.root,r.root,"project.json"),"utf8")),c=f.cluster??f.davnx,i=c?.host;i&&!i.includes("*")&&(o.push(i),c?.service&&c.internalHost!==!1&&o.push(typeof c.internalHost=="string"?c.internalHost:`internal.${i}`))}catch{}return[...new Set([...o,"lensmcp.local",...e.hosts??[]])]}h(collectHosts,"collectHosts"),p(collectHosts,"collectHosts"),d(collectHosts,"collectHosts");
|
package/gateway.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var n=Object.defineProperty;var a=(r,t)=>n(r,"name",{value:t,configurable:!0});var s=Object.defineProperty,i=a((r,t)=>s(r,"name",{value:t,configurable:!0}),"i"),o=Object.defineProperty,e=i((r,t)=>o(r,"name",{value:t,configurable:!0}),"e");Object.defineProperty(exports,"__esModule",{value:!0}),exports.manifestFromClusterDecl=exports.DEFAULT_REGISTRY_PREFIX=exports.redisRegistrySource=exports.createRegistryProviders=exports.endpointsPodProvider=exports.staticManifestProvider=exports.startProdGateway=void 0;var prod_gateway_lib_1=require("./executors/gateway/prod-gateway.lib");Object.defineProperty(exports,"startProdGateway",{enumerable:!0,get:e(function(){return prod_gateway_lib_1.startProdGateway},"get")});var providers_prod_1=require("./executors/gateway/providers-prod");Object.defineProperty(exports,"staticManifestProvider",{enumerable:!0,get:e(function(){return providers_prod_1.staticManifestProvider},"get")}),Object.defineProperty(exports,"endpointsPodProvider",{enumerable:!0,get:e(function(){return providers_prod_1.endpointsPodProvider},"get")});var registry_source_1=require("./executors/gateway/registry-source");Object.defineProperty(exports,"createRegistryProviders",{enumerable:!0,get:e(function(){return registry_source_1.createRegistryProviders},"get")}),Object.defineProperty(exports,"redisRegistrySource",{enumerable:!0,get:e(function(){return registry_source_1.redisRegistrySource},"get")}),Object.defineProperty(exports,"DEFAULT_REGISTRY_PREFIX",{enumerable:!0,get:e(function(){return registry_source_1.DEFAULT_REGISTRY_PREFIX},"get")});var manifest_1=require("./executors/gateway/manifest");Object.defineProperty(exports,"manifestFromClusterDecl",{enumerable:!0,get:e(function(){return manifest_1.manifestFromClusterDecl},"get")});
|
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var o=(t,r)=>u(t,"name",{value:r,configurable:!0});var p=Object.defineProperty,c=o((t,r)=>p(t,"name",{value:r,configurable:!0}),"c"),n=Object.defineProperty,e=c((t,r)=>n(t,"name",{value:r,configurable:!0}),"e");Object.defineProperty(exports,"__esModule",{value:!0}),exports.resolveEventFile=exports.publishTypecheckRun=exports.parseTscOutput=exports.parseTscDiagnosticLine=exports.buildTypecheckRunEvents=exports.appendTypecheckEvents=exports.createProdWebpackConfig=exports.createDevWebpackConfig=exports.buildScopePatterns=void 0;var build_scope_patterns_1=require("./build-scope-patterns");Object.defineProperty(exports,"buildScopePatterns",{enumerable:!0,get:e(function(){return build_scope_patterns_1.buildScopePatterns},"get")});var create_webpack_dev_1=require("./create-webpack-dev");Object.defineProperty(exports,"createDevWebpackConfig",{enumerable:!0,get:e(function(){return create_webpack_dev_1.createDevWebpackConfig},"get")});var create_webpack_prod_1=require("./create-webpack-prod");Object.defineProperty(exports,"createProdWebpackConfig",{enumerable:!0,get:e(function(){return create_webpack_prod_1.createProdWebpackConfig},"get")});var typecheck_bus_1=require("./typecheck-bus");Object.defineProperty(exports,"appendTypecheckEvents",{enumerable:!0,get:e(function(){return typecheck_bus_1.appendTypecheckEvents},"get")}),Object.defineProperty(exports,"buildTypecheckRunEvents",{enumerable:!0,get:e(function(){return typecheck_bus_1.buildTypecheckRunEvents},"get")}),Object.defineProperty(exports,"parseTscDiagnosticLine",{enumerable:!0,get:e(function(){return typecheck_bus_1.parseTscDiagnosticLine},"get")}),Object.defineProperty(exports,"parseTscOutput",{enumerable:!0,get:e(function(){return typecheck_bus_1.parseTscOutput},"get")}),Object.defineProperty(exports,"publishTypecheckRun",{enumerable:!0,get:e(function(){return typecheck_bus_1.publishTypecheckRun},"get")}),Object.defineProperty(exports,"resolveEventFile",{enumerable:!0,get:e(function(){return typecheck_bus_1.resolveEventFile},"get")});
|
package/main.devserver.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)}}const u=a(i=>d[(i-1)%d.length],"colorFor"),
|
|
3
|
-
`+String($),"stack")}}),A=a(($,T)=>{const
|
|
4
|
-
`;
|
|
1
|
+
"use strict";var he=Object.defineProperty;var f=(o,d)=>he(o,"name",{value:d,configurable:!0});var pe=Object.defineProperty,h=f((o,d)=>pe(o,"name",{value:d,configurable:!0}),"h"),ie=Object.defineProperty,a=h((o,d)=>ie(o,"name",{value:d,configurable:!0}),"a");Object.defineProperty(exports,"__esModule",{value:!0});const tslib_1=require("tslib"),path=tslib_1.__importStar(require("node:path")),fs=tslib_1.__importStar(require("node:fs")),os=tslib_1.__importStar(require("node:os")),node_child_process_1=require("node:child_process"),http=tslib_1.__importStar(require("node:http")),readline=tslib_1.__importStar(require("node:readline")),inspector=tslib_1.__importStar(require("node:inspector")),util=tslib_1.__importStar(require("node:util")),httpProxy=require("http-proxy"),{prettyFactory}=require("pino-pretty"),BUNDLE_PATH=process.env.BUNDLE_PATH?.trim()||"./main.js",SERVICE_NAME=process.env.SERVICE_NAME||"",SERVICE_PREFIX=process.env.SERVE_PREFIX?`/${process.env.SERVE_PREFIX}`:"",GATEWAY_MIDDLEWARE_PATH=process.env.GATEWAY_MIDDLEWARE||"",GATEWAY_CONFIG=(()=>{const o=process.env.GATEWAY_CONFIG;if(!o)return{};try{return JSON.parse(o)}catch{return{}}})();let gatewayMiddleware=null;if(GATEWAY_MIDDLEWARE_PATH)try{const o=require(GATEWAY_MIDDLEWARE_PATH);gatewayMiddleware=typeof o=="function"?o:typeof o.default=="function"?o.default:null,gatewayMiddleware||console.warn(`[gateway] ${GATEWAY_MIDDLEWARE_PATH} does not export a function, gateway disabled`)}catch(o){console.error(`[gateway] Failed to load middleware from ${GATEWAY_MIDDLEWARE_PATH}:`,o)}function applyGatewayMiddleware(o){if(gatewayMiddleware)try{gatewayMiddleware(o,GATEWAY_CONFIG)}catch(d){console.error("[gateway] Middleware error:",d)}}f(applyGatewayMiddleware,"applyGatewayMiddleware"),h(applyGatewayMiddleware,"applyGatewayMiddleware"),a(applyGatewayMiddleware,"applyGatewayMiddleware");const GATEWAY_ROUTES=(()=>{try{return JSON.parse(process.env.GATEWAY_ROUTES||"[]")}catch{return[]}})(),GATEWAY_HTTPS=process.env.GATEWAY_HTTPS==="1";function hostMatches(o,d){if(o.startsWith("*.")){const g=o.slice(1);return d.endsWith(g)||d===o.slice(2)}return d===o}f(hostMatches,"hostMatches"),h(hostMatches,"hostMatches"),a(hostMatches,"hostMatches");function matchGatewayRoute(o){if(GATEWAY_ROUTES.length===0)return;const d=(o.headers.host||"").split(":")[0],g=o.url||"/";for(const y of GATEWAY_ROUTES)if(!(y.host&&!hostMatches(y.host,d))&&!(y.prefix&&!g.startsWith(y.prefix)))return y}f(matchGatewayRoute,"matchGatewayRoute"),h(matchGatewayRoute,"matchGatewayRoute"),a(matchGatewayRoute,"matchGatewayRoute");const WORKER_NAMES=(()=>{try{return JSON.parse(process.env.WORKERS||"[]")}catch{return[]}})(),LENSMCP_WS_KEY=process.env.LENSMCP_WS_KEY||"",SOCK_DIR=LENSMCP_WS_KEY?path.join(os.tmpdir(),LENSMCP_WS_KEY,`${SERVICE_NAME||"lensmcp-cluster"}-devserver`):path.join(os.tmpdir(),`${SERVICE_NAME||"lensmcp-cluster"}-devserver`);function childSockPath(o){return path.join(SOCK_DIR,`child-${o}.sock`)}f(childSockPath,"childSockPath"),h(childSockPath,"childSockPath"),a(childSockPath,"childSockPath");function sockOwnerPath(o){return`${o}.owner`}f(sockOwnerPath,"sockOwnerPath"),h(sockOwnerPath,"sockOwnerPath"),a(sockOwnerPath,"sockOwnerPath");function claimSock(o,d=process.pid){try{fs.mkdirSync(path.dirname(o),{recursive:!0})}catch{}try{fs.writeFileSync(sockOwnerPath(o),String(d))}catch{}try{fs.unlinkSync(o)}catch{}}f(claimSock,"claimSock"),h(claimSock,"claimSock"),a(claimSock,"claimSock");function cleanupSock(o,d=process.pid){if(o){try{const g=fs.readFileSync(sockOwnerPath(o),"utf8").trim();if(g&&g!==String(d))return}catch{}try{fs.unlinkSync(o)}catch{}try{fs.unlinkSync(sockOwnerPath(o))}catch{}}}f(cleanupSock,"cleanupSock"),h(cleanupSock,"cleanupSock"),a(cleanupSock,"cleanupSock");async function importFresh(spec){process.env.DEVSERVER_MODE="1";const resolved=path.isAbsolute(spec)?spec:path.join(__dirname,spec);return eval(`delete require.cache["${resolved}"]`),eval(`require("${resolved}")`)}f(importFresh,"importFresh"),h(importFresh,"importFresh"),a(importFresh,"importFresh");function debounce(o,d){let g=null;return(...y)=>{g&&clearTimeout(g),g=setTimeout(()=>o(...y),d)}}if(f(debounce,"debounce"),h(debounce,"debounce"),a(debounce,"debounce"),process.env.APP_RUNNER==="1"){const o=a(g=>{if(!inspector.url())try{inspector.open(g,"127.0.0.1",!1)}catch(w){console.warn(`[child] inspector.open(${g}) failed (port taken by another devserver?) \u2014 falling back to a random port:`,w.message);try{inspector.open(0,"127.0.0.1",!1)}catch{}}const y=inspector.url();y&&process.send&&process.send({type:"inspector-url",url:y})},"openInspector"),d=Number(process.env.CHILD_DEBUG_PORT||"");Number.isInteger(d)&&d>1024&&o(d);try{require("@lensmcp/node-instrumentation/register")}catch{}(async()=>{let g=null,y=!1,w=!1,F=a((p,u)=>{u.statusCode=503,u.end("starting")},"delegate");async function P(){if(y)return w=!0,console.log("[child] Reload deferred \u2014 will re-swap after current swap completes"),g;if(y=!0,process.removeAllListeners("uncaughtException"),process.removeAllListeners("unhandledRejection"),process.on("uncaughtException",(_,b)=>{console.error(`[child] uncaughtException (${b}):`,_)}),process.on("unhandledRejection",_=>{const b=_ instanceof Error?_.stack||_.message:String(_);b.includes("FronteggContextScope")||b.includes("populateLoggerMetadata")||console.error("[child] unhandledRejection:",_)}),await importFresh(BUNDLE_PATH),typeof global.createChildApp!="function")throw y=!1,new Error(`Bundle '${BUNDLE_PATH}' does not export createChildApp() and the zero-touch bridge is not active. Either install @lensmcp/node-instrumentation (a plain NestFactory.create + app.listen main.ts then just works) or set global.createChildApp in main.ts when DEVSERVER_MODE === '1'.`);const p=await global.createChildApp(),u=g;return g=p,F=p.handler,console.log("[child] Swapped to fresh app (previous closing in background)"),u&&u.close().catch(_=>console.error("[child] background close error:",_)),y=!1,w?(w=!1,P()):p}f(P,"P"),h(P,"I"),a(P,"swapNow");const X=debounce(async()=>{try{console.log("[child] /webpack/reload"),await P()}catch(p){console.error("[child] reload failed:",p)}},250),O=http.createServer((p,u)=>{if(p.method==="POST"&&p.url==="/webpack/reload"){u.writeHead(200,{"content-type":"application/json"}),u.end(JSON.stringify({ok:!0})),X();return}F(p,u)}),k=process.env.CHILD_SOCK_PATH;process.on("disconnect",()=>{cleanupSock(k),process.exit(0)});try{await P();const p=path.isAbsolute(BUNDLE_PATH)?BUNDLE_PATH:path.join(__dirname,BUNDLE_PATH);console.log(`[child] Using bundle: ${p}`),claimSock(k),O.listen(k,()=>{console.log(`[child] Listening on ${k}`),process.send&&process.send({type:"ready",socketPath:k})})}catch(p){console.error("[child] Startup error:",p),process.send&&process.send({type:"boot-error",error:String(p?.stack||p)}),process.exitCode=1;return}process.on("message",async p=>{if(!(!p||typeof p!="object")){if(p.type==="debug-open"){const u=Number(p.port);o(Number.isInteger(u)&&u>1024?u:0);return}if(p.type==="reload")try{await P(),process.send&&process.send({type:"reloaded",socketPath:k})}catch(u){console.error("[child] reload error:",u),process.send&&process.send({type:"reload-error",error:String(u?.stack||u)})}}}),process.on("beforeExit",()=>{try{inspector?.close?.()}catch{}});const C=a(async p=>{console.log(`[child ${p}] shutting down\u2026`);const u=g?.close().catch(b=>console.error("[child] close error:",b)),_=new Promise(b=>O.close(()=>b()));cleanupSock(k),setTimeout(()=>process.exit(0),700).unref(),await Promise.all([u,_]),process.exit(0)},"shutdown");["SIGINT","SIGTERM","SIGHUP","SIGQUIT","SIGUSR2"].forEach(p=>{process.on(p,()=>{inspector?.close?.(),C(p)})})})()}else{let o=h(function(i){C.push(i),C.length>k&&C.splice(0,C.length-k),X?.write(i.replace(O,""));for(const S of p)try{S.res.write(S.plain?i.replace(O,""):i)}catch{p.delete(S)}},"p");a(o,"emitLogLine");const d=["\x1B[36m","\x1B[33m","\x1B[35m","\x1B[32m","\x1B[34m","\x1B[31m"],g="\x1B[0m",y=Math.max(1,Number(process.env.CHILD_COUNT||1));let w=(()=>{const i=Number(process.env.LENSMCP_DEBUG_PORT||"");return Number.isInteger(i)&&i>1024?i:0})();const F=20,P=process.env.LENSMCP_LOG_FILE||"",X=P?(()=>{try{return fs.mkdirSync(path.dirname(P),{recursive:!0}),fs.createWriteStream(P,{flags:"a"})}catch(i){return console.warn(`[parent] cannot open log file ${P}:`,i.message),null}})():null,O=/\x1b\[[0-9;]*m/g,k=2e3,C=[],p=new Set;for(const i of["log","info","warn","error"]){const S=console[i].bind(console);console[i]=(...E)=>{S(...E),o(E.map(A=>typeof A=="string"?A:util.inspect(A)).join(" ")+`
|
|
2
|
+
`)}}const u=a(i=>d[(i-1)%d.length],"colorFor"),_=a(i=>{if(y===1)return"";const S=`[child#${i}] `;return`${u(i)}${S}${g}`},"tagFor"),b=a(i=>i.startsWith("{")&&i.endsWith("}"),"isJsonLog"),re=a((i,S)=>{const E=prettyFactory({sync:!0,colorize:!0,crlf:!0,messageKey:"message",errorLikeObjectKeys:["err","error"],errorProps:"type,message,stack",ignore:["logContext","context","hostname","req","res","err.driverError","module","cloudEnvironment","frontegg-application-id","frontegg-tenant-id","frontegg-trace-id","frontegg-vendor-id","host","service","version","err","error"].join(","),messageFormat:"{if module}[{module}] {end}{if context}[{context}] {end}{if logContext}[{logContext}] {end}{message}",customPrettifiers:{stack:a($=>`
|
|
3
|
+
`+String($),"stack")}}),A=a(($,T)=>{const I=$==="stdout"?process.stdout:process.stderr,R=b(T)?E(T):`${T}
|
|
4
|
+
`;I.write(`${S}${R}`),o(`${S}${R}`)},"write"),G=a(($,T)=>{if(!$)return;const I=readline.createInterface({input:$});I.on("line",R=>A(T,R)),I.on("close",()=>{})},"attach");G(i.stdout,"stdout"),G(i.stderr,"stderr")},"wireProcLogging"),ae=a(i=>re(i.proc,_(i.id)),"wireChildLogging");(async()=>{fs.mkdirSync(SOCK_DIR,{recursive:!0});const i=httpProxy.createProxyServer({});let S=Number(process.env.PORT)||0;S||(S=9090);const E=[],A=new Set;function G(){let e=0;for(;A.has(e);)e++;return A.add(e),e}f(G,"G"),h(G,"G"),a(G,"allocDebugSlot");let $=1,T=0,I=!1,R=y,W=[];function j(){return E.filter(e=>e.healthy&&typeof e.socketPath=="string")}f(j,"K"),h(j,"Q"),a(j,"healthyChildren");function M(){const e=j();if(e.length===0)return null;const t=T%e.length;return T=(T+1)%e.length,e[t]}f(M,"M"),h(M,"U"),a(M,"pickChild");async function D(){const e=$++,t=childSockPath(e);cleanupSock(t);const l=["--enable-source-maps"];__filename.endsWith(".ts")&&l.unshift("--require","@swc-node/register");const n=w?G():-1,c=(0,node_child_process_1.fork)(__filename,{env:{...process.env,APP_RUNNER:"1",CHILD_SOCK_PATH:t,...n>=0&&{CHILD_DEBUG_PORT:String(w+n)}},stdio:["inherit","pipe","pipe","ipc"],execArgv:l}),r={id:e,proc:c,healthy:!1,lastError:null,debugSlot:n};return c.on("message",m=>{if(!m||typeof m!="object")return;const s=m;s.type==="ready"?(r.socketPath=String(s.socketPath),r.healthy=!0,console.log(`[parent] Child#${r.id} ready on socket ${r.socketPath}`)):s.type==="inspector-url"?(r.inspectorUrl=String(s.url),console.log(`[parent] Child#${r.id} Debugger listening on ${s.url}`)):s.type==="reloaded"?(r.socketPath=String(s.socketPath),r.healthy=!0,console.log(`[parent] Child#${r.id} hot-swapped on socket ${r.socketPath}`)):s.type==="reload-error"?(r.lastError=String(s.error||"unknown reload error"),console.error(`[parent] Child#${r.id} reload error: ${r.lastError}`),r.healthy=!1):s.type==="boot-error"&&(r.lastError=String(s.error||"unknown boot error"),console.error(`[parent] Child#${r.id} boot error: ${r.lastError}`),r.healthy=!1)}),c.on("exit",(m,s)=>{r.debugSlot>=0&&(A.delete(r.debugSlot),r.debugSlot=-1);const v=s==="SIGINT"||s==="SIGTERM"||m===0;if(v?console.log(`[parent] Child#${r.id} exited cleanly (code=${m}, signal=${s??"none"})`):(console.error(`[parent] Child#${r.id} crashed (code=${m}, signal=${s??"none"})`),r.lastError||(r.lastError=`Child exited abnormally (code=${m}, signal=${s??"none"})`)),r.healthy=!1,cleanupSock(r.socketPath,r.proc.pid),r.socketPath=void 0,!v&&!I){const x=E.indexOf(r);x>=0&&E.splice(x,1);const se=Date.now();if(W=W.filter(J=>se-J<3e4),W.length>=5){console.error(`[parent] crash-loop detected (${W.length} respawns/30s) \u2014 pausing auto-respawn; POST /webpack/reload to retry`);return}W.push(se),setTimeout(()=>{const J=E.filter(de=>de.proc.killed===!1).length;!I&&J<R&&(console.log(`[parent] respawning a crashed pod (${J}/${R} live)`),D().catch(()=>{}))},1500).unref?.()}}),E.push(r),ae(r),r}f(D,"U"),h(D,"K"),a(D,"spawnChild");async function Y(e){R=Math.max(R,e);const t=E.filter(n=>n.proc.killed===!1),l=e-t.length;for(let n=0;n<l;n++)await D()}f(Y,"V"),h(Y,"Z"),a(Y,"ensurePoolSize");async function z(){const e=E.filter(t=>!t.healthy||typeof t.socketPath!="string");await Promise.all(e.map(async t=>{try{t.proc.kill("SIGTERM")}catch{}cleanupSock(t.socketPath,t.proc.pid),t.socketPath=void 0;const l=E.indexOf(t);l>=0&&E.splice(l,1),await D()}))}f(z,"ee"),h(z,"oe"),a(z,"respawnUnhealthy");const N=[];function q(e){const t=path.dirname(path.isAbsolute(BUNDLE_PATH)?BUNDLE_PATH:path.resolve(BUNDLE_PATH)),l=path.join(t,`${e}.js`);if(!fs.existsSync(l))return console.error(`[parent] Worker "${e}" bundle not found: ${l}`),null;const n=["--enable-source-maps"];__filename.endsWith(".ts")&&n.unshift("--require","@swc-node/register");try{n.push("--require",require.resolve("@lensmcp/node-instrumentation/register"))}catch{}const c=(w||9229)+F+Math.max(0,WORKER_NAMES.indexOf(e));n.push(w?`--inspect=127.0.0.1:${c}`:`--inspect-port=127.0.0.1:${c}`);const r=(0,node_child_process_1.fork)(l,{env:process.env,stdio:["inherit","pipe","pipe","ipc"],execArgv:n}),m={name:e,proc:r,debugPort:c};return N.push(m),re(r,`\x1B[35m[worker:${e}] \x1B[0m`),r.on("exit",(s,v)=>{v==="SIGINT"||v==="SIGTERM"||s===0||console.error(`[parent] Worker "${e}" crashed (code=${s}, signal=${v??"none"})`);const x=N.indexOf(m);x>=0&&N.splice(x,1)}),console.log(`[parent] Worker "${e}" started (pid=${r.pid})`),m}f(q,"J"),h(q,"q"),a(q,"spawnWorkerProcess");function Q(){for(const e of[...N])try{e.proc.kill("SIGTERM")}catch{}N.length=0;for(const e of WORKER_NAMES)q(e)}f(Q,"te"),h(Q,"ne"),a(Q,"restartWorkers");const ce=debounce(async()=>{const e=j();if(e.length>0){console.log(`[parent] Forwarding reload to ${e.length} child(ren)`);for(const t of e)t.proc.send?.({type:"reload"})}await z(),WORKER_NAMES.length>0&&Q()},200),L=a(async(e,t)=>{if(e.method==="POST"&&e.url==="/webpack/reload"){t.writeHead(200,{"content-type":"application/json"}),t.end(JSON.stringify({ok:!0})),ce();return}if(e.method==="POST"&&e.url==="/webpack/scale"){let c="";e.on("data",r=>{c+=r}),e.on("end",async()=>{let r=0;try{r=Number(JSON.parse(c||"{}").pods)||0}catch{}r=Math.max(1,Math.min(r,16)),await Y(r),t.writeHead(200,{"content-type":"application/json"}),t.end(JSON.stringify({ok:!0,pods:r}))});return}if(e.method==="GET"&&e.url?.startsWith("/webpack/logs")){const c=new URL(e.url,"http://localhost").searchParams,r=Math.min(Math.max(Number(c.get("tail")??"100")||0,0),k),m=c.get("follow")!=="0",s=c.get("plain")==="1";t.writeHead(200,{"content-type":"text/plain; charset=utf-8","cache-control":"no-cache"});const v=r===0?"":C.slice(-r).join("");if(t.write(s?v.replace(O,""):v),!m){t.end();return}const x={res:t,plain:s};p.add(x),e.on("close",()=>p.delete(x));return}if(e.method==="POST"&&e.url?.startsWith("/webpack/debug")){const c=Number(new URL(e.url,"http://localhost").searchParams.get("port")||"");Number.isInteger(c)&&c>1024&&(w=c),w||(w=9229);const r=E.filter(s=>s.proc.exitCode===null&&s.proc.signalCode===null);for(const s of r){s.debugSlot<0&&(s.debugSlot=G());try{s.proc.send?.({type:"debug-open",port:w+s.debugSlot})}catch{}}for(const s of N)try{s.proc.kill("SIGUSR1")}catch{}const m=Date.now()+2e3;for(;Date.now()<m&&r.some(s=>!s.inspectorUrl);)await new Promise(s=>setTimeout(s,50));t.writeHead(200,{"content-type":"application/json"}),t.end(JSON.stringify({ok:!0,basePort:w,pods:r.map(s=>({id:s.id,inspectorUrl:s.inspectorUrl??null})),workers:N.map(s=>({name:s.name,port:s.debugPort}))},null,2)+`
|
|
5
5
|
`);return}const l=matchGatewayRoute(e);if(l?.prependPrefix&&!e.url?.startsWith(l.prependPrefix)&&(e.url=l.prependPrefix+(e.url??"/")),l?.target){applyGatewayMiddleware(e),i.web(e,t,{target:l.target,autoRewrite:typeof l.target=="string",changeOrigin:!0},c=>{console.error(`[parent] proxy error to ${l.target}:`,c),t.statusCode=502,t.setHeader("content-type","text/plain; charset=utf-8"),t.end(`Upstream error from ${l.target}.`)});return}if(SERVICE_PREFIX){if(!e.url?.startsWith(SERVICE_PREFIX)){t.writeHead(404,{"content-type":"text/plain; charset=utf-8"}),t.end(`Not found. This service is mounted at ${SERVICE_PREFIX}/`);return}e.url=e.url.slice(SERVICE_PREFIX.length)||"/"}applyGatewayMiddleware(e);const n=M();if(!n){t.statusCode=503,t.setHeader("content-type","text/plain; charset=utf-8");const c=E.map(r=>`#${r.id}: ${r.lastError??"no error recorded"}`).join(`
|
|
6
6
|
`);t.end(`No healthy children available. POST /webpack/reload to recover.
|
|
7
7
|
|
|
8
8
|
Last errors:
|
|
9
9
|
${c}`);return}i.web(e,t,{target:{socketPath:n.socketPath},headers:{"x-proxy-child-id":String(n.id)}},c=>{console.error(`[parent] proxy error to Child#${n.id}:`,c),n.healthy=!1,n.lastError=String(c?.stack||c),t.statusCode=502,t.setHeader("content-type","text/plain; charset=utf-8"),t.end(`Upstream error from Child#${n.id}. Try /webpack/reload.
|
|
10
|
-
${n.lastError}`)})},"requestHandler");let
|
|
10
|
+
${n.lastError}`)})},"requestHandler");let H,U,Z;const B=[];if(GATEWAY_HTTPS){const e=require("./basic-ssl"),t=GATEWAY_ROUTES.map(n=>n.host).filter(n=>!!n),l=path.join(process.cwd(),"node_modules",".cache","davnx-webpack");U=e.getCertificateSync(l,SERVICE_NAME||"lensmcp.dev",t),Z=e.caCertPath(),H=require("node:https").createServer({key:U,cert:U},L)}else H=http.createServer(L);const oe=a((e,t,l)=>{const n=matchGatewayRoute(e);if(n?.prependPrefix&&!e.url?.startsWith(n.prependPrefix)&&(e.url=n.prependPrefix+(e.url??"/")),n?.target){i.ws(e,t,l,{target:n.target,changeOrigin:!0},()=>t.destroy());return}const c=M();if(!c){t.destroy();return}i.ws(e,t,l,{target:{socketPath:c.socketPath}},()=>t.destroy())},"upgradeHandler");H.on("upgrade",oe),H.on("error",e=>{if(e.code==="EADDRINUSE"){console.warn(`[parent] public port ${S} already in use \u2014 continuing on the unix-socket pool only (gateway routing is unaffected). Give this service a distinct cluster.port to silence this.`);return}console.error("[parent] public server error:",e)}),await Y(y);for(const e of WORKER_NAMES)q(e);H.listen(S,()=>{const e=GATEWAY_HTTPS?"https":"http";console.log(`[parent] Listening on ${e}://localhost:${S}`),SERVICE_PREFIX&&console.log(`[parent] Service prefix: "${SERVICE_PREFIX}" (enforced \u2014 requests without it will get 404)`),gatewayMiddleware&&console.log(`[parent] Gateway middleware: ACTIVE (${GATEWAY_MIDDLEWARE_PATH})`),GATEWAY_ROUTES.length>0&&console.log(`[parent] Gateway routes: ${GATEWAY_ROUTES.map(t=>`${t.host??"*"}${t.prefix??"/"}\u2192${t.target??"children"}`).join(" ")}`),Z&&(console.log("[parent] HTTPS dev CA (trust ONCE, then rotations/new hostnames stay green):"),console.log(`[parent] sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${Z}`)),console.log(`POST ${e}://localhost:${S}/webpack/reload to trigger rolling swap/respawn`)});const K=Number(process.env.INTERNAL_PORT||0);if(K>0){const e=a((l,n)=>{const c=M();if(!c){n.statusCode=503,n.setHeader("content-type","text/plain; charset=utf-8"),n.end("No healthy children available.");return}i.web(l,n,{target:{socketPath:c.socketPath}},r=>{c.healthy=!1,c.lastError=String(r?.stack||r),n.statusCode=502,n.end(`Upstream error from Child#${c.id}.`)})},"internalHandler"),t=http.createServer(e);t.on("upgrade",(l,n,c)=>{const r=M();if(!r){n.destroy();return}i.ws(l,n,c,{target:{socketPath:r.socketPath}},()=>n.destroy())}),t.on("error",l=>{console.warn(`[parent] internal port ${K} unavailable (${l.code}).`)}),t.listen(K,()=>{console.log(`[parent] Internal (service-to-service, no gateway middleware) on http://localhost:${K}`)}),B.push(t)}const le=(()=>{try{return JSON.parse(process.env.GATEWAY_EXTRA_PORTS||"[]")}catch{return[]}})();for(const e of le){if(!Number.isInteger(e)||e===Number(S))continue;const t=GATEWAY_HTTPS?require("node:https").createServer({key:U,cert:U},L):http.createServer(L);t.on("upgrade",oe),t.on("error",l=>{console.warn(`[parent] extra port ${e} unavailable (${l.code}) \u2014 main port still up.`)}),t.listen(e,()=>{console.log(`[parent] Also listening on ${GATEWAY_HTTPS?"https":"http"}://localhost:${e}`)}),B.push(t)}const ee=path.join(SOCK_DIR,"parent.sock");claimSock(ee);const te=http.createServer(L);te.on("error",e=>{console.warn(`[parent] control socket unavailable (${e.code}) \u2014 lensmcp logs/debug attach disabled.`)}),te.listen(ee),B.push(te);const ne=a(async e=>{I=!0,console.log(`[${e}] [parent] shutting down\u2026`),cleanupSock(ee);for(const t of B)try{t.close()}catch{}for(const t of N)try{t.proc.kill("SIGTERM")}catch{}for(const t of E){try{t.proc.kill("SIGTERM")}catch{}t.socketPath&&cleanupSock(t.socketPath,t.proc.pid)}try{fs.rmdirSync(SOCK_DIR)}catch{}setTimeout(()=>process.exit(0),700).unref()},"shutdown");["SIGINT","SIGTERM","SIGHUP","SIGQUIT","SIGUSR2"].forEach(e=>process.on(e,()=>{ne(e)}));const V=Number(process.env.LENSMCP_GATEWAY_PID??0);if(Number.isInteger(V)&&V>0){const e=setInterval(()=>{try{process.kill(V,0)}catch(t){if(t.code==="EPERM")return;clearInterval(e),console.error(`[parent] gateway (pid ${V}) is gone \u2014 shutting the pod down to avoid an orphan tree.`),ne("gateway-gone")}},5e3);e.unref()}})()}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lensmcp/cluster",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.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,9 +65,9 @@
|
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@lensmcp/core": "1.
|
|
69
|
-
"@lensmcp/node-instrumentation": "1.
|
|
70
|
-
"@lensmcp/nx-plugin": "1.
|
|
68
|
+
"@lensmcp/core": "1.20.0",
|
|
69
|
+
"@lensmcp/node-instrumentation": "1.20.0",
|
|
70
|
+
"@lensmcp/nx-plugin": "1.20.0",
|
|
71
71
|
"@typescript/native-preview": "^7.0.0-dev.20260707.2",
|
|
72
72
|
"fork-ts-checker-webpack-plugin": "^9.0.0",
|
|
73
73
|
"glob": "^11.0.0",
|
package/tsgo-check-plugin.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)?
|
|
3
|
-
`);const
|
|
4
|
-
`)[0]?.slice(0,300)??""}l(firstLine,"firstLine"),r(firstLine,"firstLine");
|
|
1
|
+
"use strict";var f=Object.defineProperty;var a=(e,t)=>f(e,"name",{value:t,configurable:!0});var d=Object.defineProperty,l=a((e,t)=>d(e,"name",{value:t,configurable:!0}),"l"),u=Object.defineProperty,r=l((e,t)=>u(e,"name",{value:t,configurable:!0}),"r");Object.defineProperty(exports,"__esModule",{value:!0}),exports.TsgoCheckPlugin=exports.TSGO_MISSING_CAUSE=exports.TSGO_PACKAGE=void 0,exports.resolveTsgoPackageDir=resolveTsgoPackageDir,exports.resolveTsgoBin=resolveTsgoBin,exports.reportTsgoUnavailable=reportTsgoUnavailable,exports.writeShimTsconfig=writeShimTsconfig;const tslib_1=require("tslib"),node_child_process_1=require("node:child_process"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path")),typecheck_bus_1=require("./typecheck-bus");exports.TSGO_PACKAGE="@typescript/native-preview";function shimNames(e){return e==="win32"?["tsgo.cmd","tsgo.exe"]:["tsgo"]}a(shimNames,"shimNames"),l(shimNames,"shimNames"),r(shimNames,"shimNames");function isExecutableFile(e,t){try{if(!fs.statSync(e).isFile())return!1}catch{return!1}if(t==="win32")return!0;try{return fs.accessSync(e,fs.constants.X_OK),!0}catch{return!1}}a(isExecutableFile,"isExecutableFile"),l(isExecutableFile,"isExecutableFile"),r(isExecutableFile,"isExecutableFile");function resolveTsgoPackageDir(){try{return path.dirname(require.resolve(`${exports.TSGO_PACKAGE}/package.json`))}catch{}try{let e=path.dirname(require.resolve(exports.TSGO_PACKAGE));for(let t=0;t<6;t++){const i=path.join(e,"package.json");if(fs.existsSync(i))try{const{name:o}=JSON.parse(fs.readFileSync(i,"utf8"));if(o===exports.TSGO_PACKAGE)return e}catch{}const s=path.dirname(e);if(s===e)break;e=s}}catch{}return null}a(resolveTsgoPackageDir,"resolveTsgoPackageDir"),l(resolveTsgoPackageDir,"resolveTsgoPackageDir"),r(resolveTsgoPackageDir,"resolveTsgoPackageDir");function packageDeclaredBin(e){try{const{bin:t}=JSON.parse(fs.readFileSync(path.join(e,"package.json"),"utf8")),i=typeof t=="string"?t:t?.tsgo;return i?path.join(e,i):null}catch{return null}}a(packageDeclaredBin,"packageDeclaredBin"),l(packageDeclaredBin,"packageDeclaredBin"),r(packageDeclaredBin,"packageDeclaredBin");function ownBinCandidates(e,t){const i=path.resolve(e,"..","..",".bin"),s=shimNames(t).map(n=>path.join(i,n)),o=t==="win32"?null:packageDeclaredBin(e);return o?[o,...s]:s}a(ownBinCandidates,"ownBinCandidates"),l(ownBinCandidates,"ownBinCandidates"),r(ownBinCandidates,"ownBinCandidates");function resolveTsgoBin(e,t,i={}){const s=i.platform??process.platform,o=i.isExecutable??(p=>isExecutableFile(p,s));if(t)return o(t)?t:null;for(const p of shimNames(s)){const c=path.join(e,"node_modules",".bin",p);if(o(c))return c}const n=(i.ownPackageDir??resolveTsgoPackageDir)();return n?ownBinCandidates(n,s).find(o)??null:null}a(resolveTsgoBin,"resolveTsgoBin"),l(resolveTsgoBin,"resolveTsgoBin"),r(resolveTsgoBin,"resolveTsgoBin"),exports.TSGO_MISSING_CAUSE=`tsgo binary not found \u2014 @lensmcp/cluster depends on ${exports.TSGO_PACKAGE}, so an absent binary means an incomplete install (reinstall node_modules), a platform with no ${exports.TSGO_PACKAGE} build, or a LENSMCP_TSGO_BIN override pointing at a missing or non-executable file`;function reportTsgoUnavailable(e){try{(0,typecheck_bus_1.publishTypecheckRun)({workspaceRoot:e.workspaceRoot,project:e.appName,tool:"tsgo",tsConfig:e.tsConfig,output:"",durationMs:0,toolError:e.detail,...e.eventFile?{eventFile:e.eventFile}:{}})}catch{}}a(reportTsgoUnavailable,"reportTsgoUnavailable"),l(reportTsgoUnavailable,"reportTsgoUnavailable"),r(reportTsgoUnavailable,"reportTsgoUnavailable");function writeShimTsconfig(e,t,i){const s=path.join(i,"tmp","lensmcp-tsgo");fs.mkdirSync(s,{recursive:!0});const o=path.join(s,`${e}.tsconfig.json`);return fs.writeFileSync(o,JSON.stringify({extends:t,compilerOptions:{module:"preserve",moduleResolution:"bundler",isolatedModules:!1,baseUrl:null}},null,2)),o}a(writeShimTsconfig,"writeShimTsconfig"),l(writeShimTsconfig,"writeShimTsconfig"),r(writeShimTsconfig,"writeShimTsconfig");class TsgoCheckPlugin{static{a(this,"TsgoCheckPlugin")}static{l(this,"TsgoCheckPlugin")}static{r(this,"TsgoCheckPlugin")}constructor(t){this.timer=null,this.inflight=null,this.shimPath=null,this.disabled=!1,this.opts=t,this.spawnImpl=t.spawnImpl??node_child_process_1.spawn}apply(t){t.hooks.done.tap("TsgoCheckPlugin",i=>{i.hasErrors()||this.schedule()})}schedule(){this.disabled||(this.timer&&clearTimeout(this.timer),this.timer=setTimeout(()=>this.run(),this.opts.debounceMs??500),this.timer.unref?.())}publish(t){if(this.opts.publishEvents!==!1)try{(0,typecheck_bus_1.publishTypecheckRun)({workspaceRoot:this.opts.workspaceRoot,project:this.opts.appName,tool:"tsgo",tsConfig:this.opts.tsConfig,output:t.output,durationMs:t.durationMs,...t.toolError?{toolError:t.toolError}:{},...this.opts.eventFile?{eventFile:this.opts.eventFile}:{}})}catch{}}run(){const t=resolveTsgoBin(this.opts.workspaceRoot,this.opts.binPath);if(!t){this.disabled=!0;const n=`${exports.TSGO_MISSING_CAUSE}. Type checking is disabled for the rest of this session`;console.warn(`[tsgo] ${this.opts.appName}: ${n}.`),this.publish({output:"",durationMs:0,toolError:n});return}this.inflight&&(this.inflight.kill("SIGTERM"),this.inflight=null),this.shimPath||(this.shimPath=writeShimTsconfig(this.opts.appName,this.opts.tsConfig,this.opts.workspaceRoot));const i=Date.now(),s=this.spawnImpl(t,["--noEmit","--pretty","false","-p",this.shimPath],{cwd:this.opts.workspaceRoot,stdio:["ignore","pipe","pipe"]});this.inflight=s;let o="";s.stdout?.on("data",n=>{o+=n.toString()}),s.stderr?.on("data",n=>{o+=n.toString()}),s.on("error",()=>{this.inflight===s&&(this.inflight=null),console.warn(`[tsgo] ${this.opts.appName}: failed to spawn ${t}`),this.publish({output:"",durationMs:Date.now()-i,toolError:`failed to spawn ${t}`})}),s.on("close",(n,p)=>{if(this.inflight===s&&(this.inflight=null),p)return;const c=Date.now()-i,g=(c/1e3).toFixed(1);if(n===0){console.log(`[tsgo] ${this.opts.appName}: types clean (${g}s)`),this.publish({output:"",durationMs:c});return}o.trim()&&process.stdout.write(o.endsWith(`
|
|
2
|
+
`)?o:`${o}
|
|
3
|
+
`);const h=(o.match(/error TS\d+/g)??[]).length;console.log(`[tsgo] ${this.opts.appName}: ${h} type error${h===1?"":"s"} (${g}s)`),this.publish({output:o,durationMs:c,...h===0?{toolError:`tsgo exited ${n} with no diagnostics: ${firstLine(o)}`}:{}})})}}exports.TsgoCheckPlugin=TsgoCheckPlugin;function firstLine(e){return e.trim().split(`
|
|
4
|
+
`)[0]?.slice(0,300)??""}a(firstLine,"firstLine"),l(firstLine,"firstLine"),r(firstLine,"firstLine");
|
package/typecheck-bus.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)){const o=parseTscDiagnosticLine(
|
|
1
|
+
"use strict";var y=Object.defineProperty;var c=(e,r)=>y(e,"name",{value:r,configurable:!0});var g=Object.defineProperty,s=c((e,r)=>g(e,"name",{value:r,configurable:!0}),"s"),f=Object.defineProperty,i=s((e,r)=>f(e,"name",{value:r,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.MAX_DIAGNOSTICS_PER_RUN=void 0,exports.stripAnsi=stripAnsi,exports.parseTscDiagnosticLine=parseTscDiagnosticLine,exports.parseTscOutput=parseTscOutput,exports.buildTypecheckRunEvents=buildTypecheckRunEvents,exports.resolveEventFile=resolveEventFile,exports.appendTypecheckEvents=appendTypecheckEvents,exports.publishTypecheckRun=publishTypecheckRun;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path")),busHygiene=(()=>{try{return require("@lensmcp/node-instrumentation")}catch{return}})(),DIAG_LINE_REGEX=/^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+(TS\d+):\s+(.+)$/,ANSI_CSI=new RegExp("\x1B\\[[0-9;]*[A-Za-z]","g");function stripAnsi(e){return e.replace(ANSI_CSI,"")}c(stripAnsi,"stripAnsi"),s(stripAnsi,"stripAnsi"),i(stripAnsi,"stripAnsi");function parseTscDiagnosticLine(e){const r=stripAnsi(e).trim();if(!r)return null;const t=DIAG_LINE_REGEX.exec(r);if(!t)return null;const[,o,l,a,p,d,u]=t;return!o||!l||!a||!p||!d||!u?null:{file:o,line:Number(l),column:Number(a),severity:p==="warning"?"warning":"error",code:d,message:u}}c(parseTscDiagnosticLine,"parseTscDiagnosticLine"),s(parseTscDiagnosticLine,"parseTscDiagnosticLine"),i(parseTscDiagnosticLine,"parseTscDiagnosticLine");function parseTscOutput(e){const r=[];for(const t of e.split(`
|
|
2
|
+
`)){const o=parseTscDiagnosticLine(t);o&&r.push(o)}return r}c(parseTscOutput,"parseTscOutput"),s(parseTscOutput,"parseTscOutput"),i(parseTscOutput,"parseTscOutput"),exports.MAX_DIAGNOSTICS_PER_RUN=200;let idCounter=0;function makeId(){return idCounter=(idCounter+1)%65535,`${Date.now().toString(36)}${idCounter.toString(36)}${Math.random().toString(36).slice(2,8)}`}c(makeId,"makeId"),s(makeId,"makeId"),i(makeId,"makeId");function buildTypecheckRunEvents(e){const r=(e.now??Date.now)(),t=e.idImpl??makeId,o="pending",l={sessionId:o,source:"typescript",category:"typecheck",context:{sessionId:o,projectName:e.project}},a={project:e.project,tool:e.tool,...e.tsConfig?{tsConfig:e.tsConfig}:{}},p=e.diagnostics.filter(n=>n.severity==="error"),d=e.diagnostics.slice(0,exports.MAX_DIAGNOSTICS_PER_RUN),u=[];if(!e.toolError){u.push({...l,id:t(),timestamp:r,severity:"info",title:`tsc clear: ${e.project}`,message:`typecheck run starting for ${e.project}`,fingerprint:`tsc:${e.project}:run-start`,raw:{...a,kind:"typecheck-run",phase:"start"}});for(const n of d)u.push({...l,id:t(),timestamp:r,severity:n.severity,title:`${n.code}: ${n.message}`,message:n.message,location:{file:n.file,line:n.line,column:n.column},fingerprint:`tsc:${e.project}:${n.file}:${n.line}:${n.column}:${n.code}`,raw:{...a,kind:"typecheck-diagnostic",code:n.code}})}const h=e.toolError?"error":p.length>0?"failing":"clean";return u.push({...l,id:t(),timestamp:r,severity:"info",title:`typecheck run: ${e.project} \u2014 ${e.toolError?"tool error":`${p.length} error${p.length===1?"":"s"}`} (${e.durationMs}ms)`,...e.toolError?{message:e.toolError}:{},fingerprint:`tsc:${e.project}:run-end`,raw:{...a,kind:"typecheck-run",phase:"end",status:h,durationMs:e.durationMs,errorCount:p.length,warningCount:e.diagnostics.length-p.length,...e.diagnostics.length>d.length?{truncatedDiagnostics:e.diagnostics.length-d.length}:{},...e.toolError?{error:e.toolError}:{}}}),u}c(buildTypecheckRunEvents,"buildTypecheckRunEvents"),s(buildTypecheckRunEvents,"buildTypecheckRunEvents"),i(buildTypecheckRunEvents,"buildTypecheckRunEvents");function resolveEventFile(e){return process.env.LENSMCP_EVENT_FILE||path.join(e,".lensmcp","events.jsonl")}c(resolveEventFile,"resolveEventFile"),s(resolveEventFile,"resolveEventFile"),i(resolveEventFile,"resolveEventFile");let ensuredDir=null;function ensureDir(e){const r=path.dirname(e);ensuredDir!==r&&(fs.mkdirSync(r,{recursive:!0}),ensuredDir=r)}c(ensureDir,"ensureDir"),s(ensureDir,"ensureDir"),i(ensureDir,"ensureDir");function appendTypecheckEvents(e,r){if(r.length===0)return;const t=r.map(o=>JSON.stringify(o)).join(`
|
|
3
3
|
`)+`
|
|
4
|
-
`;try{ensureDir(
|
|
4
|
+
`;try{ensureDir(e),busHygiene?.maybeRotateEventFile(e,t.length),fs.appendFileSync(e,t)}catch(o){if(o?.code==="ENOENT"){try{ensuredDir=null,ensureDir(e),fs.appendFileSync(e,t)}catch{}return}}}c(appendTypecheckEvents,"appendTypecheckEvents"),s(appendTypecheckEvents,"appendTypecheckEvents"),i(appendTypecheckEvents,"appendTypecheckEvents");function publishTypecheckRun(e){const r=buildTypecheckRunEvents({project:e.project,tool:e.tool,...e.tsConfig?{tsConfig:e.tsConfig}:{},diagnostics:e.toolError?[]:parseTscOutput(e.output),durationMs:e.durationMs,...e.toolError?{toolError:e.toolError}:{}});return appendTypecheckEvents(e.eventFile??resolveEventFile(e.workspaceRoot),r),r}c(publishTypecheckRun,"publishTypecheckRun"),s(publishTypecheckRun,"publishTypecheckRun"),i(publishTypecheckRun,"publishTypecheckRun");
|