agent-afk 5.203.1 → 5.204.1

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
@@ -280,7 +280,7 @@ Send a message to start one, or /new for a fresh session.`}function R_(t){return
280
280
 
281
281
  ${e}`}var P1,lm=m(()=>{"use strict";P1=new Set(["script","style","noscript","template","svg"])});function D1(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 $_(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function F1(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 B_(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??D1,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(!O1.has(u.status)||d===o)return u;let p=F1(u,i)??$_(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=$_(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 O1,j_=m(()=>{"use strict";Q();O1=new Set([429,502,503,504])});import{BlockList as L1,isIP as um}from"node:net";import{lookup as N1}from"node:dns/promises";import{Agent as U1}from"undici";function W_(){let t=w.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function H1(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function dm(t){let e=um(t);return e===0?!1:j1.check(t,e===4?"ipv4":"ipv6")}async function K_(t){return N1(t,{all:!0,verbatim:!0})}async function zn(t,e={}){if(e.allowPrivateHosts??W_())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=H1(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(um(r)!==0)return dm(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??K_,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 Hs(t,e={}){let n=await zn(t,e);if(!n.allowed)throw new ve(n.reason)}async function sn(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<=H_;i++){await Hs(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??W_())?{dispatcher:W1}:{}},c=await B_(t,s,a,r.retry??{});if(!K1.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 ve(`too many redirects (>${H_}) starting from ${e}`)}var $1,B1,j1,ve,W1,H_,K1,Jn=m(()=>{"use strict";P();j_();$1=[["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]],B1=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],j1=(()=>{let t=new L1;for(let[e,n]of $1)t.addSubnet(e,n,"ipv4");for(let[e,n]of B1)t.addSubnet(e,n,"ipv6");return t})(),ve=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};W1=new U1({connect:{lookup(t,e,n){K_(t).then(r=>{let o=r.find(i=>dm(i.address));if(o!==void 0){n(new ve(`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,um(s.address))},r=>n(r,"",0))}}});H_=20,K1=new Set([301,302,303,307,308])});var fm={};qo(fm,{enforceDomainPolicy:()=>ft,loadBrowserConfig:()=>pm});import{readFileSync as q1}from"node:fs";import{join as G1}from"path";function X1(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function q_(t,e){return X1(e).test(t)}function V1(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(z1.has(e))return!0;if(J1.has(e))return!1}return!1}function G_(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function Y1(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 X_(t){let e=t===void 0||t.trim()===""?"default":t.trim();return gp(e),e}function Q1(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function Z1(t){try{return q1(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function eK(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=X_(e.defaultProfile)),n}function pm(t){let e=t?.env??w,n=t?.readFileSync??Z1,r=t?.surface??e.AGENT_SURFACE,o=V1(e.AFK_BROWSER_HEADLESS,r),s=G_(e.AFK_BROWSER_ALLOWED_DOMAINS),i=G_(e.AFK_BROWSER_BLOCKED_DOMAINS),a=Q1(e.AFK_BROWSER_DOM_SNAPSHOTS),c=Y1(e.AFK_BROWSER_BACKEND),l=X_(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():G1(Vo(),"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=eK(d,g);return h.configPath=p,h}function ft(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(q_(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>q_(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var z1,J1,an=m(()=>{"use strict";P();M();z1=new Set(["daemon","subagent","telegram","afk"]),J1=new Set(["repl","interactive","cli"])});import{readFileSync as tK}from"node:fs";import{join as nK}from"node:path";import{homedir as rK}from"node:os";function sK(t){let e=t??oK,n;try{n=tK(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 iK(t){try{return process.kill(t,0),!0}catch{return!1}}async function aK(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 mm(t){let e=sK(t);return e===null?{available:!1,connection:null,reason:"connection file missing or invalid"}:iK(e.pid)?await aK(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 oK,z_=m(()=>{"use strict";oK=nK(rK(),".config","agent-browser","connection.json")});async function J_(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 mm(),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&&cK.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 mm(),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 cK,V_=m(()=>{"use strict";z_();cK=new Set(["daemon","subagent"])});import{createHash as lK}from"crypto";function Y_(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&dK.test(t.label))}function Q_(t){return lK("sha256").update(t,"utf8").digest("hex").slice(0,8)}function Z_(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var dK,Hc=m(()=>{"use strict";dK=/password|secret|token|api[_-]?key|otp|2fa/i});import{randomBytes as uK}from"crypto";import{mkdir as pK,stat as fK,writeFile as mK}from"fs/promises";import{join as gm}from"path";import{gzip as gK}from"zlib";import{promisify as hK}from"util";function yK(t){return gm(gt(t),"browser")}function bK(t){return gm(yK(t),"screenshots")}function wK(){return new Date().toISOString().replace(/[:.]/g,"-")}function SK(){return uK(3).toString("hex")}async function qr(t,e,n){if(e.length>eT)throw new Error(`writeScreenshotSidecar: buffer exceeds ${eT} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=bK(t);await pK(r,{recursive:!0});let o=`${wK()}-${SK()}-${n}.png`,s=gm(r,o);await mK(s,e);let{size:i}=await fK(s);return{path:s,bytes:i}}var zse,eT,hm=m(()=>{"use strict";M();Hc();zse=hK(gK);eT=5*1024*1024});var Wc,tT=m(()=>{"use strict";Wc=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 c=await a.text().catch(()=>"");throw new Error(`Agent Browser ${e} failed (HTTP ${a.status}): ${c}`)}return await a.json()}finally{clearTimeout(i)}}async listTabs(){return(await this.call("tabs.list",null)).tabs}async openTab(e){return{tabId:(await this.call("tabs.open",{url:e},6e4)).tab_id}}async closeTab(e){await this.call("tabs.close",{tab_id:e})}async read(e,n){return this.call("page.read",{tab_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",{tab_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",{tab_id:e,element_id:n})}async fill(e,n,r){await this.call("page.fill",{tab_id:e,element_id:n,value:r})}async press(e,n,r){await this.call("page.press",{tab_id:e,key:n,...r?{element_id:r}:{}})}async select(e,n,r){await this.call("page.select",{tab_id:e,element_id:n,value:r})}async waitFor(e,n,r){await this.call("page.wait",{tab_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",{tab_id:e,script:n})}async screenshot(e){return this.call("page.screenshot",{tab_id:e})}}});function ym(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 nT(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 bm(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 rT(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(ym)};let s=r[0].id;await bm(t.client,t.tabId,e.action,s,e.value,e.timeoutMs);let i=await t.client.read(t.tabId,{mode:"main"}),a=ft(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 oT=m(()=>{"use strict";an()});var sT={};qo(sT,{AgentBrowserProvider:()=>wm});var wm,iT=m(()=>{"use strict";an();hm();tT();oT();wm=class{name="agent-browser";config;client;sessions=new Map;constructor(e,n){this.config=e,this.client=new Wc(n)}async open(e){let n=ft(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=ft(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=nT(n.knownElements,e.target);if(r===null){if(e.target.kind==="semantic"){let i=await rT({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 bm(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=ft(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 qr(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(ym),l=o??80,d=c.slice(0,l);e.observationCounter+=1,e.knownElements=new Map(d.map(h=>[h.id,h])),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 h=await this.client.screenshot(e.tabId),y=Buffer.from(h.data,"base64");p=(await qr(n,y,s)).path}catch{u.push("screenshot capture failed")}let f=`obs_${e.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 kK,readFileSync as vK}from"node:fs";import{createRequire as _K}from"node:module";import{dirname as TK,join as EK}from"node:path";function lT(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<xK&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function Ue(t){let e=lT(t);return cT.some(n=>e.includes(n))}function RK(){try{let e=_K(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(vK(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=EK(TK(e),o);return kK(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function Ws(){return aT??=RK()??AK,aT}function Sm(t){return t.includes("install chromium")}function nt(t,e){let n=lT(t),r=e?.latched===!0?` ${IK}`:"";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: ${Ws()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Ws()}). Or pick a different tool.${r}`}function Kc(t,e,n=!1){if(!Ue(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
282
282
 
283
- ${nt(t,{headless:e,latched:n})}`,{cause:t})}var cT,AK,xK,aT,IK,km=m(()=>{"use strict";cT=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],AK="pnpm exec playwright install chromium",xK=4;IK="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 Vn from"node:fs";import qc from"node:path";import{randomBytes as CK}from"node:crypto";function PK(){try{return"5.203.1"}catch{}try{let t=qc.resolve(import.meta.dirname,"../../../package.json"),e=Vn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var MK,Gc,dT=m(()=>{"use strict";km();M();Q();MK=PK(),Gc=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=Kc(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=Kc(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/${MK}`}}loadStorageState(e){let n=hp(e);try{if(!Vn.existsSync(n))return;let r=JSON.parse(Vn.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=hp(e);if(!Vn.existsSync(r))return;let o=await n.storageState(),s=qc.join(qc.dirname(r),`.${qc.basename(r)}.${process.pid}.${CK(4).toString("hex")}.tmp`);Vn.writeFileSync(s,JSON.stringify(o),{mode:384}),Vn.chmodSync(s,384),Vn.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 OK}from"node:crypto";function DK(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function FK(t,e,n){return`el_${OK("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function LK(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function uT(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function fT(t,e){let n=t.role??"",r=t.name??"";pT.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])fT(s,e)}async function NK(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},mT).catch(()=>[])}async function UK(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 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},mT).catch(()=>[])}function $K(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Xc(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=$K(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=NK(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,g,h]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],fT(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await UK(t)).filter(C=>pT.has(C.role??"")));let S=new Map;for(let A of p){let C=uT(A.name),B=S.get(C);(!B||B.bbox.w===0&&A.bbox.w>0)&&S.set(C,A)}let k=y.map(A=>({ax:A,dom:S.get(uT(A.name??""))})),v=r?k:k.filter(A=>A.dom?A.dom.bbox.w>0||A.dom.bbox.h>0:!0);v.sort((A,C)=>{let B=A.dom?.bbox.y??0,L=C.dom?.bbox.y??0;if(B!==L)return B-L;let U=A.dom?.bbox.x??0,F=C.dom?.bbox.x??0;return U-F}),v.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=v.slice(0,n).map((A,C)=>{let B=A.ax.role??"generic",L=A.ax.name??"",U=FK(B,L,C),F=A.dom?.bbox??{x:0,y:0,w:0,h:0},N=A.dom?.type??null,G=null;A.ax.value!==void 0&&A.ax.value!==null&&(G=String(A.ax.value)),A.ax.checked!==void 0&&(G=String(A.ax.checked)),Y_({role:B,kind:N})&&(G="[redacted]");let K={disabled:A.ax.disabled??!1};A.ax.checked!==void 0&&(K.checked=A.ax.checked===!0||A.ax.checked==="mixed"),A.ax.selected!==void 0&&(K.selected=A.ax.selected),A.ax.expanded!==void 0&&(K.expanded=A.ax.expanded);let le;A.dom?.testId?le=`[data-testid="${A.dom.testId}"]`:A.dom?.id&&(le=`#${A.dom.id}`);let An={id:U,role:B,label:DK(L),kind:N,value:G,state:K,bbox:F};return le!==void 0&&(An.selector=le),An}),x="idle";try{let A=await t.evaluate(()=>document.readyState);A==="loading"?x="loading":A==="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 D=LK(f),_=`obs_${e.observationCounter.toString(36)}`,T=new Date().toISOString();return{observationId:_,url:g,title:h,textSummary:D,interactive:R,status:{httpStatus:e.httpStatus??null,loadingState:x,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:T}}var pT,mT,gT=m(()=>{"use strict";Hc();pT=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);mT="a[href], button, input, select, textarea, [role], [tabindex], label"});async function hT(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 vm(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>hT(t,s)))).filter(o=>o!==null)}async function BK(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 _m(t,e,n){switch(e.kind){case"element_id":return jK(t,e,n);case"selector":return HK(t,e);case"semantic":return WK(t,e)}}async function jK(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 vm(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function HK(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 vm(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function WK(t,e){return e.role!==void 0?KK(t,e.text,e.role):qK(t,e.text,e)}async function KK(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 vm(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function qK(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 BK(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 hT(y.locator,y.index);if(b!==null){let S=`${b.role}:${b.label}:${h}`,k=0;for(let v=0;v<S.length;v++)k=k*31+S.charCodeAt(v)>>>0;f.push({...b,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var yT=m(()=>{"use strict"});async function Tm(t,e,n,r){let o=t.url();if(o===n)return null;let s=ft(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 bT=m(()=>{"use strict";an()});var Am={};qo(Am,{PlaywrightProvider:()=>Em});function wT(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 Em,xm=m(()=>{"use strict";dT();gT();yT();an();bT();hm();Em=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Gc(e)}async open(e){let n=ft(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 Tm(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 Xc(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 Xc(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 _m(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${wT(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(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 Tm(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 Xc(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,g),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 _m(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${wT(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 qr(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 qr(n,o,r);return s}catch{return null}}}});var Qn={};qo(Qn,{__resetBrowserRegistryForTests:()=>YK,browserProviderActive:()=>zK,closeBrowserProvider:()=>Im,getBrowserProvider:()=>XK,getLastRoutingDecision:()=>VK,peekBrowserProvider:()=>JK});function ST(){Promise.resolve(Im()).then(()=>{process.exit(130)})}function kT(){Promise.resolve(Im()).then(()=>{process.exit(143)})}function vT(){Et=null}function GK(){zc||(process.on("SIGINT",ST),process.on("SIGTERM",kT),process.on("exit",vT),zc=!0)}function _T(){zc&&(process.removeListener("SIGINT",ST),process.removeListener("SIGTERM",kT),process.removeListener("exit",vT),zc=!1)}async function XK(t){return Et!==null?Et:(Yn!==null||(Yn=(async()=>{let e=pm(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??w.AGENT_SURFACE,r=await J_({config:e,surface:n});Rm=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(iT(),sT)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(xm(),Am));o=new s(e)}return GK(),Et=o,Yn=null,o})()),Yn)}async function Im(){if(Et===null)return;let t=Et;Et=null,Yn=null,_T(),await t.shutdown()}function zK(){return Et!==null}function JK(){return Et}function VK(){return Rm}function YK(){Et=null,Yn=null,Rm=null,_T()}var Et,Yn,zc,Rm,Zn=m(()=>{"use strict";an();V_();P();Et=null,Yn=null,zc=!1,Rm=null});async function TT(t,e){try{return await L_(t,e)}catch(n){return O("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function rq(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Zn(),Qn)),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(()=>(xm(),Am)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(an(),fm)),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 ET(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??rq,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await sn(n,t,{headers:nq,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(tq.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)&&!ZK.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await TT(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof ve||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=cm({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await Hs(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>Hs(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await Hs(u.finalUrl,o);let p=await TT(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=cm({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 ve)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 ${t}: 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 ${t} (HTTP ${c??"error"}).`)}var ZK,eq,tq,nq,AT=m(()=>{"use strict";N_();lm();Jn();Q();ZK=/(text\/html|application\/xhtml\+xml)/i,eq=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,tq=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,nq={"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 iq(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(oq,{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),sq),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 xT(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?iq({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 RT(t,e){if(e.length===0)return`# Search results for "${t}"
283
+ ${nt(t,{headless:e,latched:n})}`,{cause:t})}var cT,AK,xK,aT,IK,km=m(()=>{"use strict";cT=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],AK="pnpm exec playwright install chromium",xK=4;IK="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 Vn from"node:fs";import qc from"node:path";import{randomBytes as CK}from"node:crypto";function PK(){try{return"5.204.1"}catch{}try{let t=qc.resolve(import.meta.dirname,"../../../package.json"),e=Vn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var MK,Gc,dT=m(()=>{"use strict";km();M();Q();MK=PK(),Gc=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=Kc(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=Kc(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/${MK}`}}loadStorageState(e){let n=hp(e);try{if(!Vn.existsSync(n))return;let r=JSON.parse(Vn.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=hp(e);if(!Vn.existsSync(r))return;let o=await n.storageState(),s=qc.join(qc.dirname(r),`.${qc.basename(r)}.${process.pid}.${CK(4).toString("hex")}.tmp`);Vn.writeFileSync(s,JSON.stringify(o),{mode:384}),Vn.chmodSync(s,384),Vn.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 OK}from"node:crypto";function DK(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function FK(t,e,n){return`el_${OK("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function LK(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function uT(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function fT(t,e){let n=t.role??"",r=t.name??"";pT.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])fT(s,e)}async function NK(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},mT).catch(()=>[])}async function UK(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 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},mT).catch(()=>[])}function $K(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Xc(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=$K(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=NK(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,g,h]=await Promise.all([i,a,c,l,d]),y,b=!1;u!==null?(y=[],fT(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await UK(t)).filter(C=>pT.has(C.role??"")));let S=new Map;for(let A of p){let C=uT(A.name),B=S.get(C);(!B||B.bbox.w===0&&A.bbox.w>0)&&S.set(C,A)}let k=y.map(A=>({ax:A,dom:S.get(uT(A.name??""))})),v=r?k:k.filter(A=>A.dom?A.dom.bbox.w>0||A.dom.bbox.h>0:!0);v.sort((A,C)=>{let B=A.dom?.bbox.y??0,L=C.dom?.bbox.y??0;if(B!==L)return B-L;let U=A.dom?.bbox.x??0,F=C.dom?.bbox.x??0;return U-F}),v.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=v.slice(0,n).map((A,C)=>{let B=A.ax.role??"generic",L=A.ax.name??"",U=FK(B,L,C),F=A.dom?.bbox??{x:0,y:0,w:0,h:0},N=A.dom?.type??null,G=null;A.ax.value!==void 0&&A.ax.value!==null&&(G=String(A.ax.value)),A.ax.checked!==void 0&&(G=String(A.ax.checked)),Y_({role:B,kind:N})&&(G="[redacted]");let K={disabled:A.ax.disabled??!1};A.ax.checked!==void 0&&(K.checked=A.ax.checked===!0||A.ax.checked==="mixed"),A.ax.selected!==void 0&&(K.selected=A.ax.selected),A.ax.expanded!==void 0&&(K.expanded=A.ax.expanded);let le;A.dom?.testId?le=`[data-testid="${A.dom.testId}"]`:A.dom?.id&&(le=`#${A.dom.id}`);let An={id:U,role:B,label:DK(L),kind:N,value:G,state:K,bbox:F};return le!==void 0&&(An.selector=le),An}),x="idle";try{let A=await t.evaluate(()=>document.readyState);A==="loading"?x="loading":A==="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 D=LK(f),_=`obs_${e.observationCounter.toString(36)}`,T=new Date().toISOString();return{observationId:_,url:g,title:h,textSummary:D,interactive:R,status:{httpStatus:e.httpStatus??null,loadingState:x,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:T}}var pT,mT,gT=m(()=>{"use strict";Hc();pT=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);mT="a[href], button, input, select, textarea, [role], [tabindex], label"});async function hT(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 vm(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>hT(t,s)))).filter(o=>o!==null)}async function BK(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 _m(t,e,n){switch(e.kind){case"element_id":return jK(t,e,n);case"selector":return HK(t,e);case"semantic":return WK(t,e)}}async function jK(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 vm(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function HK(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 vm(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function WK(t,e){return e.role!==void 0?KK(t,e.text,e.role):qK(t,e.text,e)}async function KK(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 vm(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function qK(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 BK(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 hT(y.locator,y.index);if(b!==null){let S=`${b.role}:${b.label}:${h}`,k=0;for(let v=0;v<S.length;v++)k=k*31+S.charCodeAt(v)>>>0;f.push({...b,id:`el_${k.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var yT=m(()=>{"use strict"});async function Tm(t,e,n,r){let o=t.url();if(o===n)return null;let s=ft(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 bT=m(()=>{"use strict";an()});var Am={};qo(Am,{PlaywrightProvider:()=>Em});function wT(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 Em,xm=m(()=>{"use strict";dT();gT();yT();an();bT();hm();Em=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Gc(e)}async open(e){let n=ft(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 Tm(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 Xc(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 Xc(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 _m(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${wT(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(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 Tm(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 Xc(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,g),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 _m(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${wT(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 qr(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 qr(n,o,r);return s}catch{return null}}}});var Qn={};qo(Qn,{__resetBrowserRegistryForTests:()=>YK,browserProviderActive:()=>zK,closeBrowserProvider:()=>Im,getBrowserProvider:()=>XK,getLastRoutingDecision:()=>VK,peekBrowserProvider:()=>JK});function ST(){Promise.resolve(Im()).then(()=>{process.exit(130)})}function kT(){Promise.resolve(Im()).then(()=>{process.exit(143)})}function vT(){Et=null}function GK(){zc||(process.on("SIGINT",ST),process.on("SIGTERM",kT),process.on("exit",vT),zc=!0)}function _T(){zc&&(process.removeListener("SIGINT",ST),process.removeListener("SIGTERM",kT),process.removeListener("exit",vT),zc=!1)}async function XK(t){return Et!==null?Et:(Yn!==null||(Yn=(async()=>{let e=pm(t),n=t?.surface??(t?.env??{}).AGENT_SURFACE??w.AGENT_SURFACE,r=await J_({config:e,surface:n});Rm=r;let o;if(r.backend==="agent-browser"){let{AgentBrowserProvider:s}=await Promise.resolve().then(()=>(iT(),sT)),i=r.availability.connection;o=new s(e,i)}else{let{PlaywrightProvider:s}=await Promise.resolve().then(()=>(xm(),Am));o=new s(e)}return GK(),Et=o,Yn=null,o})()),Yn)}async function Im(){if(Et===null)return;let t=Et;Et=null,Yn=null,_T(),await t.shutdown()}function zK(){return Et!==null}function JK(){return Et}function VK(){return Rm}function YK(){Et=null,Yn=null,Rm=null,_T()}var Et,Yn,zc,Rm,Zn=m(()=>{"use strict";an();V_();P();Et=null,Yn=null,zc=!1,Rm=null});async function TT(t,e){try{return await L_(t,e)}catch(n){return O("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function rq(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Zn(),Qn)),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(()=>(xm(),Am)),{loadBrowserConfig:i}=await Promise.resolve().then(()=>(an(),fm)),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 ET(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??rq,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await sn(n,t,{headers:nq,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(tq.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)&&!ZK.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await TT(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof ve||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=cm({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await Hs(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>Hs(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await Hs(u.finalUrl,o);let p=await TT(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=cm({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 ve)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 ${t}: 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 ${t} (HTTP ${c??"error"}).`)}var ZK,eq,tq,nq,AT=m(()=>{"use strict";N_();lm();Jn();Q();ZK=/(text\/html|application\/xhtml\+xml)/i,eq=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,tq=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,nq={"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 iq(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(oq,{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),sq),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 xT(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?iq({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 RT(t,e){if(e.length===0)return`# Search results for "${t}"
284
284
 
285
285
  (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(`
286
286
  `).trimEnd()}var oq,sq,IT=m(()=>{"use strict";Qe();oq="https://api.exa.ai/search",sq=10});function Jc(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 er=m(()=>{"use strict";km()});function pq(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=aq;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,cq)}let a=lq;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,dq)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Cm(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:kt(t,e),truncated:!0}}function fq(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=pq(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 zn(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 sn(e,i.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:h instanceof ve?{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=Cm(f,i.maxBytes);return{content:g.content,...g.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await ET(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=Cm(U_(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 ve)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),g=Ue(p)&&!Sm(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Ws()}\`)`:"";return{content:`web_scrape markdown error: ${f}${g}`,isError:!0}}let u=xT({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:uq,timeoutMs:i.timeoutMs,signal:a.signal}),f=Cm(RT(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 aq,cq,lq,dq,uq,CT,PT=m(()=>{"use strict";AT();IT();Jn();vt();lm();er();aq=3e4,cq=12e4,lq=1e5,dq=1e6,uq=10;CT=fq()});function hq(t){return mq.has(t)?"low":t==="DELETE"?"high":"medium"}function yq(t){return gq.has(t)}function Sq(t){let e={};return t.forEach((n,r)=>{let o=r.toLowerCase();wq.has(o)||bq.some(s=>o.startsWith(s))||(e[r]=n)}),e}function kq(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 vq(t,e,n){let r=Buffer.byteLength(t,"utf8"),o=t,s=!1;if(r>n&&(o=kt(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 DT(t){let{url:e,method:n,signal:r,domainCheck:o,recordEffect:s}=t,i=Math.min(t.maxResponseBytes??Pm,Mm),a={...t.headers},c=t.fetchFn??globalThis.fetch,l=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{},d=hq(n);if(o!==void 0){let _=o(e);if(!_.allowed)throw Object.assign(new Error(`web_request blocked by domain policy: ${_.reason}`),{name:"DomainPolicyError"})}let u=await zn(e,l);if(!u.allowed)throw new ve(u.reason);let{serialized:p,inferredContentType:f}=kq(t.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=yq(n)?{retries:2,baseDelayMs:300,maxDelayMs:5e3}:{retries:0},b=Date.now(),S;try{S=await sn(c,e,g,{...l,retry:y})}catch(_){throw _ instanceof ve,_}let k=Date.now()-b,v=S.headers.get("content-type")??"",E;try{let _=S.body?.getReader();if(!_)E="";else{let T=[],A=0,C=i*2;for(;;){let{done:B,value:L}=await _.read();if(B||!L)break;if(T.push(L),A+=L.byteLength,A>=C){await _.cancel();break}}E=new TextDecoder().decode(Buffer.concat(T,A))}}catch{E=""}let{body:R,truncated:x}=vq(E,v,i),D=Sq(S.headers);return s!==void 0&&Promise.resolve(s({url:e,method:n,status:S.status,risk:d,timing_ms:k})).catch(()=>{}),{status:S.status,headers:D,body:R,truncated:x,timing_ms:k,risk:d}}function FT(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 MT,OT,Pm,Mm,mq,gq,bq,wq,LT=m(()=>{"use strict";Jn();vt();MT=3e4,OT=12e4,Pm=1e5,Mm=1e6,mq=new Set(["GET","HEAD","OPTIONS"]),gq=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]);bq=["set-cookie","x-"],wq=new Set(["server","via","age","vary","authorization","www-authenticate"])});function _q(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=FT(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=MT;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,OT)}let l=Pm;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,Mm)}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 Tq(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(()=>(an(),fm)),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=_q(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:e,lookupFn:t.lookupFn,domainCheck:p,recordEffect:t.recordEffect},g;try{g=await DT(f)}catch(S){if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};if(S instanceof ve)return{content:`web_request blocked: ${S.message}`,isError:!0};let k=S instanceof Error&&S.name==="DomainPolicyError"?"blocked":"network error",v=S instanceof Error?S.message:String(S);return{content:`web_request ${k}: ${v}`,isError:!0}}if(c.signal.aborted)return{content:`web_request aborted: ${u()}`,isError:!0};let h=g.body;if(typeof h=="string")h=ht(h);else if(typeof h=="object"&&h!==null){let S=ht(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 NT,UT=m(()=>{"use strict";LT();Jn();Cn();NT=Tq()});import{existsSync as BT,mkdirSync as Eq,readFileSync as Aq,renameSync as xq,unlinkSync as Rq,writeFileSync as Iq}from"node:fs";import{dirname as $T,join as Cq}from"node:path";import{randomBytes as Pq}from"node:crypto";function tr(t){let e=t??up();if(!BT(e))return[];try{let n=Aq(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 Ks(t,e){let n=e??up();Eq($T(n),{recursive:!0});let r=Cq($T(n),`.schedules.json.${process.pid}.${Pq(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{Iq(r,o,"utf-8"),xq(r,n)}catch(s){try{BT(r)&&Rq(r)}catch{}throw s}}function jT(t,e){let n=tr(e),r=n.map(c=>c.id),o=Mq(t.name),s=Oq(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),Ks(n,e),a}function HT(t,e){let n=tr(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(Ks(o,e),!0)}function WT(t,e){return tr(e).find(n=>n.id===t)}function Mq(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function Oq(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}function KT(t){return{taskId:t.id,command:t.command,trigger:t.trigger??"cron",...t.cron!==void 0?{cronExpression:t.cron}:{},...t.notifyOn!==void 0?{notifyOn:t.notifyOn}:{},...t.notifyChat!==void 0?{notifyChat:t.notifyChat}:{}}}var qT=m(()=>{"use strict";M()});import{existsSync as Dq,readFileSync as Fq}from"node:fs";import{join as Lq}from"node:path";async function Gr(t,e,n){let r,o;try{let s=Lq(sw("default"),"port");if(!Dq(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=Fq(s,"utf-8").trim(),a=Nq(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 Nq(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 Om,GT=m(()=>{"use strict";M();Om="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 Uq}from"node:fs";import{readFile as $q}from"node:fs/promises";var XT,zT,JT,VT,YT=m(()=>{"use strict";qT();M();GT();XT=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=jT({name:n.name,command:n.command,cron:n.cron,trigger:n.trigger??"cron",notifyOn:n.notifyOn,...o!==void 0?{notifyChat:o}:{},enabled:typeof n.enabled=="boolean"?n.enabled:!0}),i=s.enabled?await Gr("POST","/tasks",{taskId:s.id,command:s.command,cron:s.cron,trigger:s.trigger,notifyOn:s.notifyOn,...s.notifyChat!==void 0?{notifyChat:s.notifyChat}:{}}):await Gr("DELETE",`/tasks/${s.id}`);return{content:JSON.stringify({id:s.id,name:s.name,cron:s.cron,enabled:s.enabled,daemonSynced:i.synced,syncDetail:i.detail,...i.synced?{}:{syncNote:Om}})}},zT=async(t,e)=>{let n=tr();return{content:JSON.stringify(n.map(r=>({id:r.id,name:r.name,cron:r.cron,trigger:r.trigger,enabled:r.enabled,notifyOn:r.notifyOn})))}},JT=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=ga();if(!Uq(s))return{content:JSON.stringify([])};let i;try{let l=await $q(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
@@ -298,7 +298,7 @@ ${nt(t,{headless:e,latched:n})}`,{cause:t})}var cT,AK,xK,aT,IK,km=m(()=>{"use st
298
298
  ?`,"m");if(!r.test(n))return!1;let o=n.replace(r,"");return nl(t,o,384),!0}function PE(t,e){if(!Gs(t))return;let r=tl(t,"utf-8").match(new RegExp(`^${Ce(e)}=(.*)$`,"m"));return r?r[1]:void 0}function ME(t){let e={};if(!Gs(t))return e;let n=tl(t,"utf-8");for(let r of n.split(`
299
299
  `)){let o=r.trim();if(!o||o.startsWith("#"))continue;let s=o.indexOf("=");if(s<=0)continue;let i=o.slice(0,s).trim(),a=o.slice(s+1);e[i]=a}return e}var OE=m(()=>{"use strict";rr()});function rl(t){let e=Go(t);return e?NG.has(t)?"non-config":e.secret?"secret":UG.has(t)||t.endsWith("_BASE_URL")?"protected":"settable":"unknown"}function DE(t,e=$G,n=BG){let r=t.trim().toLowerCase();if(e.includes(r))return!0;if(n.includes(r))return!1}function FE(t){let e=typeof t=="number"?t:Number(t);return Number.isFinite(e)?e:void 0}function LE(t,e){if(e.includes(`
300
300
  `))return{ok:!1,error:`value for ${t.name} must not contain newlines`};switch(t.type){case"number":return FE(e)===void 0?{ok:!1,error:`${t.name} expects a number, got ${JSON.stringify(e)}`}:{ok:!0,value:e.trim()};case"boolean":{let n=e.trim().toLowerCase();return DE(n)===void 0?{ok:!1,error:`${t.name} expects a boolean (true/false/1/0/yes/no/on/off), got ${JSON.stringify(e)}`}:{ok:!0,value:n}}case"json":{try{JSON.parse(e)}catch{return{ok:!1,error:`${t.name} expects valid JSON`}}return{ok:!0,value:e}}default:return{ok:!0,value:e}}}function UE(t){return NE.get(t)}function Hm(t){let e=NE.get(t);return e?e.tier:"unknown"}function $E(t,e){switch(t.type){case"boolean":{if(typeof e=="boolean")return{ok:!0,value:e};if(typeof e=="string"){let n=DE(e);if(n!==void 0)return{ok:!0,value:n}}return{ok:!1,error:`${t.path} expects a boolean`}}case"number":{let n=typeof e=="number"||typeof e=="string"?FE(e):void 0;return n===void 0?{ok:!1,error:`${t.path} expects a number`}:t.clamp?t.clamp.integer&&!Number.isInteger(n)?{ok:!1,error:`${t.path} expects an integer`}:{ok:!0,value:Math.min(t.clamp.max,Math.max(t.clamp.min,n))}:{ok:!0,value:n}}case"enum":return typeof e=="string"&&t.enumValues?.includes(e)?{ok:!0,value:e}:{ok:!1,error:`${t.path} expects one of: ${t.enumValues?.join(", ")}`};case"number-array":{let n;if(Array.isArray(e))n=e;else if(typeof e=="string")n=e.split(",").map(o=>o.trim()).filter(o=>o.length>0).map(o=>Number(o));else return{ok:!1,error:`${t.path} expects an array of numbers`};let r=[];for(let o of n){let s=typeof o=="number"?o:Number(o);if(!Number.isFinite(s))return{ok:!1,error:`${t.path} contains a non-number`};r.push(s)}return{ok:!0,value:r}}case"model-slot":{if(typeof e=="string")return e.trim().length===0?{ok:!1,error:`${t.path} must not be empty`}:{ok:!0,value:e.trim()};let n=Fw(e);return n.ok?{ok:!0,value:n.value}:{ok:!1,error:`${t.path}: ${n.error}`}}default:return typeof e!="string"?{ok:!1,error:`${t.path} expects a string`}:e.trim().length===0?{ok:!1,error:`${t.path} must not be empty`}:{ok:!0,value:e}}}function BE(t,e){let n=t;for(let r of e.split(".")){if(n===null||typeof n!="object")return;n=n[r]}return n}function jE(t,e,n){let r=e.split("."),o=t;for(let s=0;s<r.length-1;s++){let i=r[s],a=o[i];(a===null||typeof a!="object"||Array.isArray(a))&&(o[i]={}),o=o[i]}o[r[r.length-1]]=n}function HE(t,e){let n=e.split("."),r=[t],o=t;for(let i=0;i<n.length-1;i++){let a=n[i],c=o[a];if(c===null||typeof c!="object"||Array.isArray(c))return!1;o=c,r.push(o)}let s=n[n.length-1];if(!(s in o))return!1;delete o[s];for(let i=r.length-1;i>=1;i--){let a=r[i];if(Object.keys(a).length===0){let c=n[i-1];delete r[i-1][c]}else break}return!0}var NG,UG,$G,BG,jG,NE,WE=m(()=>{"use strict";P();Te();NG=new Set(["HOME","PATH","SHELL","PAGER","NODE_ENV","CI","VITEST","DEBUG","FORCE_COLOR","NO_COLOR","AGENT_SURFACE","AFK_SESSION_ID","NO_UPDATE_NOTIFIER","SCRIPT","ASCIINEMA_REC"]),UG=new Set(["AFK_MODEL_SMALL_BASE_URL","AFK_MODEL_MEDIUM_BASE_URL","AFK_MODEL_LARGE_BASE_URL","AFK_LOCAL_BASE_URL","AFK_OPENAI_BASE_URL","AFK_SYSTEM_PROMPT","AFK_DAEMON_TASK","AFK_DAEMON_TASK_ID","AFK_DAEMON_CWD","AFK_DAEMON_HOST","AFK_BROWSER_ALLOWED_DOMAINS","AFK_BROWSER_BLOCKED_DOMAINS","AFK_BROWSER_CONFIG","AFK_ALLOW_PROJECT_MCP","AFK_INTERNAL","AFK_WORKTREE_BASE","AFK_WORKTREE_BRANCH_PREFIX","AFK_WORKTREE_ON_EXIT","AFK_TELEGRAM_ALLOWED_CHAT_IDS","AFK_TELEGRAM_TAG_ONLY_CHAT_IDS","AFK_TELEGRAM_NOTIFY_MODE","AFK_TELEGRAM_PRIMARY_CHAT_ID","AFK_HOME","AFK_STATE_DIR","AFK_FRAMEWORK_DIR","TELEGRAM_DATA_DIR","AFK_TELEGRAM_CWD"]);$G=["true","1","yes","on"],BG=["false","0","no","off"];jG=[{path:"model",tier:"agent",type:"string",description:"Default model id / alias."},{path:"models.local",tier:"agent",type:"model-slot",description:"Local-tier model id (OpenAI-compatible shim: Ollama, LM Studio, vLLM, MLX). Accepts a bare id string or a { id, provider, name } object (provider: anthropic | openai | chatgpt-oauth | xai | xai-oauth \u2014 chatgpt is accepted shorthand; baseUrl/apiKey are human-gated: set them via the AFK_MODEL_<TIER>_BASE_URL / _API_KEY env vars, not here)."},{path:"models.small",tier:"agent",type:"model-slot",description:"Small-tier model id. Accepts a bare id string or a { id, provider, name } object (provider: anthropic | openai | chatgpt-oauth | xai | xai-oauth \u2014 chatgpt is accepted shorthand; baseUrl/apiKey are human-gated: set them via the AFK_MODEL_<TIER>_BASE_URL / _API_KEY env vars, not here)."},{path:"models.medium",tier:"agent",type:"model-slot",description:"Medium-tier model id. Accepts a bare id string or a { id, provider, name } object (provider: anthropic | openai | chatgpt-oauth | xai | xai-oauth \u2014 chatgpt is accepted shorthand; baseUrl/apiKey are human-gated: set them via the AFK_MODEL_<TIER>_BASE_URL / _API_KEY env vars, not here)."},{path:"models.large",tier:"agent",type:"model-slot",description:"Large-tier model id. Accepts a bare id string or a { id, provider, name } object (provider: anthropic | openai | chatgpt-oauth | xai | xai-oauth \u2014 chatgpt is accepted shorthand; baseUrl/apiKey are human-gated: set them via the AFK_MODEL_<TIER>_BASE_URL / _API_KEY env vars, not here)."},{path:"maxTokens",tier:"agent",type:"number",clamp:{min:1,max:1e6,integer:!0},description:"Deprecated and inert: not read by the generation path. Use AFK_MAX_OUTPUT_TOKENS or --max-output-tokens to cap per-response output."},{path:"temperature",tier:"agent",type:"number",clamp:{min:0,max:2},description:"Sampling temperature."},{path:"autoRouting.interactive",tier:"agent",type:"boolean",description:"Auto-route model in the REPL."},{path:"autoRouting.chat",tier:"agent",type:"boolean",description:"Auto-route model for chat."},{path:"autoRouting.telegram",tier:"agent",type:"boolean",description:"Auto-route model for Telegram."},{path:"autoRouting.daemon",tier:"agent",type:"boolean",description:"Auto-route model for the daemon."},{path:"telegram.notify.mode",tier:"human",type:"enum",enumValues:["primary","broadcast","custom"],description:"Telegram notify routing mode (human-tier: notification-redirect vector)."},{path:"telegram.notify.primaryChatId",tier:"human",type:"number",clamp:{min:-1e15,max:1e15,integer:!0},description:"Primary Telegram chat id (human-tier: notification-redirect vector)."},{path:"telegram.notify.targets",tier:"human",type:"number-array",description:"Custom Telegram target chat ids (human-tier: notification-redirect vector)."},{path:"telegram.tagOnlyChats",tier:"human",type:"number-array",description:"Chat ids where the bot answers only when addressed (reply to the bot, @mention, or text_mention resolving to the bot). Human-tier: it governs which chats the bot will respond in \u2014 a message-routing / who-can-drive-the-bot control, same class as the allowlist and telegram.notify.*. Requires Telegram privacy mode OFF for the bot to matter in groups."},{path:"telegram.verifyDone",tier:"human",type:"boolean",description:`Opt-in AFK "Done" verification gate (human-tier: a self-honesty check on the agent's own completion reporting \u2014 the agent must not be able to disable it on its own config, same rationale as enableShellHooks/permissionMode).`},{path:"enforceDoneEvidence",tier:"human",type:"boolean",description:'Opt-in AFK terminal-state enforcement gate: in autonomous mode a turn that self-certifies "Done" with no corroborating evidence (a successful file write/edit or executed command) gets a framework correction injected into the next turn, which must substantiate or downgrade the claim (issue #237). Human-tier: a self-honesty check the agent must not be able to disable on its own config, same rationale as telegram.verifyDone. Sibling of telegram.verifyDone (which only relabels the Telegram push; this one bounces the turn).'},{path:"interactive.worktreeAutoname",tier:"agent",type:"boolean",description:"Auto-name worktrees."},{path:"interactive.suggestGhost",tier:"agent",type:"boolean",description:"Ghost-text suggestions in the REPL."},{path:"interactive.thinkingUi",tier:"agent",type:"enum",enumValues:["summary","live","digest","off"],description:"Default REPL thinking-display mode."},{path:"theme",tier:"agent",type:"enum",enumValues:["dark","light","umber","auto"],description:"TUI color palette (dark | light | umber | auto). Display-only; auto detects a light/dark background from the terminal and falls back to dark. umber matches the Umber terminal and is dark-only, so auto never selects it."},{path:"updatePolicy",tier:"human",type:"enum",enumValues:["notify","auto","off"],description:"Self-update policy (human-tier: auto self-update is scope-widening)."},{path:"autoResumeOnUsageLimit",tier:"agent",type:"boolean",description:"Auto-resume after a usage-limit pause."},{path:"bgSummaries",tier:"agent",type:"boolean",description:"Background summarisation."},{path:"maxSummaryCallsPerSession",tier:"agent",type:"number",clamp:{min:1,max:500,integer:!0},description:"Cap on summary calls per session."},{path:"systemPrompt",tier:"human",type:"string",description:"Operator system-prompt overlay."},{path:"permissionMode",tier:"human",type:"enum",enumValues:["default","plan","autonomous","bypassPermissions"],description:"Session permission mode for afk chat/interactive (human-tier: privilege-escalation vector). Unset \u2192 bypassPermissions (new-install default); set `default` to re-enable path containment + the approval prompt."},{path:"enableShellHooks",tier:"human",type:"boolean",description:"Enable shell hooks (trust gate)."},{path:"enablePluginHooks",tier:"human",type:"boolean",description:"Enable Claude Code plugin-contributed hooks (trust gate for third-party plugin hooks.json; independent of enableShellHooks)."},{path:"interactive.worktreeBranchPrefix",tier:"human",type:"string",description:"Worktree branch prefix (git-flag sensitive)."},{path:"interactive.worktreeBase",tier:"human",type:"string",description:"Worktree base ref (git-flag sensitive)."},{path:"interactive.worktreeOnExit",tier:"human",type:"enum",enumValues:["ask","keep","remove"],description:"Clean-worktree quit policy (ask | keep | remove)."},{path:"daemon.task",tier:"human",type:"string",description:"Daemon task prompt."},{path:"daemon.taskId",tier:"human",type:"string",description:"Daemon task id."},{path:"daemon.verifyDone",tier:"human",type:"boolean",description:`Opt-in daemon-surface "Done" verification gate: a cron-tick completion push whose response self-certifies "Done" with no corroborating evidence (a successful file write/edit or executed command) is relabelled "\u26A0\uFE0F Done (unverified)" with a caveat line. The daemon analog of telegram.verifyDone (which is REPL-only); the daemon is single-turn-per-tick, so the only honest enforcement is relabelling the outgoing push rather than bouncing a next turn. Human-tier: a self-honesty check on the agent's own completion reporting \u2014 the agent must not be able to disable it on its own config, same rationale as telegram.verifyDone.`}],NE=new Map(jG.map(t=>[t.path,t]))});import{existsSync as KE,readFileSync as HG,copyFileSync as WG,chmodSync as KG}from"fs";function Xm(t){return t===void 0||t.length===0?"<unset>":t.length<=4?"set (****)":`set (****${t.slice(-4)})`}function il(t){return t?.filePath??pp()}function qE(t,e,n){let r=rl(t);if(r==="unknown")throw new Xs(t);if(r==="non-config")throw new Wm(t);if(r==="secret"&&!e)throw new Km(t);if(r==="protected"&&!n)throw new qm(t);return r}function GE(t,e,n){let r=qE(t,n?.allowSecret,n?.allowProtected),o=Go(t),s=LE(o,e);if(!s.ok)throw new ol(s.error);let i=il(n);return IE(i,t,s.value),{key:t,class:r,persistedTo:i,display:r==="secret"?Xm(s.value):s.value}}function XE(t,e){let n=qE(t,e?.allowSecret,e?.allowProtected),r=il(e),o=CE(r,t);return{key:t,class:n,removed:o,persistedTo:r}}function zE(t,e){let n=rl(t);if(n==="unknown")throw new Xs(t);let r=il(e),o=PE(r,t),s=ma(t),i=n==="secret"?o!==void 0?Xm(o):void 0:o;return{key:t,class:n,persisted:i,activeInProcess:s}}function JE(t){let e=il(t),n=ME(e),r=[];for(let o of Xo){let s=o.name,i=rl(s),a=n[s],c=ma(s);if(!t?.all&&a===void 0&&!c)continue;let l=i==="secret"?a!==void 0?Xm(a):void 0:a;r.push({key:s,class:i,persisted:l,activeInProcess:c})}return r}function al(t){return t?.filePath??hr()}function cl(t){if(!KE(t))return{};let e;try{e=JSON.parse(HG(t,"utf-8"))}catch{throw new sl(t)}if(e===null||typeof e!="object"||Array.isArray(e))throw new sl(t);return e}function VE(t,e){if(KE(t))try{WG(t,`${t}.bak`),KG(`${t}.bak`,384)}catch{}nl(t,JSON.stringify(e,null,2)+`
301
- `,384)}function YE(t,e){let n=Hm(t);if(n==="unknown")throw new Xs(t);if(n==="human"&&!e)throw new Gm(t);return n}function QE(t,e,n){let r=YE(t,n?.allowHumanOnly),o=UE(t),s=$E(o,e);if(!s.ok)throw new ol(s.error);let i=al(n),a=cl(i);return jE(a,t,s.value),VE(i,a),{path:t,class:r,value:s.value,persistedTo:i}}function ZE(t,e){let n=YE(t,e?.allowHumanOnly),r=al(e),o=cl(r),s=HE(o,t);return s&&VE(r,o),{path:t,class:n,removed:s,persistedTo:r}}function eA(t,e){let n=Hm(t),r=al(e),o=cl(r);return{path:t,class:n,value:BE(o,t)}}function tA(t){return cl(al(t))}var zs,Xs,Wm,Km,qm,Gm,ol,sl,nA=m(()=>{"use strict";M();P();OE();WE();zs="effective on the next session/daemon restart; the current session is unchanged",Xs=class extends Error{constructor(e){super(`unknown config key: ${e}`),this.name="UnknownKeyError"}},Wm=class extends Error{constructor(e){super(`${e} is a process/inherited env var and is not afk-configurable`),this.name="NonConfigKeyError"}},Km=class extends Error{constructor(e){super(`${e} holds a credential; the agent cannot set it. A human must run \`afk config env set ${e}\` (the value is entered masked and never enters the model context).`),this.name="SecretWriteRefused"}},qm=class extends Error{constructor(e){super(`${e} controls identity, safety, capability, autonomous runs, request routing, or where AFK's own state lives; the agent cannot set it. A human must run \`afk config env set ${e}\`.`),this.name="ProtectedEnvKeyRefused"}},Gm=class extends Error{constructor(e){super(`${e} is human-gated (prompt/hooks/identity); the agent cannot set it. A human must run \`afk config set ${e}\`.`),this.name="HumanOnlyKeyRefused"}},ol=class extends Error{constructor(e){super(e),this.name="ConfigValidationError"}},sl=class extends Error{constructor(e){super(`refusing to write: existing ${e} is not valid JSON (fix or remove it by hand first)`),this.name="MalformedConfigError"}}});function rA(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function oA(t){return t==="env"||t==="config"?t:void 0}function Ut(t){return{content:t,isError:!0}}var sA,iA,aA=m(()=>{"use strict";nA();sA=async t=>{let e=rA(t);if(!e)return Ut("config_get: expected an object input");let n=oA(e.target);if(!n)return Ut("config_get: `target` must be 'env' or 'config'");let r=typeof e.key=="string"?e.key:void 0,o=e.all===!0;try{if(n==="env"){if(r){let s=zE(r);return{content:JSON.stringify(s,null,2)}}return{content:JSON.stringify(JE({all:o}),null,2)}}if(r){let s=eA(r);return{content:JSON.stringify(s,null,2)}}return{content:JSON.stringify(tA(),null,2)}}catch(s){return Ut(`config_get: ${s.message}`)}},iA=async t=>{let e=rA(t);if(!e)return Ut("config_set: expected an object input");let n=oA(e.target);if(!n)return Ut("config_set: `target` must be 'env' or 'config'");let r=typeof e.key=="string"?e.key:void 0;if(!r)return Ut("config_set: `key` is required");let o=e.action==="unset"?"unset":"set",s=e.value;try{if(o==="unset"){if(n==="env"){let c=XE(r);return{content:c.removed?`Removed ${c.key} from afk.env (${c.persistedTo}). ${zs}.`:`${c.key} was not set in afk.env; nothing to remove.`}}let a=ZE(r);return{content:a.removed?`Removed ${a.path} from afk.config.json (${a.persistedTo}). ${zs}.`:`${a.path} was not set in afk.config.json; nothing to remove.`}}if(s==null)return Ut(`config_set: \`value\` is required to set ${r}`);if(n==="env"){if(typeof s!="string"&&typeof s!="number"&&typeof s!="boolean")return Ut("config_set: env values must be a string, number, or boolean");let a=GE(r,String(s));return{content:`Set ${a.key} = ${a.display} in afk.env (${a.persistedTo}). ${zs}.`}}let i=QE(r,s);return{content:`Set ${i.path} = ${JSON.stringify(i.value)} in afk.config.json (${i.persistedTo}). ${zs}.`}}catch(i){return Ut(`config_set: ${i.message}`)}}});function or(t,e){return t.length>e?`${t.slice(0,e)}\u2026 [truncated]`:t}function zm(t){switch(t.type){case"message":return t.message.role!=="assistant"||!t.message.content?null:{kind:"assistant",text:or(t.message.content,8e3)};case"chunk":{let e=t.chunk;return e.type==="tool_use_detail"?e.pending?null:{kind:"tool",toolName:e.toolName,input:or(e.toolInput,400)}:e.type==="tool_result"?e.isError===!0?{kind:"tool_error",content:or(e.content,400)}:{kind:"tool_result",toolUseId:e.toolUseId,content:or(e.content,400),...typeof e.durationMs=="number"?{durationMs:e.durationMs}:{},...e.metadata?.toolName!==void 0?{toolName:String(e.metadata.toolName)}:{}}:e.type==="thinking"?{kind:"thinking",text:or(e.content,8e3)}:null}case"done":{let e=t.metadata,n=e?.totalCostUsd,r=e?.durationMs,o=e?.usage,s=typeof o?.input_tokens=="number"?o.input_tokens:void 0,i=typeof o?.output_tokens=="number"?o.output_tokens:void 0,a=typeof o?.cache_read_input_tokens=="number"?o.cache_read_input_tokens:void 0,c=typeof e?.stopReason=="string"?e.stopReason:void 0;return{kind:"done",...typeof n=="number"?{costUsd:n}:{},...typeof r=="number"?{durationMs:r}:{},...s!==void 0?{inputTokens:s}:{},...i!==void 0?{outputTokens:i}:{},...a!==void 0?{cacheReadTokens:a}:{},...c!==void 0?{stopReason:c}:{}}}case"error":return{kind:"error",message:t.error.message};case"paused":return{kind:"paused",...t.resetsAt?{resetsAt:t.resetsAt.toISOString()}:{}};case"resumed":return{kind:"resumed"};case"notice":return null;case"tool-activity":return{kind:"tool_activity",activeCount:t.activeCount,activeToolUseIds:t.activeToolUseIds};case"rate_limit":return{kind:"rate_limit",...typeof t.retryAfterMs=="number"?{retryAfterMs:t.retryAfterMs}:{}};case"progress":return{kind:"progress",message:t.progress.summary??t.progress.description};case"subagent_lifecycle":return{kind:"subagent_lifecycle",subagentId:t.subagentId,status:t.status,...t.model!==void 0?{model:t.model}:{},...t.agentType!==void 0?{agentType:t.agentType}:{},...t.durationMs!==void 0?{durationMs:t.durationMs}:{},...t.totalCostUsd!==void 0?{totalCostUsd:t.totalCostUsd}:{},...t.outputBytes!==void 0?{outputBytes:t.outputBytes}:{},...t.errorClass!==void 0?{errorClass:t.errorClass}:{},...t.errorMessage!==void 0?{errorMessage:t.errorMessage}:{},...t.promptHead!==void 0?{promptHead:t.promptHead}:{}};case"background_job":return{kind:"background_job",jobId:t.jobId,status:t.status,...t.label!==void 0?{label:t.label}:{}};case"plan_mode":return{kind:"plan_mode",mode:t.mode};default:return null}}var Jm=m(()=>{"use strict"});import*as cA from"node:fs";import*as sr from"node:fs/promises";import*as lA from"node:readline";function dA(t){let e=t.trim();if(!e)return null;try{let n=JSON.parse(e);return n.v!==1||typeof n.ts!="number"||typeof n.kind!="string"?null:n}catch{return null}}async function Js(t){if(!In(t))return!1;try{return await sr.access(wr(t)),!0}catch{return!1}}async function*Vm(t){if(!In(t))return;let e;try{e=await sr.open(wr(t),"r")}catch(n){if(n.code==="ENOENT")return;throw n}try{let n=lA.createInterface({input:e.createReadStream({encoding:"utf8"}),crlfDelay:1/0});for await(let r of n){let o=dA(r);o&&(yield o)}}finally{await e.close()}}async function*Ym(t,e){if(!In(t))return;let n=wr(t),r=br(t),{fromStart:o=!1,signal:s}=e??{},i=0,a="",c=!1;async function*l(){let f=null;try{f=await sr.open(n,"r");let g=await f.stat();if(g.size<=i)return;let h=g.size-i,y=Buffer.allocUnsafe(h),{bytesRead:b}=await f.read(y,0,h,i);if(b===0)return;i+=b,a+=y.toString("utf8",0,b);let S=a.split(`
301
+ `,384)}function YE(t,e){let n=Hm(t);if(n==="unknown")throw new Xs(t);if(n==="human"&&!e)throw new Gm(t);return n}function QE(t,e,n){let r=YE(t,n?.allowHumanOnly),o=UE(t),s=$E(o,e);if(!s.ok)throw new ol(s.error);let i=al(n),a=cl(i);return jE(a,t,s.value),VE(i,a),{path:t,class:r,value:s.value,persistedTo:i}}function ZE(t,e){let n=YE(t,e?.allowHumanOnly),r=al(e),o=cl(r),s=HE(o,t);return s&&VE(r,o),{path:t,class:n,removed:s,persistedTo:r}}function eA(t,e){let n=Hm(t),r=al(e),o=cl(r);return{path:t,class:n,value:BE(o,t)}}function tA(t){return cl(al(t))}var zs,Xs,Wm,Km,qm,Gm,ol,sl,nA=m(()=>{"use strict";M();P();OE();WE();zs="effective on the next session/daemon restart; the current session is unchanged",Xs=class extends Error{constructor(e){super(`unknown config key: ${e}`),this.name="UnknownKeyError"}},Wm=class extends Error{constructor(e){super(`${e} is a process/inherited env var and is not afk-configurable`),this.name="NonConfigKeyError"}},Km=class extends Error{constructor(e){super(`${e} holds a credential; the agent cannot set it. A human must run \`afk config env set ${e}\` (the value is entered masked and never enters the model context).`),this.name="SecretWriteRefused"}},qm=class extends Error{constructor(e){super(`${e} controls identity, safety, capability, autonomous runs, request routing, or where AFK's own state lives; the agent cannot set it. A human must run \`afk config env set ${e}\`.`),this.name="ProtectedEnvKeyRefused"}},Gm=class extends Error{constructor(e){super(`${e} is human-gated (prompt/hooks/identity); the agent cannot set it. A human must run \`afk config set ${e}\`.`),this.name="HumanOnlyKeyRefused"}},ol=class extends Error{constructor(e){super(e),this.name="ConfigValidationError"}},sl=class extends Error{constructor(e){super(`refusing to write: existing ${e} is not valid JSON (fix or remove it by hand first)`),this.name="MalformedConfigError"}}});function rA(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)?t:void 0}function oA(t){return t==="env"||t==="config"?t:void 0}function Ut(t){return{content:t,isError:!0}}var sA,iA,aA=m(()=>{"use strict";nA();sA=async t=>{let e=rA(t);if(!e)return Ut("config_get: expected an object input");let n=oA(e.target);if(!n)return Ut("config_get: `target` must be 'env' or 'config'");let r=typeof e.key=="string"?e.key:void 0,o=e.all===!0;try{if(n==="env"){if(r){let s=zE(r);return{content:JSON.stringify(s,null,2)}}return{content:JSON.stringify(JE({all:o}),null,2)}}if(r){let s=eA(r);return{content:JSON.stringify(s,null,2)}}return{content:JSON.stringify(tA(),null,2)}}catch(s){return Ut(`config_get: ${s.message}`)}},iA=async t=>{let e=rA(t);if(!e)return Ut("config_set: expected an object input");let n=oA(e.target);if(!n)return Ut("config_set: `target` must be 'env' or 'config'");let r=typeof e.key=="string"?e.key:void 0;if(!r)return Ut("config_set: `key` is required");let o=e.action==="unset"?"unset":"set",s=e.value;try{if(o==="unset"){if(n==="env"){let c=XE(r);return{content:c.removed?`Removed ${c.key} from afk.env (${c.persistedTo}). ${zs}.`:`${c.key} was not set in afk.env; nothing to remove.`}}let a=ZE(r);return{content:a.removed?`Removed ${a.path} from afk.config.json (${a.persistedTo}). ${zs}.`:`${a.path} was not set in afk.config.json; nothing to remove.`}}if(s==null)return Ut(`config_set: \`value\` is required to set ${r}`);if(n==="env"){if(typeof s!="string"&&typeof s!="number"&&typeof s!="boolean")return Ut("config_set: env values must be a string, number, or boolean");let a=GE(r,String(s));return{content:`Set ${a.key} = ${a.display} in afk.env (${a.persistedTo}). ${zs}.`}}let i=QE(r,s);return{content:`Set ${i.path} = ${JSON.stringify(i.value)} in afk.config.json (${i.persistedTo}). ${zs}.`}}catch(i){return Ut(`config_set: ${i.message}`)}}});function or(t,e){return t.length>e?`${t.slice(0,e)}\u2026 [truncated]`:t}function zm(t){switch(t.type){case"message":return t.message.role!=="assistant"||!t.message.content?null:{kind:"assistant",text:or(t.message.content,8e3)};case"chunk":{let e=t.chunk;return e.type==="tool_use_detail"?e.pending?null:{kind:"tool",toolName:e.toolName,toolUseId:e.toolUseId,input:or(e.toolInput,400)}:e.type==="tool_result"?e.isError===!0?{kind:"tool_error",content:or(e.content,400),...e.metadata?.toolName!==void 0?{toolName:String(e.metadata.toolName)}:{}}:{kind:"tool_result",toolUseId:e.toolUseId,content:or(e.content,400),...typeof e.durationMs=="number"?{durationMs:e.durationMs}:{},...e.metadata?.toolName!==void 0?{toolName:String(e.metadata.toolName)}:{}}:e.type==="thinking"?{kind:"thinking",text:or(e.content,8e3)}:null}case"done":{let e=t.metadata,n=e?.totalCostUsd,r=e?.durationMs,o=e?.usage,s=typeof o?.input_tokens=="number"?o.input_tokens:void 0,i=typeof o?.output_tokens=="number"?o.output_tokens:void 0,a=typeof o?.cache_read_input_tokens=="number"?o.cache_read_input_tokens:void 0,c=typeof e?.stopReason=="string"?e.stopReason:void 0;return{kind:"done",...typeof n=="number"?{costUsd:n}:{},...typeof r=="number"?{durationMs:r}:{},...s!==void 0?{inputTokens:s}:{},...i!==void 0?{outputTokens:i}:{},...a!==void 0?{cacheReadTokens:a}:{},...c!==void 0?{stopReason:c}:{}}}case"error":return{kind:"error",message:t.error.message};case"paused":return{kind:"paused",...t.resetsAt?{resetsAt:t.resetsAt.toISOString()}:{}};case"resumed":return{kind:"resumed"};case"notice":return null;case"tool-activity":return{kind:"tool_activity",activeCount:t.activeCount,activeToolUseIds:t.activeToolUseIds};case"rate_limit":return{kind:"rate_limit",...typeof t.retryAfterMs=="number"?{retryAfterMs:t.retryAfterMs}:{}};case"progress":return{kind:"progress",message:t.progress.summary??t.progress.description};case"subagent_lifecycle":return{kind:"subagent_lifecycle",subagentId:t.subagentId,status:t.status,...t.model!==void 0?{model:t.model}:{},...t.agentType!==void 0?{agentType:t.agentType}:{},...t.durationMs!==void 0?{durationMs:t.durationMs}:{},...t.totalCostUsd!==void 0?{totalCostUsd:t.totalCostUsd}:{},...t.outputBytes!==void 0?{outputBytes:t.outputBytes}:{},...t.errorClass!==void 0?{errorClass:t.errorClass}:{},...t.errorMessage!==void 0?{errorMessage:t.errorMessage}:{},...t.promptHead!==void 0?{promptHead:t.promptHead}:{}};case"background_job":return{kind:"background_job",jobId:t.jobId,status:t.status,...t.label!==void 0?{label:t.label}:{}};case"plan_mode":return{kind:"plan_mode",mode:t.mode};default:return null}}var Jm=m(()=>{"use strict"});import*as cA from"node:fs";import*as sr from"node:fs/promises";import*as lA from"node:readline";function dA(t){let e=t.trim();if(!e)return null;try{let n=JSON.parse(e);return n.v!==1||typeof n.ts!="number"||typeof n.kind!="string"?null:n}catch{return null}}async function Js(t){if(!In(t))return!1;try{return await sr.access(wr(t)),!0}catch{return!1}}async function*Vm(t){if(!In(t))return;let e;try{e=await sr.open(wr(t),"r")}catch(n){if(n.code==="ENOENT")return;throw n}try{let n=lA.createInterface({input:e.createReadStream({encoding:"utf8"}),crlfDelay:1/0});for await(let r of n){let o=dA(r);o&&(yield o)}}finally{await e.close()}}async function*Ym(t,e){if(!In(t))return;let n=wr(t),r=br(t),{fromStart:o=!1,signal:s}=e??{},i=0,a="",c=!1;async function*l(){let f=null;try{f=await sr.open(n,"r");let g=await f.stat();if(g.size<=i)return;let h=g.size-i,y=Buffer.allocUnsafe(h),{bytesRead:b}=await f.read(y,0,h,i);if(b===0)return;i+=b,a+=y.toString("utf8",0,b);let S=a.split(`
302
302
  `);a=S.pop()??"";for(let k of S){let v=dA(k);if(v&&(v.kind==="closed"&&(c=!0),yield v,c))return}}catch(g){g.code!=="ENOENT"&&process.stderr.write(`[afk] session-ledger: tail read error for ${t}: ${String(g)}
303
303
  `)}finally{f&&await f.close().catch(()=>{})}}if(o){if(yield*l(),c)return}else try{i=(await sr.stat(n)).size}catch{}let d=null,u=null,p=()=>new Promise(f=>{let g=setTimeout(()=>{u=null,f()},qG);u=()=>{clearTimeout(g),u=null,f()},s?.addEventListener("abort",()=>{clearTimeout(g),u=null,f()},{once:!0})});try{d=cA.watch(r,{persistent:!1},()=>{u?.()})}catch{}try{for(;!s?.aborted&&!c&&(await p(),!s?.aborted);)yield*l()}finally{d?.close()}}var qG,uA=m(()=>{"use strict";M();qG=250});import*as ll from"node:fs";var cn,Vs=m(()=>{"use strict";M();Jm();Jm();uA();cn=class{sessionId;ledgerPath;stream=null;errored=!1;closed=!1;streamReady=!1;pendingLines=[];readyPromise=null;readyResolve=null;constructor(e){if(this.sessionId=e,!In(e)){this.errored=!0,this.ledgerPath="";return}this.ledgerPath=wr(e);try{ll.mkdirSync(br(e),{recursive:!0})}catch(n){process.stderr.write(`[afk] session-ledger: mkdir failed for ${e}: ${String(n)}
304
304
  `),this.errored=!0}}get active(){return!this.errored&&!this.closed}record(e){if(this.errored||this.closed)return;let n={v:1,ts:Date.now(),...e},r=JSON.stringify(n)+`