agent-afk 5.222.1 → 5.222.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -270,7 +270,7 @@ Send a message to start one, or /new for a fresh session.`}function x_(e){return
270
270
 
271
271
  ${t}`}var nG,Om=m(()=>{"use strict";nG=new Set(["script","style","noscript","template","svg"])});function sG(e,t){return new Promise((n,r)=>{if(t?.aborted){r(t.reason??new Error("aborted"));return}let o=()=>{clearTimeout(s),r(t?.reason??new Error("aborted"))},s=setTimeout(()=>{t?.removeEventListener("abort",o),n()},e);t?.addEventListener("abort",o,{once:!0})})}function N_(e,t,n){let r=Math.min(t*2**e,n);return Math.round(Math.random()*r)}function iG(e,t){let n=e.headers.get("retry-after");if(n===null)return null;let r=Number(n.trim());return!Number.isFinite(r)||r<0?null:Math.min(r*1e3,t)}async function U_(e,t,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??sG,c=n.signal??void 0,l;for(let d=0;d<=o;d++){if(c?.aborted)throw c.reason??new Error("aborted");try{let u=await e(t,n);if(!oG.has(u.status)||d===o)return u;let p=iG(u,i)??N_(d,s,i);O("[web/retryFetch] retrying",{url:t,attempt:d,status:u.status,waitMs:p}),await u.body?.cancel().catch(()=>{}),await a(p,c)}catch(u){if(c?.aborted||(l=u,d===o))throw u;let p=N_(d,s,i);O("[web/retryFetch] retrying after error",{url:t,attempt:d,waitMs:p}),await a(p,c)}}throw l??new Error("retryFetch: exhausted without a result")}var oG,$_=m(()=>{"use strict";V();oG=new Set([429,502,503,504])});import{BlockList as aG,isIP as Fm}from"node:net";import{lookup as cG}from"node:dns/promises";import{Agent as lG}from"undici";function j_(){let e=w.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return e==="1"||e==="true"}function fG(e){return e.startsWith("[")&&e.endsWith("]")?e.slice(1,-1):e}function Dm(e){let t=Fm(e);return t===0?!1:pG.check(e,t===4?"ipv4":"ipv6")}async function H_(e){return cG(e,{all:!0,verbatim:!0})}async function Yn(e,t={}){if(t.allowPrivateHosts??j_())return{allowed:!0};let n;try{n=new URL(e)}catch{return{allowed:!1,reason:`"${e}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{allowed:!1,reason:`protocol "${n.protocol}" not supported (http/https only)`};let r=fG(n.hostname),o=(a,c)=>`refusing to fetch ${c} \u2014 internal/private address ${a} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`;if(Fm(r)!==0)return Dm(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=t.lookupFn??H_,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(Dm(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function Vs(e,t={}){let n=await Yn(e,t);if(!n.allowed)throw new Te(n.reason)}async function ln(e,t,n={},r={}){let o={...r.lookupFn!==void 0?{lookupFn:r.lookupFn}:{},...r.allowPrivateHosts!==void 0?{allowPrivateHosts:r.allowPrivateHosts}:{}},s=t;for(let i=0;i<=B_;i++){await Vs(s,o);let a={...n,redirect:"manual",...e===globalThis.fetch&&!(r.allowPrivateHosts??j_())?{dispatcher:mG}:{}},c=await U_(e,s,a,r.retry??{});if(!gG.has(c.status))return c;let l=c.headers.get("location");if(l===null||l.trim()==="")return c;let d;try{d=new URL(l,c.url||s).toString()}catch{return c}await c.body?.cancel().catch(()=>{}),s=d}throw new Te(`too many redirects (>${B_}) starting from ${t}`)}var dG,uG,pG,Te,mG,B_,gG,Qn=m(()=>{"use strict";P();$_();dG=[["0.0.0.0",8],["10.0.0.0",8],["100.64.0.0",10],["127.0.0.0",8],["169.254.0.0",16],["172.16.0.0",12],["192.168.0.0",16]],uG=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],pG=(()=>{let e=new aG;for(let[t,n]of dG)e.addSubnet(t,n,"ipv4");for(let[t,n]of uG)e.addSubnet(t,n,"ipv6");return e})(),Te=class extends Error{constructor(t){super(t),this.name="EgressBlockedError"}};mG=new lG({connect:{lookup(e,t,n){H_(e).then(r=>{let o=r.find(i=>Dm(i.address));if(o!==void 0){n(new Te(`refusing to connect to ${e} (resolved) \u2014 internal/private address ${o.address} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`),"",0);return}let s=r[0];if(s===void 0){n(new Error(`DNS lookup returned no addresses for ${e}`),"",0);return}n(null,s.address,Fm(s.address))},r=>n(r,"",0))}}});B_=20,gG=new Set([301,302,303,307,308])});var Nm={};zo(Nm,{enforceDomainPolicy:()=>ft,loadBrowserConfig:()=>Lm});import{readFileSync as hG}from"node:fs";import{join as yG}from"path";function bG(e){let n=e.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function W_(e,t){return bG(t).test(e)}function kG(e,t){if(e!==void 0){let n=e.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(t!==void 0){if(wG.has(t))return!0;if(SG.has(t))return!1}return!1}function K_(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0)}function vG(e){if(e===void 0||e==="")return"auto";if(e==="playwright"||e==="agent-browser"||e==="auto")return e;throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${e}`)}function G_(e){let t=e===void 0||e.trim()===""?"default":e.trim();return Rp(t),t}function TG(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"}function _G(e){try{return hG(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}}function EG(e,t){let n={...e};if(typeof t.headless=="boolean"&&(n.headless=t.headless),Array.isArray(t.allowedDomains)&&(n.allowedDomains=t.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(t.blockedDomains)&&(n.blockedDomains=t.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof t.domSnapshots=="boolean"&&(n.domSnapshots=t.domSnapshots),t.backend==="playwright"||t.backend==="agent-browser"||t.backend==="auto")n.backend=t.backend;else if(t.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${String(t.backend)}`);return typeof t.defaultProfile=="string"&&(n.defaultProfile=G_(t.defaultProfile)),n}function Lm(e){let t=e?.env??w,n=e?.readFileSync??_G,r=e?.surface??t.AGENT_SURFACE,o=kG(t.AFK_BROWSER_HEADLESS,r),s=K_(t.AFK_BROWSER_ALLOWED_DOMAINS),i=K_(t.AFK_BROWSER_BLOCKED_DOMAINS),a=TG(t.AFK_BROWSER_DOM_SNAPSHOTS),c=vG(t.AFK_BROWSER_BACKEND),l=G_(t.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null,defaultProfile:l},u=t.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():yG(ns(),"browser.json"),f=n(p);if(f===void 0)return d;let g;try{g=JSON.parse(f)}catch(y){throw new Error(`Failed to parse browser config at ${p}: ${String(y)}`)}if(typeof g!="object"||g===null||Array.isArray(g))throw new Error(`Browser config at ${p} must be a JSON object`);let h=EG(d,g);return h.configPath=p,h}function ft(e,t){let n;try{n=new URL(e).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${e}`}}for(let r of t.blockedDomains)if(W_(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return t.allowedDomains.length>0&&!t.allowedDomains.some(o=>W_(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var wG,SG,dn=m(()=>{"use strict";P();M();wG=new Set(["daemon","subagent","telegram","afk"]),SG=new Set(["repl","interactive","cli"])});import{readFileSync as xG}from"node:fs";import{join as AG}from"node:path";import{homedir as RG}from"node:os";function CG(e){let t=e??IG,n;try{n=xG(t,"utf8")}catch{return null}let r;try{r=JSON.parse(n)}catch{return null}if(typeof r!="object"||r===null||Array.isArray(r))return null;let o=r;if(typeof o.url!="string"||typeof o.token!="string"||typeof o.pid!="number")return null;let s;try{s=new URL(o.url)}catch{return null}let{hostname:i,protocol:a}=s;if(!(i==="127.0.0.1"||i==="localhost"||i==="::1")||a!=="http:")throw new Error(`Agent Browser connection file contains an untrusted URL: ${o.url}. Only http://127.0.0.1 or http://localhost is permitted.`);return{url:o.url,token:o.token,pid:o.pid,version:typeof o.version=="string"?o.version:"unknown"}}function PG(e){try{return process.kill(e,0),!0}catch{return!1}}async function MG(e,t,n=2e3){try{let r=new AbortController,o=setTimeout(()=>r.abort(),n),s=await fetch(`${e}/health`,{method:"GET",headers:{Authorization:`Bearer ${t}`,Host:"127.0.0.1:8833"},signal:r.signal});return clearTimeout(o),s.ok}catch{return!1}}async function Um(e){let t=CG(e);return t===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:PG(t.pid)?await MG(t.url,t.token)?{available:!0,connection:t,reason:null}:{available:!1,connection:t,reason:`health probe failed at ${t.url}`}:{available:!1,connection:t,reason:`stale connection file: PID ${t.pid} not alive`}}var IG,q_=m(()=>{"use strict";IG=AG(RG(),".config","agent-browser","connection.json")});async function X_(e){let{config:t,surface:n}=e;if(t.backend==="playwright")return{backend:"playwright",reason:"explicit config: backend=playwright",probeMs:0,availability:null};if(t.backend==="agent-browser"){let i=Date.now(),a=await Um(),c=Date.now()-i;if(!a.available)throw new Error(`AFK_BROWSER_BACKEND=agent-browser but Agent Browser is not available: ${a.reason}`);return{backend:"agent-browser",reason:"explicit config: backend=agent-browser",probeMs:c,availability:a}}if(n&&OG.has(n))return{backend:"playwright",reason:`auto: surface "${n}" excluded from Agent Browser`,probeMs:0,availability:null};if(t.headless)return{backend:"playwright",reason:"auto: headless mode requires Playwright",probeMs:0,availability:null};let r=Date.now(),o=await Um(),s=Date.now()-r;return o.available?{backend:"agent-browser",reason:"auto: Agent Browser available and preferred",probeMs:s,availability:o}:{backend:"playwright",reason:`auto: Agent Browser unavailable (${o.reason})`,probeMs:s,availability:o}}var OG,z_=m(()=>{"use strict";q_();OG=new Set(["daemon","subagent"])});import{createHash as DG}from"crypto";function J_(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&FG.test(e.label))}function V_(e){return DG("sha256").update(e,"utf8").digest("hex").slice(0,8)}function Y_(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var FG,Yc=m(()=>{"use strict";FG=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as LG}from"crypto";import{mkdir as NG,stat as UG,writeFile as $G}from"fs/promises";import{join as $m}from"path";import{gzip as BG}from"zlib";import{promisify as jG}from"util";function HG(e){return $m(ht(e),"browser")}function WG(e){return $m(HG(e),"screenshots")}function KG(){return new Date().toISOString().replace(/[:.]/g,"-")}function GG(){return LG(3).toString("hex")}async function Vr(e,t,n){if(t.length>Q_)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Q_} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=WG(e);await NG(r,{recursive:!0});let o=`${KG()}-${GG()}-${n}.png`,s=$m(r,o);await $G(s,t);let{size:i}=await UG(s);return{path:s,bytes:i}}var ece,Q_,Bm=m(()=>{"use strict";M();Yc();ece=jG(BG);Q_=5*1024*1024});var Qc,Z_=m(()=>{"use strict";V();Qc=class{baseUrl;token;constructor(t){this.baseUrl=t.url,this.token=t.token}async call(t,n,r=3e4){let o={version:1,method:t,params:n},s=new AbortController,i=setTimeout(()=>s.abort(),r);try{let a=await fetch(`${this.baseUrl}/agent`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`,Host:new URL(this.baseUrl).host},body:JSON.stringify(o),signal:s.signal});if(!a.ok){let l=await a.text().catch(()=>"");throw new Error(`Agent Browser ${t} failed (HTTP ${a.status}): ${l}`)}let c=await a.json();if(c.ok===!1){let l=c.error,d=l?.code??"UNKNOWN",u=l?.message??JSON.stringify(c);throw new Error(`Agent Browser ${t} failed: [${String(d)}] ${String(u)}`)}return c.result}finally{clearTimeout(i)}}async listTabs(){return this.call("tabs.list",null)}async openTab(t){return{tabId:(await this.call("tabs.open",{url:t},6e4)).id}}async closeTab(t){await this.call("page.eval",{id:t,script:"window.close()"}).catch(n=>{O("[browser/agent-browser] closeTab window.close() failed (tab leak expected)",{tabId:t,err:n})})}async read(t,n){return this.call("page.read",{id:t,mode:n?.mode??"main",...n?.query?{query:n.query}:{},...n?.budget?{budget:n.budget}:{}})}async inspect(t,n){return this.call("page.inspect",{id:t,mode:n?.mode??"interactive",...n?.query?{query:n.query}:{},...n?.limit?{limit:n.limit}:{}})}async click(t,n){await this.call("page.click",{id:t,elementId:n})}async fill(t,n,r){await this.call("page.fill",{id:t,elementId:n,value:r})}async press(t,n,r){await this.call("page.press",{id:t,key:n,...r?{elementId:r}:{}})}async select(t,n,r){await this.call("page.select",{id:t,elementId:n,value:r})}async waitFor(t,n,r){await this.call("page.wait",{id:t,condition:n,...r?.value?{value:r.value}:{},...r?.timeout?{timeout:r.timeout}:{}},(r?.timeout??3e4)+5e3)}async evalScript(t,n){return this.call("page.eval",{id:t,script:n})}async screenshot(t){return this.call("page.screenshot",{id:t})}}});function jm(e){return{id:e.id,role:e.role,label:e.label,kind:e.kind,value:e.value,state:{disabled:e.disabled,...e.checked!==void 0?{checked:e.checked}:{},...e.selected!==void 0?{selected:e.selected}:{},...e.expanded!==void 0?{expanded:e.expanded}:{}},bbox:e.bbox,...e.selector?{selector:e.selector}:{}}}function eE(e,t){switch(t.kind){case"element_id":if(e.has(t.elementId))return t.elementId;throw new Error(`Element ${t.elementId} not found in current observation. Call browser_observe to refresh.`);case"selector":return null;case"semantic":return null}}async function Hm(e,t,n,r,o,s){switch(n){case"click":await e.click(t,r);break;case"fill":if(o===void 0)throw new Error("fill requires a value");await e.fill(t,r,o);break;case"press":if(o===void 0)throw new Error("press requires a value (key combo)");await e.press(t,o,r);break;case"select":if(o===void 0)throw new Error("select requires a value");await e.select(t,r,o);break;case"hover":throw new Error("hover is not supported by Agent Browser; use element_id from a prior observation to target clicks instead");case"scroll_to":{let i=r.replace(/\\/g,"\\\\").replace(/"/g,'\\"');await e.evalScript(t,`document.querySelector('[data-element-id="${i}"]')?.scrollIntoView({behavior:'smooth',block:'center'})`);break}case"wait_for":await e.waitFor(t,"element",{value:r,timeout:s??1e4});break;default:throw new Error(`Unknown action: ${n}`)}}async function tE(e,t){if(t.target.kind!=="semantic")throw new Error("resolveSemanticAndAct called with non-semantic target");let{elements:n}=await e.client.inspect(e.tabId,{mode:"interactive",query:t.target.text,limit:10}),r=n;if(t.target.role){let c=t.target.role.toLowerCase();r=n.filter(l=>l.role.toLowerCase()===c)}if(r.length===0)throw new Error(`No element found matching semantic target: text="${t.target.text}"`+(t.target.role?`, role="${t.target.role}"`:""));if(r.length>1)return{outcome:"ambiguous_target",query:{text:t.target.text,...t.target.role?{role:t.target.role}:{}},candidates:r.slice(0,5).map(jm)};let s=r[0].id;await Hm(e.client,e.tabId,t.action,s,t.value,t.timeoutMs);let i=await e.client.read(e.tabId,{mode:"main"}),a=ft(i.url,e.config);return a.allowed?{elementId:s}:{outcome:"blocked_by_policy",url:i.url,reason:`action navigated to blocked domain: ${a.reason}`}}var nE=m(()=>{"use strict";dn()});var rE={};zo(rE,{AgentBrowserProvider:()=>Wm});var Wm,oE=m(()=>{"use strict";dn();Bm();Z_();nE();Wm=class{name="agent-browser";config;client;sessions=new Map;constructor(t,n){this.config=t,this.client=new Qc(n)}async open(t){let n=ft(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let r=this.sessions.get(t.sessionId);if(r)await this.client.evalScript(r.tabId,`window.location.href = ${JSON.stringify(t.url)}`),await this.client.waitFor(r.tabId,"load",{timeout:t.timeoutMs??3e4});else{let{tabId:i}=await this.client.openTab(t.url);await this.client.waitFor(i,"load",{timeout:t.timeoutMs??3e4}),r={tabId:i,observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null},this.sessions.set(t.sessionId,r)}let o=await this.client.read(r.tabId,{mode:"main"}),s=ft(o.url,this.config);return s.allowed?this.buildObservation(r,t.sessionId,t.screenshot,void 0,"browser_open"):(await this.client.evalScript(r.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`redirected to blocked domain: ${s.reason}`})}async observe(t){let n=this.sessions.get(t.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${t.sessionId}. Call browser_open first.`);return this.buildObservation(n,t.sessionId,t.screenshot,t.maxElements,"browser_observe")}async act(t){let n=this.sessions.get(t.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${t.sessionId}. Call browser_open first.`);let r=eE(n.knownElements,t.target);if(r===null){if(t.target.kind==="semantic"){let i=await tE({client:this.client,config:this.config,tabId:n.tabId},t);return"outcome"in i?i:(n.lastAction=`browser_act:${t.action}`,n.lastActionAt=new Date().toISOString(),this.buildObservation(n,t.sessionId,t.screenshot,void 0,"browser_act"))}throw t.target.kind==="selector"?new Error("selector targets are not supported by Agent Browser; use element_id or semantic targets"):new Error(`Cannot resolve target: ${JSON.stringify(t.target)}`)}await Hm(this.client,n.tabId,t.action,r,t.value,t.timeoutMs),n.lastAction=`browser_act:${t.action}`,n.lastActionAt=new Date().toISOString();let o=await this.client.read(n.tabId,{mode:"main"}),s=ft(o.url,this.config);return s.allowed?this.buildObservation(n,t.sessionId,t.screenshot,void 0,"browser_act"):(await this.client.evalScript(n.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`action navigated to blocked domain: ${s.reason}`})}async render(t){throw new Error("AgentBrowserProvider does not support render(). Use PlaywrightProvider for one-shot content fetches.")}async screenshot(t){let n=this.sessions.get(t.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${t.sessionId}. Call browser_open first.`);if(t.target!==void 0||t.fullPage)throw new Error("Agent Browser does not support element or full-page screenshots; omit target and fullPage.");let r=await this.client.screenshot(n.tabId),o=Buffer.from(r.data,"base64"),s=o.length>=24?o.readUInt32BE(16):0,i=o.length>=24?o.readUInt32BE(20):0;return{path:(await Vr(t.sessionId,o,"browser_screenshot")).path,bytes:o.length,width:s,height:i,dataBase64:r.data,mediaType:"image/png"}}async extract(t){throw new Error("AgentBrowserProvider does not support extract() yet.")}async close(t){let n=this.sessions.get(t.sessionId);if(n){try{await this.client.closeTab(n.tabId)}catch{}this.sessions.delete(t.sessionId)}}describe(t){let n=this.sessions.get(t);return n?{active:!0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:1}:null}async shutdown(){let t=Array.from(this.sessions.entries()).map(async([,n])=>{try{await this.client.closeTab(n.tabId)}catch{}});await Promise.all(t),this.sessions.clear()}async buildObservation(t,n,r,o,s="browser_open"){let[i,a]=await Promise.all([this.client.read(t.tabId,{mode:"main",budget:4e3}),this.client.inspect(t.tabId,{mode:"interactive",limit:o??80})]),c=a.elements.map(jm),l=o??80,d=c.slice(0,l);t.observationCounter+=1,t.knownElements=new Map(d.map(h=>[h.id,h])),t.currentUrl=i.url,t.currentTitle=i.title;let u=[];c.length>l&&u.push(`page has ${c.length} interactive elements; showing first ${l}`);let p=null;if(r)try{let h=await this.client.screenshot(t.tabId),y=Buffer.from(h.data,"base64");p=(await Vr(n,y,s)).path}catch{u.push("screenshot capture failed")}let f=`obs_${t.observationCounter.toString(36)}`,g={httpStatus:null,loadingState:"idle",hasDialog:!1,consoleErrors:0};return{observationId:f,url:i.url,title:i.title,textSummary:i.content.slice(0,4e3),interactive:d,status:g,warnings:u,screenshotPath:p,capturedAt:new Date().toISOString()}}}});import{existsSync as qG,readFileSync as XG}from"node:fs";import{createRequire as zG}from"node:module";import{dirname as JG,join as VG}from"node:path";function aE(e){if(typeof e=="string")return e;let t=[],n=e;for(let r=0;r<QG&&n instanceof Error;r++)t.push(n.message),n=n.cause;return t.length>0?t.join(" | "):String(e)}function Ue(e){let t=aE(e);return iE.some(n=>t.includes(n))}function ZG(){try{let t=zG(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(XG(t,"utf8"));if(typeof n!="object"||n===null)return;let r=n.bin,o=typeof r=="string"?r:typeof r=="object"&&r!==null?r.playwright:void 0;if(typeof o!="string"||o.length===0)return;let s=VG(JG(t),o);return qG(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function Ys(){return sE??=ZG()??YG,sE}function Km(e){return e.includes("install chromium")}function rt(e,t){let n=aE(e),r=t?.latched===!0?` ${eq}`:"";if(n.includes("Executable doesn't exist")){let o="";return t?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":t?.headless===!1&&(o=" This launch was headed, which needs the full `chromium-*` build \u2014 the headless shell alone does not satisfy it."),`browser tools require the Playwright chromium binary. Install via: ${Ys()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Ys()}). Or pick a different tool.${r}`}function Zc(e,t,n=!1){if(!Ue(e))return e;let r=e instanceof Error?e.message:String(e);return new Error(`${r}
272
272
 
273
- ${rt(e,{headless:t,latched:n})}`,{cause:e})}var iE,YG,QG,sE,eq,Gm=m(()=>{"use strict";iE=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],YG="pnpm exec playwright install chromium",QG=4;eq="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import Zn from"node:fs";import el from"node:path";import{randomBytes as tq}from"node:crypto";function nq(){try{return"5.222.1"}catch{}try{let e=el.resolve(import.meta.dirname,"../../../package.json"),t=Zn.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var rq,tl,cE=m(()=>{"use strict";Gm();M();V();rq=nq(),tl=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(t){this.config=t}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(t){this.launchFailure={error:t}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let t;try{({chromium:t}=await import("playwright"))}catch(n){let r=Zc(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await t.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Zc(n,this.config.headless,!0);throw this.latchLaunchFailure(r),r}finally{this.launchPromise=void 0}})(),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(t){let n=this.sessions.get(t);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(t,i),s}async ensurePage(t){let n=this.sessions.get(t);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(t);let r=this.sessions.get(t);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${t}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(t){return this.sessions.get(t)?.page}async renderHtml(t,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(t,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(t){return this.sessions.get(t)?.consoleErrors??0}getLastHttpStatus(t){return this.sessions.get(t)?.lastHttpStatus??null}hasOpenDialog(t){return this.sessions.get(t)?.openDialog!==void 0}async dismissDialog(t,n=!0){let r=this.sessions.get(t);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(t){this.clearLaunchFailure();let n=this.sessions.get(t);n!==void 0&&(this.sessions.delete(t),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let t=[...this.sessions.keys()];if(await Promise.all(t.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${rq}`}}loadStorageState(t){let n=Ip(t);try{if(!Zn.existsSync(n))return;let r=JSON.parse(Zn.readFileSync(n,"utf8"));return O("[browser/vault] restored session",{profile:t,file:n}),r}catch(r){O("[browser/vault] ignoring unreadable vault",{profile:t,file:n,err:r});return}}async saveStorageState(t,n){try{let r=Ip(t);if(!Zn.existsSync(r))return;let o=await n.storageState(),s=el.join(el.dirname(r),`.${el.basename(r)}.${process.pid}.${tq(4).toString("hex")}.tmp`);Zn.writeFileSync(s,JSON.stringify(o),{mode:384}),Zn.chmodSync(s,384),Zn.renameSync(s,r),O("[browser/vault] saved session",{profile:t,file:r})}catch(r){O("[browser/vault] save failed",{profile:t,err:r})}}}});import{createHash as oq}from"node:crypto";function sq(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function iq(e,t,n){return`el_${oq("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function aq(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function lE(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function uE(e,t){let n=e.role??"",r=e.name??"";dE.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let s of e.children??[])uE(s,t)}async function cq(e){return e.evaluate(t=>{let n=Array.from(document.querySelectorAll(t)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},pE).catch(()=>[])}async function lq(e){return e.evaluate(t=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(t)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let h=s.type;h==="checkbox"?l="checkbox":h==="radio"?l="radio":h==="button"||h==="submit"||h==="reset"?l="button":h==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,g={role:l,name:c,disabled:p};u!==void 0&&(g.value=u),f!==void 0&&(g.checked=f),o.push(g)}return o},pE).catch(()=>[])}function dq(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function nl(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],s=dq(e),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=cq(e),c=e.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(e.url()),d=e.title().catch(()=>""),[u,p,f,g,h]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],uE(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await lq(e)).filter(C=>dE.has(C.role??"")));let S=new Map;for(let _ of p){let C=lE(_.name),N=S.get(C);(!N||N.bbox.w===0&&_.bbox.w>0)&&S.set(C,_)}let k=y.map(_=>({ax:_,dom:S.get(lE(_.name??""))})),T=r?k:k.filter(_=>_.dom?_.dom.bbox.w>0||_.dom.bbox.h>0:!0);T.sort((_,C)=>{let N=_.dom?.bbox.y??0,D=C.dom?.bbox.y??0;if(N!==D)return N-D;let U=_.dom?.bbox.x??0,L=C.dom?.bbox.x??0;return U-L}),T.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=T.slice(0,n).map((_,C)=>{let N=_.ax.role??"generic",D=_.ax.name??"",U=iq(N,D,C),L=_.dom?.bbox??{x:0,y:0,w:0,h:0},$=_.dom?.type??null,q=null;_.ax.value!==void 0&&_.ax.value!==null&&(q=String(_.ax.value)),_.ax.checked!==void 0&&(q=String(_.ax.checked)),J_({role:N,kind:$})&&(q="[redacted]");let K={disabled:_.ax.disabled??!1};_.ax.checked!==void 0&&(K.checked=_.ax.checked===!0||_.ax.checked==="mixed"),_.ax.selected!==void 0&&(K.selected=_.ax.selected),_.ax.expanded!==void 0&&(K.expanded=_.ax.expanded);let ne;_.dom?.testId?ne=`[data-testid="${_.dom.testId}"]`:_.dom?.id&&(ne=`#${_.dom.id}`);let In={id:U,role:N,label:sq(D),kind:$,value:q,state:K,bbox:L};return ne!==void 0&&(In.selector=ne),In}),x="idle";try{let _=await e.evaluate(()=>document.readyState);_==="loading"?x="loading":_==="interactive"?x="navigating":x="idle"}catch{x="navigating"}x!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let F=aq(f),v=`obs_${t.observationCounter.toString(36)}`,A=new Date().toISOString();return{observationId:v,url:g,title:h,textSummary:F,interactive:R,status:{httpStatus:t.httpStatus??null,loadingState:x,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:A}}var dE,pE,fE=m(()=>{"use strict";Yc();dE=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);pE="a[href], button, input, select, textarea, [role], [tabindex], label"});async function mE(e,t){try{let n=await e.nth(t).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${t}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function qm(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,s)=>mE(e,s)))).filter(o=>o!==null)}async function uq(e){let t=new Set,n=[];for(let{loc:r,count:o}of e)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}t.has(i)||(t.add(i),n.push({key:i,locator:r,index:s}))}return n}async function Xm(e,t,n){switch(t.kind){case"element_id":return pq(e,t,n);case"selector":return fq(e,t);case"semantic":return mq(e,t)}}async function pq(e,t,n){let r=n.get(t.elementId);if(r===void 0)return{outcome:"not_found",query:t};if(r.selector!==void 0){let c=e.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=e.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:t};if(s===1)return{outcome:"resolved",locator:o};let i=await qm(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function fq(e,t){let n=e.locator(t.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:t};if(r===1)return{outcome:"resolved",locator:n};let o=await qm(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function mq(e,t){return t.role!==void 0?gq(e,t.text,t.role):hq(e,t.text,t)}async function gq(e,t,n){let r=e.getByRole(n,{name:t}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:t,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await qm(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:s}}async function hq(e,t,n){let r=e.getByRole("button",{name:t}),o=e.getByRole("link",{name:t}),s=e.getByLabel(t,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await uq(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let b=await mE(y.locator,y.index);if(b!==null){let S=`${b.role}:${b.label}:${h}`,k=0;for(let T=0;T<S.length;T++)k=k*31+S.charCodeAt(T)>>>0;f.push({...b,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:f}}var gE=m(()=>{"use strict"});async function zm(e,t,n,r){let o=e.url();if(o===n)return null;let s=ft(o,t);if(s.allowed)return null;try{await e.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var hE=m(()=>{"use strict";dn()});var Vm={};zo(Vm,{PlaywrightProvider:()=>Jm});function yE(e){switch(e.kind){case"semantic":return e.role!==void 0?`semantic('${e.text}', role='${e.role}')`:`semantic('${e.text}')`;case"element_id":return`element_id(${e.elementId})`;case"selector":return`selector(${e.selector})`}}var Jm,Ym=m(()=>{"use strict";cE();fE();gE();dn();hE();Bm();Jm=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new tl(t)}async open(t){let n=ft(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let{sessionId:r}=t,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(t.url,{timeout:t.timeoutMs??3e4,waitUntil:t.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await zm(o,this.config,t.url,()=>this.close({sessionId:r}));if(u!==null)return u}(t.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await nl(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;t.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await nl(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:t.includeHidden,maxElements:t.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=t.timeoutMs??3e4,a=await Xm(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${yE(t.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(t.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(t.value??"");break;case"press":await c.press(t.value??"");break;case"select":await c.selectOption(t.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await d()}catch(y){l=y}else l=h}let u=await zm(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(t.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await nl(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${t.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,g),l!==null)throw l;return f}async render(t){return this.launcher.renderHtml(t.url,{timeoutMs:t.timeoutMs??3e4,waitUntil:t.waitFor??"load",signal:t.signal,requestGuard:t.requestGuard})}async screenshot(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(t.target!==void 0){let d=await Xm(r,t.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${yE(t.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:t.fullPage??!1});let{path:i,bytes:a}=await Vr(n,s,"browser_screenshot"),c=0,l=0;if(t.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(t){throw new Error("browser_extract not implemented in Phase 1")}async close(t){await this.launcher.closeSession(t.sessionId),this.sessions.delete(t.sessionId)}describe(t){let n=this.sessions.get(t);if(n===void 0)return null;let r=this.launcher.getPage(t);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(t){let n=this.sessions.get(t);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(t,r),r}updateSessionFromObservation(t,n,r,o,s){t.knownElements=new Map(n.map(i=>[i.id,i])),t.currentUrl=r,t.currentTitle=o,t.lastAction=s,t.lastActionAt=new Date().toISOString()}async captureScreenshot(t,n,r){try{let o=await t.screenshot({fullPage:!1}),{path:s}=await Vr(n,o,r);return s}catch{return null}}}});var tr={};zo(tr,{__resetBrowserRegistryForTests:()=>vq,browserProviderActive:()=>wq,closeBrowserProvider:()=>Zm,getBrowserProvider:()=>bq,getLastRoutingDecision:()=>kq,peekBrowserProvider:()=>Sq});function bE(){Promise.resolve(Zm()).then(()=>{process.exit(130)})}function wE(){Promise.resolve(Zm()).then(()=>{process.exit(143)})}function SE(){Et=null}function yq(){rl||(process.on("SIGINT",bE),process.on("SIGTERM",wE),process.on("exit",SE),rl=!0)}function kE(){rl&&(process.removeListener("SIGINT",bE),process.removeListener("SIGTERM",wE),process.removeListener("exit",SE),rl=!1)}async function bq(e){return Et!==null?Et:(er!==null||(er=(async()=>{let t=Lm(e),n=e?.surface??(e?.env??{}).AGENT_SURFACE??w.AGENT_SURFACE,r=await X_({config:t,surface:n});Qm=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(oE(),rE)),i=r.availability.connection;o=new s(t,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Ym(),Vm));o=new s(t)}return yq(),Et=o,er=null,o})()),er)}async function Zm(){if(Et===null)return;let e=Et;Et=null,er=null,kE(),await e.shutdown()}function wq(){return Et!==null}function Sq(){return Et}function kq(){return Qm}function vq(){Et=null,er=null,Qm=null,kE()}var Et,er,rl,Qm,nr=m(()=>{"use strict";dn();z_();P();Et=null,er=null,rl=!1,Qm=null});async function vE(e,t){try{return await D_(e,t)}catch(n){return O("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function Rq(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(nr(),tr)),r=await n();try{return await r.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Ym(),Vm)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(dn(),Nm)),a=i(),c=new s(a);try{return await c.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}finally{await c.shutdown()}}throw o}}async function TE(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??Rq,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},s=null,i="",a=e,c=null,l=null;try{let u=await ln(n,e,{headers:Aq,signal:t.signal},o);c=u.status,a=u.url||e;let p=u.headers.get("content-type")??"";if(u.ok){if(xq.test(p))throw new Error(`web_scrape markdown mode received binary content (${p.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let f=await u.text();if(Eq.test(p)&&!_q.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await vE(f,a),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(u){if(t.signal.aborted||u instanceof Te||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=Mm({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await Vs(e,o);let u=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:f=>Vs(f,o)});u.finalUrl!==e&&/^https?:\/\//i.test(u.finalUrl)&&await Vs(u.finalUrl,o);let p=await vE(u.html,u.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=Mm({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(t.signal.aborted||u instanceof Te)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,g=new Error(`web_scrape could not retrieve ${e}: fetch failed (${f}) and render failed (${p}).`);throw g.cause=u,g}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${e} (HTTP ${c??"error"}).`)}var _q,Eq,xq,Aq,_E=m(()=>{"use strict";F_();Om();Qn();V();_q=/(text\/html|application\/xhtml\+xml)/i,Eq=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,xq=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,Aq={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/web_scrape",Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}});function Pq(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await t(Iq,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":e.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),Cq),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=ue(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function EE(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?Pq({apiKey:e.exaApiKey,fetchFn:e.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function xE(e,t){if(t.length===0)return`# Search results for "${e}"
273
+ ${rt(e,{headless:t,latched:n})}`,{cause:e})}var iE,YG,QG,sE,eq,Gm=m(()=>{"use strict";iE=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],YG="pnpm exec playwright install chromium",QG=4;eq="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import Zn from"node:fs";import el from"node:path";import{randomBytes as tq}from"node:crypto";function nq(){try{return"5.222.2"}catch{}try{let e=el.resolve(import.meta.dirname,"../../../package.json"),t=Zn.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var rq,tl,cE=m(()=>{"use strict";Gm();M();V();rq=nq(),tl=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(t){this.config=t}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(t){this.launchFailure={error:t}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let t;try{({chromium:t}=await import("playwright"))}catch(n){let r=Zc(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await t.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Zc(n,this.config.headless,!0);throw this.latchLaunchFailure(r),r}finally{this.launchPromise=void 0}})(),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(t){let n=this.sessions.get(t);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(t,i),s}async ensurePage(t){let n=this.sessions.get(t);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(t);let r=this.sessions.get(t);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${t}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(t){return this.sessions.get(t)?.page}async renderHtml(t,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(t,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(t){return this.sessions.get(t)?.consoleErrors??0}getLastHttpStatus(t){return this.sessions.get(t)?.lastHttpStatus??null}hasOpenDialog(t){return this.sessions.get(t)?.openDialog!==void 0}async dismissDialog(t,n=!0){let r=this.sessions.get(t);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(t){this.clearLaunchFailure();let n=this.sessions.get(t);n!==void 0&&(this.sessions.delete(t),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let t=[...this.sessions.keys()];if(await Promise.all(t.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${rq}`}}loadStorageState(t){let n=Ip(t);try{if(!Zn.existsSync(n))return;let r=JSON.parse(Zn.readFileSync(n,"utf8"));return O("[browser/vault] restored session",{profile:t,file:n}),r}catch(r){O("[browser/vault] ignoring unreadable vault",{profile:t,file:n,err:r});return}}async saveStorageState(t,n){try{let r=Ip(t);if(!Zn.existsSync(r))return;let o=await n.storageState(),s=el.join(el.dirname(r),`.${el.basename(r)}.${process.pid}.${tq(4).toString("hex")}.tmp`);Zn.writeFileSync(s,JSON.stringify(o),{mode:384}),Zn.chmodSync(s,384),Zn.renameSync(s,r),O("[browser/vault] saved session",{profile:t,file:r})}catch(r){O("[browser/vault] save failed",{profile:t,err:r})}}}});import{createHash as oq}from"node:crypto";function sq(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function iq(e,t,n){return`el_${oq("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function aq(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function lE(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function uE(e,t){let n=e.role??"",r=e.name??"";dE.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let s of e.children??[])uE(s,t)}async function cq(e){return e.evaluate(t=>{let n=Array.from(document.querySelectorAll(t)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},pE).catch(()=>[])}async function lq(e){return e.evaluate(t=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(t)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let h=s.type;h==="checkbox"?l="checkbox":h==="radio"?l="radio":h==="button"||h==="submit"||h==="reset"?l="button":h==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,g={role:l,name:c,disabled:p};u!==void 0&&(g.value=u),f!==void 0&&(g.checked=f),o.push(g)}return o},pE).catch(()=>[])}function dq(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function nl(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],s=dq(e),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=cq(e),c=e.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(e.url()),d=e.title().catch(()=>""),[u,p,f,g,h]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],uE(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await lq(e)).filter(C=>dE.has(C.role??"")));let S=new Map;for(let _ of p){let C=lE(_.name),N=S.get(C);(!N||N.bbox.w===0&&_.bbox.w>0)&&S.set(C,_)}let k=y.map(_=>({ax:_,dom:S.get(lE(_.name??""))})),T=r?k:k.filter(_=>_.dom?_.dom.bbox.w>0||_.dom.bbox.h>0:!0);T.sort((_,C)=>{let N=_.dom?.bbox.y??0,D=C.dom?.bbox.y??0;if(N!==D)return N-D;let U=_.dom?.bbox.x??0,L=C.dom?.bbox.x??0;return U-L}),T.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=T.slice(0,n).map((_,C)=>{let N=_.ax.role??"generic",D=_.ax.name??"",U=iq(N,D,C),L=_.dom?.bbox??{x:0,y:0,w:0,h:0},$=_.dom?.type??null,q=null;_.ax.value!==void 0&&_.ax.value!==null&&(q=String(_.ax.value)),_.ax.checked!==void 0&&(q=String(_.ax.checked)),J_({role:N,kind:$})&&(q="[redacted]");let K={disabled:_.ax.disabled??!1};_.ax.checked!==void 0&&(K.checked=_.ax.checked===!0||_.ax.checked==="mixed"),_.ax.selected!==void 0&&(K.selected=_.ax.selected),_.ax.expanded!==void 0&&(K.expanded=_.ax.expanded);let ne;_.dom?.testId?ne=`[data-testid="${_.dom.testId}"]`:_.dom?.id&&(ne=`#${_.dom.id}`);let In={id:U,role:N,label:sq(D),kind:$,value:q,state:K,bbox:L};return ne!==void 0&&(In.selector=ne),In}),x="idle";try{let _=await e.evaluate(()=>document.readyState);_==="loading"?x="loading":_==="interactive"?x="navigating":x="idle"}catch{x="navigating"}x!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let F=aq(f),v=`obs_${t.observationCounter.toString(36)}`,A=new Date().toISOString();return{observationId:v,url:g,title:h,textSummary:F,interactive:R,status:{httpStatus:t.httpStatus??null,loadingState:x,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:A}}var dE,pE,fE=m(()=>{"use strict";Yc();dE=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);pE="a[href], button, input, select, textarea, [role], [tabindex], label"});async function mE(e,t){try{let n=await e.nth(t).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${t}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function qm(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,s)=>mE(e,s)))).filter(o=>o!==null)}async function uq(e){let t=new Set,n=[];for(let{loc:r,count:o}of e)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}t.has(i)||(t.add(i),n.push({key:i,locator:r,index:s}))}return n}async function Xm(e,t,n){switch(t.kind){case"element_id":return pq(e,t,n);case"selector":return fq(e,t);case"semantic":return mq(e,t)}}async function pq(e,t,n){let r=n.get(t.elementId);if(r===void 0)return{outcome:"not_found",query:t};if(r.selector!==void 0){let c=e.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=e.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:t};if(s===1)return{outcome:"resolved",locator:o};let i=await qm(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function fq(e,t){let n=e.locator(t.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:t};if(r===1)return{outcome:"resolved",locator:n};let o=await qm(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function mq(e,t){return t.role!==void 0?gq(e,t.text,t.role):hq(e,t.text,t)}async function gq(e,t,n){let r=e.getByRole(n,{name:t}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:t,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await qm(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:s}}async function hq(e,t,n){let r=e.getByRole("button",{name:t}),o=e.getByRole("link",{name:t}),s=e.getByLabel(t,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await uq(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let b=await mE(y.locator,y.index);if(b!==null){let S=`${b.role}:${b.label}:${h}`,k=0;for(let T=0;T<S.length;T++)k=k*31+S.charCodeAt(T)>>>0;f.push({...b,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:f}}var gE=m(()=>{"use strict"});async function zm(e,t,n,r){let o=e.url();if(o===n)return null;let s=ft(o,t);if(s.allowed)return null;try{await e.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var hE=m(()=>{"use strict";dn()});var Vm={};zo(Vm,{PlaywrightProvider:()=>Jm});function yE(e){switch(e.kind){case"semantic":return e.role!==void 0?`semantic('${e.text}', role='${e.role}')`:`semantic('${e.text}')`;case"element_id":return`element_id(${e.elementId})`;case"selector":return`selector(${e.selector})`}}var Jm,Ym=m(()=>{"use strict";cE();fE();gE();dn();hE();Bm();Jm=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new tl(t)}async open(t){let n=ft(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let{sessionId:r}=t,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(t.url,{timeout:t.timeoutMs??3e4,waitUntil:t.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await zm(o,this.config,t.url,()=>this.close({sessionId:r}));if(u!==null)return u}(t.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await nl(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;t.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await nl(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:t.includeHidden,maxElements:t.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=t.timeoutMs??3e4,a=await Xm(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${yE(t.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(t.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(t.value??"");break;case"press":await c.press(t.value??"");break;case"select":await c.selectOption(t.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await d()}catch(y){l=y}else l=h}let u=await zm(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(t.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await nl(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${t.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,g),l!==null)throw l;return f}async render(t){return this.launcher.renderHtml(t.url,{timeoutMs:t.timeoutMs??3e4,waitUntil:t.waitFor??"load",signal:t.signal,requestGuard:t.requestGuard})}async screenshot(t){let{sessionId:n}=t,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(t.target!==void 0){let d=await Xm(r,t.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${yE(t.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:t.fullPage??!1});let{path:i,bytes:a}=await Vr(n,s,"browser_screenshot"),c=0,l=0;if(t.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(t){throw new Error("browser_extract not implemented in Phase 1")}async close(t){await this.launcher.closeSession(t.sessionId),this.sessions.delete(t.sessionId)}describe(t){let n=this.sessions.get(t);if(n===void 0)return null;let r=this.launcher.getPage(t);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(t){let n=this.sessions.get(t);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(t,r),r}updateSessionFromObservation(t,n,r,o,s){t.knownElements=new Map(n.map(i=>[i.id,i])),t.currentUrl=r,t.currentTitle=o,t.lastAction=s,t.lastActionAt=new Date().toISOString()}async captureScreenshot(t,n,r){try{let o=await t.screenshot({fullPage:!1}),{path:s}=await Vr(n,o,r);return s}catch{return null}}}});var tr={};zo(tr,{__resetBrowserRegistryForTests:()=>vq,browserProviderActive:()=>wq,closeBrowserProvider:()=>Zm,getBrowserProvider:()=>bq,getLastRoutingDecision:()=>kq,peekBrowserProvider:()=>Sq});function bE(){Promise.resolve(Zm()).then(()=>{process.exit(130)})}function wE(){Promise.resolve(Zm()).then(()=>{process.exit(143)})}function SE(){Et=null}function yq(){rl||(process.on("SIGINT",bE),process.on("SIGTERM",wE),process.on("exit",SE),rl=!0)}function kE(){rl&&(process.removeListener("SIGINT",bE),process.removeListener("SIGTERM",wE),process.removeListener("exit",SE),rl=!1)}async function bq(e){return Et!==null?Et:(er!==null||(er=(async()=>{let t=Lm(e),n=e?.surface??(e?.env??{}).AGENT_SURFACE??w.AGENT_SURFACE,r=await X_({config:t,surface:n});Qm=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(oE(),rE)),i=r.availability.connection;o=new s(t,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Ym(),Vm));o=new s(t)}return yq(),Et=o,er=null,o})()),er)}async function Zm(){if(Et===null)return;let e=Et;Et=null,er=null,kE(),await e.shutdown()}function wq(){return Et!==null}function Sq(){return Et}function kq(){return Qm}function vq(){Et=null,er=null,Qm=null,kE()}var Et,er,rl,Qm,nr=m(()=>{"use strict";dn();z_();P();Et=null,er=null,rl=!1,Qm=null});async function vE(e,t){try{return await D_(e,t)}catch(n){return O("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function Rq(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(nr(),tr)),r=await n();try{return await r.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Ym(),Vm)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(dn(),Nm)),a=i(),c=new s(a);try{return await c.render({url:e,timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:t.requestGuard})}finally{await c.shutdown()}}throw o}}async function TE(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??Rq,o=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},s=null,i="",a=e,c=null,l=null;try{let u=await ln(n,e,{headers:Aq,signal:t.signal},o);c=u.status,a=u.url||e;let p=u.headers.get("content-type")??"";if(u.ok){if(xq.test(p))throw new Error(`web_scrape markdown mode received binary content (${p.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let f=await u.text();if(Eq.test(p)&&!_q.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await vE(f,a),t.signal.aborted)throw t.signal.reason??new Error("aborted")}}catch(u){if(t.signal.aborted||u instanceof Te||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=Mm({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await Vs(e,o);let u=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal,requestGuard:f=>Vs(f,o)});u.finalUrl!==e&&/^https?:\/\//i.test(u.finalUrl)&&await Vs(u.finalUrl,o);let p=await vE(u.html,u.finalUrl);if(t.signal.aborted)throw t.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=Mm({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(t.signal.aborted||u instanceof Te)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,g=new Error(`web_scrape could not retrieve ${e}: fetch failed (${f}) and render failed (${p}).`);throw g.cause=u,g}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${e} (HTTP ${c??"error"}).`)}var _q,Eq,xq,Aq,_E=m(()=>{"use strict";F_();Om();Qn();V();_q=/(text\/html|application\/xhtml\+xml)/i,Eq=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,xq=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,Aq={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/web_scrape",Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}});function Pq(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await t(Iq,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":e.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),Cq),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=ue(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function EE(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?Pq({apiKey:e.exaApiKey,fetchFn:e.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function xE(e,t){if(t.length===0)return`# Search results for "${e}"
274
274
 
275
275
  (no results)`;let n=[`# Search results for "${e}"`,""];return t.forEach((r,o)=>{n.push(`## ${o+1}. ${r.title}`),r.url&&n.push(r.url),r.description&&n.push(r.description),n.push("")}),n.join(`
276
276
  `).trimEnd()}var Iq,Cq,AE=m(()=>{"use strict";Je();Iq="https://api.exa.ai/search",Cq=10});function ol(e){if(e instanceof Error&&e.name==="TimeoutError")return"timeout";let t=e instanceof Error?e.message:String(e);return/Timeout\s+\d+\s*ms exceeded/i.test(t)?"timeout":void 0}var rr=m(()=>{"use strict";Gm()});function Nq(e){if(!e||typeof e!="object")return{error:"Invalid input: expected an object"};let t=e,n=t.mode??"markdown";if(n!=="markdown"&&n!=="raw"&&n!=="search")return{error:`Invalid input: mode must be one of "markdown", "raw", "search" (got ${JSON.stringify(n)})`};let r=n,o,s;if(r==="search"){if(typeof t.query!="string"||t.query.length===0)return{error:'Invalid input: search mode requires a non-empty "query" string'};s=t.query}else{if(typeof t.url!="string"||t.url.length===0)return{error:`Invalid input: ${r} mode requires a non-empty "url" string`};let c;try{c=new URL(t.url)}catch{return{error:`Invalid input: "${t.url}" is not a valid absolute URL`}}if(c.protocol!=="http:"&&c.protocol!=="https:")return{error:`Invalid input: protocol "${c.protocol}" not supported (http/https only)`};o=c.toString()}let i=Mq;if(t.timeout_ms!==void 0){if(typeof t.timeout_ms!="number"||!Number.isFinite(t.timeout_ms)||t.timeout_ms<=0)return{error:"Invalid input: timeout_ms must be a positive finite number"};i=Math.min(t.timeout_ms,Oq)}let a=Dq;if(t.max_bytes!==void 0){if(typeof t.max_bytes!="number"||!Number.isFinite(t.max_bytes)||t.max_bytes<=0)return{error:"Invalid input: max_bytes must be a positive finite number"};a=Math.min(t.max_bytes,Fq)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function eg(e,t){return Buffer.byteLength(e,"utf8")<=t?{content:e,truncated:!1}:{content:kt(e,t),truncated:!0}}function Uq(e={}){let t=e.fetchFn??globalThis.fetch,n=e.env??process.env,r=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{};return async(o,s)=>{if(typeof t!="function")return{content:"web_scrape unavailable: global fetch() is not present in this runtime (agent-afk requires Node 20+).",isError:!0};let i=Nq(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let u=s.reason;return{content:`web_scrape aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0}}let a=new AbortController,c=()=>{a.abort(s.reason)},l,d=()=>{let u=a.signal.reason;return u instanceof Error?u.message:String(u??"aborted")};try{if(s.addEventListener("abort",c,{once:!0}),l=setTimeout(()=>{a.abort(new Error(`web_scrape timeout after ${i.timeoutMs}ms`))},i.timeoutMs),i.url!==void 0){let p=await Yn(i.url,r);if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(!p.allowed)return{content:`web_scrape blocked: ${p.reason}`,isError:!0}}if(i.mode==="raw"){let p;try{let h={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};p=await ln(t,i.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:h instanceof Te?{content:`web_scrape blocked: ${h.message}`,isError:!0}:{content:`web_scrape network error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}if(!p.ok)return{content:`web_scrape HTTP ${p.status} ${p.statusText||""}`.trimEnd()+` for ${i.url}`,isError:!0};let f;try{f=await p.text()}catch(h){return{content:`web_scrape read error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}let g=eg(f,i.maxBytes);return{content:g.content,...g.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await TE(i.url,{fetchFn:t,renderFn:e.renderFn,timeoutMs:i.timeoutMs,signal:a.signal,...e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{}});if(p.markdown.trim().length===0)return{content:`web_scrape extracted no readable content from ${i.url}.`,isError:!0};let f=eg(L_(p.markdown,p.advisory),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(p instanceof Te)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),g=Ue(p)&&!Km(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Ys()}\`)`:"";return{content:`web_scrape markdown error: ${f}${g}`,isError:!0}}let u=EE({exaApiKey:n.EXA_API_KEY,fetchFn:t});if("error"in u)return{content:u.error,isError:!0};try{let p=await u.search(i.query,{limit:Lq,timeoutMs:i.timeoutMs,signal:a.signal}),f=eg(xE(i.query,p),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:{content:`web_scrape search error (${u.name}): ${p instanceof Error?p.message:String(p)}`,isError:!0}}}finally{l!==void 0&&clearTimeout(l),s.removeEventListener("abort",c)}}}var Mq,Oq,Dq,Fq,Lq,RE,IE=m(()=>{"use strict";_E();AE();Qn();vt();Om();rr();Mq=3e4,Oq=12e4,Dq=1e5,Fq=1e6,Lq=10;RE=Uq()});function jq(e){return $q.has(e)?"low":e==="DELETE"?"high":"medium"}function Hq(e){return Bq.has(e)}function Gq(e){let t={};return e.forEach((n,r)=>{let o=r.toLowerCase();Kq.has(o)||Wq.some(s=>o.startsWith(s))||(t[r]=n)}),t}function qq(e,t){if(e==null)return{serialized:void 0,inferredContentType:void 0};let n=Object.keys(t).some(o=>o.toLowerCase()==="content-type");return typeof e=="string"?{serialized:e,inferredContentType:n?void 0:"text/plain"}:{serialized:JSON.stringify(e),inferredContentType:n?void 0:"application/json"}}function Xq(e,t,n){let r=Buffer.byteLength(e,"utf8"),o=e,s=!1;if(r>n&&(o=kt(e,n),s=!0),!s&&/application\/json/i.test(t))try{return{body:JSON.parse(o),truncated:!1}}catch{}return{body:o,truncated:s}}async function ME(e){let{url:t,method:n,signal:r,domainCheck:o,recordEffect:s}=e,i=Math.min(e.maxResponseBytes??tg,ng),a={...e.headers},c=e.fetchFn??globalThis.fetch,l=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},d=jq(n);if(o!==void 0){let v=o(t);if(!v.allowed)throw Object.assign(new Error(`web_request blocked by domain policy: ${v.reason}`),{name:"DomainPolicyError"})}let u=await Yn(t,l);if(!u.allowed)throw new Te(u.reason);let{serialized:p,inferredContentType:f}=qq(e.body,a);f!==void 0&&(a["content-type"]=f);let g={method:n,headers:Object.keys(a).length>0?a:void 0,body:p,signal:r},y=Hq(n)?{retries:2,baseDelayMs:300,maxDelayMs:5e3}:{retries:0},b=Date.now(),S;try{S=await ln(c,t,g,{...l,retry:y})}catch(v){throw v instanceof Te,v}let k=Date.now()-b,T=S.headers.get("content-type")??"",E;try{let v=S.body?.getReader();if(!v)E="";else{let A=[],_=0,C=i*2;for(;;){let{done:N,value:D}=await v.read();if(N||!D)break;if(A.push(D),_+=D.byteLength,_>=C){await v.cancel();break}}E=new TextDecoder().decode(Buffer.concat(A,_))}}catch{E=""}let{body:R,truncated:x}=Xq(E,T,i),F=Gq(S.headers);return s!==void 0&&Promise.resolve(s({url:t,method:n,status:S.status,risk:d,timing_ms:k})).catch(()=>{}),{status:S.status,headers:F,body:R,truncated:x,timing_ms:k,risk:d}}function OE(e){if(typeof e!="string"||e.trim().length===0)return{error:"method must be a non-empty string (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)"};let t=e.trim().toUpperCase(),n=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];return n.includes(t)?t:{error:`method "${e}" is not supported \u2014 must be one of: ${n.join(", ")}`}}var CE,PE,tg,ng,$q,Bq,Wq,Kq,DE=m(()=>{"use strict";Qn();vt();CE=3e4,PE=12e4,tg=1e5,ng=1e6,$q=new Set(["GET","HEAD","OPTIONS"]),Bq=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]);Wq=["set-cookie","x-"],Kq=new Set(["server","via","age","vary","authorization","www-authenticate"])});function zq(e){if(!e||typeof e!="object")return{error:"Invalid input: expected an object"};let t=e;if(typeof t.url!="string"||t.url.length===0)return{error:'Invalid input: "url" must be a non-empty string'};let n;try{n=new URL(t.url)}catch{return{error:`Invalid input: "${t.url}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{error:`Invalid input: protocol "${n.protocol}" not supported (http/https only)`};n.username="",n.password="";let r=n.toString(),o=OE(t.method);if(typeof o=="object"&&"error"in o)return{error:`Invalid input: ${o.error}`};let s=o,i;if(t.body!==void 0&&t.body!==null){if(typeof t.body!="string"&&typeof t.body!="object")return{error:'Invalid input: "body" must be a string, object, or array'};i=t.body}let a={};if(t.headers!==void 0){if(typeof t.headers!="object"||t.headers===null||Array.isArray(t.headers))return{error:'Invalid input: "headers" must be a string-keyed object'};let u=t.headers;for(let[p,f]of Object.entries(u)){if(typeof f!="string")return{error:`Invalid input: header value for "${p}" must be a string`};a[p]=f}}let c=CE;if(t.timeout_ms!==void 0){if(typeof t.timeout_ms!="number"||!Number.isFinite(t.timeout_ms)||t.timeout_ms<=0)return{error:'Invalid input: "timeout_ms" must be a positive finite number'};c=Math.min(t.timeout_ms,PE)}let l=tg;if(t.max_response_bytes!==void 0){if(typeof t.max_response_bytes!="number"||!Number.isFinite(t.max_response_bytes)||t.max_response_bytes<=0)return{error:'Invalid input: "max_response_bytes" must be a positive finite number'};l=Math.min(t.max_response_bytes,ng)}let d;if(t.credential!==void 0){if(typeof t.credential!="string"||t.credential.length===0)return{error:'Invalid input: "credential" must be a non-empty string (an env var name)'};d=t.credential}return{url:r,method:s,body:i,headers:a,timeoutMs:c,maxResponseBytes:l,credential:d}}function Jq(e={}){let t=e.fetchFn??globalThis.fetch,n=e.env??process.env;async function r(){if(e.domainCheck!==void 0)return e.domainCheck;try{let{loadBrowserConfig:o,enforceDomainPolicy:s}=await Promise.resolve().then(()=>(dn(),Nm)),i=o();return a=>s(a,i)}catch{return}}return async(o,s)=>{if(typeof t!="function")return{content:"web_request unavailable: global fetch() is not present (agent-afk requires Node 20+).",isError:!0};let i=zq(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let p=s.reason;return{content:`web_request aborted: ${p instanceof Error?p.message:String(p??"aborted")}`,isError:!0}}let a={...i.headers};if(i.credential!==void 0){let p=n[i.credential];if(p===void 0||p.trim().length===0)return{content:`web_request credential error: environment variable "${i.credential}" is not set. Set it in afk.env or export it in the shell before starting AFK.`,isError:!0};if(Object.keys(a).some(g=>g.toLowerCase()==="authorization"))return{content:'web_request credential error: both "credential" and an explicit Authorization header were provided. Use one or the other.',isError:!0};a.Authorization=`Bearer ${p}`}let c=new AbortController,l=()=>c.abort(s.reason),d,u=()=>{let p=c.signal.reason;return p instanceof Error?p.message:String(p??"aborted")};try{s.addEventListener("abort",l,{once:!0}),d=setTimeout(()=>{c.abort(new Error(`web_request timeout after ${i.timeoutMs}ms`))},i.timeoutMs);let p=await r(),f={url:i.url,method:i.method,body:i.body,headers:a,maxResponseBytes:i.maxResponseBytes,signal:c.signal,fetchFn:t,lookupFn:e.lookupFn,domainCheck:p,recordEffect:e.recordEffect},g;try{g=await ME(f)}catch(S){if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};if(S instanceof Te)return{content:`web_request blocked: ${S.message}`,isError:!0};let k=S instanceof Error&&S.name==="DomainPolicyError"?"blocked":"network error",T=S instanceof Error?S.message:String(S);return{content:`web_request ${k}: ${T}`,isError:!0}}if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};let h=g.body;if(typeof h=="string")h=bt(h);else if(typeof h=="object"&&h!==null){let S=bt(JSON.stringify(h));try{h=JSON.parse(S)}catch{h=S}}let y={status:g.status,headers:g.headers,body:h,timing_ms:g.timing_ms,...g.truncated?{truncated:!0}:{}};return{content:JSON.stringify(y,null,2),...g.truncated?{truncated:!0}:{}}}finally{d!==void 0&&clearTimeout(d),s.removeEventListener("abort",l)}}}var FE,LE=m(()=>{"use strict";DE();Qn();$n();FE=Jq()});import{existsSync as UE,mkdirSync as Vq,readFileSync as Yq,renameSync as Qq,unlinkSync as Zq,writeFileSync as e2}from"node:fs";import{dirname as NE,join as t2}from"node:path";import{randomBytes as n2}from"node:crypto";function or(e){let t=e??_p();if(!UE(t))return[];try{let n=Yq(t,"utf-8");return JSON.parse(n)}catch(n){let r=n instanceof Error?n.message:String(n);return console.error(`[schedule-store] failed to parse ${t}: ${r}`),[]}}function Qs(e,t){let n=t??_p();Vq(NE(n),{recursive:!0});let r=t2(NE(n),`.schedules.json.${process.pid}.${n2(4).toString("hex")}.tmp`),o=JSON.stringify(e,null,2);try{e2(r,o,"utf-8"),Qq(r,n)}catch(s){try{UE(r)&&Zq(r)}catch{}throw s}}function $E(e,t){let n=or(t),r=n.map(c=>c.id),o=r2(e.name),s=o2(o,r),i=new Date().toISOString(),a={...e,notifyOn:e.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),Qs(n,t),a}function BE(e,t){let n=or(t),r=n.length,o=n.filter(s=>s.id!==e);return o.length===r?!1:(Qs(o,t),!0)}function jE(e,t){return or(t).find(n=>n.id===e)}function r2(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function o2(e,t){if(!t.includes(e))return e;let n=2;for(;t.includes(`${e}-${n}`);)n+=1;return`${e}-${n}`}function HE(e){return{taskId:e.id,command:e.command,trigger:e.trigger??"cron",...e.executor!==void 0?{executor:e.executor}:{},...e.cron!==void 0?{cronExpression:e.cron}:{},...e.notifyOn!==void 0?{notifyOn:e.notifyOn}:{},...e.notifyChat!==void 0?{notifyChat:e.notifyChat}:{}}}var WE=m(()=>{"use strict";M()});import{existsSync as s2,readFileSync as i2}from"node:fs";import{join as a2}from"node:path";async function Yr(e,t,n){let r,o;try{let s=a2(Aw("default"),"port");if(!s2(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=i2(s,"utf-8").trim(),a=c2(i);if(!a)return{synced:!1,detail:"daemon-not-detected (invalid port file)"};({host:r,port:o}=a)}catch{return{synced:!1,detail:"daemon-not-detected (unreadable port file)"}}try{let s=r.includes(":")?`[${r}]`:r,i=await fetch(`http://${s}:${o}${t}`,{method:e,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return i.ok?{synced:!0,detail:"synced"}:e==="POST"&&i.status===409?{synced:!0,detail:"already-registered"}:e==="DELETE"&&i.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${i.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}function c2(e){let t=parseInt(e,10);if(String(t)===e&&!Number.isNaN(t))return t<1||t>65535?null:{host:"localhost",port:t};let n=e.lastIndexOf(":");if(n<1)return null;let r=e.slice(0,n),o=e.slice(n+1);if(!/^\d+$/.test(o))return null;let s=parseInt(o,10);return Number.isNaN(s)||s<1||s>65535||/^:+$/.test(r)?null:{host:r.startsWith("[")&&r.endsWith("]")?r.slice(1,-1):r,port:s}}var rg,KE=m(()=>{"use strict";M();rg="Change saved to schedules.json, but a running daemon (if any) did not pick it up \u2014 it will apply on the next daemon (re)start."});import{existsSync as l2}from"node:fs";import{readFile as d2}from"node:fs/promises";var GE,qE,XE,zE,JE=m(()=>{"use strict";WE();M();KE();GE=async(e,t)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected object",isError:!0};let n=e;if(typeof n.name!="string"||!n.name)return{content:"Invalid input: name required",isError:!0};if(typeof n.command!="string"||!n.command)return{content:"Invalid input: command required",isError:!0};if(typeof n.cron!="string"||!n.cron)return{content:"Invalid input: cron required",isError:!0};let r=n.cron.trim().split(/\s+/);if(r.length!==5&&r.length!==6)return{content:"Invalid input: cron must be a 5 or 6-field expression",isError:!0};let o=n.notifyChat;if(o!==void 0&&typeof o!="number"&&typeof o!="string")return{content:"Invalid input: notifyChat must be a number (chat id) or string (chat id or alias name)",isError:!0};let s=n.executor;if(s!==void 0&&s!=="agent"&&s!=="shell")return{content:'Invalid input: executor must be "agent" or "shell"',isError:!0};let i=$E({name:n.name,command:n.command,cron:n.cron,...s!==void 0?{executor:s}:{},trigger:n.trigger??"cron",notifyOn:n.notifyOn,...o!==void 0?{notifyChat:o}:{},enabled:typeof n.enabled=="boolean"?n.enabled:!0}),a=i.enabled?await Yr("POST","/tasks",{taskId:i.id,command:i.command,cron:i.cron,...i.executor!==void 0?{executor:i.executor}:{},trigger:i.trigger,notifyOn:i.notifyOn,...i.notifyChat!==void 0?{notifyChat:i.notifyChat}:{}}):await Yr("DELETE",`/tasks/${i.id}`);return{content:JSON.stringify({id:i.id,name:i.name,cron:i.cron,enabled:i.enabled,daemonSynced:a.synced,syncDetail:a.detail,...a.synced?{}:{syncNote:rg}})}},qE=async(e,t)=>{let n=or();return{content:JSON.stringify(n.map(r=>({id:r.id,name:r.name,cron:r.cron,executor:r.executor??"agent",trigger:r.trigger,enabled:r.enabled,notifyOn:r.notifyOn})))}},XE=async(e,t)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected object",isError:!0};let n=e;if(typeof n.taskId!="string"||!n.taskId)return{content:"Invalid input: taskId required",isError:!0};let r=n.taskId,o=typeof n.limit=="number"?Math.min(Math.max(1,n.limit),50):10,s=Ea();if(!l2(s))return{content:JSON.stringify([])};let i;try{let l=await d2(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
package/dist/telegram.mjs CHANGED
@@ -395,7 +395,7 @@ ${o}`,paths:[e,n]}:o!==null?s={content:o,paths:[n]}:r!==null?s={content:r,paths:
395
395
 
396
396
  ${e}`}var w4,fy=h(()=>{"use strict";w4=new Set(["script","style","noscript","template","svg"])});function v4(t,e){return new Promise((n,r)=>{if(e?.aborted){r(e.reason??new Error("aborted"));return}let o=()=>{clearTimeout(s),r(e?.reason??new Error("aborted"))},s=setTimeout(()=>{e?.removeEventListener("abort",o),n()},t);e?.addEventListener("abort",o,{once:!0})})}function xR(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function T4(t,e){let n=t.headers.get("retry-after");if(n===null)return null;let r=Number(n.trim());return!Number.isFinite(r)||r<0?null:Math.min(r*1e3,e)}async function AR(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??v4,c=n.signal??void 0,l;for(let d=0;d<=o;d++){if(c?.aborted)throw c.reason??new Error("aborted");try{let u=await t(e,n);if(!k4.has(u.status)||d===o)return u;let p=T4(u,i)??xR(d,s,i);O("[web/retryFetch] retrying",{url:e,attempt:d,status:u.status,waitMs:p}),await u.body?.cancel().catch(()=>{}),await a(p,c)}catch(u){if(c?.aborted||(l=u,d===o))throw u;let p=xR(d,s,i);O("[web/retryFetch] retrying after error",{url:e,attempt:d,waitMs:p}),await a(p,c)}}throw l??new Error("retryFetch: exhausted without a result")}var k4,RR=h(()=>{"use strict";ne();k4=new Set([429,502,503,504])});import{BlockList as E4,isIP as gy}from"node:net";import{lookup as _4}from"node:dns/promises";import{Agent as x4}from"undici";function PR(){let t=k.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function P4(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function my(t){let e=gy(t);return e===0?!1:I4.check(t,e===4?"ipv4":"ipv6")}async function CR(t){return _4(t,{all:!0,verbatim:!0})}async function Nr(t,e={}){if(e.allowPrivateHosts??PR())return{allowed:!0};let n;try{n=new URL(t)}catch{return{allowed:!1,reason:`"${t}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{allowed:!1,reason:`protocol "${n.protocol}" not supported (http/https only)`};let r=P4(n.hostname),o=(a,c)=>`refusing to fetch ${c} \u2014 internal/private address ${a} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`;if(gy(r)!==0)return my(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??CR,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(my(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function ia(t,e={}){let n=await Nr(t,e);if(!n.allowed)throw new Pe(n.reason)}async function Bn(t,e,n={},r={}){let o={...r.lookupFn!==void 0?{lookupFn:r.lookupFn}:{},...r.allowPrivateHosts!==void 0?{allowPrivateHosts:r.allowPrivateHosts}:{}},s=e;for(let i=0;i<=IR;i++){await ia(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??PR())?{dispatcher:C4}:{}},c=await AR(t,s,a,r.retry??{});if(!M4.has(c.status))return c;let l=c.headers.get("location");if(l===null||l.trim()==="")return c;let d;try{d=new URL(l,c.url||s).toString()}catch{return c}await c.body?.cancel().catch(()=>{}),s=d}throw new Pe(`too many redirects (>${IR}) starting from ${e}`)}var A4,R4,I4,Pe,C4,IR,M4,$r=h(()=>{"use strict";F();RR();A4=[["0.0.0.0",8],["10.0.0.0",8],["100.64.0.0",10],["127.0.0.0",8],["169.254.0.0",16],["172.16.0.0",12],["192.168.0.0",16]],R4=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],I4=(()=>{let t=new E4;for(let[e,n]of A4)t.addSubnet(e,n,"ipv4");for(let[e,n]of R4)t.addSubnet(e,n,"ipv6");return t})(),Pe=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};C4=new x4({connect:{lookup(t,e,n){CR(t).then(r=>{let o=r.find(i=>my(i.address));if(o!==void 0){n(new Pe(`refusing to connect to ${t} (resolved) \u2014 internal/private address ${o.address} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`),"",0);return}let s=r[0];if(s===void 0){n(new Error(`DNS lookup returned no addresses for ${t}`),"",0);return}n(null,s.address,gy(s.address))},r=>n(r,"",0))}}});IR=20,M4=new Set([301,302,303,307,308])});var yy={};yo(yy,{enforceDomainPolicy:()=>It,loadBrowserConfig:()=>hy});import{readFileSync as O4}from"node:fs";import{join as D4}from"path";function F4(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function MR(t,e){return F4(e).test(t)}function $4(t,e){if(t!==void 0){let n=t.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(e!==void 0){if(L4.has(e))return!0;if(N4.has(e))return!1}return!1}function OR(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function U4(t){if(t===void 0||t==="")return"auto";if(t==="playwright"||t==="agent-browser"||t==="auto")return t;throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${t}`)}function DR(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Ym(e),e}function B4(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function j4(t){try{return O4(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function H4(t,e){let n={...t};if(typeof e.headless=="boolean"&&(n.headless=e.headless),Array.isArray(e.allowedDomains)&&(n.allowedDomains=e.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(e.blockedDomains)&&(n.blockedDomains=e.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof e.domSnapshots=="boolean"&&(n.domSnapshots=e.domSnapshots),e.backend==="playwright"||e.backend==="agent-browser"||e.backend==="auto")n.backend=e.backend;else if(e.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: must be "playwright", "agent-browser", or "auto", got: ${String(e.backend)}`);return typeof e.defaultProfile=="string"&&(n.defaultProfile=DR(e.defaultProfile)),n}function hy(t){let e=t?.env??k,n=t?.readFileSync??j4,r=t?.surface??e.AGENT_SURFACE,o=$4(e.AFK_BROWSER_HEADLESS,r),s=OR(e.AFK_BROWSER_ALLOWED_DOMAINS),i=OR(e.AFK_BROWSER_BLOCKED_DOMAINS),a=B4(e.AFK_BROWSER_DOM_SNAPSHOTS),c=U4(e.AFK_BROWSER_BACKEND),l=DR(e.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null,defaultProfile:l},u=e.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():D4(sn(),"browser.json"),f=n(p);if(f===void 0)return d;let m;try{m=JSON.parse(f)}catch(y){throw new Error(`Failed to parse browser config at ${p}: ${String(y)}`)}if(typeof m!="object"||m===null||Array.isArray(m))throw new Error(`Browser config at ${p} must be a JSON object`);let g=H4(d,m);return g.configPath=p,g}function It(t,e){let n;try{n=new URL(t).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${t}`}}for(let r of e.blockedDomains)if(MR(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>MR(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var L4,N4,jn=h(()=>{"use strict";F();N();L4=new Set(["daemon","subagent","telegram","afk"]),N4=new Set(["repl","interactive","cli"])});import{readFileSync as W4}from"node:fs";import{join as K4}from"node:path";import{homedir as G4}from"node:os";function X4(t){let e=t??q4,n;try{n=W4(e,"utf8")}catch{return null}let r;try{r=JSON.parse(n)}catch{return null}if(typeof r!="object"||r===null||Array.isArray(r))return null;let o=r;if(typeof o.url!="string"||typeof o.token!="string"||typeof o.pid!="number")return null;let s;try{s=new URL(o.url)}catch{return null}let{hostname:i,protocol:a}=s;if(!(i==="127.0.0.1"||i==="localhost"||i==="::1")||a!=="http:")throw new Error(`Agent Browser connection file contains an untrusted URL: ${o.url}. Only http://127.0.0.1 or http://localhost is permitted.`);return{url:o.url,token:o.token,pid:o.pid,version:typeof o.version=="string"?o.version:"unknown"}}function z4(t){try{return process.kill(t,0),!0}catch{return!1}}async function J4(t,e,n=2e3){try{let r=new AbortController,o=setTimeout(()=>r.abort(),n),s=await fetch(`${t}/health`,{method:"GET",headers:{Authorization:`Bearer ${e}`,Host:"127.0.0.1:8833"},signal:r.signal});return clearTimeout(o),s.ok}catch{return!1}}async function by(t){let e=X4(t);return e===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:z4(e.pid)?await J4(e.url,e.token)?{available:!0,connection:e,reason:null}:{available:!1,connection:e,reason:`health probe failed at ${e.url}`}:{available:!1,connection:e,reason:`stale connection file: PID ${e.pid} not alive`}}var q4,FR=h(()=>{"use strict";q4=K4(G4(),".config","agent-browser","connection.json")});async function LR(t){let{config:e,surface:n}=t;if(e.backend==="playwright")return{backend:"playwright",reason:"explicit config: backend=playwright",probeMs:0,availability:null};if(e.backend==="agent-browser"){let i=Date.now(),a=await by(),c=Date.now()-i;if(!a.available)throw new Error(`AFK_BROWSER_BACKEND=agent-browser but Agent Browser is not available: ${a.reason}`);return{backend:"agent-browser",reason:"explicit config: backend=agent-browser",probeMs:c,availability:a}}if(n&&V4.has(n))return{backend:"playwright",reason:`auto: surface "${n}" excluded from Agent Browser`,probeMs:0,availability:null};if(e.headless)return{backend:"playwright",reason:"auto: headless mode requires Playwright",probeMs:0,availability:null};let r=Date.now(),o=await by(),s=Date.now()-r;return o.available?{backend:"agent-browser",reason:"auto: Agent Browser available and preferred",probeMs:s,availability:o}:{backend:"playwright",reason:`auto: Agent Browser unavailable (${o.reason})`,probeMs:s,availability:o}}var V4,NR=h(()=>{"use strict";FR();V4=new Set(["daemon","subagent"])});import{createHash as Y4}from"crypto";function $R(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&Q4.test(t.label))}function UR(t){return Y4("sha256").update(t,"utf8").digest("hex").slice(0,8)}function BR(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var Q4,jd=h(()=>{"use strict";Q4=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as Z4}from"crypto";import{mkdir as eY,stat as tY,writeFile as nY}from"fs/promises";import{join as wy}from"path";import{gzip as rY}from"zlib";import{promisify as oY}from"util";function sY(t){return wy(at(t),"browser")}function iY(t){return wy(sY(t),"screenshots")}function aY(){return new Date().toISOString().replace(/[:.]/g,"-")}function cY(){return Z4(3).toString("hex")}async function Qo(t,e,n){if(e.length>jR)throw new Error(`writeScreenshotSidecar: buffer exceeds ${jR} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=iY(t);await eY(r,{recursive:!0});let o=`${aY()}-${cY()}-${n}.png`,s=wy(r,o);await nY(s,e);let{size:i}=await tY(s);return{path:s,bytes:i}}var _Se,jR,Sy=h(()=>{"use strict";N();jd();_Se=oY(rY);jR=5*1024*1024});var Hd,HR=h(()=>{"use strict";ne();Hd=class{baseUrl;token;constructor(e){this.baseUrl=e.url,this.token=e.token}async call(e,n,r=3e4){let o={version:1,method:e,params:n},s=new AbortController,i=setTimeout(()=>s.abort(),r);try{let a=await fetch(`${this.baseUrl}/agent`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.token}`,Host:new URL(this.baseUrl).host},body:JSON.stringify(o),signal:s.signal});if(!a.ok){let l=await a.text().catch(()=>"");throw new Error(`Agent Browser ${e} failed (HTTP ${a.status}): ${l}`)}let c=await a.json();if(c.ok===!1){let l=c.error,d=l?.code??"UNKNOWN",u=l?.message??JSON.stringify(c);throw new Error(`Agent Browser ${e} failed: [${String(d)}] ${String(u)}`)}return c.result}finally{clearTimeout(i)}}async listTabs(){return this.call("tabs.list",null)}async openTab(e){return{tabId:(await this.call("tabs.open",{url:e},6e4)).id}}async closeTab(e){await this.call("page.eval",{id:e,script:"window.close()"}).catch(n=>{O("[browser/agent-browser] closeTab window.close() failed (tab leak expected)",{tabId:e,err:n})})}async read(e,n){return this.call("page.read",{id:e,mode:n?.mode??"main",...n?.query?{query:n.query}:{},...n?.budget?{budget:n.budget}:{}})}async inspect(e,n){return this.call("page.inspect",{id:e,mode:n?.mode??"interactive",...n?.query?{query:n.query}:{},...n?.limit?{limit:n.limit}:{}})}async click(e,n){await this.call("page.click",{id:e,elementId:n})}async fill(e,n,r){await this.call("page.fill",{id:e,elementId:n,value:r})}async press(e,n,r){await this.call("page.press",{id:e,key:n,...r?{elementId:r}:{}})}async select(e,n,r){await this.call("page.select",{id:e,elementId:n,value:r})}async waitFor(e,n,r){await this.call("page.wait",{id:e,condition:n,...r?.value?{value:r.value}:{},...r?.timeout?{timeout:r.timeout}:{}},(r?.timeout??3e4)+5e3)}async evalScript(e,n){return this.call("page.eval",{id:e,script:n})}async screenshot(e){return this.call("page.screenshot",{id:e})}}});function ky(t){return{id:t.id,role:t.role,label:t.label,kind:t.kind,value:t.value,state:{disabled:t.disabled,...t.checked!==void 0?{checked:t.checked}:{},...t.selected!==void 0?{selected:t.selected}:{},...t.expanded!==void 0?{expanded:t.expanded}:{}},bbox:t.bbox,...t.selector?{selector:t.selector}:{}}}function WR(t,e){switch(e.kind){case"element_id":if(t.has(e.elementId))return e.elementId;throw new Error(`Element ${e.elementId} not found in current observation. Call browser_observe to refresh.`);case"selector":return null;case"semantic":return null}}async function vy(t,e,n,r,o,s){switch(n){case"click":await t.click(e,r);break;case"fill":if(o===void 0)throw new Error("fill requires a value");await t.fill(e,r,o);break;case"press":if(o===void 0)throw new Error("press requires a value (key combo)");await t.press(e,o,r);break;case"select":if(o===void 0)throw new Error("select requires a value");await t.select(e,r,o);break;case"hover":throw new Error("hover is not supported by Agent Browser; use element_id from a prior observation to target clicks instead");case"scroll_to":{let i=r.replace(/\\/g,"\\\\").replace(/"/g,'\\"');await t.evalScript(e,`document.querySelector('[data-element-id="${i}"]')?.scrollIntoView({behavior:'smooth',block:'center'})`);break}case"wait_for":await t.waitFor(e,"element",{value:r,timeout:s??1e4});break;default:throw new Error(`Unknown action: ${n}`)}}async function KR(t,e){if(e.target.kind!=="semantic")throw new Error("resolveSemanticAndAct called with non-semantic target");let{elements:n}=await t.client.inspect(t.tabId,{mode:"interactive",query:e.target.text,limit:10}),r=n;if(e.target.role){let c=e.target.role.toLowerCase();r=n.filter(l=>l.role.toLowerCase()===c)}if(r.length===0)throw new Error(`No element found matching semantic target: text="${e.target.text}"`+(e.target.role?`, role="${e.target.role}"`:""));if(r.length>1)return{outcome:"ambiguous_target",query:{text:e.target.text,...e.target.role?{role:e.target.role}:{}},candidates:r.slice(0,5).map(ky)};let s=r[0].id;await vy(t.client,t.tabId,e.action,s,e.value,e.timeoutMs);let i=await t.client.read(t.tabId,{mode:"main"}),a=It(i.url,t.config);return a.allowed?{elementId:s}:{outcome:"blocked_by_policy",url:i.url,reason:`action navigated to blocked domain: ${a.reason}`}}var GR=h(()=>{"use strict";jn()});var qR={};yo(qR,{AgentBrowserProvider:()=>Ty});var Ty,XR=h(()=>{"use strict";jn();Sy();HR();GR();Ty=class{name="agent-browser";config;client;sessions=new Map;constructor(e,n){this.config=e,this.client=new Hd(n)}async open(e){let n=It(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let r=this.sessions.get(e.sessionId);if(r)await this.client.evalScript(r.tabId,`window.location.href = ${JSON.stringify(e.url)}`),await this.client.waitFor(r.tabId,"load",{timeout:e.timeoutMs??3e4});else{let{tabId:i}=await this.client.openTab(e.url);await this.client.waitFor(i,"load",{timeout:e.timeoutMs??3e4}),r={tabId:i,observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null},this.sessions.set(e.sessionId,r)}let o=await this.client.read(r.tabId,{mode:"main"}),s=It(o.url,this.config);return s.allowed?this.buildObservation(r,e.sessionId,e.screenshot,void 0,"browser_open"):(await this.client.evalScript(r.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`redirected to blocked domain: ${s.reason}`})}async observe(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);return this.buildObservation(n,e.sessionId,e.screenshot,e.maxElements,"browser_observe")}async act(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);let r=WR(n.knownElements,e.target);if(r===null){if(e.target.kind==="semantic"){let i=await KR({client:this.client,config:this.config,tabId:n.tabId},e);return"outcome"in i?i:(n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString(),this.buildObservation(n,e.sessionId,e.screenshot,void 0,"browser_act"))}throw e.target.kind==="selector"?new Error("selector targets are not supported by Agent Browser; use element_id or semantic targets"):new Error(`Cannot resolve target: ${JSON.stringify(e.target)}`)}await vy(this.client,n.tabId,e.action,r,e.value,e.timeoutMs),n.lastAction=`browser_act:${e.action}`,n.lastActionAt=new Date().toISOString();let o=await this.client.read(n.tabId,{mode:"main"}),s=It(o.url,this.config);return s.allowed?this.buildObservation(n,e.sessionId,e.screenshot,void 0,"browser_act"):(await this.client.evalScript(n.tabId,"window.location.href = 'about:blank'").catch(()=>{}),{outcome:"blocked_by_policy",url:o.url,reason:`action navigated to blocked domain: ${s.reason}`})}async render(e){throw new Error("AgentBrowserProvider does not support render(). Use PlaywrightProvider for one-shot content fetches.")}async screenshot(e){let n=this.sessions.get(e.sessionId);if(!n)throw new Error(`No Agent Browser tab open for session ${e.sessionId}. Call browser_open first.`);if(e.target!==void 0||e.fullPage)throw new Error("Agent Browser does not support element or full-page screenshots; omit target and fullPage.");let r=await this.client.screenshot(n.tabId),o=Buffer.from(r.data,"base64"),s=o.length>=24?o.readUInt32BE(16):0,i=o.length>=24?o.readUInt32BE(20):0;return{path:(await Qo(e.sessionId,o,"browser_screenshot")).path,bytes:o.length,width:s,height:i,dataBase64:r.data,mediaType:"image/png"}}async extract(e){throw new Error("AgentBrowserProvider does not support extract() yet.")}async close(e){let n=this.sessions.get(e.sessionId);if(n){try{await this.client.closeTab(n.tabId)}catch{}this.sessions.delete(e.sessionId)}}describe(e){let n=this.sessions.get(e);return n?{active:!0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:1}:null}async shutdown(){let e=Array.from(this.sessions.entries()).map(async([,n])=>{try{await this.client.closeTab(n.tabId)}catch{}});await Promise.all(e),this.sessions.clear()}async buildObservation(e,n,r,o,s="browser_open"){let[i,a]=await Promise.all([this.client.read(e.tabId,{mode:"main",budget:4e3}),this.client.inspect(e.tabId,{mode:"interactive",limit:o??80})]),c=a.elements.map(ky),l=o??80,d=c.slice(0,l);e.observationCounter+=1,e.knownElements=new Map(d.map(g=>[g.id,g])),e.currentUrl=i.url,e.currentTitle=i.title;let u=[];c.length>l&&u.push(`page has ${c.length} interactive elements; showing first ${l}`);let p=null;if(r)try{let g=await this.client.screenshot(e.tabId),y=Buffer.from(g.data,"base64");p=(await Qo(n,y,s)).path}catch{u.push("screenshot capture failed")}let f=`obs_${e.observationCounter.toString(36)}`,m={httpStatus:null,loadingState:"idle",hasDialog:!1,consoleErrors:0};return{observationId:f,url:i.url,title:i.title,textSummary:i.content.slice(0,4e3),interactive:d,status:m,warnings:u,screenshotPath:p,capturedAt:new Date().toISOString()}}}});import{existsSync as lY,readFileSync as dY}from"node:fs";import{createRequire as uY}from"node:module";import{dirname as pY,join as fY}from"node:path";function VR(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<gY&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function Ve(t){let e=VR(t);return JR.some(n=>e.includes(n))}function hY(){try{let e=uY(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(dY(e,"utf8"));if(typeof n!="object"||n===null)return;let r=n.bin,o=typeof r=="string"?r:typeof r=="object"&&r!==null?r.playwright:void 0;if(typeof o!="string"||o.length===0)return;let s=fY(pY(e),o);return lY(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function aa(){return zR??=hY()??mY,zR}function Ey(t){return t.includes("install chromium")}function gt(t,e){let n=VR(t),r=e?.latched===!0?` ${yY}`:"";if(n.includes("Executable doesn't exist")){let o="";return e?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":e?.headless===!1&&(o=" This launch was headed, which needs the full `chromium-*` build \u2014 the headless shell alone does not satisfy it."),`browser tools require the Playwright chromium binary. Install via: ${aa()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${aa()}). Or pick a different tool.${r}`}function Wd(t,e,n=!1){if(!Ve(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
397
397
 
398
- ${gt(t,{headless:e,latched:n})}`,{cause:t})}var JR,mY,gY,zR,yY,_y=h(()=>{"use strict";JR=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],mY="pnpm exec playwright install chromium",gY=4;yY="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import Ur from"node:fs";import Kd from"node:path";import{randomBytes as bY}from"node:crypto";function wY(){try{return"5.222.1"}catch{}try{let t=Kd.resolve(import.meta.dirname,"../../../package.json"),e=Ur.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var SY,Gd,YR=h(()=>{"use strict";_y();N();ne();SY=wY(),Gd=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let e;try{({chromium:e}=await import("playwright"))}catch(n){let r=Wd(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await e.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Wd(n,this.config.headless,!0);throw this.latchLaunchFailure(r),r}finally{this.launchPromise=void 0}})(),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${SY}`}}loadStorageState(e){let n=Qm(e);try{if(!Ur.existsSync(n))return;let r=JSON.parse(Ur.readFileSync(n,"utf8"));return O("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){O("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Qm(e);if(!Ur.existsSync(r))return;let o=await n.storageState(),s=Kd.join(Kd.dirname(r),`.${Kd.basename(r)}.${process.pid}.${bY(4).toString("hex")}.tmp`);Ur.writeFileSync(s,JSON.stringify(o),{mode:384}),Ur.chmodSync(s,384),Ur.renameSync(s,r),O("[browser/vault] saved session",{profile:e,file:r})}catch(r){O("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as kY}from"node:crypto";function vY(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function TY(t,e,n){return`el_${kY("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function EY(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function QR(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function eI(t,e){let n=t.role??"",r=t.name??"";ZR.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])eI(s,e)}async function _Y(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},tI).catch(()=>[])}async function xY(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let g=s.type;g==="checkbox"?l="checkbox":g==="radio"?l="radio":g==="button"||g==="submit"||g==="reset"?l="button":g==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},tI).catch(()=>[])}function AY(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function qd(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=AY(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=_Y(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],eI(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await xY(t)).filter(C=>ZR.has(C.role??"")));let w=new Map;for(let E of p){let C=QR(E.name),H=w.get(C);(!H||H.bbox.w===0&&E.bbox.w>0)&&w.set(C,E)}let v=y.map(E=>({ax:E,dom:w.get(QR(E.name??""))})),x=r?v:v.filter(E=>E.dom?E.dom.bbox.w>0||E.dom.bbox.h>0:!0);x.sort((E,C)=>{let H=E.dom?.bbox.y??0,M=C.dom?.bbox.y??0;if(H!==M)return H-M;let $=E.dom?.bbox.x??0,U=C.dom?.bbox.x??0;return $-U}),x.length>200&&o.push("page has 200+ interactive elements; consider scoping");let _=x.slice(0,n).map((E,C)=>{let H=E.ax.role??"generic",M=E.ax.name??"",$=TY(H,M,C),U=E.dom?.bbox??{x:0,y:0,w:0,h:0},B=E.dom?.type??null,j=null;E.ax.value!==void 0&&E.ax.value!==null&&(j=String(E.ax.value)),E.ax.checked!==void 0&&(j=String(E.ax.checked)),$R({role:H,kind:B})&&(j="[redacted]");let K={disabled:E.ax.disabled??!1};E.ax.checked!==void 0&&(K.checked=E.ax.checked===!0||E.ax.checked==="mixed"),E.ax.selected!==void 0&&(K.selected=E.ax.selected),E.ax.expanded!==void 0&&(K.expanded=E.ax.expanded);let Y;E.dom?.testId?Y=`[data-testid="${E.dom.testId}"]`:E.dom?.id&&(Y=`#${E.dom.id}`);let Ft={id:$,role:H,label:vY(M),kind:B,value:j,state:K,bbox:U};return Y!==void 0&&(Ft.selector=Y),Ft}),I="idle";try{let E=await t.evaluate(()=>document.readyState);E==="loading"?I="loading":E==="interactive"?I="navigating":I="idle"}catch{I="navigating"}I!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let P=EY(f),T=`obs_${e.observationCounter.toString(36)}`,R=new Date().toISOString();return{observationId:T,url:m,title:g,textSummary:P,interactive:_,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:R}}var ZR,tI,nI=h(()=>{"use strict";jd();ZR=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);tI="a[href], button, input, select, textarea, [role], [tabindex], label"});async function rI(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${e}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function xy(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>rI(t,s)))).filter(o=>o!==null)}async function RY(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function Ay(t,e,n){switch(e.kind){case"element_id":return IY(t,e,n);case"selector":return PY(t,e);case"semantic":return CY(t,e)}}async function IY(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await xy(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function PY(t,e){let n=t.locator(e.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:e};if(r===1)return{outcome:"resolved",locator:n};let o=await xy(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function CY(t,e){return e.role!==void 0?MY(t,e.text,e.role):OY(t,e.text,e)}async function MY(t,e,n){let r=t.getByRole(n,{name:e}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:e,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await xy(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function OY(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await RY(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let y=p[g];if(y===void 0)continue;let b=await rI(y.locator,y.index);if(b!==null){let w=`${b.role}:${b.label}:${g}`,v=0;for(let x=0;x<w.length;x++)v=v*31+w.charCodeAt(x)>>>0;f.push({...b,id:`el_${v.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var oI=h(()=>{"use strict"});async function Ry(t,e,n,r){let o=t.url();if(o===n)return null;let s=It(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var sI=h(()=>{"use strict";jn()});var Py={};yo(Py,{PlaywrightProvider:()=>Iy});function iI(t){switch(t.kind){case"semantic":return t.role!==void 0?`semantic('${t.text}', role='${t.role}')`:`semantic('${t.text}')`;case"element_id":return`element_id(${t.elementId})`;case"selector":return`selector(${t.selector})`}}var Iy,Cy=h(()=>{"use strict";YR();nI();oI();jn();sI();Sy();Iy=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Gd(e)}async open(e){let n=It(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await Ry(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await qd(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await qd(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:e.includeHidden,maxElements:e.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=e.timeoutMs??3e4,a=await Ay(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${iI(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(y){l=y}else l=g}let u=await Ry(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await qd(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await Ay(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${iI(e.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:e.fullPage??!1});let{path:i,bytes:a}=await Qo(n,s,"browser_screenshot"),c=0,l=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(e){let n=this.sessions.get(e);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await Qo(n,o,r);return s}catch{return null}}}});var jr={};yo(jr,{__resetBrowserRegistryForTests:()=>UY,browserProviderActive:()=>LY,closeBrowserProvider:()=>Oy,getBrowserProvider:()=>FY,getLastRoutingDecision:()=>$Y,peekBrowserProvider:()=>NY});function aI(){Promise.resolve(Oy()).then(()=>{process.exit(130)})}function cI(){Promise.resolve(Oy()).then(()=>{process.exit(143)})}function lI(){Jt=null}function DY(){Xd||(process.on("SIGINT",aI),process.on("SIGTERM",cI),process.on("exit",lI),Xd=!0)}function dI(){Xd&&(process.removeListener("SIGINT",aI),process.removeListener("SIGTERM",cI),process.removeListener("exit",lI),Xd=!1)}async function FY(t){return Jt!==null?Jt:(Br!==null||(Br=(async()=>{let e=hy(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??k.AGENT_SURFACE,r=await LR({config:e,surface:n});My=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(XR(),qR)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Cy(),Py));o=new s(e)}return DY(),Jt=o,Br=null,o})()),Br)}async function Oy(){if(Jt===null)return;let t=Jt;Jt=null,Br=null,dI(),await t.shutdown()}function LY(){return Jt!==null}function NY(){return Jt}function $Y(){return My}function UY(){Jt=null,Br=null,My=null,dI()}var Jt,Br,Xd,My,Hr=h(()=>{"use strict";jn();NR();F();Jt=null,Br=null,Xd=!1,My=null});async function uI(t,e){try{return await TR(t,e)}catch(n){return O("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function GY(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Hr(),jr)),r=await n();try{return await r.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Cy(),Py)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(jn(),yy)),a=i(),c=new s(a);try{return await c.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}finally{await c.shutdown()}}throw o}}async function pI(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??GY,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Bn(n,t,{headers:KY,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(WY.test(p))throw new Error(`web_scrape markdown mode received binary content (${p.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let f=await u.text();if(HY.test(p)&&!jY.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await uI(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof Pe||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=py({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await ia(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>ia(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await ia(u.finalUrl,o);let p=await uI(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=py({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(e.signal.aborted||u instanceof Pe)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${c??"error"}).`)}var jY,HY,WY,KY,fI=h(()=>{"use strict";ER();fy();$r();ne();jY=/(text\/html|application\/xhtml\+xml)/i,HY=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,WY=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,KY={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/web_scrape",Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}});function zY(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(qY,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":t.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),XY),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Z(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function mI(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?zY({apiKey:t.exaApiKey,fetchFn:t.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function gI(t,e){if(e.length===0)return`# Search results for "${t}"
398
+ ${gt(t,{headless:e,latched:n})}`,{cause:t})}var JR,mY,gY,zR,yY,_y=h(()=>{"use strict";JR=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],mY="pnpm exec playwright install chromium",gY=4;yY="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import Ur from"node:fs";import Kd from"node:path";import{randomBytes as bY}from"node:crypto";function wY(){try{return"5.222.2"}catch{}try{let t=Kd.resolve(import.meta.dirname,"../../../package.json"),e=Ur.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var SY,Gd,YR=h(()=>{"use strict";_y();N();ne();SY=wY(),Gd=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=(async()=>{let e;try{({chromium:e}=await import("playwright"))}catch(n){let r=Wd(n,this.config.headless,!0);throw this.latchLaunchFailure(r),this.launchPromise=void 0,r}try{let n=await e.launch({headless:this.config.headless});return this.browser=n,this.clearLaunchFailure(),n}catch(n){let r=Wd(n,this.config.headless,!0);throw this.latchLaunchFailure(r),r}finally{this.launchPromise=void 0}})(),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${SY}`}}loadStorageState(e){let n=Qm(e);try{if(!Ur.existsSync(n))return;let r=JSON.parse(Ur.readFileSync(n,"utf8"));return O("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){O("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Qm(e);if(!Ur.existsSync(r))return;let o=await n.storageState(),s=Kd.join(Kd.dirname(r),`.${Kd.basename(r)}.${process.pid}.${bY(4).toString("hex")}.tmp`);Ur.writeFileSync(s,JSON.stringify(o),{mode:384}),Ur.chmodSync(s,384),Ur.renameSync(s,r),O("[browser/vault] saved session",{profile:e,file:r})}catch(r){O("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as kY}from"node:crypto";function vY(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function TY(t,e,n){return`el_${kY("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function EY(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function QR(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function eI(t,e){let n=t.role??"",r=t.name??"";ZR.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])eI(s,e)}async function _Y(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},tI).catch(()=>[])}async function xY(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let g=s.type;g==="checkbox"?l="checkbox":g==="radio"?l="radio":g==="button"||g==="submit"||g==="reset"?l="button":g==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},tI).catch(()=>[])}function AY(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function qd(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=AY(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=_Y(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],eI(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await xY(t)).filter(C=>ZR.has(C.role??"")));let w=new Map;for(let E of p){let C=QR(E.name),H=w.get(C);(!H||H.bbox.w===0&&E.bbox.w>0)&&w.set(C,E)}let v=y.map(E=>({ax:E,dom:w.get(QR(E.name??""))})),x=r?v:v.filter(E=>E.dom?E.dom.bbox.w>0||E.dom.bbox.h>0:!0);x.sort((E,C)=>{let H=E.dom?.bbox.y??0,M=C.dom?.bbox.y??0;if(H!==M)return H-M;let $=E.dom?.bbox.x??0,U=C.dom?.bbox.x??0;return $-U}),x.length>200&&o.push("page has 200+ interactive elements; consider scoping");let _=x.slice(0,n).map((E,C)=>{let H=E.ax.role??"generic",M=E.ax.name??"",$=TY(H,M,C),U=E.dom?.bbox??{x:0,y:0,w:0,h:0},B=E.dom?.type??null,j=null;E.ax.value!==void 0&&E.ax.value!==null&&(j=String(E.ax.value)),E.ax.checked!==void 0&&(j=String(E.ax.checked)),$R({role:H,kind:B})&&(j="[redacted]");let K={disabled:E.ax.disabled??!1};E.ax.checked!==void 0&&(K.checked=E.ax.checked===!0||E.ax.checked==="mixed"),E.ax.selected!==void 0&&(K.selected=E.ax.selected),E.ax.expanded!==void 0&&(K.expanded=E.ax.expanded);let Y;E.dom?.testId?Y=`[data-testid="${E.dom.testId}"]`:E.dom?.id&&(Y=`#${E.dom.id}`);let Ft={id:$,role:H,label:vY(M),kind:B,value:j,state:K,bbox:U};return Y!==void 0&&(Ft.selector=Y),Ft}),I="idle";try{let E=await t.evaluate(()=>document.readyState);E==="loading"?I="loading":E==="interactive"?I="navigating":I="idle"}catch{I="navigating"}I!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let P=EY(f),T=`obs_${e.observationCounter.toString(36)}`,R=new Date().toISOString();return{observationId:T,url:m,title:g,textSummary:P,interactive:_,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:R}}var ZR,tI,nI=h(()=>{"use strict";jd();ZR=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);tI="a[href], button, input, select, textarea, [role], [tabindex], label"});async function rI(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${e}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function xy(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>rI(t,s)))).filter(o=>o!==null)}async function RY(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function Ay(t,e,n){switch(e.kind){case"element_id":return IY(t,e,n);case"selector":return PY(t,e);case"semantic":return CY(t,e)}}async function IY(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await xy(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function PY(t,e){let n=t.locator(e.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:e};if(r===1)return{outcome:"resolved",locator:n};let o=await xy(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function CY(t,e){return e.role!==void 0?MY(t,e.text,e.role):OY(t,e.text,e)}async function MY(t,e,n){let r=t.getByRole(n,{name:e}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:e,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await xy(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function OY(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await RY(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let y=p[g];if(y===void 0)continue;let b=await rI(y.locator,y.index);if(b!==null){let w=`${b.role}:${b.label}:${g}`,v=0;for(let x=0;x<w.length;x++)v=v*31+w.charCodeAt(x)>>>0;f.push({...b,id:`el_${v.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var oI=h(()=>{"use strict"});async function Ry(t,e,n,r){let o=t.url();if(o===n)return null;let s=It(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var sI=h(()=>{"use strict";jn()});var Py={};yo(Py,{PlaywrightProvider:()=>Iy});function iI(t){switch(t.kind){case"semantic":return t.role!==void 0?`semantic('${t.text}', role='${t.role}')`:`semantic('${t.text}')`;case"element_id":return`element_id(${t.elementId})`;case"selector":return`selector(${t.selector})`}}var Iy,Cy=h(()=>{"use strict";YR();nI();oI();jn();sI();Sy();Iy=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Gd(e)}async open(e){let n=It(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await Ry(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await qd(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await qd(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:e.includeHidden,maxElements:e.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_act: no page open for session ${n}`);let o=this.ensureSessionState(n),s=r.url(),i=e.timeoutMs??3e4,a=await Ay(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${iI(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(y){l=y}else l=g}let u=await Ry(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await qd(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await Ay(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${iI(e.target)}`);if(d.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await d.locator.screenshot()}else s=await r.screenshot({fullPage:e.fullPage??!1});let{path:i,bytes:a}=await Qo(n,s,"browser_screenshot"),c=0,l=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(e){let n=this.sessions.get(e);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await Qo(n,o,r);return s}catch{return null}}}});var jr={};yo(jr,{__resetBrowserRegistryForTests:()=>UY,browserProviderActive:()=>LY,closeBrowserProvider:()=>Oy,getBrowserProvider:()=>FY,getLastRoutingDecision:()=>$Y,peekBrowserProvider:()=>NY});function aI(){Promise.resolve(Oy()).then(()=>{process.exit(130)})}function cI(){Promise.resolve(Oy()).then(()=>{process.exit(143)})}function lI(){Jt=null}function DY(){Xd||(process.on("SIGINT",aI),process.on("SIGTERM",cI),process.on("exit",lI),Xd=!0)}function dI(){Xd&&(process.removeListener("SIGINT",aI),process.removeListener("SIGTERM",cI),process.removeListener("exit",lI),Xd=!1)}async function FY(t){return Jt!==null?Jt:(Br!==null||(Br=(async()=>{let e=hy(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??k.AGENT_SURFACE,r=await LR({config:e,surface:n});My=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(XR(),qR)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Cy(),Py));o=new s(e)}return DY(),Jt=o,Br=null,o})()),Br)}async function Oy(){if(Jt===null)return;let t=Jt;Jt=null,Br=null,dI(),await t.shutdown()}function LY(){return Jt!==null}function NY(){return Jt}function $Y(){return My}function UY(){Jt=null,Br=null,My=null,dI()}var Jt,Br,Xd,My,Hr=h(()=>{"use strict";jn();NR();F();Jt=null,Br=null,Xd=!1,My=null});async function uI(t,e){try{return await TR(t,e)}catch(n){return O("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function GY(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Hr(),jr)),r=await n();try{return await r.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}catch(o){if(r.name==="agent-browser"){let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(Cy(),Py)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(jn(),yy)),a=i(),c=new s(a);try{return await c.render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}finally{await c.shutdown()}}throw o}}async function pI(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??GY,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Bn(n,t,{headers:KY,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(WY.test(p))throw new Error(`web_scrape markdown mode received binary content (${p.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let f=await u.text();if(HY.test(p)&&!jY.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await uI(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof Pe||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=py({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await ia(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>ia(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await ia(u.finalUrl,o);let p=await uI(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=py({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(e.signal.aborted||u instanceof Pe)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${c??"error"}).`)}var jY,HY,WY,KY,fI=h(()=>{"use strict";ER();fy();$r();ne();jY=/(text\/html|application\/xhtml\+xml)/i,HY=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,WY=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,KY={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/web_scrape",Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}});function zY(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(qY,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":t.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),XY),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Z(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function mI(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?zY({apiKey:t.exaApiKey,fetchFn:t.fetchFn}):{error:'web_scrape search mode requires a search backend. Set EXA_API_KEY (free tier at https://exa.ai) to enable it. Use mode: "markdown" to read a known URL, or mode: "raw" for a direct fetch.'}}function gI(t,e){if(e.length===0)return`# Search results for "${t}"
399
399
 
400
400
  (no results)`;let n=[`# Search results for "${t}"`,""];return e.forEach((r,o)=>{n.push(`## ${o+1}. ${r.title}`),r.url&&n.push(r.url),r.description&&n.push(r.description),n.push("")}),n.join(`
401
401
  `).trimEnd()}var qY,XY,hI=h(()=>{"use strict";nt();qY="https://api.exa.ai/search",XY=10});function zd(t){if(t instanceof Error&&t.name==="TimeoutError")return"timeout";let e=t instanceof Error?t.message:String(t);return/Timeout\s+\d+\s*ms exceeded/i.test(e)?"timeout":void 0}var Wr=h(()=>{"use strict";_y()});function e5(t){if(!t||typeof t!="object")return{error:"Invalid input: expected an object"};let e=t,n=e.mode??"markdown";if(n!=="markdown"&&n!=="raw"&&n!=="search")return{error:`Invalid input: mode must be one of "markdown", "raw", "search" (got ${JSON.stringify(n)})`};let r=n,o,s;if(r==="search"){if(typeof e.query!="string"||e.query.length===0)return{error:'Invalid input: search mode requires a non-empty "query" string'};s=e.query}else{if(typeof e.url!="string"||e.url.length===0)return{error:`Invalid input: ${r} mode requires a non-empty "url" string`};let c;try{c=new URL(e.url)}catch{return{error:`Invalid input: "${e.url}" is not a valid absolute URL`}}if(c.protocol!=="http:"&&c.protocol!=="https:")return{error:`Invalid input: protocol "${c.protocol}" not supported (http/https only)`};o=c.toString()}let i=JY;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number"||!Number.isFinite(e.timeout_ms)||e.timeout_ms<=0)return{error:"Invalid input: timeout_ms must be a positive finite number"};i=Math.min(e.timeout_ms,VY)}let a=YY;if(e.max_bytes!==void 0){if(typeof e.max_bytes!="number"||!Number.isFinite(e.max_bytes)||e.max_bytes<=0)return{error:"Invalid input: max_bytes must be a positive finite number"};a=Math.min(e.max_bytes,QY)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Dy(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:At(t,e),truncated:!0}}function t5(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env,r=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{};return async(o,s)=>{if(typeof e!="function")return{content:"web_scrape unavailable: global fetch() is not present in this runtime (agent-afk requires Node 20+).",isError:!0};let i=e5(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let u=s.reason;return{content:`web_scrape aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0}}let a=new AbortController,c=()=>{a.abort(s.reason)},l,d=()=>{let u=a.signal.reason;return u instanceof Error?u.message:String(u??"aborted")};try{if(s.addEventListener("abort",c,{once:!0}),l=setTimeout(()=>{a.abort(new Error(`web_scrape timeout after ${i.timeoutMs}ms`))},i.timeoutMs),i.url!==void 0){let p=await Nr(i.url,r);if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(!p.allowed)return{content:`web_scrape blocked: ${p.reason}`,isError:!0}}if(i.mode==="raw"){let p;try{let g={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};p=await Bn(e,i.url,g,r)}catch(g){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:g instanceof Pe?{content:`web_scrape blocked: ${g.message}`,isError:!0}:{content:`web_scrape network error: ${g instanceof Error?g.message:String(g)}`,isError:!0}}if(!p.ok)return{content:`web_scrape HTTP ${p.status} ${p.statusText||""}`.trimEnd()+` for ${i.url}`,isError:!0};let f;try{f=await p.text()}catch(g){return{content:`web_scrape read error: ${g instanceof Error?g.message:String(g)}`,isError:!0}}let m=Dy(f,i.maxBytes);return{content:m.content,...m.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await pI(i.url,{fetchFn:e,renderFn:t.renderFn,timeoutMs:i.timeoutMs,signal:a.signal,...t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{}});if(p.markdown.trim().length===0)return{content:`web_scrape extracted no readable content from ${i.url}.`,isError:!0};let f=Dy(_R(p.markdown,p.advisory),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(p instanceof Pe)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),m=Ve(p)&&!Ey(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${aa()}\`)`:"";return{content:`web_scrape markdown error: ${f}${m}`,isError:!0}}let u=mI({exaApiKey:n.EXA_API_KEY,fetchFn:e});if("error"in u)return{content:u.error,isError:!0};try{let p=await u.search(i.query,{limit:ZY,timeoutMs:i.timeoutMs,signal:a.signal}),f=Dy(gI(i.query,p),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:{content:`web_scrape search error (${u.name}): ${p instanceof Error?p.message:String(p)}`,isError:!0}}}finally{l!==void 0&&clearTimeout(l),s.removeEventListener("abort",c)}}}var JY,VY,YY,QY,ZY,yI,bI=h(()=>{"use strict";fI();hI();$r();Kt();fy();Wr();JY=3e4,VY=12e4,YY=1e5,QY=1e6,ZY=10;yI=t5()});function o5(t){return n5.has(t)?"low":t==="DELETE"?"high":"medium"}function s5(t){return r5.has(t)}function c5(t){let e={};return t.forEach((n,r)=>{let o=r.toLowerCase();a5.has(o)||i5.some(s=>o.startsWith(s))||(e[r]=n)}),e}function l5(t,e){if(t==null)return{serialized:void 0,inferredContentType:void 0};let n=Object.keys(e).some(o=>o.toLowerCase()==="content-type");return typeof t=="string"?{serialized:t,inferredContentType:n?void 0:"text/plain"}:{serialized:JSON.stringify(t),inferredContentType:n?void 0:"application/json"}}function d5(t,e,n){let r=Buffer.byteLength(t,"utf8"),o=t,s=!1;if(r>n&&(o=At(t,n),s=!0),!s&&/application\/json/i.test(e))try{return{body:JSON.parse(o),truncated:!1}}catch{}return{body:o,truncated:s}}async function kI(t){let{url:e,method:n,signal:r,domainCheck:o,recordEffect:s}=t,i=Math.min(t.maxResponseBytes??Fy,Ly),a={...t.headers},c=t.fetchFn??globalThis.fetch,l=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},d=o5(n);if(o!==void 0){let T=o(e);if(!T.allowed)throw Object.assign(new Error(`web_request blocked by domain policy: ${T.reason}`),{name:"DomainPolicyError"})}let u=await Nr(e,l);if(!u.allowed)throw new Pe(u.reason);let{serialized:p,inferredContentType:f}=l5(t.body,a);f!==void 0&&(a["content-type"]=f);let m={method:n,headers:Object.keys(a).length>0?a:void 0,body:p,signal:r},y=s5(n)?{retries:2,baseDelayMs:300,maxDelayMs:5e3}:{retries:0},b=Date.now(),w;try{w=await Bn(c,e,m,{...l,retry:y})}catch(T){throw T instanceof Pe,T}let v=Date.now()-b,x=w.headers.get("content-type")??"",A;try{let T=w.body?.getReader();if(!T)A="";else{let R=[],E=0,C=i*2;for(;;){let{done:H,value:M}=await T.read();if(H||!M)break;if(R.push(M),E+=M.byteLength,E>=C){await T.cancel();break}}A=new TextDecoder().decode(Buffer.concat(R,E))}}catch{A=""}let{body:_,truncated:I}=d5(A,x,i),P=c5(w.headers);return s!==void 0&&Promise.resolve(s({url:e,method:n,status:w.status,risk:d,timing_ms:v})).catch(()=>{}),{status:w.status,headers:P,body:_,truncated:I,timing_ms:v,risk:d}}function vI(t){if(typeof t!="string"||t.trim().length===0)return{error:"method must be a non-empty string (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)"};let e=t.trim().toUpperCase(),n=["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"];return n.includes(e)?e:{error:`method "${t}" is not supported \u2014 must be one of: ${n.join(", ")}`}}var wI,SI,Fy,Ly,n5,r5,i5,a5,TI=h(()=>{"use strict";$r();Kt();wI=3e4,SI=12e4,Fy=1e5,Ly=1e6,n5=new Set(["GET","HEAD","OPTIONS"]),r5=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]);i5=["set-cookie","x-"],a5=new Set(["server","via","age","vary","authorization","www-authenticate"])});function u5(t){if(!t||typeof t!="object")return{error:"Invalid input: expected an object"};let e=t;if(typeof e.url!="string"||e.url.length===0)return{error:'Invalid input: "url" must be a non-empty string'};let n;try{n=new URL(e.url)}catch{return{error:`Invalid input: "${e.url}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{error:`Invalid input: protocol "${n.protocol}" not supported (http/https only)`};n.username="",n.password="";let r=n.toString(),o=vI(e.method);if(typeof o=="object"&&"error"in o)return{error:`Invalid input: ${o.error}`};let s=o,i;if(e.body!==void 0&&e.body!==null){if(typeof e.body!="string"&&typeof e.body!="object")return{error:'Invalid input: "body" must be a string, object, or array'};i=e.body}let a={};if(e.headers!==void 0){if(typeof e.headers!="object"||e.headers===null||Array.isArray(e.headers))return{error:'Invalid input: "headers" must be a string-keyed object'};let u=e.headers;for(let[p,f]of Object.entries(u)){if(typeof f!="string")return{error:`Invalid input: header value for "${p}" must be a string`};a[p]=f}}let c=wI;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number"||!Number.isFinite(e.timeout_ms)||e.timeout_ms<=0)return{error:'Invalid input: "timeout_ms" must be a positive finite number'};c=Math.min(e.timeout_ms,SI)}let l=Fy;if(e.max_response_bytes!==void 0){if(typeof e.max_response_bytes!="number"||!Number.isFinite(e.max_response_bytes)||e.max_response_bytes<=0)return{error:'Invalid input: "max_response_bytes" must be a positive finite number'};l=Math.min(e.max_response_bytes,Ly)}let d;if(e.credential!==void 0){if(typeof e.credential!="string"||e.credential.length===0)return{error:'Invalid input: "credential" must be a non-empty string (an env var name)'};d=e.credential}return{url:r,method:s,body:i,headers:a,timeoutMs:c,maxResponseBytes:l,credential:d}}function p5(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env;async function r(){if(t.domainCheck!==void 0)return t.domainCheck;try{let{loadBrowserConfig:o,enforceDomainPolicy:s}=await Promise.resolve().then(()=>(jn(),yy)),i=o();return a=>s(a,i)}catch{return}}return async(o,s)=>{if(typeof e!="function")return{content:"web_request unavailable: global fetch() is not present (agent-afk requires Node 20+).",isError:!0};let i=u5(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let p=s.reason;return{content:`web_request aborted: ${p instanceof Error?p.message:String(p??"aborted")}`,isError:!0}}let a={...i.headers};if(i.credential!==void 0){let p=n[i.credential];if(p===void 0||p.trim().length===0)return{content:`web_request credential error: environment variable "${i.credential}" is not set. Set it in afk.env or export it in the shell before starting AFK.`,isError:!0};if(Object.keys(a).some(m=>m.toLowerCase()==="authorization"))return{content:'web_request credential error: both "credential" and an explicit Authorization header were provided. Use one or the other.',isError:!0};a.Authorization=`Bearer ${p}`}let c=new AbortController,l=()=>c.abort(s.reason),d,u=()=>{let p=c.signal.reason;return p instanceof Error?p.message:String(p??"aborted")};try{s.addEventListener("abort",l,{once:!0}),d=setTimeout(()=>{c.abort(new Error(`web_request timeout after ${i.timeoutMs}ms`))},i.timeoutMs);let p=await r(),f={url:i.url,method:i.method,body:i.body,headers:a,maxResponseBytes:i.maxResponseBytes,signal:c.signal,fetchFn:e,lookupFn:t.lookupFn,domainCheck:p,recordEffect:t.recordEffect},m;try{m=await kI(f)}catch(w){if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};if(w instanceof Pe)return{content:`web_request blocked: ${w.message}`,isError:!0};let v=w instanceof Error&&w.name==="DomainPolicyError"?"blocked":"network error",x=w instanceof Error?w.message:String(w);return{content:`web_request ${v}: ${x}`,isError:!0}}if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};let g=m.body;if(typeof g=="string")g=Ge(g);else if(typeof g=="object"&&g!==null){let w=Ge(JSON.stringify(g));try{g=JSON.parse(w)}catch{g=w}}let y={status:m.status,headers:m.headers,body:g,timing_ms:m.timing_ms,...m.truncated?{truncated:!0}:{}};return{content:JSON.stringify(y,null,2),...m.truncated?{truncated:!0}:{}}}finally{d!==void 0&&clearTimeout(d),s.removeEventListener("abort",l)}}}var EI,_I=h(()=>{"use strict";TI();$r();xn();EI=p5()});import{existsSync as AI,mkdirSync as f5,readFileSync as m5,renameSync as g5,unlinkSync as h5,writeFileSync as y5}from"node:fs";import{dirname as xI,join as b5}from"node:path";import{randomBytes as w5}from"node:crypto";function Kr(t){let e=t??Xm();if(!AI(e))return[];try{let n=m5(e,"utf-8");return JSON.parse(n)}catch(n){let r=n instanceof Error?n.message:String(n);return console.error(`[schedule-store] failed to parse ${e}: ${r}`),[]}}function ca(t,e){let n=e??Xm();f5(xI(n),{recursive:!0});let r=b5(xI(n),`.schedules.json.${process.pid}.${w5(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{y5(r,o,"utf-8"),g5(r,n)}catch(s){try{AI(r)&&h5(r)}catch{}throw s}}function RI(t,e){let n=Kr(e),r=n.map(c=>c.id),o=S5(t.name),s=k5(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),ca(n,e),a}function II(t,e){let n=Kr(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(ca(o,e),!0)}function PI(t,e){return Kr(e).find(n=>n.id===t)}function S5(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function k5(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}function CI(t){return{taskId:t.id,command:t.command,trigger:t.trigger??"cron",...t.executor!==void 0?{executor:t.executor}:{},...t.cron!==void 0?{cronExpression:t.cron}:{},...t.notifyOn!==void 0?{notifyOn:t.notifyOn}:{},...t.notifyChat!==void 0?{notifyChat:t.notifyChat}:{}}}var MI=h(()=>{"use strict";N()});import{existsSync as v5,readFileSync as T5}from"node:fs";import{join as E5}from"node:path";async function Zo(t,e,n){let r,o;try{let s=E5(nT("default"),"port");if(!v5(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=T5(s,"utf-8").trim(),a=_5(i);if(!a)return{synced:!1,detail:"daemon-not-detected (invalid port file)"};({host:r,port:o}=a)}catch{return{synced:!1,detail:"daemon-not-detected (unreadable port file)"}}try{let s=r.includes(":")?`[${r}]`:r,i=await fetch(`http://${s}:${o}${e}`,{method:t,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return i.ok?{synced:!0,detail:"synced"}:t==="POST"&&i.status===409?{synced:!0,detail:"already-registered"}:t==="DELETE"&&i.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${i.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}function _5(t){let e=parseInt(t,10);if(String(e)===t&&!Number.isNaN(e))return e<1||e>65535?null:{host:"localhost",port:e};let n=t.lastIndexOf(":");if(n<1)return null;let r=t.slice(0,n),o=t.slice(n+1);if(!/^\d+$/.test(o))return null;let s=parseInt(o,10);return Number.isNaN(s)||s<1||s>65535||/^:+$/.test(r)?null:{host:r.startsWith("[")&&r.endsWith("]")?r.slice(1,-1):r,port:s}}var Ny,OI=h(()=>{"use strict";N();Ny="Change saved to schedules.json, but a running daemon (if any) did not pick it up \u2014 it will apply on the next daemon (re)start."});import{existsSync as x5}from"node:fs";import{readFile as A5}from"node:fs/promises";var DI,FI,LI,NI,$I=h(()=>{"use strict";MI();N();OI();DI=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;if(typeof n.name!="string"||!n.name)return{content:"Invalid input: name required",isError:!0};if(typeof n.command!="string"||!n.command)return{content:"Invalid input: command required",isError:!0};if(typeof n.cron!="string"||!n.cron)return{content:"Invalid input: cron required",isError:!0};let r=n.cron.trim().split(/\s+/);if(r.length!==5&&r.length!==6)return{content:"Invalid input: cron must be a 5 or 6-field expression",isError:!0};let o=n.notifyChat;if(o!==void 0&&typeof o!="number"&&typeof o!="string")return{content:"Invalid input: notifyChat must be a number (chat id) or string (chat id or alias name)",isError:!0};let s=n.executor;if(s!==void 0&&s!=="agent"&&s!=="shell")return{content:'Invalid input: executor must be "agent" or "shell"',isError:!0};let i=RI({name:n.name,command:n.command,cron:n.cron,...s!==void 0?{executor:s}:{},trigger:n.trigger??"cron",notifyOn:n.notifyOn,...o!==void 0?{notifyChat:o}:{},enabled:typeof n.enabled=="boolean"?n.enabled:!0}),a=i.enabled?await Zo("POST","/tasks",{taskId:i.id,command:i.command,cron:i.cron,...i.executor!==void 0?{executor:i.executor}:{},trigger:i.trigger,notifyOn:i.notifyOn,...i.notifyChat!==void 0?{notifyChat:i.notifyChat}:{}}):await Zo("DELETE",`/tasks/${i.id}`);return{content:JSON.stringify({id:i.id,name:i.name,cron:i.cron,enabled:i.enabled,daemonSynced:a.synced,syncDetail:a.detail,...a.synced?{}:{syncNote:Ny}})}},FI=async(t,e)=>{let n=Kr();return{content:JSON.stringify(n.map(r=>({id:r.id,name:r.name,cron:r.cron,executor:r.executor??"agent",trigger:r.trigger,enabled:r.enabled,notifyOn:r.notifyOn})))}},LI=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;if(typeof n.taskId!="string"||!n.taskId)return{content:"Invalid input: taskId required",isError:!0};let r=n.taskId,o=typeof n.limit=="number"?Math.min(Math.max(1,n.limit),50):10,s=Xc();if(!x5(s))return{content:JSON.stringify([])};let i;try{let l=await A5(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`