@buoy-gg/mcp 7.0.77 → 7.0.78

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
1
  import{createRequire as q}from"module";const fe=q(import.meta.url);import I from"fs";import R from"os";import y from"path";var G='// Buoy Web helper. Chrome starts it for the Buoy Web extension (native messaging) and\n// ends it when Chrome closes. It passes messages between the extension and Buoy MCP\n// sessions, which connect over a Unix socket only this user can open.\n//\n// extension <-- stdin/stdout (native messaging) --> helper <-- ~/.buoy/web/chrome-<pid>.sock --> MCP sessions\nimport fs from "node:fs";\nimport net from "node:net";\nimport os from "node:os";\nimport path from "node:path";\n\nconst dir = process.env.BUOY_WEB_DIR ?? path.join(os.homedir(), ".buoy", "web");\nfs.mkdirSync(dir, { recursive: true, mode: 0o700 });\nfs.chmodSync(dir, 0o700);\nconst sock = path.join(dir, `chrome-${process.pid}.sock`);\nconst info = path.join(dir, `chrome-${process.pid}.json`);\n\n// ---- native messaging: 4-byte little-endian length, then JSON -----------------\nlet inbuf = Buffer.alloc(0);\nprocess.stdin.on("data", (chunk) => {\n inbuf = Buffer.concat([inbuf, chunk]);\n while (inbuf.length >= 4) {\n const n = inbuf.readUInt32LE(0);\n if (inbuf.length < 4 + n) break;\n const msg = JSON.parse(inbuf.subarray(4, 4 + n).toString("utf8"));\n inbuf = inbuf.subarray(4 + n);\n fromExtension(msg);\n }\n});\nprocess.stdin.on("end", quit); // Chrome closed or the extension let go\nprocess.stdout.on("error", quit);\nfunction toExtension(msg) {\n const body = Buffer.from(JSON.stringify(msg), "utf8");\n if (body.length > 1024 * 1024) throw new Error("Message too big for Chrome (over 1 MB).");\n const head = Buffer.alloc(4);\n head.writeUInt32LE(body.length, 0);\n process.stdout.write(Buffer.concat([head, body]));\n}\n\n// ---- MCP sessions: one JSON message per line ------------------------------------\nconst clients = new Map(); // id -> socket\nlet nextClient = 1;\nfunction fromExtension(msg) {\n const s = clients.get(msg.c);\n if (!s) return;\n const { c, ...rest } = msg;\n s.write(JSON.stringify(rest) + "\\n");\n}\n\nconst server = net.createServer((s) => {\n const c = nextClient++;\n clients.set(c, s);\n let buf = "";\n s.setEncoding("utf8");\n s.on("data", (d) => {\n buf += d;\n let i;\n while ((i = buf.indexOf("\\n")) >= 0) {\n const line = buf.slice(0, i);\n buf = buf.slice(i + 1);\n if (!line) continue;\n let msg;\n try {\n msg = JSON.parse(line);\n toExtension({ ...msg, c });\n } catch (e) {\n if (msg?.id != null) s.write(JSON.stringify({ id: msg.id, error: String(e.message ?? e) }) + "\\n");\n }\n }\n });\n const gone = () => {\n if (!clients.delete(c)) return;\n try {\n toExtension({ c, method: "client.closed" });\n } catch {}\n };\n s.on("close", gone);\n s.on("error", gone);\n});\n\n// Clear out sockets left by helpers that died without cleaning up.\nfor (const f of fs.readdirSync(dir)) {\n const m = /^chrome-(\\d+)\\.(sock|json)$/.exec(f);\n if (!m || Number(m[1]) === process.pid) continue;\n try {\n process.kill(Number(m[1]), 0);\n } catch {\n fs.rmSync(path.join(dir, f), { force: true });\n }\n}\n\nconst old = process.umask(0o177); // the socket file is created 0600\nserver.listen(sock, () => {\n process.umask(old);\n fs.writeFileSync(info, JSON.stringify({ pid: process.pid, sock, started: Date.now() }), { mode: 0o600 });\n // Tells Buoy the extension is set up, so a closed Chrome isn\'t mistaken for "no extension".\n fs.writeFileSync(path.join(dir, "seen"), new Date().toISOString(), { mode: 0o600 });\n toExtension({ ready: true }); // the extension shows "connected" only after this\n});\n\nfunction quit() {\n for (const f of [sock, info]) fs.rmSync(f, { force: true });\n process.exit(0);\n}\nprocess.on("SIGTERM", quit);\nprocess.on("SIGINT", quit);\n';import V from"crypto";import N from"fs";import X from"http";import K from"net";import z from"os";import U from"path";import{WebSocketServer as Q}from"ws";var Z=process.env.BUOY_WEB_RELAYLOG==="1";var M=(...n)=>Z&&process.stderr.write(`[buoy-web relay] ${n.join(" ")}
2
2
  `);var x=()=>process.env.BUOY_WEB_DIR??U.join(z.homedir(),".buoy","web");function ee(n=x()){let e=[];try{e=N.readdirSync(n)}catch{return[]}const i=[];for(const o of e){const a=/^chrome-(\d+)\.json$/.exec(o);if(!a)continue;try{process.kill(Number(a[1]),0);const b=JSON.parse(N.readFileSync(U.join(n,o),"utf8"));if(N.existsSync(b.sock))i.push(b)}catch{}}return i.sort((o,a)=>a.started-o.started)}function te(n){return new Promise((e,i)=>{const o=K.createConnection(n);const a=new Map;let b=1;let l="";let d=false;let v=false;const w={onEvent:()=>{},onClose:()=>{},call(m,S){if(v)return Promise.reject(new Error("Chrome's Buoy helper closed."));const c=b++;o.write(JSON.stringify({id:c,method:m,params:S})+"\n");return new Promise((O,B)=>a.set(c,{res:O,rej:B}))},close:()=>o.end()};o.setEncoding("utf8");o.on("connect",()=>{d=true;e(w)});o.on("error",m=>{if(!d)i(m)});o.on("data",m=>{l+=m;let S;while((S=l.indexOf("\n"))>=0){const c=JSON.parse(l.slice(0,S));l=l.slice(S+1);if(c.id!=null&&a.has(c.id)){const{res:O,rej:B}=a.get(c.id);a.delete(c.id);if(c.error)B(new Error(c.error));else O(c.result)}else if(c.event)w.onEvent(c.event,c.params)}});o.on("close",()=>{v=true;for(const{rej:m}of a.values())m(new Error("Chrome's Buoy helper closed."));a.clear();w.onClose()})})}async function ne({sock:n}){const e=await te(n);const i=await e.call("hello");const o=new Map;let a=1;let b=false;let l=null;const d=new Set;const v=t=>{if(l?.readyState===1)l.send(JSON.stringify(t))};const w=t=>[...o.values()].find(t);const m={url:"",hello:i,onDetach:()=>{},onClose:()=>{},idle:()=>Promise.all([...d]),close:()=>{}};async function S(t,{settle:r=false}={}){const s=o.get(t);if(s)return s;await e.call("debugger.attach",{tabId:t});if(r){const E=Date.now();while(Date.now()-E<5e3){const T=await e.call("debugger.send",{tabId:t,method:"Runtime.evaluate",params:{expression:"[location.href, document.readyState]",returnByValue:true}}).catch(()=>null);const[D,L]=T?.result?.value??[];if(D&&D!=="about:blank"&&L!=="loading")break;await new Promise(H=>setTimeout(H,50))}}const{targetInfo:u}=await e.call("debugger.send",{tabId:t,method:"Target.getTargetInfo"});const{openerId:g,openerFrameId:f,...p}=u;p.canAccessOpener=false;const h={tabId:t,sessionId:`buoy-tab-${a++}`,targetInfo:p,children:new Set,framesSent:false,held:[]};o.set(t,h);v({method:"Target.attachedToTarget",params:{sessionId:h.sessionId,targetInfo:{...p,attached:true},waitingForDebugger:false}});return h}function c(t){const r=o.get(t);if(!r)return;o.delete(t);v({method:"Target.detachedFromTarget",params:{sessionId:r.sessionId,targetId:r.targetInfo?.targetId}})}e.onEvent=(t,r)=>{if(t==="debugger.event"){const s=o.get(r.tabId);if(!s)return;const u=r.params?.sessionId;if(r.method==="Target.attachedToTarget"&&u)s.children.add(u);if(r.method==="Target.detachedFromTarget"&&u)s.children.delete(u);const g={sessionId:r.sessionId||s.sessionId,method:r.method,params:r.params};if(!s.framesSent)s.held.push(g);else v(g)}else if(t==="debugger.detached"){c(r.tabId);m.onDetach(r)}else if(t==="tabs.created"){if(b){const s=S(r.id,{settle:true}).catch(()=>{});d.add(s);void s.finally(()=>d.delete(s))}}else if(t==="tabs.removed")c(r.tabId)};e.onClose=()=>{for(const t of[...o.keys()])c(t);l?.close();m.onClose()};async function O(t,r,s){if(!s){switch(t){case"Browser.getVersion":return{protocolVersion:"1.3",product:"Chrome/BuoyWeb",userAgent:i.userAgent,jsVersion:""};case"Browser.setDownloadBehavior":case"Target.setDiscoverTargets":case"Browser.close":return{};case"Target.setAutoAttach":b=true;return{};case"Target.getTargetInfo":return{targetInfo:{targetId:"buoy-browser",type:"browser",title:"",url:"",attached:true,canAccessOpener:false}};case"Target.getBrowserContexts":return{browserContextIds:[]};case"Target.createTarget":{const p=await e.call("tabs.create",{url:r?.url});const h=await S(p.id);return{targetId:h.targetInfo.targetId}}case"Target.closeTarget":{const p=w(h=>h.targetInfo?.targetId===r?.targetId);if(!p)return{success:false};await e.call("tabs.remove",{tabId:p.tabId});return{success:true}}}const f=o.values().next().value;if(!f)throw new Error(`No Buoy tab to run ${t} on.`);return e.call("debugger.send",{tabId:f.tabId,method:t,params:r})}if(t==="Target.getTargetInfo"){const f=w(p=>p.sessionId===s);if(f)return{targetInfo:f.targetInfo}}let u=w(f=>f.sessionId===s);let g;if(!u){u=w(f=>f.children.has(s));g=s}if(!u)throw new Error(`No Buoy tab for session ${s}.`);return e.call("debugger.send",{tabId:u.tabId,sessionId:g,method:t,params:r})}const B=V.randomUUID();const _=X.createServer((t,r)=>r.writeHead(404).end());const C=new Q({server:_});C.on("connection",(t,r)=>{if(r.url!==`/${B}`||l)return t.close(4004,"No.");l=t;t.on("message",async s=>{const{id:u,sessionId:g,method:f,params:p}=JSON.parse(s.toString());try{const h=await O(f,p,g);M("ok ",g??"-",f);t.send(JSON.stringify({id:u,sessionId:g,result:h??{}}));if(f==="Page.getFrameTree"){const E=w(T=>T.sessionId===g);if(E&&!E.framesSent){E.framesSent=true;for(const T of E.held.splice(0))v(T)}}}catch(h){M("ERR",g??"-",f,h.message);t.send(JSON.stringify({id:u,sessionId:g,error:{message:String(h.message??h)}}))}});t.on("close",()=>{l=null;e.close()})});await new Promise(t=>_.listen(0,"127.0.0.1",t));m.url=`ws://127.0.0.1:${_.address().port}/${B}`;m.close=()=>{e.close();C.close();_.close()};return m}var J="gg.buoy.web";var $=["cfolfiajhlenfifknbomdogooagnlamf","kjbgbjimhjiocnfifnemmenkondjeifp",...(process.env.BUOY_WEB_EXTENSION_IDS??"").split(",").filter(Boolean)];var A=["Google/Chrome","Google/Chrome Beta","Google/Chrome Dev","Google/Chrome Canary","Chromium","BraveSoftware/Brave-Browser","Microsoft Edge","Vivaldi","Arc/User Data"];function P(){if(process.env.BUOY_WEB_NMH_DIRS)return process.env.BUOY_WEB_NMH_DIRS.split(y.delimiter).filter(Boolean);if(process.platform!=="darwin")return[];const n=y.join(R.homedir(),"Library","Application Support");return A.map(e=>y.join(n,e)).filter(e=>I.existsSync(e)).map(e=>y.join(e,"NativeMessagingHosts"))}var j=(n,e,i)=>{try{if(I.readFileSync(n,"utf8")===e)return}catch{}I.writeFileSync(n,e,{mode:i});I.chmodSync(n,i)};function oe(){try{const n=y.join(x(),"helper");I.mkdirSync(n,{recursive:true,mode:448});const e=y.join(n,"helper.mjs");const i=y.join(n,"helper.sh");j(e,G,384);const o=d=>`'${d.replace(/'/g,`'\\''`)}'`;const a=process.env.BUOY_WEB_DIR?`BUOY_WEB_DIR=${o(process.env.BUOY_WEB_DIR)} `:"";j(i,`#!/bin/sh
3
3
  ${a}exec ${o(process.execPath)} ${o(e)} "$@"
4
- `,448);const b=JSON.stringify({name:J,description:"Buoy Web helper: lets the Buoy MCP use Buoy's own tabs through the Buoy Web extension.",path:i,type:"stdio",allowed_origins:$.map(d=>`chrome-extension://${d}/`)},null,2);const l=[];for(const d of P()){try{I.mkdirSync(d,{recursive:true});j(y.join(d,`${J}.json`),b+"\n",420);l.push(d)}catch{}}return l}catch{return[]}}function re(){if(process.env.BUOY_WEB_NMH_DIRS)return false;if(process.platform!=="darwin")return false;const n=y.join(R.homedir(),"Library","Application Support");for(const e of A){let i=[];try{i=I.readdirSync(y.join(n,e))}catch{continue}for(const o of i){if(o!=="Default"&&!/^Profile \d+$/.test(o))continue;if($.some(a=>I.existsSync(y.join(n,e,o,"Extensions",a))))return true}}return false}import se from"crypto";import k from"fs";import W from"path";var ie=process.env.BUOY_TELEMETRY_URL??"https://buoy.gg/api/t";var ae=24*60*60*1e3;function Y(){const n=(process.env.BUOY_TELEMETRY??"").toLowerCase();return n==="0"||n==="false"||n==="off"||process.env.DO_NOT_TRACK==="1"}var F=false;function ce(){if(F||Y())return;F=true;try{const n=W.join(x(),"install.json");let e={};try{e=JSON.parse(k.readFileSync(n,"utf8"))}catch{}if(typeof e.installId!=="string")e={installId:se.randomUUID(),lastPingAt:0};if(Date.now()-(e.lastPingAt??0)<ae)return;e.lastPingAt=Date.now();k.mkdirSync(W.dirname(n),{recursive:true,mode:448});k.writeFileSync(n,JSON.stringify(e),{mode:384});const i=JSON.stringify({installId:e.installId,version:"7.0.77",platform:process.platform==="darwin"?"macos":process.platform==="win32"?"windows":"linux",tier:"locked",surface:"web-mcp"});void fetch(ie,{method:"POST",headers:{"content-type":"application/json"},body:i,signal:AbortSignal.timeout(5e3)}).catch(()=>{})}catch{}}export{x as webDir,ee as findHelpers,ne as startRelay,P as helperManifestDirs,oe as ensureHelper,re as extensionInstalled,Y as telemetryOff,ce as noteUse};
4
+ `,448);const b=JSON.stringify({name:J,description:"Buoy Web helper: lets the Buoy MCP use Buoy's own tabs through the Buoy Web extension.",path:i,type:"stdio",allowed_origins:$.map(d=>`chrome-extension://${d}/`)},null,2);const l=[];for(const d of P()){try{I.mkdirSync(d,{recursive:true});j(y.join(d,`${J}.json`),b+"\n",420);l.push(d)}catch{}}return l}catch{return[]}}function re(){if(process.env.BUOY_WEB_NMH_DIRS)return false;if(process.platform!=="darwin")return false;const n=y.join(R.homedir(),"Library","Application Support");for(const e of A){let i=[];try{i=I.readdirSync(y.join(n,e))}catch{continue}for(const o of i){if(o!=="Default"&&!/^Profile \d+$/.test(o))continue;if($.some(a=>I.existsSync(y.join(n,e,o,"Extensions",a))))return true}}return false}import se from"crypto";import k from"fs";import W from"path";var ie=process.env.BUOY_TELEMETRY_URL??"https://buoy.gg/api/t";var ae=24*60*60*1e3;function Y(){const n=(process.env.BUOY_TELEMETRY??"").toLowerCase();return n==="0"||n==="false"||n==="off"||process.env.DO_NOT_TRACK==="1"}var F=false;function ce(){if(F||Y())return;F=true;try{const n=W.join(x(),"install.json");let e={};try{e=JSON.parse(k.readFileSync(n,"utf8"))}catch{}if(typeof e.installId!=="string")e={installId:se.randomUUID(),lastPingAt:0};if(Date.now()-(e.lastPingAt??0)<ae)return;e.lastPingAt=Date.now();k.mkdirSync(W.dirname(n),{recursive:true,mode:448});k.writeFileSync(n,JSON.stringify(e),{mode:384});const i=JSON.stringify({installId:e.installId,version:"7.0.78",platform:process.platform==="darwin"?"macos":process.platform==="win32"?"windows":"linux",tier:"locked",surface:"web-mcp"});void fetch(ie,{method:"POST",headers:{"content-type":"application/json"},body:i,signal:AbortSignal.timeout(5e3)}).catch(()=>{})}catch{}}export{x as webDir,ee as findHelpers,ne as startRelay,P as helperManifestDirs,oe as ensureHelper,re as extensionInstalled,Y as telemetryOff,ce as noteUse};
@@ -1 +1 @@
1
- import{createRequire as e}from"module";const a=e(import.meta.url);var r="7.0.77"?"7.0.77":"0.0.0-dev";var o="@buoy-gg/mcp";export{r as VERSION,o as PACKAGE_NAME};
1
+ import{createRequire as e}from"module";const a=e(import.meta.url);var r="7.0.78"?"7.0.78":"0.0.0-dev";var o="@buoy-gg/mcp";export{r as VERSION,o as PACKAGE_NAME};
@@ -1,4 +1,4 @@
1
- import{createRequire as il}from"module";const eg=il(import.meta.url);import{PACKAGE_NAME as uo,VERSION as Nn}from"./chunk-3O76SJJM.mjs";import{accountRequired as Fn,farmFairness as rl,hasBuoyAccount as Bn,registerSimFarmTools as ol}from"./chunk-XA74T4JN.mjs";import{bootEnv as al,coreInfo as sl,ensureKeeper as cl,farmAdbTarget as ho,farmAdbTargets as ll,farmHome as dl,findShell as ul,installShell as hl,keeperAlive as Mt,keeperCall as ht,simLaunchEnv as pl,suggestCounts as fl}from"./chunk-ODGXMS2O.mjs";import{describeDevices as ml,describeDiagnosis as wl,describeInputs as gl,entitlementHasPro as jn,proRequired as bl,readEntitlement as vl,run as Be}from"./chunk-5NOZVPWB.mjs";import{accessFor as yl,currentAccess as pt,freeToolNames as $l,hasProAccess as de,isFreeAppCall as kl,meetsAccess as Ln,outsideCalls as _l,proRequiredMessage as rn,runWithAccess as po}from"./chunk-D5K6WO6B.mjs";import{freeComparison as Sl,freeJsTop as xl,freeRanking as Bi,freeWebBench as Tl,nothingLocked as qn,withLockedLines as Et}from"./chunk-OP23W722.mjs";import{GPU_RENDERER_JS as Dl,caseUrl as fo,closeWithin as Ct,formatWebBenchMarkdown as Il,isSoftwareGpu as mo,loadChromium as wo,runWebBench as Al,shuffled as Ml,snapRefreshRate as El,waitForHostLock as go,withDeadline as bo}from"./chunk-DVRR7W22.mjs";import{__commonJS as ee,__require as me,__toESM as Un}from"./chunk-MTTWR4T7.mjs";var vo=ee({"../../node_modules/pngjs/lib/chunkstream.js"(e,n){"use strict";var t=me("util");var i=me("stream");var r=n.exports=function(){i.call(this);this._buffers=[];this._buffered=0;this._reads=[];this._paused=false;this._encoding="utf8";this.writable=true};t.inherits(r,i);r.prototype.read=function(o,a){this._reads.push({length:Math.abs(o),allowLess:o<0,func:a});process.nextTick(function(){this._process();if(this._paused&&this._reads&&this._reads.length>0){this._paused=false;this.emit("drain")}}.bind(this))};r.prototype.write=function(o,a){if(!this.writable){this.emit("error",new Error("Stream not writable"));return false}let s;if(Buffer.isBuffer(o)){s=o}else{s=Buffer.from(o,a||this._encoding)}this._buffers.push(s);this._buffered+=s.length;this._process();if(this._reads&&this._reads.length===0){this._paused=true}return this.writable&&!this._paused};r.prototype.end=function(o,a){if(o){this.write(o,a)}this.writable=false;if(!this._buffers){return}if(this._buffers.length===0){this._end()}else{this._buffers.push(null);this._process()}};r.prototype.destroySoon=r.prototype.end;r.prototype._end=function(){if(this._reads.length>0){this.emit("error",new Error("Unexpected end of input"))}this.destroy()};r.prototype.destroy=function(){if(!this._buffers){return}this.writable=false;this._reads=null;this._buffers=null;this.emit("close")};r.prototype._processReadAllowingLess=function(o){this._reads.shift();let a=this._buffers[0];if(a.length>o.length){this._buffered-=o.length;this._buffers[0]=a.slice(o.length);o.func.call(this,a.slice(0,o.length))}else{this._buffered-=a.length;this._buffers.shift();o.func.call(this,a)}};r.prototype._processRead=function(o){this._reads.shift();let a=0;let s=0;let c=Buffer.alloc(o.length);while(a<o.length){let l=this._buffers[s++];let d=Math.min(l.length,o.length-a);l.copy(c,a,0,d);a+=d;if(d!==l.length){this._buffers[--s]=l.slice(d)}}if(s>0){this._buffers.splice(0,s)}this._buffered-=o.length;o.func.call(this,c)};r.prototype._process=function(){try{while(this._buffered>0&&this._reads&&this._reads.length>0){let o=this._reads[0];if(o.allowLess){this._processReadAllowingLess(o)}else if(this._buffered>=o.length){this._processRead(o)}else{break}}if(this._buffers&&!this.writable){this._end()}}catch(o){this.emit("error",o)}}}});var yo=ee({"../../node_modules/pngjs/lib/interlace.js"(e){"use strict";var n=[{x:[0],y:[0]},{x:[4],y:[0]},{x:[0,4],y:[4]},{x:[2,6],y:[0,4]},{x:[0,2,4,6],y:[2,6]},{x:[1,3,5,7],y:[0,2,4,6]},{x:[0,1,2,3,4,5,6,7],y:[1,3,5,7]}];e.getImagePasses=function(t,i){let r=[];let o=t%8;let a=i%8;let s=(t-o)/8;let c=(i-a)/8;for(let l=0;l<n.length;l++){let d=n[l];let u=s*d.x.length;let h=c*d.y.length;for(let b=0;b<d.x.length;b++){if(d.x[b]<o){u++}else{break}}for(let b=0;b<d.y.length;b++){if(d.y[b]<a){h++}else{break}}if(u>0&&h>0){r.push({width:u,height:h,index:l})}}return r};e.getInterlaceIterator=function(t){return function(i,r,o){let a=i%n[o].x.length;let s=(i-a)/n[o].x.length*8+n[o].x[a];let c=r%n[o].y.length;let l=(r-c)/n[o].y.length*8+n[o].y[c];return s*4+l*t*4}}}});var $o=ee({"../../node_modules/pngjs/lib/paeth-predictor.js"(e,n){"use strict";n.exports=function t(i,r,o){let a=i+r-o;let s=Math.abs(a-i);let c=Math.abs(a-r);let l=Math.abs(a-o);if(s<=c&&s<=l){return i}if(c<=l){return r}return o}}});var ko=ee({"../../node_modules/pngjs/lib/filter-parse.js"(e,n){"use strict";var t=yo();var i=$o();function r(a,s,c){let l=a*s;if(c!==8){l=Math.ceil(l/(8/c))}return l}var o=n.exports=function(a,s){let c=a.width;let l=a.height;let d=a.interlace;let u=a.bpp;let h=a.depth;this.read=s.read;this.write=s.write;this.complete=s.complete;this._imageIndex=0;this._images=[];if(d){let b=t.getImagePasses(c,l);for(let p=0;p<b.length;p++){this._images.push({byteWidth:r(b[p].width,u,h),height:b[p].height,lineIndex:0})}}else{this._images.push({byteWidth:r(c,u,h),height:l,lineIndex:0})}if(h===8){this._xComparison=u}else if(h===16){this._xComparison=u*2}else{this._xComparison=1}};o.prototype.start=function(){this.read(this._images[this._imageIndex].byteWidth+1,this._reverseFilterLine.bind(this))};o.prototype._unFilterType1=function(a,s,c){let l=this._xComparison;let d=l-1;for(let u=0;u<c;u++){let h=a[1+u];let b=u>d?s[u-l]:0;s[u]=h+b}};o.prototype._unFilterType2=function(a,s,c){let l=this._lastLine;for(let d=0;d<c;d++){let u=a[1+d];let h=l?l[d]:0;s[d]=u+h}};o.prototype._unFilterType3=function(a,s,c){let l=this._xComparison;let d=l-1;let u=this._lastLine;for(let h=0;h<c;h++){let b=a[1+h];let p=u?u[h]:0;let w=h>d?s[h-l]:0;let g=Math.floor((w+p)/2);s[h]=b+g}};o.prototype._unFilterType4=function(a,s,c){let l=this._xComparison;let d=l-1;let u=this._lastLine;for(let h=0;h<c;h++){let b=a[1+h];let p=u?u[h]:0;let w=h>d?s[h-l]:0;let g=h>d&&u?u[h-l]:0;let m=i(w,p,g);s[h]=b+m}};o.prototype._reverseFilterLine=function(a){let s=a[0];let c;let l=this._images[this._imageIndex];let d=l.byteWidth;if(s===0){c=a.slice(1,d+1)}else{c=Buffer.alloc(d);switch(s){case 1:this._unFilterType1(a,c,d);break;case 2:this._unFilterType2(a,c,d);break;case 3:this._unFilterType3(a,c,d);break;case 4:this._unFilterType4(a,c,d);break;default:throw new Error("Unrecognised filter type - "+s)}}this.write(c);l.lineIndex++;if(l.lineIndex>=l.height){this._lastLine=null;this._imageIndex++;l=this._images[this._imageIndex]}else{this._lastLine=c}if(l){this.read(l.byteWidth+1,this._reverseFilterLine.bind(this))}else{this._lastLine=null;this.complete()}}}});var Cl=ee({"../../node_modules/pngjs/lib/filter-parse-async.js"(e,n){"use strict";var t=me("util");var i=vo();var r=ko();var o=n.exports=function(a){i.call(this);let s=[];let c=this;this._filter=new r(a,{read:this.read.bind(this),write:function(l){s.push(l)},complete:function(){c.emit("complete",Buffer.concat(s))}});this._filter.start()};t.inherits(o,i)}});var on=ee({"../../node_modules/pngjs/lib/constants.js"(e,n){"use strict";n.exports={PNG_SIGNATURE:[137,80,78,71,13,10,26,10],TYPE_IHDR:1229472850,TYPE_IEND:1229278788,TYPE_IDAT:1229209940,TYPE_PLTE:1347179589,TYPE_tRNS:1951551059,TYPE_gAMA:1732332865,COLORTYPE_GRAYSCALE:0,COLORTYPE_PALETTE:1,COLORTYPE_COLOR:2,COLORTYPE_ALPHA:4,COLORTYPE_PALETTE_COLOR:3,COLORTYPE_COLOR_ALPHA:6,COLORTYPE_TO_BPP_MAP:{0:1,2:3,3:1,4:2,6:4},GAMMA_DIVISION:1e5}}});var _o=ee({"../../node_modules/pngjs/lib/crc.js"(e,n){"use strict";var t=[];(function(){for(let r=0;r<256;r++){let o=r;for(let a=0;a<8;a++){if(o&1){o=3988292384^o>>>1}else{o=o>>>1}}t[r]=o}})();var i=n.exports=function(){this._crc=-1};i.prototype.write=function(r){for(let o=0;o<r.length;o++){this._crc=t[(this._crc^r[o])&255]^this._crc>>>8}return true};i.prototype.crc32=function(){return this._crc^-1};i.crc32=function(r){let o=-1;for(let a=0;a<r.length;a++){o=t[(o^r[a])&255]^o>>>8}return o^-1}}});var So=ee({"../../node_modules/pngjs/lib/parser.js"(e,n){"use strict";var t=on();var i=_o();var r=n.exports=function(o,a){this._options=o;o.checkCRC=o.checkCRC!==false;this._hasIHDR=false;this._hasIEND=false;this._emittedHeadersFinished=false;this._palette=[];this._colorType=0;this._chunks={};this._chunks[t.TYPE_IHDR]=this._handleIHDR.bind(this);this._chunks[t.TYPE_IEND]=this._handleIEND.bind(this);this._chunks[t.TYPE_IDAT]=this._handleIDAT.bind(this);this._chunks[t.TYPE_PLTE]=this._handlePLTE.bind(this);this._chunks[t.TYPE_tRNS]=this._handleTRNS.bind(this);this._chunks[t.TYPE_gAMA]=this._handleGAMA.bind(this);this.read=a.read;this.error=a.error;this.metadata=a.metadata;this.gamma=a.gamma;this.transColor=a.transColor;this.palette=a.palette;this.parsed=a.parsed;this.inflateData=a.inflateData;this.finished=a.finished;this.simpleTransparency=a.simpleTransparency;this.headersFinished=a.headersFinished||function(){}};r.prototype.start=function(){this.read(t.PNG_SIGNATURE.length,this._parseSignature.bind(this))};r.prototype._parseSignature=function(o){let a=t.PNG_SIGNATURE;for(let s=0;s<a.length;s++){if(o[s]!==a[s]){this.error(new Error("Invalid file signature"));return}}this.read(8,this._parseChunkBegin.bind(this))};r.prototype._parseChunkBegin=function(o){let a=o.readUInt32BE(0);let s=o.readUInt32BE(4);let c="";for(let d=4;d<8;d++){c+=String.fromCharCode(o[d])}let l=Boolean(o[4]&32);if(!this._hasIHDR&&s!==t.TYPE_IHDR){this.error(new Error("Expected IHDR on beggining"));return}this._crc=new i;this._crc.write(Buffer.from(c));if(this._chunks[s]){return this._chunks[s](a)}if(!l){this.error(new Error("Unsupported critical chunk type "+c));return}this.read(a+4,this._skipChunk.bind(this))};r.prototype._skipChunk=function(){this.read(8,this._parseChunkBegin.bind(this))};r.prototype._handleChunkEnd=function(){this.read(4,this._parseChunkEnd.bind(this))};r.prototype._parseChunkEnd=function(o){let a=o.readInt32BE(0);let s=this._crc.crc32();if(this._options.checkCRC&&s!==a){this.error(new Error("Crc error - "+a+" - "+s));return}if(!this._hasIEND){this.read(8,this._parseChunkBegin.bind(this))}};r.prototype._handleIHDR=function(o){this.read(o,this._parseIHDR.bind(this))};r.prototype._parseIHDR=function(o){this._crc.write(o);let a=o.readUInt32BE(0);let s=o.readUInt32BE(4);let c=o[8];let l=o[9];let d=o[10];let u=o[11];let h=o[12];if(c!==8&&c!==4&&c!==2&&c!==1&&c!==16){this.error(new Error("Unsupported bit depth "+c));return}if(!(l in t.COLORTYPE_TO_BPP_MAP)){this.error(new Error("Unsupported color type"));return}if(d!==0){this.error(new Error("Unsupported compression method"));return}if(u!==0){this.error(new Error("Unsupported filter method"));return}if(h!==0&&h!==1){this.error(new Error("Unsupported interlace method"));return}this._colorType=l;let b=t.COLORTYPE_TO_BPP_MAP[this._colorType];this._hasIHDR=true;this.metadata({width:a,height:s,depth:c,interlace:Boolean(h),palette:Boolean(l&t.COLORTYPE_PALETTE),color:Boolean(l&t.COLORTYPE_COLOR),alpha:Boolean(l&t.COLORTYPE_ALPHA),bpp:b,colorType:l});this._handleChunkEnd()};r.prototype._handlePLTE=function(o){this.read(o,this._parsePLTE.bind(this))};r.prototype._parsePLTE=function(o){this._crc.write(o);let a=Math.floor(o.length/3);for(let s=0;s<a;s++){this._palette.push([o[s*3],o[s*3+1],o[s*3+2],255])}this.palette(this._palette);this._handleChunkEnd()};r.prototype._handleTRNS=function(o){this.simpleTransparency();this.read(o,this._parseTRNS.bind(this))};r.prototype._parseTRNS=function(o){this._crc.write(o);if(this._colorType===t.COLORTYPE_PALETTE_COLOR){if(this._palette.length===0){this.error(new Error("Transparency chunk must be after palette"));return}if(o.length>this._palette.length){this.error(new Error("More transparent colors than palette size"));return}for(let a=0;a<o.length;a++){this._palette[a][3]=o[a]}this.palette(this._palette)}if(this._colorType===t.COLORTYPE_GRAYSCALE){this.transColor([o.readUInt16BE(0)])}if(this._colorType===t.COLORTYPE_COLOR){this.transColor([o.readUInt16BE(0),o.readUInt16BE(2),o.readUInt16BE(4)])}this._handleChunkEnd()};r.prototype._handleGAMA=function(o){this.read(o,this._parseGAMA.bind(this))};r.prototype._parseGAMA=function(o){this._crc.write(o);this.gamma(o.readUInt32BE(0)/t.GAMMA_DIVISION);this._handleChunkEnd()};r.prototype._handleIDAT=function(o){if(!this._emittedHeadersFinished){this._emittedHeadersFinished=true;this.headersFinished()}this.read(-o,this._parseIDAT.bind(this,o))};r.prototype._parseIDAT=function(o,a){this._crc.write(a);if(this._colorType===t.COLORTYPE_PALETTE_COLOR&&this._palette.length===0){throw new Error("Expected palette not found")}this.inflateData(a);let s=o-a.length;if(s>0){this._handleIDAT(s)}else{this._handleChunkEnd()}};r.prototype._handleIEND=function(o){this.read(o,this._parseIEND.bind(this))};r.prototype._parseIEND=function(o){this._crc.write(o);this._hasIEND=true;this._handleChunkEnd();if(this.finished){this.finished()}}}});var xo=ee({"../../node_modules/pngjs/lib/bitmapper.js"(e){"use strict";var n=yo();var t=[function(){},function(s,c,l,d){if(d===c.length){throw new Error("Ran out of data")}let u=c[d];s[l]=u;s[l+1]=u;s[l+2]=u;s[l+3]=255},function(s,c,l,d){if(d+1>=c.length){throw new Error("Ran out of data")}let u=c[d];s[l]=u;s[l+1]=u;s[l+2]=u;s[l+3]=c[d+1]},function(s,c,l,d){if(d+2>=c.length){throw new Error("Ran out of data")}s[l]=c[d];s[l+1]=c[d+1];s[l+2]=c[d+2];s[l+3]=255},function(s,c,l,d){if(d+3>=c.length){throw new Error("Ran out of data")}s[l]=c[d];s[l+1]=c[d+1];s[l+2]=c[d+2];s[l+3]=c[d+3]}];var i=[function(){},function(s,c,l,d){let u=c[0];s[l]=u;s[l+1]=u;s[l+2]=u;s[l+3]=d},function(s,c,l){let d=c[0];s[l]=d;s[l+1]=d;s[l+2]=d;s[l+3]=c[1]},function(s,c,l,d){s[l]=c[0];s[l+1]=c[1];s[l+2]=c[2];s[l+3]=d},function(s,c,l){s[l]=c[0];s[l+1]=c[1];s[l+2]=c[2];s[l+3]=c[3]}];function r(s,c){let l=[];let d=0;function u(){if(d===s.length){throw new Error("Ran out of data")}let h=s[d];d++;let b,p,w,g,m,f,y,v;switch(c){default:throw new Error("unrecognised depth");case 16:y=s[d];d++;l.push((h<<8)+y);break;case 4:y=h&15;v=h>>4;l.push(v,y);break;case 2:m=h&3;f=h>>2&3;y=h>>4&3;v=h>>6&3;l.push(v,y,f,m);break;case 1:b=h&1;p=h>>1&1;w=h>>2&1;g=h>>3&1;m=h>>4&1;f=h>>5&1;y=h>>6&1;v=h>>7&1;l.push(v,y,f,m,g,w,p,b);break}}return{get:function(h){while(l.length<h){u()}let b=l.slice(0,h);l=l.slice(h);return b},resetAfterLine:function(){l.length=0},end:function(){if(d!==s.length){throw new Error("extra data found")}}}}function o(s,c,l,d,u,h){let b=s.width;let p=s.height;let w=s.index;for(let g=0;g<p;g++){for(let m=0;m<b;m++){let f=l(m,g,w);t[d](c,u,f,h);h+=d}}return h}function a(s,c,l,d,u,h){let b=s.width;let p=s.height;let w=s.index;for(let g=0;g<p;g++){for(let m=0;m<b;m++){let f=u.get(d);let y=l(m,g,w);i[d](c,f,y,h)}u.resetAfterLine()}}e.dataToBitMap=function(s,c){let l=c.width;let d=c.height;let u=c.depth;let h=c.bpp;let b=c.interlace;let p;if(u!==8){p=r(s,u)}let w;if(u<=8){w=Buffer.alloc(l*d*4)}else{w=new Uint16Array(l*d*4)}let g=Math.pow(2,u)-1;let m=0;let f;let y;if(b){f=n.getImagePasses(l,d);y=n.getInterlaceIterator(l,d)}else{let v=0;y=function(){let $=v;v+=4;return $};f=[{width:l,height:d}]}for(let v=0;v<f.length;v++){if(u===8){m=o(f[v],w,y,h,s,m)}else{a(f[v],w,y,h,p,g)}}if(u===8){if(m!==s.length){throw new Error("extra data found")}}else{p.end()}return w}}});var To=ee({"../../node_modules/pngjs/lib/format-normaliser.js"(e,n){"use strict";function t(o,a,s,c,l){let d=0;for(let u=0;u<c;u++){for(let h=0;h<s;h++){let b=l[o[d]];if(!b){throw new Error("index "+o[d]+" not in palette")}for(let p=0;p<4;p++){a[d+p]=b[p]}d+=4}}}function i(o,a,s,c,l){let d=0;for(let u=0;u<c;u++){for(let h=0;h<s;h++){let b=false;if(l.length===1){if(l[0]===o[d]){b=true}}else if(l[0]===o[d]&&l[1]===o[d+1]&&l[2]===o[d+2]){b=true}if(b){for(let p=0;p<4;p++){a[d+p]=0}}d+=4}}}function r(o,a,s,c,l){let d=255;let u=Math.pow(2,l)-1;let h=0;for(let b=0;b<c;b++){for(let p=0;p<s;p++){for(let w=0;w<4;w++){a[h+w]=Math.floor(o[h+w]*d/u+.5)}h+=4}}}n.exports=function(o,a,s=false){let c=a.depth;let l=a.width;let d=a.height;let u=a.colorType;let h=a.transColor;let b=a.palette;let p=o;if(u===3){t(o,p,l,d,b)}else{if(h){i(o,p,l,d,h)}if(c!==8&&!s){if(c===16){p=Buffer.alloc(l*d*4)}r(o,p,l,d,c)}}return p}}});var Ol=ee({"../../node_modules/pngjs/lib/parser-async.js"(e,n){"use strict";var t=me("util");var i=me("zlib");var r=vo();var o=Cl();var a=So();var s=xo();var c=To();var l=n.exports=function(d){r.call(this);this._parser=new a(d,{read:this.read.bind(this),error:this._handleError.bind(this),metadata:this._handleMetaData.bind(this),gamma:this.emit.bind(this,"gamma"),palette:this._handlePalette.bind(this),transColor:this._handleTransColor.bind(this),finished:this._finished.bind(this),inflateData:this._inflateData.bind(this),simpleTransparency:this._simpleTransparency.bind(this),headersFinished:this._headersFinished.bind(this)});this._options=d;this.writable=true;this._parser.start()};t.inherits(l,r);l.prototype._handleError=function(d){this.emit("error",d);this.writable=false;this.destroy();if(this._inflate&&this._inflate.destroy){this._inflate.destroy()}if(this._filter){this._filter.destroy();this._filter.on("error",function(){})}this.errord=true};l.prototype._inflateData=function(d){if(!this._inflate){if(this._bitmapInfo.interlace){this._inflate=i.createInflate();this._inflate.on("error",this.emit.bind(this,"error"));this._filter.on("complete",this._complete.bind(this));this._inflate.pipe(this._filter)}else{let u=(this._bitmapInfo.width*this._bitmapInfo.bpp*this._bitmapInfo.depth+7>>3)+1;let h=u*this._bitmapInfo.height;let b=Math.max(h,i.Z_MIN_CHUNK);this._inflate=i.createInflate({chunkSize:b});let p=h;let w=this.emit.bind(this,"error");this._inflate.on("error",function(m){if(!p){return}w(m)});this._filter.on("complete",this._complete.bind(this));let g=this._filter.write.bind(this._filter);this._inflate.on("data",function(m){if(!p){return}if(m.length>p){m=m.slice(0,p)}p-=m.length;g(m)});this._inflate.on("end",this._filter.end.bind(this._filter))}}this._inflate.write(d)};l.prototype._handleMetaData=function(d){this._metaData=d;this._bitmapInfo=Object.create(d);this._filter=new o(this._bitmapInfo)};l.prototype._handleTransColor=function(d){this._bitmapInfo.transColor=d};l.prototype._handlePalette=function(d){this._bitmapInfo.palette=d};l.prototype._simpleTransparency=function(){this._metaData.alpha=true};l.prototype._headersFinished=function(){this.emit("metadata",this._metaData)};l.prototype._finished=function(){if(this.errord){return}if(!this._inflate){this.emit("error","No Inflate block")}else{this._inflate.end()}};l.prototype._complete=function(d){if(this.errord){return}let u;try{let h=s.dataToBitMap(d,this._bitmapInfo);u=c(h,this._bitmapInfo,this._options.skipRescale);h=null}catch(h){this._handleError(h);return}this.emit("parsed",u)}}});var Pl=ee({"../../node_modules/pngjs/lib/bitpacker.js"(e,n){"use strict";var t=on();n.exports=function(i,r,o,a){let s=[t.COLORTYPE_COLOR_ALPHA,t.COLORTYPE_ALPHA].indexOf(a.colorType)!==-1;if(a.colorType===a.inputColorType){let m=(function(){let f=new ArrayBuffer(2);new DataView(f).setInt16(0,256,true);return new Int16Array(f)[0]!==256})();if(a.bitDepth===8||a.bitDepth===16&&m){return i}}let c=a.bitDepth!==16?i:new Uint16Array(i.buffer);let l=255;let d=t.COLORTYPE_TO_BPP_MAP[a.inputColorType];if(d===4&&!a.inputHasAlpha){d=3}let u=t.COLORTYPE_TO_BPP_MAP[a.colorType];if(a.bitDepth===16){l=65535;u*=2}let h=Buffer.alloc(r*o*u);let b=0;let p=0;let w=a.bgColor||{};if(w.red===void 0){w.red=l}if(w.green===void 0){w.green=l}if(w.blue===void 0){w.blue=l}function g(){let m;let f;let y;let v=l;switch(a.inputColorType){case t.COLORTYPE_COLOR_ALPHA:v=c[b+3];m=c[b];f=c[b+1];y=c[b+2];break;case t.COLORTYPE_COLOR:m=c[b];f=c[b+1];y=c[b+2];break;case t.COLORTYPE_ALPHA:v=c[b+1];m=c[b];f=m;y=m;break;case t.COLORTYPE_GRAYSCALE:m=c[b];f=m;y=m;break;default:throw new Error("input color type:"+a.inputColorType+" is not supported at present")}if(a.inputHasAlpha){if(!s){v/=l;m=Math.min(Math.max(Math.round((1-v)*w.red+v*m),0),l);f=Math.min(Math.max(Math.round((1-v)*w.green+v*f),0),l);y=Math.min(Math.max(Math.round((1-v)*w.blue+v*y),0),l)}}return{red:m,green:f,blue:y,alpha:v}}for(let m=0;m<o;m++){for(let f=0;f<r;f++){let y=g(c,b);switch(a.colorType){case t.COLORTYPE_COLOR_ALPHA:case t.COLORTYPE_COLOR:if(a.bitDepth===8){h[p]=y.red;h[p+1]=y.green;h[p+2]=y.blue;if(s){h[p+3]=y.alpha}}else{h.writeUInt16BE(y.red,p);h.writeUInt16BE(y.green,p+2);h.writeUInt16BE(y.blue,p+4);if(s){h.writeUInt16BE(y.alpha,p+6)}}break;case t.COLORTYPE_ALPHA:case t.COLORTYPE_GRAYSCALE:{let v=(y.red+y.green+y.blue)/3;if(a.bitDepth===8){h[p]=v;if(s){h[p+1]=y.alpha}}else{h.writeUInt16BE(v,p);if(s){h.writeUInt16BE(y.alpha,p+2)}}break}default:throw new Error("unrecognised color Type "+a.colorType)}b+=d;p+=u}}return h}}});var Rl=ee({"../../node_modules/pngjs/lib/filter-pack.js"(e,n){"use strict";var t=$o();function i(w,g,m,f,y){for(let v=0;v<m;v++){f[y+v]=w[g+v]}}function r(w,g,m){let f=0;let y=g+m;for(let v=g;v<y;v++){f+=Math.abs(w[v])}return f}function o(w,g,m,f,y,v){for(let $=0;$<m;$++){let T=$>=v?w[g+$-v]:0;let k=w[g+$]-T;f[y+$]=k}}function a(w,g,m,f){let y=0;for(let v=0;v<m;v++){let $=v>=f?w[g+v-f]:0;let T=w[g+v]-$;y+=Math.abs(T)}return y}function s(w,g,m,f,y){for(let v=0;v<m;v++){let $=g>0?w[g+v-m]:0;let T=w[g+v]-$;f[y+v]=T}}function c(w,g,m){let f=0;let y=g+m;for(let v=g;v<y;v++){let $=g>0?w[v-m]:0;let T=w[v]-$;f+=Math.abs(T)}return f}function l(w,g,m,f,y,v){for(let $=0;$<m;$++){let T=$>=v?w[g+$-v]:0;let k=g>0?w[g+$-m]:0;let D=w[g+$]-(T+k>>1);f[y+$]=D}}function d(w,g,m,f){let y=0;for(let v=0;v<m;v++){let $=v>=f?w[g+v-f]:0;let T=g>0?w[g+v-m]:0;let k=w[g+v]-($+T>>1);y+=Math.abs(k)}return y}function u(w,g,m,f,y,v){for(let $=0;$<m;$++){let T=$>=v?w[g+$-v]:0;let k=g>0?w[g+$-m]:0;let D=g>0&&$>=v?w[g+$-(m+v)]:0;let E=w[g+$]-t(T,k,D);f[y+$]=E}}function h(w,g,m,f){let y=0;for(let v=0;v<m;v++){let $=v>=f?w[g+v-f]:0;let T=g>0?w[g+v-m]:0;let k=g>0&&v>=f?w[g+v-(m+f)]:0;let D=w[g+v]-t($,T,k);y+=Math.abs(D)}return y}var b={0:i,1:o,2:s,3:l,4:u};var p={0:r,1:a,2:c,3:d,4:h};n.exports=function(w,g,m,f,y){let v;if(!("filterType"in f)||f.filterType===-1){v=[0,1,2,3,4]}else if(typeof f.filterType==="number"){v=[f.filterType]}else{throw new Error("unrecognised filter types")}if(f.bitDepth===16){y*=2}let $=g*y;let T=0;let k=0;let D=Buffer.alloc(($+1)*m);let E=v[0];for(let I=0;I<m;I++){if(v.length>1){let P=Infinity;for(let _=0;_<v.length;_++){let x=p[v[_]](w,k,$,y);if(x<P){E=v[_];P=x}}}D[T]=E;T++;b[E](w,k,$,D,T,y);T+=$;k+=$}return D}}});var Do=ee({"../../node_modules/pngjs/lib/packer.js"(e,n){"use strict";var t=on();var i=_o();var r=Pl();var o=Rl();var a=me("zlib");var s=n.exports=function(c){this._options=c;c.deflateChunkSize=c.deflateChunkSize||32*1024;c.deflateLevel=c.deflateLevel!=null?c.deflateLevel:9;c.deflateStrategy=c.deflateStrategy!=null?c.deflateStrategy:3;c.inputHasAlpha=c.inputHasAlpha!=null?c.inputHasAlpha:true;c.deflateFactory=c.deflateFactory||a.createDeflate;c.bitDepth=c.bitDepth||8;c.colorType=typeof c.colorType==="number"?c.colorType:t.COLORTYPE_COLOR_ALPHA;c.inputColorType=typeof c.inputColorType==="number"?c.inputColorType:t.COLORTYPE_COLOR_ALPHA;if([t.COLORTYPE_GRAYSCALE,t.COLORTYPE_COLOR,t.COLORTYPE_COLOR_ALPHA,t.COLORTYPE_ALPHA].indexOf(c.colorType)===-1){throw new Error("option color type:"+c.colorType+" is not supported at present")}if([t.COLORTYPE_GRAYSCALE,t.COLORTYPE_COLOR,t.COLORTYPE_COLOR_ALPHA,t.COLORTYPE_ALPHA].indexOf(c.inputColorType)===-1){throw new Error("option input color type:"+c.inputColorType+" is not supported at present")}if(c.bitDepth!==8&&c.bitDepth!==16){throw new Error("option bit depth:"+c.bitDepth+" is not supported at present")}};s.prototype.getDeflateOptions=function(){return{chunkSize:this._options.deflateChunkSize,level:this._options.deflateLevel,strategy:this._options.deflateStrategy}};s.prototype.createDeflate=function(){return this._options.deflateFactory(this.getDeflateOptions())};s.prototype.filterData=function(c,l,d){let u=r(c,l,d,this._options);let h=t.COLORTYPE_TO_BPP_MAP[this._options.colorType];let b=o(u,l,d,this._options,h);return b};s.prototype._packChunk=function(c,l){let d=l?l.length:0;let u=Buffer.alloc(d+12);u.writeUInt32BE(d,0);u.writeUInt32BE(c,4);if(l){l.copy(u,8)}u.writeInt32BE(i.crc32(u.slice(4,u.length-4)),u.length-4);return u};s.prototype.packGAMA=function(c){let l=Buffer.alloc(4);l.writeUInt32BE(Math.floor(c*t.GAMMA_DIVISION),0);return this._packChunk(t.TYPE_gAMA,l)};s.prototype.packIHDR=function(c,l){let d=Buffer.alloc(13);d.writeUInt32BE(c,0);d.writeUInt32BE(l,4);d[8]=this._options.bitDepth;d[9]=this._options.colorType;d[10]=0;d[11]=0;d[12]=0;return this._packChunk(t.TYPE_IHDR,d)};s.prototype.packIDAT=function(c){return this._packChunk(t.TYPE_IDAT,c)};s.prototype.packIEND=function(){return this._packChunk(t.TYPE_IEND,null)}}});var Nl=ee({"../../node_modules/pngjs/lib/packer-async.js"(e,n){"use strict";var t=me("util");var i=me("stream");var r=on();var o=Do();var a=n.exports=function(s){i.call(this);let c=s||{};this._packer=new o(c);this._deflate=this._packer.createDeflate();this.readable=true};t.inherits(a,i);a.prototype.pack=function(s,c,l,d){this.emit("data",Buffer.from(r.PNG_SIGNATURE));this.emit("data",this._packer.packIHDR(c,l));if(d){this.emit("data",this._packer.packGAMA(d))}let u=this._packer.filterData(s,c,l);this._deflate.on("error",this.emit.bind(this,"error"));this._deflate.on("data",function(h){this.emit("data",this._packer.packIDAT(h))}.bind(this));this._deflate.on("end",function(){this.emit("data",this._packer.packIEND());this.emit("end")}.bind(this));this._deflate.end(u)}}});var Fl=ee({"../../node_modules/pngjs/lib/sync-inflate.js"(e,n){"use strict";var t=me("assert").ok;var i=me("zlib");var r=me("util");var o=me("buffer").kMaxLength;function a(u){if(!(this instanceof a)){return new a(u)}if(u&&u.chunkSize<i.Z_MIN_CHUNK){u.chunkSize=i.Z_MIN_CHUNK}i.Inflate.call(this,u);this._offset=this._offset===void 0?this._outOffset:this._offset;this._buffer=this._buffer||this._outBuffer;if(u&&u.maxLength!=null){this._maxLength=u.maxLength}}function s(u){return new a(u)}function c(u,h){if(h){process.nextTick(h)}if(!u._handle){return}u._handle.close();u._handle=null}a.prototype._processChunk=function(u,h,b){if(typeof b==="function"){return i.Inflate._processChunk.call(this,u,h,b)}let p=this;let w=u&&u.length;let g=this._chunkSize-this._offset;let m=this._maxLength;let f=0;let y=[];let v=0;let $;this.on("error",function(E){$=E});function T(E,I){if(p._hadError){return}let P=g-I;t(P>=0,"have should not go down");if(P>0){let _=p._buffer.slice(p._offset,p._offset+P);p._offset+=P;if(_.length>m){_=_.slice(0,m)}y.push(_);v+=_.length;m-=_.length;if(m===0){return false}}if(I===0||p._offset>=p._chunkSize){g=p._chunkSize;p._offset=0;p._buffer=Buffer.allocUnsafe(p._chunkSize)}if(I===0){f+=w-E;w=E;return true}return false}t(this._handle,"zlib binding closed");let k;do{k=this._handle.writeSync(h,u,f,w,this._buffer,this._offset,g);k=k||this._writeState}while(!this._hadError&&T(k[0],k[1]));if(this._hadError){throw $}if(v>=o){c(this);throw new RangeError("Cannot create final Buffer. It would be larger than 0x"+o.toString(16)+" bytes")}let D=Buffer.concat(y,v);c(this);return D};r.inherits(a,i.Inflate);function l(u,h){if(typeof h==="string"){h=Buffer.from(h)}if(!(h instanceof Buffer)){throw new TypeError("Not a string or buffer")}let b=u._finishFlushFlag;if(b==null){b=i.Z_FINISH}return u._processChunk(h,b)}function d(u,h){return l(new a(h),u)}n.exports=e=d;e.Inflate=a;e.createInflate=s;e.inflateSync=d}});var Io=ee({"../../node_modules/pngjs/lib/sync-reader.js"(e,n){"use strict";var t=n.exports=function(i){this._buffer=i;this._reads=[]};t.prototype.read=function(i,r){this._reads.push({length:Math.abs(i),allowLess:i<0,func:r})};t.prototype.process=function(){while(this._reads.length>0&&this._buffer.length){let i=this._reads[0];if(this._buffer.length&&(this._buffer.length>=i.length||i.allowLess)){this._reads.shift();let r=this._buffer;this._buffer=r.slice(i.length);i.func.call(this,r.slice(0,i.length))}else{break}}if(this._reads.length>0){throw new Error("There are some read requests waitng on finished stream")}if(this._buffer.length>0){throw new Error("unrecognised content at end of stream")}}}});var Bl=ee({"../../node_modules/pngjs/lib/filter-parse-sync.js"(e){"use strict";var n=Io();var t=ko();e.process=function(i,r){let o=[];let a=new n(i);let s=new t(r,{read:a.read.bind(a),write:function(c){o.push(c)},complete:function(){}});s.start();a.process();return Buffer.concat(o)}}});var jl=ee({"../../node_modules/pngjs/lib/parser-sync.js"(e,n){"use strict";var t=true;var i=me("zlib");var r=Fl();if(!i.deflateSync){t=false}var o=Io();var a=Bl();var s=So();var c=xo();var l=To();n.exports=function(d,u){if(!t){throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0")}let h;function b(M){h=M}let p;function w(M){p=M}function g(M){p.transColor=M}function m(M){p.palette=M}function f(){p.alpha=true}let y;function v(M){y=M}let $=[];function T(M){$.push(M)}let k=new o(d);let D=new s(u,{read:k.read.bind(k),error:b,metadata:w,gamma:v,palette:m,transColor:g,inflateData:T,simpleTransparency:f});D.start();k.process();if(h){throw h}let E=Buffer.concat($);$.length=0;let I;if(p.interlace){I=i.inflateSync(E)}else{let M=(p.width*p.bpp*p.depth+7>>3)+1;let O=M*p.height;I=r(E,{chunkSize:O,maxLength:O})}E=null;if(!I||!I.length){throw new Error("bad png - invalid inflate data response")}let P=a.process(I,p);E=null;let _=c.dataToBitMap(P,p);P=null;let x=l(_,p,u.skipRescale);p.data=x;p.gamma=y||0;return p}}});var Ll=ee({"../../node_modules/pngjs/lib/packer-sync.js"(e,n){"use strict";var t=true;var i=me("zlib");if(!i.deflateSync){t=false}var r=on();var o=Do();n.exports=function(a,s){if(!t){throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0")}let c=s||{};let l=new o(c);let d=[];d.push(Buffer.from(r.PNG_SIGNATURE));d.push(l.packIHDR(a.width,a.height));if(a.gamma){d.push(l.packGAMA(a.gamma))}let u=l.filterData(a.data,a.width,a.height);let h=i.deflateSync(u,l.getDeflateOptions());u=null;if(!h||!h.length){throw new Error("bad png - invalid compressed data response")}d.push(l.packIDAT(h));d.push(l.packIEND());return Buffer.concat(d)}}});var ql=ee({"../../node_modules/pngjs/lib/png-sync.js"(e){"use strict";var n=jl();var t=Ll();e.read=function(i,r){return n(i,r||{})};e.write=function(i,r){return t(i,r)}}});var zn=ee({"../../node_modules/pngjs/lib/png.js"(e){"use strict";var n=me("util");var t=me("stream");var i=Ol();var r=Nl();var o=ql();var a=e.PNG=function(s){t.call(this);s=s||{};this.width=s.width|0;this.height=s.height|0;this.data=this.width>0&&this.height>0?Buffer.alloc(4*this.width*this.height):null;if(s.fill&&this.data){this.data.fill(0)}this.gamma=0;this.readable=this.writable=true;this._parser=new i(s);this._parser.on("error",this.emit.bind(this,"error"));this._parser.on("close",this._handleClose.bind(this));this._parser.on("metadata",this._metadata.bind(this));this._parser.on("gamma",this._gamma.bind(this));this._parser.on("parsed",function(c){this.data=c;this.emit("parsed",c)}.bind(this));this._packer=new r(s);this._packer.on("data",this.emit.bind(this,"data"));this._packer.on("end",this.emit.bind(this,"end"));this._parser.on("close",this._handleClose.bind(this));this._packer.on("error",this.emit.bind(this,"error"))};n.inherits(a,t);a.sync=o;a.prototype.pack=function(){if(!this.data||!this.data.length){this.emit("error","No data provided");return this}process.nextTick(function(){this._packer.pack(this.data,this.width,this.height,this.gamma)}.bind(this));return this};a.prototype.parse=function(s,c){if(c){let l,d;l=function(u){this.removeListener("error",d);this.data=u;c(null,this)}.bind(this);d=function(u){this.removeListener("parsed",l);c(u,null)}.bind(this);this.once("parsed",l);this.once("error",d)}this.end(s);return this};a.prototype.write=function(s){this._parser.write(s);return true};a.prototype.end=function(s){this._parser.end(s)};a.prototype._metadata=function(s){this.width=s.width;this.height=s.height;this.emit("metadata",s)};a.prototype._gamma=function(s){this.gamma=s};a.prototype._handleClose=function(){if(!this._parser.writable&&!this._packer.readable){this.emit("close")}};a.bitblt=function(s,c,l,d,u,h,b,p){l|=0;d|=0;u|=0;h|=0;b|=0;p|=0;if(l>s.width||d>s.height||l+u>s.width||d+h>s.height){throw new Error("bitblt reading outside image")}if(b>c.width||p>c.height||b+u>c.width||p+h>c.height){throw new Error("bitblt writing outside image")}for(let w=0;w<h;w++){s.data.copy(c.data,(p+w)*c.width+b<<2,(d+w)*s.width+l<<2,(d+w)*s.width+l+u<<2)}};a.prototype.bitblt=function(s,c,l,d,u,h,b){a.bitblt(this,s,c,l,d,u,h,b);return this};a.adjustGamma=function(s){if(s.gamma){for(let c=0;c<s.height;c++){for(let l=0;l<s.width;l++){let d=s.width*c+l<<2;for(let u=0;u<3;u++){let h=s.data[d+u]/255;h=Math.pow(h,1/2.2/s.gamma);s.data[d+u]=Math.round(h*255)}}}s.gamma=0}};a.prototype.adjustGamma=function(){a.adjustGamma(this)}}});import{DEFAULT_BROKER_PORT as Ul}from"@buoy-gg/sync-broker";var ji=Ul;var Ao=`http://localhost:${ji}`;var Mo=15e3;var Li=2500;var zl=1200;var Eo=2e4;var Wl=3e4;var Co=5e3;var Hl=15*6e4;var qi="Dashboard";var ke="All";import{readFileSync as Oo,writeFileSync as Jl,mkdirSync as Gl,renameSync as Kl,unlinkSync as Vl}from"fs";import{dirname as Yl,join as Po,resolve as Xl}from"path";import{homedir as Zl}from"os";import{createHash as Ql}from"crypto";import{validateLicense as ed,isAcceptedValidation as td,isTransientLicenseError as nd,resolveTier as id,isRecognizedAccount as rd,isBuoyToken as od,verifyFreeToken as ad,resolveAccountAccess as sd,signCache as Wn,verifyCacheSignature as cd,LICENSE_LAUNCH_VALIDATION_TTL as Ro,LICENSE_REVALIDATION_INTERVAL as ft,LICENSE_TRANSIENT_RETRY_DELAYS as No,KEYGEN_CONFIG as ld,createNodeSession as dd,CLI_AUDIENCE as ud,exchangeServiceKey as hd,isServiceKey as pd,normalizeLicenseKey as Fo,checkDevToken as fd,isDevToken as md}from"@buoy-gg/license/headless";var Bo=["BUOY_LICENSE_KEY","BUOY_KEY","EXPO_PUBLIC_BUOY_KEY","VITE_BUOY_KEY","NEXT_PUBLIC_BUOY_KEY","REACT_APP_BUOY_KEY"];function Ui(e,n=process.env){for(const t of Bo)if(n[t]!==void 0)return Fo(n[t])||null;for(const t of[".env.development.local",".env.local",".env"]){let i;try{i=Oo(Po(e,t),"utf8")}catch{continue}const r=new Map;for(const o of i.split(/\r?\n/)){const a=o.match(/^\s*(?:export\s+)?([A-Z_][A-Z_0-9]*)\s*=\s*(.*)$/);if(!a)continue;const s=a[2].trim();const c=s.match(/^(['"])(.*?)\1\s*(?:#.*)?$/);r.set(a[1],c?c[2]:s.split("#")[0].trim())}for(const o of Bo)if(r.has(o))return Fo(r.get(o))||null}return null}var wd=class{constructor(e,n={}){this.changed=e;this.key=null;this.cache=null;this.timer=null;this.unsubscribeSession=null;this.generation=0;this.busy=false;this.nextCheck=0;this.retry=0;this.lastAdmission=false;this.hasAccess=()=>this.hasKeyAccess()||this.session?.getStatus().state==="active";this.lastSessionSync=0;this.projectDir=Xl(n.projectDir??process.env.BUOY_PROJECT_DIR??process.cwd());const t=Ql("sha256").update(this.projectDir).digest("hex").slice(0,20);this.cacheFile=n.cacheFile??Po(Zl(),".buoy",`account-${t}.json`);this.session=n.session!==void 0?n.session:dd({audience:ud,openBrowser:()=>{throw new Error("The MCP does not open a browser. Run `npx --package=@buoy-gg/core buoy login`.")}})}hasKeyAccess(){return sd({initialized:true,validating:false,key:this.key,tierSource:this.cache?.tier?"key":"none",verifiedAt:this.cache?.cachedAt??null}).status==="admitted"}start(){if(this.timer)return;if(this.session){this.unsubscribeSession=this.session.subscribe(()=>this.notify());void this.session.load().then(()=>this.notify(),()=>{})}try{const e=JSON.parse(Oo(this.cacheFile,"utf8"));if(e.valid&&cd(e))this.cache=e}catch{}void this.tick();this.timer=setInterval(()=>{void this.tick()},1e3);this.timer.unref()}stop(){++this.generation;this.unsubscribeSession?.();this.unsubscribeSession=null;if(this.timer)clearInterval(this.timer);this.timer=null;this.key=null;this.cache=null;this.notify()}notify(){const e=this.hasAccess();if(e===this.lastAdmission)return;this.lastAdmission=e;this.changed()}async tick(){if(this.session&&Date.now()-this.lastSessionSync>15e3){this.lastSessionSync=Date.now();void this.session.sync().catch(()=>{})}const e=Ui(this.projectDir);if(e!==this.key){++this.generation;this.key=e;if(this.cache?.licenseKey!==e)this.cache=null;this.nextCheck=0;this.retry=0;if(!e)this.removeCache()}this.notify();if(!e||this.busy||Date.now()<this.nextCheck)return;if(this.cache&&this.hasKeyAccess()&&Date.now()-this.cache.lastValidatedAt<Ro&&this.nextCheck===0){this.nextCheck=this.cache.lastValidatedAt+Ro;return}this.busy=true;const n=this.generation;try{if(md(e)){const s=fd(e);if(!s.ok){this.cache=null;this.removeCache()}else{const c=Math.min(Date.now(),s.claims.iat*1e3);const l=s.claims.tier==="free"?"free":"pro";this.cache=Wn({licenseKey:e,licenseId:`dev:${s.claims.sid}`,valid:true,tier:l,isPro:l==="pro",expiresAt:new Date(s.claims.exp*1e3).toISOString(),cachedAt:c,lastValidatedAt:Date.now()});this.persistCache()}this.nextCheck=Date.now()+ft;return}if(pd(e)){const s=await hd(e,{origin:process.env.BUOY_SITE_URL||"https://buoy.gg"});if(n!==this.generation||Ui(this.projectDir)!==e)return;if(!s.ok){if(s.reason==="rejected"){this.cache=null;this.removeCache();this.nextCheck=Date.now()+ft}else{this.nextCheck=Date.now()+(No[this.retry++]??ft)}return}const c=Date.now();const l=s.claims.exp*1e3;this.cache=Wn({licenseKey:e,licenseId:`service:${s.claims.sid}`,valid:true,tier:"pro",isPro:true,expiresAt:new Date(l).toISOString(),cachedAt:c,lastValidatedAt:c});this.persistCache();this.retry=0;this.nextCheck=Math.max(c+6e4,l-60*60*1e3);return}if(od(e)){const s=ad(e);if(!s){this.cache=null;this.removeCache()}else{const c=Date.now();this.cache=Wn({licenseKey:e,licenseId:`token:${s.accountHash}`,valid:true,tier:"free",isPro:false,expiresAt:null,cachedAt:c,lastValidatedAt:c});this.persistCache()}this.nextCheck=Date.now()+ft;return}const t=await ed(e);if(n!==this.generation||Ui(this.projectDir)!==e)return;const i=t.data?.relationships?.product?.data?.id;const r=t.meta.code==="EXPIRED"&&(rd(t.data)||this.cache?.licenseKey===e);if(i&&i!==ld.productId||!r&&!td(t)){this.cache=null;this.removeCache();this.nextCheck=Date.now()+ft;return}const o=r?"free":id(t.data);const a=Date.now();this.cache=Wn({licenseKey:e,licenseId:t.data?.id??"",valid:true,tier:o,isPro:o==="pro",expiresAt:r?null:t.data.attributes.expiry,cachedAt:a,lastValidatedAt:a});this.persistCache();this.retry=0;this.nextCheck=a+ft}catch(t){if(n!==this.generation)return;const i=nd(t)?No[this.retry++]:void 0;this.nextCheck=Date.now()+(i??ft)}finally{this.busy=false;this.notify()}}persistCache(){try{Gl(Yl(this.cacheFile),{recursive:true,mode:448});Jl(`${this.cacheFile}.tmp`,JSON.stringify(this.cache),{mode:384});Kl(`${this.cacheFile}.tmp`,this.cacheFile)}catch{}}removeCache(){try{Vl(this.cacheFile)}catch{}}};import gd from"http";import{randomUUID as bd}from"crypto";import{io as vd}from"socket.io-client";import{createBroker as yd,brokerTokenPath as zi,readBrokerToken as $d,writeBrokerToken as kd,DASHBOARD_TOKEN_REQUIRED as _d}from"@buoy-gg/sync-broker";import{execFile as Sd}from"child_process";import{promisify as xd}from"util";import ot from"path";import Td from"os";var jo=xd(Sd);async function Dd(e){let n;try{n=new URL(e)}catch{return null}if(!Id(n.hostname))return null;const t=n.port||(n.protocol==="https:"?"443":"80");try{const{stdout:i}=await jo("lsof",["-nP",`-iTCP:${t}`,"-sTCP:LISTEN","-t"],{timeout:3e3});const r=i.split("\n").map(s=>s.trim()).find(Boolean);if(!r)return null;const{stdout:o}=await jo("lsof",["-a","-p",r,"-d","cwd","-Fn"],{timeout:3e3});const a=o.split("\n").find(s=>s.startsWith("n"));return a?ot.resolve(a.slice(1)):null}catch{return null}}function Id(e,n=Td.networkInterfaces()){const t=e.replace(/^\[|\]$/g,"").toLowerCase();if(t==="localhost"||t==="127.0.0.1"||t==="::1"||t==="10.0.2.2"||t==="10.0.3.2")return true;return Object.values(n).flat().some(i=>i?.address?.toLowerCase()===t)}function Wi(e,n){const t=ot.resolve(n);const i=e.map(a=>({deviceId:a.deviceId,score:a.root?Ad(ot.resolve(a.root),t):-1})).filter(a=>a.score>=0);if(i.length===0)return null;const r=Math.min(...i.map(a=>a.score));const o=i.filter(a=>a.score===r);return o.length===1?o[0].deviceId:null}function Ad(e,n){if(e===n)return 0;const t=ot.relative(e,n);const i=ot.relative(n,e);const r=o=>o&&!o.startsWith("..")&&!ot.isAbsolute(o);if(r(t))return t.split(ot.sep).length;if(r(i))return i.split(ot.sep).length;return-1}function Md(e,n){return e==="app"&&(n==="ping"||n==="reloadApp")}function Lo(e){return e>=2}function Ed(e){if(Md(e.toolId,e.action)){return{timeoutMs:e.fullMs,usedFullBudget:false}}if(!Lo(e.consecutiveTimeouts)){return{timeoutMs:e.fullMs,usedFullBudget:false}}if(e.now-e.lastFullBudgetAt>e.recoveryProbeMs){return{timeoutMs:e.fullMs,usedFullBudget:true}}return{timeoutMs:e.shortMs,usedFullBudget:false}}function Cd(e){if(e.consecutiveTimeouts>=2)return true;if(e.lastOkAt>0&&e.now-e.lastOkAt>e.unresponsiveAfterMs){return true}return false}var Od=3e4;var Pd=5e3;function Rd(e,n,t){if(e!=="highlight-updates"||n!=="waitFor")return 0;const i=Number(t?.timeoutMs);if(!Number.isFinite(i)||i<=0)return 0;return Math.min(i,Od)+Pd}var mt="Not ready:";var Nd=class{constructor(e={}){this.socket=null;this.admitted=false;this.createdAt=Date.now();this.lockedDevices=new Set;this.hostAccount=null;this.broker=null;this.capabilities=new Map;this.devices=[];this.sessionDevice=null;this.snapshots=new Map;this.watching=new Map;this.pendingActions=new Map;this.snapshotWaiters=new Map;this.snapshotAt=new Map;this.health=new Map;this.devServerOrigins=new Map;this.crashSeen=new Map;this.rootLookups=new Set;this.devServerRoots=new Map;this.originProbed=new Set;this.lastSeen=new Map;this.transportLost=false;this.deviceConnections=new Map;this.port=e.port??ji;this.url=e.url??(e.port?`http://localhost:${e.port}`:Ao);this.actionTimeoutMs=e.actionTimeoutMs??Mo;this.log=e.log??(n=>process.stderr.write(`[buoy-mcp] ${n}
1
+ import{createRequire as il}from"module";const eg=il(import.meta.url);import{PACKAGE_NAME as uo,VERSION as Nn}from"./chunk-3STZVJQG.mjs";import{accountRequired as Fn,farmFairness as rl,hasBuoyAccount as Bn,registerSimFarmTools as ol}from"./chunk-XA74T4JN.mjs";import{bootEnv as al,coreInfo as sl,ensureKeeper as cl,farmAdbTarget as ho,farmAdbTargets as ll,farmHome as dl,findShell as ul,installShell as hl,keeperAlive as Mt,keeperCall as ht,simLaunchEnv as pl,suggestCounts as fl}from"./chunk-ODGXMS2O.mjs";import{describeDevices as ml,describeDiagnosis as wl,describeInputs as gl,entitlementHasPro as jn,proRequired as bl,readEntitlement as vl,run as Be}from"./chunk-5NOZVPWB.mjs";import{accessFor as yl,currentAccess as pt,freeToolNames as $l,hasProAccess as de,isFreeAppCall as kl,meetsAccess as Ln,outsideCalls as _l,proRequiredMessage as rn,runWithAccess as po}from"./chunk-D5K6WO6B.mjs";import{freeComparison as Sl,freeJsTop as xl,freeRanking as Bi,freeWebBench as Tl,nothingLocked as qn,withLockedLines as Et}from"./chunk-OP23W722.mjs";import{GPU_RENDERER_JS as Dl,caseUrl as fo,closeWithin as Ct,formatWebBenchMarkdown as Il,isSoftwareGpu as mo,loadChromium as wo,runWebBench as Al,shuffled as Ml,snapRefreshRate as El,waitForHostLock as go,withDeadline as bo}from"./chunk-DVRR7W22.mjs";import{__commonJS as ee,__require as me,__toESM as Un}from"./chunk-MTTWR4T7.mjs";var vo=ee({"../../node_modules/pngjs/lib/chunkstream.js"(e,n){"use strict";var t=me("util");var i=me("stream");var r=n.exports=function(){i.call(this);this._buffers=[];this._buffered=0;this._reads=[];this._paused=false;this._encoding="utf8";this.writable=true};t.inherits(r,i);r.prototype.read=function(o,a){this._reads.push({length:Math.abs(o),allowLess:o<0,func:a});process.nextTick(function(){this._process();if(this._paused&&this._reads&&this._reads.length>0){this._paused=false;this.emit("drain")}}.bind(this))};r.prototype.write=function(o,a){if(!this.writable){this.emit("error",new Error("Stream not writable"));return false}let s;if(Buffer.isBuffer(o)){s=o}else{s=Buffer.from(o,a||this._encoding)}this._buffers.push(s);this._buffered+=s.length;this._process();if(this._reads&&this._reads.length===0){this._paused=true}return this.writable&&!this._paused};r.prototype.end=function(o,a){if(o){this.write(o,a)}this.writable=false;if(!this._buffers){return}if(this._buffers.length===0){this._end()}else{this._buffers.push(null);this._process()}};r.prototype.destroySoon=r.prototype.end;r.prototype._end=function(){if(this._reads.length>0){this.emit("error",new Error("Unexpected end of input"))}this.destroy()};r.prototype.destroy=function(){if(!this._buffers){return}this.writable=false;this._reads=null;this._buffers=null;this.emit("close")};r.prototype._processReadAllowingLess=function(o){this._reads.shift();let a=this._buffers[0];if(a.length>o.length){this._buffered-=o.length;this._buffers[0]=a.slice(o.length);o.func.call(this,a.slice(0,o.length))}else{this._buffered-=a.length;this._buffers.shift();o.func.call(this,a)}};r.prototype._processRead=function(o){this._reads.shift();let a=0;let s=0;let c=Buffer.alloc(o.length);while(a<o.length){let l=this._buffers[s++];let d=Math.min(l.length,o.length-a);l.copy(c,a,0,d);a+=d;if(d!==l.length){this._buffers[--s]=l.slice(d)}}if(s>0){this._buffers.splice(0,s)}this._buffered-=o.length;o.func.call(this,c)};r.prototype._process=function(){try{while(this._buffered>0&&this._reads&&this._reads.length>0){let o=this._reads[0];if(o.allowLess){this._processReadAllowingLess(o)}else if(this._buffered>=o.length){this._processRead(o)}else{break}}if(this._buffers&&!this.writable){this._end()}}catch(o){this.emit("error",o)}}}});var yo=ee({"../../node_modules/pngjs/lib/interlace.js"(e){"use strict";var n=[{x:[0],y:[0]},{x:[4],y:[0]},{x:[0,4],y:[4]},{x:[2,6],y:[0,4]},{x:[0,2,4,6],y:[2,6]},{x:[1,3,5,7],y:[0,2,4,6]},{x:[0,1,2,3,4,5,6,7],y:[1,3,5,7]}];e.getImagePasses=function(t,i){let r=[];let o=t%8;let a=i%8;let s=(t-o)/8;let c=(i-a)/8;for(let l=0;l<n.length;l++){let d=n[l];let u=s*d.x.length;let h=c*d.y.length;for(let b=0;b<d.x.length;b++){if(d.x[b]<o){u++}else{break}}for(let b=0;b<d.y.length;b++){if(d.y[b]<a){h++}else{break}}if(u>0&&h>0){r.push({width:u,height:h,index:l})}}return r};e.getInterlaceIterator=function(t){return function(i,r,o){let a=i%n[o].x.length;let s=(i-a)/n[o].x.length*8+n[o].x[a];let c=r%n[o].y.length;let l=(r-c)/n[o].y.length*8+n[o].y[c];return s*4+l*t*4}}}});var $o=ee({"../../node_modules/pngjs/lib/paeth-predictor.js"(e,n){"use strict";n.exports=function t(i,r,o){let a=i+r-o;let s=Math.abs(a-i);let c=Math.abs(a-r);let l=Math.abs(a-o);if(s<=c&&s<=l){return i}if(c<=l){return r}return o}}});var ko=ee({"../../node_modules/pngjs/lib/filter-parse.js"(e,n){"use strict";var t=yo();var i=$o();function r(a,s,c){let l=a*s;if(c!==8){l=Math.ceil(l/(8/c))}return l}var o=n.exports=function(a,s){let c=a.width;let l=a.height;let d=a.interlace;let u=a.bpp;let h=a.depth;this.read=s.read;this.write=s.write;this.complete=s.complete;this._imageIndex=0;this._images=[];if(d){let b=t.getImagePasses(c,l);for(let p=0;p<b.length;p++){this._images.push({byteWidth:r(b[p].width,u,h),height:b[p].height,lineIndex:0})}}else{this._images.push({byteWidth:r(c,u,h),height:l,lineIndex:0})}if(h===8){this._xComparison=u}else if(h===16){this._xComparison=u*2}else{this._xComparison=1}};o.prototype.start=function(){this.read(this._images[this._imageIndex].byteWidth+1,this._reverseFilterLine.bind(this))};o.prototype._unFilterType1=function(a,s,c){let l=this._xComparison;let d=l-1;for(let u=0;u<c;u++){let h=a[1+u];let b=u>d?s[u-l]:0;s[u]=h+b}};o.prototype._unFilterType2=function(a,s,c){let l=this._lastLine;for(let d=0;d<c;d++){let u=a[1+d];let h=l?l[d]:0;s[d]=u+h}};o.prototype._unFilterType3=function(a,s,c){let l=this._xComparison;let d=l-1;let u=this._lastLine;for(let h=0;h<c;h++){let b=a[1+h];let p=u?u[h]:0;let w=h>d?s[h-l]:0;let g=Math.floor((w+p)/2);s[h]=b+g}};o.prototype._unFilterType4=function(a,s,c){let l=this._xComparison;let d=l-1;let u=this._lastLine;for(let h=0;h<c;h++){let b=a[1+h];let p=u?u[h]:0;let w=h>d?s[h-l]:0;let g=h>d&&u?u[h-l]:0;let m=i(w,p,g);s[h]=b+m}};o.prototype._reverseFilterLine=function(a){let s=a[0];let c;let l=this._images[this._imageIndex];let d=l.byteWidth;if(s===0){c=a.slice(1,d+1)}else{c=Buffer.alloc(d);switch(s){case 1:this._unFilterType1(a,c,d);break;case 2:this._unFilterType2(a,c,d);break;case 3:this._unFilterType3(a,c,d);break;case 4:this._unFilterType4(a,c,d);break;default:throw new Error("Unrecognised filter type - "+s)}}this.write(c);l.lineIndex++;if(l.lineIndex>=l.height){this._lastLine=null;this._imageIndex++;l=this._images[this._imageIndex]}else{this._lastLine=c}if(l){this.read(l.byteWidth+1,this._reverseFilterLine.bind(this))}else{this._lastLine=null;this.complete()}}}});var Cl=ee({"../../node_modules/pngjs/lib/filter-parse-async.js"(e,n){"use strict";var t=me("util");var i=vo();var r=ko();var o=n.exports=function(a){i.call(this);let s=[];let c=this;this._filter=new r(a,{read:this.read.bind(this),write:function(l){s.push(l)},complete:function(){c.emit("complete",Buffer.concat(s))}});this._filter.start()};t.inherits(o,i)}});var on=ee({"../../node_modules/pngjs/lib/constants.js"(e,n){"use strict";n.exports={PNG_SIGNATURE:[137,80,78,71,13,10,26,10],TYPE_IHDR:1229472850,TYPE_IEND:1229278788,TYPE_IDAT:1229209940,TYPE_PLTE:1347179589,TYPE_tRNS:1951551059,TYPE_gAMA:1732332865,COLORTYPE_GRAYSCALE:0,COLORTYPE_PALETTE:1,COLORTYPE_COLOR:2,COLORTYPE_ALPHA:4,COLORTYPE_PALETTE_COLOR:3,COLORTYPE_COLOR_ALPHA:6,COLORTYPE_TO_BPP_MAP:{0:1,2:3,3:1,4:2,6:4},GAMMA_DIVISION:1e5}}});var _o=ee({"../../node_modules/pngjs/lib/crc.js"(e,n){"use strict";var t=[];(function(){for(let r=0;r<256;r++){let o=r;for(let a=0;a<8;a++){if(o&1){o=3988292384^o>>>1}else{o=o>>>1}}t[r]=o}})();var i=n.exports=function(){this._crc=-1};i.prototype.write=function(r){for(let o=0;o<r.length;o++){this._crc=t[(this._crc^r[o])&255]^this._crc>>>8}return true};i.prototype.crc32=function(){return this._crc^-1};i.crc32=function(r){let o=-1;for(let a=0;a<r.length;a++){o=t[(o^r[a])&255]^o>>>8}return o^-1}}});var So=ee({"../../node_modules/pngjs/lib/parser.js"(e,n){"use strict";var t=on();var i=_o();var r=n.exports=function(o,a){this._options=o;o.checkCRC=o.checkCRC!==false;this._hasIHDR=false;this._hasIEND=false;this._emittedHeadersFinished=false;this._palette=[];this._colorType=0;this._chunks={};this._chunks[t.TYPE_IHDR]=this._handleIHDR.bind(this);this._chunks[t.TYPE_IEND]=this._handleIEND.bind(this);this._chunks[t.TYPE_IDAT]=this._handleIDAT.bind(this);this._chunks[t.TYPE_PLTE]=this._handlePLTE.bind(this);this._chunks[t.TYPE_tRNS]=this._handleTRNS.bind(this);this._chunks[t.TYPE_gAMA]=this._handleGAMA.bind(this);this.read=a.read;this.error=a.error;this.metadata=a.metadata;this.gamma=a.gamma;this.transColor=a.transColor;this.palette=a.palette;this.parsed=a.parsed;this.inflateData=a.inflateData;this.finished=a.finished;this.simpleTransparency=a.simpleTransparency;this.headersFinished=a.headersFinished||function(){}};r.prototype.start=function(){this.read(t.PNG_SIGNATURE.length,this._parseSignature.bind(this))};r.prototype._parseSignature=function(o){let a=t.PNG_SIGNATURE;for(let s=0;s<a.length;s++){if(o[s]!==a[s]){this.error(new Error("Invalid file signature"));return}}this.read(8,this._parseChunkBegin.bind(this))};r.prototype._parseChunkBegin=function(o){let a=o.readUInt32BE(0);let s=o.readUInt32BE(4);let c="";for(let d=4;d<8;d++){c+=String.fromCharCode(o[d])}let l=Boolean(o[4]&32);if(!this._hasIHDR&&s!==t.TYPE_IHDR){this.error(new Error("Expected IHDR on beggining"));return}this._crc=new i;this._crc.write(Buffer.from(c));if(this._chunks[s]){return this._chunks[s](a)}if(!l){this.error(new Error("Unsupported critical chunk type "+c));return}this.read(a+4,this._skipChunk.bind(this))};r.prototype._skipChunk=function(){this.read(8,this._parseChunkBegin.bind(this))};r.prototype._handleChunkEnd=function(){this.read(4,this._parseChunkEnd.bind(this))};r.prototype._parseChunkEnd=function(o){let a=o.readInt32BE(0);let s=this._crc.crc32();if(this._options.checkCRC&&s!==a){this.error(new Error("Crc error - "+a+" - "+s));return}if(!this._hasIEND){this.read(8,this._parseChunkBegin.bind(this))}};r.prototype._handleIHDR=function(o){this.read(o,this._parseIHDR.bind(this))};r.prototype._parseIHDR=function(o){this._crc.write(o);let a=o.readUInt32BE(0);let s=o.readUInt32BE(4);let c=o[8];let l=o[9];let d=o[10];let u=o[11];let h=o[12];if(c!==8&&c!==4&&c!==2&&c!==1&&c!==16){this.error(new Error("Unsupported bit depth "+c));return}if(!(l in t.COLORTYPE_TO_BPP_MAP)){this.error(new Error("Unsupported color type"));return}if(d!==0){this.error(new Error("Unsupported compression method"));return}if(u!==0){this.error(new Error("Unsupported filter method"));return}if(h!==0&&h!==1){this.error(new Error("Unsupported interlace method"));return}this._colorType=l;let b=t.COLORTYPE_TO_BPP_MAP[this._colorType];this._hasIHDR=true;this.metadata({width:a,height:s,depth:c,interlace:Boolean(h),palette:Boolean(l&t.COLORTYPE_PALETTE),color:Boolean(l&t.COLORTYPE_COLOR),alpha:Boolean(l&t.COLORTYPE_ALPHA),bpp:b,colorType:l});this._handleChunkEnd()};r.prototype._handlePLTE=function(o){this.read(o,this._parsePLTE.bind(this))};r.prototype._parsePLTE=function(o){this._crc.write(o);let a=Math.floor(o.length/3);for(let s=0;s<a;s++){this._palette.push([o[s*3],o[s*3+1],o[s*3+2],255])}this.palette(this._palette);this._handleChunkEnd()};r.prototype._handleTRNS=function(o){this.simpleTransparency();this.read(o,this._parseTRNS.bind(this))};r.prototype._parseTRNS=function(o){this._crc.write(o);if(this._colorType===t.COLORTYPE_PALETTE_COLOR){if(this._palette.length===0){this.error(new Error("Transparency chunk must be after palette"));return}if(o.length>this._palette.length){this.error(new Error("More transparent colors than palette size"));return}for(let a=0;a<o.length;a++){this._palette[a][3]=o[a]}this.palette(this._palette)}if(this._colorType===t.COLORTYPE_GRAYSCALE){this.transColor([o.readUInt16BE(0)])}if(this._colorType===t.COLORTYPE_COLOR){this.transColor([o.readUInt16BE(0),o.readUInt16BE(2),o.readUInt16BE(4)])}this._handleChunkEnd()};r.prototype._handleGAMA=function(o){this.read(o,this._parseGAMA.bind(this))};r.prototype._parseGAMA=function(o){this._crc.write(o);this.gamma(o.readUInt32BE(0)/t.GAMMA_DIVISION);this._handleChunkEnd()};r.prototype._handleIDAT=function(o){if(!this._emittedHeadersFinished){this._emittedHeadersFinished=true;this.headersFinished()}this.read(-o,this._parseIDAT.bind(this,o))};r.prototype._parseIDAT=function(o,a){this._crc.write(a);if(this._colorType===t.COLORTYPE_PALETTE_COLOR&&this._palette.length===0){throw new Error("Expected palette not found")}this.inflateData(a);let s=o-a.length;if(s>0){this._handleIDAT(s)}else{this._handleChunkEnd()}};r.prototype._handleIEND=function(o){this.read(o,this._parseIEND.bind(this))};r.prototype._parseIEND=function(o){this._crc.write(o);this._hasIEND=true;this._handleChunkEnd();if(this.finished){this.finished()}}}});var xo=ee({"../../node_modules/pngjs/lib/bitmapper.js"(e){"use strict";var n=yo();var t=[function(){},function(s,c,l,d){if(d===c.length){throw new Error("Ran out of data")}let u=c[d];s[l]=u;s[l+1]=u;s[l+2]=u;s[l+3]=255},function(s,c,l,d){if(d+1>=c.length){throw new Error("Ran out of data")}let u=c[d];s[l]=u;s[l+1]=u;s[l+2]=u;s[l+3]=c[d+1]},function(s,c,l,d){if(d+2>=c.length){throw new Error("Ran out of data")}s[l]=c[d];s[l+1]=c[d+1];s[l+2]=c[d+2];s[l+3]=255},function(s,c,l,d){if(d+3>=c.length){throw new Error("Ran out of data")}s[l]=c[d];s[l+1]=c[d+1];s[l+2]=c[d+2];s[l+3]=c[d+3]}];var i=[function(){},function(s,c,l,d){let u=c[0];s[l]=u;s[l+1]=u;s[l+2]=u;s[l+3]=d},function(s,c,l){let d=c[0];s[l]=d;s[l+1]=d;s[l+2]=d;s[l+3]=c[1]},function(s,c,l,d){s[l]=c[0];s[l+1]=c[1];s[l+2]=c[2];s[l+3]=d},function(s,c,l){s[l]=c[0];s[l+1]=c[1];s[l+2]=c[2];s[l+3]=c[3]}];function r(s,c){let l=[];let d=0;function u(){if(d===s.length){throw new Error("Ran out of data")}let h=s[d];d++;let b,p,w,g,m,f,y,v;switch(c){default:throw new Error("unrecognised depth");case 16:y=s[d];d++;l.push((h<<8)+y);break;case 4:y=h&15;v=h>>4;l.push(v,y);break;case 2:m=h&3;f=h>>2&3;y=h>>4&3;v=h>>6&3;l.push(v,y,f,m);break;case 1:b=h&1;p=h>>1&1;w=h>>2&1;g=h>>3&1;m=h>>4&1;f=h>>5&1;y=h>>6&1;v=h>>7&1;l.push(v,y,f,m,g,w,p,b);break}}return{get:function(h){while(l.length<h){u()}let b=l.slice(0,h);l=l.slice(h);return b},resetAfterLine:function(){l.length=0},end:function(){if(d!==s.length){throw new Error("extra data found")}}}}function o(s,c,l,d,u,h){let b=s.width;let p=s.height;let w=s.index;for(let g=0;g<p;g++){for(let m=0;m<b;m++){let f=l(m,g,w);t[d](c,u,f,h);h+=d}}return h}function a(s,c,l,d,u,h){let b=s.width;let p=s.height;let w=s.index;for(let g=0;g<p;g++){for(let m=0;m<b;m++){let f=u.get(d);let y=l(m,g,w);i[d](c,f,y,h)}u.resetAfterLine()}}e.dataToBitMap=function(s,c){let l=c.width;let d=c.height;let u=c.depth;let h=c.bpp;let b=c.interlace;let p;if(u!==8){p=r(s,u)}let w;if(u<=8){w=Buffer.alloc(l*d*4)}else{w=new Uint16Array(l*d*4)}let g=Math.pow(2,u)-1;let m=0;let f;let y;if(b){f=n.getImagePasses(l,d);y=n.getInterlaceIterator(l,d)}else{let v=0;y=function(){let $=v;v+=4;return $};f=[{width:l,height:d}]}for(let v=0;v<f.length;v++){if(u===8){m=o(f[v],w,y,h,s,m)}else{a(f[v],w,y,h,p,g)}}if(u===8){if(m!==s.length){throw new Error("extra data found")}}else{p.end()}return w}}});var To=ee({"../../node_modules/pngjs/lib/format-normaliser.js"(e,n){"use strict";function t(o,a,s,c,l){let d=0;for(let u=0;u<c;u++){for(let h=0;h<s;h++){let b=l[o[d]];if(!b){throw new Error("index "+o[d]+" not in palette")}for(let p=0;p<4;p++){a[d+p]=b[p]}d+=4}}}function i(o,a,s,c,l){let d=0;for(let u=0;u<c;u++){for(let h=0;h<s;h++){let b=false;if(l.length===1){if(l[0]===o[d]){b=true}}else if(l[0]===o[d]&&l[1]===o[d+1]&&l[2]===o[d+2]){b=true}if(b){for(let p=0;p<4;p++){a[d+p]=0}}d+=4}}}function r(o,a,s,c,l){let d=255;let u=Math.pow(2,l)-1;let h=0;for(let b=0;b<c;b++){for(let p=0;p<s;p++){for(let w=0;w<4;w++){a[h+w]=Math.floor(o[h+w]*d/u+.5)}h+=4}}}n.exports=function(o,a,s=false){let c=a.depth;let l=a.width;let d=a.height;let u=a.colorType;let h=a.transColor;let b=a.palette;let p=o;if(u===3){t(o,p,l,d,b)}else{if(h){i(o,p,l,d,h)}if(c!==8&&!s){if(c===16){p=Buffer.alloc(l*d*4)}r(o,p,l,d,c)}}return p}}});var Ol=ee({"../../node_modules/pngjs/lib/parser-async.js"(e,n){"use strict";var t=me("util");var i=me("zlib");var r=vo();var o=Cl();var a=So();var s=xo();var c=To();var l=n.exports=function(d){r.call(this);this._parser=new a(d,{read:this.read.bind(this),error:this._handleError.bind(this),metadata:this._handleMetaData.bind(this),gamma:this.emit.bind(this,"gamma"),palette:this._handlePalette.bind(this),transColor:this._handleTransColor.bind(this),finished:this._finished.bind(this),inflateData:this._inflateData.bind(this),simpleTransparency:this._simpleTransparency.bind(this),headersFinished:this._headersFinished.bind(this)});this._options=d;this.writable=true;this._parser.start()};t.inherits(l,r);l.prototype._handleError=function(d){this.emit("error",d);this.writable=false;this.destroy();if(this._inflate&&this._inflate.destroy){this._inflate.destroy()}if(this._filter){this._filter.destroy();this._filter.on("error",function(){})}this.errord=true};l.prototype._inflateData=function(d){if(!this._inflate){if(this._bitmapInfo.interlace){this._inflate=i.createInflate();this._inflate.on("error",this.emit.bind(this,"error"));this._filter.on("complete",this._complete.bind(this));this._inflate.pipe(this._filter)}else{let u=(this._bitmapInfo.width*this._bitmapInfo.bpp*this._bitmapInfo.depth+7>>3)+1;let h=u*this._bitmapInfo.height;let b=Math.max(h,i.Z_MIN_CHUNK);this._inflate=i.createInflate({chunkSize:b});let p=h;let w=this.emit.bind(this,"error");this._inflate.on("error",function(m){if(!p){return}w(m)});this._filter.on("complete",this._complete.bind(this));let g=this._filter.write.bind(this._filter);this._inflate.on("data",function(m){if(!p){return}if(m.length>p){m=m.slice(0,p)}p-=m.length;g(m)});this._inflate.on("end",this._filter.end.bind(this._filter))}}this._inflate.write(d)};l.prototype._handleMetaData=function(d){this._metaData=d;this._bitmapInfo=Object.create(d);this._filter=new o(this._bitmapInfo)};l.prototype._handleTransColor=function(d){this._bitmapInfo.transColor=d};l.prototype._handlePalette=function(d){this._bitmapInfo.palette=d};l.prototype._simpleTransparency=function(){this._metaData.alpha=true};l.prototype._headersFinished=function(){this.emit("metadata",this._metaData)};l.prototype._finished=function(){if(this.errord){return}if(!this._inflate){this.emit("error","No Inflate block")}else{this._inflate.end()}};l.prototype._complete=function(d){if(this.errord){return}let u;try{let h=s.dataToBitMap(d,this._bitmapInfo);u=c(h,this._bitmapInfo,this._options.skipRescale);h=null}catch(h){this._handleError(h);return}this.emit("parsed",u)}}});var Pl=ee({"../../node_modules/pngjs/lib/bitpacker.js"(e,n){"use strict";var t=on();n.exports=function(i,r,o,a){let s=[t.COLORTYPE_COLOR_ALPHA,t.COLORTYPE_ALPHA].indexOf(a.colorType)!==-1;if(a.colorType===a.inputColorType){let m=(function(){let f=new ArrayBuffer(2);new DataView(f).setInt16(0,256,true);return new Int16Array(f)[0]!==256})();if(a.bitDepth===8||a.bitDepth===16&&m){return i}}let c=a.bitDepth!==16?i:new Uint16Array(i.buffer);let l=255;let d=t.COLORTYPE_TO_BPP_MAP[a.inputColorType];if(d===4&&!a.inputHasAlpha){d=3}let u=t.COLORTYPE_TO_BPP_MAP[a.colorType];if(a.bitDepth===16){l=65535;u*=2}let h=Buffer.alloc(r*o*u);let b=0;let p=0;let w=a.bgColor||{};if(w.red===void 0){w.red=l}if(w.green===void 0){w.green=l}if(w.blue===void 0){w.blue=l}function g(){let m;let f;let y;let v=l;switch(a.inputColorType){case t.COLORTYPE_COLOR_ALPHA:v=c[b+3];m=c[b];f=c[b+1];y=c[b+2];break;case t.COLORTYPE_COLOR:m=c[b];f=c[b+1];y=c[b+2];break;case t.COLORTYPE_ALPHA:v=c[b+1];m=c[b];f=m;y=m;break;case t.COLORTYPE_GRAYSCALE:m=c[b];f=m;y=m;break;default:throw new Error("input color type:"+a.inputColorType+" is not supported at present")}if(a.inputHasAlpha){if(!s){v/=l;m=Math.min(Math.max(Math.round((1-v)*w.red+v*m),0),l);f=Math.min(Math.max(Math.round((1-v)*w.green+v*f),0),l);y=Math.min(Math.max(Math.round((1-v)*w.blue+v*y),0),l)}}return{red:m,green:f,blue:y,alpha:v}}for(let m=0;m<o;m++){for(let f=0;f<r;f++){let y=g(c,b);switch(a.colorType){case t.COLORTYPE_COLOR_ALPHA:case t.COLORTYPE_COLOR:if(a.bitDepth===8){h[p]=y.red;h[p+1]=y.green;h[p+2]=y.blue;if(s){h[p+3]=y.alpha}}else{h.writeUInt16BE(y.red,p);h.writeUInt16BE(y.green,p+2);h.writeUInt16BE(y.blue,p+4);if(s){h.writeUInt16BE(y.alpha,p+6)}}break;case t.COLORTYPE_ALPHA:case t.COLORTYPE_GRAYSCALE:{let v=(y.red+y.green+y.blue)/3;if(a.bitDepth===8){h[p]=v;if(s){h[p+1]=y.alpha}}else{h.writeUInt16BE(v,p);if(s){h.writeUInt16BE(y.alpha,p+2)}}break}default:throw new Error("unrecognised color Type "+a.colorType)}b+=d;p+=u}}return h}}});var Rl=ee({"../../node_modules/pngjs/lib/filter-pack.js"(e,n){"use strict";var t=$o();function i(w,g,m,f,y){for(let v=0;v<m;v++){f[y+v]=w[g+v]}}function r(w,g,m){let f=0;let y=g+m;for(let v=g;v<y;v++){f+=Math.abs(w[v])}return f}function o(w,g,m,f,y,v){for(let $=0;$<m;$++){let T=$>=v?w[g+$-v]:0;let k=w[g+$]-T;f[y+$]=k}}function a(w,g,m,f){let y=0;for(let v=0;v<m;v++){let $=v>=f?w[g+v-f]:0;let T=w[g+v]-$;y+=Math.abs(T)}return y}function s(w,g,m,f,y){for(let v=0;v<m;v++){let $=g>0?w[g+v-m]:0;let T=w[g+v]-$;f[y+v]=T}}function c(w,g,m){let f=0;let y=g+m;for(let v=g;v<y;v++){let $=g>0?w[v-m]:0;let T=w[v]-$;f+=Math.abs(T)}return f}function l(w,g,m,f,y,v){for(let $=0;$<m;$++){let T=$>=v?w[g+$-v]:0;let k=g>0?w[g+$-m]:0;let D=w[g+$]-(T+k>>1);f[y+$]=D}}function d(w,g,m,f){let y=0;for(let v=0;v<m;v++){let $=v>=f?w[g+v-f]:0;let T=g>0?w[g+v-m]:0;let k=w[g+v]-($+T>>1);y+=Math.abs(k)}return y}function u(w,g,m,f,y,v){for(let $=0;$<m;$++){let T=$>=v?w[g+$-v]:0;let k=g>0?w[g+$-m]:0;let D=g>0&&$>=v?w[g+$-(m+v)]:0;let E=w[g+$]-t(T,k,D);f[y+$]=E}}function h(w,g,m,f){let y=0;for(let v=0;v<m;v++){let $=v>=f?w[g+v-f]:0;let T=g>0?w[g+v-m]:0;let k=g>0&&v>=f?w[g+v-(m+f)]:0;let D=w[g+v]-t($,T,k);y+=Math.abs(D)}return y}var b={0:i,1:o,2:s,3:l,4:u};var p={0:r,1:a,2:c,3:d,4:h};n.exports=function(w,g,m,f,y){let v;if(!("filterType"in f)||f.filterType===-1){v=[0,1,2,3,4]}else if(typeof f.filterType==="number"){v=[f.filterType]}else{throw new Error("unrecognised filter types")}if(f.bitDepth===16){y*=2}let $=g*y;let T=0;let k=0;let D=Buffer.alloc(($+1)*m);let E=v[0];for(let I=0;I<m;I++){if(v.length>1){let P=Infinity;for(let _=0;_<v.length;_++){let x=p[v[_]](w,k,$,y);if(x<P){E=v[_];P=x}}}D[T]=E;T++;b[E](w,k,$,D,T,y);T+=$;k+=$}return D}}});var Do=ee({"../../node_modules/pngjs/lib/packer.js"(e,n){"use strict";var t=on();var i=_o();var r=Pl();var o=Rl();var a=me("zlib");var s=n.exports=function(c){this._options=c;c.deflateChunkSize=c.deflateChunkSize||32*1024;c.deflateLevel=c.deflateLevel!=null?c.deflateLevel:9;c.deflateStrategy=c.deflateStrategy!=null?c.deflateStrategy:3;c.inputHasAlpha=c.inputHasAlpha!=null?c.inputHasAlpha:true;c.deflateFactory=c.deflateFactory||a.createDeflate;c.bitDepth=c.bitDepth||8;c.colorType=typeof c.colorType==="number"?c.colorType:t.COLORTYPE_COLOR_ALPHA;c.inputColorType=typeof c.inputColorType==="number"?c.inputColorType:t.COLORTYPE_COLOR_ALPHA;if([t.COLORTYPE_GRAYSCALE,t.COLORTYPE_COLOR,t.COLORTYPE_COLOR_ALPHA,t.COLORTYPE_ALPHA].indexOf(c.colorType)===-1){throw new Error("option color type:"+c.colorType+" is not supported at present")}if([t.COLORTYPE_GRAYSCALE,t.COLORTYPE_COLOR,t.COLORTYPE_COLOR_ALPHA,t.COLORTYPE_ALPHA].indexOf(c.inputColorType)===-1){throw new Error("option input color type:"+c.inputColorType+" is not supported at present")}if(c.bitDepth!==8&&c.bitDepth!==16){throw new Error("option bit depth:"+c.bitDepth+" is not supported at present")}};s.prototype.getDeflateOptions=function(){return{chunkSize:this._options.deflateChunkSize,level:this._options.deflateLevel,strategy:this._options.deflateStrategy}};s.prototype.createDeflate=function(){return this._options.deflateFactory(this.getDeflateOptions())};s.prototype.filterData=function(c,l,d){let u=r(c,l,d,this._options);let h=t.COLORTYPE_TO_BPP_MAP[this._options.colorType];let b=o(u,l,d,this._options,h);return b};s.prototype._packChunk=function(c,l){let d=l?l.length:0;let u=Buffer.alloc(d+12);u.writeUInt32BE(d,0);u.writeUInt32BE(c,4);if(l){l.copy(u,8)}u.writeInt32BE(i.crc32(u.slice(4,u.length-4)),u.length-4);return u};s.prototype.packGAMA=function(c){let l=Buffer.alloc(4);l.writeUInt32BE(Math.floor(c*t.GAMMA_DIVISION),0);return this._packChunk(t.TYPE_gAMA,l)};s.prototype.packIHDR=function(c,l){let d=Buffer.alloc(13);d.writeUInt32BE(c,0);d.writeUInt32BE(l,4);d[8]=this._options.bitDepth;d[9]=this._options.colorType;d[10]=0;d[11]=0;d[12]=0;return this._packChunk(t.TYPE_IHDR,d)};s.prototype.packIDAT=function(c){return this._packChunk(t.TYPE_IDAT,c)};s.prototype.packIEND=function(){return this._packChunk(t.TYPE_IEND,null)}}});var Nl=ee({"../../node_modules/pngjs/lib/packer-async.js"(e,n){"use strict";var t=me("util");var i=me("stream");var r=on();var o=Do();var a=n.exports=function(s){i.call(this);let c=s||{};this._packer=new o(c);this._deflate=this._packer.createDeflate();this.readable=true};t.inherits(a,i);a.prototype.pack=function(s,c,l,d){this.emit("data",Buffer.from(r.PNG_SIGNATURE));this.emit("data",this._packer.packIHDR(c,l));if(d){this.emit("data",this._packer.packGAMA(d))}let u=this._packer.filterData(s,c,l);this._deflate.on("error",this.emit.bind(this,"error"));this._deflate.on("data",function(h){this.emit("data",this._packer.packIDAT(h))}.bind(this));this._deflate.on("end",function(){this.emit("data",this._packer.packIEND());this.emit("end")}.bind(this));this._deflate.end(u)}}});var Fl=ee({"../../node_modules/pngjs/lib/sync-inflate.js"(e,n){"use strict";var t=me("assert").ok;var i=me("zlib");var r=me("util");var o=me("buffer").kMaxLength;function a(u){if(!(this instanceof a)){return new a(u)}if(u&&u.chunkSize<i.Z_MIN_CHUNK){u.chunkSize=i.Z_MIN_CHUNK}i.Inflate.call(this,u);this._offset=this._offset===void 0?this._outOffset:this._offset;this._buffer=this._buffer||this._outBuffer;if(u&&u.maxLength!=null){this._maxLength=u.maxLength}}function s(u){return new a(u)}function c(u,h){if(h){process.nextTick(h)}if(!u._handle){return}u._handle.close();u._handle=null}a.prototype._processChunk=function(u,h,b){if(typeof b==="function"){return i.Inflate._processChunk.call(this,u,h,b)}let p=this;let w=u&&u.length;let g=this._chunkSize-this._offset;let m=this._maxLength;let f=0;let y=[];let v=0;let $;this.on("error",function(E){$=E});function T(E,I){if(p._hadError){return}let P=g-I;t(P>=0,"have should not go down");if(P>0){let _=p._buffer.slice(p._offset,p._offset+P);p._offset+=P;if(_.length>m){_=_.slice(0,m)}y.push(_);v+=_.length;m-=_.length;if(m===0){return false}}if(I===0||p._offset>=p._chunkSize){g=p._chunkSize;p._offset=0;p._buffer=Buffer.allocUnsafe(p._chunkSize)}if(I===0){f+=w-E;w=E;return true}return false}t(this._handle,"zlib binding closed");let k;do{k=this._handle.writeSync(h,u,f,w,this._buffer,this._offset,g);k=k||this._writeState}while(!this._hadError&&T(k[0],k[1]));if(this._hadError){throw $}if(v>=o){c(this);throw new RangeError("Cannot create final Buffer. It would be larger than 0x"+o.toString(16)+" bytes")}let D=Buffer.concat(y,v);c(this);return D};r.inherits(a,i.Inflate);function l(u,h){if(typeof h==="string"){h=Buffer.from(h)}if(!(h instanceof Buffer)){throw new TypeError("Not a string or buffer")}let b=u._finishFlushFlag;if(b==null){b=i.Z_FINISH}return u._processChunk(h,b)}function d(u,h){return l(new a(h),u)}n.exports=e=d;e.Inflate=a;e.createInflate=s;e.inflateSync=d}});var Io=ee({"../../node_modules/pngjs/lib/sync-reader.js"(e,n){"use strict";var t=n.exports=function(i){this._buffer=i;this._reads=[]};t.prototype.read=function(i,r){this._reads.push({length:Math.abs(i),allowLess:i<0,func:r})};t.prototype.process=function(){while(this._reads.length>0&&this._buffer.length){let i=this._reads[0];if(this._buffer.length&&(this._buffer.length>=i.length||i.allowLess)){this._reads.shift();let r=this._buffer;this._buffer=r.slice(i.length);i.func.call(this,r.slice(0,i.length))}else{break}}if(this._reads.length>0){throw new Error("There are some read requests waitng on finished stream")}if(this._buffer.length>0){throw new Error("unrecognised content at end of stream")}}}});var Bl=ee({"../../node_modules/pngjs/lib/filter-parse-sync.js"(e){"use strict";var n=Io();var t=ko();e.process=function(i,r){let o=[];let a=new n(i);let s=new t(r,{read:a.read.bind(a),write:function(c){o.push(c)},complete:function(){}});s.start();a.process();return Buffer.concat(o)}}});var jl=ee({"../../node_modules/pngjs/lib/parser-sync.js"(e,n){"use strict";var t=true;var i=me("zlib");var r=Fl();if(!i.deflateSync){t=false}var o=Io();var a=Bl();var s=So();var c=xo();var l=To();n.exports=function(d,u){if(!t){throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0")}let h;function b(M){h=M}let p;function w(M){p=M}function g(M){p.transColor=M}function m(M){p.palette=M}function f(){p.alpha=true}let y;function v(M){y=M}let $=[];function T(M){$.push(M)}let k=new o(d);let D=new s(u,{read:k.read.bind(k),error:b,metadata:w,gamma:v,palette:m,transColor:g,inflateData:T,simpleTransparency:f});D.start();k.process();if(h){throw h}let E=Buffer.concat($);$.length=0;let I;if(p.interlace){I=i.inflateSync(E)}else{let M=(p.width*p.bpp*p.depth+7>>3)+1;let O=M*p.height;I=r(E,{chunkSize:O,maxLength:O})}E=null;if(!I||!I.length){throw new Error("bad png - invalid inflate data response")}let P=a.process(I,p);E=null;let _=c.dataToBitMap(P,p);P=null;let x=l(_,p,u.skipRescale);p.data=x;p.gamma=y||0;return p}}});var Ll=ee({"../../node_modules/pngjs/lib/packer-sync.js"(e,n){"use strict";var t=true;var i=me("zlib");if(!i.deflateSync){t=false}var r=on();var o=Do();n.exports=function(a,s){if(!t){throw new Error("To use the sync capability of this library in old node versions, please pin pngjs to v2.3.0")}let c=s||{};let l=new o(c);let d=[];d.push(Buffer.from(r.PNG_SIGNATURE));d.push(l.packIHDR(a.width,a.height));if(a.gamma){d.push(l.packGAMA(a.gamma))}let u=l.filterData(a.data,a.width,a.height);let h=i.deflateSync(u,l.getDeflateOptions());u=null;if(!h||!h.length){throw new Error("bad png - invalid compressed data response")}d.push(l.packIDAT(h));d.push(l.packIEND());return Buffer.concat(d)}}});var ql=ee({"../../node_modules/pngjs/lib/png-sync.js"(e){"use strict";var n=jl();var t=Ll();e.read=function(i,r){return n(i,r||{})};e.write=function(i,r){return t(i,r)}}});var zn=ee({"../../node_modules/pngjs/lib/png.js"(e){"use strict";var n=me("util");var t=me("stream");var i=Ol();var r=Nl();var o=ql();var a=e.PNG=function(s){t.call(this);s=s||{};this.width=s.width|0;this.height=s.height|0;this.data=this.width>0&&this.height>0?Buffer.alloc(4*this.width*this.height):null;if(s.fill&&this.data){this.data.fill(0)}this.gamma=0;this.readable=this.writable=true;this._parser=new i(s);this._parser.on("error",this.emit.bind(this,"error"));this._parser.on("close",this._handleClose.bind(this));this._parser.on("metadata",this._metadata.bind(this));this._parser.on("gamma",this._gamma.bind(this));this._parser.on("parsed",function(c){this.data=c;this.emit("parsed",c)}.bind(this));this._packer=new r(s);this._packer.on("data",this.emit.bind(this,"data"));this._packer.on("end",this.emit.bind(this,"end"));this._parser.on("close",this._handleClose.bind(this));this._packer.on("error",this.emit.bind(this,"error"))};n.inherits(a,t);a.sync=o;a.prototype.pack=function(){if(!this.data||!this.data.length){this.emit("error","No data provided");return this}process.nextTick(function(){this._packer.pack(this.data,this.width,this.height,this.gamma)}.bind(this));return this};a.prototype.parse=function(s,c){if(c){let l,d;l=function(u){this.removeListener("error",d);this.data=u;c(null,this)}.bind(this);d=function(u){this.removeListener("parsed",l);c(u,null)}.bind(this);this.once("parsed",l);this.once("error",d)}this.end(s);return this};a.prototype.write=function(s){this._parser.write(s);return true};a.prototype.end=function(s){this._parser.end(s)};a.prototype._metadata=function(s){this.width=s.width;this.height=s.height;this.emit("metadata",s)};a.prototype._gamma=function(s){this.gamma=s};a.prototype._handleClose=function(){if(!this._parser.writable&&!this._packer.readable){this.emit("close")}};a.bitblt=function(s,c,l,d,u,h,b,p){l|=0;d|=0;u|=0;h|=0;b|=0;p|=0;if(l>s.width||d>s.height||l+u>s.width||d+h>s.height){throw new Error("bitblt reading outside image")}if(b>c.width||p>c.height||b+u>c.width||p+h>c.height){throw new Error("bitblt writing outside image")}for(let w=0;w<h;w++){s.data.copy(c.data,(p+w)*c.width+b<<2,(d+w)*s.width+l<<2,(d+w)*s.width+l+u<<2)}};a.prototype.bitblt=function(s,c,l,d,u,h,b){a.bitblt(this,s,c,l,d,u,h,b);return this};a.adjustGamma=function(s){if(s.gamma){for(let c=0;c<s.height;c++){for(let l=0;l<s.width;l++){let d=s.width*c+l<<2;for(let u=0;u<3;u++){let h=s.data[d+u]/255;h=Math.pow(h,1/2.2/s.gamma);s.data[d+u]=Math.round(h*255)}}}s.gamma=0}};a.prototype.adjustGamma=function(){a.adjustGamma(this)}}});import{DEFAULT_BROKER_PORT as Ul}from"@buoy-gg/sync-broker";var ji=Ul;var Ao=`http://localhost:${ji}`;var Mo=15e3;var Li=2500;var zl=1200;var Eo=2e4;var Wl=3e4;var Co=5e3;var Hl=15*6e4;var qi="Dashboard";var ke="All";import{readFileSync as Oo,writeFileSync as Jl,mkdirSync as Gl,renameSync as Kl,unlinkSync as Vl}from"fs";import{dirname as Yl,join as Po,resolve as Xl}from"path";import{homedir as Zl}from"os";import{createHash as Ql}from"crypto";import{validateLicense as ed,isAcceptedValidation as td,isTransientLicenseError as nd,resolveTier as id,isRecognizedAccount as rd,isBuoyToken as od,verifyFreeToken as ad,resolveAccountAccess as sd,signCache as Wn,verifyCacheSignature as cd,LICENSE_LAUNCH_VALIDATION_TTL as Ro,LICENSE_REVALIDATION_INTERVAL as ft,LICENSE_TRANSIENT_RETRY_DELAYS as No,KEYGEN_CONFIG as ld,createNodeSession as dd,CLI_AUDIENCE as ud,exchangeServiceKey as hd,isServiceKey as pd,normalizeLicenseKey as Fo,checkDevToken as fd,isDevToken as md}from"@buoy-gg/license/headless";var Bo=["BUOY_LICENSE_KEY","BUOY_KEY","EXPO_PUBLIC_BUOY_KEY","VITE_BUOY_KEY","NEXT_PUBLIC_BUOY_KEY","REACT_APP_BUOY_KEY"];function Ui(e,n=process.env){for(const t of Bo)if(n[t]!==void 0)return Fo(n[t])||null;for(const t of[".env.development.local",".env.local",".env"]){let i;try{i=Oo(Po(e,t),"utf8")}catch{continue}const r=new Map;for(const o of i.split(/\r?\n/)){const a=o.match(/^\s*(?:export\s+)?([A-Z_][A-Z_0-9]*)\s*=\s*(.*)$/);if(!a)continue;const s=a[2].trim();const c=s.match(/^(['"])(.*?)\1\s*(?:#.*)?$/);r.set(a[1],c?c[2]:s.split("#")[0].trim())}for(const o of Bo)if(r.has(o))return Fo(r.get(o))||null}return null}var wd=class{constructor(e,n={}){this.changed=e;this.key=null;this.cache=null;this.timer=null;this.unsubscribeSession=null;this.generation=0;this.busy=false;this.nextCheck=0;this.retry=0;this.lastAdmission=false;this.hasAccess=()=>this.hasKeyAccess()||this.session?.getStatus().state==="active";this.lastSessionSync=0;this.projectDir=Xl(n.projectDir??process.env.BUOY_PROJECT_DIR??process.cwd());const t=Ql("sha256").update(this.projectDir).digest("hex").slice(0,20);this.cacheFile=n.cacheFile??Po(Zl(),".buoy",`account-${t}.json`);this.session=n.session!==void 0?n.session:dd({audience:ud,openBrowser:()=>{throw new Error("The MCP does not open a browser. Run `npx --package=@buoy-gg/core buoy login`.")}})}hasKeyAccess(){return sd({initialized:true,validating:false,key:this.key,tierSource:this.cache?.tier?"key":"none",verifiedAt:this.cache?.cachedAt??null}).status==="admitted"}start(){if(this.timer)return;if(this.session){this.unsubscribeSession=this.session.subscribe(()=>this.notify());void this.session.load().then(()=>this.notify(),()=>{})}try{const e=JSON.parse(Oo(this.cacheFile,"utf8"));if(e.valid&&cd(e))this.cache=e}catch{}void this.tick();this.timer=setInterval(()=>{void this.tick()},1e3);this.timer.unref()}stop(){++this.generation;this.unsubscribeSession?.();this.unsubscribeSession=null;if(this.timer)clearInterval(this.timer);this.timer=null;this.key=null;this.cache=null;this.notify()}notify(){const e=this.hasAccess();if(e===this.lastAdmission)return;this.lastAdmission=e;this.changed()}async tick(){if(this.session&&Date.now()-this.lastSessionSync>15e3){this.lastSessionSync=Date.now();void this.session.sync().catch(()=>{})}const e=Ui(this.projectDir);if(e!==this.key){++this.generation;this.key=e;if(this.cache?.licenseKey!==e)this.cache=null;this.nextCheck=0;this.retry=0;if(!e)this.removeCache()}this.notify();if(!e||this.busy||Date.now()<this.nextCheck)return;if(this.cache&&this.hasKeyAccess()&&Date.now()-this.cache.lastValidatedAt<Ro&&this.nextCheck===0){this.nextCheck=this.cache.lastValidatedAt+Ro;return}this.busy=true;const n=this.generation;try{if(md(e)){const s=fd(e);if(!s.ok){this.cache=null;this.removeCache()}else{const c=Math.min(Date.now(),s.claims.iat*1e3);const l=s.claims.tier==="free"?"free":"pro";this.cache=Wn({licenseKey:e,licenseId:`dev:${s.claims.sid}`,valid:true,tier:l,isPro:l==="pro",expiresAt:new Date(s.claims.exp*1e3).toISOString(),cachedAt:c,lastValidatedAt:Date.now()});this.persistCache()}this.nextCheck=Date.now()+ft;return}if(pd(e)){const s=await hd(e,{origin:process.env.BUOY_SITE_URL||"https://buoy.gg"});if(n!==this.generation||Ui(this.projectDir)!==e)return;if(!s.ok){if(s.reason==="rejected"){this.cache=null;this.removeCache();this.nextCheck=Date.now()+ft}else{this.nextCheck=Date.now()+(No[this.retry++]??ft)}return}const c=Date.now();const l=s.claims.exp*1e3;this.cache=Wn({licenseKey:e,licenseId:`service:${s.claims.sid}`,valid:true,tier:"pro",isPro:true,expiresAt:new Date(l).toISOString(),cachedAt:c,lastValidatedAt:c});this.persistCache();this.retry=0;this.nextCheck=Math.max(c+6e4,l-60*60*1e3);return}if(od(e)){const s=ad(e);if(!s){this.cache=null;this.removeCache()}else{const c=Date.now();this.cache=Wn({licenseKey:e,licenseId:`token:${s.accountHash}`,valid:true,tier:"free",isPro:false,expiresAt:null,cachedAt:c,lastValidatedAt:c});this.persistCache()}this.nextCheck=Date.now()+ft;return}const t=await ed(e);if(n!==this.generation||Ui(this.projectDir)!==e)return;const i=t.data?.relationships?.product?.data?.id;const r=t.meta.code==="EXPIRED"&&(rd(t.data)||this.cache?.licenseKey===e);if(i&&i!==ld.productId||!r&&!td(t)){this.cache=null;this.removeCache();this.nextCheck=Date.now()+ft;return}const o=r?"free":id(t.data);const a=Date.now();this.cache=Wn({licenseKey:e,licenseId:t.data?.id??"",valid:true,tier:o,isPro:o==="pro",expiresAt:r?null:t.data.attributes.expiry,cachedAt:a,lastValidatedAt:a});this.persistCache();this.retry=0;this.nextCheck=a+ft}catch(t){if(n!==this.generation)return;const i=nd(t)?No[this.retry++]:void 0;this.nextCheck=Date.now()+(i??ft)}finally{this.busy=false;this.notify()}}persistCache(){try{Gl(Yl(this.cacheFile),{recursive:true,mode:448});Jl(`${this.cacheFile}.tmp`,JSON.stringify(this.cache),{mode:384});Kl(`${this.cacheFile}.tmp`,this.cacheFile)}catch{}}removeCache(){try{Vl(this.cacheFile)}catch{}}};import gd from"http";import{randomUUID as bd}from"crypto";import{io as vd}from"socket.io-client";import{createBroker as yd,brokerTokenPath as zi,readBrokerToken as $d,writeBrokerToken as kd,DASHBOARD_TOKEN_REQUIRED as _d}from"@buoy-gg/sync-broker";import{execFile as Sd}from"child_process";import{promisify as xd}from"util";import ot from"path";import Td from"os";var jo=xd(Sd);async function Dd(e){let n;try{n=new URL(e)}catch{return null}if(!Id(n.hostname))return null;const t=n.port||(n.protocol==="https:"?"443":"80");try{const{stdout:i}=await jo("lsof",["-nP",`-iTCP:${t}`,"-sTCP:LISTEN","-t"],{timeout:3e3});const r=i.split("\n").map(s=>s.trim()).find(Boolean);if(!r)return null;const{stdout:o}=await jo("lsof",["-a","-p",r,"-d","cwd","-Fn"],{timeout:3e3});const a=o.split("\n").find(s=>s.startsWith("n"));return a?ot.resolve(a.slice(1)):null}catch{return null}}function Id(e,n=Td.networkInterfaces()){const t=e.replace(/^\[|\]$/g,"").toLowerCase();if(t==="localhost"||t==="127.0.0.1"||t==="::1"||t==="10.0.2.2"||t==="10.0.3.2")return true;return Object.values(n).flat().some(i=>i?.address?.toLowerCase()===t)}function Wi(e,n){const t=ot.resolve(n);const i=e.map(a=>({deviceId:a.deviceId,score:a.root?Ad(ot.resolve(a.root),t):-1})).filter(a=>a.score>=0);if(i.length===0)return null;const r=Math.min(...i.map(a=>a.score));const o=i.filter(a=>a.score===r);return o.length===1?o[0].deviceId:null}function Ad(e,n){if(e===n)return 0;const t=ot.relative(e,n);const i=ot.relative(n,e);const r=o=>o&&!o.startsWith("..")&&!ot.isAbsolute(o);if(r(t))return t.split(ot.sep).length;if(r(i))return i.split(ot.sep).length;return-1}function Md(e,n){return e==="app"&&(n==="ping"||n==="reloadApp")}function Lo(e){return e>=2}function Ed(e){if(Md(e.toolId,e.action)){return{timeoutMs:e.fullMs,usedFullBudget:false}}if(!Lo(e.consecutiveTimeouts)){return{timeoutMs:e.fullMs,usedFullBudget:false}}if(e.now-e.lastFullBudgetAt>e.recoveryProbeMs){return{timeoutMs:e.fullMs,usedFullBudget:true}}return{timeoutMs:e.shortMs,usedFullBudget:false}}function Cd(e){if(e.consecutiveTimeouts>=2)return true;if(e.lastOkAt>0&&e.now-e.lastOkAt>e.unresponsiveAfterMs){return true}return false}var Od=3e4;var Pd=5e3;function Rd(e,n,t){if(e!=="highlight-updates"||n!=="waitFor")return 0;const i=Number(t?.timeoutMs);if(!Number.isFinite(i)||i<=0)return 0;return Math.min(i,Od)+Pd}var mt="Not ready:";var Nd=class{constructor(e={}){this.socket=null;this.admitted=false;this.createdAt=Date.now();this.lockedDevices=new Set;this.hostAccount=null;this.broker=null;this.capabilities=new Map;this.devices=[];this.sessionDevice=null;this.snapshots=new Map;this.watching=new Map;this.pendingActions=new Map;this.snapshotWaiters=new Map;this.snapshotAt=new Map;this.health=new Map;this.devServerOrigins=new Map;this.crashSeen=new Map;this.rootLookups=new Set;this.devServerRoots=new Map;this.originProbed=new Set;this.lastSeen=new Map;this.transportLost=false;this.deviceConnections=new Map;this.port=e.port??ji;this.url=e.url??(e.port?`http://localhost:${e.port}`:Ao);this.actionTimeoutMs=e.actionTimeoutMs??Mo;this.log=e.log??(n=>process.stderr.write(`[buoy-mcp] ${n}
2
2
  `));this.autoSpawn=e.autoSpawnBroker??true}async start(){const e=await Hi(this.url)||await Hi(this.url,8e3);let n="connected";if(!e){if(!this.autoSpawn){throw new Error(`No Buoy broker reachable at ${this.url} and autoSpawnBroker is off. Start the Buoy desktop app, or enable autoSpawnBroker.`)}this.log(`no broker at ${this.url} \u2014 spawning one in-process on :${this.port}`);this.hostAccount=new wd(()=>this.broker?.refreshAccess());this.hostAccount.start();let t=false;this.broker=yd({canUseDesktop:this.hostAccount.hasAccess,port:this.port,onError:i=>{if(i.code==="EADDRINUSE")t=true;this.log(`broker error: ${i.code??i.message}`)}});await Fd(this.url).catch(i=>{if(!t)throw i});if(!this.broker.httpServer.listening)t=true;if(t){this.log(`another broker holds :${this.port} \u2014 connecting to it as a dashboard`);await this.broker.close().catch(()=>void 0);this.broker=null;this.hostAccount.stop();this.hostAccount=null;await this.connectSocket();return"connected"}try{kd(this.broker.dashboardToken,zi(this.port))}catch(i){this.log(`could not write the broker token file: ${i.message}`)}n="spawned"}else{this.log(`found a running broker at ${this.url} \u2014 connecting as a dashboard`)}await this.connectSocket();return n}connectSocket(){return _l(()=>new Promise((e,n)=>{const t=vd(this.url,{transports:["websocket"],query:{deviceName:qi},auth:s=>{const c=this.broker?.dashboardToken??$d(zi(this.port));s(c?{dashboardToken:c}:{})},reconnection:true,reconnectionDelay:500,timeout:4e3});this.socket=t;let i=false;const r=()=>{if(i)return;i=true;this.log("connected to broker");e()};const o=setTimeout(()=>{if(i)return;i=true;n(new Error("Broker account is locked or the broker needs an update. Sign in to Buoy Desktop or run npx --package=@buoy-gg/core buoy login for standalone MCP."))},5e3);t.on("buoy:access",s=>{const c=!!s&&typeof s==="object"&&s.protocol===1&&s.ready===true;this.setAdmission(c);if(c){clearTimeout(o);this.rearmWatches();r()}});t.on("connect",()=>{t.emit("buoy:access:request")});t.on("disconnect",()=>this.setAdmission(false,true));const a=s=>s.message===_d;t.once("connect_error",s=>{if(i)return;i=true;clearTimeout(o);n(new Error(a(s)?`The broker at ${this.url} refused this MCP as a dashboard: the token in ${zi(this.port)} is missing or stale. Update Buoy Desktop, or restart it so it writes the file.`:`failed to connect to broker at ${this.url}: ${s.message}`))});t.on("connect_error",s=>{if(!a(s)||t.active)return;setTimeout(()=>{if(this.socket===t&&!t.connected)t.connect()},1e3).unref?.()});t.on("devtool-capabilities",s=>{if(!this.admitted||this.lockedDevices.has(s.persistentDeviceId))return;this.capabilities.set(s.persistentDeviceId,s);this.trackRootLookup(this.learnDevServerOrigin(s.persistentDeviceId));if(s.tools?.some(c=>c.toolId==="console"))this.ensureWatching("console",s.persistentDeviceId)});t.on("all-devices-update",s=>{if(!this.admitted)return;if(!Array.isArray(s))return;let c=false;for(const d of s){if(d.deviceId&&(d.tier==="locked"||d.tier==="checking"))this.lockDevice(String(d.deviceId),d.tier==="checking");else if(d.deviceId&&(d.tier==="free"||d.tier==="pro")){c=this.lockedDevices.delete(String(d.deviceId))||c}}this.devices=s;const l=Date.now();for(const d of s)if(d.deviceId)this.lastSeen.set(d.deviceId,l);this.pruneStaleDevices();if(c)this.rearmWatches();else this.rearmReconnectedDevices(s)});t.on("devtool-sync",s=>{if(!this.admitted||this.lockedDevices.has(s.persistentDeviceId))return;const c=He(s.persistentDeviceId,s.toolId);this.snapshots.set(c,s.payload);this.snapshotAt.set(c,Date.now());if(s.toolId==="console")this.noteCrashReport(s.persistentDeviceId,s.payload);const l=this.snapshotWaiters.get(c);if(l&&l.length){this.snapshotWaiters.set(c,[]);for(const d of l)d(s.payload)}});t.on("devtool-action-result",s=>{if(!this.admitted)return;const c=this.pendingActions.get(s.requestId);if(!c)return;this.pendingActions.delete(s.requestId);clearTimeout(c.timer);c.resolve(s)})}))}isAdmitted(){return this.admitted}requireAdmission(){if(this.transportLost)throw new Error("The broker link was lost. Wait for it to reconnect.");if(!this.admitted)throw new Error("A verified Buoy account and an updated broker are required. Sign in to Buoy Desktop, or run npx --package=@buoy-gg/core buoy login for standalone MCP.")}setAdmission(e,n=false){this.transportLost=!e&&n;this.admitted=e;if(e)return;this.devices=[];this.lockedDevices.clear();this.capabilities.clear();this.snapshots.clear();this.snapshotAt.clear();this.devServerOrigins.clear();this.devServerRoots.clear();this.crashSeen.clear();this.originProbed.clear();this.health.clear();this.lastSeen.clear();if(!n)this.watching.clear();for(const t of this.pendingActions.values()){clearTimeout(t.timer);t.reject(new Error(n?"The broker link was lost during the call. Its result is unknown.":"Buoy account access ended while the action was pending."))}this.pendingActions.clear();for(const t of this.snapshotWaiters.values())for(const i of t)i(void 0);this.snapshotWaiters.clear();if(this.socket)this.socket.sendBuffer=[]}requireDeviceAccount(e){if(this.devices.some(n=>n.deviceId===e&&n.tier==="checking"))throw new Error(`${mt} The new app link is still checking access.`);if(this.lockedDevices.has(e))throw new Error("The device's Buoy account access ended. Sign in and verify its key.")}lockDevice(e,n=false){this.lockedDevices.add(e);this.capabilities.delete(e);this.health.delete(e);this.devServerOrigins.delete(e);this.devServerRoots.delete(e);this.originProbed.delete(e);const t=`${e}::`;for(const i of this.snapshots.keys())if(i.startsWith(t)){this.snapshots.delete(i);this.snapshotAt.delete(i)}for(const[i,r]of this.snapshotWaiters)if(i.startsWith(t)){this.snapshotWaiters.delete(i);for(const o of r)o(void 0)}for(const[i,r]of this.pendingActions)if(r.target===e||r.target===ke){clearTimeout(r.timer);this.pendingActions.delete(i);r.reject(new Error(n?"The app link changed during the call. Its result is unknown.":"Device account access ended while the action was pending."))}}pruneStaleDevices(){const e=Date.now()-Hl;for(const[n,t]of this.lastSeen){if(t>e)continue;if(this.devices.some(r=>r.deviceId===n))continue;this.lastSeen.delete(n);this.capabilities.delete(n);this.health.delete(n);this.devServerOrigins.delete(n);this.devServerRoots.delete(n);this.originProbed.delete(n);const i=`${n}::`;for(const r of[...this.snapshots.keys()]){if(r.startsWith(i)){this.snapshots.delete(r);this.snapshotAt.delete(r)}}for(const r of[...this.watching.keys()]){if(r.startsWith(i))this.watching.delete(r)}}}async stop(){this.setAdmission(false);this.hostAccount?.stop();this.hostAccount=null;for(const[,e]of this.pendingActions){clearTimeout(e.timer);e.reject(new Error("SyncClient stopped"))}this.pendingActions.clear();for(const[,e]of this.snapshotWaiters)for(const n of e)n(void 0);this.snapshotWaiters.clear();this.socket?.close();this.socket=null;if(this.broker){await this.broker.close();this.broker=null}}listDevices(){if(!this.admitted)return[];return this.devices.filter(e=>e.deviceName!==qi&&e.deviceId).map(e=>{const n=this.capabilities.get(e.deviceId);return{deviceId:e.deviceId,deviceName:e.deviceName,platform:e.platform,isConnected:e.isConnected!==false,isPro:e.isPro===true,tier:e.tier==="free"||e.tier==="pro"||e.tier==="checking"?e.tier:e.tier===void 0&&e.isPro===true?"pro":"locked",collision:e.collision===true,tools:n?.tools??[]}})}connectedDevices(){return this.listDevices().filter(e=>e.isConnected)}toolActions(e){return this.listDevices().map(n=>{const t=n.tools.find(i=>i.toolId===e);return t?{deviceId:n.deviceId,deviceName:n.deviceName,actions:t.actions}:null}).filter(n=>n!==null)}peekProjectDevice(){if(!this.admitted)return null;if(this.sessionDevice)return this.sessionDevice;const e=this.connectedDevices().filter(t=>!this.lockedDevices.has(t.deviceId)&&t.tools.length>0);const n=process.env.BUOY_PROJECT_ROOT||process.cwd();return Wi(e.map(t=>({deviceId:t.deviceId,root:this.devServerRoots.get(t.deviceId)})),n)??null}resolveDevice(e){this.requireAdmission();if(e){this.requireDeviceAccount(e);return e}const n=(l,d)=>new Error(`${mt} "${l}" (${d}) is not connected right now. If it is restarting, it usually takes a few seconds; to use another device, pass deviceId (run list_devices to see them).`);if(this.sessionDevice){const l=this.devices.find(d=>d.deviceId===this.sessionDevice);if(l&&l.isConnected!==false)return this.sessionDevice;throw n(this.sessionDevice,"the device this session was using")}const t=this.connectedDevices();const i=t.filter(l=>!this.lockedDevices.has(l.deviceId));const r=i.filter(l=>l.tools.length>0);const o=process.env.BUOY_PROJECT_ROOT||process.cwd();const a=Wi(r.map(l=>({deviceId:l.deviceId,root:this.devServerRoots.get(l.deviceId)})),o);if(a)return this.sessionDevice=a;const s=Wi(this.devices.filter(l=>l.deviceId&&l.isConnected===false&&!this.lockedDevices.has(l.deviceId)).map(l=>({deviceId:l.deviceId,root:this.devServerRoots.get(l.deviceId)})),o);if(s)throw n(s,"this project's app");if(i.length===0){if(t.length>0){throw new Error(`Devices are connected (${t.map(l=>l.deviceName).join(", ")}), but the broker has not admitted their accounts. Check app account validation and the account announcement after reconnect; this does not prove the user is signed out.`)}throw new Error("No devices are connected to the broker. Open the app with Buoy devtools running.")}if(i.length===1)return this.sessionDevice=i[0].deviceId;if(r.length===1)return this.sessionDevice=r[0].deviceId;if(r.length===0){const l=i.map(d=>d.deviceName).join(", ");throw new Error(`Connected devices (${l}) are not exposing any Buoy tools yet. Make sure the app is in the foreground with devtools mounted, then retry.`)}const c=r.map(l=>`${l.deviceName} (${l.deviceId})`).join(", ");throw new Error(`Multiple devices connected \u2014 specify deviceId. Connected: ${c}`)}requireProDevice(e){this.requireAdmission();const n=pt();if(e&&e!==ke)this.sessionDevice=e;const t=a=>{if(!a)return"";return a.tier==="locked"?` The broker has not confirmed account access for "${a.deviceName}"; a locked status does not establish whether a key is configured.`:` The connected app "${a.deviceName}" is on the ${a.tier} tier.`};const i=a=>n.level==="pro"?rn(n,t(a)):`The Buoy MCP needs an app on a Buoy account.${t(a)} Run \`npx --package=@buoy-gg/core buoy login\` in the project (free), restart the dev server with its cache cleared, then run \`list_devices\` to check.`;if(e===ke){const a=this.connectedDevices().filter(c=>c.isPro||c.tier==="free");const s=a.find(c=>!Ln(c,n.level));if(a.length===0)throw new Error(i());if(s)throw new Error(i(s));return ke}const r=this.resolveDevice(e);const o=this.connectedDevices().find(a=>a.deviceId===r);if(!Ln(o,n.level)){const a=this.accessState(r,n.level);if(a==="offline")throw new Error(`${mt} "${r}" is not connected right now. If the app is starting or reloading, it usually takes a few seconds. Run list_devices to check.`);if(a==="pending")throw new Error(`${mt} account access for "${r}" is still being confirmed (the app just connected). Try again in a moment.`);throw new Error(i(o))}return r}checkAppCall(e,n,t){const i=pt();if(!i.tool)return;const r=t===ke?this.connectedDevices().find(o=>o.tier==="free"&&!de(o)):this.listDevices().find(o=>o.deviceId===t&&!de(o));if(!r)return;if(i.level==="free"&&kl(e,n))return;throw new Error(rn({...i,level:"pro"},` The app "${r.deviceName}" is on the ${r.tier} tier${i.level==="free"?`, and this part of \`${i.tool}\` reads its ${e} data, which is Pro`:""}.`))}refuseBuoyPanelTap(e,n,t,i){if(e!=="highlight-updates"||n!=="tapElement")return null;const r=pt();if(!r.tool||r.level!=="free")return null;const o=t??{};const a=typeof o.nativeTag==="number"?o.nativeTag:null;const s=typeof o.testID==="string"&&o.testID?o.testID.toLowerCase():null;const c=a!=null||s!=null||!!o.includeBuoy;if(i===ke){if(!c||!this.connectedDevices().some(u=>u.tier==="free"&&!de(u)))return null;return Promise.reject(new Error(rn({...r,level:"pro"},' On a free app, tap one app at a time (not "All") when tapping by testID or nativeTag.')))}const l=this.listDevices().find(u=>u.deviceId===i);if(!l||de(l)||!c)return null;const d=u=>new Error(rn({...r,level:"pro"},u));if(o.includeBuoy)return Promise.reject(d(" That reaches Buoy's own panel, not the app."));return(async()=>{let u;try{u=await this.callAction("highlight-updates","describeScreen",{includeBuoy:false,includeHidden:true},i,{timeoutMs:4e3,silent:true})}catch(b){throw new Error(`Could not check that target before tapping (${b instanceof Error?b.message:String(b)}). On a free app, tap by query, or retry once the screen settles.`)}const h=(u?.elements??[]).some(b=>a!=null?b.nativeTag===a:b.testID?.toLowerCase()===s);if(!h&&a==null&&typeof o.query==="string"){const{testID:b,...p}=o;return p}if(!h){throw new Error(`"${a??String(o.testID)}" is not on the app's screen right now. On a free app, a tap by testID or nativeTag must hit an element describe_screen lists, and Buoy's own panels are Pro. Swipe it into view first, or tap by query.`)}})()}fullResultsFor(e){if(e===ke){const n=this.connectedDevices();return n.length>0&&n.every(t=>de(t))}return de(this.listDevices().find(n=>n.deviceId===e))}deviceWasAllowed(e){return Ln(this.listDevices().find(n=>n.deviceId===e),pt().level)}accessState(e,n=pt().level){const t=this.devices.find(i=>i.deviceId===e);if(!t||t.isConnected===false)return"offline";if(de(t)||n==="free"&&t.tier==="free")return"ready";return t.tier===void 0||t.tier==="checking"?"pending":"denied"}healthOf(e){let n=this.health.get(e);if(!n){n={consecutiveTimeouts:0,lastOkAt:0,lastFullBudgetAt:0};this.health.set(e,n)}return n}noteOk(e){const n=this.healthOf(e);n.consecutiveTimeouts=0;n.lastOkAt=Date.now()}noteTimeout(e){this.healthOf(e).consecutiveTimeouts+=1}isUnresponsive(e){return Lo(this.healthOf(e).consecutiveTimeouts)}timeoutFor(e,n,t){const i=this.healthOf(e);const{timeoutMs:r,usedFullBudget:o}=Ed({consecutiveTimeouts:i.consecutiveTimeouts,lastFullBudgetAt:i.lastFullBudgetAt,now:Date.now(),fullMs:this.actionTimeoutMs,shortMs:Li,recoveryProbeMs:Eo,toolId:n,action:t});if(o)i.lastFullBudgetAt=Date.now();return r}unresponsiveNote(e){const n=this.healthOf(e);const t=n.lastOkAt?Math.round((Date.now()-n.lastOkAt)/1e3):null;const i=Cd({consecutiveTimeouts:n.consecutiveTimeouts,lastOkAt:n.lastOkAt,now:Date.now(),unresponsiveAfterMs:Wl});const r=[`The app on "${e}" is not responding (${n.consecutiveTimeouts} call${n.consecutiveTimeouts===1?"":"s"} unanswered${t!=null?`, last answered ${t}s ago`:""}).`,i?"It is most likely CRASHED \u2014 a fatal render error unmounts the React tree, and the dev tools live in that tree, so nothing on-device can answer until the app is reloaded.":"It may be busy, mid-reload, or crashing."];const o=this.lastFatalFor(e);if(o)r.push(`Last captured error: ${o}`);r.push(o?"Read the crash state with get_console / get_storage (served from the last sync), then reload_app to recover.":"Try get_console (served from the last sync) for the app's last words, then reload_app to recover.");return r.join(" ")}noteCrashReport(e,n){const t=n?.entries;if(!Array.isArray(t)||t.length===0)return;const i=Math.max(...t.map(a=>typeof a?.timestamp==="number"?a.timestamp:-Infinity));const r=this.crashSeen.get(e)??new Set;let o=false;for(const a of t){const s=a?.fatal||/^\[(RENDER ERROR|FATAL)/.test(a?.message??"");if(!s||typeof a.timestamp!=="number")continue;const c=`${a.id??""}|${a.timestamp}|${(a.message??"").slice(0,120)}`;if(r.has(c))continue;r.add(c);if(i-a.timestamp<3e4)o=true}if(r.size>200)for(const a of[...r].slice(0,r.size-200))r.delete(a);this.crashSeen.set(e,r);if(!o)return;if(![...this.pendingActions.values()].some(a=>a.target===e&&a.expire&&!a.cut))return;void this.callAction("app","ping",{},e,{timeoutMs:1500,silent:true}).then(()=>void 0,()=>{const a=Date.now();for(const s of this.pendingActions.values()){if(s.target!==e||!s.expire||s.cut)continue;s.cut=true;if(s.deadline!==void 0&&s.deadline-a<=Li)continue;clearTimeout(s.timer);s.timer=setTimeout(s.expire,Li)}})}lastFatalFor(e){const n=this.snapshots.get(He(e,"console"));const t=n?.entries;if(!Array.isArray(t))return null;for(let i=t.length-1;i>=0;i--){const r=t[i];if(r?.fatal||r?.level==="error"){const o=(r.message??"").split("\n")[0];if(o)return o.length>300?`${o.slice(0,300)}\u2026`:o}}return null}snapshotAgeMs(e,n){this.requireAdmission();const t=this.snapshotAt.get(He(n,e));return t?Date.now()-t:null}noteDevServerOrigin(e,n){if(typeof n==="string"&&/^https?:\/\//.test(n)){const t=this.devServerOrigins.get(e)!==n;this.devServerOrigins.set(e,n);if(t)this.devServerRoots.delete(e);if(t||!this.devServerRoots.has(e)){const i=Dd(n).then(r=>{if(r&&this.devServerOrigins.get(e)===n)this.devServerRoots.set(e,r)});this.trackRootLookup(i)}}}async learnDevServerOrigin(e){if(this.devServerOrigins.has(e)||this.originProbed.has(e))return;this.originProbed.add(e);const n=this.capabilities.get(e)?.tools?.some(t=>t.toolId==="app");if(!n)return;try{const{payload:t}=await this.getSnapshot("app",e,{timeoutMs:4e3,silent:true});this.noteDevServerOrigin(e,t?.devServerOrigin)}catch{}}trackRootLookup(e){const n=e.catch(()=>void 0).finally(()=>this.rootLookups.delete(n));this.rootLookups.add(n)}async awaitBroker(){if(Date.now()-this.createdAt>15e3)return;for(let e=0;!this.admitted&&e<4e3;e+=100)await new Promise(n=>setTimeout(n,100));for(let e=0;this.admitted&&this.devices.length===0&&e<1500;e+=100)await new Promise(n=>setTimeout(n,100))}async settleDeviceChoice(e=1500){await this.awaitBroker();if(this.sessionDevice||this.rootLookups.size===0||this.connectedDevices().length<2)return;await Promise.race([Promise.all([...this.rootLookups]),new Promise(n=>setTimeout(n,e))]);if(this.rootLookups.size)await Promise.race([Promise.all([...this.rootLookups]),new Promise(n=>setTimeout(n,Math.min(800,e)))])}devServerOrigin(e){this.requireAdmission();const n=this.devServerOrigins.get(e);if(n)return n;const t=this.snapshots.get(He(e,"app"));if(typeof t?.devServerOrigin==="string")return t.devServerOrigin;return null}ensureWatching(e,n){const t=He(n,e);if(this.watching.has(t))return;this.watching.set(t,{toolId:e,targetDeviceId:n});this.sendWatch(e,n)}sendWatch(e,n){if(!this.admitted||!this.socket?.connected||this.lockedDevices.has(n))return;this.socket?.emit("devtool-watch",{toolId:e,targetDeviceId:n,watching:true,stream:false})}rearmWatches(){for(const{toolId:e,targetDeviceId:n}of this.watching.values()){this.sendWatch(e,n)}}rearmReconnectedDevices(e){for(const n of e){if(!n.deviceId||n.isConnected===false)continue;const t=String(n.deviceId);const i=`${n.id}|${n.connectionNonce??""}`;const r=this.deviceConnections.get(t);this.deviceConnections.set(t,i);if(r===void 0||r===i)continue;for(const{toolId:o,targetDeviceId:a}of this.watching.values()){if(a===t)this.sendWatch(o,a)}}}unwatch(e,n){const t=He(n,e);if(!this.watching.delete(t))return;if(this.admitted&&this.socket?.connected)this.socket.emit("devtool-watch",{toolId:e,targetDeviceId:n,watching:false})}cachedSnapshot(e,n){this.requireAdmission();this.requireDeviceAccount(n);this.checkAppCall(e,"@snapshot",n);return this.snapshots.get(He(n,e))}async getSnapshot(e,n,t={}){const i=this.resolveDevice(n);this.checkAppCall(e,"@snapshot",i);const r=He(i,e);this.ensureWatching(e,i);let o=t.timeoutMs??Co;if(t.timeoutMs===void 0&&this.isUnresponsive(i)){const l=this.healthOf(i);if(Date.now()-l.lastFullBudgetAt>Eo){l.lastFullBudgetAt=Date.now()}else{o=zl}}const a=this.waitForSnapshot(r,o);this.socket?.emit("request-devtool-state",{toolId:e,targetDeviceId:i});const s=await a;this.requireAdmission();this.requireDeviceAccount(i);if(s!==void 0){if(!t.silent)this.noteOk(i);return{deviceId:i,payload:s}}if(!t.silent)this.noteTimeout(i);const c=this.snapshots.get(r);if(c!==void 0){return{deviceId:i,payload:c,stale:this.staleNote(e,i)}}throw new Error(`Timed out waiting for "${e}" state from ${i} (is the tool active?). ${this.unresponsiveNote(i)}`)}lastSync(e,n){this.checkAppCall(n,"@snapshot",e);const t=this.snapshots.get(He(e,n));return t===void 0?void 0:{payload:t,ageMs:this.snapshotAgeMs(n,e)}}staleNote(e,n){const t=this.snapshotAgeMs(e,n);const i=t==null?"an earlier sync":`${Math.round(t/1e3)}s ago`;return`\u26A0\uFE0F Served from the last sync (${i}) \u2014 ${this.unresponsiveNote(n)}`}waitForSnapshot(e,n){return new Promise(t=>{const i=this.snapshotWaiters.get(e)??[];const r=setTimeout(()=>{const a=(this.snapshotWaiters.get(e)??[]).filter(s=>s!==o);this.snapshotWaiters.set(e,a);t(void 0)},n);const o=a=>{clearTimeout(r);t(a)};i.push(o);this.snapshotWaiters.set(e,i)})}async callAction(e,n,t,i,r={}){this.requireAdmission();const o=i===ke?ke:this.resolveDevice(i);this.checkAppCall(e,n,o);const a=this.refuseBuoyPanelTap(e,n,t,o);if(a)t=await a??t;if(!this.socket)throw new Error("SyncClient is not connected");const s=bd();const c=r.timeoutMs??Math.max(this.timeoutFor(o,e,n),Rd(e,n,t));const l=await new Promise((d,u)=>{const h=Date.now();const b=()=>{this.pendingActions.delete(s);if(o!==ke&&!r.silent)this.noteTimeout(o);u(new Error(`Action "${e}.${n}" got no answer in ${Date.now()-h}ms. `+(o===ke?"No device responded.":this.unresponsiveNote(o))))};const p=setTimeout(b,c);this.pendingActions.set(s,{resolve:d,reject:u,timer:p,target:o,expire:b,deadline:h+c});this.socket.emit("devtool-action",{requestId:s,toolId:e,targetDeviceId:o,action:n,params:t??{}})});if(o!==ke&&!r.silent)this.noteOk(o);if(!l.ok){throw new Error(l.error||`Action "${e}.${n}" failed on device`)}return l.result}};var He=(e,n)=>`${e}::${n}`;function Hi(e,n=800){return new Promise(t=>{const i=gd.get(e,r=>{r.resume();t((r.statusCode??0)>0)});i.setTimeout(n,()=>{i.destroy();t(false)});i.on("error",()=>t(false))})}async function Fd(e,n=20){for(let t=0;t<n;t++){if(await Hi(e,300))return;await Bd(50)}throw new Error(`Spawned broker never became reachable at ${e}`)}var Bd=e=>new Promise(n=>setTimeout(n,e));import{promises as qo}from"fs";import jd from"os";import Ld from"path";var qd=24*60*60*1e3;var Ud=1500;var zd=`https://registry.npmjs.org/${uo}/latest`;var Uo=Ld.join(jd.tmpdir(),"buoy-mcp-update-check.json");function Wd(e,n){const t=o=>o.split("-")[0].split(".").map(a=>Number(a)||0);const i=t(e);const r=t(n);for(let o=0;o<3;o++){const a=i[o]??0;const s=r[o]??0;if(a>s)return true;if(a<s)return false}return false}async function Hd(){try{const e=await qo.readFile(Uo,"utf8");const n=JSON.parse(e);if(typeof n.checkedAt==="number"&&typeof n.latest==="string"){return n}}catch{}return null}async function Jd(e){const n=new AbortController;const t=setTimeout(()=>n.abort(),Ud);try{const i=await fetch(zd,{signal:n.signal});if(!i.ok)return null;const r=await i.json();const o=typeof r.version==="string"?r.version:null;if(o){await qo.writeFile(Uo,JSON.stringify({checkedAt:e,latest:o})).catch(()=>{})}return o}catch{return null}finally{clearTimeout(t)}}async function Gd(e){const n=await Hd();if(n&&e-n.checkedAt<qd)return n.latest;return Jd(e)}async function zo(e=Date.now()){if(Nn==="0.0.0-dev")return null;try{const n=await Gd(e);if(n&&Wd(n,Nn)){return`A newer buoy-mcp is available (${n}; you're on ${Nn}). Update by re-running: npx -y ${uo}@latest init \u2014 then restart your editor.`}}catch{}return null}import{z as te}from"zod";import{execFile as Kd}from"child_process";import{promisify as Vd}from"util";import{promises as je}from"fs";import Wo from"os";import Me from"path";import{randomUUID as Ho}from"crypto";var an=Vd(Kd);var Hn=(e,n,t)=>Math.min(Math.max(e,n),t);function Jo(e){const n=e;if(n?.code==="ENOENT"){return"Xcode command-line tools (xcrun) not found. Install Xcode to capture the iOS Simulator."}const t=String(n?.stderr||n?.message||e);if(/No devices are booted|Unable to find device|current device/i.test(t)){return"No booted iOS Simulator found. Boot the Simulator with your app running, then try again."}return t.trim()||"Failed to capture the iOS Simulator."}function Yd(e){const n=[137,80,78,71,13,10,26,10];if(e.length<24||!n.every((t,i)=>e[i]===t))return null;return{width:e.readUInt32BE(16),height:e.readUInt32BE(20)}}var Xd="@react_buoy_sync_device_id";async function Jn(e){try{return await je.readdir(e)}catch{return[]}}async function Zd(e){const n=[];for(const t of await Jn(e))n.push(...await Go(Me.join(e,t)));return n}async function Go(e){const n=[];const t=Me.join(e,"Library","WebKit");for(const i of await Jn(t)){const r=Me.join(t,i,"WebsiteData","Default");for(const o of await Jn(r)){for(const a of await Jn(Me.join(r,o))){const s=Me.join(r,o,a,"LocalStorage","localstorage.sqlite3");try{await je.access(s);const{stdout:c}=await an("sqlite3",["-readonly",s,`SELECT hex(value) FROM ItemTable WHERE key='${Xd}' LIMIT 1;`],{timeout:1500});const l=c.trim();if(l)n.push(Buffer.from(l,"hex").toString("utf16le").trim())}catch{}}}}return n}var Ko=new Map;var Qd=3e4;async function Vo(e){if(process.platform!=="darwin")return{ok:false,error:"Simulator lookup needs macOS."};let n=[];try{const{stdout:i}=await an("xcrun",["simctl","list","devices","booted","-j"],{timeout:1e4});const r=JSON.parse(i).devices;n=Object.entries(r).filter(([o])=>/iOS/.test(o)).flatMap(([,o])=>o.filter(a=>a.state==="Booted"))}catch(i){return{ok:false,error:Jo(i)}}if(n.length===0)return{ok:false,error:"No iOS Simulator is booted."};const t=e?.split("-").pop();if(t){for(const i of n){if(!i.dataPath)continue;const r=Me.join(i.dataPath,"Containers","Data","Application");let o=[];try{o=await je.readdir(r)}catch{continue}for(const a of o){try{const s=(await je.readFile(Me.join(r,a,"Documents","react-buoy","@react_buoy_sync_device_id.json"),"utf8")).trim();if(s===t)return{ok:true,udid:i.udid,how:`matched ${e} to "${i.name}"`}}catch{}}}}if(t&&e){const i=n.map(c=>c.udid).sort().join(",");const r=Ko.get(e);const o=r?.booted===i&&(r.udid!==null||Date.now()-r.at<Qd);const a=o&&r?.udid?n.find(c=>c.udid===r.udid):void 0;if(a)return{ok:true,udid:a.udid,how:`matched ${e} to "${a.name}" (WebView storage)`};const s=[];if(!o){const c=await Promise.all(n.map(l=>l.dataPath?Zd(Me.join(l.dataPath,"Containers","Data","Application")):Promise.resolve([])));c.forEach((l,d)=>{if(l.includes(t))s.push(n[d])});Ko.set(e,{booted:i,udid:s.length===1?s[0].udid:null,at:Date.now()})}if(s.length===1){return{ok:true,udid:s[0].udid,how:`matched ${e} to "${s[0].name}" (WebView storage)`}}if(s.length>1){return{ok:false,error:`${s.length} booted simulators (${s.map(c=>c.name).join(", ")}) hold ${e}. Pass the udid, or shut one down.`}}}if(n.length===1)return{ok:true,udid:n[0].udid,how:`only booted simulator "${n[0].name}"`};return{ok:false,error:`${n.length} iOS Simulators are booted (${n.map(i=>i.name).join(", ")}) and none could be matched to ${e??"this device"}. Shut down the others, or capture from a single booted simulator.`}}async function eu(e){const n=new Map;if(process.platform!=="darwin"||e.length===0)return n;let t=[];try{const{stdout:r}=await an("xcrun",["simctl","list","devices","booted","-j"],{timeout:1e4});const o=JSON.parse(r).devices;t=Object.entries(o).filter(([a])=>/iOS/.test(a)).flatMap(([,a])=>a.filter(s=>s.state==="Booted"))}catch{return n}const i=new Map;for(const r of t){if(!r.dataPath)continue;const o=Me.join(r.dataPath,"Containers","Data","Application");let a=[];try{a=await je.readdir(o)}catch{continue}for(const s of a){try{const c=(await je.readFile(Me.join(o,s,"Documents","react-buoy","@react_buoy_sync_device_id.json"),"utf8")).trim();if(c)i.set(c,{name:r.name,udid:r.udid})}catch{}}}for(const r of e){const o=i.get(r.split("-").pop()??"");if(o)n.set(r,o)}return n}async function Yo(e="booted"){if(process.platform!=="darwin"){return{ok:false,error:"Screenshotting a component requires macOS with Xcode's iOS Simulator (uses `xcrun simctl`)."}}const n=Me.join(Wo.tmpdir(),`buoy-mcp-sim-${Ho()}.png`);try{await an("xcrun",["simctl","io",e,"screenshot","--type=png",n],{timeout:15e3})}catch(t){return{ok:false,error:Jo(t)}}try{const t=await je.readFile(n);const i=Yd(t);if(!i)return{ok:false,error:"Captured file wasn't a valid PNG."};return{ok:true,srcPath:n,width:i.width,height:i.height}}catch(t){return{ok:false,error:`Failed to read screenshot: ${t.message}`}}}async function tu(e,n,t){const i=Hn(Math.round(t.x),0,Math.max(0,n.width-1));const r=Hn(Math.round(t.y),0,Math.max(0,n.height-1));const o=Hn(Math.round(t.width),1,n.width-i);const a=Hn(Math.round(t.height),1,n.height-r);const s=Me.join(Wo.tmpdir(),`buoy-mcp-crop-${Ho()}.png`);try{await an("sips",["-c",String(a),String(o),"--cropOffset",String(r),String(i),e,"--out",s],{timeout:1e4});const c=await je.readFile(s);return{ok:true,buffer:c,width:o,height:a}}catch(c){const l=c;return{ok:false,error:`Crop failed: ${l?.stderr||l?.message||c}`}}finally{await je.unlink(s).catch(()=>{});await je.unlink(e).catch(()=>{})}}import{execFile as nu}from"child_process";import{promisify as iu}from"util";var Ji=Un(zn());import{execFile as ru}from"child_process";import{promisify as ou}from"util";import{promises as ie}from"fs";import sn from"os";import Y from"path";import{randomUUID as au}from"crypto";var su=Un(zn());import{execFile as cu}from"child_process";import{promisify as lu}from"util";import{promises as wt}from"fs";import Gi from"os";import Ki from"path";import{randomUUID as Vi}from"crypto";var du=lu(cu);async function xe(e,n=3e4){const t=Ki.join(Gi.tmpdir(),`buoy-devicectl-${Vi()}.json`);try{await du("xcrun",["devicectl",...e,"--quiet","--json-output",t],{timeout:n,maxBuffer:16*1024*1024});return JSON.parse(await wt.readFile(t,"utf8"))}catch(i){const r=i;let o=(r.stderr||r.stdout||r.message||"").trim();try{const a=JSON.parse(await wt.readFile(t,"utf8"));o=a.error?.userInfo?.NSLocalizedDescription?.string??o}catch{}if(/locked/i.test(o))throw new Error("The iPhone is locked. Unlock it and try again.");throw new Error(`devicectl ${e.slice(0,2).join(" ")} failed: ${o.split("\n").slice(-3).join(" ").slice(0,300)}`)}finally{await wt.unlink(t).catch(()=>void 0)}}async function uu(){if(process.platform!=="darwin")return[];return hu(await xe(["list","devices"],15e3).catch(()=>null))}function hu(e){const n=e;return(n?.result?.devices??[]).filter(t=>t.hardwareProperties?.reality==="physical"&&t.hardwareProperties?.platform==="iOS"&&t.connectionProperties?.pairingState==="paired"&&t.connectionProperties?.tunnelState!=="unavailable").map(t=>({udid:t.hardwareProperties.udid,name:t.deviceProperties?.name??"iPhone"})).filter(t=>!!t.udid)}async function Xo(e){const n=await xe(["device","info","apps","--device",e]);return(n.result?.apps??[]).filter(t=>t.bundleIdentifier&&!t.bundleIdentifier.startsWith("com.apple.")&&t.builtByDeveloper!==false).map(t=>({bundleId:t.bundleIdentifier,name:t.name??t.bundleIdentifier,path:t.url?.replace(/^file:\/\//,"")}))}async function Zo(e,n,t){const i=await xe(["device","info","files","--device",e,"--domain-type","appDataContainer","--domain-identifier",n],2e4);const r=new Set((i.result?.files??[]).map(a=>a.relativePath??a.name??""));if(!r.has(t))return null;const o=Ki.join(Gi.tmpdir(),`buoy-devfile-${Vi()}`);try{await xe(["device","copy","from","--device",e,"--domain-type","appDataContainer","--domain-identifier",n,"--source",t,"--destination",o],2e4);return await wt.readFile(o)}finally{await wt.rm(o,{recursive:true,force:true}).catch(()=>void 0)}}async function Qo(e,n){const t=await Zo(e,n,"Documents/react-buoy/@react_buoy_sync_device_id.json").catch(()=>null);const i=t?.toString("utf8").trim().replace(/^"|"$/g,"")??"";return/^[\w-]{4,64}$/.test(i)?i:null}async function ea(e){const n=Ki.join(Gi.tmpdir(),`buoy-phone-shot-${Vi()}.png`);try{await xe(["device","capture","screenshot","--device",e,"--destination",n],3e4);return await wt.readFile(n)}finally{await wt.unlink(n).catch(()=>void 0)}}var pu="The picture is all black. If the app isn't really showing black, the iPhone's own screen is off: it is asleep, or the Mac shows it in iPhone Mirroring (the phone stays locked then). Quit iPhone Mirroring, unlock the phone and keep its screen on, then try again.";function fu(e){try{const n=su.PNG.sync.read(e);const t=Math.max(1,Math.floor(n.width*n.height/4e3));for(let i=0;i<n.width*n.height;i+=t){const r=i*4;if(n.data[r]>12||n.data[r+1]>12||n.data[r+2]>12)return false}return true}catch{return false}}async function Yi(e,n,t={}){await xe(["device","process","launch","--device",e,...t.terminateExisting?["--terminate-existing"]:[],...t.url?["--payload-url",t.url]:[],n])}async function mu(e,n){await xe(["device","process","openURL","--device",e,n])}async function ta(e,n){const t=await Xo(e);const i=t.find(a=>a.bundleId===n)?.path;const r=await xe(["device","info","processes","--device",e]);const o=(r.result?.runningProcesses??[]).find(a=>i&&decodeURIComponent(a.executable??"").replace(/^file:\/\//,"").startsWith(i.replace(/\/$/,"")));if(!o?.processIdentifier)return false;await xe(["device","process","terminate","--device",e,"--pid",String(o.processIdentifier)]);return true}async function wu(e,n){await xe(["device","uninstall","app","--device",e,n],12e4)}async function gu(e,n){await xe(["device","install","app","--device",e,n],3e5)}async function bu(e,n,t,i){await xe(["device","copy","to","--device",e,"--domain-type","appDataContainer","--domain-identifier",n,"--source",t,"--destination",i],3e4)}function vu(e,n,t){return["devicectl","device","capture","screen-record","--device",e,"--destination",n,"--duration",String(t)]}var na=new Map;async function Gn(e){const n=na.get(e);if(n)return n;const t=await xe(["list","devices"]);const i=t.result?.devices?.find(r=>r.hardwareProperties?.udid===e)?.identifier;if(!i)throw new Error("CoreDevice doesn't list this iPhone right now. Check that it is connected and unlocked.");na.set(e,i);return i}import{execFile as yu}from"child_process";import{promisify as $u}from"util";import{promises as Xi}from"fs";import Ot from"path";import{WebSocket as ku}from"ws";import{execFile as _u}from"child_process";import{promisify as Su}from"util";var Zi=/\{\{\s*secret:([A-Za-z_][A-Za-z0-9_]*)\s*\}\}/g;var Pt=6;var Qi=new Map;var ia=()=>false;function xu(e){ia=e}function Tu(e){Zi.lastIndex=0;return Zi.test(e)}function Kn(e,n=process.env){if(!Tu(e))return e;if(ia()){throw new Error("A screen recording is running, and a video can't hide a typed secret. Stop the recording first (screen_recording stop), then type it.")}const t=[];const i=[];const r=e.replace(Zi,(o,a)=>{const s=n[`BUOY_SECRET_${a}`]??n[a];if(s===void 0||s===""){t.push(a);return""}if(s.length<Pt){i.push(a);return""}Qi.set(a,s);return s});if(t.length){throw new Error(`No value for ${t.map(o=>`{{secret:${o}}}`).join(", ")}. Set ${t.map(o=>`BUOY_SECRET_${o}`).join(", ")} in the environment the MCP server runs in (for example in your editor's MCP config "env").`)}if(i.length){throw new Error(`${i.map(o=>`{{secret:${o}}}`).join(", ")} is shorter than ${Pt} characters, so Buoy can't hide it reliably in what it sends back. Use a longer value, or type it as plain text if it isn't sensitive.`)}return r}function ra(e=process.env){const n=new Map(Qi);for(const[t,i]of Object.entries(e))if(t.startsWith("BUOY_SECRET_")&&i)n.set(t.slice("BUOY_SECRET_".length),i);return n}var Du=e=>e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Te(e){const n=new Map;for(const[r,o]of ra()){if(o.length<Pt)continue;for(const a of[o,JSON.stringify(o).slice(1,-1),encodeURIComponent(o)])n.set(a,r);for(let a=o.length-1;a>=Pt;a--){n.set(`${o.slice(0,a)}\u2026`,r);n.set(`${o.slice(0,a)}...`,r);if(a>=8)n.set(o.slice(0,a),r)}}if(n.size===0)return e;const t=[...n.keys()].sort((r,o)=>o.length-r.length);const i=new RegExp(t.map(Du).join("|"),"g");return e.replace(i,(r,o,a)=>{if(/^\d+$/.test(r)){const s=a.slice(Math.max(0,o-8),o);const c=a.slice(o+r.length,o+r.length+8);if(/(\d|\d\.)$/.test(s)||/^(\d|\.\d|[eE][+-]?\d)/.test(c))return r;if(/[:[,]\s*$/.test(s)&&/^\s*([,\]}]|$)/.test(c)&&!Iu(a,o))return`"{{secret:${n.get(r)}}}"`}return`{{secret:${n.get(r)}}}`})}function Iu(e,n){let t=false;for(let i=0;i<n;i++){if(e[i]==="\\")i++;else if(e[i]==='"')t=!t}return t}function er(){return[...Qi.values()]}function Au(){return[...ra().values()].filter(e=>e.length>=Pt)}var oa=Su(_u);var tr="Android control needs adb on this computer (Android SDK platform-tools). Install it, or add it to PATH.";function ue(e){return`'${e.replace(/'/g,`'\\''`)}'`}function aa(e){if(!/^[A-Za-z][\w]*(\.[A-Za-z_][\w]*)+$/.test(e))throw new Error(`"${e}" is not a valid Android package name.`);return e}function cn(e,n){const t=e?ho(e):null;if(t)return{bin:t.adb,args:["-P",String(t.port),"-s",e,...n]};return{bin:"adb",args:e?["-s",e,...n]:n}}async function Le(e,n,t=15e3){try{const i=cn(e,n);const{stdout:r}=await oa(i.bin,i.args,{timeout:t,maxBuffer:32*1024*1024});return r}catch(i){const r=i;if(r.code==="ENOENT")throw new Error(tr);const o=n[0]==="shell"?`shell ${(n[1]??"").split(" ")[0]}`:n.slice(0,2).join(" ");const a=n[0]==="shell"?r.stderr||(r.killed?"timed out":"no error text"):r.stderr||r.message||"";const s=Te(a.replace(/'[^']*'/g,"'\u2026'")).trim().slice(0,300);throw new Error(`adb ${o} failed: ${s}`)}}function J(e,n,t=15e3){return Le(e,["shell",n],t)}async function sa(e,n,t=15e3){try{const i=cn(e,n);const{stdout:r}=await oa(i.bin,i.args,{timeout:t,encoding:"buffer",maxBuffer:64*1024*1024});return r}catch(i){const r=i;if(r.code==="ENOENT")throw new Error(tr);throw new Error(`adb ${n.slice(0,2).join(" ")} failed: ${r.message.slice(0,300)}`)}}async function ca(){const e=[...ll().keys()];try{const n=Mu(await Le(null,["devices"]));return[...n,...e.filter(t=>!n.includes(t))]}catch(n){if(e.length&&n.message===tr)return e;throw n}}function Mu(e){return e.split("\n").slice(1).map(n=>n.trim().split(/\s+/)).filter(n=>n[1]==="device").map(n=>n[0])}async function Vn(e){const n=Eu(await J(e,"wm size"));const t=Cu(await J(e,"dumpsys input").catch(()=>""));return t%2===1?{width:n.height,height:n.width}:n}function Eu(e){const n=/Override size:\s*(\d+)x(\d+)/.exec(e);const t=/Physical size:\s*(\d+)x(\d+)/.exec(e);const i=n??t;if(!i)throw new Error(`Could not read the Android screen size (adb said: ${e.trim().slice(0,120)}).`);return{width:Number(i[1]),height:Number(i[2])}}function Cu(e){const n=/SurfaceOrientation:\s*(\d)/.exec(e);return n?Number(n[1]):0}async function nr(e,n){const t=await J(e,"dumpsys window windows").catch(()=>"");return Ou(t,n)}function Ou(e,n){const t=e.split(/\n(?=\s*Window #\d+)/);for(const i of t){if(!i.includes(`${n}/`))continue;const r=/mFrame=\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]/.exec(i)??/\bframe=\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]/.exec(i);if(r){const[o,a,s,c]=r.slice(1).map(Number);if(s>o&&c>a)return{x:o,y:a,width:s-o,height:c-a}}}return null}async function Pu(e){return Ru(await J(e,"dumpsys activity activities"))}function Ru(e){const n=/(?:topResumedActivity|mResumedActivity|ResumedActivity)[^\n]*?\s([a-zA-Z][\w.]*)\/[\w.$]+/.exec(e);return n?n[1]:null}async function Nu(e){const n=await J(e,"pm list packages -3");return n.split("\n").map(t=>t.trim().replace(/^package:/,"")).filter(t=>/^[A-Za-z][\w.]+$/.test(t))}async function la(e,n){aa(n);const t=await J(e,`run-as ${ue(n)} cat files/react-buoy/@react_buoy_sync_device_id.json 2>/dev/null`,5e3).catch(()=>"");const i=t.trim().replace(/^"|"$/g,"");if(/^[\w-]{4,64}$/.test(i))return i;const r=await sa(e,["exec-out",`run-as ${ue(n)} sh -c 'cat app_webview/Default/"Local Storage"/leveldb/*.log app_webview/Default/"Local Storage"/leveldb/*.ldb 2>/dev/null'`],5e3).catch(()=>null);return r?Fu(r):null}function Fu(e){const n=e.toString("latin1");const t=/@react_buoy_sync_device_id([\s\S])\x01([\w-]{4,64})/g;let i=null;for(let r=t.exec(n);r;r=t.exec(n)){const o=r[1].charCodeAt(0)-1;if(o>=4&&o<=r[2].length)i=r[2].slice(0,o)}return i}function Bu(e){if(/[^\x20-\x7e]/.test(e))throw new Error("adb can only type plain ASCII text. Use tap_element's text for other characters.");return ue(e.replace(/ /g,"%s"))}async function ju(e,n,t,i){const[r,o]=[Math.round(n),Math.round(t)];if(i)await J(e,`input swipe ${r} ${o} ${r} ${o} ${Math.round(i)}`);else await J(e,`input tap ${r} ${o}`)}async function Lu(e,n,t,i){const r=[...n,...t].map(o=>Math.round(o)).join(" ");await J(e,`input swipe ${r} ${Math.round(i)}`)}async function qu(e,n){const t=n.replace(/ /g,"\0");for(let i=0;i<t.length;i+=40){const r=t.slice(i,i+40).replace(/\u0000/g," ");await J(e,`input text ${Bu(r)}`)}}async function Uu(e){const n=await sa(e,["exec-out","screencap","-p"]);if(n.length<8||n.readUInt32BE(0)!==2303741511)throw new Error("The Android screenshot was not a PNG.");return n}async function da(e,n){if(n){await J(e,"settings put global sysui_demo_allowed 1");for(const t of["-e command enter","-e command clock -e hhmm 0941","-e command battery -e level 100 -e plugged false","-e command network -e wifi show -e level 4","-e command notifications -e visible false"]){await J(e,`am broadcast -a com.android.systemui.demo ${t}`).catch(()=>void 0)}}else{await J(e,"am broadcast -a com.android.systemui.demo -e command exit").catch(()=>void 0)}}async function ir(e){const n=await Le(e,["exec-out","uiautomator","dump","/dev/tty"],2e4);return zu(n)}function zu(e){const n=[];const t=(i,r)=>{const o=new RegExp(`\\s${r}="([^"]*)"`).exec(i);return o?Wu(o[1]):""};for(const i of e.matchAll(/<node\b[^>]*>/g)){const r=i[0];const o=/\[(-?\d+),(-?\d+)\]\[(-?\d+),(-?\d+)\]/.exec(t(r,"bounds"));if(!o)continue;const[a,s,c,l]=o.slice(1).map(Number);n.push({text:t(r,"text"),desc:t(r,"content-desc"),id:t(r,"resource-id"),cls:t(r,"class"),clickable:t(r,"clickable")==="true",bounds:{x:a,y:s,width:c-a,height:l-s}})}return n}function Wu(e){return e.replace(/&quot;/g,'"').replace(/&apos;/g,"'").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&#(\d+);/g,(n,t)=>String.fromCharCode(Number(t))).replace(/&amp;/g,"&")}function Hu(e,n){const t=n.trim().toLowerCase();const i=c=>{let l=0;for(const d of[c.desc,c.text,c.id.split("/").pop()??""]){const u=d.trim().toLowerCase();if(!u)continue;if(u===t)l=Math.max(l,3);else if(u.startsWith(t))l=Math.max(l,2);else if(u.includes(t))l=Math.max(l,1)}return l};const r=e.filter(c=>c.bounds.width>0&&c.bounds.height>0&&i(c)>0);const o=Math.max(0,...r.map(i));const a=r.filter(c=>i(c)===o);let s=a.filter((c,l)=>a.findIndex(d=>JSON.stringify(d.bounds)===JSON.stringify(c.bounds))===l);if(s.length>1){const c=s.filter(l=>[l.desc,l.text,l.id.split("/").pop()??""].some(d=>d.trim()===n.trim()));if(c.length)s=c}if(s.length>1){const c=s.filter(l=>l.clickable||/EditText|Button/.test(l.cls));if(c.length)s=c}return s}var Ju=$u(yu);var ua=/^(@buoy\/session:|buoy-gg-license|buoy-gg-device-fingerprint$|@react_buoy_sync_device_id$|@react_buoy_install)/;async function rr(e){return Xi.readdir(e).catch(()=>[])}async function or(e){const n=[];const t=Ot.join(e,"Library","WebKit");for(const i of await rr(t)){const r=Ot.join(t,i,"WebsiteData","Default");for(const o of await rr(r)){for(const a of await rr(Ot.join(r,o))){const s=Ot.join(r,o,a);const c=Ot.join(s,"LocalStorage","localstorage.sqlite3");if(!await Xi.access(c).then(()=>true,()=>false))continue;const l=await Xi.readFile(Ot.join(s,"origin")).then(d=>d.toString("hex"),()=>"");if(l)n.push({db:c,origin:l})}}}return n}var ha=(e,n,t=true)=>Ju("sqlite3",[...t?["-readonly"]:[],e,n],{timeout:5e3}).then(i=>i.stdout);async function Gu(e){const n=[];for(const{db:t,origin:i}of await or(e)){const r=await ha(t,"SELECT key, hex(value) FROM ItemTable;");for(const o of r.split("\n")){const a=o.lastIndexOf("|");if(a<0)continue;const s=o.slice(0,a);if(ua.test(s))n.push({key:s,value:o.slice(a+1),origin:i})}}return n}async function Ku(e,n){if(!n.length)return false;const t=await or(e);const i=new Set(n.map(r=>r.origin??""));for(const r of i){const o=r?t.find(s=>s.origin===r):void 0;if(!o)return false;const a=n.filter(s=>(s.origin??"")===r&&/^[0-9A-F]*$/i.test(s.value)).map(s=>`('${s.key.replace(/'/g,"''")}', X'${s.value}')`).join(",");if(a)await ha(o.db,`INSERT OR REPLACE INTO ItemTable (key, value) VALUES ${a};`,false)}return true}async function Vu(e,n=15e3){const t=Date.now()+n;while(Date.now()<t){if((await or(e)).length)return true;await new Promise(i=>setTimeout(i,500))}return false}async function Yu(e,n,t){const i=(await J(e,`pidof ${n}`).catch(()=>"")).trim().split(/\s+/)[0];if(!i)throw new Error("the app is not running");const r=(await Le(e,["forward","tcp:0",`localabstract:webview_devtools_remote_${i}`])).trim();try{const o=await(await fetch(`http://127.0.0.1:${r}/json`)).json();const a=o.find(s=>s.type==="page"&&s.webSocketDebuggerUrl);if(!a?.webSocketDebuggerUrl)throw new Error("no debuggable WebView page (needs a debug build)");return await new Promise((s,c)=>{const l=new ku(a.webSocketDebuggerUrl);const d=setTimeout(()=>{l.close();c(new Error("the WebView did not answer"))},5e3);l.on("open",()=>l.send(JSON.stringify({id:1,method:"Runtime.evaluate",params:{expression:t,returnByValue:true}})));l.on("message",u=>{const h=JSON.parse(String(u));if(h.id!==1)return;clearTimeout(d);l.close();if(h.result?.exceptionDetails)c(new Error("the WebView script failed"));else s(h.result?.result?.value)});l.on("error",u=>{clearTimeout(d);c(u)})})}finally{await Le(e,["forward","--remove",`tcp:${r}`]).catch(()=>void 0)}}async function pa(e,n,t,i=15e3){const r=Date.now()+i;let o;while(Date.now()<r){try{return await Yu(e,n,t)}catch(a){o=a;await new Promise(s=>setTimeout(s,700))}}throw o instanceof Error?o:new Error("the WebView did not open")}async function Xu(e,n){const t=await J(e,`run-as ${n} sh -c 'ls app_webview/Default/"Local Storage"/leveldb 2>/dev/null'`).catch(()=>"");return/CURRENT|\.log/.test(t)}async function Zu(e,n){if(!(await J(e,`pidof ${n}`).catch(()=>"")).trim()){await J(e,`monkey -p ${n} -c android.intent.category.LAUNCHER 1`)}const t=await pa(e,n,`(() => { const re = ${ua}; const out = []; for (let i = 0; i < localStorage.length; i++) { const k = localStorage.key(i); if (k && re.test(k)) out.push({ key: k, value: localStorage.getItem(k) }); } return out; })()`);return Array.isArray(t)?t.filter(i=>typeof i.key==="string"&&typeof i.value==="string"):[]}async function Qu(e,n,t){await pa(e,n,`(() => { for (const r of ${JSON.stringify(t)}) localStorage.setItem(r.key, r.value); setTimeout(() => location.reload(), 50); return true; })()`)}var eh=/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i;var th=/^[0-9A-F]{8}-[0-9A-F]{16}$/i;var nh=/^[0-9A-F]{40}$/i;function fa(e){return typeof e==="string"&&(eh.test(e)||th.test(e)||nh.test(e))}function ma(e,n="udid"){if(fa(e))return e;const t=typeof e==="string"?e.slice(0,60):typeof e;throw new Error(`"${t}" is not a ${n}. A simulator udid looks like 1B2C3D4E-5F60-4718-9A2B-3C4D5E6F7A8B (xcrun simctl list devices).`)}var wa=ou(ru);var at=new Map;function Yn(e){return at.get(e)}async function Je(e,n,t=2e4,i){try{const{stdout:r}=await wa(e,n,{timeout:t,maxBuffer:16*1024*1024,env:i?{...process.env,...i}:void 0});return r}catch(r){const o=r;if(o.code==="ENOENT")throw new Error(e==="xcrun"?"This needs macOS with Xcode (xcrun simctl).":`${e} is not installed.`);throw new Error(`${e} ${n.slice(0,2).join(" ")} failed: ${(o.stderr||o.message||"").trim().slice(0,300)}`)}}var we=(e,n)=>Je("xcrun",["simctl",...e],n);async function ar(e,n){const t=await pl(e,n).catch(()=>({}));return Je("xcrun",["simctl","launch",e,n],void 0,t)}var ln=e=>e.split("-").pop()??"";async function sr(e,n){if(!n){const t=await cr(e,["rn"]);return t.length?t:cr(e,["webview"])}return cr(e,n)}async function cr(e,n){let t=[];try{const r=JSON.parse(await we(["list","devices","booted","-j"])).devices;t=Object.entries(r).filter(([o])=>/iOS/.test(o)).flatMap(([,o])=>o.filter(a=>a.state==="Booted"))}catch{return[]}const i=await Promise.all(t.map(r=>ga(e,r.udid,r.dataPath,n)));return t.flatMap((r,o)=>i[o]?[{udid:r.udid,name:r.name,found:i[o]}]:[])}function lr(e,n){return new Error(`${n.length} booted simulators hold "${e}" (one is probably a clone): ${n.map(t=>`${t.name} (${t.udid})`).join(", ")}. Pass udid to choose, or shut the extra one down.`)}async function ga(e,n,t,i){const r=ln(e);if(!r)return null;if(!t){try{const c=JSON.parse(await we(["list","devices","-j"])).devices;t=Object.values(c).flat().find(l=>l.udid===n)?.dataPath}catch{return null}}if(!t)return null;const o=Y.join(t,"Containers","Data","Application");let a=[];try{a=await ie.readdir(o)}catch{return null}const s=await Promise.all(a.map(c=>dr(Y.join(o,c),r,i)));for(const[c,l]of a.entries()){const d=Y.join(o,l);if(!s[c])continue;let u=null;try{u=(await Je("plutil",["-extract","MCMMetadataIdentifier","raw","-o","-",Y.join(d,".com.apple.mobile_container_manager.metadata.plist")])).trim()||null}catch{}return{container:d,bundleId:u,kind:s[c]}}return null}async function dr(e,n,t=["rn","webview"]){if(t.includes("rn")){try{if((await ie.readFile(Y.join(e,"Documents","react-buoy","@react_buoy_sync_device_id.json"),"utf8")).trim()===n)return"rn"}catch{}}if(!t.includes("webview"))return null;return(await Go(e).catch(()=>[])).includes(n)?"webview":null}async function ih(e,n){const t=ln(e);const i=n.serial?[n.serial]:await ca();if(i.length===0)throw new Error("No Android device or emulator is connected to adb.");for(const r of i){const o=await Pu(r).catch(()=>null);const a=await Nu(r).catch(()=>[]);const s=[n.bundleId,o,...a].filter((c,l,d)=>!!c&&d.indexOf(c)===l).slice(0,80);for(const c of s){if(await la(r,c).catch(()=>null)===t)return{platform:"android",serial:r,packageName:c}}}return null}async function rh(e){const n=ln(e);for(const t of await uu()){for(const i of await Xo(t.udid).catch(()=>[])){if(await Qo(t.udid,i.bundleId)===n)return{platform:"ios-device",udid:t.udid,name:t.name,bundleId:i.bundleId}}}return null}var ur=new Map;function dn(e,n,t={}){if(t.udid||t.serial||t.bundleId)return ba(e,n,t);const i=`${e}|${n??""}`;const r=ur.get(i);if(r)return r;const o=ba(e,n,t).finally(()=>ur.delete(i));ur.set(i,o);return o}async function ba(e,n,t={}){if(e==="All")throw new Error('Device control acts on one app. Pass its deviceId, not "All".');const i=at.get(e);if(i&&!t.udid&&!t.serial&&await ya(e,i)){if(i.platform==="ios"&&!i.picked){const l=await sr(e,i.idKind?[i.idKind]:void 0);if(l.length>1)throw lr(e,l);if(!l.some(d=>d.udid===i.udid)){at.delete(e);throw new Error(`The sim no longer holds "${e}". Try the host scan again.`)}}return i}if(i)at.delete(e);if(n==="android"){const l=await ih(e,t);if(!l){throw new Error(`Could not prove which Android device and app run "${e}". Buoy checks the app's install id with run-as, which needs a debug build of the app on a device adb can reach${t.serial?` (looked on ${t.serial})`:""}.`)}at.set(e,l);return l}if(n&&n!=="ios")throw new Error(`Device control works on iOS Simulators and Android. This app runs on "${n}".`);if(process.platform!=="darwin")throw new Error("iOS control needs macOS with Xcode.");let r=t.udid===void 0?void 0:ma(t.udid,"simulator udid");let o=r??"";let a=null;if(!r){const l=await sr(e);a=l.length===1?l[0]:null;if(l.length>1)throw lr(e,l);const d=l.length===1?{ok:true,udid:l[0].udid,how:`matched ${e} to "${l[0].name}"`}:await Vo(e);if(!d.ok||!/^matched /.test(d.how)){const u=await rh(e).catch(()=>null);if(u){at.set(e,u);return u}throw new Error(`Could not find which simulator or iPhone runs "${e}": no booted simulator holds its install id, and no connected iPhone has it (an iPhone must be unlocked, paired, and run a development build).`)}r=d.udid;o=/"([^"]+)"/.exec(d.how)?.[1]??r}const s=a?.udid===r?await dr(a.found.container,ln(e),[a.found.kind])?a.found:null:await ga(e,r);if(!s)throw new Error(`Simulator ${r} does not hold "${e}".`);const c={platform:"ios",udid:r,name:o,bundleId:t.bundleId??s?.bundleId??null,container:s?.container??null,picked:!!t.udid,idKind:s.kind};at.set(e,c);return c}async function va(e,n){if(n.platform==="ios"&&!n.picked){const t=await sr(e);if(t.length>1)throw lr(e,t)}if(await ya(e,n))return n;at.delete(e);return dn(e,n.platform==="android"?"android":"ios",n.platform==="ios"&&n.picked?{udid:n.udid}:{})}async function ya(e,n){const t=ln(e);if(n.platform==="android")return await la(n.serial,n.packageName).catch(()=>null)===t;if(n.platform==="ios-device")return await Qo(n.udid,n.bundleId).catch(()=>null)===t;if(n.container)return!!await dr(n.container,t);const i=await Vo(e);return i.ok&&i.udid===n.udid&&/^matched /.test(i.how)}function hr(e){if(e.platform==="android")return aa(e.packageName);if(e.platform==="ios-device")return e.bundleId;if(!e.bundleId)throw new Error("Could not tell which app this is on the simulator (its container has no bundle metadata).");return e.bundleId}async function un(e){if(e.platform==="android")return Uu(e.serial);if(e.platform==="ios-device")return ea(e.udid);const n=await Yo(e.udid);if(!n.ok||!n.srcPath)throw new Error(n.error??"Screenshot failed.");try{return await ie.readFile(n.srcPath)}finally{await ie.unlink(n.srcPath).catch(()=>{})}}async function Rt(e,n=1280){if(process.platform==="darwin"){const r=Y.join(sn.tmpdir(),`buoy-mcp-img-${au()}.png`);const o=r.replace(/\.png$/,".jpg");await ie.writeFile(r,e);try{await Je("sips",["-Z",String(n),"-s","format","jpeg","-s","formatOptions","70",r,"--out",o],15e3);const a=await Je("sips",["-g","pixelWidth","-g","pixelHeight",o]);return{data:(await ie.readFile(o)).toString("base64"),mimeType:"image/jpeg",width:Number(/pixelWidth:\s*(\d+)/.exec(a)?.[1]??0),height:Number(/pixelHeight:\s*(\d+)/.exec(a)?.[1]??0)}}finally{await ie.unlink(r).catch(()=>{});await ie.unlink(o).catch(()=>{})}}const t=oh(Ji.PNG.sync.read(e),Math.min(n,1024));const i=Ji.PNG.sync.write(t,{colorType:2,deflateLevel:9});return{data:i.toString("base64"),mimeType:"image/png",width:t.width,height:t.height}}function oh(e,n){const t=Math.min(1,n/Math.max(e.width,e.height));if(t===1)return e;const i=Math.max(1,Math.round(e.width*t));const r=Math.max(1,Math.round(e.height*t));const o=new Ji.PNG({width:i,height:r});const a=e.width/i;const s=e.height/r;for(let c=0;c<r;c++){const l=Math.floor(c*s);const d=Math.max(l+1,Math.floor((c+1)*s));for(let u=0;u<i;u++){const h=Math.floor(u*a);const b=Math.max(h+1,Math.floor((u+1)*a));const p=[0,0,0,0];let w=0;for(let m=l;m<d;m++){for(let f=h;f<b;f++){const y=(m*e.width+f)*4;for(let v=0;v<4;v++)p[v]+=e.data[y+v];w++}}const g=(c*i+u)*4;for(let m=0;m<4;m++)o.data[g+m]=Math.round(p[m]/w)}}return o}var pr=new Set;async function ah(e,n){let t=false;try{if(e.platform==="ios"){const i=await we(["status_bar",e.udid,"list"]).catch(()=>"");const r=i.split(/^=+$/m).slice(1).join("").trim();if(!r){await we(["status_bar",e.udid,"override","--time","9:41","--batteryState","charged","--batteryLevel","100","--wifiBars","3","--cellularBars","4"]);t=true}}else if(e.platform==="android"){const i=(await J(e.serial,"settings get global sysui_demo_allowed").catch(()=>"")).trim();if(i!=="1"&&!pr.has(e.serial)){pr.add(e.serial);await da(e.serial,true);t=true}}if(t)await new Promise(i=>setTimeout(i,400))}catch{t=false}try{return{result:await n(),steadied:t}}finally{if(t){if(e.platform==="ios")await we(["status_bar",e.udid,"clear"]).catch(()=>void 0);else if(e.platform==="android"){await da(e.serial,false);await J(e.serial,"settings put global sysui_demo_allowed 0").catch(()=>void 0);pr.delete(e.serial)}}}}async function fr(e){const n=hr(e);if(e.platform==="ios-device"){const t=await ta(e.udid,n);return t?`Quit ${n}.`:`${n} was not running.`}if(e.platform==="ios"){await we(["terminate",e.udid,n]).catch(t=>{if(!/found nothing to terminate|not running/i.test(String(t)))throw t})}else{await J(e.serial,`am force-stop ${ue(n)}`)}return`Quit ${n}.`}async function Nt(e){const n=hr(e);if(e.platform==="ios")await ar(e.udid,n);else if(e.platform==="ios-device")await Yi(e.udid,n);else await J(e.serial,`monkey -p ${ue(n)} -c android.intent.category.LAUNCHER 1`);return`Launched ${n}.`}async function sh(e){if(e.platform==="ios-device"){await Yi(e.udid,"com.apple.Preferences");return"Sent to the background for real (Settings opened on top)."}if(e.platform==="ios"){await we(["launch",e.udid,"com.apple.Preferences"]);return"Sent to the background for real (Settings opened on top)."}await J(e.serial,"input keyevent 3");return"Sent to the background for real (pressed Home)."}async function ch(e,n){if(!/^[a-zA-Z][\w+.-]*:/.test(n))throw new Error(`"${n}" is not a link with a scheme (like https://\u2026 or myapp://\u2026).`);if(e.platform==="ios-device"){await mu(e.udid,n);return"Opened through the OS on the iPhone."}if(e.platform==="ios"){await we(["openurl",e.udid,n]);return'Opened through the OS. A custom scheme may first show an "Open in" prompt on the simulator.'}await J(e.serial,`am start -a android.intent.action.VIEW -d ${ue(n)}`);return"Opened through the OS (an Android VIEW intent)."}var lh=["buoy-license","react-buoy/@react_buoy_sync_device_id.json","react-buoy/@react_buoy_install.json"];async function $a(e){const n=Y.join(e,"Info.plist");const t=a=>Je("plutil",["-extract",a,"raw","-o","-",n]).then(s=>s.trim()).catch(()=>"");const i=await t("CFBundleIdentifier");if(!i)throw new Error(`${e} has no Info.plist with a bundle id. Pass a built .app folder.`);const r=(await Je("plutil",["-extract","CFBundleSupportedPlatforms","json","-o","-",n]).catch(()=>"[]")).toLowerCase();const o=(await t("DTPlatformName")).toLowerCase();return{bundleId:i,simulator:r.includes("iphonesimulator")||o==="iphonesimulator"}}async function dh(e){const n=[process.env.ANDROID_HOME,process.env.ANDROID_SDK_ROOT,Y.join(sn.homedir(),"Library","Android","sdk"),Y.join(sn.homedir(),"Android","Sdk")].filter(t=>!!t);for(const t of n){const i=Y.join(t,"build-tools");const r=(await ie.readdir(i).catch(()=>[])).sort().reverse();for(const o of r){for(const a of["aapt2","aapt"]){const s=Y.join(i,o,a);try{await ie.access(s)}catch{continue}const c=await Je(s,a==="aapt2"?["dump","packagename",e]:["dump","badging",e]).catch(()=>"");const l=a==="aapt2"?c.trim().split("\n")[0]:/package: name='([^']+)'/.exec(c)?.[1]??"";if(l)return l}}}throw new Error("Could not read the APK's package name (needs aapt2 from the Android SDK build-tools). Nothing was changed.")}async function uh(e,n,t=true){const i=hr(e);const r=Y.resolve(n);try{await ie.access(r)}catch{throw new Error(`No build at ${r}. Pass appPath: the built .app folder (iOS Simulator) or .apk file (Android). Nothing was changed.`)}if(e.platform==="android")return hh(e,i,r,t);if(e.platform==="ios-device")return ph(e,i,r,t);if(!/\.app\/?$/i.test(r))throw new Error("On the iOS Simulator, appPath must be a built .app folder. Nothing was changed.");const o=await $a(r);if(o.bundleId!==i)throw new Error(`${Y.basename(r)} is ${o.bundleId}, but this app is ${i}. Nothing was changed.`);if(!o.simulator)throw new Error(`${Y.basename(r)} is a device build, not a simulator build. Nothing was changed.`);const a=t?await ie.mkdtemp(Y.join(sn.tmpdir(),"buoy-mcp-keep-")):null;try{let s=false;let c=[];if(a){await ie.chmod(a,448);const d=(await we(["get_app_container",e.udid,i,"data"]).catch(()=>"")).trim();if(d)s=await ka(Y.join(d,"Documents"),a);if(d&&!s){try{c=await Gu(d)}catch(u){throw new Error(`Couldn't read Buoy's sign-in from the app's WebView storage (${u.message}). Nothing was changed. Pass keepBuoy: false to reinstall anyway.`)}}}await we(["terminate",e.udid,i]).catch(()=>void 0);await we(["uninstall",e.udid,i]);try{await we(["install",e.udid,r],18e4)}catch(d){throw new Error(`The app was removed, but installing ${Y.basename(r)} failed: ${d.message}. Install it again by hand.`)}let l="";if(a&&s){try{const d=(await we(["get_app_container",e.udid,i,"data"])).trim();await ka(a,Y.join(d,"Documents"));e.container=d;l=" Kept Buoy's sign-in and device id, so the same deviceId still works."}catch(d){l=` Buoy's sign-in could not be restored (${d.message}): sign in to Buoy again in the app.`}}else if(c.length){try{const d=(await we(["get_app_container",e.udid,i,"data"])).trim();await ar(e.udid,i);const u=await Vu(d);await we(["terminate",e.udid,i]).catch(()=>void 0);if(!u||!await Ku(d,c))throw new Error("the app made no WebView storage");e.container=d;l=" Kept Buoy's sign-in and device id, so the same deviceId still works."}catch(d){l=` Buoy's sign-in could not be restored (${d.message}): sign in to Buoy again in the app.`}}else if(t){l=" The old install had no Buoy sign-in to keep."}await ar(e.udid,i);return`Reinstalled ${i} from ${r} and launched it. The app's own data is gone, like a new user.${l}`}finally{if(a)await ie.rm(a,{recursive:true,force:true}).catch(()=>void 0)}}async function ka(e,n){let t=false;for(const i of lh){const r=Y.join(e,i);try{await ie.access(r)}catch{continue}const o=Y.join(n,i);await ie.mkdir(Y.dirname(o),{recursive:true});await ie.cp(r,o,{recursive:true,force:true});t=true}return t}async function hh(e,n,t,i){if(!/\.apk$/i.test(t))throw new Error("On Android, appPath must be an .apk file. Nothing was changed.");const r=await dh(t);if(r!==n)throw new Error(`${Y.basename(t)} is ${r}, but this app is ${n}. Nothing was changed.`);const o=[];if(i){const c=await J(e.serial,`run-as ${ue(n)} find files/buoy-license files/react-buoy -maxdepth 1 -type f 2>/dev/null`).catch(()=>"");const l=c.split("\n").map(d=>d.trim()).filter(d=>d.startsWith("files/buoy-license/")||/react-buoy\/@react_buoy_(sync_device_id|install)\.json$/.test(d));for(const d of l){const u=await J(e.serial,`run-as ${ue(n)} base64 ${ue(d)}`).catch(()=>"");if(u.trim())o.push({rel:d,data:u.replace(/\s+/g,"")})}}let a=[];if(i&&!o.length&&await Xu(e.serial,n)){try{a=await Zu(e.serial,n)}catch(c){throw new Error(`Couldn't read Buoy's sign-in from the app's WebView (${c.message}). Nothing was changed. Pass keepBuoy: false to reinstall anyway.`)}}await Le(e.serial,["install","-r","-d",t],18e4);await J(e.serial,`pm clear ${ue(n)}`);let s="";if(a.length){await Nt(e);try{await Qu(e.serial,n,a);s=" Kept Buoy's sign-in and device id, so the same deviceId still works."}catch(c){s=` Buoy's sign-in could not be restored (${c.message}): sign in to Buoy again in the app.`}return`Reinstalled ${n} from ${t} and launched it. The app's data is gone, like a new user.${s}`}if(o.length){try{for(const c of o){const l=Y.posix.dirname(c.rel);await J(e.serial,`echo ${ue(c.data)} | run-as ${ue(n)} sh -c ${ue(`mkdir -p ${ue(l)} && base64 -d > ${ue(c.rel)}`)}`)}s=" Kept Buoy's sign-in and device id, so the same deviceId still works."}catch(c){s=` Buoy's sign-in could not be restored (${c.message}): sign in to Buoy again in the app.`}}else if(i){s=" No Buoy sign-in could be read to keep (needs a debug build): sign in to Buoy again in the app."}await Nt(e);return`Reinstalled ${n} from ${t} and launched it. The app's data is gone, like a new user.${s}`}async function ph(e,n,t,i){if(!/\.app\/?$/i.test(t))throw new Error("On an iPhone, appPath must be a built .app folder (a device build). Nothing was changed.");const r=await $a(t);if(r.bundleId!==n)throw new Error(`${Y.basename(t)} is ${r.bundleId}, but this app is ${n}. Nothing was changed.`);if(r.simulator)throw new Error(`${Y.basename(t)} is a simulator build, not a device build. Nothing was changed.`);const o=["Documents/buoy-license/buoy-gg-license.json","Documents/react-buoy/@react_buoy_sync_device_id.json","Documents/react-buoy/@react_buoy_install.json"];const a=i?await ie.mkdtemp(Y.join(sn.tmpdir(),"buoy-mcp-keep-")):null;try{const s=[];if(a){await ie.chmod(a,448);for(const l of o){let d;try{d=await Zo(e.udid,n,l)}catch(h){throw new Error(`Could not back up Buoy's ${Y.basename(l)} from the iPhone (${h.message}). Nothing was changed.`)}if(!d)continue;const u=Y.join(a,l.replace(/\//g,"__"));await ie.writeFile(u,d,{mode:384});s.push({rel:l,local:u})}}await ta(e.udid,n).catch(()=>false);await wu(e.udid,n);try{await gu(e.udid,t)}catch(l){throw new Error(`The app was removed, but installing ${Y.basename(t)} failed: ${l.message}. Install it again from Xcode.`)}let c="";if(s.length){try{for(const u of s)await bu(e.udid,n,u.local,u.rel);const l=s.some(u=>u.rel.includes("buoy-license"));const d=s.some(u=>u.rel.includes("sync_device_id"));c=l?` Kept Buoy's sign-in${d?" and device id, so the same deviceId still works":""}.`:` Kept the device id; there was no Buoy sign-in to keep, so sign in to Buoy in the app.`}catch(l){c=` Buoy's sign-in could not be restored (${l.message}): sign in to Buoy again in the app.`}}else if(i)c=" The old install had no Buoy sign-in to keep.";await Yi(e.udid,n);return`Reinstalled ${n} on the iPhone and launched it. The app's own data is gone, like a new user.${c}`}finally{if(a)await ie.rm(a,{recursive:true,force:true}).catch(()=>void 0)}}async function fh(e){const n=JSON.parse(await we(["list","devices","available","-j"])).devices;const t=Object.entries(n).filter(([s])=>/iOS/.test(s)).flatMap(([,s])=>s);const i=e.trim().toLowerCase();const r=t.filter(s=>s.udid.toLowerCase()===i||s.name.toLowerCase()===i);const o=r.length?r:t.filter(s=>s.name.toLowerCase().includes(i));if(o.length===0)throw new Error(`No iOS Simulator matches "${e}". Run \`xcrun simctl list devices available\` to see them.`);if(o.length>1)throw new Error(`${o.length} simulators match "${e}": ${o.map(s=>`${s.name} (${s.udid})`).join(", ")}. Pass the udid.`);const a=o[0];if(a.state!=="Booted"){try{await wa("xcrun",["simctl","boot",a.udid],{timeout:12e4,env:al()})}catch(s){const c=s;throw new Error(`xcrun simctl boot failed: ${(c.stderr||c.message||"").trim().slice(0,300)}`)}}await Je("open",["-a","Simulator","--args","-CurrentDeviceUDID",a.udid]).catch(()=>void 0);return a.state==="Booted"?`${a.name} (${a.udid}) was already booted.`:`Booted ${a.name} (${a.udid}).`}var mh=iu(nu);async function ge(e,n,t={},i={}){if(n==="All")throw new Error('Device control acts on one app. Pass its deviceId, not "All".');let r;let o=true;try{r=e.requireProDevice(n)}catch(c){const l=c instanceof Error?c.message:String(c);const d=l.startsWith(mt)&&/is not connected right now/.test(l)?/"([^"]+)"/.exec(l)?.[1]:void 0;const u=d?e.deviceWasAllowed(d):false;if(!i.allowOffline||!d||!u)throw c;r=d;o=false}const a=e.listDevices().find(c=>c.deviceId===r)?.platform;let s=await dn(r,a,t);if(i.changesApp&&Yn(r)===s)s=await va(r,s);return{id:r,host:s,online:o}}function Ft(e){if(e.platform==="ios")return`simulator "${e.name}"`;if(e.platform==="ios-device")return`iPhone "${e.name}"`;return`Android device ${e.serial}`}var mr=new Map;function _a(e){if(!mr.has(e))mr.set(e,mh("which",[e],{timeout:3e3}).then(()=>true,()=>false));return mr.get(e)}async function wh(e,n){let t=n;if(e.platform==="android"){const r=Yn(e.deviceId);const o=r??(e.isConnected?await Promise.race([dn(e.deviceId,"android").catch(()=>void 0),new Promise(s=>setTimeout(()=>s(void 0),3e3))]):void 0);const a=o?.platform==="android"&&!!ho(o.serial)||await _a("adb");return{kind:"android",...o&&o.platform==="android"?{id:o.serial,name:o.packageName}:{},can:["screenshot","screen_recording","baseline diffs","quit/launch/reinstall","real lifecycle events","native_tap/type/swipe","native_inspect"],...!a?{missing:["adb (Android SDK platform-tools)"]}:!o?{missing:["proof of which phone runs it (needs a debug build reachable by adb)"]}:{}}}if(e.platform!=="ios")return{kind:e.platform??"unknown",can:[],missing:["host control works on iOS and Android apps"]};let i=Yn(e.deviceId);if(!i&&!t&&e.isConnected){i=await Promise.race([dn(e.deviceId,"ios").catch(()=>void 0),new Promise(r=>setTimeout(()=>r(void 0),4e3))])}if(!t&&i?.platform==="ios")t={name:i.name,udid:i.udid};if(i?.platform==="ios-device"){return{kind:"physical iPhone",id:i.udid,name:i.name,can:["screenshot","screen_recording (if this iPhone supports it)","baseline diffs","quit/launch/reinstall","open_url","native_tap/type/swipe/pinch (by query, testID, nativeTag or x/y; not label)","native_inspect (the app's side only)"]}}if(t){const r=await _a("idb");return{kind:"ios simulator",id:t.udid,name:t.name,can:["screenshot","screen_recording","baseline diffs","quit/launch/reinstall/boot","real lifecycle events",...r?["native_tap/type/swipe/pinch","native_inspect"]:[]],...r?{}:{missing:["idb for real touches (brew install facebook/fb/idb-companion && pipx install fb-idb)"]}}}return void 0}function Bt(e){return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}function jt(e){return{isError:true,content:[{type:"text",text:e}]}}function Sa(e,n){e.registerTool("list_devices",{description:"List the apps connected to Buoy: id, name, platform, whether it is connected and has MCP access, the simulator or phone it runs on with the host controls that work there (screenshot, recording, app control, real touches) and anything missing, and the Buoy tools it exposes. Start here. Pass details:true for every tool's action names.",inputSchema:{details:te.boolean().optional().describe("Also list every action of every tool. Default false (tool names only); list_tool_actions gives one tool's actions."),includeDisconnected:te.boolean().optional().describe("Also list apps that were seen before but are not connected now. Default false.")}},async(t={})=>{const i=await zo();let r=n.listDevices();for(let b=0;r.length===0&&b<10;b++){await new Promise(p=>setTimeout(p,200));r=n.listDevices()}if(r.length===0){return Bt({devices:[],hint:"No devices connected. Open the app with Buoy devtools running, then retry.",...i?{updateAvailable:i}:{}})}const o=t.includeDisconnected?0:r.filter(b=>!b.isConnected).length;if(!t.includeDisconnected)r=r.filter(b=>b.isConnected);if(r.length===0){return Bt({devices:[],hint:`No app is connected right now${o?` (${o} seen before; pass includeDisconnected:true to list them)`:""}. Open the app with Buoy devtools running, then retry.`,...i?{updateAvailable:i}:{}})}const a=await eu(r.filter(b=>b.platform==="ios").map(b=>b.deviceId)).catch(()=>new Map);const s=r.filter(b=>b.isConnected);const c=s.some(b=>de(b));const l=s.some(b=>b.tier!=="locked");const d=s.filter(b=>b.collision);const u=await Promise.all(r.map(b=>b.isConnected?wh(b,a.get(b.deviceId)).catch(()=>void 0):void 0));const h=r.map((b,p)=>{const w=a.get(b.deviceId);const g=u[p];return{deviceId:b.deviceId,deviceName:b.deviceName,platform:b.platform,isConnected:b.isConnected,isPro:b.isPro,tier:b.tier,...!b.isPro&&de(b)?{weekendPass:true}:{},access:n.accessState(b.deviceId,"free"),...w?{simulator:w}:{},...g?{host:g}:{},...b.collision?{collision:true}:{},tools:t.details?b.tools:b.tools.map(m=>m.toolId)}});return Bt({devices:h,...t.details?{}:{note:`Tool names only. Pass details:true, or list_tool_actions({toolId}), for action names.${o?` ${o} apps seen before but not connected now are left out (includeDisconnected:true lists them).`:""}`},...d.length>0?{warning:`${d.map(b=>`"${b.deviceId}"`).join(", ")}: more than one app is registered under this id, so actions sent to it land on an arbitrary device. Give each device its own externalSync.deviceId (or leave it unset for a per-install default) before mutating anything.`}:{},...c?{}:{hint:l?`The connected app is on the free tier, so only the free MCP tools work: ${$l().join(", ")} (get_network_requests without includeBodies; get_triage without storage values). Every other tool needs Buoy Pro (https://buoy.gg/pricing). After upgrading, the user runs \`npx --package=@buoy-gg/core buoy login\` again, or signs in again in the app. A headless app can take a Pro key through \`licenseKey\`.`:"The broker has not confirmed account access for the connected devices, so data/action tools are blocked. A locked status can mean missing configuration, pending/failed validation, or a missing account announcement after reconnect; it does not prove the user is signed out. Check app account status and broker compatibility."},...i?{updateAvailable:i}:{}})});e.registerTool("list_tool_actions",{description:"List the actions a tool exposes, and which connected devices offer it. Leave toolId out to list every tool's actions. Use the action names with call_action.",inputSchema:{toolId:te.string().optional().describe('The tool id, e.g. "perf-monitor", "network", "react-query". Leave out for every tool.'),tool:te.string().optional().describe("Same as toolId."),deviceId:te.string().optional().describe("Only list what this device offers.")}},async({toolId:t,tool:i,deviceId:r})=>{const o=t??i;if(!o){const c=n.connectedDevices().filter(d=>!r||d.deviceId===r);if(c.length===0)return jt(r?`No connected device "${r}". Call list_devices.`:"No devices are connected. Call list_devices.");const l=c.map(d=>[`**${d.deviceName}** (${d.deviceId})`,...d.tools.map(u=>`- ${u.toolId}: ${u.actions.join(", ")}`)].join("\n"));return{content:[{type:"text",text:`${l.join("\n\n")}
3
3
 
4
4
  Call one with call_action({toolId, action, params}).`}]}}const a=new Set(n.connectedDevices().map(c=>c.deviceId));const s=n.toolActions(o).filter(c=>a.has(c.deviceId)&&(!r||c.deviceId===r));if(s.length===0){const c=[...new Set(n.connectedDevices().flatMap(l=>l.tools.map(d=>d.toolId)))].sort();return jt(`No connected device exposes tool "${o}". Tool ids: ${c.join(", ")||"(none connected)"}. MCP tool names like "${o}" are not tool ids.`)}return Bt({toolId:o,offerings:s})});e.registerTool("get_snapshot",{description:"Read a tool's current state (its sync snapshot) from a device. Starts watching the tool and returns the next fresh snapshot.",inputSchema:{toolId:te.string().optional().describe("The tool id to read state from."),tool:te.string().optional().describe("Same as toolId."),deviceId:te.string().optional().describe("The device to act on: its id from list_devices or from your instructions. Pass it whenever more than one app may be connected. Once a call names a device, later calls in this session use it when deviceId is left out."),timeoutMs:te.number().optional().describe("How long to wait for a fresh snapshot before falling back to the cached one.")}},async({toolId:t,tool:i,deviceId:r,timeoutMs:o})=>{try{const a=t??i;if(!a)return jt("get_snapshot needs toolId (see list_tool_actions).");const s=n.requireProDevice(r);const{payload:c,stale:l}=await n.getSnapshot(a,s,{timeoutMs:o});return Bt({toolId:a,deviceId:s,...l?{stale:l}:{},snapshot:c})}catch(a){return jt(xa(a))}});e.registerTool("call_action",{description:"Invoke any action a tool exposes (see list_tool_actions) and return its result. This is the generic escape hatch that works for every Buoy tool.",inputSchema:{toolId:te.string().optional().describe('The tool id, e.g. "perf-monitor".'),tool:te.string().optional().describe("Same as toolId."),action:te.string().describe('The action name, e.g. "startRecording", "clearAll".'),params:te.union([te.record(te.unknown()),te.string()]).optional().describe("JSON params object for the action (shape depends on the action)."),args:te.union([te.record(te.unknown()),te.string()]).optional().describe("Same as params."),deviceId:te.string().optional().describe('The device to act on: its id from list_devices or from your instructions. Pass it whenever more than one app may be connected. Once a call names a device, later calls in this session use it when deviceId is left out. Or "All" to broadcast.'),timeoutMs:te.number().optional().describe("Max time to wait for the device's result.")}},async({toolId:t,tool:i,action:r,params:o,args:a,deviceId:s,timeoutMs:c})=>{try{const l=t??i;if(!l)return jt("call_action needs toolId (see list_tool_actions).");const d=gh(o??a);const u=n.requireProDevice(s);const h=await n.callAction(l,r,d,u,{timeoutMs:c});return Bt({toolId:l,action:r,ok:true,result:h??null})}catch(l){return jt(xa(l))}})}function gh(e){if(e===void 0||typeof e==="object")return e;const n=e.trim();if(!n)return void 0;let t;try{t=JSON.parse(n)}catch{throw new Error('params is a string but not JSON. Pass an object, e.g. {"user": {...}}.')}if(!t||typeof t!=="object"||Array.isArray(t))throw new Error("params must be a JSON object.");return t}function xa(e){return e instanceof Error?e.message:String(e)}var Lt=(e,n,t)=>Math.max(n,Math.min(t,e));var wr="__batch_warmup__";var bh={nominal:"\u{1F7E2} nominal",fair:"\u{1F7E1} fair",serious:"\u{1F7E0} serious",critical:"\u{1F534} critical",unknown:"\u2014"};var qt={perCaseDurationMs:5e3,settleMs:600,navTimeoutMs:5e3,runsPerCase:3,coolDownMs:2e3,discardWarmupRuns:0};function Ut(e,n,t){return e??n??t}function Xn(e,n={}){const t=[];const i=(e.targetRoute||"").trim();if(!i)throw new Error("targetRoute is required (the screen to benchmark).");let r=(e.bounceRoute||"").trim();if(!r)r=i==="/"?"/_buoy_bounce":"/";if(r===i){throw new Error(`bounceRoute ("${r}") must differ from targetRoute \u2014 it's the screen we bounce to so the test screen fully remounts each run.`)}if(!Array.isArray(e.cases)||e.cases.length===0){throw new Error("At least one case is required.")}const o=e.cases.map((u,h)=>{const b=(u.name||"").trim()||`case ${h+1}`;return{id:`case-${h}`,name:b,params:u.params??{},route:u.route}});const a=Lt(Math.round(Ut(e.runsPerCase,n.runsPerCase,qt.runsPerCase)),1,10);const s=Lt(Math.round(Ut(e.coolDownMs,n.coolDownMs,qt.coolDownMs)),0,3e4);const c=Lt(Math.round(Ut(e.discardWarmupRuns,n.discardWarmupRuns,qt.discardWarmupRuns)),0,a-1);const l=e.shuffleCases??n.shuffleCases??o.length>3;if(o.length>3&&l===false){t.push("shuffleCases is off with >3 cases \u2014 later cases may be thermally throttled, biasing results. Consider enabling it.")}if(a===1){t.push("runsPerCase=1 \u2014 no median/variance; a single noisy run can mislead. 3+ is recommended.")}const d={targetRoute:i,bounceRoute:r,perCaseDurationMs:Lt(Math.round(Ut(e.perCaseDurationMs,n.perCaseDurationMs,qt.perCaseDurationMs)),1e3,6e4),settleMs:Lt(Math.round(Ut(e.settleMs,n.settleMs,qt.settleMs)),0,1e4),navTimeoutMs:Lt(Math.round(Ut(e.navTimeoutMs,n.navTimeoutMs,qt.navTimeoutMs)),1e3,3e4),cases:o,runsPerCase:a,coolDownMs:s,discardWarmupRuns:c,discardWarmupCase:e.discardWarmupCase??n.discardWarmupCase??true,shuffleCases:l,reloadBetweenCases:e.reloadBetweenCases??n.reloadBetweenCases??false,captureRenders:e.captureRenders??n.captureRenders??true};return{config:d,warnings:t}}function Ta(e){const n=c=>c>=1e3?`${(c/1e3).toFixed(c%1e3?1:0)}s`:`${c}ms`;const t=e.runsPerCase??1;const i=gr(e);const r=i/6e4;const o=r>=1?`~${r.toFixed(1)} min`:`~${Math.round(i/1e3)}s`;const a=[`**${n(e.perCaseDurationMs)} measured per page**`,t>1?`**${t} runs each** (median taken)`:`**1 run each** (no median \u2014 noisier)`,e.reloadBetweenCases?"**full reload between pages** (no state leaks across tests)":"no reload between pages",e.shuffleCases?"shuffled order (cancels thermal bias)":"fixed order",e.captureRenders!==false?"render capture on (per-component why-data)":"render capture off"];const s=e.settleMs+e.perCaseDurationMs+(e.coolDownMs??0)+1800;return`${a.join(", ")}. That's ~${n(s)} wall-clock per page; for ${e.cases.length} page(s) \xD7 ${t} run(s), **${o}** total.`}function gr(e){const n=1800;const t=e.settleMs+e.perCaseDurationMs+e.coolDownMs+n;let i=e.cases.length*(e.runsPerCase??1)*t;if(e.reloadBetweenCases)i+=e.cases.length*3e3;return i}function vh(e){const n=[];const t=e.deviceMaxRefreshRate;if(e.uiFps!=null&&t&&e.uiFps<t*.95){n.push("UI thread drops frames")}else if(e.uiJank!=null&&e.uiJank>=2){n.push("UI jank spikes")}if(e.cpu!=null&&e.cpu>=90)n.push("CPU near cap");if(e.jsJank!=null&&e.jsJank>=5)n.push("JS thread stalls");return n}function yh(e){const n=[];const t=e.deviceMaxRefreshRate;if(e.jsFps!=null&&t&&e.jsFps<t*.95){n.push("Low main-thread frame rate")}else if(e.longFrames!=null&&e.frames>0&&e.longFrames/e.frames>=.02){n.push("Frequent long frames")}const i=Math.max(e.frameGapMaxMs??0,e.edgeSilenceMs??0);if(i>=100)n.push(`Freeze of ${Math.round(i)} ms`);if(e.longTaskPct!=null&&e.longTaskPct>=20)n.push("Long tasks block the main thread");if(e.forcedLayoutMs!=null&&e.forcedLayoutMs>=50){n.push(`Forced layout in scripts (${Math.round(e.forcedLayoutMs)} ms)`)}if(e.styleLayoutMs!=null&&e.styleLayoutMs>=100){n.push(`Style and layout in slow frames (${Math.round(e.styleLayoutMs)} ms)`)}if(e.worstInteractionMs!=null&&e.worstInteractionMs>=200){n.push(`Slow response to input (${Math.round(e.worstInteractionMs)} ms)`)}if(e.layoutShift!=null&&e.layoutShift>=.1)n.push(`Layout shifts (${e.layoutShift})`);if(e.domGrowth!=null&&e.domGrowth>0){n.push(`DOM grew every run (+${e.domGrowth} nodes): check for a leak`)}return n}function $h(e){const n=e.filter(i=>!i.batchFailureReason&&!i.discardedWarmup).sort((i,r)=>(i.runIndex??0)-(r.runIndex??0)).map(i=>i.webRun?.domNodesStart).filter(i=>typeof i==="number");if(n.length<3)return null;for(let i=1;i<n.length;i++)if(n[i]<=n[i-1])return null;const t=n[n.length-1]-n[0];return t>=Math.max(50,n[0]*.05)?t:null}function kh(e,n){const t=e.find(r=>r.isBaseline);if(t)return t;const i=n?.[0]?.name;if(i){const r=e.filter(o=>o.caseName===i);if(r.length===1)return r[0]}return e[0]}function Zn(e,n,t,i=[]){const r=e.filter(m=>m.batchId===n);const o=new Map(i.map(m=>[m.index,m.reason]));const a=Array.from(new Set(r.map(m=>m.batchIndex??0))).sort((m,f)=>m-f);const s=m=>{const f=r.filter($=>($.batchIndex??0)===m);if(f.length===0)return void 0;const y=f.filter($=>!$.batchFailureReason&&!$.discardedWarmup);const v=y.filter($=>$.webRun?.fps!=null);if(v.length>0&&v.length===y.length){const $=[...v].sort((T,k)=>T.webRun.fps-k.webRun.fps);return $[Math.floor(($.length-1)/2)]}if(y.length>0){return y.find($=>$.isMedianRun===true)??y.find($=>$.runIndex===0||$.runIndex===void 0)??y[0]}return f.find($=>$.batchFailureReason)??f[0]};const c=m=>typeof m==="number"?m:null;const l=a.map(m=>{const f=s(m);const y=r.filter(R=>(R.batchIndex??0)===m);const v=y.length;const $=y.filter(R=>!R.batchFailureReason&&!R.discardedWarmup);const T=R=>R.webRun?R.webRun.fps??R.jsFpsAvg:R.uiFpsAvg;const k=$.map(T).filter(R=>typeof R==="number");const D=f?.name??t?.[m]?.name??`case ${m+1}`;const E=r.some(R=>(R.batchIndex??0)===m&&R.isBaseline===true);const I=o.get(m)??f?.batchFailureReason;const P=y.every(R=>R.batchFailureReason||R.discardedWarmup);const _=Boolean(I)||!f||P;const x={batchIndex:m,caseName:D,params:f?.params??{},runs:v,failed:_,...f?.route?{route:f.route}:{},...E?{isBaseline:true}:{},failureReason:_?I??(P&&f?"only warmup runs were saved":"no run recorded"):void 0,uiFps:c(f?.uiFpsAvg),jsFps:c(f?.jsFpsAvg),cpu:c(f?.cpuAvg),memMb:c(f?.memMaxMb),jsJank:c(f?.jsJankFrames),uiJank:c(f?.uiJankFrames),deviceMaxRefreshRate:c(f?.deviceMaxRefreshRate),deltaUiFps:null,deltaJsFps:null,validRuns:$.length,fpsMin:k.length?Oe(Math.min(...k),1):null,fpsMax:k.length?Oe(Math.max(...k),1):null,...f?.thermalState?{thermalState:f.thermalState}:{},renderCommits:c(f?.renderCommits),renderWasted:f?.renderWasted,topRenderers:f?.topRenderers??[]};const M=f?.webRun;if(!M)return{...x,flags:_?[]:vh(x)};const O=[...M.longTasksSupported?[]:["long tasks"],...M.heapSupported?[]:["JS heap"],...M.loaf===null?["long animation frames"]:[]];const F={...x,platform:"web",uiFps:null,uiJank:null,jsJank:null,cpu:null,memMb:M.heapSupported?x.memMb:null,deviceMaxRefreshRate:Math.max(x.deviceMaxRefreshRate??0,M.refreshHz??0)||null,longTaskPct:M.longTaskPct,frameGapP95Ms:M.frameGapP95Ms,frameGapMaxMs:M.frameGapMaxMs,edgeSilenceMs:M.edgeSilenceMs??null,jsFps:M.fps??x.jsFps,longFrames:M.longFrames,...O.length?{missingMetrics:O}:{},loafBlockingMs:M.loaf?.blockingMs??null,styleLayoutMs:M.loaf?.styleLayoutMs??null,forcedLayoutMs:M.loaf?.forcedLayoutMs??null,topScripts:M.loaf?.topScripts??[],worstInteractionMs:M.interactions?.worstMs??null,layoutShift:M.layoutShift??null,domNodes:M.domNodesEnd??null,domGrowth:$h(y),pageLoad:M.pageLoad??null,refreshCalibrated:M.refreshCalibrated??null};return{...F,flags:_?[]:yh({...F,frames:M.frames})}}).filter(m=>m.caseName!==wr).map((m,f)=>({...m,batchIndex:f}));const d=kh(l,t);if(d){d.isBaseline=true;for(const m of l){if(m===d)continue;if(m.uiFps!=null&&d.uiFps!=null)m.deltaUiFps=Oe(m.uiFps-d.uiFps,1);if(m.jsFps!=null&&d.jsFps!=null)m.deltaJsFps=Oe(m.jsFps-d.jsFps,1)}}const u=l.filter(m=>!m.failed);const h=(m,f)=>{let y;let v=NaN;for(const $ of u){const T=m($);if(T==null)continue;if(y===void 0||f(T,v)){y=$;v=T}}return y?.caseName};const b=m=>m.platform==="web"?m.longFrames??null:m.jsJank==null&&m.uiJank==null?null:(m.jsJank??0)+(m.uiJank??0);const p={uiFps:h(m=>m.uiFps,(m,f)=>m>f),jsFps:h(m=>m.jsFps,(m,f)=>m>f),lowestCpu:h(m=>m.cpu,(m,f)=>m<f),lowestMem:h(m=>m.memMb,(m,f)=>m<f),fewestJank:h(b,(m,f)=>m<f),fewestLongTasks:h(m=>m.longTaskPct??null,(m,f)=>m<f)};const w=u.filter(m=>m.flags.length>0).map(m=>({caseName:m.caseName,flags:m.flags}));const g=u.filter(m=>m.flags.length===0).sort((m,f)=>(f.uiFps??f.jsFps??0)-(m.uiFps??m.jsFps??0)||(m.cpu??m.longTaskPct??Infinity)-(f.cpu??f.longTaskPct??Infinity)||(m.memMb??Infinity)-(f.memMb??Infinity)).map(m=>m.caseName);return{batchId:n,baselineName:d?.caseName??null,deviceMaxRefreshRate:u.find(m=>m.deviceMaxRefreshRate!=null)?.deviceMaxRefreshRate??null,rows:l,leaders:p,flagged:w,balanced:g}}function _h(e){const n=e.filter(a=>!a.failed);if(n.length===0)return[];const t=n.map(a=>a.pageLoad?.navigationId);if(t.some(a=>a==null)||new Set(t).size!==t.length)return[];if(n.some(a=>(a.pageLoad?.pageAgeMs??Infinity)>3e4))return[];const i=a=>(a??"").replace(/\/+$/,"")||"/";const r=a=>{const s=a.pageLoad;if(!s?.loadPath||i(s.loadPath)!==i(a.route))return false;const c=new URLSearchParams(s.loadSearch??"");const l=[...c.keys()];if(new Set(l).size!==l.length)return false;const d=Object.entries(a.params);return l.length===d.length&&d.every(([u,h])=>c.get(u)===h)};if(n.some(a=>!r(a)))return[];const o=a=>a==null?"\u2014":String(Math.round(a));return[`**Page load** (each case started on a fresh page load):`,"",`| Case | TTFB ms | FCP ms | LCP ms | DOM ready ms | Script KB | Total KB |`,`|------|--------:|-------:|-------:|-------------:|----------:|---------:|`,...n.map(a=>{const s=a.pageLoad;return`| ${a.caseName} | ${o(s.ttfbMs)} | ${o(s.fcpMs)} | ${o(s.lcpMs)} | ${o(s.domContentLoadedMs)} | ${o(s.scriptKb)} | ${o(s.totalKb)} |`}),"",`_KB is bytes over the network. 0 can mean the file came from cache, so compare cold loads with cold loads._`]}function Da(e){const n=o=>o.platform==="web"?o.jsFps:o.uiFps;const t=e.filter(o=>!o.failed&&n(o)!=null&&o.fpsMin!=null&&o.fpsMax!=null).sort((o,a)=>(n(a)??0)-(n(o)??0));if(t.length<2)return null;const[i,r]=t;if((i.validRuns??0)<2||(r.validRuns??0)<2){return`**Too few runs to separate the top cases.** ${i.caseName} and ${r.caseName} each need 2+ valid runs before their FPS gap means anything.`}if((r.fpsMax??0)>=(i.fpsMin??0)||(n(i)??0)-(n(r)??0)<=2){return`**Too close to call:** ${i.caseName} (${i.fpsMin}\u2013${i.fpsMax} FPS) and ${r.caseName} (${r.fpsMin}\u2013${r.fpsMax} FPS) overlap or sit within 2 FPS. No clear winner between them; more runs may separate them.`}return null}function hn(e){const n=(h,b=1)=>h==null?"\u2014":h.toFixed(b);const t=h=>h==null?"":h>0?` (+${h.toFixed(1)})`:` (${h.toFixed(1)})`;const i=[];i.push(`### Benchmark batch \`${e.batchId}\``);if(e.rows.some(h=>h.platform==="web")){xh(e,i);return i.join("\n")}i.push(`**No single winner \u2014 weigh the trade-offs.** UI-thread health matters more than raw averages: a cheap run that drops UI frames is worse than a pricier one that holds them.`);i.push("");const r=e.rows.some(h=>h.thermalState);const o=r?" Thermal |":"";const a=r?"-------|":"";i.push(`| # | Case | UI FPS | JS FPS | CPU % | Mem MB | JS jank | UI jank |${o} Flags |`);i.push(`|---|------|-------:|-------:|------:|-------:|--------:|--------:|${a}-------|`);for(const h of e.rows){const b=r?` ${bh[h.thermalState??"unknown"]??"\u2014"} |`:"";if(h.failed){i.push(`| ${h.batchIndex} | ${h.caseName} | \u2014 | \u2014 | \u2014 | \u2014 | \u2014 | \u2014 |${b} \u274C FAILED (${h.failureReason}) |`);continue}const p=h.flags.length?`\u26A0\uFE0F ${h.flags.join("; ")}`:"no flags";i.push(`| ${h.batchIndex} | ${h.caseName} | ${n(h.uiFps)}${t(h.deltaUiFps)} | ${n(h.jsFps)}${t(h.deltaJsFps)} | ${n(h.cpu)} | ${n(h.memMb)} | ${n(h.jsJank,0)} | ${n(h.uiJank,0)} |${b} ${p} |`)}const s=Da(e.rows);if(s){i.push("");i.push(s)}const c=e.rows.filter(h=>h.thermalState==="serious"||h.thermalState==="critical");if(c.length){i.push("");i.push(`**\u{1F525} Thermally throttled: ${c.map(h=>h.caseName).join(", ")}.** A throttled device runs SLOWER at a LOWER cpu%, so these cases can look like the cheapest in the batch while actually delivering fewer frames \u2014 check their UI FPS and jank, and re-run them on a cool device before drawing any conclusion.`)}i.push("");const l=e.leaders;const d=[l.uiFps&&`UI FPS \u2192 **${l.uiFps}**`,l.jsFps&&`JS FPS \u2192 **${l.jsFps}**`,l.lowestCpu&&`lowest CPU \u2192 **${l.lowestCpu}**`,l.lowestMem&&`lowest mem \u2192 **${l.lowestMem}**`,l.fewestJank&&`fewest jank \u2192 **${l.fewestJank}**`].filter(Boolean).join(" \xB7 ");if(d)i.push(`**Per-metric best:** ${d}`);i.push(e.balanced.length?`**No configured risk flags:** ${e.balanced.join(", ")}. Check missing metrics and workload requirements before choosing.`:`**No configured risk flags:** no candidates listed. Review failures, available metrics and flags before choosing.`);if(e.flagged.length){i.push(`**\u26A0\uFE0F At-risk:** ${e.flagged.map(h=>`${h.caseName} (${h.flags.join("; ")})`).join(" \xB7 ")}`)}const u=e.rows.filter(h=>!h.failed&&(h.renderCommits!=null||h.topRenderers.length>0)).map(h=>{const b=h.topRenderers.map(g=>`${g.name} \xD7${g.renders} (${g.totalMs}ms${g.cause?`, ${g.cause}`:""})`).join(", ");const p=h.renderCommits!=null?`${h.renderCommits} commits`:"";const w=h.renderWasted!=null?`${h.renderWasted} wasted`:"";return`- **${h.caseName}** \u2014 ${[p,w,b].filter(Boolean).join(": ")}`});if(u.length){i.push("");i.push("**Renders (median run)** \u2014 `wasted` = parent cascades + identity-only prop churn (removable). Cause per component: `propsUnstable` means a parent handed it a fresh function/object with unchanged values \u2014 fix upstream.");i.push(...u)}i.push("");i.push(`_Deltas vs baseline (\`${e.baselineName??"case #0"}\`). Don't pick on one metric \u2014 explain the trade-off (e.g. "A is cheapest but drops UI frames \u2192 jank risk; B costs more CPU but caps nothing")._`);return i.join("\n")}function br(e,n){const t=(i,r)=>({a:{avg:Oe(i.avg,1),p95:Oe(i.p95,1)},b:{avg:Oe(r.avg,1),p95:Oe(r.p95,1)},deltaAvg:Oe(r.avg-i.avg,1)});return{a:e.name,b:n.name,uiFps:t(e.stats.uiFps,n.stats.uiFps),jsFps:t(e.stats.jsFps,n.stats.jsFps),cpuUsage:t(e.stats.cpuUsage,n.stats.cpuUsage),memoryUsage:t(e.stats.memoryUsage,n.stats.memoryUsage),jsJankFrames:{a:e.stats.jsJankFrames,b:n.stats.jsJankFrames,delta:n.stats.jsJankFrames-e.stats.jsJankFrames},uiJankFrames:{a:e.stats.uiJankFrames,b:n.stats.uiJankFrames,delta:n.stats.uiJankFrames-e.stats.uiJankFrames},...Ia(e.renders,n.renders)}}function Sh(e,n){const t=(a,s,c)=>({a:a??null,b:s??null,delta:a!=null&&s!=null?Oe(s-a,1):null,better:c});const i=a=>a.webRun.heapSupported?Oe(a.stats.memoryUsage.max,1):null;const r=e.webRun;const o=n.webRun;return{a:e.name,b:n.name,platform:"web",note:"Browser runs: FPS is the main thread's whole-run requestAnimationFrame rate; long tasks % is not CPU. null = this browser couldn't measure it.",fps:t(r.fps??e.stats.jsFps.avg,o.fps??n.stats.jsFps.avg,"higher"),frameGapP95Ms:t(r.frameGapP95Ms,o.frameGapP95Ms,"lower"),frameGapMaxMs:t(r.frameGapMaxMs,o.frameGapMaxMs,"lower"),longFrames:t(r.longFrames,o.longFrames,"lower"),longTaskPct:t(r.longTaskPct,o.longTaskPct,"lower"),slowFrameBlockingMs:t(r.loaf?.blockingMs,o.loaf?.blockingMs,"lower"),styleLayoutPaintMs:t(r.loaf?.styleLayoutMs,o.loaf?.styleLayoutMs,"lower"),forcedLayoutMs:t(r.loaf?.forcedLayoutMs,o.loaf?.forcedLayoutMs,"lower"),worstInteractionMs:t(r.interactions?.worstMs,o.interactions?.worstMs,"lower"),layoutShift:t(r.layoutShift,o.layoutShift,"lower"),domNodes:t(r.domNodesEnd,o.domNodesEnd,"lower"),jsHeapMb:t(i(e),i(n),"lower"),topScripts:{a:r.loaf?.topScripts??[],b:o.loaf?.topScripts??[]},...Ia(e.renders,n.renders)}}function Ia(e,n){if(!e&&!n)return null;const t=i=>i??0;return{renders:{total:{a:t(e?.totalRenders),b:t(n?.totalRenders),delta:t(n?.totalRenders)-t(e?.totalRenders)},commits:{a:t(e?.totalCommits),b:t(n?.totalCommits),delta:t(n?.totalCommits)-t(e?.totalCommits)},wasted:{a:t(e?.wastedRenders),b:t(n?.wastedRenders),delta:t(n?.wastedRenders)-t(e?.wastedRenders)},causes:{a:e?.causes??{},b:n?.causes??{}}}}}function Oe(e,n){const t=Math.pow(10,n);return Math.round(e*t)/t}function xh(e,n){const t=(d,u=1)=>d==null?"\u2014":d.toFixed(u);const i=d=>d==null?"":d>0?` (+${d.toFixed(1)})`:` (${d.toFixed(1)})`;n.push(`**How to read this.** This is a browser run. FPS is the main thread's frame rate (requestAnimationFrame); it can't see frames dropped later by the GPU or compositor. Long tasks % is time the main thread was blocked by tasks over 50 ms, not CPU use. For Chrome's own dropped-frame count, use run_web_benchmark.`);n.push("");n.push(`| # | Case | FPS | p95 frame gap ms | Worst gap ms | Long frames | Long tasks % | JS heap MB | Flags |`);n.push(`|---|------|----:|-----------------:|-------------:|------------:|-------------:|--------:|-------|`);for(const d of e.rows){const u=d.isBaseline?`${d.caseName} (baseline)`:d.caseName;if(d.failed){n.push(`| ${d.batchIndex} | ${u} | \u2014 | \u2014 | \u2014 | \u2014 | \u2014 | \u2014 | \u274C FAILED (${d.failureReason}) |`);continue}const h=d.flags.length?`\u26A0\uFE0F ${d.flags.join("; ")}`:"no flags";n.push(`| ${d.batchIndex} | ${u} | ${t(d.jsFps)}${i(d.deltaJsFps)} | ${t(d.frameGapP95Ms)} | ${t(d.frameGapMaxMs)} | ${t(d.longFrames,0)} | ${t(d.longTaskPct)} | ${t(d.memMb)} | ${h} |`)}const r=e.rows.filter(d=>!d.failed).map(d=>{const u=[d.loafBlockingMs!=null&&d.loafBlockingMs>0&&`slow frames blocked input ${d.loafBlockingMs} ms`,d.styleLayoutMs!=null&&d.styleLayoutMs>0&&`style + layout ${d.styleLayoutMs} ms`,d.forcedLayoutMs!=null&&d.forcedLayoutMs>0&&`forced layout ${d.forcedLayoutMs} ms`,d.worstInteractionMs!=null&&`slowest input ${d.worstInteractionMs} ms`,d.layoutShift!=null&&d.layoutShift>0&&`layout shift ${d.layoutShift}`,d.domNodes!=null&&`${d.domNodes} DOM nodes${d.domGrowth?` (+${d.domGrowth} over the runs)`:""}`,d.topScripts&&d.topScripts.length>0&&`top scripts: ${d.topScripts.slice(0,3).map(h=>`${h.name} ${h.ms} ms`).join(", ")}`].filter(Boolean);return u.length?`- **${d.caseName}**: ${u.join(" \xB7 ")}`:null}).filter(Boolean);if(r.length){n.push("");n.push(`**Why frames were slow** (Long Animation Frames, Event Timing, DOM size; slow frames that ran past a run's end are left out):`);n.push(...r)}const o=_h(e.rows);if(o.length){n.push("");n.push(...o)}const a=Da(e.rows);if(a){n.push("");n.push(a)}const s=Array.from(new Set(e.rows.flatMap(d=>d.missingMetrics??[])));if(s.length){n.push("");n.push(`**Not measured in this browser:** ${s.join(", ")}. These show as \u2014 and can't win or lose.`)}if(e.rows.some(d=>d.refreshCalibrated===false)){n.push("");n.push(`**Refresh rate not checked on an idle screen:** the batch couldn't reach its bounce screen first, so the screen rate (and frame budgets) may read low.`)}if(e.deviceMaxRefreshRate){n.push("");n.push(`Screen rate: ${e.deviceMaxRefreshRate} Hz. A frame gap over ${(1500/e.deviceMaxRefreshRate).toFixed(1)} ms missed at least one frame.`)}n.push("");const c=e.leaders;const l=[c.jsFps&&`FPS \u2192 **${c.jsFps}**`,c.fewestJank&&`fewest long frames \u2192 **${c.fewestJank}**`,c.fewestLongTasks&&`fewest long tasks \u2192 **${c.fewestLongTasks}**`,c.lowestMem&&`lowest heap \u2192 **${c.lowestMem}**`].filter(Boolean).join(" \xB7 ");if(l)n.push(`**Per-metric leaders:** ${l}`);if(e.flagged.length){n.push(`**\u26A0\uFE0F At-risk:** ${e.flagged.map(d=>`${d.caseName} (${d.flags.join("; ")})`).join(" \xB7 ")}`)}n.push(e.balanced.length?`**No configured risk flags:** ${e.balanced.join(", ")}. Check missing metrics and workload requirements before choosing.`:`**No configured risk flags:** no candidates listed. Review failures, available metrics and flags before choosing.`);n.push("");n.push(`_Deltas vs baseline (\`${e.baselineName??"case #0"}\`). Confirm finalists on a real phone browser: desktop numbers don't predict mobile GPU, memory or heat._`)}import{z as G}from"zod";import{z as Th}from"zod";var A=e=>({content:[{type:"text",text:e}]});var S=e=>({isError:true,content:[{type:"text",text:e}]});var j=e=>e instanceof Error?e.message:String(e);var L=Th.string().optional().describe("The device to act on: its id from list_devices or from your instructions. Pass it whenever more than one app may be connected. Once a call names a device, later calls in this session use it when deviceId is left out.");var Ge=()=>process.env.BUOY_LOAD_CORE_TOOLS==="0"?void 0:{"anthropic/alwaysLoad":true};function Dh(e,n){return typeof e==="number"&&e>0?e:n}function st(e){return e?`${e}
@@ -1,4 +1,4 @@
1
- import{createRequire as A}from"module";const G=A(import.meta.url);import{PACKAGE_NAME as l,VERSION as v}from"./chunk-3O76SJJM.mjs";import{spawnSync as m}from"child_process";import s from"fs";import E from"os";import c from"path";function g(){return{BUOY_VERIFY:"auto"}}var w="https://registry.npmjs.org";var f=3e3;function R(e={}){const t=e.cwd??process.cwd();const r=e.skillSrcDir??c.resolve(__dirname,"../skill");const n=e.log??(a=>process.stdout.write(a+"\n"));const o=k(e,n);const i=[];d(c.join(t,".mcp.json"),"mcpServers",o,t,i);s.mkdirSync(c.join(t,".cursor"),{recursive:true});d(c.join(t,".cursor","mcp.json"),"mcpServers",o,t,i);if(s.existsSync(c.join(t,".vscode"))){d(c.join(t,".vscode","mcp.json"),"servers",o,t,i)}D(r,t,i);x(c.join(t,"CLAUDE.md"),t,i);x(c.join(t,"AGENTS.md"),t,i);n("Buoy MCP configuration written:");for(const a of i)n(" \u2022 "+a);n("");n("Next steps:");n(" 1. Restart your editor (or reconnect the MCP server) to load `buoy`.");n(" 2. Sign in: run `npx --package=@buoy-gg/core buoy login` in your app's folder. Then open an app with the required Buoy tools and sync integration.");n(" 3. Confirm the device and tools are available. Free accounts get the basic MCP tools; Pro adds the rest.");n("");n(`Want your AI to use the web too? Run \`npx -y ${l}@latest init --web\` for Buoy Web (free, no account).`);if(o.command==="npx"){n("");n(`The editor launches the server with \`npx -y ${l}@latest\`, so it stays`);n(`Registry access may be needed. Re-run \`npx -y ${l}@latest init\` to refresh configuration.`)}else if(!e.cliPath){n("");n(`This uses a pinned local install (no network on startup). To update it later,`);n(`To update the local package, run: npx -y ${o.args[0]?.replace(/dist[/\\]cli\.js$/,"")??""}@latest init --local`)}}function k(e,t){if(e.cliPath){return{type:"stdio",command:"node",args:[e.cliPath],env:g()}}const r=e.mode??"auto";if(r==="npx"){return y()}if(r==="local"){return $(e,t)}const n=I();if(n.reachable){return y()}t(`\u26A0 npm registry ${n.registry?`(${n.registry}) `:""}looks unreachable \u2014 \`npx @latest\` would hang your editor at startup. Falling back to a pinned local install.`);return $(e,t)}function y(){return{type:"stdio",command:"npx",args:["-y",`${l}@latest`],env:g()}}function $(e,t){const r=e.installDir??process.env.BUOY_MCP_HOME??c.join(E.homedir(),".buoy-mcp");const n=e.registry??w;const o=C(r,n,t);if(o){return{type:"stdio",command:"node",args:[o],env:g()}}t("\u26A0 local install failed \u2014 writing the npx entry instead (see the error above).");return y()}function C(e,t,r){const n=`${l}@${v==="0.0.0-dev"?"latest":v}`;s.mkdirSync(e,{recursive:true});const o=process.platform==="win32"?"npm.cmd":"npm";r(`Installing ${n} into ${e} from ${t} \u2026`);const i=m(o,["install",n,"--prefix",e,"--registry",t,`--@buoy-gg:registry=${t}`,"--no-audit","--no-fund","--loglevel=error"],{stdio:["ignore","ignore","inherit"],encoding:"utf8"});if(i.status!==0){r(`\u26A0 npm install exited with code ${i.status??"?"}${i.error?` (${i.error.message})`:""}.`);return null}const a=c.join(e,"node_modules",l,"dist","cli.js");if(!s.existsSync(a)){r(`\u26A0 install finished but ${a} is missing.`);return null}return a}function I(){const e=P();if(!e)return{reachable:false,registry:null};if(/^https?:\/\/registry\.npmjs\.org\/?$/i.test(e)){return{reachable:true,registry:e}}return{reachable:T(e),registry:e}}function P(){const e=S("@buoy-gg:registry");if(e)return e;const t=S("registry");return t??w}function S(e){const t=process.platform==="win32"?"npm.cmd":"npm";const r=m(t,["config","get",e],{encoding:"utf8",timeout:f});if(r.status!==0||typeof r.stdout!=="string")return null;const n=r.stdout.trim();if(!n||n==="undefined"||n==="null")return null;return n}function T(e){const t=m(process.execPath,["-e",F,e,String(f)],{encoding:"utf8",timeout:f+2e3});return t.status===0}var F=`
1
+ import{createRequire as A}from"module";const G=A(import.meta.url);import{PACKAGE_NAME as l,VERSION as v}from"./chunk-3STZVJQG.mjs";import{spawnSync as m}from"child_process";import s from"fs";import E from"os";import c from"path";function g(){return{BUOY_VERIFY:"auto"}}var w="https://registry.npmjs.org";var f=3e3;function R(e={}){const t=e.cwd??process.cwd();const r=e.skillSrcDir??c.resolve(__dirname,"../skill");const n=e.log??(a=>process.stdout.write(a+"\n"));const o=k(e,n);const i=[];d(c.join(t,".mcp.json"),"mcpServers",o,t,i);s.mkdirSync(c.join(t,".cursor"),{recursive:true});d(c.join(t,".cursor","mcp.json"),"mcpServers",o,t,i);if(s.existsSync(c.join(t,".vscode"))){d(c.join(t,".vscode","mcp.json"),"servers",o,t,i)}D(r,t,i);x(c.join(t,"CLAUDE.md"),t,i);x(c.join(t,"AGENTS.md"),t,i);n("Buoy MCP configuration written:");for(const a of i)n(" \u2022 "+a);n("");n("Next steps:");n(" 1. Restart your editor (or reconnect the MCP server) to load `buoy`.");n(" 2. Sign in: run `npx --package=@buoy-gg/core buoy login` in your app's folder. Then open an app with the required Buoy tools and sync integration.");n(" 3. Confirm the device and tools are available. Free accounts get the basic MCP tools; Pro adds the rest.");n("");n(`Want your AI to use the web too? Run \`npx -y ${l}@latest init --web\` for Buoy Web (free, no account).`);if(o.command==="npx"){n("");n(`The editor launches the server with \`npx -y ${l}@latest\`, so it stays`);n(`Registry access may be needed. Re-run \`npx -y ${l}@latest init\` to refresh configuration.`)}else if(!e.cliPath){n("");n(`This uses a pinned local install (no network on startup). To update it later,`);n(`To update the local package, run: npx -y ${o.args[0]?.replace(/dist[/\\]cli\.js$/,"")??""}@latest init --local`)}}function k(e,t){if(e.cliPath){return{type:"stdio",command:"node",args:[e.cliPath],env:g()}}const r=e.mode??"auto";if(r==="npx"){return y()}if(r==="local"){return $(e,t)}const n=I();if(n.reachable){return y()}t(`\u26A0 npm registry ${n.registry?`(${n.registry}) `:""}looks unreachable \u2014 \`npx @latest\` would hang your editor at startup. Falling back to a pinned local install.`);return $(e,t)}function y(){return{type:"stdio",command:"npx",args:["-y",`${l}@latest`],env:g()}}function $(e,t){const r=e.installDir??process.env.BUOY_MCP_HOME??c.join(E.homedir(),".buoy-mcp");const n=e.registry??w;const o=C(r,n,t);if(o){return{type:"stdio",command:"node",args:[o],env:g()}}t("\u26A0 local install failed \u2014 writing the npx entry instead (see the error above).");return y()}function C(e,t,r){const n=`${l}@${v==="0.0.0-dev"?"latest":v}`;s.mkdirSync(e,{recursive:true});const o=process.platform==="win32"?"npm.cmd":"npm";r(`Installing ${n} into ${e} from ${t} \u2026`);const i=m(o,["install",n,"--prefix",e,"--registry",t,`--@buoy-gg:registry=${t}`,"--no-audit","--no-fund","--loglevel=error"],{stdio:["ignore","ignore","inherit"],encoding:"utf8"});if(i.status!==0){r(`\u26A0 npm install exited with code ${i.status??"?"}${i.error?` (${i.error.message})`:""}.`);return null}const a=c.join(e,"node_modules",l,"dist","cli.js");if(!s.existsSync(a)){r(`\u26A0 install finished but ${a} is missing.`);return null}return a}function I(){const e=P();if(!e)return{reachable:false,registry:null};if(/^https?:\/\/registry\.npmjs\.org\/?$/i.test(e)){return{reachable:true,registry:e}}return{reachable:T(e),registry:e}}function P(){const e=S("@buoy-gg:registry");if(e)return e;const t=S("registry");return t??w}function S(e){const t=process.platform==="win32"?"npm.cmd":"npm";const r=m(t,["config","get",e],{encoding:"utf8",timeout:f});if(r.status!==0||typeof r.stdout!=="string")return null;const n=r.stdout.trim();if(!n||n==="undefined"||n==="null")return null;return n}function T(e){const t=m(process.execPath,["-e",F,e,String(f)],{encoding:"utf8",timeout:f+2e3});return t.status===0}var F=`
2
2
  const url = process.argv[1];
3
3
  const ms = Number(process.argv[2]) || 3000;
4
4
  const c = new AbortController();