browser-devtools-mcp 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{$ as ni,A as Gs,B as Ks,C as Xs,D as Js,E as Ys,L as G,N as os,P as dn,Q as Qs,R as Zs,S as dt,T as Jt,U as rs,V as Yt,Y as ei,Z as ti,a as s,aa as oi,c as qs,ca as ri,ea as si,fa as Mn,g as zt,ga as Dn,h as Vt,ha as bn,i as Gt,ia as bt,j as Kt,k as En,ka as Bn,l as Nn,la as ii,m as cn,n as mn,o as Pn,oa as ai,p as Ws,pa as li,q as $s,qa as ui,r as js,ra as ci,s as ns,sa as An,t as zs,ta as mi,u as pn,v as Rn,va as pi,w as Vs,x as Xt,y as kn,ya as di,z as _n}from"./core-IV5QBQ2N.js";import{z as bi}from"zod";var Ln=class{static{s(this,"TakeAriaSnapshot")}name(){return"a11y_take-aria-snapshot"}description(){return`
1
+ import{$ as ii,A as Js,B as Qs,C as Zs,D as ei,E as ti,L as K,N as rs,P as hn,Q as ni,R as oi,S as pt,T as Yt,U as ss,V as Jt,Y as ri,Z as si,a as s,aa as ai,c as zs,ca as li,ea as ui,fa as Dn,g as zt,ga as Bn,h as Vt,ha as gn,i as Gt,ia as dt,j as Kt,k as Nn,ka as An,l as Pn,la as ci,m as pn,n as dn,o as Rn,oa as mi,p as Vs,pa as pi,q as Gs,qa as di,r as Ks,ra as bi,s as os,sa as Ln,t as Xs,ta as hi,u as bn,v as kn,va as gi,w as Ys,x as Xt,y as _n,ya as fi,z as Mn}from"./core-IV5QBQ2N.js";import{z as yi}from"zod";var Fn=class{static{s(this,"TakeAriaSnapshot")}name(){return"a11y_take-aria-snapshot"}description(){return`
2
2
  Captures an ARIA (accessibility) snapshot of the current page or a specific element.
3
3
  If a selector is provided, the snapshot is scoped to that element; otherwise, the entire page is captured.
4
4
  The output includes the page URL, title, and a YAML-formatted accessibility tree.
@@ -7,14 +7,14 @@ The output includes the page URL, title, and a YAML-formatted accessibility tree
7
7
  - Use in combination with "a11y_take-ax-tree-snapshot" tool for comprehensive UI analysis
8
8
  - Provides semantic structure and accessibility roles
9
9
  - Helps identify accessibility issues and page hierarchy problems
10
- `}inputSchema(){return{selector:bi.string().describe("CSS selector for element to take snapshot.").optional()}}outputSchema(){return{output:bi.string().describe("Includes the page URL, title, and a YAML-formatted accessibility tree.")}}async handle(e,t){let n=await e.page.locator(t.selector||"body").ariaSnapshot();return{output:`
10
+ `}inputSchema(){return{selector:yi.string().describe("CSS selector for element to take snapshot.").optional()}}outputSchema(){return{output:yi.string().describe("Includes the page URL, title, and a YAML-formatted accessibility tree.")}}async handle(e,t){let n=await e.page.locator(t.selector||"body").ariaSnapshot();return{output:`
11
11
  - Page URL: ${e.page.url()}
12
12
  - Page Title: ${await e.page.title()}
13
13
  - Page/Component Snapshot:
14
14
  \`\`\`yaml
15
15
  ${n}
16
16
  \`\`\`
17
- `.trim()}}};import{z as S}from"zod";var gi=!0,hi=!0,fi=!1,yi=!1,wi=!1,Ti=80,Si=["display","visibility","opacity","pointer-events","position","z-index","color","background-color","border-color","border-width","border-style","font-family","font-size","font-weight","line-height","letter-spacing","text-align","text-decoration-line","white-space","overflow","overflow-x","overflow-y","transform","cursor"],_l=new Set(["button","link","textbox","checkbox","radio","combobox","switch","tab","menuitem","dialog","heading","listbox","listitem","option"]),Ml=12,xi=2e3;function Dl(o){let e={};if(!o)return e;for(let t=0;t<o.length;t+=2){let n=String(o[t]),r=String(o[t+1]??"");e[n]=r}return e}s(Dl,"attrsToObj");var Fn=class{static{s(this,"TakeAxTreeSnapshot")}name(){return"accessibility_take-ax-tree-snapshot"}description(){return`
17
+ `.trim()}}};import{z as T}from"zod";var wi=!0,Ti=!0,Si=!1,xi=!1,vi=!1,Ii=80,Ci=["display","visibility","opacity","pointer-events","position","z-index","color","background-color","border-color","border-width","border-style","font-family","font-size","font-weight","line-height","letter-spacing","text-align","text-decoration-line","white-space","overflow","overflow-x","overflow-y","transform","cursor"],Bl=new Set(["button","link","textbox","checkbox","radio","combobox","switch","tab","menuitem","dialog","heading","listbox","listitem","option"]),Al=12,Ei=2e3;function Ll(o){let e={};if(!o)return e;for(let t=0;t<o.length;t+=2){let n=String(o[t]),r=String(o[t+1]??"");e[n]=r}return e}s(Ll,"attrsToObj");var Un=class{static{s(this,"TakeAxTreeSnapshot")}name(){return"accessibility_take-ax-tree-snapshot"}description(){return`
18
18
  Captures a UI-focused snapshot by combining Chromium's Accessibility (AX) tree with runtime visual diagnostics.
19
19
 
20
20
  Use this tool to detect UI issues like:
@@ -36,7 +36,7 @@ Important notes for AI-driven UI debugging:
36
36
  - When not occluded, "topElement" is null (even if "elementFromPoint" returns the element itself or its descendant).
37
37
  - "selectorHint" is a best-effort locator (prefers "data-testid" / "data-selector" / "id"). It may not be unique.
38
38
  - Use "onlyVisible" / "onlyInViewport" to reduce output when focusing on what the user currently sees.
39
- `.trim()}inputSchema(){return{roles:S.array(S.enum(["button","link","textbox","checkbox","radio","combobox","switch","tab","menuitem","dialog","heading","listbox","listitem","option"])).describe("Optional role allowlist. If omitted, a built-in set of interactive roles is used.").optional(),includeStyles:S.boolean().describe("Whether to include computed CSS styles for each node. Styles are extracted via runtime getComputedStyle().").optional().default(gi),includeRuntimeVisual:S.boolean().describe("Whether to compute runtime visual information (bounding box, visibility, viewport).").optional().default(hi),checkOcclusion:S.boolean().describe("If true, checks whether each element is visually occluded by another element using elementFromPoint() sampled at multiple points. Disabled by default.").optional().default(fi),onlyVisible:S.boolean().describe("If true, only visually visible nodes are returned.").optional().default(yi),onlyInViewport:S.boolean().describe("If true, only nodes intersecting the viewport are returned.").optional().default(wi),textPreviewMaxLength:S.number().int().positive().describe("Maximum length of the text preview extracted from each element.").optional().default(Ti),styleProperties:S.array(S.string()).describe("List of CSS computed style properties to extract.").optional().default([...Si])}}outputSchema(){return{url:S.string().describe("The current page URL at the time the AX snapshot was captured."),title:S.string().describe("The document title of the page at the time of the snapshot."),axNodeCount:S.number().int().nonnegative().describe("Total number of nodes returned by Chromium Accessibility.getFullAXTree before filtering."),candidateCount:S.number().int().nonnegative().describe("Number of DOM-backed AX nodes that passed role filtering before enrichment."),enrichedCount:S.number().int().nonnegative().describe("Number of nodes included in the final enriched snapshot output."),truncatedBySafetyCap:S.boolean().describe("Indicates whether the result set was truncated by an internal safety cap to prevent excessive output size."),nodes:S.array(S.object({axNodeId:S.string().describe("Unique identifier of the accessibility node within the AX tree."),parentAxNodeId:S.string().nullable().describe("Parent AX node id in the full AX tree. Null if this node is a root."),childAxNodeIds:S.array(S.string()).describe("Child AX node ids in the full AX tree (may include nodes not present in the filtered output)."),role:S.string().nullable().describe("ARIA role of the accessibility node (e.g. button, link, textbox)."),name:S.string().nullable().describe("Accessible name computed by the browser accessibility engine."),ignored:S.boolean().nullable().describe("Whether the accessibility node is marked as ignored."),backendDOMNodeId:S.number().int().describe("Chromium backend DOM node identifier used to map AX nodes to DOM elements."),domNodeId:S.number().int().nullable().describe("Resolved DOM nodeId from CDP if available; may be null because nodeId is not guaranteed to be stable/resolved."),frameId:S.string().nullable().describe("Frame identifier if the node belongs to an iframe or subframe."),localName:S.string().nullable().describe("Lowercased DOM tag name of the mapped element (e.g. div, button, input)."),id:S.string().nullable().describe("DOM id attribute of the mapped element."),className:S.string().nullable().describe("DOM class attribute of the mapped element."),selectorHint:S.string().nullable().describe("Best-effort selector hint for targeting this element (prefers data-testid/data-selector/id)."),textPreview:S.string().nullable().describe("Short preview of rendered text content or aria-label, truncated to the configured maximum length."),value:S.any().nullable().describe("Raw AX value payload associated with the node, if present."),description:S.any().nullable().describe("Raw AX description payload associated with the node, if present."),properties:S.array(S.any()).nullable().describe("Additional AX properties exposed by the accessibility tree."),styles:S.record(S.string(),S.string()).optional().describe("Subset of computed CSS styles for the element as string key-value pairs."),runtime:S.object({boundingBox:S.object({x:S.number().describe("X coordinate of the element relative to the viewport."),y:S.number().describe("Y coordinate of the element relative to the viewport."),width:S.number().describe("Width of the element in CSS pixels."),height:S.number().describe("Height of the element in CSS pixels.")}).nullable().describe("Bounding box computed at runtime using getBoundingClientRect."),isVisible:S.boolean().describe("Whether the element is considered visually visible (display, visibility, opacity, and size)."),isInViewport:S.boolean().describe("Whether the element intersects the current viewport."),occlusion:S.object({samplePoints:S.array(S.object({x:S.number().describe("Sample point X (viewport coordinates) used for occlusion testing."),y:S.number().describe("Sample point Y (viewport coordinates) used for occlusion testing."),hit:S.boolean().describe("True if elementFromPoint at this point returned a different element that is not a descendant.")})).describe("Sample points used for occlusion detection (center + corners)."),isOccluded:S.boolean().describe("True if at least one sample point is covered by another element."),topElement:S.object({localName:S.string().nullable().describe("Tag name of the occluding element."),id:S.string().nullable().describe("DOM id of the occluding element (may be null if none)."),className:S.string().nullable().describe("DOM class of the occluding element (may be null if none)."),selectorHint:S.string().nullable().describe("Best-effort selector hint for the occluding element."),boundingBox:S.object({x:S.number().describe("X coordinate of the occluding element bounding box."),y:S.number().describe("Y coordinate of the occluding element bounding box."),width:S.number().describe("Width of the occluding element bounding box."),height:S.number().describe("Height of the occluding element bounding box.")}).nullable().describe("Bounding box of the occluding element (if available).")}).nullable().describe("Identity and geometry of the occluding element. Null when not occluded."),intersection:S.object({x:S.number().describe("Intersection rect X."),y:S.number().describe("Intersection rect Y."),width:S.number().describe("Intersection rect width."),height:S.number().describe("Intersection rect height."),area:S.number().describe("Intersection rect area in CSS pixels squared.")}).nullable().describe("Intersection box between this element and the occluding element. Null if not occluded or cannot compute.")}).optional().describe("Occlusion detection results. Only present when checkOcclusion=true.")}).optional().describe("Runtime-derived visual information representing how the element is actually rendered.")})).describe("List of enriched DOM-backed AX nodes combining accessibility metadata with visual diagnostics.")}}async handle(e,t){let n=e.page,r=t.includeRuntimeVisual??hi,i=t.includeStyles??gi,a=t.checkOcclusion??fi,l=t.onlyVisible??yi,u=t.onlyInViewport??wi;if((l||u)&&!r)throw new Error("onlyVisible/onlyInViewport require includeRuntimeVisual=true.");if(a&&!r)throw new Error("checkOcclusion requires includeRuntimeVisual=true.");let m=t.textPreviewMaxLength??Ti,c=t.styleProperties&&t.styleProperties.length>0?t.styleProperties:Si,p=Array.from(c).map(k=>k.toLowerCase()),b=t.roles&&t.roles.length>0?new Set(t.roles):new Set(Array.from(_l)),T=await n.context().newCDPSession(n);try{await T.send("DOM.enable"),await T.send("Accessibility.enable"),r&&await T.send("Runtime.enable");let k=await T.send("Accessibility.getFullAXTree"),M=k.nodes??k,f=new Map,I=new Map;for(let H of M){let X=String(H.nodeId),xe=(H.childIds??[]).map(de=>String(de));I.set(X,xe);for(let de of xe)f.set(de,X)}let W=M.filter(H=>{if(typeof H.backendDOMNodeId!="number")return!1;let X=H.role?.value??null;return X?b.has(String(X)):!1}),ie=W.length,Y=W.length>xi;Y&&(W=W.slice(0,xi));let _=[...W],L=[],F=[],q=s(async()=>{for(;_.length>0;){let H=_.shift();if(!H)return;let X=String(H.nodeId),ue=f.get(X)??null,xe=I.get(X)??[],de=H.backendDOMNodeId,Q=null,w=null,ce=null,V=null,U=null;try{let Pe=(await T.send("DOM.describeNode",{backendNodeId:de}))?.node;if(Pe){let _e=Pe.nodeId;typeof _e=="number"&&_e>0?Q=_e:Q=null,w=Pe.localName??(Pe.nodeName?String(Pe.nodeName).toLowerCase():null);let yt=Dl(Pe.attributes);ce=yt.id??null,V=yt.class??null}}catch{}if(r)try{U=(await T.send("DOM.resolveNode",{backendNodeId:de}))?.object?.objectId??null}catch{}let J=H.role?.value?String(H.role.value):null,Ne=H.name?.value?String(H.name.value):null,Ie=typeof H.ignored=="boolean"?H.ignored:null,ze={axNodeId:X,parentAxNodeId:ue,childAxNodeIds:xe,role:J,name:Ne,ignored:Ie,backendDOMNodeId:de,domNodeId:Q,frameId:H.frameId??null,localName:w,id:ce,className:V,selectorHint:null,textPreview:null,value:H.value??null,description:H.description??null,properties:Array.isArray(H.properties)?H.properties:null},Ce=L.push(ze)-1;F[Ce]=U}},"worker"),j=Array.from({length:Ml},()=>q());if(await Promise.all(j),r){let X=(await T.send("Runtime.evaluate",{expression:"globalThis",returnByValue:!1}))?.result?.objectId;if(X){let ue=F.map(Q=>Q?{objectId:Q}:{value:null}),de=(await T.send("Runtime.callFunctionOn",{objectId:X,returnByValue:!0,functionDeclaration:`
39
+ `.trim()}inputSchema(){return{roles:T.array(T.enum(["button","link","textbox","checkbox","radio","combobox","switch","tab","menuitem","dialog","heading","listbox","listitem","option"])).describe("Optional role allowlist. If omitted, a built-in set of interactive roles is used.").optional(),includeStyles:T.boolean().describe("Whether to include computed CSS styles for each node. Styles are extracted via runtime getComputedStyle().").optional().default(wi),includeRuntimeVisual:T.boolean().describe("Whether to compute runtime visual information (bounding box, visibility, viewport).").optional().default(Ti),checkOcclusion:T.boolean().describe("If true, checks whether each element is visually occluded by another element using elementFromPoint() sampled at multiple points. Disabled by default.").optional().default(Si),onlyVisible:T.boolean().describe("If true, only visually visible nodes are returned.").optional().default(xi),onlyInViewport:T.boolean().describe("If true, only nodes intersecting the viewport are returned.").optional().default(vi),textPreviewMaxLength:T.number().int().positive().describe("Maximum length of the text preview extracted from each element.").optional().default(Ii),styleProperties:T.array(T.string()).describe("List of CSS computed style properties to extract.").optional().default([...Ci])}}outputSchema(){return{url:T.string().describe("The current page URL at the time the AX snapshot was captured."),title:T.string().describe("The document title of the page at the time of the snapshot."),axNodeCount:T.number().int().nonnegative().describe("Total number of nodes returned by Chromium Accessibility.getFullAXTree before filtering."),candidateCount:T.number().int().nonnegative().describe("Number of DOM-backed AX nodes that passed role filtering before enrichment."),enrichedCount:T.number().int().nonnegative().describe("Number of nodes included in the final enriched snapshot output."),truncatedBySafetyCap:T.boolean().describe("Indicates whether the result set was truncated by an internal safety cap to prevent excessive output size."),nodes:T.array(T.object({axNodeId:T.string().describe("Unique identifier of the accessibility node within the AX tree."),parentAxNodeId:T.string().nullable().describe("Parent AX node id in the full AX tree. Null if this node is a root."),childAxNodeIds:T.array(T.string()).describe("Child AX node ids in the full AX tree (may include nodes not present in the filtered output)."),role:T.string().nullable().describe("ARIA role of the accessibility node (e.g. button, link, textbox)."),name:T.string().nullable().describe("Accessible name computed by the browser accessibility engine."),ignored:T.boolean().nullable().describe("Whether the accessibility node is marked as ignored."),backendDOMNodeId:T.number().int().describe("Chromium backend DOM node identifier used to map AX nodes to DOM elements."),domNodeId:T.number().int().nullable().describe("Resolved DOM nodeId from CDP if available; may be null because nodeId is not guaranteed to be stable/resolved."),frameId:T.string().nullable().describe("Frame identifier if the node belongs to an iframe or subframe."),localName:T.string().nullable().describe("Lowercased DOM tag name of the mapped element (e.g. div, button, input)."),id:T.string().nullable().describe("DOM id attribute of the mapped element."),className:T.string().nullable().describe("DOM class attribute of the mapped element."),selectorHint:T.string().nullable().describe("Best-effort selector hint for targeting this element (prefers data-testid/data-selector/id)."),textPreview:T.string().nullable().describe("Short preview of rendered text content or aria-label, truncated to the configured maximum length."),value:T.any().nullable().describe("Raw AX value payload associated with the node, if present."),description:T.any().nullable().describe("Raw AX description payload associated with the node, if present."),properties:T.array(T.any()).nullable().describe("Additional AX properties exposed by the accessibility tree."),styles:T.record(T.string(),T.string()).optional().describe("Subset of computed CSS styles for the element as string key-value pairs."),runtime:T.object({boundingBox:T.object({x:T.number().describe("X coordinate of the element relative to the viewport."),y:T.number().describe("Y coordinate of the element relative to the viewport."),width:T.number().describe("Width of the element in CSS pixels."),height:T.number().describe("Height of the element in CSS pixels.")}).nullable().describe("Bounding box computed at runtime using getBoundingClientRect."),isVisible:T.boolean().describe("Whether the element is considered visually visible (display, visibility, opacity, and size)."),isInViewport:T.boolean().describe("Whether the element intersects the current viewport."),occlusion:T.object({samplePoints:T.array(T.object({x:T.number().describe("Sample point X (viewport coordinates) used for occlusion testing."),y:T.number().describe("Sample point Y (viewport coordinates) used for occlusion testing."),hit:T.boolean().describe("True if elementFromPoint at this point returned a different element that is not a descendant.")})).describe("Sample points used for occlusion detection (center + corners)."),isOccluded:T.boolean().describe("True if at least one sample point is covered by another element."),topElement:T.object({localName:T.string().nullable().describe("Tag name of the occluding element."),id:T.string().nullable().describe("DOM id of the occluding element (may be null if none)."),className:T.string().nullable().describe("DOM class of the occluding element (may be null if none)."),selectorHint:T.string().nullable().describe("Best-effort selector hint for the occluding element."),boundingBox:T.object({x:T.number().describe("X coordinate of the occluding element bounding box."),y:T.number().describe("Y coordinate of the occluding element bounding box."),width:T.number().describe("Width of the occluding element bounding box."),height:T.number().describe("Height of the occluding element bounding box.")}).nullable().describe("Bounding box of the occluding element (if available).")}).nullable().describe("Identity and geometry of the occluding element. Null when not occluded."),intersection:T.object({x:T.number().describe("Intersection rect X."),y:T.number().describe("Intersection rect Y."),width:T.number().describe("Intersection rect width."),height:T.number().describe("Intersection rect height."),area:T.number().describe("Intersection rect area in CSS pixels squared.")}).nullable().describe("Intersection box between this element and the occluding element. Null if not occluded or cannot compute.")}).optional().describe("Occlusion detection results. Only present when checkOcclusion=true.")}).optional().describe("Runtime-derived visual information representing how the element is actually rendered.")})).describe("List of enriched DOM-backed AX nodes combining accessibility metadata with visual diagnostics.")}}async handle(e,t){let n=e.page,r=t.includeRuntimeVisual??Ti,i=t.includeStyles??wi,a=t.checkOcclusion??Si,l=t.onlyVisible??xi,u=t.onlyInViewport??vi;if((l||u)&&!r)throw new Error("onlyVisible/onlyInViewport require includeRuntimeVisual=true.");if(a&&!r)throw new Error("checkOcclusion requires includeRuntimeVisual=true.");let m=t.textPreviewMaxLength??Ii,c=t.styleProperties&&t.styleProperties.length>0?t.styleProperties:Ci,p=Array.from(c).map(x=>x.toLowerCase()),b=t.roles&&t.roles.length>0?new Set(t.roles):new Set(Array.from(Bl)),f=await n.context().newCDPSession(n);try{await f.send("DOM.enable"),await f.send("Accessibility.enable"),r&&await f.send("Runtime.enable");let x=await f.send("Accessibility.getFullAXTree"),B=x.nodes??x,w=new Map,U=new Map;for(let M of B){let ee=String(M.nodeId),ce=(M.childIds??[]).map(fe=>String(fe));U.set(ee,ce);for(let fe of ce)w.set(fe,ee)}let D=B.filter(M=>{if(typeof M.backendDOMNodeId!="number")return!1;let ee=M.role?.value??null;return ee?b.has(String(ee)):!1}),H=D.length,Q=D.length>Ei;Q&&(D=D.slice(0,Ei));let $=[...D],P=[],W=[],G=s(async()=>{for(;$.length>0;){let M=$.shift();if(!M)return;let ee=String(M.nodeId),ue=w.get(ee)??null,ce=U.get(ee)??[],fe=M.backendDOMNodeId,te=null,me=null,v=null,pe=null,V=null;try{let Ce=(await f.send("DOM.describeNode",{backendNodeId:fe}))?.node;if(Ce){let We=Ce.nodeId;typeof We=="number"&&We>0?te=We:te=null,me=Ce.localName??(Ce.nodeName?String(Ce.nodeName).toLowerCase():null);let Le=Ll(Ce.attributes);v=Le.id??null,pe=Le.class??null}}catch{}if(r)try{V=(await f.send("DOM.resolveNode",{backendNodeId:fe}))?.object?.objectId??null}catch{}let q=M.role?.value?String(M.role.value):null,X=M.name?.value?String(M.name.value):null,Pe=typeof M.ignored=="boolean"?M.ignored:null,Ie={axNodeId:ee,parentAxNodeId:ue,childAxNodeIds:ce,role:q,name:X,ignored:Pe,backendDOMNodeId:fe,domNodeId:te,frameId:M.frameId??null,localName:me,id:v,className:pe,selectorHint:null,textPreview:null,value:M.value??null,description:M.description??null,properties:Array.isArray(M.properties)?M.properties:null},ft=P.push(Ie)-1;W[ft]=V}},"worker"),_=Array.from({length:Al},()=>G());if(await Promise.all(_),r){let ee=(await f.send("Runtime.evaluate",{expression:"globalThis",returnByValue:!1}))?.result?.objectId;if(ee){let ue=W.map(te=>te?{objectId:te}:{value:null}),fe=(await f.send("Runtime.callFunctionOn",{objectId:ee,returnByValue:!0,functionDeclaration:`
40
40
  function(textMax, includeStyles, styleProps, checkOcclusion, ...els) {
41
41
  function selectorHintFor(el) {
42
42
  if (!(el instanceof Element)) { return null; }
@@ -259,32 +259,31 @@ function(textMax, includeStyles, styleProps, checkOcclusion, ...els) {
259
259
  };
260
260
  });
261
261
  }
262
- `,arguments:[{value:m},{value:i},{value:p},{value:a},...ue]}))?.result?.value??[];for(let Q=0;Q<L.length;Q++){let w=de[Q];w&&(L[Q].selectorHint=w.selectorHint??null,L[Q].textPreview=w.textPreview??null,w.styles&&(L[Q].styles=w.styles),w.runtime&&(L[Q].runtime=w.runtime))}}}let ee=L;return(l||u)&&(ee=ee.filter(H=>!(!H.runtime||l&&!H.runtime.isVisible||u&&!H.runtime.isInViewport))),{url:String(n.url()),title:String(await n.title()),axNodeCount:M.length,candidateCount:ie,enrichedCount:ee.length,truncatedBySafetyCap:Y,nodes:ee}}finally{await T.detach().catch(()=>{})}}};var Ii=[new Ln,new Fn];import{z as gt}from"zod";var Ci=5e4,Un=class{static{s(this,"GetAsHtml")}name(){return"content_get-as-html"}description(){return`
262
+ `,arguments:[{value:m},{value:i},{value:p},{value:a},...ue]}))?.result?.value??[];for(let te=0;te<P.length;te++){let me=fe[te];me&&(P[te].selectorHint=me.selectorHint??null,P[te].textPreview=me.textPreview??null,me.styles&&(P[te].styles=me.styles),me.runtime&&(P[te].runtime=me.runtime))}}}let oe=P;return(l||u)&&(oe=oe.filter(M=>!(!M.runtime||l&&!M.runtime.isVisible||u&&!M.runtime.isInViewport))),{url:String(n.url()),title:String(await n.title()),axNodeCount:B.length,candidateCount:H,enrichedCount:oe.length,truncatedBySafetyCap:Q,nodes:oe}}finally{await f.detach().catch(()=>{})}}};var Oi=[new Fn,new Un];import{z as bt}from"zod";var Ni=5e4,Hn=class{static{s(this,"GetAsHtml")}name(){return"content_get-as-html"}description(){return`
263
263
  Gets the HTML content of the current page.
264
264
  By default, all <script> tags are removed from the output unless "removeScripts" is explicitly set to "false".
265
- `}inputSchema(){return{selector:gt.string().describe("CSS selector to limit the HTML content to a specific container.").optional(),removeScripts:gt.boolean().describe('Remove all script tags from the HTML (default: "true").').optional().default(!0),removeComments:gt.boolean().describe('Remove all HTML comments (default: "false").').optional().default(!1),removeStyles:gt.boolean().describe('Remove all style tags from the HTML (default: "false").').optional().default(!1),removeMeta:gt.boolean().describe('Remove all meta tags from the HTML (default: "false").').optional().default(!1),cleanHtml:gt.boolean().describe('Perform comprehensive HTML cleaning (default: "false").').optional().default(!1),minify:gt.boolean().describe('Minify the HTML output (default: "false").').optional().default(!1),maxLength:gt.number().int().positive().describe(`Maximum number of characters to return (default: "${Ci}").`).optional().default(Ci)}}outputSchema(){return{output:gt.string().describe("The requested HTML content of the page.")}}async handle(e,t){let{selector:n,removeScripts:r,removeComments:i,removeStyles:a,removeMeta:l,minify:u,cleanHtml:m,maxLength:c}=t,p;if(n){let I=await e.page.$(n);if(!I)throw new Error(`Element with selector "${n}" not found`);p=await I.evaluate(W=>W.outerHTML)}else p=await e.page.content();let b=r||m,T=i||m,k=a||m,M=l||m;(b||T||k||M||u)&&(p=await e.page.evaluate(({html:I,removeScripts:W,removeComments:ie,removeStyles:Y,removeMeta:_,minify:L})=>{let F=document.createElement("template");F.innerHTML=I;let q=F.content;if(W&&q.querySelectorAll("script").forEach(K=>K.remove()),Y&&q.querySelectorAll("style").forEach(K=>K.remove()),_&&q.querySelectorAll("meta").forEach(K=>K.remove()),ie){let ee=s(K=>{let H=K.childNodes;for(let X=H.length-1;X>=0;X--){let ue=H[X];ue.nodeType===8?K.removeChild(ue):ue.nodeType===1&&ee(ue)}},"removeComments");ee(q)}let j=F.innerHTML;return L&&(j=j.replace(/>\s+</g,"><").trim()),j},{html:p,removeScripts:b,removeComments:T,removeStyles:k,removeMeta:M,minify:u}));let f=p;return f.length>c&&(f=f.slice(0,c)+`
266
- <!-- Output truncated due to size limits -->`),{output:f}}};import{z as ss}from"zod";var vi=5e4,Hn=class{static{s(this,"GetAsText")}name(){return"content_get-as-text"}description(){return"Gets the visible text content of the current page."}inputSchema(){return{selector:ss.string().describe("CSS selector to limit the text content to a specific container.").optional(),maxLength:ss.number().int().positive().describe(`Maximum number of characters to return (default: "${vi}").`).optional().default(vi)}}outputSchema(){return{output:ss.string().describe("The requested text content of the page.")}}async handle(e,t){let{selector:n,maxLength:r}=t,a=await e.page.evaluate(({selector:l})=>{let u=l?document.querySelector(l):document.body;if(!u)throw new Error(`Element with selector "${l}" not found`);let m=document.createTreeWalker(u,NodeFilter.SHOW_TEXT,{acceptNode:s(b=>{let T=window.getComputedStyle(b.parentElement);return T.display!=="none"&&T.visibility!=="hidden"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT},"acceptNode")}),c="",p;for(;p=m.nextNode();){let b=p.textContent?.trim();b&&(c+=b+`
267
- `)}return c.trim()},{selector:n});return a.length>r&&(a=a.slice(0,r)+`
268
- [Output truncated due to size limits]`),{output:a}}};function Te(o){let e=Object.keys(o).filter(t=>isNaN(Number(t))).map(t=>o[t]);if(e.length===0)throw new Error("Enum has no values");return e}s(Te,"getEnumKeyTuples");function st(o,e){let t=Object.keys(o).filter(i=>isNaN(Number(i))).map(i=>o[i]),n=e?.caseInsensitive??!0,r=new Map(t.map(i=>[n?i.toLowerCase():i,i]));return i=>{let a=n?i.toLowerCase():i,l=r.get(a);if(l===void 0)throw new Error(`Invalid enum value: "${i}"`);return l}}s(st,"createEnumTransformer");function qn(o=new Date){let e=s(t=>String(t).padStart(2,"0"),"pad");return o.getFullYear()+e(o.getMonth()+1)+e(o.getDate())+"-"+e(o.getHours())+e(o.getMinutes())+e(o.getSeconds())}s(qn,"formattedTimeForFilename");import Bl from"node:os";import Al from"node:path";import{z as it}from"zod";var Oi=(r=>(r.PIXEL="px",r.INCH="in",r.CENTIMETER="cm",r.MILLIMETER="mm",r))(Oi||{}),Wn=(p=>(p.LETTER="Letter",p.LEGAL="Legal",p.TABLOID="Tabloid",p.LEDGER="Ledger",p.A0="A0",p.A1="A1",p.A2="A2",p.A3="A3",p.A4="A4",p.A5="A5",p.A6="A6",p))(Wn||{}),is="page",St="1cm",Ll="A4",Fl={top:St,right:St,bottom:St,left:St},$n=class{static{s(this,"SaveAsPdf")}name(){return"content_save-as-pdf"}description(){return"Saves the current page as a PDF file."}inputSchema(){return{outputPath:it.string().describe("Directory path where PDF will be saved. By default OS tmp directory is used.").optional().default(Bl.tmpdir()),name:it.string().describe(`Name of the save/export. Default value is "${is}". Note that final saved/exported file name is in the "{name}-{time}.pdf" format in which "{time}" is in the "YYYYMMDD-HHmmss" format.`).optional().default(is),format:it.enum(Te(Wn)).transform(st(Wn)).describe(`Page format. Valid values are: ${Te(Wn)}.`).optional().default(Ll),printBackground:it.boolean().describe('Whether to print background graphics (default: "false").').optional().default(!1),margin:it.object({top:it.string().describe("Top margin.").default(St),right:it.string().describe("Right margin.").default(St),bottom:it.string().describe("Bottom margin.").default(St),left:it.string().describe("Left margin.").default(St)}).describe(`Page margins. Numeric margin values labeled with units ("100px", "10cm", etc ...). Unlabeled values are treated as pixels. Valid units are: ${Te(Oi)}.`).optional()}}outputSchema(){return{filePath:it.string().describe("Full path of the saved PDF file.")}}async handle(e,t){let n=`${t.name||is}-${qn()}.pdf`,r=Al.resolve(t.outputPath,n),i={path:r,format:t.format,printBackground:t.printBackground,margin:t.margin||Fl};return await e.page.pdf(i),{filePath:r}}};import Ul from"node:os";import Hl from"node:path";import jn from"jpeg-js";import{PNG as ql}from"pngjs";import{z as Ke}from"zod";var zn=(t=>(t.PNG="png",t.JPEG="jpeg",t))(zn||{}),as="screenshot",Ei="png",Ni=100,Vn=class{static{s(this,"TakeScreenshot")}name(){return"content_take-screenshot"}description(){return`Takes a screenshot of the current page or a specific element.
269
- The screenshot is always saved to the file system and the file path is returned.
270
- By default, the image data is NOT included in the response to reduce payload size.
271
- If the AI assistant cannot access the MCP server's file system (e.g., remote MCP server,
272
- containerized environment, or different machine), set "includeBase64" to true to receive
273
- the image data directly in the response.`}inputSchema(){return{outputPath:Ke.string().describe("Directory path where screenshot will be saved. By default OS tmp directory is used.").optional().default(Ul.tmpdir()),name:Ke.string().describe(`Name of the screenshot. Default value is "${as}". Note that final saved/exported file name is in the "{name}-{time}.{type}" format in which "{time}" is in the "YYYYMMDD-HHmmss" format.`).optional().default(as),selector:Ke.string().describe("CSS selector for element to take screenshot.").optional(),fullPage:Ke.boolean().describe('Whether to take a screenshot of the full scrollable page, instead of the currently visible viewport (default: "false").').optional().default(!1),type:Ke.enum(Te(zn)).transform(st(zn)).describe(`Page format. Valid values are: ${Te(zn)}`).optional().default(Ei),quality:Ke.number().int().min(0).max(Ni).describe("The quality of the image, between 0-100. Not applicable to png images.").optional(),includeBase64:Ke.boolean().describe("If true, includes the screenshot image data (base64-encoded) in the response. Default is false since the file path is usually sufficient when the AI assistant can access the MCP server file system. Set to true when the AI assistant cannot access the file system where the MCP server runs (e.g., remote server, container, or different machine) and needs to receive the image directly in the response.").optional().default(!1)}}outputSchema(){return{filePath:Ke.string().describe("Full path of the saved screenshot file."),image:Ke.object({data:Ke.any().describe("Base64-encoded image data."),mimeType:Ke.string().describe("MIME type of the image.")}).optional().describe('Image data included only when "includeBase64" input parameter is set to true.')}}_scaleImageToSize(e,t){let{data:n,width:r,height:i}=e,a=Math.max(1,Math.floor(t.width)),l=Math.max(1,Math.floor(t.height));if(r===a&&i===l)return e;if(r<=0||i<=0)throw new Error("Invalid input image");if(t.width<=0||t.height<=0||!isFinite(t.width)||!isFinite(t.height))throw new Error("Invalid output dimensions");let u=s((_,L,F)=>_<L?L:_>F?F:_,"clamp"),m=s((_,L)=>{let F=_*_,q=F*_;L[0]=-.5*_+1*F-.5*q,L[1]=1-2.5*F+1.5*q,L[2]=.5*_+2*F-1.5*q,L[3]=-.5*F+.5*q},"weights"),c=r*4,p=a*4,b=new Int32Array(a*4),T=new Float32Array(a*4),k=new Float32Array(4),M=r/a;for(let _=0;_<a;_++){let L=(_+.5)*M-.5,F=Math.floor(L),q=L-F;m(q,k);let j=_*4,ee=u(F-1,0,r-1),K=u(F+0,0,r-1),H=u(F+1,0,r-1),X=u(F+2,0,r-1);b[j+0]=ee<<2,b[j+1]=K<<2,b[j+2]=H<<2,b[j+3]=X<<2,T[j+0]=k[0],T[j+1]=k[1],T[j+2]=k[2],T[j+3]=k[3]}let f=new Int32Array(l*4),I=new Float32Array(l*4),W=new Float32Array(4),ie=i/l;for(let _=0;_<l;_++){let L=(_+.5)*ie-.5,F=Math.floor(L),q=L-F;m(q,W);let j=_*4,ee=u(F-1,0,i-1),K=u(F+0,0,i-1),H=u(F+1,0,i-1),X=u(F+2,0,i-1);f[j+0]=ee*c,f[j+1]=K*c,f[j+2]=H*c,f[j+3]=X*c,I[j+0]=W[0],I[j+1]=W[1],I[j+2]=W[2],I[j+3]=W[3]}let Y=new Uint8Array(a*l*4);for(let _=0;_<l;_++){let L=_*4,F=f[L+0],q=f[L+1],j=f[L+2],ee=f[L+3],K=I[L+0],H=I[L+1],X=I[L+2],ue=I[L+3],xe=_*p;for(let de=0;de<a;de++){let Q=de*4,w=b[Q+0],ce=b[Q+1],V=b[Q+2],U=b[Q+3],J=T[Q+0],Ne=T[Q+1],Ie=T[Q+2],ze=T[Q+3],Ce=xe+(de<<2);for(let oe=0;oe<4;oe++){let Pe=n[F+w+oe]*J+n[F+ce+oe]*Ne+n[F+V+oe]*Ie+n[F+U+oe]*ze,_e=n[q+w+oe]*J+n[q+ce+oe]*Ne+n[q+V+oe]*Ie+n[q+U+oe]*ze,yt=n[j+w+oe]*J+n[j+ce+oe]*Ne+n[j+V+oe]*Ie+n[j+U+oe]*ze,et=n[ee+w+oe]*J+n[ee+ce+oe]*Ne+n[ee+V+oe]*Ie+n[ee+U+oe]*ze,tt=Pe*K+_e*H+yt*X+et*ue;Y[Ce+oe]=tt<0?0:tt>255?255:tt|0}}}return{data:Buffer.from(Y.buffer),width:a,height:l}}_scaleImageToFitMessage(e,t){let r=12058624e-1,i=1568,a=t==="png"?ql.sync.read(e):jn.decode(e,{maxMemoryUsageInMB:512}),l=a.width*a.height,u=Math.min(i/a.width,i/a.height,Math.sqrt(r/l));u>1&&(u=1);let m=a.width*u|0,c=a.height*u|0,p=this._scaleImageToSize(a,{width:m,height:c}),b,T=t,k=t==="png"?75:70;t==="png"?(b=jn.encode(p,k).data,T="jpeg"):b=jn.encode(p,k).data;let M=0,f=5;for(;b.length>819200&&M<f;)k=Math.max(50,k-10),k<=50&&b.length>819200&&(u*=.85,m=Math.max(200,a.width*u|0),c=Math.max(200,a.height*u|0),p=this._scaleImageToSize(a,{width:m,height:c})),b=jn.encode(p,k).data,M++;return b}async handle(e,t){let n=t.type||Ei,r=`${t.name||as}-${qn()}.${n}`,i=Hl.resolve(t.outputPath,r),a=n==="png"?void 0:t.quality??Ni,l={path:i,type:n,fullPage:!!t.fullPage,quality:a};if(t.selector){let c=await e.page.$(t.selector);if(!c)throw new Error(`Element not found: ${t.selector}`);l.element=c}let u=await e.page.screenshot(l),m={filePath:i};return t.includeBase64&&(m.image={data:this._scaleImageToFitMessage(u,n),mimeType:`image/${n}`}),m}};var Pi=[new Un,new Hn,new $n,new Vn];import{z as Re}from"zod";var ls={maxSnapshots:1e3,maxCallStackDepth:20,maxFramesWithScopes:5,maxAsyncStackSegments:10,maxFramesPerAsyncSegment:10,maxDOMMutations:100,maxDOMHtmlSnippetLength:200,maxPendingRequests:1e3,maxResponseBodyLength:1e4,networkCleanupTimeoutMs:5e3},us=new WeakMap;function Ut(){let o=Date.now(),e=Math.floor(Math.random()*1e6);return`${o.toString(36)}-${e.toString(36)}`}s(Ut,"_generateId");function Wl(o,e){try{let t=o.trim();return/^[=<>!%]/.test(t)&&(t=`hitCount ${t}`),!!new Function("hitCount",`return (${t});`)(e)}catch{return!1}}s(Wl,"_evaluateHitCondition");async function $l(o,e,t){let n={};for(let r of t.values())try{let i=await o.evaluateOnCallFrame(e,r.expression);if(i.exceptionDetails)n[r.expression]=`[Error: ${i.exceptionDetails.text||"Evaluation failed"}]`;else{let a=await o.extractValueDeep(i.result,2);n[r.expression]=a}}catch(i){n[r.expression]=`[Error: ${i.message||"Unknown error"}]`}return n}s($l,"_evaluateWatchExpressionsOnFrame");function ki(o,e,t,n){let r=us.get(o);if(r)return r;let i=new Qs(e,t),a=new Zs(e),l={...ls,...n},u={v8Api:i,sourceMapResolver:a,probes:new Map,watchExpressions:new Map,domBreakpoints:new Map,networkBreakpoints:new Map,snapshots:[],snapshotSequence:0,config:l,enabled:!1,sourceMapsLoaded:!1,exceptionBreakpoint:"none",networkInterceptionEnabled:!1,recentDOMMutations:[]};return us.set(o,u),u}s(ki,"_ensureStore");function ge(o){return us.get(o)}s(ge,"_getStore");async function jl(o,e,t=3){let n=[];for(let r of e.scopeChain)if(!(r.type==="global"||r.type==="script"||r.type==="with"||r.type==="eval"||r.type==="wasm-expression-stack")){if(n.length>=t)break;try{let i=await o.getScopeVariables(r),a=[];for(let[l,u]of Object.entries(i))a.push({name:l,value:u,type:typeof u});n.push({type:r.type,name:r.name,variables:a})}catch{}}return n}s(jl,"_captureScopes");async function zl(o,e,t,n){let r=[];t&&(r=await jl(o,e));let i;if(n){let a=n.generatedToOriginal(e.location.scriptId,e.location.lineNumber,e.location.columnNumber??0);a&&(i={source:a.source,line:a.line+1,column:a.column!==void 0?a.column+1:void 0,name:a.name})}return{functionName:e.functionName||"(anonymous)",url:e.url||"",lineNumber:e.location.lineNumber+1,columnNumber:e.location.columnNumber!==void 0?e.location.columnNumber+1:void 0,scriptId:e.location.scriptId,scopes:r,originalLocation:i}}s(zl,"_callFrameToSnapshot");function Vl(o,e,t,n){if(!o)return;let r=t??ls.maxAsyncStackSegments,i=n??ls.maxFramesPerAsyncSegment,a=[],l=o,u=0;for(;l&&u<r;){let m=[];for(let c of l.callFrames.slice(0,i)){let p;if(e){let b=e.generatedToOriginal(c.location.scriptId,c.location.lineNumber,c.location.columnNumber??0);b&&(p={source:b.source,line:b.line+1,column:b.column!==void 0?b.column+1:void 0,name:b.name})}m.push({functionName:c.functionName||"(anonymous)",url:c.url||"",lineNumber:c.location.lineNumber+1,columnNumber:c.location.columnNumber!==void 0?c.location.columnNumber+1:void 0,originalLocation:p})}m.length>0&&a.push({description:l.description,callFrames:m}),l=l.parent,u++}if(a.length!==0)return{segments:a}}s(Vl,"_convertAsyncStackTrace");async function Ue(o,e,t){let n=ki(o,e,t?.v8Options,t?.config);if(!n.enabled){await n.v8Api.enable(),n.v8Api.on("scriptParsed",r=>{n.sourceMapResolver.registerScript(r)});for(let r of n.v8Api.getScripts())n.sourceMapResolver.registerScript(r);n.v8Api.on("paused",async r=>{let i=Date.now();try{let a=r.reason==="exception"||r.reason==="promiseRejection",l=r.reason==="DOM",u=r.hitBreakpoints||[],m,c=!0,p,b;if(l&&r.data){let f=r.data;for(let I of n.domBreakpoints.values())if(I.enabled&&(I.nodeId===f.nodeId||!f.nodeId)){p=I,b={type:I.type,selector:I.selector,targetNode:f.targetNode?`<${f.targetNode.nodeName?.toLowerCase()||"unknown"}>`:void 0,attributeName:f.attributeName||I.attributeName};break}}if(p&&b)try{let f=await e.evaluate(I=>{let W=window;if(!W.__domBreakpointMutations)return null;let ie=W.__domBreakpointMutations;for(let Y=ie.length-1;Y>=0;Y--)if(ie[Y].breakpointId===I)return ie[Y];return null},p.id);f&&(b.oldValue=f.oldValue,b.newValue=f.newValue,b.targetNode=f.targetOuterHTML,f.attributeName&&(b.attributeName=f.attributeName))}catch{}for(let f of n.probes.values()){if(!f.enabled)continue;if(f.v8BreakpointIds.some(W=>u.includes(W))){m=f,f.hitCondition&&(c=Wl(f.hitCondition,f.hitCount+1));break}}let T=m!==void 0&&c,k=a&&n.exceptionBreakpoint!=="none",M=p!==void 0;if(m&&(m.hitCount++,m.lastHitAt=Date.now()),p&&(p.hitCount++,p.lastHitAt=Date.now()),(T||k||M)&&r.callFrames.length>0){let f=r.callFrames[0],I;if(m&&m.kind==="logpoint"&&m.logExpression)try{let K=await n.v8Api.evaluateOnCallFrame(f.callFrameId,m.logExpression,{returnByValue:!0,generatePreview:!0});I=n.v8Api.extractValue(K.result)}catch{I="[evaluation error]"}let W;if(a&&r.data){let K=r.data;W={type:r.reason==="promiseRejection"?"promiseRejection":"exception",message:K.description||K.value||String(K),name:K.className,stack:K.description}}let ie,Y=n.sourceMapResolver.generatedToOriginal(f.location.scriptId,f.location.lineNumber,f.location.columnNumber??0);Y&&(ie={source:Y.source,line:Y.line+1,column:Y.column!==void 0?Y.column+1:void 0,name:Y.name});let _=m?.id??p?.id??"__exception__",L=m?.kind==="logpoint",F=[];if(!L){let K=r.callFrames.slice(0,n.config.maxCallStackDepth);for(let H=0;H<K.length;H++){let X=K[H],ue=H<n.config.maxFramesWithScopes,xe=await zl(n.v8Api,X,ue,n.sourceMapResolver);F.push(xe)}}let q;L||(q=Vl(r.asyncStackTrace,n.sourceMapResolver,n.config.maxAsyncStackSegments,n.config.maxFramesPerAsyncSegment));let j;!L&&n.watchExpressions.size>0&&(j=await $l(n.v8Api,f.callFrameId,n.watchExpressions));let ee={id:Ut(),probeId:_,timestamp:Date.now(),sequenceNumber:++n.snapshotSequence,url:f.url||"",lineNumber:f.location.lineNumber+1,columnNumber:f.location.columnNumber!==void 0?f.location.columnNumber+1:void 0,originalLocation:ie,exception:W,domChange:b,callStack:F,asyncStackTrace:q,logResult:I,watchResults:j,captureTimeMs:Date.now()-i};n.snapshots.push(ee),n.snapshots.length>n.config.maxSnapshots&&n.snapshots.splice(0,n.snapshots.length-n.config.maxSnapshots)}}finally{await n.v8Api.resume()}}),n.enabled=!0,n.sourceMapResolver.loadAllSourceMaps().then(()=>{n.sourceMapsLoaded=!0}).catch(()=>{})}}s(Ue,"enableDebugging");function N(o){return ge(o)?.enabled??!1}s(N,"isDebuggingEnabled");async function _i(o,e,t,n,r=1){let i=ki(o,e);i.enabled||await Ue(o,e);let a=await i.sourceMapResolver.resolveLocationByUrl(t,n,r);return a?{source:a.source,line:a.line+1,column:a.column+1,name:a.name}:null}s(_i,"resolveSourceLocation");async function Mi(o,e){let t=ge(o);if(!t||!t.enabled)throw new Error("Debugging is not enabled");await t.v8Api.setPauseOnExceptions(e),t.exceptionBreakpoint=e}s(Mi,"setExceptionBreakpoint");function gn(o){return ge(o)?.exceptionBreakpoint??"none"}s(gn,"getExceptionBreakpoint");function Di(o){return ge(o)?.sourceMapResolver.hasSourceMaps()??!1}s(Di,"hasSourceMaps");async function Gn(o,e){let t=ge(o);if(!t||!t.enabled)throw new Error("Debugging is not enabled");let n=Ut(),r;e.condition?r=`(${e.condition})`:r="true";let i=e.lineNumber-1,a=(e.columnNumber??1)-1,l=t.sourceMapResolver.originalToGenerated(e.urlPattern,i,a),u,m=0;if(l)u=(await t.v8Api.setBreakpoint({scriptId:l.scriptId,lineNumber:l.location.line,columnNumber:l.location.column},r)).breakpointId,m=1;else{let b=e.urlPattern.replace(/\\([.*+?^${}()|[\]\\/-])/g,"$1").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*").replace(/\\\?/g,"."),T=await t.v8Api.setBreakpointByUrl({urlRegex:b,lineNumber:e.lineNumber-1,columnNumber:e.columnNumber?e.columnNumber-1:void 0,condition:r});u=T.breakpointId,m=T.locations.length}let c={id:n,kind:e.kind,enabled:!0,urlPattern:e.urlPattern,lineNumber:e.lineNumber,columnNumber:e.columnNumber,condition:e.condition,logExpression:e.logExpression,hitCondition:e.hitCondition,v8BreakpointIds:[u],resolvedLocations:m,hitCount:0,createdAt:Date.now()};return t.probes.set(n,c),c}s(Gn,"createProbe");async function xt(o,e){let t=ge(o);if(!t)return!1;let n=t.probes.get(e);if(!n)return!1;for(let r of n.v8BreakpointIds)try{await t.v8Api.removeBreakpoint(r)}catch{}return t.probes.delete(e),!0}s(xt,"removeProbe");function Se(o){let e=ge(o);return e?Array.from(e.probes.values()):[]}s(Se,"listProbes");function Kn(o,e){let t=ge(o);if(t)return t.probes.get(e)}s(Kn,"getProbe");function It(o){let e=ge(o);return e?[...e.snapshots]:[]}s(It,"getSnapshots");function at(o,e){let t=ge(o);return t?t.snapshots.filter(n=>n.probeId===e):[]}s(at,"getSnapshotsByProbe");function Be(o,e){let t=ge(o);if(!t)return 0;let n=t.snapshots.length;return t.snapshots=t.snapshots.filter(r=>r.probeId!==e),n-t.snapshots.length}s(Be,"clearSnapshotsByProbe");function Bi(o){let e=ge(o);if(!e||e.snapshots.length===0)return{totalSnapshots:0,snapshotsByProbe:{},averageCaptureTimeMs:0};let t={},n=0;for(let r of e.snapshots)t[r.probeId]=(t[r.probeId]||0)+1,n+=r.captureTimeMs;return{totalSnapshots:e.snapshots.length,snapshotsByProbe:t,oldestTimestamp:e.snapshots[0].timestamp,newestTimestamp:e.snapshots[e.snapshots.length-1].timestamp,averageCaptureTimeMs:n/e.snapshots.length}}s(Bi,"getSnapshotStats");function Ai(o,e){let t=ge(o);if(!t)throw new Error("Debug store not initialized");let n=Ut(),r={id:n,expression:e,createdAt:Date.now()};return t.watchExpressions.set(n,r),r}s(Ai,"addWatchExpression");function Li(o,e){let t=ge(o);return t?t.watchExpressions.delete(e):!1}s(Li,"removeWatchExpression");function Xn(o){let e=ge(o);return e?Array.from(e.watchExpressions.values()):[]}s(Xn,"listWatchExpressions");function Fi(o){let e=ge(o);if(!e)return 0;let t=e.watchExpressions.size;return e.watchExpressions.clear(),t}s(Fi,"clearWatchExpressions");async function Ui(o,e,t){let n=ge(o);if(!n||!n.enabled)throw new Error("Debugging is not enabled");let r=await n.v8Api.getCdp();await r.send("DOM.enable");let{root:i}=await r.send("DOM.getDocument",{depth:0}),{nodeId:a}=await r.send("DOM.querySelector",{nodeId:i.nodeId,selector:t.selector});if(!a||a===0)throw new Error(`Element not found: ${t.selector}`);let l=t.type==="subtree-modified"?"subtree-modified":t.type==="attribute-modified"?"attribute-modified":"node-removed";await r.send("DOMDebugger.setDOMBreakpoint",{nodeId:a,type:l});let u=Ut(),m={id:u,selector:t.selector,type:t.type,attributeName:t.attributeName,enabled:!0,nodeId:a,hitCount:0,createdAt:Date.now()};return n.domBreakpoints.set(u,m),await e.evaluate(({selector:c,breakpointId:p,type:b,attrName:T,maxMutations:k,maxHtmlSnippetLength:M})=>{let f=document.querySelector(c);if(!f)return;let I=window;I.__domBreakpointData=I.__domBreakpointData||{},I.__domBreakpointMutations=I.__domBreakpointMutations||[],I.__domBreakpointData[p]={selector:c,type:b,attrName:T,currentAttrs:{}};for(let Y of f.attributes)I.__domBreakpointData[p].currentAttrs[Y.name]=Y.value;let W=new MutationObserver(Y=>{for(let _ of Y){let L=_.target;if(_.type==="attributes"){let F=_.attributeName||"";if(T&&T!==F)continue;let q={breakpointId:p,selector:c,type:"attribute-modified",attributeName:F,oldValue:_.oldValue,newValue:L.getAttribute(F),targetOuterHTML:L.outerHTML.substring(0,M),timestamp:Date.now()};I.__domBreakpointMutations.push(q),I.__domBreakpointMutations.length>k&&I.__domBreakpointMutations.shift(),I.__domBreakpointData[p].currentAttrs[F]=L.getAttribute(F)}else if(_.type==="childList"){let F={breakpointId:p,selector:c,type:"subtree-modified",addedNodes:_.addedNodes.length,removedNodes:_.removedNodes.length,targetOuterHTML:L.outerHTML.substring(0,M),timestamp:Date.now()};I.__domBreakpointMutations.push(F),I.__domBreakpointMutations.length>k&&I.__domBreakpointMutations.shift()}}}),ie={attributes:b==="attribute-modified",attributeOldValue:b==="attribute-modified",childList:b==="subtree-modified"||b==="node-removed",subtree:b==="subtree-modified"};T&&(ie.attributeFilter=[T]),W.observe(f,ie),I.__domBreakpointObservers=I.__domBreakpointObservers||{},I.__domBreakpointObservers[p]=W},{selector:t.selector,breakpointId:u,type:t.type,attrName:t.attributeName,maxMutations:n.config.maxDOMMutations,maxHtmlSnippetLength:n.config.maxDOMHtmlSnippetLength}),m}s(Ui,"setDOMBreakpoint");async function cs(o,e,t){let n=ge(o);if(!n)return!1;let r=n.domBreakpoints.get(e);if(!r||!r.nodeId)return!1;try{let i=await n.v8Api.getCdp(),a=r.type==="subtree-modified"?"subtree-modified":r.type==="attribute-modified"?"attribute-modified":"node-removed";await i.send("DOMDebugger.removeDOMBreakpoint",{nodeId:r.nodeId,type:a})}catch{}if(t)try{await t.evaluate(i=>{let a=window;a.__domBreakpointObservers&&a.__domBreakpointObservers[i]&&(a.__domBreakpointObservers[i].disconnect(),delete a.__domBreakpointObservers[i]),a.__domBreakpointData&&delete a.__domBreakpointData[i],a.__domBreakpointMutations&&(a.__domBreakpointMutations=a.__domBreakpointMutations.filter(l=>l.breakpointId!==i))},e)}catch{}return n.domBreakpoints.delete(e)}s(cs,"removeDOMBreakpoint");function Ct(o){let e=ge(o);return e?Array.from(e.domBreakpoints.values()):[]}s(Ct,"listDOMBreakpoints");async function Hi(o,e){let t=ge(o);if(!t)return 0;let n=Array.from(t.domBreakpoints.keys());for(let r of n)await cs(o,r,e);return n.length}s(Hi,"clearDOMBreakpoints");async function Gl(o,e){if(o.networkInterceptionEnabled)return;let t=await o.v8Api.getCdp();await t.send("Fetch.enable",{patterns:[{urlPattern:"*",requestStage:"Request"}]}),t.on("Fetch.requestPaused",async r=>{let i=r.requestId,a=r.request.url,l=r.request.method;try{let u;for(let m of o.networkBreakpoints.values()){if(!m.enabled)continue;let c=m.urlPattern.replace(/\\([.*+?^${}()|[\]\\/-])/g,"$1");if(new RegExp(c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*")).test(a)&&!(m.method&&m.method.toUpperCase()!==l.toUpperCase())&&m.timing==="request"){u=m;break}}if(u&&u.timing==="request"){let m={url:a,method:l,requestHeaders:r.request.headers,requestBody:r.request.postData,resourceType:r.resourceType,timing:"request"},c={id:Ut(),probeId:u.id,timestamp:Date.now(),sequenceNumber:++o.snapshotSequence,url:a,lineNumber:0,networkRequest:m,callStack:[],captureTimeMs:0};o.watchExpressions.size>0&&(c.watchResults=await Ri(o,e)),o.snapshots.push(c),o.snapshots.length>o.config.maxSnapshots&&o.snapshots.splice(0,o.snapshots.length-o.config.maxSnapshots),u.hitCount++,u.lastHitAt=Date.now()}await t.send("Fetch.continueRequest",{requestId:i})}catch{try{await t.send("Fetch.continueRequest",{requestId:i})}catch{}}}),await t.send("Network.enable");let n=new Map;t.on("Network.requestWillBeSent",r=>{if(n.set(r.requestId,{method:r.request.method,postData:r.request.postData}),n.size>o.config.maxPendingRequests){let i=n.keys().next().value;i&&n.delete(i)}}),t.on("Network.responseReceived",async r=>{let i=r.requestId,a=r.response.url,l=n.get(i),u=l?.method||r.type||"GET",m=r.response.status;for(let c of o.networkBreakpoints.values()){if(!c.enabled||c.timing!=="response")continue;let p=c.urlPattern.replace(/\\([.*+?^${}()|[\]\\/-])/g,"$1");if(!new RegExp(p.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*")).test(a)||c.method&&c.method.toUpperCase()!==u.toUpperCase()||c.onError&&m<400)continue;let T;try{let f=await t.send("Network.getResponseBody",{requestId:i});f.base64Encoded?T=Buffer.from(f.body,"base64").toString("utf-8"):T=f.body,T&&T.length>o.config.maxResponseBodyLength&&(T=T.substring(0,o.config.maxResponseBodyLength)+"... [truncated]")}catch{}let k={url:a,method:u,requestBody:l?.postData,status:m,statusText:r.response.statusText,responseHeaders:r.response.headers,responseBody:T,resourceType:r.type,timing:"response"},M={id:Ut(),probeId:c.id,timestamp:Date.now(),sequenceNumber:++o.snapshotSequence,url:a,lineNumber:0,networkRequest:k,callStack:[],captureTimeMs:0};o.watchExpressions.size>0&&(M.watchResults=await Ri(o,e)),o.snapshots.push(M),o.snapshots.length>o.config.maxSnapshots&&o.snapshots.splice(0,o.snapshots.length-o.config.maxSnapshots),c.hitCount++,c.lastHitAt=Date.now(),n.delete(i);break}}),t.on("Network.loadingFinished",r=>{setTimeout(()=>{n.delete(r.requestId)},o.config.networkCleanupTimeoutMs)}),o.networkInterceptionEnabled=!0}s(Gl,"_enableNetworkInterception");async function Ri(o,e){let t={};for(let n of o.watchExpressions.values())try{let r=await e.evaluate(i=>{try{return(0,eval)(i)}catch(a){return`[Error: ${a.message}]`}},n.expression);t[n.expression]=r}catch(r){t[n.expression]=`[Error: ${r.message}]`}return t}s(Ri,"_evaluateWatchExpressions");async function qi(o,e,t){let n=ge(o);if(!n||!n.enabled)throw new Error("Debugging is not enabled");await Gl(n,e);let r=Ut(),i={id:r,urlPattern:t.urlPattern,method:t.method,timing:t.timing||"request",onError:t.onError,enabled:!0,hitCount:0,createdAt:Date.now()};return n.networkBreakpoints.set(r,i),i}s(qi,"setNetworkBreakpoint");function Wi(o,e){let t=ge(o);return t?t.networkBreakpoints.delete(e):!1}s(Wi,"removeNetworkBreakpoint");function vt(o){let e=ge(o);return e?Array.from(e.networkBreakpoints.values()):[]}s(vt,"listNetworkBreakpoints");function $i(o){let e=ge(o);if(!e)return 0;let t=e.networkBreakpoints.size;return e.networkBreakpoints.clear(),t}s($i,"clearNetworkBreakpoints");var Jn=class{static{s(this,"Status")}name(){return"debug_status"}description(){return`
265
+ `}inputSchema(){return{selector:bt.string().describe("CSS selector to limit the HTML content to a specific container.").optional(),removeScripts:bt.boolean().describe('Remove all script tags from the HTML (default: "true").').optional().default(!0),removeComments:bt.boolean().describe('Remove all HTML comments (default: "false").').optional().default(!1),removeStyles:bt.boolean().describe('Remove all style tags from the HTML (default: "false").').optional().default(!1),removeMeta:bt.boolean().describe('Remove all meta tags from the HTML (default: "false").').optional().default(!1),cleanHtml:bt.boolean().describe('Perform comprehensive HTML cleaning (default: "false").').optional().default(!1),minify:bt.boolean().describe('Minify the HTML output (default: "false").').optional().default(!1),maxLength:bt.number().int().positive().describe(`Maximum number of characters to return (default: "${Ni}").`).optional().default(Ni)}}outputSchema(){return{output:bt.string().describe("The requested HTML content of the page.")}}async handle(e,t){let{selector:n,removeScripts:r,removeComments:i,removeStyles:a,removeMeta:l,minify:u,cleanHtml:m,maxLength:c}=t,p;if(n){let U=await e.page.$(n);if(!U)throw new Error(`Element with selector "${n}" not found`);p=await U.evaluate(D=>D.outerHTML)}else p=await e.page.content();let b=r||m,f=i||m,x=a||m,B=l||m;(b||f||x||B||u)&&(p=await e.page.evaluate(U=>{let D=U.html,H=U.removeScripts,Q=U.removeComments,$=U.removeStyles,P=U.removeMeta,W=U.minify,G=document.createElement("template");G.innerHTML=D;let _=G.content;if(H&&_.querySelectorAll("script").forEach(M=>M.remove()),$&&_.querySelectorAll("style").forEach(M=>M.remove()),P&&_.querySelectorAll("meta").forEach(M=>M.remove()),Q){let Y=s(M=>{let ee=M.childNodes;for(let ue=ee.length-1;ue>=0;ue--){let ce=ee[ue];ce.nodeType===8?M.removeChild(ce):ce.nodeType===1&&Y(ce)}},"removeComments");Y(_)}let oe=G.innerHTML;return W&&(oe=oe.replace(/>\s+</g,"><").trim()),oe},{html:p,removeScripts:b,removeComments:f,removeStyles:x,removeMeta:B,minify:u}));let w=p;return w.length>c&&(w=w.slice(0,c)+`
266
+ <!-- Output truncated due to size limits -->`),{output:w}}};import{z as is}from"zod";var Pi=5e4,Wn=class{static{s(this,"GetAsText")}name(){return"content_get-as-text"}description(){return"Gets the visible text content of the current page."}inputSchema(){return{selector:is.string().describe("CSS selector to limit the text content to a specific container.").optional(),maxLength:is.number().int().positive().describe(`Maximum number of characters to return (default: "${Pi}").`).optional().default(Pi)}}outputSchema(){return{output:is.string().describe("The requested text content of the page.")}}async handle(e,t){let{selector:n,maxLength:r}=t,a=await e.page.evaluate(l=>{let u=l.selector,m=u?document.querySelector(u):document.body;if(!m)throw new Error(`Element with selector "${u}" not found`);let c=document.createTreeWalker(m,NodeFilter.SHOW_TEXT,{acceptNode:s(f=>{let x=window.getComputedStyle(f.parentElement);return x.display!=="none"&&x.visibility!=="hidden"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT},"acceptNode")}),p="",b;for(;b=c.nextNode();){let f=b.textContent?.trim();f&&(p+=f+`
267
+ `)}return p.trim()},{selector:n});return a.length>r&&(a=a.slice(0,r)+`
268
+ [Output truncated due to size limits]`),{output:a}}};function xe(o){let e=Object.keys(o).filter(t=>isNaN(Number(t))).map(t=>o[t]);if(e.length===0)throw new Error("Enum has no values");return e}s(xe,"getEnumKeyTuples");function rt(o,e){let t=Object.keys(o).filter(i=>isNaN(Number(i))).map(i=>o[i]),n=e?.caseInsensitive??!0,r=new Map(t.map(i=>[n?i.toLowerCase():i,i]));return i=>{let a=n?i.toLowerCase():i,l=r.get(a);if(l===void 0)throw new Error(`Invalid enum value: "${i}"`);return l}}s(rt,"createEnumTransformer");function qn(o=new Date){let e=s(t=>String(t).padStart(2,"0"),"pad");return o.getFullYear()+e(o.getMonth()+1)+e(o.getDate())+"-"+e(o.getHours())+e(o.getMinutes())+e(o.getSeconds())}s(qn,"formattedTimeForFilename");import Fl from"node:os";import Ul from"node:path";import{z as st}from"zod";var Ri=(r=>(r.PIXEL="px",r.INCH="in",r.CENTIMETER="cm",r.MILLIMETER="mm",r))(Ri||{}),$n=(p=>(p.LETTER="Letter",p.LEGAL="Legal",p.TABLOID="Tabloid",p.LEDGER="Ledger",p.A0="A0",p.A1="A1",p.A2="A2",p.A3="A3",p.A4="A4",p.A5="A5",p.A6="A6",p))($n||{}),as="page",Tt="1cm",Hl="A4",Wl={top:Tt,right:Tt,bottom:Tt,left:Tt},jn=class{static{s(this,"SaveAsPdf")}name(){return"content_save-as-pdf"}description(){return"Saves the current page as a PDF file."}inputSchema(){return{outputPath:st.string().describe("Directory path where PDF will be saved. By default OS tmp directory is used.").optional().default(Fl.tmpdir()),name:st.string().describe(`Name of the save/export. Default value is "${as}". Note that final saved/exported file name is in the "{name}-{time}.pdf" format in which "{time}" is in the "YYYYMMDD-HHmmss" format.`).optional().default(as),format:st.enum(xe($n)).transform(rt($n)).describe(`Page format. Valid values are: ${xe($n)}.`).optional().default(Hl),printBackground:st.boolean().describe('Whether to print background graphics (default: "false").').optional().default(!1),margin:st.object({top:st.string().describe("Top margin.").default(Tt),right:st.string().describe("Right margin.").default(Tt),bottom:st.string().describe("Bottom margin.").default(Tt),left:st.string().describe("Left margin.").default(Tt)}).describe(`Page margins. Numeric margin values labeled with units ("100px", "10cm", etc ...). Unlabeled values are treated as pixels. Valid units are: ${xe(Ri)}.`).optional()}}outputSchema(){return{filePath:st.string().describe("Full path of the saved PDF file.")}}async handle(e,t){let n=`${t.name||as}-${qn()}.pdf`,r=Ul.resolve(t.outputPath,n),i={path:r,format:t.format,printBackground:t.printBackground,margin:t.margin||Wl};return await e.page.pdf(i),{filePath:r}}};import ql from"node:os";import $l from"node:path";import zn from"jpeg-js";import{PNG as jl}from"pngjs";import{z as Xe}from"zod";var Vn=(t=>(t.PNG="png",t.JPEG="jpeg",t))(Vn||{}),ls="screenshot",ki="png",_i=100,Gn=class{static{s(this,"TakeScreenshot")}name(){return"content_take-screenshot"}description(){return`Takes a screenshot of the current page or a specific element.
269
+ The screenshot is ALWAYS saved to the file system; the file path is returned.
270
+ By default, image data is NOT included in the response (includeBase64 defaults to false).
271
+ **Prefer ARIA or AX tree snapshots for structure/layout/accessibility; use this tool only when you truly need to see the visual appearance of the UI.**
272
+ Do NOT set includeBase64 to true unless the assistant cannot read the file from the returned path (e.g. remote server, container). When in doubt, omit includeBase64 or set it to false.`}inputSchema(){return{outputPath:Xe.string().describe("Directory path where screenshot will be saved. By default OS tmp directory is used.").optional().default(ql.tmpdir()),name:Xe.string().describe(`Name of the screenshot. Default value is "${ls}". Note that final saved/exported file name is in the "{name}-{time}.{type}" format in which "{time}" is in the "YYYYMMDD-HHmmss" format.`).optional().default(ls),selector:Xe.string().describe("CSS selector for element to take screenshot.").optional(),fullPage:Xe.boolean().describe('Whether to take a screenshot of the full scrollable page, instead of the currently visible viewport (default: "false").').optional().default(!1),type:Xe.enum(xe(Vn)).transform(rt(Vn)).describe(`Page format. Valid values are: ${xe(Vn)}`).optional().default(ki),quality:Xe.number().int().min(0).max(_i).describe("The quality of the image, between 0-100. Not applicable to png images.").optional(),includeBase64:Xe.boolean().describe("If true, includes base64 image data in the response (increases payload size). Default is false. The screenshot is always saved to disk; use the returned file path to read it. Set to true ONLY when the assistant cannot access the MCP server file system (e.g. remote/container). Avoid setting to true otherwise.").optional().default(!1)}}outputSchema(){return{filePath:Xe.string().describe("Full path of the saved screenshot file."),image:Xe.object({data:Xe.any().describe("Base64-encoded image data."),mimeType:Xe.string().describe("MIME type of the image.")}).optional().describe('Image data included only when "includeBase64" input parameter is set to true.')}}_scaleImageToSize(e,t){let{data:n,width:r,height:i}=e,a=Math.max(1,Math.floor(t.width)),l=Math.max(1,Math.floor(t.height));if(r===a&&i===l)return e;if(r<=0||i<=0)throw new Error("Invalid input image");if(t.width<=0||t.height<=0||!isFinite(t.width)||!isFinite(t.height))throw new Error("Invalid output dimensions");let u=s(($,P,W)=>$<P?P:$>W?W:$,"clamp"),m=s(($,P)=>{let W=$*$,G=W*$;P[0]=-.5*$+1*W-.5*G,P[1]=1-2.5*W+1.5*G,P[2]=.5*$+2*W-1.5*G,P[3]=-.5*W+.5*G},"weights"),c=r*4,p=a*4,b=new Int32Array(a*4),f=new Float32Array(a*4),x=new Float32Array(4),B=r/a;for(let $=0;$<a;$++){let P=($+.5)*B-.5,W=Math.floor(P),G=P-W;m(G,x);let _=$*4,oe=u(W-1,0,r-1),Y=u(W+0,0,r-1),M=u(W+1,0,r-1),ee=u(W+2,0,r-1);b[_+0]=oe<<2,b[_+1]=Y<<2,b[_+2]=M<<2,b[_+3]=ee<<2,f[_+0]=x[0],f[_+1]=x[1],f[_+2]=x[2],f[_+3]=x[3]}let w=new Int32Array(l*4),U=new Float32Array(l*4),D=new Float32Array(4),H=i/l;for(let $=0;$<l;$++){let P=($+.5)*H-.5,W=Math.floor(P),G=P-W;m(G,D);let _=$*4,oe=u(W-1,0,i-1),Y=u(W+0,0,i-1),M=u(W+1,0,i-1),ee=u(W+2,0,i-1);w[_+0]=oe*c,w[_+1]=Y*c,w[_+2]=M*c,w[_+3]=ee*c,U[_+0]=D[0],U[_+1]=D[1],U[_+2]=D[2],U[_+3]=D[3]}let Q=new Uint8Array(a*l*4);for(let $=0;$<l;$++){let P=$*4,W=w[P+0],G=w[P+1],_=w[P+2],oe=w[P+3],Y=U[P+0],M=U[P+1],ee=U[P+2],ue=U[P+3],ce=$*p;for(let fe=0;fe<a;fe++){let te=fe*4,me=b[te+0],v=b[te+1],pe=b[te+2],V=b[te+3],q=f[te+0],X=f[te+1],Pe=f[te+2],Ie=f[te+3],ft=ce+(fe<<2);for(let J=0;J<4;J++){let Ce=n[W+me+J]*q+n[W+v+J]*X+n[W+pe+J]*Pe+n[W+V+J]*Ie,We=n[G+me+J]*q+n[G+v+J]*X+n[G+pe+J]*Pe+n[G+V+J]*Ie,Le=n[_+me+J]*q+n[_+v+J]*X+n[_+pe+J]*Pe+n[_+V+J]*Ie,un=n[oe+me+J]*q+n[oe+v+J]*X+n[oe+pe+J]*Pe+n[oe+V+J]*Ie,qe=Ce*Y+We*M+Le*ee+un*ue;Q[ft+J]=qe<0?0:qe>255?255:qe|0}}}return{data:Buffer.from(Q.buffer),width:a,height:l}}_scaleImageToFitMessage(e,t){let r=12058624e-1,i=1568,a=t==="png"?jl.sync.read(e):zn.decode(e,{maxMemoryUsageInMB:512}),l=a.width*a.height,u=Math.min(i/a.width,i/a.height,Math.sqrt(r/l));u>1&&(u=1);let m=a.width*u|0,c=a.height*u|0,p=this._scaleImageToSize(a,{width:m,height:c}),b,f=t,x=t==="png"?75:70;t==="png"?(b=zn.encode(p,x).data,f="jpeg"):b=zn.encode(p,x).data;let B=0,w=5;for(;b.length>819200&&B<w;)x=Math.max(50,x-10),x<=50&&b.length>819200&&(u*=.85,m=Math.max(200,a.width*u|0),c=Math.max(200,a.height*u|0),p=this._scaleImageToSize(a,{width:m,height:c})),b=zn.encode(p,x).data,B++;return b}async handle(e,t){let n=t.type||ki,r=`${t.name||ls}-${qn()}.${n}`,i=$l.resolve(t.outputPath,r),a=n==="png"?void 0:t.quality??_i,l={path:i,type:n,fullPage:!!t.fullPage,quality:a};if(t.selector){let c=await e.page.$(t.selector);if(!c)throw new Error(`Element not found: ${t.selector}`);l.element=c}let u=await e.page.screenshot(l),m={filePath:i};return t.includeBase64&&(m.image={data:this._scaleImageToFitMessage(u,n),mimeType:`image/${n}`}),m}};var Mi=[new Hn,new Wn,new jn,new Gn];import{z as Re}from"zod";var us={maxSnapshots:1e3,maxCallStackDepth:20,maxFramesWithScopes:5,maxAsyncStackSegments:10,maxFramesPerAsyncSegment:10,maxDOMMutations:100,maxDOMHtmlSnippetLength:200,maxPendingRequests:1e3,maxResponseBodyLength:1e4,networkCleanupTimeoutMs:5e3},cs=new WeakMap;function Ft(){let o=Date.now(),e=Math.floor(Math.random()*1e6);return`${o.toString(36)}-${e.toString(36)}`}s(Ft,"_generateId");function zl(o,e){try{let t=o.trim();return/^[=<>!%]/.test(t)&&(t=`hitCount ${t}`),!!new Function("hitCount",`return (${t});`)(e)}catch{return!1}}s(zl,"_evaluateHitCondition");async function Vl(o,e,t){let n={};for(let r of t.values())try{let i=await o.evaluateOnCallFrame(e,r.expression);if(i.exceptionDetails)n[r.expression]=`[Error: ${i.exceptionDetails.text||"Evaluation failed"}]`;else{let a=await o.extractValueDeep(i.result,2);n[r.expression]=a}}catch(i){n[r.expression]=`[Error: ${i.message||"Unknown error"}]`}return n}s(Vl,"_evaluateWatchExpressionsOnFrame");function Bi(o,e,t,n){let r=cs.get(o);if(r)return r;let i=new ni(e,t),a=new oi(e),l={...us,...n},u={v8Api:i,sourceMapResolver:a,probes:new Map,watchExpressions:new Map,domBreakpoints:new Map,networkBreakpoints:new Map,snapshots:[],snapshotSequence:0,config:l,enabled:!1,sourceMapsLoaded:!1,exceptionBreakpoint:"none",networkInterceptionEnabled:!1,recentDOMMutations:[]};return cs.set(o,u),u}s(Bi,"_ensureStore");function ge(o){return cs.get(o)}s(ge,"_getStore");async function Gl(o,e,t=3){let n=[];for(let r of e.scopeChain)if(!(r.type==="global"||r.type==="script"||r.type==="with"||r.type==="eval"||r.type==="wasm-expression-stack")){if(n.length>=t)break;try{let i=await o.getScopeVariables(r),a=[];for(let[l,u]of Object.entries(i))a.push({name:l,value:u,type:typeof u});n.push({type:r.type,name:r.name,variables:a})}catch{}}return n}s(Gl,"_captureScopes");async function Kl(o,e,t,n){let r=[];t&&(r=await Gl(o,e));let i;if(n){let a=n.generatedToOriginal(e.location.scriptId,e.location.lineNumber,e.location.columnNumber??0);a&&(i={source:a.source,line:a.line+1,column:a.column!==void 0?a.column+1:void 0,name:a.name})}return{functionName:e.functionName||"(anonymous)",url:e.url||"",lineNumber:e.location.lineNumber+1,columnNumber:e.location.columnNumber!==void 0?e.location.columnNumber+1:void 0,scriptId:e.location.scriptId,scopes:r,originalLocation:i}}s(Kl,"_callFrameToSnapshot");function Xl(o,e,t,n){if(!o)return;let r=t??us.maxAsyncStackSegments,i=n??us.maxFramesPerAsyncSegment,a=[],l=o,u=0;for(;l&&u<r;){let m=[];for(let c of l.callFrames.slice(0,i)){let p;if(e){let b=e.generatedToOriginal(c.location.scriptId,c.location.lineNumber,c.location.columnNumber??0);b&&(p={source:b.source,line:b.line+1,column:b.column!==void 0?b.column+1:void 0,name:b.name})}m.push({functionName:c.functionName||"(anonymous)",url:c.url||"",lineNumber:c.location.lineNumber+1,columnNumber:c.location.columnNumber!==void 0?c.location.columnNumber+1:void 0,originalLocation:p})}m.length>0&&a.push({description:l.description,callFrames:m}),l=l.parent,u++}if(a.length!==0)return{segments:a}}s(Xl,"_convertAsyncStackTrace");async function Ue(o,e,t){let n=Bi(o,e,t?.v8Options,t?.config);if(!n.enabled){await n.v8Api.enable(),n.v8Api.on("scriptParsed",r=>{n.sourceMapResolver.registerScript(r)});for(let r of n.v8Api.getScripts())n.sourceMapResolver.registerScript(r);n.v8Api.on("paused",async r=>{let i=Date.now();try{let a=r.reason==="exception"||r.reason==="promiseRejection",l=r.reason==="DOM",u=r.hitBreakpoints||[],m,c=!0,p,b;if(l&&r.data){let w=r.data;for(let U of n.domBreakpoints.values())if(U.enabled&&(U.nodeId===w.nodeId||!w.nodeId)){p=U,b={type:U.type,selector:U.selector,targetNode:w.targetNode?`<${w.targetNode.nodeName?.toLowerCase()||"unknown"}>`:void 0,attributeName:w.attributeName||U.attributeName};break}}if(p&&b)try{let w=await e.evaluate(U=>{let D=window;if(!D.__domBreakpointMutations)return null;let H=D.__domBreakpointMutations;for(let Q=H.length-1;Q>=0;Q--)if(H[Q].breakpointId===U)return H[Q];return null},p.id);w&&(b.oldValue=w.oldValue,b.newValue=w.newValue,b.targetNode=w.targetOuterHTML,w.attributeName&&(b.attributeName=w.attributeName))}catch{}for(let w of n.probes.values()){if(!w.enabled)continue;if(w.v8BreakpointIds.some(D=>u.includes(D))){m=w,w.hitCondition&&(c=zl(w.hitCondition,w.hitCount+1));break}}let f=m!==void 0&&c,x=a&&n.exceptionBreakpoint!=="none",B=p!==void 0;if(m&&(m.hitCount++,m.lastHitAt=Date.now()),p&&(p.hitCount++,p.lastHitAt=Date.now()),(f||x||B)&&r.callFrames.length>0){let w=r.callFrames[0],U;if(m&&m.kind==="logpoint"&&m.logExpression)try{let Y=await n.v8Api.evaluateOnCallFrame(w.callFrameId,m.logExpression,{returnByValue:!0,generatePreview:!0});U=n.v8Api.extractValue(Y.result)}catch{U="[evaluation error]"}let D;if(a&&r.data){let Y=r.data;D={type:r.reason==="promiseRejection"?"promiseRejection":"exception",message:Y.description||Y.value||String(Y),name:Y.className,stack:Y.description}}let H,Q=n.sourceMapResolver.generatedToOriginal(w.location.scriptId,w.location.lineNumber,w.location.columnNumber??0);Q&&(H={source:Q.source,line:Q.line+1,column:Q.column!==void 0?Q.column+1:void 0,name:Q.name});let $=m?.id??p?.id??"__exception__",P=m?.kind==="logpoint",W=[];if(!P){let Y=r.callFrames.slice(0,n.config.maxCallStackDepth);for(let M=0;M<Y.length;M++){let ee=Y[M],ue=M<n.config.maxFramesWithScopes,ce=await Kl(n.v8Api,ee,ue,n.sourceMapResolver);W.push(ce)}}let G;P||(G=Xl(r.asyncStackTrace,n.sourceMapResolver,n.config.maxAsyncStackSegments,n.config.maxFramesPerAsyncSegment));let _;!P&&n.watchExpressions.size>0&&(_=await Vl(n.v8Api,w.callFrameId,n.watchExpressions));let oe={id:Ft(),probeId:$,timestamp:Date.now(),sequenceNumber:++n.snapshotSequence,url:w.url||"",lineNumber:w.location.lineNumber+1,columnNumber:w.location.columnNumber!==void 0?w.location.columnNumber+1:void 0,originalLocation:H,exception:D,domChange:b,callStack:W,asyncStackTrace:G,logResult:U,watchResults:_,captureTimeMs:Date.now()-i};n.snapshots.push(oe),n.snapshots.length>n.config.maxSnapshots&&n.snapshots.splice(0,n.snapshots.length-n.config.maxSnapshots)}}finally{await n.v8Api.resume()}}),n.enabled=!0,n.sourceMapResolver.loadAllSourceMaps().then(()=>{n.sourceMapsLoaded=!0}).catch(()=>{})}}s(Ue,"enableDebugging");function N(o){return ge(o)?.enabled??!1}s(N,"isDebuggingEnabled");async function Ai(o,e,t,n,r=1){let i=Bi(o,e);i.enabled||await Ue(o,e);let a=await i.sourceMapResolver.resolveLocationByUrl(t,n,r);return a?{source:a.source,line:a.line+1,column:a.column+1,name:a.name}:null}s(Ai,"resolveSourceLocation");async function Li(o,e){let t=ge(o);if(!t||!t.enabled)throw new Error("Debugging is not enabled");await t.v8Api.setPauseOnExceptions(e),t.exceptionBreakpoint=e}s(Li,"setExceptionBreakpoint");function fn(o){return ge(o)?.exceptionBreakpoint??"none"}s(fn,"getExceptionBreakpoint");function Fi(o){return ge(o)?.sourceMapResolver.hasSourceMaps()??!1}s(Fi,"hasSourceMaps");async function Kn(o,e){let t=ge(o);if(!t||!t.enabled)throw new Error("Debugging is not enabled");let n=Ft(),r;e.condition?r=`(${e.condition})`:r="true";let i=e.lineNumber-1,a=(e.columnNumber??1)-1,l=t.sourceMapResolver.originalToGenerated(e.urlPattern,i,a),u,m=0;if(l)u=(await t.v8Api.setBreakpoint({scriptId:l.scriptId,lineNumber:l.location.line,columnNumber:l.location.column},r)).breakpointId,m=1;else{let b=e.urlPattern.replace(/\\([.*+?^${}()|[\]\\/-])/g,"$1").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*").replace(/\\\?/g,"."),f=await t.v8Api.setBreakpointByUrl({urlRegex:b,lineNumber:e.lineNumber-1,columnNumber:e.columnNumber?e.columnNumber-1:void 0,condition:r});u=f.breakpointId,m=f.locations.length}let c={id:n,kind:e.kind,enabled:!0,urlPattern:e.urlPattern,lineNumber:e.lineNumber,columnNumber:e.columnNumber,condition:e.condition,logExpression:e.logExpression,hitCondition:e.hitCondition,v8BreakpointIds:[u],resolvedLocations:m,hitCount:0,createdAt:Date.now()};return t.probes.set(n,c),c}s(Kn,"createProbe");async function St(o,e){let t=ge(o);if(!t)return!1;let n=t.probes.get(e);if(!n)return!1;for(let r of n.v8BreakpointIds)try{await t.v8Api.removeBreakpoint(r)}catch{}return t.probes.delete(e),!0}s(St,"removeProbe");function ve(o){let e=ge(o);return e?Array.from(e.probes.values()):[]}s(ve,"listProbes");function Xn(o,e){let t=ge(o);if(t)return t.probes.get(e)}s(Xn,"getProbe");function xt(o){let e=ge(o);return e?[...e.snapshots]:[]}s(xt,"getSnapshots");function it(o,e){let t=ge(o);return t?t.snapshots.filter(n=>n.probeId===e):[]}s(it,"getSnapshotsByProbe");function De(o,e){let t=ge(o);if(!t)return 0;let n=t.snapshots.length;return t.snapshots=t.snapshots.filter(r=>r.probeId!==e),n-t.snapshots.length}s(De,"clearSnapshotsByProbe");function Ui(o){let e=ge(o);if(!e||e.snapshots.length===0)return{totalSnapshots:0,snapshotsByProbe:{},averageCaptureTimeMs:0};let t={},n=0;for(let r of e.snapshots)t[r.probeId]=(t[r.probeId]||0)+1,n+=r.captureTimeMs;return{totalSnapshots:e.snapshots.length,snapshotsByProbe:t,oldestTimestamp:e.snapshots[0].timestamp,newestTimestamp:e.snapshots[e.snapshots.length-1].timestamp,averageCaptureTimeMs:n/e.snapshots.length}}s(Ui,"getSnapshotStats");function Hi(o,e){let t=ge(o);if(!t)throw new Error("Debug store not initialized");let n=Ft(),r={id:n,expression:e,createdAt:Date.now()};return t.watchExpressions.set(n,r),r}s(Hi,"addWatchExpression");function Wi(o,e){let t=ge(o);return t?t.watchExpressions.delete(e):!1}s(Wi,"removeWatchExpression");function Yn(o){let e=ge(o);return e?Array.from(e.watchExpressions.values()):[]}s(Yn,"listWatchExpressions");function qi(o){let e=ge(o);if(!e)return 0;let t=e.watchExpressions.size;return e.watchExpressions.clear(),t}s(qi,"clearWatchExpressions");async function $i(o,e,t){let n=ge(o);if(!n||!n.enabled)throw new Error("Debugging is not enabled");let r=await n.v8Api.getCdp();await r.send("DOM.enable");let{root:i}=await r.send("DOM.getDocument",{depth:0}),{nodeId:a}=await r.send("DOM.querySelector",{nodeId:i.nodeId,selector:t.selector});if(!a||a===0)throw new Error(`Element not found: ${t.selector}`);let l=t.type==="subtree-modified"?"subtree-modified":t.type==="attribute-modified"?"attribute-modified":"node-removed";await r.send("DOMDebugger.setDOMBreakpoint",{nodeId:a,type:l});let u=Ft(),m={id:u,selector:t.selector,type:t.type,attributeName:t.attributeName,enabled:!0,nodeId:a,hitCount:0,createdAt:Date.now()};return n.domBreakpoints.set(u,m),await e.evaluate(c=>{let p=c.selector,b=c.breakpointId,f=c.type,x=c.attrName,B=c.maxMutations,w=c.maxHtmlSnippetLength,U=document.querySelector(p);if(!U)return;let D=window;D.__domBreakpointData=D.__domBreakpointData||{},D.__domBreakpointMutations=D.__domBreakpointMutations||[],D.__domBreakpointData[b]={selector:p,type:f,attrName:x,currentAttrs:{}};for(let $ of U.attributes)D.__domBreakpointData[b].currentAttrs[$.name]=$.value;let H=new MutationObserver($=>{for(let P of $){let W=P.target;if(P.type==="attributes"){let G=P.attributeName||"";if(x&&x!==G)continue;let _={breakpointId:b,selector:p,type:"attribute-modified",attributeName:G,oldValue:P.oldValue,newValue:W.getAttribute(G),targetOuterHTML:W.outerHTML.substring(0,w),timestamp:Date.now()};D.__domBreakpointMutations.push(_),D.__domBreakpointMutations.length>B&&D.__domBreakpointMutations.shift(),D.__domBreakpointData[b].currentAttrs[G]=W.getAttribute(G)}else if(P.type==="childList"){let G={breakpointId:b,selector:p,type:"subtree-modified",addedNodes:P.addedNodes.length,removedNodes:P.removedNodes.length,targetOuterHTML:W.outerHTML.substring(0,w),timestamp:Date.now()};D.__domBreakpointMutations.push(G),D.__domBreakpointMutations.length>B&&D.__domBreakpointMutations.shift()}}}),Q={attributes:f==="attribute-modified",attributeOldValue:f==="attribute-modified",childList:f==="subtree-modified"||f==="node-removed",subtree:f==="subtree-modified"};x&&(Q.attributeFilter=[x]),H.observe(U,Q),D.__domBreakpointObservers=D.__domBreakpointObservers||{},D.__domBreakpointObservers[b]=H},{selector:t.selector,breakpointId:u,type:t.type,attrName:t.attributeName,maxMutations:n.config.maxDOMMutations,maxHtmlSnippetLength:n.config.maxDOMHtmlSnippetLength}),m}s($i,"setDOMBreakpoint");async function ms(o,e,t){let n=ge(o);if(!n)return!1;let r=n.domBreakpoints.get(e);if(!r||!r.nodeId)return!1;try{let i=await n.v8Api.getCdp(),a=r.type==="subtree-modified"?"subtree-modified":r.type==="attribute-modified"?"attribute-modified":"node-removed";await i.send("DOMDebugger.removeDOMBreakpoint",{nodeId:r.nodeId,type:a})}catch{}if(t)try{await t.evaluate(i=>{let a=window;a.__domBreakpointObservers&&a.__domBreakpointObservers[i]&&(a.__domBreakpointObservers[i].disconnect(),delete a.__domBreakpointObservers[i]),a.__domBreakpointData&&delete a.__domBreakpointData[i],a.__domBreakpointMutations&&(a.__domBreakpointMutations=a.__domBreakpointMutations.filter(l=>l.breakpointId!==i))},e)}catch{}return n.domBreakpoints.delete(e)}s(ms,"removeDOMBreakpoint");function vt(o){let e=ge(o);return e?Array.from(e.domBreakpoints.values()):[]}s(vt,"listDOMBreakpoints");async function ji(o,e){let t=ge(o);if(!t)return 0;let n=Array.from(t.domBreakpoints.keys());for(let r of n)await ms(o,r,e);return n.length}s(ji,"clearDOMBreakpoints");async function Yl(o,e){if(o.networkInterceptionEnabled)return;let t=await o.v8Api.getCdp();await t.send("Fetch.enable",{patterns:[{urlPattern:"*",requestStage:"Request"}]}),t.on("Fetch.requestPaused",async r=>{let i=r.requestId,a=r.request.url,l=r.request.method;try{let u;for(let m of o.networkBreakpoints.values()){if(!m.enabled)continue;let c=m.urlPattern.replace(/\\([.*+?^${}()|[\]\\/-])/g,"$1");if(new RegExp(c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*")).test(a)&&!(m.method&&m.method.toUpperCase()!==l.toUpperCase())&&m.timing==="request"){u=m;break}}if(u&&u.timing==="request"){let m={url:a,method:l,requestHeaders:r.request.headers,requestBody:r.request.postData,resourceType:r.resourceType,timing:"request"},c={id:Ft(),probeId:u.id,timestamp:Date.now(),sequenceNumber:++o.snapshotSequence,url:a,lineNumber:0,networkRequest:m,callStack:[],captureTimeMs:0};o.watchExpressions.size>0&&(c.watchResults=await Di(o,e)),o.snapshots.push(c),o.snapshots.length>o.config.maxSnapshots&&o.snapshots.splice(0,o.snapshots.length-o.config.maxSnapshots),u.hitCount++,u.lastHitAt=Date.now()}await t.send("Fetch.continueRequest",{requestId:i})}catch{try{await t.send("Fetch.continueRequest",{requestId:i})}catch{}}}),await t.send("Network.enable");let n=new Map;t.on("Network.requestWillBeSent",r=>{if(n.set(r.requestId,{method:r.request.method,postData:r.request.postData}),n.size>o.config.maxPendingRequests){let i=n.keys().next().value;i&&n.delete(i)}}),t.on("Network.responseReceived",async r=>{let i=r.requestId,a=r.response.url,l=n.get(i),u=l?.method||r.type||"GET",m=r.response.status;for(let c of o.networkBreakpoints.values()){if(!c.enabled||c.timing!=="response")continue;let p=c.urlPattern.replace(/\\([.*+?^${}()|[\]\\/-])/g,"$1");if(!new RegExp(p.replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/\\\*/g,".*")).test(a)||c.method&&c.method.toUpperCase()!==u.toUpperCase()||c.onError&&m<400)continue;let f;try{let w=await t.send("Network.getResponseBody",{requestId:i});w.base64Encoded?f=Buffer.from(w.body,"base64").toString("utf-8"):f=w.body,f&&f.length>o.config.maxResponseBodyLength&&(f=f.substring(0,o.config.maxResponseBodyLength)+"... [truncated]")}catch{}let x={url:a,method:u,requestBody:l?.postData,status:m,statusText:r.response.statusText,responseHeaders:r.response.headers,responseBody:f,resourceType:r.type,timing:"response"},B={id:Ft(),probeId:c.id,timestamp:Date.now(),sequenceNumber:++o.snapshotSequence,url:a,lineNumber:0,networkRequest:x,callStack:[],captureTimeMs:0};o.watchExpressions.size>0&&(B.watchResults=await Di(o,e)),o.snapshots.push(B),o.snapshots.length>o.config.maxSnapshots&&o.snapshots.splice(0,o.snapshots.length-o.config.maxSnapshots),c.hitCount++,c.lastHitAt=Date.now(),n.delete(i);break}}),t.on("Network.loadingFinished",r=>{setTimeout(()=>{n.delete(r.requestId)},o.config.networkCleanupTimeoutMs)}),o.networkInterceptionEnabled=!0}s(Yl,"_enableNetworkInterception");async function Di(o,e){let t={};for(let n of o.watchExpressions.values())try{let r=await e.evaluate(i=>{try{return(0,eval)(i)}catch(a){return`[Error: ${a.message}]`}},n.expression);t[n.expression]=r}catch(r){t[n.expression]=`[Error: ${r.message}]`}return t}s(Di,"_evaluateWatchExpressions");async function zi(o,e,t){let n=ge(o);if(!n||!n.enabled)throw new Error("Debugging is not enabled");await Yl(n,e);let r=Ft(),i={id:r,urlPattern:t.urlPattern,method:t.method,timing:t.timing||"request",onError:t.onError,enabled:!0,hitCount:0,createdAt:Date.now()};return n.networkBreakpoints.set(r,i),i}s(zi,"setNetworkBreakpoint");function Vi(o,e){let t=ge(o);return t?t.networkBreakpoints.delete(e):!1}s(Vi,"removeNetworkBreakpoint");function It(o){let e=ge(o);return e?Array.from(e.networkBreakpoints.values()):[]}s(It,"listNetworkBreakpoints");function Gi(o){let e=ge(o);if(!e)return 0;let t=e.networkBreakpoints.size;return e.networkBreakpoints.clear(),t}s(Gi,"clearNetworkBreakpoints");var Jn=class{static{s(this,"Status")}name(){return"debug_status"}description(){return`
274
273
  Returns the current debugging status including:
275
274
  - Whether debugging is enabled
276
275
  - Source map status
277
276
  - Exceptionpoint state
278
277
  - Count of tracepoints, logpoints, watches, dompoints and netpoints
279
278
  - Snapshot statistics
280
- `}inputSchema(){return{}}outputSchema(){return{enabled:Re.boolean().describe("Whether debugging is enabled"),hasSourceMaps:Re.boolean().describe("Whether source maps are loaded"),exceptionBreakpoint:Re.string().describe("Exceptionpoint state (none, uncaught, all)"),tracepointCount:Re.number().describe("Number of tracepoints"),logpointCount:Re.number().describe("Number of logpoints"),watchExpressionCount:Re.number().describe("Number of watch expressions"),dompointCount:Re.number().describe("Number of dompoints"),netpointCount:Re.number().describe("Number of netpoints"),snapshotStats:Re.object({totalSnapshots:Re.number(),snapshotsByProbe:Re.record(Re.number()),oldestTimestamp:Re.number().optional(),newestTimestamp:Re.number().optional(),averageCaptureTimeMs:Re.number()}).nullable().describe("Snapshot statistics")}}async handle(e,t){if(!N(e.browserContext))return{enabled:!1,hasSourceMaps:!1,exceptionBreakpoint:"none",tracepointCount:0,logpointCount:0,watchExpressionCount:0,dompointCount:0,netpointCount:0,snapshotStats:null};let r=Se(e.browserContext),i=r.filter(l=>l.kind==="tracepoint").length,a=r.filter(l=>l.kind==="logpoint").length;return{enabled:!0,hasSourceMaps:Di(e.browserContext),exceptionBreakpoint:gn(e.browserContext),tracepointCount:i,logpointCount:a,watchExpressionCount:Xn(e.browserContext).length,dompointCount:Ct(e.browserContext).length,netpointCount:vt(e.browserContext).length,snapshotStats:Bi(e.browserContext)}}};import{z as Ot}from"zod";var Yn=class{static{s(this,"ResolveSourceLocation")}name(){return"debug_resolve-source-location"}description(){return`
279
+ `}inputSchema(){return{}}outputSchema(){return{enabled:Re.boolean().describe("Whether debugging is enabled"),hasSourceMaps:Re.boolean().describe("Whether source maps are loaded"),exceptionBreakpoint:Re.string().describe("Exceptionpoint state (none, uncaught, all)"),tracepointCount:Re.number().describe("Number of tracepoints"),logpointCount:Re.number().describe("Number of logpoints"),watchExpressionCount:Re.number().describe("Number of watch expressions"),dompointCount:Re.number().describe("Number of dompoints"),netpointCount:Re.number().describe("Number of netpoints"),snapshotStats:Re.object({totalSnapshots:Re.number(),snapshotsByProbe:Re.record(Re.number()),oldestTimestamp:Re.number().optional(),newestTimestamp:Re.number().optional(),averageCaptureTimeMs:Re.number()}).nullable().describe("Snapshot statistics")}}async handle(e,t){if(!N(e.browserContext))return{enabled:!1,hasSourceMaps:!1,exceptionBreakpoint:"none",tracepointCount:0,logpointCount:0,watchExpressionCount:0,dompointCount:0,netpointCount:0,snapshotStats:null};let r=ve(e.browserContext),i=r.filter(l=>l.kind==="tracepoint").length,a=r.filter(l=>l.kind==="logpoint").length;return{enabled:!0,hasSourceMaps:Fi(e.browserContext),exceptionBreakpoint:fn(e.browserContext),tracepointCount:i,logpointCount:a,watchExpressionCount:Yn(e.browserContext).length,dompointCount:vt(e.browserContext).length,netpointCount:It(e.browserContext).length,snapshotStats:Ui(e.browserContext)}}};import{z as Ct}from"zod";var Qn=class{static{s(this,"ResolveSourceLocation")}name(){return"debug_resolve-source-location"}description(){return`
281
280
  Resolves a generated/bundled code location to its original source via source maps.
282
281
  Useful for translating minified stack traces or bundle line numbers to original TypeScript/JavaScript source.
283
282
 
284
283
  Requires a page with debugging context (debugging is auto-enabled on first use).
285
284
  Input: generated script URL, line, column (1-based).
286
285
  Output: original source path, line, column when a source map is available.
287
- `}inputSchema(){return{url:Ot.string().describe("Generated script URL (e.g. https://example.com/bundle.js or relative path)"),line:Ot.number().int().positive().describe("Line number in generated code (1-based)"),column:Ot.number().int().nonnegative().describe("Column number in generated code (1-based, default 1)").optional()}}outputSchema(){return{resolved:Ot.boolean().describe("Whether the location was resolved to original source"),source:Ot.string().optional().describe("Original source file path"),line:Ot.number().optional().describe("Line number in original source (1-based)"),column:Ot.number().optional().describe("Column number in original source (1-based)"),name:Ot.string().optional().describe("Original identifier name if available")}}async handle(e,t){let n=await _i(e.browserContext,e.page,t.url,t.line,t.column??1);return n?{resolved:!0,source:n.source,line:n.line,column:n.column,name:n.name}:{resolved:!1}}};import{z as $e}from"zod";var Qn=class{static{s(this,"PutTracepoint")}name(){return"debug_put-tracepoint"}description(){return`
286
+ `}inputSchema(){return{url:Ct.string().describe("Generated script URL (e.g. https://example.com/bundle.js or relative path)"),line:Ct.number().int().positive().describe("Line number in generated code (1-based)"),column:Ct.number().int().nonnegative().describe("Column number in generated code (1-based, default 1)").optional()}}outputSchema(){return{resolved:Ct.boolean().describe("Whether the location was resolved to original source"),source:Ct.string().optional().describe("Original source file path"),line:Ct.number().optional().describe("Line number in original source (1-based)"),column:Ct.number().optional().describe("Column number in original source (1-based)"),name:Ct.string().optional().describe("Original identifier name if available")}}async handle(e,t){let n=await Ai(e.browserContext,e.page,t.url,t.line,t.column??1);return n?{resolved:!0,source:n.source,line:n.line,column:n.column,name:n.name}:{resolved:!1}}};import{z as ze}from"zod";var Zn=class{static{s(this,"PutTracepoint")}name(){return"debug_put-tracepoint"}description(){return`
288
287
  Puts a non-blocking tracepoint at the specified location.
289
288
  When hit, a snapshot of the call stack and local variables is captured
290
289
  automatically without pausing execution.
@@ -298,7 +297,7 @@ DO NOT escape characters yourself (e.g., don't use "app\\.js").
298
297
 
299
298
  Returns resolvedLocations: number of scripts where the tracepoint was set.
300
299
  If 0, the pattern didn't match any loaded scripts.
301
- `}inputSchema(){return{urlPattern:$e.string().describe('Script URL pattern (e.g., "app.js"). Auto-escaped, do not add backslashes.'),lineNumber:$e.number().int().positive().describe("Line number (1-based)"),columnNumber:$e.number().int().nonnegative().describe("Column number (1-based). Optional.").optional(),condition:$e.string().describe("Conditional expression - only triggers if this evaluates to true").optional(),hitCondition:$e.string().describe('Hit count condition, e.g., "== 5" (5th hit), ">= 10" (10th and after), "% 10 == 0" (every 10th)').optional()}}outputSchema(){return{id:$e.string().describe("Tracepoint ID"),urlPattern:$e.string().describe("URL pattern"),lineNumber:$e.number().describe("Line number"),columnNumber:$e.number().optional().describe("Column number"),condition:$e.string().optional().describe("Condition expression"),hitCondition:$e.string().optional().describe("Hit count condition"),resolvedLocations:$e.number().describe("Number of locations where tracepoint was resolved")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=await Gn(e.browserContext,{kind:"tracepoint",urlPattern:t.urlPattern,lineNumber:t.lineNumber,columnNumber:t.columnNumber,condition:t.condition,hitCondition:t.hitCondition});return{id:n.id,urlPattern:n.urlPattern,lineNumber:n.lineNumber,columnNumber:n.columnNumber,condition:n.condition,hitCondition:n.hitCondition,resolvedLocations:n.resolvedLocations}}};import{z as ms}from"zod";var Zn=class{static{s(this,"RemoveTracepoint")}name(){return"debug_remove-tracepoint"}description(){return"Removes a tracepoint by its ID."}inputSchema(){return{id:ms.string().describe("Tracepoint ID to remove")}}outputSchema(){return{success:ms.boolean().describe("Whether the tracepoint was removed"),message:ms.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{success:!1,message:"No active tracepoints"};let n=Kn(e.browserContext,t.id);if(!n||n.kind!=="tracepoint")return{success:!1,message:`Tracepoint ${t.id} not found`};let r=await xt(e.browserContext,t.id);return{success:r,message:r?`Tracepoint ${t.id} removed`:"Failed to remove tracepoint"}}};import{z as He}from"zod";var eo=class{static{s(this,"ListTracepoints")}name(){return"debug_list-tracepoints"}description(){return"Lists all active tracepoints."}inputSchema(){return{}}outputSchema(){return{tracepoints:He.array(He.object({id:He.string(),urlPattern:He.string(),lineNumber:He.number(),columnNumber:He.number().optional(),condition:He.string().optional(),hitCondition:He.string().optional(),enabled:He.boolean(),resolvedLocations:He.number(),hitCount:He.number(),lastHitAt:He.number().optional()})).describe("List of tracepoints"),total:He.number().describe("Total count")}}async handle(e,t){if(!N(e.browserContext))return{tracepoints:[],total:0};let r=Se(e.browserContext).filter(i=>i.kind==="tracepoint").map(i=>({id:i.id,urlPattern:i.urlPattern,lineNumber:i.lineNumber,columnNumber:i.columnNumber,condition:i.condition,hitCondition:i.hitCondition,enabled:i.enabled,resolvedLocations:i.resolvedLocations,hitCount:i.hitCount,lastHitAt:i.lastHitAt}));return{tracepoints:r,total:r.length}}};import{z as ji}from"zod";var to=class{static{s(this,"ClearTracepoints")}name(){return"debug_clear-tracepoints"}description(){return"Removes all tracepoints."}inputSchema(){return{}}outputSchema(){return{clearedCount:ji.number().describe("Number of tracepoints cleared"),message:ji.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No tracepoints to clear"};let n=Se(e.browserContext).filter(i=>i.kind==="tracepoint"),r=0;for(let i of n)await xt(e.browserContext,i.id)&&r++;return{clearedCount:r,message:`Cleared ${r} tracepoint(s)`}}};import{z as Ae}from"zod";var no=class{static{s(this,"PutLogpoint")}name(){return"debug_put-logpoint"}description(){return`
300
+ `}inputSchema(){return{urlPattern:ze.string().describe('Script URL pattern (e.g., "app.js"). Auto-escaped, do not add backslashes.'),lineNumber:ze.number().int().positive().describe("Line number (1-based)"),columnNumber:ze.number().int().nonnegative().describe("Column number (1-based). Optional.").optional(),condition:ze.string().describe("Conditional expression - only triggers if this evaluates to true").optional(),hitCondition:ze.string().describe('Hit count condition, e.g., "== 5" (5th hit), ">= 10" (10th and after), "% 10 == 0" (every 10th)').optional()}}outputSchema(){return{id:ze.string().describe("Tracepoint ID"),urlPattern:ze.string().describe("URL pattern"),lineNumber:ze.number().describe("Line number"),columnNumber:ze.number().optional().describe("Column number"),condition:ze.string().optional().describe("Condition expression"),hitCondition:ze.string().optional().describe("Hit count condition"),resolvedLocations:ze.number().describe("Number of locations where tracepoint was resolved")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=await Kn(e.browserContext,{kind:"tracepoint",urlPattern:t.urlPattern,lineNumber:t.lineNumber,columnNumber:t.columnNumber,condition:t.condition,hitCondition:t.hitCondition});return{id:n.id,urlPattern:n.urlPattern,lineNumber:n.lineNumber,columnNumber:n.columnNumber,condition:n.condition,hitCondition:n.hitCondition,resolvedLocations:n.resolvedLocations}}};import{z as ps}from"zod";var eo=class{static{s(this,"RemoveTracepoint")}name(){return"debug_remove-tracepoint"}description(){return"Removes a tracepoint by its ID."}inputSchema(){return{id:ps.string().describe("Tracepoint ID to remove")}}outputSchema(){return{success:ps.boolean().describe("Whether the tracepoint was removed"),message:ps.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{success:!1,message:"No active tracepoints"};let n=Xn(e.browserContext,t.id);if(!n||n.kind!=="tracepoint")return{success:!1,message:`Tracepoint ${t.id} not found`};let r=await St(e.browserContext,t.id);return{success:r,message:r?`Tracepoint ${t.id} removed`:"Failed to remove tracepoint"}}};import{z as He}from"zod";var to=class{static{s(this,"ListTracepoints")}name(){return"debug_list-tracepoints"}description(){return"Lists all active tracepoints."}inputSchema(){return{}}outputSchema(){return{tracepoints:He.array(He.object({id:He.string(),urlPattern:He.string(),lineNumber:He.number(),columnNumber:He.number().optional(),condition:He.string().optional(),hitCondition:He.string().optional(),enabled:He.boolean(),resolvedLocations:He.number(),hitCount:He.number(),lastHitAt:He.number().optional()})).describe("List of tracepoints"),total:He.number().describe("Total count")}}async handle(e,t){if(!N(e.browserContext))return{tracepoints:[],total:0};let r=ve(e.browserContext).filter(i=>i.kind==="tracepoint").map(i=>({id:i.id,urlPattern:i.urlPattern,lineNumber:i.lineNumber,columnNumber:i.columnNumber,condition:i.condition,hitCondition:i.hitCondition,enabled:i.enabled,resolvedLocations:i.resolvedLocations,hitCount:i.hitCount,lastHitAt:i.lastHitAt}));return{tracepoints:r,total:r.length}}};import{z as Ki}from"zod";var no=class{static{s(this,"ClearTracepoints")}name(){return"debug_clear-tracepoints"}description(){return"Removes all tracepoints."}inputSchema(){return{}}outputSchema(){return{clearedCount:Ki.number().describe("Number of tracepoints cleared"),message:Ki.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No tracepoints to clear"};let n=ve(e.browserContext).filter(i=>i.kind==="tracepoint"),r=0;for(let i of n)await St(e.browserContext,i.id)&&r++;return{clearedCount:r,message:`Cleared ${r} tracepoint(s)`}}};import{z as Be}from"zod";var oo=class{static{s(this,"PutLogpoint")}name(){return"debug_put-logpoint"}description(){return`
302
301
  Puts a logpoint at the specified location.
303
302
  When the logpoint is hit, the logExpression is evaluated and the result
304
303
  is captured in the snapshot's logResult field.
@@ -314,14 +313,14 @@ logExpression examples:
314
313
  - Object: "{ user, timestamp: Date.now() }"
315
314
 
316
315
  Returns resolvedLocations: 0 means pattern didn't match any loaded scripts.
317
- `}inputSchema(){return{urlPattern:Ae.string().describe('Script URL pattern (e.g., "app.js"). Auto-escaped, do not add backslashes.'),lineNumber:Ae.number().int().positive().describe("Line number (1-based)"),logExpression:Ae.string().describe("Expression to evaluate and log when hit"),columnNumber:Ae.number().int().nonnegative().describe("Column number (1-based). Optional.").optional(),condition:Ae.string().describe("Conditional expression - logpoint only hits if this evaluates to true").optional(),hitCondition:Ae.string().describe('Hit count condition, e.g., "== 5" (5th hit), ">= 10" (10th and after), "% 10 == 0" (every 10th)').optional()}}outputSchema(){return{id:Ae.string().describe("Debug point ID"),urlPattern:Ae.string().describe("URL pattern"),lineNumber:Ae.number().describe("Line number"),logExpression:Ae.string().describe("Log expression"),columnNumber:Ae.number().optional().describe("Column number"),condition:Ae.string().optional().describe("Condition expression"),hitCondition:Ae.string().optional().describe("Hit count condition"),resolvedLocations:Ae.number().describe("Number of locations where logpoint was resolved")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=await Gn(e.browserContext,{kind:"logpoint",urlPattern:t.urlPattern,lineNumber:t.lineNumber,logExpression:t.logExpression,columnNumber:t.columnNumber,condition:t.condition,hitCondition:t.hitCondition});return{id:n.id,urlPattern:n.urlPattern,lineNumber:n.lineNumber,logExpression:n.logExpression||t.logExpression,columnNumber:n.columnNumber,condition:n.condition,hitCondition:n.hitCondition,resolvedLocations:n.resolvedLocations}}};import{z as ps}from"zod";var oo=class{static{s(this,"RemoveLogpoint")}name(){return"debug_remove-logpoint"}description(){return"Removes a logpoint by its ID."}inputSchema(){return{id:ps.string().describe("Logpoint ID to remove")}}outputSchema(){return{success:ps.boolean().describe("Whether the logpoint was removed"),message:ps.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{success:!1,message:"No active logpoints"};let n=Kn(e.browserContext,t.id);if(!n||n.kind!=="logpoint")return{success:!1,message:`Logpoint ${t.id} not found`};let r=await xt(e.browserContext,t.id);return{success:r,message:r?`Logpoint ${t.id} removed`:"Failed to remove logpoint"}}};import{z as Le}from"zod";var ro=class{static{s(this,"ListLogpoints")}name(){return"debug_list-logpoints"}description(){return"Lists all active logpoints."}inputSchema(){return{}}outputSchema(){return{logpoints:Le.array(Le.object({id:Le.string(),urlPattern:Le.string(),lineNumber:Le.number(),logExpression:Le.string(),columnNumber:Le.number().optional(),condition:Le.string().optional(),hitCondition:Le.string().optional(),enabled:Le.boolean(),resolvedLocations:Le.number(),hitCount:Le.number(),lastHitAt:Le.number().optional()})).describe("List of logpoints"),total:Le.number().describe("Total count")}}async handle(e,t){if(!N(e.browserContext))return{logpoints:[],total:0};let r=Se(e.browserContext).filter(i=>i.kind==="logpoint").map(i=>({id:i.id,urlPattern:i.urlPattern,lineNumber:i.lineNumber,logExpression:i.logExpression||"",columnNumber:i.columnNumber,condition:i.condition,hitCondition:i.hitCondition,enabled:i.enabled,resolvedLocations:i.resolvedLocations,hitCount:i.hitCount,lastHitAt:i.lastHitAt}));return{logpoints:r,total:r.length}}};import{z as zi}from"zod";var so=class{static{s(this,"ClearLogpoints")}name(){return"debug_clear-logpoints"}description(){return"Removes all logpoints."}inputSchema(){return{}}outputSchema(){return{clearedCount:zi.number().describe("Number of logpoints cleared"),message:zi.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No logpoints to clear"};let n=Se(e.browserContext).filter(i=>i.kind==="logpoint"),r=0;for(let i of n)await xt(e.browserContext,i.id)&&r++;return{clearedCount:r,message:`Cleared ${r} logpoint(s)`}}};import{z as io}from"zod";var ao=class{static{s(this,"PutExceptionpoint")}name(){return"debug_put-exceptionpoint"}description(){return`
316
+ `}inputSchema(){return{urlPattern:Be.string().describe('Script URL pattern (e.g., "app.js"). Auto-escaped, do not add backslashes.'),lineNumber:Be.number().int().positive().describe("Line number (1-based)"),logExpression:Be.string().describe("Expression to evaluate and log when hit"),columnNumber:Be.number().int().nonnegative().describe("Column number (1-based). Optional.").optional(),condition:Be.string().describe("Conditional expression - logpoint only hits if this evaluates to true").optional(),hitCondition:Be.string().describe('Hit count condition, e.g., "== 5" (5th hit), ">= 10" (10th and after), "% 10 == 0" (every 10th)').optional()}}outputSchema(){return{id:Be.string().describe("Debug point ID"),urlPattern:Be.string().describe("URL pattern"),lineNumber:Be.number().describe("Line number"),logExpression:Be.string().describe("Log expression"),columnNumber:Be.number().optional().describe("Column number"),condition:Be.string().optional().describe("Condition expression"),hitCondition:Be.string().optional().describe("Hit count condition"),resolvedLocations:Be.number().describe("Number of locations where logpoint was resolved")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=await Kn(e.browserContext,{kind:"logpoint",urlPattern:t.urlPattern,lineNumber:t.lineNumber,logExpression:t.logExpression,columnNumber:t.columnNumber,condition:t.condition,hitCondition:t.hitCondition});return{id:n.id,urlPattern:n.urlPattern,lineNumber:n.lineNumber,logExpression:n.logExpression||t.logExpression,columnNumber:n.columnNumber,condition:n.condition,hitCondition:n.hitCondition,resolvedLocations:n.resolvedLocations}}};import{z as ds}from"zod";var ro=class{static{s(this,"RemoveLogpoint")}name(){return"debug_remove-logpoint"}description(){return"Removes a logpoint by its ID."}inputSchema(){return{id:ds.string().describe("Logpoint ID to remove")}}outputSchema(){return{success:ds.boolean().describe("Whether the logpoint was removed"),message:ds.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{success:!1,message:"No active logpoints"};let n=Xn(e.browserContext,t.id);if(!n||n.kind!=="logpoint")return{success:!1,message:`Logpoint ${t.id} not found`};let r=await St(e.browserContext,t.id);return{success:r,message:r?`Logpoint ${t.id} removed`:"Failed to remove logpoint"}}};import{z as Ae}from"zod";var so=class{static{s(this,"ListLogpoints")}name(){return"debug_list-logpoints"}description(){return"Lists all active logpoints."}inputSchema(){return{}}outputSchema(){return{logpoints:Ae.array(Ae.object({id:Ae.string(),urlPattern:Ae.string(),lineNumber:Ae.number(),logExpression:Ae.string(),columnNumber:Ae.number().optional(),condition:Ae.string().optional(),hitCondition:Ae.string().optional(),enabled:Ae.boolean(),resolvedLocations:Ae.number(),hitCount:Ae.number(),lastHitAt:Ae.number().optional()})).describe("List of logpoints"),total:Ae.number().describe("Total count")}}async handle(e,t){if(!N(e.browserContext))return{logpoints:[],total:0};let r=ve(e.browserContext).filter(i=>i.kind==="logpoint").map(i=>({id:i.id,urlPattern:i.urlPattern,lineNumber:i.lineNumber,logExpression:i.logExpression||"",columnNumber:i.columnNumber,condition:i.condition,hitCondition:i.hitCondition,enabled:i.enabled,resolvedLocations:i.resolvedLocations,hitCount:i.hitCount,lastHitAt:i.lastHitAt}));return{logpoints:r,total:r.length}}};import{z as Xi}from"zod";var io=class{static{s(this,"ClearLogpoints")}name(){return"debug_clear-logpoints"}description(){return"Removes all logpoints."}inputSchema(){return{}}outputSchema(){return{clearedCount:Xi.number().describe("Number of logpoints cleared"),message:Xi.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No logpoints to clear"};let n=ve(e.browserContext).filter(i=>i.kind==="logpoint"),r=0;for(let i of n)await St(e.browserContext,i.id)&&r++;return{clearedCount:r,message:`Cleared ${r} logpoint(s)`}}};import{z as ao}from"zod";var lo=class{static{s(this,"PutExceptionpoint")}name(){return"debug_put-exceptionpoint"}description(){return`
318
317
  Sets the exception tracepoint state:
319
318
  - "none": Don't capture on exceptions
320
319
  - "uncaught": Capture only on uncaught exceptions
321
320
  - "all": Capture on all exceptions (caught and uncaught)
322
321
 
323
322
  When an exception occurs, a snapshot is captured with exception details.
324
- `}inputSchema(){return{state:io.enum(["none","uncaught","all"]).describe("Exception tracepoint state")}}outputSchema(){return{previousState:io.string().describe("Previous state"),currentState:io.string().describe("Current state"),message:io.string().describe("Status message")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=gn(e.browserContext);await Mi(e.browserContext,t.state);let r=gn(e.browserContext);return{previousState:n,currentState:r,message:`Exception tracepoint set to: ${r}`}}};import{z as fn}from"zod";import{z as y}from"zod";var ds=y.object({source:y.string().describe("Original source file path"),line:y.number().describe("1-based line number"),column:y.number().optional().describe("1-based column number"),name:y.string().optional().describe("Original identifier name")}),Kl=y.object({name:y.string().describe("Variable name"),value:y.any().describe("Variable value"),type:y.string().describe("Variable type")}),Xl=y.object({type:y.string().describe("Scope type (global, local, closure, etc.)"),name:y.string().optional().describe("Scope name"),variables:y.array(Kl).describe("Variables in this scope")}),bs=y.object({functionName:y.string().describe("Function name"),url:y.string().describe("Script URL"),lineNumber:y.number().describe("1-based line number"),columnNumber:y.number().optional().describe("1-based column number"),scriptId:y.string().describe("V8 script ID"),scopes:y.array(Xl).describe("Variable scopes"),originalLocation:ds.optional().describe("Original source location")}),Jl=y.object({functionName:y.string().describe("Function name"),url:y.string().describe("Script URL"),lineNumber:y.number().describe("1-based line number"),columnNumber:y.number().optional().describe("1-based column number"),originalLocation:ds.optional().describe("Original source location")}),Yl=y.object({description:y.string().optional().describe("Async boundary (Promise.then, setTimeout, etc.)"),callFrames:y.array(Jl).describe("Frames in this segment")}),gs=y.object({segments:y.array(Yl).describe("Chain of async segments")}),hn=y.object({id:y.string().describe("Snapshot ID"),probeId:y.string().describe("Probe ID that triggered this snapshot"),timestamp:y.number().describe("Unix timestamp (ms)"),sequenceNumber:y.number().describe("Monotonic sequence number for ordering"),url:y.string().describe("Script URL where snapshot was taken"),lineNumber:y.number().describe("1-based line number"),columnNumber:y.number().optional().describe("1-based column number"),originalLocation:ds.optional().describe("Original source location"),captureTimeMs:y.number().describe("Time taken to capture snapshot (ms)")}),Vi=hn.extend({callStack:y.array(bs).describe("Call stack with local variables"),asyncStackTrace:gs.optional().describe("Async stack trace"),watchResults:y.record(y.any()).optional().describe("Watch expression results")}),Gi=hn.extend({logResult:y.any().optional().describe("Result of log expression evaluation")}),Ql=y.object({type:y.enum(["exception","promiseRejection"]).describe("Exception type"),message:y.string().describe("Exception message"),name:y.string().optional().describe("Exception name/class"),stack:y.string().optional().describe("Stack trace string")}),Ki=hn.extend({exception:Ql.optional().describe("Exception information"),callStack:y.array(bs).describe("Call stack at exception"),asyncStackTrace:gs.optional().describe("Async stack trace"),watchResults:y.record(y.any()).optional().describe("Watch expression results")}),Zl=y.object({type:y.enum(["subtree-modified","attribute-modified","node-removed"]).describe("DOM mutation type"),selector:y.string().describe("CSS selector of watched element"),targetNode:y.string().optional().describe("Outer HTML snippet of target"),attributeName:y.string().optional().describe("Changed attribute name"),oldValue:y.string().optional().describe("Previous value"),newValue:y.string().optional().describe("New value")}),Xi=hn.extend({domChange:Zl.optional().describe("DOM change information"),callStack:y.array(bs).describe("Call stack when DOM changed"),asyncStackTrace:gs.optional().describe("Async stack trace"),watchResults:y.record(y.any()).optional().describe("Watch expression results")}),eu=y.object({url:y.string().describe("Request URL"),method:y.string().describe("HTTP method"),requestHeaders:y.record(y.string()).optional().describe("Request headers"),requestBody:y.string().optional().describe("Request body"),status:y.number().optional().describe("Response status code"),statusText:y.string().optional().describe("Response status text"),responseHeaders:y.record(y.string()).optional().describe("Response headers"),responseBody:y.string().optional().describe("Response body"),resourceType:y.string().optional().describe("Resource type (xhr, fetch, etc.)"),timing:y.enum(["request","response"]).describe("When snapshot was taken"),duration:y.number().optional().describe("Request duration (ms)"),error:y.string().optional().describe("Error message if failed")}),Ji=hn.extend({networkRequest:eu.optional().describe("Network request/response info")});var lo=class{static{s(this,"GetTracepointSnapshots")}name(){return"debug_get-tracepoint-snapshots"}description(){return`
323
+ `}inputSchema(){return{state:ao.enum(["none","uncaught","all"]).describe("Exception tracepoint state")}}outputSchema(){return{previousState:ao.string().describe("Previous state"),currentState:ao.string().describe("Current state"),message:ao.string().describe("Status message")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=fn(e.browserContext);await Li(e.browserContext,t.state);let r=fn(e.browserContext);return{previousState:n,currentState:r,message:`Exception tracepoint set to: ${r}`}}};import{z as wn}from"zod";import{z as y}from"zod";var bs=y.object({source:y.string().describe("Original source file path"),line:y.number().describe("1-based line number"),column:y.number().optional().describe("1-based column number"),name:y.string().optional().describe("Original identifier name")}),Jl=y.object({name:y.string().describe("Variable name"),value:y.any().describe("Variable value"),type:y.string().describe("Variable type")}),Ql=y.object({type:y.string().describe("Scope type (global, local, closure, etc.)"),name:y.string().optional().describe("Scope name"),variables:y.array(Jl).describe("Variables in this scope")}),hs=y.object({functionName:y.string().describe("Function name"),url:y.string().describe("Script URL"),lineNumber:y.number().describe("1-based line number"),columnNumber:y.number().optional().describe("1-based column number"),scriptId:y.string().describe("V8 script ID"),scopes:y.array(Ql).describe("Variable scopes"),originalLocation:bs.optional().describe("Original source location")}),Zl=y.object({functionName:y.string().describe("Function name"),url:y.string().describe("Script URL"),lineNumber:y.number().describe("1-based line number"),columnNumber:y.number().optional().describe("1-based column number"),originalLocation:bs.optional().describe("Original source location")}),eu=y.object({description:y.string().optional().describe("Async boundary (Promise.then, setTimeout, etc.)"),callFrames:y.array(Zl).describe("Frames in this segment")}),gs=y.object({segments:y.array(eu).describe("Chain of async segments")}),yn=y.object({id:y.string().describe("Snapshot ID"),probeId:y.string().describe("Probe ID that triggered this snapshot"),timestamp:y.number().describe("Unix timestamp (ms)"),sequenceNumber:y.number().describe("Monotonic sequence number for ordering"),url:y.string().describe("Script URL where snapshot was taken"),lineNumber:y.number().describe("1-based line number"),columnNumber:y.number().optional().describe("1-based column number"),originalLocation:bs.optional().describe("Original source location"),captureTimeMs:y.number().describe("Time taken to capture snapshot (ms)")}),Yi=yn.extend({callStack:y.array(hs).describe("Call stack with local variables"),asyncStackTrace:gs.optional().describe("Async stack trace"),watchResults:y.record(y.any()).optional().describe("Watch expression results")}),Ji=yn.extend({logResult:y.any().optional().describe("Result of log expression evaluation")}),tu=y.object({type:y.enum(["exception","promiseRejection"]).describe("Exception type"),message:y.string().describe("Exception message"),name:y.string().optional().describe("Exception name/class"),stack:y.string().optional().describe("Stack trace string")}),Qi=yn.extend({exception:tu.optional().describe("Exception information"),callStack:y.array(hs).describe("Call stack at exception"),asyncStackTrace:gs.optional().describe("Async stack trace"),watchResults:y.record(y.any()).optional().describe("Watch expression results")}),nu=y.object({type:y.enum(["subtree-modified","attribute-modified","node-removed"]).describe("DOM mutation type"),selector:y.string().describe("CSS selector of watched element"),targetNode:y.string().optional().describe("Outer HTML snippet of target"),attributeName:y.string().optional().describe("Changed attribute name"),oldValue:y.string().optional().describe("Previous value"),newValue:y.string().optional().describe("New value")}),Zi=yn.extend({domChange:nu.optional().describe("DOM change information"),callStack:y.array(hs).describe("Call stack when DOM changed"),asyncStackTrace:gs.optional().describe("Async stack trace"),watchResults:y.record(y.any()).optional().describe("Watch expression results")}),ou=y.object({url:y.string().describe("Request URL"),method:y.string().describe("HTTP method"),requestHeaders:y.record(y.string()).optional().describe("Request headers"),requestBody:y.string().optional().describe("Request body"),status:y.number().optional().describe("Response status code"),statusText:y.string().optional().describe("Response status text"),responseHeaders:y.record(y.string()).optional().describe("Response headers"),responseBody:y.string().optional().describe("Response body"),resourceType:y.string().optional().describe("Resource type (xhr, fetch, etc.)"),timing:y.enum(["request","response"]).describe("When snapshot was taken"),duration:y.number().optional().describe("Request duration (ms)"),error:y.string().optional().describe("Error message if failed")}),ea=yn.extend({networkRequest:ou.optional().describe("Network request/response info")});var uo=class{static{s(this,"GetTracepointSnapshots")}name(){return"debug_get-tracepoint-snapshots"}description(){return`
325
324
  Retrieves snapshots captured by tracepoints.
326
325
 
327
326
  Each snapshot contains:
@@ -329,7 +328,7 @@ Each snapshot contains:
329
328
  - Async stack trace (if available)
330
329
  - Original source location (if source maps loaded)
331
330
  - Watch expression results
332
- `}inputSchema(){return{probeId:fn.string().describe("Filter by specific tracepoint ID").optional(),fromSequence:fn.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:fn.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:fn.array(Vi).describe("Array of tracepoint snapshots"),total:fn.number().describe("Total number of matching snapshots")}}async handle(e,t){if(!N(e.browserContext))return{snapshots:[],total:0};let n;if(t.probeId)n=at(e.browserContext,t.probeId);else{let i=new Set(Se(e.browserContext).filter(a=>a.kind==="tracepoint").map(a=>a.id));n=It(e.browserContext).filter(a=>i.has(a.probeId))}t.fromSequence!==void 0&&(n=n.filter(i=>i.sequenceNumber>t.fromSequence));let r=n.length;return t.limit&&n.length>t.limit&&(n=n.slice(0,t.limit)),{snapshots:n,total:r}}};import{z as hs}from"zod";var uo=class{static{s(this,"ClearTracepointSnapshots")}name(){return"debug_clear-tracepoint-snapshots"}description(){return"Clears snapshots captured by tracepoints. Optionally filter by specific tracepoint ID."}inputSchema(){return{probeId:hs.string().describe("Clear only snapshots for this tracepoint ID").optional()}}outputSchema(){return{clearedCount:hs.number().describe("Number of snapshots cleared"),message:hs.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No snapshots to clear"};let n=0;if(t.probeId)n=Be(e.browserContext,t.probeId);else{let r=Se(e.browserContext).filter(i=>i.kind==="tracepoint").map(i=>i.id);for(let i of r)n+=Be(e.browserContext,i)}return{clearedCount:n,message:`Cleared ${n} tracepoint snapshot(s)`}}};import{z as yn}from"zod";var co=class{static{s(this,"GetLogpointSnapshots")}name(){return"debug_get-logpoint-snapshots"}description(){return`
331
+ `}inputSchema(){return{probeId:wn.string().describe("Filter by specific tracepoint ID").optional(),fromSequence:wn.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:wn.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:wn.array(Yi).describe("Array of tracepoint snapshots"),total:wn.number().describe("Total number of matching snapshots")}}async handle(e,t){if(!N(e.browserContext))return{snapshots:[],total:0};let n;if(t.probeId)n=it(e.browserContext,t.probeId);else{let i=new Set(ve(e.browserContext).filter(a=>a.kind==="tracepoint").map(a=>a.id));n=xt(e.browserContext).filter(a=>i.has(a.probeId))}t.fromSequence!==void 0&&(n=n.filter(i=>i.sequenceNumber>t.fromSequence));let r=n.length;return t.limit&&n.length>t.limit&&(n=n.slice(0,t.limit)),{snapshots:n,total:r}}};import{z as fs}from"zod";var co=class{static{s(this,"ClearTracepointSnapshots")}name(){return"debug_clear-tracepoint-snapshots"}description(){return"Clears snapshots captured by tracepoints. Optionally filter by specific tracepoint ID."}inputSchema(){return{probeId:fs.string().describe("Clear only snapshots for this tracepoint ID").optional()}}outputSchema(){return{clearedCount:fs.number().describe("Number of snapshots cleared"),message:fs.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No snapshots to clear"};let n=0;if(t.probeId)n=De(e.browserContext,t.probeId);else{let r=ve(e.browserContext).filter(i=>i.kind==="tracepoint").map(i=>i.id);for(let i of r)n+=De(e.browserContext,i)}return{clearedCount:n,message:`Cleared ${n} tracepoint snapshot(s)`}}};import{z as Tn}from"zod";var mo=class{static{s(this,"GetLogpointSnapshots")}name(){return"debug_get-logpoint-snapshots"}description(){return`
333
332
  Retrieves snapshots captured by logpoints.
334
333
 
335
334
  Each snapshot contains:
@@ -339,7 +338,7 @@ Each snapshot contains:
339
338
 
340
339
  Note: Logpoints do NOT capture call stack or watch expressions.
341
340
  Use tracepoints if you need full debug context.
342
- `}inputSchema(){return{probeId:yn.string().describe("Filter by specific logpoint ID").optional(),fromSequence:yn.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:yn.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:yn.array(Gi).describe("Array of logpoint snapshots"),total:yn.number().describe("Total number of matching snapshots")}}async handle(e,t){if(!N(e.browserContext))return{snapshots:[],total:0};let n;if(t.probeId)n=at(e.browserContext,t.probeId);else{let a=new Set(Se(e.browserContext).filter(l=>l.kind==="logpoint").map(l=>l.id));n=It(e.browserContext).filter(l=>a.has(l.probeId))}t.fromSequence!==void 0&&(n=n.filter(a=>a.sequenceNumber>t.fromSequence));let r=n.length;return t.limit&&n.length>t.limit&&(n=n.slice(0,t.limit)),{snapshots:n.map(a=>({id:a.id,probeId:a.probeId,timestamp:a.timestamp,sequenceNumber:a.sequenceNumber,url:a.url,lineNumber:a.lineNumber,columnNumber:a.columnNumber,originalLocation:a.originalLocation,captureTimeMs:a.captureTimeMs,logResult:a.logResult})),total:r}}};import{z as fs}from"zod";var mo=class{static{s(this,"ClearLogpointSnapshots")}name(){return"debug_clear-logpoint-snapshots"}description(){return"Clears snapshots captured by logpoints. Optionally filter by specific logpoint ID."}inputSchema(){return{probeId:fs.string().describe("Clear only snapshots for this logpoint ID").optional()}}outputSchema(){return{clearedCount:fs.number().describe("Number of snapshots cleared"),message:fs.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No snapshots to clear"};let n=0;if(t.probeId)n=Be(e.browserContext,t.probeId);else{let r=Se(e.browserContext).filter(i=>i.kind==="logpoint").map(i=>i.id);for(let i of r)n+=Be(e.browserContext,i)}return{clearedCount:n,message:`Cleared ${n} logpoint snapshot(s)`}}};import{z as po}from"zod";var bo=class{static{s(this,"GetExceptionpointSnapshots")}name(){return"debug_get-exceptionpoint-snapshots"}description(){return`
341
+ `}inputSchema(){return{probeId:Tn.string().describe("Filter by specific logpoint ID").optional(),fromSequence:Tn.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:Tn.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:Tn.array(Ji).describe("Array of logpoint snapshots"),total:Tn.number().describe("Total number of matching snapshots")}}async handle(e,t){if(!N(e.browserContext))return{snapshots:[],total:0};let n;if(t.probeId)n=it(e.browserContext,t.probeId);else{let a=new Set(ve(e.browserContext).filter(l=>l.kind==="logpoint").map(l=>l.id));n=xt(e.browserContext).filter(l=>a.has(l.probeId))}t.fromSequence!==void 0&&(n=n.filter(a=>a.sequenceNumber>t.fromSequence));let r=n.length;return t.limit&&n.length>t.limit&&(n=n.slice(0,t.limit)),{snapshots:n.map(a=>({id:a.id,probeId:a.probeId,timestamp:a.timestamp,sequenceNumber:a.sequenceNumber,url:a.url,lineNumber:a.lineNumber,columnNumber:a.columnNumber,originalLocation:a.originalLocation,captureTimeMs:a.captureTimeMs,logResult:a.logResult})),total:r}}};import{z as ys}from"zod";var po=class{static{s(this,"ClearLogpointSnapshots")}name(){return"debug_clear-logpoint-snapshots"}description(){return"Clears snapshots captured by logpoints. Optionally filter by specific logpoint ID."}inputSchema(){return{probeId:ys.string().describe("Clear only snapshots for this logpoint ID").optional()}}outputSchema(){return{clearedCount:ys.number().describe("Number of snapshots cleared"),message:ys.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No snapshots to clear"};let n=0;if(t.probeId)n=De(e.browserContext,t.probeId);else{let r=ve(e.browserContext).filter(i=>i.kind==="logpoint").map(i=>i.id);for(let i of r)n+=De(e.browserContext,i)}return{clearedCount:n,message:`Cleared ${n} logpoint snapshot(s)`}}};import{z as bo}from"zod";var ho=class{static{s(this,"GetExceptionpointSnapshots")}name(){return"debug_get-exceptionpoint-snapshots"}description(){return`
343
342
  Retrieves snapshots captured by exceptionpoints.
344
343
 
345
344
  Each snapshot contains:
@@ -348,7 +347,7 @@ Each snapshot contains:
348
347
  - Async stack trace (if available)
349
348
  - Original source location (if source maps loaded)
350
349
  - Watch expression results
351
- `}inputSchema(){return{fromSequence:po.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:po.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:po.array(Ki).describe("Array of exceptionpoint snapshots"),total:po.number().describe("Total number of matching snapshots")}}async handle(e,t){if(!N(e.browserContext))return{snapshots:[],total:0};let n=at(e.browserContext,"__exception__");t.fromSequence!==void 0&&(n=n.filter(i=>i.sequenceNumber>t.fromSequence));let r=n.length;return t.limit&&n.length>t.limit&&(n=n.slice(0,t.limit)),{snapshots:n,total:r}}};import{z as Yi}from"zod";var go=class{static{s(this,"ClearExceptionpointSnapshots")}name(){return"debug_clear-exceptionpoint-snapshots"}description(){return"Clears all snapshots captured by exceptionpoints."}inputSchema(){return{}}outputSchema(){return{clearedCount:Yi.number().describe("Number of snapshots cleared"),message:Yi.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No snapshots to clear"};let n=Be(e.browserContext,"__exception__");return{clearedCount:n,message:`Cleared ${n} exceptionpoint snapshot(s)`}}};import{z as wn}from"zod";var ho=class{static{s(this,"GetDompointSnapshots")}name(){return"debug_get-dompoint-snapshots"}description(){return`
350
+ `}inputSchema(){return{fromSequence:bo.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:bo.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:bo.array(Qi).describe("Array of exceptionpoint snapshots"),total:bo.number().describe("Total number of matching snapshots")}}async handle(e,t){if(!N(e.browserContext))return{snapshots:[],total:0};let n=it(e.browserContext,"__exception__");t.fromSequence!==void 0&&(n=n.filter(i=>i.sequenceNumber>t.fromSequence));let r=n.length;return t.limit&&n.length>t.limit&&(n=n.slice(0,t.limit)),{snapshots:n,total:r}}};import{z as ta}from"zod";var go=class{static{s(this,"ClearExceptionpointSnapshots")}name(){return"debug_clear-exceptionpoint-snapshots"}description(){return"Clears all snapshots captured by exceptionpoints."}inputSchema(){return{}}outputSchema(){return{clearedCount:ta.number().describe("Number of snapshots cleared"),message:ta.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No snapshots to clear"};let n=De(e.browserContext,"__exception__");return{clearedCount:n,message:`Cleared ${n} exceptionpoint snapshot(s)`}}};import{z as Sn}from"zod";var fo=class{static{s(this,"GetDompointSnapshots")}name(){return"debug_get-dompoint-snapshots"}description(){return`
352
351
  Retrieves snapshots captured by dompoints.
353
352
 
354
353
  Each snapshot contains:
@@ -357,14 +356,14 @@ Each snapshot contains:
357
356
  - Async stack trace (if available)
358
357
  - Original source location (if source maps loaded)
359
358
  - Watch expression results
360
- `}inputSchema(){return{probeId:wn.string().describe("Filter by specific dompoint ID").optional(),fromSequence:wn.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:wn.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:wn.array(Xi).describe("Array of dompoint snapshots"),total:wn.number().describe("Total number of matching snapshots")}}async handle(e,t){if(!N(e.browserContext))return{snapshots:[],total:0};let n;if(t.probeId)n=at(e.browserContext,t.probeId);else{let i=new Set(Ct(e.browserContext).map(a=>a.id));n=It(e.browserContext).filter(a=>i.has(a.probeId))}t.fromSequence!==void 0&&(n=n.filter(i=>i.sequenceNumber>t.fromSequence));let r=n.length;return t.limit&&n.length>t.limit&&(n=n.slice(0,t.limit)),{snapshots:n,total:r}}};import{z as ys}from"zod";var fo=class{static{s(this,"ClearDompointSnapshots")}name(){return"debug_clear-dompoint-snapshots"}description(){return"Clears snapshots captured by dompoints. If probeId is specified, only clears snapshots for that dompoint."}inputSchema(){return{probeId:ys.string().describe("Optional dompoint ID to clear snapshots for").optional()}}outputSchema(){return{clearedCount:ys.number().describe("Number of snapshots cleared"),message:ys.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No snapshots to clear"};let n=0;if(t.probeId)n=Be(e.browserContext,t.probeId);else{let r=Ct(e.browserContext);for(let i of r)n+=Be(e.browserContext,i.id)}return{clearedCount:n,message:`Cleared ${n} dompoint snapshot(s)`}}};import{z as Tn}from"zod";var yo=class{static{s(this,"GetNetpointSnapshots")}name(){return"debug_get-netpoint-snapshots"}description(){return`
359
+ `}inputSchema(){return{probeId:Sn.string().describe("Filter by specific dompoint ID").optional(),fromSequence:Sn.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:Sn.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:Sn.array(Zi).describe("Array of dompoint snapshots"),total:Sn.number().describe("Total number of matching snapshots")}}async handle(e,t){if(!N(e.browserContext))return{snapshots:[],total:0};let n;if(t.probeId)n=it(e.browserContext,t.probeId);else{let i=new Set(vt(e.browserContext).map(a=>a.id));n=xt(e.browserContext).filter(a=>i.has(a.probeId))}t.fromSequence!==void 0&&(n=n.filter(i=>i.sequenceNumber>t.fromSequence));let r=n.length;return t.limit&&n.length>t.limit&&(n=n.slice(0,t.limit)),{snapshots:n,total:r}}};import{z as ws}from"zod";var yo=class{static{s(this,"ClearDompointSnapshots")}name(){return"debug_clear-dompoint-snapshots"}description(){return"Clears snapshots captured by dompoints. If probeId is specified, only clears snapshots for that dompoint."}inputSchema(){return{probeId:ws.string().describe("Optional dompoint ID to clear snapshots for").optional()}}outputSchema(){return{clearedCount:ws.number().describe("Number of snapshots cleared"),message:ws.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No snapshots to clear"};let n=0;if(t.probeId)n=De(e.browserContext,t.probeId);else{let r=vt(e.browserContext);for(let i of r)n+=De(e.browserContext,i.id)}return{clearedCount:n,message:`Cleared ${n} dompoint snapshot(s)`}}};import{z as xn}from"zod";var wo=class{static{s(this,"GetNetpointSnapshots")}name(){return"debug_get-netpoint-snapshots"}description(){return`
361
360
  Retrieves snapshots captured by netpoints.
362
361
 
363
362
  Each snapshot contains:
364
363
  - Network request info (URL, method, headers, body)
365
364
  - Response info (status, headers, body) when available
366
365
  - Timing information
367
- `}inputSchema(){return{probeId:Tn.string().describe("Filter by specific netpoint ID").optional(),fromSequence:Tn.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:Tn.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:Tn.array(Ji).describe("Array of netpoint snapshots"),total:Tn.number().describe("Total number of matching snapshots")}}async handle(e,t){if(!N(e.browserContext))return{snapshots:[],total:0};let n;if(t.probeId)n=at(e.browserContext,t.probeId);else{let i=new Set(vt(e.browserContext).map(a=>a.id));n=It(e.browserContext).filter(a=>i.has(a.probeId))}t.fromSequence!==void 0&&(n=n.filter(i=>i.sequenceNumber>t.fromSequence));let r=n.length;return t.limit&&n.length>t.limit&&(n=n.slice(0,t.limit)),{snapshots:n,total:r}}};import{z as ws}from"zod";var wo=class{static{s(this,"ClearNetpointSnapshots")}name(){return"debug_clear-netpoint-snapshots"}description(){return"Clears snapshots captured by netpoints. If probeId is specified, only clears snapshots for that netpoint."}inputSchema(){return{probeId:ws.string().describe("Optional netpoint ID to clear snapshots for").optional()}}outputSchema(){return{clearedCount:ws.number().describe("Number of snapshots cleared"),message:ws.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No snapshots to clear"};let n=0;if(t.probeId)n=Be(e.browserContext,t.probeId);else{let r=vt(e.browserContext);for(let i of r)n+=Be(e.browserContext,i.id)}return{clearedCount:n,message:`Cleared ${n} netpoint snapshot(s)`}}};import{z as To}from"zod";var So=class{static{s(this,"AddWatch")}name(){return"debug_add-watch"}description(){return`
366
+ `}inputSchema(){return{probeId:xn.string().describe("Filter by specific netpoint ID").optional(),fromSequence:xn.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:xn.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:xn.array(ea).describe("Array of netpoint snapshots"),total:xn.number().describe("Total number of matching snapshots")}}async handle(e,t){if(!N(e.browserContext))return{snapshots:[],total:0};let n;if(t.probeId)n=it(e.browserContext,t.probeId);else{let i=new Set(It(e.browserContext).map(a=>a.id));n=xt(e.browserContext).filter(a=>i.has(a.probeId))}t.fromSequence!==void 0&&(n=n.filter(i=>i.sequenceNumber>t.fromSequence));let r=n.length;return t.limit&&n.length>t.limit&&(n=n.slice(0,t.limit)),{snapshots:n,total:r}}};import{z as Ts}from"zod";var To=class{static{s(this,"ClearNetpointSnapshots")}name(){return"debug_clear-netpoint-snapshots"}description(){return"Clears snapshots captured by netpoints. If probeId is specified, only clears snapshots for that netpoint."}inputSchema(){return{probeId:Ts.string().describe("Optional netpoint ID to clear snapshots for").optional()}}outputSchema(){return{clearedCount:Ts.number().describe("Number of snapshots cleared"),message:Ts.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No snapshots to clear"};let n=0;if(t.probeId)n=De(e.browserContext,t.probeId);else{let r=It(e.browserContext);for(let i of r)n+=De(e.browserContext,i.id)}return{clearedCount:n,message:`Cleared ${n} netpoint snapshot(s)`}}};import{z as So}from"zod";var xo=class{static{s(this,"AddWatch")}name(){return"debug_add-watch"}description(){return`
368
367
  Adds a watch expression to be evaluated at every breakpoint hit.
369
368
  Watch expression results are included in the snapshot's watchResults field.
370
369
 
@@ -375,14 +374,14 @@ Examples:
375
374
  - "JSON.stringify(config)"
376
375
 
377
376
  Watch expressions are evaluated in the context of the paused frame.
378
- `}inputSchema(){return{expression:To.string().describe("JavaScript expression to watch")}}outputSchema(){return{id:To.string().describe("Watch expression ID"),expression:To.string().describe("The watch expression"),message:To.string().describe("Status message")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=Ai(e.browserContext,t.expression);return{id:n.id,expression:n.expression,message:`Watch expression added: ${t.expression}`}}};import{z as Ts}from"zod";var xo=class{static{s(this,"RemoveWatch")}name(){return"debug_remove-watch"}description(){return`
377
+ `}inputSchema(){return{expression:So.string().describe("JavaScript expression to watch")}}outputSchema(){return{id:So.string().describe("Watch expression ID"),expression:So.string().describe("The watch expression"),message:So.string().describe("Status message")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=Hi(e.browserContext,t.expression);return{id:n.id,expression:n.expression,message:`Watch expression added: ${t.expression}`}}};import{z as Ss}from"zod";var vo=class{static{s(this,"RemoveWatch")}name(){return"debug_remove-watch"}description(){return`
379
378
  Removes a watch expression by its ID.
380
379
  Use debug_list-watches to get the IDs of active watch expressions.
381
- `}inputSchema(){return{id:Ts.string().describe("Watch expression ID to remove")}}outputSchema(){return{success:Ts.boolean().describe("Whether the watch was removed"),message:Ts.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{success:!1,message:"Debugging is not active"};let n=Li(e.browserContext,t.id);return{success:n,message:n?`Watch expression ${t.id} removed`:`Watch expression ${t.id} not found`}}};import{z as Qt}from"zod";var Io=class{static{s(this,"ListWatches")}name(){return"debug_list-watches"}description(){return`
380
+ `}inputSchema(){return{id:Ss.string().describe("Watch expression ID to remove")}}outputSchema(){return{success:Ss.boolean().describe("Whether the watch was removed"),message:Ss.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{success:!1,message:"Debugging is not active"};let n=Wi(e.browserContext,t.id);return{success:n,message:n?`Watch expression ${t.id} removed`:`Watch expression ${t.id} not found`}}};import{z as Qt}from"zod";var Io=class{static{s(this,"ListWatches")}name(){return"debug_list-watches"}description(){return`
382
381
  Lists all active watch expressions.
383
- `}inputSchema(){return{}}outputSchema(){return{watches:Qt.array(Qt.object({id:Qt.string(),expression:Qt.string(),createdAt:Qt.number()})).describe("List of watch expressions"),total:Qt.number().describe("Total count")}}async handle(e,t){if(!N(e.browserContext))return{watches:[],total:0};let r=Xn(e.browserContext).map(i=>({id:i.id,expression:i.expression,createdAt:i.createdAt}));return{watches:r,total:r.length}}};import{z as Qi}from"zod";var Co=class{static{s(this,"ClearWatches")}name(){return"debug_clear-watches"}description(){return`
382
+ `}inputSchema(){return{}}outputSchema(){return{watches:Qt.array(Qt.object({id:Qt.string(),expression:Qt.string(),createdAt:Qt.number()})).describe("List of watch expressions"),total:Qt.number().describe("Total count")}}async handle(e,t){if(!N(e.browserContext))return{watches:[],total:0};let r=Yn(e.browserContext).map(i=>({id:i.id,expression:i.expression,createdAt:i.createdAt}));return{watches:r,total:r.length}}};import{z as na}from"zod";var Co=class{static{s(this,"ClearWatches")}name(){return"debug_clear-watches"}description(){return`
384
383
  Removes all watch expressions.
385
- `}inputSchema(){return{}}outputSchema(){return{clearedCount:Qi.number().describe("Number of watch expressions cleared"),message:Qi.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No watch expressions to clear"};let n=Fi(e.browserContext);return{clearedCount:n,message:`Cleared ${n} watch expression(s)`}}};import{z as ht}from"zod";var vo=class{static{s(this,"PutDompoint")}name(){return"debug_put-dompoint"}description(){return`
384
+ `}inputSchema(){return{}}outputSchema(){return{clearedCount:na.number().describe("Number of watch expressions cleared"),message:na.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No watch expressions to clear"};let n=qi(e.browserContext);return{clearedCount:n,message:`Cleared ${n} watch expression(s)`}}};import{z as ht}from"zod";var Eo=class{static{s(this,"PutDompoint")}name(){return"debug_put-dompoint"}description(){return`
386
385
  Puts a DOM tracepoint that triggers when the element changes.
387
386
 
388
387
  Types:
@@ -395,7 +394,7 @@ When triggered, a snapshot is captured with DOM change info.
395
394
  Example:
396
395
  - selector: "#myButton", type: "attribute-modified", attributeName: "disabled"
397
396
  - selector: ".list-container", type: "subtree-modified"
398
- `}inputSchema(){return{selector:ht.string().describe("CSS selector for the target element"),type:ht.enum(["subtree-modified","attribute-modified","node-removed"]).describe("Type of DOM change to monitor"),attributeName:ht.string().describe("For attribute-modified: specific attribute to monitor").optional()}}outputSchema(){return{id:ht.string().describe("Dompoint ID"),selector:ht.string().describe("CSS selector"),type:ht.string().describe("Dompoint type"),attributeName:ht.string().optional().describe("Monitored attribute"),nodeId:ht.number().optional().describe("CDP node ID"),message:ht.string().describe("Status message")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=await Ui(e.browserContext,e.page,{selector:t.selector,type:t.type,attributeName:t.attributeName});return{id:n.id,selector:n.selector,type:n.type,attributeName:n.attributeName,nodeId:n.nodeId,message:`Dompoint set on "${t.selector}" for ${t.type}`}}};import{z as Ss}from"zod";var Oo=class{static{s(this,"RemoveDompoint")}name(){return"debug_remove-dompoint"}description(){return"Removes a dompoint by its ID."}inputSchema(){return{id:Ss.string().describe("Dompoint ID to remove")}}outputSchema(){return{success:Ss.boolean().describe("Whether the dompoint was removed"),message:Ss.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{success:!1,message:"No active dompoints"};let n=await cs(e.browserContext,t.id,e.page);return{success:n,message:n?`Dompoint ${t.id} removed`:`Dompoint ${t.id} not found`}}};import{z as lt}from"zod";var Eo=class{static{s(this,"ListDompoints")}name(){return"debug_list-dompoints"}description(){return"Lists all active dompoints."}inputSchema(){return{}}outputSchema(){return{dompoints:lt.array(lt.object({id:lt.string(),selector:lt.string(),type:lt.string(),attributeName:lt.string().optional(),enabled:lt.boolean(),hitCount:lt.number(),lastHitAt:lt.number().optional()})).describe("List of dompoints"),total:lt.number().describe("Total count")}}async handle(e,t){if(!N(e.browserContext))return{dompoints:[],total:0};let r=Ct(e.browserContext).map(i=>({id:i.id,selector:i.selector,type:i.type,attributeName:i.attributeName,enabled:i.enabled,hitCount:i.hitCount,lastHitAt:i.lastHitAt}));return{dompoints:r,total:r.length}}};import{z as Zi}from"zod";var No=class{static{s(this,"ClearDompoints")}name(){return"debug_clear-dompoints"}description(){return"Removes all dompoints."}inputSchema(){return{}}outputSchema(){return{clearedCount:Zi.number().describe("Number of dompoints cleared"),message:Zi.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No dompoints to clear"};let n=await Hi(e.browserContext,e.page);return{clearedCount:n,message:`Cleared ${n} dompoint(s)`}}};import{z as ut}from"zod";var Po=class{static{s(this,"PutNetpoint")}name(){return"debug_put-netpoint"}description(){return`
397
+ `}inputSchema(){return{selector:ht.string().describe("CSS selector for the target element"),type:ht.enum(["subtree-modified","attribute-modified","node-removed"]).describe("Type of DOM change to monitor"),attributeName:ht.string().describe("For attribute-modified: specific attribute to monitor").optional()}}outputSchema(){return{id:ht.string().describe("Dompoint ID"),selector:ht.string().describe("CSS selector"),type:ht.string().describe("Dompoint type"),attributeName:ht.string().optional().describe("Monitored attribute"),nodeId:ht.number().optional().describe("CDP node ID"),message:ht.string().describe("Status message")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=await $i(e.browserContext,e.page,{selector:t.selector,type:t.type,attributeName:t.attributeName});return{id:n.id,selector:n.selector,type:n.type,attributeName:n.attributeName,nodeId:n.nodeId,message:`Dompoint set on "${t.selector}" for ${t.type}`}}};import{z as xs}from"zod";var Oo=class{static{s(this,"RemoveDompoint")}name(){return"debug_remove-dompoint"}description(){return"Removes a dompoint by its ID."}inputSchema(){return{id:xs.string().describe("Dompoint ID to remove")}}outputSchema(){return{success:xs.boolean().describe("Whether the dompoint was removed"),message:xs.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{success:!1,message:"No active dompoints"};let n=await ms(e.browserContext,t.id,e.page);return{success:n,message:n?`Dompoint ${t.id} removed`:`Dompoint ${t.id} not found`}}};import{z as at}from"zod";var No=class{static{s(this,"ListDompoints")}name(){return"debug_list-dompoints"}description(){return"Lists all active dompoints."}inputSchema(){return{}}outputSchema(){return{dompoints:at.array(at.object({id:at.string(),selector:at.string(),type:at.string(),attributeName:at.string().optional(),enabled:at.boolean(),hitCount:at.number(),lastHitAt:at.number().optional()})).describe("List of dompoints"),total:at.number().describe("Total count")}}async handle(e,t){if(!N(e.browserContext))return{dompoints:[],total:0};let r=vt(e.browserContext).map(i=>({id:i.id,selector:i.selector,type:i.type,attributeName:i.attributeName,enabled:i.enabled,hitCount:i.hitCount,lastHitAt:i.lastHitAt}));return{dompoints:r,total:r.length}}};import{z as oa}from"zod";var Po=class{static{s(this,"ClearDompoints")}name(){return"debug_clear-dompoints"}description(){return"Removes all dompoints."}inputSchema(){return{}}outputSchema(){return{clearedCount:oa.number().describe("Number of dompoints cleared"),message:oa.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No dompoints to clear"};let n=await ji(e.browserContext,e.page);return{clearedCount:n,message:`Cleared ${n} dompoint(s)`}}};import{z as lt}from"zod";var Ro=class{static{s(this,"PutNetpoint")}name(){return"debug_put-netpoint"}description(){return`
399
398
  Puts a network tracepoint that triggers on matching HTTP requests.
400
399
 
401
400
  When triggered, a snapshot is captured with request/response details including:
@@ -412,7 +411,7 @@ Parameters:
412
411
  Examples:
413
412
  - urlPattern: "**/api/users/**", timing: "response"
414
413
  - urlPattern: "**/graphql", method: "POST", timing: "request"
415
- `}inputSchema(){return{urlPattern:ut.string().describe("Glob pattern to match request URLs"),method:ut.string().describe("HTTP method filter (GET, POST, PUT, DELETE, etc.)").optional(),timing:ut.enum(["request","response"]).describe('When to trigger: "request" or "response". Default: "request"').optional().default("request"),onError:ut.boolean().describe("Only trigger on error responses (4xx, 5xx)").optional()}}outputSchema(){return{id:ut.string().describe("Netpoint ID"),urlPattern:ut.string().describe("URL pattern"),method:ut.string().optional().describe("HTTP method filter"),timing:ut.string().describe("Trigger timing"),onError:ut.boolean().optional().describe("Error-only filter"),message:ut.string().describe("Status message")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=await qi(e.browserContext,e.page,{urlPattern:t.urlPattern,method:t.method,timing:t.timing||"request",onError:t.onError});return{id:n.id,urlPattern:n.urlPattern,method:n.method,timing:n.timing,onError:n.onError,message:`Netpoint set for ${t.urlPattern} on ${t.timing||"request"}`}}};import{z as xs}from"zod";var Ro=class{static{s(this,"RemoveNetpoint")}name(){return"debug_remove-netpoint"}description(){return"Removes a netpoint by its ID."}inputSchema(){return{id:xs.string().describe("Netpoint ID to remove")}}outputSchema(){return{success:xs.boolean().describe("Whether the netpoint was removed"),message:xs.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{success:!1,message:"No active netpoints"};let n=Wi(e.browserContext,t.id);return{success:n,message:n?`Netpoint ${t.id} removed`:`Netpoint ${t.id} not found`}}};import{z as Xe}from"zod";var ko=class{static{s(this,"ListNetpoints")}name(){return"debug_list-netpoints"}description(){return"Lists all active netpoints."}inputSchema(){return{}}outputSchema(){return{netpoints:Xe.array(Xe.object({id:Xe.string(),urlPattern:Xe.string(),method:Xe.string().optional(),timing:Xe.string(),onError:Xe.boolean().optional(),enabled:Xe.boolean(),hitCount:Xe.number(),lastHitAt:Xe.number().optional()})).describe("List of netpoints"),total:Xe.number().describe("Total count")}}async handle(e,t){if(!N(e.browserContext))return{netpoints:[],total:0};let r=vt(e.browserContext).map(i=>({id:i.id,urlPattern:i.urlPattern,method:i.method,timing:i.timing,onError:i.onError,enabled:i.enabled,hitCount:i.hitCount,lastHitAt:i.lastHitAt}));return{netpoints:r,total:r.length}}};import{z as ea}from"zod";var _o=class{static{s(this,"ClearNetpoints")}name(){return"debug_clear-netpoints"}description(){return"Removes all netpoints."}inputSchema(){return{}}outputSchema(){return{clearedCount:ea.number().describe("Number of netpoints cleared"),message:ea.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No netpoints to clear"};let n=$i(e.browserContext);return{clearedCount:n,message:`Cleared ${n} netpoint(s)`}}};var ta=[new Jn,new Yn,new Qn,new Zn,new eo,new to,new no,new oo,new ro,new so,new ao,new lo,new uo,new co,new mo,new bo,new go,new ho,new fo,new yo,new wo,new So,new xo,new Io,new Co,new vo,new Oo,new Eo,new No,new Po,new Ro,new ko,new _o];import Is from"sharp";import tu from"ssim.js";var nu=!1,ou=10;function ru(o){return Number.isFinite(o)?Math.max(0,Math.min(1,o)):0}s(ru,"_clamp01");async function na(o,e,t,n){let r;if(n==="semantic"){r=Is(o).resize(e,t,{fit:"cover",position:"centre"});let l=Math.max(1,Math.floor(e/2)),u=Math.max(1,Math.floor(t/2));r=r.resize(l,u,{fit:"cover",position:"centre"}).grayscale(nu).blur(ou)}else r=Is(o).resize(e,t,{fit:"cover",position:"centre"});let i=await r.ensureAlpha().raw().toBuffer({resolveWithObject:!0});return{data:new Uint8ClampedArray(i.data.buffer,i.data.byteOffset,i.data.byteLength),width:i.info.width,height:i.info.height}}s(na,"_loadNormalized");function su(o,e){let t=tu({data:o.data,width:o.width,height:o.height},{data:e.data,width:e.width,height:e.height}),n=Number(t.mssim??t.ssim??0);return ru(n)}s(su,"_computeSsim");async function oa(o,e,t){let n=t?.mode??"semantic",r=t?.canvasWidth,i=t?.canvasHeight;if(typeof r!="number"||!Number.isFinite(r)||r<=0||typeof i!="number"||!Number.isFinite(i)||i<=0){let m=await Is(e.image).metadata();if(r=m.width??0,i=m.height??0,r<=0||i<=0)throw new Error("Failed to read Figma image dimensions.")}let a=await na(e.image,r,i,n),l=await na(o.image,r,i,n);return{score:su(a,l)}}s(oa,"compare");function ra(o,e){let t=Math.min(o.length,e.length),n=0;for(let r=0;r<t;r++)n+=o[r]*e[r];return n}s(ra,"dot");function Cs(o){let e=0;for(let t=0;t<o.length;t++){let n=o[t];e+=n*n}return Math.sqrt(e)}s(Cs,"norm");function sa(o){let e=Cs(o);if(e===0)return o.slice();let t=new Array(o.length);for(let n=0;n<o.length;n++)t[n]=o[n]/e;return t}s(sa,"l2Normalize");function Mo(o,e,t){if(t){let r=sa(o),i=sa(e);return ra(r,i)}let n=Cs(o)*Cs(e);return n===0?0:ra(o,e)/n}s(Mo,"cosineSimilarity");import{BedrockRuntimeClient as ia,InvokeModelCommand as iu}from"@aws-sdk/client-bedrock-runtime";import{fromIni as au}from"@aws-sdk/credential-providers";import lu from"sharp";var uu=1024,cu=90,mu=1024;async function pu(o,e,t){let n=lu(o),r=t?.maxDim||uu;if(n=n.resize({width:r,height:r,fit:"inside",withoutEnlargement:!0}),e==="png")return await n.png().toBuffer();let i=t?.jpegQuality||cu;return await n.jpeg({quality:i}).toBuffer()}s(pu,"_prepareImage");var du=new Set(["amazon.titan-embed-image-v1"]),bu="amazon.titan-embed-image-v1",Zt;function gu(){return _n&&!!Xt}s(gu,"_isAwsBedrockActive");function hu(){if(Zt)return Zt;let o=Xt;if(!o)return;let e=kn;return e?(Zt=new ia({region:o,credentials:au({profile:e})}),Zt):(Zt=new ia({region:o}),Zt)}s(hu,"_getOrCreateBedrockClient");async function fu(o,e,t,n){let i={inputImage:(await pu(o.image,o.type,t)).toString("base64"),embeddingConfig:{outputEmbeddingLength:mu}},a=new iu({modelId:n,contentType:"application/json",accept:"application/json",body:Buffer.from(JSON.stringify(i),"utf-8")}),l=await e.send(a),u=l?.body instanceof Uint8Array?l.body:new Uint8Array(l?.body??[]),m=Buffer.from(u).toString("utf-8"),c;try{c=m?JSON.parse(m):{}}catch{throw new Error(`Amazon Bedrock Titan returned non-JSON response for embeddings: ${m.slice(0,300)}`)}let p=c?.embedding??c?.embeddings?.[0]??c?.outputEmbedding??c?.vector;if(!Array.isArray(p)||p.length===0||typeof p[0]!="number")throw new Error(`Unexpected Amazon Bedrock Titan image embedding response format: ${m.slice(0,500)}`);return p}s(fu,"_embedImageWithAmazonBedrockTitan");async function yu(o,e,t){let n=e?.modelId??Gs??bu;if(!du.has(n))throw new Error(`Unsupported Amazon Bedrock image embedding model id: ${n}`);return await fu(o,t,e,n)}s(yu,"_embedImageWithAmazonBedrock");async function aa(o,e){if(gu()){let t=hu();return t?yu(o,e,t):void 0}}s(aa,"_embedImage");async function la(o,e,t){let n=typeof t?.normalize=="boolean"?t.normalize:!0,r=await aa(e,t);if(!r)return;let i=await aa(o,t);return i?{score:Mo(r,i,n)}:void 0}s(la,"compare");import{BedrockRuntimeClient as ua,InvokeModelCommand as wu}from"@aws-sdk/client-bedrock-runtime";import{fromIni as Tu}from"@aws-sdk/credential-providers";import Su from"sharp";var xu=`
414
+ `}inputSchema(){return{urlPattern:lt.string().describe("Glob pattern to match request URLs"),method:lt.string().describe("HTTP method filter (GET, POST, PUT, DELETE, etc.)").optional(),timing:lt.enum(["request","response"]).describe('When to trigger: "request" or "response". Default: "request"').optional().default("request"),onError:lt.boolean().describe("Only trigger on error responses (4xx, 5xx)").optional()}}outputSchema(){return{id:lt.string().describe("Netpoint ID"),urlPattern:lt.string().describe("URL pattern"),method:lt.string().optional().describe("HTTP method filter"),timing:lt.string().describe("Trigger timing"),onError:lt.boolean().optional().describe("Error-only filter"),message:lt.string().describe("Status message")}}async handle(e,t){N(e.browserContext)||await Ue(e.browserContext,e.page);let n=await zi(e.browserContext,e.page,{urlPattern:t.urlPattern,method:t.method,timing:t.timing||"request",onError:t.onError});return{id:n.id,urlPattern:n.urlPattern,method:n.method,timing:n.timing,onError:n.onError,message:`Netpoint set for ${t.urlPattern} on ${t.timing||"request"}`}}};import{z as vs}from"zod";var ko=class{static{s(this,"RemoveNetpoint")}name(){return"debug_remove-netpoint"}description(){return"Removes a netpoint by its ID."}inputSchema(){return{id:vs.string().describe("Netpoint ID to remove")}}outputSchema(){return{success:vs.boolean().describe("Whether the netpoint was removed"),message:vs.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{success:!1,message:"No active netpoints"};let n=Vi(e.browserContext,t.id);return{success:n,message:n?`Netpoint ${t.id} removed`:`Netpoint ${t.id} not found`}}};import{z as Ye}from"zod";var _o=class{static{s(this,"ListNetpoints")}name(){return"debug_list-netpoints"}description(){return"Lists all active netpoints."}inputSchema(){return{}}outputSchema(){return{netpoints:Ye.array(Ye.object({id:Ye.string(),urlPattern:Ye.string(),method:Ye.string().optional(),timing:Ye.string(),onError:Ye.boolean().optional(),enabled:Ye.boolean(),hitCount:Ye.number(),lastHitAt:Ye.number().optional()})).describe("List of netpoints"),total:Ye.number().describe("Total count")}}async handle(e,t){if(!N(e.browserContext))return{netpoints:[],total:0};let r=It(e.browserContext).map(i=>({id:i.id,urlPattern:i.urlPattern,method:i.method,timing:i.timing,onError:i.onError,enabled:i.enabled,hitCount:i.hitCount,lastHitAt:i.lastHitAt}));return{netpoints:r,total:r.length}}};import{z as ra}from"zod";var Mo=class{static{s(this,"ClearNetpoints")}name(){return"debug_clear-netpoints"}description(){return"Removes all netpoints."}inputSchema(){return{}}outputSchema(){return{clearedCount:ra.number().describe("Number of netpoints cleared"),message:ra.string().describe("Status message")}}async handle(e,t){if(!N(e.browserContext))return{clearedCount:0,message:"No netpoints to clear"};let n=Gi(e.browserContext);return{clearedCount:n,message:`Cleared ${n} netpoint(s)`}}};var sa=[new Jn,new Qn,new Zn,new eo,new to,new no,new oo,new ro,new so,new io,new lo,new uo,new co,new mo,new po,new ho,new go,new fo,new yo,new wo,new To,new xo,new vo,new Io,new Co,new Eo,new Oo,new No,new Po,new Ro,new ko,new _o,new Mo];import Is from"sharp";import ru from"ssim.js";var su=!1,iu=10;function au(o){return Number.isFinite(o)?Math.max(0,Math.min(1,o)):0}s(au,"_clamp01");async function ia(o,e,t,n){let r;if(n==="semantic"){r=Is(o).resize(e,t,{fit:"cover",position:"centre"});let l=Math.max(1,Math.floor(e/2)),u=Math.max(1,Math.floor(t/2));r=r.resize(l,u,{fit:"cover",position:"centre"}).grayscale(su).blur(iu)}else r=Is(o).resize(e,t,{fit:"cover",position:"centre"});let i=await r.ensureAlpha().raw().toBuffer({resolveWithObject:!0});return{data:new Uint8ClampedArray(i.data.buffer,i.data.byteOffset,i.data.byteLength),width:i.info.width,height:i.info.height}}s(ia,"_loadNormalized");function lu(o,e){let t=ru({data:o.data,width:o.width,height:o.height},{data:e.data,width:e.width,height:e.height}),n=Number(t.mssim??t.ssim??0);return au(n)}s(lu,"_computeSsim");async function aa(o,e,t){let n=t?.mode??"semantic",r=t?.canvasWidth,i=t?.canvasHeight;if(typeof r!="number"||!Number.isFinite(r)||r<=0||typeof i!="number"||!Number.isFinite(i)||i<=0){let m=await Is(e.image).metadata();if(r=m.width??0,i=m.height??0,r<=0||i<=0)throw new Error("Failed to read Figma image dimensions.")}let a=await ia(e.image,r,i,n),l=await ia(o.image,r,i,n);return{score:lu(a,l)}}s(aa,"compare");function la(o,e){let t=Math.min(o.length,e.length),n=0;for(let r=0;r<t;r++)n+=o[r]*e[r];return n}s(la,"dot");function Cs(o){let e=0;for(let t=0;t<o.length;t++){let n=o[t];e+=n*n}return Math.sqrt(e)}s(Cs,"norm");function ua(o){let e=Cs(o);if(e===0)return o.slice();let t=new Array(o.length);for(let n=0;n<o.length;n++)t[n]=o[n]/e;return t}s(ua,"l2Normalize");function Do(o,e,t){if(t){let r=ua(o),i=ua(e);return la(r,i)}let n=Cs(o)*Cs(e);return n===0?0:la(o,e)/n}s(Do,"cosineSimilarity");import{BedrockRuntimeClient as ca,InvokeModelCommand as uu}from"@aws-sdk/client-bedrock-runtime";import{fromIni as cu}from"@aws-sdk/credential-providers";import mu from"sharp";var pu=1024,du=90,bu=1024;async function hu(o,e,t){let n=mu(o),r=t?.maxDim||pu;if(n=n.resize({width:r,height:r,fit:"inside",withoutEnlargement:!0}),e==="png")return await n.png().toBuffer();let i=t?.jpegQuality||du;return await n.jpeg({quality:i}).toBuffer()}s(hu,"_prepareImage");var gu=new Set(["amazon.titan-embed-image-v1"]),fu="amazon.titan-embed-image-v1",Zt;function yu(){return Mn&&!!Xt}s(yu,"_isAwsBedrockActive");function wu(){if(Zt)return Zt;let o=Xt;if(!o)return;let e=_n;return e?(Zt=new ca({region:o,credentials:cu({profile:e})}),Zt):(Zt=new ca({region:o}),Zt)}s(wu,"_getOrCreateBedrockClient");async function Tu(o,e,t,n){let i={inputImage:(await hu(o.image,o.type,t)).toString("base64"),embeddingConfig:{outputEmbeddingLength:bu}},a=new uu({modelId:n,contentType:"application/json",accept:"application/json",body:Buffer.from(JSON.stringify(i),"utf-8")}),l=await e.send(a),u=l?.body instanceof Uint8Array?l.body:new Uint8Array(l?.body??[]),m=Buffer.from(u).toString("utf-8"),c;try{c=m?JSON.parse(m):{}}catch{throw new Error(`Amazon Bedrock Titan returned non-JSON response for embeddings: ${m.slice(0,300)}`)}let p=c?.embedding??c?.embeddings?.[0]??c?.outputEmbedding??c?.vector;if(!Array.isArray(p)||p.length===0||typeof p[0]!="number")throw new Error(`Unexpected Amazon Bedrock Titan image embedding response format: ${m.slice(0,500)}`);return p}s(Tu,"_embedImageWithAmazonBedrockTitan");async function Su(o,e,t){let n=e?.modelId??Js??fu;if(!gu.has(n))throw new Error(`Unsupported Amazon Bedrock image embedding model id: ${n}`);return await Tu(o,t,e,n)}s(Su,"_embedImageWithAmazonBedrock");async function ma(o,e){if(yu()){let t=wu();return t?Su(o,e,t):void 0}}s(ma,"_embedImage");async function pa(o,e,t){let n=typeof t?.normalize=="boolean"?t.normalize:!0,r=await ma(e,t);if(!r)return;let i=await ma(o,t);return i?{score:Do(r,i,n)}:void 0}s(pa,"compare");import{BedrockRuntimeClient as da,InvokeModelCommand as xu}from"@aws-sdk/client-bedrock-runtime";import{fromIni as vu}from"@aws-sdk/credential-providers";import Iu from"sharp";var Cu=`
416
415
  You are analyzing a UI screenshot to compare it against another UI.
417
416
 
418
417
  Your goal is to produce a STRUCTURAL LAYOUT FINGERPRINT that remains stable
@@ -474,7 +473,7 @@ FORMAT
474
473
  - Keep the output under ~30 lines.
475
474
 
476
475
  Return plain text only. No markdown.
477
- `;function Iu(o){return o?.prompt??xu.trim()}s(Iu,"_resolvePrompt");function Cu(o){return typeof o?.maxDim=="number"&&o.maxDim>0?Math.floor(o.maxDim):1024}s(Cu,"_resolveMaxDim");function vu(o){return o?.imageFormat==="jpeg"?"jpeg":"png"}s(vu,"_resolveImageFormat");function Ou(o){let e=o?.jpegQuality;return typeof e=="number"&&e>=50&&e<=100?Math.floor(e):90}s(Ou,"_resolveJpegQuality");async function Eu(o,e){let t=Cu(e),n=vu(e),r=Ou(e),i=Su(o).resize({width:t,height:t,fit:"inside",withoutEnlargement:!0}),a,l;return n==="png"?(a=await i.png().toBuffer(),l="image/png"):(a=await i.jpeg({quality:r}).toBuffer(),l="image/jpeg"),{bytes:a,mimeType:l}}s(Eu,"_preprocessImage");var Nu=new Set(["amazon.titan-embed-text-v2:0"]),Pu="amazon.titan-embed-text-v2:0",Ru=new Set(["anthropic.claude-3-haiku-20240307-v1","anthropic.claude-3-sonnet-20240229-v1:0","anthropic.claude-3-5-sonnet-20241022-v2:0","anthropic.claude-3-7-sonnet-20250219-v1:0","anthropic.claude-3-opus-20240229-v1:0","anthropic.claude-haiku-4-5-20251001-v1:0","anthropic.claude-opus-4-1-20250805-v1:0","anthropic.claude-opus-4-5-20251101-v1:0"]),ku="anthropic.claude-3-sonnet-20240229-v1:0",en;function pa(){return _n&&!!Xt}s(pa,"_isAwsBedrockActive");function da(){if(en)return en;let o=Xt;if(!o)return;let e=kn;return e?(en=new ua({region:o,credentials:Tu({profile:e})}),en):(en=new ua({region:o}),en)}s(da,"_getOrCreateBedrockClient");async function ba(o,e,t){let n=new wu({modelId:e,contentType:"application/json",accept:"application/json",body:Buffer.from(JSON.stringify(t))}),r=await o.send(n),i=Buffer.from(r.body).toString("utf-8");return JSON.parse(i)}s(ba,"_invokeBedrock");async function _u(o,e,t,n){let{bytes:r,mimeType:i}=await Eu(o.image,e),l={anthropic_version:"bedrock-2023-05-31",max_tokens:1e4,temperature:0,messages:[{role:"user",content:[{type:"text",text:Iu(e)},{type:"image",source:{type:"base64",media_type:i,data:r.toString("base64")}}]}]},u=await ba(t,n,l),m=u?.content?.[0]?.text??u?.output_text??u?.completion;if(!m||!m.trim())throw new Error("Amazon Bedrock Claude returned empty description.");return m.trim()}s(_u,"_describeUIWithAmazonBedrockClaude");async function Mu(o,e,t){let i=(await ba(e,t,{inputText:o}))?.embedding;if(!Array.isArray(i)||typeof i[0]!="number")throw new Error("Unexpected embedding response for Amazon Bedrock Titan text embedding.");return i}s(Mu,"_embedTextWithAmazonBedrockTitan");async function Du(o,e,t){let n=e?.visionModelId??Xs??ku;if(!Ru.has(n))throw new Error(`Unsupported Amazon Bedrock vision model id: ${n}`);return await _u(o,e,t,n)}s(Du,"_describeUIWithAmazonBedrock");async function Bu(o,e,t){let n=e?.textEmbedModelId??Ks??Pu;if(!Nu.has(n))throw new Error(`Unsupported Amazon Bedrock text embedding model id: ${n}`);return await Mu(o,t,n)}s(Bu,"_embedTextWithAmazonBedrock");async function ca(o,e){if(pa()){let t=da();return t?Du(o,e,t):void 0}}s(ca,"_describeUI");async function ma(o,e){if(pa()){let t=da();return t?Bu(o,e,t):void 0}}s(ma,"_embedTextVector");async function ga(o,e,t){let n=typeof t?.normalize=="boolean"?t.normalize:!0,r=await ca(e,t);if(!r)return;let i=await ca(o,t);if(!i)return;let a=await ma(r,t);if(!a)return;let l=await ma(i,t);return l?{score:Mo(a,l,n)}:void 0}s(ga,"compare");var Au=.25,Lu=.5,Fu=.25;function Do(o){return Number.isFinite(o)?Math.max(0,Math.min(1,o)):0}s(Do,"_clamp01");function vs(o,e){return typeof o=="number"&&Number.isFinite(o)&&o>0?o:e}s(vs,"_weightOrDefault");async function ha(o,e,t){let n=[],r=vs(t?.weights?.mssim,Au),i=vs(t?.weights?.vectorEmbedding,Lu),a=vs(t?.weights?.textEmbedding,Fu),l=await oa(o,e,t?.mssim),u=Do(l.score);n.push(`mssim=${u.toFixed(5)}`);let m;try{let M=await la(o,e,t?.imageEmbedding);M&&typeof M.score=="number"?(m=Do(M.score),n.push(`image-embedding=${m.toFixed(5)}`)):n.push("image-embedding=skipped (inactive)")}catch(M){n.push(`image-embedding=skipped (${M instanceof Error?M.message:String(M)})`)}let c;try{let M=await ga(o,e,t?.textEmbedding);M&&typeof M.score=="number"?(c=Do(M.score),n.push(`text-embedding=${c.toFixed(5)}`)):n.push("text-embedding=skipped (inactive)")}catch(M){n.push(`text-embedding=skipped (${M instanceof Error?M.message:String(M)})`)}let p=[{name:"mssim",score:u,weight:r}];typeof m=="number"&&p.push({name:"image-embedding",score:m,weight:i}),typeof c=="number"&&p.push({name:"text-embedding",score:c,weight:a});let b=p.reduce((M,f)=>M+f.weight,0),T=b>0?p.reduce((M,f)=>M+f.score*(f.weight/b),0):0,k=Do(T);return n.push(`combined=${k.toFixed(5)} (signals=${p.map(M=>M.name).join(", ")})`),{score:k,notes:n}}s(ha,"compareWithNotes");import Uu from"node:crypto";function Hu(){let o=Js;if(!o)throw new Error("No Figma access token configured");return o}s(Hu,"_requireFigmaToken");function qu(o){return o==="jpg"?{mimeType:"image/jpeg",type:"jpeg"}:{mimeType:"image/png",type:"png"}}s(qu,"_mimeTypeFor");function Wu(o){let e=Uu.createHash("sha256");return e.update(o.fileKey),e.update("|"),e.update(o.nodeId),e.update("|"),e.update(o.format??"png"),e.update("|"),e.update(String(o.scale??2)),e.digest("hex").slice(0,24)}s(Wu,"_buildCacheKey");async function $u(o,e){let t=await fetch(o,{method:"GET",headers:{"X-Figma-Token":e,Accept:"application/json"}}),n=await t.text(),r;try{r=n?JSON.parse(n):{}}catch{throw new Error(`Figma API returned non-JSON response (status=${t.status}). Body: ${n.slice(0,500)}`)}if(!t.ok){let i=typeof r?.err=="string"?r.err:`Figma API error (status=${t.status})`;throw new Error(i)}return r}s($u,"_fetchJson");async function ju(o){let e=await fetch(o,{method:"GET"});if(!e.ok){let n=await e.text().catch(()=>"");throw new Error(`Failed to download Figma rendered image (status=${e.status}): ${n.slice(0,300)}`)}let t=await e.arrayBuffer();return Buffer.from(t)}s(ju,"_fetchBinary");async function fa(o){let e=Hu(),t=o.format??"png",n=typeof o.scale=="number"&&o.scale>0?o.scale:2,{mimeType:r,type:i}=qu(t),a=Ys,l=o.fileKey,u=o.nodeId,m=`${a}/images/${encodeURIComponent(l)}?ids=${encodeURIComponent(u)}&format=${encodeURIComponent(t)}&scale=${encodeURIComponent(String(n))}`,c=await $u(m,e),p=c.images?.[u];if(!p){let M=typeof c.err=="string"&&c.err.trim()?c.err:"Figma did not return an image URL for the given nodeId.";throw new Error(M)}let b=await ju(p),T=Wu(o),k={image:b,mimeType:r,type:i,cacheKey:T};return o.includeId===!0&&(k.nodeId=u,k.fileKey=l),k}s(fa,"getFigmaDesignScreenshot");import{z as pe}from"zod";var ya="png",zu=!0,wa="semantic",Bo=class{static{s(this,"ComparePageWithDesign")}name(){return"figma_compare-page-with-design"}description(){return`
476
+ `;function Eu(o){return o?.prompt??Cu.trim()}s(Eu,"_resolvePrompt");function Ou(o){return typeof o?.maxDim=="number"&&o.maxDim>0?Math.floor(o.maxDim):1024}s(Ou,"_resolveMaxDim");function Nu(o){return o?.imageFormat==="jpeg"?"jpeg":"png"}s(Nu,"_resolveImageFormat");function Pu(o){let e=o?.jpegQuality;return typeof e=="number"&&e>=50&&e<=100?Math.floor(e):90}s(Pu,"_resolveJpegQuality");async function Ru(o,e){let t=Ou(e),n=Nu(e),r=Pu(e),i=Iu(o).resize({width:t,height:t,fit:"inside",withoutEnlargement:!0}),a,l;return n==="png"?(a=await i.png().toBuffer(),l="image/png"):(a=await i.jpeg({quality:r}).toBuffer(),l="image/jpeg"),{bytes:a,mimeType:l}}s(Ru,"_preprocessImage");var ku=new Set(["amazon.titan-embed-text-v2:0"]),_u="amazon.titan-embed-text-v2:0",Mu=new Set(["anthropic.claude-3-haiku-20240307-v1","anthropic.claude-3-sonnet-20240229-v1:0","anthropic.claude-3-5-sonnet-20241022-v2:0","anthropic.claude-3-7-sonnet-20250219-v1:0","anthropic.claude-3-opus-20240229-v1:0","anthropic.claude-haiku-4-5-20251001-v1:0","anthropic.claude-opus-4-1-20250805-v1:0","anthropic.claude-opus-4-5-20251101-v1:0"]),Du="anthropic.claude-3-sonnet-20240229-v1:0",en;function ga(){return Mn&&!!Xt}s(ga,"_isAwsBedrockActive");function fa(){if(en)return en;let o=Xt;if(!o)return;let e=_n;return e?(en=new da({region:o,credentials:vu({profile:e})}),en):(en=new da({region:o}),en)}s(fa,"_getOrCreateBedrockClient");async function ya(o,e,t){let n=new xu({modelId:e,contentType:"application/json",accept:"application/json",body:Buffer.from(JSON.stringify(t))}),r=await o.send(n),i=Buffer.from(r.body).toString("utf-8");return JSON.parse(i)}s(ya,"_invokeBedrock");async function Bu(o,e,t,n){let{bytes:r,mimeType:i}=await Ru(o.image,e),l={anthropic_version:"bedrock-2023-05-31",max_tokens:1e4,temperature:0,messages:[{role:"user",content:[{type:"text",text:Eu(e)},{type:"image",source:{type:"base64",media_type:i,data:r.toString("base64")}}]}]},u=await ya(t,n,l),m=u?.content?.[0]?.text??u?.output_text??u?.completion;if(!m||!m.trim())throw new Error("Amazon Bedrock Claude returned empty description.");return m.trim()}s(Bu,"_describeUIWithAmazonBedrockClaude");async function Au(o,e,t){let i=(await ya(e,t,{inputText:o}))?.embedding;if(!Array.isArray(i)||typeof i[0]!="number")throw new Error("Unexpected embedding response for Amazon Bedrock Titan text embedding.");return i}s(Au,"_embedTextWithAmazonBedrockTitan");async function Lu(o,e,t){let n=e?.visionModelId??Zs??Du;if(!Mu.has(n))throw new Error(`Unsupported Amazon Bedrock vision model id: ${n}`);return await Bu(o,e,t,n)}s(Lu,"_describeUIWithAmazonBedrock");async function Fu(o,e,t){let n=e?.textEmbedModelId??Qs??_u;if(!ku.has(n))throw new Error(`Unsupported Amazon Bedrock text embedding model id: ${n}`);return await Au(o,t,n)}s(Fu,"_embedTextWithAmazonBedrock");async function ba(o,e){if(ga()){let t=fa();return t?Lu(o,e,t):void 0}}s(ba,"_describeUI");async function ha(o,e){if(ga()){let t=fa();return t?Fu(o,e,t):void 0}}s(ha,"_embedTextVector");async function wa(o,e,t){let n=typeof t?.normalize=="boolean"?t.normalize:!0,r=await ba(e,t);if(!r)return;let i=await ba(o,t);if(!i)return;let a=await ha(r,t);if(!a)return;let l=await ha(i,t);return l?{score:Do(a,l,n)}:void 0}s(wa,"compare");var Uu=.25,Hu=.5,Wu=.25;function Bo(o){return Number.isFinite(o)?Math.max(0,Math.min(1,o)):0}s(Bo,"_clamp01");function Es(o,e){return typeof o=="number"&&Number.isFinite(o)&&o>0?o:e}s(Es,"_weightOrDefault");async function Ta(o,e,t){let n=[],r=Es(t?.weights?.mssim,Uu),i=Es(t?.weights?.vectorEmbedding,Hu),a=Es(t?.weights?.textEmbedding,Wu),l=await aa(o,e,t?.mssim),u=Bo(l.score);n.push(`mssim=${u.toFixed(5)}`);let m;try{let B=await pa(o,e,t?.imageEmbedding);B&&typeof B.score=="number"?(m=Bo(B.score),n.push(`image-embedding=${m.toFixed(5)}`)):n.push("image-embedding=skipped (inactive)")}catch(B){n.push(`image-embedding=skipped (${B instanceof Error?B.message:String(B)})`)}let c;try{let B=await wa(o,e,t?.textEmbedding);B&&typeof B.score=="number"?(c=Bo(B.score),n.push(`text-embedding=${c.toFixed(5)}`)):n.push("text-embedding=skipped (inactive)")}catch(B){n.push(`text-embedding=skipped (${B instanceof Error?B.message:String(B)})`)}let p=[{name:"mssim",score:u,weight:r}];typeof m=="number"&&p.push({name:"image-embedding",score:m,weight:i}),typeof c=="number"&&p.push({name:"text-embedding",score:c,weight:a});let b=p.reduce((B,w)=>B+w.weight,0),f=b>0?p.reduce((B,w)=>B+w.score*(w.weight/b),0):0,x=Bo(f);return n.push(`combined=${x.toFixed(5)} (signals=${p.map(B=>B.name).join(", ")})`),{score:x,notes:n}}s(Ta,"compareWithNotes");import qu from"node:crypto";function $u(){let o=ei;if(!o)throw new Error("No Figma access token configured");return o}s($u,"_requireFigmaToken");function ju(o){return o==="jpg"?{mimeType:"image/jpeg",type:"jpeg"}:{mimeType:"image/png",type:"png"}}s(ju,"_mimeTypeFor");function zu(o){let e=qu.createHash("sha256");return e.update(o.fileKey),e.update("|"),e.update(o.nodeId),e.update("|"),e.update(o.format??"png"),e.update("|"),e.update(String(o.scale??2)),e.digest("hex").slice(0,24)}s(zu,"_buildCacheKey");async function Vu(o,e){let t=await fetch(o,{method:"GET",headers:{"X-Figma-Token":e,Accept:"application/json"}}),n=await t.text(),r;try{r=n?JSON.parse(n):{}}catch{throw new Error(`Figma API returned non-JSON response (status=${t.status}). Body: ${n.slice(0,500)}`)}if(!t.ok){let i=typeof r?.err=="string"?r.err:`Figma API error (status=${t.status})`;throw new Error(i)}return r}s(Vu,"_fetchJson");async function Gu(o){let e=await fetch(o,{method:"GET"});if(!e.ok){let n=await e.text().catch(()=>"");throw new Error(`Failed to download Figma rendered image (status=${e.status}): ${n.slice(0,300)}`)}let t=await e.arrayBuffer();return Buffer.from(t)}s(Gu,"_fetchBinary");async function Sa(o){let e=$u(),t=o.format??"png",n=typeof o.scale=="number"&&o.scale>0?o.scale:2,{mimeType:r,type:i}=ju(t),a=ti,l=o.fileKey,u=o.nodeId,m=`${a}/images/${encodeURIComponent(l)}?ids=${encodeURIComponent(u)}&format=${encodeURIComponent(t)}&scale=${encodeURIComponent(String(n))}`,c=await Vu(m,e),p=c.images?.[u];if(!p){let B=typeof c.err=="string"&&c.err.trim()?c.err:"Figma did not return an image URL for the given nodeId.";throw new Error(B)}let b=await Gu(p),f=zu(o),x={image:b,mimeType:r,type:i,cacheKey:f};return o.includeId===!0&&(x.nodeId=u,x.fileKey=l),x}s(Sa,"getFigmaDesignScreenshot");import{z as be}from"zod";var xa="png",Ku=!0,va="semantic",Ao=class{static{s(this,"ComparePageWithDesign")}name(){return"figma_compare-page-with-design"}description(){return`
478
477
  Compares the CURRENT PAGE UI against a Figma design snapshot and returns a combined similarity score.
479
478
 
480
479
  What this tool does:
@@ -492,7 +491,7 @@ How to use it effectively:
492
491
  - Notes explain which signals were used or skipped; skipped signals usually mean missing cloud configuration (e.g. AWS_REGION, inference profile, etc).
493
492
 
494
493
  This tool is designed for UI regression checks, design parity checks, and "does this page still match the intended layout?" validation.
495
- `.trim()}inputSchema(){return{figmaFileKey:pe.string().min(1).describe("Figma file key (the part after /file/ in Figma URL)."),figmaNodeId:pe.string().min(1).describe('Figma node id to render (frame/component node id like "12:34").'),selector:pe.string().optional().describe("Optional CSS selector to compare only a specific region of the page."),fullPage:pe.boolean().optional().default(zu).describe("If true, captures the full scrollable page. Ignored when selector is provided."),figmaScale:pe.number().int().positive().optional().describe("Optional scale factor for Figma raster export (e.g. 1, 2, 3)."),figmaFormat:pe.enum(["png","jpg"]).optional().describe("Optional raster format for Figma snapshot."),weights:pe.object({mssim:pe.number().positive().optional().describe("Weight for MSSIM signal."),imageEmbedding:pe.number().positive().optional().describe("Weight for image embedding signal."),textEmbedding:pe.number().positive().optional().describe("Weight for vision\u2192text\u2192text embedding signal.")}).optional().describe("Optional weights to combine signals. Only active signals participate."),mssimMode:pe.enum(["raw","semantic"]).optional().default(wa).describe("MSSIM mode. semantic is more robust for real-data vs design-data comparisons."),maxDim:pe.number().int().positive().optional().describe("Optional preprocessing max dimension forwarded to compare pipeline."),jpegQuality:pe.number().int().min(50).max(100).optional().describe("Optional JPEG quality forwarded to compare pipeline (used only when JPEG encoding is selected internally).")}}outputSchema(){return{score:pe.number().describe("Combined similarity score in the range [0..1]. Higher means more similar."),notes:pe.array(pe.string()).describe("Human-readable notes explaining which signals were used and their individual scores."),meta:pe.object({pageUrl:pe.string().describe("URL of the page that was compared."),pageTitle:pe.string().describe("Title of the page that was compared."),figmaFileKey:pe.string().describe("Figma file key used for the design snapshot."),figmaNodeId:pe.string().describe("Figma node id used for the design snapshot."),selector:pe.string().nullable().describe("Selector used for page screenshot, if any. Null means full page."),fullPage:pe.boolean().describe("Whether the page screenshot was full-page."),pageImageType:pe.enum(["png","jpeg"]).describe("Image type of the captured page screenshot."),figmaImageType:pe.enum(["png","jpeg"]).describe("Image type of the captured Figma snapshot.")}).describe("Metadata about what was compared.")}}async handle(e,t){let n=String(e.page.url()),r=String(await e.page.title()),i=t.figmaFormat??"png",a=typeof t.figmaScale=="number"?t.figmaScale:void 0,l=await fa({fileKey:t.figmaFileKey,nodeId:t.figmaNodeId,format:i,scale:a}),u;if(typeof t.selector=="string"&&t.selector.trim()){let b=t.selector.trim(),T=e.page.locator(b);if(await T.count()===0)throw new Error(`Element not found for selector: ${b}`);u=await T.first().screenshot({type:ya})}else{let b=t.fullPage!==!1;u=await e.page.screenshot({type:ya,fullPage:b})}let m={image:u,type:"png",name:"page"},c={image:l.image,type:l.type==="jpeg"?"jpeg":"png",name:"figma"},p=await ha(m,c,{weights:t.weights?{mssim:t.weights.mssim,vectorEmbedding:t.weights.imageEmbedding,textEmbedding:t.weights.textEmbedding}:void 0,mssim:{mode:t.mssimMode??wa},imageEmbedding:{maxDim:t.maxDim,jpegQuality:typeof t.jpegQuality=="number"?t.jpegQuality:void 0},textEmbedding:{maxDim:t.maxDim,jpegQuality:typeof t.jpegQuality=="number"?t.jpegQuality:void 0}});return{score:p.score,notes:p.notes,meta:{pageUrl:n,pageTitle:r,figmaFileKey:t.figmaFileKey,figmaNodeId:t.figmaNodeId,selector:typeof t.selector=="string"&&t.selector.trim()?t.selector.trim():null,fullPage:typeof t.selector=="string"&&t.selector.trim()?!1:t.fullPage!==!1,pageImageType:"png",figmaImageType:l.type}}}};var Ta=[new Bo];import{z as Vu}from"zod";var Ao=class{static{s(this,"Click")}name(){return"interaction_click"}description(){return"Clicks an element on the page."}inputSchema(){return{selector:Vu.string().describe("CSS selector for the element to click.")}}outputSchema(){return{}}async handle(e,t){return await(await e.page.waitForSelector(t.selector)).click(),{}}};import{z as Sa}from"zod";var Lo=class{static{s(this,"Drag")}name(){return"interaction_drag"}description(){return"Drags an element to a target location."}inputSchema(){return{sourceSelector:Sa.string().describe("CSS selector for the element to drag."),targetSelector:Sa.string().describe("CSS selector for the target location.")}}outputSchema(){return{}}async handle(e,t){let n=await e.page.waitForSelector(t.sourceSelector),r=await e.page.waitForSelector(t.targetSelector),i=await n.boundingBox(),a=await r.boundingBox();if(!i||!a)throw new Error("Could not get element positions for drag operation");return await e.page.mouse.move(i.x+i.width/2,i.y+i.height/2),await e.page.mouse.down(),await e.page.mouse.move(a.x+a.width/2,a.y+a.height/2),await e.page.mouse.up(),{}}};import{z as xa}from"zod";var Fo=class{static{s(this,"Fill")}name(){return"interaction_fill"}description(){return"Fills out an input field."}inputSchema(){return{selector:xa.string().describe("CSS selector for the input field."),value:xa.string().describe("Value to fill.")}}outputSchema(){return{}}async handle(e,t){return await(await e.page.waitForSelector(t.selector)).fill(t.value),{}}};import{z as Gu}from"zod";var Uo=class{static{s(this,"Hover")}name(){return"interaction_hover"}description(){return"Hovers an element on the page."}inputSchema(){return{selector:Gu.string().describe("CSS selector for the element to hover.")}}outputSchema(){return{}}async handle(e,t){return await(await e.page.waitForSelector(t.selector)).hover(),{}}};import{z as Sn}from"zod";var Ia=50,Ca=10,Ho=class{static{s(this,"PressKey")}name(){return"interaction_press-key"}description(){return`
494
+ `.trim()}inputSchema(){return{figmaFileKey:be.string().min(1).describe("Figma file key (the part after /file/ in Figma URL)."),figmaNodeId:be.string().min(1).describe('Figma node id to render (frame/component node id like "12:34").'),selector:be.string().optional().describe("Optional CSS selector to compare only a specific region of the page."),fullPage:be.boolean().optional().default(Ku).describe("If true, captures the full scrollable page. Ignored when selector is provided."),figmaScale:be.number().int().positive().optional().describe("Optional scale factor for Figma raster export (e.g. 1, 2, 3)."),figmaFormat:be.enum(["png","jpg"]).optional().describe("Optional raster format for Figma snapshot."),weights:be.object({mssim:be.number().positive().optional().describe("Weight for MSSIM signal."),imageEmbedding:be.number().positive().optional().describe("Weight for image embedding signal."),textEmbedding:be.number().positive().optional().describe("Weight for vision\u2192text\u2192text embedding signal.")}).optional().describe("Optional weights to combine signals. Only active signals participate."),mssimMode:be.enum(["raw","semantic"]).optional().default(va).describe("MSSIM mode. semantic is more robust for real-data vs design-data comparisons."),maxDim:be.number().int().positive().optional().describe("Optional preprocessing max dimension forwarded to compare pipeline."),jpegQuality:be.number().int().min(50).max(100).optional().describe("Optional JPEG quality forwarded to compare pipeline (used only when JPEG encoding is selected internally).")}}outputSchema(){return{score:be.number().describe("Combined similarity score in the range [0..1]. Higher means more similar."),notes:be.array(be.string()).describe("Human-readable notes explaining which signals were used and their individual scores."),meta:be.object({pageUrl:be.string().describe("URL of the page that was compared."),pageTitle:be.string().describe("Title of the page that was compared."),figmaFileKey:be.string().describe("Figma file key used for the design snapshot."),figmaNodeId:be.string().describe("Figma node id used for the design snapshot."),selector:be.string().nullable().describe("Selector used for page screenshot, if any. Null means full page."),fullPage:be.boolean().describe("Whether the page screenshot was full-page."),pageImageType:be.enum(["png","jpeg"]).describe("Image type of the captured page screenshot."),figmaImageType:be.enum(["png","jpeg"]).describe("Image type of the captured Figma snapshot.")}).describe("Metadata about what was compared.")}}async handle(e,t){let n=String(e.page.url()),r=String(await e.page.title()),i=t.figmaFormat??"png",a=typeof t.figmaScale=="number"?t.figmaScale:void 0,l=await Sa({fileKey:t.figmaFileKey,nodeId:t.figmaNodeId,format:i,scale:a}),u;if(typeof t.selector=="string"&&t.selector.trim()){let b=t.selector.trim(),f=e.page.locator(b);if(await f.count()===0)throw new Error(`Element not found for selector: ${b}`);u=await f.first().screenshot({type:xa})}else{let b=t.fullPage!==!1;u=await e.page.screenshot({type:xa,fullPage:b})}let m={image:u,type:"png",name:"page"},c={image:l.image,type:l.type==="jpeg"?"jpeg":"png",name:"figma"},p=await Ta(m,c,{weights:t.weights?{mssim:t.weights.mssim,vectorEmbedding:t.weights.imageEmbedding,textEmbedding:t.weights.textEmbedding}:void 0,mssim:{mode:t.mssimMode??va},imageEmbedding:{maxDim:t.maxDim,jpegQuality:typeof t.jpegQuality=="number"?t.jpegQuality:void 0},textEmbedding:{maxDim:t.maxDim,jpegQuality:typeof t.jpegQuality=="number"?t.jpegQuality:void 0}});return{score:p.score,notes:p.notes,meta:{pageUrl:n,pageTitle:r,figmaFileKey:t.figmaFileKey,figmaNodeId:t.figmaNodeId,selector:typeof t.selector=="string"&&t.selector.trim()?t.selector.trim():null,fullPage:typeof t.selector=="string"&&t.selector.trim()?!1:t.fullPage!==!1,pageImageType:"png",figmaImageType:l.type}}}};var Ia=[new Ao];import{z as Ca}from"zod";var Xu=1e4,Lo=class{static{s(this,"Click")}name(){return"interaction_click"}description(){return"Clicks an element on the page."}inputSchema(){return{selector:Ca.string().describe("CSS selector for the element to click."),timeoutMs:Ca.number().int().positive().optional().describe("Timeout in ms to wait for the element (default 10000). Use a shorter value (e.g. 5000) to fail faster if the selector might be invalid.")}}outputSchema(){return{}}async handle(e,t){let n=t.timeoutMs??Xu;return await(await e.page.waitForSelector(t.selector,{state:"visible",timeout:n})).click(),{}}};import{z as Os}from"zod";var Yu=1e4,Fo=class{static{s(this,"Drag")}name(){return"interaction_drag"}description(){return"Drags an element to a target location."}inputSchema(){return{sourceSelector:Os.string().describe("CSS selector for the element to drag."),targetSelector:Os.string().describe("CSS selector for the target location."),timeoutMs:Os.number().int().positive().optional().describe("Timeout in ms to wait for source and target elements (default 10000). Use a shorter value (e.g. 5000) to fail faster if selectors might be invalid.")}}outputSchema(){return{}}async handle(e,t){let n=t.timeoutMs??Yu,r=await e.page.waitForSelector(t.sourceSelector,{state:"visible",timeout:n}),i=await e.page.waitForSelector(t.targetSelector,{state:"visible",timeout:n}),a=await r.boundingBox(),l=await i.boundingBox();if(!a||!l)throw new Error("Could not get element positions for drag operation");return await e.page.mouse.move(a.x+a.width/2,a.y+a.height/2),await e.page.mouse.down(),await e.page.mouse.move(l.x+l.width/2,l.y+l.height/2),await e.page.mouse.up(),{}}};import{z as Ns}from"zod";var Ju=1e4,Uo=class{static{s(this,"Fill")}name(){return"interaction_fill"}description(){return"Fills out an input field."}inputSchema(){return{selector:Ns.string().describe("CSS selector for the input field."),value:Ns.string().describe("Value to fill."),timeoutMs:Ns.number().int().positive().optional().describe("Timeout in ms to wait for the element (default 10000). Use a shorter value (e.g. 5000) to fail faster if the selector might be invalid.")}}outputSchema(){return{}}async handle(e,t){let n=t.timeoutMs??Ju;return await(await e.page.waitForSelector(t.selector,{state:"visible",timeout:n})).fill(t.value),{}}};import{z as Ea}from"zod";var Qu=1e4,Ho=class{static{s(this,"Hover")}name(){return"interaction_hover"}description(){return"Hovers an element on the page."}inputSchema(){return{selector:Ea.string().describe("CSS selector for the element to hover."),timeoutMs:Ea.number().int().positive().optional().describe("Timeout in ms to wait for the element (default 10000). Use a shorter value (e.g. 5000) to fail faster if the selector might be invalid.")}}outputSchema(){return{}}async handle(e,t){let n=t.timeoutMs??Qu;return await(await e.page.waitForSelector(t.selector,{state:"visible",timeout:n})).hover(),{}}};import{z as tn}from"zod";var Oa=50,Na=10,Zu=1e4,Wo=class{static{s(this,"PressKey")}name(){return"interaction_press-key"}description(){return`
496
495
  Presses a keyboard key with optional "hold" and auto-repeat behavior.
497
496
 
498
497
  Key facts:
@@ -506,7 +505,7 @@ Execution logic:
506
505
  \u2192 a single keyboard.press() is executed.
507
506
  - If holdMs is provided AND repeat=true:
508
507
  \u2192 keyboard.press() is called repeatedly until holdMs elapses.
509
- `.trim()}inputSchema(){return{key:Sn.string().describe('Keyboard key to press (e.g. "Enter", "ArrowDown", "a").'),selector:Sn.string().describe("Optional CSS selector to focus before sending the key.").optional(),holdMs:Sn.number().int().min(0).describe("Optional duration in milliseconds to hold the key. With repeat=true, this is the total repeat duration.").optional(),repeat:Sn.boolean().optional().default(!1).describe("If true, simulates key auto-repeat by pressing the key repeatedly (useful for scrolling)."),repeatIntervalMs:Sn.number().int().min(Ca).optional().default(Ia).describe("Interval between repeated key presses in ms (only when repeat=true).")}}outputSchema(){return{}}async handle(e,t){t.selector&&await(await e.page.waitForSelector(t.selector)).focus();let n=t.holdMs??0,r=t.repeat===!0;if(n<=0||r===!1)return await e.page.keyboard.press(t.key,n>0?{delay:n}:void 0),{};let i=typeof t.repeatIntervalMs=="number"&&Number.isFinite(t.repeatIntervalMs)&&t.repeatIntervalMs>=Ca?Math.floor(t.repeatIntervalMs):Ia,a=Date.now();for(;Date.now()-a<n;)await e.page.keyboard.press(t.key),await e.page.waitForTimeout(i);return{}}};import{z as Je}from"zod";var Ku=200,Xu=200,qo=class{static{s(this,"ResizeViewport")}name(){return"interaction_resize-viewport"}description(){return`
508
+ `.trim()}inputSchema(){return{key:tn.string().describe('Keyboard key to press (e.g. "Enter", "ArrowDown", "a").'),selector:tn.string().describe("Optional CSS selector to focus before sending the key.").optional(),holdMs:tn.number().int().min(0).describe("Optional duration in milliseconds to hold the key. With repeat=true, this is the total repeat duration.").optional(),repeat:tn.boolean().optional().default(!1).describe("If true, simulates key auto-repeat by pressing the key repeatedly (useful for scrolling)."),repeatIntervalMs:tn.number().int().min(Na).optional().default(Oa).describe("Interval between repeated key presses in ms (only when repeat=true)."),timeoutMs:tn.number().int().positive().optional().describe("Timeout in ms to wait for the element when selector is provided (default 10000). Use a shorter value to fail faster if the selector might be invalid.")}}outputSchema(){return{}}async handle(e,t){if(t.selector){let l=t.timeoutMs??Zu;await(await e.page.waitForSelector(t.selector,{state:"visible",timeout:l})).focus()}let n=t.holdMs??0,r=t.repeat===!0;if(n<=0||r===!1)return await e.page.keyboard.press(t.key,n>0?{delay:n}:void 0),{};let i=typeof t.repeatIntervalMs=="number"&&Number.isFinite(t.repeatIntervalMs)&&t.repeatIntervalMs>=Na?Math.floor(t.repeatIntervalMs):Oa,a=Date.now();for(;Date.now()-a<n;)await e.page.keyboard.press(t.key),await e.page.waitForTimeout(i);return{}}};import{z as Je}from"zod";var ec=200,tc=200,qo=class{static{s(this,"ResizeViewport")}name(){return"interaction_resize-viewport"}description(){return`
510
509
  Resizes the PAGE VIEWPORT using Playwright viewport emulation (page.setViewportSize).
511
510
 
512
511
  This affects:
@@ -519,7 +518,7 @@ Notes:
519
518
  - Runtime switching to viewport=null (binding to real window size) is not supported by Playwright.
520
519
  If you need real window-driven responsive behavior, start the BrowserContext with viewport: null
521
520
  and use the window resize tool instead.
522
- `.trim()}inputSchema(){return{width:Je.number().int().min(Ku).describe("Target viewport width in CSS pixels."),height:Je.number().int().min(Xu).describe("Target viewport height in CSS pixels.")}}outputSchema(){return{requested:Je.object({width:Je.number().int().describe("Requested viewport width (CSS pixels)."),height:Je.number().int().describe("Requested viewport height (CSS pixels).")}).describe("Requested viewport configuration."),viewport:Je.object({innerWidth:Je.number().int().describe("window.innerWidth after resize (CSS pixels)."),innerHeight:Je.number().int().describe("window.innerHeight after resize (CSS pixels)."),outerWidth:Je.number().int().describe("window.outerWidth after resize (CSS pixels)."),outerHeight:Je.number().int().describe("window.outerHeight after resize (CSS pixels)."),devicePixelRatio:Je.number().describe("window.devicePixelRatio after resize.")}).describe("Viewport metrics observed inside the page after resizing.")}}async handle(e,t){await e.page.setViewportSize({width:t.width,height:t.height});let n=await e.page.evaluate(()=>({innerWidth:window.innerWidth,innerHeight:window.innerHeight,outerWidth:window.outerWidth,outerHeight:window.outerHeight,devicePixelRatio:window.devicePixelRatio}));return{requested:{width:t.width,height:t.height},viewport:{innerWidth:Number(n.innerWidth),innerHeight:Number(n.innerHeight),outerWidth:Number(n.outerWidth),outerHeight:Number(n.outerHeight),devicePixelRatio:Number(n.devicePixelRatio)}}}};import{z as ae}from"zod";var Ju=200,Yu=200,Wo=class{static{s(this,"ResizeWindow")}name(){return"interaction_resize-window"}description(){return`
521
+ `.trim()}inputSchema(){return{width:Je.number().int().min(ec).describe("Target viewport width in CSS pixels."),height:Je.number().int().min(tc).describe("Target viewport height in CSS pixels.")}}outputSchema(){return{requested:Je.object({width:Je.number().int().describe("Requested viewport width (CSS pixels)."),height:Je.number().int().describe("Requested viewport height (CSS pixels).")}).describe("Requested viewport configuration."),viewport:Je.object({innerWidth:Je.number().int().describe("window.innerWidth after resize (CSS pixels)."),innerHeight:Je.number().int().describe("window.innerHeight after resize (CSS pixels)."),outerWidth:Je.number().int().describe("window.outerWidth after resize (CSS pixels)."),outerHeight:Je.number().int().describe("window.outerHeight after resize (CSS pixels)."),devicePixelRatio:Je.number().describe("window.devicePixelRatio after resize.")}).describe("Viewport metrics observed inside the page after resizing.")}}async handle(e,t){await e.page.setViewportSize({width:t.width,height:t.height});let n=await e.page.evaluate(()=>({innerWidth:window.innerWidth,innerHeight:window.innerHeight,outerWidth:window.outerWidth,outerHeight:window.outerHeight,devicePixelRatio:window.devicePixelRatio}));return{requested:{width:t.width,height:t.height},viewport:{innerWidth:Number(n.innerWidth),innerHeight:Number(n.innerHeight),outerWidth:Number(n.outerWidth),outerHeight:Number(n.outerHeight),devicePixelRatio:Number(n.devicePixelRatio)}}}};import{z as ae}from"zod";var nc=200,oc=200,$o=class{static{s(this,"ResizeWindow")}name(){return"interaction_resize-window"}description(){return`
523
522
  Resizes the REAL BROWSER WINDOW (OS-level window) for the current page using Chrome DevTools Protocol (CDP).
524
523
 
525
524
  This tool works best on Chromium-based browsers (Chromium/Chrome/Edge).
@@ -529,7 +528,7 @@ so the page layout follows the OS window size.
529
528
  Important:
530
529
  - If Playwright viewport emulation is enabled (viewport is NOT null), resizing the OS window may not change page layout.
531
530
  - On non-Chromium browsers (Firefox/WebKit), CDP is not available and this tool will fail.
532
- `.trim()}inputSchema(){return{width:ae.number().int().min(Ju).optional().describe('Target window width in pixels (required when state="normal").'),height:ae.number().int().min(Yu).optional().describe('Target window height in pixels (required when state="normal").'),state:ae.enum(["normal","maximized","minimized","fullscreen"]).optional().default("normal").describe('Target window state. If not "normal", width/height may be ignored by the browser.')}}outputSchema(){return{requested:ae.object({width:ae.number().int().nullable().describe("Requested window width (pixels). Null if not provided."),height:ae.number().int().nullable().describe("Requested window height (pixels). Null if not provided."),state:ae.enum(["normal","maximized","minimized","fullscreen"]).describe("Requested window state.")}).describe("Requested window change parameters."),before:ae.object({windowId:ae.number().int().describe("CDP window id for the current target."),state:ae.string().nullable().describe("Window state before resizing."),left:ae.number().int().nullable().describe("Window left position before resizing."),top:ae.number().int().nullable().describe("Window top position before resizing."),width:ae.number().int().nullable().describe("Window width before resizing."),height:ae.number().int().nullable().describe("Window height before resizing.")}).describe("Window bounds before resizing."),after:ae.object({windowId:ae.number().int().describe("CDP window id for the current target."),state:ae.string().nullable().describe("Window state after resizing."),left:ae.number().int().nullable().describe("Window left position after resizing."),top:ae.number().int().nullable().describe("Window top position after resizing."),width:ae.number().int().nullable().describe("Window width after resizing."),height:ae.number().int().nullable().describe("Window height after resizing.")}).describe("Window bounds after resizing."),viewport:ae.object({innerWidth:ae.number().int().describe("window.innerWidth after resizing (CSS pixels)."),innerHeight:ae.number().int().describe("window.innerHeight after resizing (CSS pixels)."),outerWidth:ae.number().int().describe("window.outerWidth after resizing (CSS pixels)."),outerHeight:ae.number().int().describe("window.outerHeight after resizing (CSS pixels)."),devicePixelRatio:ae.number().describe("window.devicePixelRatio after resizing.")}).describe("Page viewport metrics after resizing (helps verify responsive behavior).")}}async handle(e,t){let n=t.state??"normal",r=t.width,i=t.height;if(n==="normal"&&(typeof r!="number"||typeof i!="number"))throw new Error('state="normal" requires both width and height.');let a=e.page,l=await a.context().newCDPSession(a);try{let u=await l.send("Browser.getWindowForTarget",{}),m=Number(u.windowId),c=u.bounds??{},p={windowId:m,state:typeof c.windowState=="string"?c.windowState:null,left:typeof c.left=="number"?c.left:null,top:typeof c.top=="number"?c.top:null,width:typeof c.width=="number"?c.width:null,height:typeof c.height=="number"?c.height:null},b={};n!=="normal"?b.windowState=n:(b.windowState="normal",b.width=r,b.height=i),await l.send("Browser.setWindowBounds",{windowId:m,bounds:b});let k=(await l.send("Browser.getWindowForTarget",{})).bounds??{},M={windowId:m,state:typeof k.windowState=="string"?k.windowState:null,left:typeof k.left=="number"?k.left:null,top:typeof k.top=="number"?k.top:null,width:typeof k.width=="number"?k.width:null,height:typeof k.height=="number"?k.height:null},f=await a.evaluate(()=>({innerWidth:window.innerWidth,innerHeight:window.innerHeight,outerWidth:window.outerWidth,outerHeight:window.outerHeight,devicePixelRatio:window.devicePixelRatio})),I={innerWidth:Number(f.innerWidth),innerHeight:Number(f.innerHeight),outerWidth:Number(f.outerWidth),outerHeight:Number(f.outerHeight),devicePixelRatio:Number(f.devicePixelRatio)};return{requested:{width:typeof r=="number"?r:null,height:typeof i=="number"?i:null,state:n},before:p,after:M,viewport:I}}catch(u){let m=String(u?.message??u);throw new Error(`Failed to resize real browser window via CDP. This tool works best on Chromium-based browsers. Original error: ${m}`)}finally{await l.detach().catch(()=>{})}}};import{z as va}from"zod";var $o=class{static{s(this,"Select")}name(){return"interaction_select"}description(){return"Select an element on the page with the given value"}inputSchema(){return{selector:va.string().describe("CSS selector for element to select."),value:va.string().describe("Value to select.")}}outputSchema(){return{}}async handle(e,t){return await(await e.page.waitForSelector(t.selector)).selectOption(t.value),{}}};import{z as te}from"zod";var Oa="auto",Ea="by",jo=class{static{s(this,"Scroll")}name(){return"interaction_scroll"}description(){return`
531
+ `.trim()}inputSchema(){return{width:ae.number().int().min(nc).optional().describe('Target window width in pixels (required when state="normal").'),height:ae.number().int().min(oc).optional().describe('Target window height in pixels (required when state="normal").'),state:ae.enum(["normal","maximized","minimized","fullscreen"]).optional().default("normal").describe('Target window state. If not "normal", width/height may be ignored by the browser.')}}outputSchema(){return{requested:ae.object({width:ae.number().int().nullable().describe("Requested window width (pixels). Null if not provided."),height:ae.number().int().nullable().describe("Requested window height (pixels). Null if not provided."),state:ae.enum(["normal","maximized","minimized","fullscreen"]).describe("Requested window state.")}).describe("Requested window change parameters."),before:ae.object({windowId:ae.number().int().describe("CDP window id for the current target."),state:ae.string().nullable().describe("Window state before resizing."),left:ae.number().int().nullable().describe("Window left position before resizing."),top:ae.number().int().nullable().describe("Window top position before resizing."),width:ae.number().int().nullable().describe("Window width before resizing."),height:ae.number().int().nullable().describe("Window height before resizing.")}).describe("Window bounds before resizing."),after:ae.object({windowId:ae.number().int().describe("CDP window id for the current target."),state:ae.string().nullable().describe("Window state after resizing."),left:ae.number().int().nullable().describe("Window left position after resizing."),top:ae.number().int().nullable().describe("Window top position after resizing."),width:ae.number().int().nullable().describe("Window width after resizing."),height:ae.number().int().nullable().describe("Window height after resizing.")}).describe("Window bounds after resizing."),viewport:ae.object({innerWidth:ae.number().int().describe("window.innerWidth after resizing (CSS pixels)."),innerHeight:ae.number().int().describe("window.innerHeight after resizing (CSS pixels)."),outerWidth:ae.number().int().describe("window.outerWidth after resizing (CSS pixels)."),outerHeight:ae.number().int().describe("window.outerHeight after resizing (CSS pixels)."),devicePixelRatio:ae.number().describe("window.devicePixelRatio after resizing.")}).describe("Page viewport metrics after resizing (helps verify responsive behavior).")}}async handle(e,t){let n=t.state??"normal",r=t.width,i=t.height;if(n==="normal"&&(typeof r!="number"||typeof i!="number"))throw new Error('state="normal" requires both width and height.');let a=e.page,l=await a.context().newCDPSession(a);try{let u=await l.send("Browser.getWindowForTarget",{}),m=Number(u.windowId),c=u.bounds??{},p={windowId:m,state:typeof c.windowState=="string"?c.windowState:null,left:typeof c.left=="number"?c.left:null,top:typeof c.top=="number"?c.top:null,width:typeof c.width=="number"?c.width:null,height:typeof c.height=="number"?c.height:null},b={};n!=="normal"?b.windowState=n:(b.windowState="normal",b.width=r,b.height=i),await l.send("Browser.setWindowBounds",{windowId:m,bounds:b});let x=(await l.send("Browser.getWindowForTarget",{})).bounds??{},B={windowId:m,state:typeof x.windowState=="string"?x.windowState:null,left:typeof x.left=="number"?x.left:null,top:typeof x.top=="number"?x.top:null,width:typeof x.width=="number"?x.width:null,height:typeof x.height=="number"?x.height:null},w=await a.evaluate(()=>({innerWidth:window.innerWidth,innerHeight:window.innerHeight,outerWidth:window.outerWidth,outerHeight:window.outerHeight,devicePixelRatio:window.devicePixelRatio})),U={innerWidth:Number(w.innerWidth),innerHeight:Number(w.innerHeight),outerWidth:Number(w.outerWidth),outerHeight:Number(w.outerHeight),devicePixelRatio:Number(w.devicePixelRatio)};return{requested:{width:typeof r=="number"?r:null,height:typeof i=="number"?i:null,state:n},before:p,after:B,viewport:U}}catch(u){let m=String(u?.message??u);throw new Error(`Failed to resize real browser window via CDP. This tool works best on Chromium-based browsers. Original error: ${m}`)}finally{await l.detach().catch(()=>{})}}};import{z as Ps}from"zod";var rc=1e4,jo=class{static{s(this,"Select")}name(){return"interaction_select"}description(){return"Select an element on the page with the given value"}inputSchema(){return{selector:Ps.string().describe("CSS selector for element to select."),value:Ps.string().describe("Value to select."),timeoutMs:Ps.number().int().positive().optional().describe("Timeout in ms to wait for the element (default 10000). Use a shorter value (e.g. 5000) to fail faster if the selector might be invalid.")}}outputSchema(){return{}}async handle(e,t){let n=t.timeoutMs??rc;return await(await e.page.waitForSelector(t.selector,{state:"visible",timeout:n})).selectOption(t.value),{}}};import{z as ne}from"zod";var Pa="auto",Ra="by",zo=class{static{s(this,"Scroll")}name(){return"interaction_scroll"}description(){return`
533
532
  Scrolls the page viewport or a specific scrollable element.
534
533
 
535
534
  Modes:
@@ -545,70 +544,70 @@ Use this tool to:
545
544
  - Jump to the top/bottom without knowing exact positions
546
545
  - Bring elements into view before clicking
547
546
  - Inspect lazy-loaded content that appears on scroll
548
- `.trim()}inputSchema(){return{mode:te.enum(["by","to","top","bottom","left","right"]).optional().default(Ea).describe('Scroll mode. "by" uses dx/dy, "to" uses x/y, and top/bottom/left/right jump to edges.'),selector:te.string().optional().describe("Optional CSS selector for a scrollable container. If omitted, scrolls the document viewport."),dx:te.number().optional().describe('Horizontal scroll delta in pixels (used when mode="by"). Default: 0.'),dy:te.number().optional().describe('Vertical scroll delta in pixels (used when mode="by"). Default: 0.'),x:te.number().optional().describe('Absolute horizontal scroll position in pixels (used when mode="to").'),y:te.number().optional().describe('Absolute vertical scroll position in pixels (used when mode="to").'),behavior:te.enum(["auto","smooth"]).optional().default(Oa).describe('Native scroll behavior. Use "auto" for deterministic automation.')}}outputSchema(){return{mode:te.enum(["by","to","top","bottom","left","right"]).describe("The scroll mode used."),selector:te.string().nullable().describe("The selector of the scroll container if provided; otherwise null (document viewport)."),behavior:te.enum(["auto","smooth"]).describe("The scroll behavior used."),before:te.object({x:te.number().describe("ScrollLeft before scrolling."),y:te.number().describe("ScrollTop before scrolling."),scrollWidth:te.number().describe("Total scrollable width before scrolling."),scrollHeight:te.number().describe("Total scrollable height before scrolling."),clientWidth:te.number().describe("Viewport/container client width before scrolling."),clientHeight:te.number().describe("Viewport/container client height before scrolling.")}).describe("Scroll metrics before the scroll action."),after:te.object({x:te.number().describe("ScrollLeft after scrolling."),y:te.number().describe("ScrollTop after scrolling."),scrollWidth:te.number().describe("Total scrollable width after scrolling."),scrollHeight:te.number().describe("Total scrollable height after scrolling."),clientWidth:te.number().describe("Viewport/container client width after scrolling."),clientHeight:te.number().describe("Viewport/container client height after scrolling.")}).describe("Scroll metrics after the scroll action."),canScrollX:te.boolean().describe("Whether horizontal scrolling is possible (scrollWidth > clientWidth)."),canScrollY:te.boolean().describe("Whether vertical scrolling is possible (scrollHeight > clientHeight)."),maxScrollX:te.number().describe("Maximum horizontal scrollLeft (scrollWidth - clientWidth)."),maxScrollY:te.number().describe("Maximum vertical scrollTop (scrollHeight - clientHeight)."),isAtLeft:te.boolean().describe("Whether the scroll position is at the far left."),isAtRight:te.boolean().describe("Whether the scroll position is at the far right."),isAtTop:te.boolean().describe("Whether the scroll position is at the very top."),isAtBottom:te.boolean().describe("Whether the scroll position is at the very bottom.")}}async handle(e,t){let n=t.mode??Ea,r=t.selector,i=t.behavior??Oa,a=t.dx??0,l=t.dy??0,u=t.x,m=t.y;if(n==="to"&&typeof u!="number"&&typeof m!="number")throw new Error('mode="to" requires at least one of x or y.');if(n==="by"&&a===0&&l===0)throw new Error('mode="by" requires dx and/or dy to be non-zero.');let c=await e.page.evaluate(({modeEval:p,selectorEval:b,dxEval:T,dyEval:k,xEval:M,yEval:f,behaviorEval:I})=>{let W=s(()=>{if(b){let ce=document.querySelector(b);if(!ce)throw new Error(`Element with selector "${b}" not found`);return ce}let w=document.scrollingElement||document.documentElement||document.body;if(!w)throw new Error("No scrolling element available.");return w},"getTarget"),ie=s(w=>({x:w.scrollLeft,y:w.scrollTop,scrollWidth:w.scrollWidth,scrollHeight:w.scrollHeight,clientWidth:w.clientWidth,clientHeight:w.clientHeight}),"readMetrics"),Y=s((w,ce,V)=>w<ce?ce:w>V?V:w,"clamp"),_=s(w=>{let ce=Math.max(0,w.scrollWidth-w.clientWidth),V=Math.max(0,w.scrollHeight-w.clientHeight);if(p==="by"){let U=Y(w.scrollLeft+T,0,ce),J=Y(w.scrollTop+k,0,V);w.scrollTo({left:U,top:J,behavior:I});return}if(p==="to"){let U=typeof M=="number"?Y(M,0,ce):w.scrollLeft,J=typeof f=="number"?Y(f,0,V):w.scrollTop;w.scrollTo({left:U,top:J,behavior:I});return}if(p==="top"){w.scrollTo({top:0,left:w.scrollLeft,behavior:I});return}if(p==="bottom"){w.scrollTo({top:V,left:w.scrollLeft,behavior:I});return}if(p==="left"){w.scrollTo({left:0,top:w.scrollTop,behavior:I});return}if(p==="right"){w.scrollTo({left:ce,top:w.scrollTop,behavior:I});return}},"doScroll"),L=W(),F=ie(L);_(L);let q=ie(L),j=Math.max(0,q.scrollWidth-q.clientWidth),ee=Math.max(0,q.scrollHeight-q.clientHeight),K=q.scrollWidth>q.clientWidth,H=q.scrollHeight>q.clientHeight,X=1,ue=q.x<=X,xe=q.x>=j-X,de=q.y<=X,Q=q.y>=ee-X;return{before:F,after:q,canScrollX:K,canScrollY:H,maxScrollX:j,maxScrollY:ee,isAtLeft:ue,isAtRight:xe,isAtTop:de,isAtBottom:Q}},{modeEval:n,selectorEval:r,dxEval:a,dyEval:l,xEval:u,yEval:m,behaviorEval:i});return{mode:n,selector:r??null,behavior:i,before:c.before,after:c.after,canScrollX:c.canScrollX,canScrollY:c.canScrollY,maxScrollX:c.maxScrollX,maxScrollY:c.maxScrollY,isAtLeft:c.isAtLeft,isAtRight:c.isAtRight,isAtTop:c.isAtTop,isAtBottom:c.isAtBottom}}};var Na=[new Ao,new Lo,new Fo,new Uo,new Ho,new qo,new Wo,new $o,new jo];import{z as tn}from"zod";var Qu=0,Zu="load",zo=class{static{s(this,"GoBack")}name(){return"navigation_go-back"}description(){return`
547
+ `.trim()}inputSchema(){return{mode:ne.enum(["by","to","top","bottom","left","right"]).optional().default(Ra).describe('Scroll mode. "by" uses dx/dy, "to" uses x/y, and top/bottom/left/right jump to edges.'),selector:ne.string().optional().describe("Optional CSS selector for a scrollable container. If omitted, scrolls the document viewport."),dx:ne.number().optional().describe('Horizontal scroll delta in pixels (used when mode="by"). Default: 0.'),dy:ne.number().optional().describe('Vertical scroll delta in pixels (used when mode="by"). Default: 0.'),x:ne.number().optional().describe('Absolute horizontal scroll position in pixels (used when mode="to").'),y:ne.number().optional().describe('Absolute vertical scroll position in pixels (used when mode="to").'),behavior:ne.enum(["auto","smooth"]).optional().default(Pa).describe('Native scroll behavior. Use "auto" for deterministic automation.')}}outputSchema(){return{mode:ne.enum(["by","to","top","bottom","left","right"]).describe("The scroll mode used."),selector:ne.string().nullable().describe("The selector of the scroll container if provided; otherwise null (document viewport)."),behavior:ne.enum(["auto","smooth"]).describe("The scroll behavior used."),before:ne.object({x:ne.number().describe("ScrollLeft before scrolling."),y:ne.number().describe("ScrollTop before scrolling."),scrollWidth:ne.number().describe("Total scrollable width before scrolling."),scrollHeight:ne.number().describe("Total scrollable height before scrolling."),clientWidth:ne.number().describe("Viewport/container client width before scrolling."),clientHeight:ne.number().describe("Viewport/container client height before scrolling.")}).describe("Scroll metrics before the scroll action."),after:ne.object({x:ne.number().describe("ScrollLeft after scrolling."),y:ne.number().describe("ScrollTop after scrolling."),scrollWidth:ne.number().describe("Total scrollable width after scrolling."),scrollHeight:ne.number().describe("Total scrollable height after scrolling."),clientWidth:ne.number().describe("Viewport/container client width after scrolling."),clientHeight:ne.number().describe("Viewport/container client height after scrolling.")}).describe("Scroll metrics after the scroll action."),canScrollX:ne.boolean().describe("Whether horizontal scrolling is possible (scrollWidth > clientWidth)."),canScrollY:ne.boolean().describe("Whether vertical scrolling is possible (scrollHeight > clientHeight)."),maxScrollX:ne.number().describe("Maximum horizontal scrollLeft (scrollWidth - clientWidth)."),maxScrollY:ne.number().describe("Maximum vertical scrollTop (scrollHeight - clientHeight)."),isAtLeft:ne.boolean().describe("Whether the scroll position is at the far left."),isAtRight:ne.boolean().describe("Whether the scroll position is at the far right."),isAtTop:ne.boolean().describe("Whether the scroll position is at the very top."),isAtBottom:ne.boolean().describe("Whether the scroll position is at the very bottom.")}}async handle(e,t){let n=t.mode??Ra,r=t.selector,i=t.behavior??Pa,a=t.dx??0,l=t.dy??0,u=t.x,m=t.y;if(n==="to"&&typeof u!="number"&&typeof m!="number")throw new Error('mode="to" requires at least one of x or y.');if(n==="by"&&a===0&&l===0)throw new Error('mode="by" requires dx and/or dy to be non-zero.');let c=await e.page.evaluate(p=>{let b=p.modeEval,f=p.selectorEval,x=p.dxEval,B=p.dyEval,w=p.xEval,U=p.yEval,D=p.behaviorEval,H=s(()=>{if(f){let pe=document.querySelector(f);if(!pe)throw new Error(`Element with selector "${f}" not found`);return pe}let v=document.scrollingElement||document.documentElement||document.body;if(!v)throw new Error("No scrolling element available.");return v},"getTarget"),Q=s(v=>({x:v.scrollLeft,y:v.scrollTop,scrollWidth:v.scrollWidth,scrollHeight:v.scrollHeight,clientWidth:v.clientWidth,clientHeight:v.clientHeight}),"readMetrics"),$=s((v,pe,V)=>v<pe?pe:v>V?V:v,"clamp"),P=s(v=>{let pe=Math.max(0,v.scrollWidth-v.clientWidth),V=Math.max(0,v.scrollHeight-v.clientHeight);if(b==="by"){let q=$(v.scrollLeft+x,0,pe),X=$(v.scrollTop+B,0,V);v.scrollTo({left:q,top:X,behavior:D});return}if(b==="to"){let q=typeof w=="number"?$(w,0,pe):v.scrollLeft,X=typeof U=="number"?$(U,0,V):v.scrollTop;v.scrollTo({left:q,top:X,behavior:D});return}if(b==="top"){v.scrollTo({top:0,left:v.scrollLeft,behavior:D});return}if(b==="bottom"){v.scrollTo({top:V,left:v.scrollLeft,behavior:D});return}if(b==="left"){v.scrollTo({left:0,top:v.scrollTop,behavior:D});return}if(b==="right"){v.scrollTo({left:pe,top:v.scrollTop,behavior:D});return}},"doScroll"),W=H(),G=Q(W);P(W);let _=Q(W),oe=Math.max(0,_.scrollWidth-_.clientWidth),Y=Math.max(0,_.scrollHeight-_.clientHeight),M=_.scrollWidth>_.clientWidth,ee=_.scrollHeight>_.clientHeight,ue=1,ce=_.x<=ue,fe=_.x>=oe-ue,te=_.y<=ue,me=_.y>=Y-ue;return{before:G,after:_,canScrollX:M,canScrollY:ee,maxScrollX:oe,maxScrollY:Y,isAtLeft:ce,isAtRight:fe,isAtTop:te,isAtBottom:me}},{modeEval:n,selectorEval:r,dxEval:a,dyEval:l,xEval:u,yEval:m,behaviorEval:i});return{mode:n,selector:r??null,behavior:i,before:c.before,after:c.after,canScrollX:c.canScrollX,canScrollY:c.canScrollY,maxScrollX:c.maxScrollX,maxScrollY:c.maxScrollY,isAtLeft:c.isAtLeft,isAtRight:c.isAtRight,isAtTop:c.isAtTop,isAtBottom:c.isAtBottom}}};var ka=[new Lo,new Fo,new Uo,new Ho,new Wo,new qo,new $o,new jo,new zo];import{z as nn}from"zod";var sc=0,ic="load",Vo=class{static{s(this,"GoBack")}name(){return"navigation_go-back"}description(){return`
549
548
  Navigates to the previous page in history.
550
549
  In case of multiple redirects, the navigation will resolve with the response of the last redirect.
551
550
  If cannot go back, returns empty response.
552
- `}inputSchema(){return{timeout:tn.number().int().nonnegative().describe("Maximum operation time in milliseconds. Defaults to `0` - no timeout.").optional().default(Qu),waitUntil:tn.enum(["load","domcontentloaded","networkidle","commit"]).describe("\nWhen to consider operation succeeded, defaults to `load`. Events can be either:\n- `domcontentloaded`: Consider operation to be finished when the `DOMContentLoaded` event is fired.\n- `load`: Consider operation to be finished when the `load` event is fired.\n- `networkidle`: **DISCOURAGED** consider operation to be finished when there are no network connections for\n at least `500` ms. Don't use this method for testing, rely on web assertions to assess readiness instead.\n- `commit`: Consider operation to be finished when network response is received and the document started loading.").optional().default(Zu)}}outputSchema(){return{url:tn.string().describe("Contains the URL of the navigated page.").optional(),status:tn.number().int().positive().describe("Contains the status code of the navigated page (e.g., 200 for a success).").optional(),statusText:tn.string().describe('Contains the status text of the navigated page (e.g. usually an "OK" for a success).').optional(),ok:tn.boolean().describe("Contains a boolean stating whether the navigated page was successful (status in the range 200-299) or not.").optional()}}async handle(e,t){let n=await e.page.goBack({timeout:t.timeout,waitUntil:t.waitUntil});return{url:n?.url(),status:n?.status(),statusText:n?.statusText(),ok:n?.ok()}}};import{z as nn}from"zod";var ec=0,tc="load",Vo=class{static{s(this,"GoForward")}name(){return"navigation_go-forward"}description(){return`
551
+ `}inputSchema(){return{timeout:nn.number().int().nonnegative().describe("Maximum operation time in milliseconds. Defaults to `0` - no timeout.").optional().default(sc),waitUntil:nn.enum(["load","domcontentloaded","networkidle","commit"]).describe("\nWhen to consider operation succeeded, defaults to `load`. Events can be either:\n- `domcontentloaded`: Consider operation to be finished when the `DOMContentLoaded` event is fired.\n- `load`: Consider operation to be finished when the `load` event is fired.\n- `networkidle`: **DISCOURAGED** consider operation to be finished when there are no network connections for\n at least `500` ms. Don't use this method for testing, rely on web assertions to assess readiness instead.\n- `commit`: Consider operation to be finished when network response is received and the document started loading.").optional().default(ic)}}outputSchema(){return{url:nn.string().describe("Contains the URL of the navigated page.").optional(),status:nn.number().int().positive().describe("Contains the status code of the navigated page (e.g., 200 for a success).").optional(),statusText:nn.string().describe('Contains the status text of the navigated page (e.g. usually an "OK" for a success).').optional(),ok:nn.boolean().describe("Contains a boolean stating whether the navigated page was successful (status in the range 200-299) or not.").optional()}}async handle(e,t){let n=await e.page.goBack({timeout:t.timeout,waitUntil:t.waitUntil});return{url:n?.url(),status:n?.status(),statusText:n?.statusText(),ok:n?.ok()}}};import{z as on}from"zod";var ac=0,lc="load",Go=class{static{s(this,"GoForward")}name(){return"navigation_go-forward"}description(){return`
553
552
  Navigates to the next page in history.
554
553
  In case of multiple redirects, the navigation will resolve with the response of the last redirect.
555
554
  If cannot go back, returns empty response.
556
- `}inputSchema(){return{timeout:nn.number().int().nonnegative().describe("Maximum operation time in milliseconds. Defaults to `0` - no timeout.").optional().default(ec),waitUntil:nn.enum(["load","domcontentloaded","networkidle","commit"]).describe("\nWhen to consider operation succeeded, defaults to `load`. Events can be either:\n- `domcontentloaded`: Consider operation to be finished when the `DOMContentLoaded` event is fired.\n- `load`: Consider operation to be finished when the `load` event is fired.\n- `networkidle`: **DISCOURAGED** consider operation to be finished when there are no network connections for\n at least `500` ms. Don't use this method for testing, rely on web assertions to assess readiness instead.\n- `commit`: Consider operation to be finished when network response is received and the document started loading.").optional().default(tc)}}outputSchema(){return{url:nn.string().describe("Contains the URL of the navigated page.").optional(),status:nn.number().int().positive().describe("Contains the status code of the navigated page (e.g., 200 for a success).").optional(),statusText:nn.string().describe('Contains the status text of the navigated page (e.g. usually an "OK" for a success).').optional(),ok:nn.boolean().describe("Contains a boolean stating whether the navigated page was successful (status in the range 200-299) or not.").optional()}}async handle(e,t){let n=await e.page.goForward({timeout:t.timeout,waitUntil:t.waitUntil});return{url:n?.url(),status:n?.status(),statusText:n?.statusText(),ok:n?.ok()}}};import{z as Ht}from"zod";var nc=0,oc="load",Go=class{static{s(this,"GoTo")}name(){return"navigation_go-to"}description(){return`
555
+ `}inputSchema(){return{timeout:on.number().int().nonnegative().describe("Maximum operation time in milliseconds. Defaults to `0` - no timeout.").optional().default(ac),waitUntil:on.enum(["load","domcontentloaded","networkidle","commit"]).describe("\nWhen to consider operation succeeded, defaults to `load`. Events can be either:\n- `domcontentloaded`: Consider operation to be finished when the `DOMContentLoaded` event is fired.\n- `load`: Consider operation to be finished when the `load` event is fired.\n- `networkidle`: **DISCOURAGED** consider operation to be finished when there are no network connections for\n at least `500` ms. Don't use this method for testing, rely on web assertions to assess readiness instead.\n- `commit`: Consider operation to be finished when network response is received and the document started loading.").optional().default(lc)}}outputSchema(){return{url:on.string().describe("Contains the URL of the navigated page.").optional(),status:on.number().int().positive().describe("Contains the status code of the navigated page (e.g., 200 for a success).").optional(),statusText:on.string().describe('Contains the status text of the navigated page (e.g. usually an "OK" for a success).').optional(),ok:on.boolean().describe("Contains a boolean stating whether the navigated page was successful (status in the range 200-299) or not.").optional()}}async handle(e,t){let n=await e.page.goForward({timeout:t.timeout,waitUntil:t.waitUntil});return{url:n?.url(),status:n?.status(),statusText:n?.statusText(),ok:n?.ok()}}};import{z as Ut}from"zod";var uc=0,cc="load",Ko=class{static{s(this,"GoTo")}name(){return"navigation_go-to"}description(){return`
557
556
  Navigates to the given URL.
558
557
  **NOTE**: The tool either throws an error or returns a main resource response.
559
558
  The only exceptions are navigation to \`about:blank\` or navigation to the same URL with a different hash,
560
559
  which would succeed and return empty response.
561
- `}inputSchema(){return{url:Ht.string().describe("URL to navigate page to. The url should include scheme, e.g. `http://`, `https://`."),timeout:Ht.number().int().nonnegative().describe("Maximum operation time in milliseconds. Defaults to `0` - no timeout.").optional().default(nc),waitUntil:Ht.enum(["load","domcontentloaded","networkidle","commit"]).describe("\nWhen to consider operation succeeded, defaults to `load`. Events can be either:\n- `domcontentloaded`: Consider operation to be finished when the `DOMContentLoaded` event is fired.\n- `load`: Consider operation to be finished when the `load` event is fired.\n- `networkidle`: **DISCOURAGED** consider operation to be finished when there are no network connections for\n at least `500` ms. Don't use this method for testing, rely on web assertions to assess readiness instead.\n- `commit`: Consider operation to be finished when network response is received and the document started loading.").optional().default(oc)}}outputSchema(){return{url:Ht.string().describe("Contains the URL of the navigated page.").optional(),status:Ht.number().int().positive().describe("Contains the status code of the navigated page (e.g., 200 for a success).").optional(),statusText:Ht.string().describe('Contains the status text of the navigated page (e.g. usually an "OK" for a success).').optional(),ok:Ht.boolean().describe("Contains a boolean stating whether the navigated page was successful (status in the range 200-299) or not.").optional()}}async handle(e,t){let n=await e.page.goto(t.url,{timeout:t.timeout,waitUntil:t.waitUntil});return{url:n?.url(),status:n?.status(),statusText:n?.statusText(),ok:n?.ok()}}};import{z as on}from"zod";var rc=0,sc="load",Ko=class{static{s(this,"Reload")}name(){return"navigation_reload"}description(){return`
560
+ `}inputSchema(){return{url:Ut.string().describe("URL to navigate page to. The url should include scheme, e.g. `http://`, `https://`."),timeout:Ut.number().int().nonnegative().describe("Maximum operation time in milliseconds. Defaults to `0` - no timeout.").optional().default(uc),waitUntil:Ut.enum(["load","domcontentloaded","networkidle","commit"]).describe("\nWhen to consider operation succeeded, defaults to `load`. Events can be either:\n- `domcontentloaded`: Consider operation to be finished when the `DOMContentLoaded` event is fired.\n- `load`: Consider operation to be finished when the `load` event is fired.\n- `networkidle`: **DISCOURAGED** consider operation to be finished when there are no network connections for\n at least `500` ms. Don't use this method for testing, rely on web assertions to assess readiness instead.\n- `commit`: Consider operation to be finished when network response is received and the document started loading.").optional().default(cc)}}outputSchema(){return{url:Ut.string().describe("Contains the URL of the navigated page.").optional(),status:Ut.number().int().positive().describe("Contains the status code of the navigated page (e.g., 200 for a success).").optional(),statusText:Ut.string().describe('Contains the status text of the navigated page (e.g. usually an "OK" for a success).').optional(),ok:Ut.boolean().describe("Contains a boolean stating whether the navigated page was successful (status in the range 200-299) or not.").optional()}}async handle(e,t){let n=await e.page.goto(t.url,{timeout:t.timeout,waitUntil:t.waitUntil});return{url:n?.url(),status:n?.status(),statusText:n?.statusText(),ok:n?.ok()}}};import{z as rn}from"zod";var mc=0,pc="load",Xo=class{static{s(this,"Reload")}name(){return"navigation_reload"}description(){return`
562
561
  Reloads the current page.
563
562
  In case of multiple redirects, the navigation resolves with the response of the last redirect.
564
563
  If the reload does not produce a response, returns empty response.
565
- `}inputSchema(){return{timeout:on.number().int().nonnegative().describe("Maximum operation time in milliseconds. Defaults to `0` - no timeout.").optional().default(rc),waitUntil:on.enum(["load","domcontentloaded","networkidle","commit"]).describe("\nWhen to consider operation succeeded, defaults to `load`. Events can be either:\n- `domcontentloaded`: Consider operation to be finished when the `DOMContentLoaded` event is fired.\n- `load`: Consider operation to be finished when the `load` event is fired.\n- `networkidle`: **DISCOURAGED** consider operation to be finished when there are no network connections for\n at least `500` ms. Don't use this method for testing, rely on web assertions to assess readiness instead.\n- `commit`: Consider operation to be finished when network response is received and the document started loading.").optional().default(sc)}}outputSchema(){return{url:on.string().describe("Contains the URL of the reloaded page.").optional(),status:on.number().int().positive().describe("Contains the status code of the reloaded page (e.g., 200 for a success).").optional(),statusText:on.string().describe('Contains the status text of the reloaded page (e.g. usually an "OK" for a success).').optional(),ok:on.boolean().describe("Contains a boolean stating whether the reloaded page was successful (status in the range 200-299) or not.").optional()}}async handle(e,t){let n=await e.page.reload({timeout:t.timeout,waitUntil:t.waitUntil});return{url:n?.url(),status:n?.status(),statusText:n?.statusText(),ok:n?.ok()}}};var Pa=[new zo,new Vo,new Go,new Ko];import{z as Oe}from"zod";var Xo=class{static{s(this,"GetConsoleMessages")}name(){return"o11y_get-console-messages"}description(){return"Retrieves console messages/logs from the browser with filtering options."}inputSchema(){return{type:Oe.enum(Te(dt)).transform(st(dt)).describe(`
564
+ `}inputSchema(){return{timeout:rn.number().int().nonnegative().describe("Maximum operation time in milliseconds. Defaults to `0` - no timeout.").optional().default(mc),waitUntil:rn.enum(["load","domcontentloaded","networkidle","commit"]).describe("\nWhen to consider operation succeeded, defaults to `load`. Events can be either:\n- `domcontentloaded`: Consider operation to be finished when the `DOMContentLoaded` event is fired.\n- `load`: Consider operation to be finished when the `load` event is fired.\n- `networkidle`: **DISCOURAGED** consider operation to be finished when there are no network connections for\n at least `500` ms. Don't use this method for testing, rely on web assertions to assess readiness instead.\n- `commit`: Consider operation to be finished when network response is received and the document started loading.").optional().default(pc)}}outputSchema(){return{url:rn.string().describe("Contains the URL of the reloaded page.").optional(),status:rn.number().int().positive().describe("Contains the status code of the reloaded page (e.g., 200 for a success).").optional(),statusText:rn.string().describe('Contains the status text of the reloaded page (e.g. usually an "OK" for a success).').optional(),ok:rn.boolean().describe("Contains a boolean stating whether the reloaded page was successful (status in the range 200-299) or not.").optional()}}async handle(e,t){let n=await e.page.reload({timeout:t.timeout,waitUntil:t.waitUntil});return{url:n?.url(),status:n?.status(),statusText:n?.statusText(),ok:n?.ok()}}};var _a=[new Vo,new Go,new Ko,new Xo];import{z as Oe}from"zod";var Yo=class{static{s(this,"GetConsoleMessages")}name(){return"o11y_get-console-messages"}description(){return"Retrieves console messages/logs from the browser with filtering options."}inputSchema(){return{type:Oe.enum(xe(pt)).transform(rt(pt)).describe(`
566
565
  Type of console messages to retrieve.
567
566
  When specified, console messages with equal or higher levels are retrieved.
568
- Valid values are (in ascending order according to their levels): ${Te(dt)}.`).optional(),search:Oe.string().describe("Text to search for in console messages.").optional(),timestamp:Oe.number().int().nonnegative().describe(`
567
+ Valid values are (in ascending order according to their levels): ${xe(pt)}.`).optional(),search:Oe.string().describe("Text to search for in console messages.").optional(),timestamp:Oe.number().int().nonnegative().describe(`
569
568
  Start time filter as a Unix epoch timestamp in milliseconds.
570
569
  If provided, only console messages recorded at or after this timestamp will be returned.`).optional(),sequenceNumber:Oe.number().int().nonnegative().describe(`
571
570
  Sequence number for incremental retrieval.
572
571
  If provided, only console messages with a sequence number greater than this value will be returned.
573
- This allows clients to fetch console messages incrementally by passing the last received sequence number on subsequent requests.`).optional(),limit:Oe.object({count:Oe.number().int().nonnegative().default(0).describe(`
574
- Count of the maximum number of console messages to return.
572
+ This allows clients to fetch console messages incrementally by passing the last received sequence number on subsequent requests.`).optional(),limit:Oe.object({count:Oe.number().int().nonnegative().default(100).describe(`
573
+ Count of the maximum number of console messages to return (default 100).
575
574
  If the result exceeds this limit, it will be truncated.
576
- "0" means no count limit.`),from:Oe.enum(["start","end"]).default("end").describe(`
575
+ 0 means no count limit (return all).`),from:Oe.enum(["start","end"]).default("end").describe(`
577
576
  Controls which side is kept when truncation is applied.
578
577
  "start" keeps the first N items (trims from the end).
579
- "end" keeps the last N items (trims from the start).`)}).describe("Maximum number of console messages to return.").optional()}}outputSchema(){return{messages:Oe.array(Oe.object({type:Oe.string().describe("Type of the console message."),text:Oe.string().describe("Text of the console message."),location:Oe.object({url:Oe.string().describe("URL of the resource."),lineNumber:Oe.number().nonnegative().describe("0-based line number in the resource."),columnNumber:Oe.number().nonnegative().describe("0-based column number in the resource.")}).describe("Location of the console message in the resource.").optional(),timestamp:Oe.number().int().nonnegative().describe("Unix epoch timestamp (in milliseconds) of the console message."),sequenceNumber:Oe.number().int().nonnegative().describe(`
578
+ "end" keeps the last N items (trims from the start).`)}).default({count:100,from:"end"}).describe("Maximum number of console messages to return. Default: last 100. Use count 0 for no limit.").optional()}}outputSchema(){return{messages:Oe.array(Oe.object({type:Oe.string().describe("Type of the console message."),text:Oe.string().describe("Text of the console message."),location:Oe.object({url:Oe.string().describe("URL of the resource."),lineNumber:Oe.number().nonnegative().describe("0-based line number in the resource."),columnNumber:Oe.number().nonnegative().describe("0-based column number in the resource.")}).describe("Location of the console message in the resource.").optional(),timestamp:Oe.number().int().nonnegative().describe("Unix epoch timestamp (in milliseconds) of the console message."),sequenceNumber:Oe.number().int().nonnegative().describe(`
580
579
  A monotonically increasing sequence number assigned to each console message.
581
580
  It reflects the order in which messages were captured and can be used by clients
582
581
  to retrieve messages incrementally by requesting only those with a higher sequence
583
- number than the last one received.`)}).describe("Console message item.")).describe("Retrieved console messages.")}}async handle(e,t){let n=t.type?Jt[t.type]?.code:void 0,r=e.getConsoleMessages().filter(l=>{let u=!0;return n!==void 0&&(u=l.level.code>=n),u&&t.timestamp&&(u=l.timestamp>=t.timestamp),u&&t.sequenceNumber&&(u=l.sequenceNumber>t.sequenceNumber),u&&t.search&&(u=l.text.includes(t.search)),u});return{messages:(t.limit?.count?t.limit.from==="start"?r.slice(0,t.limit.count):r.slice(-t.limit.count):r).map(l=>({type:l.type,text:l.text,location:l.location?{url:l.location.url,lineNumber:l.location.lineNumber,columnNumber:l.location.columnNumber}:void 0,timestamp:l.timestamp,sequenceNumber:l.sequenceNumber}))}}};import{z as ne}from"zod";var Jo=class{static{s(this,"GetHttpRequests")}name(){return"o11y_get-http-requests"}description(){return"Retrieves HTTP requests from the browser with filtering options."}inputSchema(){return{resourceType:ne.enum(Te(Yt)).transform(st(Yt)).describe(`
582
+ number than the last one received.`)}).describe("Console message item.")).describe("Retrieved console messages.")}}async handle(e,t){let n=t.type?Yt[t.type]?.code:void 0,r=e.getConsoleMessages().filter(l=>{let u=!0;return n!==void 0&&(u=l.level.code>=n),u&&t.timestamp&&(u=l.timestamp>=t.timestamp),u&&t.sequenceNumber&&(u=l.sequenceNumber>t.sequenceNumber),u&&t.search&&(u=l.text.includes(t.search)),u});return{messages:(t.limit?.count?t.limit.from==="start"?r.slice(0,t.limit.count):r.slice(-t.limit.count):r).map(l=>({type:l.type,text:l.text,location:l.location?{url:l.location.url,lineNumber:l.location.lineNumber,columnNumber:l.location.columnNumber}:void 0,timestamp:l.timestamp,sequenceNumber:l.sequenceNumber}))}}};import{z as re}from"zod";var Jo=class{static{s(this,"GetHttpRequests")}name(){return"o11y_get-http-requests"}description(){return"Retrieves HTTP requests from the browser with filtering options."}inputSchema(){return{resourceType:re.enum(xe(Jt)).transform(rt(Jt)).describe(`
584
583
  Resource type of the HTTP requests to retrieve.
585
- Valid values are: ${Te(Yt)}.`).optional(),status:ne.object({min:ne.number().int().positive().describe("Minimum status code of the HTTP requests to retrieve.").optional(),max:ne.number().int().positive().describe("Maximum status code of the HTTP requests to retrieve.").optional()}).describe("Status code of the HTTP requests to retrieve.").optional(),ok:ne.boolean().describe(`
584
+ Valid values are: ${xe(Jt)}.`).optional(),status:re.object({min:re.number().int().positive().describe("Minimum status code of the HTTP requests to retrieve.").optional(),max:re.number().int().positive().describe("Maximum status code of the HTTP requests to retrieve.").optional()}).describe("Status code of the HTTP requests to retrieve.").optional(),ok:re.boolean().describe(`
586
585
  Whether to retrieve successful or failed HTTP requests.
587
586
  An HTTP request is considered successful only if its status code is 2XX.
588
587
  Otherwise (non-2XX status code or no response at all because of timeout, network failure, etc ...) it is considered as failed.
589
- When this flag is not set, all (successful and failed HTTP requests) are retrieved.`).optional(),timestamp:ne.number().int().nonnegative().describe(`
588
+ When this flag is not set, all (successful and failed HTTP requests) are retrieved.`).optional(),timestamp:re.number().int().nonnegative().describe(`
590
589
  Start time filter as a Unix epoch timestamp in milliseconds.
591
590
  If provided, only HTTP requests recorded at or after this timestamp will be returned.
592
- `).optional(),sequenceNumber:ne.number().int().nonnegative().describe(`
591
+ `).optional(),sequenceNumber:re.number().int().nonnegative().describe(`
593
592
  Sequence number for incremental retrieval.
594
593
  If provided, only HTTP requests with a sequence number greater than this value will be returned.
595
594
  This allows clients to fetch HTTP requests incrementally by passing the last received sequence number on subsequent requests.
596
- `).optional(),limit:ne.object({count:ne.number().int().nonnegative().default(0).describe(`
597
- Count of the maximum number of HTTP requests to return.
595
+ `).optional(),limit:re.object({count:re.number().int().nonnegative().default(100).describe(`
596
+ Count of the maximum number of HTTP requests to return (default 100).
598
597
  If the result exceeds this limit, it will be truncated.
599
- "0" means no count limit.`),from:ne.enum(["start","end"]).default("end").describe(`
598
+ 0 means no count limit (return all).`),from:re.enum(["start","end"]).default("end").describe(`
600
599
  Controls which side is kept when truncation is applied.
601
600
  "start" keeps the first N items (trims from the end).
602
- "end" keeps the last N items (trims from the start).`)}).describe("Maximum number of HTTP requests to return.").optional()}}outputSchema(){return{requests:ne.array(ne.object({url:ne.string().describe("HTTP request url."),method:ne.enum(Te(rs)).describe(`HTTP request method. Valid values are: ${Te(rs)}`),headers:ne.record(ne.string(),ne.string()).describe("HTTP request headers as key-value pairs."),body:ne.string().describe("HTTP request body if available.").optional(),resourceType:ne.enum(Te(Yt)).describe(`
601
+ "end" keeps the last N items (trims from the start).`)}).default({count:100,from:"end"}).describe("Maximum number of HTTP requests to return. Default: last 100. Use count 0 for no limit.").optional()}}outputSchema(){return{requests:re.array(re.object({url:re.string().describe("HTTP request url."),method:re.enum(xe(ss)).describe(`HTTP request method. Valid values are: ${xe(ss)}`),headers:re.record(re.string(),re.string()).describe("HTTP request headers as key-value pairs."),body:re.string().describe("HTTP request body if available.").optional(),resourceType:re.enum(xe(Jt)).describe(`
603
602
  HTTP request resource type as it was perceived by the rendering engine.
604
- Valid values are: ${Te(Yt)}`),failure:ne.string().describe("Error message of the HTTP request if failed.").optional(),duration:ne.number().describe('HTTP request duration in milliseconds. "-1" if not available (no response).').optional(),response:ne.object({status:ne.number().int().positive().describe("HTTP response status code."),statusText:ne.string().describe("HTTP response status text."),headers:ne.record(ne.string(),ne.string()).describe("HTTP response headers as key-value pairs."),body:ne.string().describe("HTTP response body if available.").optional()}).describe("HTTP response.").optional(),ok:ne.boolean().describe(`
603
+ Valid values are: ${xe(Jt)}`),failure:re.string().describe("Error message of the HTTP request if failed.").optional(),duration:re.number().describe('HTTP request duration in milliseconds. "-1" if not available (no response).').optional(),response:re.object({status:re.number().int().positive().describe("HTTP response status code."),statusText:re.string().describe("HTTP response status text."),headers:re.record(re.string(),re.string()).describe("HTTP response headers as key-value pairs."),body:re.string().describe("HTTP response body if available.").optional()}).describe("HTTP response.").optional(),ok:re.boolean().describe(`
605
604
  Flag to represent whether the HTTP request successful or failed.
606
605
  An HTTP request is considered successful only if its status code is 2XX.
607
- Otherwise (non-2XX status code or no response at all because of timeout, network failure, etc ...) it is considered as failed.`).optional(),timestamp:ne.number().int().nonnegative().describe("Unix epoch timestamp (in milliseconds) of the HTTP request."),sequenceNumber:ne.number().int().nonnegative().describe(`
606
+ Otherwise (non-2XX status code or no response at all because of timeout, network failure, etc ...) it is considered as failed.`).optional(),timestamp:re.number().int().nonnegative().describe("Unix epoch timestamp (in milliseconds) of the HTTP request."),sequenceNumber:re.number().int().nonnegative().describe(`
608
607
  A monotonically increasing sequence number assigned to each HTTP request.
609
608
  It reflects the order in which requests were captured and can be used by clients
610
609
  to retrieve requests incrementally by requesting only those with a higher sequence
611
- number than the last one received.`)}).describe("HTTP request item.")).describe("Retrieved HTTP requests.")}}async handle(e,t){let n=e.getHttpRequests().filter(a=>{let l=!0;return l&&t.resourceType&&(l=a.resourceType===t.resourceType),l&&t.status&&(l&&t.status.min&&(l=a.response?a.response.status>=t.status.min:!1),l&&t.status.max&&(l=a.response?a.response.status<=t.status.max:!1)),l&&t.ok!==void 0&&(l=a.ok),l&&t.timestamp&&(l=a.timestamp>=t.timestamp),l&&t.sequenceNumber&&(l=a.sequenceNumber>t.sequenceNumber),l});return{requests:(t.limit?.count?t.limit.from==="start"?n.slice(0,t.limit.count):n.slice(-t.limit.count):n).map(a=>({url:a.url,method:a.method,headers:a.headers,body:a.body,resourceType:a.resourceType,failure:a.failure,duration:a.duration,response:a.response?{status:a.response.status,statusText:a.response.statusText,headers:a.response.headers,body:a.response.body}:void 0,ok:a.ok,timestamp:a.timestamp,sequenceNumber:a.sequenceNumber}))}}};import{z as ic}from"zod";var Yo=class{static{s(this,"GetTraceId")}name(){return"o11y_get-trace-id"}description(){return"Gets the OpenTelemetry compatible trace id of the current session."}inputSchema(){return{}}outputSchema(){return{traceId:ic.string().describe("The OpenTelemetry compatible trace id of the current session if available.").optional()}}async handle(e,t){return{traceId:await e.getTraceId()}}};import{z as $}from"zod";var Ra=0,ac=3e4;function Qo(o,e,t){return typeof o!="number"||!Number.isFinite(o)?{rating:"not_available",value:null,unit:"ms",thresholds:{good:e,poor:t}}:o<=e?{rating:"good",value:o,unit:"ms",thresholds:{good:e,poor:t}}:o>t?{rating:"poor",value:o,unit:"ms",thresholds:{good:e,poor:t}}:{rating:"needs_improvement",value:o,unit:"ms",thresholds:{good:e,poor:t}}}s(Qo,"rateMs");function lc(o,e,t){return typeof o!="number"||!Number.isFinite(o)?{rating:"not_available",value:null,unit:"score",thresholds:{good:e,poor:t}}:o<=e?{rating:"good",value:o,unit:"score",thresholds:{good:e,poor:t}}:o>t?{rating:"poor",value:o,unit:"score",thresholds:{good:e,poor:t}}:{rating:"needs_improvement",value:o,unit:"score",thresholds:{good:e,poor:t}}}s(lc,"rateScore");function Os(o){return o==="needs_improvement"?"needs improvement":o==="not_available"?"not available":o}s(Os,"formatRating");function uc(o){let e=o.ratings.lcp.rating,t=o.ratings.inp.rating,n=o.ratings.cls.rating,r=o.ratings.ttfb.rating,i=o.ratings.fcp.rating,a=e==="good"&&t==="good"&&n==="good",l=[];a?l.push("Core Web Vitals look good (LCP, INP and CLS are all within recommended thresholds)."):l.push("Core Web Vitals need attention. Focus on the worst-rated metric first (LCP, INP, or CLS).");let u=[],m=[],c=[],p=[],b=[],T=[];return o.lcpSelectorHint&&T.push(`LCP element hint (best-effort): ${o.lcpSelectorHint}`),e==="poor"||e==="needs_improvement"?(u.push("Optimize the LCP element (often the hero image, headline, or main content above the fold)."),u.push("Reduce render-blocking resources (critical CSS, JS). Consider inlining critical CSS and deferring non-critical JS."),u.push('Preload the LCP resource (e.g., <link rel="preload"> for the hero image/font) and ensure it is discoverable without heavy JS.'),u.push("Improve server response and caching. A slow TTFB often delays LCP."),u.push("Avoid client-only rendering for above-the-fold content when possible; stream/SSR critical content.")):e==="good"?u.push("LCP is within the recommended threshold. Keep the above-the-fold path lean."):u.push("LCP is not available in this browser/session. Consider using Chromium or a page-load scenario that produces LCP entries."),t==="poor"||t==="needs_improvement"?(m.push("Break up long main-thread tasks. Aim to keep tasks under ~50ms (split work, yield to the event loop)."),m.push("Reduce expensive work in input handlers (click, pointer, key events). Move non-urgent work to idle time."),m.push("Avoid synchronous layout thrash during interactions (batch DOM reads/writes, reduce forced reflow)."),m.push("Defer heavy third-party scripts and reduce JavaScript bundle size to improve responsiveness.")):t==="good"?m.push("INP is within the recommended threshold. Keep interaction handlers lightweight."):m.push("INP is not available in this browser/session. It requires Event Timing support and user interactions."),n==="poor"||n==="needs_improvement"?(c.push("Reserve space for images/iframes/ads (set width/height or aspect-ratio) to prevent layout jumps."),c.push("Avoid inserting content above existing content unless it is in response to a user interaction."),c.push("Use stable font loading (font-display: swap/optional) and consider preloading critical fonts to reduce text shifts."),c.push("Be careful with late-loading banners/toasts; render them in reserved containers.")):n==="good"?c.push("CLS is within the recommended threshold. Keep layout stable during load and async updates."):c.push("CLS is not available in this browser/session. Consider Chromium or a scenario with visible layout changes."),r==="poor"||r==="needs_improvement"?(p.push("Improve backend latency: reduce server processing time, optimize DB queries, and eliminate unnecessary middleware."),p.push("Enable CDN/edge caching where possible. Use caching headers and avoid dynamic responses for static content."),p.push("Reduce cold-start and TLS overhead (keep-alive, warm pools, edge runtimes).")):r==="good"?p.push("TTFB is good. Backend/network latency is unlikely to be the primary bottleneck."):p.push("TTFB is not available in this browser/session."),i==="poor"||i==="needs_improvement"?(b.push("Reduce render-blocking CSS/JS and prioritize critical content for first paint."),b.push("Optimize above-the-fold resources and avoid large synchronous scripts during initial load."),b.push("Consider code-splitting and preloading critical assets to improve first paint.")):i==="good"?b.push("FCP is good. The page provides early visual feedback."):b.push("FCP is not available in this browser/session."),T.push("For reliable debugging, capture metrics after navigation and after user actions that trigger loading or layout changes."),T.push("If values look unstable, try adding waitMs (e.g., 1000-3000) and re-measure after the UI settles."),{coreWebVitalsPassed:a,summary:l,lcp:u,inp:m,cls:c,ttfb:p,fcp:b,general:T}}s(uc,"buildRecommendations");var Zo=class{static{s(this,"GetWebVitals")}name(){return"o11y_get-web-vitals"}description(){return`
610
+ number than the last one received.`)}).describe("HTTP request item.")).describe("Retrieved HTTP requests.")}}async handle(e,t){let n=e.getHttpRequests().filter(a=>{let l=!0;return l&&t.resourceType&&(l=a.resourceType===t.resourceType),l&&t.status&&(l&&t.status.min&&(l=a.response?a.response.status>=t.status.min:!1),l&&t.status.max&&(l=a.response?a.response.status<=t.status.max:!1)),l&&t.ok!==void 0&&(l=a.ok),l&&t.timestamp&&(l=a.timestamp>=t.timestamp),l&&t.sequenceNumber&&(l=a.sequenceNumber>t.sequenceNumber),l});return{requests:(t.limit?.count?t.limit.from==="start"?n.slice(0,t.limit.count):n.slice(-t.limit.count):n).map(a=>({url:a.url,method:a.method,headers:a.headers,body:a.body,resourceType:a.resourceType,failure:a.failure,duration:a.duration,response:a.response?{status:a.response.status,statusText:a.response.statusText,headers:a.response.headers,body:a.response.body}:void 0,ok:a.ok,timestamp:a.timestamp,sequenceNumber:a.sequenceNumber}))}}};import{z as dc}from"zod";var Qo=class{static{s(this,"GetTraceId")}name(){return"o11y_get-trace-id"}description(){return"Gets the OpenTelemetry compatible trace id of the current session."}inputSchema(){return{}}outputSchema(){return{traceId:dc.string().describe("The OpenTelemetry compatible trace id of the current session if available.").optional()}}async handle(e,t){return{traceId:await e.getTraceId()}}};import{z as j}from"zod";var Ma=0,bc=3e4;function Zo(o,e,t){return typeof o!="number"||!Number.isFinite(o)?{rating:"not_available",value:null,unit:"ms",thresholds:{good:e,poor:t}}:o<=e?{rating:"good",value:o,unit:"ms",thresholds:{good:e,poor:t}}:o>t?{rating:"poor",value:o,unit:"ms",thresholds:{good:e,poor:t}}:{rating:"needs_improvement",value:o,unit:"ms",thresholds:{good:e,poor:t}}}s(Zo,"rateMs");function hc(o,e,t){return typeof o!="number"||!Number.isFinite(o)?{rating:"not_available",value:null,unit:"score",thresholds:{good:e,poor:t}}:o<=e?{rating:"good",value:o,unit:"score",thresholds:{good:e,poor:t}}:o>t?{rating:"poor",value:o,unit:"score",thresholds:{good:e,poor:t}}:{rating:"needs_improvement",value:o,unit:"score",thresholds:{good:e,poor:t}}}s(hc,"rateScore");function Rs(o){return o==="needs_improvement"?"needs improvement":o==="not_available"?"not available":o}s(Rs,"formatRating");function gc(o){let e=o.ratings.lcp.rating,t=o.ratings.inp.rating,n=o.ratings.cls.rating,r=o.ratings.ttfb.rating,i=o.ratings.fcp.rating,a=e==="good"&&t==="good"&&n==="good",l=[];a?l.push("Core Web Vitals look good (LCP, INP and CLS are all within recommended thresholds)."):l.push("Core Web Vitals need attention. Focus on the worst-rated metric first (LCP, INP, or CLS).");let u=[],m=[],c=[],p=[],b=[],f=[];return o.lcpSelectorHint&&f.push(`LCP element hint (best-effort): ${o.lcpSelectorHint}`),e==="poor"||e==="needs_improvement"?(u.push("Optimize the LCP element (often the hero image, headline, or main content above the fold)."),u.push("Reduce render-blocking resources (critical CSS, JS). Consider inlining critical CSS and deferring non-critical JS."),u.push('Preload the LCP resource (e.g., <link rel="preload"> for the hero image/font) and ensure it is discoverable without heavy JS.'),u.push("Improve server response and caching. A slow TTFB often delays LCP."),u.push("Avoid client-only rendering for above-the-fold content when possible; stream/SSR critical content.")):e==="good"?u.push("LCP is within the recommended threshold. Keep the above-the-fold path lean."):u.push("LCP is not available in this browser/session. Consider using Chromium or a page-load scenario that produces LCP entries."),t==="poor"||t==="needs_improvement"?(m.push("Break up long main-thread tasks. Aim to keep tasks under ~50ms (split work, yield to the event loop)."),m.push("Reduce expensive work in input handlers (click, pointer, key events). Move non-urgent work to idle time."),m.push("Avoid synchronous layout thrash during interactions (batch DOM reads/writes, reduce forced reflow)."),m.push("Defer heavy third-party scripts and reduce JavaScript bundle size to improve responsiveness.")):t==="good"?m.push("INP is within the recommended threshold. Keep interaction handlers lightweight."):m.push("INP is not available in this browser/session. It requires Event Timing support and user interactions."),n==="poor"||n==="needs_improvement"?(c.push("Reserve space for images/iframes/ads (set width/height or aspect-ratio) to prevent layout jumps."),c.push("Avoid inserting content above existing content unless it is in response to a user interaction."),c.push("Use stable font loading (font-display: swap/optional) and consider preloading critical fonts to reduce text shifts."),c.push("Be careful with late-loading banners/toasts; render them in reserved containers.")):n==="good"?c.push("CLS is within the recommended threshold. Keep layout stable during load and async updates."):c.push("CLS is not available in this browser/session. Consider Chromium or a scenario with visible layout changes."),r==="poor"||r==="needs_improvement"?(p.push("Improve backend latency: reduce server processing time, optimize DB queries, and eliminate unnecessary middleware."),p.push("Enable CDN/edge caching where possible. Use caching headers and avoid dynamic responses for static content."),p.push("Reduce cold-start and TLS overhead (keep-alive, warm pools, edge runtimes).")):r==="good"?p.push("TTFB is good. Backend/network latency is unlikely to be the primary bottleneck."):p.push("TTFB is not available in this browser/session."),i==="poor"||i==="needs_improvement"?(b.push("Reduce render-blocking CSS/JS and prioritize critical content for first paint."),b.push("Optimize above-the-fold resources and avoid large synchronous scripts during initial load."),b.push("Consider code-splitting and preloading critical assets to improve first paint.")):i==="good"?b.push("FCP is good. The page provides early visual feedback."):b.push("FCP is not available in this browser/session."),f.push("For reliable debugging, capture metrics after navigation and after user actions that trigger loading or layout changes."),f.push("If values look unstable, try adding waitMs (e.g., 1000-3000) and re-measure after the UI settles."),{coreWebVitalsPassed:a,summary:l,lcp:u,inp:m,cls:c,ttfb:p,fcp:b,general:f}}s(gc,"buildRecommendations");var er=class{static{s(this,"GetWebVitals")}name(){return"o11y_get-web-vitals"}description(){return`
612
611
  Collects Web Vitals-style performance metrics and provides recommendations based on Google's thresholds.
613
612
 
614
613
  Core Web Vitals:
@@ -624,7 +623,7 @@ Guidance:
624
623
  - Call after navigation and after user actions.
625
624
  - If you need more stable LCP/CLS/INP, pass waitMs (e.g. 1000-3000).
626
625
  - Some metrics may be unavailable depending on browser support and whether interactions occurred.
627
- `.trim()}inputSchema(){return{waitMs:$.number().int().min(0).max(ac).optional().default(Ra).describe("Optional wait duration in milliseconds before reading metrics (default: 0)."),includeDebug:$.boolean().optional().default(!1).describe("If true, returns additional debug details such as entry counts and LCP element hint.")}}outputSchema(){let e=$.object({rating:$.enum(["good","needs_improvement","poor","not_available"]).describe("Rating based on Google thresholds."),value:$.number().nullable().describe("Metric value (null if unavailable)."),unit:$.enum(["ms","score"]).describe("Unit of the metric."),thresholds:$.object({good:$.number().describe('Upper bound for the "good" rating.'),poor:$.number().describe('Lower bound for the "poor" rating.')}).describe("Thresholds used for rating.")});return{url:$.string().describe("Current page URL."),title:$.string().describe("Current page title."),timestampMs:$.number().int().describe("Unix epoch timestamp (ms) when the metrics were captured."),metrics:$.object({lcpMs:$.number().nullable().describe("Largest Contentful Paint in milliseconds."),inpMs:$.number().nullable().describe("Interaction to Next Paint in milliseconds (best-effort approximation)."),cls:$.number().nullable().describe("Cumulative Layout Shift score."),ttfbMs:$.number().nullable().describe("Time to First Byte in milliseconds."),fcpMs:$.number().nullable().describe("First Contentful Paint in milliseconds.")}).describe("Raw metric values (null if unavailable)."),ratings:$.object({lcp:e.describe("LCP rating."),inp:e.describe("INP rating."),cls:e.describe("CLS rating."),ttfb:e.describe("TTFB rating."),fcp:e.describe("FCP rating.")}).describe("Ratings computed from Google thresholds."),recommendations:$.object({coreWebVitalsPassed:$.boolean().describe('True if all Core Web Vitals are rated "good".'),summary:$.array($.string()).describe("High-level summary and prioritization guidance."),lcp:$.array($.string()).describe("Recommendations for improving LCP."),inp:$.array($.string()).describe("Recommendations for improving INP."),cls:$.array($.string()).describe("Recommendations for improving CLS."),ttfb:$.array($.string()).describe("Recommendations for improving TTFB."),fcp:$.array($.string()).describe("Recommendations for improving FCP."),general:$.array($.string()).describe("General measurement and debugging notes.")}).describe("Recommendations based on the measured values and their ratings."),notes:$.array($.string()).describe("Notes about metric availability, browser limitations, and interpretation."),debug:$.object({waitMs:$.number().int().describe("Actual wait duration used before reading metrics."),entries:$.object({navigation:$.number().int().describe("Count of navigation entries."),paint:$.number().int().describe("Count of paint entries."),lcp:$.number().int().describe("Count of largest-contentful-paint entries."),layoutShift:$.number().int().describe("Count of layout-shift entries."),eventTiming:$.number().int().describe("Count of event timing entries.")}).describe("Counts of PerformanceEntry types used to compute metrics."),lastLcpSelectorHint:$.string().nullable().describe("Best-effort selector hint for the last LCP element (if available)."),lastLcpTagName:$.string().nullable().describe("Tag name of the last LCP element (if available).")}).optional().describe("Optional debug details.")}}async handle(e,t){let n=t.waitMs??Ra,r=t.includeDebug===!0,i=String(e.page.url()),a=String(await e.page.title()),l=Date.now(),u=await e.page.evaluate(async({waitMsEval:ie,includeDebugEval:Y})=>{let _=[],L=s(U=>new Promise(J=>{setTimeout(()=>J(),U)}),"sleep");ie>0&&await L(ie);let F=null,q=performance.getEntriesByType("navigation")??[];if(q.length>0){let U=q[0];typeof U.responseStart=="number"&&U.responseStart>=0&&(F=U.responseStart)}else _.push("TTFB: navigation entries not available (older browser or restricted timing).");let j=null,ee=performance.getEntriesByType("paint")??[],K=ee.find(U=>U.name==="first-contentful-paint");K&&typeof K.startTime=="number"?j=K.startTime:_.push("FCP: paint entries not available (browser may not support Paint Timing).");let H=null,X=null,ue=performance.getEntriesByType("largest-contentful-paint")??[];if(ue.length>0){let U=ue[ue.length-1];typeof U.startTime=="number"&&(H=U.startTime),U.element&&U.element instanceof Element&&(X=U.element)}else _.push("LCP: largest-contentful-paint entries not available (requires LCP support).");let xe=s(U=>{if(!U)return null;let J=U.getAttribute("data-testid")||U.getAttribute("data-test-id")||U.getAttribute("data-test");if(J&&J.trim())return'[data-testid="'+J.replace(/"/g,'\\"')+'"]';let Ne=U.getAttribute("data-selector");if(Ne&&Ne.trim())return'[data-selector="'+Ne.replace(/"/g,'\\"')+'"]';if(U.id)try{return"#"+CSS.escape(U.id)}catch{return"#"+String(U.id)}return U.tagName?U.tagName.toLowerCase():null},"selectorHintFor"),de=null,Q=performance.getEntriesByType("layout-shift")??[];if(Q.length>0){let U=0;for(let J of Q)J&&J.hadRecentInput===!0||typeof J.value=="number"&&(U+=J.value);de=U}else _.push("CLS: layout-shift entries not available (requires Layout Instability API support).");let w=null,ce=performance.getEntriesByType("event")??[];if(ce.length>0){let U=0;for(let J of ce){let Ne=typeof J.interactionId=="number"?J.interactionId:0,Ie=typeof J.duration=="number"?J.duration:0;Ne>0&&Ie>U&&(U=Ie)}U>0?w=U:_.push("INP: event timing entries exist but no interactionId-based events were found.")}else _.push("INP: event timing entries not available (requires Event Timing API support).");_.length===0?_.push("All requested metrics were available."):_.push("Some metrics may be null due to browser support limitations.");let V={metrics:{ttfbMs:F,fcpMs:j,lcpMs:H,cls:de,inpMs:w},notes:_,lcp:{selectorHint:xe(X),tagName:X?String(X.tagName).toLowerCase():null},debug:{waitMs:ie,entries:{navigation:q.length,paint:ee.length,lcp:ue.length,layoutShift:Q.length,eventTiming:ce.length}}};return Y?(V.debug.lastLcpSelectorHint=V.lcp.selectorHint,V.debug.lastLcpTagName=V.lcp.tagName):delete V.debug,V},{waitMsEval:n,includeDebugEval:r}),m=typeof u?.metrics?.lcpMs=="number"?u.metrics.lcpMs:null,c=typeof u?.metrics?.inpMs=="number"?u.metrics.inpMs:null,p=typeof u?.metrics?.cls=="number"?u.metrics.cls:null,b=typeof u?.metrics?.ttfbMs=="number"?u.metrics.ttfbMs:null,T=typeof u?.metrics?.fcpMs=="number"?u.metrics.fcpMs:null,k={lcp:Qo(m,2500,4e3),inp:Qo(c,200,500),cls:lc(p,.1,.25),ttfb:Qo(b,800,1800),fcp:Qo(T,1800,3e3)},M=typeof u?.lcp?.selectorHint=="string"?u.lcp.selectorHint:null,f=uc({ratings:k,lcpSelectorHint:M}),I=Array.isArray(u?.notes)?u.notes:[];I.push(`Ratings: LCP=${Os(k.lcp.rating)}, INP=${Os(k.inp.rating)}, CLS=${Os(k.cls.rating)}.`);let W={url:i,title:a,timestampMs:l,metrics:{lcpMs:m,inpMs:c,cls:p,ttfbMs:b,fcpMs:T},ratings:k,recommendations:f,notes:I};return r&&u?.debug&&(W.debug=u.debug),W}};import cc from"node:crypto";function er(){return cc.randomBytes(16).toString("hex")}s(er,"newTraceId");import{z as mc}from"zod";var tr=class{static{s(this,"NewTraceId")}name(){return"o11y_new-trace-id"}description(){return"Generates new OpenTelemetry compatible trace id and sets it to the current session."}inputSchema(){return{}}outputSchema(){return{traceId:mc.string().describe("The generated new OpenTelemetry compatible trace id.")}}async handle(e,t){let n=er();return await e.setTraceId(n),{traceId:n}}};import{z as pc}from"zod";var nr=class{static{s(this,"SetTraceId")}name(){return"o11y_set-trace-id"}description(){return"Sets the OpenTelemetry compatible trace id of the current session."}inputSchema(){return{traceId:pc.string().describe("The OpenTelemetry compatible trace id to be set.")}}outputSchema(){return{}}async handle(e,t){return await e.setTraceId(t.traceId),{}}};var ka=[new Xo,new Jo,new Yo,new Zo,new tr,new nr];import{z as A}from"zod";var _a=30,Ma=2e3,Da=!0,dc=25,bc=5e4,or=class{static{s(this,"GetComponentForElement")}name(){return"react_get-component-for-element"}description(){return`
626
+ `.trim()}inputSchema(){return{waitMs:j.number().int().min(0).max(bc).optional().default(Ma).describe("Optional wait duration in milliseconds before reading metrics (default: 0)."),includeDebug:j.boolean().optional().default(!1).describe("If true, returns additional debug details such as entry counts and LCP element hint.")}}outputSchema(){let e=j.object({rating:j.enum(["good","needs_improvement","poor","not_available"]).describe("Rating based on Google thresholds."),value:j.number().nullable().describe("Metric value (null if unavailable)."),unit:j.enum(["ms","score"]).describe("Unit of the metric."),thresholds:j.object({good:j.number().describe('Upper bound for the "good" rating.'),poor:j.number().describe('Lower bound for the "poor" rating.')}).describe("Thresholds used for rating.")});return{url:j.string().describe("Current page URL."),title:j.string().describe("Current page title."),timestampMs:j.number().int().describe("Unix epoch timestamp (ms) when the metrics were captured."),metrics:j.object({lcpMs:j.number().nullable().describe("Largest Contentful Paint in milliseconds."),inpMs:j.number().nullable().describe("Interaction to Next Paint in milliseconds (best-effort approximation)."),cls:j.number().nullable().describe("Cumulative Layout Shift score."),ttfbMs:j.number().nullable().describe("Time to First Byte in milliseconds."),fcpMs:j.number().nullable().describe("First Contentful Paint in milliseconds.")}).describe("Raw metric values (null if unavailable)."),ratings:j.object({lcp:e.describe("LCP rating."),inp:e.describe("INP rating."),cls:e.describe("CLS rating."),ttfb:e.describe("TTFB rating."),fcp:e.describe("FCP rating.")}).describe("Ratings computed from Google thresholds."),recommendations:j.object({coreWebVitalsPassed:j.boolean().describe('True if all Core Web Vitals are rated "good".'),summary:j.array(j.string()).describe("High-level summary and prioritization guidance."),lcp:j.array(j.string()).describe("Recommendations for improving LCP."),inp:j.array(j.string()).describe("Recommendations for improving INP."),cls:j.array(j.string()).describe("Recommendations for improving CLS."),ttfb:j.array(j.string()).describe("Recommendations for improving TTFB."),fcp:j.array(j.string()).describe("Recommendations for improving FCP."),general:j.array(j.string()).describe("General measurement and debugging notes.")}).describe("Recommendations based on the measured values and their ratings."),notes:j.array(j.string()).describe("Notes about metric availability, browser limitations, and interpretation."),debug:j.object({waitMs:j.number().int().describe("Actual wait duration used before reading metrics."),entries:j.object({navigation:j.number().int().describe("Count of navigation entries."),paint:j.number().int().describe("Count of paint entries."),lcp:j.number().int().describe("Count of largest-contentful-paint entries."),layoutShift:j.number().int().describe("Count of layout-shift entries."),eventTiming:j.number().int().describe("Count of event timing entries.")}).describe("Counts of PerformanceEntry types used to compute metrics."),lastLcpSelectorHint:j.string().nullable().describe("Best-effort selector hint for the last LCP element (if available)."),lastLcpTagName:j.string().nullable().describe("Tag name of the last LCP element (if available).")}).optional().describe("Optional debug details.")}}async handle(e,t){let n=t.waitMs??Ma,r=t.includeDebug===!0,i=String(e.page.url()),a=String(await e.page.title()),l=Date.now(),u=await e.page.evaluate(async H=>{let Q=H.waitMsEval,$=H.includeDebugEval,P=[],W=s(q=>new Promise(X=>{setTimeout(()=>X(),q)}),"sleep");Q>0&&await W(Q);let G=null,_=performance.getEntriesByType("navigation")??[];if(_.length>0){let q=_[0];typeof q.responseStart=="number"&&q.responseStart>=0&&(G=q.responseStart)}else P.push("TTFB: navigation entries not available (older browser or restricted timing).");let oe=null,Y=performance.getEntriesByType("paint")??[],M=Y.find(q=>q.name==="first-contentful-paint");M&&typeof M.startTime=="number"?oe=M.startTime:P.push("FCP: paint entries not available (browser may not support Paint Timing).");let ee=null,ue=null,ce=performance.getEntriesByType("largest-contentful-paint")??[];if(ce.length>0){let q=ce[ce.length-1];typeof q.startTime=="number"&&(ee=q.startTime),q.element&&q.element instanceof Element&&(ue=q.element)}else P.push("LCP: largest-contentful-paint entries not available (requires LCP support).");let fe=s(q=>{if(!q)return null;let X=q.getAttribute("data-testid")||q.getAttribute("data-test-id")||q.getAttribute("data-test");if(X&&X.trim())return'[data-testid="'+X.replace(/"/g,'\\"')+'"]';let Pe=q.getAttribute("data-selector");if(Pe&&Pe.trim())return'[data-selector="'+Pe.replace(/"/g,'\\"')+'"]';if(q.id)try{return"#"+CSS.escape(q.id)}catch{return"#"+String(q.id)}return q.tagName?q.tagName.toLowerCase():null},"selectorHintFor"),te=null,me=performance.getEntriesByType("layout-shift")??[];if(me.length>0){let q=0;for(let X of me)X&&X.hadRecentInput===!0||typeof X.value=="number"&&(q+=X.value);te=q}else P.push("CLS: layout-shift entries not available (requires Layout Instability API support).");let v=null,pe=performance.getEntriesByType("event")??[];if(pe.length>0){let q=0;for(let X of pe){let Pe=typeof X.interactionId=="number"?X.interactionId:0,Ie=typeof X.duration=="number"?X.duration:0;Pe>0&&Ie>q&&(q=Ie)}q>0?v=q:P.push("INP: event timing entries exist but no interactionId-based events were found.")}else P.push("INP: event timing entries not available (requires Event Timing API support).");P.length===0?P.push("All requested metrics were available."):P.push("Some metrics may be null due to browser support limitations.");let V={metrics:{ttfbMs:G,fcpMs:oe,lcpMs:ee,cls:te,inpMs:v},notes:P,lcp:{selectorHint:fe(ue),tagName:ue?String(ue.tagName).toLowerCase():null},debug:{waitMs:Q,entries:{navigation:_.length,paint:Y.length,lcp:ce.length,layoutShift:me.length,eventTiming:pe.length}}};return $?(V.debug.lastLcpSelectorHint=V.lcp.selectorHint,V.debug.lastLcpTagName=V.lcp.tagName):delete V.debug,V},{waitMsEval:n,includeDebugEval:r}),m=typeof u?.metrics?.lcpMs=="number"?u.metrics.lcpMs:null,c=typeof u?.metrics?.inpMs=="number"?u.metrics.inpMs:null,p=typeof u?.metrics?.cls=="number"?u.metrics.cls:null,b=typeof u?.metrics?.ttfbMs=="number"?u.metrics.ttfbMs:null,f=typeof u?.metrics?.fcpMs=="number"?u.metrics.fcpMs:null,x={lcp:Zo(m,2500,4e3),inp:Zo(c,200,500),cls:hc(p,.1,.25),ttfb:Zo(b,800,1800),fcp:Zo(f,1800,3e3)},B=typeof u?.lcp?.selectorHint=="string"?u.lcp.selectorHint:null,w=gc({ratings:x,lcpSelectorHint:B}),U=Array.isArray(u?.notes)?u.notes:[];U.push(`Ratings: LCP=${Rs(x.lcp.rating)}, INP=${Rs(x.inp.rating)}, CLS=${Rs(x.cls.rating)}.`);let D={url:i,title:a,timestampMs:l,metrics:{lcpMs:m,inpMs:c,cls:p,ttfbMs:b,fcpMs:f},ratings:x,recommendations:w,notes:U};return r&&u?.debug&&(D.debug=u.debug),D}};import fc from"node:crypto";function tr(){return fc.randomBytes(16).toString("hex")}s(tr,"newTraceId");import{z as yc}from"zod";var nr=class{static{s(this,"NewTraceId")}name(){return"o11y_new-trace-id"}description(){return"Generates new OpenTelemetry compatible trace id and sets it to the current session."}inputSchema(){return{}}outputSchema(){return{traceId:yc.string().describe("The generated new OpenTelemetry compatible trace id.")}}async handle(e,t){let n=tr();return await e.setTraceId(n),{traceId:n}}};import{z as wc}from"zod";var or=class{static{s(this,"SetTraceId")}name(){return"o11y_set-trace-id"}description(){return"Sets the OpenTelemetry compatible trace id of the current session."}inputSchema(){return{traceId:wc.string().describe("The OpenTelemetry compatible trace id to be set.")}}outputSchema(){return{}}async handle(e,t){return await e.setTraceId(t.traceId),{}}};var Da=[new Yo,new Jo,new Qo,new er,new nr,new or];import{z as F}from"zod";var Ba=30,Aa=2e3,La=!0,Tc=25,Sc=5e4,rr=class{static{s(this,"GetComponentForElement")}name(){return"react_get-component-for-element"}description(){return`
628
627
  Finds the React component(s) associated with a DOM element using React Fiber (best-effort).
629
628
 
630
629
  How it works:
@@ -643,7 +642,7 @@ What to expect (important for AI debugging):
643
642
  - wrappersDetected/wrapperFrames help interpret memo/forwardRef/context boundaries that can otherwise look confusing.
644
643
  - If hostMapping.strategy is "ancestor-fallback", the stack may include unrelated frames; try a more specific selector
645
644
  or target a deeper DOM node to improve mapping accuracy.
646
- `.trim()}inputSchema(){return{selector:A.string().optional().describe("CSS selector for the target element. If provided, takes precedence over x/y."),x:A.number().int().optional().describe("Viewport X coordinate in CSS pixels. Used when selector is not provided."),y:A.number().int().optional().describe("Viewport Y coordinate in CSS pixels. Used when selector is not provided."),maxStackDepth:A.number().int().positive().optional().default(_a).describe("Maximum number of component frames to return in the component stack."),includePropsPreview:A.boolean().optional().default(Da).describe("If true, includes a best-effort, truncated props preview for the nearest component."),maxPropsPreviewChars:A.number().int().positive().optional().default(Ma).describe("Maximum characters for props preview (after safe stringification).")}}outputSchema(){return{target:A.object({selector:A.string().nullable(),point:A.object({x:A.number().int().nullable(),y:A.number().int().nullable()}),found:A.boolean(),domHint:A.string().nullable(),elementPath:A.string().nullable()}),react:A.object({detected:A.boolean(),detectionReason:A.string(),fiberKey:A.string().nullable(),hostMapping:A.object({fiberOnTargetElement:A.boolean().describe("Whether the initial fiber pointer was found directly on the target element."),anchorDomHint:A.string().nullable().describe("DOM hint of the element where fiber pointer was found (target or ancestor)."),targetDomHint:A.string().nullable().describe("DOM hint of the actual target element."),hostFiberMatchedTarget:A.boolean().describe("Whether we found the exact host fiber for target element (fiber.stateNode === targetEl) via subtree scan."),subtreeScanNodesScanned:A.number().int().describe("Number of fiber nodes scanned during subtree search."),subtreeScanMaxNodes:A.number().int().describe("Maximum fiber nodes allowed to scan (safety cap)."),strategy:A.enum(["direct-on-target","ancestor-subtree-scan","ancestor-fallback"]).describe("Mapping strategy used to produce the final stack.")}),nearestComponent:A.object({name:A.string().nullable(),displayName:A.string().nullable(),kind:A.enum(["function","class","unknown"]),debugSource:A.object({fileName:A.string().optional(),lineNumber:A.number().int().optional(),columnNumber:A.number().int().optional()}).optional(),propsPreview:A.string().optional()}).nullable(),componentStack:A.array(A.object({name:A.string().nullable(),displayName:A.string().nullable(),kind:A.enum(["function","class","unknown"]),debugSource:A.object({fileName:A.string().optional(),lineNumber:A.number().int().optional(),columnNumber:A.number().int().optional()}).optional()})),componentStackText:A.string(),wrappersDetected:A.array(A.string()),wrapperFrames:A.array(A.object({wrapper:A.string(),frameIndex:A.number().int(),frameLabel:A.string()})),notes:A.array(A.string())})}}async handle(e,t){let n=typeof t.selector=="string"&&t.selector.trim()?t.selector.trim():void 0,r=typeof t.x=="number"&&Number.isFinite(t.x)?Math.floor(t.x):void 0,i=typeof t.y=="number"&&Number.isFinite(t.y)?Math.floor(t.y):void 0;if(!n&&(typeof r!="number"||typeof i!="number"))throw new Error("Provide either selector, or both x and y for elementFromPoint.");let a=typeof t.maxStackDepth=="number"&&t.maxStackDepth>0?Math.floor(t.maxStackDepth):_a,l=t.includePropsPreview===void 0?Da:t.includePropsPreview===!0,u=typeof t.maxPropsPreviewChars=="number"&&Number.isFinite(t.maxPropsPreviewChars)&&t.maxPropsPreviewChars>0?Math.floor(t.maxPropsPreviewChars):Ma;return await e.page.evaluate(({selectorEval:c,xEval:p,yEval:b,maxStackDepthEval:T,includePropsPreviewEval:k,maxPropsPreviewCharsEval:M,maxElementPathDepthEval:f,maxFiberNodesToScanEval:I})=>{let W=[];function ie(h){if(!h)return null;let v=h.tagName.toLowerCase(),C=h.id&&h.id.trim()?"#"+h.id.trim():"",P=typeof h.className=="string"?h.className:"",D=P?"."+P.trim().split(/\s+/).slice(0,4).join("."):"";return v+C+D}s(ie,"domHint");function Y(h,v){if(!h)return null;let C=[],P=h,D=0;for(;P&&D<v;){let B=P.tagName?P.tagName.toLowerCase():"unknown",Z=P.id&&P.id.trim()?"#"+P.id.trim():"",se=typeof P.className=="string"?P.className:"",me=se?se.trim().split(/\s+/).filter(Boolean).slice(0,3):[],ve=me.length>0?"."+me.join("."):"",Ve="";try{let Dt=P.parentElement;if(Dt){let un=Array.from(Dt.children).filter(Bt=>Bt.tagName===P.tagName);if(un.length>1){let Bt=un.indexOf(P)+1;Bt>0&&(Ve=`:nth-of-type(${Bt})`)}}}catch{}C.push(`${B}${Z}${ve}${Ve}`),P=P.parentElement,D++}return C.reverse(),C.join(" > ")}s(Y,"buildElementPath");function _(h){if(!h)return null;let v=Object.getOwnPropertyNames(h);for(let C of v)if(C.startsWith("__reactFiber$")||C.startsWith("__reactInternalInstance$"))return C;return null}s(_,"findFiberKeyOn");function L(h){if(!h)return null;let v=_(h);if(v){let P=h[v];if(P)return{fiber:P,fiberKey:v,onTarget:!0,anchorEl:h}}let C=h;for(;C;){let P=_(C);if(P){let D=C[P];if(D)return{fiber:D,fiberKey:P,onTarget:!1,anchorEl:C}}C=C.parentElement}return null}s(L,"findFiberForElement");function F(h,v,C){if(!h)return{hostFiber:null,scanned:0,found:!1};if(h.stateNode===v)return{hostFiber:h,scanned:1,found:!0};let P=[],D=new Set;P.push(h),D.add(h);let B=0;for(;P.length>0;){let Z=P.shift();if(B++,Z&&Z.stateNode===v)return{hostFiber:Z,scanned:B,found:!0};if(B>=C)return{hostFiber:null,scanned:B,found:!1};let se=Z?Z.child:null;se&&!D.has(se)&&(D.add(se),P.push(se));let me=Z?Z.sibling:null;me&&!D.has(me)&&(D.add(me),P.push(me))}return{hostFiber:null,scanned:B,found:!1}}s(F,"findHostFiberForDomElement");function q(h){if(!h)return!1;let v=h.prototype;return!!(v&&v.isReactComponent)}s(q,"isClassComponentType");function j(h){if(!h)return null;if(typeof h=="function"){let v=h.displayName;return typeof v=="string"&&v.trim()?v.trim():typeof h.name=="string"&&h.name.trim()?h.name.trim():"Anonymous"}if(typeof h=="object"){let v=h.displayName;if(typeof v=="string"&&v.trim())return v.trim();let C=h.render;if(typeof C=="function"){let P=C.displayName;return typeof P=="string"&&P.trim()?P.trim():typeof C.name=="string"&&C.name.trim()?C.name.trim():"Anonymous"}}return null}s(j,"typeDisplayName");function ee(h){if(!h)return null;if(typeof h=="function")return typeof h.name=="string"&&h.name.trim()?h.name.trim():null;if(typeof h=="object"){let v=h.render;return typeof v=="function"&&typeof v.name=="string"&&v.name.trim()?v.name.trim():null}return null}s(ee,"typeName");function K(h){if(!h)return h;if(typeof h=="object"){let v=h.render;if(typeof v=="function")return v}return h}s(K,"unwrapType");function H(h){return h?typeof K(h.type??h.elementType)=="function":!1}s(H,"isMeaningfulComponentFiber");function X(h){if(!h)return"unknown";let v=K(h.type??h.elementType);return typeof v=="function"?q(v)?"class":"function":"unknown"}s(X,"inferKind");function ue(h){let v=h?h._debugSource:void 0;if(!v||typeof v!="object")return;let C={};return typeof v.fileName=="string"&&(C.fileName=v.fileName),typeof v.lineNumber=="number"&&(C.lineNumber=v.lineNumber),typeof v.columnNumber=="number"&&(C.columnNumber=v.columnNumber),Object.keys(C).length>0?C:void 0}s(ue,"getDebugSource");function xe(h,v){let C=new WeakSet;function P(B,Z){if(B===null)return null;let se=typeof B;if(se==="string")return B.length>500?B.slice(0,500)+"\u2026":B;if(se==="number"||se==="boolean")return B;if(se==="bigint")return String(B);if(se!=="undefined"){if(se==="function")return"[function]";if(se==="symbol")return String(B);if(se==="object"){if(B instanceof Element)return"[Element "+(B.tagName?B.tagName.toLowerCase():"")+"]";if(B instanceof Window)return"[Window]";if(B instanceof Document)return"[Document]";if(B instanceof Date)return B.toISOString();if(C.has(B))return"[circular]";if(C.add(B),Array.isArray(B))return Z<=0?"[array len="+B.length+"]":B.slice(0,20).map(Ve=>P(Ve,Z-1));if(Z<=0)return"[object]";let me={},ve=Object.keys(B).slice(0,40);for(let Ve of ve)try{me[Ve]=P(B[Ve],Z-1)}catch{me[Ve]="[unreadable]"}return me}return String(B)}}s(P,"helper");let D="";try{D=JSON.stringify(P(h,2))}catch{try{D=String(h)}catch{D="[unserializable]"}}return D.length>v?D.slice(0,v)+"\u2026(truncated)":D}s(xe,"safeStringify");function de(h){return h.map(C=>{let P=C?.displayName,D=C?.name;return typeof P=="string"&&P.trim()?P.trim():typeof D=="string"&&D.trim()?D.trim():"Anonymous"}).filter(C=>!!C).reverse().join(" > ")}s(de,"stackTextFromFrames");function Q(h){let v=K(h.type??h.elementType),C=ee(v),P=j(v),D=X(h),B=ue(h),Z={name:C,displayName:P,kind:D};return B&&(Z.debugSource=B),Z}s(Q,"frameFromFiber");function w(h){let v=h.displayName?h.displayName:"",C=h.name?h.name:"",P=h.debugSource,D=P&&typeof P=="object"?`${String(P.fileName??"")}:${String(P.lineNumber??"")}:${String(P.columnNumber??"")}`:"";return`${v}|${C}|${h.kind}|${D}`}s(w,"makeFrameKey");function ce(h){let v=[],C=null;for(let P of h){let D=w(P);C&&D===C||(v.push(P),C=D)}return v}s(ce,"collapseConsecutiveDuplicates");function V(h){let v=new Set;function C(D){let B=D.trim().toLowerCase();B&&v.add(B)}s(C,"canonicalAdd");for(let D of h){let B=typeof D.displayName=="string"&&D.displayName.trim()?D.displayName.trim():typeof D.name=="string"&&D.name.trim()?D.name.trim():"";if(!B)continue;let Z=B.toLowerCase();/^memo(\(|$)/i.test(B)&&C("memo"),Z.includes("forwardref")&&C("forwardref"),Z.includes(".provider")&&C("context-provider"),Z.includes(".consumer")&&C("context-consumer"),Z.includes("suspense")&&C("suspense"),Z.includes("fragment")&&C("fragment"),Z.includes("strictmode")&&C("strictmode"),Z.includes("profiler")&&C("profiler")}let P=Array.from(v);return P.sort((D,B)=>D<B?-1:D>B?1:0),P}s(V,"detectWrappers");function U(h,v){let C=[],P=new Set(v.map(D=>D.toLowerCase()));for(let D=0;D<h.length;D++){let B=h[D],Z=B.displayName&&B.displayName.trim()?B.displayName.trim():B.name&&B.name.trim()?B.name.trim():"Anonymous",se=Z.toLowerCase();for(let me of P){let ve=!1;me==="memo"?ve=/^memo(\(|$)/i.test(Z):me==="forwardref"?ve=se.includes("forwardref"):me==="context-provider"?ve=se.includes(".provider"):me==="context-consumer"?ve=se.includes(".consumer"):me==="suspense"?ve=se.includes("suspense"):me==="fragment"?ve=se.includes("fragment"):me==="strictmode"?ve=se.includes("strictmode"):me==="profiler"&&(ve=se.includes("profiler")),ve&&C.push({wrapper:me,frameIndex:D,frameLabel:Z})}}return C}s(U,"findWrapperFrames");let J=null;if(c&&c.trim())try{J=document.querySelector(c)}catch{J=null}else typeof p=="number"&&typeof b=="number"&&(J=document.elementFromPoint(p,b));let Ne=!!J,Ie=ie(J),ze=Y(J,f);if(!Ne)return{target:{selector:c??null,point:{x:typeof p=="number"?p:null,y:typeof b=="number"?b:null},found:!1,domHint:null,elementPath:null},react:{detected:!1,detectionReason:"Target element not found.",fiberKey:null,hostMapping:{fiberOnTargetElement:!1,anchorDomHint:null,targetDomHint:null,hostFiberMatchedTarget:!1,subtreeScanNodesScanned:0,subtreeScanMaxNodes:I,strategy:"ancestor-fallback"},nearestComponent:null,componentStack:[],componentStackText:"",wrappersDetected:[],wrapperFrames:[],notes:["No DOM element could be resolved; cannot inspect React."]}};let Ce=L(J);if(!Ce)return W.push("No React fiber pointer found on the element or its ancestors."),W.push("This can happen if the page is not React, uses a different renderer, or runs with hardened/minified internals."),{target:{selector:c??null,point:{x:typeof p=="number"?p:null,y:typeof b=="number"?b:null},found:!0,domHint:Ie,elementPath:ze},react:{detected:!1,detectionReason:"React fiber not found on element/ancestors.",fiberKey:null,hostMapping:{fiberOnTargetElement:!1,anchorDomHint:null,targetDomHint:Ie,hostFiberMatchedTarget:!1,subtreeScanNodesScanned:0,subtreeScanMaxNodes:I,strategy:"ancestor-fallback"},nearestComponent:null,componentStack:[],componentStackText:"",wrappersDetected:[],wrapperFrames:[],notes:W}};let oe=Ce.fiber,Pe=Ce.onTarget,_e=0,yt=ie(Ce.anchorEl),et="direct-on-target";if(!Ce.onTarget){et="ancestor-fallback";let h=F(Ce.fiber,J,I);_e=h.scanned,h.found&&h.hostFiber?(oe=h.hostFiber,Pe=!0,et="ancestor-subtree-scan",W.push(`Mapped target DOM element to host fiber by scanning fiber subtree (scanned=${_e}).`)):(Pe=!1,W.push(`Could not find exact host fiber for the target element in the ancestor fiber subtree (scanned=${_e}). Falling back to ancestor fiber stack; some frames may be unrelated.`))}let tt={fiberOnTargetElement:Ce.onTarget,anchorDomHint:yt,targetDomHint:Ie,hostFiberMatchedTarget:Pe,subtreeScanNodesScanned:_e,subtreeScanMaxNodes:I,strategy:et},mt=null,kt=oe;for(;kt;){if(H(kt)){mt=kt;break}kt=kt.return??null}mt||W.push("Fiber was found, but no meaningful function/class component was detected in the return chain.");let Wt=[],ln=new Set,pt=mt;for(;pt&&Wt.length<T;){if(ln.has(pt)){W.push("Detected a cycle in fiber.return chain; stopping stack traversal.");break}ln.add(pt),H(pt)&&Wt.push(Q(pt)),pt=pt.return??null}let $t=Wt.length>0?ce(Wt):[],Qr=de($t),jt=V($t),Zr=U($t,jt);jt.length>=3&&W.push(`Wrapper-heavy stack detected (${jt.join(", ")}). Interpreting nearestComponent may require skipping wrappers.`);let _t=null;if(mt&&(_t=Q(mt),k))try{let h=mt.memoizedProps;h!==void 0?_t.propsPreview=xe(h,M):W.push("memoizedProps not available on nearest component fiber.")}catch{W.push("Failed to read memoizedProps for nearest component (best-effort).")}return W.push("React Fiber inspection uses non-public internals; fields are best-effort."),W.push("Component names may come from displayName, wrappers, third-party libraries, or minified production builds."),et==="ancestor-fallback"&&W.push("Host mapping fallback was used; consider selecting a deeper/more specific DOM element for a more accurate component stack."),{target:{selector:c??null,point:{x:typeof p=="number"?p:null,y:typeof b=="number"?b:null},found:!0,domHint:Ie,elementPath:ze},react:{detected:!0,detectionReason:et==="direct-on-target"?"React fiber found on the target element.":et==="ancestor-subtree-scan"?"React fiber found on an ancestor; exact host fiber located via subtree scan.":"React fiber found on an ancestor; exact host fiber not found, stack may include unrelated frames.",fiberKey:Ce.fiberKey,hostMapping:tt,nearestComponent:_t,componentStack:$t,componentStackText:Qr,wrappersDetected:jt,wrapperFrames:Zr,notes:W}}},{selectorEval:n??null,xEval:typeof r=="number"?r:null,yEval:typeof i=="number"?i:null,maxStackDepthEval:a,includePropsPreviewEval:l,maxPropsPreviewCharsEval:u,maxElementPathDepthEval:dc,maxFiberNodesToScanEval:bc})}};import{z as E}from"zod";var Ba="contains",Aa=200,La=!0,Fa=!0,Ua=80,Ha=5,gc=50,hc=20,fc=25e4,rr=class{static{s(this,"GetElementForComponent")}name(){return"react_get-element-for-component"}description(){return`
645
+ `.trim()}inputSchema(){return{selector:F.string().optional().describe("CSS selector for the target element. If provided, takes precedence over x/y."),x:F.number().int().optional().describe("Viewport X coordinate in CSS pixels. Used when selector is not provided."),y:F.number().int().optional().describe("Viewport Y coordinate in CSS pixels. Used when selector is not provided."),maxStackDepth:F.number().int().positive().optional().default(Ba).describe("Maximum number of component frames to return in the component stack."),includePropsPreview:F.boolean().optional().default(La).describe("If true, includes a best-effort, truncated props preview for the nearest component."),maxPropsPreviewChars:F.number().int().positive().optional().default(Aa).describe("Maximum characters for props preview (after safe stringification).")}}outputSchema(){return{target:F.object({selector:F.string().nullable(),point:F.object({x:F.number().int().nullable(),y:F.number().int().nullable()}),found:F.boolean(),domHint:F.string().nullable(),elementPath:F.string().nullable()}),react:F.object({detected:F.boolean(),detectionReason:F.string(),fiberKey:F.string().nullable(),hostMapping:F.object({fiberOnTargetElement:F.boolean().describe("Whether the initial fiber pointer was found directly on the target element."),anchorDomHint:F.string().nullable().describe("DOM hint of the element where fiber pointer was found (target or ancestor)."),targetDomHint:F.string().nullable().describe("DOM hint of the actual target element."),hostFiberMatchedTarget:F.boolean().describe("Whether we found the exact host fiber for target element (fiber.stateNode === targetEl) via subtree scan."),subtreeScanNodesScanned:F.number().int().describe("Number of fiber nodes scanned during subtree search."),subtreeScanMaxNodes:F.number().int().describe("Maximum fiber nodes allowed to scan (safety cap)."),strategy:F.enum(["direct-on-target","ancestor-subtree-scan","ancestor-fallback"]).describe("Mapping strategy used to produce the final stack.")}),nearestComponent:F.object({name:F.string().nullable(),displayName:F.string().nullable(),kind:F.enum(["function","class","unknown"]),debugSource:F.object({fileName:F.string().optional(),lineNumber:F.number().int().optional(),columnNumber:F.number().int().optional()}).optional(),propsPreview:F.string().optional()}).nullable(),componentStack:F.array(F.object({name:F.string().nullable(),displayName:F.string().nullable(),kind:F.enum(["function","class","unknown"]),debugSource:F.object({fileName:F.string().optional(),lineNumber:F.number().int().optional(),columnNumber:F.number().int().optional()}).optional()})),componentStackText:F.string(),wrappersDetected:F.array(F.string()),wrapperFrames:F.array(F.object({wrapper:F.string(),frameIndex:F.number().int(),frameLabel:F.string()})),notes:F.array(F.string())})}}async handle(e,t){let n=typeof t.selector=="string"&&t.selector.trim()?t.selector.trim():void 0,r=typeof t.x=="number"&&Number.isFinite(t.x)?Math.floor(t.x):void 0,i=typeof t.y=="number"&&Number.isFinite(t.y)?Math.floor(t.y):void 0;if(!n&&(typeof r!="number"||typeof i!="number"))throw new Error("Provide either selector, or both x and y for elementFromPoint.");let a=typeof t.maxStackDepth=="number"&&t.maxStackDepth>0?Math.floor(t.maxStackDepth):Ba,l=t.includePropsPreview===void 0?La:t.includePropsPreview===!0,u=typeof t.maxPropsPreviewChars=="number"&&Number.isFinite(t.maxPropsPreviewChars)&&t.maxPropsPreviewChars>0?Math.floor(t.maxPropsPreviewChars):Aa;return await e.page.evaluate(c=>{let p=c.selectorEval,b=c.xEval,f=c.yEval,x=c.maxStackDepthEval,B=c.includePropsPreviewEval,w=c.maxPropsPreviewCharsEval,U=c.maxElementPathDepthEval,D=c.maxFiberNodesToScanEval,H=[];function Q(g){if(!g)return null;let C=g.tagName.toLowerCase(),I=g.id&&g.id.trim()?"#"+g.id.trim():"",R=typeof g.className=="string"?g.className:"",A=R?"."+R.trim().split(/\s+/).slice(0,4).join("."):"";return C+I+A}s(Q,"domHint");function $(g,C){if(!g)return null;let I=[],R=g,A=0;for(;R&&A<C;){let L=R.tagName?R.tagName.toLowerCase():"unknown",Z=R.id&&R.id.trim()?"#"+R.id.trim():"",ie=typeof R.className=="string"?R.className:"",de=ie?ie.trim().split(/\s+/).filter(Boolean).slice(0,3):[],Ee=de.length>0?"."+de.join("."):"",Ge="";try{let Mt=R.parentElement;if(Mt){let mn=Array.from(Mt.children).filter(Dt=>Dt.tagName===R.tagName);if(mn.length>1){let Dt=mn.indexOf(R)+1;Dt>0&&(Ge=`:nth-of-type(${Dt})`)}}}catch{}I.push(`${L}${Z}${Ee}${Ge}`),R=R.parentElement,A++}return I.reverse(),I.join(" > ")}s($,"buildElementPath");function P(g){if(!g)return null;let C=Object.getOwnPropertyNames(g);for(let I of C)if(I.startsWith("__reactFiber$")||I.startsWith("__reactInternalInstance$"))return I;return null}s(P,"findFiberKeyOn");function W(g){if(!g)return null;let C=P(g);if(C){let R=g[C];if(R)return{fiber:R,fiberKey:C,onTarget:!0,anchorEl:g}}let I=g;for(;I;){let R=P(I);if(R){let A=I[R];if(A)return{fiber:A,fiberKey:R,onTarget:!1,anchorEl:I}}I=I.parentElement}return null}s(W,"findFiberForElement");function G(g,C,I){if(!g)return{hostFiber:null,scanned:0,found:!1};if(g.stateNode===C)return{hostFiber:g,scanned:1,found:!0};let R=[],A=new Set;R.push(g),A.add(g);let L=0;for(;R.length>0;){let Z=R.shift();if(L++,Z&&Z.stateNode===C)return{hostFiber:Z,scanned:L,found:!0};if(L>=I)return{hostFiber:null,scanned:L,found:!1};let ie=Z?Z.child:null;ie&&!A.has(ie)&&(A.add(ie),R.push(ie));let de=Z?Z.sibling:null;de&&!A.has(de)&&(A.add(de),R.push(de))}return{hostFiber:null,scanned:L,found:!1}}s(G,"findHostFiberForDomElement");function _(g){if(!g)return!1;let C=g.prototype;return!!(C&&C.isReactComponent)}s(_,"isClassComponentType");function oe(g){if(!g)return null;if(typeof g=="function"){let C=g.displayName;return typeof C=="string"&&C.trim()?C.trim():typeof g.name=="string"&&g.name.trim()?g.name.trim():"Anonymous"}if(typeof g=="object"){let C=g.displayName;if(typeof C=="string"&&C.trim())return C.trim();let I=g.render;if(typeof I=="function"){let R=I.displayName;return typeof R=="string"&&R.trim()?R.trim():typeof I.name=="string"&&I.name.trim()?I.name.trim():"Anonymous"}}return null}s(oe,"typeDisplayName");function Y(g){if(!g)return null;if(typeof g=="function")return typeof g.name=="string"&&g.name.trim()?g.name.trim():null;if(typeof g=="object"){let C=g.render;return typeof C=="function"&&typeof C.name=="string"&&C.name.trim()?C.name.trim():null}return null}s(Y,"typeName");function M(g){if(!g)return g;if(typeof g=="object"){let C=g.render;if(typeof C=="function")return C}return g}s(M,"unwrapType");function ee(g){return g?typeof M(g.type??g.elementType)=="function":!1}s(ee,"isMeaningfulComponentFiber");function ue(g){if(!g)return"unknown";let C=M(g.type??g.elementType);return typeof C=="function"?_(C)?"class":"function":"unknown"}s(ue,"inferKind");function ce(g){let C=g?g._debugSource:void 0;if(!C||typeof C!="object")return;let I={};return typeof C.fileName=="string"&&(I.fileName=C.fileName),typeof C.lineNumber=="number"&&(I.lineNumber=C.lineNumber),typeof C.columnNumber=="number"&&(I.columnNumber=C.columnNumber),Object.keys(I).length>0?I:void 0}s(ce,"getDebugSource");function fe(g,C){let I=new WeakSet;function R(L,Z){if(L===null)return null;let ie=typeof L;if(ie==="string")return L.length>500?L.slice(0,500)+"\u2026":L;if(ie==="number"||ie==="boolean")return L;if(ie==="bigint")return String(L);if(ie!=="undefined"){if(ie==="function")return"[function]";if(ie==="symbol")return String(L);if(ie==="object"){if(L instanceof Element)return"[Element "+(L.tagName?L.tagName.toLowerCase():"")+"]";if(L instanceof Window)return"[Window]";if(L instanceof Document)return"[Document]";if(L instanceof Date)return L.toISOString();if(I.has(L))return"[circular]";if(I.add(L),Array.isArray(L))return Z<=0?"[array len="+L.length+"]":L.slice(0,20).map(Ge=>R(Ge,Z-1));if(Z<=0)return"[object]";let de={},Ee=Object.keys(L).slice(0,40);for(let Ge of Ee)try{de[Ge]=R(L[Ge],Z-1)}catch{de[Ge]="[unreadable]"}return de}return String(L)}}s(R,"helper");let A="";try{A=JSON.stringify(R(g,2))}catch{try{A=String(g)}catch{A="[unserializable]"}}return A.length>C?A.slice(0,C)+"\u2026(truncated)":A}s(fe,"safeStringify");function te(g){return g.map(I=>{let R=I?.displayName,A=I?.name;return typeof R=="string"&&R.trim()?R.trim():typeof A=="string"&&A.trim()?A.trim():"Anonymous"}).filter(I=>!!I).reverse().join(" > ")}s(te,"stackTextFromFrames");function me(g){let C=M(g.type??g.elementType),I=Y(C),R=oe(C),A=ue(g),L=ce(g),Z={name:I,displayName:R,kind:A};return L&&(Z.debugSource=L),Z}s(me,"frameFromFiber");function v(g){let C=g.displayName?g.displayName:"",I=g.name?g.name:"",R=g.debugSource,A=R&&typeof R=="object"?`${String(R.fileName??"")}:${String(R.lineNumber??"")}:${String(R.columnNumber??"")}`:"";return`${C}|${I}|${g.kind}|${A}`}s(v,"makeFrameKey");function pe(g){let C=[],I=null;for(let R of g){let A=v(R);I&&A===I||(C.push(R),I=A)}return C}s(pe,"collapseConsecutiveDuplicates");function V(g){let C=new Set;function I(A){let L=A.trim().toLowerCase();L&&C.add(L)}s(I,"canonicalAdd");for(let A of g){let L=typeof A.displayName=="string"&&A.displayName.trim()?A.displayName.trim():typeof A.name=="string"&&A.name.trim()?A.name.trim():"";if(!L)continue;let Z=L.toLowerCase();/^memo(\(|$)/i.test(L)&&I("memo"),Z.includes("forwardref")&&I("forwardref"),Z.includes(".provider")&&I("context-provider"),Z.includes(".consumer")&&I("context-consumer"),Z.includes("suspense")&&I("suspense"),Z.includes("fragment")&&I("fragment"),Z.includes("strictmode")&&I("strictmode"),Z.includes("profiler")&&I("profiler")}let R=Array.from(C);return R.sort((A,L)=>A<L?-1:A>L?1:0),R}s(V,"detectWrappers");function q(g,C){let I=[],R=new Set(C.map(A=>A.toLowerCase()));for(let A=0;A<g.length;A++){let L=g[A],Z=L.displayName&&L.displayName.trim()?L.displayName.trim():L.name&&L.name.trim()?L.name.trim():"Anonymous",ie=Z.toLowerCase();for(let de of R){let Ee=!1;de==="memo"?Ee=/^memo(\(|$)/i.test(Z):de==="forwardref"?Ee=ie.includes("forwardref"):de==="context-provider"?Ee=ie.includes(".provider"):de==="context-consumer"?Ee=ie.includes(".consumer"):de==="suspense"?Ee=ie.includes("suspense"):de==="fragment"?Ee=ie.includes("fragment"):de==="strictmode"?Ee=ie.includes("strictmode"):de==="profiler"&&(Ee=ie.includes("profiler")),Ee&&I.push({wrapper:de,frameIndex:A,frameLabel:Z})}}return I}s(q,"findWrapperFrames");let X=null;if(p&&p.trim())try{X=document.querySelector(p)}catch{X=null}else typeof b=="number"&&typeof f=="number"&&(X=document.elementFromPoint(b,f));let Pe=!!X,Ie=Q(X),ft=$(X,U);if(!Pe)return{target:{selector:p??null,point:{x:typeof b=="number"?b:null,y:typeof f=="number"?f:null},found:!1,domHint:null,elementPath:null},react:{detected:!1,detectionReason:"Target element not found.",fiberKey:null,hostMapping:{fiberOnTargetElement:!1,anchorDomHint:null,targetDomHint:null,hostFiberMatchedTarget:!1,subtreeScanNodesScanned:0,subtreeScanMaxNodes:D,strategy:"ancestor-fallback"},nearestComponent:null,componentStack:[],componentStackText:"",wrappersDetected:[],wrapperFrames:[],notes:["No DOM element could be resolved; cannot inspect React."]}};let J=W(X);if(!J)return H.push("No React fiber pointer found on the element or its ancestors."),H.push("This can happen if the page is not React, uses a different renderer, or runs with hardened/minified internals."),{target:{selector:p??null,point:{x:typeof b=="number"?b:null,y:typeof f=="number"?f:null},found:!0,domHint:Ie,elementPath:ft},react:{detected:!1,detectionReason:"React fiber not found on element/ancestors.",fiberKey:null,hostMapping:{fiberOnTargetElement:!1,anchorDomHint:null,targetDomHint:Ie,hostFiberMatchedTarget:!1,subtreeScanNodesScanned:0,subtreeScanMaxNodes:D,strategy:"ancestor-fallback"},nearestComponent:null,componentStack:[],componentStackText:"",wrappersDetected:[],wrapperFrames:[],notes:H}};let Ce=J.fiber,We=J.onTarget,Le=0,un=Q(J.anchorEl),qe="direct-on-target";if(!J.onTarget){qe="ancestor-fallback";let g=G(J.fiber,X,D);Le=g.scanned,g.found&&g.hostFiber?(Ce=g.hostFiber,We=!0,qe="ancestor-subtree-scan",H.push(`Mapped target DOM element to host fiber by scanning fiber subtree (scanned=${Le}).`)):(We=!1,H.push(`Could not find exact host fiber for the target element in the ancestor fiber subtree (scanned=${Le}). Falling back to ancestor fiber stack; some frames may be unrelated.`))}let Wt={fiberOnTargetElement:J.onTarget,anchorDomHint:un,targetDomHint:Ie,hostFiberMatchedTarget:We,subtreeScanNodesScanned:Le,subtreeScanMaxNodes:D,strategy:qe},ct=null,Rt=Ce;for(;Rt;){if(ee(Rt)){ct=Rt;break}Rt=Rt.return??null}ct||H.push("Fiber was found, but no meaningful function/class component was detected in the return chain.");let qt=[],cn=new Set,mt=ct;for(;mt&&qt.length<x;){if(cn.has(mt)){H.push("Detected a cycle in fiber.return chain; stopping stack traversal.");break}cn.add(mt),ee(mt)&&qt.push(me(mt)),mt=mt.return??null}let $t=qt.length>0?pe(qt):[],Zr=te($t),jt=V($t),es=q($t,jt);jt.length>=3&&H.push(`Wrapper-heavy stack detected (${jt.join(", ")}). Interpreting nearestComponent may require skipping wrappers.`);let kt=null;if(ct&&(kt=me(ct),B))try{let g=ct.memoizedProps;g!==void 0?kt.propsPreview=fe(g,w):H.push("memoizedProps not available on nearest component fiber.")}catch{H.push("Failed to read memoizedProps for nearest component (best-effort).")}return H.push("React Fiber inspection uses non-public internals; fields are best-effort."),H.push("Component names may come from displayName, wrappers, third-party libraries, or minified production builds."),qe==="ancestor-fallback"&&H.push("Host mapping fallback was used; consider selecting a deeper/more specific DOM element for a more accurate component stack."),{target:{selector:p??null,point:{x:typeof b=="number"?b:null,y:typeof f=="number"?f:null},found:!0,domHint:Ie,elementPath:ft},react:{detected:!0,detectionReason:qe==="direct-on-target"?"React fiber found on the target element.":qe==="ancestor-subtree-scan"?"React fiber found on an ancestor; exact host fiber located via subtree scan.":"React fiber found on an ancestor; exact host fiber not found, stack may include unrelated frames.",fiberKey:J.fiberKey,hostMapping:Wt,nearestComponent:kt,componentStack:$t,componentStackText:Zr,wrappersDetected:jt,wrapperFrames:es,notes:H}}},{selectorEval:n??null,xEval:typeof r=="number"?r:null,yEval:typeof i=="number"?i:null,maxStackDepthEval:a,includePropsPreviewEval:l,maxPropsPreviewCharsEval:u,maxElementPathDepthEval:Tc,maxFiberNodesToScanEval:Sc})}};import{z as O}from"zod";var Fa="contains",Ua=200,Ha=!0,Wa=!0,qa=80,$a=5,xc=50,vc=20,Ic=25e4,sr=class{static{s(this,"GetElementForComponent")}name(){return"react_get-element-for-component"}description(){return`
647
646
  Maps a React COMPONENT INSTANCE to the DOM elements it renders (its "DOM footprint") by traversing the React Fiber graph.
648
647
 
649
648
  Selection strategy:
@@ -661,7 +660,7 @@ Important behavior:
661
660
  Operational note for MCP users:
662
661
  - If you are using a persistent/headful browser and want more reliable root discovery and component search,
663
662
  install the "React Developer Tools" Chrome extension in that browser profile (manual step by the user).
664
- `.trim()}inputSchema(){return{anchorSelector:E.string().optional().describe("DOM CSS selector used as an anchor to pick a concrete component instance near that element."),anchorX:E.number().int().nonnegative().optional().describe("Anchor X coordinate (viewport pixels)."),anchorY:E.number().int().nonnegative().optional().describe("Anchor Y coordinate (viewport pixels)."),componentName:E.string().optional().describe("React component name/displayName to search in the Fiber graph."),matchStrategy:E.enum(["exact","contains"]).optional().default(Ba).describe("How to match componentName against Fiber type/displayName."),fileNameHint:E.string().optional().describe('Best-effort debug source file hint (usually endsWith match), e.g., "UserCard.tsx".'),lineNumber:E.number().int().positive().optional().describe("Optional debug source line number hint (dev builds only)."),maxElements:E.number().int().positive().optional().default(Aa).describe("Maximum number of DOM elements to return from the selected component subtree."),onlyVisible:E.boolean().optional().default(La).describe("If true, only visually visible elements are returned."),onlyInViewport:E.boolean().optional().default(Fa).describe("If true, only elements intersecting the viewport are returned."),textPreviewMaxLength:E.number().int().positive().optional().default(Ua).describe("Max length for per-element text preview (innerText/textContent/aria-label)."),maxMatches:E.number().int().positive().optional().default(Ha).describe("Max number of matching component candidates to return/rank.")}}outputSchema(){return{reactDetected:E.boolean().describe("True if __REACT_DEVTOOLS_GLOBAL_HOOK__ looks available."),fiberDetected:E.boolean().describe("True if DOM appears to contain React Fiber pointers (__reactFiber$...)."),rootDiscovery:E.enum(["devtools-hook","dom-fiber-scan","none"]).describe("How roots were discovered."),component:E.object({name:E.string().nullable(),displayName:E.string().nullable(),debugSource:E.object({fileName:E.string().nullable(),lineNumber:E.number().int().nullable(),columnNumber:E.number().int().nullable()}).nullable(),componentStack:E.array(E.string()),selection:E.enum(["anchor","query","query+anchor","unknown"]),scoring:E.object({score:E.number(),nameMatched:E.boolean(),debugSourceMatched:E.boolean(),anchorRelated:E.boolean(),proximityPx:E.number().nullable().optional()}).optional()}).nullable(),candidates:E.array(E.object({name:E.string().nullable(),displayName:E.string().nullable(),debugSource:E.object({fileName:E.string().nullable(),lineNumber:E.number().int().nullable(),columnNumber:E.number().int().nullable()}).nullable(),componentStack:E.array(E.string()),selection:E.enum(["anchor","query","query+anchor","unknown"]),scoring:E.object({score:E.number(),nameMatched:E.boolean(),debugSourceMatched:E.boolean(),anchorRelated:E.boolean(),proximityPx:E.number().nullable().optional()}).optional(),domFootprintCount:E.number().int()})).describe("Ranked candidate matches (best-first)."),elements:E.array(E.object({tagName:E.string(),id:E.string().nullable(),className:E.string().nullable(),selectorHint:E.string().nullable(),textPreview:E.string().nullable(),boundingBox:E.object({x:E.number(),y:E.number(),width:E.number(),height:E.number()}).nullable(),isVisible:E.boolean(),isInViewport:E.boolean()})),notes:E.array(E.string())}}async handle(e,t){let n=t.anchorSelector,r=t.anchorX,i=t.anchorY,a=t.componentName,l=t.matchStrategy??Ba,u=t.fileNameHint,m=t.lineNumber,c=t.maxElements??Aa,p=t.onlyVisible??La,b=t.onlyInViewport??Fa,T=t.textPreviewMaxLength??Ua,k=t.maxMatches??Ha,M=typeof n=="string"&&n.trim().length>0,f=typeof r=="number"&&typeof i=="number",I=typeof a=="string"&&a.trim().length>0||typeof u=="string"&&u.trim().length>0||typeof m=="number";if(!M&&!f&&!I)throw new Error("Provide at least one targeting method: anchorSelector, (anchorX+anchorY), or componentName/debugSource hints.");return await e.page.evaluate(({anchorSelectorEval:ie,anchorXEval:Y,anchorYEval:_,componentNameEval:L,matchStrategyEval:F,fileNameHintEval:q,lineNumberEval:j,maxElementsEval:ee,onlyVisibleEval:K,onlyInViewportEval:H,textPreviewMaxLengthEval:X,maxMatchesEval:ue,maxRootsScan:xe,maxFibersVisited:de,stackLimit:Q})=>{let w=[];function ce(g){return typeof Element<"u"&&g instanceof Element}s(ce,"isElement");function V(g){if(typeof g!="string")return null;let d=g.trim();return d||null}s(V,"normalizeStr");function U(g){let d=g,x=Object.keys(d);for(let O of x)if(O.startsWith("__reactFiber$")){let R=d[O];if(R)return R}for(let O of x)if(O.startsWith("__reactInternalInstance$")){let R=d[O];if(R)return R}return null}s(U,"getFiberFromDomElement");function J(){let d=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;return!d||typeof d.getFiberRoots!="function"?null:d}s(J,"getDevtoolsHook");function Ne(g){let d=[],x=g.renderers;return!x||typeof x.forEach!="function"?d:(x.forEach((O,R)=>{try{let z=g.getFiberRoots(R);z&&typeof z.forEach=="function"&&z.forEach(re=>{re&&d.push(re)})}catch{}}),d.slice(0,xe))}s(Ne,"getAllRootsFromHook");function Ie(g){let d=[],x=Array.from(document.querySelectorAll("*")),O=x.length>5e3?Math.ceil(x.length/5e3):1;for(let R=0;R<x.length;R+=O){let z=x[R],re=U(z);if(re&&(d.push(re),d.length>=g))break}return d}s(Ie,"getSeedFibersFromDomScan");function ze(g){if(typeof g!="function")return null;let d=g,x=V(d.displayName);if(x)return x;let O=V(d.name);return O||null}s(ze,"getFunctionDisplayName");function Ce(g){if(!g)return null;let d=g.type??g.elementType??null;if(!d)return null;if(typeof d=="function")return ze(d);if(typeof d=="string")return d;let x=V(d.displayName);return x||V(d.name)}s(Ce,"getFiberTypeName");function oe(g){if(!g)return null;let d=g.type??g.elementType??null;if(!d)return null;let x=V(d.displayName);return x||Ce(g)}s(oe,"getDisplayName");function Pe(g){let d=new Set,x=[],O=s(R=>{R&&(d.has(R)||(d.add(R),x.push(R)))},"push");O(g),O(g?.alternate);for(let R=0;R<8;R++){let z=x[R];if(!z)break;O(z?._debugOwner),O(z?._debugOwner?.alternate)}for(let R of x){let z=R?._debugSource??R?._debugOwner?._debugSource??R?.type?._debugSource??R?.elementType?._debugSource??null;if(!z)continue;let re=V(z.fileName)??null,he=typeof z.lineNumber=="number"?z.lineNumber:null,Fe=typeof z.columnNumber=="number"?z.columnNumber:null;if(re||he!==null||Fe!==null)return{fileName:re,lineNumber:he,columnNumber:Fe}}return null}s(Pe,"getDebugSource");function _e(g){let d=g?.stateNode;return ce(d)}s(_e,"isHostFiber");function yt(g,d){let x=[],O=g??null;for(let z=0;z<d&&O;z++){let re=oe(O),he=_e(O);re&&!he&&x.push(re),O=O.return??null}if(x.length===0){O=g??null;for(let z=0;z<d&&O;z++){let re=oe(O);re&&x.push(re),O=O.return??null}}let R=[];for(let z of x)(R.length===0||R[R.length-1]!==z)&&R.push(z);return R}s(yt,"buildComponentStack");function et(g){let d=g??null,x=new Set;for(;d;){let O=d.alternate??d;if(x.has(O))break;if(x.add(O),!_e(d))return d;d=d.return??null}return null}s(et,"firstMeaningfulComponentAbove");function tt(g,d,x){if(!g)return!1;let O=g.trim(),R=d.trim();return!O||!R?!1:x==="exact"?O===R:O.toLowerCase().includes(R.toLowerCase())}s(tt,"matchesName");function mt(g,d,x){let O=Pe(g);if(!O)return!1;if(d){let R=d.trim();if(R){let z=(O.fileName??"").trim();if(!z)return!1;let re=z.toLowerCase(),he=R.toLowerCase();if(!(re.endsWith(he)||re.includes(he)))return!1}}return!(typeof x=="number"&&(O.lineNumber===null||Math.abs(O.lineNumber-x)>3))}s(mt,"matchesDebugSource");function kt(g){if(!g)return null;let d=g.current;return d?d.child??d:g}s(kt,"toStartFiber");function Wt(g,d,x){if(g&&g.trim()){let O=document.querySelector(g);return O||(w.push(`anchorSelector did not match any element: ${g}`),null)}if(typeof d=="number"&&typeof x=="number"){let O=document.elementFromPoint(d,x);return O||(w.push(`anchorPoint did not hit any element: (${d}, ${x})`),null)}return null}s(Wt,"pickAnchorElement");function ln(g){let d=V(g.getAttribute("data-testid"))??V(g.getAttribute("data-test-id"))??V(g.getAttribute("data-test"))??null;if(d)return`[data-testid='${d.replace(/'/g,"\\'")}']`;let x=V(g.getAttribute("data-selector"))??null;if(x)return`[data-selector='${x.replace(/'/g,"\\'")}']`;if(g.id)try{return`#${CSS.escape(g.id)}`}catch{return`#${g.id}`}return g.tagName.toLowerCase()}s(ln,"selectorHintFor");function pt(g,d){let x=V(g.getAttribute("aria-label"))??null;if(x)return x.slice(0,d);let O=String(g.innerText??g.textContent??"").trim();return O?O.slice(0,d):null}s(pt,"textPreviewFor");function $t(g){let d=g.getBoundingClientRect(),x=getComputedStyle(g),O=x.display!=="none"&&x.visibility!=="hidden"&&parseFloat(x.opacity||"1")>0&&d.width>0&&d.height>0,R=window.innerWidth,z=window.innerHeight,re=d.right>0&&d.bottom>0&&d.left<R&&d.top<z,he=Number.isFinite(d.x)&&Number.isFinite(d.y)&&Number.isFinite(d.width)&&Number.isFinite(d.height)?{x:d.x,y:d.y,width:d.width,height:d.height}:null,Fe=d.left+d.width/2,ye=d.top+d.height/2;return{boundingBox:he,isVisible:O,isInViewport:re,centerX:Fe,centerY:ye}}s($t,"computeRuntime");function Qr(g,d,x,O,R){let z=[],re=new Set,he=[];g&&he.push(g);let Fe=new Set;for(;he.length>0&&!(z.length>=d);){let ye=he.pop();if(!ye)continue;let nt=ye.alternate??ye;if(Fe.has(nt))continue;if(Fe.add(nt),_e(ye)){let be=ye.stateNode;if(!re.has(be)){re.add(be);let Me=$t(be);if(!(x&&!Me.isVisible)){if(!(O&&!Me.isInViewport)){let ot=be.tagName.toLowerCase(),Lt=be.id?String(be.id):null,Ge=be.className,rt=typeof Ge=="string"&&Ge.trim()?Ge.trim():null;z.push({tagName:ot,id:Lt,className:rt,selectorHint:ln(be),textPreview:pt(be,R),boundingBox:Me.boundingBox,isVisible:Me.isVisible,isInViewport:Me.isInViewport})}}}}let wt=ye.child??null,At=ye.sibling??null;wt&&he.push(wt),At&&he.push(At)}return z}s(Qr,"collectDomElementsFromFiberSubtree");function jt(g,d,x){let O=d.componentName?d.componentName.trim():void 0,R=!!O,z=d.fileNameHint?d.fileNameHint.trim():void 0,re=!!z,he=typeof d.lineNumber=="number";if(!(R||re||he))return[];let ye=[];for(let be of g){let Me=kt(be);Me&&ye.push(Me)}let nt=new Set,wt=[],At=0;for(;ye.length>0&&!(wt.length>=x);){let be=ye.pop();if(!be)continue;let Me=be.alternate??be;if(nt.has(Me))continue;if(nt.add(Me),At++,At>de){w.push(`Fiber traversal safety cap reached (${de}). Results may be incomplete.`);break}let ot=oe(be),Lt=Ce(be),Ge=R?tt(ot,O,d.matchStrategy)||tt(Lt,O,d.matchStrategy):!0,rt=re||he?mt(be,z,d.lineNumber):!0;Ge&&rt&&wt.push(be);let Ft=be.child??null,De=be.sibling??null;Ft&&ye.push(Ft),De&&ye.push(De)}return wt}s(jt,"findFibersByQuery");function Zr(g,d,x,O,R,z,re,he,Fe){let ye=R.componentName?R.componentName.trim():void 0,nt=!!ye,wt=oe(g),At=Ce(g),be=nt?tt(wt,ye,R.matchStrategy)||tt(At,ye,R.matchStrategy):!1,Me=V(R.fileNameHint)||typeof R.lineNumber=="number"?mt(g,V(R.fileNameHint)??void 0,typeof R.lineNumber=="number"?R.lineNumber:void 0):!1,ot=Qr(g,z,re,he,Fe),Lt=!1,Ge=null;if(d){let Ft=ln(d);if(Lt=ot.some(De=>!De.selectorHint||!Ft?!1:De.selectorHint===Ft)||ot.some(De=>{if(!De.boundingBox)return!1;let qe=d.getBoundingClientRect(),Tt=De.boundingBox;return qe.left<Tt.x+Tt.width&&qe.left+qe.width>Tt.x&&qe.top<Tt.y+Tt.height&&qe.top+qe.height>Tt.y}),typeof x=="number"&&typeof O=="number"&&ot.length>0){let De=null;for(let qe of ot){if(!qe.boundingBox)continue;let Tt=qe.boundingBox.x+qe.boundingBox.width/2,Fs=qe.boundingBox.y+qe.boundingBox.height/2,Us=Tt-x,Hs=Fs-O,ts=Math.sqrt(Us*Us+Hs*Hs);(De===null||ts<De)&&(De=ts)}Ge=De}}let rt=0;if(rt+=be?3:0,rt+=Me?3:0,rt+=Lt?2:0,rt+=Math.min(1.5,ot.length/25),typeof Ge=="number"&&Number.isFinite(Ge)){let Ft=Math.max(0,Math.min(1,1-Ge/1e3));rt+=1.5*Ft}return{score:rt,nameMatched:be,debugSourceMatched:Me,anchorRelated:Lt,proximityPx:Ge,dom:ot}}s(Zr,"scoreCandidate");let _t=J(),Mt=!!_t;Mt?w.push("React DevTools hook detected. Root discovery will use getFiberRoots() (more reliable)."):(w.push("React DevTools hook was not detected (__REACT_DEVTOOLS_GLOBAL_HOOK__)."),w.push('If you are using a persistent/headful browser profile, install the "React Developer Tools" Chrome extension in that profile (manual step by the user) to enable reliable root discovery and component search.'));let h=(()=>{let g=document.body;return g?!!(U(g)||Ie(1).length>0):!1})();h?w.push("React Fiber pointers detected on DOM nodes. Anchor-based mapping may still work without the DevTools hook (best-effort)."):w.push("No React Fiber pointers were detected on DOM nodes (__reactFiber$...). This can happen if the page is not React, React has not rendered yet, or internals are unavailable.");let v=Wt(ie,Y,_),C=null;if(v){let g=U(v);if(g){let d=g,x=g.alternate??null,O=d;x&&(x.child||x.sibling)&&!(d.child||d.sibling)&&(O=x);let R=et(O);R?C=R:w.push("Anchor fiber found but no meaningful component fiber was found above it.")}else w.push("Anchor element found but React fiber was not found on it.")}let P=[],D="none";if(_t){let g=Ne(_t);g.length>0&&(P=g,D="devtools-hook")}if(P.length===0&&h){let g=Ie(10);g.length>0&&(P=g,D="dom-fiber-scan",w.push("Using DOM fiber scan as fallback root discovery (best-effort)."))}let B=!!V(L)||!!V(q)||typeof j=="number",Z={componentName:V(L)??void 0,matchStrategy:F,fileNameHint:V(q)??void 0,lineNumber:typeof j=="number"?j:void 0},se=[];B&&(P.length>0?se=jt(P,Z,Math.max(1,Math.floor(ue))):w.push("Query was provided but no roots could be discovered. Provide an anchorSelector/anchorX+anchorY so we can map via DOM fiber pointers."));let me=[];C&&me.push(C);for(let g of se)me.push(g);let ve=[],Ve=new Set;for(let g of me){let d=g?.alternate??g;g&&!Ve.has(d)&&(Ve.add(d),ve.push(g))}if(ve.length===0)return Mt||w.push("No candidates found. Without the DevTools hook, component search may be unreliable unless you provide a strong anchor."),{reactDetected:Mt,fiberDetected:h,rootDiscovery:D,component:null,candidates:[],elements:[],notes:[...w,"Failed to select a target component fiber. Provide a better anchor, or ensure React is present and render has happened."]};let Dt=[];for(let g of ve){let d=Zr(g,v,Y,_,Z,ee,K,H,X),x="unknown",O=C?(C.alternate??C)===(g.alternate??g):!1,R=se.some(nt=>(nt.alternate??nt)===(g.alternate??g));O&&R?x="query+anchor":O?x="anchor":R?x="query":x="unknown";let z=Ce(g),re=oe(g),he=Pe(g),Fe=yt(g,Q),ye={name:z,displayName:re,debugSource:he,componentStack:Fe,selection:x,scoring:{score:d.score,nameMatched:d.nameMatched,debugSourceMatched:d.debugSourceMatched,anchorRelated:d.anchorRelated,proximityPx:d.proximityPx}};Dt.push({fiber:g,meta:ye,dom:d.dom,domFootprintCount:d.dom.length})}Dt.sort((g,d)=>(d.meta.scoring?.score??0)-(g.meta.scoring?.score??0));let un=Dt[0],Bt=Dt.slice(0,Math.max(1,Math.floor(ue))).map(g=>({...g.meta,domFootprintCount:g.domFootprintCount})),es=un.dom;return B&&(Z.fileNameHint||typeof Z.lineNumber=="number")&&(Bt.some(d=>!!(d.debugSource?.fileName||d.debugSource?.lineNumber!==null))||(w.push("debugSource hints were provided, but no _debugSource information was found on matched fibers. This is common in production builds and some dev toolchains."),w.push('React DevTools may still display "Rendered by <file>:<line>" using sourcemaps/stack traces even when fiber._debugSource is null.'))),es.length>=ee&&w.push(`Element list was truncated at maxElements=${ee}. Increase maxElements if needed.`),es.length===0&&w.push("No DOM elements were returned for the selected component. It may render no host elements, or filtering (onlyVisible/onlyInViewport) removed them."),!Mt&&h?w.push("React DevTools hook was not detected, but DOM fiber pointers were found. Using DOM-fiber scanning and anchor-based mapping (best-effort)."):!Mt&&!h&&w.push("React DevTools hook was not detected and no DOM fiber pointers were found. Component-to-DOM mapping is unavailable on this page."),{reactDetected:Mt,fiberDetected:h,rootDiscovery:D,component:un.meta,candidates:Bt,elements:es,notes:[...w,"Component metadata is best-effort. Wrappers (memo/forwardRef/HOCs), Suspense/Offscreen, and portals may make names/stacks noisy."]}},{anchorSelectorEval:typeof n=="string"&&n.trim()?n.trim():void 0,anchorXEval:typeof r=="number"&&Number.isFinite(r)?Math.floor(r):void 0,anchorYEval:typeof i=="number"&&Number.isFinite(i)?Math.floor(i):void 0,componentNameEval:typeof a=="string"&&a.trim()?a.trim():void 0,matchStrategyEval:l,fileNameHintEval:typeof u=="string"&&u.trim()?u.trim():void 0,lineNumberEval:typeof m=="number"&&Number.isFinite(m)?Math.floor(m):void 0,maxElementsEval:Math.max(1,Math.floor(c)),onlyVisibleEval:!!p,onlyInViewportEval:!!b,textPreviewMaxLengthEval:Math.max(1,Math.floor(T)),maxMatchesEval:Math.max(1,Math.floor(k)),maxRootsScan:hc,maxFibersVisited:fc,stackLimit:gc})}};var qa=[new or,new rr];import{z as Wa}from"zod";var sr=class{static{s(this,"JsInBrowser")}name(){return"run_js-in-browser"}description(){return`
663
+ `.trim()}inputSchema(){return{anchorSelector:O.string().optional().describe("DOM CSS selector used as an anchor to pick a concrete component instance near that element."),anchorX:O.number().int().nonnegative().optional().describe("Anchor X coordinate (viewport pixels)."),anchorY:O.number().int().nonnegative().optional().describe("Anchor Y coordinate (viewport pixels)."),componentName:O.string().optional().describe("React component name/displayName to search in the Fiber graph."),matchStrategy:O.enum(["exact","contains"]).optional().default(Fa).describe("How to match componentName against Fiber type/displayName."),fileNameHint:O.string().optional().describe('Best-effort debug source file hint (usually endsWith match), e.g., "UserCard.tsx".'),lineNumber:O.number().int().positive().optional().describe("Optional debug source line number hint (dev builds only)."),maxElements:O.number().int().positive().optional().default(Ua).describe("Maximum number of DOM elements to return from the selected component subtree."),onlyVisible:O.boolean().optional().default(Ha).describe("If true, only visually visible elements are returned."),onlyInViewport:O.boolean().optional().default(Wa).describe("If true, only elements intersecting the viewport are returned."),textPreviewMaxLength:O.number().int().positive().optional().default(qa).describe("Max length for per-element text preview (innerText/textContent/aria-label)."),maxMatches:O.number().int().positive().optional().default($a).describe("Max number of matching component candidates to return/rank.")}}outputSchema(){return{reactDetected:O.boolean().describe("True if __REACT_DEVTOOLS_GLOBAL_HOOK__ looks available."),fiberDetected:O.boolean().describe("True if DOM appears to contain React Fiber pointers (__reactFiber$...)."),rootDiscovery:O.enum(["devtools-hook","dom-fiber-scan","none"]).describe("How roots were discovered."),component:O.object({name:O.string().nullable(),displayName:O.string().nullable(),debugSource:O.object({fileName:O.string().nullable(),lineNumber:O.number().int().nullable(),columnNumber:O.number().int().nullable()}).nullable(),componentStack:O.array(O.string()),selection:O.enum(["anchor","query","query+anchor","unknown"]),scoring:O.object({score:O.number(),nameMatched:O.boolean(),debugSourceMatched:O.boolean(),anchorRelated:O.boolean(),proximityPx:O.number().nullable().optional()}).optional()}).nullable(),candidates:O.array(O.object({name:O.string().nullable(),displayName:O.string().nullable(),debugSource:O.object({fileName:O.string().nullable(),lineNumber:O.number().int().nullable(),columnNumber:O.number().int().nullable()}).nullable(),componentStack:O.array(O.string()),selection:O.enum(["anchor","query","query+anchor","unknown"]),scoring:O.object({score:O.number(),nameMatched:O.boolean(),debugSourceMatched:O.boolean(),anchorRelated:O.boolean(),proximityPx:O.number().nullable().optional()}).optional(),domFootprintCount:O.number().int()})).describe("Ranked candidate matches (best-first)."),elements:O.array(O.object({tagName:O.string(),id:O.string().nullable(),className:O.string().nullable(),selectorHint:O.string().nullable(),textPreview:O.string().nullable(),boundingBox:O.object({x:O.number(),y:O.number(),width:O.number(),height:O.number()}).nullable(),isVisible:O.boolean(),isInViewport:O.boolean()})),notes:O.array(O.string())}}async handle(e,t){let n=t.anchorSelector,r=t.anchorX,i=t.anchorY,a=t.componentName,l=t.matchStrategy??Fa,u=t.fileNameHint,m=t.lineNumber,c=t.maxElements??Ua,p=t.onlyVisible??Ha,b=t.onlyInViewport??Wa,f=t.textPreviewMaxLength??qa,x=t.maxMatches??$a,B=typeof n=="string"&&n.trim().length>0,w=typeof r=="number"&&typeof i=="number",U=typeof a=="string"&&a.trim().length>0||typeof u=="string"&&u.trim().length>0||typeof m=="number";if(!B&&!w&&!U)throw new Error("Provide at least one targeting method: anchorSelector, (anchorX+anchorY), or componentName/debugSource hints.");return await e.page.evaluate(H=>{let Q=H.anchorSelectorEval,$=H.anchorXEval,P=H.anchorYEval,W=H.componentNameEval,G=H.matchStrategyEval,_=H.fileNameHintEval,oe=H.lineNumberEval,Y=H.maxElementsEval,M=H.onlyVisibleEval,ee=H.onlyInViewportEval,ue=H.textPreviewMaxLengthEval,ce=H.maxMatchesEval,fe=H.maxRootsScan,te=H.maxFibersVisited,me=H.stackLimit,v=[];function pe(h){return typeof Element<"u"&&h instanceof Element}s(pe,"isElement");function V(h){if(typeof h!="string")return null;let d=h.trim();return d||null}s(V,"normalizeStr");function q(h){let d=h,S=Object.keys(d);for(let E of S)if(E.startsWith("__reactFiber$")){let k=d[E];if(k)return k}for(let E of S)if(E.startsWith("__reactInternalInstance$")){let k=d[E];if(k)return k}return null}s(q,"getFiberFromDomElement");function X(){let d=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;return!d||typeof d.getFiberRoots!="function"?null:d}s(X,"getDevtoolsHook");function Pe(h){let d=[],S=h.renderers;return!S||typeof S.forEach!="function"?d:(S.forEach((E,k)=>{try{let z=h.getFiberRoots(k);z&&typeof z.forEach=="function"&&z.forEach(se=>{se&&d.push(se)})}catch{}}),d.slice(0,fe))}s(Pe,"getAllRootsFromHook");function Ie(h){let d=[],S=Array.from(document.querySelectorAll("*")),E=S.length>5e3?Math.ceil(S.length/5e3):1;for(let k=0;k<S.length;k+=E){let z=S[k],se=q(z);if(se&&(d.push(se),d.length>=h))break}return d}s(Ie,"getSeedFibersFromDomScan");function ft(h){if(typeof h!="function")return null;let d=h,S=V(d.displayName);if(S)return S;let E=V(d.name);return E||null}s(ft,"getFunctionDisplayName");function J(h){if(!h)return null;let d=h.type??h.elementType??null;if(!d)return null;if(typeof d=="function")return ft(d);if(typeof d=="string")return d;let S=V(d.displayName);return S||V(d.name)}s(J,"getFiberTypeName");function Ce(h){if(!h)return null;let d=h.type??h.elementType??null;if(!d)return null;let S=V(d.displayName);return S||J(h)}s(Ce,"getDisplayName");function We(h){let d=new Set,S=[],E=s(k=>{k&&(d.has(k)||(d.add(k),S.push(k)))},"push");E(h),E(h?.alternate);for(let k=0;k<8;k++){let z=S[k];if(!z)break;E(z?._debugOwner),E(z?._debugOwner?.alternate)}for(let k of S){let z=k?._debugSource??k?._debugOwner?._debugSource??k?.type?._debugSource??k?.elementType?._debugSource??null;if(!z)continue;let se=V(z.fileName)??null,ye=typeof z.lineNumber=="number"?z.lineNumber:null,Fe=typeof z.columnNumber=="number"?z.columnNumber:null;if(se||ye!==null||Fe!==null)return{fileName:se,lineNumber:ye,columnNumber:Fe}}return null}s(We,"getDebugSource");function Le(h){let d=h?.stateNode;return pe(d)}s(Le,"isHostFiber");function un(h,d){let S=[],E=h??null;for(let z=0;z<d&&E;z++){let se=Ce(E),ye=Le(E);se&&!ye&&S.push(se),E=E.return??null}if(S.length===0){E=h??null;for(let z=0;z<d&&E;z++){let se=Ce(E);se&&S.push(se),E=E.return??null}}let k=[];for(let z of S)(k.length===0||k[k.length-1]!==z)&&k.push(z);return k}s(un,"buildComponentStack");function qe(h){let d=h??null,S=new Set;for(;d;){let E=d.alternate??d;if(S.has(E))break;if(S.add(E),!Le(d))return d;d=d.return??null}return null}s(qe,"firstMeaningfulComponentAbove");function Wt(h,d,S){if(!h)return!1;let E=h.trim(),k=d.trim();return!E||!k?!1:S==="exact"?E===k:E.toLowerCase().includes(k.toLowerCase())}s(Wt,"matchesName");function ct(h,d,S){let E=We(h);if(!E)return!1;if(d){let k=d.trim();if(k){let z=(E.fileName??"").trim();if(!z)return!1;let se=z.toLowerCase(),ye=k.toLowerCase();if(!(se.endsWith(ye)||se.includes(ye)))return!1}}return!(typeof S=="number"&&(E.lineNumber===null||Math.abs(E.lineNumber-S)>3))}s(ct,"matchesDebugSource");function Rt(h){if(!h)return null;let d=h.current;return d?d.child??d:h}s(Rt,"toStartFiber");function qt(h,d,S){if(h&&h.trim()){let E=document.querySelector(h);return E||(v.push(`anchorSelector did not match any element: ${h}`),null)}if(typeof d=="number"&&typeof S=="number"){let E=document.elementFromPoint(d,S);return E||(v.push(`anchorPoint did not hit any element: (${d}, ${S})`),null)}return null}s(qt,"pickAnchorElement");function cn(h){let d=V(h.getAttribute("data-testid"))??V(h.getAttribute("data-test-id"))??V(h.getAttribute("data-test"))??null;if(d)return`[data-testid='${d.replace(/'/g,"\\'")}']`;let S=V(h.getAttribute("data-selector"))??null;if(S)return`[data-selector='${S.replace(/'/g,"\\'")}']`;if(h.id)try{return`#${CSS.escape(h.id)}`}catch{return`#${h.id}`}return h.tagName.toLowerCase()}s(cn,"selectorHintFor");function mt(h,d){let S=V(h.getAttribute("aria-label"))??null;if(S)return S.slice(0,d);let E=String(h.innerText??h.textContent??"").trim();return E?E.slice(0,d):null}s(mt,"textPreviewFor");function $t(h){let d=h.getBoundingClientRect(),S=getComputedStyle(h),E=S.display!=="none"&&S.visibility!=="hidden"&&parseFloat(S.opacity||"1")>0&&d.width>0&&d.height>0,k=window.innerWidth,z=window.innerHeight,se=d.right>0&&d.bottom>0&&d.left<k&&d.top<z,ye=Number.isFinite(d.x)&&Number.isFinite(d.y)&&Number.isFinite(d.width)&&Number.isFinite(d.height)?{x:d.x,y:d.y,width:d.width,height:d.height}:null,Fe=d.left+d.width/2,Te=d.top+d.height/2;return{boundingBox:ye,isVisible:E,isInViewport:se,centerX:Fe,centerY:Te}}s($t,"computeRuntime");function Zr(h,d,S,E,k){let z=[],se=new Set,ye=[];h&&ye.push(h);let Fe=new Set;for(;ye.length>0&&!(z.length>=d);){let Te=ye.pop();if(!Te)continue;let tt=Te.alternate??Te;if(Fe.has(tt))continue;if(Fe.add(tt),Le(Te)){let he=Te.stateNode;if(!se.has(he)){se.add(he);let _e=$t(he);if(!(S&&!_e.isVisible)){if(!(E&&!_e.isInViewport)){let nt=he.tagName.toLowerCase(),At=he.id?String(he.id):null,Ke=he.className,ot=typeof Ke=="string"&&Ke.trim()?Ke.trim():null;z.push({tagName:nt,id:At,className:ot,selectorHint:cn(he),textPreview:mt(he,k),boundingBox:_e.boundingBox,isVisible:_e.isVisible,isInViewport:_e.isInViewport})}}}}let yt=Te.child??null,Bt=Te.sibling??null;yt&&ye.push(yt),Bt&&ye.push(Bt)}return z}s(Zr,"collectDomElementsFromFiberSubtree");function jt(h,d,S){let E=d.componentName?d.componentName.trim():void 0,k=!!E,z=d.fileNameHint?d.fileNameHint.trim():void 0,se=!!z,ye=typeof d.lineNumber=="number";if(!(k||se||ye))return[];let Te=[];for(let he of h){let _e=Rt(he);_e&&Te.push(_e)}let tt=new Set,yt=[],Bt=0;for(;Te.length>0&&!(yt.length>=S);){let he=Te.pop();if(!he)continue;let _e=he.alternate??he;if(tt.has(_e))continue;if(tt.add(_e),Bt++,Bt>te){v.push(`Fiber traversal safety cap reached (${te}). Results may be incomplete.`);break}let nt=Ce(he),At=J(he),Ke=k?Wt(nt,E,d.matchStrategy)||Wt(At,E,d.matchStrategy):!0,ot=se||ye?ct(he,z,d.lineNumber):!0;Ke&&ot&&yt.push(he);let Lt=he.child??null,Me=he.sibling??null;Lt&&Te.push(Lt),Me&&Te.push(Me)}return yt}s(jt,"findFibersByQuery");function es(h,d,S,E,k,z,se,ye,Fe){let Te=k.componentName?k.componentName.trim():void 0,tt=!!Te,yt=Ce(h),Bt=J(h),he=tt?Wt(yt,Te,k.matchStrategy)||Wt(Bt,Te,k.matchStrategy):!1,_e=V(k.fileNameHint)||typeof k.lineNumber=="number"?ct(h,V(k.fileNameHint)??void 0,typeof k.lineNumber=="number"?k.lineNumber:void 0):!1,nt=Zr(h,z,se,ye,Fe),At=!1,Ke=null;if(d){let Lt=cn(d);if(At=nt.some(Me=>!Me.selectorHint||!Lt?!1:Me.selectorHint===Lt)||nt.some(Me=>{if(!Me.boundingBox)return!1;let $e=d.getBoundingClientRect(),wt=Me.boundingBox;return $e.left<wt.x+wt.width&&$e.left+$e.width>wt.x&&$e.top<wt.y+wt.height&&$e.top+$e.height>wt.y}),typeof S=="number"&&typeof E=="number"&&nt.length>0){let Me=null;for(let $e of nt){if(!$e.boundingBox)continue;let wt=$e.boundingBox.x+$e.boundingBox.width/2,qs=$e.boundingBox.y+$e.boundingBox.height/2,$s=wt-S,js=qs-E,ns=Math.sqrt($s*$s+js*js);(Me===null||ns<Me)&&(Me=ns)}Ke=Me}}let ot=0;if(ot+=he?3:0,ot+=_e?3:0,ot+=At?2:0,ot+=Math.min(1.5,nt.length/25),typeof Ke=="number"&&Number.isFinite(Ke)){let Lt=Math.max(0,Math.min(1,1-Ke/1e3));ot+=1.5*Lt}return{score:ot,nameMatched:he,debugSourceMatched:_e,anchorRelated:At,proximityPx:Ke,dom:nt}}s(es,"scoreCandidate");let kt=X(),_t=!!kt;_t?v.push("React DevTools hook detected. Root discovery will use getFiberRoots() (more reliable)."):(v.push("React DevTools hook was not detected (__REACT_DEVTOOLS_GLOBAL_HOOK__)."),v.push('If you are using a persistent/headful browser profile, install the "React Developer Tools" Chrome extension in that profile (manual step by the user) to enable reliable root discovery and component search.'));let g=(()=>{let h=document.body;return h?!!(q(h)||Ie(1).length>0):!1})();g?v.push("React Fiber pointers detected on DOM nodes. Anchor-based mapping may still work without the DevTools hook (best-effort)."):v.push("No React Fiber pointers were detected on DOM nodes (__reactFiber$...). This can happen if the page is not React, React has not rendered yet, or internals are unavailable.");let C=qt(Q,$,P),I=null;if(C){let h=q(C);if(h){let d=h,S=h.alternate??null,E=d;S&&(S.child||S.sibling)&&!(d.child||d.sibling)&&(E=S);let k=qe(E);k?I=k:v.push("Anchor fiber found but no meaningful component fiber was found above it.")}else v.push("Anchor element found but React fiber was not found on it.")}let R=[],A="none";if(kt){let h=Pe(kt);h.length>0&&(R=h,A="devtools-hook")}if(R.length===0&&g){let h=Ie(10);h.length>0&&(R=h,A="dom-fiber-scan",v.push("Using DOM fiber scan as fallback root discovery (best-effort)."))}let L=!!V(W)||!!V(_)||typeof oe=="number",Z={componentName:V(W)??void 0,matchStrategy:G,fileNameHint:V(_)??void 0,lineNumber:typeof oe=="number"?oe:void 0},ie=[];L&&(R.length>0?ie=jt(R,Z,Math.max(1,Math.floor(ce))):v.push("Query was provided but no roots could be discovered. Provide an anchorSelector/anchorX+anchorY so we can map via DOM fiber pointers."));let de=[];I&&de.push(I);for(let h of ie)de.push(h);let Ee=[],Ge=new Set;for(let h of de){let d=h?.alternate??h;h&&!Ge.has(d)&&(Ge.add(d),Ee.push(h))}if(Ee.length===0)return _t||v.push("No candidates found. Without the DevTools hook, component search may be unreliable unless you provide a strong anchor."),{reactDetected:_t,fiberDetected:g,rootDiscovery:A,component:null,candidates:[],elements:[],notes:[...v,"Failed to select a target component fiber. Provide a better anchor, or ensure React is present and render has happened."]};let Mt=[];for(let h of Ee){let d=es(h,C,$,P,Z,Y,M,ee,ue),S="unknown",E=I?(I.alternate??I)===(h.alternate??h):!1,k=ie.some(tt=>(tt.alternate??tt)===(h.alternate??h));E&&k?S="query+anchor":E?S="anchor":k?S="query":S="unknown";let z=J(h),se=Ce(h),ye=We(h),Fe=un(h,me),Te={name:z,displayName:se,debugSource:ye,componentStack:Fe,selection:S,scoring:{score:d.score,nameMatched:d.nameMatched,debugSourceMatched:d.debugSourceMatched,anchorRelated:d.anchorRelated,proximityPx:d.proximityPx}};Mt.push({fiber:h,meta:Te,dom:d.dom,domFootprintCount:d.dom.length})}Mt.sort((h,d)=>(d.meta.scoring?.score??0)-(h.meta.scoring?.score??0));let mn=Mt[0],Dt=Mt.slice(0,Math.max(1,Math.floor(ce))).map(h=>({...h.meta,domFootprintCount:h.domFootprintCount})),ts=mn.dom;return L&&(Z.fileNameHint||typeof Z.lineNumber=="number")&&(Dt.some(d=>!!(d.debugSource?.fileName||d.debugSource?.lineNumber!==null))||(v.push("debugSource hints were provided, but no _debugSource information was found on matched fibers. This is common in production builds and some dev toolchains."),v.push('React DevTools may still display "Rendered by <file>:<line>" using sourcemaps/stack traces even when fiber._debugSource is null.'))),ts.length>=Y&&v.push(`Element list was truncated at maxElements=${Y}. Increase maxElements if needed.`),ts.length===0&&v.push("No DOM elements were returned for the selected component. It may render no host elements, or filtering (onlyVisible/onlyInViewport) removed them."),!_t&&g?v.push("React DevTools hook was not detected, but DOM fiber pointers were found. Using DOM-fiber scanning and anchor-based mapping (best-effort)."):!_t&&!g&&v.push("React DevTools hook was not detected and no DOM fiber pointers were found. Component-to-DOM mapping is unavailable on this page."),{reactDetected:_t,fiberDetected:g,rootDiscovery:A,component:mn.meta,candidates:Dt,elements:ts,notes:[...v,"Component metadata is best-effort. Wrappers (memo/forwardRef/HOCs), Suspense/Offscreen, and portals may make names/stacks noisy."]}},{anchorSelectorEval:typeof n=="string"&&n.trim()?n.trim():void 0,anchorXEval:typeof r=="number"&&Number.isFinite(r)?Math.floor(r):void 0,anchorYEval:typeof i=="number"&&Number.isFinite(i)?Math.floor(i):void 0,componentNameEval:typeof a=="string"&&a.trim()?a.trim():void 0,matchStrategyEval:l,fileNameHintEval:typeof u=="string"&&u.trim()?u.trim():void 0,lineNumberEval:typeof m=="number"&&Number.isFinite(m)?Math.floor(m):void 0,maxElementsEval:Math.max(1,Math.floor(c)),onlyVisibleEval:!!p,onlyInViewportEval:!!b,textPreviewMaxLengthEval:Math.max(1,Math.floor(f)),maxMatchesEval:Math.max(1,Math.floor(x)),maxRootsScan:vc,maxFibersVisited:Ic,stackLimit:xc})}};var ja=[new rr,new sr];import{z as za}from"zod";var ir=class{static{s(this,"JsInBrowser")}name(){return"run_js-in-browser"}description(){return`
665
664
  Runs custom JavaScript INSIDE the active browser page using Playwright's "page.evaluate()".
666
665
 
667
666
  This code executes in the PAGE CONTEXT (real browser environment):
@@ -679,10 +678,11 @@ Notes:
679
678
  - The code runs in an isolated execution context, but within the page
680
679
  - No direct access to Node.js APIs
681
680
  - Return value must be serializable
682
- `}inputSchema(){return{script:Wa.string().describe("JavaScript code to execute.")}}outputSchema(){return{result:Wa.any().describe(`
681
+ - The script is executed as a function body, so "return" statements are valid and their value is returned to the caller.
682
+ `}inputSchema(){return{script:za.string().describe('JavaScript code to execute. May use "return" to pass a serializable value back; the script runs as a function body.')}}outputSchema(){return{result:za.any().describe(`
683
683
  The result of the evaluation. This value can be of any type, including primitives, arrays, or objects.
684
684
  It represents the direct return value of the JavaScript expression executed in the page context.
685
- The structure and type of this value are not constrained and depend entirely on the evaluated code.`)}}async handle(e,t){return{result:await e.page.evaluate(t.script)}}};import yc from"node:crypto";import $a from"node:vm";import{z as Es}from"zod";var ja=5e3,wc=3e4;function Tc(o){if(o==null||typeof o=="string"||typeof o=="number"||typeof o=="boolean")return o;try{return JSON.parse(JSON.stringify(o))}catch{return String(o)}}s(Tc,"_toJsonSafe");var ir=class{static{s(this,"JsInSandbox")}name(){return"run_js-in-sandbox"}description(){return`
685
+ The structure and type of this value are not constrained and depend entirely on the evaluated code.`)}}async handle(e,t){let n=`(function() { ${t.script} })()`;return{result:await e.page.evaluate(n)}}};import Cc from"node:crypto";import Va from"node:vm";import{z as ks}from"zod";var Ga=5e3,Ec=3e4;function Oc(o){if(o==null||typeof o=="string"||typeof o=="number"||typeof o=="boolean")return o;try{return JSON.parse(JSON.stringify(o))}catch{return String(o)}}s(Oc,"_toJsonSafe");var ar=class{static{s(this,"JsInSandbox")}name(){return"run_js-in-sandbox"}description(){return`
686
686
  Runs custom JavaScript inside a Node.js VM sandbox.
687
687
 
688
688
  This runs on the MCP SERVER (not in the browser).
@@ -707,20 +707,20 @@ NOT available:
707
707
  - globalThis
708
708
 
709
709
  This is NOT a security boundary. Intended for trusted automation logic.
710
- `.trim()}inputSchema(){return{code:Es.string().describe("JavaScript code (async allowed)."),timeoutMs:Es.number().int().min(0).max(wc).optional().default(ja).describe("Max VM CPU time for synchronous execution in milliseconds.")}}outputSchema(){return{result:Es.any().describe(`
710
+ `.trim()}inputSchema(){return{code:ks.string().describe("JavaScript code (async allowed)."),timeoutMs:ks.number().int().min(0).max(Ec).optional().default(Ga).describe("Max VM CPU time for synchronous execution in milliseconds.")}}outputSchema(){return{result:ks.any().describe(`
711
711
  Return value of the sandboxed code (best-effort JSON-safe).
712
712
  If user returns undefined but logs exist, returns { logs }.
713
- If error occurs, returns { error, logs }.`)}}async handle(e,t){let n=[],r={log:s((...m)=>{n.push({level:"log",message:m.map(c=>String(c)).join(" ")})},"log"),warn:s((...m)=>{n.push({level:"warn",message:m.map(c=>String(c)).join(" ")})},"warn"),error:s((...m)=>{n.push({level:"error",message:m.map(c=>String(c)).join(" ")})},"error")},i=s(async m=>{let c=Math.max(0,Math.floor(m));await new Promise(p=>{setTimeout(()=>p(),c)})},"sleep"),a={page:e.page,console:r,sleep:i,Math,JSON,Number,String,Boolean,Array,Object,Date,RegExp,isFinite,isNaN,parseInt,parseFloat,URL,URLSearchParams,TextEncoder,TextDecoder,structuredClone,crypto:{randomUUID:yc.randomUUID},AbortController,setTimeout,clearTimeout},l=$a.createContext(a),u=`
713
+ If error occurs, returns { error, logs }.`)}}async handle(e,t){let n=[],r={log:s((...m)=>{n.push({level:"log",message:m.map(c=>String(c)).join(" ")})},"log"),warn:s((...m)=>{n.push({level:"warn",message:m.map(c=>String(c)).join(" ")})},"warn"),error:s((...m)=>{n.push({level:"error",message:m.map(c=>String(c)).join(" ")})},"error")},i=s(async m=>{let c=Math.max(0,Math.floor(m));await new Promise(p=>{setTimeout(()=>p(),c)})},"sleep"),a={page:e.page,console:r,sleep:i,Math,JSON,Number,String,Boolean,Array,Object,Date,RegExp,isFinite,isNaN,parseInt,parseFloat,URL,URLSearchParams,TextEncoder,TextDecoder,structuredClone,crypto:{randomUUID:Cc.randomUUID},AbortController,setTimeout,clearTimeout},l=Va.createContext(a),u=`
714
714
  'use strict';
715
715
  (async () => {
716
716
  ${String(t.code??"")}
717
717
  })()
718
- `.trim();try{let c=new $a.Script(u,{filename:"mcp-sandbox.js"}).runInContext(l,{timeout:t.timeoutMs??ja}),p=await Promise.resolve(c);return p===void 0&&n.length>0?{result:{logs:n}}:{result:Tc(p)}}catch(m){return{result:{error:m instanceof Error?m.stack??m.message:String(m),logs:n}}}}};var za=[new sr,new ir];import Sc from"picomatch";var Va=new WeakMap;function rn(o){let e=Va.get(o);if(e)return e;let t={stubs:[],installed:!1};return Va.set(o,t),t}s(rn,"_ensureStore");function Ga(){let o=Date.now(),e=Math.floor(Math.random()*1e6);return`${o.toString(36)}-${e.toString(36)}`}s(Ga,"_nowId");async function xc(o){o<=0||await new Promise(e=>{setTimeout(()=>e(),o)})}s(xc,"_sleep");function Ns(o){return typeof o!="number"||!Number.isFinite(o)||o<=0?-1:Math.floor(o)}s(Ns,"_normalizeTimes");function Ka(o,e){return o===-1?!0:e<o}s(Ka,"_isTimesRemaining");function Xa(o){if(typeof o=="number"&&Number.isFinite(o))return Math.max(0,Math.min(1,o))}s(Xa,"_normalizeChance");function Ic(o){return o===void 0?!0:o<=0?!1:o>=1?!0:Math.random()<o}s(Ic,"_shouldApplyChance");function Ja(o){let e=o.trim();return e?Sc(e,{dot:!0,nocase:!1}):()=>!1}s(Ja,"_compileMatcher");function Cc(o,e){for(let t of o)if(t.enabled&&Ka(t.times,t.usedCount)&&t.matcher(e)&&!(t.kind==="mock_http_response"&&!Ic(t.chance)))return t}s(Cc,"_pickStub");async function vc(o,e){let t=o.request();if(e.usedCount++,e.delayMs>0&&await xc(e.delayMs),e.kind==="mock_http_response"){if(e.action==="abort"){let a=e.abortErrorCode??"failed";await o.abort(a);return}let n=typeof e.status=="number"?e.status:200,r=e.headers??{},i=typeof e.body=="string"?e.body:"";await o.fulfill({status:n,headers:r,body:i});return}else if(e.kind==="intercept_http_request"){let r={headers:{...t.headers(),...e.modifications.headers??{}}};typeof e.modifications.method=="string"&&e.modifications.method.trim()&&(r.method=e.modifications.method.trim().toUpperCase()),typeof e.modifications.body=="string"&&(r.postData=e.modifications.body),await o.continue(r);return}await o.continue()}s(vc,"_applyStub");async function ar(o){let e=rn(o);e.installed||(await o.route("**/*",async t=>{let n=t.request().url(),r=rn(o),i=Cc(r.stubs,n);if(!i){await t.continue();return}try{await vc(t,i)}finally{Ka(i.times,i.usedCount)||(r.stubs=r.stubs.filter(a=>a.id!==i.id))}}),e.installed=!0)}s(ar,"ensureRoutingInstalled");function Ya(o,e){let t=rn(o),n={...e,kind:"mock_http_response",id:Ga(),usedCount:0,matcher:Ja(e.pattern),times:Ns(e.times),delayMs:Math.max(0,Math.floor(e.delayMs)),chance:Xa(e.chance)};return t.stubs.push(n),n}s(Ya,"addMockHttpResponseStub");function Qa(o,e){let t=rn(o),n={...e,kind:"intercept_http_request",id:Ga(),usedCount:0,matcher:Ja(e.pattern),times:Ns(e.times),delayMs:Math.max(0,Math.floor(e.delayMs))};return t.stubs.push(n),n}s(Qa,"addHttpInterceptRequestStub");function Za(o,e){let t=rn(o);if(!e){let r=t.stubs.length;return t.stubs=[],r}let n=t.stubs.length;return t.stubs=t.stubs.filter(r=>r.id!==e),n-t.stubs.length}s(Za,"clearStub");function el(o){return[...rn(o).stubs]}s(el,"listStubs");function lr(o){return typeof o!="number"||!Number.isFinite(o)||o<=0?0:Math.floor(o)}s(lr,"normalizeDelayMs");function ur(o){return Ns(o)}s(ur,"normalizeTimesPublic");function cr(o){if(!o)return;let e={};for(let[t,n]of Object.entries(o))e[String(t)]=String(n);return e}s(cr,"normalizeHeaders");function mr(o){if(typeof o=="string")return o;if(o&&typeof o=="object")return JSON.stringify(o)}s(mr,"normalizeBody");function tl(o){if(typeof o!="string")return;let e=o.trim();if(e)return e}s(tl,"normalizeAbortCode");function nl(o){if(typeof o!="string")return;let e=o.trim();if(e)return e.toUpperCase()}s(nl,"normalizeMethod");function ol(o){return Xa(o)}s(ol,"normalizeChance");import{z as rl}from"zod";var pr=class{static{s(this,"Clear")}name(){return"stub_clear"}description(){return`
718
+ `.trim();try{let c=new Va.Script(u,{filename:"mcp-sandbox.js"}).runInContext(l,{timeout:t.timeoutMs??Ga}),p=await Promise.resolve(c);return p===void 0&&n.length>0?{result:{logs:n}}:{result:Oc(p)}}catch(m){return{result:{error:m instanceof Error?m.stack??m.message:String(m),logs:n}}}}};var Ka=[new ir,new ar];import Nc from"picomatch";var Xa=new WeakMap;function sn(o){let e=Xa.get(o);if(e)return e;let t={stubs:[],installed:!1};return Xa.set(o,t),t}s(sn,"_ensureStore");function Ya(){let o=Date.now(),e=Math.floor(Math.random()*1e6);return`${o.toString(36)}-${e.toString(36)}`}s(Ya,"_nowId");async function Pc(o){o<=0||await new Promise(e=>{setTimeout(()=>e(),o)})}s(Pc,"_sleep");function _s(o){return typeof o!="number"||!Number.isFinite(o)||o<=0?-1:Math.floor(o)}s(_s,"_normalizeTimes");function Ja(o,e){return o===-1?!0:e<o}s(Ja,"_isTimesRemaining");function Qa(o){if(typeof o=="number"&&Number.isFinite(o))return Math.max(0,Math.min(1,o))}s(Qa,"_normalizeChance");function Rc(o){return o===void 0?!0:o<=0?!1:o>=1?!0:Math.random()<o}s(Rc,"_shouldApplyChance");function Za(o){let e=o.trim();return e?Nc(e,{dot:!0,nocase:!1}):()=>!1}s(Za,"_compileMatcher");function kc(o,e){for(let t of o)if(t.enabled&&Ja(t.times,t.usedCount)&&t.matcher(e)&&!(t.kind==="mock_http_response"&&!Rc(t.chance)))return t}s(kc,"_pickStub");async function _c(o,e){let t=o.request();if(e.usedCount++,e.delayMs>0&&await Pc(e.delayMs),e.kind==="mock_http_response"){if(e.action==="abort"){let a=e.abortErrorCode??"failed";await o.abort(a);return}let n=typeof e.status=="number"?e.status:200,r=e.headers??{},i=typeof e.body=="string"?e.body:"";await o.fulfill({status:n,headers:r,body:i});return}else if(e.kind==="intercept_http_request"){let r={headers:{...t.headers(),...e.modifications.headers??{}}};typeof e.modifications.method=="string"&&e.modifications.method.trim()&&(r.method=e.modifications.method.trim().toUpperCase()),typeof e.modifications.body=="string"&&(r.postData=e.modifications.body),await o.continue(r);return}await o.continue()}s(_c,"_applyStub");async function lr(o){let e=sn(o);e.installed||(await o.route("**/*",async t=>{let n=t.request().url(),r=sn(o),i=kc(r.stubs,n);if(!i){await t.continue();return}try{await _c(t,i)}finally{Ja(i.times,i.usedCount)||(r.stubs=r.stubs.filter(a=>a.id!==i.id))}}),e.installed=!0)}s(lr,"ensureRoutingInstalled");function el(o,e){let t=sn(o),n={...e,kind:"mock_http_response",id:Ya(),usedCount:0,matcher:Za(e.pattern),times:_s(e.times),delayMs:Math.max(0,Math.floor(e.delayMs)),chance:Qa(e.chance)};return t.stubs.push(n),n}s(el,"addMockHttpResponseStub");function tl(o,e){let t=sn(o),n={...e,kind:"intercept_http_request",id:Ya(),usedCount:0,matcher:Za(e.pattern),times:_s(e.times),delayMs:Math.max(0,Math.floor(e.delayMs))};return t.stubs.push(n),n}s(tl,"addHttpInterceptRequestStub");function nl(o,e){let t=sn(o);if(!e){let r=t.stubs.length;return t.stubs=[],r}let n=t.stubs.length;return t.stubs=t.stubs.filter(r=>r.id!==e),n-t.stubs.length}s(nl,"clearStub");function ol(o){return[...sn(o).stubs]}s(ol,"listStubs");function ur(o){return typeof o!="number"||!Number.isFinite(o)||o<=0?0:Math.floor(o)}s(ur,"normalizeDelayMs");function cr(o){return _s(o)}s(cr,"normalizeTimesPublic");function mr(o){if(!o)return;let e={};for(let[t,n]of Object.entries(o))e[String(t)]=String(n);return e}s(mr,"normalizeHeaders");function pr(o){if(typeof o=="string")return o;if(o&&typeof o=="object")return JSON.stringify(o)}s(pr,"normalizeBody");function rl(o){if(typeof o!="string")return;let e=o.trim();if(e)return e}s(rl,"normalizeAbortCode");function sl(o){if(typeof o!="string")return;let e=o.trim();if(e)return e.toUpperCase()}s(sl,"normalizeMethod");function il(o){return Qa(o)}s(il,"normalizeChance");import{z as al}from"zod";var dr=class{static{s(this,"Clear")}name(){return"stub_clear"}description(){return`
719
719
  Clears stubs installed.
720
720
 
721
721
  - If stubId is provided, clears only that stub.
722
722
  - If stubId is omitted, clears all stubs for the current session/context.
723
- `.trim()}inputSchema(){return{stubId:rl.string().optional().describe("Stub id to remove. Omit to remove all stubs.")}}outputSchema(){return{clearedCount:rl.number().int().nonnegative().describe("Number of stubs removed.")}}async handle(e,t){return{clearedCount:Za(e.browserContext,t.stubId)}}};import{z as we}from"zod";var dr=class{static{s(this,"InterceptHttpRequest")}name(){return"stub_intercept-http-request"}description(){return`
723
+ `.trim()}inputSchema(){return{stubId:al.string().optional().describe("Stub id to remove. Omit to remove all stubs.")}}outputSchema(){return{clearedCount:al.number().int().nonnegative().describe("Number of stubs removed.")}}async handle(e,t){return{clearedCount:nl(e.browserContext,t.stubId)}}};import{z as Se}from"zod";var br=class{static{s(this,"InterceptHttpRequest")}name(){return"stub_intercept-http-request"}description(){return`
724
724
  Installs a request interceptor stub that can modify outgoing requests before they are sent.
725
725
 
726
726
  Use cases:
@@ -733,10 +733,10 @@ Notes:
733
733
  - pattern is a glob matched against the full request URL (picomatch).
734
734
  - This modifies requests; it does not change responses.
735
735
  - times limits how many times the interceptor applies (-1 means infinite).
736
- `.trim()}inputSchema(){return{pattern:we.string().describe("Glob pattern matched against the full request URL (picomatch)."),modifications:we.object({headers:we.record(we.string(),we.string()).optional().describe("Headers to merge into the outgoing request headers."),body:we.union([we.string(),we.record(we.string(),we.any()),we.array(we.any())]).optional().describe("Override request body. If object/array, it will be JSON-stringified."),method:we.string().optional().describe("Override HTTP method (e.g., POST, PUT).")}).optional().describe("Request modifications to apply."),delayMs:we.number().int().nonnegative().optional().describe("Artificial delay in milliseconds before continuing the request."),times:we.number().int().optional().describe("Apply only N times, then let through. Omit for infinite.")}}outputSchema(){return{stubId:we.string().describe("Unique id of the installed stub."),kind:we.literal("intercept_http_request").describe("Stub kind."),pattern:we.string().describe("Glob pattern."),enabled:we.boolean().describe("Whether the stub is enabled."),delayMs:we.number().int().describe("Applied artificial delay in milliseconds."),times:we.number().int().describe("Max applications (-1 means infinite).")}}async handle(e,t){await ar(e.browserContext);let n=lr(t.delayMs),r=ur(t.times),i=cr(t.modifications?.headers),a=mr(t.modifications?.body),l=nl(t.modifications?.method),u=Qa(e.browserContext,{enabled:!0,pattern:t.pattern,modifications:{headers:i,body:a,method:l},delayMs:n,times:r});return{stubId:u.id,kind:"intercept_http_request",pattern:u.pattern,enabled:u.enabled,delayMs:u.delayMs,times:u.times}}};import{z as Ye}from"zod";var br=class{static{s(this,"List")}name(){return"stub_list"}description(){return`
736
+ `.trim()}inputSchema(){return{pattern:Se.string().describe("Glob pattern matched against the full request URL (picomatch)."),modifications:Se.object({headers:Se.record(Se.string(),Se.string()).optional().describe("Headers to merge into the outgoing request headers."),body:Se.union([Se.string(),Se.record(Se.string(),Se.any()),Se.array(Se.any())]).optional().describe("Override request body. If object/array, it will be JSON-stringified."),method:Se.string().optional().describe("Override HTTP method (e.g., POST, PUT).")}).optional().describe("Request modifications to apply."),delayMs:Se.number().int().nonnegative().optional().describe("Artificial delay in milliseconds before continuing the request."),times:Se.number().int().optional().describe("Apply only N times, then let through. Omit for infinite.")}}outputSchema(){return{stubId:Se.string().describe("Unique id of the installed stub."),kind:Se.literal("intercept_http_request").describe("Stub kind."),pattern:Se.string().describe("Glob pattern."),enabled:Se.boolean().describe("Whether the stub is enabled."),delayMs:Se.number().int().describe("Applied artificial delay in milliseconds."),times:Se.number().int().describe("Max applications (-1 means infinite).")}}async handle(e,t){await lr(e.browserContext);let n=ur(t.delayMs),r=cr(t.times),i=mr(t.modifications?.headers),a=pr(t.modifications?.body),l=sl(t.modifications?.method),u=tl(e.browserContext,{enabled:!0,pattern:t.pattern,modifications:{headers:i,body:a,method:l},delayMs:n,times:r});return{stubId:u.id,kind:"intercept_http_request",pattern:u.pattern,enabled:u.enabled,delayMs:u.delayMs,times:u.times}}};import{z as Qe}from"zod";var hr=class{static{s(this,"List")}name(){return"stub_list"}description(){return`
737
737
  Lists currently installed stubs for the active browser context/session.
738
738
  Useful to debug why certain calls are being mocked/intercepted.
739
- `.trim()}inputSchema(){return{}}outputSchema(){return{stubs:Ye.array(Ye.object({id:Ye.string().describe("Stub id."),kind:Ye.string().describe("Stub kind."),enabled:Ye.boolean().describe("Whether stub is enabled."),pattern:Ye.string().describe("Glob pattern (picomatch)."),delayMs:Ye.number().int().describe("Artificial delay in ms."),times:Ye.number().int().describe("Max applications (-1 means infinite)."),usedCount:Ye.number().int().describe("How many times it has been applied."),action:Ye.string().optional().describe("For mock_response: fulfill/abort."),status:Ye.number().int().optional().describe("For mock_response: HTTP status (if set).")}))}}async handle(e,t){return{stubs:el(e.browserContext).map(r=>{let i={id:r.id,kind:r.kind,enabled:r.enabled,pattern:r.pattern,delayMs:r.delayMs,times:r.times,usedCount:r.usedCount};return r.kind==="mock_http_response"&&(i.action=r.action,typeof r.status=="number"&&(i.status=r.status)),i})}}};import{z as le}from"zod";var gr=class{static{s(this,"MockHttpResponse")}name(){return"stub_mock-http-response"}description(){return`
739
+ `.trim()}inputSchema(){return{}}outputSchema(){return{stubs:Qe.array(Qe.object({id:Qe.string().describe("Stub id."),kind:Qe.string().describe("Stub kind."),enabled:Qe.boolean().describe("Whether stub is enabled."),pattern:Qe.string().describe("Glob pattern (picomatch)."),delayMs:Qe.number().int().describe("Artificial delay in ms."),times:Qe.number().int().describe("Max applications (-1 means infinite)."),usedCount:Qe.number().int().describe("How many times it has been applied."),action:Qe.string().optional().describe("For mock_response: fulfill/abort."),status:Qe.number().int().optional().describe("For mock_response: HTTP status (if set).")}))}}async handle(e,t){return{stubs:ol(e.browserContext).map(r=>{let i={id:r.id,kind:r.kind,enabled:r.enabled,pattern:r.pattern,delayMs:r.delayMs,times:r.times,usedCount:r.usedCount};return r.kind==="mock_http_response"&&(i.action=r.action,typeof r.status=="number"&&(i.status=r.status)),i})}}};import{z as le}from"zod";var gr=class{static{s(this,"MockHttpResponse")}name(){return"stub_mock-http-response"}description(){return`
740
740
  Installs a response stub for matching requests using glob patterns (picomatch).
741
741
 
742
742
  Use cases:
@@ -750,7 +750,7 @@ Notes:
750
750
  - pattern is a glob matched against the full request URL.
751
751
  - stubs are evaluated in insertion order; first match wins.
752
752
  - times limits how many times the stub applies (-1 means infinite).
753
- `.trim()}inputSchema(){return{pattern:le.string().describe("Glob pattern matched against the full request URL (picomatch)."),response:le.object({action:le.enum(["fulfill","abort"]).optional().default("fulfill").describe("Fulfill with a mocked response or abort the request."),status:le.number().int().min(100).max(599).optional().describe("HTTP status code (used when action=fulfill)."),headers:le.record(le.string(),le.string()).optional().describe("HTTP headers for the mocked response."),body:le.union([le.string(),le.record(le.string(),le.any()),le.array(le.any())]).optional().describe("Response body. If object/array, it will be JSON-stringified."),abortErrorCode:le.string().optional().describe('Playwright abort error code (used when action=abort), e.g. "timedout".')}).describe("Mock response configuration."),delayMs:le.number().int().nonnegative().optional().describe("Artificial delay in milliseconds before applying the stub."),times:le.number().int().optional().describe("Apply only N times, then let through. Omit for infinite."),chance:le.number().min(0).max(1).optional().describe("Probability (0..1) to apply the stub per request (flaky testing).")}}outputSchema(){return{stubId:le.string().describe("Unique id of the installed stub (use it to clear later)."),kind:le.literal("mock_http_response").describe("Stub kind."),pattern:le.string().describe("Glob pattern."),enabled:le.boolean().describe("Whether the stub is enabled."),delayMs:le.number().int().describe("Applied artificial delay in milliseconds."),times:le.number().int().describe("Max applications (-1 means infinite)."),chance:le.number().optional().describe("Apply probability (omit means always)."),action:le.enum(["fulfill","abort"]).describe("Applied action."),status:le.number().int().optional().describe("HTTP status (present when action=fulfill).")}}async handle(e,t){await ar(e.browserContext);let n=t.response.action??"fulfill",r=lr(t.delayMs),i=ur(t.times),a=ol(t.chance),l=t.response.status,u=cr(t.response.headers),m=mr(t.response.body),c=tl(t.response.abortErrorCode),p=Ya(e.browserContext,{enabled:!0,pattern:t.pattern,action:n,status:l,headers:u,body:m,abortErrorCode:c,delayMs:r,times:i,chance:a}),b={stubId:p.id,kind:"mock_http_response",pattern:p.pattern,enabled:p.enabled,delayMs:p.delayMs,times:p.times,action:p.action};return typeof p.chance=="number"&&(b.chance=p.chance),p.action==="fulfill"&&(b.status=typeof p.status=="number"?p.status:200),b}};var sl=[new pr,new dr,new br,new gr];import{z as Qe}from"zod";var il=3e4,al=500,ll=0,ul=50,hr=class{static{s(this,"WaitForNetworkIdle")}name(){return"sync_wait-for-network-idle"}description(){return`
753
+ `.trim()}inputSchema(){return{pattern:le.string().describe("Glob pattern matched against the full request URL (picomatch)."),response:le.object({action:le.enum(["fulfill","abort"]).optional().default("fulfill").describe("Fulfill with a mocked response or abort the request."),status:le.number().int().min(100).max(599).optional().describe("HTTP status code (used when action=fulfill)."),headers:le.record(le.string(),le.string()).optional().describe("HTTP headers for the mocked response."),body:le.union([le.string(),le.record(le.string(),le.any()),le.array(le.any())]).optional().describe("Response body. If object/array, it will be JSON-stringified."),abortErrorCode:le.string().optional().describe('Playwright abort error code (used when action=abort), e.g. "timedout".')}).describe("Mock response configuration."),delayMs:le.number().int().nonnegative().optional().describe("Artificial delay in milliseconds before applying the stub."),times:le.number().int().optional().describe("Apply only N times, then let through. Omit for infinite."),chance:le.number().min(0).max(1).optional().describe("Probability (0..1) to apply the stub per request (flaky testing).")}}outputSchema(){return{stubId:le.string().describe("Unique id of the installed stub (use it to clear later)."),kind:le.literal("mock_http_response").describe("Stub kind."),pattern:le.string().describe("Glob pattern."),enabled:le.boolean().describe("Whether the stub is enabled."),delayMs:le.number().int().describe("Applied artificial delay in milliseconds."),times:le.number().int().describe("Max applications (-1 means infinite)."),chance:le.number().optional().describe("Apply probability (omit means always)."),action:le.enum(["fulfill","abort"]).describe("Applied action."),status:le.number().int().optional().describe("HTTP status (present when action=fulfill).")}}async handle(e,t){await lr(e.browserContext);let n=t.response.action??"fulfill",r=ur(t.delayMs),i=cr(t.times),a=il(t.chance),l=t.response.status,u=mr(t.response.headers),m=pr(t.response.body),c=rl(t.response.abortErrorCode),p=el(e.browserContext,{enabled:!0,pattern:t.pattern,action:n,status:l,headers:u,body:m,abortErrorCode:c,delayMs:r,times:i,chance:a}),b={stubId:p.id,kind:"mock_http_response",pattern:p.pattern,enabled:p.enabled,delayMs:p.delayMs,times:p.times,action:p.action};return typeof p.chance=="number"&&(b.chance=p.chance),p.action==="fulfill"&&(b.status=typeof p.status=="number"?p.status:200),b}};var ll=[new dr,new br,new hr,new gr];import{z as Ze}from"zod";var ul=3e4,cl=500,ml=0,pl=50,fr=class{static{s(this,"WaitForNetworkIdle")}name(){return"sync_wait-for-network-idle"}description(){return`
754
754
  Waits until the page reaches a network-idle condition based on the session's tracked in-flight request count.
755
755
 
756
756
  Definition:
@@ -766,15 +766,15 @@ Notes:
766
766
  - This tool does NOT rely on window globals or page-injected counters.
767
767
  - It uses server-side tracking, so it works reliably even with strict CSP.
768
768
  - If the page has long-polling or never-ending requests, increase maxConnections or accept a shorter idleTimeMs.
769
- `.trim()}inputSchema(){return{timeoutMs:Qe.number().int().min(0).optional().default(il).describe("Maximum time to wait before failing (milliseconds).."),idleTimeMs:Qe.number().int().min(0).optional().default(al).describe("How long the network must stay idle continuously before resolving (milliseconds)."),maxConnections:Qe.number().int().min(0).optional().default(ll).describe("Idle threshold. Network is considered idle when in-flight requests <= maxConnections."),pollIntervalMs:Qe.number().int().min(10).optional().default(ul).describe("Polling interval used to sample the in-flight request count (milliseconds).")}}outputSchema(){return{waitedMs:Qe.number().int().nonnegative().describe("Total time waited until the network became idle or the tool timed out (milliseconds)."),idleTimeMs:Qe.number().int().nonnegative().describe("Idle duration required for success (milliseconds)."),timeoutMs:Qe.number().int().nonnegative().describe("Maximum allowed wait time (milliseconds)."),maxConnections:Qe.number().int().nonnegative().describe("Idle threshold used: in-flight requests must be <= this value."),pollIntervalMs:Qe.number().int().nonnegative().describe("Polling interval used to sample the in-flight request count (milliseconds)."),finalInFlightRequests:Qe.number().int().nonnegative().describe("The last observed number of in-flight requests at the moment the tool returned."),observedIdleMs:Qe.number().int().nonnegative().describe("How long the in-flight request count stayed <= maxConnections right before returning (milliseconds).")}}async handle(e,t){let n=t.timeoutMs??il,r=t.idleTimeMs??al,i=t.maxConnections??ll,a=t.pollIntervalMs??ul,l=Date.now(),u=l+n,m=l,c=0;for(;;){let p=Date.now();c=e.numOfInFlightRequests(),c>i&&(m=p);let b=p-m;if(b>=r)return{waitedMs:p-l,idleTimeMs:r,timeoutMs:n,maxConnections:i,pollIntervalMs:a,finalInFlightRequests:c,observedIdleMs:b};if(p>=u){let T=p-l;throw new Error(`Timed out after ${T}ms waiting for network idle (idleTimeMs=${r}, maxConnections=${i}, inFlight=${c}).`)}await this.sleep(a)}}async sleep(e){await new Promise(t=>{setTimeout(()=>t(),e)})}};var cl=[new hr];import Ec from"node:fs";import{chromium as pl,firefox as dl,webkit as bl}from"playwright";var Nc="chromium",ml=new Map,fr=new Map;function Pc(o){return JSON.stringify(o)}s(Pc,"_browserKey");function Rc(o){let e={headless:o.headless,executablePath:o.executablePath,handleSIGINT:!1,handleSIGTERM:!1};if(o.useInstalledOnSystem)if(o.browserType==="chromium")e.channel="chrome",e.args=["--disable-blink-features=AutomationControlled"],e.ignoreDefaultArgs=["--disable-extensions"];else throw new Error(`Browser type ${o.browserType} is not supported to be used from the one installed on the system`);return e}s(Rc,"_browserLaunchOptions");async function kc(o){let e;switch(o.browserType){case"firefox":e=dl;break;case"webkit":e=bl;break;default:e=pl;break}return e.launch(Rc(o))}s(kc,"_createBrowser");async function _c(o){let e=Pc(o),t=ml.get(e);if(t&&!t.isConnected()){try{await t.close().catch(()=>{})}catch{}t=void 0}return t||(t=await kc(o),ml.set(e,t)),t}s(_c,"_getBrowser");function Mc(o){return o.persistent.userDataDir}s(Mc,"_persistentBrowserContextKey");function Dc(o){let e=o.browserOptions,t={headless:e.headless,executablePath:e.executablePath,bypassCSP:!0,viewport:e.headless?void 0:null,locale:o.locale};if(e.useInstalledOnSystem)if(e.browserType==="chromium")t.channel="chrome",t.args=["--disable-blink-features=AutomationControlled"],t.ignoreDefaultArgs=["--disable-extensions"];else throw new Error(`Browser type ${e.browserType} is not supported to be used from the one installed on the system`);return t}s(Dc,"_persistentBrowserContextLaunchOptions");async function Bc(o){let e;switch(o.browserOptions.browserType){case"firefox":e=dl;break;case"webkit":e=bl;break;default:e=pl;break}let t=o.persistent.userDataDir;Ec.mkdirSync(t,{recursive:!0});let n=await e.launchPersistentContext(t,Dc(o));for(let r of n.pages())try{await r.close()}catch{}return n}s(Bc,"_createPersistentBrowserContext");async function Ac(o){let e=Mc(o),t=fr.get(e);if(t&&!t.browser()?.isConnected()){try{await t.close().catch(()=>{})}catch{}t=void 0}if(!t)t=await Bc(o),fr.set(e,t);else throw new Error(`There is already active persistent browser context in the user data directory: ${o.persistent?.userDataDir}`);return t}s(Ac,"_getPersistentBrowserContext");async function gl(o={browserOptions:{browserType:Nc,headless:zt,executablePath:En,useInstalledOnSystem:Kt},persistent:Vt?{userDataDir:Gt}:void 0,locale:Nn}){return o.persistent?{browserContext:await Ac(o)}:{browserContext:await(await _c(o.browserOptions)).newContext({viewport:o.browserOptions.headless?void 0:null,bypassCSP:!0,locale:o.locale})}}s(gl,"newBrowserContext");async function hl(o,e={}){return await o.newPage()}s(hl,"newPage");async function fl(o){await o.close();let e=!1;for(let[t,n]of fr.entries())o===n&&(fr.delete(t),e=!0);return e}s(fl,"closeBrowserContext");function Lc(o){let e=o.trim();return e.startsWith("/")||(e="/"+e),e.endsWith("/")||(e=e+"/"),e}s(Lc,"_normalizeBasePath");function Fc(o){let e=o.trim();return e&&(e.endsWith("/")?e.slice(0,-1):e)}s(Fc,"_normalizeUpstreamBaseUrl");function Uc(o,e){try{let n=new URL(o).pathname;if(!n.startsWith(e))return null;let r=n.slice(e.length);return r?r.startsWith("/")?r:"/"+r:null}catch{return null}}s(Uc,"_computeSuffixPath");function Hc(o,e,t){try{let r=new URL(t).search??"";return o+e+r}catch{return o+e}}s(Hc,"_appendSuffixToUpstream");var yr=class{static{s(this,"OTELProxy")}config;queue;workers;isRunning;isInstalled;metrics;constructor(e){let t=e.maxQueueSize??200,n=e.concurrency??2,r=e.respondNoContent??!0,i=Lc(e.localPath),a=Fc(e.upstreamUrl);this.config={...e,localPath:i,upstreamUrl:a,maxQueueSize:t,concurrency:n,respondNoContent:r},this.queue=[],this.workers=[],this.isRunning=!1,this.isInstalled=!1,this.metrics={routedRequests:0,acceptedBatches:0,droppedBatches:0,forwardedBatches:0,failedBatches:0,inFlight:0,queueSize:0,lastError:null}}getMetrics(){return{...this.metrics,queueSize:this.queue.length}}async install(e){if(this.isInstalled)return;let t=this.config.localPath;if(!t.startsWith("/"))throw new Error('localPath must start with "/" (e.g. "/__mcp_otel/").');let n=`**${t}**`;await e.route(n,async r=>{await this._handleRoute(r)}),this.isInstalled=!0,this.isRunning||await this.start(),G(`[otel-proxy] installed route pattern: ${n} (basePath=${t}, upstreamBase=${this.config.upstreamUrl})`)}async uninstall(e){if(!this.isInstalled)return;let t=`**${this.config.localPath}**`;try{await e.unroute(t)}catch{}this.isInstalled=!1,await this.stop()}async start(){if(this.isRunning)return;this.isRunning=!0;let e=Math.max(1,this.config.concurrency);for(let t=0;t<e;t++){let n=this._workerLoop(t);this.workers.push(n)}G(`[otel-proxy] started with concurrency=${e}, maxQueueSize=${this.config.maxQueueSize}`)}async stop(){if(this.isRunning){this.isRunning=!1,this.queue.length=0;try{await Promise.allSettled(this.workers)}finally{this.workers.length=0}G("[otel-proxy] stopped")}}async _handleRoute(e){let t=e.request();if(this.metrics.routedRequests++,t.method().toUpperCase()==="OPTIONS"){await this._fulfillFast(e);return}if(this.config.shouldForward&&!this.config.shouldForward(t)){await this._fulfillFast(e);return}let n=t.url(),r=this.config.localPath,i=Uc(n,r);if(!i){await e.fallback();return}let a=Hc(this.config.upstreamUrl,i,n),u=await t.postDataBuffer()??Buffer.alloc(0),c=t.headers()["content-type"]??"application/x-protobuf",p=t.method(),b={"content-type":c};if(this.config.upstreamHeaders)for(let[k,M]of Object.entries(this.config.upstreamHeaders))b[k]=M;if(this.queue.length>=this.config.maxQueueSize){this.metrics.droppedBatches++,await this._fulfillFast(e),os(`[otel-proxy] dropped batch (queue full: ${this.queue.length}/${this.config.maxQueueSize}) suffix=${i}`);return}let T={body:u,contentType:c,createdAtMs:Date.now(),upstreamUrl:a,method:p,headers:b};this.queue.push(T),this.metrics.acceptedBatches++,await this._fulfillFast(e)}async _fulfillFast(e){let t=this.config.respondNoContent?204:200;if(t===204){await e.fulfill({status:t});return}await e.fulfill({status:t,headers:{"content-type":"text/plain; charset=utf-8"},body:""})}async _workerLoop(e){for(;this.isRunning;){let t=this.queue.shift();if(!t){await this._sleep(25);continue}this.metrics.inFlight++;try{await this._forwardUpstream(t),this.metrics.forwardedBatches++}catch(n){this.metrics.failedBatches++;let r=n instanceof Error?n.message:String(n);this.metrics.lastError=r,os(`[otel-proxy] worker=${e} forward failed: ${r}`)}finally{this.metrics.inFlight--}}}async _forwardUpstream(e){let t=await fetch(e.upstreamUrl,{method:e.method,headers:e.headers,body:new Uint8Array(e.body)});if(t.status<200||t.status>=300){let n=await this._safeReadText(t);throw new Error(`upstream returned ${t.status} for ${e.upstreamUrl}: ${n}`)}}async _safeReadText(e){try{return(await e.text()).slice(0,500)}catch{return""}}async _sleep(e){await new Promise(t=>{setTimeout(()=>t(),e)})}};import*as Sr from"node:fs";import*as Et from"node:path";import{fileURLToPath as qc}from"node:url";var Wc=qc(import.meta.url),$c=Et.dirname(Wc),wr="/__mcp_otel/",jc="otel-initializer.bundle.js";function zc(){return ns?ns:Et.join($c,"platform","browser","otel")}s(zc,"_getOtelAssetsDir");function Vc(){if(pn==="otlp/http"||Rn){if(!Rn)throw new Error('OTEL exporter HTTP url must be set when OTEL exporter type is "otlp/http"');return{type:"otlp/http",url:wr,upstreamURL:Rn,headers:Vs}}else{if(pn==="console")return{type:"console"};if(pn==="none")return{type:"none"};throw new Error(`Invalid OTEL exporter type ${pn}`)}}s(Vc,"_getOTELExporterConfig");function Gc(){return{userInteractionEvents:zs}}s(Gc,"_getOTELInstrumentationConfig");function Kc(){return{serviceName:$s,serviceVersion:js,exporter:Vc(),instrumentation:Gc(),debug:!1}}s(Kc,"_getOTELConfig");function Xc(o,e){let t=Et.isAbsolute(o)?o:Et.join(process.cwd(),o),n=Et.join(t,e);if(!Sr.existsSync(n))throw new Error(`OTEL bundle not found at: ${n}`);return Sr.readFileSync(n,"utf-8")}s(Xc,"_readBundleContent");async function Jc(o,e){await o.evaluate(t=>{let n=globalThis;n.__MCP_DEVTOOLS__||(n.__MCP_DEVTOOLS__={}),n.__MCP_TRACE_ID__=t.traceId,n.__mcpOtel&&typeof n.__mcpOtel.init=="function"?n.__mcpOtel.init(t):(n.__MCP_DEVTOOLS__.otelInitialized=!1,n.__MCP_DEVTOOLS__.otelInitError="__mcpOtel.init is not available while applying config")},e).catch(t=>{let n=t instanceof Error?t.message:String(t);G(`[otel-controller] applyConfigToPage failed (ignored): ${n}`)})}s(Jc,"_applyConfigToPage");function Yc(o,e){let t=new WeakMap,n=s(a=>{if(t.has(a))return;let l=s(async u=>{u===a.mainFrame()&&await Jc(a,e())},"onFrameNavigated");t.set(a,l),a.on("framenavigated",l)},"attachToPage");for(let a of o.pages())n(a);let r=s(a=>{n(a)},"onNewPage");o.on("page",r);let i=s(()=>{try{o.off("page",r)}catch{}for(let a of o.pages()){let l=t.get(a);if(l)try{a.off("framenavigated",l)}catch{}}},"detach");return G("[otel-controller] auto-sync installed (page+framenavigated)"),{detach:i}}s(Yc,"_installAutoSync");var Tr=class{static{s(this,"OTELController")}browserContext;config;proxy;initialized=!1;autoSyncDetach;constructor(e){this.browserContext=e,this.config=Kc()}async init(e){if(this.initialized){G("[otel-controller] init skipped: BrowserContext already initialized");return}if(!e.traceId||!e.traceId.trim())throw new Error("[otel-controller] init requires a non-empty traceId");this.config.traceId=e.traceId;let t=zc();this.config.exporter.type==="otlp/http"&&(this.proxy=new yr({localPath:wr,upstreamUrl:this.config.exporter.upstreamURL,upstreamHeaders:{...this.config.exporter.headers??{}}}),await this.proxy.install(this.browserContext)),G(`[otel-controller] exporter=${this.config.exporter.type} localBase=${wr}`+(this.config.exporter.type==="otlp/http"?` upstreamBase=${this.config.exporter.upstreamURL}`:""));let n=Xc(t,jc),r=Yc(this.browserContext,()=>this.config);this.autoSyncDetach=r.detach,await this.browserContext.addInitScript({content:n}),await this.browserContext.addInitScript(i=>{let a=globalThis;a.__MCP_DEVTOOLS__||(a.__MCP_DEVTOOLS__={}),a.__MCP_TRACE_ID__=i.traceId,a.__mcpOtel&&typeof a.__mcpOtel.init=="function"?a.__mcpOtel.init(i):(a.__MCP_DEVTOOLS__.otelInitialized=!1,a.__MCP_DEVTOOLS__.otelInitError="__mcpOtel.init is not available (initializer bundle did not install)")},this.config),this.initialized=!0,G("[otel-controller] init installed: bundle + config init scripts + auto-sync")}isOTELRequest(e){return new URL(e.url()).pathname.startsWith(wr)}async isInitialized(e){return await e.evaluate(()=>globalThis.__MCP_DEVTOOLS__?.otelInitialized===!0)}async getInitError(e){return await e.evaluate(()=>{let n=globalThis.__MCP_DEVTOOLS__?.otelInitError;if(typeof n=="string"&&n.trim())return n})}async getTraceId(e){return await e.evaluate(()=>{let t=globalThis;if(t.__mcpOtel&&typeof t.__mcpOtel.getTraceId=="function"){let r=t.__mcpOtel.getTraceId();if(typeof r=="string"&&r.trim())return r}let n=t.__MCP_TRACE_ID__;if(typeof n=="string"&&n.trim())return n})}async setTraceId(e,t){this.config.traceId=t,await e.evaluate(n=>{let r=globalThis;r.__mcpOtel&&typeof r.__mcpOtel.setTraceId=="function"?r.__mcpOtel.setTraceId(n):r.__MCP_TRACE_ID__=n},t)}async close(){if(this.autoSyncDetach){try{this.autoSyncDetach()}catch{}this.autoSyncDetach=void 0}this.proxy&&(await this.proxy.uninstall(this.browserContext),this.proxy=void 0)}};var xr=class{static{s(this,"BrowserToolSessionContext")}_sessionId;options;otelController;consoleMessages=[];httpRequests=[];initialized=!1;closed=!1;traceId;_numOfInFlightRequests=0;_lastNetworkActivityTimestamp=0;browserContext;page;constructor(e,t,n,r){this._sessionId=e,this.browserContext=t,this.page=n,this.options=r,this.otelController=new Tr(this.browserContext)}async init(){if(this.closed)throw new Error("Session context is already closed");if(this.initialized)throw new Error("Session context is already initialized");let e=this,t=0;this.page.on("console",r=>{e.consoleMessages.push(e._toConsoleMessage(r,++t)),e.consoleMessages.length>cn&&e.consoleMessages.splice(0,e.consoleMessages.length-cn)}),this.page.on("pageerror",r=>{e.consoleMessages.push(e._errorToConsoleMessage(r,++t)),e.consoleMessages.length>cn&&e.consoleMessages.splice(0,e.consoleMessages.length-cn)});let n=0;this.page.on("request",async r=>{e.otelController.isOTELRequest(r)||(e._numOfInFlightRequests++,e._lastNetworkActivityTimestamp=Date.now())}),this.page.on("requestfinished",async r=>{e.otelController.isOTELRequest(r)||(e._numOfInFlightRequests--,e._lastNetworkActivityTimestamp=Date.now(),e.httpRequests.push(await e._toHttpRequest(r,++n)),e.httpRequests.length>mn&&e.httpRequests.splice(0,e.httpRequests.length-mn))}),this.page.on("requestfailed",async r=>{e.otelController.isOTELRequest(r)||(e._numOfInFlightRequests--,e._lastNetworkActivityTimestamp=Date.now(),e.httpRequests.push(await e._toHttpRequest(r,++n)),e.httpRequests.length>mn&&e.httpRequests.splice(0,e.httpRequests.length-mn))}),this.options.otelEnable&&(this.traceId=er(),await this.otelController.init({traceId:this.traceId})),this.initialized=!0}_toConsoleMessageLevelName(e){switch(e){case"assert":case"error":return"error";case"warning":return"warning";case"count":case"dir":case"dirxml":case"info":case"log":case"table":case"time":case"timeEnd":return"info";case"clear":case"debug":case"endGroup":case"profile":case"profileEnd":case"startGroup":case"startGroupCollapsed":case"trace":return"debug";default:return"info"}}_toConsoleMessage(e,t){let n=Date.now(),r=this._toConsoleMessageLevelName(e.type()),i=Jt[r].code;return{type:e.type(),text:e.text(),level:{name:r,code:i},location:{url:e.location().url,lineNumber:e.location().lineNumber,columnNumber:e.location().columnNumber},timestamp:n,sequenceNumber:t}}_errorToConsoleMessage(e,t){let n=Date.now();return e instanceof Error?{type:"error",text:e.message,level:{name:"error",code:3},timestamp:n,sequenceNumber:t}:{type:"error",text:String(e),level:{name:"error",code:3},timestamp:n,sequenceNumber:t}}_isBodyLikelyPresent(e,t){return!(t==="HEAD"||t==="OPTIONS"||e===204||e===304||e>=300&&e<400)}async _safeReadResponseBody(e){try{let n=e.request().method(),r=e.status();return this._isBodyLikelyPresent(r,n)?(await e.body()).toString("utf-8"):void 0}catch{return}}async _toHttpRequest(e,t){let n=await e.response();return{url:e.url(),method:e.method(),headers:e.headers(),body:e.postData()||void 0,resourceType:e.resourceType(),failure:e.failure()?.errorText,duration:e.timing().responseEnd,response:n?{status:n.status(),statusText:n.statusText(),headers:n.headers(),body:await this._safeReadResponseBody(n)}:void 0,ok:n?n.ok():!1,timestamp:Math.floor(e.timing().startTime),sequenceNumber:t}}numOfInFlightRequests(){return this._numOfInFlightRequests}lastNetworkActivityTimestamp(){return this._lastNetworkActivityTimestamp}sessionId(){return this._sessionId}async getTraceId(){return this.traceId}async setTraceId(e){if(!this.options.otelEnable)throw new Error("OTEL is not enabled");this.traceId=e,await this.otelController.setTraceId(this.page,e)}getConsoleMessages(){return this.consoleMessages}getHttpRequests(){return this.httpRequests}async close(){if(this.closed)return!1;G(`Closing OTEL controller of the session with id ${this._sessionId} ...`),await this.otelController.close();try{G(`Closing browser context of the session with id ${this._sessionId} ...`),await fl(this.browserContext)}catch(e){G(`Error occurred while closing browser context of the session with id ${this._sessionId} ...`,e)}return this.consoleMessages.length=0,this.httpRequests.length=0,this.closed=!0,!0}};var Ir=class{static{s(this,"BrowserToolExecutor")}sessionIdProvider;sessionContext;constructor(e){this.sessionIdProvider=e}async _createSessionContext(){let e=await gl(),t=await hl(e.browserContext),n=this.sessionIdProvider(),r=new xr(n,e.browserContext,t,{otelEnable:Ws});return await r.init(),r}async _sessionContext(){return this.sessionContext||(this.sessionContext=await this._createSessionContext(),G(`Created session context on the first tool call for the session with id ${this.sessionContext.sessionId()}`)),this.sessionContext}async executeTool(e,t){G(`Executing tool ${e.name()} with input: ${dn(t)}`);try{let n=await this._sessionContext(),r=await e.handle(n,t);return G(`Executed tool ${e.name()} and got output: ${dn(r)}`),r}catch(n){throw G(`Error occurred while executing ${e.name()}: ${n}`),n}}};var Cr=[...Ii,...Pi,...ta,...Ta,...Na,...Pa,...ka,...qa,...za,...sl,...cl];function yl(o){return new Ir(o)}s(yl,"createToolExecutor");import{Option as qt}from"commander";var Ps=class{static{s(this,"BrowserCliProvider")}platform="browser";cliName="browser-devtools-cli";tools=Cr;sessionDescription="Manage browser sessions";cliExamples=["browser-devtools-cli --no-headless interactive","browser-devtools-cli --persistent --no-headless interactive"];bashCompletionOptions="--headless --no-headless --persistent --no-persistent --user-data-dir --use-system-browser --browser-path";bashCompletionCommands="daemon session tools config completion interactive navigation content interaction a11y accessibility o11y react run stub sync figma debug";zshCompletionOptions=` '--headless[Run in headless mode]' \\
769
+ `.trim()}inputSchema(){return{timeoutMs:Ze.number().int().min(0).optional().default(ul).describe("Maximum time to wait before failing (milliseconds).."),idleTimeMs:Ze.number().int().min(0).optional().default(cl).describe("How long the network must stay idle continuously before resolving (milliseconds)."),maxConnections:Ze.number().int().min(0).optional().default(ml).describe("Idle threshold. Network is considered idle when in-flight requests <= maxConnections."),pollIntervalMs:Ze.number().int().min(10).optional().default(pl).describe("Polling interval used to sample the in-flight request count (milliseconds).")}}outputSchema(){return{waitedMs:Ze.number().int().nonnegative().describe("Total time waited until the network became idle or the tool timed out (milliseconds)."),idleTimeMs:Ze.number().int().nonnegative().describe("Idle duration required for success (milliseconds)."),timeoutMs:Ze.number().int().nonnegative().describe("Maximum allowed wait time (milliseconds)."),maxConnections:Ze.number().int().nonnegative().describe("Idle threshold used: in-flight requests must be <= this value."),pollIntervalMs:Ze.number().int().nonnegative().describe("Polling interval used to sample the in-flight request count (milliseconds)."),finalInFlightRequests:Ze.number().int().nonnegative().describe("The last observed number of in-flight requests at the moment the tool returned."),observedIdleMs:Ze.number().int().nonnegative().describe("How long the in-flight request count stayed <= maxConnections right before returning (milliseconds).")}}async handle(e,t){let n=t.timeoutMs??ul,r=t.idleTimeMs??cl,i=t.maxConnections??ml,a=t.pollIntervalMs??pl,l=Date.now(),u=l+n,m=l,c=0;for(;;){let p=Date.now();c=e.numOfInFlightRequests(),c>i&&(m=p);let b=p-m;if(b>=r)return{waitedMs:p-l,idleTimeMs:r,timeoutMs:n,maxConnections:i,pollIntervalMs:a,finalInFlightRequests:c,observedIdleMs:b};if(p>=u){let f=p-l;throw new Error(`Timed out after ${f}ms waiting for network idle (idleTimeMs=${r}, maxConnections=${i}, inFlight=${c}).`)}await this.sleep(a)}}async sleep(e){await new Promise(t=>{setTimeout(()=>t(),e)})}};var dl=[new fr];import Dc from"node:fs";import{chromium as hl,firefox as gl,webkit as fl}from"playwright";var Bc="chromium",bl=new Map,yr=new Map;function Ac(o){return JSON.stringify(o)}s(Ac,"_browserKey");function Lc(o){let e={headless:o.headless,executablePath:o.executablePath,handleSIGINT:!1,handleSIGTERM:!1};if(o.useInstalledOnSystem)if(o.browserType==="chromium")e.channel="chrome",e.args=["--disable-blink-features=AutomationControlled"],e.ignoreDefaultArgs=["--disable-extensions"];else throw new Error(`Browser type ${o.browserType} is not supported to be used from the one installed on the system`);return e}s(Lc,"_browserLaunchOptions");async function Fc(o){let e;switch(o.browserType){case"firefox":e=gl;break;case"webkit":e=fl;break;default:e=hl;break}return e.launch(Lc(o))}s(Fc,"_createBrowser");async function Uc(o){let e=Ac(o),t=bl.get(e);if(t&&!t.isConnected()){try{await t.close().catch(()=>{})}catch{}t=void 0}return t||(t=await Fc(o),bl.set(e,t)),t}s(Uc,"_getBrowser");function Hc(o){return o.persistent.userDataDir}s(Hc,"_persistentBrowserContextKey");function Wc(o){let e=o.browserOptions,t={headless:e.headless,executablePath:e.executablePath,bypassCSP:!0,viewport:e.headless?void 0:null,locale:o.locale};if(e.useInstalledOnSystem)if(e.browserType==="chromium")t.channel="chrome",t.args=["--disable-blink-features=AutomationControlled"],t.ignoreDefaultArgs=["--disable-extensions"];else throw new Error(`Browser type ${e.browserType} is not supported to be used from the one installed on the system`);return t}s(Wc,"_persistentBrowserContextLaunchOptions");async function qc(o){let e;switch(o.browserOptions.browserType){case"firefox":e=gl;break;case"webkit":e=fl;break;default:e=hl;break}let t=o.persistent.userDataDir;Dc.mkdirSync(t,{recursive:!0});let n=await e.launchPersistentContext(t,Wc(o));for(let r of n.pages())try{await r.close()}catch{}return n}s(qc,"_createPersistentBrowserContext");async function $c(o){let e=Hc(o),t=yr.get(e);if(t&&!t.browser()?.isConnected()){try{await t.close().catch(()=>{})}catch{}t=void 0}if(!t)t=await qc(o),yr.set(e,t);else throw new Error(`There is already active persistent browser context in the user data directory: ${o.persistent?.userDataDir}`);return t}s($c,"_getPersistentBrowserContext");async function yl(o={browserOptions:{browserType:Bc,headless:zt,executablePath:Nn,useInstalledOnSystem:Kt},persistent:Vt?{userDataDir:Gt}:void 0,locale:Pn}){return o.persistent?{browserContext:await $c(o)}:{browserContext:await(await Uc(o.browserOptions)).newContext({viewport:o.browserOptions.headless?void 0:null,bypassCSP:!0,locale:o.locale})}}s(yl,"newBrowserContext");async function wl(o,e={}){return await o.newPage()}s(wl,"newPage");async function Tl(o){await o.close();let e=!1;for(let[t,n]of yr.entries())o===n&&(yr.delete(t),e=!0);return e}s(Tl,"closeBrowserContext");function jc(o){let e=o.trim();return e.startsWith("/")||(e="/"+e),e.endsWith("/")||(e=e+"/"),e}s(jc,"_normalizeBasePath");function zc(o){let e=o.trim();return e&&(e.endsWith("/")?e.slice(0,-1):e)}s(zc,"_normalizeUpstreamBaseUrl");function Vc(o,e){try{let n=new URL(o).pathname;if(!n.startsWith(e))return null;let r=n.slice(e.length);return r?r.startsWith("/")?r:"/"+r:null}catch{return null}}s(Vc,"_computeSuffixPath");function Gc(o,e,t){try{let r=new URL(t).search??"";return o+e+r}catch{return o+e}}s(Gc,"_appendSuffixToUpstream");var wr=class{static{s(this,"OTELProxy")}config;queue;workers;isRunning;isInstalled;metrics;constructor(e){let t=e.maxQueueSize??200,n=e.concurrency??2,r=e.respondNoContent??!0,i=jc(e.localPath),a=zc(e.upstreamUrl);this.config={...e,localPath:i,upstreamUrl:a,maxQueueSize:t,concurrency:n,respondNoContent:r},this.queue=[],this.workers=[],this.isRunning=!1,this.isInstalled=!1,this.metrics={routedRequests:0,acceptedBatches:0,droppedBatches:0,forwardedBatches:0,failedBatches:0,inFlight:0,queueSize:0,lastError:null}}getMetrics(){return{...this.metrics,queueSize:this.queue.length}}async install(e){if(this.isInstalled)return;let t=this.config.localPath;if(!t.startsWith("/"))throw new Error('localPath must start with "/" (e.g. "/__mcp_otel/").');let n=`**${t}**`;await e.route(n,async r=>{await this._handleRoute(r)}),this.isInstalled=!0,this.isRunning||await this.start(),K(`[otel-proxy] installed route pattern: ${n} (basePath=${t}, upstreamBase=${this.config.upstreamUrl})`)}async uninstall(e){if(!this.isInstalled)return;let t=`**${this.config.localPath}**`;try{await e.unroute(t)}catch{}this.isInstalled=!1,await this.stop()}async start(){if(this.isRunning)return;this.isRunning=!0;let e=Math.max(1,this.config.concurrency);for(let t=0;t<e;t++){let n=this._workerLoop(t);this.workers.push(n)}K(`[otel-proxy] started with concurrency=${e}, maxQueueSize=${this.config.maxQueueSize}`)}async stop(){if(this.isRunning){this.isRunning=!1,this.queue.length=0;try{await Promise.allSettled(this.workers)}finally{this.workers.length=0}K("[otel-proxy] stopped")}}async _handleRoute(e){let t=e.request();if(this.metrics.routedRequests++,t.method().toUpperCase()==="OPTIONS"){await this._fulfillFast(e);return}if(this.config.shouldForward&&!this.config.shouldForward(t)){await this._fulfillFast(e);return}let n=t.url(),r=this.config.localPath,i=Vc(n,r);if(!i){await e.fallback();return}let a=Gc(this.config.upstreamUrl,i,n),u=await t.postDataBuffer()??Buffer.alloc(0),c=t.headers()["content-type"]??"application/x-protobuf",p=t.method(),b={"content-type":c};if(this.config.upstreamHeaders)for(let[x,B]of Object.entries(this.config.upstreamHeaders))b[x]=B;if(this.queue.length>=this.config.maxQueueSize){this.metrics.droppedBatches++,await this._fulfillFast(e),rs(`[otel-proxy] dropped batch (queue full: ${this.queue.length}/${this.config.maxQueueSize}) suffix=${i}`);return}let f={body:u,contentType:c,createdAtMs:Date.now(),upstreamUrl:a,method:p,headers:b};this.queue.push(f),this.metrics.acceptedBatches++,await this._fulfillFast(e)}async _fulfillFast(e){let t=this.config.respondNoContent?204:200;if(t===204){await e.fulfill({status:t});return}await e.fulfill({status:t,headers:{"content-type":"text/plain; charset=utf-8"},body:""})}async _workerLoop(e){for(;this.isRunning;){let t=this.queue.shift();if(!t){await this._sleep(25);continue}this.metrics.inFlight++;try{await this._forwardUpstream(t),this.metrics.forwardedBatches++}catch(n){this.metrics.failedBatches++;let r=n instanceof Error?n.message:String(n);this.metrics.lastError=r,rs(`[otel-proxy] worker=${e} forward failed: ${r}`)}finally{this.metrics.inFlight--}}}async _forwardUpstream(e){let t=await fetch(e.upstreamUrl,{method:e.method,headers:e.headers,body:new Uint8Array(e.body)});if(t.status<200||t.status>=300){let n=await this._safeReadText(t);throw new Error(`upstream returned ${t.status} for ${e.upstreamUrl}: ${n}`)}}async _safeReadText(e){try{return(await e.text()).slice(0,500)}catch{return""}}async _sleep(e){await new Promise(t=>{setTimeout(()=>t(),e)})}};import*as xr from"node:fs";import*as Et from"node:path";import{fileURLToPath as Kc}from"node:url";var Xc=Kc(import.meta.url),Yc=Et.dirname(Xc),Tr="/__mcp_otel/",Jc="otel-initializer.bundle.js";function Qc(){return os?os:Et.join(Yc,"platform","browser","otel")}s(Qc,"_getOtelAssetsDir");function Zc(){if(bn==="otlp/http"||kn){if(!kn)throw new Error('OTEL exporter HTTP url must be set when OTEL exporter type is "otlp/http"');return{type:"otlp/http",url:Tr,upstreamURL:kn,headers:Ys}}else{if(bn==="console")return{type:"console"};if(bn==="none")return{type:"none"};throw new Error(`Invalid OTEL exporter type ${bn}`)}}s(Zc,"_getOTELExporterConfig");function em(){return{userInteractionEvents:Xs}}s(em,"_getOTELInstrumentationConfig");function tm(){return{serviceName:Gs,serviceVersion:Ks,exporter:Zc(),instrumentation:em(),debug:!1}}s(tm,"_getOTELConfig");function nm(o,e){let t=Et.isAbsolute(o)?o:Et.join(process.cwd(),o),n=Et.join(t,e);if(!xr.existsSync(n))throw new Error(`OTEL bundle not found at: ${n}`);return xr.readFileSync(n,"utf-8")}s(nm,"_readBundleContent");async function om(o,e){await o.evaluate(t=>{let n=globalThis;n.__MCP_DEVTOOLS__||(n.__MCP_DEVTOOLS__={}),n.__MCP_TRACE_ID__=t.traceId,n.__mcpOtel&&typeof n.__mcpOtel.init=="function"?n.__mcpOtel.init(t):(n.__MCP_DEVTOOLS__.otelInitialized=!1,n.__MCP_DEVTOOLS__.otelInitError="__mcpOtel.init is not available while applying config")},e).catch(t=>{let n=t instanceof Error?t.message:String(t);K(`[otel-controller] applyConfigToPage failed (ignored): ${n}`)})}s(om,"_applyConfigToPage");function rm(o,e){let t=new WeakMap,n=s(a=>{if(t.has(a))return;let l=s(async u=>{u===a.mainFrame()&&await om(a,e())},"onFrameNavigated");t.set(a,l),a.on("framenavigated",l)},"attachToPage");for(let a of o.pages())n(a);let r=s(a=>{n(a)},"onNewPage");o.on("page",r);let i=s(()=>{try{o.off("page",r)}catch{}for(let a of o.pages()){let l=t.get(a);if(l)try{a.off("framenavigated",l)}catch{}}},"detach");return K("[otel-controller] auto-sync installed (page+framenavigated)"),{detach:i}}s(rm,"_installAutoSync");var Sr=class{static{s(this,"OTELController")}browserContext;config;proxy;initialized=!1;autoSyncDetach;constructor(e){this.browserContext=e,this.config=tm()}async init(e){if(this.initialized){K("[otel-controller] init skipped: BrowserContext already initialized");return}if(!e.traceId||!e.traceId.trim())throw new Error("[otel-controller] init requires a non-empty traceId");this.config.traceId=e.traceId;let t=Qc();this.config.exporter.type==="otlp/http"&&(this.proxy=new wr({localPath:Tr,upstreamUrl:this.config.exporter.upstreamURL,upstreamHeaders:{...this.config.exporter.headers??{}}}),await this.proxy.install(this.browserContext)),K(`[otel-controller] exporter=${this.config.exporter.type} localBase=${Tr}`+(this.config.exporter.type==="otlp/http"?` upstreamBase=${this.config.exporter.upstreamURL}`:""));let n=nm(t,Jc),r=rm(this.browserContext,()=>this.config);this.autoSyncDetach=r.detach,await this.browserContext.addInitScript({content:n}),await this.browserContext.addInitScript(i=>{let a=globalThis;a.__MCP_DEVTOOLS__||(a.__MCP_DEVTOOLS__={}),a.__MCP_TRACE_ID__=i.traceId,a.__mcpOtel&&typeof a.__mcpOtel.init=="function"?a.__mcpOtel.init(i):(a.__MCP_DEVTOOLS__.otelInitialized=!1,a.__MCP_DEVTOOLS__.otelInitError="__mcpOtel.init is not available (initializer bundle did not install)")},this.config),this.initialized=!0,K("[otel-controller] init installed: bundle + config init scripts + auto-sync")}isOTELRequest(e){return new URL(e.url()).pathname.startsWith(Tr)}async isInitialized(e){return await e.evaluate(()=>globalThis.__MCP_DEVTOOLS__?.otelInitialized===!0)}async getInitError(e){return await e.evaluate(()=>{let n=globalThis.__MCP_DEVTOOLS__?.otelInitError;if(typeof n=="string"&&n.trim())return n})}async getTraceId(e){return await e.evaluate(()=>{let t=globalThis;if(t.__mcpOtel&&typeof t.__mcpOtel.getTraceId=="function"){let r=t.__mcpOtel.getTraceId();if(typeof r=="string"&&r.trim())return r}let n=t.__MCP_TRACE_ID__;if(typeof n=="string"&&n.trim())return n})}async setTraceId(e,t){this.config.traceId=t,await e.evaluate(n=>{let r=globalThis;r.__mcpOtel&&typeof r.__mcpOtel.setTraceId=="function"?r.__mcpOtel.setTraceId(n):r.__MCP_TRACE_ID__=n},t)}async close(){if(this.autoSyncDetach){try{this.autoSyncDetach()}catch{}this.autoSyncDetach=void 0}this.proxy&&(await this.proxy.uninstall(this.browserContext),this.proxy=void 0)}};var vr=class{static{s(this,"BrowserToolSessionContext")}_sessionId;options;otelController;consoleMessages=[];httpRequests=[];initialized=!1;closed=!1;traceId;_numOfInFlightRequests=0;_lastNetworkActivityTimestamp=0;browserContext;page;constructor(e,t,n,r){this._sessionId=e,this.browserContext=t,this.page=n,this.options=r,this.otelController=new Sr(this.browserContext)}async init(){if(this.closed)throw new Error("Session context is already closed");if(this.initialized)throw new Error("Session context is already initialized");let e=this,t=0;this.page.on("console",r=>{e.consoleMessages.push(e._toConsoleMessage(r,++t)),e.consoleMessages.length>pn&&e.consoleMessages.splice(0,e.consoleMessages.length-pn)}),this.page.on("pageerror",r=>{e.consoleMessages.push(e._errorToConsoleMessage(r,++t)),e.consoleMessages.length>pn&&e.consoleMessages.splice(0,e.consoleMessages.length-pn)});let n=0;this.page.on("request",async r=>{e.otelController.isOTELRequest(r)||(e._numOfInFlightRequests++,e._lastNetworkActivityTimestamp=Date.now())}),this.page.on("requestfinished",async r=>{e.otelController.isOTELRequest(r)||(e._numOfInFlightRequests--,e._lastNetworkActivityTimestamp=Date.now(),e.httpRequests.push(await e._toHttpRequest(r,++n)),e.httpRequests.length>dn&&e.httpRequests.splice(0,e.httpRequests.length-dn))}),this.page.on("requestfailed",async r=>{e.otelController.isOTELRequest(r)||(e._numOfInFlightRequests--,e._lastNetworkActivityTimestamp=Date.now(),e.httpRequests.push(await e._toHttpRequest(r,++n)),e.httpRequests.length>dn&&e.httpRequests.splice(0,e.httpRequests.length-dn))}),this.options.otelEnable&&(this.traceId=tr(),await this.otelController.init({traceId:this.traceId})),this.initialized=!0}_toConsoleMessageLevelName(e){switch(e){case"assert":case"error":return"error";case"warning":return"warning";case"count":case"dir":case"dirxml":case"info":case"log":case"table":case"time":case"timeEnd":return"info";case"clear":case"debug":case"endGroup":case"profile":case"profileEnd":case"startGroup":case"startGroupCollapsed":case"trace":return"debug";default:return"info"}}_toConsoleMessage(e,t){let n=Date.now(),r=this._toConsoleMessageLevelName(e.type()),i=Yt[r].code;return{type:e.type(),text:e.text(),level:{name:r,code:i},location:{url:e.location().url,lineNumber:e.location().lineNumber,columnNumber:e.location().columnNumber},timestamp:n,sequenceNumber:t}}_errorToConsoleMessage(e,t){let n=Date.now();return e instanceof Error?{type:"error",text:e.message,level:{name:"error",code:3},timestamp:n,sequenceNumber:t}:{type:"error",text:String(e),level:{name:"error",code:3},timestamp:n,sequenceNumber:t}}_isBodyLikelyPresent(e,t){return!(t==="HEAD"||t==="OPTIONS"||e===204||e===304||e>=300&&e<400)}async _safeReadResponseBody(e){try{let n=e.request().method(),r=e.status();return this._isBodyLikelyPresent(r,n)?(await e.body()).toString("utf-8"):void 0}catch{return}}async _toHttpRequest(e,t){let n=await e.response();return{url:e.url(),method:e.method(),headers:e.headers(),body:e.postData()||void 0,resourceType:e.resourceType(),failure:e.failure()?.errorText,duration:e.timing().responseEnd,response:n?{status:n.status(),statusText:n.statusText(),headers:n.headers(),body:await this._safeReadResponseBody(n)}:void 0,ok:n?n.ok():!1,timestamp:Math.floor(e.timing().startTime),sequenceNumber:t}}numOfInFlightRequests(){return this._numOfInFlightRequests}lastNetworkActivityTimestamp(){return this._lastNetworkActivityTimestamp}sessionId(){return this._sessionId}async getTraceId(){return this.traceId}async setTraceId(e){if(!this.options.otelEnable)throw new Error("OTEL is not enabled");this.traceId=e,await this.otelController.setTraceId(this.page,e)}getConsoleMessages(){return this.consoleMessages}getHttpRequests(){return this.httpRequests}async close(){if(this.closed)return!1;K(`Closing OTEL controller of the session with id ${this._sessionId} ...`),await this.otelController.close();try{K(`Closing browser context of the session with id ${this._sessionId} ...`),await Tl(this.browserContext)}catch(e){K(`Error occurred while closing browser context of the session with id ${this._sessionId} ...`,e)}return this.consoleMessages.length=0,this.httpRequests.length=0,this.closed=!0,!0}};var Ir=class{static{s(this,"BrowserToolExecutor")}sessionIdProvider;sessionContext;constructor(e){this.sessionIdProvider=e}async _createSessionContext(){let e=await yl(),t=await wl(e.browserContext),n=this.sessionIdProvider(),r=new vr(n,e.browserContext,t,{otelEnable:Vs});return await r.init(),r}async _sessionContext(){return this.sessionContext||(this.sessionContext=await this._createSessionContext(),K(`Created session context on the first tool call for the session with id ${this.sessionContext.sessionId()}`)),this.sessionContext}async executeTool(e,t){K(`Executing tool ${e.name()} with input: ${hn(t)}`);try{let n=await this._sessionContext(),r=await e.handle(n,t);return K(`Executed tool ${e.name()} and got output: ${hn(r)}`),r}catch(n){throw K(`Error occurred while executing ${e.name()}: ${n}`),n}}};var Cr=[...Oi,...Mi,...sa,...Ia,...ka,..._a,...Da,...ja,...Ka,...ll,...dl];function Sl(o){return new Ir(o)}s(Sl,"createToolExecutor");import{Option as Ht}from"commander";var Ms=class{static{s(this,"BrowserCliProvider")}platform="browser";cliName="browser-devtools-cli";tools=Cr;sessionDescription="Manage browser sessions";cliExamples=["browser-devtools-cli --no-headless interactive","browser-devtools-cli --persistent --no-headless interactive"];bashCompletionOptions="--headless --no-headless --persistent --no-persistent --user-data-dir --use-system-browser --browser-path";bashCompletionCommands="daemon session tools config completion interactive navigation content interaction a11y accessibility o11y react run stub sync figma debug";zshCompletionOptions=` '--headless[Run in headless mode]' \\
770
770
  '--no-headless[Run in headful mode]' \\
771
771
  '--persistent[Use persistent context]' \\
772
772
  '--no-persistent[Use ephemeral context]' \\
773
773
  '--user-data-dir[User data directory]:path:_files -/' \\
774
774
  '--use-system-browser[Use system browser]' \\
775
- '--browser-path[Browser executable path]:path:_files' \\`;zshCompletionCommands=[{name:"daemon",description:"Manage the daemon server"},{name:"session",description:"Manage browser sessions"},{name:"tools",description:"List and inspect available tools"},{name:"config",description:"Show current configuration"},{name:"completion",description:"Generate shell completion scripts"},{name:"interactive",description:"Start interactive REPL mode"},{name:"navigation",description:"Navigation commands"},{name:"content",description:"Content extraction commands"},{name:"interaction",description:"Interaction commands"},{name:"a11y",description:"Accessibility commands"},{name:"accessibility",description:"Extended accessibility commands"},{name:"o11y",description:"Observability commands"},{name:"react",description:"React debugging commands"},{name:"run",description:"Script execution commands"},{name:"stub",description:"HTTP stubbing commands"},{name:"sync",description:"Synchronization commands"},{name:"figma",description:"Figma integration commands"},{name:"debug",description:"Non-blocking debugging commands"}];replPrompt="browser> ";cliDescription="Browser DevTools MCP CLI";packageName="browser-devtools-mcp";buildEnv(e){let t={...process.env};return e.headless!==void 0&&(t.BROWSER_HEADLESS_ENABLE=String(e.headless)),e.persistent!==void 0&&(t.BROWSER_PERSISTENT_ENABLE=String(e.persistent)),e.userDataDir!==void 0&&(t.BROWSER_PERSISTENT_USER_DATA_DIR=e.userDataDir),e.useSystemBrowser!==void 0&&(t.BROWSER_USE_INSTALLED_ON_SYSTEM=String(e.useSystemBrowser)),e.browserPath!==void 0&&(t.BROWSER_EXECUTABLE_PATH=e.browserPath),t}addOptions(e){return e.addOption(new qt("--headless","Run browser in headless mode (no visible window)").default(zt)).addOption(new qt("--no-headless","Run browser in headful mode (visible window)")).addOption(new qt("--persistent","Use persistent browser context (preserves cookies, localStorage)").default(Vt)).addOption(new qt("--no-persistent","Use ephemeral browser context (cleared on session end)")).addOption(new qt("--user-data-dir <path>","Directory for persistent browser context user data").default(Gt)).addOption(new qt("--use-system-browser","Use system-installed Chrome instead of bundled browser").default(Kt)).addOption(new qt("--browser-path <path>","Custom browser executable path"))}getConfig(){return{headless:zt,persistent:Vt,userDataDir:Gt,useSystemBrowser:Kt,executablePath:En,locale:Nn}}formatConfig(e){let t=[" Browser:",` Headless: ${e.headless}`,` Persistent: ${e.persistent}`,` User Data Dir: ${e.userDataDir||"(default)"}`,` Use System Browser: ${e.useSystemBrowser}`,` Executable Path: ${e.executablePath||"(bundled)"}`];return e.locale&&t.push(` Locale: ${e.locale}`),t.join(`
775
+ '--browser-path[Browser executable path]:path:_files' \\`;zshCompletionCommands=[{name:"daemon",description:"Manage the daemon server"},{name:"session",description:"Manage browser sessions"},{name:"tools",description:"List and inspect available tools"},{name:"config",description:"Show current configuration"},{name:"completion",description:"Generate shell completion scripts"},{name:"interactive",description:"Start interactive REPL mode"},{name:"navigation",description:"Navigation commands"},{name:"content",description:"Content extraction commands"},{name:"interaction",description:"Interaction commands"},{name:"a11y",description:"Accessibility commands"},{name:"accessibility",description:"Extended accessibility commands"},{name:"o11y",description:"Observability commands"},{name:"react",description:"React debugging commands"},{name:"run",description:"Script execution commands"},{name:"stub",description:"HTTP stubbing commands"},{name:"sync",description:"Synchronization commands"},{name:"figma",description:"Figma integration commands"},{name:"debug",description:"Non-blocking debugging commands"}];replPrompt="browser> ";cliDescription="Browser DevTools MCP CLI";packageName="browser-devtools-mcp";buildEnv(e){let t={...process.env};return e.headless!==void 0&&(t.BROWSER_HEADLESS_ENABLE=String(e.headless)),e.persistent!==void 0&&(t.BROWSER_PERSISTENT_ENABLE=String(e.persistent)),e.userDataDir!==void 0&&(t.BROWSER_PERSISTENT_USER_DATA_DIR=e.userDataDir),e.useSystemBrowser!==void 0&&(t.BROWSER_USE_INSTALLED_ON_SYSTEM=String(e.useSystemBrowser)),e.browserPath!==void 0&&(t.BROWSER_EXECUTABLE_PATH=e.browserPath),t}addOptions(e){return e.addOption(new Ht("--headless","Run browser in headless mode (no visible window)").default(zt)).addOption(new Ht("--no-headless","Run browser in headful mode (visible window)")).addOption(new Ht("--persistent","Use persistent browser context (preserves cookies, localStorage)").default(Vt)).addOption(new Ht("--no-persistent","Use ephemeral browser context (cleared on session end)")).addOption(new Ht("--user-data-dir <path>","Directory for persistent browser context user data").default(Gt)).addOption(new Ht("--use-system-browser","Use system-installed Chrome instead of bundled browser").default(Kt)).addOption(new Ht("--browser-path <path>","Custom browser executable path"))}getConfig(){return{headless:zt,persistent:Vt,userDataDir:Gt,useSystemBrowser:Kt,executablePath:Nn,locale:Pn}}formatConfig(e){let t=[" Browser:",` Headless: ${e.headless}`,` Persistent: ${e.persistent}`,` User Data Dir: ${e.userDataDir||"(default)"}`,` Use System Browser: ${e.useSystemBrowser}`,` Executable Path: ${e.executablePath||"(bundled)"}`];return e.locale&&t.push(` Locale: ${e.locale}`),t.join(`
776
776
  `)}formatConfigForRepl(e){return[` headless = ${e.headless??zt}`,` persistent = ${e.persistent??Vt}`,` user-data-dir = ${e.userDataDir||Gt||"(default)"}`,` use-system-browser = ${e.useSystemBrowser??Kt}`,` browser-path = ${e.browserPath||"(auto)"}`].join(`
777
- `)}},Tl=new Ps;var Sl=`
777
+ `)}},vl=new Ms;var Il=`
778
778
  This MCP server exposes a Playwright-powered browser runtime to AI agents,
779
779
  enabling deep, bidirectional debugging and interaction with live web pages.
780
780
 
@@ -850,6 +850,14 @@ Core capabilities include:
850
850
  - Clean lifecycle management and teardown
851
851
 
852
852
  UI debugging guidance for AI agents:
853
+
854
+ *** INSPECTION PREFERENCE (follow this order) ***
855
+ 1. Prefer "a11y_take-aria-snapshot" first for page structure, roles, and semantics. Use it when you need to understand what is on the page, hierarchy, or accessibility.
856
+ 2. If you need layout, bounding boxes, visibility, or occlusion: use "a11y_take-ax-tree-snapshot" (optionally with checkOcclusion:true). This often suffices instead of a screenshot.
857
+ 3. Use "content_take-screenshot" ONLY when you genuinely need to see how the UI looks visually (e.g. visual design check, pixel-level verification, or when snapshots are insufficient). Do not take screenshots just to "see the page"\u2014use ARIA or AX snapshot instead.
858
+ *** SCREENSHOT TOOL: includeBase64 ***
859
+ - The screenshot is always saved to disk; the tool returns the file path. Do NOT set includeBase64 to true unless the assistant cannot read files from that path (e.g. remote MCP server, container). Leave includeBase64 false (default) to avoid large responses; read the image from the returned path when possible.
860
+
853
861
  - Prefer Accessibility (AX) and ARIA snapshots over raw DOM dumps when diagnosing UI problems.
854
862
  These snapshots provide higher-signal, semantically meaningful anchors (roles, names, states) that
855
863
  map more reliably to what users perceive and what assistive tech can interact with.
@@ -892,14 +900,18 @@ This server is designed for AI coding assistants, visual debugging agents, and a
892
900
  that need to reason about what a page looks like, how it is structured, and how it behaves \u2014 all through a single MCP interface.
893
901
 
894
902
  It treats the browser as a queryable, inspectable, and controllable execution environment rather than a static screenshot source.
895
- `,xl=`
903
+ `,Cl=`
896
904
  <ui_debugging_policy>
897
905
  When asked to check for UI problems, layout issues, or visual bugs, ALWAYS follow this policy:
898
906
 
899
907
  1. **Synchronization**: If the page loads content asynchronously, call "sync_wait-for-network-idle" first
900
908
  to ensure the page is stable before inspection.
901
909
 
902
- 2. **Visual Inspection**: Call "content_take-screenshot" for general aesthetics and layout overview.
910
+ 2. **Inspection order (prefer snapshots over screenshots)**:
911
+ - First try "a11y_take-aria-snapshot" for structure, roles, and semantics.
912
+ - If you need layout/occlusion/visibility: use "a11y_take-ax-tree-snapshot" (with "checkOcclusion:true" when interactions fail).
913
+ - Call "content_take-screenshot" ONLY when you truly need to see the visual appearance of the UI (e.g. design check, pixel verification). Do not take screenshots just to see the page\u2014use ARIA or AX snapshot instead.
914
+ - When taking a screenshot, do NOT set "includeBase64" to true unless the assistant cannot read the returned file path (e.g. remote/container). The image is always saved to disk.
903
915
 
904
916
  3. **Accessibility Tree Analysis**: Call "a11y_take-ax-tree-snapshot" tool with "checkOcclusion:true"
905
917
  - Provides precise bounding boxes, runtime visual data, and occlusion detection
@@ -964,9 +976,11 @@ When asked to check for UI problems, layout issues, or visual bugs, ALWAYS follo
964
976
  - Use "debug_status" to check current debugging state and probe counts
965
977
 
966
978
  **Tool Usage Notes:**
979
+ - ARIA snapshot first for structure/roles/semantics; then AX tree for layout/occlusion/positioning.
980
+ - Screenshot only when you must see the actual pixels (e.g. visual design); otherwise use snapshots.
981
+ - Do not set includeBase64 on screenshot unless the assistant cannot read the file path.
967
982
  - AX tree: Technical measurements, occlusion, precise positioning, visual diagnostics
968
983
  - ARIA snapshot: Semantic understanding, accessibility structure, role hierarchy
969
- - Screenshot: Quick visual reference, but not sufficient alone
970
984
  - Network idle: Essential for SPAs and async content
971
985
  - Web Vitals: Performance context for UI issues
972
986
  - Tracepoints: Deep code investigation with call stack and variables (non-blocking)
@@ -981,7 +995,7 @@ When asked to check for UI problems, layout issues, or visual bugs, ALWAYS follo
981
995
  - Use scroll tool if elements are below the fold before inspection.
982
996
  - For responsive issues, use resize-viewport or resize-window tools to test different sizes.
983
997
  </ui_debugging_policy>
984
- `;var Il={serverInfo:{instructions:Sl,policies:[xl]},toolsInfo:{tools:Cr,createToolExecutor:yl},cliInfo:{cliProvider:Tl}};import{z as ke}from"zod";var vr=class{static{s(this,"Connect")}name(){return"debug_connect"}description(){return`
998
+ `;var El={serverInfo:{instructions:Il,policies:[Cl]},toolsInfo:{tools:Cr,createToolExecutor:Sl},cliInfo:{cliProvider:vl}};import{z as ke}from"zod";var Er=class{static{s(this,"Connect")}name(){return"debug_connect"}description(){return`
985
999
  Connects to a Node.js process for V8 debugging.
986
1000
 
987
1001
  Supports multiple connection methods:
@@ -1002,14 +1016,14 @@ When MCP runs in a container connecting to another container:
1002
1016
 
1003
1017
  Once connected, you can use tracepoints, logpoints, exceptionpoints,
1004
1018
  and watch expressions - the same debugging tools available for browser.
1005
- `}inputSchema(){return{pid:ke.number().int().positive().describe("Process ID to connect to").optional(),processName:ke.string().describe('Process name pattern to search for (e.g., "server.js", "api")').optional(),containerId:ke.string().describe("Docker container ID - process runs inside this container").optional(),containerName:ke.string().describe("Docker container name or pattern (e.g., my-node-app) - resolved via docker ps -f name=").optional(),host:ke.string().describe("Inspector host (default: 127.0.0.1); for containerized MCP use host.docker.internal or container name").optional(),port:ke.number().int().positive().describe("Inspector port (default: 9229); for Docker use host-mapped port").optional(),wsUrl:ke.string().describe("Direct WebSocket URL (e.g., ws://127.0.0.1:9229/abc-123)").optional()}}outputSchema(){return{connected:ke.boolean().describe("Whether connection was successful"),pid:ke.number().describe("Process ID"),command:ke.string().optional().describe("Process command line"),containerId:ke.string().optional().describe("Docker container ID when connected via container"),inspectorHost:ke.string().optional().describe("Inspector host"),inspectorPort:ke.number().optional().describe("Inspector port"),webSocketUrl:ke.string().optional().describe("WebSocket URL"),title:ke.string().describe("Target title")}}async handle(e,t){let n=await e.connect({pid:t.pid,processName:t.processName,containerId:t.containerId,containerName:t.containerName,host:t.host,port:t.port,wsUrl:t.wsUrl,activateIfNeeded:!0});return{connected:!0,pid:n.processInfo.pid,command:n.processInfo.command,containerId:n.processInfo.containerId,inspectorHost:n.processInfo.inspectorHost,inspectorPort:n.processInfo.inspectorPort,webSocketUrl:n.processInfo.webSocketUrl,title:n.target.title}}};import{z as Qc}from"zod";var Or=class{static{s(this,"Disconnect")}name(){return"debug_disconnect"}description(){return"Disconnects from the currently connected Node.js process and cleans up debugging resources."}inputSchema(){return{}}outputSchema(){return{disconnected:Qc.boolean().describe("Whether disconnection was successful")}}async handle(e,t){return await e.disconnect(),{disconnected:!0}}};import{z as fe}from"zod";function Cl(o,e,t,n,r){let i;if(e)i=ii(o,e);else if(r){let a=bt(o),l=new Set(a.filter(m=>m.kind===r).map(m=>m.id)),u=Bn(o);r==="tracepoint"?i=u.filter(m=>l.has(m.probeId)||m.probeId==="__exception__"):i=u.filter(m=>l.has(m.probeId))}else i=Bn(o);return t!==void 0&&(i=i.filter(a=>a.sequenceNumber>t)),n!==void 0&&(i=i.slice(-n)),i}s(Cl,"_filterSnapshots");var Er=class{static{s(this,"GetTracepointSnapshots")}name(){return"debug_get-tracepoint-snapshots"}description(){return"Retrieves snapshots captured by tracepoints on the Node.js process. Each snapshot contains call stack with local variables, async stack trace, watch expression results, and traceContext (traceId, spanId) when the process uses @opentelemetry/api."}inputSchema(){return{probeId:fe.string().describe("Filter by specific tracepoint ID").optional(),fromSequence:fe.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:fe.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:fe.array(fe.any()).describe("Captured snapshots"),count:fe.number().describe("Number of snapshots returned")}}async handle(e,t){let n=Cl(e.storeKey,t.probeId,t.fromSequence,t.limit,"tracepoint");return{snapshots:n,count:n.length}}},Nr=class{static{s(this,"GetLogpointSnapshots")}name(){return"debug_get-logpoint-snapshots"}description(){return"Retrieves snapshots captured by logpoints on the Node.js process. Each snapshot contains the log expression result and traceContext (traceId, spanId) when the process uses @opentelemetry/api."}inputSchema(){return{probeId:fe.string().describe("Filter by specific logpoint ID").optional(),fromSequence:fe.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence").optional(),limit:fe.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:fe.array(fe.any()).describe("Captured snapshots"),count:fe.number().describe("Number of snapshots returned")}}async handle(e,t){let n=Cl(e.storeKey,t.probeId,t.fromSequence,t.limit,"logpoint");return{snapshots:n,count:n.length}}},Pr=class{static{s(this,"GetExceptionpointSnapshots")}name(){return"debug_get-exceptionpoint-snapshots"}description(){return"Retrieves snapshots captured by exception breakpoints on the Node.js process. Snapshots include traceContext (traceId, spanId) when the process uses @opentelemetry/api."}inputSchema(){return{fromSequence:fe.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence").optional(),limit:fe.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:fe.array(fe.any()).describe("Captured snapshots"),count:fe.number().describe("Number of snapshots returned")}}async handle(e,t){let r=Bn(e.storeKey).filter(i=>i.probeId==="__exception__");return t.fromSequence!==void 0&&(r=r.filter(i=>i.sequenceNumber>t.fromSequence)),t.limit!==void 0&&(r=r.slice(-t.limit)),{snapshots:r,count:r.length}}},Rr=class{static{s(this,"ClearTracepointSnapshots")}name(){return"debug_clear-tracepoint-snapshots"}description(){return"Clears tracepoint snapshots. Optionally filter by specific tracepoint ID."}inputSchema(){return{probeId:fe.string().describe("Clear only snapshots for this tracepoint ID").optional()}}outputSchema(){return{cleared:fe.number().describe("Number of snapshots cleared")}}async handle(e,t){let{clearSnapshots:n,clearSnapshotsByProbe:r}=await import("./core-B3VLZZCP.js");return{cleared:t.probeId?r(e.storeKey,t.probeId):n(e.storeKey)}}},kr=class{static{s(this,"ClearLogpointSnapshots")}name(){return"debug_clear-logpoint-snapshots"}description(){return"Clears logpoint snapshots. Optionally filter by specific logpoint ID."}inputSchema(){return{probeId:fe.string().describe("Clear only snapshots for this logpoint ID").optional()}}outputSchema(){return{cleared:fe.number().describe("Number of snapshots cleared")}}async handle(e,t){let{clearSnapshotsByProbe:n,clearSnapshots:r}=await import("./core-B3VLZZCP.js");return{cleared:t.probeId?n(e.storeKey,t.probeId):r(e.storeKey)}}},_r=class{static{s(this,"ClearExceptionpointSnapshots")}name(){return"debug_clear-exceptionpoint-snapshots"}description(){return"Clears all exception snapshots."}inputSchema(){return{}}outputSchema(){return{cleared:fe.number().describe("Number of snapshots cleared")}}async handle(e,t){let{clearSnapshotsByProbe:n}=await import("./core-B3VLZZCP.js");return{cleared:n(e.storeKey,"__exception__")}}};import{z as Ee}from"zod";var Dr=class{static{s(this,"GetLogs")}name(){return"debug_get-logs"}description(){return"Retrieves console messages/logs from the Node.js process with filtering options."}inputSchema(){return{type:Ee.enum(Te(dt)).transform(st(dt)).describe(`Type of console messages to retrieve. When specified, messages with equal or higher levels are retrieved. Valid values: ${Te(dt).join(", ")}.`).optional(),search:Ee.string().describe("Text to search for in console messages.").optional(),timestamp:Ee.number().int().nonnegative().describe("Start time filter as Unix epoch timestamp in milliseconds. If provided, only messages recorded at or after this timestamp will be returned.").optional(),sequenceNumber:Ee.number().int().nonnegative().describe("Sequence number for incremental retrieval. If provided, only messages with sequence number greater than this value will be returned.").optional(),limit:Ee.object({count:Ee.number().int().nonnegative().default(0).describe("Max number of messages. 0 = no limit."),from:Ee.enum(["start","end"]).default("end").describe("Which side to keep when truncated.")}).describe("Maximum number of console messages to return.").optional()}}outputSchema(){return{messages:Ee.array(Ee.object({type:Ee.string().describe("Type of the console message."),text:Ee.string().describe("Text of the console message."),location:Ee.object({url:Ee.string().describe("URL of the resource."),lineNumber:Ee.number().nonnegative().describe("0-based line number."),columnNumber:Ee.number().nonnegative().describe("0-based column number.")}).describe("Location of the console message.").optional(),timestamp:Ee.number().int().nonnegative().describe("Unix epoch timestamp (ms)."),sequenceNumber:Ee.number().int().nonnegative().describe("Monotonic sequence number.")})).describe("Retrieved console messages.")}}async handle(e,t){let n=t.type?Jt[t.type]?.code:void 0,r=li(e.storeKey).filter(l=>!(n!==void 0&&l.level.code<n||t.timestamp&&l.timestamp<t.timestamp||t.sequenceNumber&&l.sequenceNumber<=t.sequenceNumber||t.search&&!l.text.includes(t.search)));return{messages:(t.limit?.count?t.limit.from==="start"?r.slice(0,t.limit.count):r.slice(-t.limit.count):r).map(l=>({type:l.type,text:l.text,location:l.location?{url:l.location.url,lineNumber:l.location.lineNumber,columnNumber:l.location.columnNumber}:void 0,timestamp:l.timestamp,sequenceNumber:l.sequenceNumber}))}}};import{z as ct}from"zod";var Br=class{static{s(this,"RemoveTracepoint")}name(){return"debug_remove-tracepoint"}description(){return"Removes a tracepoint by its ID."}inputSchema(){return{id:ct.string().describe("Tracepoint ID to remove")}}outputSchema(){return{removed:ct.boolean().describe("Whether the tracepoint was removed")}}async handle(e,t){return{removed:await bn(e.storeKey,t.id)}}},Ar=class{static{s(this,"ListTracepoints")}name(){return"debug_list-tracepoints"}description(){return"Lists all active tracepoints on the Node.js process."}inputSchema(){return{}}outputSchema(){return{tracepoints:ct.array(ct.any()).describe("Active tracepoints")}}async handle(e,t){return{tracepoints:bt(e.storeKey).filter(r=>r.kind==="tracepoint").map(r=>({id:r.id,urlPattern:r.urlPattern,lineNumber:r.lineNumber,columnNumber:r.columnNumber,condition:r.condition,hitCondition:r.hitCondition,hitCount:r.hitCount,resolvedLocations:r.resolvedLocations,enabled:r.enabled}))}}},Lr=class{static{s(this,"ClearTracepoints")}name(){return"debug_clear-tracepoints"}description(){return"Removes all tracepoints from the Node.js process."}inputSchema(){return{}}outputSchema(){return{cleared:ct.number().describe("Number of tracepoints cleared")}}async handle(e,t){let n=bt(e.storeKey).filter(i=>i.kind==="tracepoint"),r=0;for(let i of n)await bn(e.storeKey,i.id)&&r++;return{cleared:r}}},Fr=class{static{s(this,"RemoveLogpoint")}name(){return"debug_remove-logpoint"}description(){return"Removes a logpoint by its ID."}inputSchema(){return{id:ct.string().describe("Logpoint ID to remove")}}outputSchema(){return{removed:ct.boolean().describe("Whether the logpoint was removed")}}async handle(e,t){return{removed:await bn(e.storeKey,t.id)}}},Ur=class{static{s(this,"ListLogpoints")}name(){return"debug_list-logpoints"}description(){return"Lists all active logpoints on the Node.js process."}inputSchema(){return{}}outputSchema(){return{logpoints:ct.array(ct.any()).describe("Active logpoints")}}async handle(e,t){return{logpoints:bt(e.storeKey).filter(r=>r.kind==="logpoint").map(r=>({id:r.id,urlPattern:r.urlPattern,lineNumber:r.lineNumber,logExpression:r.logExpression,condition:r.condition,hitCondition:r.hitCondition,hitCount:r.hitCount,resolvedLocations:r.resolvedLocations,enabled:r.enabled}))}}},Hr=class{static{s(this,"ClearLogpoints")}name(){return"debug_clear-logpoints"}description(){return"Removes all logpoints from the Node.js process."}inputSchema(){return{}}outputSchema(){return{cleared:ct.number().describe("Number of logpoints cleared")}}async handle(e,t){let n=bt(e.storeKey).filter(i=>i.kind==="logpoint"),r=0;for(let i of n)await bn(e.storeKey,i.id)&&r++;return{cleared:r}}};import{z as Rs}from"zod";var qr=class{static{s(this,"PutExceptionpoint")}name(){return"debug_put-exceptionpoint"}description(){return`
1019
+ `}inputSchema(){return{pid:ke.number().int().positive().describe("Process ID to connect to").optional(),processName:ke.string().describe('Process name pattern to search for (e.g., "server.js", "api")').optional(),containerId:ke.string().describe("Docker container ID - process runs inside this container").optional(),containerName:ke.string().describe("Docker container name or pattern (e.g., my-node-app) - resolved via docker ps -f name=").optional(),host:ke.string().describe("Inspector host (default: 127.0.0.1); for containerized MCP use host.docker.internal or container name").optional(),port:ke.number().int().positive().describe("Inspector port (default: 9229); for Docker use host-mapped port").optional(),wsUrl:ke.string().describe("Direct WebSocket URL (e.g., ws://127.0.0.1:9229/abc-123)").optional()}}outputSchema(){return{connected:ke.boolean().describe("Whether connection was successful"),pid:ke.number().describe("Process ID"),command:ke.string().optional().describe("Process command line"),containerId:ke.string().optional().describe("Docker container ID when connected via container"),inspectorHost:ke.string().optional().describe("Inspector host"),inspectorPort:ke.number().optional().describe("Inspector port"),webSocketUrl:ke.string().optional().describe("WebSocket URL"),title:ke.string().describe("Target title")}}async handle(e,t){let n=await e.connect({pid:t.pid,processName:t.processName,containerId:t.containerId,containerName:t.containerName,host:t.host,port:t.port,wsUrl:t.wsUrl,activateIfNeeded:!0});return{connected:!0,pid:n.processInfo.pid,command:n.processInfo.command,containerId:n.processInfo.containerId,inspectorHost:n.processInfo.inspectorHost,inspectorPort:n.processInfo.inspectorPort,webSocketUrl:n.processInfo.webSocketUrl,title:n.target.title}}};import{z as sm}from"zod";var Or=class{static{s(this,"Disconnect")}name(){return"debug_disconnect"}description(){return"Disconnects from the currently connected Node.js process and cleans up debugging resources."}inputSchema(){return{}}outputSchema(){return{disconnected:sm.boolean().describe("Whether disconnection was successful")}}async handle(e,t){return await e.disconnect(),{disconnected:!0}}};import{z as we}from"zod";function Ol(o,e,t,n,r){let i;if(e)i=ci(o,e);else if(r){let a=dt(o),l=new Set(a.filter(m=>m.kind===r).map(m=>m.id)),u=An(o);r==="tracepoint"?i=u.filter(m=>l.has(m.probeId)||m.probeId==="__exception__"):i=u.filter(m=>l.has(m.probeId))}else i=An(o);return t!==void 0&&(i=i.filter(a=>a.sequenceNumber>t)),n!==void 0&&(i=i.slice(-n)),i}s(Ol,"_filterSnapshots");var Nr=class{static{s(this,"GetTracepointSnapshots")}name(){return"debug_get-tracepoint-snapshots"}description(){return"Retrieves snapshots captured by tracepoints on the Node.js process. Each snapshot contains call stack with local variables, async stack trace, watch expression results, and traceContext (traceId, spanId) when the process uses @opentelemetry/api."}inputSchema(){return{probeId:we.string().describe("Filter by specific tracepoint ID").optional(),fromSequence:we.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence (for polling)").optional(),limit:we.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:we.array(we.any()).describe("Captured snapshots"),count:we.number().describe("Number of snapshots returned")}}async handle(e,t){let n=Ol(e.storeKey,t.probeId,t.fromSequence,t.limit,"tracepoint");return{snapshots:n,count:n.length}}},Pr=class{static{s(this,"GetLogpointSnapshots")}name(){return"debug_get-logpoint-snapshots"}description(){return"Retrieves snapshots captured by logpoints on the Node.js process. Each snapshot contains the log expression result and traceContext (traceId, spanId) when the process uses @opentelemetry/api."}inputSchema(){return{probeId:we.string().describe("Filter by specific logpoint ID").optional(),fromSequence:we.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence").optional(),limit:we.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:we.array(we.any()).describe("Captured snapshots"),count:we.number().describe("Number of snapshots returned")}}async handle(e,t){let n=Ol(e.storeKey,t.probeId,t.fromSequence,t.limit,"logpoint");return{snapshots:n,count:n.length}}},Rr=class{static{s(this,"GetExceptionpointSnapshots")}name(){return"debug_get-exceptionpoint-snapshots"}description(){return"Retrieves snapshots captured by exception breakpoints on the Node.js process. Snapshots include traceContext (traceId, spanId) when the process uses @opentelemetry/api."}inputSchema(){return{fromSequence:we.number().int().nonnegative().describe("Return snapshots with sequence number > fromSequence").optional(),limit:we.number().int().positive().describe("Maximum number of snapshots to return").optional()}}outputSchema(){return{snapshots:we.array(we.any()).describe("Captured snapshots"),count:we.number().describe("Number of snapshots returned")}}async handle(e,t){let r=An(e.storeKey).filter(i=>i.probeId==="__exception__");return t.fromSequence!==void 0&&(r=r.filter(i=>i.sequenceNumber>t.fromSequence)),t.limit!==void 0&&(r=r.slice(-t.limit)),{snapshots:r,count:r.length}}},kr=class{static{s(this,"ClearTracepointSnapshots")}name(){return"debug_clear-tracepoint-snapshots"}description(){return"Clears tracepoint snapshots. Optionally filter by specific tracepoint ID."}inputSchema(){return{probeId:we.string().describe("Clear only snapshots for this tracepoint ID").optional()}}outputSchema(){return{cleared:we.number().describe("Number of snapshots cleared")}}async handle(e,t){let{clearSnapshots:n,clearSnapshotsByProbe:r}=await import("./core-B3VLZZCP.js");return{cleared:t.probeId?r(e.storeKey,t.probeId):n(e.storeKey)}}},_r=class{static{s(this,"ClearLogpointSnapshots")}name(){return"debug_clear-logpoint-snapshots"}description(){return"Clears logpoint snapshots. Optionally filter by specific logpoint ID."}inputSchema(){return{probeId:we.string().describe("Clear only snapshots for this logpoint ID").optional()}}outputSchema(){return{cleared:we.number().describe("Number of snapshots cleared")}}async handle(e,t){let{clearSnapshotsByProbe:n,clearSnapshots:r}=await import("./core-B3VLZZCP.js");return{cleared:t.probeId?n(e.storeKey,t.probeId):r(e.storeKey)}}},Mr=class{static{s(this,"ClearExceptionpointSnapshots")}name(){return"debug_clear-exceptionpoint-snapshots"}description(){return"Clears all exception snapshots."}inputSchema(){return{}}outputSchema(){return{cleared:we.number().describe("Number of snapshots cleared")}}async handle(e,t){let{clearSnapshotsByProbe:n}=await import("./core-B3VLZZCP.js");return{cleared:n(e.storeKey,"__exception__")}}};import{z as Ne}from"zod";var Br=class{static{s(this,"GetLogs")}name(){return"debug_get-logs"}description(){return"Retrieves console messages/logs from the Node.js process with filtering options."}inputSchema(){return{type:Ne.enum(xe(pt)).transform(rt(pt)).describe(`Type of console messages to retrieve. When specified, messages with equal or higher levels are retrieved. Valid values: ${xe(pt).join(", ")}.`).optional(),search:Ne.string().describe("Text to search for in console messages.").optional(),timestamp:Ne.number().int().nonnegative().describe("Start time filter as Unix epoch timestamp in milliseconds. If provided, only messages recorded at or after this timestamp will be returned.").optional(),sequenceNumber:Ne.number().int().nonnegative().describe("Sequence number for incremental retrieval. If provided, only messages with sequence number greater than this value will be returned.").optional(),limit:Ne.object({count:Ne.number().int().nonnegative().default(0).describe("Max number of messages. 0 = no limit."),from:Ne.enum(["start","end"]).default("end").describe("Which side to keep when truncated.")}).describe("Maximum number of console messages to return.").optional()}}outputSchema(){return{messages:Ne.array(Ne.object({type:Ne.string().describe("Type of the console message."),text:Ne.string().describe("Text of the console message."),location:Ne.object({url:Ne.string().describe("URL of the resource."),lineNumber:Ne.number().nonnegative().describe("0-based line number."),columnNumber:Ne.number().nonnegative().describe("0-based column number.")}).describe("Location of the console message.").optional(),timestamp:Ne.number().int().nonnegative().describe("Unix epoch timestamp (ms)."),sequenceNumber:Ne.number().int().nonnegative().describe("Monotonic sequence number.")})).describe("Retrieved console messages.")}}async handle(e,t){let n=t.type?Yt[t.type]?.code:void 0,r=pi(e.storeKey).filter(l=>!(n!==void 0&&l.level.code<n||t.timestamp&&l.timestamp<t.timestamp||t.sequenceNumber&&l.sequenceNumber<=t.sequenceNumber||t.search&&!l.text.includes(t.search)));return{messages:(t.limit?.count?t.limit.from==="start"?r.slice(0,t.limit.count):r.slice(-t.limit.count):r).map(l=>({type:l.type,text:l.text,location:l.location?{url:l.location.url,lineNumber:l.location.lineNumber,columnNumber:l.location.columnNumber}:void 0,timestamp:l.timestamp,sequenceNumber:l.sequenceNumber}))}}};import{z as ut}from"zod";var Ar=class{static{s(this,"RemoveTracepoint")}name(){return"debug_remove-tracepoint"}description(){return"Removes a tracepoint by its ID."}inputSchema(){return{id:ut.string().describe("Tracepoint ID to remove")}}outputSchema(){return{removed:ut.boolean().describe("Whether the tracepoint was removed")}}async handle(e,t){return{removed:await gn(e.storeKey,t.id)}}},Lr=class{static{s(this,"ListTracepoints")}name(){return"debug_list-tracepoints"}description(){return"Lists all active tracepoints on the Node.js process."}inputSchema(){return{}}outputSchema(){return{tracepoints:ut.array(ut.any()).describe("Active tracepoints")}}async handle(e,t){return{tracepoints:dt(e.storeKey).filter(r=>r.kind==="tracepoint").map(r=>({id:r.id,urlPattern:r.urlPattern,lineNumber:r.lineNumber,columnNumber:r.columnNumber,condition:r.condition,hitCondition:r.hitCondition,hitCount:r.hitCount,resolvedLocations:r.resolvedLocations,enabled:r.enabled}))}}},Fr=class{static{s(this,"ClearTracepoints")}name(){return"debug_clear-tracepoints"}description(){return"Removes all tracepoints from the Node.js process."}inputSchema(){return{}}outputSchema(){return{cleared:ut.number().describe("Number of tracepoints cleared")}}async handle(e,t){let n=dt(e.storeKey).filter(i=>i.kind==="tracepoint"),r=0;for(let i of n)await gn(e.storeKey,i.id)&&r++;return{cleared:r}}},Ur=class{static{s(this,"RemoveLogpoint")}name(){return"debug_remove-logpoint"}description(){return"Removes a logpoint by its ID."}inputSchema(){return{id:ut.string().describe("Logpoint ID to remove")}}outputSchema(){return{removed:ut.boolean().describe("Whether the logpoint was removed")}}async handle(e,t){return{removed:await gn(e.storeKey,t.id)}}},Hr=class{static{s(this,"ListLogpoints")}name(){return"debug_list-logpoints"}description(){return"Lists all active logpoints on the Node.js process."}inputSchema(){return{}}outputSchema(){return{logpoints:ut.array(ut.any()).describe("Active logpoints")}}async handle(e,t){return{logpoints:dt(e.storeKey).filter(r=>r.kind==="logpoint").map(r=>({id:r.id,urlPattern:r.urlPattern,lineNumber:r.lineNumber,logExpression:r.logExpression,condition:r.condition,hitCondition:r.hitCondition,hitCount:r.hitCount,resolvedLocations:r.resolvedLocations,enabled:r.enabled}))}}},Wr=class{static{s(this,"ClearLogpoints")}name(){return"debug_clear-logpoints"}description(){return"Removes all logpoints from the Node.js process."}inputSchema(){return{}}outputSchema(){return{cleared:ut.number().describe("Number of logpoints cleared")}}async handle(e,t){let n=dt(e.storeKey).filter(i=>i.kind==="logpoint"),r=0;for(let i of n)await gn(e.storeKey,i.id)&&r++;return{cleared:r}}};import{z as Ds}from"zod";var qr=class{static{s(this,"PutExceptionpoint")}name(){return"debug_put-exceptionpoint"}description(){return`
1006
1020
  Sets the exception tracepoint state for a Node.js process:
1007
1021
  - "none": Don't capture on exceptions
1008
1022
  - "uncaught": Capture only on uncaught exceptions
1009
1023
  - "all": Capture on all exceptions (caught and uncaught)
1010
1024
 
1011
1025
  When an exception occurs, a snapshot is captured with exception details.
1012
- `}inputSchema(){return{state:Rs.enum(["none","uncaught","all"]).describe("Exception tracepoint state")}}outputSchema(){return{state:Rs.string().describe("New exception tracepoint state"),previousState:Rs.string().describe("Previous state")}}async handle(e,t){let n=Mn(e.storeKey);return await si(e.storeKey,t.state),{state:t.state,previousState:n}}};import{z as Ze}from"zod";var Wr=class{static{s(this,"PutLogpoint")}name(){return"debug_put-logpoint"}description(){return`
1026
+ `}inputSchema(){return{state:Ds.enum(["none","uncaught","all"]).describe("Exception tracepoint state")}}outputSchema(){return{state:Ds.string().describe("New exception tracepoint state"),previousState:Ds.string().describe("Previous state")}}async handle(e,t){let n=Dn(e.storeKey);return await ui(e.storeKey,t.state),{state:t.state,previousState:n}}};import{z as et}from"zod";var $r=class{static{s(this,"PutLogpoint")}name(){return"debug_put-logpoint"}description(){return`
1013
1027
  Puts a logpoint on a Node.js backend process.
1014
1028
  When the logpoint is hit, the logExpression is evaluated and the result
1015
1029
  is captured in the snapshot's logResult field.
@@ -1023,7 +1037,7 @@ logExpression examples:
1023
1037
  - Simple value: "user.name"
1024
1038
  - Template: "\`User: \${user.name}, Age: \${user.age}\`"
1025
1039
  - Object: "{ user, timestamp: Date.now() }"
1026
- `}inputSchema(){return{urlPattern:Ze.string().describe('Script file path pattern (e.g., "server.js"). Auto-escaped.'),lineNumber:Ze.number().int().positive().describe("Line number (1-based)"),columnNumber:Ze.number().int().nonnegative().describe("Column number (1-based). Optional.").optional(),logExpression:Ze.string().describe("Expression to evaluate and log when hit"),condition:Ze.string().describe("Conditional expression - logpoint only hits if this evaluates to true").optional(),hitCondition:Ze.string().describe("Hit count condition").optional()}}outputSchema(){return{id:Ze.string().describe("Logpoint ID"),urlPattern:Ze.string().describe("URL pattern"),lineNumber:Ze.number().describe("Line number"),logExpression:Ze.string().describe("Log expression"),resolvedLocations:Ze.number().describe("Number of locations resolved")}}async handle(e,t){let n=await Dn(e.storeKey,{kind:"logpoint",urlPattern:t.urlPattern,lineNumber:t.lineNumber,columnNumber:t.columnNumber,logExpression:t.logExpression,condition:t.condition,hitCondition:t.hitCondition});return{id:n.id,urlPattern:n.urlPattern,lineNumber:n.lineNumber,logExpression:n.logExpression||"",resolvedLocations:n.resolvedLocations}}};import{z as je}from"zod";var $r=class{static{s(this,"PutTracepoint")}name(){return"debug_put-tracepoint"}description(){return`
1040
+ `}inputSchema(){return{urlPattern:et.string().describe('Script file path pattern (e.g., "server.js"). Auto-escaped.'),lineNumber:et.number().int().positive().describe("Line number (1-based)"),columnNumber:et.number().int().nonnegative().describe("Column number (1-based). Optional.").optional(),logExpression:et.string().describe("Expression to evaluate and log when hit"),condition:et.string().describe("Conditional expression - logpoint only hits if this evaluates to true").optional(),hitCondition:et.string().describe("Hit count condition").optional()}}outputSchema(){return{id:et.string().describe("Logpoint ID"),urlPattern:et.string().describe("URL pattern"),lineNumber:et.number().describe("Line number"),logExpression:et.string().describe("Log expression"),resolvedLocations:et.number().describe("Number of locations resolved")}}async handle(e,t){let n=await Bn(e.storeKey,{kind:"logpoint",urlPattern:t.urlPattern,lineNumber:t.lineNumber,columnNumber:t.columnNumber,logExpression:t.logExpression,condition:t.condition,hitCondition:t.hitCondition});return{id:n.id,urlPattern:n.urlPattern,lineNumber:n.lineNumber,logExpression:n.logExpression||"",resolvedLocations:n.resolvedLocations}}};import{z as Ve}from"zod";var jr=class{static{s(this,"PutTracepoint")}name(){return"debug_put-tracepoint"}description(){return`
1027
1041
  Puts a non-blocking tracepoint on a Node.js backend process.
1028
1042
  When hit, a snapshot of the call stack and local variables is captured
1029
1043
  automatically without pausing execution.
@@ -1037,26 +1051,26 @@ DO NOT escape characters yourself.
1037
1051
 
1038
1052
  Returns resolvedLocations: number of scripts where the tracepoint was set.
1039
1053
  If 0, the pattern didn't match any loaded scripts.
1040
- `}inputSchema(){return{urlPattern:je.string().describe('Script file path pattern (e.g., "server.js"). Auto-escaped.'),lineNumber:je.number().int().positive().describe("Line number (1-based)"),columnNumber:je.number().int().nonnegative().describe("Column number (1-based). Optional.").optional(),condition:je.string().describe("Conditional expression - only triggers if this evaluates to true").optional(),hitCondition:je.string().describe('Hit count condition, e.g., "== 5", ">= 10", "% 10 == 0"').optional()}}outputSchema(){return{id:je.string().describe("Tracepoint ID"),urlPattern:je.string().describe("URL pattern"),lineNumber:je.number().describe("Line number"),columnNumber:je.number().optional().describe("Column number"),condition:je.string().optional().describe("Condition expression"),hitCondition:je.string().optional().describe("Hit count condition"),resolvedLocations:je.number().describe("Number of locations where tracepoint was resolved")}}async handle(e,t){let n=await Dn(e.storeKey,{kind:"tracepoint",urlPattern:t.urlPattern,lineNumber:t.lineNumber,columnNumber:t.columnNumber,condition:t.condition,hitCondition:t.hitCondition});return{id:n.id,urlPattern:n.urlPattern,lineNumber:n.lineNumber,columnNumber:n.columnNumber,condition:n.condition,hitCondition:n.hitCondition,resolvedLocations:n.resolvedLocations}}};import{z as Nt}from"zod";var jr=class{static{s(this,"ResolveSourceLocation")}name(){return"debug_resolve-source-location"}description(){return`
1054
+ `}inputSchema(){return{urlPattern:Ve.string().describe('Script file path pattern (e.g., "server.js"). Auto-escaped.'),lineNumber:Ve.number().int().positive().describe("Line number (1-based)"),columnNumber:Ve.number().int().nonnegative().describe("Column number (1-based). Optional.").optional(),condition:Ve.string().describe("Conditional expression - only triggers if this evaluates to true").optional(),hitCondition:Ve.string().describe('Hit count condition, e.g., "== 5", ">= 10", "% 10 == 0"').optional()}}outputSchema(){return{id:Ve.string().describe("Tracepoint ID"),urlPattern:Ve.string().describe("URL pattern"),lineNumber:Ve.number().describe("Line number"),columnNumber:Ve.number().optional().describe("Column number"),condition:Ve.string().optional().describe("Condition expression"),hitCondition:Ve.string().optional().describe("Hit count condition"),resolvedLocations:Ve.number().describe("Number of locations where tracepoint was resolved")}}async handle(e,t){let n=await Bn(e.storeKey,{kind:"tracepoint",urlPattern:t.urlPattern,lineNumber:t.lineNumber,columnNumber:t.columnNumber,condition:t.condition,hitCondition:t.hitCondition});return{id:n.id,urlPattern:n.urlPattern,lineNumber:n.lineNumber,columnNumber:n.columnNumber,condition:n.condition,hitCondition:n.hitCondition,resolvedLocations:n.resolvedLocations}}};import{z as Ot}from"zod";var zr=class{static{s(this,"ResolveSourceLocation")}name(){return"debug_resolve-source-location"}description(){return`
1041
1055
  Resolves a generated/bundled code location to its original source via source maps.
1042
1056
  Useful for translating minified stack traces or bundle line numbers to original TypeScript/JavaScript source.
1043
1057
 
1044
1058
  Requires an active Node.js debug connection (call debug_connect first).
1045
1059
  Input: generated script URL (e.g. file path), line, column (1-based).
1046
1060
  Output: original source path, line, column when a source map is available.
1047
- `}inputSchema(){return{url:Nt.string().describe("Generated script URL (e.g. file:///path/to/dist/app.js)"),line:Nt.number().int().positive().describe("Line number in generated code (1-based)"),column:Nt.number().int().nonnegative().describe("Column number in generated code (1-based, default 1)").optional()}}outputSchema(){return{resolved:Nt.boolean().describe("Whether the location was resolved to original source"),source:Nt.string().optional().describe("Original source file path"),line:Nt.number().optional().describe("Line number in original source (1-based)"),column:Nt.number().optional().describe("Column number in original source (1-based)"),name:Nt.string().optional().describe("Original identifier name if available")}}async handle(e,t){let n=await ri(e.storeKey,t.url,t.line,t.column??1);return n?{resolved:!0,source:n.source,line:n.line,column:n.column,name:n.name}:{resolved:!1}}};import{z as ft}from"zod";var zr=class{static{s(this,"Status")}name(){return"debug_status"}description(){return`
1061
+ `}inputSchema(){return{url:Ot.string().describe("Generated script URL (e.g. file:///path/to/dist/app.js)"),line:Ot.number().int().positive().describe("Line number in generated code (1-based)"),column:Ot.number().int().nonnegative().describe("Column number in generated code (1-based, default 1)").optional()}}outputSchema(){return{resolved:Ot.boolean().describe("Whether the location was resolved to original source"),source:Ot.string().optional().describe("Original source file path"),line:Ot.number().optional().describe("Line number in original source (1-based)"),column:Ot.number().optional().describe("Column number in original source (1-based)"),name:Ot.string().optional().describe("Original identifier name if available")}}async handle(e,t){let n=await li(e.storeKey,t.url,t.line,t.column??1);return n?{resolved:!0,source:n.source,line:n.line,column:n.column,name:n.name}:{resolved:!1}}};import{z as gt}from"zod";var Vr=class{static{s(this,"Status")}name(){return"debug_status"}description(){return`
1048
1062
  Returns the current Node.js debugging status including:
1049
1063
  - Whether connected and debugging is enabled
1050
1064
  - Source map status
1051
1065
  - Exceptionpoint state
1052
1066
  - Count of tracepoints, logpoints, watches
1053
1067
  - Snapshot statistics
1054
- `}inputSchema(){return{}}outputSchema(){return{connected:ft.boolean().describe("Whether connected to a Node.js process"),enabled:ft.boolean().describe("Whether debugging is enabled"),pid:ft.number().optional().describe("Connected process PID"),hasSourceMaps:ft.boolean().describe("Whether source maps are loaded"),exceptionBreakpoint:ft.string().describe("Exceptionpoint state"),tracepointCount:ft.number().describe("Number of tracepoints"),logpointCount:ft.number().describe("Number of logpoints"),watchExpressionCount:ft.number().describe("Number of watch expressions"),snapshotStats:ft.any().nullable().describe("Snapshot statistics")}}async handle(e,t){if(!e.isConnected)return{connected:!1,enabled:!1,hasSourceMaps:!1,exceptionBreakpoint:"none",tracepointCount:0,logpointCount:0,watchExpressionCount:0,snapshotStats:null};let n=e.storeKey,r=oi(n),i=bt(n);return{connected:!0,enabled:r,pid:e.processInfo?.pid,hasSourceMaps:pi(n),exceptionBreakpoint:Mn(n),tracepointCount:i.filter(a=>a.kind==="tracepoint").length,logpointCount:i.filter(a=>a.kind==="logpoint").length,watchExpressionCount:An(n).length,snapshotStats:r?ai(n):null}}};import{z as Pt}from"zod";var Vr=class{static{s(this,"AddWatch")}name(){return"debug_add-watch"}description(){return`
1068
+ `}inputSchema(){return{}}outputSchema(){return{connected:gt.boolean().describe("Whether connected to a Node.js process"),enabled:gt.boolean().describe("Whether debugging is enabled"),pid:gt.number().optional().describe("Connected process PID"),hasSourceMaps:gt.boolean().describe("Whether source maps are loaded"),exceptionBreakpoint:gt.string().describe("Exceptionpoint state"),tracepointCount:gt.number().describe("Number of tracepoints"),logpointCount:gt.number().describe("Number of logpoints"),watchExpressionCount:gt.number().describe("Number of watch expressions"),snapshotStats:gt.any().nullable().describe("Snapshot statistics")}}async handle(e,t){if(!e.isConnected)return{connected:!1,enabled:!1,hasSourceMaps:!1,exceptionBreakpoint:"none",tracepointCount:0,logpointCount:0,watchExpressionCount:0,snapshotStats:null};let n=e.storeKey,r=ai(n),i=dt(n);return{connected:!0,enabled:r,pid:e.processInfo?.pid,hasSourceMaps:gi(n),exceptionBreakpoint:Dn(n),tracepointCount:i.filter(a=>a.kind==="tracepoint").length,logpointCount:i.filter(a=>a.kind==="logpoint").length,watchExpressionCount:Ln(n).length,snapshotStats:r?mi(n):null}}};import{z as Nt}from"zod";var Gr=class{static{s(this,"AddWatch")}name(){return"debug_add-watch"}description(){return`
1055
1069
  Adds a watch expression to be evaluated at every tracepoint hit on the Node.js process.
1056
1070
  Watch expression results are included in the snapshot's watchResults field.
1057
1071
 
1058
1072
  Examples: "user.name", "this.state", "items.length", "JSON.stringify(config)"
1059
- `}inputSchema(){return{expression:Pt.string().describe("JavaScript expression to watch")}}outputSchema(){return{id:Pt.string().describe("Watch expression ID"),expression:Pt.string().describe("The expression")}}async handle(e,t){let n=ui(e.storeKey,t.expression);return{id:n.id,expression:n.expression}}},Gr=class{static{s(this,"RemoveWatch")}name(){return"debug_remove-watch"}description(){return"Removes a watch expression by its ID."}inputSchema(){return{id:Pt.string().describe("Watch expression ID to remove")}}outputSchema(){return{removed:Pt.boolean().describe("Whether the watch was removed")}}async handle(e,t){return{removed:ci(e.storeKey,t.id)}}},Kr=class{static{s(this,"ListWatches")}name(){return"debug_list-watches"}description(){return"Lists all active watch expressions."}inputSchema(){return{}}outputSchema(){return{watches:Pt.array(Pt.any()).describe("Active watch expressions")}}async handle(e,t){return{watches:An(e.storeKey)}}},Xr=class{static{s(this,"ClearWatches")}name(){return"debug_clear-watches"}description(){return"Removes all watch expressions."}inputSchema(){return{}}outputSchema(){return{cleared:Pt.number().describe("Number of watches cleared")}}async handle(e,t){return{cleared:mi(e.storeKey)}}};var vl=[new vr,new Or,new zr,new $r,new Br,new Ar,new Lr,new Wr,new Fr,new Ur,new Hr,new qr,new Er,new Rr,new Nr,new kr,new Pr,new _r,new Dr,new jr,new Vr,new Gr,new Kr,new Xr];import{z as ks}from"zod";var Jr=class{static{s(this,"RunJsInNode")}name(){return"run_js-in-node"}description(){return`
1073
+ `}inputSchema(){return{expression:Nt.string().describe("JavaScript expression to watch")}}outputSchema(){return{id:Nt.string().describe("Watch expression ID"),expression:Nt.string().describe("The expression")}}async handle(e,t){let n=di(e.storeKey,t.expression);return{id:n.id,expression:n.expression}}},Kr=class{static{s(this,"RemoveWatch")}name(){return"debug_remove-watch"}description(){return"Removes a watch expression by its ID."}inputSchema(){return{id:Nt.string().describe("Watch expression ID to remove")}}outputSchema(){return{removed:Nt.boolean().describe("Whether the watch was removed")}}async handle(e,t){return{removed:bi(e.storeKey,t.id)}}},Xr=class{static{s(this,"ListWatches")}name(){return"debug_list-watches"}description(){return"Lists all active watch expressions."}inputSchema(){return{}}outputSchema(){return{watches:Nt.array(Nt.any()).describe("Active watch expressions")}}async handle(e,t){return{watches:Ln(e.storeKey)}}},Yr=class{static{s(this,"ClearWatches")}name(){return"debug_clear-watches"}description(){return"Removes all watch expressions."}inputSchema(){return{}}outputSchema(){return{cleared:Nt.number().describe("Number of watches cleared")}}async handle(e,t){return{cleared:hi(e.storeKey)}}};var Nl=[new Er,new Or,new Vr,new jr,new Ar,new Lr,new Fr,new $r,new Ur,new Hr,new Wr,new qr,new Nr,new kr,new Pr,new _r,new Rr,new Mr,new Br,new zr,new Gr,new Kr,new Xr,new Yr];import{z as Bs}from"zod";var Jr=class{static{s(this,"RunJsInNode")}name(){return"run_js-in-node"}description(){return`
1060
1074
  Runs custom JavaScript INSIDE the connected Node.js process using CDP Runtime.evaluate.
1061
1075
 
1062
1076
  This code executes in the NODE PROCESS CONTEXT (real Node.js environment):
@@ -1075,13 +1089,13 @@ Notes:
1075
1089
  - Execution blocks the Node event loop until the script completes
1076
1090
  - Long-running scripts will block the process; use short expressions
1077
1091
  - Return value must be serializable (JSON-compatible)
1078
- `}inputSchema(){return{script:ks.string().describe("JavaScript code to execute in the Node process."),timeoutMs:ks.number().int().min(100).max(3e4).describe("Max evaluation time in milliseconds (default: 5000, max: 30000).").optional()}}outputSchema(){return{result:ks.any().describe("The result of the evaluation. Can be primitives, arrays, or objects. Must be serializable (JSON-compatible).")}}async handle(e,t){return{result:await di(e.storeKey,t.script,t.timeoutMs??5e3)}}};var Ol=[new Jr];import{EventEmitter as Zc}from"node:events";import{WebSocket as em}from"ws";var _s=class extends Zc{static{s(this,"NodeCDPSession")}ws=null;reqId=0;pending=new Map;connected=!1;wsUrl;constructor(e){super(),this.wsUrl=e}async connect(){if(!this.connected)return new Promise((e,t)=>{this.ws=new em(this.wsUrl);let n=setTimeout(()=>{t(new Error(`Connection timeout to ${this.wsUrl}`)),this.ws?.close()},1e4);this.ws.on("open",()=>{clearTimeout(n),this.connected=!0,e()}),this.ws.on("error",r=>{clearTimeout(n),this.connected||t(r)}),this.ws.on("close",()=>{this.connected=!1;for(let[r,i]of this.pending)i.reject(new Error("CDP session closed"));this.pending.clear()}),this.ws.on("message",r=>{try{let i=JSON.parse(r.toString());this._handleMessage(i)}catch{}})})}async send(e,t){if(!this.ws||!this.connected)throw new Error("CDP session is not connected");let n=++this.reqId;return new Promise((r,i)=>{this.pending.set(n,{resolve:r,reject:i});let a=JSON.stringify({id:n,method:e,params:t||{}});this.ws.send(a,l=>{l&&(this.pending.delete(n),i(l))}),setTimeout(()=>{this.pending.has(n)&&(this.pending.delete(n),i(new Error(`CDP command timeout: ${e}`)))},3e4)})}async detach(){if(this.ws){this.connected=!1,this.ws.close(),this.ws=null;for(let[,e]of this.pending)e.reject(new Error("CDP session detached"));this.pending.clear()}}isConnected(){return this.connected}_handleMessage(e){if(e.id!==void 0){let t=this.pending.get(e.id);t&&(this.pending.delete(e.id),e.error?t.reject(new Error(`CDP error: ${e.error.message||JSON.stringify(e.error)}`)):t.resolve(e.result||{}))}else e.method&&this.emit(e.method,e.params)}};async function xn(o){let e=new _s(o);return await e.connect(),e}s(xn,"createNodeCDPSession");import{execSync as In}from"node:child_process";import*as El from"node:http";var Rt="127.0.0.1",an=9229,Ms=1e4,Nl=200,tm=20;async function Yr(o=Rt,e=an,t=5e3){return new Promise((n,r)=>{let i=setTimeout(()=>{r(new Error(`Inspector discovery timeout on ${o}:${e}`))},t),a=El.get(`http://${o}:${e}/json/list`,l=>{let u="";l.on("data",m=>{u+=m}),l.on("end",()=>{clearTimeout(i);try{let m=JSON.parse(u);n(m)}catch{r(new Error(`Invalid response from inspector at ${o}:${e}`))}})});a.on("error",l=>{clearTimeout(i),r(new Error(`Cannot reach inspector at ${o}:${e}: ${l.message}`))}),a.end()})}s(Yr,"discoverInspectorTargets");async function nm(o=Rt,e=an,t=tm){for(let n=e;n<e+t;n++)try{let r=await Yr(o,n,1e3);if(r.length>0)return{port:n,targets:r}}catch{}return null}s(nm,"scanForInspector");function om(o){try{let e=process.platform,t;e==="win32"?t=In(`wmic process where "name like '%node%'" get ProcessId,CommandLine /format:csv`,{encoding:"utf-8",timeout:5e3}):t=In('ps aux | grep -E "[n]ode|[t]s-node|[n]px"',{encoding:"utf-8",timeout:5e3});let n=[];for(let r of t.split(`
1079
- `)){let i=r.trim();if(i)if(e==="win32"){let a=i.split(",");if(a.length>=3){let l=parseInt(a[a.length-1],10),u=a.slice(1,-1).join(",");!isNaN(l)&&l>0&&n.push({pid:l,command:u})}}else{let a=i.split(/\s+/);if(a.length>=11){let l=parseInt(a[1],10),u=a.slice(10).join(" ");!isNaN(l)&&l>0&&n.push({pid:l,command:u})}}}if(o){let r=new RegExp(o,"i");return n.filter(i=>r.test(i.command))}return n}catch{return[]}}s(om,"findNodeProcesses");async function rm(o,e=Rt,t=Ms){if(process.platform==="win32")throw new Error("SIGUSR1 activation is not supported on Windows. Start the Node.js process with --inspect flag or NODE_OPTIONS=--inspect instead.");try{process.kill(o,0)}catch{throw new Error(`Process ${o} does not exist or is not accessible`)}G(`Sending SIGUSR1 to process ${o} to activate V8 Inspector...`),process.kill(o,"SIGUSR1");let n=Date.now();for(;Date.now()-n<t;){let r=await nm(e,an,10);if(r)return G(`Inspector activated on port ${r.port} for process ${o}`),r;await new Promise(i=>setTimeout(i,Nl))}throw new Error(`Timeout waiting for inspector to activate on process ${o}`)}s(rm,"activateInspector");function sm(o){try{let t=In(`docker ps -q -f name=${o}`,{encoding:"utf-8",timeout:5e3}).trim().split(`
1080
- `).filter(Boolean);return t.length===0?null:(t.length>1&&G(`Multiple containers match "${o}", using first: ${t[0]}`),t[0])}catch(e){if(/Cannot connect to the Docker daemon|docker: command not found/i.test(e.message??""))throw new Error(`${e.message} When MCP runs in a container, mount /var/run/docker.sock and ensure the docker CLI is available.`);return null}}s(sm,"resolveContainerId");async function im(o,e=Rt,t=an,n=Ms){if(process.platform==="win32")throw new Error("Docker container activation may have limitations on Windows. Ensure the container has port 9229 exposed and Node is started with --inspect.");let r;try{let a=In(`docker exec ${o} sh -c "ps aux 2>/dev/null | grep '[n]ode' | head -1"`,{encoding:"utf-8",timeout:5e3}).trim();if(!a)throw new Error(`No Node.js process found inside container ${o}`);if(r=a.split(/\s+/).filter(Boolean)[1]||"",!r||!/^\d+$/.test(r))throw new Error(`Could not parse Node PID from container ${o}`)}catch(a){if(a.message?.includes("No Node.js process"))throw a;let l=/Cannot connect to the Docker daemon|docker: command not found/i.test(a.message??"")?" When MCP runs in a container, mount /var/run/docker.sock and ensure the docker CLI is available.":"";throw new Error(`Cannot find Node process in container ${o}: ${a.message}. Ensure Docker is running and the container has a Node.js process.${l}`)}G(`Sending SIGUSR1 to Node process ${r} inside container ${o}...`);try{In(`docker exec ${o} kill -USR1 ${r}`,{encoding:"utf-8",timeout:5e3})}catch(a){let l=/Cannot connect to the Docker daemon|docker: command not found/i.test(a.message??"")?" When MCP runs in a container, mount /var/run/docker.sock and ensure the docker CLI is available.":"";throw new Error(`Failed to send SIGUSR1 to container ${o}: ${a.message}${l}`)}let i=Date.now();for(;Date.now()-i<n;){try{let a=await Yr(e,t,2e3);if(a.length>0)return G(`Inspector active at ${e}:${t} for container ${o}`),{port:t,targets:a}}catch{}await new Promise(a=>setTimeout(a,Nl))}throw new Error(`Timeout waiting for inspector from container ${o}. Ensure the container exposes port 9229 (e.g. docker run -p 9229:9229 ...) and Node is started with --inspect or --inspect=0.0.0.0:9229.`)}s(im,"activateInspectorInContainer");async function Pl(o){let e=o.host||Rt,t=o.timeoutMs||Ms,n=o.activateIfNeeded!==!1;if(o.wsUrl)return G(`Connecting to Node.js inspector via WebSocket: ${o.wsUrl}`),{session:await xn(o.wsUrl),processInfo:{pid:0,inspectorActive:!0,webSocketUrl:o.wsUrl},target:{id:"direct",type:"node",title:"Direct WebSocket connection",url:"",webSocketDebuggerUrl:o.wsUrl}};let r=o.containerId??null;if(!r&&o.containerName&&(r=sm(o.containerName),!r))throw new Error(`No running container found matching name: ${o.containerName}`);if(r){let m=o.port||an,c=[];try{c=await Yr(e,m,3e3)}catch{}if(c.length===0&&n&&(G(`Inspector not active. Activating via SIGUSR1 in container ${r}...`),c=(await im(r,e,m,t)).targets),c.length===0)throw new Error(`Cannot connect to Node.js in container ${r}. Inspector not active. Ensure port 9229 is exposed (e.g. -p 9229:9229) and use activateIfNeeded or start Node with --inspect.`);let p=c[0],b=p.webSocketDebuggerUrl;return e!==Rt&&(b=b.replace(/ws:\/\/[^:]+:/,`ws://${e}:`)),{session:await xn(b),processInfo:{pid:0,inspectorActive:!0,inspectorHost:e,inspectorPort:m,webSocketUrl:b,containerId:r},target:p}}let i=o.pid,a;if(!i&&o.processName){let m=om(o.processName);if(m.length===0)throw new Error(`No Node.js process found matching: ${o.processName}`);if(m.length>1){let c=m.map(p=>` PID ${p.pid}: ${p.command}`).join(`
1092
+ `}inputSchema(){return{script:Bs.string().describe("JavaScript code to execute in the Node process."),timeoutMs:Bs.number().int().min(100).max(3e4).describe("Max evaluation time in milliseconds (default: 5000, max: 30000).").optional()}}outputSchema(){return{result:Bs.any().describe("The result of the evaluation. Can be primitives, arrays, or objects. Must be serializable (JSON-compatible).")}}async handle(e,t){return{result:await fi(e.storeKey,t.script,t.timeoutMs??5e3)}}};var Pl=[new Jr];import{EventEmitter as im}from"node:events";import{WebSocket as am}from"ws";var As=class extends im{static{s(this,"NodeCDPSession")}ws=null;reqId=0;pending=new Map;connected=!1;wsUrl;constructor(e){super(),this.wsUrl=e}async connect(){if(!this.connected)return new Promise((e,t)=>{this.ws=new am(this.wsUrl);let n=setTimeout(()=>{t(new Error(`Connection timeout to ${this.wsUrl}`)),this.ws?.close()},1e4);this.ws.on("open",()=>{clearTimeout(n),this.connected=!0,e()}),this.ws.on("error",r=>{clearTimeout(n),this.connected||t(r)}),this.ws.on("close",()=>{this.connected=!1;for(let[r,i]of this.pending)i.reject(new Error("CDP session closed"));this.pending.clear()}),this.ws.on("message",r=>{try{let i=JSON.parse(r.toString());this._handleMessage(i)}catch{}})})}async send(e,t){if(!this.ws||!this.connected)throw new Error("CDP session is not connected");let n=++this.reqId;return new Promise((r,i)=>{this.pending.set(n,{resolve:r,reject:i});let a=JSON.stringify({id:n,method:e,params:t||{}});this.ws.send(a,l=>{l&&(this.pending.delete(n),i(l))}),setTimeout(()=>{this.pending.has(n)&&(this.pending.delete(n),i(new Error(`CDP command timeout: ${e}`)))},3e4)})}async detach(){if(this.ws){this.connected=!1,this.ws.close(),this.ws=null;for(let[,e]of this.pending)e.reject(new Error("CDP session detached"));this.pending.clear()}}isConnected(){return this.connected}_handleMessage(e){if(e.id!==void 0){let t=this.pending.get(e.id);t&&(this.pending.delete(e.id),e.error?t.reject(new Error(`CDP error: ${e.error.message||JSON.stringify(e.error)}`)):t.resolve(e.result||{}))}else e.method&&this.emit(e.method,e.params)}};async function vn(o){let e=new As(o);return await e.connect(),e}s(vn,"createNodeCDPSession");import{execSync as In}from"node:child_process";import*as Rl from"node:http";var Pt="127.0.0.1",ln=9229,Ls=1e4,kl=200,lm=20;async function Qr(o=Pt,e=ln,t=5e3){return new Promise((n,r)=>{let i=setTimeout(()=>{r(new Error(`Inspector discovery timeout on ${o}:${e}`))},t),a=Rl.get(`http://${o}:${e}/json/list`,l=>{let u="";l.on("data",m=>{u+=m}),l.on("end",()=>{clearTimeout(i);try{let m=JSON.parse(u);n(m)}catch{r(new Error(`Invalid response from inspector at ${o}:${e}`))}})});a.on("error",l=>{clearTimeout(i),r(new Error(`Cannot reach inspector at ${o}:${e}: ${l.message}`))}),a.end()})}s(Qr,"discoverInspectorTargets");async function um(o=Pt,e=ln,t=lm){for(let n=e;n<e+t;n++)try{let r=await Qr(o,n,1e3);if(r.length>0)return{port:n,targets:r}}catch{}return null}s(um,"scanForInspector");function cm(o){try{let e=process.platform,t;e==="win32"?t=In(`wmic process where "name like '%node%'" get ProcessId,CommandLine /format:csv`,{encoding:"utf-8",timeout:5e3}):t=In('ps aux | grep -E "[n]ode|[t]s-node|[n]px"',{encoding:"utf-8",timeout:5e3});let n=[];for(let r of t.split(`
1093
+ `)){let i=r.trim();if(i)if(e==="win32"){let a=i.split(",");if(a.length>=3){let l=parseInt(a[a.length-1],10),u=a.slice(1,-1).join(",");!isNaN(l)&&l>0&&n.push({pid:l,command:u})}}else{let a=i.split(/\s+/);if(a.length>=11){let l=parseInt(a[1],10),u=a.slice(10).join(" ");!isNaN(l)&&l>0&&n.push({pid:l,command:u})}}}if(o){let r=new RegExp(o,"i");return n.filter(i=>r.test(i.command))}return n}catch{return[]}}s(cm,"findNodeProcesses");async function mm(o,e=Pt,t=Ls){if(process.platform==="win32")throw new Error("SIGUSR1 activation is not supported on Windows. Start the Node.js process with --inspect flag or NODE_OPTIONS=--inspect instead.");try{process.kill(o,0)}catch{throw new Error(`Process ${o} does not exist or is not accessible`)}K(`Sending SIGUSR1 to process ${o} to activate V8 Inspector...`),process.kill(o,"SIGUSR1");let n=Date.now();for(;Date.now()-n<t;){let r=await um(e,ln,10);if(r)return K(`Inspector activated on port ${r.port} for process ${o}`),r;await new Promise(i=>setTimeout(i,kl))}throw new Error(`Timeout waiting for inspector to activate on process ${o}`)}s(mm,"activateInspector");function pm(o){try{let t=In(`docker ps -q -f name=${o}`,{encoding:"utf-8",timeout:5e3}).trim().split(`
1094
+ `).filter(Boolean);return t.length===0?null:(t.length>1&&K(`Multiple containers match "${o}", using first: ${t[0]}`),t[0])}catch(e){if(/Cannot connect to the Docker daemon|docker: command not found/i.test(e.message??""))throw new Error(`${e.message} When MCP runs in a container, mount /var/run/docker.sock and ensure the docker CLI is available.`);return null}}s(pm,"resolveContainerId");async function dm(o,e=Pt,t=ln,n=Ls){if(process.platform==="win32")throw new Error("Docker container activation may have limitations on Windows. Ensure the container has port 9229 exposed and Node is started with --inspect.");let r;try{let a=In(`docker exec ${o} sh -c "ps aux 2>/dev/null | grep '[n]ode' | head -1"`,{encoding:"utf-8",timeout:5e3}).trim();if(!a)throw new Error(`No Node.js process found inside container ${o}`);if(r=a.split(/\s+/).filter(Boolean)[1]||"",!r||!/^\d+$/.test(r))throw new Error(`Could not parse Node PID from container ${o}`)}catch(a){if(a.message?.includes("No Node.js process"))throw a;let l=/Cannot connect to the Docker daemon|docker: command not found/i.test(a.message??"")?" When MCP runs in a container, mount /var/run/docker.sock and ensure the docker CLI is available.":"";throw new Error(`Cannot find Node process in container ${o}: ${a.message}. Ensure Docker is running and the container has a Node.js process.${l}`)}K(`Sending SIGUSR1 to Node process ${r} inside container ${o}...`);try{In(`docker exec ${o} kill -USR1 ${r}`,{encoding:"utf-8",timeout:5e3})}catch(a){let l=/Cannot connect to the Docker daemon|docker: command not found/i.test(a.message??"")?" When MCP runs in a container, mount /var/run/docker.sock and ensure the docker CLI is available.":"";throw new Error(`Failed to send SIGUSR1 to container ${o}: ${a.message}${l}`)}let i=Date.now();for(;Date.now()-i<n;){try{let a=await Qr(e,t,2e3);if(a.length>0)return K(`Inspector active at ${e}:${t} for container ${o}`),{port:t,targets:a}}catch{}await new Promise(a=>setTimeout(a,kl))}throw new Error(`Timeout waiting for inspector from container ${o}. Ensure the container exposes port 9229 (e.g. docker run -p 9229:9229 ...) and Node is started with --inspect or --inspect=0.0.0.0:9229.`)}s(dm,"activateInspectorInContainer");async function _l(o){let e=o.host||Pt,t=o.timeoutMs||Ls,n=o.activateIfNeeded!==!1;if(o.wsUrl)return K(`Connecting to Node.js inspector via WebSocket: ${o.wsUrl}`),{session:await vn(o.wsUrl),processInfo:{pid:0,inspectorActive:!0,webSocketUrl:o.wsUrl},target:{id:"direct",type:"node",title:"Direct WebSocket connection",url:"",webSocketDebuggerUrl:o.wsUrl}};let r=o.containerId??null;if(!r&&o.containerName&&(r=pm(o.containerName),!r))throw new Error(`No running container found matching name: ${o.containerName}`);if(r){let m=o.port||ln,c=[];try{c=await Qr(e,m,3e3)}catch{}if(c.length===0&&n&&(K(`Inspector not active. Activating via SIGUSR1 in container ${r}...`),c=(await dm(r,e,m,t)).targets),c.length===0)throw new Error(`Cannot connect to Node.js in container ${r}. Inspector not active. Ensure port 9229 is exposed (e.g. -p 9229:9229) and use activateIfNeeded or start Node with --inspect.`);let p=c[0],b=p.webSocketDebuggerUrl;return e!==Pt&&(b=b.replace(/ws:\/\/[^:]+:/,`ws://${e}:`)),{session:await vn(b),processInfo:{pid:0,inspectorActive:!0,inspectorHost:e,inspectorPort:m,webSocketUrl:b,containerId:r},target:p}}let i=o.pid,a;if(!i&&o.processName){let m=cm(o.processName);if(m.length===0)throw new Error(`No Node.js process found matching: ${o.processName}`);if(m.length>1){let c=m.map(p=>` PID ${p.pid}: ${p.command}`).join(`
1081
1095
  `);throw new Error(`Multiple Node.js processes match "${o.processName}":
1082
1096
  ${c}
1083
- Please specify a PID directly.`)}i=m[0].pid,a=m[0].command,G(`Found Node.js process: PID ${i} - ${a}`)}let l=o.port||an,u=[];try{u=await Yr(e,l,3e3)}catch{}if(u.length>0){let m=u[0];G(`Inspector already active at ${e}:${l}, connecting...`);let c=m.webSocketDebuggerUrl;return e!==Rt&&(c=c.replace(/ws:\/\/[^:]+:/,`ws://${e}:`)),{session:await xn(c),processInfo:{pid:i||0,command:a,inspectorActive:!0,inspectorHost:e,inspectorPort:l,webSocketUrl:c},target:m}}if(i&&n){G(`Inspector not active on ${e}:${l}. Activating via SIGUSR1 on PID ${i}...`);let{port:m,targets:c}=await rm(i,e,t);if(c.length===0)throw new Error(`Inspector activated on port ${m} but no targets found`);let p=c[0],b=p.webSocketDebuggerUrl;return e!==Rt&&(b=b.replace(/ws:\/\/[^:]+:/,`ws://${e}:`)),{session:await xn(b),processInfo:{pid:i,command:a,inspectorActive:!0,inspectorHost:e,inspectorPort:m,webSocketUrl:b},target:p}}throw i?new Error(`Cannot connect to process ${i}. Inspector is not active and activation failed. Try starting the process with NODE_OPTIONS=--inspect or --inspect flag.`):new Error("No target specified. Provide a PID, process name, port, or WebSocket URL. If the process is not started with --inspect, provide a PID to activate via SIGUSR1.")}s(Pl,"connectToNodeProcess");var Cn=class{static{s(this,"NodeToolSessionContext")}_sessionId;_connection=null;_storeKey=null;closed=!1;constructor(e){this._sessionId=e}sessionId(){return this._sessionId}async connect(e){if(this._connection)throw new Error("Already connected to a Node.js process. Disconnect first.");G(`Connecting to Node.js process with options: ${JSON.stringify(e)}`);let t=await Pl(e);return this._connection=t,this._storeKey=ei(t.processInfo.pid,t.processInfo.webSocketUrl),await ti(this._storeKey,t.session,{pid:t.processInfo.pid,command:t.processInfo.command}),G(`Connected to Node.js process: PID=${t.processInfo.pid}, store=${this._storeKey}`),{processInfo:t.processInfo,target:t.target}}async disconnect(){!this._connection||!this._storeKey||(G(`Disconnecting from Node.js process: ${this._storeKey}`),await ni(this._storeKey),await this._connection.session.detach(),this._connection=null,this._storeKey=null)}get storeKey(){if(!this._storeKey)throw new Error("Not connected to any Node.js process. Call connect first.");return this._storeKey}get isConnected(){return this._connection!==null&&this._connection.session.isConnected()}get processInfo(){return this._connection?.processInfo??null}async close(){return this.closed?!1:(await this.disconnect(),this.closed=!0,!0)}};var vn=class{static{s(this,"NodeToolExecutor")}sessionIdProvider;sessionContext;constructor(e){this.sessionIdProvider=e}_sessionContext(){if(!this.sessionContext){let e=this.sessionIdProvider();this.sessionContext=new Cn(e),G(`Created Node.js session context for session ${e}`)}return this.sessionContext}async executeTool(e,t){G(`Executing Node.js tool ${e.name()} with input: ${dn(t)}`);try{let n=this._sessionContext(),r=await e.handle(n,t);return G(`Executed Node.js tool ${e.name()} successfully`),r}catch(n){throw G(`Error executing Node.js tool ${e.name()}: ${n}`),n}}};var On=[...vl,...Ol];function Ds(o){return new vn(o)}s(Ds,"createToolExecutor");var Bs=class{static{s(this,"NodeCliProvider")}platform="node";cliName="node-devtools-cli";tools=On;sessionDescription="Manage Node.js debugging sessions";cliExamples=["node-devtools-cli interactive","node-devtools-cli connect --pid 12345"];bashCompletionOptions="";bashCompletionCommands="daemon session tools config completion interactive connect disconnect status tracepoint logpoint exceptionpoint watch";zshCompletionOptions="";zshCompletionCommands=[{name:"daemon",description:"Manage the daemon server"},{name:"session",description:"Manage Node.js debug sessions"},{name:"tools",description:"List and inspect available tools"},{name:"config",description:"Show current configuration"},{name:"completion",description:"Generate shell completion scripts"},{name:"interactive",description:"Start interactive REPL mode"},{name:"connect",description:"Connect to a Node.js process"},{name:"disconnect",description:"Disconnect from current process"},{name:"status",description:"Show connection status"},{name:"tracepoint",description:"Tracepoint commands"},{name:"logpoint",description:"Logpoint commands"},{name:"exceptionpoint",description:"Exceptionpoint commands"},{name:"watch",description:"Watch expression commands"}];replPrompt="node> ";cliDescription="Node.js DevTools MCP CLI";packageName="browser-devtools-mcp";buildEnv(e){return{...process.env}}addOptions(e){return e}getConfig(){return{consoleMessagesBufferSize:Pn}}formatConfig(e){return[" Node.js:",` Console Messages Buffer: ${e.consoleMessagesBufferSize??Pn}`].join(`
1084
- `)}formatConfigForRepl(e){return` console-messages-buffer = ${Pn}`}},Rl=new Bs;var As=`
1097
+ Please specify a PID directly.`)}i=m[0].pid,a=m[0].command,K(`Found Node.js process: PID ${i} - ${a}`)}let l=o.port||ln,u=[];try{u=await Qr(e,l,3e3)}catch{}if(u.length>0){let m=u[0];K(`Inspector already active at ${e}:${l}, connecting...`);let c=m.webSocketDebuggerUrl;return e!==Pt&&(c=c.replace(/ws:\/\/[^:]+:/,`ws://${e}:`)),{session:await vn(c),processInfo:{pid:i||0,command:a,inspectorActive:!0,inspectorHost:e,inspectorPort:l,webSocketUrl:c},target:m}}if(i&&n){K(`Inspector not active on ${e}:${l}. Activating via SIGUSR1 on PID ${i}...`);let{port:m,targets:c}=await mm(i,e,t);if(c.length===0)throw new Error(`Inspector activated on port ${m} but no targets found`);let p=c[0],b=p.webSocketDebuggerUrl;return e!==Pt&&(b=b.replace(/ws:\/\/[^:]+:/,`ws://${e}:`)),{session:await vn(b),processInfo:{pid:i,command:a,inspectorActive:!0,inspectorHost:e,inspectorPort:m,webSocketUrl:b},target:p}}throw i?new Error(`Cannot connect to process ${i}. Inspector is not active and activation failed. Try starting the process with NODE_OPTIONS=--inspect or --inspect flag.`):new Error("No target specified. Provide a PID, process name, port, or WebSocket URL. If the process is not started with --inspect, provide a PID to activate via SIGUSR1.")}s(_l,"connectToNodeProcess");var Cn=class{static{s(this,"NodeToolSessionContext")}_sessionId;_connection=null;_storeKey=null;closed=!1;constructor(e){this._sessionId=e}sessionId(){return this._sessionId}async connect(e){if(this._connection)throw new Error("Already connected to a Node.js process. Disconnect first.");K(`Connecting to Node.js process with options: ${JSON.stringify(e)}`);let t=await _l(e);return this._connection=t,this._storeKey=ri(t.processInfo.pid,t.processInfo.webSocketUrl),await si(this._storeKey,t.session,{pid:t.processInfo.pid,command:t.processInfo.command}),K(`Connected to Node.js process: PID=${t.processInfo.pid}, store=${this._storeKey}`),{processInfo:t.processInfo,target:t.target}}async disconnect(){!this._connection||!this._storeKey||(K(`Disconnecting from Node.js process: ${this._storeKey}`),await ii(this._storeKey),await this._connection.session.detach(),this._connection=null,this._storeKey=null)}get storeKey(){if(!this._storeKey)throw new Error("Not connected to any Node.js process. Call connect first.");return this._storeKey}get isConnected(){return this._connection!==null&&this._connection.session.isConnected()}get processInfo(){return this._connection?.processInfo??null}async close(){return this.closed?!1:(await this.disconnect(),this.closed=!0,!0)}};var En=class{static{s(this,"NodeToolExecutor")}sessionIdProvider;sessionContext;constructor(e){this.sessionIdProvider=e}_sessionContext(){if(!this.sessionContext){let e=this.sessionIdProvider();this.sessionContext=new Cn(e),K(`Created Node.js session context for session ${e}`)}return this.sessionContext}async executeTool(e,t){K(`Executing Node.js tool ${e.name()} with input: ${hn(t)}`);try{let n=this._sessionContext(),r=await e.handle(n,t);return K(`Executed Node.js tool ${e.name()} successfully`),r}catch(n){throw K(`Error executing Node.js tool ${e.name()}: ${n}`),n}}};var On=[...Nl,...Pl];function Fs(o){return new En(o)}s(Fs,"createToolExecutor");var Us=class{static{s(this,"NodeCliProvider")}platform="node";cliName="node-devtools-cli";tools=On;sessionDescription="Manage Node.js debugging sessions";cliExamples=["node-devtools-cli interactive","node-devtools-cli connect --pid 12345"];bashCompletionOptions="";bashCompletionCommands="daemon session tools config completion interactive connect disconnect status tracepoint logpoint exceptionpoint watch";zshCompletionOptions="";zshCompletionCommands=[{name:"daemon",description:"Manage the daemon server"},{name:"session",description:"Manage Node.js debug sessions"},{name:"tools",description:"List and inspect available tools"},{name:"config",description:"Show current configuration"},{name:"completion",description:"Generate shell completion scripts"},{name:"interactive",description:"Start interactive REPL mode"},{name:"connect",description:"Connect to a Node.js process"},{name:"disconnect",description:"Disconnect from current process"},{name:"status",description:"Show connection status"},{name:"tracepoint",description:"Tracepoint commands"},{name:"logpoint",description:"Logpoint commands"},{name:"exceptionpoint",description:"Exceptionpoint commands"},{name:"watch",description:"Watch expression commands"}];replPrompt="node> ";cliDescription="Node.js DevTools MCP CLI";packageName="browser-devtools-mcp";buildEnv(e){return{...process.env}}addOptions(e){return e}getConfig(){return{consoleMessagesBufferSize:Rn}}formatConfig(e){return[" Node.js:",` Console Messages Buffer: ${e.consoleMessagesBufferSize??Rn}`].join(`
1098
+ `)}formatConfigForRepl(e){return` console-messages-buffer = ${Rn}`}},Ml=new Us;var Hs=`
1085
1099
  Node.js Backend Debugging Platform
1086
1100
 
1087
1101
  This platform provides non-blocking V8 debugging for Node.js backend processes.
@@ -1113,7 +1127,7 @@ and provides the same debugging capabilities as browser debugging.
1113
1127
  3. Trigger the code paths (e.g., make API requests)
1114
1128
  4. Retrieve captured snapshots with call stack, variables, and watch results
1115
1129
  5. Disconnect when done
1116
- `,Ls=`
1130
+ `,Ws=`
1117
1131
  Node.js Debugging Best Practices:
1118
1132
  - Always connect before attempting to set probes
1119
1133
  - Use logpoints for lightweight monitoring, tracepoints for full context
@@ -1121,4 +1135,4 @@ Node.js Debugging Best Practices:
1121
1135
  - Use source maps when debugging TypeScript or compiled code
1122
1136
  - Disconnect cleanly when done to avoid leaving inspector sessions open
1123
1137
  - Use exception breakpoints to catch unhandled errors
1124
- `;var kl={serverInfo:{instructions:As,policies:[Ls]},toolsInfo:{tools:On,createToolExecutor:Ds},cliInfo:{cliProvider:Rl}};function am(){return qs==="node"?kl:Il}s(am,"_resolvePlatformInfo");var ex=am();export{ex as a};
1138
+ `;var Dl={serverInfo:{instructions:Hs,policies:[Ws]},toolsInfo:{tools:On,createToolExecutor:Fs},cliInfo:{cliProvider:Ml}};function bm(){return zs==="node"?Dl:El}s(bm,"_resolvePlatformInfo");var ax=bm();export{ax as a};