@lensmcp/cluster 1.25.16 → 1.25.18

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.
Files changed (131) hide show
  1. package/basic-ssl.js +1 -1
  2. package/build-host.js +1 -1
  3. package/build-scope-patterns.js +1 -1
  4. package/bundle-parent.js +1 -1
  5. package/checkout-cache.js +1 -1
  6. package/create-webpack-dev.js +1 -1
  7. package/create-webpack-prod.js +1 -1
  8. package/dev-devtool.js +1 -1
  9. package/devserver-notifier.js +1 -1
  10. package/devserver-transport.js +1 -1
  11. package/error-stack-release.js +1 -1
  12. package/executors/build/build.impl.js +1 -1
  13. package/executors/gateway/body-stall.js +1 -1
  14. package/executors/gateway/canonical-path.js +1 -1
  15. package/executors/gateway/client-ip.js +1 -1
  16. package/executors/gateway/gateway-errors.js +1 -1
  17. package/executors/gateway/gateway.impl.js +1 -1
  18. package/executors/gateway/gateway.lib.js +1 -1
  19. package/executors/gateway/health-check.js +1 -1
  20. package/executors/gateway/jwks-verify.d.ts +37 -2
  21. package/executors/gateway/jwks-verify.js +1 -1
  22. package/executors/gateway/jwt-claims.js +1 -1
  23. package/executors/gateway/main.prod-gateway.js +2 -2
  24. package/executors/gateway/main.rollout.js +4 -4
  25. package/executors/gateway/manifest.js +1 -1
  26. package/executors/gateway/metrics.js +1 -1
  27. package/executors/gateway/otel-tracing.js +1 -1
  28. package/executors/gateway/prod-config.js +1 -1
  29. package/executors/gateway/prod-gateway.lib.js +1 -1
  30. package/executors/gateway/prod-runtime/access-log.js +1 -1
  31. package/executors/gateway/prod-runtime/app.js +1 -1
  32. package/executors/gateway/prod-runtime/auth.js +1 -1
  33. package/executors/gateway/prod-runtime/body-stall.js +1 -1
  34. package/executors/gateway/prod-runtime/cors.js +1 -1
  35. package/executors/gateway/prod-runtime/edge.js +1 -1
  36. package/executors/gateway/prod-runtime/handler.js +1 -1
  37. package/executors/gateway/prod-runtime/hooks.js +1 -1
  38. package/executors/gateway/prod-runtime/observability.js +1 -1
  39. package/executors/gateway/prod-runtime/rollout.js +1 -1
  40. package/executors/gateway/prod-runtime/routing.js +1 -1
  41. package/executors/gateway/prod-runtime/server.js +1 -1
  42. package/executors/gateway/prod-runtime/trust.js +1 -1
  43. package/executors/gateway/prod-runtime/upgrade.js +7 -7
  44. package/executors/gateway/prod-runtime/upstream.js +1 -1
  45. package/executors/gateway/providers-prod.js +1 -1
  46. package/executors/gateway/rate-limit.js +2 -2
  47. package/executors/gateway/registry-source.js +1 -1
  48. package/executors/gateway/rollout-ops.js +2 -2
  49. package/executors/gateway/runtime/act.js +1 -1
  50. package/executors/gateway/runtime/auth.js +1 -1
  51. package/executors/gateway/runtime/chooser.js +12 -12
  52. package/executors/gateway/runtime/control.js +2 -2
  53. package/executors/gateway/runtime/dev-auth.js +1 -1
  54. package/executors/gateway/runtime/discovery.js +1 -1
  55. package/executors/gateway/runtime/edge.d.ts +7 -0
  56. package/executors/gateway/runtime/edge.js +1 -1
  57. package/executors/gateway/runtime/guest-graph.js +2 -2
  58. package/executors/gateway/runtime/guest-replay.js +2 -2
  59. package/executors/gateway/runtime/handler.js +1 -1
  60. package/executors/gateway/runtime/hmr-reload.js +1 -1
  61. package/executors/gateway/runtime/hooks.js +1 -1
  62. package/executors/gateway/runtime/instance.js +2 -2
  63. package/executors/gateway/runtime/lens-children.js +1 -1
  64. package/executors/gateway/runtime/lifecycle.js +3 -3
  65. package/executors/gateway/runtime/observability.js +2 -2
  66. package/executors/gateway/runtime/own-log.js +4 -4
  67. package/executors/gateway/runtime/pod-env.js +2 -2
  68. package/executors/gateway/runtime/pod-output.js +1 -1
  69. package/executors/gateway/runtime/pod-probe.js +1 -1
  70. package/executors/gateway/runtime/process-names.js +1 -1
  71. package/executors/gateway/runtime/project-graph-store.js +1 -1
  72. package/executors/gateway/runtime/proxy.js +1 -1
  73. package/executors/gateway/runtime/registration-guards.js +1 -1
  74. package/executors/gateway/runtime/route-registry.js +1 -1
  75. package/executors/gateway/runtime/scope.js +1 -1
  76. package/executors/gateway/runtime/serve-launch.js +3 -3
  77. package/executors/gateway/runtime/server.d.ts +39 -2
  78. package/executors/gateway/runtime/server.js +2 -2
  79. package/executors/gateway/runtime/service-keys.js +1 -1
  80. package/executors/gateway/runtime/shared-build.js +4 -4
  81. package/executors/gateway/runtime/source-poller.js +1 -1
  82. package/executors/gateway/runtime/types.js +1 -1
  83. package/executors/gateway/runtime/upgrade.js +1 -1
  84. package/executors/gateway/runtime/workspace-log.js +1 -1
  85. package/executors/gateway/runtime/workspace-middleware.js +1 -1
  86. package/executors/gateway/runtime/workspace-registry.js +1 -1
  87. package/executors/gateway/ssrf-guard.js +1 -1
  88. package/executors/serve/serve.impl.js +1 -1
  89. package/executors/trust/hostname.js +1 -1
  90. package/executors/trust/trust.impl.js +3 -3
  91. package/exit-reason.js +2 -2
  92. package/fork-ts-check-reporter.js +1 -1
  93. package/gateway.js +1 -1
  94. package/gc-notice.js +1 -1
  95. package/graph-snapshot.js +1 -1
  96. package/handoff-retire.js +1 -1
  97. package/heap-snapshot.js +1 -1
  98. package/hot-swap-registries.js +1 -1
  99. package/index.js +1 -1
  100. package/inspector-secret.js +1 -1
  101. package/main.devserver.js +11 -11
  102. package/notice-generation.js +1 -1
  103. package/package.json +4 -4
  104. package/perf/heavy-barrel-import.js +1 -1
  105. package/perf/perf-config.js +1 -1
  106. package/perf/perf-rule-events.js +2 -2
  107. package/perf/perf-rules-analysis.js +1 -1
  108. package/perf/perf-rules-plugin.js +1 -1
  109. package/perf/source-scan.js +5 -5
  110. package/perf/workspace-libraries.js +2 -2
  111. package/pod-memory-events.js +2 -2
  112. package/pod-memory.js +1 -1
  113. package/pod-sock.js +1 -1
  114. package/process-name.js +1 -1
  115. package/redis-disconnect-fix.js +1 -1
  116. package/schema-first-instance.js +1 -1
  117. package/serve-runner.js +1 -1
  118. package/service-build-events.js +1 -1
  119. package/shared-build/attach.js +2 -2
  120. package/shared-build/host.js +3 -3
  121. package/shared-build/protocol.js +1 -1
  122. package/shared-build/shared-compilation.js +3 -3
  123. package/shared-build/signature.js +1 -1
  124. package/stdio-guard.js +1 -1
  125. package/swap-mode.js +1 -1
  126. package/swap-recycle.js +1 -1
  127. package/tsgo-check-plugin.js +4 -4
  128. package/typecheck-bus.js +3 -3
  129. package/typecheck-queue.js +1 -1
  130. package/worker-supervisor.js +2 -2
  131. package/workspace-paths.js +1 -1
