lensmcp 1.23.8 → 1.23.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bundled/dashboard.js
CHANGED
|
@@ -66,7 +66,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
66
66
|
`);import{createSocket as rD}from"node:dgram";import{closeSync as nD,existsSync as w1,openSync as iD,readSync as sD,statSync as $1}from"node:fs";import{createServer as aD}from"node:net";import{existsSync as B1,unlinkSync as C1}from"node:fs";var oD=1024*1024;function x1(e){let t=e.onError??(()=>{});try{B1(e.path)&&C1(e.path)}catch{}let r=new Set,i=e.maxFrameBytes??oD,u=aD(n=>{r.add(n);let a="";n.setEncoding("utf8"),n.on("data",l=>{a+=l;let d;for(;(d=a.indexOf(`
|
|
67
67
|
`))!==-1;){let p=a.slice(0,d);a=a.slice(d+1),p&&e.onMessage(p)}a.length>i&&(t(new Error(`uds: frame exceeded ${i} bytes without a newline \u2014 connection dropped`)),a="",n.destroy())}),n.on("error",l=>t(l)),n.on("close",()=>r.delete(n))});return u.on("error",n=>t(n)),u.listen(e.path,()=>e.onListening?.()),u.unref(),{close:o(()=>new Promise(n=>{for(let a of r)try{a.destroy()}catch{}r.clear();try{u.close(()=>{try{B1(e.path)&&C1(e.path)}catch{}n()})}catch{n()}}),"close")}}s(x1,"Ff"),o(x1,"createUdsServer");function k1(e){let t=e.eventFile??process.env.LENSMCP_EVENT_FILE,r=e.socketPath??process.env.LENSMCP_IPC_SOCKET,i=e.udsPath??process.env.LENSMCP_UDS,u=e.onError??(()=>{}),n=0,a=o(f=>{let m=f.trim();if(!m)return;let h;try{h=JSON.parse(m)}catch{return}if(!(!h||typeof h!="object"||!("id"in h)||!("source"in h)))try{e.sessionId&&h.sessionId==="pending"&&(h.sessionId=e.sessionId,h.context&&h.context.sessionId==="pending"&&(h.context.sessionId=e.sessionId)),e.bus.publish(h),n+=1}catch(E){u(E)}},"publish"),l=[],d=!1,p=!1,c=!1;if(t){d=!0;let f=0,m="",h=!1,E=e.replayBytes??Number(process.env.LENSMCP_REPLAY_BYTES??4*1024*1024);if(w1(t))try{let A=$1(t).size;Number.isFinite(E)&&E>0&&A>0?(f=Math.max(0,A-E),h=f>0):f=A}catch{f=0}let D=Buffer.alloc(64*1024),B=setInterval(o(()=>{if(!w1(t))return;let A;try{A=$1(t).size}catch{return}for(A<f&&(f=0,m="");f<A;){let I;try{I=iD(t,"r")}catch(j){u(j);return}try{let j=Math.min(D.length,A-f),F=sD(I,D,0,j,f);if(F<=0)break;f+=F,m+=D.toString("utf8",0,F);let b;for(;(b=m.indexOf(`
|
|
68
68
|
`))!==-1;){let w=m.slice(0,b);if(m=m.slice(b+1),h){h=!1;continue}a(w)}}finally{nD(I)}}},"drain"),e.pollMs??50);B.unref?.(),l.push(()=>clearInterval(B))}if(r){let[f,m]=r.split(":"),h=Number(m);if(f&&Number.isFinite(h)){p=!0;let E;try{E=rD("udp4"),E.on("message",D=>a(D.toString("utf8"))),E.on("error",D=>u(D)),E.bind(h,f),E.unref()}catch(D){u(D),p=!1}if(E){let D=E;l.push(()=>new Promise(B=>{try{D.close(()=>B())}catch{B()}}))}}}if(i)try{let f=x1({path:i,onMessage:o(m=>a(m),"onMessage"),onError:u});c=!0,l.push(()=>f.close())}catch(f){u(f)}let g=[];return d&&g.push("file"),p&&g.push("udp"),c&&g.push("uds"),{mode:g.join("+")||"none",count:o(()=>n,"count"),async stop(){for(let f of l)try{await f()}catch{}}}}s(k1,"Bf"),o(k1,"startEventIngest");import{existsSync as lD,readFileSync as A1}from"node:fs";import{dirname as dD,join as cD}from"node:path";function _1(e=process.cwd()){let t=Wl("nx.json",e);if(!t)return Je();try{let r=JSON.parse(A1(t,"utf8"));return Je(r.lensmcp?.thresholds)}catch{return Je()}}s(_1,"Zf"),o(_1,"loadWorkspaceThresholds");function I1(e=process.cwd()){let t=Wl("nx.json",e);if(!t)return lt;try{let r=JSON.parse(A1(t,"utf8"));return d1(r.lensmcp?.flows)}catch(r){return{...lt,problems:[`${t} could not be read as JSON (${r instanceof Error?r.message:String(r)}) \u2014 flow config ignored`]}}}s(I1,"qf"),o(I1,"loadWorkspaceFlowsConfig");function Wl(e,t){let r=t;for(let i=0;i<8;i++){let u=cD(r,e);if(lD(u))return u;let n=dD(r);if(n===r)break;r=n}}s(Wl,"$$"),o(Wl,"findUp");function S(e,t,r,i){var u=arguments.length,n=u<3?t:i===null?i=Object.getOwnPropertyDescriptor(t,r):i,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")n=Reflect.decorate(e,t,r,i);else for(var l=e.length-1;l>=0;l--)(a=e[l])&&(n=(u<3?a(n):u>3?a(t,r,n):a(t,r))||n);return u>3&&n&&Object.defineProperty(t,r,n),n}s(S,"$"),o(S,"__decorate");import{App as pD}from"@frontmcp/sdk";import{Resource as mD,ResourceContext as fD}from"@frontmcp/sdk";var gD=o(e=>typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0,"asRecord"),hD=o(e=>Array.isArray(e)?e.length:void 0,"arrayLen"),dt=o(e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,"asCount"),Gl=o(e=>typeof e=="string"?e:void 0,"asString");function de(e,...t){for(let r of t){let i=hD(e[r])??dt(e[r]);if(i!==void 0)return i}}s(de,"fe"),o(de,"countOf");var Ee=o((e,t,r=`${t}s`)=>`${e} ${e===1?t:r}`,"plural");function Ai(e,t,r,i,u){if(t>0)return{state:"failed",count:t,detail:`${Ee(t,`${i} error`)} \u2014 read ${u}`};if(r>0)return{state:"warning",count:r,detail:Ee(r,`${i} warning`)};let n=Gl(e.status);return n==="clean"||n==="passed"?{state:"passed",count:0,detail:`${i} clean`}:{state:"unknown",detail:`${i} has not reported a result yet (status=${n??"absent"})`}}s(Ai,"Vf"),o(Ai,"fromStatusField");var _i=[{kind:"typecheck",resource:"typecheck://current",reads:o(()=>["typecheck://errors"],"reads"),blocking:!0,source:"typescript",read:o(e=>Ai(e,de(e,"errorCount","errors")??0,0,"typecheck","typecheck://errors"),"read")},{kind:"lint",resource:"lint://current",reads:o(e=>e==="warning"?["lint://warnings"]:["lint://errors"],"reads"),blocking:!0,source:"eslint",read:o(e=>Ai(e,de(e,"errorCount","errors")??0,de(e,"warningCount","warnings")??0,"lint","lint://errors"),"read")},{kind:"build",resource:"build://current",reads:o(e=>e==="warning"?["build://current"]:["build://failures"],"reads"),blocking:!0,source:"vite",read:o(e=>Ai(e,de(e,"failures","failureCount")??0,de(e,"warnings","warningCount")??0,"build","build://failures"),"read")},{kind:"runtime",resource:"runtime://browser/errors",reads:o(()=>["runtime://browser/errors","runtime://browser/failed-requests"],"reads"),blocking:!0,source:"client-runtime",read:o(e=>{let t=de(e,"count","entries")??0;return t>0?{state:"failed",count:t,detail:`${Ee(t,"browser runtime error")} \u2014 read runtime://browser/errors`}:{state:"unknown",count:0,detail:"no browser runtime errors recorded (a browser may never have connected)"}},"read")},{kind:"runtime",resource:"runtime://errors",reads:o(()=>["runtime://errors"],"reads"),blocking:!0,source:"nestjs",read:o(e=>{let t=de(e,"count","entries")??0;return t>0?{state:"failed",count:t,detail:`${Ee(t,"server-side error")} \u2014 read runtime://errors (route, status, request id and stack)`}:{state:"unknown",count:0,detail:"no server-side errors recorded (no pod may have handled a request yet)"}},"read")},{kind:"cluster",resource:"process://cluster",reads:o(()=>["process://cluster"],"reads"),blocking:!0,source:"gateway",read:o(e=>{if((de(e,"services")??0)===0)return{state:"unknown",detail:"no cluster lifecycle events seen (the gateway may not be running)"};let t=de(e,"crashLooping")??0,r=de(e,"wedged")??0,i=de(e,"buildFailed")??0,u=de(e,"down")??0,n=dt(e.restarts)??0;if(t>0||r>0||i>0){let l=[t>0?`${Ee(t,"service")} crash-looping`:void 0,r>0?`${Ee(r,"service")} wedged`:void 0,i>0?`${Ee(i,"service")} failing to build`:void 0].filter(Boolean);return{state:"failed",count:t+r+i,detail:`${l.join(", ")} \u2014 read process://cluster (requests to them 502)`}}if(u>0)return{state:"warning",count:u,detail:`${Ee(u,"service")} down (idle scale-to-zero is normal; the next request restarts it)`};let a=de(e,"up")??0;return{state:"passed",count:0,detail:`${Ee(a,"service")} up${n>0?`, ${Ee(n,"restart")} this session`:""}`}},"read")},{kind:"memory",resource:"memory://leaks/suspected",reads:o(()=>["memory://leaks/suspected","memory://owners/growing"],"reads"),blocking:!1,source:"memory",read:o(e=>{let t=de(e,"suspected","leaks")??0;return t>0?{state:"warning",count:t,detail:`${Ee(t,"suspected leak")} \u2014 read memory://leaks/suspected`}:{state:"passed",count:0,detail:"no suspected leaks"}},"read")},{kind:"visual",resource:"visual://violations/current",reads:o(()=>["visual://violations/current"],"reads"),blocking:!1,source:"visual",read:o(e=>{let t=de(e,"violations")??0;return t>0?{state:"warning",count:t,detail:`${Ee(t,"visual violation")} \u2014 read visual://violations/current`}:{state:"passed",count:0,detail:"no visual violations"}},"read")},{kind:"perf",resource:"perf://slow-routes",reads:o(()=>["perf://slow-routes"],"reads"),blocking:!1,source:"perf",read:o(e=>{let t=de(e,"routes")??0,r=dt(e.thresholdMs);return t>0?{state:"warning",count:t,detail:`${Ee(t,"route")} over${r?` ${r}ms`:" the slow-route threshold"} \u2014 read perf://slow-routes`}:{state:"passed",count:0,detail:"no slow routes"}},"read")},{kind:"duplicate-requests",resource:"perf://duplicate-requests",reads:o(()=>["perf://duplicate-requests"],"reads"),blocking:!1,source:"perf",read:o(e=>{let t=de(e,"endpoints")??0,r=dt(e.peakThreshold);return t>0?{state:"warning",count:t,detail:`${Ee(t,"endpoint")} called ${r?`\u2265${r}\xD7`:"several times"} concurrently by one page \u2014 read perf://duplicate-requests`}:{state:"passed",count:0,detail:"no duplicated requests"}},"read")},{kind:"db",resource:"db://slow-queries",reads:o(()=>["db://slow-queries","db://analysis"],"reads"),blocking:!1,source:"db",read:o(e=>{let t=de(e,"queries")??0,r=dt(e.thresholdMs);return t>0?{state:"warning",count:t,detail:`${Ee(t,"query shape")} over${r?` ${r}ms`:" the slow-query threshold"} \u2014 read db://slow-queries`}:{state:"passed",count:0,detail:"no slow query shapes"}},"read")},{kind:"egress",resource:"net://egress/hosts",reads:o(e=>e==="warning"?["net://egress/hosts","net://egress/failures"]:["net://egress/hosts"],"reads"),blocking:!1,source:"external",read:o(e=>{let t=de(e,"failingHosts")??0,r=de(e,"slowHosts")??0,i=dt(e.thresholdMs);return t>0?{state:"warning",count:t,detail:`${Ee(t,"external host")} failing \u2014 read net://egress/failures`}:r>0?{state:"warning",count:r,detail:`${Ee(r,"external host")} over${i?` ${i}ms`:" the slow-egress threshold"} \u2014 read net://egress/hosts`}:{state:"passed",count:0,detail:"no failing or slow external calls"}},"read")}],Y7=_i.map(e=>e.resource);async function S1(e,t){let r={kind:t.kind,resource:t.resource},i;try{i=gD(await e.read(t.resource))}catch{return{...r,producer:"none",state:"unknown",detail:`no producer for ${t.resource} \u2014 this signal is unmonitored, not healthy`,reads:t.reads("unknown")}}if(!i)return{...r,producer:"none",state:"unknown",detail:`${t.resource} produced no readable payload`,reads:t.reads("unknown")};let u=Gl(i.producer),n=(e.revision(t.resource)??0)>0,a=u==="none"?"none":u==="connected"||n?"connected":"none",l=Gl(i.detail);if(a==="none")return{...r,producer:a,state:"unknown",detail:l??(u==="none"?`${t.resource} reports no producer attached \u2014 this signal is unmonitored, not healthy`:`${t.resource} is registered but has never reported \u2014 this signal is unmonitored, not healthy`),reads:t.reads("unknown")};let d;try{d=t.read(i)}catch{d={state:"unknown",detail:`${t.resource} payload could not be interpreted`}}let p=i.stale===!0,c=p?`${d.detail} (as of ${dt(i.ageMs)!==void 0?F1(dt(i.ageMs)):"a while ago"}; nothing has re-checked since)`:d.detail;return{...r,producer:a,state:d.state,...d.count===void 0?{}:{count:d.count},...p?{stale:!0}:{},detail:c,reads:t.reads(d.state)}}s(S1,"mR"),o(S1,"readSignal");function F1(e){return e<6e4?`${Math.max(1,Math.round(e/1e3))}s ago`:e<36e5?`${Math.round(e/6e4)}m ago`:`${Math.round(e/36e5)}h ago`}s(F1,"gR"),o(F1,"describeAge");async function Kl(e){return Promise.all(_i.map(t=>S1(e,t)))}s(Kl,"bs"),o(Kl,"readSignals");var Ir=o(e=>_i.find(t=>t.resource===e.resource)??_i.find(t=>t.kind===e.kind),"specFor");function Hl(e){return{source:Ir(e).source,severity:e.state==="failed"?"error":"warning",title:e.detail,fingerprint:`agent-status:${e.kind}:${e.state}`,resource:e.reads[0]??e.resource}}s(Hl,"x$"),o(Hl,"toItem");function z1(e){let t={failed:3,warning:2,unknown:1,passed:0},r=o(n=>{let a=e.filter(l=>l.kind===n);return a.length===0?"unknown":a.reduce((l,d)=>t[d.state]>t[l]?d.state:l,a[0].state)},"pick"),i=o(n=>n==="failed"?"failed":n==="passed"||n==="warning"?"passed":"unknown","tri"),u=o(n=>n,"quad");return{typecheck:i(r("typecheck")),lint:i(r("lint")),build:i(r("build")),runtime:u(r("runtime")),visual:u(r("visual")),memory:u(r("memory"))}}s(z1,"hR"),o(z1,"toChecks");function j1(e){let t=e.filter(p=>p.state==="failed"),r=e.filter(p=>p.state==="warning"),i=e.filter(p=>p.state==="passed"),u=t.filter(p=>Ir(p).blocking).map(Hl),n=[...t.filter(p=>!Ir(p).blocking),...r].map(Hl),a=u.length>0?"failing":n.length>0?"warning":i.length>0?"clean":"starting",l=[...t.filter(p=>Ir(p).blocking).flatMap(p=>p.reads),...t.filter(p=>!Ir(p).blocking).flatMap(p=>p.reads),...r.flatMap(p=>p.reads)],d=[...new Set(l)];return d.length===0&&d.push("events://recent"),{status:a,blocking:u,warnings:n,suggestedReads:d,checks:z1(e)}}s(j1,"_$"),o(j1,"deriveVerdict");function N1(e=process.env){let t=e.LENSMCP_TRANSPORT==="http"||e.LENSMCP_TRANSPORT==="socket",r=e.LENSMCP_PORT;return{mode:t?"shared":"embedded",pid:process.pid,startedAt:new Date(Date.now()-Math.round(process.uptime()*1e3)).toISOString(),...t&&r?{url:`http://127.0.0.1:${r}/mcp`}:{}}}s(N1,"vR"),o(N1,"readServerInfo");async function Ii(e){let t=await Kl(e.resources),r=j1(t);return{schemaVersion:1,revision:e.revision,updatedAt:new Date().toISOString(),sessionId:e.sessionId,server:N1(),status:r.status,blocking:r.blocking,warnings:r.warnings,suggestedReads:r.suggestedReads,checks:r.checks,signals:t}}s(Ii,"qt"),o(Ii,"aggregateStatus");var Xl="agent://current-status",Yl=class extends fD{static{s(this,"Kf")}static{o(this,"AgentCurrentStatusResource")}async execute(){let e=this.get(q);try{return await e.read(Xl)}catch{}let t=this.get(Fl);return Ii({resources:e,sessionId:t.id,revision:e.revision(Xl)??0})}};Yl=S([mD({name:"agent-current-status",uri:Xl,mimeType:"application/json",description:'Workspace health in one read: status (clean/warning/failing/starting), what is BLOCKING (typecheck/lint/build errors, browser runtime errors, wedged or crash-looping services), warnings, and the exact resources to read next. Signals with no producer report `producer: "none"` \u2014 unmonitored, not healthy.'})],Yl);var vD=Yl;import{Resource as yD,ResourceContext as ED}from"@frontmcp/sdk";var Ql=class extends ED{static{s(this,"Xf")}static{o(this,"ProcessClusterResource")}async execute(){return this.get(q).read("process://cluster")}};Ql=S([yD({name:"process-cluster",uri:"process://cluster",mimeType:"application/json",description:"Dev-cluster service health: which services are up / down / wedged / crash-looping, restart counts, and the error lines services printed (ERROR in, error TS\u2026, EADDRINUSE). Read this when a request 502s or a dev server stopped responding."})],Ql);var bD=Ql;import{Tool as DD,ToolContext as wD}from"@frontmcp/sdk";var O1=["typecheck","lint","build","runtime","cluster"],$D=[...O1,"all"],BD={typecheck:[{signal:"typecheck://current",resource:"typecheck://errors",keys:["errors"],hint:"TypeScript diagnostics from the watching tsc. Already computed \u2014 no need to run `nx typecheck`."}],lint:[{signal:"lint://current",resource:"lint://errors",keys:["errors"],hint:"ESLint errors from the watching lint pass. Already computed \u2014 no need to run `nx lint`."}],build:[{signal:"build://current",resource:"build://failures",keys:["failures"],hint:"Bundler/compile failures. The dev server is serving a stale or broken bundle until these clear."}],runtime:[{signal:"runtime://browser/errors",resource:"runtime://browser/errors",keys:["entries"],hint:"Uncaught errors from the browser. Pair with flow_list_recent to see what the user did first."},{signal:"runtime://errors",resource:"runtime://errors",keys:["entries"],hint:"Errors a dev service raised while handling a request (a 500 from a curl, an e2e runner or the page) \u2014 route, status, request id and stack. No browser is involved."}],cluster:[{signal:"process://cluster",resource:"process://cluster",keys:["errors"],hint:"Error lines printed by dev services (ERROR in / error TS / EADDRINUSE). A wedged or crash-looping service 502s every request routed to it."}]},CD=o(e=>typeof e=="object"&&e!==null&&!Array.isArray(e)?e:void 0,"asRecord");async function R1(e,t){let r;try{r=CD(await e.read(t.resource))}catch{return[]}if(!r)return[];for(let i of t.keys){let u=r[i];if(Array.isArray(u))return u}return[]}s(R1,"kR"),o(R1,"readItems");async function T1(e){let t=e.kind==="all"?O1:[e.kind],r=await Kl(e.resources),i=new Map(r.map(n=>[n.resource,n])),u=[];for(let n of t)for(let a of BD[n]){let l=i.get(a.signal),d=l?.producer??"none",p=l?.state??"unknown",c=d==="none"?[]:await R1(e.resources,a);u.push({kind:n,resource:a.resource,producer:d,state:p,count:c.length,returned:Math.min(c.length,e.limit),items:c.slice(0,e.limit),detail:l?.detail??`no producer for ${a.resource} \u2014 unmonitored, not healthy`,hint:a.hint})}return{kind:e.kind,totalErrors:u.reduce((n,a)=>n+a.count,0),unmonitored:[...new Set(u.filter(n=>n.producer==="none").map(n=>n.kind))],groups:u}}s(T1,"em"),o(T1,"collectErrors");var M1={name:"observe.current_status",description:'Workspace health in one call: whether anything is BLOCKING right now (typecheck errors, lint errors, build failures, browser runtime errors, wedged or crash-looping dev services), plus warnings and the exact resources to read next. Call this FIRST when a build, dev server, or page looks broken \u2014 and before running `nx typecheck` / `nx lint` for a project the dev cluster already watches, because those results are already computed here. Signals reporting `producer: "none"` are UNMONITORED, not healthy. Use observe.errors for the individual error items.'},zt={name:"observe.errors",description:"The actual error items the lens already computed: TypeScript diagnostics, ESLint errors, build failures, uncaught browser errors, server-side request errors (a dev service's 500: route, status, stack), and error lines printed by dev services (ERROR in\u2026, error TS\u2026, EADDRINUSE). Filter with `kind`. Prefer this over running `nx typecheck` / `nx lint` or tailing a dev-server log for a project the dev cluster watches: the watching producers already have the answer, so this costs one call instead of a rebuild. Each group reports `producer` \u2014 `none` means nothing is feeding that check, so an empty list there is NOT proof it is clean.",kinds:$D,defaultKind:"all",defaultLimit:25,maxLimit:200},P1="agent://current-status",ed=class extends wD{static{s(this,"rm")}static{o(this,"ObserveCurrentStatusTool")}async execute(){let e=this.get(q);try{return await e.read(P1)}catch{}let t=this.get(Fl);return Ii({resources:e,sessionId:t.id,revision:e.revision(P1)??0})}};ed=S([DD({name:M1.name,description:M1.description,inputSchema:{}})],ed);var xD=ed;import{Tool as kD,ToolContext as AD,z as U1}from"@frontmcp/sdk";var td=class extends AD{static{s(this,"om")}static{o(this,"ObserveErrorsTool")}async execute(e){let t=this.get(q);return T1({resources:t,kind:e.kind,limit:e.limit})}};td=S([kD({name:zt.name,description:zt.description,inputSchema:{kind:U1.enum(zt.kinds).default(zt.defaultKind).describe("Which failures to return. 'runtime' = browser errors AND a service's own request errors (the 500 case); 'cluster' = dev-service/pod errors (the 502 case). Default 'all'."),limit:U1.number().int().positive().max(zt.maxLimit).default(zt.defaultLimit).describe(`Max items per kind (default ${zt.defaultLimit}). \`count\` still reports the true total.`)}})],td);var _D=td;import{spawn as ID}from"node:child_process";import{existsSync as ud,readFileSync as SD}from"node:fs";import{join as Z1}from"node:path";import{Job as FD,JobContext as zD,z as Ce}from"@frontmcp/sdk";import{existsSync as jD}from"node:fs";import{dirname as ND,join as OD,relative as RD,resolve as jt,isAbsolute as TD}from"node:path";var MD=6;function q1(e=process.env,t=process.cwd()){return jt(e.LENSMCP_WORKSPACE_ROOT??t)}s(q1,"I$"),o(q1,"resolveAllowedRoot");function Si(e,t){let r=RD(jt(e),jt(t));return r===""||!r.startsWith("..")&&!TD(r)}s(Si,"sm"),o(Si,"isWithinRoot");function L1(e,t){let r=jt(e);if(t===void 0)return{ok:!0,cwd:r};let i=jt(r,t);return Si(r,i)?{ok:!0,cwd:i}:{ok:!1,reason:`cwd ${i} is outside this server's workspace (${r}). verify_fix runs a workspace-defined Nx target, so it only runs in the workspace this server was started for. Set LENSMCP_WORKSPACE_ROOT to serve a different one.`}}s(L1,"R$"),o(L1,"confineToWorkspace");function J1(e,t){let r=jt(t),i=jt(e);if(Si(r,i))for(let u=0;u<MD;u++){if(jD(OD(i,"nx.json")))return i;if(i===r)break;let n=ND(i);if(n===i||!Si(r,n))break;i=n}}s(J1,"T$"),o(J1,"findNxWorkspaceRootWithin");var PD=/^[@A-Za-z0-9][\w./-]*$/;function V1(e){return e.length<=214&&PD.test(e)}s(V1,"E$"),o(V1,"isValidProjectName");var rd=class extends zD{static{s(this,"cm")}static{o(this,"VerifyFixJob")}async execute(e){let t=Date.now(),r=e.project??process.env.LENSMCP_VERIFY_PROJECT??"example-web",i=q1(),u=L1(i,e.cwd);if(!u.ok)return this.log(`[verify_fix] refused: ${u.reason}`),{status:"errored",project:r,durationMs:Date.now()-t,stages:[],reportPath:null};let n=u.cwd;if(!V1(r))return this.log(`[verify_fix] refused: ${r} is not a valid Nx project name`),{status:"errored",project:r,durationMs:Date.now()-t,stages:[],reportPath:null};let a=J1(n,i);if(!a)return this.log(`No nx.json found between ${n} and ${i}`),{status:"errored",project:r,durationMs:Date.now()-t,stages:[],reportPath:null};let l=W1("nx",[a]);if(!l)return this.log(`Could not find node_modules/.bin/nx under ${a}`),{status:"errored",project:r,durationMs:Date.now()-t,stages:[],reportPath:null};this.log(`[verify_fix] nx run ${r}:agent-verify (cwd=${a})`);let d=ID(l,["run",`${r}:agent-verify`],{cwd:a,env:{...process.env},stdio:["ignore","pipe","pipe"]}),p=[],c=o(D=>{let B=/\[agent-verify\] ([a-z]+): (passed|failed|skipped|errored)/.exec(D);B&&B[1]&&B[2]&&(p.push({name:B[1],result:B[2],durationMs:0}),this.log(` ${B[1]}: ${B[2]}`))},"captureLine");nd(d.stdout,c),nd(d.stderr,c);let g=!1,f=setTimeout(()=>{g=!0;try{d.kill("SIGTERM")}catch{}},e.timeoutMs),m=await new Promise(D=>{d.on("exit",B=>D(B??1))});if(clearTimeout(f),g)return{status:"timeout",project:r,durationMs:Date.now()-t,stages:p,reportPath:null};let h=Z1(a,".lensmcp","verifications","latest.json"),E;if(ud(h))try{E=JSON.parse(SD(h,"utf-8"))}catch{E=void 0}return{status:E?.status??(m===0?"passed":"failed"),project:r,durationMs:E?.durationMs??Date.now()-t,stages:E?.stages??p,reportPath:ud(h)?h:null}}};rd=S([FD({name:"observe.verify_fix",description:"Run the deterministic verification loop (typecheck \u2192 lint \u2192 build) for a host project. Returns a per-stage report; suggested next read on failure is the relevant *://errors resource.",inputSchema:{project:Ce.string().describe('Nx project name in the host workspace to verify. Defaults to LENSMCP_VERIFY_PROJECT or "example-web".').optional(),cwd:Ce.string().describe("Directory to verify from. MUST be inside the workspace this server was started for (LENSMCP_WORKSPACE_ROOT, else the server's cwd); a path outside it is refused. Defaults to that workspace root.").optional(),timeoutMs:Ce.number().int().positive().default(5*6e4).describe("How long to wait for the verify pipeline before declaring it stuck.")},outputSchema:{status:Ce.enum(["passed","failed","errored","timeout"]),project:Ce.string().nullable(),durationMs:Ce.number(),stages:Ce.array(Ce.object({name:Ce.string(),result:Ce.enum(["passed","failed","skipped","errored"]),durationMs:Ce.number(),exitCode:Ce.number().optional(),summary:Ce.string().optional()})),reportPath:Ce.string().nullable()}})],rd);var UD=rd;function W1(e,t){for(let r of t){let i=Z1(r,"node_modules",".bin",e);if(ud(i))return i}}s(W1,"LR"),o(W1,"locateBin");function nd(e,t){if(!e)return;let r="";e.setEncoding("utf-8"),e.on("data",i=>{r+=typeof i=="string"?i:i.toString("utf-8");let u;for(;(u=r.indexOf(`
|
|
69
|
-
`))!==-1;){let n=r.slice(0,u);r=r.slice(u+1),t(n)}}),e.on("end",()=>{r.length&&t(r)})}s(nd,"A$"),o(nd,"bufferLines");var G1=class{static{s(this,"lm")}static{o(this,"AgentApp")}};G1=S([pD({id:"agent",name:"Agent",description:"Agent-facing summary, suggested reads, verification.",resources:[vD,bD],tools:[xD,_D],jobs:[UD]})],G1);var ZD={"service-starting":"starting","service-respawn":"starting","lens-app-up":"starting","service-up":"up","cold-start":"up","service-down":"down","idle-kill":"idle","service-recycle":"wedged","pod-recycle":"wedged","service-crash-loop":"crash-looping","lens-handoff-complete":"up","gateway-up":"up","gateway-down":"down","lens-child-starting":"starting","lens-child-up":"up","lens-child-exit":"down"},qD=new Set(["service-respawn","service-recycle","pod-recycle","lens-handoff-complete"]),LD=class{static{s(this,"Qn")}static{o(this,"ClusterHealth")}constructor(){this.services=new Map,this.errors=[]}ingest(e){if(e.source!=="gateway"||e.category!=="cluster")return!1;let t=e.raw??{},r=typeof t.kind=="string"?t.kind:void 0;if(!r)return!1;let i=typeof t.project=="string"?t.project:void 0;if(!i)return!1;if(r==="service-error"){let a=typeof t.line=="string"?t.line:e.message??e.title;this.errors.push({project:i,timestamp:e.timestamp,line:a,fingerprint:e.fingerprint}),this.errors.length>50&&this.errors.splice(0,this.errors.length-50);let l=this.touch(i,e.timestamp);return l.buildFailed=!0,l.lastTitle=e.title,!0}if(r==="lens-handoff-start"){let a=this.touch(i,e.timestamp);return t.oldServing!==!0&&(a.state="starting"),a.lastTitle=e.title,!0}if(r==="lens-handoff-failed"){let a=this.touch(i,e.timestamp);return t.oldKept!==!0&&(a.state="down"),a.lastTitle=e.title,!0}let u=ZD[r];if(!u)return!1;let n=this.touch(i,e.timestamp);return n.state=u,n.lastTitle=e.title,qD.has(r)&&(n.restarts+=1),u==="up"&&(n.buildFailed=!1),!0}snapshot(){let e=[...this.services.values()].sort((r,i)=>r.project.localeCompare(i.project)),t=o(r=>e.filter(i=>i.state===r).map(i=>i.project),"byState");return{services:e,up:t("up"),down:t("down"),wedged:t("wedged"),crashLooping:t("crash-looping"),idle:t("idle"),buildFailed:e.filter(r=>r.buildFailed).map(r=>r.project),restarts:e.reduce((r,i)=>r+i.restarts,0),errors:this.errors.slice()}}touch(e,t){let r=this.services.get(e);if(!r){if(this.services.size>=100){let i;for(let u of this.services.values())(!i||u.lastSeenAt<i.lastSeenAt)&&(i=u);i&&this.services.delete(i.project)}r={project:e,state:"starting",restarts:0,buildFailed:!1,lastTitle:"",lastSeenAt:t},this.services.set(e,r)}return r.lastSeenAt=t,r}},Fi="agent://current-status",zi="process://cluster",JD=250,VD=new Set(["build","lint","typecheck","runtime","cluster","memory","visual","performance"]);function K1(e){let t=new LD,r=e.sessionId??"pending",i,u=o(()=>{i||(i=setTimeout(()=>{i=void 0,e.resources.markDirty(Fi)},JD),i.unref?.())},"scheduleStatusRefresh"),n=o(l=>{let d=t.ingest(l);d&&e.resources.markDirty(zi),(d||VD.has(l.category))&&u()},"handler"),a=e.bus.subscribe(n);return e.resources.register(zi,()=>({schemaVersion:1,revision:e.resources.revision(zi)??0,updatedAt:new Date().toISOString(),...t.snapshot()})),e.resources.register(Fi,()=>Ii({resources:e.resources,sessionId:r,revision:e.resources.revision(Fi)??0})),{unsubscribe:o(()=>{a(),i&&(clearTimeout(i),i=void 0)},"unsubscribe"),uris:[Fi,zi]}}s(K1,"dm"),o(K1,"installAgentReducer");import{App as WD}from"@frontmcp/sdk";import{Resource as GD,ResourceContext as KD}from"@frontmcp/sdk";var id=class extends KD{static{s(this,"pm")}static{o(this,"FlowRecentResource")}async execute(){return this.get(q).read("flow://recent")}};id=S([GD({name:"flow-recent",uri:"flow://recent",mimeType:"application/json",description:"Last 50 flows seen this session, most recent first."})],id);var HD=id;import{Resource as XD,ResourceContext as YD}from"@frontmcp/sdk";var sd=class extends YD{static{s(this,"mm")}static{o(this,"FlowCurrentResource")}async execute(){return this.get(q).read("flow://current")}};sd=S([XD({name:"flow-current",uri:"flow://current",mimeType:"application/json",description:"The most recently active flow (origin + event count + headline)."})],sd);var QD=sd;import{Resource as ew,ResourceContext as tw}from"@frontmcp/sdk";var ad=class extends tw{static{s(this,"hm")}static{o(this,"FlowOriginsRecentResource")}async execute(){return this.get(q).read("flow://origins/recent")}};ad=S([ew({name:"flow-origins-recent",uri:"flow://origins/recent",mimeType:"application/json",description:"Last 50 flow-origin events (one per detected flow start)."})],ad);var uw=ad;import{Tool as rw,ToolContext as nw,z as ji}from"@frontmcp/sdk";var H1;function od(e){H1=e}s(od,"xs"),o(od,"setActiveFlowLookups");function Ve(){return H1}s(Ve,"be"),o(Ve,"activeFlowLookups");var iw=120;function ld(e,t,r){return{id:e.id,kind:e.kind,label:e.label,category:t,phase:e.phase,startOffsetMs:Math.max(0,e.start-r),durationMs:e.durationMs,events:e.counts.total,signal:e.counts.signal,errors:e.counts.errors,worstSeverity:e.worstSeverity,projects:e.projects,...e.route?{route:e.route}:{},...e.method?{method:e.method}:{},...e.part?{part:e.part}:{},...e.hot?{hot:e.hot}:{},...e.after?{after:e.after}:{}}}s(ld,"ym"),o(ld,"segmentView");function dd(e,t={}){let{segmentation:r,classification:i,segmentCategories:u}=e,n=Math.max(1,t.maxSegments??iw),a=r.segments.reduce((p,c)=>Math.min(p,c.start),1/0),l=Number.isFinite(a)?a:0,d=r.segments;if(d.length>n){let p=o(g=>g.counts.errors*1e6+g.counts.signal,"rank"),c=new Set([...d].sort((g,f)=>p(f)-p(g)||(g.id<f.id?-1:1)).slice(0,n).map(g=>g.id));d=d.filter(g=>c.has(g.id))}return{flowId:r.flowId,category:i.category,decidedBy:i.decidedBy,...i.subject?{subject:i.subject}:{},tags:i.tags,origin:i.origin,stats:{events:r.stats.events,signal:r.stats.signal,bookkeeping:r.stats.bookkeeping,segments:r.stats.segments,phases:r.stats.phases},phases:r.phases.map(p=>({index:p.index,startOffsetMs:Math.max(0,p.start-l),endOffsetMs:Math.max(0,p.end-l),segmentIds:p.segmentIds})),segments:d.map(p=>ld(p,u[p.id]??"other",l)),segmentsTruncated:d.length<r.segments.length}}s(dd,"bm"),o(dd,"overviewOf");function X1(e,t,r){let i=t.segmentation.segments.find(n=>n.id===r);if(!i)return;let u=new Set(i.eventIds);return e.filter(n=>u.has(n.id))}s(X1,"O$"),o(X1,"eventsOfSegment");function Y1(e,t){return e.filter(r=>(t.category===void 0||r.category===t.category)&&(t.tag===void 0||r.tags.includes(t.tag))&&(t.subject===void 0||r.subject===t.subject))}s(Y1,"N$"),o(Y1,"filterClassified");function Q1(e){let t=e.map(r=>({category:r.category,...r.subject?{subject:r.subject}:{},id:r.summary.flowId}));return i1(t).map(r=>({category:r.category,count:r.count,subjects:r.subjects.map(i=>({...i.subject!==void 0?{subject:i.subject}:{},count:i.count,flowIds:i.items.map(u=>u.id)}))}))}s(Q1,"P$"),o(Q1,"groupClassified");function e3(e){let t={};for(let r of e)t[r.category]=(t[r.category]??0)+1;return t}s(e3,"D$"),o(e3,"categoryCounts");function t3(e,t){if(!e)return{found:!1,reason:"no active flow reducer"};let r=e.getFlowSummary(t.flowId),i=e.getFlowEvents(t.flowId);if(!r||!i)return{found:!1,flowId:t.flowId};let u=e.analyzeFlow(t.flowId);if(t.segmentId){let a=u?X1(i,u,t.segmentId):void 0,l=u?.segmentation.segments.find(c=>c.id===t.segmentId);if(!u||!a||!l)return{found:!1,flowId:t.flowId,segmentId:t.segmentId,reason:"unknown segment id for this flow (the flow may have changed \u2014 re-read overview.segments)",segmentIds:u?.segmentation.segments.map(c=>c.id)??[]};let d=u.segmentation.segments.reduce((c,g)=>Math.min(c,g.start),1/0),{events:p}=Di(a,{includeRaw:t.includeRaw});return{found:!0,summary:r,segment:ld(l,u.segmentCategories[l.id]??"other",Number.isFinite(d)?d:l.start),truncated:p.length>t.limit,events:p.slice(0,t.limit)}}let{events:n}=Di(i,{includeRaw:t.includeRaw});if(t.expand){let a=n.find(p=>p.id===t.expand);if(!a)return{found:!1,flowId:t.flowId,expand:t.expand};let l=new Set(a.memberIds??[a.id]),d=i.filter(p=>l.has(p.id));return{found:!0,flowId:t.flowId,expanded:{id:a.id,title:a.title,count:d.length},events:d.map(p=>({id:p.id,timestamp:p.timestamp,source:p.source,category:p.category,severity:p.severity,title:p.title,message:p.message,...t.includeRaw?{raw:p.raw}:{}}))}}return{found:!0,summary:r,...u?{overview:dd(u)}:{},truncated:n.length>t.limit,events:n.slice(0,t.limit)}}s(t3,"M$"),o(t3,"getFlowDetail");async function u3(e,t,r){if(e){let u=e.classifiedRecent(),n=Y1(u,{...t.category?{category:t.category}:{},...t.tag?{tag:t.tag}:{}}),a=n.slice(0,t.limit);return{flows:a.map(l=>({...l.summary,category:l.category,decidedBy:l.decidedBy,...l.subject?{subject:l.subject}:{},tags:l.tags,segmentCount:l.segmentCount,phaseCount:l.phaseCount,signalCount:l.signalCount})),totalKnown:u.length,matching:n.length,categories:e3(u),...t.groupBy==="category"?{groups:Q1(a)}:{}}}let i=await r();return{flows:i.flows.slice(0,t.limit),totalKnown:i.flows.length}}s(u3,"C$"),o(u3,"listRecentFlows");function r3(e,t){if(!e)return{found:!1,reason:"no active flow reducer"};let r=e.analyzeFlow(t.flowId);return r?{found:!0,...dd(r,{maxSegments:t.maxSegments})}:{found:!1,flowId:t.flowId}}s(r3,"U$"),o(r3,"getFlowSegments");var cd=class extends nw{static{s(this,"wm")}static{o(this,"FlowListRecentTool")}async execute(e){return u3(Ve(),e,async()=>await this.get(q).read("flow://recent"))}};cd=S([rw({name:"flow.list_recent",description:'Lists the last N flows with their origin + event count + headline, and what each one IS: `category` (page-load, user-action, api, ai, test, or one you defined in nx.json#lensmcp.flows), `subject` (the templated page, component or route), `tags` (fan-out, has-error, slow, storm\u2026), `segmentCount`/`phaseCount`. Filter with `category` / `tag`; pass `groupBy: "category"` to also get the flows grouped category \u2192 subject; `categories` always counts every known flow per category. Same data as flow://recent but with a tunable limit.',inputSchema:{limit:ji.number().int().positive().max(50).default(10).describe("How many flows to return (default 10, max 50)."),category:ji.string().optional().describe('Only flows in this category, e.g. "page-load" or "checkout".'),tag:ji.string().optional().describe('Only flows carrying this tag, e.g. "has-error" or "fan-out".'),groupBy:ji.enum(["none","category"]).default("none").describe('"category" adds `groups`: the returned flows grouped category \u2192 subject.')}})],cd);var sw=cd;import{Tool as aw,ToolContext as ow,z as Sr}from"@frontmcp/sdk";var pd=class extends ow{static{s(this,"xm")}static{o(this,"FlowGetTool")}async execute(e){return t3(Ve(),e)}};pd=S([aw({name:"flow.get",description:'Returns one flow as the ordered, parented mechanism tree the dashboard renders: each node has `parent`, `area`, `start`, `durationMs`, and repeated work is collapsed (`count`, `memberIds`). Pass `expand: "<node id>"` to list the individual events a collapsed node stands for, or `includeRaw: true` for the full `event.raw` payloads. The response also carries `overview`: the flow cut into segments (one backend request each, UI bursts, the origin) grouped into phases, with its category, subject and tags \u2014 for a big flow read that first, then pass `segmentId: "<segment id>"` to get just that unit as a mechanism tree.',inputSchema:{flowId:Sr.string().describe("Flow id from flow://recent."),includeRaw:Sr.boolean().default(!1),limit:Sr.number().int().positive().max(500).default(200),expand:Sr.string().optional().describe("A node id from a previous call: returns the individual events it collapsed."),segmentId:Sr.string().optional().describe("A segment id from `overview.segments` (or flow.segments): returns only that unit of the flow, shaped like the whole.")}})],pd);var lw=pd;import{Tool as dw,ToolContext as cw,z as pw}from"@frontmcp/sdk";var md=class extends cw{static{s(this,"km")}static{o(this,"FlowFindByOriginTool")}async execute(e){let t=Ve();if(!t)return{found:!1,reason:"no active flow reducer"};let r=t.findFlowsByOrigin(e.originNodeId);return{found:r.length>0,count:r.length,flows:r}}};md=S([dw({name:"flow.find_by_origin",description:"Returns all flows whose origin node id matches `originNodeId` (e.g. a data-agent-component target).",inputSchema:{originNodeId:pw.string().describe("Origin node id \u2014 usually the value of data-agent-component on the originating element.")}})],md);var mw=md;import{Tool as fw,ToolContext as gw,z as hw}from"@frontmcp/sdk";import*as vw from"node:fs";import{dirname as yw,join as n3}from"node:path";var Ew="ai",bw=/^ai_[0-9a-z]{8,40}$/,Ni=o(e=>typeof e=="string"&&bw.test(e),"isAiCallId");function i3(e){return n3(yw(e),Ew)}s(i3,"uT"),o(i3,"aiContentDir");function s3(e,t){if(!Ni(t))throw new Error("invalid ai call id");return n3(i3(e),`${t}.json`)}s(s3,"lT"),o(s3,"aiContentFile");function fd(e,t){if(Ni(t))try{let r=JSON.parse(vw.readFileSync(s3(e,t),"utf8"));return r&&r.schemaVersion===1&&r.id===t?r:void 0}catch{return}}s(fd,"ks"),o(fd,"readAiContent");var gd=class extends gw{static{s(this,"Im")}static{o(this,"AiGetCallTool")}async execute(e){if(!Ni(e.callId))return{found:!1,reason:"invalid call id"};let t=fd(process.env.LENSMCP_EVENT_FILE??`${process.cwd()}/.lensmcp/events.jsonl`,e.callId);return t?{found:!0,call:t}:{found:!1,callId:e.callId,reason:"no captured content for this call \u2014 it was not captured (LENSMCP_AI_CAPTURE=content), or it has been rotated away"}}};gd=S([fw({name:"ai.get_call",description:"Returns the prompt and completion of ONE AI call (OpenAI, Anthropic, \u2026) captured by the node tap: system prompt, messages, tools offered, completion, tool calls, usage. `callId` is the `ai.contentRef` of a flow node whose kind is `ai-call` (see flow.get). Only exists when the service ran with LENSMCP_AI_CAPTURE=content; the text was redacted and size-capped when it was captured, and `truncated: true` says if anything was cut.",inputSchema:{callId:hw.string().describe('The contentRef of an ai-call flow node, e.g. "ai_0abc12345xyz78".')}})],gd);var Dw=gd;import{Tool as ww,ToolContext as $w,z as a3}from"@frontmcp/sdk";var hd=class extends $w{static{s(this,"Rm")}static{o(this,"FlowSegmentsTool")}async execute(e){return r3(Ve(),e)}};hd=S([ww({name:"flow.segments",description:"Returns one flow cut into segments and phases \u2014 the right first read for a flow with hundreds or thousands of events. Each segment is a backend request (its browser fetch, every service hop, db/redis/ai work and any queue worker it enqueued), a UI burst (state updates and renders, named by what churned), the origin that started the flow, or background noise; with times relative to the flow start, event/error counts, and a category. Also returns the flow's category, subject and tags. Open one unit with flow.get { flowId, segmentId }.",inputSchema:{flowId:a3.string().describe("Flow id from flow://recent or flow.list_recent."),maxSegments:a3.number().int().positive().max(500).default(120).describe("Cap on segments listed (failing and heaviest are kept first when it truncates).")}})],hd);var Bw=hd,o3=class{static{s(this,"Tm")}static{o(this,"FlowApp")}};o3=S([WD({id:"flow",name:"Flow",description:"Causal-chain index: every event carries a flowId; the app surfaces recent flows + origin events. story.compile turns one of these into a phase summary.",resources:[HD,QD,uw],tools:[sw,lw,Bw,mw,Dw]})],o3);var Oi="flow://recent",Ri="flow://current",Ti="flow://origins/recent",Fr=50,l3=50,vd=2e3,Cw=4*1024*1024,yd=32*1024*1024,xw=Fr+10;function d3(e){let t={flows:new Map,origins:[],recentOrder:[],retainedEvents:0,retainedBytes:0,evictedEvents:0,evictedForBytes:0},r=o((c,g,f,m=!0)=>{let h=Math.min(g,c.events.length);if(h<=0)return;if(m&&h>0&&(c.events[0]?.raw??{}).kind==="flow-origin"&&c.events.length>1){let D=c.eventBytes[1]??0;if(c.events.splice(1,1),c.eventBytes.splice(1,1),c.retainedBytes=Math.max(0,c.retainedBytes-D),t.retainedEvents=Math.max(0,t.retainedEvents-1),t.retainedBytes=Math.max(0,t.retainedBytes-D),t.evictedEvents+=1,f&&(t.evictedForBytes+=1),h-=1,h<=0)return}let E=0;for(let D=0;D<h;D+=1)E+=c.eventBytes[D]??0;c.events.splice(0,h),c.eventBytes.splice(0,h),c.retainedBytes=Math.max(0,c.retainedBytes-E),t.retainedEvents=Math.max(0,t.retainedEvents-h),t.retainedBytes=Math.max(0,t.retainedBytes-E),t.evictedEvents+=h,f&&(t.evictedForBytes+=h)},"evictPrefix"),i=o(c=>{let g=0,f=c.retainedBytes;for(;f>Cw&&g<c.eventBytes.length;)f-=c.eventBytes[g]??0,g+=1;r(c,g,!0)},"enforceEntryByteCap"),u=o(()=>{for(let c=t.recentOrder.length-1;t.retainedBytes>yd&&c>=0;c-=1){let g=t.flows.get(t.recentOrder[c]);if(!g)continue;let f=0,m=t.retainedBytes;for(;m>yd&&f<g.eventBytes.length;)m-=g.eventBytes[f]??0,f+=1;r(g,f,!0)}},"enforceGlobalByteCap"),n=o(c=>{let g=c.context.flowId;if(!g)return;let f=(c.raw??{}).kind;if(f==="subscription-added"||f==="subscription-removed"||f==="hook-run"||f==="store-created"||f==="singleton-instance"||f==="visual-frame")return;let m=f==="flow-origin",h=t.flows.get(g);if(!h){h={summary:{flowId:g,originType:c.context.originType,originNodeId:c.context.originNodeId,startedAt:c.timestamp,lastSeenAt:c.timestamp,eventCount:0,headline:c.title},events:[],eventBytes:[],retainedBytes:0,hasOrigin:!1},t.flows.set(g,h);let B={flowId:g,originType:c.context.originType,originNodeId:c.context.originNodeId,at:c.timestamp,label:c.title,eventId:c.id};t.origins.push(B),t.origins.length>l3&&t.origins.splice(0,t.origins.length-l3),e.resources.markDirty(Ti)}m&&!h.hasOrigin&&(h.hasOrigin=!0,h.summary.headline=c.title,c.context.originType&&(h.summary.originType=c.context.originType),c.context.originNodeId&&(h.summary.originNodeId=c.context.originNodeId)),c.timestamp<h.summary.startedAt&&(h.summary.startedAt=c.timestamp);let E=ki(c);h.events.push(c),h.eventBytes.push(E),h.retainedBytes+=E,t.retainedEvents+=1,t.retainedBytes+=E,h.events.length>vd&&r(h,h.events.length-vd,!1),i(h),h.summary.eventCount+=1,h.summary.lastSeenAt=c.timestamp;let D=t.recentOrder.indexOf(g);if(D>=0&&t.recentOrder.splice(D,1),t.recentOrder.unshift(g),t.recentOrder.length>Fr){let B=t.recentOrder.splice(Fr);for(let A of B){let I=t.flows.get(A);I&&r(I,I.events.length,!1,!1),t.flows.delete(A)}}u(),t.currentFlowId!==g&&(t.currentFlowId=g,e.resources.markDirty(Ri)),e.resources.markDirty(Oi)},"handler"),a=e.bus.subscribe(n);e.resources.register(Oi,()=>({schemaVersion:1,revision:e.resources.revision(Oi)??0,updatedAt:new Date().toISOString(),flows:t.recentOrder.map(c=>t.flows.get(c)?.summary).filter(c=>!!c)})),e.resources.register(Ri,()=>{let c=t.currentFlowId,g=c?t.flows.get(c):void 0;return{schemaVersion:1,revision:e.resources.revision(Ri)??0,updatedAt:new Date().toISOString(),flow:g?.summary??null}}),e.resources.register(Ti,()=>({schemaVersion:1,revision:e.resources.revision(Ti)??0,updatedAt:new Date().toISOString(),origins:t.origins.slice().reverse()}));let l=e.flows??lt,d=new Map,p={getFlowEvents(c){return t.flows.get(c)?.events.slice().sort((g,f)=>g.timestamp-f.timestamp)},getFlowSummary(c){return t.flows.get(c)?.summary},recentFlowIds(){return t.recentOrder.slice()},findFlowsByOrigin(c){return[...t.flows.values()].filter(g=>g.summary.originNodeId===c).map(g=>g.summary)},flowsConfig:l,analyzeFlow(c){let g=t.flows.get(c);if(!g)return;let f=`${g.summary.eventCount}:${g.events.length}:${g.summary.lastSeenAt}`,m=d.get(c);if(m&&m.key===f)return d.delete(c),d.set(c,m),m.analysis;let h=xi(p.getFlowEvents(c)??[],l);for(d.delete(c),d.set(c,{key:f,analysis:h});d.size>xw;)d.delete(d.keys().next().value);return h},classifiedRecent(c=Fr){let g=[];for(let f of t.recentOrder){if(g.length>=c)break;let m=t.flows.get(f)?.summary,h=p.analyzeFlow(f);!m||!h||g.push({summary:m,category:h.classification.category,decidedBy:h.classification.decidedBy,...h.classification.subject?{subject:h.classification.subject}:{},tags:h.classification.tags,segmentCount:h.segmentation.stats.segments,phaseCount:h.segmentation.stats.phases,signalCount:h.segmentation.stats.signal})}return g}};return od(p),{unsubscribe:o(()=>{od(void 0),a()},"unsubscribe"),uris:[Oi,Ri,Ti],lookups:p,retentionStats:o(()=>({residentEvents:t.retainedEvents,residentBytes:t.retainedBytes,evictedEvents:t.evictedEvents,evictedForBytes:t.evictedForBytes,eventCap:Fr*vd,byteCap:yd}),"retentionStats")}}s(d3,"zm"),o(d3,"installFlowReducer");import{App as kw}from"@frontmcp/sdk";import{Resource as Aw,ResourceContext as _w}from"@frontmcp/sdk";var Ed=class extends _w{static{s(this,"jm")}static{o(this,"StoryRecentResource")}async execute(){return this.get(q).read("story://recent")}};Ed=S([Aw({name:"story-recent",uri:"story://recent",mimeType:"application/json",description:"Last 50 compiled stories (one per flow), most recent first."})],Ed);var Iw=Ed;import{Resource as Sw,ResourceContext as Fw}from"@frontmcp/sdk";var bd=class extends Fw{static{s(this,"Nm")}static{o(this,"StoryLastResource")}async execute(){return this.get(q).read("story://last")}};bd=S([Sw({name:"story-last",uri:"story://last",mimeType:"application/json",description:"The most recently compiled story (full phase list)."})],bd);var zw=bd;import{Tool as jw,ToolContext as Nw,z as Ow}from"@frontmcp/sdk";var Mi="story://recent",Pi="story://last",Oe={byFlowId:new Map,order:[]},c3=!1;function p3(e){return c3||(e.resources.register(Mi,()=>({schemaVersion:1,revision:e.resources.revision(Mi)??0,updatedAt:new Date().toISOString(),stories:Oe.order.map(t=>Oe.byFlowId.get(t)).filter(t=>!!t).map(t=>({flowId:t.flowId,origin:t.origin,phaseCount:t.phases.length,startedAt:t.startedAt,endedAt:t.endedAt,eventCount:t.eventCount,finalState:t.finalState}))})),e.resources.register(Pi,()=>{let t=Oe.order[0],r=t?Oe.byFlowId.get(t):void 0;return{schemaVersion:1,revision:e.resources.revision(Pi)??0,updatedAt:new Date().toISOString(),story:r??null}}),c3=!0),m3(e.resources),{uris:[Mi,Pi]}}s(p3,"Mm"),o(p3,"installStoryReducer");var Dd;function m3(e){Dd=o(t=>{e.markDirty(t)},"markDirty")}s(m3,"_T"),o(m3,"setMarkDirty");function wd(e){Oe.byFlowId.set(e.flowId,e);let t=Oe.order.indexOf(e.flowId);if(t>=0&&Oe.order.splice(t,1),Oe.order.unshift(e.flowId),Oe.order.length>50){let r=Oe.order.splice(50);for(let i of r)Oe.byFlowId.delete(i)}Dd?.(Mi),Dd?.(Pi)}s(wd,"ro"),o(wd,"recordCompiledStory");function f3(e){return Oe.byFlowId.get(e)}s(f3,"Cm"),o(f3,"getCompiledStory");var $d=class extends Nw{static{s(this,"Um")}static{o(this,"StoryCompileTool")}async execute(e){let t=Ve();if(!t)return{compiled:!1,reason:"no active flow reducer"};let r=t.getFlowEvents(e.flowId);if(!r)return{compiled:!1,flowId:e.flowId};let i=Is(r,{flowId:e.flowId});return i?(wd(i),{compiled:!0,story:i}):{compiled:!1,flowId:e.flowId}}};$d=S([jw({name:"story.compile",description:"Compile a flow into a `FlowStory` (origin, phases, finalState). Caches the result; subsequent story.get(flowId) calls return it directly.",inputSchema:{flowId:Ow.string().describe("Flow id (from flow://recent).")}})],$d);var Rw=$d;import{Tool as Tw,ToolContext as Mw,z as Pw}from"@frontmcp/sdk";var Bd=class extends Mw{static{s(this,"Fm")}static{o(this,"StoryGetTool")}async execute(e){let t=f3(e.flowId);return t?{found:!0,story:t}:{found:!1,flowId:e.flowId}}};Bd=S([Tw({name:"story.get",description:"Returns a previously compiled story. If the story has not been compiled yet, returns `found: false`; call story.compile first.",inputSchema:{flowId:Pw.string().describe("Flow id.")}})],Bd);var Uw=Bd,g3=class{static{s(this,"Zm")}static{o(this,"StoryApp")}};g3=S([kw({id:"story",name:"Story",description:"Compiles flows into phase summaries (user-action / loading-ui / backend-request / state-update / final-render).",resources:[Iw,zw],tools:[Rw,Uw]})],g3);import{App as Zw}from"@frontmcp/sdk";import{Resource as qw,ResourceContext as Lw}from"@frontmcp/sdk";var Cd=class extends Lw{static{s(this,"qm")}static{o(this,"BuildCurrentResource")}async execute(){return this.get(q).read("build://current")}};Cd=S([qw({name:"build-current",uri:"build://current",mimeType:"application/json",description:"Current build status (clean / warning / failing), open failures and warnings."})],Cd);var Jw=Cd;import{Resource as Vw,ResourceContext as Ww}from"@frontmcp/sdk";var xd=class extends Ww{static{s(this,"Gm")}static{o(this,"BuildFailuresResource")}async execute(){return this.get(q).read("build://failures")}};xd=S([Vw({name:"build-failures",uri:"build://failures",mimeType:"application/json",description:"Currently-open build failures (deduped by fingerprint)."})],xd);var Gw=xd;import{Resource as Kw,ResourceContext as Hw}from"@frontmcp/sdk";var kd=class extends Hw{static{s(this,"Km")}static{o(this,"BuildRecentResource")}async execute(){return this.get(q).read("build://events/recent")}};kd=S([Kw({name:"build-events-recent",uri:"build://events/recent",mimeType:"application/json",description:"Last 50 build/lint/typecheck/HMR events in chronological order."})],kd);var Xw=kd,h3=class{static{s(this,"Xm")}static{o(this,"BuildApp")}};h3=S([Zw({id:"build",name:"Build",description:"Vite / TS / lint / HMR state.",resources:[Jw,Gw,Xw]})],h3);var Ui="build://current",Zi="build://failures",qi="build://events/recent",Yw=new Set(["vite","rollup","typescript","eslint"]),v3=new Set(["build","typecheck","lint"]),y3=50,Qw="Install the LensMCP Vite plugin (@lensmcp/vite-plugin) in the dev server, or run under the dev cluster, so build events reach this session.";function E3(e){let t=e.raw;return t&&typeof t=="object"?t:{}}s(E3,"LT"),o(E3,"readRaw");function b3(e,t){return e==="typecheck"?"tsc":e==="lint"?"eslint":t}s(b3,"FT"),o(b3,"defaultTool");function D3(e){let t={status:"unknown",recent:[],failures:new Map,warnings:new Map,hmrUpdates:0,producers:new Map,sawVerdict:!1},r=o((f,m)=>{let h=t.producers.get(f);t.producers.set(f,{id:f,tool:m.tool,...m.project?{project:m.project}:{},firstReportedAt:h?.firstReportedAt??m.at,lastReportedAt:Math.max(h?.lastReportedAt??0,m.at),lastRunStatus:m.runStatus,errorCount:m.errorCount??h?.errorCount??0,...m.warningCount!==void 0?{warningCount:m.warningCount}:h?.warningCount!==void 0?{warningCount:h.warningCount}:{},...m.durationMs!==void 0?{lastRunDurationMs:m.durationMs}:h?.lastRunDurationMs!==void 0?{lastRunDurationMs:h.lastRunDurationMs}:{},...m.error?{error:m.error}:{}}),St(t.producers,xr)},"touchProducer"),i=o(f=>{for(let[m,h]of t.failures)f(h)&&t.failures.delete(m);for(let[m,h]of t.warnings)f(h)&&t.warnings.delete(m)},"drop"),u=o((f,m)=>{i(h=>h.domain===f&&(m===void 0||h.project===m))},"clearScope"),n=o((f,m)=>{if(m.length===0)return;let h=new Set(m);i(E=>E.domain===f&&E.file!==void 0&&h.has(E.file))},"clearFiles"),a=o(()=>{if(t.failures.size>0){t.status="failing";return}if(t.warnings.size>0){t.status="warning";return}let f=[...t.producers.values()].some(m=>m.lastRunStatus==="error");t.status=f||!t.sawVerdict?"unknown":"clean"},"recomputeStatus"),l=o(()=>{e.resources.markDirty(Ui),e.resources.markDirty(Zi),e.resources.markDirty(qi)},"markDirty"),d=o(f=>{if([...t.failures.values()].some(m=>m.project===f)||[...t.warnings.values()].some(m=>m.project===f)||[...t.producers.values()].some(m=>m.project===f)){for(let m of v3)u(m,f);for(let[m,h]of t.producers)h.project===f&&t.producers.delete(m);t.sawVerdict=[...t.producers.values()].some(m=>m.lastRunStatus!=="error"),a(),l()}},"supersedeProject"),p=o(f=>{if(f.source==="gateway"&&f.category==="cluster"){let j=f.raw??null,F=j?.kind;(F==="service-starting"||F==="service-respawn")&&j?.project&&d(j.project);return}if(!Yw.has(f.source)||!v3.has(f.category))return;let m=f.category,h=E3(f),E=h.project,D=h.tool??b3(m,f.source),B=`${D}:${E??"*"}`,A=typeof h.kind=="string"&&h.kind.endsWith("-run"),I={id:f.id,timestamp:f.timestamp,severity:f.severity,title:f.title,...f.message!==void 0?{message:f.message}:{},...f.location?.file?{file:f.location.file}:h.file?{file:h.file}:{},domain:m,...E?{project:E}:{},fingerprint:f.fingerprint};if(f.severity==="info"&&(A&&h.phase==="start"||f.title.startsWith("tsc clear")||f.title.startsWith("ESLint clear"))){u(m,E),t.lastRunAt=f.timestamp,zr(t,I),r(B,{tool:D,...E?{project:E}:{},at:f.timestamp,runStatus:"running"}),A||(t.sawVerdict=!0),a(),l();return}if(A&&h.phase==="end"){let j=h.status==="error"?"error":h.status==="failing"?"failing":"clean";j==="clean"&&u(m,E),j!=="error"&&(t.sawVerdict=!0),t.lastRunAt=f.timestamp,zr(t,I),r(B,{tool:D,...E?{project:E}:{},at:f.timestamp,runStatus:j,...h.durationMs!==void 0?{durationMs:h.durationMs}:{},...h.errorCount!==void 0?{errorCount:h.errorCount}:{},...h.warningCount!==void 0?{warningCount:h.warningCount}:{},...h.error?{error:h.error}:{}}),a(),l();return}if(h.kind==="hmr"||f.title.startsWith("HMR ")){t.hmrUpdates+=1;let j=[...I.file?[I.file]:[],...f.relatedFiles??[]];n("build",j),t.lastRunAt=f.timestamp,t.sawVerdict=!0,zr(t,I),r(B,{tool:D,...E?{project:E}:{},at:f.timestamp,runStatus:"clean"}),a(),l();return}zr(t,I),f.severity==="error"||f.severity==="fatal"?(t.failures.set(I.fingerprint,I),t.warnings.delete(I.fingerprint)):f.severity==="warning"?t.failures.has(I.fingerprint)||t.warnings.set(I.fingerprint,I):(t.failures.delete(I.fingerprint),t.warnings.delete(I.fingerprint)),t.lastRunAt=f.timestamp,t.sawVerdict=!0,r(B,{tool:D,...E?{project:E}:{},at:f.timestamp,runStatus:t.failures.size>0?"failing":"clean"}),a(),l()},"handler"),c=e.bus.subscribe(p),g=o(()=>yi({producers:[...t.producers.values()],domain:"build",noProducerHint:Qw}),"health");return e.resources.register(Ui,()=>({schemaVersion:1,revision:e.resources.revision(Ui)??0,updatedAt:new Date().toISOString(),status:t.status,failures:[...t.failures.values()],warnings:[...t.warnings.values()],hmrUpdates:t.hmrUpdates,lastRunAt:t.lastRunAt,...g()})),e.resources.register(Zi,()=>({schemaVersion:1,revision:e.resources.revision(Zi)??0,updatedAt:new Date().toISOString(),failures:[...t.failures.values()],...g()})),e.resources.register(qi,()=>({schemaVersion:1,revision:e.resources.revision(qi)??0,updatedAt:new Date().toISOString(),events:t.recent.slice()})),{unsubscribe:c,uris:[Ui,Zi,qi]}}s(D3,"Hm"),o(D3,"installBuildReducer");function zr(e,t){e.recent.push(t),e.recent.length>y3&&e.recent.splice(0,e.recent.length-y3)}s(zr,"Os"),o(zr,"pushRecent");import{App as e$}from"@frontmcp/sdk";import{Resource as t$,ResourceContext as u$}from"@frontmcp/sdk";var Ad=class extends u${static{s(this,"Ym")}static{o(this,"LintCurrentResource")}async execute(){return this.get(q).read("lint://current")}};Ad=S([t$({name:"lint-current",uri:"lint://current",mimeType:"application/json",description:"Current lint status (clean / warning / failing) + counts."})],Ad);var r$=Ad;import{Resource as n$,ResourceContext as i$}from"@frontmcp/sdk";var _d=class extends i${static{s(this,"eg")}static{o(this,"LintErrorsResource")}async execute(){return this.get(q).read("lint://errors")}};_d=S([n$({name:"lint-errors",uri:"lint://errors",mimeType:"application/json",description:"Currently-open ESLint errors (deduped by fingerprint)."})],_d);var s$=_d;import{Resource as a$,ResourceContext as o$}from"@frontmcp/sdk";var Id=class extends o${static{s(this,"rg")}static{o(this,"LintWarningsResource")}async execute(){return this.get(q).read("lint://warnings")}};Id=S([a$({name:"lint-warnings",uri:"lint://warnings",mimeType:"application/json",description:"Currently-open ESLint warnings."})],Id);var l$=Id,w3=class{static{s(this,"og")}static{o(this,"LintApp")}};w3=S([e$({id:"lint",name:"Lint",description:"ESLint state.",resources:[r$,s$,l$]})],w3);var Li="lint://current",Ji="lint://errors",Vi="lint://warnings",d$="Nothing runs ESLint in the dev loop, so this is expected. Run `lensmcp lint [paths\u2026]` to publish a run; until then treat lint as UNCHECKED, not passing.";function $3(e){let t=e.raw;return t&&typeof t=="object"?t:{}}s($3,"XT"),o($3,"readRaw");function B3(e){let t={status:"unknown",errors:new Map,warnings:new Map,producers:new Map,sawVerdict:!1},r=o((c,g)=>{let f=t.producers.get(c);t.producers.set(c,{id:c,tool:g.tool,...g.project?{project:g.project}:{},firstReportedAt:f?.firstReportedAt??g.at,lastReportedAt:Math.max(f?.lastReportedAt??0,g.at),lastRunStatus:g.runStatus,errorCount:g.errorCount??f?.errorCount??0,...g.warningCount!==void 0?{warningCount:g.warningCount}:f?.warningCount!==void 0?{warningCount:f.warningCount}:{},...g.durationMs!==void 0?{lastRunDurationMs:g.durationMs}:f?.lastRunDurationMs!==void 0?{lastRunDurationMs:f.lastRunDurationMs}:{},...g.error?{error:g.error}:{}}),St(t.producers,xr)},"touchProducer"),i=o((c,g)=>{let f=o((m,h)=>{for(let[E,D]of m)h(D)&&m.delete(E)},"drop");if(c){f(t.errors,m=>m.project===c),f(t.warnings,m=>m.project===c);return}if(g){f(t.errors,m=>m.file===g),f(t.warnings,m=>m.file===g);return}t.errors.clear(),t.warnings.clear()},"clearScope"),u=o(()=>{if(t.errors.size>0){t.status="failing";return}if(t.warnings.size>0){t.status="warning";return}let c=[...t.producers.values()].some(g=>g.lastRunStatus==="error");t.status=c||!t.sawVerdict?"unknown":"clean"},"recomputeStatus"),n=o(()=>{e.resources.markDirty(Li),e.resources.markDirty(Ji),e.resources.markDirty(Vi)},"markDirty"),a=o(c=>{if([...t.errors.values()].some(g=>g.project===c)||[...t.warnings.values()].some(g=>g.project===c)||[...t.producers.values()].some(g=>g.project===c)){i(c,void 0);for(let[g,f]of t.producers)f.project===c&&t.producers.delete(g);t.sawVerdict=[...t.producers.values()].some(g=>g.lastRunStatus!=="error"),u(),n()}},"supersedeProject"),l=o(c=>{if(c.source==="gateway"&&c.category==="cluster"){let A=c.raw??null,I=A?.kind;(I==="service-starting"||I==="service-respawn")&&A?.project&&a(A.project);return}if(c.source!=="eslint"||c.category!=="lint")return;let g=$3(c),f=g.project,m=g.tool??"eslint",h=`${m}:${f??"*"}`,E=g.kind==="lint-run";if(c.severity==="info"&&(E&&g.phase==="start"||c.title.startsWith("ESLint clear"))){i(f,c.location?.file),t.lastRunAt=c.timestamp,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:"running"}),E||(t.sawVerdict=!0),u(),n();return}if(E&&g.phase==="end"){let A=g.status==="error"?"error":g.status==="failing"?"failing":"clean";A!=="error"&&(t.sawVerdict=!0),t.lastRunAt=c.timestamp,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:A,...g.durationMs!==void 0?{durationMs:g.durationMs}:{},...g.errorCount!==void 0?{errorCount:g.errorCount}:{},...g.warningCount!==void 0?{warningCount:g.warningCount}:{},...g.error?{error:g.error}:{}}),u(),n();return}let D=c.title.match(/^\[([^\]]+)\]/),B={id:c.id,timestamp:c.timestamp,severity:c.severity,...g.rule?{rule:g.rule}:D?.[1]?{rule:D[1]}:{},message:c.message??c.title,...c.location?.file?{file:c.location.file}:{},...c.location?.line!==void 0?{line:c.location.line}:{},...c.location?.column!==void 0?{column:c.location.column}:{},...f?{project:f}:{},fingerprint:c.fingerprint};if(c.severity==="error"||c.severity==="fatal")t.errors.set(B.fingerprint,B),t.warnings.delete(B.fingerprint);else if(c.severity==="warning")t.errors.has(B.fingerprint)||t.warnings.set(B.fingerprint,B);else return;t.lastRunAt=c.timestamp,t.sawVerdict=!0,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:t.errors.size>0?"failing":"clean"}),u(),n()},"handler"),d=e.bus.subscribe(l),p=o(()=>yi({producers:[...t.producers.values()],domain:"lint",noProducerHint:d$}),"health");return e.resources.register(Li,()=>({schemaVersion:1,revision:e.resources.revision(Li)??0,updatedAt:new Date().toISOString(),status:t.status,errorCount:t.errors.size,warningCount:t.warnings.size,lastRunAt:t.lastRunAt,...p()})),e.resources.register(Ji,()=>({schemaVersion:1,revision:e.resources.revision(Ji)??0,updatedAt:new Date().toISOString(),errors:[...t.errors.values()],...p()})),e.resources.register(Vi,()=>({schemaVersion:1,revision:e.resources.revision(Vi)??0,updatedAt:new Date().toISOString(),warnings:[...t.warnings.values()],...p()})),{unsubscribe:d,uris:[Li,Ji,Vi]}}s(B3,"ig"),o(B3,"installLintReducer");import{App as c$}from"@frontmcp/sdk";import{Resource as p$,ResourceContext as m$}from"@frontmcp/sdk";var Sd=class extends m${static{s(this,"sg")}static{o(this,"TypecheckCurrentResource")}async execute(){return this.get(q).read("typecheck://current")}};Sd=S([p$({name:"typecheck-current",uri:"typecheck://current",mimeType:"application/json",description:"Current TypeScript typecheck status + error count."})],Sd);var f$=Sd;import{Resource as g$,ResourceContext as h$}from"@frontmcp/sdk";var Fd=class extends h${static{s(this,"cg")}static{o(this,"TypecheckErrorsResource")}async execute(){return this.get(q).read("typecheck://errors")}};Fd=S([g$({name:"typecheck-errors",uri:"typecheck://errors",mimeType:"application/json",description:"Current TypeScript errors (deduped by fingerprint)."})],Fd);var v$=Fd,C3=class{static{s(this,"lg")}static{o(this,"TypecheckApp")}};C3=S([c$({id:"typecheck",name:"Typecheck",description:"TypeScript diagnostics from `tsc --watch`.",resources:[f$,v$]})],C3);var Wi="typecheck://current",Gi="typecheck://errors",y$="Wire one: the dev cluster publishes from `TsgoCheckPlugin` when `LENSMCP_TYPECHECK=tsgo` (@lensmcp/cluster), or call `startTscCollector()` from @lensmcp/session for a `tsc --watch` workspace.";function x3(e){let t=e.raw;return t&&typeof t=="object"?t:{}}s(x3,"nE"),o(x3,"readRaw");function k3(e){let t={status:"unknown",errors:new Map,producers:new Map,sawVerdict:!1},r=o((c,g)=>{let f=t.producers.get(c),m={id:c,tool:g.tool,...g.project?{project:g.project}:{},firstReportedAt:f?.firstReportedAt??g.at,lastReportedAt:Math.max(f?.lastReportedAt??0,g.at),lastRunStatus:g.runStatus,errorCount:g.errorCount??f?.errorCount??0,...g.durationMs!==void 0?{lastRunDurationMs:g.durationMs}:f?.lastRunDurationMs!==void 0?{lastRunDurationMs:f.lastRunDurationMs}:{},...g.warningCount!==void 0?{warningCount:g.warningCount}:{},...g.error?{error:g.error}:{}};t.producers.set(c,m),St(t.producers,xr)},"touchProducer"),i=o(c=>{if(!c){t.errors.clear();return}for(let[g,f]of t.errors)f.project===c&&t.errors.delete(g)},"clearScope"),u=o(()=>{if(t.errors.size>0){t.status="failing";return}let c=[...t.producers.values()].some(g=>g.lastRunStatus==="error");t.status=c||!t.sawVerdict?"unknown":"clean"},"recomputeStatus"),n=o(()=>{e.resources.markDirty(Wi),e.resources.markDirty(Gi)},"markDirty"),a=o(c=>{let g=[...t.errors.values()].some(m=>m.project===c),f=[...t.producers.values()].some(m=>m.project===c);if(!(!g&&!f)){i(c);for(let[m,h]of t.producers)h.project===c&&t.producers.delete(m);t.sawVerdict=[...t.producers.values()].some(m=>m.lastRunStatus!=="error"),u(),n()}},"supersedeProject"),l=o(c=>{if(c.source==="gateway"&&c.category==="cluster"){let A=c.raw??null,I=A?.kind;(I==="service-starting"||I==="service-respawn")&&A?.project&&a(A.project);return}if(c.source!=="typescript"||c.category!=="typecheck")return;let g=x3(c),f=g.project,m=g.tool??"tsc",h=`${m}:${f??"*"}`,E=g.kind==="typecheck-run";if(c.severity==="info"&&(E&&g.phase==="start"||c.title.startsWith("tsc clear"))){i(f),t.lastRunAt=c.timestamp,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:"running"}),E||(t.sawVerdict=!0),u(),n();return}if(E&&g.phase==="end"){let A=g.status==="error"?"error":g.status==="failing"?"failing":"clean";A!=="error"&&(t.sawVerdict=!0),t.lastRunAt=c.timestamp,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:A,...g.durationMs!==void 0?{durationMs:g.durationMs}:{},...g.errorCount!==void 0?{errorCount:g.errorCount}:{},...g.warningCount!==void 0?{warningCount:g.warningCount}:{},...g.error?{error:g.error}:{}}),u(),n();return}if(c.severity!=="error"&&c.severity!=="fatal")return;let D=c.title.match(/\bTS(\d+):/),B={id:c.id,timestamp:c.timestamp,...g.code?{code:g.code}:D?{code:`TS${D[1]}`}:{},message:c.message??c.title,...c.location?.file?{file:c.location.file}:{},...c.location?.line!==void 0?{line:c.location.line}:{},...c.location?.column!==void 0?{column:c.location.column}:{},...f?{project:f}:{},fingerprint:c.fingerprint};t.errors.set(B.fingerprint,B),t.lastRunAt=c.timestamp,t.sawVerdict=!0,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:"failing"}),u(),n()},"handler"),d=e.bus.subscribe(l),p=o(()=>yi({producers:[...t.producers.values()],domain:"typecheck",noProducerHint:y$}),"health");return e.resources.register(Wi,()=>({schemaVersion:1,revision:e.resources.revision(Wi)??0,updatedAt:new Date().toISOString(),status:t.status,errorCount:t.errors.size,lastRunAt:t.lastRunAt,...p()})),e.resources.register(Gi,()=>({schemaVersion:1,revision:e.resources.revision(Gi)??0,updatedAt:new Date().toISOString(),errors:[...t.errors.values()],...p()})),{unsubscribe:d,uris:[Wi,Gi]}}s(k3,"dg"),o(k3,"installTypecheckReducer");import{App as E$}from"@frontmcp/sdk";import{Resource as b$,ResourceContext as D$}from"@frontmcp/sdk";var zd=class extends D${static{s(this,"pg")}static{o(this,"BundleCurrentResource")}async execute(){return this.get(q).read("bundle://current")}};zd=S([b$({name:"bundle-current",uri:"bundle://current",mimeType:"application/json",description:"Most recent Vite/Rollup bundle report (chunks + sizes)."})],zd);var w$=zd;import{Resource as $$,ResourceContext as B$}from"@frontmcp/sdk";var jd=class extends B${static{s(this,"mg")}static{o(this,"BundleChunksResource")}async execute(){return this.get(q).read("bundle://chunks")}};jd=S([$$({name:"bundle-chunks",uri:"bundle://chunks",mimeType:"application/json",description:"Per-chunk bundle sizes (most recent build)."})],jd);var C$=jd;import{Resource as x$,ResourceContext as k$}from"@frontmcp/sdk";var Nd=class extends k${static{s(this,"hg")}static{o(this,"BundleModulesResource")}async execute(){return this.get(q).read("bundle://modules")}};Nd=S([x$({name:"bundle-modules",uri:"bundle://modules",mimeType:"application/json",description:"Flattened per-module bundle sizes (most recent build)."})],Nd);var A$=Nd;import{Resource as _$,ResourceContext as I$}from"@frontmcp/sdk";var Od=class extends I${static{s(this,"yg")}static{o(this,"BundleRegressionsResource")}async execute(){return this.get(q).read("bundle://regressions")}};Od=S([_$({name:"bundle-regressions",uri:"bundle://regressions",mimeType:"application/json",description:"Chunks/modules that grew, were added, or were removed vs the baseline."})],Od);var S$=Od;import{Resource as F$,ResourceContext as z$}from"@frontmcp/sdk";var Rd=class extends z${static{s(this,"wg")}static{o(this,"BundleCompareResource")}async execute(){return this.get(q).read("bundle://compare/latest")}};Rd=S([F$({name:"bundle-compare-latest",uri:"bundle://compare/latest",mimeType:"application/json",description:"Most recent build vs baseline: totals + delta."})],Rd);var j$=Rd,A3=class{static{s(this,"xg")}static{o(this,"BundleApp")}};A3=S([E$({id:"bundle",name:"Bundle",description:"Vite/Rollup bundle reports + regressions against baseline.",resources:[w$,C$,A$,S$,j$]})],A3);function Td(e,t){let r=[],i=new Map(e.chunks.map(n=>[n.name,n])),u=new Map(t.chunks.map(n=>[n.name,n]));for(let[n,a]of u){let l=i.get(n);if(!l){r.push({kind:"chunk-added",name:n,afterBytes:a.sizeBytes,deltaBytes:a.sizeBytes});continue}let d=a.sizeBytes-l.sizeBytes;d>256&&r.push({kind:"chunk-grew",name:n,beforeBytes:l.sizeBytes,afterBytes:a.sizeBytes,deltaBytes:d}),r.push(..._3(l,a))}for(let[n,a]of i)u.has(n)||r.push({kind:"chunk-removed",name:n,beforeBytes:a.sizeBytes,deltaBytes:-a.sizeBytes});return r.sort((n,a)=>Math.abs(a.deltaBytes)-Math.abs(n.deltaBytes))}s(Td,"Us"),o(Td,"compareReports");function _3(e,t){let r=[],i=new Map(e.modules.map(u=>[u.id,u.sizeBytes]));for(let u of t.modules){let n=i.get(u.id);if(n===void 0)u.sizeBytes>256&&r.push({kind:"module-added",name:`${t.name}::${u.id}`,afterBytes:u.sizeBytes,deltaBytes:u.sizeBytes});else{let a=u.sizeBytes-n;a>256&&r.push({kind:"module-grew",name:`${t.name}::${u.id}`,beforeBytes:n,afterBytes:u.sizeBytes,deltaBytes:a})}}return r}s(_3,"gE"),o(_3,"compareModules");var Ki="bundle://current",Hi="bundle://chunks",Xi="bundle://modules",jr="bundle://regressions",Nr="bundle://compare/latest";function I3(e){let t={baseline:e.initialBaseline,regressions:[]},r=o(u=>{if(u.source!=="rollup"&&u.source!=="vite"||u.category!=="build")return;let n=u.raw;if(!n||typeof n!="object"||!("kind"in n)||n.kind!=="bundle-report")return;let a=n.report;!a||!Array.isArray(a.chunks)||(t.current=a,t.regressions=t.baseline?Td(t.baseline,a):[],e.resources.markDirty(Ki),e.resources.markDirty(Hi),e.resources.markDirty(Xi),e.resources.markDirty(jr),e.resources.markDirty(Nr))},"handler"),i=e.bus.subscribe(r);return e.resources.register(Ki,()=>({schemaVersion:1,revision:e.resources.revision(Ki)??0,updatedAt:new Date().toISOString(),report:t.current??null})),e.resources.register(Hi,()=>({schemaVersion:1,revision:e.resources.revision(Hi)??0,updatedAt:new Date().toISOString(),chunks:t.current?.chunks??[]})),e.resources.register(Xi,()=>{let u=t.current?.chunks.flatMap(n=>n.modules.map(a=>({...a,chunk:n.name})))??[];return{schemaVersion:1,revision:e.resources.revision(Xi)??0,updatedAt:new Date().toISOString(),modules:u}}),e.resources.register(jr,()=>({schemaVersion:1,revision:e.resources.revision(jr)??0,updatedAt:new Date().toISOString(),regressions:t.regressions.slice()})),e.resources.register(Nr,()=>({schemaVersion:1,revision:e.resources.revision(Nr)??0,updatedAt:new Date().toISOString(),baseline:t.baseline??null,current:t.current??null,deltaBytes:t.baseline&&t.current?t.current.totalBytes-t.baseline.totalBytes:0})),{unsubscribe:i,uris:[Ki,Hi,Xi,jr,Nr],setBaseline:o(u=>{t.baseline=u,t.current&&(t.regressions=Td(t.baseline,t.current)),e.resources.markDirty(jr),e.resources.markDirty(Nr)},"setBaseline")}}s(I3,"_g"),o(I3,"installBundleReducer");import{App as N$}from"@frontmcp/sdk";import{Resource as O$,ResourceContext as R$}from"@frontmcp/sdk";var Md=class extends R${static{s(this,"kg")}static{o(this,"RuntimeBrowserConsoleResource")}async execute(){return this.get(q).read("runtime://browser/console")}};Md=S([O$({name:"runtime-browser-console",uri:"runtime://browser/console",mimeType:"application/json",description:"Most recent 200 console.* messages from any tab."})],Md);var T$=Md;import{Resource as M$,ResourceContext as P$}from"@frontmcp/sdk";var Pd=class extends P${static{s(this,"Ig")}static{o(this,"RuntimeBrowserErrorsResource")}async execute(){return this.get(q).read("runtime://browser/errors")}};Pd=S([M$({name:"runtime-browser-errors",uri:"runtime://browser/errors",mimeType:"application/json",description:"Uncaught browser errors + promise rejections, per tab, since that tab's current page load (a reload retracts the previous document's errors)."})],Pd);var U$=Pd;import{Resource as Z$,ResourceContext as q$}from"@frontmcp/sdk";var Ud=class extends q${static{s(this,"Tg")}static{o(this,"RuntimeServerErrorsResource")}async execute(){return this.get(q).read("runtime://errors")}};Ud=S([Z$({name:"runtime-errors",uri:"runtime://errors",mimeType:"application/json",description:"Errors raised INSIDE a backend pod, with no browser involved \u2014 the 500s a curl, an e2e runner or a queue job produces. Each entry carries the route, the status, the request id the gateway stamped, and the stack. Use this when a server-side call failed and no browser flow exists to explain it; `runtime://browser/errors` is the browser-side counterpart."})],Ud);var L$=Ud;import{Resource as J$,ResourceContext as V$}from"@frontmcp/sdk";var Zd=class extends V${static{s(this,"Ag")}static{o(this,"RuntimeBrowserNetworkResource")}async execute(){return this.get(q).read("runtime://browser/network")}};Zd=S([J$({name:"runtime-browser-network",uri:"runtime://browser/network",mimeType:"application/json",description:"Recent fetch / XHR / browser network activity."})],Zd);var W$=Zd;import{Resource as G$,ResourceContext as K$}from"@frontmcp/sdk";var qd=class extends K${static{s(this,"jg")}static{o(this,"RuntimeBrowserFailedRequestsResource")}async execute(){return this.get(q).read("runtime://browser/failed-requests")}};qd=S([G$({name:"runtime-browser-failed-requests",uri:"runtime://browser/failed-requests",mimeType:"application/json",description:"Recent failed network requests (status >= 400 or transport errors)."})],qd);var H$=qd,S3=class{static{s(this,"Ng")}static{o(this,"RuntimeApp")}};S3=S([N$({id:"runtime",name:"Runtime",description:"Live browser/node runtime state (console, errors, network).",resources:[T$,U$,L$,W$,H$]})],S3);var mu="runtime://browser/console",fu="runtime://browser/errors",gu="runtime://browser/network",hu="runtime://browser/failed-requests",vu="runtime://errors",X$="default",Ld=o(e=>e??X$,"tabOf");function F3(e){if(e.category!=="runtime")return!1;let t=e.raw;return t&&typeof t=="object"&&t.kind==="ready"?!0:e.title==="Client runtime ready"}s(F3,"TE"),o(F3,"isDocumentBoundary");function z3(e){if(e.category!=="runtime")return!1;let t=e.raw;return!!(t&&typeof t=="object"&&t.kind==="gone")}s(z3,"EE"),o(z3,"isTabGone");function j3(e){let t=(e.now??(()=>Date.now()))(),r={console:[],errors:[],network:[],failed:[],serverErrors:[],readyByTab:new Map,changedAt:new Map},i=o((d,p)=>{r.changedAt.set(d,p),e.resources.markDirty(d)},"touch"),u=o((d,p,c)=>{let g=d.filter(f=>!(Ld(f.tabId)===p&&f.timestamp<c));g.length!==d.length&&(d.length=0,d.push(...g))},"retract"),n=o(d=>{if(N3(d)){let c=d.raw?.project;if(c){let g=r.serverErrors.length;r.serverErrors=r.serverErrors.filter(f=>f.project!==c),r.serverErrors.length!==g&&i(vu,d.timestamp)}return}if(O3(d)){r.lastServerEventAt=Math.max(r.lastServerEventAt??0,d.timestamp),yu(r.serverErrors,R3(d),100),i(vu,d.timestamp);return}if(!(d.source==="client-runtime"||d.source==="chrome")&&!(d.source==="react"&&d.category==="network"))return;if(r.lastEventAt=Math.max(r.lastEventAt??0,d.timestamp),z3(d)){let c=Ld(d.context.tabId);u(r.errors,c,Number.POSITIVE_INFINITY),u(r.failed,c,Number.POSITIVE_INFINITY),r.readyByTab.delete(c);for(let g of[fu,hu,mu,gu])i(g,d.timestamp);return}if(F3(d)){let c=Ld(d.context.tabId);r.readyByTab.set(c,Math.max(r.readyByTab.get(c)??0,d.timestamp)),r.lastReadyAt=Math.max(r.lastReadyAt??0,d.timestamp);let g=d.timestamp-1e3;u(r.errors,c,g),u(r.failed,c,g);for(let f of[fu,hu,mu,gu])i(f,d.timestamp);return}let p={id:d.id,timestamp:d.timestamp,severity:d.severity,title:d.title,message:d.message,source:d.source,fingerprint:d.fingerprint,tabId:d.context.tabId,url:d.context.url,raw:d.raw};if(d.category==="network"){yu(r.network,p,200),i(gu,d.timestamp),d.severity==="error"&&(yu(r.failed,p,50),i(hu,d.timestamp));return}(d.severity==="error"||d.severity==="fatal")&&(yu(r.errors,p,100),i(fu,d.timestamp)),d.title?.startsWith("console.")&&(yu(r.console,p,200),i(mu,d.timestamp))},"handler"),a=e.bus.subscribe(n),l=o((d,p)=>T3(e.resources,d,p,r,t),"snap");return e.resources.register(vu,()=>l(vu,r.serverErrors)),e.resources.register(mu,()=>l(mu,r.console)),e.resources.register(fu,()=>l(fu,r.errors)),e.resources.register(gu,()=>l(gu,r.network)),e.resources.register(hu,()=>l(hu,r.failed)),{unsubscribe:a,uris:[mu,fu,gu,hu,vu]}}s(j3,"Dg"),o(j3,"installRuntimeReducer");function Jd(e){let t=e.raw??null,r=e.context;return t?.project??r.projectName}s(Jd,"W$"),o(Jd,"projectOf");function N3(e){if(e.source!=="gateway"||e.category!=="cluster")return!1;let t=e.raw?.kind;return t==="service-starting"||t==="service-respawn"}s(N3,"AE"),o(N3,"isGenerationBoundary");function O3(e){if(e.source!=="nestjs"||e.severity!=="error"&&e.severity!=="fatal")return!1;let t=e.raw??{};return t.kind==="server-request"||t.kind==="uncaught"?!0:t.kind!=="log"?!1:t.request?.error?!0:/\b[A-Za-z0-9_$]*(?:Error|Exception)\b|\b(?:ERROR|FATAL)\b/.test(e.title??"")}s(O3,"zE"),o(O3,"isServerError");function R3(e){let t=(e.raw??{}).request??{},r=t.error;return{id:e.id,timestamp:e.timestamp,severity:e.severity,title:e.title,message:e.message??r?.message,source:e.source,fingerprint:e.fingerprint,...e.context.requestId?{requestId:e.context.requestId}:{},...Jd(e)?{project:Jd(e)}:{},...typeof t.route=="string"?{route:t.route}:{},...typeof t.status=="number"?{status:t.status}:{},...r?.stack?{stack:r.stack}:{},raw:e.raw}}s(R3,"jE"),o(R3,"serverEntry");function T3(e,t,r,i,u){let n=t===vu,a=n?i.lastServerEventAt:i.lastEventAt,l=a!==void 0;return{schemaVersion:1,revision:e.revision(t)??0,updatedAt:new Date(i.changedAt.get(t)??u).toISOString(),count:r.length,entries:r.slice(),producer:l?"connected":"none",lastEventAt:a,lastReadyAt:i.lastReadyAt,detail:n?l?r.length===0?"No server-side errors held. Pods HAVE reported, but a new pod generation retracts the errors of the one it replaced \u2014 so this is NOT evidence the routes are healthy: nobody may have re-made the failing request since.":`${r.length} server-side error${r.length===1?"":"s"} from ${new Set(r.map(d=>d.project??"unknown")).size} project${new Set(r.map(d=>d.project??"unknown")).size===1?"":"s"}`:"No pod has ever reported into this session \u2014 this is NOT evidence the backend is healthy, nothing is watching. Run the backend under the dev cluster so pod errors reach this session.":l?`browser attached; ${r.length} entr${r.length===1?"y":"ies"} from ${i.readyByTab.size} open tab${i.readyByTab.size===1?"":"s"}`+(i.lastReadyAt===void 0?" (no page load observed yet)":""):"No browser has ever reported into this session \u2014 this is NOT evidence the app is healthy, nothing is watching. Open the app under the dev cluster (or the Vite dev server with @lensmcp/vite-plugin installed) so browser events reach this session."}}s(T3,"OE"),o(T3,"snapshot");function yu(e,t,r){e.push(t),e.length>r&&e.splice(0,e.length-r)}s(yu,"io"),o(yu,"pushBounded");import{App as Y$}from"@frontmcp/sdk";import{Resource as Q$,ResourceContext as eB}from"@frontmcp/sdk";var Vd=class extends eB{static{s(this,"Mg")}static{o(this,"BrowserTabsResource")}async execute(){return this.get(q).read("browser://tabs")}};Vd=S([Q$({name:"browser-tabs",uri:"browser://tabs",mimeType:"application/json",description:"Open browser tabs with per-tab status, url, and event counts. `status` reflects the tab's CURRENT page load \u2014 a reload resets it."})],Vd);var tB=Vd;import{Resource as uB,ResourceContext as rB}from"@frontmcp/sdk";var Wd=class extends rB{static{s(this,"Ug")}static{o(this,"BrowserActiveTabResource")}async execute(){return this.get(q).read("browser://active-tab")}};Wd=S([uB({name:"browser-active-tab",uri:"browser://active-tab",mimeType:"application/json",description:"The currently-focused browser tab."})],Wd);var nB=Wd,M3=class{static{s(this,"Fg")}static{o(this,"BrowserApp")}};M3=S([Y$({id:"browser",name:"Browser",description:"Per-tab browser state (multi-tab refinement comes in Phase 6).",resources:[tB,nB]})],M3);var ct="browser://tabs",pt="browser://active-tab";function P3(e){if(e.category!=="runtime")return!1;let t=e.raw;return t&&typeof t=="object"&&t.kind==="ready"?!0:e.title==="Client runtime ready"}s(P3,"UE"),o(P3,"isDocumentBoundary");function U3(e){if(e.category!=="runtime")return!1;let t=e.raw;return!!(t&&typeof t=="object"&&t.kind==="gone")}s(U3,"LE"),o(U3,"isTabGone");function Z3(e){let t=(e.now??(()=>Date.now()))(),r={tabs:new Map,changedAt:new Map},i=o(a=>{if(a.source!=="chrome"&&a.source!=="client-runtime")return;let l=a.context.tabId??"default";if(U3(a)){if(r.tabs.delete(l),r.activePageId===l){let p=[...r.tabs.keys()];r.activePageId=p[p.length-1]}r.lastEventAt=Math.max(r.lastEventAt??0,a.timestamp),r.changedAt.set(ct,a.timestamp),r.changedAt.set(pt,a.timestamp),e.resources.markDirty(ct),e.resources.markDirty(pt);return}let d=r.tabs.get(l);if(d||(d={pageId:l,url:a.context.url??"",status:"unknown",unreadEvents:0,totalEvents:0,loads:0}),r.tabs.delete(l),r.tabs.set(l,d),r.tabs.size>100){let p=r.tabs.keys().next().value;p!==void 0&&p!==l&&r.tabs.delete(p)}a.context.url&&(d.url=a.context.url),d.totalEvents+=1,d.lastEventAt=a.timestamp,r.activePageId=l,r.lastEventAt=Math.max(r.lastEventAt??0,a.timestamp),P3(a)?(d.status="clean",d.unreadEvents=0,d.loads+=1,d.lastReadyAt=a.timestamp):(d.unreadEvents+=1,a.severity==="error"||a.severity==="fatal"?d.status="failing":d.status!=="failing"&&a.severity==="warning"?d.status="warning":d.status==="unknown"&&(d.status="clean")),r.changedAt.set(ct,a.timestamp),r.changedAt.set(pt,a.timestamp),e.resources.markDirty(ct),e.resources.markDirty(pt)},"handler"),u=e.bus.subscribe(i),n=o(a=>new Date(r.changedAt.get(a)??t).toISOString(),"stamp");return e.resources.register(ct,()=>({schemaVersion:1,revision:e.resources.revision(ct)??0,updatedAt:n(ct),activePageId:r.activePageId,tabs:[...r.tabs.values()],lastEventAt:r.lastEventAt,producer:r.lastEventAt===void 0?"none":"connected"})),e.resources.register(pt,()=>{let a=r.activePageId;return{schemaVersion:1,revision:e.resources.revision(pt)??0,updatedAt:n(pt),tab:a?r.tabs.get(a)??null:null,lastEventAt:r.lastEventAt,producer:r.lastEventAt===void 0?"none":"connected"}}),{unsubscribe:u,uris:[ct,pt]}}s(Z3,"Bg"),o(Z3,"installBrowserReducer");import{App as iB}from"@frontmcp/sdk";import{Resource as sB,ResourceContext as aB}from"@frontmcp/sdk";var Gd=class extends aB{static{s(this,"Zg")}static{o(this,"NestProvidersResource")}async execute(){return this.get(q).read("nest://providers")}};Gd=S([sB({name:"nest-providers",uri:"nest://providers",mimeType:"application/json",description:"All known NestJS singleton-instance generations (with lifecycle)."})],Gd);var oB=Gd;import{Resource as lB,ResourceContext as dB}from"@frontmcp/sdk";var Kd=class extends dB{static{s(this,"Vg")}static{o(this,"NestRequestsResource")}async execute(){return this.get(q).read("nest://requests/recent")}};Kd=S([lB({name:"nest-requests-recent",uri:"nest://requests/recent",mimeType:"application/json",description:"Last 50 NestJS server requests with status + duration."})],Kd);var cB=Kd,q3=class{static{s(this,"Jg")}static{o(this,"NestApp")}};q3=S([iB({id:"nest",name:"Nest",description:"NestJS providers, request lifecycle, singleton generations.",resources:[oB,cB]})],q3);var Yi="nest://providers",Qi="nest://requests/recent";function L3(e){let t={providers:new Map,recentRequests:[]},r=o(u=>{if(u.source!=="nestjs")return;let n=u.raw??null;if(n?.kind==="singleton-instance"&&n.provider){let a=n.provider;if(t.providers.delete(a.instanceId),t.providers.set(a.instanceId,{...a}),t.providers.size>500){for(let l of t.providers.keys())if(t.providers.delete(l),t.providers.size<=500)break}e.resources.markDirty(Yi);return}if(n?.kind==="server-request"&&n.request){let a={...n.request,fingerprint:u.fingerprint,id:u.id};t.recentRequests.push(a),t.recentRequests.length>50&&t.recentRequests.splice(0,t.recentRequests.length-50),e.resources.markDirty(Qi);return}},"handler"),i=e.bus.subscribe(r);return e.resources.register(Yi,()=>({schemaVersion:1,revision:e.resources.revision(Yi)??0,updatedAt:new Date().toISOString(),providers:[...t.providers.values()]})),e.resources.register(Qi,()=>({schemaVersion:1,revision:e.resources.revision(Qi)??0,updatedAt:new Date().toISOString(),requests:t.recentRequests.slice()})),{unsubscribe:i,uris:[Yi,Qi]}}s(L3,"Kg"),o(L3,"installNestReducer");import{App as pB}from"@frontmcp/sdk";import{Resource as mB,ResourceContext as fB}from"@frontmcp/sdk";var Hd=class extends fB{static{s(this,"Wg")}static{o(this,"TraceRecentResource")}async execute(){return this.get(q).read("trace://recent")}};Hd=S([mB({name:"trace-recent",uri:"trace://recent",mimeType:"application/json",description:"Last 100 trace spans (flattened)."})],Hd);var gB=Hd;import{Resource as hB,ResourceContext as vB}from"@frontmcp/sdk";var Xd=class extends vB{static{s(this,"Hg")}static{o(this,"TraceFailedResource")}async execute(){return this.get(q).read("trace://failed")}};Xd=S([hB({name:"trace-failed",uri:"trace://failed",mimeType:"application/json",description:"Trace spans that ended with status=error."})],Xd);var yB=Xd,J3=class{static{s(this,"Qg")}static{o(this,"TraceApp")}};J3=S([pB({id:"trace",name:"Trace",description:"Cross-process span timeline (Phase 3 \u2014 flat; Phase 7 promotes to multi-axis graph).",resources:[gB,yB]})],J3);var es="trace://recent",ts="trace://failed";function V3(e){let t={recent:[],failed:[]},r=o(u=>{let n=u.raw??null;if(!n||n.kind!=="span"||!n.span?.name)return;let a={id:u.id,traceId:n.span.traceId,parentSpanId:n.span.parentSpanId,flowId:n.span.flowId??u.context.flowId,requestId:n.span.requestId??u.context.requestId,name:n.span.name,source:u.source,startTime:n.span.startTime??u.timestamp,endTime:n.span.endTime,durationMs:n.span.durationMs,status:n.span.status??(u.severity==="error"?"error":"ok")};Yd(t.recent,a,100),a.status==="error"&&Yd(t.failed,a,50),e.resources.markDirty(es),a.status==="error"&&e.resources.markDirty(ts)},"handler"),i=e.bus.subscribe(r);return e.resources.register(es,()=>({schemaVersion:1,revision:e.resources.revision(es)??0,updatedAt:new Date().toISOString(),spans:t.recent.slice()})),e.resources.register(ts,()=>({schemaVersion:1,revision:e.resources.revision(ts)??0,updatedAt:new Date().toISOString(),spans:t.failed.slice()})),{unsubscribe:i,uris:[es,ts]}}s(V3,"eh"),o(V3,"installTraceReducer");function Yd(e,t,r){e.push(t),e.length>r&&e.splice(0,e.length-r)}s(Yd,"X$"),o(Yd,"pushBounded");import{App as EB}from"@frontmcp/sdk";import{Resource as bB,ResourceContext as DB}from"@frontmcp/sdk";var Qd=class extends DB{static{s(this,"th")}static{o(this,"PerfSlowRoutesResource")}async execute(){return this.get(q).read("perf://slow-routes")}};Qd=S([bB({name:"perf-slow-routes",uri:"perf://slow-routes",mimeType:"application/json",description:"Routes that are slow NOW (\u2265 threshold on their latest call, or repeatedly lately). A one-off spike is retracted once later calls prove the route recovered; worstEver keeps the history."})],Qd);var wB=Qd;import{Resource as $B,ResourceContext as BB}from"@frontmcp/sdk";var ec=class extends BB{static{s(this,"nh")}static{o(this,"PerfDuplicateRequestsResource")}async execute(){return this.get(q).read("perf://duplicate-requests")}};ec=S([$B({name:"perf-duplicate-requests",uri:"perf://duplicate-requests",mimeType:"application/json",description:"Endpoints one page called SEVERAL TIMES CONCURRENTLY \u2014 the missing-dedupe signal (a hook fetching outside the shared resource cache, multiplied by however many components mount it). Concurrency, not count: sequential repeats are a caching question and are not reported. The threshold sits above 2 so React StrictMode\u2019s double-invoke never fires it. Two consecutive clean loads retract a finding, so a fix clears it without a restart."})],ec);var CB=ec,W3=class{static{s(this,"ih")}static{o(this,"PerfApp")}};W3=S([EB({id:"perf",name:"Perf",description:"Performance signals: slow server routes, and endpoints one page calls concurrently (the missing-dedupe signal).",resources:[wB,CB]})],W3);var us="perf://slow-routes",rs=20,G3=2,xB=200;function K3(e){let t=Je(e.thresholds).slowRouteMs,r=(e.now??(()=>Date.now()))(),i={routes:new Map},u=o(d=>{let p=d.raw??null;if(p?.kind!=="server-request"||!p.request)return;let{method:c,route:g}=p.request,f=p.request.durationMs??0,m=`${c} ${g}`,h=i.routes.get(m);if(h||(h={method:c,route:g,recent:[],samples:0,slowSamples:0,lastDurationMs:f,lastSeenAt:d.timestamp,worstEverMs:0,worstEverAt:d.timestamp}),i.routes.delete(m),i.routes.set(m,h),h.recent.push(f),h.recent.length>rs&&h.recent.splice(0,h.recent.length-rs),h.samples+=1,f>=t&&(h.slowSamples+=1),h.lastDurationMs=f,h.lastSeenAt=d.timestamp,f>h.worstEverMs&&(h.worstEverMs=f,h.worstEverAt=d.timestamp),i.routes.size>xB){let E=i.routes.keys().next().value;E!==void 0&&i.routes.delete(E)}i.lastSampleAt=Math.max(i.lastSampleAt??0,d.timestamp),i.changedAt=d.timestamp,e.resources.markDirty(us)},"handler"),n=e.bus.subscribe(u),a=o(d=>d.recent.reduce((p,c)=>c>=t?p+1:p,0),"recentSlowCount"),l=o(d=>d.lastDurationMs>=t||a(d)>=G3,"currentlySlow");return e.resources.register(us,()=>{let d=[...i.routes.values()].filter(l);return{schemaVersion:1,revision:e.resources.revision(us)??0,updatedAt:new Date(i.changedAt??r).toISOString(),thresholdMs:t,routes:d.map(p=>({method:p.method,route:p.route,worstRecentMs:Math.max(...p.recent),lastDurationMs:p.lastDurationMs,lastSeenAt:p.lastSeenAt,samples:p.samples,slowSamples:p.slowSamples,recentSlowSamples:a(p),worstEverMs:p.worstEverMs,worstEverAt:p.worstEverAt})).sort((p,c)=>c.worstRecentMs-p.worstRecentMs),routesTracked:i.routes.size,recentSampleWindow:rs,minRecentSlowToKeep:G3,lastSampleAt:i.lastSampleAt,producer:i.lastSampleAt===void 0?"none":"connected",detail:i.lastSampleAt===void 0?"No server request has ever been observed \u2014 this is NOT evidence the backend is fast, nothing is watching. Run the backend under the dev cluster (or with @lensmcp/nest-instrumentation) so request timings reach this session.":`${i.routes.size} route${i.routes.size===1?"":"s"} observed; ${d.length} slow in the last ${rs} calls each (\u2265${t}ms).`}}),{unsubscribe:n,uris:[us]}}s(K3,"sh"),o(K3,"installPerfReducer");var ns="perf://duplicate-requests",tc=10,H3=2,kB=200,X3=300,AB=new Set(["t","_","cacheBust","ts"]);function Y3(e){try{let t=new URL(e,"http://lensmcp.invalid");for(let u of[...t.searchParams.keys()])AB.has(u)&&t.searchParams.delete(u);let r=t.searchParams.toString(),i=`${t.pathname}${r?`?${r}`:""}`;return t.host==="lensmcp.invalid"?i:`${t.origin}${i}`}catch{return e}}s(Y3,"ex"),o(Y3,"normalizeRequestUrl");function Q3(e){if(e.length===0)return 0;let t=[];for(let{start:u,end:n}of e)t.push({at:u,delta:1}),t.push({at:n+1,delta:-1});t.sort((u,n)=>u.at-n.at||u.delta-n.delta);let r=0,i=0;for(let{delta:u}of t)r+=u,r>i&&(i=r);return i}s(Q3,"tx"),o(Q3,"peakConcurrency");function e6(e){let t=Je(e.thresholds).duplicateRequestPeak,r=(e.now??(()=>Date.now()))(),i={endpoints:new Map},u=o(d=>{if(d.category!=="network")return;let p=d.raw??null;if(p?.kind!=="fetch-done"&&p?.kind!=="fetch-error"||!p.url||!p.method)return;let c=Y3(p.url),g=p.method.toUpperCase();if(typeof p.startedAt!="number")return;let f=p.startedAt,m=f+(typeof p.durationMs=="number"?p.durationMs:0),h=d.context?.originNodeId??null,E=d.context?.flowId??null,D=`${g} ${c} @ ${h??"-"}`,B=i.endpoints.get(D);if(B||(B={method:g,url:c,originNodeId:h,currentFlowId:E,currentIntervals:[],currentPeak:0,recentPeaks:[],totalRequests:0,lastSeenAt:d.timestamp,worstEverPeak:0,worstEverAt:d.timestamp}),i.endpoints.delete(D),i.endpoints.set(D,B),E!==B.currentFlowId&&(B.currentIntervals.length>0&&(B.recentPeaks.push(B.currentPeak),B.recentPeaks.length>tc&&B.recentPeaks.splice(0,B.recentPeaks.length-tc)),B.currentFlowId=E,B.currentIntervals=[],B.currentPeak=0),B.currentIntervals.push({start:f,end:m}),B.currentIntervals.length>X3&&B.currentIntervals.splice(0,B.currentIntervals.length-X3),B.currentPeak=Q3(B.currentIntervals),B.totalRequests+=1,B.lastSeenAt=d.timestamp,B.currentPeak>B.worstEverPeak&&(B.worstEverPeak=B.currentPeak,B.worstEverAt=d.timestamp),i.endpoints.size>kB){let A=i.endpoints.keys().next().value;A!==void 0&&i.endpoints.delete(A)}i.lastSampleAt=Math.max(i.lastSampleAt??0,d.timestamp),i.changedAt=d.timestamp,e.resources.markDirty(ns)},"handler"),n=e.bus.subscribe(u),a=o(d=>{let p=[...d.recentPeaks,...d.currentIntervals.length>0?[d.currentPeak]:[]],c=0;for(let g=p.length-1;g>=0&&!((p[g]??0)>=t);g-=1)c+=1;return c},"consecutiveCleanFlows"),l=o(d=>d.worstEverPeak>=t&&a(d)<H3,"currentlyDuplicated");return e.resources.register(ns,()=>{let d=[...i.endpoints.values()].filter(l);return{schemaVersion:1,revision:e.resources.revision(ns)??0,updatedAt:new Date(i.changedAt??r).toISOString(),peakThreshold:t,endpoints:d.map(p=>({method:p.method,url:p.url,originNodeId:p.originNodeId,peakConcurrent:p.currentPeak,cleanFlowsSince:a(p),flowsObserved:p.recentPeaks.length+(p.currentIntervals.length>0?1:0),totalRequests:p.totalRequests,worstEverPeak:p.worstEverPeak,worstEverAt:p.worstEverAt,lastSeenAt:p.lastSeenAt})).sort((p,c)=>c.peakConcurrent-p.peakConcurrent),endpointsTracked:i.endpoints.size,recentFlowWindow:tc,minCleanFlowsToRetract:H3,lastSampleAt:i.lastSampleAt,producer:i.lastSampleAt===void 0?"none":"connected",detail:i.lastSampleAt===void 0?"No browser fetch has ever been observed \u2014 this is NOT evidence the app fetches cleanly, nothing is watching. Load a page under the dev cluster so flow-fetch events reach this session.":d.length===0?`${i.endpoints.size} endpoint${i.endpoints.size===1?"":"s"} observed; none exceeded ${t} concurrent identical calls.`:`${d.length} endpoint${d.length===1?"":"s"} called \u2265${t}\xD7 concurrently \u2014 usually a hook fetching outside the shared resource cache, multiplied by however many components mount it.`}}),{unsubscribe:n,uris:[ns]}}s(e6,"ch"),o(e6,"installDuplicateRequestsReducer");import{App as _B}from"@frontmcp/sdk";import{Resource as IB,ResourceContext as SB}from"@frontmcp/sdk";var uc=class extends SB{static{s(this,"uh")}static{o(this,"DbSlowQueriesResource")}async execute(){return this.get(q).read("db://slow-queries")}};uc=S([IB({name:"db-slow-queries",uri:"db://slow-queries",mimeType:"application/json",description:"Query shapes (project\xB7op\xB7table) whose worst observed duration crosses the slowQueryMs threshold, aggregated live from the pg instrumentation. counts are an undercount for hot shapes (the emitter flood-guards per shape); suppressedEvents carries the drop count."})],uc);var FB=uc;import{Resource as zB,ResourceContext as jB}from"@frontmcp/sdk";var rc=class extends jB{static{s(this,"dh")}static{o(this,"DbAnalysisResource")}async execute(){return this.get(q).read("db://analysis")}};rc=S([zB({name:"db-analysis",uri:"db://analysis",mimeType:"application/json",description:"The latest DB analyzer run per project (missing indexes, seq-scan hot spots, unused indexes, migration-parity drift, slow statements) \u2014 ingested from the workspace analyzer's `db-analyze-run` events on the lens bus file."})],rc);var NB=rc,t6=class{static{s(this,"fh")}static{o(this,"DbApp")}};t6=S([_B({id:"db",name:"Db",description:"Database signals: slow query shapes observed live from the pg instrumentation, and the latest externally-ingested analyzer run (missing indexes, migration parity, unused indexes).",resources:[FB,NB]})],t6);var is="db://slow-queries",ss="db://analysis",u6=50,OB=20,RB=200;function r6(e){let t=e[jl];if(!t)return;let r=Array.isArray(t.paths)?t.paths:[];for(let i of r){let u=typeof i=="string"?/^findings\[\] \(\+(\d+) items dropped\)$/.exec(i):null;if(u)return Number(u[1])}return r.some(i=>typeof i=="string"&&i.startsWith("findings"))?0:void 0}s(r6,"pA"),o(r6,"findingsDroppedByClamp");function n6(e){let t=Je(e.thresholds).slowQueryMs,r=(e.now??(()=>Date.now()))(),i={shapes:new Map,analyzeRuns:new Map},u=o(l=>{let d=l.raw??null;if(d){if(d.kind==="db-query"){let p=d.project??"unknown",c=d.op??"query",g=d.table??"query",f=d.durationMs??0,m=`${p}|${c}|${g}`,h=i.shapes.get(m);if(h||(h={project:p,op:c,table:g,count:0,errorCount:0,totalMs:0,maxMs:0,maxAt:l.timestamp,recent:[],rowsTotal:0,lastSql:"",lastDurationMs:0,lastSeenAt:l.timestamp,suppressed:0}),i.shapes.delete(m),i.shapes.set(m,h),h.count+=1,d.error!==void 0&&(h.errorCount+=1),h.totalMs+=f,f>h.maxMs&&(h.maxMs=f,h.maxAt=l.timestamp),h.recent.push(f),h.recent.length>u6&&h.recent.splice(0,h.recent.length-u6),h.rowsTotal+=d.rows??0,d.query&&(h.lastSql=d.query),h.lastDurationMs=f,h.lastSeenAt=l.timestamp,h.suppressed+=d.floodSuppressed??0,i.shapes.size>RB){let E=i.shapes.keys().next().value;E!==void 0&&i.shapes.delete(E)}i.lastQueryAt=Math.max(i.lastQueryAt??0,l.timestamp),i.changedAt=l.timestamp,e.resources.markDirty(is);return}if(d.kind==="db-analyze-run"){let p=d.project??"unknown",c=r6(d);i.analyzeRuns.set(p,{project:p,runAt:d.runAt??l.timestamp,tool:d.tool??"unknown",findings:Array.isArray(d.findings)?d.findings:[],...c!==void 0?{droppedFindings:c}:{}}),St(i.analyzeRuns,xr),i.lastAnalyzeAt=Math.max(i.lastAnalyzeAt??0,l.timestamp),i.changedAt=l.timestamp,e.resources.markDirty(ss)}}},"handler"),n=e.bus.subscribe(u),a=o(l=>{if(l.length===0)return 0;let d=[...l].sort((p,c)=>p-c);return d[Math.min(d.length-1,Math.floor(d.length*.95))]??0},"p95");return e.resources.register(is,()=>{let l=[...i.shapes.values()].filter(d=>d.maxMs>=t);return{schemaVersion:1,revision:e.resources.revision(is)??0,updatedAt:new Date(i.changedAt??r).toISOString(),thresholdMs:t,queries:l.map(d=>({project:d.project,op:d.op,table:d.table,count:d.count,errorCount:d.errorCount,maxMs:d.maxMs,maxAt:d.maxAt,avgMs:Math.round(d.totalMs/Math.max(d.count,1)*10)/10,p95Ms:a(d.recent),rowsTotal:d.rowsTotal,lastDurationMs:d.lastDurationMs,lastSeenAt:d.lastSeenAt,lastSql:d.lastSql,suppressedEvents:d.suppressed})).sort((d,p)=>p.maxMs-d.maxMs).slice(0,OB),shapesTracked:i.shapes.size,note:"count/avg are an UNDERCOUNT for hot shapes: the emitter flood-guards each query-shape fingerprint at 30 burst / 5 events/s; suppressedEvents is the emitter's own count of dropped events.",lastSampleAt:i.lastQueryAt,producer:i.lastQueryAt===void 0?"none":"connected",detail:i.lastQueryAt===void 0?"No db-query event has ever been observed \u2014 this is NOT evidence queries are fast, nothing is watching. Run the backend under the dev cluster (the @lensmcp/cluster serve preload taps pg) so query timings reach this session.":`${i.shapes.size} query shape${i.shapes.size===1?"":"s"} observed; ${l.length} with a worst duration \u2265${t}ms.`}}),e.resources.register(ss,()=>{let l=[...i.analyzeRuns.values()].sort((D,B)=>B.runAt-D.runAt),d=l.flatMap(D=>D.findings),p=d.length,c=d.filter(D=>D.severity==="error").length,g=d.filter(D=>D.severity==="warning").length,f=p-c-g,m=l.filter(D=>D.droppedFindings!==void 0),h=m.reduce((D,B)=>D+(B.droppedFindings??0),0),E=m.length>0;return{schemaVersion:1,revision:e.resources.revision(ss)??0,updatedAt:new Date(i.changedAt??r).toISOString(),runs:l,findingCount:p,errorCount:c,warningCount:g,infoCount:f,...E?{incomplete:!0,droppedFindings:h}:{},lastSampleAt:i.lastAnalyzeAt,producer:i.lastAnalyzeAt===void 0?"none":"connected",detail:i.lastAnalyzeAt===void 0?"No db-analyze run has ever been ingested \u2014 this is NOT evidence the schema is healthy, nothing has analyzed it. Run the workspace's DB analyzer (it appends a `db-analyze-run` event to the lens bus file) to populate this.":`${l.length} analyze run${l.length===1?"":"s"} held (latest per project); ${p} finding${p===1?"":"s"} (${c} error, ${g} warning, ${f} info).`+(E?` INCOMPLETE: ${h>0?`${h} more findings were`:"part of a run was"} cut by the bus payload bound before reaching the lens (an event over 32 KiB keeps only the first 64 items of a list), and the cut takes whatever came last. The analyzer must keep one run under that bound, most severe first.`:"")}}),{unsubscribe:n,uris:[is,ss]}}s(n6,"mh"),o(n6,"installDbReducer");import{App as TB}from"@frontmcp/sdk";import{Resource as MB,ResourceContext as PB}from"@frontmcp/sdk";var nc=class extends PB{static{s(this,"gh")}static{o(this,"NetEgressHostsResource")}async execute(){return this.get(q).read("net://egress/hosts")}};nc=S([MB({name:"net-egress-hosts",uri:"net://egress/hosts",mimeType:"application/json",description:"External hosts this backend called (pod \u2192 third party), rolled up per project\xB7host with count, error/4xx/5xx counters, p95 and worst duration, plus the top endpoints under each. `slow` and `failing` are retracted by later healthy responses, so a one-off blip does not warn all day."})],nc);var UB=nc;import{Resource as ZB,ResourceContext as qB}from"@frontmcp/sdk";var ic=class extends qB{static{s(this,"vh")}static{o(this,"NetEgressRecentResource")}async execute(){return this.get(q).read("net://egress/recent")}};ic=S([ZB({name:"net-egress-recent",uri:"net://egress/recent",mimeType:"application/json",description:"The last 200 outbound calls with their RAW path and the flowId that caused them \u2014 the evidence behind net://egress/hosts. Query strings are never captured; treat this as the sensitive view, since a path segment can itself be a secret."})],ic);var LB=ic;import{Resource as JB,ResourceContext as VB}from"@frontmcp/sdk";var sc=class extends VB{static{s(this,"bh")}static{o(this,"NetEgressFailuresResource")}async execute(){return this.get(q).read("net://egress/failures")}};sc=S([JB({name:"net-egress-failures",uri:"net://egress/failures",mimeType:"application/json",description:"Outbound calls that failed \u2014 transport errors and any status \u2265 400 \u2014 kept in their own ring so a high-volume host cannot evict the one failure you need. Empty is NOT proof nothing failed: check `producer`."})],sc);var WB=sc,i6=class{static{s(this,"$h")}static{o(this,"NetApp")}};i6=S([TB({id:"net",name:"Net",description:"Outbound (egress) HTTP the backend makes to THIRD PARTIES \u2014 which external services, how often, how slow, and whether they failed. The server-side twin of runtime://browser/network. Internal service-to-service traffic is deliberately absent: the gateway already attributes it.",resources:[UB,LB,WB]})],i6);var as="net://egress/hosts",os="net://egress/recent",ls="net://egress/failures",Eu=20,GB=25,KB=200,HB=20,XB=5,s6=200,a6=50,o6=2;function l6(e){return e.length===0?!1:!!(/^\d{2,}$/.test(e)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)||/^[A-Z][A-Z0-9]*-\d+$/.test(e)||e.length>=16&&/^[A-Za-z0-9_-]+$/.test(e)&&/\d/.test(e))}s(l6,"kA"),o(l6,"isIdSegment");function d6(e){let[t="/"]=e.split("?"),r=t.split("/"),i=[];for(let n of r){if(i.length>12){i.push("\u2026");break}i.push(l6(n)?":id":n)}let u=i.join("/");return u.length===0?"/":u}s(d6,"sx"),o(d6,"templatisePath");function c6(e){let t=Je(e.thresholds).slowEgressMs,r=(e.now??(()=>Date.now()))(),i={hosts:new Map,recent:[],failures:[]},u=o(c=>{let g=c.raw??null;if(!g||g.kind!=="egress")return;let f=g.project??"unknown",m=g.host??"unknown",h=(g.method??"GET").toUpperCase(),E=g.durationMs??0,D=typeof g.status=="number"?g.status:void 0,B=g.error===void 0?void 0:String(g.error),A=B!==void 0||D!==void 0&&D>=400,I=g.path??"(path not captured \u2014 upgrade @lensmcp/node-instrumentation)",j=`${f}|${m}`,F=i.hosts.get(j);F||(F={project:f,host:m,count:0,errorCount:0,status4xx:0,status5xx:0,totalMs:0,maxMs:0,maxAt:c.timestamp,recent:[],outcomes:[],firstSeenAt:c.timestamp,lastSeenAt:c.timestamp,lastDurationMs:0,lastBad:!1,suppressed:0,endpoints:new Map}),i.hosts.delete(j),i.hosts.set(j,F),F.count+=1,B!==void 0&&(F.errorCount+=1),D!==void 0&&D>=400&&D<500&&(F.status4xx+=1),D!==void 0&&D>=500&&(F.status5xx+=1),F.totalMs+=E,E>F.maxMs&&(F.maxMs=E,F.maxAt=c.timestamp),F.recent.push(E),F.recent.length>Eu&&F.recent.splice(0,F.recent.length-Eu),F.outcomes.push(A),F.outcomes.length>Eu&&F.outcomes.splice(0,F.outcomes.length-Eu),F.lastDurationMs=E,F.lastBad=A,F.lastSeenAt=c.timestamp,F.suppressed+=g.floodSuppressed??0;let b=d6(I),w=`${h} ${b}`,C=F.endpoints.get(w);if(C||(C={method:h,path:b,count:0,errorCount:0,status4xx:0,status5xx:0,totalMs:0,maxMs:0,recent:[],lastDurationMs:0,lastSeenAt:c.timestamp}),F.endpoints.delete(w),F.endpoints.set(w,C),C.count+=1,B!==void 0&&(C.errorCount+=1,C.lastError=B),D!==void 0&&D>=400&&D<500&&(C.status4xx+=1),D!==void 0&&D>=500&&(C.status5xx+=1),C.totalMs+=E,E>C.maxMs&&(C.maxMs=E),C.recent.push(E),C.recent.length>Eu&&C.recent.splice(0,C.recent.length-Eu),C.lastStatus=D,C.lastDurationMs=E,C.lastSeenAt=c.timestamp,F.endpoints.size>HB){let te=F.endpoints.keys().next().value;te!==void 0&&F.endpoints.delete(te)}if(i.hosts.size>KB){let te=i.hosts.keys().next().value;te!==void 0&&i.hosts.delete(te)}let N=c.context??{},O={id:c.id,timestamp:c.timestamp,project:f,method:h,host:m,path:I,...D!==void 0?{status:D}:{},...B!==void 0?{error:B}:{},durationMs:E,...N.flowId?{flowId:N.flowId}:{},...N.requestId?{requestId:N.requestId}:{}};i.recent.push(O),i.recent.length>s6&&i.recent.splice(0,i.recent.length-s6),A&&(i.failures.push(O),i.failures.length>a6&&i.failures.splice(0,i.failures.length-a6),e.resources.markDirty(ls)),i.lastSampleAt=Math.max(i.lastSampleAt??0,c.timestamp),i.changedAt=c.timestamp,e.resources.markDirty(as),e.resources.markDirty(os)},"handler"),n=e.bus.subscribe(u),a=o(c=>{if(c.length===0)return 0;let g=[...c].sort((f,m)=>f-m);return g[Math.min(g.length-1,Math.floor(g.length*.95))]??0},"p95"),l=o(c=>c.lastDurationMs>=t||c.recent.filter(g=>g>=t).length>=o6,"isSlow"),d=o(c=>c.lastBad||c.outcomes.filter(Boolean).length>=o6,"isFailing"),p=o(c=>{let g=c.outcomes.filter(Boolean).length;return d(c)?`${g} of the last ${c.outcomes.length} call${c.outcomes.length===1?"":"s"} failed`:l(c)?`${c.recent.filter(f=>f>=t).length} of the last ${c.recent.length} call${c.recent.length===1?"":"s"} took \u2265${t}ms`:"healthy"},"describe");return e.resources.register(as,()=>{let c=[...i.hosts.values()],g=c.filter(d),f=c.filter(m=>!d(m)&&l(m));return{schemaVersion:1,revision:e.resources.revision(as)??0,updatedAt:new Date(i.changedAt??r).toISOString(),thresholdMs:t,hosts:c.map(m=>({project:m.project,host:m.host,count:m.count,errorCount:m.errorCount,status4xx:m.status4xx,status5xx:m.status5xx,avgMs:Math.round(m.totalMs/Math.max(m.count,1)*10)/10,p95Ms:a(m.recent),maxMs:m.maxMs,maxAt:m.maxAt,lastDurationMs:m.lastDurationMs,firstSeenAt:m.firstSeenAt,lastSeenAt:m.lastSeenAt,slow:l(m),failing:d(m),detail:p(m),suppressedEvents:m.suppressed,endpoints:[...m.endpoints.values()].map(h=>({method:h.method,path:h.path,count:h.count,errorCount:h.errorCount,status4xx:h.status4xx,status5xx:h.status5xx,avgMs:Math.round(h.totalMs/Math.max(h.count,1)*10)/10,p95Ms:a(h.recent),maxMs:h.maxMs,...h.lastStatus!==void 0?{lastStatus:h.lastStatus}:{},...h.lastError!==void 0?{lastError:h.lastError}:{},lastSeenAt:h.lastSeenAt})).sort((h,E)=>E.maxMs-h.maxMs).slice(0,XB)})).sort((m,h)=>m.failing!==h.failing?m.failing?-1:1:h.maxMs-m.maxMs).slice(0,GB),hostsTracked:i.hosts.size,failingHosts:g.length,slowHosts:f.length,note:"count/avg are an UNDERCOUNT for hot hosts: the emitter flood-guards each host fingerprint at 30 burst / 5 events/s; suppressedEvents is the emitter's own count of dropped events. Query strings are not captured; endpoint paths are templatised (\u2026/:id).",lastSampleAt:i.lastSampleAt,producer:i.lastSampleAt===void 0?"none":"connected",detail:i.lastSampleAt===void 0?"No egress event has ever been observed \u2014 this is NOT evidence the app makes no external calls, nothing is watching. Run the backend under the dev cluster (the @lensmcp/cluster serve preload taps fetch and http/https) so outbound calls reach this session. Internal destinations (*.local, loopback, RFC1918) are skipped by design \u2014 the gateway already attributes service-to-service traffic.":`${i.hosts.size} external host${i.hosts.size===1?"":"s"} observed; ${g.length} failing, ${f.length} slower than ${t}ms.`}}),e.resources.register(os,()=>({schemaVersion:1,revision:e.resources.revision(os)??0,updatedAt:new Date(i.changedAt??r).toISOString(),entries:[...i.recent],count:i.recent.length,note:"Raw paths, as requested. flowId joins an outbound call back to the click that caused it. Treat this as the sensitive view: a path segment can itself be a secret (a presigned key, a reset token), which the templatised rollup collapses but this does not.",lastSampleAt:i.lastSampleAt,producer:i.lastSampleAt===void 0?"none":"connected",detail:i.lastSampleAt===void 0?"No egress event has ever been observed \u2014 this is NOT evidence the app makes no external calls, nothing is watching.":`${i.recent.length} recent outbound call${i.recent.length===1?"":"s"}.`})),e.resources.register(ls,()=>({schemaVersion:1,revision:e.resources.revision(ls)??0,updatedAt:new Date(i.changedAt??r).toISOString(),entries:[...i.failures],count:i.failures.length,note:"A separate ring from net://egress/recent on purpose: a host called 200\xD7/min would otherwise evict the one 503 you need.",lastSampleAt:i.lastSampleAt,producer:i.lastSampleAt===void 0?"none":"connected",detail:i.lastSampleAt===void 0?"No egress event has ever been observed \u2014 an empty list here is NOT evidence that nothing failed, nothing is watching.":`${i.failures.length} failed outbound call${i.failures.length===1?"":"s"} held.`})),{unsubscribe:n,uris:[as,os,ls]}}s(c6,"xh"),o(c6,"installNetReducer");import{App as YB}from"@frontmcp/sdk";import{Resource as QB,ResourceContext as e2}from"@frontmcp/sdk";var ac=class extends e2{static{s(this,"_h")}static{o(this,"VisualCurrentResource")}async execute(){return this.get(q).read("visual://current")}};ac=S([QB({name:"visual-current",uri:"visual://current",mimeType:"application/json",description:"Most recent visual-frame (causedBy, changedNodes, stable)."})],ac);var t2=ac;import{Resource as u2,ResourceContext as r2}from"@frontmcp/sdk";var oc=class extends r2{static{s(this,"Sh")}static{o(this,"VisualViolationsCurrentResource")}async execute(){return this.get(q).read("visual://violations/current")}};oc=S([u2({name:"visual-violations-current",uri:"visual://violations/current",mimeType:"application/json",description:"Violations of the CURRENT frame, regardless of timing mode. Every rule re-runs per frame, so a fixed violation simply stops being reported."})],oc);var n2=oc;import{Resource as i2,ResourceContext as s2}from"@frontmcp/sdk";var lc=class extends s2{static{s(this,"Rh")}static{o(this,"VisualViolationsStableResource")}async execute(){return this.get(q).read("visual://violations/stable")}};lc=S([i2({name:"visual-violations-stable",uri:"visual://violations/stable",mimeType:"application/json",description:'Violations from rules with timing "after-animation" | "stable-only" | "always".'})],lc);var a2=lc;import{Resource as o2,ResourceContext as l2}from"@frontmcp/sdk";var dc=class extends l2{static{s(this,"Eh")}static{o(this,"VisualViolationsDuringAnimationResource")}async execute(){return this.get(q).read("visual://violations/during-animation")}};dc=S([o2({name:"visual-violations-during-animation",uri:"visual://violations/during-animation",mimeType:"application/json",description:"Violations seen on midpoint (during-animation) samples only."})],dc);var d2=dc;import{Resource as c2,ResourceContext as p2}from"@frontmcp/sdk";var cc=class extends p2{static{s(this,"zh")}static{o(this,"VisualRulesResource")}async execute(){return this.get(q).read("visual://rules")}};cc=S([c2({name:"visual-rules",uri:"visual://rules",mimeType:"application/json",description:"All registered visual rules (builtins + lensmcp.rules.json + visual.register_rule)."})],cc);var m2=cc;import{Resource as f2,ResourceContext as g2}from"@frontmcp/sdk";var pc=class extends g2{static{s(this,"Oh")}static{o(this,"VisualTokensResource")}async execute(){return this.get(q).read("visual://tokens")}};pc=S([f2({name:"visual-tokens",uri:"visual://tokens",mimeType:"application/json",description:"Resolved design tokens from lensmcp.tokens.json."})],pc);var h2=pc;import{Tool as v2,ToolContext as y2,z as p6}from"@frontmcp/sdk";import{existsSync as E2,mkdirSync as b2,readFileSync as D2,writeFileSync as w2}from"node:fs";import{dirname as $2,join as mc}from"node:path";function fc(e=process.env,t=process.cwd()){let r=e.LENSMCP_EVENT_FILE;return r?$2(r):mc(t,".lensmcp")}s(fc,"ta"),o(fc,"captureDir");function m6(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}s(m6,"BA"),o(m6,"pidAlive");function gc(e,t=m6){let r=mc(e,Bb);try{if(!E2(r))return;let i=JSON.parse(D2(r,"utf8"));return typeof i?.pid!="number"||!Number.isFinite(i.pid)?void 0:t(i.pid)?i:void 0}catch{return}}s(gc,"ra"),o(gc,"liveRunner");function f6(e,t){try{return b2(e,{recursive:!0}),w2(mc(e,$b),JSON.stringify(t)),!0}catch{return!1}}s(f6,"ax"),o(f6,"publishCaptureRequest");var hc;async function g6(e,t){let r=hc;if(r)return{fresh:await r.promise,coalesced:!0,requestId:r.requestId};let i=t().finally(()=>{hc=void 0});return hc={promise:i,requestId:e},{fresh:await i,coalesced:!1,requestId:e}}s(g6,"cx"),o(g6,"captureSingleFlight");async function h6(e){let t=e.now??(()=>Date.now()),r=e.sleep??(a=>new Promise(l=>setTimeout(l,a))),i=e.budgetMs??8e3,u=e.pollMs??100,n=t()+i;for(;t()<n;){await r(u);let a=await e.readFrameId();if(a!==void 0&&a!==e.before)return!0}return!1}s(h6,"ux"),o(h6,"waitForFreshFrame");var vc=class extends y2{static{s(this,"Mh")}static{o(this,"VisualCaptureFrameTool")}async execute(e){let t=this.get(zl),r=this.get(q),i=o(async()=>(await r.read("visual://current"))?.frame?.id,"readFrameId"),u=await i(),n=qt(),a=Date.now();t.publish({id:qt(),sessionId:"visual.capture_frame",timestamp:a,source:"visual",category:"visual",severity:"info",context:{sessionId:"visual.capture_frame"},fingerprint:`visual-capture-request:${e.cause}`,title:`visual.capture_frame(${e.cause})`,raw:{kind:"visual-capture-request",cause:e.cause,stable:e.stable,requestId:n}});let l=fc(),d=gc(l),p=!1,c=await g6(n,async()=>(p=f6(l,{requestedAt:a,cause:e.cause,stable:e.stable,requestId:n}),p&&d?await h6({readFrameId:i,before:u}):!1));return{requested:c.coalesced?!0:p,cause:e.cause,stable:e.stable,fresh:c.fresh,coalesced:c.coalesced,requestId:c.requestId,waitedMs:Date.now()-a,runner:d?{pid:d.pid,url:d.url}:void 0,latest:await r.read("visual://current")}}};vc=S([v2({name:"visual.capture_frame",description:"Capture a fresh visual frame. Signals the host capture runner (which launches a headless browser on demand), waits for the new frame, and returns it. Frames are captured per request \u2014 no browser is held open between calls.",inputSchema:{cause:p6.enum(["page-load","route-change","user-action","react-commit","state-update","api-response","hmr-update","animation-tick"]).default("user-action").describe("Hint why this frame is being requested."),stable:p6.boolean().default(!0).describe("Whether to treat the captured frame as the stable final state.")}})],vc);var B2=vc;import{Tool as C2,ToolContext as x2,z as k2}from"@frontmcp/sdk";var yc=class extends x2{static{s(this,"Uh")}static{o(this,"VisualInspectNodeTool")}async execute(e){let t=await this.get(q).read("visual://current");if(!t.frame)return{found:!1,uid:e.uid};let r=t.frame.changedNodes.filter(i=>i.uid===e.uid);return{found:r.length>0,uid:e.uid,frameId:t.frame.id,changes:r}}};yc=S([C2({name:"visual.inspect_node",description:"Returns the changedNodes entry for `uid` from visual://current \u2014 the per-property before/after used to compute the latest frame.",inputSchema:{uid:k2.string().describe('Node uid as it appeared in visual://current.changedNodes (e.g. "hero-card" or "bid:42").')}})],yc);var A2=yc;import{Tool as _2,ToolContext as I2,z as S2}from"@frontmcp/sdk";var Ec=class extends I2{static{s(this,"Fh")}static{o(this,"VisualCompareFramesTool")}async execute(e){let t=await this.get(q).read("visual://current");return t.frame?e.frameId&&e.frameId!==t.frame.id?{found:!1,reason:"Only the latest frame is retained in Phase 4."}:{found:!0,frameId:t.frame.id,causedBy:t.frame.causedBy,changedCount:t.frame.changedNodes.length,appeared:t.frame.appearedNodes.length,disappeared:t.frame.disappearedNodes.length,changedNodes:t.frame.changedNodes.slice(0,50)}:{found:!1}}};Ec=S([_2({name:"visual.compare_frames",description:"Summarises the last visual-frame. Phase 4 ships a single-frame view (Phase 6 adds story-relative deltas).",inputSchema:{frameId:S2.string().optional().describe("Optional frame id; defaults to the latest.")}})],Ec);var F2=Ec;import{Tool as z2,ToolContext as j2,z as N2}from"@frontmcp/sdk";var bc=class extends j2{static{s(this,"Zh")}static{o(this,"VisualExplainViolationTool")}async execute(e){let t=(await this.get(q).read("visual://violations/current")).violations.find(r=>r.id===e.violationId);return t?{found:!0,violation:t,explanation:v6(t)}:{found:!1,violationId:e.violationId}}};bc=S([z2({name:"visual.explain_violation",description:"Returns the full violation record (rule id + expected/actual + evidence.cssCause / trace / screenshot crop URIs) for a given violationId.",inputSchema:{violationId:N2.string().describe("Id of the violation as seen in visual://violations/current.")}})],bc);var O2=bc;function v6(e){let t=[`Rule ${e.ruleId} (${e.ruleType}) at ${e.element.component??e.element.uid}.`,`Expected: ${JSON.stringify(e.expected)}`,`Actual: ${JSON.stringify(e.actual)}`];return e.evidence.cssCause&&t.push(`CSS cause: ${e.evidence.cssCause.selector} { ${e.evidence.cssCause.declaration??"?"} }`+(e.evidence.cssCause.file?` @ ${e.evidence.cssCause.file}:${e.evidence.cssCause.line??"?"}`:"")),e.evidence.trace&&t.push(`Trace: ${e.evidence.trace}`),e.evidence.screenshotCrop&&t.push(`Crop: ${e.evidence.screenshotCrop}`),t.join(`
|
|
69
|
+
`))!==-1;){let n=r.slice(0,u);r=r.slice(u+1),t(n)}}),e.on("end",()=>{r.length&&t(r)})}s(nd,"A$"),o(nd,"bufferLines");var G1=class{static{s(this,"lm")}static{o(this,"AgentApp")}};G1=S([pD({id:"agent",name:"Agent",description:"Agent-facing summary, suggested reads, verification.",resources:[vD,bD],tools:[xD,_D],jobs:[UD]})],G1);var ZD={"service-starting":"starting","service-respawn":"starting","lens-app-up":"starting","service-up":"up","cold-start":"up","service-down":"down","idle-kill":"idle","service-recycle":"wedged","pod-recycle":"wedged","service-crash-loop":"crash-looping","lens-handoff-complete":"up","gateway-up":"up","gateway-down":"down","lens-child-starting":"starting","lens-child-up":"up","lens-child-exit":"down"},qD=new Set(["service-respawn","service-recycle","pod-recycle","lens-handoff-complete"]),LD=class{static{s(this,"Qn")}static{o(this,"ClusterHealth")}constructor(){this.services=new Map,this.errors=[]}ingest(e){if(e.source!=="gateway"||e.category!=="cluster")return!1;let t=e.raw??{},r=typeof t.kind=="string"?t.kind:void 0;if(!r)return!1;let i=typeof t.project=="string"?t.project:void 0;if(!i)return!1;if(r==="service-error"){let a=typeof t.line=="string"?t.line:e.message??e.title;this.errors.push({project:i,timestamp:e.timestamp,line:a,fingerprint:e.fingerprint}),this.errors.length>50&&this.errors.splice(0,this.errors.length-50);let l=this.touch(i,e.timestamp);return l.buildFailed=!0,l.lastTitle=e.title,!0}if(r==="service-recovered"){let a=this.services.get(i);return a?(a.lastSeenAt=e.timestamp,this.resolve(a),a.lastTitle=e.title,!0):!1}if(r==="lens-handoff-start"){let a=this.touch(i,e.timestamp);return t.oldServing!==!0&&(a.state="starting"),a.lastTitle=e.title,!0}if(r==="lens-handoff-failed"){let a=this.touch(i,e.timestamp);return t.oldKept!==!0&&(a.state="down"),a.lastTitle=e.title,!0}let u=ZD[r];if(!u)return!1;let n=this.touch(i,e.timestamp);return n.state=u,n.lastTitle=e.title,qD.has(r)&&(n.restarts+=1),u==="up"&&this.resolve(n),!0}resolve(e){e.buildFailed=!1,this.errors.splice(0,this.errors.length,...this.errors.filter(t=>t.project!==e.project))}snapshot(){let e=[...this.services.values()].sort((r,i)=>r.project.localeCompare(i.project)),t=o(r=>e.filter(i=>i.state===r).map(i=>i.project),"byState");return{services:e,up:t("up"),down:t("down"),wedged:t("wedged"),crashLooping:t("crash-looping"),idle:t("idle"),buildFailed:e.filter(r=>r.buildFailed).map(r=>r.project),restarts:e.reduce((r,i)=>r+i.restarts,0),errors:this.errors.slice()}}touch(e,t){let r=this.services.get(e);if(!r){if(this.services.size>=100){let i;for(let u of this.services.values())(!i||u.lastSeenAt<i.lastSeenAt)&&(i=u);i&&this.services.delete(i.project)}r={project:e,state:"starting",restarts:0,buildFailed:!1,lastTitle:"",lastSeenAt:t},this.services.set(e,r)}return r.lastSeenAt=t,r}},Fi="agent://current-status",zi="process://cluster",JD=250,VD=new Set(["build","lint","typecheck","runtime","cluster","memory","visual","performance"]);function K1(e){let t=new LD,r=e.sessionId??"pending",i,u=o(()=>{i||(i=setTimeout(()=>{i=void 0,e.resources.markDirty(Fi)},JD),i.unref?.())},"scheduleStatusRefresh"),n=o(l=>{let d=t.ingest(l);d&&e.resources.markDirty(zi),(d||VD.has(l.category))&&u()},"handler"),a=e.bus.subscribe(n);return e.resources.register(zi,()=>({schemaVersion:1,revision:e.resources.revision(zi)??0,updatedAt:new Date().toISOString(),...t.snapshot()})),e.resources.register(Fi,()=>Ii({resources:e.resources,sessionId:r,revision:e.resources.revision(Fi)??0})),{unsubscribe:o(()=>{a(),i&&(clearTimeout(i),i=void 0)},"unsubscribe"),uris:[Fi,zi]}}s(K1,"dm"),o(K1,"installAgentReducer");import{App as WD}from"@frontmcp/sdk";import{Resource as GD,ResourceContext as KD}from"@frontmcp/sdk";var id=class extends KD{static{s(this,"pm")}static{o(this,"FlowRecentResource")}async execute(){return this.get(q).read("flow://recent")}};id=S([GD({name:"flow-recent",uri:"flow://recent",mimeType:"application/json",description:"Last 50 flows seen this session, most recent first."})],id);var HD=id;import{Resource as XD,ResourceContext as YD}from"@frontmcp/sdk";var sd=class extends YD{static{s(this,"mm")}static{o(this,"FlowCurrentResource")}async execute(){return this.get(q).read("flow://current")}};sd=S([XD({name:"flow-current",uri:"flow://current",mimeType:"application/json",description:"The most recently active flow (origin + event count + headline)."})],sd);var QD=sd;import{Resource as ew,ResourceContext as tw}from"@frontmcp/sdk";var ad=class extends tw{static{s(this,"hm")}static{o(this,"FlowOriginsRecentResource")}async execute(){return this.get(q).read("flow://origins/recent")}};ad=S([ew({name:"flow-origins-recent",uri:"flow://origins/recent",mimeType:"application/json",description:"Last 50 flow-origin events (one per detected flow start)."})],ad);var uw=ad;import{Tool as rw,ToolContext as nw,z as ji}from"@frontmcp/sdk";var H1;function od(e){H1=e}s(od,"xs"),o(od,"setActiveFlowLookups");function Ve(){return H1}s(Ve,"be"),o(Ve,"activeFlowLookups");var iw=120;function ld(e,t,r){return{id:e.id,kind:e.kind,label:e.label,category:t,phase:e.phase,startOffsetMs:Math.max(0,e.start-r),durationMs:e.durationMs,events:e.counts.total,signal:e.counts.signal,errors:e.counts.errors,worstSeverity:e.worstSeverity,projects:e.projects,...e.route?{route:e.route}:{},...e.method?{method:e.method}:{},...e.part?{part:e.part}:{},...e.hot?{hot:e.hot}:{},...e.after?{after:e.after}:{}}}s(ld,"ym"),o(ld,"segmentView");function dd(e,t={}){let{segmentation:r,classification:i,segmentCategories:u}=e,n=Math.max(1,t.maxSegments??iw),a=r.segments.reduce((p,c)=>Math.min(p,c.start),1/0),l=Number.isFinite(a)?a:0,d=r.segments;if(d.length>n){let p=o(g=>g.counts.errors*1e6+g.counts.signal,"rank"),c=new Set([...d].sort((g,f)=>p(f)-p(g)||(g.id<f.id?-1:1)).slice(0,n).map(g=>g.id));d=d.filter(g=>c.has(g.id))}return{flowId:r.flowId,category:i.category,decidedBy:i.decidedBy,...i.subject?{subject:i.subject}:{},tags:i.tags,origin:i.origin,stats:{events:r.stats.events,signal:r.stats.signal,bookkeeping:r.stats.bookkeeping,segments:r.stats.segments,phases:r.stats.phases},phases:r.phases.map(p=>({index:p.index,startOffsetMs:Math.max(0,p.start-l),endOffsetMs:Math.max(0,p.end-l),segmentIds:p.segmentIds})),segments:d.map(p=>ld(p,u[p.id]??"other",l)),segmentsTruncated:d.length<r.segments.length}}s(dd,"bm"),o(dd,"overviewOf");function X1(e,t,r){let i=t.segmentation.segments.find(n=>n.id===r);if(!i)return;let u=new Set(i.eventIds);return e.filter(n=>u.has(n.id))}s(X1,"O$"),o(X1,"eventsOfSegment");function Y1(e,t){return e.filter(r=>(t.category===void 0||r.category===t.category)&&(t.tag===void 0||r.tags.includes(t.tag))&&(t.subject===void 0||r.subject===t.subject))}s(Y1,"N$"),o(Y1,"filterClassified");function Q1(e){let t=e.map(r=>({category:r.category,...r.subject?{subject:r.subject}:{},id:r.summary.flowId}));return i1(t).map(r=>({category:r.category,count:r.count,subjects:r.subjects.map(i=>({...i.subject!==void 0?{subject:i.subject}:{},count:i.count,flowIds:i.items.map(u=>u.id)}))}))}s(Q1,"P$"),o(Q1,"groupClassified");function e3(e){let t={};for(let r of e)t[r.category]=(t[r.category]??0)+1;return t}s(e3,"D$"),o(e3,"categoryCounts");function t3(e,t){if(!e)return{found:!1,reason:"no active flow reducer"};let r=e.getFlowSummary(t.flowId),i=e.getFlowEvents(t.flowId);if(!r||!i)return{found:!1,flowId:t.flowId};let u=e.analyzeFlow(t.flowId);if(t.segmentId){let a=u?X1(i,u,t.segmentId):void 0,l=u?.segmentation.segments.find(c=>c.id===t.segmentId);if(!u||!a||!l)return{found:!1,flowId:t.flowId,segmentId:t.segmentId,reason:"unknown segment id for this flow (the flow may have changed \u2014 re-read overview.segments)",segmentIds:u?.segmentation.segments.map(c=>c.id)??[]};let d=u.segmentation.segments.reduce((c,g)=>Math.min(c,g.start),1/0),{events:p}=Di(a,{includeRaw:t.includeRaw});return{found:!0,summary:r,segment:ld(l,u.segmentCategories[l.id]??"other",Number.isFinite(d)?d:l.start),truncated:p.length>t.limit,events:p.slice(0,t.limit)}}let{events:n}=Di(i,{includeRaw:t.includeRaw});if(t.expand){let a=n.find(p=>p.id===t.expand);if(!a)return{found:!1,flowId:t.flowId,expand:t.expand};let l=new Set(a.memberIds??[a.id]),d=i.filter(p=>l.has(p.id));return{found:!0,flowId:t.flowId,expanded:{id:a.id,title:a.title,count:d.length},events:d.map(p=>({id:p.id,timestamp:p.timestamp,source:p.source,category:p.category,severity:p.severity,title:p.title,message:p.message,...t.includeRaw?{raw:p.raw}:{}}))}}return{found:!0,summary:r,...u?{overview:dd(u)}:{},truncated:n.length>t.limit,events:n.slice(0,t.limit)}}s(t3,"M$"),o(t3,"getFlowDetail");async function u3(e,t,r){if(e){let u=e.classifiedRecent(),n=Y1(u,{...t.category?{category:t.category}:{},...t.tag?{tag:t.tag}:{}}),a=n.slice(0,t.limit);return{flows:a.map(l=>({...l.summary,category:l.category,decidedBy:l.decidedBy,...l.subject?{subject:l.subject}:{},tags:l.tags,segmentCount:l.segmentCount,phaseCount:l.phaseCount,signalCount:l.signalCount})),totalKnown:u.length,matching:n.length,categories:e3(u),...t.groupBy==="category"?{groups:Q1(a)}:{}}}let i=await r();return{flows:i.flows.slice(0,t.limit),totalKnown:i.flows.length}}s(u3,"C$"),o(u3,"listRecentFlows");function r3(e,t){if(!e)return{found:!1,reason:"no active flow reducer"};let r=e.analyzeFlow(t.flowId);return r?{found:!0,...dd(r,{maxSegments:t.maxSegments})}:{found:!1,flowId:t.flowId}}s(r3,"U$"),o(r3,"getFlowSegments");var cd=class extends nw{static{s(this,"wm")}static{o(this,"FlowListRecentTool")}async execute(e){return u3(Ve(),e,async()=>await this.get(q).read("flow://recent"))}};cd=S([rw({name:"flow.list_recent",description:'Lists the last N flows with their origin + event count + headline, and what each one IS: `category` (page-load, user-action, api, ai, test, or one you defined in nx.json#lensmcp.flows), `subject` (the templated page, component or route), `tags` (fan-out, has-error, slow, storm\u2026), `segmentCount`/`phaseCount`. Filter with `category` / `tag`; pass `groupBy: "category"` to also get the flows grouped category \u2192 subject; `categories` always counts every known flow per category. Same data as flow://recent but with a tunable limit.',inputSchema:{limit:ji.number().int().positive().max(50).default(10).describe("How many flows to return (default 10, max 50)."),category:ji.string().optional().describe('Only flows in this category, e.g. "page-load" or "checkout".'),tag:ji.string().optional().describe('Only flows carrying this tag, e.g. "has-error" or "fan-out".'),groupBy:ji.enum(["none","category"]).default("none").describe('"category" adds `groups`: the returned flows grouped category \u2192 subject.')}})],cd);var sw=cd;import{Tool as aw,ToolContext as ow,z as Sr}from"@frontmcp/sdk";var pd=class extends ow{static{s(this,"xm")}static{o(this,"FlowGetTool")}async execute(e){return t3(Ve(),e)}};pd=S([aw({name:"flow.get",description:'Returns one flow as the ordered, parented mechanism tree the dashboard renders: each node has `parent`, `area`, `start`, `durationMs`, and repeated work is collapsed (`count`, `memberIds`). Pass `expand: "<node id>"` to list the individual events a collapsed node stands for, or `includeRaw: true` for the full `event.raw` payloads. The response also carries `overview`: the flow cut into segments (one backend request each, UI bursts, the origin) grouped into phases, with its category, subject and tags \u2014 for a big flow read that first, then pass `segmentId: "<segment id>"` to get just that unit as a mechanism tree.',inputSchema:{flowId:Sr.string().describe("Flow id from flow://recent."),includeRaw:Sr.boolean().default(!1),limit:Sr.number().int().positive().max(500).default(200),expand:Sr.string().optional().describe("A node id from a previous call: returns the individual events it collapsed."),segmentId:Sr.string().optional().describe("A segment id from `overview.segments` (or flow.segments): returns only that unit of the flow, shaped like the whole.")}})],pd);var lw=pd;import{Tool as dw,ToolContext as cw,z as pw}from"@frontmcp/sdk";var md=class extends cw{static{s(this,"km")}static{o(this,"FlowFindByOriginTool")}async execute(e){let t=Ve();if(!t)return{found:!1,reason:"no active flow reducer"};let r=t.findFlowsByOrigin(e.originNodeId);return{found:r.length>0,count:r.length,flows:r}}};md=S([dw({name:"flow.find_by_origin",description:"Returns all flows whose origin node id matches `originNodeId` (e.g. a data-agent-component target).",inputSchema:{originNodeId:pw.string().describe("Origin node id \u2014 usually the value of data-agent-component on the originating element.")}})],md);var mw=md;import{Tool as fw,ToolContext as gw,z as hw}from"@frontmcp/sdk";import*as vw from"node:fs";import{dirname as yw,join as n3}from"node:path";var Ew="ai",bw=/^ai_[0-9a-z]{8,40}$/,Ni=o(e=>typeof e=="string"&&bw.test(e),"isAiCallId");function i3(e){return n3(yw(e),Ew)}s(i3,"uT"),o(i3,"aiContentDir");function s3(e,t){if(!Ni(t))throw new Error("invalid ai call id");return n3(i3(e),`${t}.json`)}s(s3,"lT"),o(s3,"aiContentFile");function fd(e,t){if(Ni(t))try{let r=JSON.parse(vw.readFileSync(s3(e,t),"utf8"));return r&&r.schemaVersion===1&&r.id===t?r:void 0}catch{return}}s(fd,"ks"),o(fd,"readAiContent");var gd=class extends gw{static{s(this,"Im")}static{o(this,"AiGetCallTool")}async execute(e){if(!Ni(e.callId))return{found:!1,reason:"invalid call id"};let t=fd(process.env.LENSMCP_EVENT_FILE??`${process.cwd()}/.lensmcp/events.jsonl`,e.callId);return t?{found:!0,call:t}:{found:!1,callId:e.callId,reason:"no captured content for this call \u2014 it was not captured (LENSMCP_AI_CAPTURE=content), or it has been rotated away"}}};gd=S([fw({name:"ai.get_call",description:"Returns the prompt and completion of ONE AI call (OpenAI, Anthropic, \u2026) captured by the node tap: system prompt, messages, tools offered, completion, tool calls, usage. `callId` is the `ai.contentRef` of a flow node whose kind is `ai-call` (see flow.get). Only exists when the service ran with LENSMCP_AI_CAPTURE=content; the text was redacted and size-capped when it was captured, and `truncated: true` says if anything was cut.",inputSchema:{callId:hw.string().describe('The contentRef of an ai-call flow node, e.g. "ai_0abc12345xyz78".')}})],gd);var Dw=gd;import{Tool as ww,ToolContext as $w,z as a3}from"@frontmcp/sdk";var hd=class extends $w{static{s(this,"Rm")}static{o(this,"FlowSegmentsTool")}async execute(e){return r3(Ve(),e)}};hd=S([ww({name:"flow.segments",description:"Returns one flow cut into segments and phases \u2014 the right first read for a flow with hundreds or thousands of events. Each segment is a backend request (its browser fetch, every service hop, db/redis/ai work and any queue worker it enqueued), a UI burst (state updates and renders, named by what churned), the origin that started the flow, or background noise; with times relative to the flow start, event/error counts, and a category. Also returns the flow's category, subject and tags. Open one unit with flow.get { flowId, segmentId }.",inputSchema:{flowId:a3.string().describe("Flow id from flow://recent or flow.list_recent."),maxSegments:a3.number().int().positive().max(500).default(120).describe("Cap on segments listed (failing and heaviest are kept first when it truncates).")}})],hd);var Bw=hd,o3=class{static{s(this,"Tm")}static{o(this,"FlowApp")}};o3=S([WD({id:"flow",name:"Flow",description:"Causal-chain index: every event carries a flowId; the app surfaces recent flows + origin events. story.compile turns one of these into a phase summary.",resources:[HD,QD,uw],tools:[sw,lw,Bw,mw,Dw]})],o3);var Oi="flow://recent",Ri="flow://current",Ti="flow://origins/recent",Fr=50,l3=50,vd=2e3,Cw=4*1024*1024,yd=32*1024*1024,xw=Fr+10;function d3(e){let t={flows:new Map,origins:[],recentOrder:[],retainedEvents:0,retainedBytes:0,evictedEvents:0,evictedForBytes:0},r=o((c,g,f,m=!0)=>{let h=Math.min(g,c.events.length);if(h<=0)return;if(m&&h>0&&(c.events[0]?.raw??{}).kind==="flow-origin"&&c.events.length>1){let D=c.eventBytes[1]??0;if(c.events.splice(1,1),c.eventBytes.splice(1,1),c.retainedBytes=Math.max(0,c.retainedBytes-D),t.retainedEvents=Math.max(0,t.retainedEvents-1),t.retainedBytes=Math.max(0,t.retainedBytes-D),t.evictedEvents+=1,f&&(t.evictedForBytes+=1),h-=1,h<=0)return}let E=0;for(let D=0;D<h;D+=1)E+=c.eventBytes[D]??0;c.events.splice(0,h),c.eventBytes.splice(0,h),c.retainedBytes=Math.max(0,c.retainedBytes-E),t.retainedEvents=Math.max(0,t.retainedEvents-h),t.retainedBytes=Math.max(0,t.retainedBytes-E),t.evictedEvents+=h,f&&(t.evictedForBytes+=h)},"evictPrefix"),i=o(c=>{let g=0,f=c.retainedBytes;for(;f>Cw&&g<c.eventBytes.length;)f-=c.eventBytes[g]??0,g+=1;r(c,g,!0)},"enforceEntryByteCap"),u=o(()=>{for(let c=t.recentOrder.length-1;t.retainedBytes>yd&&c>=0;c-=1){let g=t.flows.get(t.recentOrder[c]);if(!g)continue;let f=0,m=t.retainedBytes;for(;m>yd&&f<g.eventBytes.length;)m-=g.eventBytes[f]??0,f+=1;r(g,f,!0)}},"enforceGlobalByteCap"),n=o(c=>{let g=c.context.flowId;if(!g)return;let f=(c.raw??{}).kind;if(f==="subscription-added"||f==="subscription-removed"||f==="hook-run"||f==="store-created"||f==="singleton-instance"||f==="visual-frame")return;let m=f==="flow-origin",h=t.flows.get(g);if(!h){h={summary:{flowId:g,originType:c.context.originType,originNodeId:c.context.originNodeId,startedAt:c.timestamp,lastSeenAt:c.timestamp,eventCount:0,headline:c.title},events:[],eventBytes:[],retainedBytes:0,hasOrigin:!1},t.flows.set(g,h);let B={flowId:g,originType:c.context.originType,originNodeId:c.context.originNodeId,at:c.timestamp,label:c.title,eventId:c.id};t.origins.push(B),t.origins.length>l3&&t.origins.splice(0,t.origins.length-l3),e.resources.markDirty(Ti)}m&&!h.hasOrigin&&(h.hasOrigin=!0,h.summary.headline=c.title,c.context.originType&&(h.summary.originType=c.context.originType),c.context.originNodeId&&(h.summary.originNodeId=c.context.originNodeId)),c.timestamp<h.summary.startedAt&&(h.summary.startedAt=c.timestamp);let E=ki(c);h.events.push(c),h.eventBytes.push(E),h.retainedBytes+=E,t.retainedEvents+=1,t.retainedBytes+=E,h.events.length>vd&&r(h,h.events.length-vd,!1),i(h),h.summary.eventCount+=1,h.summary.lastSeenAt=c.timestamp;let D=t.recentOrder.indexOf(g);if(D>=0&&t.recentOrder.splice(D,1),t.recentOrder.unshift(g),t.recentOrder.length>Fr){let B=t.recentOrder.splice(Fr);for(let A of B){let I=t.flows.get(A);I&&r(I,I.events.length,!1,!1),t.flows.delete(A)}}u(),t.currentFlowId!==g&&(t.currentFlowId=g,e.resources.markDirty(Ri)),e.resources.markDirty(Oi)},"handler"),a=e.bus.subscribe(n);e.resources.register(Oi,()=>({schemaVersion:1,revision:e.resources.revision(Oi)??0,updatedAt:new Date().toISOString(),flows:t.recentOrder.map(c=>t.flows.get(c)?.summary).filter(c=>!!c)})),e.resources.register(Ri,()=>{let c=t.currentFlowId,g=c?t.flows.get(c):void 0;return{schemaVersion:1,revision:e.resources.revision(Ri)??0,updatedAt:new Date().toISOString(),flow:g?.summary??null}}),e.resources.register(Ti,()=>({schemaVersion:1,revision:e.resources.revision(Ti)??0,updatedAt:new Date().toISOString(),origins:t.origins.slice().reverse()}));let l=e.flows??lt,d=new Map,p={getFlowEvents(c){return t.flows.get(c)?.events.slice().sort((g,f)=>g.timestamp-f.timestamp)},getFlowSummary(c){return t.flows.get(c)?.summary},recentFlowIds(){return t.recentOrder.slice()},findFlowsByOrigin(c){return[...t.flows.values()].filter(g=>g.summary.originNodeId===c).map(g=>g.summary)},flowsConfig:l,analyzeFlow(c){let g=t.flows.get(c);if(!g)return;let f=`${g.summary.eventCount}:${g.events.length}:${g.summary.lastSeenAt}`,m=d.get(c);if(m&&m.key===f)return d.delete(c),d.set(c,m),m.analysis;let h=xi(p.getFlowEvents(c)??[],l);for(d.delete(c),d.set(c,{key:f,analysis:h});d.size>xw;)d.delete(d.keys().next().value);return h},classifiedRecent(c=Fr){let g=[];for(let f of t.recentOrder){if(g.length>=c)break;let m=t.flows.get(f)?.summary,h=p.analyzeFlow(f);!m||!h||g.push({summary:m,category:h.classification.category,decidedBy:h.classification.decidedBy,...h.classification.subject?{subject:h.classification.subject}:{},tags:h.classification.tags,segmentCount:h.segmentation.stats.segments,phaseCount:h.segmentation.stats.phases,signalCount:h.segmentation.stats.signal})}return g}};return od(p),{unsubscribe:o(()=>{od(void 0),a()},"unsubscribe"),uris:[Oi,Ri,Ti],lookups:p,retentionStats:o(()=>({residentEvents:t.retainedEvents,residentBytes:t.retainedBytes,evictedEvents:t.evictedEvents,evictedForBytes:t.evictedForBytes,eventCap:Fr*vd,byteCap:yd}),"retentionStats")}}s(d3,"zm"),o(d3,"installFlowReducer");import{App as kw}from"@frontmcp/sdk";import{Resource as Aw,ResourceContext as _w}from"@frontmcp/sdk";var Ed=class extends _w{static{s(this,"jm")}static{o(this,"StoryRecentResource")}async execute(){return this.get(q).read("story://recent")}};Ed=S([Aw({name:"story-recent",uri:"story://recent",mimeType:"application/json",description:"Last 50 compiled stories (one per flow), most recent first."})],Ed);var Iw=Ed;import{Resource as Sw,ResourceContext as Fw}from"@frontmcp/sdk";var bd=class extends Fw{static{s(this,"Nm")}static{o(this,"StoryLastResource")}async execute(){return this.get(q).read("story://last")}};bd=S([Sw({name:"story-last",uri:"story://last",mimeType:"application/json",description:"The most recently compiled story (full phase list)."})],bd);var zw=bd;import{Tool as jw,ToolContext as Nw,z as Ow}from"@frontmcp/sdk";var Mi="story://recent",Pi="story://last",Oe={byFlowId:new Map,order:[]},c3=!1;function p3(e){return c3||(e.resources.register(Mi,()=>({schemaVersion:1,revision:e.resources.revision(Mi)??0,updatedAt:new Date().toISOString(),stories:Oe.order.map(t=>Oe.byFlowId.get(t)).filter(t=>!!t).map(t=>({flowId:t.flowId,origin:t.origin,phaseCount:t.phases.length,startedAt:t.startedAt,endedAt:t.endedAt,eventCount:t.eventCount,finalState:t.finalState}))})),e.resources.register(Pi,()=>{let t=Oe.order[0],r=t?Oe.byFlowId.get(t):void 0;return{schemaVersion:1,revision:e.resources.revision(Pi)??0,updatedAt:new Date().toISOString(),story:r??null}}),c3=!0),m3(e.resources),{uris:[Mi,Pi]}}s(p3,"Mm"),o(p3,"installStoryReducer");var Dd;function m3(e){Dd=o(t=>{e.markDirty(t)},"markDirty")}s(m3,"_T"),o(m3,"setMarkDirty");function wd(e){Oe.byFlowId.set(e.flowId,e);let t=Oe.order.indexOf(e.flowId);if(t>=0&&Oe.order.splice(t,1),Oe.order.unshift(e.flowId),Oe.order.length>50){let r=Oe.order.splice(50);for(let i of r)Oe.byFlowId.delete(i)}Dd?.(Mi),Dd?.(Pi)}s(wd,"ro"),o(wd,"recordCompiledStory");function f3(e){return Oe.byFlowId.get(e)}s(f3,"Cm"),o(f3,"getCompiledStory");var $d=class extends Nw{static{s(this,"Um")}static{o(this,"StoryCompileTool")}async execute(e){let t=Ve();if(!t)return{compiled:!1,reason:"no active flow reducer"};let r=t.getFlowEvents(e.flowId);if(!r)return{compiled:!1,flowId:e.flowId};let i=Is(r,{flowId:e.flowId});return i?(wd(i),{compiled:!0,story:i}):{compiled:!1,flowId:e.flowId}}};$d=S([jw({name:"story.compile",description:"Compile a flow into a `FlowStory` (origin, phases, finalState). Caches the result; subsequent story.get(flowId) calls return it directly.",inputSchema:{flowId:Ow.string().describe("Flow id (from flow://recent).")}})],$d);var Rw=$d;import{Tool as Tw,ToolContext as Mw,z as Pw}from"@frontmcp/sdk";var Bd=class extends Mw{static{s(this,"Fm")}static{o(this,"StoryGetTool")}async execute(e){let t=f3(e.flowId);return t?{found:!0,story:t}:{found:!1,flowId:e.flowId}}};Bd=S([Tw({name:"story.get",description:"Returns a previously compiled story. If the story has not been compiled yet, returns `found: false`; call story.compile first.",inputSchema:{flowId:Pw.string().describe("Flow id.")}})],Bd);var Uw=Bd,g3=class{static{s(this,"Zm")}static{o(this,"StoryApp")}};g3=S([kw({id:"story",name:"Story",description:"Compiles flows into phase summaries (user-action / loading-ui / backend-request / state-update / final-render).",resources:[Iw,zw],tools:[Rw,Uw]})],g3);import{App as Zw}from"@frontmcp/sdk";import{Resource as qw,ResourceContext as Lw}from"@frontmcp/sdk";var Cd=class extends Lw{static{s(this,"qm")}static{o(this,"BuildCurrentResource")}async execute(){return this.get(q).read("build://current")}};Cd=S([qw({name:"build-current",uri:"build://current",mimeType:"application/json",description:"Current build status (clean / warning / failing), open failures and warnings."})],Cd);var Jw=Cd;import{Resource as Vw,ResourceContext as Ww}from"@frontmcp/sdk";var xd=class extends Ww{static{s(this,"Gm")}static{o(this,"BuildFailuresResource")}async execute(){return this.get(q).read("build://failures")}};xd=S([Vw({name:"build-failures",uri:"build://failures",mimeType:"application/json",description:"Currently-open build failures (deduped by fingerprint)."})],xd);var Gw=xd;import{Resource as Kw,ResourceContext as Hw}from"@frontmcp/sdk";var kd=class extends Hw{static{s(this,"Km")}static{o(this,"BuildRecentResource")}async execute(){return this.get(q).read("build://events/recent")}};kd=S([Kw({name:"build-events-recent",uri:"build://events/recent",mimeType:"application/json",description:"Last 50 build/lint/typecheck/HMR events in chronological order."})],kd);var Xw=kd,h3=class{static{s(this,"Xm")}static{o(this,"BuildApp")}};h3=S([Zw({id:"build",name:"Build",description:"Vite / TS / lint / HMR state.",resources:[Jw,Gw,Xw]})],h3);var Ui="build://current",Zi="build://failures",qi="build://events/recent",Yw=new Set(["vite","rollup","typescript","eslint"]),v3=new Set(["build","typecheck","lint"]),y3=50,Qw="Install the LensMCP Vite plugin (@lensmcp/vite-plugin) in the dev server, or run under the dev cluster, so build events reach this session.";function E3(e){let t=e.raw;return t&&typeof t=="object"?t:{}}s(E3,"LT"),o(E3,"readRaw");function b3(e,t){return e==="typecheck"?"tsc":e==="lint"?"eslint":t}s(b3,"FT"),o(b3,"defaultTool");function D3(e){let t={status:"unknown",recent:[],failures:new Map,warnings:new Map,hmrUpdates:0,producers:new Map,sawVerdict:!1},r=o((f,m)=>{let h=t.producers.get(f);t.producers.set(f,{id:f,tool:m.tool,...m.project?{project:m.project}:{},firstReportedAt:h?.firstReportedAt??m.at,lastReportedAt:Math.max(h?.lastReportedAt??0,m.at),lastRunStatus:m.runStatus,errorCount:m.errorCount??h?.errorCount??0,...m.warningCount!==void 0?{warningCount:m.warningCount}:h?.warningCount!==void 0?{warningCount:h.warningCount}:{},...m.durationMs!==void 0?{lastRunDurationMs:m.durationMs}:h?.lastRunDurationMs!==void 0?{lastRunDurationMs:h.lastRunDurationMs}:{},...m.error?{error:m.error}:{}}),St(t.producers,xr)},"touchProducer"),i=o(f=>{for(let[m,h]of t.failures)f(h)&&t.failures.delete(m);for(let[m,h]of t.warnings)f(h)&&t.warnings.delete(m)},"drop"),u=o((f,m)=>{i(h=>h.domain===f&&(m===void 0||h.project===m))},"clearScope"),n=o((f,m)=>{if(m.length===0)return;let h=new Set(m);i(E=>E.domain===f&&E.file!==void 0&&h.has(E.file))},"clearFiles"),a=o(()=>{if(t.failures.size>0){t.status="failing";return}if(t.warnings.size>0){t.status="warning";return}let f=[...t.producers.values()].some(m=>m.lastRunStatus==="error");t.status=f||!t.sawVerdict?"unknown":"clean"},"recomputeStatus"),l=o(()=>{e.resources.markDirty(Ui),e.resources.markDirty(Zi),e.resources.markDirty(qi)},"markDirty"),d=o(f=>{if([...t.failures.values()].some(m=>m.project===f)||[...t.warnings.values()].some(m=>m.project===f)||[...t.producers.values()].some(m=>m.project===f)){for(let m of v3)u(m,f);for(let[m,h]of t.producers)h.project===f&&t.producers.delete(m);t.sawVerdict=[...t.producers.values()].some(m=>m.lastRunStatus!=="error"),a(),l()}},"supersedeProject"),p=o(f=>{if(f.source==="gateway"&&f.category==="cluster"){let j=f.raw??null,F=j?.kind;(F==="service-starting"||F==="service-respawn")&&j?.project&&d(j.project);return}if(!Yw.has(f.source)||!v3.has(f.category))return;let m=f.category,h=E3(f),E=h.project,D=h.tool??b3(m,f.source),B=`${D}:${E??"*"}`,A=typeof h.kind=="string"&&h.kind.endsWith("-run"),I={id:f.id,timestamp:f.timestamp,severity:f.severity,title:f.title,...f.message!==void 0?{message:f.message}:{},...f.location?.file?{file:f.location.file}:h.file?{file:h.file}:{},domain:m,...E?{project:E}:{},fingerprint:f.fingerprint};if(f.severity==="info"&&(A&&h.phase==="start"||f.title.startsWith("tsc clear")||f.title.startsWith("ESLint clear"))){u(m,E),t.lastRunAt=f.timestamp,zr(t,I),r(B,{tool:D,...E?{project:E}:{},at:f.timestamp,runStatus:"running"}),A||(t.sawVerdict=!0),a(),l();return}if(A&&h.phase==="end"){let j=h.status==="error"?"error":h.status==="failing"?"failing":"clean";j==="clean"&&u(m,E),j!=="error"&&(t.sawVerdict=!0),t.lastRunAt=f.timestamp,zr(t,I),r(B,{tool:D,...E?{project:E}:{},at:f.timestamp,runStatus:j,...h.durationMs!==void 0?{durationMs:h.durationMs}:{},...h.errorCount!==void 0?{errorCount:h.errorCount}:{},...h.warningCount!==void 0?{warningCount:h.warningCount}:{},...h.error?{error:h.error}:{}}),a(),l();return}if(h.kind==="hmr"||f.title.startsWith("HMR ")){t.hmrUpdates+=1;let j=[...I.file?[I.file]:[],...f.relatedFiles??[]];n("build",j),t.lastRunAt=f.timestamp,t.sawVerdict=!0,zr(t,I),r(B,{tool:D,...E?{project:E}:{},at:f.timestamp,runStatus:"clean"}),a(),l();return}zr(t,I),f.severity==="error"||f.severity==="fatal"?(t.failures.set(I.fingerprint,I),t.warnings.delete(I.fingerprint)):f.severity==="warning"?t.failures.has(I.fingerprint)||t.warnings.set(I.fingerprint,I):(t.failures.delete(I.fingerprint),t.warnings.delete(I.fingerprint)),t.lastRunAt=f.timestamp,t.sawVerdict=!0,r(B,{tool:D,...E?{project:E}:{},at:f.timestamp,runStatus:t.failures.size>0?"failing":"clean"}),a(),l()},"handler"),c=e.bus.subscribe(p),g=o(()=>yi({producers:[...t.producers.values()],domain:"build",noProducerHint:Qw}),"health");return e.resources.register(Ui,()=>({schemaVersion:1,revision:e.resources.revision(Ui)??0,updatedAt:new Date().toISOString(),status:t.status,failures:[...t.failures.values()],warnings:[...t.warnings.values()],hmrUpdates:t.hmrUpdates,lastRunAt:t.lastRunAt,...g()})),e.resources.register(Zi,()=>({schemaVersion:1,revision:e.resources.revision(Zi)??0,updatedAt:new Date().toISOString(),failures:[...t.failures.values()],...g()})),e.resources.register(qi,()=>({schemaVersion:1,revision:e.resources.revision(qi)??0,updatedAt:new Date().toISOString(),events:t.recent.slice()})),{unsubscribe:c,uris:[Ui,Zi,qi]}}s(D3,"Hm"),o(D3,"installBuildReducer");function zr(e,t){e.recent.push(t),e.recent.length>y3&&e.recent.splice(0,e.recent.length-y3)}s(zr,"Os"),o(zr,"pushRecent");import{App as e$}from"@frontmcp/sdk";import{Resource as t$,ResourceContext as u$}from"@frontmcp/sdk";var Ad=class extends u${static{s(this,"Ym")}static{o(this,"LintCurrentResource")}async execute(){return this.get(q).read("lint://current")}};Ad=S([t$({name:"lint-current",uri:"lint://current",mimeType:"application/json",description:"Current lint status (clean / warning / failing) + counts."})],Ad);var r$=Ad;import{Resource as n$,ResourceContext as i$}from"@frontmcp/sdk";var _d=class extends i${static{s(this,"eg")}static{o(this,"LintErrorsResource")}async execute(){return this.get(q).read("lint://errors")}};_d=S([n$({name:"lint-errors",uri:"lint://errors",mimeType:"application/json",description:"Currently-open ESLint errors (deduped by fingerprint)."})],_d);var s$=_d;import{Resource as a$,ResourceContext as o$}from"@frontmcp/sdk";var Id=class extends o${static{s(this,"rg")}static{o(this,"LintWarningsResource")}async execute(){return this.get(q).read("lint://warnings")}};Id=S([a$({name:"lint-warnings",uri:"lint://warnings",mimeType:"application/json",description:"Currently-open ESLint warnings."})],Id);var l$=Id,w3=class{static{s(this,"og")}static{o(this,"LintApp")}};w3=S([e$({id:"lint",name:"Lint",description:"ESLint state.",resources:[r$,s$,l$]})],w3);var Li="lint://current",Ji="lint://errors",Vi="lint://warnings",d$="Nothing runs ESLint in the dev loop, so this is expected. Run `lensmcp lint [paths\u2026]` to publish a run; until then treat lint as UNCHECKED, not passing.";function $3(e){let t=e.raw;return t&&typeof t=="object"?t:{}}s($3,"XT"),o($3,"readRaw");function B3(e){let t={status:"unknown",errors:new Map,warnings:new Map,producers:new Map,sawVerdict:!1},r=o((c,g)=>{let f=t.producers.get(c);t.producers.set(c,{id:c,tool:g.tool,...g.project?{project:g.project}:{},firstReportedAt:f?.firstReportedAt??g.at,lastReportedAt:Math.max(f?.lastReportedAt??0,g.at),lastRunStatus:g.runStatus,errorCount:g.errorCount??f?.errorCount??0,...g.warningCount!==void 0?{warningCount:g.warningCount}:f?.warningCount!==void 0?{warningCount:f.warningCount}:{},...g.durationMs!==void 0?{lastRunDurationMs:g.durationMs}:f?.lastRunDurationMs!==void 0?{lastRunDurationMs:f.lastRunDurationMs}:{},...g.error?{error:g.error}:{}}),St(t.producers,xr)},"touchProducer"),i=o((c,g)=>{let f=o((m,h)=>{for(let[E,D]of m)h(D)&&m.delete(E)},"drop");if(c){f(t.errors,m=>m.project===c),f(t.warnings,m=>m.project===c);return}if(g){f(t.errors,m=>m.file===g),f(t.warnings,m=>m.file===g);return}t.errors.clear(),t.warnings.clear()},"clearScope"),u=o(()=>{if(t.errors.size>0){t.status="failing";return}if(t.warnings.size>0){t.status="warning";return}let c=[...t.producers.values()].some(g=>g.lastRunStatus==="error");t.status=c||!t.sawVerdict?"unknown":"clean"},"recomputeStatus"),n=o(()=>{e.resources.markDirty(Li),e.resources.markDirty(Ji),e.resources.markDirty(Vi)},"markDirty"),a=o(c=>{if([...t.errors.values()].some(g=>g.project===c)||[...t.warnings.values()].some(g=>g.project===c)||[...t.producers.values()].some(g=>g.project===c)){i(c,void 0);for(let[g,f]of t.producers)f.project===c&&t.producers.delete(g);t.sawVerdict=[...t.producers.values()].some(g=>g.lastRunStatus!=="error"),u(),n()}},"supersedeProject"),l=o(c=>{if(c.source==="gateway"&&c.category==="cluster"){let A=c.raw??null,I=A?.kind;(I==="service-starting"||I==="service-respawn")&&A?.project&&a(A.project);return}if(c.source!=="eslint"||c.category!=="lint")return;let g=$3(c),f=g.project,m=g.tool??"eslint",h=`${m}:${f??"*"}`,E=g.kind==="lint-run";if(c.severity==="info"&&(E&&g.phase==="start"||c.title.startsWith("ESLint clear"))){i(f,c.location?.file),t.lastRunAt=c.timestamp,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:"running"}),E||(t.sawVerdict=!0),u(),n();return}if(E&&g.phase==="end"){let A=g.status==="error"?"error":g.status==="failing"?"failing":"clean";A!=="error"&&(t.sawVerdict=!0),t.lastRunAt=c.timestamp,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:A,...g.durationMs!==void 0?{durationMs:g.durationMs}:{},...g.errorCount!==void 0?{errorCount:g.errorCount}:{},...g.warningCount!==void 0?{warningCount:g.warningCount}:{},...g.error?{error:g.error}:{}}),u(),n();return}let D=c.title.match(/^\[([^\]]+)\]/),B={id:c.id,timestamp:c.timestamp,severity:c.severity,...g.rule?{rule:g.rule}:D?.[1]?{rule:D[1]}:{},message:c.message??c.title,...c.location?.file?{file:c.location.file}:{},...c.location?.line!==void 0?{line:c.location.line}:{},...c.location?.column!==void 0?{column:c.location.column}:{},...f?{project:f}:{},fingerprint:c.fingerprint};if(c.severity==="error"||c.severity==="fatal")t.errors.set(B.fingerprint,B),t.warnings.delete(B.fingerprint);else if(c.severity==="warning")t.errors.has(B.fingerprint)||t.warnings.set(B.fingerprint,B);else return;t.lastRunAt=c.timestamp,t.sawVerdict=!0,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:t.errors.size>0?"failing":"clean"}),u(),n()},"handler"),d=e.bus.subscribe(l),p=o(()=>yi({producers:[...t.producers.values()],domain:"lint",noProducerHint:d$}),"health");return e.resources.register(Li,()=>({schemaVersion:1,revision:e.resources.revision(Li)??0,updatedAt:new Date().toISOString(),status:t.status,errorCount:t.errors.size,warningCount:t.warnings.size,lastRunAt:t.lastRunAt,...p()})),e.resources.register(Ji,()=>({schemaVersion:1,revision:e.resources.revision(Ji)??0,updatedAt:new Date().toISOString(),errors:[...t.errors.values()],...p()})),e.resources.register(Vi,()=>({schemaVersion:1,revision:e.resources.revision(Vi)??0,updatedAt:new Date().toISOString(),warnings:[...t.warnings.values()],...p()})),{unsubscribe:d,uris:[Li,Ji,Vi]}}s(B3,"ig"),o(B3,"installLintReducer");import{App as c$}from"@frontmcp/sdk";import{Resource as p$,ResourceContext as m$}from"@frontmcp/sdk";var Sd=class extends m${static{s(this,"sg")}static{o(this,"TypecheckCurrentResource")}async execute(){return this.get(q).read("typecheck://current")}};Sd=S([p$({name:"typecheck-current",uri:"typecheck://current",mimeType:"application/json",description:"Current TypeScript typecheck status + error count."})],Sd);var f$=Sd;import{Resource as g$,ResourceContext as h$}from"@frontmcp/sdk";var Fd=class extends h${static{s(this,"cg")}static{o(this,"TypecheckErrorsResource")}async execute(){return this.get(q).read("typecheck://errors")}};Fd=S([g$({name:"typecheck-errors",uri:"typecheck://errors",mimeType:"application/json",description:"Current TypeScript errors (deduped by fingerprint)."})],Fd);var v$=Fd,C3=class{static{s(this,"lg")}static{o(this,"TypecheckApp")}};C3=S([c$({id:"typecheck",name:"Typecheck",description:"TypeScript diagnostics from `tsc --watch`.",resources:[f$,v$]})],C3);var Wi="typecheck://current",Gi="typecheck://errors",y$="Wire one: the dev cluster publishes from `TsgoCheckPlugin` when `LENSMCP_TYPECHECK=tsgo` (@lensmcp/cluster), or call `startTscCollector()` from @lensmcp/session for a `tsc --watch` workspace.";function x3(e){let t=e.raw;return t&&typeof t=="object"?t:{}}s(x3,"nE"),o(x3,"readRaw");function k3(e){let t={status:"unknown",errors:new Map,producers:new Map,sawVerdict:!1},r=o((c,g)=>{let f=t.producers.get(c),m={id:c,tool:g.tool,...g.project?{project:g.project}:{},firstReportedAt:f?.firstReportedAt??g.at,lastReportedAt:Math.max(f?.lastReportedAt??0,g.at),lastRunStatus:g.runStatus,errorCount:g.errorCount??f?.errorCount??0,...g.durationMs!==void 0?{lastRunDurationMs:g.durationMs}:f?.lastRunDurationMs!==void 0?{lastRunDurationMs:f.lastRunDurationMs}:{},...g.warningCount!==void 0?{warningCount:g.warningCount}:{},...g.error?{error:g.error}:{}};t.producers.set(c,m),St(t.producers,xr)},"touchProducer"),i=o(c=>{if(!c){t.errors.clear();return}for(let[g,f]of t.errors)f.project===c&&t.errors.delete(g)},"clearScope"),u=o(()=>{if(t.errors.size>0){t.status="failing";return}let c=[...t.producers.values()].some(g=>g.lastRunStatus==="error");t.status=c||!t.sawVerdict?"unknown":"clean"},"recomputeStatus"),n=o(()=>{e.resources.markDirty(Wi),e.resources.markDirty(Gi)},"markDirty"),a=o(c=>{let g=[...t.errors.values()].some(m=>m.project===c),f=[...t.producers.values()].some(m=>m.project===c);if(!(!g&&!f)){i(c);for(let[m,h]of t.producers)h.project===c&&t.producers.delete(m);t.sawVerdict=[...t.producers.values()].some(m=>m.lastRunStatus!=="error"),u(),n()}},"supersedeProject"),l=o(c=>{if(c.source==="gateway"&&c.category==="cluster"){let A=c.raw??null,I=A?.kind;(I==="service-starting"||I==="service-respawn")&&A?.project&&a(A.project);return}if(c.source!=="typescript"||c.category!=="typecheck")return;let g=x3(c),f=g.project,m=g.tool??"tsc",h=`${m}:${f??"*"}`,E=g.kind==="typecheck-run";if(c.severity==="info"&&(E&&g.phase==="start"||c.title.startsWith("tsc clear"))){i(f),t.lastRunAt=c.timestamp,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:"running"}),E||(t.sawVerdict=!0),u(),n();return}if(E&&g.phase==="end"){let A=g.status==="error"?"error":g.status==="failing"?"failing":"clean";A!=="error"&&(t.sawVerdict=!0),t.lastRunAt=c.timestamp,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:A,...g.durationMs!==void 0?{durationMs:g.durationMs}:{},...g.errorCount!==void 0?{errorCount:g.errorCount}:{},...g.warningCount!==void 0?{warningCount:g.warningCount}:{},...g.error?{error:g.error}:{}}),u(),n();return}if(c.severity!=="error"&&c.severity!=="fatal")return;let D=c.title.match(/\bTS(\d+):/),B={id:c.id,timestamp:c.timestamp,...g.code?{code:g.code}:D?{code:`TS${D[1]}`}:{},message:c.message??c.title,...c.location?.file?{file:c.location.file}:{},...c.location?.line!==void 0?{line:c.location.line}:{},...c.location?.column!==void 0?{column:c.location.column}:{},...f?{project:f}:{},fingerprint:c.fingerprint};t.errors.set(B.fingerprint,B),t.lastRunAt=c.timestamp,t.sawVerdict=!0,r(h,{tool:m,...f?{project:f}:{},at:c.timestamp,runStatus:"failing"}),u(),n()},"handler"),d=e.bus.subscribe(l),p=o(()=>yi({producers:[...t.producers.values()],domain:"typecheck",noProducerHint:y$}),"health");return e.resources.register(Wi,()=>({schemaVersion:1,revision:e.resources.revision(Wi)??0,updatedAt:new Date().toISOString(),status:t.status,errorCount:t.errors.size,lastRunAt:t.lastRunAt,...p()})),e.resources.register(Gi,()=>({schemaVersion:1,revision:e.resources.revision(Gi)??0,updatedAt:new Date().toISOString(),errors:[...t.errors.values()],...p()})),{unsubscribe:d,uris:[Wi,Gi]}}s(k3,"dg"),o(k3,"installTypecheckReducer");import{App as E$}from"@frontmcp/sdk";import{Resource as b$,ResourceContext as D$}from"@frontmcp/sdk";var zd=class extends D${static{s(this,"pg")}static{o(this,"BundleCurrentResource")}async execute(){return this.get(q).read("bundle://current")}};zd=S([b$({name:"bundle-current",uri:"bundle://current",mimeType:"application/json",description:"Most recent Vite/Rollup bundle report (chunks + sizes)."})],zd);var w$=zd;import{Resource as $$,ResourceContext as B$}from"@frontmcp/sdk";var jd=class extends B${static{s(this,"mg")}static{o(this,"BundleChunksResource")}async execute(){return this.get(q).read("bundle://chunks")}};jd=S([$$({name:"bundle-chunks",uri:"bundle://chunks",mimeType:"application/json",description:"Per-chunk bundle sizes (most recent build)."})],jd);var C$=jd;import{Resource as x$,ResourceContext as k$}from"@frontmcp/sdk";var Nd=class extends k${static{s(this,"hg")}static{o(this,"BundleModulesResource")}async execute(){return this.get(q).read("bundle://modules")}};Nd=S([x$({name:"bundle-modules",uri:"bundle://modules",mimeType:"application/json",description:"Flattened per-module bundle sizes (most recent build)."})],Nd);var A$=Nd;import{Resource as _$,ResourceContext as I$}from"@frontmcp/sdk";var Od=class extends I${static{s(this,"yg")}static{o(this,"BundleRegressionsResource")}async execute(){return this.get(q).read("bundle://regressions")}};Od=S([_$({name:"bundle-regressions",uri:"bundle://regressions",mimeType:"application/json",description:"Chunks/modules that grew, were added, or were removed vs the baseline."})],Od);var S$=Od;import{Resource as F$,ResourceContext as z$}from"@frontmcp/sdk";var Rd=class extends z${static{s(this,"wg")}static{o(this,"BundleCompareResource")}async execute(){return this.get(q).read("bundle://compare/latest")}};Rd=S([F$({name:"bundle-compare-latest",uri:"bundle://compare/latest",mimeType:"application/json",description:"Most recent build vs baseline: totals + delta."})],Rd);var j$=Rd,A3=class{static{s(this,"xg")}static{o(this,"BundleApp")}};A3=S([E$({id:"bundle",name:"Bundle",description:"Vite/Rollup bundle reports + regressions against baseline.",resources:[w$,C$,A$,S$,j$]})],A3);function Td(e,t){let r=[],i=new Map(e.chunks.map(n=>[n.name,n])),u=new Map(t.chunks.map(n=>[n.name,n]));for(let[n,a]of u){let l=i.get(n);if(!l){r.push({kind:"chunk-added",name:n,afterBytes:a.sizeBytes,deltaBytes:a.sizeBytes});continue}let d=a.sizeBytes-l.sizeBytes;d>256&&r.push({kind:"chunk-grew",name:n,beforeBytes:l.sizeBytes,afterBytes:a.sizeBytes,deltaBytes:d}),r.push(..._3(l,a))}for(let[n,a]of i)u.has(n)||r.push({kind:"chunk-removed",name:n,beforeBytes:a.sizeBytes,deltaBytes:-a.sizeBytes});return r.sort((n,a)=>Math.abs(a.deltaBytes)-Math.abs(n.deltaBytes))}s(Td,"Us"),o(Td,"compareReports");function _3(e,t){let r=[],i=new Map(e.modules.map(u=>[u.id,u.sizeBytes]));for(let u of t.modules){let n=i.get(u.id);if(n===void 0)u.sizeBytes>256&&r.push({kind:"module-added",name:`${t.name}::${u.id}`,afterBytes:u.sizeBytes,deltaBytes:u.sizeBytes});else{let a=u.sizeBytes-n;a>256&&r.push({kind:"module-grew",name:`${t.name}::${u.id}`,beforeBytes:n,afterBytes:u.sizeBytes,deltaBytes:a})}}return r}s(_3,"gE"),o(_3,"compareModules");var Ki="bundle://current",Hi="bundle://chunks",Xi="bundle://modules",jr="bundle://regressions",Nr="bundle://compare/latest";function I3(e){let t={baseline:e.initialBaseline,regressions:[]},r=o(u=>{if(u.source!=="rollup"&&u.source!=="vite"||u.category!=="build")return;let n=u.raw;if(!n||typeof n!="object"||!("kind"in n)||n.kind!=="bundle-report")return;let a=n.report;!a||!Array.isArray(a.chunks)||(t.current=a,t.regressions=t.baseline?Td(t.baseline,a):[],e.resources.markDirty(Ki),e.resources.markDirty(Hi),e.resources.markDirty(Xi),e.resources.markDirty(jr),e.resources.markDirty(Nr))},"handler"),i=e.bus.subscribe(r);return e.resources.register(Ki,()=>({schemaVersion:1,revision:e.resources.revision(Ki)??0,updatedAt:new Date().toISOString(),report:t.current??null})),e.resources.register(Hi,()=>({schemaVersion:1,revision:e.resources.revision(Hi)??0,updatedAt:new Date().toISOString(),chunks:t.current?.chunks??[]})),e.resources.register(Xi,()=>{let u=t.current?.chunks.flatMap(n=>n.modules.map(a=>({...a,chunk:n.name})))??[];return{schemaVersion:1,revision:e.resources.revision(Xi)??0,updatedAt:new Date().toISOString(),modules:u}}),e.resources.register(jr,()=>({schemaVersion:1,revision:e.resources.revision(jr)??0,updatedAt:new Date().toISOString(),regressions:t.regressions.slice()})),e.resources.register(Nr,()=>({schemaVersion:1,revision:e.resources.revision(Nr)??0,updatedAt:new Date().toISOString(),baseline:t.baseline??null,current:t.current??null,deltaBytes:t.baseline&&t.current?t.current.totalBytes-t.baseline.totalBytes:0})),{unsubscribe:i,uris:[Ki,Hi,Xi,jr,Nr],setBaseline:o(u=>{t.baseline=u,t.current&&(t.regressions=Td(t.baseline,t.current)),e.resources.markDirty(jr),e.resources.markDirty(Nr)},"setBaseline")}}s(I3,"_g"),o(I3,"installBundleReducer");import{App as N$}from"@frontmcp/sdk";import{Resource as O$,ResourceContext as R$}from"@frontmcp/sdk";var Md=class extends R${static{s(this,"kg")}static{o(this,"RuntimeBrowserConsoleResource")}async execute(){return this.get(q).read("runtime://browser/console")}};Md=S([O$({name:"runtime-browser-console",uri:"runtime://browser/console",mimeType:"application/json",description:"Most recent 200 console.* messages from any tab."})],Md);var T$=Md;import{Resource as M$,ResourceContext as P$}from"@frontmcp/sdk";var Pd=class extends P${static{s(this,"Ig")}static{o(this,"RuntimeBrowserErrorsResource")}async execute(){return this.get(q).read("runtime://browser/errors")}};Pd=S([M$({name:"runtime-browser-errors",uri:"runtime://browser/errors",mimeType:"application/json",description:"Uncaught browser errors + promise rejections, per tab, since that tab's current page load (a reload retracts the previous document's errors)."})],Pd);var U$=Pd;import{Resource as Z$,ResourceContext as q$}from"@frontmcp/sdk";var Ud=class extends q${static{s(this,"Tg")}static{o(this,"RuntimeServerErrorsResource")}async execute(){return this.get(q).read("runtime://errors")}};Ud=S([Z$({name:"runtime-errors",uri:"runtime://errors",mimeType:"application/json",description:"Errors raised INSIDE a backend pod, with no browser involved \u2014 the 500s a curl, an e2e runner or a queue job produces. Each entry carries the route, the status, the request id the gateway stamped, and the stack. Use this when a server-side call failed and no browser flow exists to explain it; `runtime://browser/errors` is the browser-side counterpart."})],Ud);var L$=Ud;import{Resource as J$,ResourceContext as V$}from"@frontmcp/sdk";var Zd=class extends V${static{s(this,"Ag")}static{o(this,"RuntimeBrowserNetworkResource")}async execute(){return this.get(q).read("runtime://browser/network")}};Zd=S([J$({name:"runtime-browser-network",uri:"runtime://browser/network",mimeType:"application/json",description:"Recent fetch / XHR / browser network activity."})],Zd);var W$=Zd;import{Resource as G$,ResourceContext as K$}from"@frontmcp/sdk";var qd=class extends K${static{s(this,"jg")}static{o(this,"RuntimeBrowserFailedRequestsResource")}async execute(){return this.get(q).read("runtime://browser/failed-requests")}};qd=S([G$({name:"runtime-browser-failed-requests",uri:"runtime://browser/failed-requests",mimeType:"application/json",description:"Recent failed network requests (status >= 400 or transport errors)."})],qd);var H$=qd,S3=class{static{s(this,"Ng")}static{o(this,"RuntimeApp")}};S3=S([N$({id:"runtime",name:"Runtime",description:"Live browser/node runtime state (console, errors, network).",resources:[T$,U$,L$,W$,H$]})],S3);var mu="runtime://browser/console",fu="runtime://browser/errors",gu="runtime://browser/network",hu="runtime://browser/failed-requests",vu="runtime://errors",X$="default",Ld=o(e=>e??X$,"tabOf");function F3(e){if(e.category!=="runtime")return!1;let t=e.raw;return t&&typeof t=="object"&&t.kind==="ready"?!0:e.title==="Client runtime ready"}s(F3,"TE"),o(F3,"isDocumentBoundary");function z3(e){if(e.category!=="runtime")return!1;let t=e.raw;return!!(t&&typeof t=="object"&&t.kind==="gone")}s(z3,"EE"),o(z3,"isTabGone");function j3(e){let t=(e.now??(()=>Date.now()))(),r={console:[],errors:[],network:[],failed:[],serverErrors:[],readyByTab:new Map,changedAt:new Map},i=o((d,p)=>{r.changedAt.set(d,p),e.resources.markDirty(d)},"touch"),u=o((d,p,c)=>{let g=d.filter(f=>!(Ld(f.tabId)===p&&f.timestamp<c));g.length!==d.length&&(d.length=0,d.push(...g))},"retract"),n=o(d=>{if(N3(d)){let c=d.raw?.project;if(c){let g=r.serverErrors.length;r.serverErrors=r.serverErrors.filter(f=>f.project!==c),r.serverErrors.length!==g&&i(vu,d.timestamp)}return}if(O3(d)){r.lastServerEventAt=Math.max(r.lastServerEventAt??0,d.timestamp),yu(r.serverErrors,R3(d),100),i(vu,d.timestamp);return}if(!(d.source==="client-runtime"||d.source==="chrome")&&!(d.source==="react"&&d.category==="network"))return;if(r.lastEventAt=Math.max(r.lastEventAt??0,d.timestamp),z3(d)){let c=Ld(d.context.tabId);u(r.errors,c,Number.POSITIVE_INFINITY),u(r.failed,c,Number.POSITIVE_INFINITY),r.readyByTab.delete(c);for(let g of[fu,hu,mu,gu])i(g,d.timestamp);return}if(F3(d)){let c=Ld(d.context.tabId);r.readyByTab.set(c,Math.max(r.readyByTab.get(c)??0,d.timestamp)),r.lastReadyAt=Math.max(r.lastReadyAt??0,d.timestamp);let g=d.timestamp-1e3;u(r.errors,c,g),u(r.failed,c,g);for(let f of[fu,hu,mu,gu])i(f,d.timestamp);return}let p={id:d.id,timestamp:d.timestamp,severity:d.severity,title:d.title,message:d.message,source:d.source,fingerprint:d.fingerprint,tabId:d.context.tabId,url:d.context.url,raw:d.raw};if(d.category==="network"){yu(r.network,p,200),i(gu,d.timestamp),d.severity==="error"&&(yu(r.failed,p,50),i(hu,d.timestamp));return}(d.severity==="error"||d.severity==="fatal")&&(yu(r.errors,p,100),i(fu,d.timestamp)),d.title?.startsWith("console.")&&(yu(r.console,p,200),i(mu,d.timestamp))},"handler"),a=e.bus.subscribe(n),l=o((d,p)=>T3(e.resources,d,p,r,t),"snap");return e.resources.register(vu,()=>l(vu,r.serverErrors)),e.resources.register(mu,()=>l(mu,r.console)),e.resources.register(fu,()=>l(fu,r.errors)),e.resources.register(gu,()=>l(gu,r.network)),e.resources.register(hu,()=>l(hu,r.failed)),{unsubscribe:a,uris:[mu,fu,gu,hu,vu]}}s(j3,"Dg"),o(j3,"installRuntimeReducer");function Jd(e){let t=e.raw??null,r=e.context;return t?.project??r.projectName}s(Jd,"W$"),o(Jd,"projectOf");function N3(e){if(e.source!=="gateway"||e.category!=="cluster")return!1;let t=e.raw?.kind;return t==="service-starting"||t==="service-respawn"}s(N3,"AE"),o(N3,"isGenerationBoundary");function O3(e){if(e.source!=="nestjs"||e.severity!=="error"&&e.severity!=="fatal")return!1;let t=e.raw??{};return t.kind==="server-request"||t.kind==="uncaught"?!0:t.kind!=="log"?!1:t.request?.error?!0:/\b[A-Za-z0-9_$]*(?:Error|Exception)\b|\b(?:ERROR|FATAL)\b/.test(e.title??"")}s(O3,"zE"),o(O3,"isServerError");function R3(e){let t=(e.raw??{}).request??{},r=t.error;return{id:e.id,timestamp:e.timestamp,severity:e.severity,title:e.title,message:e.message??r?.message,source:e.source,fingerprint:e.fingerprint,...e.context.requestId?{requestId:e.context.requestId}:{},...Jd(e)?{project:Jd(e)}:{},...typeof t.route=="string"?{route:t.route}:{},...typeof t.status=="number"?{status:t.status}:{},...r?.stack?{stack:r.stack}:{},raw:e.raw}}s(R3,"jE"),o(R3,"serverEntry");function T3(e,t,r,i,u){let n=t===vu,a=n?i.lastServerEventAt:i.lastEventAt,l=a!==void 0;return{schemaVersion:1,revision:e.revision(t)??0,updatedAt:new Date(i.changedAt.get(t)??u).toISOString(),count:r.length,entries:r.slice(),producer:l?"connected":"none",lastEventAt:a,lastReadyAt:i.lastReadyAt,detail:n?l?r.length===0?"No server-side errors held. Pods HAVE reported, but a new pod generation retracts the errors of the one it replaced \u2014 so this is NOT evidence the routes are healthy: nobody may have re-made the failing request since.":`${r.length} server-side error${r.length===1?"":"s"} from ${new Set(r.map(d=>d.project??"unknown")).size} project${new Set(r.map(d=>d.project??"unknown")).size===1?"":"s"}`:"No pod has ever reported into this session \u2014 this is NOT evidence the backend is healthy, nothing is watching. Run the backend under the dev cluster so pod errors reach this session.":l?`browser attached; ${r.length} entr${r.length===1?"y":"ies"} from ${i.readyByTab.size} open tab${i.readyByTab.size===1?"":"s"}`+(i.lastReadyAt===void 0?" (no page load observed yet)":""):"No browser has ever reported into this session \u2014 this is NOT evidence the app is healthy, nothing is watching. Open the app under the dev cluster (or the Vite dev server with @lensmcp/vite-plugin installed) so browser events reach this session."}}s(T3,"OE"),o(T3,"snapshot");function yu(e,t,r){e.push(t),e.length>r&&e.splice(0,e.length-r)}s(yu,"io"),o(yu,"pushBounded");import{App as Y$}from"@frontmcp/sdk";import{Resource as Q$,ResourceContext as eB}from"@frontmcp/sdk";var Vd=class extends eB{static{s(this,"Mg")}static{o(this,"BrowserTabsResource")}async execute(){return this.get(q).read("browser://tabs")}};Vd=S([Q$({name:"browser-tabs",uri:"browser://tabs",mimeType:"application/json",description:"Open browser tabs with per-tab status, url, and event counts. `status` reflects the tab's CURRENT page load \u2014 a reload resets it."})],Vd);var tB=Vd;import{Resource as uB,ResourceContext as rB}from"@frontmcp/sdk";var Wd=class extends rB{static{s(this,"Ug")}static{o(this,"BrowserActiveTabResource")}async execute(){return this.get(q).read("browser://active-tab")}};Wd=S([uB({name:"browser-active-tab",uri:"browser://active-tab",mimeType:"application/json",description:"The currently-focused browser tab."})],Wd);var nB=Wd,M3=class{static{s(this,"Fg")}static{o(this,"BrowserApp")}};M3=S([Y$({id:"browser",name:"Browser",description:"Per-tab browser state (multi-tab refinement comes in Phase 6).",resources:[tB,nB]})],M3);var ct="browser://tabs",pt="browser://active-tab";function P3(e){if(e.category!=="runtime")return!1;let t=e.raw;return t&&typeof t=="object"&&t.kind==="ready"?!0:e.title==="Client runtime ready"}s(P3,"UE"),o(P3,"isDocumentBoundary");function U3(e){if(e.category!=="runtime")return!1;let t=e.raw;return!!(t&&typeof t=="object"&&t.kind==="gone")}s(U3,"LE"),o(U3,"isTabGone");function Z3(e){let t=(e.now??(()=>Date.now()))(),r={tabs:new Map,changedAt:new Map},i=o(a=>{if(a.source!=="chrome"&&a.source!=="client-runtime")return;let l=a.context.tabId??"default";if(U3(a)){if(r.tabs.delete(l),r.activePageId===l){let p=[...r.tabs.keys()];r.activePageId=p[p.length-1]}r.lastEventAt=Math.max(r.lastEventAt??0,a.timestamp),r.changedAt.set(ct,a.timestamp),r.changedAt.set(pt,a.timestamp),e.resources.markDirty(ct),e.resources.markDirty(pt);return}let d=r.tabs.get(l);if(d||(d={pageId:l,url:a.context.url??"",status:"unknown",unreadEvents:0,totalEvents:0,loads:0}),r.tabs.delete(l),r.tabs.set(l,d),r.tabs.size>100){let p=r.tabs.keys().next().value;p!==void 0&&p!==l&&r.tabs.delete(p)}a.context.url&&(d.url=a.context.url),d.totalEvents+=1,d.lastEventAt=a.timestamp,r.activePageId=l,r.lastEventAt=Math.max(r.lastEventAt??0,a.timestamp),P3(a)?(d.status="clean",d.unreadEvents=0,d.loads+=1,d.lastReadyAt=a.timestamp):(d.unreadEvents+=1,a.severity==="error"||a.severity==="fatal"?d.status="failing":d.status!=="failing"&&a.severity==="warning"?d.status="warning":d.status==="unknown"&&(d.status="clean")),r.changedAt.set(ct,a.timestamp),r.changedAt.set(pt,a.timestamp),e.resources.markDirty(ct),e.resources.markDirty(pt)},"handler"),u=e.bus.subscribe(i),n=o(a=>new Date(r.changedAt.get(a)??t).toISOString(),"stamp");return e.resources.register(ct,()=>({schemaVersion:1,revision:e.resources.revision(ct)??0,updatedAt:n(ct),activePageId:r.activePageId,tabs:[...r.tabs.values()],lastEventAt:r.lastEventAt,producer:r.lastEventAt===void 0?"none":"connected"})),e.resources.register(pt,()=>{let a=r.activePageId;return{schemaVersion:1,revision:e.resources.revision(pt)??0,updatedAt:n(pt),tab:a?r.tabs.get(a)??null:null,lastEventAt:r.lastEventAt,producer:r.lastEventAt===void 0?"none":"connected"}}),{unsubscribe:u,uris:[ct,pt]}}s(Z3,"Bg"),o(Z3,"installBrowserReducer");import{App as iB}from"@frontmcp/sdk";import{Resource as sB,ResourceContext as aB}from"@frontmcp/sdk";var Gd=class extends aB{static{s(this,"Zg")}static{o(this,"NestProvidersResource")}async execute(){return this.get(q).read("nest://providers")}};Gd=S([sB({name:"nest-providers",uri:"nest://providers",mimeType:"application/json",description:"All known NestJS singleton-instance generations (with lifecycle)."})],Gd);var oB=Gd;import{Resource as lB,ResourceContext as dB}from"@frontmcp/sdk";var Kd=class extends dB{static{s(this,"Vg")}static{o(this,"NestRequestsResource")}async execute(){return this.get(q).read("nest://requests/recent")}};Kd=S([lB({name:"nest-requests-recent",uri:"nest://requests/recent",mimeType:"application/json",description:"Last 50 NestJS server requests with status + duration."})],Kd);var cB=Kd,q3=class{static{s(this,"Jg")}static{o(this,"NestApp")}};q3=S([iB({id:"nest",name:"Nest",description:"NestJS providers, request lifecycle, singleton generations.",resources:[oB,cB]})],q3);var Yi="nest://providers",Qi="nest://requests/recent";function L3(e){let t={providers:new Map,recentRequests:[]},r=o(u=>{if(u.source!=="nestjs")return;let n=u.raw??null;if(n?.kind==="singleton-instance"&&n.provider){let a=n.provider;if(t.providers.delete(a.instanceId),t.providers.set(a.instanceId,{...a}),t.providers.size>500){for(let l of t.providers.keys())if(t.providers.delete(l),t.providers.size<=500)break}e.resources.markDirty(Yi);return}if(n?.kind==="server-request"&&n.request){let a={...n.request,fingerprint:u.fingerprint,id:u.id};t.recentRequests.push(a),t.recentRequests.length>50&&t.recentRequests.splice(0,t.recentRequests.length-50),e.resources.markDirty(Qi);return}},"handler"),i=e.bus.subscribe(r);return e.resources.register(Yi,()=>({schemaVersion:1,revision:e.resources.revision(Yi)??0,updatedAt:new Date().toISOString(),providers:[...t.providers.values()]})),e.resources.register(Qi,()=>({schemaVersion:1,revision:e.resources.revision(Qi)??0,updatedAt:new Date().toISOString(),requests:t.recentRequests.slice()})),{unsubscribe:i,uris:[Yi,Qi]}}s(L3,"Kg"),o(L3,"installNestReducer");import{App as pB}from"@frontmcp/sdk";import{Resource as mB,ResourceContext as fB}from"@frontmcp/sdk";var Hd=class extends fB{static{s(this,"Wg")}static{o(this,"TraceRecentResource")}async execute(){return this.get(q).read("trace://recent")}};Hd=S([mB({name:"trace-recent",uri:"trace://recent",mimeType:"application/json",description:"Last 100 trace spans (flattened)."})],Hd);var gB=Hd;import{Resource as hB,ResourceContext as vB}from"@frontmcp/sdk";var Xd=class extends vB{static{s(this,"Hg")}static{o(this,"TraceFailedResource")}async execute(){return this.get(q).read("trace://failed")}};Xd=S([hB({name:"trace-failed",uri:"trace://failed",mimeType:"application/json",description:"Trace spans that ended with status=error."})],Xd);var yB=Xd,J3=class{static{s(this,"Qg")}static{o(this,"TraceApp")}};J3=S([pB({id:"trace",name:"Trace",description:"Cross-process span timeline (Phase 3 \u2014 flat; Phase 7 promotes to multi-axis graph).",resources:[gB,yB]})],J3);var es="trace://recent",ts="trace://failed";function V3(e){let t={recent:[],failed:[]},r=o(u=>{let n=u.raw??null;if(!n||n.kind!=="span"||!n.span?.name)return;let a={id:u.id,traceId:n.span.traceId,parentSpanId:n.span.parentSpanId,flowId:n.span.flowId??u.context.flowId,requestId:n.span.requestId??u.context.requestId,name:n.span.name,source:u.source,startTime:n.span.startTime??u.timestamp,endTime:n.span.endTime,durationMs:n.span.durationMs,status:n.span.status??(u.severity==="error"?"error":"ok")};Yd(t.recent,a,100),a.status==="error"&&Yd(t.failed,a,50),e.resources.markDirty(es),a.status==="error"&&e.resources.markDirty(ts)},"handler"),i=e.bus.subscribe(r);return e.resources.register(es,()=>({schemaVersion:1,revision:e.resources.revision(es)??0,updatedAt:new Date().toISOString(),spans:t.recent.slice()})),e.resources.register(ts,()=>({schemaVersion:1,revision:e.resources.revision(ts)??0,updatedAt:new Date().toISOString(),spans:t.failed.slice()})),{unsubscribe:i,uris:[es,ts]}}s(V3,"eh"),o(V3,"installTraceReducer");function Yd(e,t,r){e.push(t),e.length>r&&e.splice(0,e.length-r)}s(Yd,"X$"),o(Yd,"pushBounded");import{App as EB}from"@frontmcp/sdk";import{Resource as bB,ResourceContext as DB}from"@frontmcp/sdk";var Qd=class extends DB{static{s(this,"th")}static{o(this,"PerfSlowRoutesResource")}async execute(){return this.get(q).read("perf://slow-routes")}};Qd=S([bB({name:"perf-slow-routes",uri:"perf://slow-routes",mimeType:"application/json",description:"Routes that are slow NOW (\u2265 threshold on their latest call, or repeatedly lately). A one-off spike is retracted once later calls prove the route recovered; worstEver keeps the history."})],Qd);var wB=Qd;import{Resource as $B,ResourceContext as BB}from"@frontmcp/sdk";var ec=class extends BB{static{s(this,"nh")}static{o(this,"PerfDuplicateRequestsResource")}async execute(){return this.get(q).read("perf://duplicate-requests")}};ec=S([$B({name:"perf-duplicate-requests",uri:"perf://duplicate-requests",mimeType:"application/json",description:"Endpoints one page called SEVERAL TIMES CONCURRENTLY \u2014 the missing-dedupe signal (a hook fetching outside the shared resource cache, multiplied by however many components mount it). Concurrency, not count: sequential repeats are a caching question and are not reported. The threshold sits above 2 so React StrictMode\u2019s double-invoke never fires it. Two consecutive clean loads retract a finding, so a fix clears it without a restart."})],ec);var CB=ec,W3=class{static{s(this,"ih")}static{o(this,"PerfApp")}};W3=S([EB({id:"perf",name:"Perf",description:"Performance signals: slow server routes, and endpoints one page calls concurrently (the missing-dedupe signal).",resources:[wB,CB]})],W3);var us="perf://slow-routes",rs=20,G3=2,xB=200;function K3(e){let t=Je(e.thresholds).slowRouteMs,r=(e.now??(()=>Date.now()))(),i={routes:new Map},u=o(d=>{let p=d.raw??null;if(p?.kind!=="server-request"||!p.request)return;let{method:c,route:g}=p.request,f=p.request.durationMs??0,m=`${c} ${g}`,h=i.routes.get(m);if(h||(h={method:c,route:g,recent:[],samples:0,slowSamples:0,lastDurationMs:f,lastSeenAt:d.timestamp,worstEverMs:0,worstEverAt:d.timestamp}),i.routes.delete(m),i.routes.set(m,h),h.recent.push(f),h.recent.length>rs&&h.recent.splice(0,h.recent.length-rs),h.samples+=1,f>=t&&(h.slowSamples+=1),h.lastDurationMs=f,h.lastSeenAt=d.timestamp,f>h.worstEverMs&&(h.worstEverMs=f,h.worstEverAt=d.timestamp),i.routes.size>xB){let E=i.routes.keys().next().value;E!==void 0&&i.routes.delete(E)}i.lastSampleAt=Math.max(i.lastSampleAt??0,d.timestamp),i.changedAt=d.timestamp,e.resources.markDirty(us)},"handler"),n=e.bus.subscribe(u),a=o(d=>d.recent.reduce((p,c)=>c>=t?p+1:p,0),"recentSlowCount"),l=o(d=>d.lastDurationMs>=t||a(d)>=G3,"currentlySlow");return e.resources.register(us,()=>{let d=[...i.routes.values()].filter(l);return{schemaVersion:1,revision:e.resources.revision(us)??0,updatedAt:new Date(i.changedAt??r).toISOString(),thresholdMs:t,routes:d.map(p=>({method:p.method,route:p.route,worstRecentMs:Math.max(...p.recent),lastDurationMs:p.lastDurationMs,lastSeenAt:p.lastSeenAt,samples:p.samples,slowSamples:p.slowSamples,recentSlowSamples:a(p),worstEverMs:p.worstEverMs,worstEverAt:p.worstEverAt})).sort((p,c)=>c.worstRecentMs-p.worstRecentMs),routesTracked:i.routes.size,recentSampleWindow:rs,minRecentSlowToKeep:G3,lastSampleAt:i.lastSampleAt,producer:i.lastSampleAt===void 0?"none":"connected",detail:i.lastSampleAt===void 0?"No server request has ever been observed \u2014 this is NOT evidence the backend is fast, nothing is watching. Run the backend under the dev cluster (or with @lensmcp/nest-instrumentation) so request timings reach this session.":`${i.routes.size} route${i.routes.size===1?"":"s"} observed; ${d.length} slow in the last ${rs} calls each (\u2265${t}ms).`}}),{unsubscribe:n,uris:[us]}}s(K3,"sh"),o(K3,"installPerfReducer");var ns="perf://duplicate-requests",tc=10,H3=2,kB=200,X3=300,AB=new Set(["t","_","cacheBust","ts"]);function Y3(e){try{let t=new URL(e,"http://lensmcp.invalid");for(let u of[...t.searchParams.keys()])AB.has(u)&&t.searchParams.delete(u);let r=t.searchParams.toString(),i=`${t.pathname}${r?`?${r}`:""}`;return t.host==="lensmcp.invalid"?i:`${t.origin}${i}`}catch{return e}}s(Y3,"ex"),o(Y3,"normalizeRequestUrl");function Q3(e){if(e.length===0)return 0;let t=[];for(let{start:u,end:n}of e)t.push({at:u,delta:1}),t.push({at:n+1,delta:-1});t.sort((u,n)=>u.at-n.at||u.delta-n.delta);let r=0,i=0;for(let{delta:u}of t)r+=u,r>i&&(i=r);return i}s(Q3,"tx"),o(Q3,"peakConcurrency");function e6(e){let t=Je(e.thresholds).duplicateRequestPeak,r=(e.now??(()=>Date.now()))(),i={endpoints:new Map},u=o(d=>{if(d.category!=="network")return;let p=d.raw??null;if(p?.kind!=="fetch-done"&&p?.kind!=="fetch-error"||!p.url||!p.method)return;let c=Y3(p.url),g=p.method.toUpperCase();if(typeof p.startedAt!="number")return;let f=p.startedAt,m=f+(typeof p.durationMs=="number"?p.durationMs:0),h=d.context?.originNodeId??null,E=d.context?.flowId??null,D=`${g} ${c} @ ${h??"-"}`,B=i.endpoints.get(D);if(B||(B={method:g,url:c,originNodeId:h,currentFlowId:E,currentIntervals:[],currentPeak:0,recentPeaks:[],totalRequests:0,lastSeenAt:d.timestamp,worstEverPeak:0,worstEverAt:d.timestamp}),i.endpoints.delete(D),i.endpoints.set(D,B),E!==B.currentFlowId&&(B.currentIntervals.length>0&&(B.recentPeaks.push(B.currentPeak),B.recentPeaks.length>tc&&B.recentPeaks.splice(0,B.recentPeaks.length-tc)),B.currentFlowId=E,B.currentIntervals=[],B.currentPeak=0),B.currentIntervals.push({start:f,end:m}),B.currentIntervals.length>X3&&B.currentIntervals.splice(0,B.currentIntervals.length-X3),B.currentPeak=Q3(B.currentIntervals),B.totalRequests+=1,B.lastSeenAt=d.timestamp,B.currentPeak>B.worstEverPeak&&(B.worstEverPeak=B.currentPeak,B.worstEverAt=d.timestamp),i.endpoints.size>kB){let A=i.endpoints.keys().next().value;A!==void 0&&i.endpoints.delete(A)}i.lastSampleAt=Math.max(i.lastSampleAt??0,d.timestamp),i.changedAt=d.timestamp,e.resources.markDirty(ns)},"handler"),n=e.bus.subscribe(u),a=o(d=>{let p=[...d.recentPeaks,...d.currentIntervals.length>0?[d.currentPeak]:[]],c=0;for(let g=p.length-1;g>=0&&!((p[g]??0)>=t);g-=1)c+=1;return c},"consecutiveCleanFlows"),l=o(d=>d.worstEverPeak>=t&&a(d)<H3,"currentlyDuplicated");return e.resources.register(ns,()=>{let d=[...i.endpoints.values()].filter(l);return{schemaVersion:1,revision:e.resources.revision(ns)??0,updatedAt:new Date(i.changedAt??r).toISOString(),peakThreshold:t,endpoints:d.map(p=>({method:p.method,url:p.url,originNodeId:p.originNodeId,peakConcurrent:p.currentPeak,cleanFlowsSince:a(p),flowsObserved:p.recentPeaks.length+(p.currentIntervals.length>0?1:0),totalRequests:p.totalRequests,worstEverPeak:p.worstEverPeak,worstEverAt:p.worstEverAt,lastSeenAt:p.lastSeenAt})).sort((p,c)=>c.peakConcurrent-p.peakConcurrent),endpointsTracked:i.endpoints.size,recentFlowWindow:tc,minCleanFlowsToRetract:H3,lastSampleAt:i.lastSampleAt,producer:i.lastSampleAt===void 0?"none":"connected",detail:i.lastSampleAt===void 0?"No browser fetch has ever been observed \u2014 this is NOT evidence the app fetches cleanly, nothing is watching. Load a page under the dev cluster so flow-fetch events reach this session.":d.length===0?`${i.endpoints.size} endpoint${i.endpoints.size===1?"":"s"} observed; none exceeded ${t} concurrent identical calls.`:`${d.length} endpoint${d.length===1?"":"s"} called \u2265${t}\xD7 concurrently \u2014 usually a hook fetching outside the shared resource cache, multiplied by however many components mount it.`}}),{unsubscribe:n,uris:[ns]}}s(e6,"ch"),o(e6,"installDuplicateRequestsReducer");import{App as _B}from"@frontmcp/sdk";import{Resource as IB,ResourceContext as SB}from"@frontmcp/sdk";var uc=class extends SB{static{s(this,"uh")}static{o(this,"DbSlowQueriesResource")}async execute(){return this.get(q).read("db://slow-queries")}};uc=S([IB({name:"db-slow-queries",uri:"db://slow-queries",mimeType:"application/json",description:"Query shapes (project\xB7op\xB7table) whose worst observed duration crosses the slowQueryMs threshold, aggregated live from the pg instrumentation. counts are an undercount for hot shapes (the emitter flood-guards per shape); suppressedEvents carries the drop count."})],uc);var FB=uc;import{Resource as zB,ResourceContext as jB}from"@frontmcp/sdk";var rc=class extends jB{static{s(this,"dh")}static{o(this,"DbAnalysisResource")}async execute(){return this.get(q).read("db://analysis")}};rc=S([zB({name:"db-analysis",uri:"db://analysis",mimeType:"application/json",description:"The latest DB analyzer run per project (missing indexes, seq-scan hot spots, unused indexes, migration-parity drift, slow statements) \u2014 ingested from the workspace analyzer's `db-analyze-run` events on the lens bus file."})],rc);var NB=rc,t6=class{static{s(this,"fh")}static{o(this,"DbApp")}};t6=S([_B({id:"db",name:"Db",description:"Database signals: slow query shapes observed live from the pg instrumentation, and the latest externally-ingested analyzer run (missing indexes, migration parity, unused indexes).",resources:[FB,NB]})],t6);var is="db://slow-queries",ss="db://analysis",u6=50,OB=20,RB=200;function r6(e){let t=e[jl];if(!t)return;let r=Array.isArray(t.paths)?t.paths:[];for(let i of r){let u=typeof i=="string"?/^findings\[\] \(\+(\d+) items dropped\)$/.exec(i):null;if(u)return Number(u[1])}return r.some(i=>typeof i=="string"&&i.startsWith("findings"))?0:void 0}s(r6,"pA"),o(r6,"findingsDroppedByClamp");function n6(e){let t=Je(e.thresholds).slowQueryMs,r=(e.now??(()=>Date.now()))(),i={shapes:new Map,analyzeRuns:new Map},u=o(l=>{let d=l.raw??null;if(d){if(d.kind==="db-query"){let p=d.project??"unknown",c=d.op??"query",g=d.table??"query",f=d.durationMs??0,m=`${p}|${c}|${g}`,h=i.shapes.get(m);if(h||(h={project:p,op:c,table:g,count:0,errorCount:0,totalMs:0,maxMs:0,maxAt:l.timestamp,recent:[],rowsTotal:0,lastSql:"",lastDurationMs:0,lastSeenAt:l.timestamp,suppressed:0}),i.shapes.delete(m),i.shapes.set(m,h),h.count+=1,d.error!==void 0&&(h.errorCount+=1),h.totalMs+=f,f>h.maxMs&&(h.maxMs=f,h.maxAt=l.timestamp),h.recent.push(f),h.recent.length>u6&&h.recent.splice(0,h.recent.length-u6),h.rowsTotal+=d.rows??0,d.query&&(h.lastSql=d.query),h.lastDurationMs=f,h.lastSeenAt=l.timestamp,h.suppressed+=d.floodSuppressed??0,i.shapes.size>RB){let E=i.shapes.keys().next().value;E!==void 0&&i.shapes.delete(E)}i.lastQueryAt=Math.max(i.lastQueryAt??0,l.timestamp),i.changedAt=l.timestamp,e.resources.markDirty(is);return}if(d.kind==="db-analyze-run"){let p=d.project??"unknown",c=r6(d);i.analyzeRuns.set(p,{project:p,runAt:d.runAt??l.timestamp,tool:d.tool??"unknown",findings:Array.isArray(d.findings)?d.findings:[],...c!==void 0?{droppedFindings:c}:{}}),St(i.analyzeRuns,xr),i.lastAnalyzeAt=Math.max(i.lastAnalyzeAt??0,l.timestamp),i.changedAt=l.timestamp,e.resources.markDirty(ss)}}},"handler"),n=e.bus.subscribe(u),a=o(l=>{if(l.length===0)return 0;let d=[...l].sort((p,c)=>p-c);return d[Math.min(d.length-1,Math.floor(d.length*.95))]??0},"p95");return e.resources.register(is,()=>{let l=[...i.shapes.values()].filter(d=>d.maxMs>=t);return{schemaVersion:1,revision:e.resources.revision(is)??0,updatedAt:new Date(i.changedAt??r).toISOString(),thresholdMs:t,queries:l.map(d=>({project:d.project,op:d.op,table:d.table,count:d.count,errorCount:d.errorCount,maxMs:d.maxMs,maxAt:d.maxAt,avgMs:Math.round(d.totalMs/Math.max(d.count,1)*10)/10,p95Ms:a(d.recent),rowsTotal:d.rowsTotal,lastDurationMs:d.lastDurationMs,lastSeenAt:d.lastSeenAt,lastSql:d.lastSql,suppressedEvents:d.suppressed})).sort((d,p)=>p.maxMs-d.maxMs).slice(0,OB),shapesTracked:i.shapes.size,note:"count/avg are an UNDERCOUNT for hot shapes: the emitter flood-guards each query-shape fingerprint at 30 burst / 5 events/s; suppressedEvents is the emitter's own count of dropped events.",lastSampleAt:i.lastQueryAt,producer:i.lastQueryAt===void 0?"none":"connected",detail:i.lastQueryAt===void 0?"No db-query event has ever been observed \u2014 this is NOT evidence queries are fast, nothing is watching. Run the backend under the dev cluster (the @lensmcp/cluster serve preload taps pg) so query timings reach this session.":`${i.shapes.size} query shape${i.shapes.size===1?"":"s"} observed; ${l.length} with a worst duration \u2265${t}ms.`}}),e.resources.register(ss,()=>{let l=[...i.analyzeRuns.values()].sort((D,B)=>B.runAt-D.runAt),d=l.flatMap(D=>D.findings),p=d.length,c=d.filter(D=>D.severity==="error").length,g=d.filter(D=>D.severity==="warning").length,f=p-c-g,m=l.filter(D=>D.droppedFindings!==void 0),h=m.reduce((D,B)=>D+(B.droppedFindings??0),0),E=m.length>0;return{schemaVersion:1,revision:e.resources.revision(ss)??0,updatedAt:new Date(i.changedAt??r).toISOString(),runs:l,findingCount:p,errorCount:c,warningCount:g,infoCount:f,...E?{incomplete:!0,droppedFindings:h}:{},lastSampleAt:i.lastAnalyzeAt,producer:i.lastAnalyzeAt===void 0?"none":"connected",detail:i.lastAnalyzeAt===void 0?"No db-analyze run has ever been ingested \u2014 this is NOT evidence the schema is healthy, nothing has analyzed it. Run the workspace's DB analyzer (it appends a `db-analyze-run` event to the lens bus file) to populate this.":`${l.length} analyze run${l.length===1?"":"s"} held (latest per project); ${p} finding${p===1?"":"s"} (${c} error, ${g} warning, ${f} info).`+(E?` INCOMPLETE: ${h>0?`${h} more findings were`:"part of a run was"} cut by the bus payload bound before reaching the lens (an event over 32 KiB keeps only the first 64 items of a list), and the cut takes whatever came last. The analyzer must keep one run under that bound, most severe first.`:"")}}),{unsubscribe:n,uris:[is,ss]}}s(n6,"mh"),o(n6,"installDbReducer");import{App as TB}from"@frontmcp/sdk";import{Resource as MB,ResourceContext as PB}from"@frontmcp/sdk";var nc=class extends PB{static{s(this,"gh")}static{o(this,"NetEgressHostsResource")}async execute(){return this.get(q).read("net://egress/hosts")}};nc=S([MB({name:"net-egress-hosts",uri:"net://egress/hosts",mimeType:"application/json",description:"External hosts this backend called (pod \u2192 third party), rolled up per project\xB7host with count, error/4xx/5xx counters, p95 and worst duration, plus the top endpoints under each. `slow` and `failing` are retracted by later healthy responses, so a one-off blip does not warn all day."})],nc);var UB=nc;import{Resource as ZB,ResourceContext as qB}from"@frontmcp/sdk";var ic=class extends qB{static{s(this,"vh")}static{o(this,"NetEgressRecentResource")}async execute(){return this.get(q).read("net://egress/recent")}};ic=S([ZB({name:"net-egress-recent",uri:"net://egress/recent",mimeType:"application/json",description:"The last 200 outbound calls with their RAW path and the flowId that caused them \u2014 the evidence behind net://egress/hosts. Query strings are never captured; treat this as the sensitive view, since a path segment can itself be a secret."})],ic);var LB=ic;import{Resource as JB,ResourceContext as VB}from"@frontmcp/sdk";var sc=class extends VB{static{s(this,"bh")}static{o(this,"NetEgressFailuresResource")}async execute(){return this.get(q).read("net://egress/failures")}};sc=S([JB({name:"net-egress-failures",uri:"net://egress/failures",mimeType:"application/json",description:"Outbound calls that failed \u2014 transport errors and any status \u2265 400 \u2014 kept in their own ring so a high-volume host cannot evict the one failure you need. Empty is NOT proof nothing failed: check `producer`."})],sc);var WB=sc,i6=class{static{s(this,"$h")}static{o(this,"NetApp")}};i6=S([TB({id:"net",name:"Net",description:"Outbound (egress) HTTP the backend makes to THIRD PARTIES \u2014 which external services, how often, how slow, and whether they failed. The server-side twin of runtime://browser/network. Internal service-to-service traffic is deliberately absent: the gateway already attributes it.",resources:[UB,LB,WB]})],i6);var as="net://egress/hosts",os="net://egress/recent",ls="net://egress/failures",Eu=20,GB=25,KB=200,HB=20,XB=5,s6=200,a6=50,o6=2;function l6(e){return e.length===0?!1:!!(/^\d{2,}$/.test(e)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)||/^[A-Z][A-Z0-9]*-\d+$/.test(e)||e.length>=16&&/^[A-Za-z0-9_-]+$/.test(e)&&/\d/.test(e))}s(l6,"kA"),o(l6,"isIdSegment");function d6(e){let[t="/"]=e.split("?"),r=t.split("/"),i=[];for(let n of r){if(i.length>12){i.push("\u2026");break}i.push(l6(n)?":id":n)}let u=i.join("/");return u.length===0?"/":u}s(d6,"sx"),o(d6,"templatisePath");function c6(e){let t=Je(e.thresholds).slowEgressMs,r=(e.now??(()=>Date.now()))(),i={hosts:new Map,recent:[],failures:[]},u=o(c=>{let g=c.raw??null;if(!g||g.kind!=="egress")return;let f=g.project??"unknown",m=g.host??"unknown",h=(g.method??"GET").toUpperCase(),E=g.durationMs??0,D=typeof g.status=="number"?g.status:void 0,B=g.error===void 0?void 0:String(g.error),A=B!==void 0||D!==void 0&&D>=400,I=g.path??"(path not captured \u2014 upgrade @lensmcp/node-instrumentation)",j=`${f}|${m}`,F=i.hosts.get(j);F||(F={project:f,host:m,count:0,errorCount:0,status4xx:0,status5xx:0,totalMs:0,maxMs:0,maxAt:c.timestamp,recent:[],outcomes:[],firstSeenAt:c.timestamp,lastSeenAt:c.timestamp,lastDurationMs:0,lastBad:!1,suppressed:0,endpoints:new Map}),i.hosts.delete(j),i.hosts.set(j,F),F.count+=1,B!==void 0&&(F.errorCount+=1),D!==void 0&&D>=400&&D<500&&(F.status4xx+=1),D!==void 0&&D>=500&&(F.status5xx+=1),F.totalMs+=E,E>F.maxMs&&(F.maxMs=E,F.maxAt=c.timestamp),F.recent.push(E),F.recent.length>Eu&&F.recent.splice(0,F.recent.length-Eu),F.outcomes.push(A),F.outcomes.length>Eu&&F.outcomes.splice(0,F.outcomes.length-Eu),F.lastDurationMs=E,F.lastBad=A,F.lastSeenAt=c.timestamp,F.suppressed+=g.floodSuppressed??0;let b=d6(I),w=`${h} ${b}`,C=F.endpoints.get(w);if(C||(C={method:h,path:b,count:0,errorCount:0,status4xx:0,status5xx:0,totalMs:0,maxMs:0,recent:[],lastDurationMs:0,lastSeenAt:c.timestamp}),F.endpoints.delete(w),F.endpoints.set(w,C),C.count+=1,B!==void 0&&(C.errorCount+=1,C.lastError=B),D!==void 0&&D>=400&&D<500&&(C.status4xx+=1),D!==void 0&&D>=500&&(C.status5xx+=1),C.totalMs+=E,E>C.maxMs&&(C.maxMs=E),C.recent.push(E),C.recent.length>Eu&&C.recent.splice(0,C.recent.length-Eu),C.lastStatus=D,C.lastDurationMs=E,C.lastSeenAt=c.timestamp,F.endpoints.size>HB){let te=F.endpoints.keys().next().value;te!==void 0&&F.endpoints.delete(te)}if(i.hosts.size>KB){let te=i.hosts.keys().next().value;te!==void 0&&i.hosts.delete(te)}let N=c.context??{},O={id:c.id,timestamp:c.timestamp,project:f,method:h,host:m,path:I,...D!==void 0?{status:D}:{},...B!==void 0?{error:B}:{},durationMs:E,...N.flowId?{flowId:N.flowId}:{},...N.requestId?{requestId:N.requestId}:{}};i.recent.push(O),i.recent.length>s6&&i.recent.splice(0,i.recent.length-s6),A&&(i.failures.push(O),i.failures.length>a6&&i.failures.splice(0,i.failures.length-a6),e.resources.markDirty(ls)),i.lastSampleAt=Math.max(i.lastSampleAt??0,c.timestamp),i.changedAt=c.timestamp,e.resources.markDirty(as),e.resources.markDirty(os)},"handler"),n=e.bus.subscribe(u),a=o(c=>{if(c.length===0)return 0;let g=[...c].sort((f,m)=>f-m);return g[Math.min(g.length-1,Math.floor(g.length*.95))]??0},"p95"),l=o(c=>c.lastDurationMs>=t||c.recent.filter(g=>g>=t).length>=o6,"isSlow"),d=o(c=>c.lastBad||c.outcomes.filter(Boolean).length>=o6,"isFailing"),p=o(c=>{let g=c.outcomes.filter(Boolean).length;return d(c)?`${g} of the last ${c.outcomes.length} call${c.outcomes.length===1?"":"s"} failed`:l(c)?`${c.recent.filter(f=>f>=t).length} of the last ${c.recent.length} call${c.recent.length===1?"":"s"} took \u2265${t}ms`:"healthy"},"describe");return e.resources.register(as,()=>{let c=[...i.hosts.values()],g=c.filter(d),f=c.filter(m=>!d(m)&&l(m));return{schemaVersion:1,revision:e.resources.revision(as)??0,updatedAt:new Date(i.changedAt??r).toISOString(),thresholdMs:t,hosts:c.map(m=>({project:m.project,host:m.host,count:m.count,errorCount:m.errorCount,status4xx:m.status4xx,status5xx:m.status5xx,avgMs:Math.round(m.totalMs/Math.max(m.count,1)*10)/10,p95Ms:a(m.recent),maxMs:m.maxMs,maxAt:m.maxAt,lastDurationMs:m.lastDurationMs,firstSeenAt:m.firstSeenAt,lastSeenAt:m.lastSeenAt,slow:l(m),failing:d(m),detail:p(m),suppressedEvents:m.suppressed,endpoints:[...m.endpoints.values()].map(h=>({method:h.method,path:h.path,count:h.count,errorCount:h.errorCount,status4xx:h.status4xx,status5xx:h.status5xx,avgMs:Math.round(h.totalMs/Math.max(h.count,1)*10)/10,p95Ms:a(h.recent),maxMs:h.maxMs,...h.lastStatus!==void 0?{lastStatus:h.lastStatus}:{},...h.lastError!==void 0?{lastError:h.lastError}:{},lastSeenAt:h.lastSeenAt})).sort((h,E)=>E.maxMs-h.maxMs).slice(0,XB)})).sort((m,h)=>m.failing!==h.failing?m.failing?-1:1:h.maxMs-m.maxMs).slice(0,GB),hostsTracked:i.hosts.size,failingHosts:g.length,slowHosts:f.length,note:"count/avg are an UNDERCOUNT for hot hosts: the emitter flood-guards each host fingerprint at 30 burst / 5 events/s; suppressedEvents is the emitter's own count of dropped events. Query strings are not captured; endpoint paths are templatised (\u2026/:id).",lastSampleAt:i.lastSampleAt,producer:i.lastSampleAt===void 0?"none":"connected",detail:i.lastSampleAt===void 0?"No egress event has ever been observed \u2014 this is NOT evidence the app makes no external calls, nothing is watching. Run the backend under the dev cluster (the @lensmcp/cluster serve preload taps fetch and http/https) so outbound calls reach this session. Internal destinations (*.local, loopback, RFC1918) are skipped by design \u2014 the gateway already attributes service-to-service traffic.":`${i.hosts.size} external host${i.hosts.size===1?"":"s"} observed; ${g.length} failing, ${f.length} slower than ${t}ms.`}}),e.resources.register(os,()=>({schemaVersion:1,revision:e.resources.revision(os)??0,updatedAt:new Date(i.changedAt??r).toISOString(),entries:[...i.recent],count:i.recent.length,note:"Raw paths, as requested. flowId joins an outbound call back to the click that caused it. Treat this as the sensitive view: a path segment can itself be a secret (a presigned key, a reset token), which the templatised rollup collapses but this does not.",lastSampleAt:i.lastSampleAt,producer:i.lastSampleAt===void 0?"none":"connected",detail:i.lastSampleAt===void 0?"No egress event has ever been observed \u2014 this is NOT evidence the app makes no external calls, nothing is watching.":`${i.recent.length} recent outbound call${i.recent.length===1?"":"s"}.`})),e.resources.register(ls,()=>({schemaVersion:1,revision:e.resources.revision(ls)??0,updatedAt:new Date(i.changedAt??r).toISOString(),entries:[...i.failures],count:i.failures.length,note:"A separate ring from net://egress/recent on purpose: a host called 200\xD7/min would otherwise evict the one 503 you need.",lastSampleAt:i.lastSampleAt,producer:i.lastSampleAt===void 0?"none":"connected",detail:i.lastSampleAt===void 0?"No egress event has ever been observed \u2014 an empty list here is NOT evidence that nothing failed, nothing is watching.":`${i.failures.length} failed outbound call${i.failures.length===1?"":"s"} held.`})),{unsubscribe:n,uris:[as,os,ls]}}s(c6,"xh"),o(c6,"installNetReducer");import{App as YB}from"@frontmcp/sdk";import{Resource as QB,ResourceContext as e2}from"@frontmcp/sdk";var ac=class extends e2{static{s(this,"_h")}static{o(this,"VisualCurrentResource")}async execute(){return this.get(q).read("visual://current")}};ac=S([QB({name:"visual-current",uri:"visual://current",mimeType:"application/json",description:"Most recent visual-frame (causedBy, changedNodes, stable)."})],ac);var t2=ac;import{Resource as u2,ResourceContext as r2}from"@frontmcp/sdk";var oc=class extends r2{static{s(this,"Sh")}static{o(this,"VisualViolationsCurrentResource")}async execute(){return this.get(q).read("visual://violations/current")}};oc=S([u2({name:"visual-violations-current",uri:"visual://violations/current",mimeType:"application/json",description:"Violations of the CURRENT frame, regardless of timing mode. Every rule re-runs per frame, so a fixed violation simply stops being reported."})],oc);var n2=oc;import{Resource as i2,ResourceContext as s2}from"@frontmcp/sdk";var lc=class extends s2{static{s(this,"Rh")}static{o(this,"VisualViolationsStableResource")}async execute(){return this.get(q).read("visual://violations/stable")}};lc=S([i2({name:"visual-violations-stable",uri:"visual://violations/stable",mimeType:"application/json",description:'Violations from rules with timing "after-animation" | "stable-only" | "always".'})],lc);var a2=lc;import{Resource as o2,ResourceContext as l2}from"@frontmcp/sdk";var dc=class extends l2{static{s(this,"Eh")}static{o(this,"VisualViolationsDuringAnimationResource")}async execute(){return this.get(q).read("visual://violations/during-animation")}};dc=S([o2({name:"visual-violations-during-animation",uri:"visual://violations/during-animation",mimeType:"application/json",description:"Violations seen on midpoint (during-animation) samples only."})],dc);var d2=dc;import{Resource as c2,ResourceContext as p2}from"@frontmcp/sdk";var cc=class extends p2{static{s(this,"zh")}static{o(this,"VisualRulesResource")}async execute(){return this.get(q).read("visual://rules")}};cc=S([c2({name:"visual-rules",uri:"visual://rules",mimeType:"application/json",description:"All registered visual rules (builtins + lensmcp.rules.json + visual.register_rule)."})],cc);var m2=cc;import{Resource as f2,ResourceContext as g2}from"@frontmcp/sdk";var pc=class extends g2{static{s(this,"Oh")}static{o(this,"VisualTokensResource")}async execute(){return this.get(q).read("visual://tokens")}};pc=S([f2({name:"visual-tokens",uri:"visual://tokens",mimeType:"application/json",description:"Resolved design tokens from lensmcp.tokens.json."})],pc);var h2=pc;import{Tool as v2,ToolContext as y2,z as p6}from"@frontmcp/sdk";import{existsSync as E2,mkdirSync as b2,readFileSync as D2,writeFileSync as w2}from"node:fs";import{dirname as $2,join as mc}from"node:path";function fc(e=process.env,t=process.cwd()){let r=e.LENSMCP_EVENT_FILE;return r?$2(r):mc(t,".lensmcp")}s(fc,"ta"),o(fc,"captureDir");function m6(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}s(m6,"BA"),o(m6,"pidAlive");function gc(e,t=m6){let r=mc(e,Bb);try{if(!E2(r))return;let i=JSON.parse(D2(r,"utf8"));return typeof i?.pid!="number"||!Number.isFinite(i.pid)?void 0:t(i.pid)?i:void 0}catch{return}}s(gc,"ra"),o(gc,"liveRunner");function f6(e,t){try{return b2(e,{recursive:!0}),w2(mc(e,$b),JSON.stringify(t)),!0}catch{return!1}}s(f6,"ax"),o(f6,"publishCaptureRequest");var hc;async function g6(e,t){let r=hc;if(r)return{fresh:await r.promise,coalesced:!0,requestId:r.requestId};let i=t().finally(()=>{hc=void 0});return hc={promise:i,requestId:e},{fresh:await i,coalesced:!1,requestId:e}}s(g6,"cx"),o(g6,"captureSingleFlight");async function h6(e){let t=e.now??(()=>Date.now()),r=e.sleep??(a=>new Promise(l=>setTimeout(l,a))),i=e.budgetMs??8e3,u=e.pollMs??100,n=t()+i;for(;t()<n;){await r(u);let a=await e.readFrameId();if(a!==void 0&&a!==e.before)return!0}return!1}s(h6,"ux"),o(h6,"waitForFreshFrame");var vc=class extends y2{static{s(this,"Mh")}static{o(this,"VisualCaptureFrameTool")}async execute(e){let t=this.get(zl),r=this.get(q),i=o(async()=>(await r.read("visual://current"))?.frame?.id,"readFrameId"),u=await i(),n=qt(),a=Date.now();t.publish({id:qt(),sessionId:"visual.capture_frame",timestamp:a,source:"visual",category:"visual",severity:"info",context:{sessionId:"visual.capture_frame"},fingerprint:`visual-capture-request:${e.cause}`,title:`visual.capture_frame(${e.cause})`,raw:{kind:"visual-capture-request",cause:e.cause,stable:e.stable,requestId:n}});let l=fc(),d=gc(l),p=!1,c=await g6(n,async()=>(p=f6(l,{requestedAt:a,cause:e.cause,stable:e.stable,requestId:n}),p&&d?await h6({readFrameId:i,before:u}):!1));return{requested:c.coalesced?!0:p,cause:e.cause,stable:e.stable,fresh:c.fresh,coalesced:c.coalesced,requestId:c.requestId,waitedMs:Date.now()-a,runner:d?{pid:d.pid,url:d.url}:void 0,latest:await r.read("visual://current")}}};vc=S([v2({name:"visual.capture_frame",description:"Capture a fresh visual frame. Signals the host capture runner (which launches a headless browser on demand), waits for the new frame, and returns it. Frames are captured per request \u2014 no browser is held open between calls.",inputSchema:{cause:p6.enum(["page-load","route-change","user-action","react-commit","state-update","api-response","hmr-update","animation-tick"]).default("user-action").describe("Hint why this frame is being requested."),stable:p6.boolean().default(!0).describe("Whether to treat the captured frame as the stable final state.")}})],vc);var B2=vc;import{Tool as C2,ToolContext as x2,z as k2}from"@frontmcp/sdk";var yc=class extends x2{static{s(this,"Uh")}static{o(this,"VisualInspectNodeTool")}async execute(e){let t=await this.get(q).read("visual://current");if(!t.frame)return{found:!1,uid:e.uid};let r=t.frame.changedNodes.filter(i=>i.uid===e.uid);return{found:r.length>0,uid:e.uid,frameId:t.frame.id,changes:r}}};yc=S([C2({name:"visual.inspect_node",description:"Returns the changedNodes entry for `uid` from visual://current \u2014 the per-property before/after used to compute the latest frame.",inputSchema:{uid:k2.string().describe('Node uid as it appeared in visual://current.changedNodes (e.g. "hero-card" or "bid:42").')}})],yc);var A2=yc;import{Tool as _2,ToolContext as I2,z as S2}from"@frontmcp/sdk";var Ec=class extends I2{static{s(this,"Fh")}static{o(this,"VisualCompareFramesTool")}async execute(e){let t=await this.get(q).read("visual://current");return t.frame?e.frameId&&e.frameId!==t.frame.id?{found:!1,reason:"Only the latest frame is retained in Phase 4."}:{found:!0,frameId:t.frame.id,causedBy:t.frame.causedBy,changedCount:t.frame.changedNodes.length,appeared:t.frame.appearedNodes.length,disappeared:t.frame.disappearedNodes.length,changedNodes:t.frame.changedNodes.slice(0,50)}:{found:!1}}};Ec=S([_2({name:"visual.compare_frames",description:"Summarises the last visual-frame. Phase 4 ships a single-frame view (Phase 6 adds story-relative deltas).",inputSchema:{frameId:S2.string().optional().describe("Optional frame id; defaults to the latest.")}})],Ec);var F2=Ec;import{Tool as z2,ToolContext as j2,z as N2}from"@frontmcp/sdk";var bc=class extends j2{static{s(this,"Zh")}static{o(this,"VisualExplainViolationTool")}async execute(e){let t=(await this.get(q).read("visual://violations/current")).violations.find(r=>r.id===e.violationId);return t?{found:!0,violation:t,explanation:v6(t)}:{found:!1,violationId:e.violationId}}};bc=S([z2({name:"visual.explain_violation",description:"Returns the full violation record (rule id + expected/actual + evidence.cssCause / trace / screenshot crop URIs) for a given violationId.",inputSchema:{violationId:N2.string().describe("Id of the violation as seen in visual://violations/current.")}})],bc);var O2=bc;function v6(e){let t=[`Rule ${e.ruleId} (${e.ruleType}) at ${e.element.component??e.element.uid}.`,`Expected: ${JSON.stringify(e.expected)}`,`Actual: ${JSON.stringify(e.actual)}`];return e.evidence.cssCause&&t.push(`CSS cause: ${e.evidence.cssCause.selector} { ${e.evidence.cssCause.declaration??"?"} }`+(e.evidence.cssCause.file?` @ ${e.evidence.cssCause.file}:${e.evidence.cssCause.line??"?"}`:"")),e.evidence.trace&&t.push(`Trace: ${e.evidence.trace}`),e.evidence.screenshotCrop&&t.push(`Crop: ${e.evidence.screenshotCrop}`),t.join(`
|
|
70
70
|
`)}s(v6,"ez"),o(v6,"buildExplanation");import{Tool as R2,ToolContext as T2,z as Fe}from"@frontmcp/sdk";import{mkdirSync as M2,readFileSync as P2,renameSync as U2,writeFileSync as Z2}from"node:fs";import{join as q2}from"node:path";var L2=500;function y6(e){try{return process.kill(e,0),!0}catch(t){return t.code==="EPERM"}}s(y6,"az"),o(y6,"pidAlive");function E6(e){try{let t=JSON.parse(P2(e,"utf8"));return Array.isArray(t?.rules)?t.rules:[]}catch{return[]}}s(E6,"cz"),o(E6,"readEntries");function b6(e,t,r={}){let i=r.pid??process.pid,u=r.isAlive??y6,n=q2(e,Cb),a=[...E6(n).filter(d=>typeof d?.registeredBy=="number"&&typeof d?.rule?.id=="string"&&d.rule.id!==t.id&&(d.registeredBy===i||u(d.registeredBy))),{rule:t,registeredBy:i,registeredAt:(r.now??Date.now)()}].slice(-L2);M2(e,{recursive:!0});let l=`${n}.${i}.tmp`;return Z2(l,JSON.stringify({schemaVersion:1,rules:a})),U2(l,n),a}s(b6,"dx"),o(b6,"registerSessionRule");var Dc=class extends T2{static{s(this,"Vh")}static{o(this,"VisualRegisterRuleTool")}async execute(e){let t=this.get(zl),r=this.get(q),i={id:e.id,type:e.type,target:e.target,severity:e.severity,timing:e.timing,expected:e.expected,breakpoints:e.breakpoints};t.publish({id:qt(),sessionId:"visual.register_rule",timestamp:Date.now(),source:"visual",category:"visual",severity:"info",context:{sessionId:"visual.register_rule"},fingerprint:`visual-rule-registered:${e.id}`,title:`visual.register_rule(${e.id})`,raw:{kind:"visual-rule-registered",rule:i}});let u=fc(),n=!1,a;try{b6(u,i),n=gc(u)!==void 0,a=n?"The capture runner evaluates this rule on the next captured frame (visual.capture_frame).":"No capture runner is listening, so nothing will evaluate this rule until one starts (the dev cluster gateway or agent-dev). It is listed, not enforced."}catch(l){a=`Could not hand the rule to the capture runner (${l.message}). It is listed, but will NOT be evaluated.`}return{registered:!0,evaluated:n,note:a,rule:{id:e.id,type:e.type,target:e.target},rules:await r.read("visual://rules")}}};Dc=S([R2({name:"visual.register_rule",description:"Register (or replace) a visual rule. It is handed to the capture runner, which evaluates it on every frame captured from now on, for as long as this lens server runs. The result says whether a runner is listening; if `evaluated` is false the rule is only listed, and no violation can come of it.",inputSchema:{id:Fe.string().describe("Stable rule id; replaces a prior rule with the same id."),type:Fe.enum(["grid-spacing","alignment","overflow","text-clipping","color-contrast","token-usage","z-index","responsive","custom"]).describe("Built-in rule type to evaluate."),target:Fe.string().optional().describe('CSS-like selector / role:label / [data-agent-component="\u2026"]; default = every node.'),severity:Fe.enum(["info","warning","error"]).default("warning"),timing:Fe.enum(["always","after-animation","stable-only","during-animation"]).default("always"),expected:Fe.record(Fe.string(),Fe.unknown()).default({}).describe('Rule-type-specific expectations (e.g. { gap: "spacing.6" }).'),breakpoints:Fe.record(Fe.string(),Fe.record(Fe.string(),Fe.unknown())).optional().describe("Per-breakpoint expectation overrides for the responsive rule type.")}})],Dc);var J2=Dc,D6=class{static{s(this,"Jh")}static{o(this,"VisualApp")}};D6=S([YB({id:"visual",name:"Visual",description:"Visual rule engine: DOMSnapshot/LayerTree diffs, grid/alignment/overflow/contrast/z-index rules, design tokens.",resources:[t2,n2,a2,d2,m2,h2],tools:[B2,A2,F2,O2,J2]})],D6);var Or="visual://current",Rr="visual://violations/current",Tr="visual://violations/stable",Mr="visual://violations/during-animation",Pr="visual://rules",Ur="visual://tokens";function w6(e){let t=(e.now??(()=>Date.now()))(),r={violations:[],rules:[],framesSeen:0,changedAt:new Map},i=o((f,m)=>{r.changedAt.set(f,m),e.resources.markDirty(f)},"touch"),u=o(f=>{i(Rr,f),i(Tr,f),i(Mr,f)},"touchViolationViews"),n=o(f=>{let m=f.raw??null;if(m?.kind)switch(m.kind){case"visual-frame":{let h=m.frame;if(!h)return;r.currentFrame=h,r.lastFrameAt=f.timestamp,r.framesSeen+=1,r.rulesEvaluated=typeof m.rulesEvaluated=="number"?m.rulesEvaluated:void 0,i(Or,f.timestamp);let E=r.violations.length;r.violations=r.violations.filter(D=>D.frameId===h.id),E!==r.violations.length&&u(f.timestamp);return}case"visual-violation":if(!m.violation)return;r.violations.push(m.violation),r.violations.length>50&&r.violations.splice(0,r.violations.length-50),u(f.timestamp);return;case"visual-rule-registered":{let h=m.rule;if(!h)return;let E=r.rules.findIndex(D=>D.id===h.id);E>=0&&r.rules.splice(E,1),r.rules.push(h),r.rules.length>500&&r.rules.splice(0,r.rules.length-500),i(Pr,f.timestamp);return}case"visual-tokens-loaded":if(!m.tokens)return;r.tokens=m.tokens,i(Ur,f.timestamp);return;default:return}},"handler"),a=e.bus.subscribe(n),l=o(f=>new Date(r.changedAt.get(f)??t).toISOString(),"stamp"),d="No visual frame has ever been captured \u2014 an empty violation list is NOT evidence the UI is correct, nothing is looking. Drive a capture (visual_capture_frame) or run the browser-capture loop so frames reach this session.",p=o(()=>`${r.framesSeen} frame${r.framesSeen===1?"":"s"} captured`,"frameCount"),c=o(()=>({framesSeen:r.framesSeen,lastFrameAt:r.lastFrameAt,currentFrameId:r.currentFrame?.id,...r.rulesEvaluated!==void 0?{rulesEvaluated:r.rulesEvaluated}:{},producer:r.framesSeen===0?"none":"connected",detail:r.framesSeen===0?d:r.rulesEvaluated===void 0?`${p()}; ${r.rules.length} rule${r.rules.length===1?"":"s"} registered.`:`${p()}; ${r.rulesEvaluated} rule${r.rulesEvaluated===1?"":"s"} evaluated on the current one.`}),"frameHealth"),g=o(()=>{let f=c();return r.framesSeen===0||r.rulesEvaluated===void 0?r.framesSeen===0?f:{...f,detail:`${f.detail} Violations are those of the CURRENT frame \u2014 every rule is re-run per frame, so anything fixed simply stops being reported.`}:r.rulesEvaluated===0?{...f,producer:"none",detail:`${p()}, but NO rule was evaluated on the current one \u2014 an empty violation list is NOT evidence the UI is correct, nothing is being checked. Add rules to \`lensmcp.rules.json\` at the workspace root, or register one with visual.register_rule.`}:{...f,detail:`${f.detail} Violations are those of the CURRENT frame \u2014 every rule is re-run per frame, so anything fixed simply stops being reported.`}},"violationHealth");return e.resources.register(Or,()=>({schemaVersion:1,revision:e.resources.revision(Or)??0,updatedAt:l(Or),frame:r.currentFrame??null,...c()})),e.resources.register(Rr,()=>({schemaVersion:1,revision:e.resources.revision(Rr)??0,updatedAt:l(Rr),violations:r.violations.slice(),...g()})),e.resources.register(Tr,()=>({schemaVersion:1,revision:e.resources.revision(Tr)??0,updatedAt:l(Tr),violations:r.violations.filter(f=>f.timing==="after-animation"||f.timing==="stable-only"||f.timing==="always"),...g()})),e.resources.register(Mr,()=>({schemaVersion:1,revision:e.resources.revision(Mr)??0,updatedAt:l(Mr),violations:r.violations.filter(f=>f.timing==="during-animation"),...g()})),e.resources.register(Pr,()=>({schemaVersion:1,revision:e.resources.revision(Pr)??0,updatedAt:l(Pr),rules:r.rules.slice()})),e.resources.register(Ur,()=>({schemaVersion:1,revision:e.resources.revision(Ur)??0,updatedAt:l(Ur),tokens:r.tokens??null})),{unsubscribe:a,uris:[Or,Rr,Tr,Mr,Pr,Ur]}}s(w6,"Kh"),o(w6,"installVisualReducer");import{App as V2}from"@frontmcp/sdk";import{Resource as W2,ResourceContext as G2}from"@frontmcp/sdk";var wc=class extends G2{static{s(this,"Wh")}static{o(this,"ReactPagesCurrentResource")}async execute(){return this.get(q).read("react://pages/current")}};wc=S([W2({name:"react-pages-current",uri:"react://pages/current",mimeType:"application/json",description:"The most recently active React page (from <LensmcpRoot>)."})],wc);var K2=wc;import{Resource as H2,ResourceContext as X2}from"@frontmcp/sdk";var $c=class extends X2{static{s(this,"Hh")}static{o(this,"ReactComponentsHotResource")}async execute(){return this.get(q).read("react://components/hot")}};$c=S([H2({name:"react-components-hot",uri:"react://components/hot",mimeType:"application/json",description:"Components ranked by render count this session."})],$c);var Y2=$c;import{Resource as Q2,ResourceContext as eC}from"@frontmcp/sdk";var Bc=class extends eC{static{s(this,"Qh")}static{o(this,"ReactRendersSlowResource")}async execute(){return this.get(q).read("react://renders/slow")}};Bc=S([Q2({name:"react-renders-slow",uri:"react://renders/slow",mimeType:"application/json",description:"Renders with actualDurationMs >= threshold (default 16ms)."})],Bc);var tC=Bc;import{Resource as uC,ResourceContext as rC}from"@frontmcp/sdk";var Cc=class extends rC{static{s(this,"tv")}static{o(this,"ReactRendersRecentResource")}async execute(){return this.get(q).read("react://renders/recent")}};Cc=S([uC({name:"react-renders-recent",uri:"react://renders/recent",mimeType:"application/json",description:"Last 100 render commits with attribution (why)."})],Cc);var nC=Cc;import{Resource as iC,ResourceContext as sC}from"@frontmcp/sdk";var xc=class extends sC{static{s(this,"nv")}static{o(this,"ReactEffectsRecentResource")}async execute(){return this.get(q).read("react://effects/recent")}};xc=S([iC({name:"react-effects-recent",uri:"react://effects/recent",mimeType:"application/json",description:"Last 100 useEffect runs/cleanups from tracedUseEffect."})],xc);var aC=xc;import{Resource as oC,ResourceContext as lC}from"@frontmcp/sdk";var kc=class extends lC{static{s(this,"iv")}static{o(this,"ReactMemosRecomputedResource")}async execute(){return this.get(q).read("react://memos/recomputed")}};kc=S([oC({name:"react-memos-recomputed",uri:"react://memos/recomputed",mimeType:"application/json",description:"Recent useMemo recomputations (depsHash changed)."})],kc);var dC=kc;import{Resource as cC,ResourceContext as pC}from"@frontmcp/sdk";var Ac=class extends pC{static{s(this,"av")}static{o(this,"ReactHooksRecentResource")}async execute(){return this.get(q).read("react://hooks/recent")}};Ac=S([cC({name:"react-hooks-recent",uri:"react://hooks/recent",mimeType:"application/json",description:"Recent hook-run events (useMemo / useCallback)."})],Ac);var mC=Ac;import{Tool as fC,ToolContext as gC,z as _c}from"@frontmcp/sdk";var Ic=class extends gC{static{s(this,"lv")}static{o(this,"GraphExplainRerenderTool")}async execute(e){let t=await this.get(q).read("react://renders/recent"),r;if(e.renderNodeId)r=t.renders.find(u=>u.id===e.renderNodeId);else if(e.componentInstanceId)for(let u=t.renders.length-1;u>=0;u--){let n=t.renders[u];if(n&&n.componentInstanceId===e.componentInstanceId){r=n;break}}else if(e.componentLogicalId)for(let u=t.renders.length-1;u>=0;u--){let n=t.renders[u];if(n&&n.componentLogicalId===e.componentLogicalId){r=n;break}}if(!r)return{found:!1,searched:e};let i=(r.why??[]).map(u=>({...u,summary:$6(u)}));return{found:!0,renderNodeId:r.id,componentInstanceId:r.componentInstanceId,componentLogicalId:r.componentLogicalId,componentName:r.componentName,page:r.page,route:r.route,phase:r.phase,actualDurationMs:r.actualDurationMs,why:i,parentRenderId:r.parentRenderId}}};Ic=S([fC({name:"graph.explain_rerender",description:"Returns the most recent render record for a component (by `renderNodeId`, `componentInstanceId`, or `componentLogicalId`), with its `why` causal list (valtio-path / parent-render / hook-dep-changed / props / context / react-state / force).",inputSchema:{renderNodeId:_c.string().optional().describe("Exact render commit id from react://renders/recent."),componentInstanceId:_c.string().optional().describe("Component instance id; resolves to that instance\u2019s last render."),componentLogicalId:_c.string().optional().describe("Component logical id (e.g. react:component:src/App.tsx:CardGrid); resolves to its most recent render across HMR generations.")}})],Ic);var hC=Ic;function $6(e){switch(e.type){case"valtio-path":return`valtio path ${String(e.path)} changed (${e.changedKeys?.join(",")??""})`;case"react-state":return`useState hook #${String(e.hookIndex)} changed`;case"context":return`context ${String(e.contextName)} changed`;case"props":return`prop(s) changed: ${e.changedKeys?.join(",")??""}`;case"parent-render":return`parent render ${String(e.parentRenderId)} triggered this`;case"hook-dep-changed":return`hook ${String(e.hookInstanceId)} deps changed`;case"force":return`forced render: ${String(e.reason)}`;default:return`unknown cause: ${JSON.stringify(e)}`}}s($6,"Tz"),o($6,"summariseWhy");var B6=class{static{s(this,"pv")}static{o(this,"ReactApp")}};B6=S([V2({id:"react",name:"React",description:"React render attribution: pages, hot components, slow renders, hook + effect + memo events. Hosts graph.explain_rerender.",resources:[K2,Y2,tC,nC,aC,dC,mC],tools:[hC]})],B6);var Zr="react://pages/current",ds="react://components/hot",cs="react://renders/slow",ps="react://renders/recent",ms="react://effects/recent",fs="react://memos/recomputed",gs="react://hooks/recent",hs=100,Sc=50,C6=500;function x6(e){let t=Je(e.thresholds).slowRenderMs,r={rendersRecent:[],rendersSlow:[],effectsRecent:[],hooksRecent:[],memosRecomputed:[],rendersByInstance:new Map,hotByLogical:new Map},i=o(n=>{if(n.source!=="react")return;let a=n.raw??null;if(a?.kind)switch(a.kind){case"render":{let l=a.render;if(!l)return;if(bu(r.rendersRecent,l,hs),r.rendersByInstance.delete(l.componentInstanceId),r.rendersByInstance.set(l.componentInstanceId,l),r.rendersByInstance.size>C6){for(let p of r.rendersByInstance.keys())if(r.rendersByInstance.delete(p),r.rendersByInstance.size<=C6)break}l.actualDurationMs>=t&&(bu(r.rendersSlow,l,Sc),r.rendersSlow.sort((p,c)=>c.actualDurationMs-p.actualDurationMs),r.rendersSlow.length>Sc&&(r.rendersSlow.length=Sc));let d=r.hotByLogical.get(l.componentLogicalId);d?(d.renderCount+=1,d.totalActualMs+=l.actualDurationMs,d.lastRenderId=l.id):r.hotByLogical.set(l.componentLogicalId,{componentLogicalId:l.componentLogicalId,componentName:l.componentName,renderCount:1,totalActualMs:l.actualDurationMs,lastRenderId:l.id}),(l.page||l.route)&&(r.currentPage={page:l.page??"(unknown)",route:l.route,updatedAt:n.timestamp},e.resources.markDirty(Zr)),e.resources.markDirty(ps),e.resources.markDirty(ds),l.actualDurationMs>=t&&e.resources.markDirty(cs);return}case"effect-run":{let l=a.effect;if(!l)return;bu(r.effectsRecent,l,hs),e.resources.markDirty(ms);return}case"hook-run":{let l=a.hook;if(!l)return;bu(r.hooksRecent,l,hs),e.resources.markDirty(gs),l.recomputed&&l.hookType==="useMemo"&&(bu(r.memosRecomputed,l,hs),e.resources.markDirty(fs));return}case"component-mount":case"component-unmount":{let l=a.component;if(!l)return;(l.page||l.route)&&(r.currentPage={page:l.page??"(unknown)",route:l.route,updatedAt:n.timestamp},e.resources.markDirty(Zr));return}default:return}},"handler"),u=e.bus.subscribe(i);return e.resources.register(Zr,()=>({schemaVersion:1,revision:e.resources.revision(Zr)??0,updatedAt:new Date().toISOString(),page:r.currentPage??null})),e.resources.register(ds,()=>({schemaVersion:1,revision:e.resources.revision(ds)??0,updatedAt:new Date().toISOString(),components:[...r.hotByLogical.values()].sort((n,a)=>a.renderCount-n.renderCount)})),e.resources.register(cs,()=>({schemaVersion:1,revision:e.resources.revision(cs)??0,updatedAt:new Date().toISOString(),thresholdMs:t,renders:r.rendersSlow.slice()})),e.resources.register(ps,()=>({schemaVersion:1,revision:e.resources.revision(ps)??0,updatedAt:new Date().toISOString(),renders:r.rendersRecent.slice()})),e.resources.register(ms,()=>({schemaVersion:1,revision:e.resources.revision(ms)??0,updatedAt:new Date().toISOString(),effects:r.effectsRecent.slice()})),e.resources.register(fs,()=>({schemaVersion:1,revision:e.resources.revision(fs)??0,updatedAt:new Date().toISOString(),memos:r.memosRecomputed.slice()})),e.resources.register(gs,()=>({schemaVersion:1,revision:e.resources.revision(gs)??0,updatedAt:new Date().toISOString(),hooks:r.hooksRecent.slice()})),{unsubscribe:u,uris:[Zr,ds,cs,ps,ms,fs,gs],lookups:{latestRenderFor(n){return r.rendersByInstance.get(n)},latestRenderForLogical(n){if(r.hotByLogical.get(n))for(let a=r.rendersRecent.length-1;a>=0;a--){let l=r.rendersRecent[a];if(l&&l.componentLogicalId===n)return l}}}}}s(x6,"mv"),o(x6,"installReactReducer");function bu(e,t,r){e.push(t),e.length>r&&e.splice(0,e.length-r)}s(bu,"mo"),o(bu,"pushBounded");import{App as vC}from"@frontmcp/sdk";import{Resource as yC,ResourceContext as EC}from"@frontmcp/sdk";var Fc=class extends EC{static{s(this,"gv")}static{o(this,"ValtioUpdatesRecentResource")}async execute(){return this.get(q).read("valtio://updates/recent")}};Fc=S([yC({name:"valtio-updates-recent",uri:"valtio://updates/recent",mimeType:"application/json",description:"Last 100 Valtio state-update events with path + changedKeys + subscribers."})],Fc);var bC=Fc;import{Resource as DC,ResourceContext as wC}from"@frontmcp/sdk";var zc=class extends wC{static{s(this,"vv")}static{o(this,"ValtioStoresResource")}async execute(){return this.get(q).read("valtio://stores")}};zc=S([DC({name:"valtio-stores",uri:"valtio://stores",mimeType:"application/json",description:"Registered Valtio stores (created via lensmcp-wrapped proxy())."})],zc);var $C=zc;import{Resource as BC,ResourceContext as CC}from"@frontmcp/sdk";var jc=class extends CC{static{s(this,"bv")}static{o(this,"ValtioSubscribersResource")}async execute(){return this.get(q).read("valtio://subscribers")}};jc=S([BC({name:"valtio-subscribers",uri:"valtio://subscribers",mimeType:"application/json",description:"Per-(storeId, path) list of component instance ids currently subscribed via tracked useSnapshot."})],jc);var xC=jc,k6=class{static{s(this,"$v")}static{o(this,"ValtioApp")}};k6=S([vC({id:"valtio",name:"Valtio",description:"Valtio store + subscription tracking. Phase 5 ships updates/stores/subscribers; per-path subscriber walks land via graph.explain_rerender.",resources:[bC,$C,xC]})],k6);var vs="valtio://updates/recent",ys="valtio://stores",qr="valtio://subscribers",A6=100,_6=1e3,kC=1e3,AC=256,_C=256;function I6(e,t){if(e.size<=t)return;let r=e.values();for(;e.size>t;){let i=r.next();if(i.done)break;e.delete(i.value)}}s(I6,"Lz"),o(I6,"capSet");function Nc(e){let t=Array.isArray(e.paths)?e.paths.filter(r=>typeof r=="string"):void 0;return t&&t.length>0?t.slice(0,AC):typeof e.path=="string"?[e.path]:[]}s(Nc,"gx"),o(Nc,"subscriptionPaths");function Oc(e){return e.componentLogicalId??e.componentInstanceId??"react:component:anonymous"}s(Oc,"hx"),o(Oc,"subscriberId");function S6(e){let t={updates:[],stores:new Map,subscribers:new Map,latestUpdateByPath:new Map},r=o(u=>{if(u.source!=="valtio")return;let n=u.raw??null;if(n?.kind)switch(n.kind){case"state-update":{let a=n.update;if(!a)return;let l={...a,emittedAt:u.timestamp};t.updates.push(l),t.updates.length>A6&&t.updates.splice(0,t.updates.length-A6);let d=`${a.storeId}::${a.path}`;if(t.latestUpdateByPath.delete(d),t.latestUpdateByPath.set(d,l),t.latestUpdateByPath.size>_6){for(let p of t.latestUpdateByPath.keys())if(t.latestUpdateByPath.delete(p),t.latestUpdateByPath.size<=_6)break}e.resources.markDirty(vs);return}case"store-created":{let a=n.store;if(!a)return;t.stores.set(a.storeId,{...a,createdAt:u.timestamp}),e.resources.markDirty(ys);return}case"subscription-added":{let a=n.subscription;if(!a||!a.componentInstanceId)return;let l=Oc(a);for(let d of Nc(a)){let p=`${a.storeId}::${d}`,c=t.subscribers.get(p);c||(c=new Map,t.subscribers.set(p,c));let g=c.get(l);g||(g=new Set,c.set(l,g)),g.add(a.componentInstanceId),St(c,xr),I6(g,_C)}St(t.subscribers,kC),e.resources.markDirty(qr);return}case"subscription-removed":{let a=n.subscription;if(!a||!a.componentInstanceId)return;let l=Oc(a);for(let d of Nc(a)){let p=`${a.storeId}::${d}`,c=t.subscribers.get(p);if(!c)continue;let g=c.get(l);g&&(g.delete(a.componentInstanceId),g.size===0&&c.delete(l)),c.size===0&&t.subscribers.delete(p)}e.resources.markDirty(qr);return}default:return}},"handler"),i=e.bus.subscribe(r);return e.resources.register(vs,()=>({schemaVersion:1,revision:e.resources.revision(vs)??0,updatedAt:new Date().toISOString(),updates:t.updates.slice()})),e.resources.register(ys,()=>({schemaVersion:1,revision:e.resources.revision(ys)??0,updatedAt:new Date().toISOString(),stores:[...t.stores.values()]})),e.resources.register(qr,()=>({schemaVersion:1,revision:e.resources.revision(qr)??0,updatedAt:new Date().toISOString(),subscriptions:[...t.subscribers.entries()].map(([u,n])=>{let[a,l]=u.split("::");return{storeId:a,path:l,componentInstanceIds:[...n.keys()]}})})),{unsubscribe:i,uris:[vs,ys,qr],lookups:{latestUpdateForPath(u,n){return t.latestUpdateByPath.get(`${u}::${n}`)},subscribersFor(u,n){return[...t.subscribers.get(`${u}::${n}`)?.keys()??[]]}}}}s(S6,"xv"),o(S6,"installValtioReducer");import{App as IC}from"@frontmcp/sdk";import{Resource as SC,ResourceContext as FC}from"@frontmcp/sdk";var Rc=class extends FC{static{s(this,"_v")}static{o(this,"GraphPatternsResource")}async execute(){return this.get(q).read("graph://patterns")}};Rc=S([SC({name:"graph-patterns",uri:"graph://patterns",mimeType:"application/json",description:"Recent detected anti-patterns (db-in-loop, n+1-query, render-storm)."})],Rc);var zC=Rc;import{Resource as jC,ResourceContext as NC}from"@frontmcp/sdk";var Tc=class extends NC{static{s(this,"Sv")}static{o(this,"GraphEventLoopLagResource")}async execute(){return this.get(q).read("graph://performance/event-loop-lag")}};Tc=S([jC({name:"graph-event-loop-lag",uri:"graph://performance/event-loop-lag",mimeType:"application/json",description:"Recent event-loop-lag samples + the max lag seen."})],Tc);var OC=Tc;import{Tool as RC,ToolContext as TC,z as MC}from"@frontmcp/sdk";var F6;function Mc(e){F6=e}s(Mc,"pa"),o(Mc,"setActiveGraphBuffer");function Lr(){return F6?.events??[]}s(Lr,"It"),o(Lr,"currentEvents");function Nt(){let e=new Vp;return h1(e,Lr()),e}s(Nt,"Ce"),o(Nt,"buildGraph");var Pc=class extends TC{static{s(this,"Rv")}static{o(this,"GraphGetNodeTool")}async execute(e){let t=Nt().getNode(e.nodeId);return t?{found:!0,node:t}:{found:!1,nodeId:e.nodeId}}};Pc=S([RC({name:"graph.get_node",description:"Returns a single graph node by id (built from the current event window).",inputSchema:{nodeId:MC.string().describe("Node id (usually the originating event id).")}})],Pc);var PC=Pc;import{Tool as UC,ToolContext as ZC,z as Du}from"@frontmcp/sdk";var qC=["ownership","caused","async","data","render","state","network","backend","db","visual","performance","memory","lifecycle"],Uc=class extends ZC{static{s(this,"Ev")}static{o(this,"GraphTraverseTool")}async execute(e){let t=Nt().traverse({from:e.from,lens:e.lens,depth:e.depth,direction:e.direction,maxNodes:e.maxNodes});return{nodeCount:t.nodes.length,edgeCount:t.edges.length,nodes:t.nodes.map(r=>({id:r.id,type:r.type,name:r.name,durationMs:r.durationMs,flowId:r.context.flowId})),edges:t.edges.map(r=>({from:r.from,to:r.to,axis:r.axis,type:r.type}))}}};Uc=S([UC({name:"graph.traverse",description:'Walk the multi-axis trace graph from a node along one or more edge axes (the "lens"). Bounded by depth + node count.',inputSchema:{from:Du.string().describe("Start node id."),lens:Du.array(Du.enum(qC)).min(1).describe('Edge axes to follow (e.g. ["caused","backend"]).'),depth:Du.number().int().positive().max(12).default(4),direction:Du.enum(["out","in","both"]).default("both"),maxNodes:Du.number().int().positive().max(1e3).default(200)}})],Uc);var LC=Uc;import{Tool as JC,ToolContext as VC,z as WC}from"@frontmcp/sdk";var Zc=class extends VC{static{s(this,"zv")}static{o(this,"GraphFindDbInLoopTool")}async execute(e){let t=Jl(Lr(),{threshold:e.threshold});return{count:t.length,matches:t}}};Zc=S([JC({name:"graph.find_db_in_loop",description:"Scan the current event window for loops that issued more than `threshold` DB calls (N+1-ish backend anti-pattern).",inputSchema:{threshold:WC.number().int().positive().default(5)}})],Zc);var GC=Zc;import{Tool as KC,ToolContext as HC,z as XC}from"@frontmcp/sdk";var qc=class extends HC{static{s(this,"Ov")}static{o(this,"GraphFindSlowPathTool")}async execute(e){let t=Nt(),r=new Map,i=Lr(),u=e.from?[e.from]:i.filter(l=>l.context.originNodeId===void 0&&l.context.flowId).map(l=>l.id);for(let l of i){let d=t.traverse({from:l.id,lens:["caused","async","backend"],depth:1,direction:"out",maxNodes:50});r.set(l.id,d.edges.filter(p=>p.from===l.id).map(p=>p.to))}let n=o(l=>t.getNode(l)?.durationMs??0,"durationOf"),a=m1(u.length?u:i.map(l=>l.id),r,n);return{totalDurationMs:a.totalDurationMs,path:a.path.map(l=>{let d=t.getNode(l);return{id:l,name:d?.name,type:d?.type,durationMs:d?.durationMs}})}}};qc=S([KC({name:"graph.find_slow_path",description:"Find the slowest cumulative chain on the caused/async/backend axes starting from a node (or every flow origin if `from` is omitted).",inputSchema:{from:XC.string().optional().describe("Start node id; defaults to all flow origins.")}})],qc);var YC=qc;import{Tool as QC,ToolContext as ex,z as z6}from"@frontmcp/sdk";var Lc=class extends ex{static{s(this,"Pv")}static{o(this,"GraphTraceFromOriginTool")}async execute(e){let t=Nt(),r=e.originNodeId;if(!t.getNode(r)){let n=Lr().find(a=>a.context.originNodeId===e.originNodeId||a.raw?.origin?.nodeId===e.originNodeId);n&&(r=n.id)}let i=t.getNode(r);if(!i)return{found:!1,originNodeId:e.originNodeId};let u=t.traverse({from:r,lens:["caused","render","state","backend","async"],depth:e.depth,direction:"out",maxNodes:500});return{found:!0,origin:{id:r,name:i.name,type:i.type},nodeCount:u.nodes.length,nodes:u.nodes.map(n=>({id:n.id,type:n.type,name:n.name,durationMs:n.durationMs}))}}};Lc=S([QC({name:"graph.trace_from_origin",description:'Given an origin node id (e.g. a data-agent-component value or an event id), returns every node reachable on the caused/render/state/backend axes \u2014 "what did this cause?".',inputSchema:{originNodeId:z6.string().describe("Origin node id, logicalId, or originating event id."),depth:z6.number().int().positive().max(12).default(6)}})],Lc);var tx=Lc;import{Tool as ux,ToolContext as rx,z as j6}from"@frontmcp/sdk";var Jc=class extends rx{static{s(this,"Mv")}static{o(this,"GraphFindStateUpdatesCausedByTool")}async execute(e){let t=Nt();if(!t.getNode(e.from))return{found:!1,from:e.from};let r=t.traverse({from:e.from,lens:["caused","state"],depth:e.depth,direction:"out",maxNodes:500}).nodes.filter(i=>i.type==="state-update");return{found:!0,count:r.length,stateUpdates:r.map(i=>({id:i.id,name:i.name,logicalId:i.logicalId}))}}};Jc=S([ux({name:"graph.find_state_updates_caused_by",description:'From an origin node, returns the state-update nodes reachable on the caused/state axes \u2014 "what state changed because of this?".',inputSchema:{from:j6.string().describe("Origin node id."),depth:j6.number().int().positive().max(12).default(6)}})],Jc);var nx=Jc;import{Tool as ix,ToolContext as sx,z as N6}from"@frontmcp/sdk";var Vc=class extends sx{static{s(this,"Uv")}static{o(this,"GraphFindBackendWorkCausedByClickTool")}async execute(e){let t=Nt();if(!t.getNode(e.from))return{found:!1,from:e.from};let r=t.traverse({from:e.from,lens:["caused","backend","async"],depth:e.depth,direction:"out",maxNodes:500}).nodes.filter(i=>i.type==="server-request");return{found:!0,count:r.length,requests:r.map(i=>({id:i.id,name:i.name,durationMs:i.durationMs}))}}};Vc=S([ix({name:"graph.find_backend_work_caused_by_click",description:'From a UI origin node, returns the server-request nodes reachable on the caused/backend/async axes \u2014 "what backend work did this click trigger?".',inputSchema:{from:N6.string().describe("UI origin node id (e.g. the user-action event id)."),depth:N6.number().int().positive().max(12).default(8)}})],Vc);var ax=Vc,O6=class{static{s(this,"Fv")}static{o(this,"GraphApp")}};O6=S([IC({id:"graph",name:"Graph",description:"Multi-axis causal graph: traverse by lens, trace from origin, find slow paths + db-in-loop / n+1 / render-storm patterns.",resources:[zC,OC],tools:[PC,LC,GC,YC,tx,nx,ax]})],O6);var wu="graph://patterns",$u="graph://performance/event-loop-lag",Wc=2e3,R6=8*1024*1024,ox=100,T6=100;function M6(e){let t=Je(e.thresholds),r=(e.now??(()=>Date.now()))(),i={events:[]},u=[],n=0,a=0,l=0,d=new Set,p=[],c=new Map,g,f=new Map,m=o(j=>{switch(j.kind){case"n+1-query":return`n+1:${String(j.details.signature??"")}`;case"render-storm":return`storm:${String(j.details.componentInstanceId??"")}`;case"db-in-loop":return`dbloop:${j.evidence[0]??""}`;default:return`${j.kind}:${j.evidence.join(",")}`}},"patternKey"),h=o(j=>{c.set(wu,j),e.resources.markDirty(wu)},"markPatterns"),E=o((j,F)=>{let b=m(j);if(f.delete(b),f.set(b,j),f.size>ox){let w=f.keys().next().value;w!==void 0&&f.delete(w)}h(F)},"pushPattern"),D=o(j=>{let F=!1;for(let[b,w]of f){if(w.evidence.length===0)continue;let C=w.evidence.filter(N=>d.has(N));if(C.length===0){f.delete(b),F=!0;continue}C.length!==w.evidence.length&&(w.evidence=C,F=!0)}F&&h(j)},"dropUnevidencedPatterns"),B=o(j=>{g=j.timestamp;let F=ki(j);i.events.push(j),u.push(F),n+=F,d.add(j.id);let b=Math.max(0,i.events.length-Wc),w=n;for(let O=0;O<b;O+=1)w-=u[O]??0;let C=0;for(;w>R6&&b<u.length;)w-=u[b]??0,b+=1,C+=1;if(b>0){let O=i.events.splice(0,b);u.splice(0,b),n=Math.max(0,w),a+=O.length,l+=C;for(let te of O)d.delete(te.id);D(j.timestamp)}let N=j.raw??null;if(N?.kind==="loop")for(let O of Jl(i.events,{threshold:t.dbInLoop}))E(O,j.timestamp);if(N?.kind==="db-query")for(let O of c1(i.events,{threshold:t.nPlusOne}))E(O,j.timestamp);if(j.source==="react"&&N?.kind==="render")for(let O of p1(i.events,{threshold:t.renderStorm}))E(O,j.timestamp);j.source==="perf"&&N?.kind==="event-loop-lag"&&typeof N.lagMs=="number"&&(p.push({at:j.timestamp,lagMs:N.lagMs,source:j.source}),p.length>T6&&p.splice(0,p.length-T6),c.set($u,j.timestamp),e.resources.markDirty($u))},"handler"),A=e.bus.subscribe(B);Mc(i);let I=o(j=>new Date(c.get(j)??r).toISOString(),"stamp");return e.resources.register(wu,()=>({schemaVersion:1,revision:e.resources.revision(wu)??0,updatedAt:I(wu),patterns:[...f.values()],eventsBuffered:i.events.length,eventBufferCapacity:Wc,lastEventAt:g,producer:g===void 0?"none":"connected"})),e.resources.register($u,()=>({schemaVersion:1,revision:e.resources.revision($u)??0,updatedAt:I($u),samples:p.slice(),maxLagMs:p.reduce((j,F)=>Math.max(j,F.lagMs),0),lastEventAt:g})),{unsubscribe:o(()=>{Mc(void 0),A()},"unsubscribe"),uris:[wu,$u],retentionStats:o(()=>({residentEvents:i.events.length,residentBytes:n,evictedEvents:a,evictedForBytes:l,eventCap:Wc,byteCap:R6}),"retentionStats")}}s(M6,"Zv"),o(M6,"installGraphReducer");import{App as lx}from"@frontmcp/sdk";import{Resource as dx,ResourceContext as cx}from"@frontmcp/sdk";var Gc=class extends cx{static{s(this,"qv")}static{o(this,"MemoryCurrentResource")}async execute(){return this.get(q).read("memory://current")}};Gc=S([dx({name:"memory-current",uri:"memory://current",mimeType:"application/json",description:"Last process-memory sample (heapUsed / rss)."})],Gc);var px=Gc;import{Resource as mx,ResourceContext as fx}from"@frontmcp/sdk";var Kc=class extends fx{static{s(this,"Gv")}static{o(this,"MemoryOwnersResource")}async execute(){return this.get(q).read("memory://owners")}};Kc=S([mx({name:"memory-owners",uri:"memory://owners",mimeType:"application/json",description:"All tracked container owners with current item count + byte estimate."})],Kc);var gx=Kc;import{Resource as hx,ResourceContext as vx}from"@frontmcp/sdk";var Hc=class extends vx{static{s(this,"Kv")}static{o(this,"MemoryOwnersGrowingResource")}async execute(){return this.get(q).read("memory://owners/growing")}};Hc=S([hx({name:"memory-owners-growing",uri:"memory://owners/growing",mimeType:"application/json",description:"Top 20 container owners by growth-since-start."})],Hc);var yx=Hc;import{Resource as Ex,ResourceContext as bx}from"@frontmcp/sdk";var Xc=class extends bx{static{s(this,"Xv")}static{o(this,"MemoryLeaksSuspectedResource")}async execute(){return this.get(q).read("memory://leaks/suspected")}};Xc=S([Ex({name:"memory-leaks-suspected",uri:"memory://leaks/suspected",mimeType:"application/json",description:"Suspected leaks: per-flow retentions + stale-generation singletons."})],Xc);var Dx=Xc;import{Tool as wx,ToolContext as $x,z as Bx}from"@frontmcp/sdk";var P6;function Yc(e){P6=e}s(Yc,"fa"),o(Yc,"setActiveMemoryLookups");function Es(){return P6}s(Es,"Gt"),o(Es,"activeMemoryLookups");var Qc=class extends $x{static{s(this,"Yv")}static{o(this,"MemoryFindGrowthByFlowTool")}async execute(e){let t=Es();if(!t)return{found:!1,reason:"no active memory reducer"};let r=t.growthByFlow(e.flowId);return{found:!0,flowId:e.flowId,owners:r}}};Qc=S([wx({name:"memory.find_growth_by_flow",description:'Returns the container owners mutated during a flow and how much each grew \u2014 "what did this flow allocate?".',inputSchema:{flowId:Bx.string().describe("Flow id.")}})],Qc);var Cx=Qc;import{Tool as xx,ToolContext as kx,z as Ax}from"@frontmcp/sdk";var ep=class extends kx{static{s(this,"ey")}static{o(this,"MemoryFindFlowsThatMutatedOwnerTool")}async execute(e){let t=Es();if(!t)return{found:!1,reason:"no active memory reducer"};let r=t.flowsThatMutatedOwner(e.ownerId);return{found:!0,ownerId:e.ownerId,flowIds:r}}};ep=S([xx({name:"memory.find_flows_that_mutated_owner",description:"Returns the flow ids that mutated a given container owner.",inputSchema:{ownerId:Ax.string().describe("Owner id (<ownerInstanceId>::<fieldName>).")}})],ep);var _x=ep;import{Tool as Ix,ToolContext as Sx,z as Fx}from"@frontmcp/sdk";var tp=class extends Sx{static{s(this,"ry")}static{o(this,"MemoryExplainLeakTool")}async execute(e){let t=Es();if(!t)return{found:!1,reason:"no active memory reducer"};let r=t.getLeak(e.leakIndex);if(!r)return{found:!1,leakIndex:e.leakIndex};let i,u;if(r.kind==="retention"){let n=r.detail;i=`Owner ${n.ownerId} grew by ${n.growth} items during flow ${n.flowId} and did not shrink after the flow settled.`,u="Add a TTL / max-size eviction policy to this container, or clear it when the owning scope is disposed. If it is a request-scoped cache, move it off the singleton."}else{let n=r.detail;i=`Disposed singleton ${n.logicalId} (generation ${n.generation}) still retains ${n.retainedBytes} bytes \u2014 a stale generation kept alive after HMR/reload.`,u="Ensure listeners/timers registered by the old instance are removed in the dispose hook (OnModuleDestroy / cleanup), so the previous generation can be garbage-collected."}return{found:!0,leak:r,narrative:i,recommendation:u}}};tp=S([Ix({name:"memory.explain_leak",description:"Returns a narrative explanation of a suspected leak (by index in memory://leaks/suspected): which owner, which flow, what grew, and a remediation hint.",inputSchema:{leakIndex:Fx.number().int().nonnegative().describe("Index into memory://leaks/suspected.")}})],tp);var zx=tp,U6=class{static{s(this,"oy")}static{o(this,"MemoryApp")}};U6=S([lx({id:"memory",name:"Memory",description:"Container-owner growth tracking + suspect-leak / stale-generation detection. Hosts memory.explain_leak.",resources:[px,gx,yx,Dx],tools:[Cx,_x,zx]})],U6);var Jr="memory://current",Vr="memory://owners",Wr="memory://owners/growing",Ot="memory://leaks/suspected",jx=200,Z6=50,Nx=500;function q6(e){let t=(e.now??(()=>Date.now()))(),r={owners:new Map,leaks:new Map,changedAt:new Map},i=o((E,D)=>{r.changedAt.set(E,D),e.resources.markDirty(E)},"touch"),u=o((E,D)=>{if(r.leaks.delete(E),r.leaks.set(E,D),r.leaks.size>jx){let B=r.leaks.keys().next().value;B!==void 0&&r.leaks.delete(B)}},"pushLeak"),n=new Map,a=o((E,D)=>{E!==D&&(n.delete(E),n.set(E,D),n.size>5e3&&n.delete(n.keys().next().value))},"noteRequestFlow"),l=o((E,D)=>{if(E.flowIds.add(D),E.flowIds.size>Z6){for(let B of E.flowIds)if(E.flowIds.delete(B),E.flowIds.size<=Z6)break}},"noteFlow"),d=o((E,D,B)=>{let A=r.owners.get(E);if(A||(A={ownerId:E,itemCount:D,estimatedBytes:0,startCount:D,mutations:0,flowIds:new Set,lastMutatedAt:B}),r.owners.delete(E),r.owners.set(E,A),r.owners.size>Nx){let I=r.owners.keys().next().value;I!==void 0&&I!==E&&r.owners.delete(I)}return A},"ensure"),p=o((E,D)=>{let B=!1;for(let[A,I]of r.leaks){if(I.kind!=="retention"||I.ownerId!==E)continue;let j=I.detail.startCount;typeof j=="number"&&D<=j&&(r.leaks.delete(A),B=!0)}return B},"retractReleasedRetentions"),c=o(E=>{if(E.source!=="memory"&&E.source!=="perf")return;let D=E.raw??null;if(D?.kind)switch(r.lastEventAt=Math.max(r.lastEventAt??0,E.timestamp),D.kind){case"memory-mutation":{if(!D.mutation)return;let B=D.mutation,A=d(B.ownerNodeId,B.beforeCount??B.afterCount,E.timestamp);A.itemCount=B.afterCount,A.estimatedBytes=B.afterCount*64,A.mutations+=1,A.lastMutatedAt=E.timestamp,E.context.flowId&&l(A,E.context.flowId),E.context.requestId&&E.context.flowId&&a(E.context.requestId,E.context.flowId),i(Vr,E.timestamp),i(Wr,E.timestamp),p(B.ownerNodeId,B.afterCount)&&i(Ot,E.timestamp);return}case"memory-retention":{if(!D.retention)return;let B=D.retention,A=B.requestId?B.flowId:n.get(B.flowId)??B.flowId;u(`retention:${B.ownerId}:${A}`,{kind:"retention",ownerId:B.ownerId,flowId:A,detail:{...B,flowId:A},at:E.timestamp}),i(Ot,E.timestamp);return}case"singleton-stale-generation":{if(!D.staleGeneration)return;let B=D.staleGeneration;u(`stale:${B.logicalId}:${B.generation}`,{kind:"stale-generation",logicalId:B.logicalId,detail:{...B},at:E.timestamp}),i(Ot,E.timestamp);return}case"process-memory":{if(!D.memory)return;r.current={...D.role?{role:D.role}:{},heapUsed:D.memory.heapUsed,heapTotal:D.memory.heapTotal,rss:D.memory.rss,external:D.memory.external,arrayBuffers:D.memory.arrayBuffers,at:E.timestamp},i(Jr,E.timestamp);return}default:return}},"handler"),g=e.bus.subscribe(c),f=o(E=>new Date(r.changedAt.get(E)??t).toISOString(),"stamp"),m=o(()=>({lastEventAt:r.lastEventAt,ownersTracked:r.owners.size,producer:r.lastEventAt===void 0?"none":"connected",detail:r.lastEventAt===void 0?"No memory event has ever been observed \u2014 an empty leak list is NOT evidence there is no leak, nothing is watching. Run under the dev cluster with @lensmcp/memory-tracker wired.":`${r.owners.size} owner${r.owners.size===1?"":"s"} tracked; ${r.leaks.size} suspected leak${r.leaks.size===1?"":"s"}.`}),"health");e.resources.register(Jr,()=>({schemaVersion:1,revision:e.resources.revision(Jr)??0,updatedAt:f(Jr),current:r.current??null})),e.resources.register(Vr,()=>({schemaVersion:1,revision:e.resources.revision(Vr)??0,updatedAt:f(Vr),owners:[...r.owners.values()].map(up),...m()})),e.resources.register(Wr,()=>({schemaVersion:1,revision:e.resources.revision(Wr)??0,updatedAt:f(Wr),owners:[...r.owners.values()].map(up).filter(E=>E.growthSinceStart>0).sort((E,D)=>D.growthSinceStart-E.growthSinceStart).slice(0,20),...m()})),e.resources.register(Ot,()=>({schemaVersion:1,revision:e.resources.revision(Ot)??0,updatedAt:f(Ot),suspected:[...r.leaks.values()],...m()}));let h={ownersMutatedByFlow(E){return[...r.owners.values()].filter(D=>D.flowIds.has(E))},growthByFlow(E){return[...r.owners.values()].filter(D=>D.flowIds.has(E)).map(D=>({ownerId:D.ownerId,growth:D.itemCount-D.startCount}))},flowsThatMutatedOwner(E){let D=r.owners.get(E);return D?[...D.flowIds]:[]},getLeak(E){return[...r.leaks.values()][E]},allLeaks(){return[...r.leaks.values()]}};return Yc(h),{unsubscribe:o(()=>{Yc(void 0),g()},"unsubscribe"),uris:[Jr,Vr,Wr,Ot],lookups:h}}s(q6,"iy"),o(q6,"installMemoryReducer");function up(e){return{ownerId:e.ownerId,itemCount:e.itemCount,estimatedBytes:e.estimatedBytes,mutations:e.mutations,startCount:e.startCount,growthSinceStart:e.itemCount-e.startCount,lastMutatedAt:e.lastMutatedAt,flowIds:[...e.flowIds]}}s(up,"Sx"),o(up,"toOwnerView");function L6(){let{session:e,providers:t}=D1(),r=_1(),i=I1();for(let E of i.problems)console.error(`[lensmcp] nx.json lensmcp.flows: ${E}`);D3({bus:e.bus,resources:e.resources}),B3({bus:e.bus,resources:e.resources}),k3({bus:e.bus,resources:e.resources}),I3({bus:e.bus,resources:e.resources}),j3({bus:e.bus,resources:e.resources}),Z3({bus:e.bus,resources:e.resources}),L3({bus:e.bus,resources:e.resources}),V3({bus:e.bus,resources:e.resources}),K3({bus:e.bus,resources:e.resources,thresholds:r}),e6({bus:e.bus,resources:e.resources,thresholds:r}),n6({bus:e.bus,resources:e.resources,thresholds:r}),c6({bus:e.bus,resources:e.resources,thresholds:r}),w6({bus:e.bus,resources:e.resources}),x6({bus:e.bus,resources:e.resources,thresholds:r}),S6({bus:e.bus,resources:e.resources});let u=d3({bus:e.bus,resources:e.resources,flows:i});e.registerReducerRetention("flow",u.retentionStats),p3({resources:e.resources});let n=M6({bus:e.bus,resources:e.resources,thresholds:r});e.registerReducerRetention("graph",n.retentionStats),q6({bus:e.bus,resources:e.resources}),K1({bus:e.bus,resources:e.resources,sessionId:e.id});let a=3e4,l=512*1024*1024,d=0,p=o(()=>{let E=process.memoryUsage(),D=Date.now(),B=E.rss>=l;B&&D-d>=5*6e4&&(d=D,console.warn(`[lensmcp] high process memory: rss=${Math.round(E.rss/1024/1024)}MB heap=${Math.round(E.heapUsed/1024/1024)}MB`)),e.bus.publish({id:qt(),sessionId:e.id,timestamp:D,source:"perf",category:"runtime",severity:B?"warning":"info",context:{sessionId:e.id},fingerprint:Gp({kind:"process-memory",identity:process.env.LENSMCP_PROCESS_ROLE??"session"}),title:`LensMCP process memory (${process.env.LENSMCP_PROCESS_ROLE??"session"})`,raw:{kind:"process-memory",role:process.env.LENSMCP_PROCESS_ROLE??"session",memory:{rss:E.rss,heapUsed:E.heapUsed,heapTotal:E.heapTotal,external:E.external,arrayBuffers:E.arrayBuffers}}})},"publishProcessMemory");p();let c=setInterval(p,a);c.unref?.(),e.onShutdown({name:"process-memory",stop:o(()=>clearInterval(c),"stop")});let g=1200,f=new Map,m=e.bus.subscribe(E=>{let D=E.context.flowId;if(!D)return;let B=f.get(D);B&&clearTimeout(B);let A=setTimeout(()=>{f.delete(D);try{let I=Ve()?.getFlowEvents(D);if(!I||I.length===0)return;let j=Is(I,{flowId:D});j&&wd(j)}catch{}},g);A.unref?.(),f.set(D,A)});e.onShutdown({name:"story-autocompile",stop:o(()=>{m();for(let E of f.values())clearTimeout(E);f.clear()},"stop")});let h=k1({bus:e.bus,sessionId:e.id,onError:o(E=>console.error("[lensmcp] ingest error:",E),"onError")});return h.mode!=="none"&&console.error(`[lensmcp] event ingest active (mode=${h.mode})`),e.onShutdown({name:"event-ingest",stop:o(()=>h.stop(),"stop")}),{session:e,providers:t,ingest:h,flows:i}}s(L6,"Ix"),o(L6,"createLensSession");var Ox=new Set(["localhost","127.0.0.1","lensmcp.local"]);function J6(e){if(!e)return!1;let t=e.trim().toLowerCase();if(t.startsWith("[")){let r=t.indexOf("]");return r!==-1&&t.slice(1,r)==="::1"}return t.indexOf(":")===t.lastIndexOf(":")&&(t=t.split(":")[0]??""),Ox.has(t)}s(J6,"jj"),o(J6,"hostHeaderIsLocal");function V6(e,t){if(!e||J6(t))return{ok:!0};let r=(t??"").replace(/[^\x20-\x7e]/g,"?").slice(0,80);return{ok:!1,status:403,error:"this dashboard answers only requests addressed to this machine (localhost, 127.0.0.1, [::1] or lensmcp.local)"+(r?`; this one was addressed to "${r}"`:"")}}s(V6,"Rx"),o(V6,"dashboardHostVerdict");import{randomBytes as Rx,timingSafeEqual as Tx}from"node:crypto";import{chmodSync as Mx,mkdirSync as Px,readFileSync as Ux,writeFileSync as Zx}from"node:fs";import{dirname as qx,join as Lx}from"node:path";var rp="__lensmcp_token";function np(e){return Lx(e,".lensmcp","dashboard-token")}s(np,"sy"),o(np,"dashboardTokenPath");function W6(e,t,r,i={}){if(r)return{source:"loopback"};if(e.LENSMCP_ALLOW_INSECURE==="1")return{source:"disabled"};let u=e.LENSMCP_DASHBOARD_TOKEN?.trim();if(u)return{token:u,source:"env"};let n=i.read??(c=>Ux(c,"utf8")),a=i.write??((c,g)=>Zx(c,g,{mode:384})),l=i.ensureDir??(c=>{Px(c,{recursive:!0,mode:448})}),d=i.chmod??((c,g)=>Mx(c,g)),p=np(t);try{let c=n(p).trim();if(c){try{d(p,384)}catch{}return{token:c,source:"file"}}}catch{}try{l(qx(p));let c=Rx(32).toString("hex");a(p,`${c}
|
|
71
71
|
`);try{d(p,384)}catch{}return{token:c,source:"created"}}catch(c){return{source:"unavailable",reason:c instanceof Error?c.message:String(c)}}}s(W6,"Ex"),o(W6,"resolveDashboardToken");function ip(e,t){let r=Buffer.from(e,"utf8"),i=Buffer.from(t,"utf8");return r.length!==i.length?!1:Tx(r,i)}s(ip,"Tx"),o(ip,"sameSecret");function G6(e,t,r){if(!e)return!0;let i=Array.isArray(t)?t[0]:t,u=/^Bearer\s+(.+)$/i.exec((i??"").trim())?.[1]?.trim();if(u&&ip(u,e))return!0;let n=r?.trim();return!!n&&ip(n,e)}s(G6,"Ax"),o(G6,"dashboardAuthorized");function K6(e){return e==="/api"||e.startsWith("/api/")}s(K6,"zx"),o(K6,"isDataEndpoint");function H6(e){let t=Number(process.env.LENSMCP_PARENT_PID??0);!Number.isInteger(t)||t<=0||setInterval(()=>{process.ppid!==t&&(console.error(`[lensmcp] ${e}: parent gateway (pid ${t}) is gone \u2014 exiting to free the port.`),process.exit(0))},5e3).unref()}s(H6,"jx"),o(H6,"watchParentGateway");import{closeSync as Jx,openSync as Vx,readSync as Wx,statSync as Gx}from"node:fs";function X6(e,t,r){let i=Gx(e).size;if(i===0)return[];let u=Math.max(0,i-t),n=Buffer.alloc(i-u),a=Vx(e,"r");try{Wx(a,n,0,n.length,u)}finally{Jx(a)}let l=n.toString("utf8").trim().split(`
|
|
72
72
|
`);return u>0&&l.shift(),l.slice(-r)}s(X6,"Ox"),o(X6,"readEventTailLines");import{execFileSync as Kx}from"node:child_process";import{createHash as Hx}from"node:crypto";import{readdirSync as Y6,readFileSync as bs}from"node:fs";import{homedir as Xx}from"node:os";var Q6=new Set(["db","redis","queue","memory","external","fs","exec"]);function Qe(e){let t=Number(e??0);return Number.isFinite(t)&&t>=0?t:0}s(Qe,"Rt"),o(Qe,"finite");var Yx=class{static{s(this,"ga")}static{o(this,"ClusterState")}constructor(e){this.opts=e,this.gateway=null,this.services=new Map,this.edges=new Map,this.recent=[],this.dataNodes=new Map,this.declCache={at:0,decls:[]},this.registryCache={at:0}}reduce(e){if(Q6.has(e.source)){let u=e.raw??{},n=e.context??{},a=String(u.queue??u.store??u.name??e.source),l=n.projectName??u.project,d=typeof l=="string"&&l?l:void 0,p=e.source+":"+a,c=this.dataNodes.get(p),g=u.kind==="queue-state",f=u.kind==="fs-ops"?Qe(u.reads)+Qe(u.writes):g?0:1,m=new Set(c?.usedBy??[]);d&&m.add(d),this.dataNodes.set(p,{id:p,kind:e.source,name:a,viaProject:c?.viaProject??d??"unknown",usedBy:[...m].sort(),count:(c?.count??0)+f,lastSeenAt:e.timestamp,counts:g?u.counts:c?.counts,recent:g?u.recent:c?.recent}),this.opts.onChange?.();return}if(e.source!=="gateway")return;let t=e.raw??{},r=typeof t.kind=="string"?t.kind:"",i=e.timestamp;if(r==="gateway-up")this.gateway={at:i,ports:t.ports??[],routes:t.routes??[]};else if(r==="gateway-down")this.gateway&&(this.gateway={...this.gateway,ports:[]});else if(r==="gateway-traffic"){this.gateway||(this.gateway={at:i,ports:[],routes:[]}),this.gateway.aliveAt=i;let u=String(t.host??""),n=String(t.project??""),a=typeof t.caller=="string"?t.caller:void 0,l=(a?a+"\u21D2":"")+u+"\u2192"+n,d=this.edges.get(l);this.edges.set(l,{host:u,project:n,caller:a,count:(d?.count??0)+Qe(t.count),avgMs:Qe(t.avgMs),errors:(d?.errors??0)+Qe(t.errors),lastSeenAt:i})}else if(r.startsWith("service-")||r==="cold-start"||r==="autoscale"||r==="idle-kill"){let u=String(t.project??"");if(!u)return;let n=this.services.get(u),a={project:u,state:n?.state??"unknown",pods:n?.pods,lastColdStartMs:n?.lastColdStartMs,lastEventAt:i,lastEvent:e.title};r==="service-starting"&&(a.state="starting"),r==="service-up"&&(a.state="up",a.pods=Qe(t.pods??a.pods)),r==="cold-start"&&(a.state="up",a.pods=Qe(t.pods??a.pods),typeof t.durationMs=="number"&&(a.lastColdStartMs=t.durationMs)),r==="autoscale"&&(a.pods=Qe(t.to??a.pods)),(r==="service-down"||r==="idle-kill")&&(a.state="down",a.pods=0,r==="idle-kill"&&(a.idle=!0)),this.services.set(u,a)}this.recent.push({at:i,title:e.title,severity:e.severity}),this.recent.length>40&&this.recent.splice(0,this.recent.length-40),this.opts.onChange?.()}discoverDecls(){if(Date.now()-this.declCache.at<1e4)return this.declCache.decls;let e=[],t,r=o((i,u)=>{if(u>4)return;let n;try{n=Y6(i,{withFileTypes:!0})}catch{return}for(let a of n){if(a.name==="node_modules"||a.name.startsWith("."))continue;let l=`${i}/${a.name}`;if(a.isDirectory())r(l,u+1);else if(a.name==="project.json")try{let d=JSON.parse(bs(l,"utf8")),p=d.targets??{};!t&&/cluster:trust$/.test(p.trust?.executor??"")&&(t=String(d.name??""));let c=d.cluster??d.davnx;if(!c)continue;let g=p["serve-hmr"]?.options?.internalPort,f=(p["serve-hmr"]?.options?.workers??[]).map(h=>h.name),m=typeof c.service=="string"?c.service:void 0;e.push({project:String(d.name??l),host:c.host,path:c.path,internalHost:c.internalHost,service:m,port:c.port,upstream:c.upstream,prependPrefix:c.prependPrefix,default:c.default,internalPort:g,workers:f,podNames:m?this.podNames(m):[],eager:c.eager,minPods:c.minPods,maxPods:c.maxPods,auth:c.auth})}catch{}}},"walk");return r(this.opts.root,0),this.declCache={at:Date.now(),decls:e,...t?{trustProject:t}:{}},e}trustCommand(){return this.discoverDecls(),`yarn nx run ${this.declCache.trustProject||"gateway"}:trust`}podNames(e){try{return Y6(this.opts.podSockDir(e)).filter(t=>t.endsWith(".sock")).map(t=>t.replace(".sock","")).sort()}catch{return[]}}hostsSetup(e){let t="";try{t=(this.opts.readHosts??(()=>bs("/etc/hosts","utf8")))()}catch{}let r=t.split(`
|