@@ -1 +1 @@
1
- "use strict";var b=Object.defineProperty;var S=(e,a)=>b(e,"name",{value:a,configurable:!0});var h=Object.defineProperty,c=S((e,a)=>h(e,"name",{value:a,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.ACT_MAX_IDENTITIES=exports.ACT_RETAIN_MS=exports.ACT_TICKET_MS=exports.ACT_TICKET=exports.ACT_HEADER=void 0,exports.fromBrowser=fromBrowser,exports.actTicketOf=actTicketOf,exports.setActTicketAside=setActTicketAside,exports.createActStore=createActStore;const tslib_1=require("tslib"),node_crypto_1=require("node:crypto"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path"));exports.ACT_HEADER="x-lensmcp-act",exports.ACT_TICKET=Symbol.for("lensmcp.gateway.actTicket"),exports.ACT_TICKET_MS=6e4,exports.ACT_RETAIN_MS=720*60*6e4,exports.ACT_MAX_IDENTITIES=20;const TOKEN_MARGIN_S=30,MAX_OPEN_TICKETS=200,WRITE_EVERY_MS=3e4,TIME_CLAIMS=new Set(["exp","iat","nbf","jti"]),TICKET_VALUE=/^[A-Za-z0-9_-]{43}$/;function fromBrowser(e){return typeof e.headers["sec-fetch-mode"]=="string"||typeof e.headers["sec-fetch-site"]=="string"}S(fromBrowser,"fromBrowser"),c(fromBrowser,"fromBrowser");function actTicketOf(e){return e[exports.ACT_TICKET]}S(actTicketOf,"actTicketOf"),c(actTicketOf,"actTicketOf");function setActTicketAside(e){const a=e.headers[exports.ACT_HEADER];typeof a=="string"&&TICKET_VALUE.test(a)&&(e[exports.ACT_TICKET]=a)}S(setActTicketAside,"setActTicketAside"),c(setActTicketAside,"setActTicketAside");const str=c(e=>typeof e=="string"&&e.length>0&&e.length<=256?e:void 0,"str"),keyOf=c(e=>{const a=str(e.sub);return a?`${a}\0${str(e.tid)??""}`:void 0},"keyOf"),safeName=c(e=>e.replace(/[^A-Za-z0-9._-]/g,"_").slice(0,120)||"_","safeName");function viewOf(e,a){const A=e.claims,d=Array.isArray(A.roles)?A.roles.filter(T=>typeof T=="string").slice(0,20):void 0,y=str(A.tid),u=str(A.email),E=str(A.name)??str(A.preferred_username);return{user:str(A.sub),...y?{tenant:y}:{},...u?{email:u}:{},...E?{name:E}:{},...d?.length?{roles:d}:{},host:e.host,firstSeenAt:e.firstSeenAt,lastSeenAt:e.lastSeenAt,mode:e.token&&e.tokenExp!==void 0&&e.tokenExp-TOKEN_MARGIN_S>a/1e3?"token":"identity"}}S(viewOf,"viewOf"),c(viewOf,"viewOf");function createActStore(e={}){const a=e.now??Date.now,A=new Map,d=new Map,y=new Map,u=new Set,E=c(t=>e.dir?path.join(e.dir,`${safeName(t)}.json`):void 0,"file"),T=c(t=>{let s=A.get(t);if(s)return s;s=new Map,A.set(t,s);const n=E(t);if(!n)return s;try{const o=JSON.parse(fs.readFileSync(n,"utf8"));for(const i of Array.isArray(o.identities)?o.identities:[]){const r=i;if(!r||typeof r!="object"||!r.claims||typeof r.claims!="object"||typeof r.host!="string"||typeof r.firstSeenAt!="number"||typeof r.lastSeenAt!="number")continue;const f=keyOf(r.claims);f&&s.set(f,{claims:r.claims,host:r.host,firstSeenAt:r.firstSeenAt,lastSeenAt:r.lastSeenAt})}}catch{}return s},"load"),g=c((t,s)=>{for(const[n,o]of t)s-o.lastSeenAt>exports.ACT_RETAIN_MS&&t.delete(n);if(t.size>exports.ACT_MAX_IDENTITIES){const n=[...t.entries()].sort((o,i)=>o[1].lastSeenAt-i[1].lastSeenAt).slice(0,t.size-exports.ACT_MAX_IDENTITIES);for(const[o]of n)t.delete(o)}},"prune"),k=c((t,s)=>{const n=E(t),o=A.get(t);if(u.delete(t),!(!n||!o)){y.set(t,s);try{fs.mkdirSync(path.dirname(n),{recursive:!0,mode:448});const i=[...o.values()].map(f=>({claims:f.claims,host:f.host,firstSeenAt:f.firstSeenAt,lastSeenAt:f.lastSeenAt})),r=`${n}.${process.pid}.tmp`;fs.writeFileSync(r,JSON.stringify({identities:i},null,1),{mode:384}),fs.renameSync(r,n)}catch{}}},"write"),I=c((t,s,n,o,i=a())=>{const r=keyOf(s);if(!r)return;const f=T(t),_={};for(const[x,w]of Object.entries(s))TIME_CLAIMS.has(x)||(_[x]=w);const m=f.get(r),l=typeof s.exp=="number"?s.exp:void 0,p=!m||m.host!==o||JSON.stringify(m.claims)!==JSON.stringify(_);f.set(r,{claims:_,host:o,firstSeenAt:m?.firstSeenAt??i,lastSeenAt:i,...n&&l!==void 0?{token:n,tokenExp:l}:m?.token?{token:m.token,tokenExp:m.tokenExp}:{}}),g(f,i),p&&u.add(t),(p||i-(y.get(t)??0)>=WRITE_EVERY_MS)&&k(t,i)},"remember"),C=c((t,s=a())=>{const n=T(t);return g(n,s),[...n.values()].sort((o,i)=>i.lastSeenAt-o.lastSeenAt).map(o=>viewOf(o,s))},"list");return{remember:I,list:C,mint:c((t,s,n=a())=>{const o=T(t);g(o,n);const i=s.user?.trim().toLowerCase(),r=s.tenant?.trim(),f=[...o.entries()].filter(([,l])=>{const p=l.claims;return r&&str(p.tid)!==r?!1:i?[p.sub,p.email,p.name,p.preferred_username].some(x=>typeof x=="string"&&x.toLowerCase()===i):!0}).sort((l,p)=>p[1].lastSeenAt-l[1].lastSeenAt)[0];if(!f){const l=C(t,n);return{error:l.length?`No signed-in identity matches${i?` user '${s.user}'`:""}${r?` in tenant '${r}'`:""} \u2014 ${l.length} known (see identities).`:"No one has signed in to this workspace's app since the gateway started remembering identities. Sign in once in the browser \u2014 the gateway keeps the identity it verified for 30 days.",identities:l}}for(const[l,p]of d)p.expiresAt<=n&&d.delete(l);d.size>=MAX_OPEN_TICKETS&&d.delete(d.keys().next().value);const _=(0,node_crypto_1.randomBytes)(32).toString("base64url"),m=n+exports.ACT_TICKET_MS;return d.set(_,{wsKey:t,key:f[0],expiresAt:m}),{ticket:_,expiresAt:m,identity:viewOf(f[1],n)}},"mint"),redeem:c((t,s,n=a())=>{const o=d.get(t);if(!o||(d.delete(t),o.expiresAt<=n||o.wsKey!==s))return;const i=T(s).get(o.key);if(!i)return;const r=viewOf(i,n);return r.mode==="token"?{token:i.token,claims:i.claims,view:r}:{claims:i.claims,view:r}},"redeem"),flush:c(()=>{const t=a();for(const s of[...u])k(s,t)},"flush")}}S(createActStore,"createActStore"),c(createActStore,"createActStore");
1
+ "use strict";var M=Object.defineProperty;var u=(e,a)=>M(e,"name",{value:a,configurable:!0});var b=Object.defineProperty,S=u((e,a)=>b(e,"name",{value:a,configurable:!0}),"S"),h=Object.defineProperty,c=S((e,a)=>h(e,"name",{value:a,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.ACT_MAX_IDENTITIES=exports.ACT_RETAIN_MS=exports.ACT_TICKET_MS=exports.ACT_TICKET=exports.ACT_HEADER=void 0,exports.fromBrowser=fromBrowser,exports.actTicketOf=actTicketOf,exports.setActTicketAside=setActTicketAside,exports.createActStore=createActStore;const tslib_1=require("tslib"),node_crypto_1=require("node:crypto"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path"));exports.ACT_HEADER="x-lensmcp-act",exports.ACT_TICKET=Symbol.for("lensmcp.gateway.actTicket"),exports.ACT_TICKET_MS=6e4,exports.ACT_RETAIN_MS=720*60*6e4,exports.ACT_MAX_IDENTITIES=20;const TOKEN_MARGIN_S=30,MAX_OPEN_TICKETS=200,WRITE_EVERY_MS=3e4,TIME_CLAIMS=new Set(["exp","iat","nbf","jti"]),TICKET_VALUE=/^[A-Za-z0-9_-]{43}$/;function fromBrowser(e){return typeof e.headers["sec-fetch-mode"]=="string"||typeof e.headers["sec-fetch-site"]=="string"}u(fromBrowser,"fromBrowser"),S(fromBrowser,"fromBrowser"),c(fromBrowser,"fromBrowser");function actTicketOf(e){return e[exports.ACT_TICKET]}u(actTicketOf,"actTicketOf"),S(actTicketOf,"actTicketOf"),c(actTicketOf,"actTicketOf");function setActTicketAside(e){const a=e.headers[exports.ACT_HEADER];typeof a=="string"&&TICKET_VALUE.test(a)&&(e[exports.ACT_TICKET]=a)}u(setActTicketAside,"setActTicketAside"),S(setActTicketAside,"setActTicketAside"),c(setActTicketAside,"setActTicketAside");const str=c(e=>typeof e=="string"&&e.length>0&&e.length<=256?e:void 0,"str"),keyOf=c(e=>{const a=str(e.sub);return a?`${a}\0${str(e.tid)??""}`:void 0},"keyOf"),safeName=c(e=>e.replace(/[^A-Za-z0-9._-]/g,"_").slice(0,120)||"_","safeName");function viewOf(e,a){const p=e.claims,d=Array.isArray(p.roles)?p.roles.filter(_=>typeof _=="string").slice(0,20):void 0,E=str(p.tid),T=str(p.email),x=str(p.name)??str(p.preferred_username);return{user:str(p.sub),...E?{tenant:E}:{},...T?{email:T}:{},...x?{name:x}:{},...d?.length?{roles:d}:{},host:e.host,firstSeenAt:e.firstSeenAt,lastSeenAt:e.lastSeenAt,mode:e.token&&e.tokenExp!==void 0&&e.tokenExp-TOKEN_MARGIN_S>a/1e3?"token":"identity"}}u(viewOf,"viewOf"),S(viewOf,"viewOf"),c(viewOf,"viewOf");function createActStore(e={}){const a=e.now??Date.now,p=new Map,d=new Map,E=new Map,T=new Set,x=c(t=>e.dir?path.join(e.dir,`${safeName(t)}.json`):void 0,"file"),_=c(t=>{let r=p.get(t);if(r)return r;r=new Map,p.set(t,r);const n=x(t);if(!n)return r;try{const o=JSON.parse(fs.readFileSync(n,"utf8"));for(const i of Array.isArray(o.identities)?o.identities:[]){const s=i;if(!s||typeof s!="object"||!s.claims||typeof s.claims!="object"||typeof s.host!="string"||typeof s.firstSeenAt!="number"||typeof s.lastSeenAt!="number")continue;const f=keyOf(s.claims);f&&r.set(f,{claims:s.claims,host:s.host,firstSeenAt:s.firstSeenAt,lastSeenAt:s.lastSeenAt})}}catch{}return r},"load"),g=c((t,r)=>{for(const[n,o]of t)r-o.lastSeenAt>exports.ACT_RETAIN_MS&&t.delete(n);if(t.size>exports.ACT_MAX_IDENTITIES){const n=[...t.entries()].sort((o,i)=>o[1].lastSeenAt-i[1].lastSeenAt).slice(0,t.size-exports.ACT_MAX_IDENTITIES);for(const[o]of n)t.delete(o)}},"prune"),w=c((t,r)=>{const n=x(t),o=p.get(t);if(T.delete(t),!(!n||!o)){E.set(t,r);try{fs.mkdirSync(path.dirname(n),{recursive:!0,mode:448});const i=[...o.values()].map(f=>({claims:f.claims,host:f.host,firstSeenAt:f.firstSeenAt,lastSeenAt:f.lastSeenAt})),s=`${n}.${process.pid}.tmp`;fs.writeFileSync(s,JSON.stringify({identities:i},null,1),{mode:384}),fs.renameSync(s,n)}catch{}}},"write"),I=c((t,r,n,o,i=a())=>{const s=keyOf(r);if(!s)return;const f=_(t),y={};for(const[k,v]of Object.entries(r))TIME_CLAIMS.has(k)||(y[k]=v);const m=f.get(s),l=typeof r.exp=="number"?r.exp:void 0,A=!m||m.host!==o||JSON.stringify(m.claims)!==JSON.stringify(y);f.set(s,{claims:y,host:o,firstSeenAt:m?.firstSeenAt??i,lastSeenAt:i,...n&&l!==void 0?{token:n,tokenExp:l}:m?.token?{token:m.token,tokenExp:m.tokenExp}:{}}),g(f,i),A&&T.add(t),(A||i-(E.get(t)??0)>=WRITE_EVERY_MS)&&w(t,i)},"remember"),C=c((t,r=a())=>{const n=_(t);return g(n,r),[...n.values()].sort((o,i)=>i.lastSeenAt-o.lastSeenAt).map(o=>viewOf(o,r))},"list");return{remember:I,list:C,mint:c((t,r,n=a())=>{const o=_(t);g(o,n);const i=r.user?.trim().toLowerCase(),s=r.tenant?.trim(),f=[...o.entries()].filter(([,l])=>{const A=l.claims;return s&&str(A.tid)!==s?!1:i?[A.sub,A.email,A.name,A.preferred_username].some(k=>typeof k=="string"&&k.toLowerCase()===i):!0}).sort((l,A)=>A[1].lastSeenAt-l[1].lastSeenAt)[0];if(!f){const l=C(t,n);return{error:l.length?`No signed-in identity matches${i?` user '${r.user}'`:""}${s?` in tenant '${s}'`:""} \u2014 ${l.length} known (see identities).`:"No one has signed in to this workspace's app since the gateway started remembering identities. Sign in once in the browser \u2014 the gateway keeps the identity it verified for 30 days.",identities:l}}for(const[l,A]of d)A.expiresAt<=n&&d.delete(l);d.size>=MAX_OPEN_TICKETS&&d.delete(d.keys().next().value);const y=(0,node_crypto_1.randomBytes)(32).toString("base64url"),m=n+exports.ACT_TICKET_MS;return d.set(y,{wsKey:t,key:f[0],expiresAt:m}),{ticket:y,expiresAt:m,identity:viewOf(f[1],n)}},"mint"),redeem:c((t,r,n=a())=>{const o=d.get(t);if(!o||(d.delete(t),o.expiresAt<=n||o.wsKey!==r))return;const i=_(r).get(o.key);if(!i)return;const s=viewOf(i,n);return s.mode==="token"?{token:i.token,claims:i.claims,view:s}:{claims:i.claims,view:s}},"redeem"),flush:c(()=>{const t=a();for(const r of[...T])w(r,t)},"flush")}}u(createActStore,"createActStore"),S(createActStore,"createActStore"),c(createActStore,"createActStore");
@@ -1 +1 @@
1
- "use strict";var _=Object.defineProperty;var w=(a,s)=>_(a,"name",{value:s,configurable:!0});var b=Object.defineProperty,p=w((a,s)=>b(a,"name",{value:s,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.declaredCallerIds=declaredCallerIds,exports.createEdgeAuth=createEdgeAuth;const manifest_1=require("../manifest"),act_1=require("./act"),chooser_1=require("./chooser"),dev_auth_1=require("./dev-auth"),edge_1=require("./edge"),NO_CALLER_IDS=new Set;function declaredCallerIds(a,s,c){const k=(a.registry?a.registry.allServices():a.services).filter(r=>c===void 0||r.wsKey===c),i=k.find(r=>r.project===s)?.decl.callerIds;if(!Array.isArray(i)||i.length===0)return NO_CALLER_IDS;const e=new Set(k.map(r=>r.project));for(const[r,n]of a.keyToProject)(c===void 0||a.keyToWorkspace?.get(r)===c)&&e.add(n);return new Set(i.filter(r=>typeof r=="string"&&r!==s&&!e.has(r)))}w(declaredCallerIds,"declaredCallerIds"),p(declaredCallerIds,"declaredCallerIds");const bearerOf=p(a=>{const s=a.headers.authorization,c=Array.isArray(s)?s[0]:s;return typeof c=="string"&&c.startsWith("Bearer ")?c.slice(7):void 0},"bearerOf");function createEdgeAuth(a,s,c,k){const{traceStep:i}=s;return{internal:p((e,r,n)=>{const v=String(e.headers["x-api-key"]??""),o=a.keyToProject.get(v);if(!o)return i(n,"auth",{mode:"x-api-key",ok:!1}),{ok:!1,status:401,reason:"unauthorized",detail:"Invalid or missing x-api-key for internal route."};const l=a.keyToWorkspace?.get(v),t=r.svc?.wsKey;if(l&&t&&l!==t)return i(n,"auth",{mode:"x-api-key",ok:!1,reason:"cross-workspace",caller:o,callerWorkspace:l,routeWorkspace:t}),{ok:!1,status:401,reason:"unauthorized",detail:"Invalid or missing x-api-key for internal route."};const d=(0,edge_1.claimedCallerIdOf)(e),h=d!==void 0&&d!==o&&declaredCallerIds(a,o,l).has(d)?d:o;e.headers["x-api-key-id"]=h,l?e.headers["x-api-key-workspace"]=l:delete e.headers["x-api-key-workspace"],e.__lensmcpCaller=o,delete e.headers["x-api-key"];const u=(0,edge_1.callerContextOf)(e);for(const[g,y]of Object.entries(u))e.headers[g]=y;return i(n,"auth",{mode:"x-api-key",ok:!0,caller:o,...h!==o?{as:h}:{},...d!==void 0&&d!==o&&h===o?{claimRefused:d}:{},...l?{callerWorkspace:l}:{},...u["x-tenant-id"]!==void 0?{callerTenant:!0}:{},...u["x-user-id"]!==void 0?{callerUser:!0}:{}}),{ok:!0,caller:o}},"internal"),public:p((e,r,n,v)=>{const o=r.wsKey??r.svc?.wsKey??a.wsKey,l=(0,act_1.actTicketOf)(e);let t;if(l!==void 0){if(t=k&&(0,chooser_1.isLoopbackRequest)(e)?k.redeem(l,o):void 0,!t)return i(n,"auth",{mode:"act",ok:!1}),{ok:!1,status:401,reason:"unauthorized",detail:"Unauthorized: the act ticket is unknown, spent, expired or for another workspace \u2014 ask for a new one (lensmcp call)."};t.token?e.headers.authorization=`Bearer ${t.token}`:delete e.headers.authorization}const d=p(u=>t?{act:u,as:t.view.user,...t.view.tenant?{tenant:t.view.tenant}:{}}:{},"actStep"),h=r.auth;if(h){const u=v??(0,edge_1.canonicalPath)(e.url??"/")??(e.url??"/").split("?")[0],g=(e.method??"GET").toUpperCase(),y=(0,manifest_1.authRuleFor)(h,u,g);if(y.mode==="jwt"){const x=String(e.headers.host??"").split(":")[0].toLowerCase();let m=t&&!t.token?"identity":"token",f=m==="identity"?t.claims:(0,dev_auth_1.verifyDevJwt)(e,c?.for(x));return!f&&t&&(m="identity",f=t.claims,delete e.headers.authorization),f?y.rule&&!(0,manifest_1.evalRule)(y.rule,(0,dev_auth_1.devAttrs)(e,f,u))?(i(n,"authz",{ok:!1,...d(m)}),{ok:!1,status:403,reason:"forbidden",detail:"Forbidden: insufficient permission"}):((0,dev_auth_1.stampIdentity)(e,f),k&&!t&&(0,act_1.fromBrowser)(e)&&k.remember(o,f,bearerOf(e),x),i(n,"auth",{mode:"jwt",ok:!0,...d(m)}),{ok:!0,claims:f}):(i(n,"auth",{mode:"jwt",ok:!1}),{ok:!1,status:401,reason:"unauthorized",detail:"Unauthorized: invalid or missing token"})}return i(n,"auth",{mode:y.mode,...d(t?.token?"token":"identity")}),{ok:!0}}return i(n,"auth",{mode:"public",unconfigured:!0,...d(t?.token?"token":"identity")}),{ok:!0}},"publicAuth")}}w(createEdgeAuth,"createEdgeAuth"),p(createEdgeAuth,"createEdgeAuth");
1
+ "use strict";var z=Object.defineProperty;var g=(r,o)=>z(r,"name",{value:o,configurable:!0});var _=Object.defineProperty,w=g((r,o)=>_(r,"name",{value:o,configurable:!0}),"w"),b=Object.defineProperty,p=w((r,o)=>b(r,"name",{value:o,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.declaredCallerIds=declaredCallerIds,exports.createEdgeAuth=createEdgeAuth;const manifest_1=require("../manifest"),act_1=require("./act"),chooser_1=require("./chooser"),dev_auth_1=require("./dev-auth"),edge_1=require("./edge"),NO_CALLER_IDS=new Set;function declaredCallerIds(r,o,c){const h=(r.registry?r.registry.allServices():r.services).filter(a=>c===void 0||a.wsKey===c),s=h.find(a=>a.project===o)?.decl.callerIds;if(!Array.isArray(s)||s.length===0)return NO_CALLER_IDS;const e=new Set(h.map(a=>a.project));for(const[a,n]of r.keyToProject)(c===void 0||r.keyToWorkspace?.get(a)===c)&&e.add(n);return new Set(s.filter(a=>typeof a=="string"&&a!==o&&!e.has(a)))}g(declaredCallerIds,"declaredCallerIds"),w(declaredCallerIds,"declaredCallerIds"),p(declaredCallerIds,"declaredCallerIds");const bearerOf=p(r=>{const o=r.headers.authorization,c=Array.isArray(o)?o[0]:o;return typeof c=="string"&&c.startsWith("Bearer ")?c.slice(7):void 0},"bearerOf");function createEdgeAuth(r,o,c,h){const{traceStep:s}=o;return{internal:p((e,a,n)=>{const m=String(e.headers["x-api-key"]??""),i=r.keyToProject.get(m);if(!i)return s(n,"auth",{mode:"x-api-key",ok:!1}),{ok:!1,status:401,reason:"unauthorized",detail:"Invalid or missing x-api-key for internal route."};const l=r.keyToWorkspace?.get(m),t=a.svc?.wsKey;if(l&&t&&l!==t)return s(n,"auth",{mode:"x-api-key",ok:!1,reason:"cross-workspace",caller:i,callerWorkspace:l,routeWorkspace:t}),{ok:!1,status:401,reason:"unauthorized",detail:"Invalid or missing x-api-key for internal route."};const d=(0,edge_1.claimedCallerIdOf)(e),k=d!==void 0&&d!==i&&declaredCallerIds(r,i,l).has(d)?d:i;e.headers["x-api-key-id"]=k,l?e.headers["x-api-key-workspace"]=l:delete e.headers["x-api-key-workspace"],e.__lensmcpCaller=i,delete e.headers["x-api-key"];const u=(0,edge_1.callerContextOf)(e);for(const[x,y]of Object.entries(u))e.headers[x]=y;return s(n,"auth",{mode:"x-api-key",ok:!0,caller:i,...k!==i?{as:k}:{},...d!==void 0&&d!==i&&k===i?{claimRefused:d}:{},...l?{callerWorkspace:l}:{},...u["x-tenant-id"]!==void 0?{callerTenant:!0}:{},...u["x-user-id"]!==void 0?{callerUser:!0}:{}}),{ok:!0,caller:i}},"internal"),public:p((e,a,n,m)=>{const i=a.wsKey??a.svc?.wsKey??r.wsKey,l=(0,act_1.actTicketOf)(e);let t;if(l!==void 0){if(t=h&&(0,chooser_1.isLoopbackRequest)(e)?h.redeem(l,i):void 0,!t)return s(n,"auth",{mode:"act",ok:!1}),{ok:!1,status:401,reason:"unauthorized",detail:"Unauthorized: the act ticket is unknown, spent, expired or for another workspace \u2014 ask for a new one (lensmcp call)."};t.token?e.headers.authorization=`Bearer ${t.token}`:delete e.headers.authorization}const d=p(u=>t?{act:u,as:t.view.user,...t.view.tenant?{tenant:t.view.tenant}:{}}:{},"actStep"),k=a.auth;if(k){const u=m??(0,edge_1.canonicalPath)(e.url??"/")??(e.url??"/").split("?")[0],x=(e.method??"GET").toUpperCase(),y=(0,manifest_1.authRuleFor)(k,u,x);if(y.mode==="jwt"){const j=String(e.headers.host??"").split(":")[0].toLowerCase();let v=t&&!t.token?"identity":"token",f=v==="identity"?t.claims:(0,dev_auth_1.verifyDevJwt)(e,c?.for(j));return!f&&t&&(v="identity",f=t.claims,delete e.headers.authorization),f?y.rule&&!(0,manifest_1.evalRule)(y.rule,(0,dev_auth_1.devAttrs)(e,f,u))?(s(n,"authz",{ok:!1,...d(v)}),{ok:!1,status:403,reason:"forbidden",detail:"Forbidden: insufficient permission"}):((0,dev_auth_1.stampIdentity)(e,f),h&&!t&&(0,act_1.fromBrowser)(e)&&h.remember(i,f,bearerOf(e),j),s(n,"auth",{mode:"jwt",ok:!0,...d(v)}),{ok:!0,claims:f}):(s(n,"auth",{mode:"jwt",ok:!1}),{ok:!1,status:401,reason:"unauthorized",detail:"Unauthorized: invalid or missing token"})}return s(n,"auth",{mode:y.mode,...d(t?.token?"token":"identity")}),{ok:!0}}return s(n,"auth",{mode:"public",unconfigured:!0,...d(t?.token?"token":"identity")}),{ok:!0}},"publicAuth")}}g(createEdgeAuth,"createEdgeAuth"),w(createEdgeAuth,"createEdgeAuth"),p(createEdgeAuth,"createEdgeAuth");
@@ -1,16 +1,16 @@
1
- "use strict";var m=Object.defineProperty;var l=(a,t)=>m(a,"name",{value:t,configurable:!0});var b=Object.defineProperty,i=l((a,t)=>b(a,"name",{value:t,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.isLoopbackRequest=isLoopbackRequest,exports.displayRoot=displayRoot,exports.renderChooserPage=renderChooserPage,exports.serveChooser=serveChooser;const node_os_1=require("node:os"),workspace_registry_1=require("./workspace-registry"),esc=i(a=>a.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t]),"esc");function isLoopbackRequest(a){const t=a.socket?.remoteAddress;if(!t)return!1;const o=t.startsWith("::ffff:")?t.slice(7):t;return o==="::1"||o==="127.0.0.1"||/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(o)}l(isLoopbackRequest,"isLoopbackRequest"),i(isLoopbackRequest,"isLoopbackRequest");function displayRoot(a,t=(0,node_os_1.homedir)()){const o=a.replace(/\/+$/,"").split("/").filter(Boolean),c=o.slice(-2).join("/");if(!c)return"/";const p=t!==""&&(a===t||a.startsWith(`${t}/`)),s=o.length>2;return p?s?`~/\u2026/${c}`:`~/${c}`:s?`\u2026/${c}`:`/${c}`}l(displayRoot,"displayRoot"),i(displayRoot,"displayRoot");function renderChooserPage(a,t){const o=a.map(e=>({...e,live:e.key===t||(0,workspace_registry_1.isWorkspaceLive)(e)})).sort((e,n)=>Number(n.live)-Number(e.live)||e.key.localeCompare(n.key)),c=new Set(o.map(e=>e.key)),p=i(e=>!!e.instance&&c.has(e.instance.baseKey),"nested"),s=o.filter(e=>!p(e)),x=i(e=>o.filter(n=>n.instance?.baseKey===e),"worktreesOf"),f=i(e=>e.key===t?'<span class="badge here">running here</span>':e.live?'<span class="badge live">live</span>':'<span class="badge off">offline</span>',"badgeOf"),h=i(e=>{const n=x(e);if(n.length===0)return"";const d=n.map(r=>{const g=`<span class="wt-name">${esc(r.instance?.name??r.key)}</span> ${f(r)}<span class="wt-apex">${esc(r.instance?.apex??"")}</span>`;return r.live?`<a class="wt is-live" href="${esc(r.base)}/">${g}<span class="open">Open \u2192</span></a>`:`<div class="wt is-off">${g}</div>`}).join(`
1
+ "use strict";var y=Object.defineProperty;var p=(o,t)=>y(o,"name",{value:t,configurable:!0});var m=Object.defineProperty,l=p((o,t)=>m(o,"name",{value:t,configurable:!0}),"l"),b=Object.defineProperty,i=l((o,t)=>b(o,"name",{value:t,configurable:!0}),"i");Object.defineProperty(exports,"__esModule",{value:!0}),exports.isLoopbackRequest=isLoopbackRequest,exports.displayRoot=displayRoot,exports.renderChooserPage=renderChooserPage,exports.serveChooser=serveChooser;const node_os_1=require("node:os"),workspace_registry_1=require("./workspace-registry"),esc=i(o=>o.replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t]),"esc");function isLoopbackRequest(o){const t=o.socket?.remoteAddress;if(!t)return!1;const a=t.startsWith("::ffff:")?t.slice(7):t;return a==="::1"||a==="127.0.0.1"||/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(a)}p(isLoopbackRequest,"isLoopbackRequest"),l(isLoopbackRequest,"isLoopbackRequest"),i(isLoopbackRequest,"isLoopbackRequest");function displayRoot(o,t=(0,node_os_1.homedir)()){const a=o.replace(/\/+$/,"").split("/").filter(Boolean),c=a.slice(-2).join("/");if(!c)return"/";const d=t!==""&&(o===t||o.startsWith(`${t}/`)),r=a.length>2;return d?r?`~/\u2026/${c}`:`~/${c}`:r?`\u2026/${c}`:`/${c}`}p(displayRoot,"displayRoot"),l(displayRoot,"displayRoot"),i(displayRoot,"displayRoot");function renderChooserPage(o,t){const a=o.map(e=>({...e,live:e.key===t||(0,workspace_registry_1.isWorkspaceLive)(e)})).sort((e,n)=>Number(n.live)-Number(e.live)||e.key.localeCompare(n.key)),c=new Set(a.map(e=>e.key)),d=i(e=>!!e.instance&&c.has(e.instance.baseKey),"nested"),r=a.filter(e=>!d(e)),h=i(e=>a.filter(n=>n.instance?.baseKey===e),"worktreesOf"),g=i(e=>e.key===t?'<span class="badge here">running here</span>':e.live?'<span class="badge live">live</span>':'<span class="badge off">offline</span>',"badgeOf"),u=i(e=>{const n=h(e);if(n.length===0)return"";const f=n.map(s=>{const x=`<span class="wt-name">${esc(s.instance?.name??s.key)}</span> ${g(s)}<span class="wt-apex">${esc(s.instance?.apex??"")}</span>`;return s.live?`<a class="wt is-live" href="${esc(s.base)}/">${x}<span class="open">Open \u2192</span></a>`:`<div class="wt is-off">${x}</div>`}).join(`
2
2
  `);return`
3
- <div class="worktrees"><div class="wt-head">Worktrees \xB7 ${n.filter(r=>r.live).length} running</div>
4
- ${d}
5
- </div>`},"worktreeList"),u=s.length===0?'<p class="empty">No workspaces registered yet. Start a gateway in a workspace (<code>lensmcp gateway start</code>) and it will appear here.</p>':s.map(e=>{const n=e.live?'<span class="open">Open dashboard \u2192</span>':'<span class="hint">start its gateway to open</span>',d=e.instance?`<div class="root">worktree <b>${esc(e.instance.name)}</b> of ${esc(e.instance.baseKey)} \xB7 ${esc(e.instance.apex)}</div>`:"",r=`<div class="card-main">
6
- <div class="key">${esc(e.key)} ${f(e)}</div>
7
- <div class="root">${esc(displayRoot(e.root))}</div>${d}
3
+ <div class="worktrees"><div class="wt-head">Worktrees \xB7 ${n.filter(s=>s.live).length} running</div>
4
+ ${f}
5
+ </div>`},"worktreeList"),v=r.length===0?'<p class="empty">No workspaces registered yet. Start a gateway in a workspace (<code>lensmcp gateway start</code>) and it will appear here.</p>':r.map(e=>{const n=e.live?'<span class="open">Open dashboard \u2192</span>':'<span class="hint">start its gateway to open</span>',f=e.instance?`<div class="root">worktree <b>${esc(e.instance.name)}</b> of ${esc(e.instance.baseKey)} \xB7 ${esc(e.instance.apex)}</div>`:"",s=`<div class="card-main">
6
+ <div class="key">${esc(e.key)} ${g(e)}</div>
7
+ <div class="root">${esc(displayRoot(e.root))}</div>${f}
8
8
  </div>
9
9
  <div class="card-action">${n}</div>`;return`<div class="group">${e.live?`<a class="card is-live" href="${esc(e.base)}/">
10
- ${r}
10
+ ${s}
11
11
  </a>`:`<div class="card is-off">
12
- ${r}
13
- </div>`}${h(e.key)}</div>`}).join(`
12
+ ${s}
13
+ </div>`}${u(e.key)}</div>`}).join(`
14
14
  `);return`<!doctype html>
15
15
  <html lang="en"><head>
16
16
  <meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
@@ -55,10 +55,10 @@
55
55
  <body><div class="wrap">
56
56
  <header>
57
57
  <h1>LensMCP workspaces</h1>
58
- <p class="sub">Pick a workspace to open its dashboard. ${s.filter(e=>e.live).length} live \xB7 ${s.length} known${o.length>s.length?` \xB7 ${o.length-s.length} worktree${o.length-s.length===1?"":"s"}`:""}.</p>
58
+ <p class="sub">Pick a workspace to open its dashboard. ${r.filter(e=>e.live).length} live \xB7 ${r.length} known${a.length>r.length?` \xB7 ${a.length-r.length} worktree${a.length-r.length===1?"":"s"}`:""}.</p>
59
59
  </header>
60
60
  <div class="list">
61
- ${u}
61
+ ${v}
62
62
  </div>
63
63
  <footer>Served by the gateway on <code>lensmcp.local</code>. This list updates as gateways start and stop.</footer>
64
- </div></body></html>`}l(renderChooserPage,"renderChooserPage"),i(renderChooserPage,"renderChooserPage");function serveChooser(a,t,o){if(o&&!isLoopbackRequest(o)){a.writeHead(404,{"content-type":"text/plain; charset=utf-8","cache-control":"no-store"}),a.end("not found");return}const c=renderChooserPage((0,workspace_registry_1.readWorkspaces)(),t);a.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),a.end(c)}l(serveChooser,"serveChooser"),i(serveChooser,"serveChooser");
64
+ </div></body></html>`}p(renderChooserPage,"renderChooserPage"),l(renderChooserPage,"renderChooserPage"),i(renderChooserPage,"renderChooserPage");function serveChooser(o,t,a){if(a&&!isLoopbackRequest(a)){o.writeHead(404,{"content-type":"text/plain; charset=utf-8","cache-control":"no-store"}),o.end("not found");return}const c=renderChooserPage((0,workspace_registry_1.readWorkspaces)(),t);o.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),o.end(c)}p(serveChooser,"serveChooser"),l(serveChooser,"serveChooser"),i(serveChooser,"serveChooser");
@@ -1,2 +1,2 @@
1
- "use strict";var b=Object.defineProperty;var g=(s,r)=>b(s,"name",{value:r,configurable:!0});var G=Object.defineProperty,u=g((s,r)=>G(s,"name",{value:r,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.clusterVersion=void 0,exports.instanceSummary=instanceSummary,exports.controlSocketPath=controlSocketPath,exports.versionAtLoad=versionAtLoad,exports.readClusterVersion=readClusterVersion,exports.ensureOwnerOnlyDir=ensureOwnerOnlyDir,exports.startControlServer=startControlServer;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),http=tslib_1.__importStar(require("node:http")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path")),discovery_1=require("./discovery"),guest_graph_1=require("./guest-graph"),guest_replay_1=require("./guest-replay"),registration_guards_1=require("./registration-guards"),scope_1=require("./scope"),service_keys_1=require("./service-keys"),workspace_log_1=require("./workspace-log"),workspace_middleware_1=require("./workspace-middleware");function instanceSummary(s){const r=s?.instance;return r?{instance:r.name,baseKey:r.baseKey,apex:r.apex,baseApex:r.baseApex,...r.frozen?{frozen:!0}:{}}:{}}g(instanceSummary,"instanceSummary"),u(instanceSummary,"instanceSummary");function controlSocketPath(){const s=process.env.LENSMCP_HOME||os.homedir();return path.join(s,".lensmcp","control.sock")}g(controlSocketPath,"controlSocketPath"),u(controlSocketPath,"controlSocketPath");const CONTROL_BODY_BYTES=1e6;class BodyTooLarge extends Error{static{g(this,"BodyTooLarge")}static{u(this,"BodyTooLarge")}constructor(r){super(`body too large (over ${r} bytes)`),this.limit=r}}exports.clusterVersion=versionAtLoad(()=>readClusterVersion(__dirname));function versionAtLoad(s){const r=s();return()=>r}g(versionAtLoad,"versionAtLoad"),u(versionAtLoad,"versionAtLoad");function readClusterVersion(s){let r=s;for(let w=0;w<6;w++){const h=path.join(r,"package.json");if(fs.existsSync(h))try{const l=JSON.parse(fs.readFileSync(h,"utf8"));if(l.name==="@lensmcp/cluster"&&typeof l.version=="string")return l.version}catch{}const a=path.dirname(r);if(a===r)break;r=a}}g(readClusterVersion,"readClusterVersion"),u(readClusterVersion,"readClusterVersion");function readJsonBody(s,r=CONTROL_BODY_BYTES){return new Promise((w,h)=>{const a=[];let l=0,k=!1;s.on("data",m=>{if(!k){if(l+=m.length,l>r){k=!0,a.length=0,h(new BodyTooLarge(r));return}a.push(m)}}),s.on("end",()=>{if(k)return;const m=Buffer.concat(a).toString("utf8");try{w({value:m?JSON.parse(m):{},bytes:l})}catch(S){h(S)}}),s.on("error",h)})}g(readJsonBody,"readJsonBody"),u(readJsonBody,"readJsonBody");function graphShare(s,r){return r-Buffer.byteLength(JSON.stringify({...s,projectGraph:null}))}g(graphShare,"graphShare"),u(graphShare,"graphShare");function graphVerdict(s){return s?s.refused===void 0?{forwarded:!0,accepted:!0}:{forwarded:!0,accepted:!1,reason:s.refused}:{forwarded:!1,accepted:!1}}g(graphVerdict,"graphVerdict"),u(graphVerdict,"graphVerdict");function ensureOwnerOnlyDir(s){try{fs.mkdirSync(s,{recursive:!0,mode:448})}catch{}try{const r=fs.lstatSync(s);return r.isDirectory()?((r.mode&63)!==0&&fs.chmodSync(s,448),!0):!1}catch{return!1}}g(ensureOwnerOnlyDir,"ensureOwnerOnlyDir"),u(ensureOwnerOnlyDir,"ensureOwnerOnlyDir");function startControlServer(s){const{rt:r}=s,w=controlSocketPath(),h=path.dirname(w);ensureOwnerOnlyDir(h)||console.warn(`[gateway] control home ${h} is not a usable owner-only directory \u2014 refusing to expose the control plane there.`);try{fs.unlinkSync(w)}catch{}const a=u((e,n,i)=>{e.writeHead(n,{"content-type":"application/json"}),e.end(JSON.stringify(i))},"send"),l=u(async(e,n)=>{if(!e.wsKey||!e.root)return{status:400,json:{error:"wsKey and root are required"}};const i=e.projects??{},t=(0,discovery_1.projectSourceRoots)(e.root,i,e.projectDependencies),o=(0,scope_1.readLensScope)(e.root),c=o.key===e.wsKey,y=c&&o.sockNs!==e.wsKey?o.sockNs:void 0,{routes:d,services:p,instance:f}=(0,discovery_1.discoverRoutes)(e.root,i,void 0,e.wsKey,t,y,c?o.instance:void 0),O=(0,workspace_middleware_1.findGatewayMiddleware)(e.root,i),$={wsKey:e.wsKey,...y?{sockNs:y}:{},root:e.root,routes:d,services:p,...f?{instance:f}:{},...O?{middleware:O}:{}},j=(0,registration_guards_1.refuseRegistration)(r.registry,$);if(j)return console.warn(`[gateway] refused to register '${e.wsKey}' from ${e.root}: ${j.error}`),{status:409,json:j};try{const v=(0,service_keys_1.adoptServiceKeys)(r,e.root,p,e.wsKey);v.added.length>0&&console.log(`[gateway] adopted east-west keys for ${e.wsKey}: ${v.added.join(", ")}`),v.regenerated.length>0&&console.warn(`[gateway] ${e.root} carried another workspace's east-west keys (a copied key file) \u2014 new keys for ${e.wsKey}: ${v.regenerated.join(", ")}`)}catch(v){console.error(`[gateway] could not adopt east-west keys for ${e.wsKey}: ${v.message}`)}try{(0,workspace_log_1.workspaceLogWriter)(e.root)?.(`[gateway] ${new Date().toISOString()} this workspace ('${e.wsKey}') is served by the daemon at ${r.root} (pid ${process.pid}); its gateway-level log is ${path.join(r.root,".lensmcp","gateway.log")}. Pod output for this workspace follows here. Attach live with \`lensmcp logs <service>\`.
2
- `)}catch{}let K;if(r.graphStores){const v={root:e.root,daemonRoot:r.root,otherRoots:r.registry.keys().filter(_=>_!==e.wsKey).flatMap(_=>r.registry.get(_)?.root??[])};K=e.projectGraph===void 0?void 0:(0,guest_graph_1.admitForwardedGraph)(e.projectGraph,{...v,bytes:graphShare(e,n)}),K?.refused!==void 0&&console.warn(`[gateway] refused the project graph '${e.wsKey}' forwarded from ${e.root}: ${K.refused} \u2014 its services start through \`nx run\` until the gateway computes it`),(0,registration_guards_1.sameRoot)(e.root,r.root)||r.graphStores.set((0,guest_graph_1.createGuestGraphStore)({wsKey:e.wsKey,root:e.root,...K?{admission:K}:{},context:v}))}return r.registry.register($),await s.onRegister?.($),r.rebuildRoutes(),r.root&&!(0,registration_guards_1.sameRoot)(e.root,r.root)&&(0,guest_replay_1.recordGuest)({wsKey:e.wsKey,root:e.root,projects:i,...e.projectDependencies?{projectDependencies:e.projectDependencies}:{},daemonRoot:r.root,registeredAt:new Date().toISOString()}),{status:200,json:{ok:!0,wsKey:e.wsKey,routes:d.length,services:p.length,workspaces:r.registry.keys(),...r.graphStores?{projectGraph:graphVerdict(K)}:{}}}},"register"),k=u((e,n)=>{const i=r.registry.get(e);if(!i)return{error:`no workspace '${e}' is registered`,workspaces:r.registry.keys()};const t=i.services.find(o=>o.project===n);return t?{svc:t}:{error:`'${e}' has no service '${n}'`,services:i.services.map(o=>o.project)}},"findService"),m=u(e=>({wsKey:e.wsKey,service:e.project,state:e.state,...e.generation!==void 0?{generation:e.generation}:{},...e.restart?{restart:e.restart}:{}}),"restartView"),S=http.createServer((e,n)=>{(async()=>{try{const i=(e.url??"").split("?")[0];if(e.method==="GET"&&i==="/list")return a(n,200,{workspaces:r.registry.keys().map(t=>{const o=r.registry.get(t);return{key:t,root:o?.root,routes:o?.routes.length??0,services:o?.services.length??0,...instanceSummary(o)}})});if(e.method==="GET"&&i==="/status"){const t=(0,exports.clusterVersion)();return a(n,200,{daemon:{pid:process.pid,wsKey:r.wsKey,...t?{version:t}:{}},workspaces:r.registry.keys().map(o=>{const c=r.registry.get(o);return{key:o,root:c?.root,routes:c?.routes.length??0,services:c?.services.length??0,isDaemon:o===r.wsKey,...instanceSummary(c)}}),services:r.registry.allServices().map(o=>({project:o.project,wsKey:o.wsKey,host:o.decl.host,state:o.state,...o.generation!==void 0?{generation:o.generation}:{},...o.restart?{restart:o.restart}:{}}))})}if(e.method==="GET"&&i==="/instance-env"){const t=new URL(e.url??"/","http://control").searchParams.get("wsKey")??"",o=r.registry.get(t);return o?o.instance?a(n,200,{wsKey:t,root:o.root,...instanceSummary(o),env:o.instance.env}):a(n,404,{error:`'${t}' is not an instance`}):a(n,404,{error:`no workspace '${t}' is registered`})}if(i==="/restart"&&(e.method==="POST"||e.method==="GET")){const t=e.method==="GET"?Object.fromEntries(new URL(e.url??"/","http://control").searchParams):(await readJsonBody(e)).value??{},o=typeof t.wsKey=="string"?t.wsKey:"",c=typeof t.service=="string"?t.service:"";if(!o||!c)return a(n,400,{error:"wsKey and service are required"});const y=k(o,c);if("error"in y)return a(n,404,y);const d=y.svc;if(e.method==="GET")return a(n,200,m(d));if(!s.restartService)return a(n,501,{error:"this gateway cannot restart a service"});const p=typeof t.reason=="string"&&t.reason.trim()?t.reason.trim().slice(0,200):"asked for",f=s.restartService(d,{hard:t.hard===!0,reason:p});return"refused"in f?a(n,409,{error:f.refused,...m(d)}):a(n,202,{ok:!0,already:f.already,...m(d)})}if(e.method==="GET"&&i==="/identities"||e.method==="POST"&&i==="/act"){const t=e.method==="GET"?Object.fromEntries(new URL(e.url??"/","http://control").searchParams):(await readJsonBody(e)).value??{},o=typeof t.wsKey=="string"?t.wsKey:"";if(!o)return a(n,400,{error:"wsKey is required"});if(!r.registry.get(o)&&o!==r.wsKey)return a(n,404,{error:`no workspace '${o}' is registered`,workspaces:r.registry.keys()});if(!s.act)return a(n,501,{error:"acting as a signed-in user is turned off on this gateway (LENSMCP_GW_ACT=0)"});if(e.method==="GET")return a(n,200,{wsKey:o,identities:s.act.list(o)});const c=u(f=>typeof t[f]=="string"&&t[f].trim()?t[f].trim().slice(0,256):void 0,"pick"),y=c("user"),d=c("tenant"),p=s.act.mint(o,{...y?{user:y}:{},...d?{tenant:d}:{}});return"error"in p?a(n,404,{wsKey:o,...p}):a(n,200,{wsKey:o,...p})}if(e.method==="POST"&&i==="/register"){const{value:t,bytes:o}=await readJsonBody(e,CONTROL_BODY_BYTES+guest_graph_1.MAX_FORWARDED_GRAPH_BYTES),c=await l(t,o);return a(n,c.status,c.json)}if(e.method==="POST"&&i==="/unregister"){const t=(await readJsonBody(e)).value;if(!t.wsKey)return a(n,400,{error:"wsKey is required"});const o=(0,registration_guards_1.refuseUnregistration)(r.registry,{wsKey:t.wsKey,...t.root?{root:t.root}:{}},r.wsKey);if(o)return console.warn(`[gateway] refused to unregister '${t.wsKey}'${t.root?` for ${t.root}`:""}: ${o.error}`),a(n,409,o);const c=r.registry.unregister(t.wsKey);if(c){for(const y of c.services){const d=(0,service_keys_1.serviceKeyId)(y.wsKey??t.wsKey,y.project),p=r.serviceKeys[d];p&&(delete r.serviceKeys[d],r.keyToProject.delete(p),r.keyToWorkspace?.delete(p))}for(const y of c.services)s.killService(y,"workspace unregistered");r.graphStores?.delete(c.root),(0,guest_replay_1.forgetGuest)(t.wsKey),s.onUnregister?.(c)}return r.rebuildRoutes(),a(n,200,{ok:!0,removed:!!c,workspaces:r.registry.keys()})}a(n,404,{error:"not found"})}catch(i){if(i instanceof BodyTooLarge)return e.resume(),a(n,413,{error:i.message});a(n,500,{error:i.message})}})()});return S.listen(w,()=>{try{fs.chmodSync(w,384)}catch(e){console.warn(`[gateway] could not restrict ${w} to 0600:`,e.message)}}),{socketPath:w,async replay(){const{replay:e,gone:n}=(0,guest_replay_1.guestsToReplay)(r.root,(0,guest_replay_1.readGuests)()),i={replayed:[],refused:[],gone:n.map(t=>t.wsKey)};for(const t of n)(0,guest_replay_1.forgetGuest)(t.wsKey),console.log(`[gateway] not re-hosting '${t.wsKey}': ${t.root} is no longer a workspace \u2014 forgotten`);for(const t of e)if(!r.registry.has(t.wsKey))try{const o=await l({wsKey:t.wsKey,root:t.root,projects:t.projects,...t.projectDependencies?{projectDependencies:t.projectDependencies}:{}},0);o.status===200?(i.replayed.push(t.wsKey),console.log(`[gateway] re-hosted '${t.wsKey}' (${t.root}) \u2014 registered before this daemon restarted`)):(i.refused.push(t.wsKey),console.warn(`[gateway] could not re-host '${t.wsKey}' (${t.root}): ${JSON.stringify(o.json)} \u2014 \`lensmcp gateway start\` there`))}catch(o){i.refused.push(t.wsKey),console.warn(`[gateway] could not re-host '${t.wsKey}' (${t.root}): ${o.message}`)}return i},close:u(()=>{S.close();try{fs.unlinkSync(w)}catch{}},"close")}}g(startControlServer,"startControlServer"),u(startControlServer,"startControlServer");
1
+ "use strict";var P=Object.defineProperty;var l=(s,r)=>P(s,"name",{value:r,configurable:!0});var b=Object.defineProperty,g=l((s,r)=>b(s,"name",{value:r,configurable:!0}),"g"),G=Object.defineProperty,u=g((s,r)=>G(s,"name",{value:r,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.clusterVersion=void 0,exports.instanceSummary=instanceSummary,exports.controlSocketPath=controlSocketPath,exports.versionAtLoad=versionAtLoad,exports.readClusterVersion=readClusterVersion,exports.ensureOwnerOnlyDir=ensureOwnerOnlyDir,exports.startControlServer=startControlServer;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),http=tslib_1.__importStar(require("node:http")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path")),discovery_1=require("./discovery"),guest_graph_1=require("./guest-graph"),guest_replay_1=require("./guest-replay"),registration_guards_1=require("./registration-guards"),scope_1=require("./scope"),service_keys_1=require("./service-keys"),workspace_log_1=require("./workspace-log"),workspace_middleware_1=require("./workspace-middleware");function instanceSummary(s){const r=s?.instance;return r?{instance:r.name,baseKey:r.baseKey,apex:r.apex,baseApex:r.baseApex,...r.frozen?{frozen:!0}:{}}:{}}l(instanceSummary,"instanceSummary"),g(instanceSummary,"instanceSummary"),u(instanceSummary,"instanceSummary");function controlSocketPath(){const s=process.env.LENSMCP_HOME||os.homedir();return path.join(s,".lensmcp","control.sock")}l(controlSocketPath,"controlSocketPath"),g(controlSocketPath,"controlSocketPath"),u(controlSocketPath,"controlSocketPath");const CONTROL_BODY_BYTES=1e6;class BodyTooLarge extends Error{static{l(this,"BodyTooLarge")}static{g(this,"BodyTooLarge")}static{u(this,"BodyTooLarge")}constructor(r){super(`body too large (over ${r} bytes)`),this.limit=r}}exports.clusterVersion=versionAtLoad(()=>readClusterVersion(__dirname));function versionAtLoad(s){const r=s();return()=>r}l(versionAtLoad,"versionAtLoad"),g(versionAtLoad,"versionAtLoad"),u(versionAtLoad,"versionAtLoad");function readClusterVersion(s){let r=s;for(let w=0;w<6;w++){const m=path.join(r,"package.json");if(fs.existsSync(m))try{const f=JSON.parse(fs.readFileSync(m,"utf8"));if(f.name==="@lensmcp/cluster"&&typeof f.version=="string")return f.version}catch{}const a=path.dirname(r);if(a===r)break;r=a}}l(readClusterVersion,"readClusterVersion"),g(readClusterVersion,"readClusterVersion"),u(readClusterVersion,"readClusterVersion");function readJsonBody(s,r=CONTROL_BODY_BYTES){return new Promise((w,m)=>{const a=[];let f=0,S=!1;s.on("data",v=>{if(!S){if(f+=v.length,f>r){S=!0,a.length=0,m(new BodyTooLarge(r));return}a.push(v)}}),s.on("end",()=>{if(S)return;const v=Buffer.concat(a).toString("utf8");try{w({value:v?JSON.parse(v):{},bytes:f})}catch(j){m(j)}}),s.on("error",m)})}l(readJsonBody,"readJsonBody"),g(readJsonBody,"readJsonBody"),u(readJsonBody,"readJsonBody");function graphShare(s,r){return r-Buffer.byteLength(JSON.stringify({...s,projectGraph:null}))}l(graphShare,"graphShare"),g(graphShare,"graphShare"),u(graphShare,"graphShare");function graphVerdict(s){return s?s.refused===void 0?{forwarded:!0,accepted:!0}:{forwarded:!0,accepted:!1,reason:s.refused}:{forwarded:!1,accepted:!1}}l(graphVerdict,"graphVerdict"),g(graphVerdict,"graphVerdict"),u(graphVerdict,"graphVerdict");function ensureOwnerOnlyDir(s){try{fs.mkdirSync(s,{recursive:!0,mode:448})}catch{}try{const r=fs.lstatSync(s);return r.isDirectory()?((r.mode&63)!==0&&fs.chmodSync(s,448),!0):!1}catch{return!1}}l(ensureOwnerOnlyDir,"ensureOwnerOnlyDir"),g(ensureOwnerOnlyDir,"ensureOwnerOnlyDir"),u(ensureOwnerOnlyDir,"ensureOwnerOnlyDir");function startControlServer(s){const{rt:r}=s,w=controlSocketPath(),m=path.dirname(w);ensureOwnerOnlyDir(m)||console.warn(`[gateway] control home ${m} is not a usable owner-only directory \u2014 refusing to expose the control plane there.`);try{fs.unlinkSync(w)}catch{}const a=u((e,n,i)=>{e.writeHead(n,{"content-type":"application/json"}),e.end(JSON.stringify(i))},"send"),f=u(async(e,n)=>{if(!e.wsKey||!e.root)return{status:400,json:{error:"wsKey and root are required"}};const i=e.projects??{},t=(0,discovery_1.projectSourceRoots)(e.root,i,e.projectDependencies),o=(0,scope_1.readLensScope)(e.root),c=o.key===e.wsKey,y=c&&o.sockNs!==e.wsKey?o.sockNs:void 0,{routes:d,services:p,instance:h}=(0,discovery_1.discoverRoutes)(e.root,i,void 0,e.wsKey,t,y,c?o.instance:void 0),T=(0,workspace_middleware_1.findGatewayMiddleware)(e.root,i),$={wsKey:e.wsKey,...y?{sockNs:y}:{},root:e.root,routes:d,services:p,...h?{instance:h}:{},...T?{middleware:T}:{}},_=(0,registration_guards_1.refuseRegistration)(r.registry,$);if(_)return console.warn(`[gateway] refused to register '${e.wsKey}' from ${e.root}: ${_.error}`),{status:409,json:_};try{const K=(0,service_keys_1.adoptServiceKeys)(r,e.root,p,e.wsKey);K.added.length>0&&console.log(`[gateway] adopted east-west keys for ${e.wsKey}: ${K.added.join(", ")}`),K.regenerated.length>0&&console.warn(`[gateway] ${e.root} carried another workspace's east-west keys (a copied key file) \u2014 new keys for ${e.wsKey}: ${K.regenerated.join(", ")}`)}catch(K){console.error(`[gateway] could not adopt east-west keys for ${e.wsKey}: ${K.message}`)}try{(0,workspace_log_1.workspaceLogWriter)(e.root)?.(`[gateway] ${new Date().toISOString()} this workspace ('${e.wsKey}') is served by the daemon at ${r.root} (pid ${process.pid}); its gateway-level log is ${path.join(r.root,".lensmcp","gateway.log")}. Pod output for this workspace follows here. Attach live with \`lensmcp logs <service>\`.
2
+ `)}catch{}let k;if(r.graphStores){const K={root:e.root,daemonRoot:r.root,otherRoots:r.registry.keys().filter(O=>O!==e.wsKey).flatMap(O=>r.registry.get(O)?.root??[])};k=e.projectGraph===void 0?void 0:(0,guest_graph_1.admitForwardedGraph)(e.projectGraph,{...K,bytes:graphShare(e,n)}),k?.refused!==void 0&&console.warn(`[gateway] refused the project graph '${e.wsKey}' forwarded from ${e.root}: ${k.refused} \u2014 its services start through \`nx run\` until the gateway computes it`),(0,registration_guards_1.sameRoot)(e.root,r.root)||r.graphStores.set((0,guest_graph_1.createGuestGraphStore)({wsKey:e.wsKey,root:e.root,...k?{admission:k}:{},context:K}))}return r.registry.register($),await s.onRegister?.($),r.rebuildRoutes(),r.root&&!(0,registration_guards_1.sameRoot)(e.root,r.root)&&(0,guest_replay_1.recordGuest)({wsKey:e.wsKey,root:e.root,projects:i,...e.projectDependencies?{projectDependencies:e.projectDependencies}:{},daemonRoot:r.root,registeredAt:new Date().toISOString()}),{status:200,json:{ok:!0,wsKey:e.wsKey,routes:d.length,services:p.length,workspaces:r.registry.keys(),...r.graphStores?{projectGraph:graphVerdict(k)}:{}}}},"register"),S=u((e,n)=>{const i=r.registry.get(e);if(!i)return{error:`no workspace '${e}' is registered`,workspaces:r.registry.keys()};const t=i.services.find(o=>o.project===n);return t?{svc:t}:{error:`'${e}' has no service '${n}'`,services:i.services.map(o=>o.project)}},"findService"),v=u(e=>({wsKey:e.wsKey,service:e.project,state:e.state,...e.generation!==void 0?{generation:e.generation}:{},...e.restart?{restart:e.restart}:{}}),"restartView"),j=http.createServer((e,n)=>{(async()=>{try{const i=(e.url??"").split("?")[0];if(e.method==="GET"&&i==="/list")return a(n,200,{workspaces:r.registry.keys().map(t=>{const o=r.registry.get(t);return{key:t,root:o?.root,routes:o?.routes.length??0,services:o?.services.length??0,...instanceSummary(o)}})});if(e.method==="GET"&&i==="/status"){const t=(0,exports.clusterVersion)();return a(n,200,{daemon:{pid:process.pid,wsKey:r.wsKey,...t?{version:t}:{}},workspaces:r.registry.keys().map(o=>{const c=r.registry.get(o);return{key:o,root:c?.root,routes:c?.routes.length??0,services:c?.services.length??0,isDaemon:o===r.wsKey,...instanceSummary(c)}}),services:r.registry.allServices().map(o=>({project:o.project,wsKey:o.wsKey,host:o.decl.host,state:o.state,...o.generation!==void 0?{generation:o.generation}:{},...o.restart?{restart:o.restart}:{}}))})}if(e.method==="GET"&&i==="/instance-env"){const t=new URL(e.url??"/","http://control").searchParams.get("wsKey")??"",o=r.registry.get(t);return o?o.instance?a(n,200,{wsKey:t,root:o.root,...instanceSummary(o),env:o.instance.env}):a(n,404,{error:`'${t}' is not an instance`}):a(n,404,{error:`no workspace '${t}' is registered`})}if(i==="/restart"&&(e.method==="POST"||e.method==="GET")){const t=e.method==="GET"?Object.fromEntries(new URL(e.url??"/","http://control").searchParams):(await readJsonBody(e)).value??{},o=typeof t.wsKey=="string"?t.wsKey:"",c=typeof t.service=="string"?t.service:"";if(!o||!c)return a(n,400,{error:"wsKey and service are required"});const y=S(o,c);if("error"in y)return a(n,404,y);const d=y.svc;if(e.method==="GET")return a(n,200,v(d));if(!s.restartService)return a(n,501,{error:"this gateway cannot restart a service"});const p=typeof t.reason=="string"&&t.reason.trim()?t.reason.trim().slice(0,200):"asked for",h=s.restartService(d,{hard:t.hard===!0,reason:p});return"refused"in h?a(n,409,{error:h.refused,...v(d)}):a(n,202,{ok:!0,already:h.already,...v(d)})}if(e.method==="GET"&&i==="/identities"||e.method==="POST"&&i==="/act"){const t=e.method==="GET"?Object.fromEntries(new URL(e.url??"/","http://control").searchParams):(await readJsonBody(e)).value??{},o=typeof t.wsKey=="string"?t.wsKey:"";if(!o)return a(n,400,{error:"wsKey is required"});if(!r.registry.get(o)&&o!==r.wsKey)return a(n,404,{error:`no workspace '${o}' is registered`,workspaces:r.registry.keys()});if(!s.act)return a(n,501,{error:"acting as a signed-in user is turned off on this gateway (LENSMCP_GW_ACT=0)"});if(e.method==="GET")return a(n,200,{wsKey:o,identities:s.act.list(o)});const c=u(h=>typeof t[h]=="string"&&t[h].trim()?t[h].trim().slice(0,256):void 0,"pick"),y=c("user"),d=c("tenant"),p=s.act.mint(o,{...y?{user:y}:{},...d?{tenant:d}:{}});return"error"in p?a(n,404,{wsKey:o,...p}):a(n,200,{wsKey:o,...p})}if(e.method==="POST"&&i==="/register"){const{value:t,bytes:o}=await readJsonBody(e,CONTROL_BODY_BYTES+guest_graph_1.MAX_FORWARDED_GRAPH_BYTES),c=await f(t,o);return a(n,c.status,c.json)}if(e.method==="POST"&&i==="/unregister"){const t=(await readJsonBody(e)).value;if(!t.wsKey)return a(n,400,{error:"wsKey is required"});const o=(0,registration_guards_1.refuseUnregistration)(r.registry,{wsKey:t.wsKey,...t.root?{root:t.root}:{}},r.wsKey);if(o)return console.warn(`[gateway] refused to unregister '${t.wsKey}'${t.root?` for ${t.root}`:""}: ${o.error}`),a(n,409,o);const c=r.registry.unregister(t.wsKey);if(c){for(const y of c.services){const d=(0,service_keys_1.serviceKeyId)(y.wsKey??t.wsKey,y.project),p=r.serviceKeys[d];p&&(delete r.serviceKeys[d],r.keyToProject.delete(p),r.keyToWorkspace?.delete(p))}for(const y of c.services)s.killService(y,"workspace unregistered");r.graphStores?.delete(c.root),(0,guest_replay_1.forgetGuest)(t.wsKey),s.onUnregister?.(c)}return r.rebuildRoutes(),a(n,200,{ok:!0,removed:!!c,workspaces:r.registry.keys()})}a(n,404,{error:"not found"})}catch(i){if(i instanceof BodyTooLarge)return e.resume(),a(n,413,{error:i.message});a(n,500,{error:i.message})}})()});return j.listen(w,()=>{try{fs.chmodSync(w,384)}catch(e){console.warn(`[gateway] could not restrict ${w} to 0600:`,e.message)}}),{socketPath:w,async replay(){const{replay:e,gone:n}=(0,guest_replay_1.guestsToReplay)(r.root,(0,guest_replay_1.readGuests)()),i={replayed:[],refused:[],gone:n.map(t=>t.wsKey)};for(const t of n)(0,guest_replay_1.forgetGuest)(t.wsKey),console.log(`[gateway] not re-hosting '${t.wsKey}': ${t.root} is no longer a workspace \u2014 forgotten`);for(const t of e)if(!r.registry.has(t.wsKey))try{const o=await f({wsKey:t.wsKey,root:t.root,projects:t.projects,...t.projectDependencies?{projectDependencies:t.projectDependencies}:{}},0);o.status===200?(i.replayed.push(t.wsKey),console.log(`[gateway] re-hosted '${t.wsKey}' (${t.root}) \u2014 registered before this daemon restarted`)):(i.refused.push(t.wsKey),console.warn(`[gateway] could not re-host '${t.wsKey}' (${t.root}): ${JSON.stringify(o.json)} \u2014 \`lensmcp gateway start\` there`))}catch(o){i.refused.push(t.wsKey),console.warn(`[gateway] could not re-host '${t.wsKey}' (${t.root}): ${o.message}`)}return i},close:u(()=>{j.close();try{fs.unlinkSync(w)}catch{}},"close")}}l(startControlServer,"startControlServer"),g(startControlServer,"startControlServer"),u(startControlServer,"startControlServer");
@@ -1 +1 @@
1
- "use strict";var h=Object.defineProperty;var a=(e,r)=>h(e,"name",{value:r,configurable:!0});var l=Object.defineProperty,u=a((e,r)=>l(e,"name",{value:r,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.devAttrs=void 0,exports.verifyDevJwt=verifyDevJwt,exports.stampIdentity=stampIdentity;const node_crypto_1=require("node:crypto"),edge_1=require("./edge");function bearerToken(e){const r=Array.isArray(e.headers.authorization)?e.headers.authorization[0]:e.headers.authorization,t=String(r??"");return t.startsWith("Bearer ")?t.slice(7):void 0}a(bearerToken,"bearerToken"),u(bearerToken,"bearerToken");function verifyDevJwt(e,r){const t=bearerToken(e);if(!t)return;const[s,n,f]=t.split(".");if(!s||!n||!f)return;if(r)return r.verify(t);let o;try{o=JSON.parse(Buffer.from(s,"base64url").toString()).alg}catch{return}if(typeof o=="string"&&o!=="HS256"){if(process.env.LENSMCP_GW_DEV_JWT_INSECURE_DECODE!=="1")return;try{const i=JSON.parse(Buffer.from(n,"base64url").toString());return typeof i.exp=="number"&&Date.now()/1e3>i.exp?void 0:i}catch{return}}const d=process.env.AUTH_JWT_SECRET??"tetros-dev-secret",y=(0,node_crypto_1.createHmac)("sha256",d).update(`${s}.${n}`).digest("base64url"),p=Buffer.from(f),c=Buffer.from(y);if(!(p.length!==c.length||!(0,node_crypto_1.timingSafeEqual)(p,c)))try{const i=JSON.parse(Buffer.from(n,"base64url").toString());return typeof i.exp=="number"&&Date.now()/1e3>i.exp?void 0:i}catch{return}}a(verifyDevJwt,"verifyDevJwt"),u(verifyDevJwt,"verifyDevJwt");function stampIdentity(e,r){const t=u((f,o)=>{o!=null&&o!==""&&(e.headers[f]=String(o))},"set");t("x-user-id",r.sub),t("x-tenant-id",r.tid);const s=r.roles;Array.isArray(s)&&s.length&&(e.headers["x-user-roles"]=s.map(String).join(","));const n=r.perms;Array.isArray(n)&&n.length&&(e.headers["x-user-permissions"]=n.map(String).join(","))}a(stampIdentity,"stampIdentity"),u(stampIdentity,"stampIdentity");const devAttrs=u((e,r,t)=>({...r,ip:(0,edge_1.clientIpOf)(e),method:(e.method??"GET").toUpperCase(),path:t??(0,edge_1.canonicalPath)(e.url??"/")??(e.url??"/").split("?")[0]}),"devAttrs");exports.devAttrs=devAttrs;
1
+ "use strict";var m=Object.defineProperty;var f=(e,r)=>m(e,"name",{value:r,configurable:!0});var h=Object.defineProperty,a=f((e,r)=>h(e,"name",{value:r,configurable:!0}),"a"),l=Object.defineProperty,u=a((e,r)=>l(e,"name",{value:r,configurable:!0}),"u");Object.defineProperty(exports,"__esModule",{value:!0}),exports.devAttrs=void 0,exports.verifyDevJwt=verifyDevJwt,exports.stampIdentity=stampIdentity;const node_crypto_1=require("node:crypto"),edge_1=require("./edge");function bearerToken(e){const r=Array.isArray(e.headers.authorization)?e.headers.authorization[0]:e.headers.authorization,t=String(r??"");return t.startsWith("Bearer ")?t.slice(7):void 0}f(bearerToken,"bearerToken"),a(bearerToken,"bearerToken"),u(bearerToken,"bearerToken");function verifyDevJwt(e,r){const t=bearerToken(e);if(!t)return;const[s,n,p]=t.split(".");if(!s||!n||!p)return;if(r)return r.verify(t);let i;try{i=JSON.parse(Buffer.from(s,"base64url").toString()).alg}catch{return}if(typeof i=="string"&&i!=="HS256"){if(process.env.LENSMCP_GW_DEV_JWT_INSECURE_DECODE!=="1")return;try{const o=JSON.parse(Buffer.from(n,"base64url").toString());return typeof o.exp=="number"&&Date.now()/1e3>o.exp?void 0:o}catch{return}}const y=process.env.AUTH_JWT_SECRET??"tetros-dev-secret",v=(0,node_crypto_1.createHmac)("sha256",y).update(`${s}.${n}`).digest("base64url"),c=Buffer.from(p),d=Buffer.from(v);if(!(c.length!==d.length||!(0,node_crypto_1.timingSafeEqual)(c,d)))try{const o=JSON.parse(Buffer.from(n,"base64url").toString());return typeof o.exp=="number"&&Date.now()/1e3>o.exp?void 0:o}catch{return}}f(verifyDevJwt,"verifyDevJwt"),a(verifyDevJwt,"verifyDevJwt"),u(verifyDevJwt,"verifyDevJwt");function stampIdentity(e,r){const t=u((p,i)=>{i!=null&&i!==""&&(e.headers[p]=String(i))},"set");t("x-user-id",r.sub),t("x-tenant-id",r.tid);const s=r.roles;Array.isArray(s)&&s.length&&(e.headers["x-user-roles"]=s.map(String).join(","));const n=r.perms;Array.isArray(n)&&n.length&&(e.headers["x-user-permissions"]=n.map(String).join(","))}f(stampIdentity,"stampIdentity"),a(stampIdentity,"stampIdentity"),u(stampIdentity,"stampIdentity");const devAttrs=u((e,r,t)=>({...r,ip:(0,edge_1.clientIpOf)(e),method:(e.method??"GET").toUpperCase(),path:t??(0,edge_1.canonicalPath)(e.url??"/")??(e.url??"/").split("?")[0]}),"devAttrs");exports.devAttrs=devAttrs;
@@ -1 +1 @@
1
- "use strict";var A=Object.defineProperty;var h=(e,s)=>A(e,"name",{value:s,configurable:!0});var I=Object.defineProperty,p=h((e,s)=>I(e,"name",{value:s,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.RETIRING_SUFFIX=void 0,exports.stopRoutingTo=stopRoutingTo,exports.pickSock=pickSock,exports.lensPortFromUpstream=lensPortFromUpstream,exports.rewriteInstanceDecls=rewriteInstanceDecls,exports.discoverRoutes=discoverRoutes,exports.projectSourceRoots=projectSourceRoots;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path")),manifest_1=require("../manifest"),pod_sock_1=require("../../../pod-sock"),instance_1=require("./instance"),scope_1=require("./scope");exports.RETIRING_SUFFIX=".retiring";function sockIdentity(e){try{const s=fs.statSync(e);return`${s.dev}:${s.ino}:${s.ctimeMs}`}catch{return}}h(sockIdentity,"sockIdentity"),p(sockIdentity,"sockIdentity");function stopRoutingTo(e,s=()=>!0){let a;try{a=fs.readdirSync(e.dir)}catch{a=[]}const r=a.filter(t=>(0,pod_sock_1.isPodSockName)(t)&&s(t)).map(t=>path.join(e.dir,t));if(r.length===0)return r;const l=e.retired??=new Map;for(const t of r){const d=sockIdentity(t);d!==void 0&&l.set(t,d)}const n=new Set(r);return e.socks=e.socks.filter(t=>!n.has(t)),e.idx=-1,r}h(stopRoutingTo,"stopRoutingTo"),p(stopRoutingTo,"stopRoutingTo");function stillRetired(e,s){const a=e.retired?.get(s);return a===void 0?!1:sockIdentity(s)===a?!0:(e.retired?.delete(s),!1)}h(stillRetired,"stillRetired"),p(stillRetired,"stillRetired");function pickSock(e,s=1500){const a=Date.now();if(a-e.scannedAt>s){try{const r=fs.readdirSync(e.dir),l=r.filter(t=>(0,pod_sock_1.isPodSockName)(t)&&!stillRetired(e,path.join(e.dir,t)));if(e.retired)for(const t of[...e.retired.keys()])r.includes(path.basename(t))||e.retired.delete(t);const n=l.filter(t=>!r.includes(t+exports.RETIRING_SUFFIX));e.socks=(n.length>0?n:l).map(t=>path.join(e.dir,t))}catch{e.socks=[]}e.scannedAt=a}if(e.socks.length!==0)return e.idx=(e.idx+1)%e.socks.length,e.socks[e.idx]}h(pickSock,"pickSock"),p(pickSock,"pickSock");function lensPortFromUpstream(e){if(!e)return;const s=/:(\d+)/.exec(e);return s?Number(s[1]):void 0}h(lensPortFromUpstream,"lensPortFromUpstream"),p(lensPortFromUpstream,"lensPortFromUpstream");function rewriteInstanceDecls(e,s){const a=e.flatMap(([,n])=>[...n.host?[n.host]:[],...typeof n.internalHost=="string"?[n.internalHost]:[]]),r=s.apex??(0,instance_1.commonApex)(a);if(!r)return console.warn(`[gateway] instance '${s.name}': the declared hosts share no apex \u2014 set \`instance.apex\` in .lensmcp/config.json; no host is served for it.`),{decls:e.map(([n,t])=>[n,{...t,host:void 0,internalHost:!1,default:!1}])};const l=[];for(const[n,t]of e){const d={...t};if(t.host){const c=(0,instance_1.rewriteHost)(t.host,r,s.name);c||console.warn(`[gateway] instance '${s.name}': ${n}'s host ${t.host} is outside ${r} \u2014 not served for the instance.`),d.host=c}if(typeof t.internalHost=="string"){const c=(0,instance_1.rewriteHost)(t.internalHost,r,s.name);c||console.warn(`[gateway] instance '${s.name}': ${n}'s internal host ${t.internalHost} is outside ${r} \u2014 not served for the instance.`),d.internalHost=c??!1}l.push([n,d])}return{decls:l,baseApex:r,apex:`${s.name}.${r}`}}h(rewriteInstanceDecls,"rewriteInstanceDecls"),p(rewriteInstanceDecls,"rewriteInstanceDecls");function discoverRoutes(e,s,a=os.tmpdir(),r="",l={},n=r,t){const d=n||r,c=p(i=>d?path.join(a,d,`${i}-devserver`):path.join(a,`${i}-devserver`),"sockDirFor"),u=[],g=[],_=[],H=[],S={};let y,w=[];const F=new Map;for(const[i,o]of Object.entries(s))try{const f=JSON.parse(fs.readFileSync(path.join(e,o.root,"project.json"),"utf8")),m=f.cluster??f.davnx;m&&(w.push([i,m]),F.set(i,o.root))}catch{continue}let v={};t&&({decls:w,...v}=rewriteInstanceDecls(w,t));for(const[i,o]of w){const f={root:F.get(i)};let m,j,k,R;if(!o.service&&o.sources!==void 0&&console.warn(`[gateway] ${i}: cluster.sources is read from pod (service) decls only \u2014 ignored.`),o.service)o.lens&&console.warn(`[gateway] ${i}: cluster.lens is ignored for pod (service) decls \u2014 backends are instrumented by serve-hmr.`),m={dir:c(o.service),socks:[],idx:-1,scannedAt:0},j={project:i,decl:o,root:e,wsKey:r,...d!==r?{sockNs:d}:{},pool:m,state:"down",lastUsed:Date.now(),inflight:0,lastScaleAt:0},g.push(j);else if(o.lens){const x=o.port??lensPortFromUpstream(o.upstream)??5173;k=`http://localhost:${x}`,R={project:i,...r?{workspaceKey:r}:{},workspaceRoot:e,projectRoot:path.join(e,f.root),port:x,...l[i]?.length?{sourceRoots:l[i]}:{}},_.push(R)}else if(k=o.upstream??(o.port?`http://localhost:${o.port}`:void 0),!k){console.warn(`[gateway] ${i}: no service/upstream/port \u2014 skipped.`);continue}const b={...r?{wsKey:r}:{},project:i,prependPrefix:o.prependPrefix,target:k,pool:m,svc:j,prefix:o.path,auth:o.auth,lens:R};if(o.host&&(u.push({...b,host:o.host}),H.push(o.host),S[i]={host:o.host},m&&o.internalHost!==!1)){const x=typeof o.internalHost=="string"?o.internalHost:`internal.${o.host}`;u.push({...b,host:x,internal:!0}),S[i]={host:o.host,internalHost:x}}o.default&&(y={...b,prefix:void 0})}y&&(y.apex=v.apex??(0,scope_1.baseDomainOf)(H),u.push(y));let $;if(t&&v.apex&&v.baseApex){const i={name:t.name,apex:v.apex,baseApex:v.baseApex},o=(0,instance_1.instanceEnv)(e,(0,instance_1.instanceBuiltinEnv)(i,S));$={...i,baseKey:t.baseKey,env:o,...t.frozen?{frozen:!0}:{}};for(const f of g)f.instanceEnv=o,t.frozen&&(f.frozen=!0);for(const f of _)f.env=o,t.frozen&&(f.frozen=!0)}return(0,manifest_1.sortBySpecificity)(u),{routes:u,services:g,...$?{instance:$}:{}}}h(discoverRoutes,"discoverRoutes"),p(discoverRoutes,"discoverRoutes");function projectSourceRoots(e,s,a={}){const r={};for(const l of Object.keys(s)){const n=new Set,t=p(c=>{if(!n.has(c)){n.add(c);for(const u of a[c]??[])t(u)}},"visit");t(l);const d=[...n].map(c=>s[c]?.root).filter(c=>typeof c=="string").map(c=>path.resolve(e,c)).filter(c=>{const u=path.relative(e,c);return u===""||u!==".."&&!u.startsWith(`..${path.sep}`)&&!path.isAbsolute(u)});r[l]=[...new Set(d)]}return r}h(projectSourceRoots,"projectSourceRoots"),p(projectSourceRoots,"projectSourceRoots");
1
+ "use strict";var q=Object.defineProperty;var m=(e,o)=>q(e,"name",{value:o,configurable:!0});var A=Object.defineProperty,h=m((e,o)=>A(e,"name",{value:o,configurable:!0}),"h"),I=Object.defineProperty,p=h((e,o)=>I(e,"name",{value:o,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.RETIRING_SUFFIX=void 0,exports.stopRoutingTo=stopRoutingTo,exports.pickSock=pickSock,exports.lensPortFromUpstream=lensPortFromUpstream,exports.rewriteInstanceDecls=rewriteInstanceDecls,exports.discoverRoutes=discoverRoutes,exports.projectSourceRoots=projectSourceRoots;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path")),manifest_1=require("../manifest"),pod_sock_1=require("../../../pod-sock"),instance_1=require("./instance"),scope_1=require("./scope");exports.RETIRING_SUFFIX=".retiring";function sockIdentity(e){try{const o=fs.statSync(e);return`${o.dev}:${o.ino}:${o.ctimeMs}`}catch{return}}m(sockIdentity,"sockIdentity"),h(sockIdentity,"sockIdentity"),p(sockIdentity,"sockIdentity");function stopRoutingTo(e,o=()=>!0){let a;try{a=fs.readdirSync(e.dir)}catch{a=[]}const r=a.filter(t=>(0,pod_sock_1.isPodSockName)(t)&&o(t)).map(t=>path.join(e.dir,t));if(r.length===0)return r;const l=e.retired??=new Map;for(const t of r){const d=sockIdentity(t);d!==void 0&&l.set(t,d)}const n=new Set(r);return e.socks=e.socks.filter(t=>!n.has(t)),e.idx=-1,r}m(stopRoutingTo,"stopRoutingTo"),h(stopRoutingTo,"stopRoutingTo"),p(stopRoutingTo,"stopRoutingTo");function stillRetired(e,o){const a=e.retired?.get(o);return a===void 0?!1:sockIdentity(o)===a?!0:(e.retired?.delete(o),!1)}m(stillRetired,"stillRetired"),h(stillRetired,"stillRetired"),p(stillRetired,"stillRetired");function pickSock(e,o=1500){const a=Date.now();if(a-e.scannedAt>o){try{const r=fs.readdirSync(e.dir),l=r.filter(t=>(0,pod_sock_1.isPodSockName)(t)&&!stillRetired(e,path.join(e.dir,t)));if(e.retired)for(const t of[...e.retired.keys()])r.includes(path.basename(t))||e.retired.delete(t);const n=l.filter(t=>!r.includes(t+exports.RETIRING_SUFFIX));e.socks=(n.length>0?n:l).map(t=>path.join(e.dir,t))}catch{e.socks=[]}e.scannedAt=a}if(e.socks.length!==0)return e.idx=(e.idx+1)%e.socks.length,e.socks[e.idx]}m(pickSock,"pickSock"),h(pickSock,"pickSock"),p(pickSock,"pickSock");function lensPortFromUpstream(e){if(!e)return;const o=/:(\d+)/.exec(e);return o?Number(o[1]):void 0}m(lensPortFromUpstream,"lensPortFromUpstream"),h(lensPortFromUpstream,"lensPortFromUpstream"),p(lensPortFromUpstream,"lensPortFromUpstream");function rewriteInstanceDecls(e,o){const a=e.flatMap(([,n])=>[...n.host?[n.host]:[],...typeof n.internalHost=="string"?[n.internalHost]:[]]),r=o.apex??(0,instance_1.commonApex)(a);if(!r)return console.warn(`[gateway] instance '${o.name}': the declared hosts share no apex \u2014 set \`instance.apex\` in .lensmcp/config.json; no host is served for it.`),{decls:e.map(([n,t])=>[n,{...t,host:void 0,internalHost:!1,default:!1}])};const l=[];for(const[n,t]of e){const d={...t};if(t.host){const c=(0,instance_1.rewriteHost)(t.host,r,o.name);c||console.warn(`[gateway] instance '${o.name}': ${n}'s host ${t.host} is outside ${r} \u2014 not served for the instance.`),d.host=c}if(typeof t.internalHost=="string"){const c=(0,instance_1.rewriteHost)(t.internalHost,r,o.name);c||console.warn(`[gateway] instance '${o.name}': ${n}'s internal host ${t.internalHost} is outside ${r} \u2014 not served for the instance.`),d.internalHost=c??!1}l.push([n,d])}return{decls:l,baseApex:r,apex:`${o.name}.${r}`}}m(rewriteInstanceDecls,"rewriteInstanceDecls"),h(rewriteInstanceDecls,"rewriteInstanceDecls"),p(rewriteInstanceDecls,"rewriteInstanceDecls");function discoverRoutes(e,o,a=os.tmpdir(),r="",l={},n=r,t){const d=n||r,c=p(i=>d?path.join(a,d,`${i}-devserver`):path.join(a,`${i}-devserver`),"sockDirFor"),u=[],S=[],H=[],F=[],R={};let k,w=[];const P=new Map;for(const[i,s]of Object.entries(o))try{const f=JSON.parse(fs.readFileSync(path.join(e,s.root,"project.json"),"utf8")),v=f.cluster??f.davnx;v&&(w.push([i,v]),P.set(i,s.root))}catch{continue}let x={};t&&({decls:w,...x}=rewriteInstanceDecls(w,t));for(const[i,s]of w){const f={root:P.get(i)};let v,$,g,b;if(!s.service&&s.sources!==void 0&&console.warn(`[gateway] ${i}: cluster.sources is read from pod (service) decls only \u2014 ignored.`),s.service)s.lens&&console.warn(`[gateway] ${i}: cluster.lens is ignored for pod (service) decls \u2014 backends are instrumented by serve-hmr.`),v={dir:c(s.service),socks:[],idx:-1,scannedAt:0},$={project:i,decl:s,root:e,wsKey:r,...d!==r?{sockNs:d}:{},pool:v,state:"down",lastUsed:Date.now(),inflight:0,lastScaleAt:0},S.push($);else if(s.lens){const y=s.port??lensPortFromUpstream(s.upstream)??5173;g=`http://localhost:${y}`,b={project:i,...r?{workspaceKey:r}:{},workspaceRoot:e,projectRoot:path.join(e,f.root),port:y,...l[i]?.length?{sourceRoots:l[i]}:{}},H.push(b)}else if(g=s.upstream??(s.port?`http://localhost:${s.port}`:void 0),!g){console.warn(`[gateway] ${i}: no service/upstream/port \u2014 skipped.`);continue}const _={...r?{wsKey:r}:{},project:i,prependPrefix:s.prependPrefix,target:g,pool:v,svc:$,prefix:s.path,auth:s.auth,lens:b};if(s.host&&(u.push({..._,host:s.host}),F.push(s.host),R[i]={host:s.host},v&&s.internalHost!==!1)){const y=typeof s.internalHost=="string"?s.internalHost:`internal.${s.host}`;u.push({..._,host:y,internal:!0}),R[i]={host:s.host,internalHost:y}}s.default&&(k={..._,prefix:void 0})}k&&(k.apex=x.apex??(0,scope_1.baseDomainOf)(F),u.push(k));let j;if(t&&x.apex&&x.baseApex){const i={name:t.name,apex:x.apex,baseApex:x.baseApex},s=(0,instance_1.instanceEnv)(e,(0,instance_1.instanceBuiltinEnv)(i,R));j={...i,baseKey:t.baseKey,env:s,...t.frozen?{frozen:!0}:{}};for(const f of S)f.instanceEnv=s,t.frozen&&(f.frozen=!0);for(const f of H)f.env=s,t.frozen&&(f.frozen=!0)}return(0,manifest_1.sortBySpecificity)(u),{routes:u,services:S,...j?{instance:j}:{}}}m(discoverRoutes,"discoverRoutes"),h(discoverRoutes,"discoverRoutes"),p(discoverRoutes,"discoverRoutes");function projectSourceRoots(e,o,a={}){const r={};for(const l of Object.keys(o)){const n=new Set,t=p(c=>{if(!n.has(c)){n.add(c);for(const u of a[c]??[])t(u)}},"visit");t(l);const d=[...n].map(c=>o[c]?.root).filter(c=>typeof c=="string").map(c=>path.resolve(e,c)).filter(c=>{const u=path.relative(e,c);return u===""||u!==".."&&!u.startsWith(`..${path.sep}`)&&!path.isAbsolute(u)});r[l]=[...new Set(d)]}return r}m(projectSourceRoots,"projectSourceRoots"),h(projectSourceRoots,"projectSourceRoots"),p(projectSourceRoots,"projectSourceRoots");
@@ -104,6 +104,13 @@ export declare const cors: (req: http.IncomingMessage, res: http.ServerResponse,
104
104
  * requested headers echoed back. `methods` differs by caller — the no-route host-root uses the narrow
105
105
  * `GET,HEAD,OPTIONS`; a routed path uses the wide verb list.
106
106
  */
107
+ /**
108
+ * How long a browser may reuse a preflight's answer: Chrome's cap (Firefox allows 24 h). Without it every preflighted
109
+ * request was preflighted again after Chrome's 5 s default — a page polling a URL with an `x-request-id` (session
110
+ * replay joins every request to its backend run: planning/replay/00-plan.md D5) paid an OPTIONS round trip per poll.
111
+ * The cache is per origin and URL, so a URL with an id in its path still asks once per id.
112
+ */
113
+ export declare const PREFLIGHT_MAX_AGE = "7200";
107
114
  export declare const corsPreflight: (req: http.IncomingMessage, res: http.ServerResponse, methods: string, routes: readonly {
108
115
  host?: string;
109
116
  }[]) => void;
@@ -1 +1 @@
1
- "use strict";var d=Object.defineProperty;var c=(e,r)=>d(e,"name",{value:r,configurable:!0});var p=Object.defineProperty,o=c((e,r)=>p(e,"name",{value:r,configurable:!0}),"o");Object.defineProperty(exports,"__esModule",{value:!0}),exports.PREFLIGHT_METHODS_ROUTED=exports.PREFLIGHT_METHODS_NOROUTE=exports.corsPreflight=exports.cors=exports.isRoutedOrigin=exports.callerContextOf=exports.claimedCallerIdOf=exports.CLAIMED_CALLER_ID=exports.CALLER_CONTEXT=exports.CALLER_CONTEXT_HEADERS=exports.GATEWAY_OWNED_HEADERS=exports.sendError=exports.stampForwardingHeaders=exports.clientIpOf=exports.resolveClientIp=exports.CLIENT_IP=exports.rememberRawTarget=exports.rawTargetOf=exports.RAW_TARGET=exports.canonicalPath=exports.canonicalize=exports.ENCODED_STRUCTURE=void 0,exports.stripOwnedHeaders=stripOwnedHeaders;const gateway_errors_1=require("../gateway-errors"),client_ip_1=require("../client-ip"),manifest_1=require("../manifest"),act_1=require("./act");var canonical_path_1=require("../canonical-path");Object.defineProperty(exports,"ENCODED_STRUCTURE",{enumerable:!0,get:o(function(){return canonical_path_1.ENCODED_STRUCTURE},"get")}),Object.defineProperty(exports,"canonicalize",{enumerable:!0,get:o(function(){return canonical_path_1.canonicalize},"get")}),Object.defineProperty(exports,"canonicalPath",{enumerable:!0,get:o(function(){return canonical_path_1.canonicalPath},"get")}),Object.defineProperty(exports,"RAW_TARGET",{enumerable:!0,get:o(function(){return canonical_path_1.RAW_TARGET},"get")}),Object.defineProperty(exports,"rawTargetOf",{enumerable:!0,get:o(function(){return canonical_path_1.rawTargetOf},"get")}),Object.defineProperty(exports,"rememberRawTarget",{enumerable:!0,get:o(function(){return canonical_path_1.rememberRawTarget},"get")}),exports.CLIENT_IP=Symbol.for("lensmcp.gateway.clientIp");const FORWARDED=Symbol.for("lensmcp.gateway.forwarded"),peerOnly=(0,client_ip_1.createClientIpResolver)({}),resolverOf=o(e=>e.clientIp??peerOnly,"resolverOf"),peerOf=o(e=>e.socket?.remoteAddress??"","peerOf"),resolveClientIp=o((e,r)=>{const t=resolverOf(e).clientIpOf(r,peerOf(r));return r[exports.CLIENT_IP]=t,t},"resolveClientIp");exports.resolveClientIp=resolveClientIp;const clientIpOf=o(e=>e[exports.CLIENT_IP]??peerOf(e),"clientIpOf");exports.clientIpOf=clientIpOf;const stampForwardingHeaders=o((e,r)=>{const t=r;if(t[FORWARDED])return;t[FORWARDED]=!0;const s=peerOf(r);r.headers["x-forwarded-for"]=resolverOf(e).forwardedFor(r,s),r.headers["x-forwarded-proto"]=e.https?"https":"http";const n=r.headers.host;(resolverOf(e).trustProxyHops===0||!r.headers["x-forwarded-host"])&&(n?r.headers["x-forwarded-host"]=n:delete r.headers["x-forwarded-host"])},"stampForwardingHeaders");exports.stampForwardingHeaders=stampForwardingHeaders;const sendError=o((e,r,t,s,n,i,l)=>{const a=(0,gateway_errors_1.ensureRequestId)(r);return e.headersSent||e.writeHead(t,{"content-type":gateway_errors_1.GATEWAY_ERROR_CONTENT_TYPE,"x-request-id":a,...l??{}}),e.end((0,gateway_errors_1.gatewayErrorBody)(t,s,a,n,i)),a},"sendError");exports.sendError=sendError,exports.GATEWAY_OWNED_HEADERS=["x-internal-token","x-api-key-id","x-api-key-workspace","x-user-id","x-tenant-id","x-user-roles","x-user-permissions",act_1.ACT_HEADER],exports.CALLER_CONTEXT_HEADERS=["x-tenant-id","x-user-id"],exports.CALLER_CONTEXT=Symbol.for("lensmcp.gateway.callerContext"),exports.CLAIMED_CALLER_ID=Symbol.for("lensmcp.gateway.claimedCallerId");const CALLER_ID_VALUE=/^[a-z0-9][a-z0-9._-]{0,63}$/i,CALLER_CONTEXT_VALUE=/^[\x21-\x2b\x2d-\x7e]{1,128}$/;function stripOwnedHeaders(e){const r={};for(const s of exports.CALLER_CONTEXT_HEADERS){const n=e.headers[s];typeof n=="string"&&CALLER_CONTEXT_VALUE.test(n)&&(r[s]=n)}e[exports.CALLER_CONTEXT]=r;const t=e.headers["x-api-key-id"];typeof t=="string"&&CALLER_ID_VALUE.test(t)&&(e[exports.CLAIMED_CALLER_ID]=t),(0,act_1.setActTicketAside)(e);for(const s of exports.GATEWAY_OWNED_HEADERS)delete e.headers[s]}c(stripOwnedHeaders,"stripOwnedHeaders"),o(stripOwnedHeaders,"stripOwnedHeaders");const claimedCallerIdOf=o(e=>e[exports.CLAIMED_CALLER_ID],"claimedCallerIdOf");exports.claimedCallerIdOf=claimedCallerIdOf;const callerContextOf=o(e=>e[exports.CALLER_CONTEXT]??{},"callerContextOf");exports.callerContextOf=callerContextOf;const isRoutedOrigin=o((e,r)=>{if(!e||e==="null")return!1;let t;try{t=new URL(e).hostname.toLowerCase()}catch{return!1}return t?t==="localhost"||t==="127.0.0.1"||t==="::1"?!0:r.some(s=>!!s.host&&(0,manifest_1.hostMatches)(s.host,t)):!1},"isRoutedOrigin");exports.isRoutedOrigin=isRoutedOrigin;const cors=o((e,r,t)=>{const s=e.headers.origin;typeof s!="string"||s===""||(r.setHeader("vary","Origin"),(0,exports.isRoutedOrigin)(s,t)&&(r.setHeader("access-control-allow-origin",s),r.setHeader("access-control-allow-credentials","true")))},"cors");exports.cors=cors;const corsPreflight=o((e,r,t,s)=>{(0,exports.cors)(e,r,s),r.writeHead(204,{"access-control-allow-methods":t,"access-control-allow-headers":String(e.headers["access-control-request-headers"]??"*")}),r.end()},"corsPreflight");exports.corsPreflight=corsPreflight,exports.PREFLIGHT_METHODS_NOROUTE="GET,HEAD,OPTIONS",exports.PREFLIGHT_METHODS_ROUTED="GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS";
1
+ "use strict";var x=Object.defineProperty;var i=(e,r)=>x(e,"name",{value:r,configurable:!0});var E=Object.defineProperty,c=i((e,r)=>E(e,"name",{value:r,configurable:!0}),"c"),p=Object.defineProperty,o=c((e,r)=>p(e,"name",{value:r,configurable:!0}),"o");Object.defineProperty(exports,"__esModule",{value:!0}),exports.PREFLIGHT_METHODS_ROUTED=exports.PREFLIGHT_METHODS_NOROUTE=exports.corsPreflight=exports.PREFLIGHT_MAX_AGE=exports.cors=exports.isRoutedOrigin=exports.callerContextOf=exports.claimedCallerIdOf=exports.CLAIMED_CALLER_ID=exports.CALLER_CONTEXT=exports.CALLER_CONTEXT_HEADERS=exports.GATEWAY_OWNED_HEADERS=exports.sendError=exports.stampForwardingHeaders=exports.clientIpOf=exports.resolveClientIp=exports.CLIENT_IP=exports.rememberRawTarget=exports.rawTargetOf=exports.RAW_TARGET=exports.canonicalPath=exports.canonicalize=exports.ENCODED_STRUCTURE=void 0,exports.stripOwnedHeaders=stripOwnedHeaders;const gateway_errors_1=require("../gateway-errors"),client_ip_1=require("../client-ip"),manifest_1=require("../manifest"),act_1=require("./act");var canonical_path_1=require("../canonical-path");Object.defineProperty(exports,"ENCODED_STRUCTURE",{enumerable:!0,get:o(function(){return canonical_path_1.ENCODED_STRUCTURE},"get")}),Object.defineProperty(exports,"canonicalize",{enumerable:!0,get:o(function(){return canonical_path_1.canonicalize},"get")}),Object.defineProperty(exports,"canonicalPath",{enumerable:!0,get:o(function(){return canonical_path_1.canonicalPath},"get")}),Object.defineProperty(exports,"RAW_TARGET",{enumerable:!0,get:o(function(){return canonical_path_1.RAW_TARGET},"get")}),Object.defineProperty(exports,"rawTargetOf",{enumerable:!0,get:o(function(){return canonical_path_1.rawTargetOf},"get")}),Object.defineProperty(exports,"rememberRawTarget",{enumerable:!0,get:o(function(){return canonical_path_1.rememberRawTarget},"get")}),exports.CLIENT_IP=Symbol.for("lensmcp.gateway.clientIp");const FORWARDED=Symbol.for("lensmcp.gateway.forwarded"),peerOnly=(0,client_ip_1.createClientIpResolver)({}),resolverOf=o(e=>e.clientIp??peerOnly,"resolverOf"),peerOf=o(e=>e.socket?.remoteAddress??"","peerOf"),resolveClientIp=o((e,r)=>{const t=resolverOf(e).clientIpOf(r,peerOf(r));return r[exports.CLIENT_IP]=t,t},"resolveClientIp");exports.resolveClientIp=resolveClientIp;const clientIpOf=o(e=>e[exports.CLIENT_IP]??peerOf(e),"clientIpOf");exports.clientIpOf=clientIpOf;const stampForwardingHeaders=o((e,r)=>{const t=r;if(t[FORWARDED])return;t[FORWARDED]=!0;const s=peerOf(r);r.headers["x-forwarded-for"]=resolverOf(e).forwardedFor(r,s),r.headers["x-forwarded-proto"]=e.https?"https":"http";const n=r.headers.host;(resolverOf(e).trustProxyHops===0||!r.headers["x-forwarded-host"])&&(n?r.headers["x-forwarded-host"]=n:delete r.headers["x-forwarded-host"])},"stampForwardingHeaders");exports.stampForwardingHeaders=stampForwardingHeaders;const sendError=o((e,r,t,s,n,l,d)=>{const a=(0,gateway_errors_1.ensureRequestId)(r);return e.headersSent||e.writeHead(t,{"content-type":gateway_errors_1.GATEWAY_ERROR_CONTENT_TYPE,"x-request-id":a,...d??{}}),e.end((0,gateway_errors_1.gatewayErrorBody)(t,s,a,n,l)),a},"sendError");exports.sendError=sendError,exports.GATEWAY_OWNED_HEADERS=["x-internal-token","x-api-key-id","x-api-key-workspace","x-user-id","x-tenant-id","x-user-roles","x-user-permissions",act_1.ACT_HEADER],exports.CALLER_CONTEXT_HEADERS=["x-tenant-id","x-user-id"],exports.CALLER_CONTEXT=Symbol.for("lensmcp.gateway.callerContext"),exports.CLAIMED_CALLER_ID=Symbol.for("lensmcp.gateway.claimedCallerId");const CALLER_ID_VALUE=/^[a-z0-9][a-z0-9._-]{0,63}$/i,CALLER_CONTEXT_VALUE=/^[\x21-\x2b\x2d-\x7e]{1,128}$/;function stripOwnedHeaders(e){const r={};for(const s of exports.CALLER_CONTEXT_HEADERS){const n=e.headers[s];typeof n=="string"&&CALLER_CONTEXT_VALUE.test(n)&&(r[s]=n)}e[exports.CALLER_CONTEXT]=r;const t=e.headers["x-api-key-id"];typeof t=="string"&&CALLER_ID_VALUE.test(t)&&(e[exports.CLAIMED_CALLER_ID]=t),(0,act_1.setActTicketAside)(e);for(const s of exports.GATEWAY_OWNED_HEADERS)delete e.headers[s]}i(stripOwnedHeaders,"stripOwnedHeaders"),c(stripOwnedHeaders,"stripOwnedHeaders"),o(stripOwnedHeaders,"stripOwnedHeaders");const claimedCallerIdOf=o(e=>e[exports.CLAIMED_CALLER_ID],"claimedCallerIdOf");exports.claimedCallerIdOf=claimedCallerIdOf;const callerContextOf=o(e=>e[exports.CALLER_CONTEXT]??{},"callerContextOf");exports.callerContextOf=callerContextOf;const isRoutedOrigin=o((e,r)=>{if(!e||e==="null")return!1;let t;try{t=new URL(e).hostname.toLowerCase()}catch{return!1}return t?t==="localhost"||t==="127.0.0.1"||t==="::1"?!0:r.some(s=>!!s.host&&(0,manifest_1.hostMatches)(s.host,t)):!1},"isRoutedOrigin");exports.isRoutedOrigin=isRoutedOrigin;const cors=o((e,r,t)=>{const s=e.headers.origin;typeof s!="string"||s===""||(r.setHeader("vary","Origin"),(0,exports.isRoutedOrigin)(s,t)&&(r.setHeader("access-control-allow-origin",s),r.setHeader("access-control-allow-credentials","true")))},"cors");exports.cors=cors,exports.PREFLIGHT_MAX_AGE="7200";const corsPreflight=o((e,r,t,s)=>{(0,exports.cors)(e,r,s),r.writeHead(204,{"access-control-allow-methods":t,"access-control-allow-headers":String(e.headers["access-control-request-headers"]??"*"),"access-control-max-age":exports.PREFLIGHT_MAX_AGE}),r.end()},"corsPreflight");exports.corsPreflight=corsPreflight,exports.PREFLIGHT_METHODS_NOROUTE="GET,HEAD,OPTIONS",exports.PREFLIGHT_METHODS_ROUTED="GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS";
@@ -1,2 +1,2 @@
1
- "use strict";var _=Object.defineProperty;var u=(e,r)=>_(e,"name",{value:r,configurable:!0});var l=Object.defineProperty,f=u((e,r)=>l(e,"name",{value:r,configurable:!0}),"f");Object.defineProperty(exports,"__esModule",{value:!0}),exports.GUEST_GRAPH_RETRY_MS=exports.MAX_FORWARDED_PROJECTS=exports.MAX_FORWARDED_GRAPH_BYTES=exports.FORWARDED_GRAPH_FORMAT=void 0,exports.ownedByThisUser=ownedByThisUser,exports.admitForwardedGraph=admitForwardedGraph,exports.compactSourceMaps=compactSourceMaps,exports.projectsOnly=projectsOnly,exports.snapshotWorkspaceGraph=snapshotWorkspaceGraph,exports.graphSnapshotScript=graphSnapshotScript,exports.guestGraphEnv=guestGraphEnv,exports.forwardedGraphInChild=forwardedGraphInChild,exports.createGuestGraphStore=createGuestGraphStore;const tslib_1=require("tslib"),node_child_process_1=require("node:child_process"),fs=tslib_1.__importStar(require("node:fs")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path")),pod_env_1=require("./pod-env"),project_graph_store_1=require("./project-graph-store"),registration_guards_1=require("./registration-guards");exports.FORWARDED_GRAPH_FORMAT=1,exports.MAX_FORWARDED_GRAPH_BYTES=8*1024*1024,exports.MAX_FORWARDED_PROJECTS=2e4,exports.GUEST_GRAPH_RETRY_MS=6e4;const GUEST_GRAPH_TIMEOUT_MS=12e4,SIGNATURE=/^(?:-|\?|\d+(?:\.\d+)?:\d+:\d+)$/;function megabytes(e){return`${(e/(1024*1024)).toFixed(1)} MB`}u(megabytes,"megabytes"),f(megabytes,"megabytes");const isRecord=f(e=>!!e&&typeof e=="object"&&!Array.isArray(e),"isRecord");function insideWorkspace(e){return e===""||path.isAbsolute(e)||/^[a-zA-Z]:/.test(e)?!1:!path.posix.normalize(e.replace(/\\/g,"/")).split("/").includes("..")}u(insideWorkspace,"insideWorkspace"),f(insideWorkspace,"insideWorkspace");function ownedByThisUser(e){const r=fs.statSync(e,{throwIfNoEntry:!1});if(!r?.isDirectory())return!1;if(typeof process.getuid!="function")return!0;const t=process.getuid();return r.uid===t||t===0&&r.uid===Number(process.env.SUDO_UID)}u(ownedByThisUser,"ownedByThisUser"),f(ownedByThisUser,"ownedByThisUser");function relativeDeclaringFiles(e,r){return(0,project_graph_store_1.declaringFiles)(e,r).map(t=>path.relative(e,t).split(path.sep).join("/"))}u(relativeDeclaringFiles,"relativeDeclaringFiles"),f(relativeDeclaringFiles,"relativeDeclaringFiles");function shapeProblem(e){if(!isRecord(e)||!isRecord(e.nodes)||!isRecord(e.dependencies))return"it has no `nodes` and `dependencies`";const r=e.nodes,t=Object.keys(r);if(t.length>exports.MAX_FORWARDED_PROJECTS)return`it names ${t.length} projects (at most ${exports.MAX_FORWARDED_PROJECTS})`;for(const o of t){const s=r[o];if(!isRecord(s)||s.name!==o||typeof s.type!="string"||!isRecord(s.data))return`project '${o}' is not a project node`;const n=s.data.root;if(typeof n!="string"||!insideWorkspace(n))return`project '${o}' has a root outside the workspace (${String(n)})`;const p=s.data.targets;if(p!==void 0&&(!isRecord(p)||!Object.values(p).every(isRecord)))return`project '${o}' has malformed targets`}for(const[o,s]of Object.entries(e.dependencies)){if(!(o in r)||!Array.isArray(s))return`the dependencies of '${o}' are not a known project's`;for(const n of s)if(!isRecord(n)||n.source!==o||typeof n.target!="string"||!(n.target in r)||typeof n.type!="string")return`a dependency of '${o}' is malformed`}}u(shapeProblem,"shapeProblem"),f(shapeProblem,"shapeProblem");function sourceMapsProblem(e){if(e!==void 0){if(!isRecord(e))return"its source maps are not a map";for(const[r,t]of Object.entries(e)){if(!isRecord(t))return`the source map of ${r} is malformed`;for(const o of Object.values(t))if(!Array.isArray(o)||o.length!==2||o[0]!==null&&typeof o[0]!="string"||typeof o[1]!="string")return`the source map of ${r} is malformed`}}}u(sourceMapsProblem,"sourceMapsProblem"),f(sourceMapsProblem,"sourceMapsProblem");function admitForwardedGraph(e,r){const t=f(a=>({refused:a}),"refuse");if(r.bytes>exports.MAX_FORWARDED_GRAPH_BYTES)return t(`${megabytes(r.bytes)} is over the ${megabytes(exports.MAX_FORWARDED_GRAPH_BYTES)} limit`);if(!isRecord(e))return t("it is not a project graph");if(e.format!==exports.FORWARDED_GRAPH_FORMAT)return t(`its format is ${String(e.format)}, and this gateway reads ${exports.FORWARDED_GRAPH_FORMAT}`);const o=e.root;if(typeof o!="string"||!path.isAbsolute(o))return t("it does not say which workspace it describes");if(!(0,registration_guards_1.sameRoot)(o,r.root))return t(`it describes ${o}, not the registering workspace ${r.root}`);if((0,registration_guards_1.sameRoot)(r.root,r.daemonRoot))return t(`${r.root} is the gateway's own workspace \u2014 the gateway reads that graph itself`);if(r.otherRoots.some(a=>(0,registration_guards_1.sameRoot)(a,r.root)))return t(`${r.root} is registered under another key`);if(!ownedByThisUser(r.root))return t(`${r.root} is not a directory this user owns`);const s=e.startedAt;if(typeof s!="number"||!Number.isFinite(s))return t("it does not say when it was computed");const n=shapeProblem(e.projectGraph)??sourceMapsProblem(e.sourceMaps);if(n)return t(n);const p=e.projectGraph,i=e.files;if(!isRecord(i))return t("it carries no fingerprint of its declaring files");const c=(0,registration_guards_1.canonicalRoot)(r.root),h=relativeDeclaringFiles(c,p),d=Object.keys(i),g=h.filter(a=>!(a in i));return g.length>0||d.length!==h.length?t(`its fingerprint does not cover exactly the files that declare it${g.length>0?` (no ${g[0]})`:""}`):Object.values(i).every(a=>typeof a=="string"&&SIGNATURE.test(a))?{snapshot:{root:c,startedAt:s,files:new Map(h.map(a=>[path.join(c,a),i[a]])),projectGraph:{nodes:p.nodes,dependencies:p.dependencies,externalNodes:{}},...e.sourceMaps!==void 0?{sourceMaps:e.sourceMaps}:{}}}:t("its fingerprint is malformed")}u(admitForwardedGraph,"admitForwardedGraph"),f(admitForwardedGraph,"admitForwardedGraph");function compactSourceMaps(e,r){const t={};for(const o of Object.values(e.nodes)){const s=r[o.data.root];if(!s)continue;const n=new Set;for(const i of Object.keys(o.data.targets??{})){const c=`targets.${i}`,h=new Set;for(const[d,g]of Object.entries(s)){if(d!==c&&!d.startsWith(`${c}.`))continue;const a=JSON.stringify(g);h.has(a)||(h.add(a),n.add(d))}}const p={};for(const[i,c]of Object.entries(s))n.has(i)&&(p[i]=c);t[o.data.root]=p}return t}u(compactSourceMaps,"compactSourceMaps"),f(compactSourceMaps,"compactSourceMaps");function projectsOnly(e){const r={};for(const[t,o]of Object.entries(e.dependencies))t in e.nodes&&(r[t]=o.filter(s=>s.target in e.nodes));return{nodes:e.nodes,dependencies:r}}u(projectsOnly,"projectsOnly"),f(projectsOnly,"projectsOnly");async function snapshotWorkspaceGraph(e,r=()=>(0,project_graph_store_1.computeProjectGraphInProcess)(e)){const t=Date.now(),o=(0,project_graph_store_1.filesystemNow)(),s=await r(),n=projectsOnly(s.projectGraph),p={};for(const i of(0,project_graph_store_1.declaringFiles)(e,s.projectGraph)){const c=fs.statSync(i,{throwIfNoEntry:!1});p[path.relative(e,i).split(path.sep).join("/")]=c&&c.mtimeMs>o?"?":(0,project_graph_store_1.statSignature)(i)}return{format:exports.FORWARDED_GRAPH_FORMAT,root:e,startedAt:t,projectGraph:n,...s.sourceMaps?{sourceMaps:compactSourceMaps(n,s.sourceMaps)}:{},files:p}}u(snapshotWorkspaceGraph,"snapshotWorkspaceGraph"),f(snapshotWorkspaceGraph,"snapshotWorkspaceGraph");function graphSnapshotScript(e=path.join(__dirname,"../../..")){const r=path.join(e,"graph-snapshot.js");if(fs.existsSync(r))return{path:r,execArgv:[]};const t=path.join(e,"graph-snapshot.ts");if(fs.existsSync(t))try{return{path:t,execArgv:["--require",require.resolve("@swc-node/register")]}}catch{return}}u(graphSnapshotScript,"graphSnapshotScript"),f(graphSnapshotScript,"graphSnapshotScript");function guestGraphEnv(e,r,t){const o={...(0,pod_env_1.podBaseEnv)(e,r,t)};for(const s of Object.keys(o))(s.startsWith("NX_TASK_")||["NX_WORKSPACE_ROOT","NX_WORKSPACE_ROOT_PATH","NX_WORKSPACE_DATA_DIRECTORY","NX_PROJECT_GRAPH_CACHE_DIRECTORY"].includes(s))&&delete o[s];return o.NX_DAEMON="false",o.NX_ISOLATE_PLUGINS="false",o}u(guestGraphEnv,"guestGraphEnv"),f(guestGraphEnv,"guestGraphEnv");function forwardedGraphInChild(e,r,t=graphSnapshotScript()){if(!t)return Promise.reject(new Error("graph-snapshot.js is missing from @lensmcp/cluster"));const o=fs.mkdtempSync(path.join(os.tmpdir(),"lensmcp-graph-")),s=path.join(o,"graph.json");return new Promise((n,p)=>{let i="";const c=(0,node_child_process_1.spawn)(process.execPath,[...t.execArgv,t.path,s],{cwd:e,env:r,stdio:["ignore","ignore","pipe"]});c.stderr?.on("data",d=>{i.length<4096&&(i+=d.toString())});const h=setTimeout(()=>c.kill("SIGKILL"),GUEST_GRAPH_TIMEOUT_MS);h.unref(),c.on("error",d=>{clearTimeout(h),p(d)}),c.on("exit",(d,g)=>{if(clearTimeout(h),d!==0){const a=i.trim().split(`
2
- `).pop();p(new Error(`the graph computation in ${e} exited ${g??d}${a?` \u2014 ${a}`:""}`));return}try{const a=fs.statSync(s).size;n({bytes:a,graph:a>exports.MAX_FORWARDED_GRAPH_BYTES?void 0:JSON.parse(fs.readFileSync(s,"utf8"))})}catch(a){p(a)}})}).finally(()=>fs.rmSync(o,{recursive:!0,force:!0}))}u(forwardedGraphInChild,"forwardedGraphInChild"),f(forwardedGraphInChild,"forwardedGraphInChild");function createGuestGraphStore(e,r=process.env){const{wsKey:t,admission:o,context:s}=e,n=(0,registration_guards_1.canonicalRoot)(e.root),p=e.compute??(()=>forwardedGraphInChild(n,guestGraphEnv(r,s.daemonRoot,n))),i=o===void 0?"its registration forwarded none":o.refused!==void 0?`the project graph its registration forwarded was refused: ${o.refused}`:void 0;return(0,project_graph_store_1.createProjectGraphStore)(n,async()=>{const{graph:c,bytes:h}=await p(),d=admitForwardedGraph(c,{...s,bytes:h});if(d.refused!==void 0)throw new Error(`the computed project graph was refused: ${d.refused}`);return{projectGraph:d.snapshot.projectGraph,...d.snapshot.sourceMaps?{sourceMaps:d.snapshot.sourceMaps}:{}}},{...o?.snapshot?{seed:o.snapshot}:{},...i?{error:i}:{},retryAfterFailureMs:exports.GUEST_GRAPH_RETRY_MS,onRefreshed:f(c=>console.log(`[gateway] project graph of '${t}' (${n}) refreshed \u2014 ${Object.keys(c.projectGraph.nodes).length} projects; its services start through the serve runner again`),"onRefreshed")})}u(createGuestGraphStore,"createGuestGraphStore"),f(createGuestGraphStore,"createGuestGraphStore");
1
+ "use strict";var m=Object.defineProperty;var h=(e,t)=>m(e,"name",{value:t,configurable:!0});var _=Object.defineProperty,u=h((e,t)=>_(e,"name",{value:t,configurable:!0}),"u"),l=Object.defineProperty,f=u((e,t)=>l(e,"name",{value:t,configurable:!0}),"f");Object.defineProperty(exports,"__esModule",{value:!0}),exports.GUEST_GRAPH_RETRY_MS=exports.MAX_FORWARDED_PROJECTS=exports.MAX_FORWARDED_GRAPH_BYTES=exports.FORWARDED_GRAPH_FORMAT=void 0,exports.ownedByThisUser=ownedByThisUser,exports.admitForwardedGraph=admitForwardedGraph,exports.compactSourceMaps=compactSourceMaps,exports.projectsOnly=projectsOnly,exports.snapshotWorkspaceGraph=snapshotWorkspaceGraph,exports.graphSnapshotScript=graphSnapshotScript,exports.guestGraphEnv=guestGraphEnv,exports.forwardedGraphInChild=forwardedGraphInChild,exports.createGuestGraphStore=createGuestGraphStore;const tslib_1=require("tslib"),node_child_process_1=require("node:child_process"),fs=tslib_1.__importStar(require("node:fs")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path")),pod_env_1=require("./pod-env"),project_graph_store_1=require("./project-graph-store"),registration_guards_1=require("./registration-guards");exports.FORWARDED_GRAPH_FORMAT=1,exports.MAX_FORWARDED_GRAPH_BYTES=8*1024*1024,exports.MAX_FORWARDED_PROJECTS=2e4,exports.GUEST_GRAPH_RETRY_MS=6e4;const GUEST_GRAPH_TIMEOUT_MS=12e4,SIGNATURE=/^(?:-|\?|\d+(?:\.\d+)?:\d+:\d+)$/;function megabytes(e){return`${(e/(1024*1024)).toFixed(1)} MB`}h(megabytes,"megabytes"),u(megabytes,"megabytes"),f(megabytes,"megabytes");const isRecord=f(e=>!!e&&typeof e=="object"&&!Array.isArray(e),"isRecord");function insideWorkspace(e){return e===""||path.isAbsolute(e)||/^[a-zA-Z]:/.test(e)?!1:!path.posix.normalize(e.replace(/\\/g,"/")).split("/").includes("..")}h(insideWorkspace,"insideWorkspace"),u(insideWorkspace,"insideWorkspace"),f(insideWorkspace,"insideWorkspace");function ownedByThisUser(e){const t=fs.statSync(e,{throwIfNoEntry:!1});if(!t?.isDirectory())return!1;if(typeof process.getuid!="function")return!0;const r=process.getuid();return t.uid===r||r===0&&t.uid===Number(process.env.SUDO_UID)}h(ownedByThisUser,"ownedByThisUser"),u(ownedByThisUser,"ownedByThisUser"),f(ownedByThisUser,"ownedByThisUser");function relativeDeclaringFiles(e,t){return(0,project_graph_store_1.declaringFiles)(e,t).map(r=>path.relative(e,r).split(path.sep).join("/"))}h(relativeDeclaringFiles,"relativeDeclaringFiles"),u(relativeDeclaringFiles,"relativeDeclaringFiles"),f(relativeDeclaringFiles,"relativeDeclaringFiles");function shapeProblem(e){if(!isRecord(e)||!isRecord(e.nodes)||!isRecord(e.dependencies))return"it has no `nodes` and `dependencies`";const t=e.nodes,r=Object.keys(t);if(r.length>exports.MAX_FORWARDED_PROJECTS)return`it names ${r.length} projects (at most ${exports.MAX_FORWARDED_PROJECTS})`;for(const o of r){const s=t[o];if(!isRecord(s)||s.name!==o||typeof s.type!="string"||!isRecord(s.data))return`project '${o}' is not a project node`;const n=s.data.root;if(typeof n!="string"||!insideWorkspace(n))return`project '${o}' has a root outside the workspace (${String(n)})`;const p=s.data.targets;if(p!==void 0&&(!isRecord(p)||!Object.values(p).every(isRecord)))return`project '${o}' has malformed targets`}for(const[o,s]of Object.entries(e.dependencies)){if(!(o in t)||!Array.isArray(s))return`the dependencies of '${o}' are not a known project's`;for(const n of s)if(!isRecord(n)||n.source!==o||typeof n.target!="string"||!(n.target in t)||typeof n.type!="string")return`a dependency of '${o}' is malformed`}}h(shapeProblem,"shapeProblem"),u(shapeProblem,"shapeProblem"),f(shapeProblem,"shapeProblem");function sourceMapsProblem(e){if(e!==void 0){if(!isRecord(e))return"its source maps are not a map";for(const[t,r]of Object.entries(e)){if(!isRecord(r))return`the source map of ${t} is malformed`;for(const o of Object.values(r))if(!Array.isArray(o)||o.length!==2||o[0]!==null&&typeof o[0]!="string"||typeof o[1]!="string")return`the source map of ${t} is malformed`}}}h(sourceMapsProblem,"sourceMapsProblem"),u(sourceMapsProblem,"sourceMapsProblem"),f(sourceMapsProblem,"sourceMapsProblem");function admitForwardedGraph(e,t){const r=f(a=>({refused:a}),"refuse");if(t.bytes>exports.MAX_FORWARDED_GRAPH_BYTES)return r(`${megabytes(t.bytes)} is over the ${megabytes(exports.MAX_FORWARDED_GRAPH_BYTES)} limit`);if(!isRecord(e))return r("it is not a project graph");if(e.format!==exports.FORWARDED_GRAPH_FORMAT)return r(`its format is ${String(e.format)}, and this gateway reads ${exports.FORWARDED_GRAPH_FORMAT}`);const o=e.root;if(typeof o!="string"||!path.isAbsolute(o))return r("it does not say which workspace it describes");if(!(0,registration_guards_1.sameRoot)(o,t.root))return r(`it describes ${o}, not the registering workspace ${t.root}`);if((0,registration_guards_1.sameRoot)(t.root,t.daemonRoot))return r(`${t.root} is the gateway's own workspace \u2014 the gateway reads that graph itself`);if(t.otherRoots.some(a=>(0,registration_guards_1.sameRoot)(a,t.root)))return r(`${t.root} is registered under another key`);if(!ownedByThisUser(t.root))return r(`${t.root} is not a directory this user owns`);const s=e.startedAt;if(typeof s!="number"||!Number.isFinite(s))return r("it does not say when it was computed");const n=shapeProblem(e.projectGraph)??sourceMapsProblem(e.sourceMaps);if(n)return r(n);const p=e.projectGraph,i=e.files;if(!isRecord(i))return r("it carries no fingerprint of its declaring files");const c=(0,registration_guards_1.canonicalRoot)(t.root),g=relativeDeclaringFiles(c,p),d=Object.keys(i),R=g.filter(a=>!(a in i));return R.length>0||d.length!==g.length?r(`its fingerprint does not cover exactly the files that declare it${R.length>0?` (no ${R[0]})`:""}`):Object.values(i).every(a=>typeof a=="string"&&SIGNATURE.test(a))?{snapshot:{root:c,startedAt:s,files:new Map(g.map(a=>[path.join(c,a),i[a]])),projectGraph:{nodes:p.nodes,dependencies:p.dependencies,externalNodes:{}},...e.sourceMaps!==void 0?{sourceMaps:e.sourceMaps}:{}}}:r("its fingerprint is malformed")}h(admitForwardedGraph,"admitForwardedGraph"),u(admitForwardedGraph,"admitForwardedGraph"),f(admitForwardedGraph,"admitForwardedGraph");function compactSourceMaps(e,t){const r={};for(const o of Object.values(e.nodes)){const s=t[o.data.root];if(!s)continue;const n=new Set;for(const i of Object.keys(o.data.targets??{})){const c=`targets.${i}`,g=new Set;for(const[d,R]of Object.entries(s)){if(d!==c&&!d.startsWith(`${c}.`))continue;const a=JSON.stringify(R);g.has(a)||(g.add(a),n.add(d))}}const p={};for(const[i,c]of Object.entries(s))n.has(i)&&(p[i]=c);r[o.data.root]=p}return r}h(compactSourceMaps,"compactSourceMaps"),u(compactSourceMaps,"compactSourceMaps"),f(compactSourceMaps,"compactSourceMaps");function projectsOnly(e){const t={};for(const[r,o]of Object.entries(e.dependencies))r in e.nodes&&(t[r]=o.filter(s=>s.target in e.nodes));return{nodes:e.nodes,dependencies:t}}h(projectsOnly,"projectsOnly"),u(projectsOnly,"projectsOnly"),f(projectsOnly,"projectsOnly");async function snapshotWorkspaceGraph(e,t=()=>(0,project_graph_store_1.computeProjectGraphInProcess)(e)){const r=Date.now(),o=(0,project_graph_store_1.filesystemNow)(),s=await t(),n=projectsOnly(s.projectGraph),p={};for(const i of(0,project_graph_store_1.declaringFiles)(e,s.projectGraph)){const c=fs.statSync(i,{throwIfNoEntry:!1});p[path.relative(e,i).split(path.sep).join("/")]=c&&c.mtimeMs>o?"?":(0,project_graph_store_1.statSignature)(i)}return{format:exports.FORWARDED_GRAPH_FORMAT,root:e,startedAt:r,projectGraph:n,...s.sourceMaps?{sourceMaps:compactSourceMaps(n,s.sourceMaps)}:{},files:p}}h(snapshotWorkspaceGraph,"snapshotWorkspaceGraph"),u(snapshotWorkspaceGraph,"snapshotWorkspaceGraph"),f(snapshotWorkspaceGraph,"snapshotWorkspaceGraph");function graphSnapshotScript(e=path.join(__dirname,"../../..")){const t=path.join(e,"graph-snapshot.js");if(fs.existsSync(t))return{path:t,execArgv:[]};const r=path.join(e,"graph-snapshot.ts");if(fs.existsSync(r))try{return{path:r,execArgv:["--require",require.resolve("@swc-node/register")]}}catch{return}}h(graphSnapshotScript,"graphSnapshotScript"),u(graphSnapshotScript,"graphSnapshotScript"),f(graphSnapshotScript,"graphSnapshotScript");function guestGraphEnv(e,t,r){const o={...(0,pod_env_1.podBaseEnv)(e,t,r)};for(const s of Object.keys(o))(s.startsWith("NX_TASK_")||["NX_WORKSPACE_ROOT","NX_WORKSPACE_ROOT_PATH","NX_WORKSPACE_DATA_DIRECTORY","NX_PROJECT_GRAPH_CACHE_DIRECTORY"].includes(s))&&delete o[s];return o.NX_DAEMON="false",o.NX_ISOLATE_PLUGINS="false",o}h(guestGraphEnv,"guestGraphEnv"),u(guestGraphEnv,"guestGraphEnv"),f(guestGraphEnv,"guestGraphEnv");function forwardedGraphInChild(e,t,r=graphSnapshotScript()){if(!r)return Promise.reject(new Error("graph-snapshot.js is missing from @lensmcp/cluster"));const o=fs.mkdtempSync(path.join(os.tmpdir(),"lensmcp-graph-")),s=path.join(o,"graph.json");return new Promise((n,p)=>{let i="";const c=(0,node_child_process_1.spawn)(process.execPath,[...r.execArgv,r.path,s],{cwd:e,env:t,stdio:["ignore","ignore","pipe"]});c.stderr?.on("data",d=>{i.length<4096&&(i+=d.toString())});const g=setTimeout(()=>c.kill("SIGKILL"),GUEST_GRAPH_TIMEOUT_MS);g.unref(),c.on("error",d=>{clearTimeout(g),p(d)}),c.on("exit",(d,R)=>{if(clearTimeout(g),d!==0){const a=i.trim().split(`
2
+ `).pop();p(new Error(`the graph computation in ${e} exited ${R??d}${a?` \u2014 ${a}`:""}`));return}try{const a=fs.statSync(s).size;n({bytes:a,graph:a>exports.MAX_FORWARDED_GRAPH_BYTES?void 0:JSON.parse(fs.readFileSync(s,"utf8"))})}catch(a){p(a)}})}).finally(()=>fs.rmSync(o,{recursive:!0,force:!0}))}h(forwardedGraphInChild,"forwardedGraphInChild"),u(forwardedGraphInChild,"forwardedGraphInChild"),f(forwardedGraphInChild,"forwardedGraphInChild");function createGuestGraphStore(e,t=process.env){const{wsKey:r,admission:o,context:s}=e,n=(0,registration_guards_1.canonicalRoot)(e.root),p=e.compute??(()=>forwardedGraphInChild(n,guestGraphEnv(t,s.daemonRoot,n))),i=o===void 0?"its registration forwarded none":o.refused!==void 0?`the project graph its registration forwarded was refused: ${o.refused}`:void 0;return(0,project_graph_store_1.createProjectGraphStore)(n,async()=>{const{graph:c,bytes:g}=await p(),d=admitForwardedGraph(c,{...s,bytes:g});if(d.refused!==void 0)throw new Error(`the computed project graph was refused: ${d.refused}`);return{projectGraph:d.snapshot.projectGraph,...d.snapshot.sourceMaps?{sourceMaps:d.snapshot.sourceMaps}:{}}},{...o?.snapshot?{seed:o.snapshot}:{},...i?{error:i}:{},retryAfterFailureMs:exports.GUEST_GRAPH_RETRY_MS,onRefreshed:f(c=>console.log(`[gateway] project graph of '${r}' (${n}) refreshed \u2014 ${Object.keys(c.projectGraph.nodes).length} projects; its services start through the serve runner again`),"onRefreshed")})}h(createGuestGraphStore,"createGuestGraphStore"),u(createGuestGraphStore,"createGuestGraphStore"),f(createGuestGraphStore,"createGuestGraphStore");
@@ -1,2 +1,2 @@
1
- "use strict";var a=Object.defineProperty;var n=(r,t)=>a(r,"name",{value:t,configurable:!0});var c=Object.defineProperty,o=n((r,t)=>c(r,"name",{value:t,configurable:!0}),"o");Object.defineProperty(exports,"__esModule",{value:!0}),exports.guestsFile=guestsFile,exports.readGuests=readGuests,exports.recordGuest=recordGuest,exports.forgetGuest=forgetGuest,exports.guestsToReplay=guestsToReplay;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path"));function guestsFile(){return path.join(process.env.LENSMCP_HOME||os.homedir(),".lensmcp","guests.json")}n(guestsFile,"guestsFile"),o(guestsFile,"guestsFile");function readGuests(r=guestsFile()){try{const t=JSON.parse(fs.readFileSync(r,"utf8"));return Array.isArray(t)?t.filter(e=>!!e&&typeof e=="object"&&typeof e.wsKey=="string"&&typeof e.root=="string"&&typeof e.daemonRoot=="string"&&!!e.projects&&typeof e.projects=="object"):[]}catch{return[]}}n(readGuests,"readGuests"),o(readGuests,"readGuests");function writeGuests(r,t){fs.mkdirSync(path.dirname(t),{recursive:!0,mode:448});const e=`${t}.${process.pid}.tmp`;fs.writeFileSync(e,JSON.stringify(r,null,2)+`
2
- `,{mode:384}),fs.renameSync(e,t)}n(writeGuests,"writeGuests"),o(writeGuests,"writeGuests");function recordGuest(r,t=guestsFile()){try{writeGuests([...readGuests(t).filter(e=>e.wsKey!==r.wsKey),r],t)}catch(e){console.warn(`[gateway] could not record '${r.wsKey}' for replay (${e.message}) \u2014 a daemon restart will not bring it back`)}}n(recordGuest,"recordGuest"),o(recordGuest,"recordGuest");function forgetGuest(r,t=guestsFile()){try{const e=readGuests(t),s=e.filter(i=>i.wsKey!==r);s.length!==e.length&&writeGuests(s,t)}catch{}}n(forgetGuest,"forgetGuest"),o(forgetGuest,"forgetGuest");const same=o((r,t)=>{const e=o(s=>{try{return fs.realpathSync(s)}catch{return path.resolve(s)}},"real");return e(r)===e(t)},"same");function guestsToReplay(r,t){const e=[],s=[];for(const i of t)!same(i.daemonRoot,r)||same(i.root,r)||(fs.existsSync(path.join(i.root,"package.json"))?e:s).push(i);return{replay:e,gone:s}}n(guestsToReplay,"guestsToReplay"),o(guestsToReplay,"guestsToReplay");
1
+ "use strict";var p=Object.defineProperty;var u=(r,t)=>p(r,"name",{value:t,configurable:!0});var a=Object.defineProperty,n=u((r,t)=>a(r,"name",{value:t,configurable:!0}),"n"),c=Object.defineProperty,o=n((r,t)=>c(r,"name",{value:t,configurable:!0}),"o");Object.defineProperty(exports,"__esModule",{value:!0}),exports.guestsFile=guestsFile,exports.readGuests=readGuests,exports.recordGuest=recordGuest,exports.forgetGuest=forgetGuest,exports.guestsToReplay=guestsToReplay;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),os=tslib_1.__importStar(require("node:os")),path=tslib_1.__importStar(require("node:path"));function guestsFile(){return path.join(process.env.LENSMCP_HOME||os.homedir(),".lensmcp","guests.json")}u(guestsFile,"guestsFile"),n(guestsFile,"guestsFile"),o(guestsFile,"guestsFile");function readGuests(r=guestsFile()){try{const t=JSON.parse(fs.readFileSync(r,"utf8"));return Array.isArray(t)?t.filter(e=>!!e&&typeof e=="object"&&typeof e.wsKey=="string"&&typeof e.root=="string"&&typeof e.daemonRoot=="string"&&!!e.projects&&typeof e.projects=="object"):[]}catch{return[]}}u(readGuests,"readGuests"),n(readGuests,"readGuests"),o(readGuests,"readGuests");function writeGuests(r,t){fs.mkdirSync(path.dirname(t),{recursive:!0,mode:448});const e=`${t}.${process.pid}.tmp`;fs.writeFileSync(e,JSON.stringify(r,null,2)+`
2
+ `,{mode:384}),fs.renameSync(e,t)}u(writeGuests,"writeGuests"),n(writeGuests,"writeGuests"),o(writeGuests,"writeGuests");function recordGuest(r,t=guestsFile()){try{writeGuests([...readGuests(t).filter(e=>e.wsKey!==r.wsKey),r],t)}catch(e){console.warn(`[gateway] could not record '${r.wsKey}' for replay (${e.message}) \u2014 a daemon restart will not bring it back`)}}u(recordGuest,"recordGuest"),n(recordGuest,"recordGuest"),o(recordGuest,"recordGuest");function forgetGuest(r,t=guestsFile()){try{const e=readGuests(t),s=e.filter(i=>i.wsKey!==r);s.length!==e.length&&writeGuests(s,t)}catch{}}u(forgetGuest,"forgetGuest"),n(forgetGuest,"forgetGuest"),o(forgetGuest,"forgetGuest");const same=o((r,t)=>{const e=o(s=>{try{return fs.realpathSync(s)}catch{return path.resolve(s)}},"real");return e(r)===e(t)},"same");function guestsToReplay(r,t){const e=[],s=[];for(const i of t)!same(i.daemonRoot,r)||same(i.root,r)||(fs.existsSync(path.join(i.root,"package.json"))?e:s).push(i);return{replay:e,gone:s}}u(guestsToReplay,"guestsToReplay"),n(guestsToReplay,"guestsToReplay"),o(guestsToReplay,"guestsToReplay");
@@ -1 +1 @@
1
- "use strict";var q=Object.defineProperty;var y=(f,n)=>q(f,"name",{value:n,configurable:!0});var x=Object.defineProperty,p=y((f,n)=>x(f,"name",{value:n,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.createHandler=createHandler;const manifest_1=require("../manifest"),service_keys_1=require("./service-keys"),gateway_errors_1=require("../gateway-errors"),discovery_1=require("./discovery"),edge_1=require("./edge"),observability_1=require("./observability"),chooser_1=require("./chooser");function createHandler(f){const{rt:n,obs:d,auth:v,proxy:_,hooks:i}=f,O=p(e=>(e.headers.host||"").split(":")[0],"hostOf"),S=p((e,t)=>{if((0,edge_1.cors)(e,t,n.routes),e.method==="OPTIONS"){t.writeHead(204,{"access-control-allow-methods":edge_1.PREFLIGHT_METHODS_NOROUTE,"access-control-allow-headers":String(e.headers["access-control-request-headers"]??"*")}),t.end();return}const o=(e.headers.host||"").split(":")[0],u=n.routes.filter(r=>r.host&&(0,manifest_1.hostMatches)(r.host,o)&&r.prefix),s=(e.url??"/").split("?")[0];if((s==="/"||s==="/index.html"||s==="")&&n.routes.some(r=>r.host&&(0,manifest_1.hostMatches)(r.host,o)&&r.project===observability_1.LENS_DASHBOARD_PROJECT)){(0,chooser_1.serveChooser)(t,n.wsKey,e);return}if(u.length>0&&(s==="/health"||s==="/healthz")){const r=u.map(l=>({project:l.project,prefix:l.prefix,pods:l.pool?((0,discovery_1.pickSock)(l.pool,0),l.pool.socks.length):void 0,state:l.svc?.state??(l.target?"up":"unknown")})),h=r.every(l=>l.state!=="down"||!0);t.writeHead(h?200:503,{"content-type":"application/json"}),t.end(JSON.stringify({status:"ok",host:o,services:r},null,2));return}if(u.length>0&&s==="/.well-known/services"){t.writeHead(200,{"content-type":"application/json"}),t.end(JSON.stringify({host:o,services:u.map(r=>({prefix:r.prefix,project:r.project,internal:!!r.internal}))},null,2));return}(0,edge_1.sendError)(t,e,404,"not_found",u.length>0?`No service mounted at ${s}. Mounted on ${o}: ${[...new Set(u.map(r=>r.prefix))].join(", ")} (+ /health, /.well-known/services)`:"No gateway route for this hostname.")},"handleNoRoute"),b=p(async(e,t)=>{if(!e.headers.host){const r=e.authority??e.headers[":authority"];r&&(e.headers.host=r)}(0,edge_1.stripOwnedHeaders)(e);let o=d.beginTrace(e);const u=Date.now();(0,gateway_errors_1.ensureRequestId)(e),o&&(d.traceStep(o,"received",{host:o.host,method:o.method,url:o.url}),e.__lensmcpTrace=o);const s=i.httpContext(e,t,o);try{const r=e.url??"/",h=(0,edge_1.canonicalize)(r);if(h===void 0){d.traceStep(o,"bad-path",{}),d.finishTrace(o,"gateway",400),(0,edge_1.sendError)(t,e,400,"bad_request","Bad Request");return}const l=h.policy,m=h.path+h.query;if(m!==r&&(0,edge_1.rememberRawTarget)(e,r),e.url=m,(0,edge_1.resolveClientIp)(n,e),i.has("onRequest")&&(await i.run("onRequest",s),s.responded()))return;const a=(0,manifest_1.matchRoute)(n.routes,O(e),l+h.query);if(!a){S(e,t);return}s.route=a;const w=d.startHeadlessFlow(e,a,o,u);if(w!==o&&(o=w,s.trace=w,e.__lensmcpTrace=w),d.traceStep(o,"route-match",{project:a.project,...a.prefix?{prefix:a.prefix}:{},...a.host?{routeHost:a.host}:{},...a.internal?{internal:!0}:{}}),e.method==="OPTIONS"){(0,edge_1.cors)(e,t,n.routes),t.writeHead(204,{"access-control-allow-methods":edge_1.PREFLIGHT_METHODS_ROUTED,"access-control-allow-headers":String(e.headers["access-control-request-headers"]??"*")}),t.end();return}if((0,edge_1.cors)(e,t,n.routes),i.has("beforeAuth")&&(await i.run("beforeAuth",s),s.responded()))return;if(a.internal){const c=v.internal(e,a,o);if(!c.ok){d.finishTrace(o,a.project,c.status,void 0,a),(0,edge_1.sendError)(t,e,c.status,c.reason,c.detail);return}s.caller=c.caller}else{const c=v.public(e,a,o,l);if(!c.ok){d.finishTrace(o,a.project,c.status,void 0,a),(0,edge_1.sendError)(t,e,c.status,c.reason,c.detail);return}if(s.claims=c.claims,i.has("afterAuth")&&(await i.run("afterAuth",s),s.responded()))return}const g=a.pool?n.serviceKeys[(0,service_keys_1.serviceKeyId)(a.svc?.wsKey,a.project)]:void 0;if(g&&(e.headers["x-internal-token"]=g),(0,edge_1.stampForwardingHeaders)(n,e),i.has("beforeForward")&&(await i.run("beforeForward",s),s.responded()))return;i.has("onResponse")&&t.on("close",()=>{s.status=t.statusCode??0,i.run("onResponse",s)}),_.forward(a,e,t)}catch(r){s.error=r,console.error(`[gateway] ${new Date().toISOString()} pipeline error traceId=${(0,gateway_errors_1.ensureRequestId)(e)}: ${r?.stack??String(r)}`),i.has("onError")&&await i.run("onError",s),s.responded()||(0,edge_1.sendError)(t,e,500,"internal","Internal gateway error.")}},"runPipeline");return(e,t)=>{b(e,t)}}y(createHandler,"createHandler"),p(createHandler,"createHandler");
1
+ "use strict";var S=Object.defineProperty;var v=(h,n)=>S(h,"name",{value:n,configurable:!0});var O=Object.defineProperty,y=v((h,n)=>O(h,"name",{value:n,configurable:!0}),"y"),R=Object.defineProperty,p=y((h,n)=>R(h,"name",{value:n,configurable:!0}),"p");Object.defineProperty(exports,"__esModule",{value:!0}),exports.createHandler=createHandler;const manifest_1=require("../manifest"),service_keys_1=require("./service-keys"),gateway_errors_1=require("../gateway-errors"),discovery_1=require("./discovery"),edge_1=require("./edge"),observability_1=require("./observability"),chooser_1=require("./chooser");function createHandler(h){const{rt:n,obs:l,auth:m,proxy:E,hooks:i}=h,H=p(e=>(e.headers.host||"").split(":")[0],"hostOf"),b=p((e,t)=>{if((0,edge_1.cors)(e,t,n.routes),e.method==="OPTIONS"){t.writeHead(204,{"access-control-allow-methods":edge_1.PREFLIGHT_METHODS_NOROUTE,"access-control-allow-headers":String(e.headers["access-control-request-headers"]??"*"),"access-control-max-age":edge_1.PREFLIGHT_MAX_AGE}),t.end();return}const s=(e.headers.host||"").split(":")[0],d=n.routes.filter(r=>r.host&&(0,manifest_1.hostMatches)(r.host,s)&&r.prefix),o=(e.url??"/").split("?")[0];if((o==="/"||o==="/index.html"||o==="")&&n.routes.some(r=>r.host&&(0,manifest_1.hostMatches)(r.host,s)&&r.project===observability_1.LENS_DASHBOARD_PROJECT)){(0,chooser_1.serveChooser)(t,n.wsKey,e);return}if(d.length>0&&(o==="/health"||o==="/healthz")){const r=d.map(u=>({project:u.project,prefix:u.prefix,pods:u.pool?((0,discovery_1.pickSock)(u.pool,0),u.pool.socks.length):void 0,state:u.svc?.state??(u.target?"up":"unknown")})),f=r.every(u=>u.state!=="down"||!0);t.writeHead(f?200:503,{"content-type":"application/json"}),t.end(JSON.stringify({status:"ok",host:s,services:r},null,2));return}if(d.length>0&&o==="/.well-known/services"){t.writeHead(200,{"content-type":"application/json"}),t.end(JSON.stringify({host:s,services:d.map(r=>({prefix:r.prefix,project:r.project,internal:!!r.internal}))},null,2));return}(0,edge_1.sendError)(t,e,404,"not_found",d.length>0?`No service mounted at ${o}. Mounted on ${s}: ${[...new Set(d.map(r=>r.prefix))].join(", ")} (+ /health, /.well-known/services)`:"No gateway route for this hostname.")},"handleNoRoute"),x=p(async(e,t)=>{if(!e.headers.host){const r=e.authority??e.headers[":authority"];r&&(e.headers.host=r)}(0,edge_1.stripOwnedHeaders)(e);let s=l.beginTrace(e);const d=Date.now();(0,gateway_errors_1.ensureRequestId)(e),s&&(l.traceStep(s,"received",{host:s.host,method:s.method,url:s.url}),e.__lensmcpTrace=s);const o=i.httpContext(e,t,s);try{const r=e.url??"/",f=(0,edge_1.canonicalize)(r);if(f===void 0){l.traceStep(s,"bad-path",{}),l.finishTrace(s,"gateway",400),(0,edge_1.sendError)(t,e,400,"bad_request","Bad Request");return}const u=f.policy,_=f.path+f.query;if(_!==r&&(0,edge_1.rememberRawTarget)(e,r),e.url=_,(0,edge_1.resolveClientIp)(n,e),i.has("onRequest")&&(await i.run("onRequest",o),o.responded()))return;const a=(0,manifest_1.matchRoute)(n.routes,H(e),u+f.query);if(!a){b(e,t);return}o.route=a;const w=l.startHeadlessFlow(e,a,s,d);if(w!==s&&(s=w,o.trace=w,e.__lensmcpTrace=w),l.traceStep(s,"route-match",{project:a.project,...a.prefix?{prefix:a.prefix}:{},...a.host?{routeHost:a.host}:{},...a.internal?{internal:!0}:{}}),e.method==="OPTIONS"){(0,edge_1.cors)(e,t,n.routes),t.writeHead(204,{"access-control-allow-methods":edge_1.PREFLIGHT_METHODS_ROUTED,"access-control-allow-headers":String(e.headers["access-control-request-headers"]??"*"),"access-control-max-age":edge_1.PREFLIGHT_MAX_AGE}),t.end();return}if((0,edge_1.cors)(e,t,n.routes),i.has("beforeAuth")&&(await i.run("beforeAuth",o),o.responded()))return;if(a.internal){const c=m.internal(e,a,s);if(!c.ok){l.finishTrace(s,a.project,c.status,void 0,a),(0,edge_1.sendError)(t,e,c.status,c.reason,c.detail);return}o.caller=c.caller}else{const c=m.public(e,a,s,u);if(!c.ok){l.finishTrace(s,a.project,c.status,void 0,a),(0,edge_1.sendError)(t,e,c.status,c.reason,c.detail);return}if(o.claims=c.claims,i.has("afterAuth")&&(await i.run("afterAuth",o),o.responded()))return}const g=a.pool?n.serviceKeys[(0,service_keys_1.serviceKeyId)(a.svc?.wsKey,a.project)]:void 0;if(g&&(e.headers["x-internal-token"]=g),(0,edge_1.stampForwardingHeaders)(n,e),i.has("beforeForward")&&(await i.run("beforeForward",o),o.responded()))return;i.has("onResponse")&&t.on("close",()=>{o.status=t.statusCode??0,i.run("onResponse",o)}),E.forward(a,e,t)}catch(r){o.error=r,console.error(`[gateway] ${new Date().toISOString()} pipeline error traceId=${(0,gateway_errors_1.ensureRequestId)(e)}: ${r?.stack??String(r)}`),i.has("onError")&&await i.run("onError",o),o.responded()||(0,edge_1.sendError)(t,e,500,"internal","Internal gateway error.")}},"runPipeline");return(e,t)=>{x(e,t)}}v(createHandler,"createHandler"),y(createHandler,"createHandler"),p(createHandler,"createHandler");
@@ -1 +1 @@
1
- "use strict";var a=Object.defineProperty;var l=(n,e)=>a(n,"name",{value:e,configurable:!0});var c=Object.defineProperty,f=l((n,e)=>c(n,"name",{value:e,configurable:!0}),"f");Object.defineProperty(exports,"__esModule",{value:!0}),exports.VITE_FULL_RELOAD_PAYLOAD=void 0,exports.encodeWsTextFrame=encodeWsTextFrame,exports.registerHmrClient=registerHmrClient,exports.broadcastFullReload=broadcastFullReload,exports.VITE_FULL_RELOAD_PAYLOAD='{"type":"full-reload"}';function encodeWsTextFrame(n){const e=Buffer.from(n,"utf8"),t=e.length;if(t<126)return Buffer.concat([Buffer.from([129,t]),e]);if(t<=65535){const r=Buffer.alloc(4);return r[0]=129,r[1]=126,r.writeUInt16BE(t,2),Buffer.concat([r,e])}const o=Buffer.alloc(10);return o[0]=129,o[1]=127,o.writeBigUInt64BE(BigInt(t),2),Buffer.concat([o,e])}l(encodeWsTextFrame,"encodeWsTextFrame"),f(encodeWsTextFrame,"encodeWsTextFrame");function registerHmrClient(n,e,t){const o=n.hmrClients??=new Map;let r=o.get(e);r||o.set(e,r=new Set),r.add(t);const s=f(()=>{r.delete(t),r.size===0&&o.delete(e)},"drop");t.once("close",s),t.once("error",s)}l(registerHmrClient,"registerHmrClient"),f(registerHmrClient,"registerHmrClient");function broadcastFullReload(n,e){const t=n.hmrClients?.get(e);if(!t||t.size===0)return 0;const o=encodeWsTextFrame(exports.VITE_FULL_RELOAD_PAYLOAD);let r=0;for(const s of t)if(!s.destroyed)try{s.write(o),r+=1}catch{}return r}l(broadcastFullReload,"broadcastFullReload"),f(broadcastFullReload,"broadcastFullReload");
1
+ "use strict";var u=Object.defineProperty;var i=(o,e)=>u(o,"name",{value:e,configurable:!0});var a=Object.defineProperty,l=i((o,e)=>a(o,"name",{value:e,configurable:!0}),"l"),c=Object.defineProperty,f=l((o,e)=>c(o,"name",{value:e,configurable:!0}),"f");Object.defineProperty(exports,"__esModule",{value:!0}),exports.VITE_FULL_RELOAD_PAYLOAD=void 0,exports.encodeWsTextFrame=encodeWsTextFrame,exports.registerHmrClient=registerHmrClient,exports.broadcastFullReload=broadcastFullReload,exports.VITE_FULL_RELOAD_PAYLOAD='{"type":"full-reload"}';function encodeWsTextFrame(o){const e=Buffer.from(o,"utf8"),r=e.length;if(r<126)return Buffer.concat([Buffer.from([129,r]),e]);if(r<=65535){const t=Buffer.alloc(4);return t[0]=129,t[1]=126,t.writeUInt16BE(r,2),Buffer.concat([t,e])}const n=Buffer.alloc(10);return n[0]=129,n[1]=127,n.writeBigUInt64BE(BigInt(r),2),Buffer.concat([n,e])}i(encodeWsTextFrame,"encodeWsTextFrame"),l(encodeWsTextFrame,"encodeWsTextFrame"),f(encodeWsTextFrame,"encodeWsTextFrame");function registerHmrClient(o,e,r){const n=o.hmrClients??=new Map;let t=n.get(e);t||n.set(e,t=new Set),t.add(r);const s=f(()=>{t.delete(r),t.size===0&&n.delete(e)},"drop");r.once("close",s),r.once("error",s)}i(registerHmrClient,"registerHmrClient"),l(registerHmrClient,"registerHmrClient"),f(registerHmrClient,"registerHmrClient");function broadcastFullReload(o,e){const r=o.hmrClients?.get(e);if(!r||r.size===0)return 0;const n=encodeWsTextFrame(exports.VITE_FULL_RELOAD_PAYLOAD);let t=0;for(const s of r)if(!s.destroyed)try{s.write(n),t+=1}catch{}return t}i(broadcastFullReload,"broadcastFullReload"),l(broadcastFullReload,"broadcastFullReload"),f(broadcastFullReload,"broadcastFullReload");
@@ -1 +1 @@
1
- "use strict";var u=Object.defineProperty;var i=(t,e)=>u(t,"name",{value:e,configurable:!0});var a=Object.defineProperty,n=i((t,e)=>a(t,"name",{value:e,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.createHooks=createHooks;const edge_1=require("./edge"),TERMINAL_PHASES=new Set(["onResponse","onError"]);function createHooks(t){return{run:n(async(e,r)=>{const o=t[e];if(!o||o.length===0)return;const d=TERMINAL_PHASES.has(e);for(const s of o){if(!d&&r.responded())return;await s(r)}},"run"),has:n(e=>(t[e]?.length??0)>0,"has"),httpContext:n((e,r,o)=>({req:e,res:r,socket:void 0,trace:o,route:void 0,claims:void 0,caller:void 0,pod:void 0,error:void 0,status:void 0,sendError:n((d,s,c)=>(0,edge_1.sendError)(r,e,d,s,c),"sendError"),responded:n(()=>r.writableEnded||r.headersSent,"responded")}),"httpContext"),upgradeContext:n((e,r,o)=>({req:e,res:void 0,socket:r,trace:o,route:void 0,claims:void 0,caller:void 0,pod:void 0,error:void 0,status:void 0,sendError:n(()=>{try{r.destroy()}catch{}},"sendError"),responded:n(()=>r.destroyed,"responded")}),"upgradeContext")}}i(createHooks,"createHooks"),n(createHooks,"createHooks");
1
+ "use strict";var p=Object.defineProperty;var c=(o,e)=>p(o,"name",{value:e,configurable:!0});var u=Object.defineProperty,i=c((o,e)=>u(o,"name",{value:e,configurable:!0}),"i"),a=Object.defineProperty,n=i((o,e)=>a(o,"name",{value:e,configurable:!0}),"n");Object.defineProperty(exports,"__esModule",{value:!0}),exports.createHooks=createHooks;const edge_1=require("./edge"),TERMINAL_PHASES=new Set(["onResponse","onError"]);function createHooks(o){return{run:n(async(e,r)=>{const t=o[e];if(!t||t.length===0)return;const d=TERMINAL_PHASES.has(e);for(const s of t){if(!d&&r.responded())return;await s(r)}},"run"),has:n(e=>(o[e]?.length??0)>0,"has"),httpContext:n((e,r,t)=>({req:e,res:r,socket:void 0,trace:t,route:void 0,claims:void 0,caller:void 0,pod:void 0,error:void 0,status:void 0,sendError:n((d,s,v)=>(0,edge_1.sendError)(r,e,d,s,v),"sendError"),responded:n(()=>r.writableEnded||r.headersSent,"responded")}),"httpContext"),upgradeContext:n((e,r,t)=>({req:e,res:void 0,socket:r,trace:t,route:void 0,claims:void 0,caller:void 0,pod:void 0,error:void 0,status:void 0,sendError:n(()=>{try{r.destroy()}catch{}},"sendError"),responded:n(()=>r.destroyed,"responded")}),"upgradeContext")}}c(createHooks,"createHooks"),i(createHooks,"createHooks"),n(createHooks,"createHooks");
@@ -1,2 +1,2 @@
1
- "use strict";var x=Object.defineProperty;var a=(t,e)=>x(t,"name",{value:e,configurable:!0});var h=Object.defineProperty,c=a((t,e)=>h(t,"name",{value:e,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.INSTANCE_NAME_PATTERN=void 0,exports.parseInstanceDecl=parseInstanceDecl,exports.instanceKey=instanceKey,exports.instanceSockNs=instanceSockNs,exports.commonApex=commonApex,exports.rewriteHost=rewriteHost,exports.envSuffix=envSuffix,exports.instanceBuiltinEnv=instanceBuiltinEnv,exports.instanceEnvFile=instanceEnvFile,exports.instanceResourcesEnvFile=instanceResourcesEnvFile,exports.parseInstanceEnv=parseInstanceEnv,exports.instanceEnv=instanceEnv;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path"));exports.INSTANCE_NAME_PATTERN=/^[a-z0-9](?:[a-z0-9-]{0,18}[a-z0-9])?$/;const HOST_PATTERN=/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/;function parseInstanceDecl(t){if(!t||typeof t!="object")return;const e=t;if(typeof e.name!="string"||!exports.INSTANCE_NAME_PATTERN.test(e.name)||typeof e.baseKey!="string"||e.baseKey.length===0)return;const n=typeof e.apex=="string"&&HOST_PATTERN.test(e.apex.toLowerCase())?e.apex.toLowerCase():void 0;return{name:e.name,baseKey:e.baseKey,...n?{apex:n}:{},...typeof e.mainRoot=="string"&&e.mainRoot.length>0?{mainRoot:e.mainRoot}:{},...e.frozen===!0?{frozen:!0}:{}}}a(parseInstanceDecl,"parseInstanceDecl"),c(parseInstanceDecl,"parseInstanceDecl");function instanceKey(t,e){return`${t}-${e}`}a(instanceKey,"instanceKey"),c(instanceKey,"instanceKey");function instanceSockNs(t){let e=2166136261;for(let n=0;n<t.length;n++)e^=t.charCodeAt(n),e=Math.imul(e,16777619);return`i-${(e>>>0&16777215).toString(16).padStart(6,"0")}`}a(instanceSockNs,"instanceSockNs"),c(instanceSockNs,"instanceSockNs");function commonApex(t){const e=t.map(s=>s.toLowerCase().replace(/^\*\./,"")).filter(s=>s.length>0).map(s=>s.split(".").reverse());if(e.length===0)return;const n=[];for(let s=0;;s++){const i=e[0]?.[s];if(i===void 0||!e.every(r=>r[s]===i))break;n.push(i)}return n.length>=2?n.reverse().join("."):void 0}a(commonApex,"commonApex"),c(commonApex,"commonApex");function rewriteHost(t,e,n){const s=t.toLowerCase();if(s.startsWith("*.")){const i=rewriteHost(s.slice(2),e,n);return i===void 0?void 0:`*.${i}`}if(s===e)return`${n}.${e}`;if(s.endsWith(`.${e}`))return`${s.slice(0,-e.length)}${n}.${e}`}a(rewriteHost,"rewriteHost"),c(rewriteHost,"rewriteHost");function envSuffix(t){return t.toUpperCase().replace(/[^A-Z0-9]+/g,"_").replace(/^_+|_+$/g,"")}a(envSuffix,"envSuffix"),c(envSuffix,"envSuffix");function instanceBuiltinEnv(t,e){const n={LENSMCP_INSTANCE:t.name,LENSMCP_APEX:t.apex,LENSMCP_BASE_APEX:t.baseApex},s={};for(const[i,r]of Object.entries(e).sort(([o],[l])=>o.localeCompare(l))){const o=envSuffix(i);o&&(r.host&&(n[`LENSMCP_HOST_${o}`]=r.host),r.internalHost&&(n[`LENSMCP_INTERNAL_HOST_${o}`]=r.internalHost),(r.host||r.internalHost)&&(s[i]={...r.host?{host:r.host}:{},...r.internalHost?{internalHost:r.internalHost}:{}}))}return n.LENSMCP_HOSTS_JSON=JSON.stringify(s),n}a(instanceBuiltinEnv,"instanceBuiltinEnv"),c(instanceBuiltinEnv,"instanceBuiltinEnv");function instanceEnvFile(t){return path.join(t,".lensmcp","instance.env")}a(instanceEnvFile,"instanceEnvFile"),c(instanceEnvFile,"instanceEnvFile");function instanceResourcesEnvFile(t){return path.join(t,".lensmcp","instance.resources.env")}a(instanceResourcesEnvFile,"instanceResourcesEnvFile"),c(instanceResourcesEnvFile,"instanceResourcesEnvFile");function parseInstanceEnv(t,e){const n={},s=[],i=c(o=>n[o]??e[o]??"","lookup"),r=c(o=>o.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(l,u)=>i(u)),"expand");return t.split(/\r?\n/).forEach((o,l)=>{const u=o.trim();if(u===""||u.startsWith("#"))return;const v=/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(u);if(!v){s.push(l+1);return}const[,_,p]=v;let E;if(p.startsWith("'")){const f=p.indexOf("'",1);if(f<0){s.push(l+1);return}E=p.slice(1,f)}else if(p.startsWith('"')){const f=p.indexOf('"',1);if(f<0){s.push(l+1);return}E=r(p.slice(1,f).replace(/\\n/g,`
2
- `))}else E=r(p.replace(/\s+#.*$/,"").trim());n[_]=E}),{env:n,skipped:s}}a(parseInstanceEnv,"parseInstanceEnv"),c(parseInstanceEnv,"parseInstanceEnv");function instanceEnv(t,e){let n={...e};for(const s of[instanceResourcesEnvFile(t),instanceEnvFile(t)]){let i;try{i=fs.readFileSync(s,"utf8")}catch{continue}const{env:r,skipped:o}=parseInstanceEnv(i,n);o.length>0&&console.warn(`[gateway] ${s}: skipped malformed line(s) ${o.join(", ")}`),n={...n,...r}}return{...n,...e}}a(instanceEnv,"instanceEnv"),c(instanceEnv,"instanceEnv");
1
+ "use strict";var S=Object.defineProperty;var p=(n,e)=>S(n,"name",{value:e,configurable:!0});var x=Object.defineProperty,a=p((n,e)=>x(n,"name",{value:e,configurable:!0}),"a"),h=Object.defineProperty,c=a((n,e)=>h(n,"name",{value:e,configurable:!0}),"c");Object.defineProperty(exports,"__esModule",{value:!0}),exports.INSTANCE_NAME_PATTERN=void 0,exports.parseInstanceDecl=parseInstanceDecl,exports.instanceKey=instanceKey,exports.instanceSockNs=instanceSockNs,exports.commonApex=commonApex,exports.rewriteHost=rewriteHost,exports.envSuffix=envSuffix,exports.instanceBuiltinEnv=instanceBuiltinEnv,exports.instanceEnvFile=instanceEnvFile,exports.instanceResourcesEnvFile=instanceResourcesEnvFile,exports.parseInstanceEnv=parseInstanceEnv,exports.instanceEnv=instanceEnv;const tslib_1=require("tslib"),fs=tslib_1.__importStar(require("node:fs")),path=tslib_1.__importStar(require("node:path"));exports.INSTANCE_NAME_PATTERN=/^[a-z0-9](?:[a-z0-9-]{0,18}[a-z0-9])?$/;const HOST_PATTERN=/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+$/;function parseInstanceDecl(n){if(!n||typeof n!="object")return;const e=n;if(typeof e.name!="string"||!exports.INSTANCE_NAME_PATTERN.test(e.name)||typeof e.baseKey!="string"||e.baseKey.length===0)return;const t=typeof e.apex=="string"&&HOST_PATTERN.test(e.apex.toLowerCase())?e.apex.toLowerCase():void 0;return{name:e.name,baseKey:e.baseKey,...t?{apex:t}:{},...typeof e.mainRoot=="string"&&e.mainRoot.length>0?{mainRoot:e.mainRoot}:{},...e.frozen===!0?{frozen:!0}:{}}}p(parseInstanceDecl,"parseInstanceDecl"),a(parseInstanceDecl,"parseInstanceDecl"),c(parseInstanceDecl,"parseInstanceDecl");function instanceKey(n,e){return`${n}-${e}`}p(instanceKey,"instanceKey"),a(instanceKey,"instanceKey"),c(instanceKey,"instanceKey");function instanceSockNs(n){let e=2166136261;for(let t=0;t<n.length;t++)e^=n.charCodeAt(t),e=Math.imul(e,16777619);return`i-${(e>>>0&16777215).toString(16).padStart(6,"0")}`}p(instanceSockNs,"instanceSockNs"),a(instanceSockNs,"instanceSockNs"),c(instanceSockNs,"instanceSockNs");function commonApex(n){const e=n.map(s=>s.toLowerCase().replace(/^\*\./,"")).filter(s=>s.length>0).map(s=>s.split(".").reverse());if(e.length===0)return;const t=[];for(let s=0;;s++){const o=e[0]?.[s];if(o===void 0||!e.every(r=>r[s]===o))break;t.push(o)}return t.length>=2?t.reverse().join("."):void 0}p(commonApex,"commonApex"),a(commonApex,"commonApex"),c(commonApex,"commonApex");function rewriteHost(n,e,t){const s=n.toLowerCase();if(s.startsWith("*.")){const o=rewriteHost(s.slice(2),e,t);return o===void 0?void 0:`*.${o}`}if(s===e)return`${t}.${e}`;if(s.endsWith(`.${e}`))return`${s.slice(0,-e.length)}${t}.${e}`}p(rewriteHost,"rewriteHost"),a(rewriteHost,"rewriteHost"),c(rewriteHost,"rewriteHost");function envSuffix(n){return n.toUpperCase().replace(/[^A-Z0-9]+/g,"_").replace(/^_+|_+$/g,"")}p(envSuffix,"envSuffix"),a(envSuffix,"envSuffix"),c(envSuffix,"envSuffix");function instanceBuiltinEnv(n,e){const t={LENSMCP_INSTANCE:n.name,LENSMCP_APEX:n.apex,LENSMCP_BASE_APEX:n.baseApex},s={};for(const[o,r]of Object.entries(e).sort(([i],[u])=>i.localeCompare(u))){const i=envSuffix(o);i&&(r.host&&(t[`LENSMCP_HOST_${i}`]=r.host),r.internalHost&&(t[`LENSMCP_INTERNAL_HOST_${i}`]=r.internalHost),(r.host||r.internalHost)&&(s[o]={...r.host?{host:r.host}:{},...r.internalHost?{internalHost:r.internalHost}:{}}))}return t.LENSMCP_HOSTS_JSON=JSON.stringify(s),t}p(instanceBuiltinEnv,"instanceBuiltinEnv"),a(instanceBuiltinEnv,"instanceBuiltinEnv"),c(instanceBuiltinEnv,"instanceBuiltinEnv");function instanceEnvFile(n){return path.join(n,".lensmcp","instance.env")}p(instanceEnvFile,"instanceEnvFile"),a(instanceEnvFile,"instanceEnvFile"),c(instanceEnvFile,"instanceEnvFile");function instanceResourcesEnvFile(n){return path.join(n,".lensmcp","instance.resources.env")}p(instanceResourcesEnvFile,"instanceResourcesEnvFile"),a(instanceResourcesEnvFile,"instanceResourcesEnvFile"),c(instanceResourcesEnvFile,"instanceResourcesEnvFile");function parseInstanceEnv(n,e){const t={},s=[],o=c(i=>t[i]??e[i]??"","lookup"),r=c(i=>i.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(u,f)=>o(f)),"expand");return n.split(/\r?\n/).forEach((i,u)=>{const f=i.trim();if(f===""||f.startsWith("#"))return;const _=/^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/.exec(f);if(!_){s.push(u+1);return}const[,m,l]=_;let E;if(l.startsWith("'")){const v=l.indexOf("'",1);if(v<0){s.push(u+1);return}E=l.slice(1,v)}else if(l.startsWith('"')){const v=l.indexOf('"',1);if(v<0){s.push(u+1);return}E=r(l.slice(1,v).replace(/\\n/g,`
2
+ `))}else E=r(l.replace(/\s+#.*$/,"").trim());t[m]=E}),{env:t,skipped:s}}p(parseInstanceEnv,"parseInstanceEnv"),a(parseInstanceEnv,"parseInstanceEnv"),c(parseInstanceEnv,"parseInstanceEnv");function instanceEnv(n,e){let t={...e};for(const s of[instanceResourcesEnvFile(n),instanceEnvFile(n)]){let o;try{o=fs.readFileSync(s,"utf8")}catch{continue}const{env:r,skipped:i}=parseInstanceEnv(o,t);i.length>0&&console.warn(`[gateway] ${s}: skipped malformed line(s) ${i.join(", ")}`),t={...t,...r}}return{...t,...e}}p(instanceEnv,"instanceEnv"),a(instanceEnv,"instanceEnv"),c(instanceEnv,"instanceEnv");