agent-afk 5.109.0 → 5.110.0

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/telegram.mjs CHANGED
@@ -211,7 +211,7 @@ ${o}`,paths:[e,n]}:o!==null?s={content:o,paths:[n]}:r!==null?s={content:r,paths:
211
211
 
212
212
  ${e}`}var tU,Xp=h(()=>{"use strict";tU=new Set(["script","style","noscript","template","svg"])});function oU(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 QS(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function sU(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 ZS(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??oU,l=n.signal??void 0,c;for(let d=0;d<=o;d++){if(l?.aborted)throw l.reason??new Error("aborted");try{let u=await t(e,n);if(!rU.has(u.status)||d===o)return u;let p=sU(u,i)??QS(d,s,i);N("[web/retryFetch] retrying",{url:e,attempt:d,status:u.status,waitMs:p}),await u.body?.cancel().catch(()=>{}),await a(p,l)}catch(u){if(l?.aborted||(c=u,d===o))throw u;let p=QS(d,s,i);N("[web/retryFetch] retrying after error",{url:e,attempt:d,waitMs:p}),await a(p,l)}}throw c??new Error("retryFetch: exhausted without a result")}var rU,ev=h(()=>{"use strict";de();rU=new Set([429,502,503,504])});import{BlockList as iU,isIP as Zp}from"node:net";import{lookup as aU}from"node:dns/promises";import{Agent as lU}from"undici";function nv(){let t=S.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function pU(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function Qp(t){let e=Zp(t);return e===0?!1:uU.check(t,e===4?"ipv4":"ipv6")}async function rv(t){return aU(t,{all:!0,verbatim:!0})}async function ef(t,e={}){if(e.allowPrivateHosts??nv())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=pU(n.hostname),o=(a,l)=>`refusing to fetch ${l} \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(Zp(r)!==0)return Qp(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??rv,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(Qp(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function ls(t,e={}){let n=await ef(t,e);if(!n.allowed)throw new ft(n.reason)}async function Za(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<=tv;i++){await ls(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??nv())?{dispatcher:fU}:{}},l=await ZS(t,s,a,r.retry??{});if(!mU.has(l.status))return l;let c=l.headers.get("location");if(c===null||c.trim()==="")return l;let d;try{d=new URL(c,l.url||s).toString()}catch{return l}await l.body?.cancel().catch(()=>{}),s=d}throw new ft(`too many redirects (>${tv}) starting from ${e}`)}var cU,dU,uU,ft,fU,tv,mU,tf=h(()=>{"use strict";$();ev();cU=[["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]],dU=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],uU=(()=>{let t=new iU;for(let[e,n]of cU)t.addSubnet(e,n,"ipv4");for(let[e,n]of dU)t.addSubnet(e,n,"ipv6");return t})(),ft=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};fU=new lU({connect:{lookup(t,e,n){rv(t).then(r=>{let o=r.find(i=>Qp(i.address));if(o!==void 0){n(new ft(`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,Zp(s.address))},r=>n(r,"",0))}}});tv=20,mU=new Set([301,302,303,307,308])});import{readFileSync as gU}from"node:fs";import{join as hU}from"path";function yU(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function ov(t,e){return yU(e).test(t)}function SU(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(bU.has(e))return!0;if(wU.has(e))return!1}return!1}function sv(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function vU(t){if(t===void 0||t===""||t==="playwright")return"playwright";throw new Error(`AFK_BROWSER_BACKEND: only "playwright" is supported in Phase 1, got: ${t}`)}function iv(t){let e=t===void 0||t.trim()===""?"default":t.trim();return bu(e),e}function kU(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function EU(t){try{return gU(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function _U(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")n.backend="playwright";else if(e.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: only "playwright" is supported in Phase 1, got: ${String(e.backend)}`);return typeof e.defaultProfile=="string"&&(n.defaultProfile=iv(e.defaultProfile)),n}function av(t){let e=t?.env??S,n=t?.readFileSync??EU,r=t?.surface??e.AGENT_SURFACE,o=SU(e.AFK_BROWSER_HEADLESS,r),s=sv(e.AFK_BROWSER_ALLOWED_DOMAINS),i=sv(e.AFK_BROWSER_BLOCKED_DOMAINS),a=kU(e.AFK_BROWSER_DOM_SNAPSHOTS),l=vU(e.AFK_BROWSER_BACKEND),c=iv(e.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:l,configPath:null,defaultProfile:c},u=e.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():hU(Dt(),"browser.json"),f=n(p);if(f===void 0)return d;let m;try{m=JSON.parse(f)}catch(y){throw new Error(`Failed to parse browser config at ${p}: ${String(y)}`)}if(typeof m!="object"||m===null||Array.isArray(m))throw new Error(`Browser config at ${p} must be a JSON object`);let g=_U(d,m);return g.configPath=p,g}function el(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(ov(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>ov(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var bU,wU,tl=h(()=>{"use strict";$();B();bU=new Set(["daemon","subagent","telegram","afk"]),wU=new Set(["repl","interactive","cli"])});import{existsSync as AU,readFileSync as TU}from"node:fs";import{createRequire as RU}from"node:module";import{dirname as xU,join as CU}from"node:path";function dv(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<IU&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function $e(t){let e=dv(t);return cv.some(n=>e.includes(n))}function MU(){try{let e=RU(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(TU(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=CU(xU(e),o);return AU(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function cs(){return lv??=MU()??PU,lv}function nf(t){return t.includes("install chromium")}function ot(t,e){let n=dv(t),r=e?.latched===!0?` ${OU}`:"";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: ${cs()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${cs()}). Or pick a different tool.${r}`}function rf(t,e,n=!1){if(!$e(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
213
213
 
214
- ${ot(t,{headless:e,latched:n})}`,{cause:t})}var cv,PU,IU,lv,OU,of=h(()=>{"use strict";cv=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],PU="pnpm exec playwright install chromium",IU=4;OU="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import zn from"node:fs";import nl from"node:path";import{randomBytes as DU}from"node:crypto";import{chromium as FU}from"playwright";function LU(){try{return"5.109.0"}catch{}try{let t=nl.resolve(import.meta.dirname,"../../../package.json"),e=zn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var NU,rl,uv=h(()=>{"use strict";of();B();de();NU=LU(),rl=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=FU.launch({headless:this.config.headless}).then(e=>(this.browser=e,this.launchPromise=void 0,this.clearLaunchFailure(),e)).catch(e=>{this.launchPromise=void 0;let n=rf(e,this.config.headless,!0);throw this.latchLaunchFailure(n),n}),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(l){s=l,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(),l;try{l=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let c=await a.content();if(s!==void 0)throw s;let d=a.url(),u=l!==null?l.status():null;return{html:c,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/${NU}`}}loadStorageState(e){let n=wu(e);try{if(!zn.existsSync(n))return;let r=JSON.parse(zn.readFileSync(n,"utf8"));return N("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){N("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=wu(e);if(!zn.existsSync(r))return;let o=await n.storageState(),s=nl.join(nl.dirname(r),`.${nl.basename(r)}.${process.pid}.${DU(4).toString("hex")}.tmp`);zn.writeFileSync(s,JSON.stringify(o),{mode:384}),zn.chmodSync(s,384),zn.renameSync(s,r),N("[browser/vault] saved session",{profile:e,file:r})}catch(r){N("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as $U}from"crypto";function pv(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&UU.test(t.label))}function fv(t){return $U("sha256").update(t,"utf8").digest("hex").slice(0,8)}function mv(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var UU,ol=h(()=>{"use strict";UU=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as BU}from"node:crypto";function jU(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function HU(t,e,n){return`el_${BU("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function WU(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function gv(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function yv(t,e){let n=t.role??"",r=t.name??"";hv.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])yv(s,e)}async function KU(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(),l=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a==="input"?o.type||null:o.getAttribute("type");r.push({name:l,tagName:a,type:c,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},bv).catch(()=>[])}async function GU(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")??"",l=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a||(n[i]??"");if(i==="input"){let g=s.type;g==="checkbox"?c="checkbox":g==="radio"?c="radio":g==="button"||g==="submit"||g==="reset"?c="button":g==="search"?c="searchbox":c="textbox"}if(!c)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,m={role:c,name:l,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},bv).catch(()=>[])}function qU(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function sl(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=qU(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=KU(t),l=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),c=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,l,c,d]),y,w=!1;u!==null?(y=[],yv(u,y)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,y=(await GU(t)).filter(U=>hv.has(U.role??"")));let k=new Map;for(let P of p){let U=gv(P.name),J=k.get(U);(!J||J.bbox.w===0&&P.bbox.w>0)&&k.set(U,P)}let T=y.map(P=>({ax:P,dom:k.get(gv(P.name??""))})),E=r?T:T.filter(P=>P.dom?P.dom.bbox.w>0||P.dom.bbox.h>0:!0);E.sort((P,U)=>{let J=P.dom?.bbox.y??0,I=U.dom?.bbox.y??0;if(J!==I)return J-I;let j=P.dom?.bbox.x??0,L=U.dom?.bbox.x??0;return j-L}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let A=E.slice(0,n).map((P,U)=>{let J=P.ax.role??"generic",I=P.ax.name??"",j=HU(J,I,U),L=P.dom?.bbox??{x:0,y:0,w:0,h:0},M=P.dom?.type??null,F=null;P.ax.value!==void 0&&P.ax.value!==null&&(F=String(P.ax.value)),P.ax.checked!==void 0&&(F=String(P.ax.checked)),pv({role:J,kind:M})&&(F="[redacted]");let H={disabled:P.ax.disabled??!1};P.ax.checked!==void 0&&(H.checked=P.ax.checked===!0||P.ax.checked==="mixed"),P.ax.selected!==void 0&&(H.selected=P.ax.selected),P.ax.expanded!==void 0&&(H.expanded=P.ax.expanded);let X;P.dom?.testId?X=`[data-testid="${P.dom.testId}"]`:P.dom?.id&&(X=`#${P.dom.id}`);let ee={id:j,role:J,label:jU(I),kind:M,value:F,state:H,bbox:L};return X!==void 0&&(ee.selector=X),ee}),C="idle";try{let P=await t.evaluate(()=>document.readyState);P==="loading"?C="loading":P==="interactive"?C="navigating":C="idle"}catch{C="navigating"}C!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),w&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let x=WU(f),v=`obs_${e.observationCounter.toString(36)}`,R=new Date().toISOString();return{observationId:v,url:m,title:g,textSummary:x,interactive:A,status:{httpStatus:e.httpStatus??null,loadingState:C,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:R}}var hv,bv,wv=h(()=>{"use strict";ol();hv=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);bv="a[href], button, input, select, textarea, [role], [tabindex], label"});async function Sv(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,l=a.getAttribute("role")??a.tagName.toLowerCase(),c=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:l,label:c,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 sf(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>Sv(t,s)))).filter(o=>o!==null)}async function zU(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 l=a,c=l.getBoundingClientRect();return`${l.tagName}@${Math.round(c.x)},${Math.round(c.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function af(t,e,n){switch(e.kind){case"element_id":return VU(t,e,n);case"selector":return JU(t,e);case"semantic":return YU(t,e)}}async function VU(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 l=t.locator(r.selector);if(await l.count()===1)return{outcome:"resolved",locator:l}}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 sf(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function JU(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 sf(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function YU(t,e){return e.role!==void 0?XU(t,e.text,e.role):QU(t,e.text,e)}async function XU(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 sf(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function QU(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,l]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+l===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}),l>0&&d.push({loc:s,count:l});let u=await zU(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let y=p[g];if(y===void 0)continue;let w=await Sv(y.locator,y.index);if(w!==null){let k=`${w.role}:${w.label}:${g}`,T=0;for(let E=0;E<k.length;E++)T=T*31+k.charCodeAt(E)>>>0;f.push({...w,id:`el_${T.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var vv=h(()=>{"use strict"});async function lf(t,e,n,r){let o=t.url();if(o===n)return null;let s=el(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 kv=h(()=>{"use strict";tl()});import{randomBytes as ZU}from"crypto";import{mkdir as eB,stat as tB,writeFile as nB}from"fs/promises";import{join as cf}from"path";import{gzip as rB}from"zlib";import{promisify as oB}from"util";function sB(t){return cf(_n(t),"browser")}function iB(t){return cf(sB(t),"screenshots")}function aB(){return new Date().toISOString().replace(/[:.]/g,"-")}function lB(){return ZU(3).toString("hex")}async function df(t,e,n){if(e.length>Ev)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Ev} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=iB(t);await eB(r,{recursive:!0});let o=`${aB()}-${lB()}-${n}.png`,s=cf(r,o);await nB(s,e);let{size:i}=await tB(s);return{path:s,bytes:i}}var x7,Ev,_v=h(()=>{"use strict";B();ol();x7=oB(rB);Ev=5*1024*1024});var Tv={};du(Tv,{PlaywrightProvider:()=>uf});function Av(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 uf,Rv=h(()=>{"use strict";uv();wv();vv();tl();kv();_v();uf=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new rl(e)}async open(e){let n=el(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 l=o.url();if(!(a!==null&&(l===""||l==="about:blank"))){let u=await lf(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 sl(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 sl(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 af(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${Av(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:l}=a,c=null,d=async()=>{switch(e.action){case"click":await l.click({timeout:i});break;case"fill":await l.fill(e.value??"");break;case"press":await l.press(e.value??"");break;case"select":await l.selectOption(e.value??"");break;case"hover":await l.hover({timeout:i});break;case"scroll_to":await l.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await l.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(y){c=y}else c=g}let u=await lf(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||c!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await sl(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),c!==null)throw c;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 af(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${Av(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 df(n,s,"browser_screenshot"),l=0,c=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));l=d.w,c=d.h}catch{let d=r.viewportSize();l=d?.width??0,c=d?.height??0}else{let d=r.viewportSize();l=d?.width??0,c=d?.height??0}return{path:i,bytes:a,width:l,height:c,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 df(n,o,r);return s}catch{return null}}}});var Jn={};du(Jn,{__resetBrowserRegistryForTests:()=>fB,browserProviderActive:()=>uB,closeBrowserProvider:()=>pf,getBrowserProvider:()=>dB,peekBrowserProvider:()=>pB});function xv(){Promise.resolve(pf()).then(()=>{process.exit(130)})}function Cv(){Promise.resolve(pf()).then(()=>{process.exit(143)})}function Pv(){Rt=null}function cB(){il||(process.on("SIGINT",xv),process.on("SIGTERM",Cv),process.on("exit",Pv),il=!0)}function Iv(){il&&(process.removeListener("SIGINT",xv),process.removeListener("SIGTERM",Cv),process.removeListener("exit",Pv),il=!1)}async function dB(t){return Rt!==null?Rt:(Vn!==null||(Vn=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(Rv(),Tv)),n=av(t),r=new e(n);return cB(),Rt=r,Vn=null,r})()),Vn)}async function pf(){if(Rt===null)return;let t=Rt;Rt=null,Vn=null,Iv(),await t.shutdown()}function uB(){return Rt!==null}function pB(){return Rt}function fB(){Rt=null,Vn=null,Iv()}var Rt,Vn,il,Yn=h(()=>{"use strict";tl();Rt=null,Vn=null,il=!1});async function Mv(t,e){try{return await JS(t,e)}catch(n){return N("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function wB(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Yn(),Jn));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function Ov(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??wB,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,l=null,c=null;try{let u=await Za(n,t,{headers:bB,signal:e.signal},o);l=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(yB.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(hB.test(p)&&!gB.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await Mv(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof ft||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;c=u}if(!(s===null||s.textLength<200)&&s!==null){let u=Yp({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await ls(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>ls(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await ls(u.finalUrl,o);let p=await Mv(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=Yp({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 ft)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=c instanceof Error?c.message:`HTTP ${l??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${l??"error"}).`)}var gB,hB,yB,bB,Dv=h(()=>{"use strict";YS();Xp();tf();de();gB=/(text\/html|application\/xhtml\+xml)/i,hB=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,yB=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,bB={"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 kB(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(SB,{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),vB),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let l="";try{let d=await s.text(),u=ke(d);u&&(l=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let c=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${c}${l}`)}let i;try{i=await s.json()}catch(l){throw new Error(`Exa Search response was not JSON: ${l instanceof Error?l.message:String(l)}`)}return(i.results??[]).slice(0,r).map(l=>({title:(l.title??"").trim()||"(untitled)",url:l.url??"",description:(l.highlights?.[0]??"").trim()})).filter(l=>l.url.length>0)}}}function Fv(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?kB({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 Lv(t,e){if(e.length===0)return`# Search results for "${t}"
214
+ ${ot(t,{headless:e,latched:n})}`,{cause:t})}var cv,PU,IU,lv,OU,of=h(()=>{"use strict";cv=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],PU="pnpm exec playwright install chromium",IU=4;OU="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import zn from"node:fs";import nl from"node:path";import{randomBytes as DU}from"node:crypto";import{chromium as FU}from"playwright";function LU(){try{return"5.110.0"}catch{}try{let t=nl.resolve(import.meta.dirname,"../../../package.json"),e=zn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var NU,rl,uv=h(()=>{"use strict";of();B();de();NU=LU(),rl=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=FU.launch({headless:this.config.headless}).then(e=>(this.browser=e,this.launchPromise=void 0,this.clearLaunchFailure(),e)).catch(e=>{this.launchPromise=void 0;let n=rf(e,this.config.headless,!0);throw this.latchLaunchFailure(n),n}),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(l){s=l,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(),l;try{l=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let c=await a.content();if(s!==void 0)throw s;let d=a.url(),u=l!==null?l.status():null;return{html:c,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/${NU}`}}loadStorageState(e){let n=wu(e);try{if(!zn.existsSync(n))return;let r=JSON.parse(zn.readFileSync(n,"utf8"));return N("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){N("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=wu(e);if(!zn.existsSync(r))return;let o=await n.storageState(),s=nl.join(nl.dirname(r),`.${nl.basename(r)}.${process.pid}.${DU(4).toString("hex")}.tmp`);zn.writeFileSync(s,JSON.stringify(o),{mode:384}),zn.chmodSync(s,384),zn.renameSync(s,r),N("[browser/vault] saved session",{profile:e,file:r})}catch(r){N("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as $U}from"crypto";function pv(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&UU.test(t.label))}function fv(t){return $U("sha256").update(t,"utf8").digest("hex").slice(0,8)}function mv(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var UU,ol=h(()=>{"use strict";UU=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as BU}from"node:crypto";function jU(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function HU(t,e,n){return`el_${BU("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function WU(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function gv(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function yv(t,e){let n=t.role??"",r=t.name??"";hv.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])yv(s,e)}async function KU(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(),l=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a==="input"?o.type||null:o.getAttribute("type");r.push({name:l,tagName:a,type:c,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},bv).catch(()=>[])}async function GU(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")??"",l=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a||(n[i]??"");if(i==="input"){let g=s.type;g==="checkbox"?c="checkbox":g==="radio"?c="radio":g==="button"||g==="submit"||g==="reset"?c="button":g==="search"?c="searchbox":c="textbox"}if(!c)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,m={role:c,name:l,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},bv).catch(()=>[])}function qU(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function sl(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=qU(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=KU(t),l=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),c=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,l,c,d]),y,w=!1;u!==null?(y=[],yv(u,y)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,y=(await GU(t)).filter(U=>hv.has(U.role??"")));let k=new Map;for(let P of p){let U=gv(P.name),J=k.get(U);(!J||J.bbox.w===0&&P.bbox.w>0)&&k.set(U,P)}let T=y.map(P=>({ax:P,dom:k.get(gv(P.name??""))})),E=r?T:T.filter(P=>P.dom?P.dom.bbox.w>0||P.dom.bbox.h>0:!0);E.sort((P,U)=>{let J=P.dom?.bbox.y??0,I=U.dom?.bbox.y??0;if(J!==I)return J-I;let j=P.dom?.bbox.x??0,L=U.dom?.bbox.x??0;return j-L}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let A=E.slice(0,n).map((P,U)=>{let J=P.ax.role??"generic",I=P.ax.name??"",j=HU(J,I,U),L=P.dom?.bbox??{x:0,y:0,w:0,h:0},M=P.dom?.type??null,F=null;P.ax.value!==void 0&&P.ax.value!==null&&(F=String(P.ax.value)),P.ax.checked!==void 0&&(F=String(P.ax.checked)),pv({role:J,kind:M})&&(F="[redacted]");let H={disabled:P.ax.disabled??!1};P.ax.checked!==void 0&&(H.checked=P.ax.checked===!0||P.ax.checked==="mixed"),P.ax.selected!==void 0&&(H.selected=P.ax.selected),P.ax.expanded!==void 0&&(H.expanded=P.ax.expanded);let X;P.dom?.testId?X=`[data-testid="${P.dom.testId}"]`:P.dom?.id&&(X=`#${P.dom.id}`);let ee={id:j,role:J,label:jU(I),kind:M,value:F,state:H,bbox:L};return X!==void 0&&(ee.selector=X),ee}),C="idle";try{let P=await t.evaluate(()=>document.readyState);P==="loading"?C="loading":P==="interactive"?C="navigating":C="idle"}catch{C="navigating"}C!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),w&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let x=WU(f),v=`obs_${e.observationCounter.toString(36)}`,R=new Date().toISOString();return{observationId:v,url:m,title:g,textSummary:x,interactive:A,status:{httpStatus:e.httpStatus??null,loadingState:C,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:R}}var hv,bv,wv=h(()=>{"use strict";ol();hv=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);bv="a[href], button, input, select, textarea, [role], [tabindex], label"});async function Sv(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,l=a.getAttribute("role")??a.tagName.toLowerCase(),c=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:l,label:c,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 sf(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>Sv(t,s)))).filter(o=>o!==null)}async function zU(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 l=a,c=l.getBoundingClientRect();return`${l.tagName}@${Math.round(c.x)},${Math.round(c.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function af(t,e,n){switch(e.kind){case"element_id":return VU(t,e,n);case"selector":return JU(t,e);case"semantic":return YU(t,e)}}async function VU(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 l=t.locator(r.selector);if(await l.count()===1)return{outcome:"resolved",locator:l}}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 sf(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function JU(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 sf(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function YU(t,e){return e.role!==void 0?XU(t,e.text,e.role):QU(t,e.text,e)}async function XU(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 sf(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function QU(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,l]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+l===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}),l>0&&d.push({loc:s,count:l});let u=await zU(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let y=p[g];if(y===void 0)continue;let w=await Sv(y.locator,y.index);if(w!==null){let k=`${w.role}:${w.label}:${g}`,T=0;for(let E=0;E<k.length;E++)T=T*31+k.charCodeAt(E)>>>0;f.push({...w,id:`el_${T.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var vv=h(()=>{"use strict"});async function lf(t,e,n,r){let o=t.url();if(o===n)return null;let s=el(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 kv=h(()=>{"use strict";tl()});import{randomBytes as ZU}from"crypto";import{mkdir as eB,stat as tB,writeFile as nB}from"fs/promises";import{join as cf}from"path";import{gzip as rB}from"zlib";import{promisify as oB}from"util";function sB(t){return cf(_n(t),"browser")}function iB(t){return cf(sB(t),"screenshots")}function aB(){return new Date().toISOString().replace(/[:.]/g,"-")}function lB(){return ZU(3).toString("hex")}async function df(t,e,n){if(e.length>Ev)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Ev} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=iB(t);await eB(r,{recursive:!0});let o=`${aB()}-${lB()}-${n}.png`,s=cf(r,o);await nB(s,e);let{size:i}=await tB(s);return{path:s,bytes:i}}var x7,Ev,_v=h(()=>{"use strict";B();ol();x7=oB(rB);Ev=5*1024*1024});var Tv={};du(Tv,{PlaywrightProvider:()=>uf});function Av(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 uf,Rv=h(()=>{"use strict";uv();wv();vv();tl();kv();_v();uf=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new rl(e)}async open(e){let n=el(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 l=o.url();if(!(a!==null&&(l===""||l==="about:blank"))){let u=await lf(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 sl(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 sl(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 af(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${Av(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:l}=a,c=null,d=async()=>{switch(e.action){case"click":await l.click({timeout:i});break;case"fill":await l.fill(e.value??"");break;case"press":await l.press(e.value??"");break;case"select":await l.selectOption(e.value??"");break;case"hover":await l.hover({timeout:i});break;case"scroll_to":await l.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await l.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(y){c=y}else c=g}let u=await lf(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||c!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await sl(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),c!==null)throw c;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 af(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${Av(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 df(n,s,"browser_screenshot"),l=0,c=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));l=d.w,c=d.h}catch{let d=r.viewportSize();l=d?.width??0,c=d?.height??0}else{let d=r.viewportSize();l=d?.width??0,c=d?.height??0}return{path:i,bytes:a,width:l,height:c,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 df(n,o,r);return s}catch{return null}}}});var Jn={};du(Jn,{__resetBrowserRegistryForTests:()=>fB,browserProviderActive:()=>uB,closeBrowserProvider:()=>pf,getBrowserProvider:()=>dB,peekBrowserProvider:()=>pB});function xv(){Promise.resolve(pf()).then(()=>{process.exit(130)})}function Cv(){Promise.resolve(pf()).then(()=>{process.exit(143)})}function Pv(){Rt=null}function cB(){il||(process.on("SIGINT",xv),process.on("SIGTERM",Cv),process.on("exit",Pv),il=!0)}function Iv(){il&&(process.removeListener("SIGINT",xv),process.removeListener("SIGTERM",Cv),process.removeListener("exit",Pv),il=!1)}async function dB(t){return Rt!==null?Rt:(Vn!==null||(Vn=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(Rv(),Tv)),n=av(t),r=new e(n);return cB(),Rt=r,Vn=null,r})()),Vn)}async function pf(){if(Rt===null)return;let t=Rt;Rt=null,Vn=null,Iv(),await t.shutdown()}function uB(){return Rt!==null}function pB(){return Rt}function fB(){Rt=null,Vn=null,Iv()}var Rt,Vn,il,Yn=h(()=>{"use strict";tl();Rt=null,Vn=null,il=!1});async function Mv(t,e){try{return await JS(t,e)}catch(n){return N("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function wB(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Yn(),Jn));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function Ov(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??wB,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,l=null,c=null;try{let u=await Za(n,t,{headers:bB,signal:e.signal},o);l=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(yB.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(hB.test(p)&&!gB.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await Mv(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof ft||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;c=u}if(!(s===null||s.textLength<200)&&s!==null){let u=Yp({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await ls(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>ls(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await ls(u.finalUrl,o);let p=await Mv(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=Yp({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 ft)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=c instanceof Error?c.message:`HTTP ${l??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${l??"error"}).`)}var gB,hB,yB,bB,Dv=h(()=>{"use strict";YS();Xp();tf();de();gB=/(text\/html|application\/xhtml\+xml)/i,hB=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,yB=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,bB={"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 kB(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(SB,{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),vB),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let l="";try{let d=await s.text(),u=ke(d);u&&(l=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let c=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${c}${l}`)}let i;try{i=await s.json()}catch(l){throw new Error(`Exa Search response was not JSON: ${l instanceof Error?l.message:String(l)}`)}return(i.results??[]).slice(0,r).map(l=>({title:(l.title??"").trim()||"(untitled)",url:l.url??"",description:(l.highlights?.[0]??"").trim()})).filter(l=>l.url.length>0)}}}function Fv(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?kB({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 Lv(t,e){if(e.length===0)return`# Search results for "${t}"
215
215
 
216
216
  (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(`
217
217
  `).trimEnd()}var SB,vB,Nv=h(()=>{"use strict";Ut();SB="https://api.exa.ai/search",vB=10});function al(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 Xn=h(()=>{"use strict";of()});function xB(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 l;try{l=new URL(e.url)}catch{return{error:`Invalid input: "${e.url}" is not a valid absolute URL`}}if(l.protocol!=="http:"&&l.protocol!=="https:")return{error:`Invalid input: protocol "${l.protocol}" not supported (http/https only)`};o=l.toString()}let i=EB;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,_B)}let a=AB;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,TB)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function ff(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:Nt(t,e),truncated:!0}}function CB(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=xB(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,l=()=>{a.abort(s.reason)},c,d=()=>{let u=a.signal.reason;return u instanceof Error?u.message:String(u??"aborted")};try{if(s.addEventListener("abort",l,{once:!0}),c=setTimeout(()=>{a.abort(new Error(`web_scrape timeout after ${i.timeoutMs}ms`))},i.timeoutMs),i.url!==void 0){let p=await ef(i.url,r);if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(!p.allowed)return{content:`web_scrape blocked: ${p.reason}`,isError:!0}}if(i.mode==="raw"){let p;try{let g={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};p=await Za(e,i.url,g,r)}catch(g){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:g instanceof ft?{content:`web_scrape blocked: ${g.message}`,isError:!0}:{content:`web_scrape network error: ${g instanceof Error?g.message:String(g)}`,isError:!0}}if(!p.ok)return{content:`web_scrape HTTP ${p.status} ${p.statusText||""}`.trimEnd()+` for ${i.url}`,isError:!0};let f;try{f=await p.text()}catch(g){return{content:`web_scrape read error: ${g instanceof Error?g.message:String(g)}`,isError:!0}}let m=ff(f,i.maxBytes);return{content:m.content,...m.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await Ov(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=ff(XS(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 ft)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),m=$e(p)&&!nf(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${cs()}\`)`:"";return{content:`web_scrape markdown error: ${f}${m}`,isError:!0}}let u=Fv({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:RB,timeoutMs:i.timeoutMs,signal:a.signal}),f=ff(Lv(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{c!==void 0&&clearTimeout(c),s.removeEventListener("abort",l)}}}var EB,_B,AB,TB,RB,$v,Uv=h(()=>{"use strict";Dv();Nv();tf();tn();Xp();Xn();EB=3e4,_B=12e4,AB=1e5,TB=1e6,RB=10;$v=CB()});import{existsSync as jv,mkdirSync as PB,readFileSync as IB,renameSync as MB,unlinkSync as OB,writeFileSync as DB}from"node:fs";import{dirname as Bv,join as FB}from"node:path";import{randomBytes as LB}from"node:crypto";function Fr(t){let e=t??gu();if(!jv(e))return[];try{let n=IB(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 ll(t,e){let n=e??gu();PB(Bv(n),{recursive:!0});let r=FB(Bv(n),`.schedules.json.${process.pid}.${LB(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{DB(r,o,"utf-8"),MB(r,n)}catch(s){try{jv(r)&&OB(r)}catch{}throw s}}function Hv(t,e){let n=Fr(e),r=n.map(l=>l.id),o=NB(t.name),s=$B(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),ll(n,e),a}function Wv(t,e){let n=Fr(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(ll(o,e),!0)}function Kv(t,e){return Fr(e).find(n=>n.id===t)}function NB(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function $B(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}var Gv=h(()=>{"use strict";B()});import{existsSync as UB,readFileSync as BB}from"node:fs";import{join as jB}from"node:path";async function ds(t,e,n){let r;try{let o=jB(oy("default"),"port");if(!UB(o))return{synced:!1,detail:"daemon-not-detected (no port file)"};let s=BB(o,"utf-8").trim();if(r=parseInt(s,10),Number.isNaN(r))return{synced:!1,detail:"daemon-not-detected (invalid port file)"}}catch{return{synced:!1,detail:"daemon-not-detected (unreadable port file)"}}try{let o=await fetch(`http://localhost:${r}${e}`,{method:t,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return o.ok?{synced:!0,detail:"synced"}:t==="POST"&&o.status===409?{synced:!0,detail:"already-registered"}:t==="DELETE"&&o.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${o.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}var mf,qv=h(()=>{"use strict";B();mf="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 HB}from"node:fs";import{readFile as WB}from"node:fs/promises";var zv,Vv,Jv,Yv,Xv=h(()=>{"use strict";Gv();B();qv();zv=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=Hv({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 ds("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 ds("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:mf}})}},Vv=async(t,e)=>{let n=Fr();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})))}},Jv=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=Ti();if(!HB(s))return{content:JSON.stringify([])};let i;try{let c=await WB(s);i=(c.length>1048576?c.subarray(c.length-1048576):c).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
@@ -1434,7 +1434,7 @@ The instructions below come from this operator's configuration (AFK.md, afk.conf
1434
1434
  ${dM}
1435
1435
 
1436
1436
  ${r}`}fe();Fs();tt();bt();Ce();Zn();function uM(t){return se(t)}function pM(t){let e=S.AFK_DEFAULT_SUBAGENT_MODEL;return e&&e.length>0?e:typeof t=="string"&&z(t)==="openai-compatible"?t:"medium"}function nJ(t){if(t===void 0)return;if(t==="max")return Number.POSITIVE_INFINITY;if(t===""||t==="NaN")throw new Error(`Invalid --max-output-tokens value: ${JSON.stringify(t)}. Expected a positive integer or 'max'.`);if(!/^\d+$/.test(t))throw new Error(`Invalid --max-output-tokens value: ${JSON.stringify(t)}. Expected a positive integer or 'max'.`);let e=Number(t);if(!Number.isFinite(e)||!Number.isInteger(e)||e<=0)throw new Error(`Invalid --max-output-tokens value: ${JSON.stringify(t)}. Must be a positive integer.`);return e}function fM(){return nJ(S.AFK_MAX_OUTPUT_TOKENS)}function rJ(t){if(t===void 0)return;let e=Number(t);if(!(!Number.isFinite(e)||e<=0))return Math.floor(e)}function mM(){return rJ(S.AFK_MAX_TOOL_USE_ITERATIONS)}import{existsSync as oJ,readFileSync as sJ}from"fs";var iJ=["TELEGRAM_BOT_TOKEN","AFK_TELEGRAM_ALLOWED_CHAT_IDS","TELEGRAM_VERBOSE","TELEGRAM_DATA_DIR"];function aJ(t){let e=new Map;if(!oJ(t))return e;try{let n=sJ(t,"utf-8");for(let r of n.split(`
1437
- `)){let o=r.trim();if(!o||o.startsWith("#"))continue;let s=o.indexOf("=");if(s===-1)continue;let i=o.slice(0,s).trim(),a=o.slice(s+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),e.set(i,a)}}catch{}return e}function gM(t,e){if(t!=="TELEGRAM_BOT_TOKEN")return e;let n=e.indexOf(":");return n===-1?`${e.slice(0,4)}***`:`${e.slice(0,n+1)}***`}function hM(t,e=console.log){let n=aJ(t);for(let r of iJ){let o=n.get(r);if(o===void 0)continue;let s=process.env[r];s!==void 0&&s!==o&&e(`\u{1F527} ${r}: file value (${gM(r,o)}) overrides shell value (${gM(r,s)})`),process.env[r]=o}}$();Zt();ss();function Ah(t){return t==="openai-compatible"||t==="openai-codex"}function yM(t,e={}){let{openaiApiKey:n=S.OPENAI_API_KEY,codexApiKey:r=S.CODEX_API_KEY,loadAnthropicCredential:o=Wa,detectMode:s=hr}=e;if(Ah(t))return{kind:"openai",notices:[n||r?"\u{1F4DD} Using OPENAI_API_KEY / CODEX_API_KEY for OpenAI auth":"\u{1F4DD} Will attempt API key from ~/.codex/auth.json (run `afk provider auth diagnose` for details)"]};let i=o();if(!i||i.length===0)return{kind:"missing",errors:["\u274C Claude models require ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN."," Set one in your environment, run `afk login`, or sign in to Claude Code."]};let a=s(i)==="oauth"?"CLAUDE_CODE_OAUTH_TOKEN":"ANTHROPIC_API_KEY";return{kind:"anthropic",credential:i,envVar:a,notices:[a==="CLAUDE_CODE_OAUTH_TOKEN"?"\u{1F4DD} Using CLAUDE_CODE_OAUTH_TOKEN for Anthropic auth (OAuth, auto-refresh on 401)":"\u{1F4DD} Using ANTHROPIC_API_KEY for Anthropic auth"]}}function bM(t,e,n={}){let r=n.log??console.log,o=n.error??console.error;if(t.kind==="missing"){for(let s of t.errors)o(s);return!1}t.kind==="anthropic"&&(process.env[t.envVar]=t.credential,e.apiKey=t.credential);for(let s of t.notices)r(s);return!0}import{readFileSync as lJ}from"fs";import{dirname as cJ,join as dJ}from"path";import{fileURLToPath as uJ}from"url";var mi="unknown",pJ=["../package.json","../../package.json"];function Jd(t=cJ(uJ(import.meta.url)),e=n=>lJ(n,"utf8")){for(let n of pJ)try{let r=JSON.parse(e(dJ(t,n)));if(typeof r.version=="string"&&r.version.length>0)return r.version}catch{}return mi}fe();Ze();sm();$();B();import{randomUUID as HJ}from"node:crypto";import{createHash as LJ}from"crypto";import{appendFileSync as NJ}from"fs";import{mkdir as $J,open as UJ,writeFile as BJ}from"fs/promises";import{join as FM}from"path";import{z as b}from"zod";var wM=["policy-refusal","timeout","budget","permission-denied","hook-block","abort","elicitation-declined","denial-breaker","repeat-failure","no-such-target"],SM=new Set(["policy-refusal","permission-denied","hook-block","abort","elicitation-declined","no-such-target"]);var fJ=b.object({phase:b.literal("started"),toolUseId:b.string(),name:b.string(),inputBytes:b.number().int().nonnegative(),subagentId:b.string().optional()}),vM=b.enum(wM),mJ=b.object({phase:b.literal("completed"),toolUseId:b.string(),name:b.string(),resultBytes:b.number().int().nonnegative(),isError:b.boolean(),truncated:b.boolean(),durationMs:b.number().nonnegative(),incomplete:b.boolean().optional(),incompleteReason:b.string().optional(),circuitBreaker:b.boolean().optional(),failureClass:vM.optional(),batchIndex:b.number().int().positive().optional(),batchSize:b.number().int().positive().optional(),subagentId:b.string().optional()}),kM=b.discriminatedUnion("phase",[fJ,mJ]),gJ=b.enum(["PreToolUse","PostToolUse","PostToolUseFailure","SessionStart","SessionEnd","SubagentStart","SubagentStop"]),EM=b.object({hookEvent:gJ,decision:b.union([b.literal("block"),b.literal("approve")]).optional(),reason:b.string().optional(),blockedTool:b.string().optional(),subagentId:b.string().optional(),injectedContextBytes:b.number().int().nonnegative().optional(),durationMs:b.number().nonnegative().optional(),approvalOutcome:b.enum(["carve-out","approved","denied","unrecognised","timeout","decline","cancel","hard-block"]).optional()}),hJ=b.object({transition:b.literal("started"),subagentId:b.string(),parentId:b.string(),model:b.string(),allowedTools:b.array(b.string()).readonly().optional(),systemPromptHash:b.string().optional(),promptHead:b.string().optional(),agentType:b.string().optional(),resolvedAgentType:b.string().optional()}),yJ=b.object({transition:b.literal("succeeded"),subagentId:b.string(),durationMs:b.number().nonnegative(),turnCount:b.number().int().nonnegative(),totalCostUsd:b.number().nonnegative().optional(),outputBytes:b.number().int().nonnegative(),stopReason:b.string().optional()}),bJ=b.object({transition:b.literal("failed"),subagentId:b.string(),errorClass:b.string(),errorMessage:b.string(),partialOutputBytes:b.number().int().nonnegative(),failureClass:vM.optional()}),wJ=b.object({transition:b.literal("cancelled"),subagentId:b.string(),source:b.enum(["cascade","explicit"]),timeout:b.boolean().optional()}),_M=b.discriminatedUnion("transition",[hJ,yJ,bJ,wJ]),SJ=b.object({transition:b.literal("started"),jobId:b.string(),subagentId:b.string(),label:b.string(),model:b.string()}),vJ=b.object({transition:b.literal("completed"),jobId:b.string(),subagentId:b.string(),durationMs:b.number().nonnegative(),outputBytes:b.number().int().nonnegative()}),kJ=b.object({transition:b.literal("failed"),jobId:b.string(),subagentId:b.string(),durationMs:b.number().nonnegative(),errorClass:b.string(),errorMessage:b.string()}),EJ=b.object({transition:b.literal("cancelled"),jobId:b.string(),subagentId:b.string(),source:b.enum(["explicit","cascade"])}),_J=b.object({transition:b.literal("joined"),jobId:b.string(),subagentId:b.string(),jobStatus:b.enum(["completed","failed","cancelled"])}),AJ=b.object({transition:b.literal("delivered"),jobId:b.string(),subagentId:b.string(),jobStatus:b.enum(["completed","failed","cancelled"])}),AM=b.discriminatedUnion("transition",[SJ,vJ,kJ,EJ,_J,AJ]),TM=b.object({kind:b.literal("monetary"),runningCostUsd:b.number().nonnegative(),maxBudgetUsd:b.number().nonnegative(),lastTurnCostUsd:b.number().nonnegative()}),TJ=b.enum(["user_signal","cascade","timeout","budget","hook_block"]),RM=b.object({origin:TJ,cascadedTo:b.array(b.string()).readonly(),reason:b.string().optional()}),xM=b.enum(["manual","token_threshold","turn_count"]),RJ=b.object({path:b.string(),sizeBytes:b.number().int().nonnegative(),sha256:b.string().regex(/^[0-9a-f]{64}$/)}),xJ=b.object({trigger:xM,preCompactionMessages:b.array(b.unknown()),summary:b.string(),keptTailCount:b.number().int().nonnegative(),keepLastNConfig:b.number().int().nonnegative(),messagesBefore:b.number().int().nonnegative(),messagesAfter:b.number().int().nonnegative(),tokensSavedEstimate:b.number().nonnegative().optional(),summarizationTokens:b.object({input:b.number().int().nonnegative(),output:b.number().int().nonnegative()}).optional()}),CJ=b.object({trigger:xM,preCompactionMessagesRef:RJ,summary:b.string(),keptTailCount:b.number().int().nonnegative(),keepLastNConfig:b.number().int().nonnegative(),messagesBefore:b.number().int().nonnegative(),messagesAfter:b.number().int().nonnegative(),tokensSavedEstimate:b.number().nonnegative().optional(),summarizationTokens:b.object({input:b.number().int().nonnegative(),output:b.number().int().nonnegative()}).optional()}),PJ=b.enum(["model_end_turn","truncated","iteration_cap","abort","timeout","budget_exceeded","hook_blocked","max_turns_exceeded"]),CM=b.object({reason:PJ,finalTurnCount:b.number().int().nonnegative(),finalCostUsd:b.number().nonnegative(),finalTokens:b.object({input:b.number().int().nonnegative().optional(),output:b.number().int().nonnegative().optional(),cacheRead:b.number().int().nonnegative().optional(),cacheCreation:b.number().int().nonnegative().optional()}),lastStopReason:b.string().optional(),guidance:b.string().optional()}),PM=b.object({source:b.string(),assertion:b.string(),evidence:b.array(b.string()).readonly(),confidence:b.number().min(0).max(1),dissent:b.string().optional()}),IJ=b.enum(["browser_open","browser_observe","browser_act","browser_screenshot","browser_extract","browser_close"]),MJ=b.enum(["click","fill","press","select","hover","scroll_to","wait_for"]),OJ=b.object({kind:b.enum(["semantic","element_id","selector"]),text:b.string().max(80).optional(),role:b.string().optional(),elementId:b.string().optional(),selectorHash:b.string().regex(/^[0-9a-f]{8}$/).optional()}),IM=b.object({jobId:b.string(),subagentId:b.string(),byteLength:b.number().int().nonnegative()}),MM=b.object({tool:IJ,action:MJ.optional(),toolUseId:b.string(),target:OJ.optional(),urlBefore:b.string().nullable(),urlAfter:b.string().nullable(),status:b.enum(["ok","error","ambiguous_target","blocked_by_policy"]),screenshotPath:b.string().optional(),observationSummary:b.string().max(500).optional(),error:b.object({reason:b.string(),recoverable:b.boolean()}).optional(),durationMs:b.number().nonnegative()}),DJ=b.enum(["bootstrap_start","bootstrap_done","session_init_start","session_init_done","mcp_connect_start","mcp_connect_done","mcp_server_start","mcp_server_done","loop_start","loop_end","model_ttfb","interrupt_halt","rate_limit","ttfb_timeout","usage_limit_pause","usage_limit_resume","overload_pause","overload_resume","idle_watchdog_fired","pause_extension_granted","suspected_loop","compaction_disabled"]),OM=b.object({phase:DJ,durationMs:b.number().nonnegative().optional(),metadata:b.record(b.string(),b.union([b.string(),b.number(),b.boolean()])).optional(),model:b.string().optional(),resolvedModel:b.string().optional(),origin:b.enum(["cli","telegram","daemon","web","unknown"]).optional(),actor:b.enum(["main","subagent"]).optional()}),FJ=b.object({status:b.enum(["succeeded","failed","cancelled"]),finalCostUsd:b.number().nonnegative(),finalTurnCount:b.number().int().nonnegative(),closedAt:b.string().datetime(),incomplete:b.boolean().optional(),subagentCount:b.number().int().nonnegative().optional(),subagentTokens:b.object({input:b.number().int().nonnegative().optional(),output:b.number().int().nonnegative().optional(),cacheRead:b.number().int().nonnegative().optional(),cacheCreation:b.number().int().nonnegative().optional()}).optional(),subagentCostUsd:b.number().nonnegative().optional()}),DM=b.discriminatedUnion("kind",[b.object({kind:b.literal("tool_call"),payload:kM}),b.object({kind:b.literal("hook_decision"),payload:EM}),b.object({kind:b.literal("subagent_lifecycle"),payload:_M}),b.object({kind:b.literal("background_agent"),payload:AM}),b.object({kind:b.literal("budget"),payload:TM}),b.object({kind:b.literal("abort"),payload:RM}),b.object({kind:b.literal("compaction"),payload:xJ}),b.object({kind:b.literal("closure"),payload:CM}),b.object({kind:b.literal("claim"),payload:PM}),b.object({kind:b.literal("browser_event"),payload:MM}),b.object({kind:b.literal("queued_user_message"),payload:IM}),b.object({kind:b.literal("session_phase"),payload:OM})]),Nke=b.discriminatedUnion("kind",[b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("tool_call"),payload:kM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("hook_decision"),payload:EM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("subagent_lifecycle"),payload:_M}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("background_agent"),payload:AM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("budget"),payload:TM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("abort"),payload:RM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("compaction"),payload:CJ}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("closure"),payload:CM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("claim"),payload:PM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("browser_event"),payload:MM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("queued_user_message"),payload:IM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("session_phase"),payload:OM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("session_sealed"),payload:FJ})]);var Yd=new Set,LM=!1;function jJ(){LM||(LM=!0,process.on("exit",()=>{for(let t of Yd)t.sealOnProcessExit()}))}var Xd=class{traceDir;tracePath;seq=0;sealed=!1;sealRecordPersisted=!1;fh=null;writeQueue=Promise.resolve();constructor(e){this.traceDir=e.traceDir,this.tracePath=FM(this.traceDir,"trace.jsonl")}getTracePath(){return this.tracePath}async write(e){if(this.sealed)throw new Error("NdjsonTraceWriter: trace is sealed; write() rejected");return DM.parse(e),this.enqueue(async()=>{await this.ensureOpen();let n=await this.materializePersistedEvent(e);await this.appendLine(n)})}async seal(e){this.sealed||(this.sealed=!0,await this.enqueue(async()=>{if(await this.ensureOpen(),this.sealRecordPersisted)return;let n={ts:new Date().toISOString(),seq:this.seq++,kind:"session_sealed",payload:e};await this.appendLine(n),this.sealRecordPersisted=!0,this.fh&&await this.fh.sync()}),await this.closeHandle())}async close(){await this.enqueue(async()=>{}),await this.closeHandle()}enqueue(e){let n=this.writeQueue.then(e,e);return this.writeQueue=n.then(()=>{},()=>{}),n}async ensureOpen(){this.fh||(await $J(this.traceDir,{recursive:!0}),this.fh=await UJ(this.tracePath,"a"),Yd.add(this),jJ())}async closeHandle(){if(Yd.delete(this),!this.fh)return;let e=this.fh;this.fh=null,await e.close()}sealOnProcessExit(){if(this.sealRecordPersisted||this.seq===0)return;this.sealed=!0,Yd.delete(this);try{let n={ts:new Date().toISOString(),seq:this.seq++,kind:"session_sealed",payload:{status:"failed",finalCostUsd:0,finalTurnCount:0,closedAt:new Date().toISOString(),incomplete:!0}};NJ(this.tracePath,`${JSON.stringify(n)}
1437
+ `)){let o=r.trim();if(!o||o.startsWith("#"))continue;let s=o.indexOf("=");if(s===-1)continue;let i=o.slice(0,s).trim(),a=o.slice(s+1).trim();(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),e.set(i,a)}}catch{}return e}function gM(t,e){if(t!=="TELEGRAM_BOT_TOKEN")return e;let n=e.indexOf(":");return n===-1?`${e.slice(0,4)}***`:`${e.slice(0,n+1)}***`}function hM(t,e=console.log){let n=aJ(t);for(let r of iJ){let o=n.get(r);if(o===void 0)continue;let s=process.env[r];s!==void 0&&s!==o&&e(`\u{1F527} ${r}: file value (${gM(r,o)}) overrides shell value (${gM(r,s)})`),process.env[r]=o}}$();Zt();ss();function Ah(t){return t==="openai-compatible"||t==="openai-codex"}function yM(t,e={}){let{openaiApiKey:n=S.OPENAI_API_KEY,codexApiKey:r=S.CODEX_API_KEY,loadAnthropicCredential:o=Wa,detectMode:s=hr}=e;if(Ah(t))return{kind:"openai",notices:[n||r?"\u{1F4DD} Using OPENAI_API_KEY / CODEX_API_KEY for OpenAI auth":"\u{1F4DD} Will attempt API key from ~/.codex/auth.json (run `afk provider auth diagnose` for details)"]};let i=o();if(!i||i.length===0)return{kind:"missing",errors:["\u274C Claude models require ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN."," Set one in your environment, run `afk login`, or sign in to Claude Code."]};let a=s(i)==="oauth"?"CLAUDE_CODE_OAUTH_TOKEN":"ANTHROPIC_API_KEY";return{kind:"anthropic",credential:i,envVar:a,notices:[a==="CLAUDE_CODE_OAUTH_TOKEN"?"\u{1F4DD} Using CLAUDE_CODE_OAUTH_TOKEN for Anthropic auth (OAuth, auto-refresh on 401)":"\u{1F4DD} Using ANTHROPIC_API_KEY for Anthropic auth"]}}function bM(t,e,n={}){let r=n.log??console.log,o=n.error??console.error;if(t.kind==="missing"){for(let s of t.errors)o(s);return!1}t.kind==="anthropic"&&(process.env[t.envVar]=t.credential,e.apiKey=t.credential);for(let s of t.notices)r(s);return!0}import{readFileSync as lJ}from"fs";import{dirname as cJ,join as dJ}from"path";import{fileURLToPath as uJ}from"url";var mi="unknown",pJ=["../package.json","../../package.json"];function Jd(t=cJ(uJ(import.meta.url)),e=n=>lJ(n,"utf8")){for(let n of pJ)try{let r=JSON.parse(e(dJ(t,n)));if(typeof r.version=="string"&&r.version.length>0)return r.version}catch{}return mi}fe();Ze();sm();$();B();import{randomUUID as HJ}from"node:crypto";import{createHash as LJ}from"crypto";import{appendFileSync as NJ}from"fs";import{mkdir as $J,open as UJ,writeFile as BJ}from"fs/promises";import{join as FM}from"path";import{z as b}from"zod";var wM=["policy-refusal","timeout","budget","permission-denied","hook-block","abort","elicitation-declined","denial-breaker","repeat-failure","no-such-target"],SM=new Set(["policy-refusal","permission-denied","hook-block","abort","elicitation-declined","no-such-target"]);var fJ=b.object({phase:b.literal("started"),toolUseId:b.string(),name:b.string(),inputBytes:b.number().int().nonnegative(),subagentId:b.string().optional()}),vM=b.enum(wM),mJ=b.object({phase:b.literal("completed"),toolUseId:b.string(),name:b.string(),resultBytes:b.number().int().nonnegative(),isError:b.boolean(),truncated:b.boolean(),durationMs:b.number().nonnegative(),incomplete:b.boolean().optional(),incompleteReason:b.string().optional(),circuitBreaker:b.boolean().optional(),failureClass:vM.optional(),batchIndex:b.number().int().positive().optional(),batchSize:b.number().int().positive().optional(),subagentId:b.string().optional()}),kM=b.discriminatedUnion("phase",[fJ,mJ]),gJ=b.enum(["PreToolUse","PostToolUse","PostToolUseFailure","SessionStart","SessionEnd","SubagentStart","SubagentStop"]),EM=b.object({hookEvent:gJ,decision:b.union([b.literal("block"),b.literal("approve")]).optional(),reason:b.string().optional(),blockedTool:b.string().optional(),subagentId:b.string().optional(),injectedContextBytes:b.number().int().nonnegative().optional(),durationMs:b.number().nonnegative().optional(),approvalOutcome:b.enum(["carve-out","approved","denied","unrecognised","timeout","decline","cancel","hard-block"]).optional()}),hJ=b.object({transition:b.literal("started"),subagentId:b.string(),parentId:b.string(),model:b.string(),allowedTools:b.array(b.string()).readonly().optional(),systemPromptHash:b.string().optional(),promptHead:b.string().optional(),agentType:b.string().optional(),resolvedAgentType:b.string().optional()}),yJ=b.object({transition:b.literal("succeeded"),subagentId:b.string(),durationMs:b.number().nonnegative(),turnCount:b.number().int().nonnegative(),totalCostUsd:b.number().nonnegative().optional(),outputBytes:b.number().int().nonnegative(),stopReason:b.string().optional()}),bJ=b.object({transition:b.literal("failed"),subagentId:b.string(),errorClass:b.string(),errorMessage:b.string(),partialOutputBytes:b.number().int().nonnegative(),failureClass:vM.optional()}),wJ=b.object({transition:b.literal("cancelled"),subagentId:b.string(),source:b.enum(["cascade","explicit"]),timeout:b.boolean().optional()}),_M=b.discriminatedUnion("transition",[hJ,yJ,bJ,wJ]),SJ=b.object({transition:b.literal("started"),jobId:b.string(),subagentId:b.string(),label:b.string(),model:b.string()}),vJ=b.object({transition:b.literal("completed"),jobId:b.string(),subagentId:b.string(),durationMs:b.number().nonnegative(),outputBytes:b.number().int().nonnegative()}),kJ=b.object({transition:b.literal("failed"),jobId:b.string(),subagentId:b.string(),durationMs:b.number().nonnegative(),errorClass:b.string(),errorMessage:b.string()}),EJ=b.object({transition:b.literal("cancelled"),jobId:b.string(),subagentId:b.string(),source:b.enum(["explicit","cascade"])}),_J=b.object({transition:b.literal("joined"),jobId:b.string(),subagentId:b.string(),jobStatus:b.enum(["completed","failed","cancelled"])}),AJ=b.object({transition:b.literal("delivered"),jobId:b.string(),subagentId:b.string(),jobStatus:b.enum(["completed","failed","cancelled"])}),AM=b.discriminatedUnion("transition",[SJ,vJ,kJ,EJ,_J,AJ]),TM=b.object({kind:b.literal("monetary"),runningCostUsd:b.number().nonnegative(),maxBudgetUsd:b.number().nonnegative(),lastTurnCostUsd:b.number().nonnegative()}),TJ=b.enum(["user_signal","cascade","timeout","budget","hook_block"]),RM=b.object({origin:TJ,cascadedTo:b.array(b.string()).readonly(),reason:b.string().optional()}),xM=b.enum(["manual","token_threshold","turn_count"]),RJ=b.object({path:b.string(),sizeBytes:b.number().int().nonnegative(),sha256:b.string().regex(/^[0-9a-f]{64}$/)}),xJ=b.object({trigger:xM,preCompactionMessages:b.array(b.unknown()),summary:b.string(),keptTailCount:b.number().int().nonnegative(),keepLastNConfig:b.number().int().nonnegative(),messagesBefore:b.number().int().nonnegative(),messagesAfter:b.number().int().nonnegative(),tokensSavedEstimate:b.number().nonnegative().optional(),summarizationTokens:b.object({input:b.number().int().nonnegative(),output:b.number().int().nonnegative()}).optional()}),CJ=b.object({trigger:xM,preCompactionMessagesRef:RJ,summary:b.string(),keptTailCount:b.number().int().nonnegative(),keepLastNConfig:b.number().int().nonnegative(),messagesBefore:b.number().int().nonnegative(),messagesAfter:b.number().int().nonnegative(),tokensSavedEstimate:b.number().nonnegative().optional(),summarizationTokens:b.object({input:b.number().int().nonnegative(),output:b.number().int().nonnegative()}).optional()}),PJ=b.enum(["model_end_turn","truncated","iteration_cap","abort","timeout","budget_exceeded","hook_blocked","max_turns_exceeded"]),CM=b.object({reason:PJ,finalTurnCount:b.number().int().nonnegative(),finalCostUsd:b.number().nonnegative(),finalTokens:b.object({input:b.number().int().nonnegative().optional(),output:b.number().int().nonnegative().optional(),cacheRead:b.number().int().nonnegative().optional(),cacheCreation:b.number().int().nonnegative().optional()}),lastStopReason:b.string().optional(),guidance:b.string().optional()}),PM=b.object({source:b.string(),assertion:b.string(),evidence:b.array(b.string()).readonly(),confidence:b.number().min(0).max(1),dissent:b.string().optional()}),IJ=b.enum(["browser_open","browser_observe","browser_act","browser_screenshot","browser_extract","browser_close"]),MJ=b.enum(["click","fill","press","select","hover","scroll_to","wait_for"]),OJ=b.object({kind:b.enum(["semantic","element_id","selector"]),text:b.string().max(80).optional(),role:b.string().optional(),elementId:b.string().optional(),selectorHash:b.string().regex(/^[0-9a-f]{8}$/).optional()}),IM=b.object({jobId:b.string(),subagentId:b.string(),byteLength:b.number().int().nonnegative()}),MM=b.object({tool:IJ,action:MJ.optional(),toolUseId:b.string(),target:OJ.optional(),urlBefore:b.string().nullable(),urlAfter:b.string().nullable(),status:b.enum(["ok","error","ambiguous_target","blocked_by_policy"]),screenshotPath:b.string().optional(),observationSummary:b.string().max(500).optional(),error:b.object({reason:b.string(),recoverable:b.boolean()}).optional(),durationMs:b.number().nonnegative()}),DJ=b.enum(["bootstrap_start","bootstrap_done","session_init_start","session_init_done","mcp_connect_start","mcp_connect_done","mcp_server_start","mcp_server_done","loop_start","loop_end","model_ttfb","interrupt_halt","rate_limit","ttfb_timeout","usage_limit_pause","usage_limit_resume","overload_pause","overload_resume","idle_watchdog_fired","pause_extension_granted","suspected_loop","compaction_disabled","boot_warning"]),OM=b.object({phase:DJ,durationMs:b.number().nonnegative().optional(),metadata:b.record(b.string(),b.union([b.string(),b.number(),b.boolean()])).optional(),model:b.string().optional(),resolvedModel:b.string().optional(),origin:b.enum(["cli","telegram","daemon","web","unknown"]).optional(),actor:b.enum(["main","subagent"]).optional()}),FJ=b.object({status:b.enum(["succeeded","failed","cancelled"]),finalCostUsd:b.number().nonnegative(),finalTurnCount:b.number().int().nonnegative(),closedAt:b.string().datetime(),incomplete:b.boolean().optional(),subagentCount:b.number().int().nonnegative().optional(),subagentTokens:b.object({input:b.number().int().nonnegative().optional(),output:b.number().int().nonnegative().optional(),cacheRead:b.number().int().nonnegative().optional(),cacheCreation:b.number().int().nonnegative().optional()}).optional(),subagentCostUsd:b.number().nonnegative().optional()}),DM=b.discriminatedUnion("kind",[b.object({kind:b.literal("tool_call"),payload:kM}),b.object({kind:b.literal("hook_decision"),payload:EM}),b.object({kind:b.literal("subagent_lifecycle"),payload:_M}),b.object({kind:b.literal("background_agent"),payload:AM}),b.object({kind:b.literal("budget"),payload:TM}),b.object({kind:b.literal("abort"),payload:RM}),b.object({kind:b.literal("compaction"),payload:xJ}),b.object({kind:b.literal("closure"),payload:CM}),b.object({kind:b.literal("claim"),payload:PM}),b.object({kind:b.literal("browser_event"),payload:MM}),b.object({kind:b.literal("queued_user_message"),payload:IM}),b.object({kind:b.literal("session_phase"),payload:OM})]),Nke=b.discriminatedUnion("kind",[b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("tool_call"),payload:kM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("hook_decision"),payload:EM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("subagent_lifecycle"),payload:_M}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("background_agent"),payload:AM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("budget"),payload:TM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("abort"),payload:RM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("compaction"),payload:CJ}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("closure"),payload:CM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("claim"),payload:PM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("browser_event"),payload:MM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("queued_user_message"),payload:IM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("session_phase"),payload:OM}),b.object({ts:b.string().datetime(),seq:b.number().int().nonnegative(),kind:b.literal("session_sealed"),payload:FJ})]);var Yd=new Set,LM=!1;function jJ(){LM||(LM=!0,process.on("exit",()=>{for(let t of Yd)t.sealOnProcessExit()}))}var Xd=class{traceDir;tracePath;seq=0;sealed=!1;sealRecordPersisted=!1;fh=null;writeQueue=Promise.resolve();constructor(e){this.traceDir=e.traceDir,this.tracePath=FM(this.traceDir,"trace.jsonl")}getTracePath(){return this.tracePath}async write(e){if(this.sealed)throw new Error("NdjsonTraceWriter: trace is sealed; write() rejected");return DM.parse(e),this.enqueue(async()=>{await this.ensureOpen();let n=await this.materializePersistedEvent(e);await this.appendLine(n)})}async seal(e){this.sealed||(this.sealed=!0,await this.enqueue(async()=>{if(await this.ensureOpen(),this.sealRecordPersisted)return;let n={ts:new Date().toISOString(),seq:this.seq++,kind:"session_sealed",payload:e};await this.appendLine(n),this.sealRecordPersisted=!0,this.fh&&await this.fh.sync()}),await this.closeHandle())}async close(){await this.enqueue(async()=>{}),await this.closeHandle()}enqueue(e){let n=this.writeQueue.then(e,e);return this.writeQueue=n.then(()=>{},()=>{}),n}async ensureOpen(){this.fh||(await $J(this.traceDir,{recursive:!0}),this.fh=await UJ(this.tracePath,"a"),Yd.add(this),jJ())}async closeHandle(){if(Yd.delete(this),!this.fh)return;let e=this.fh;this.fh=null,await e.close()}sealOnProcessExit(){if(this.sealRecordPersisted||this.seq===0)return;this.sealed=!0,Yd.delete(this);try{let n={ts:new Date().toISOString(),seq:this.seq++,kind:"session_sealed",payload:{status:"failed",finalCostUsd:0,finalTurnCount:0,closedAt:new Date().toISOString(),incomplete:!0}};NJ(this.tracePath,`${JSON.stringify(n)}
1438
1438
  `),this.sealRecordPersisted=!0}catch{}let e=this.fh;this.fh=null,e&&e.close().catch(()=>{})}async appendLine(e){if(!this.fh)throw new Error("NdjsonTraceWriter: file handle missing");await this.fh.appendFile(`${JSON.stringify(e)}
1439
1439
  `)}async materializePersistedEvent(e){let n=new Date().toISOString(),r=this.seq++;if(e.kind==="compaction"){let o=await this.persistCompactionSidecar(e.payload,r,n);return{ts:n,seq:r,kind:"compaction",payload:o}}return{ts:n,seq:r,kind:e.kind,payload:e.payload}}async persistCompactionSidecar(e,n,r){let o=r.replace(/[:.]/g,"-"),s=FM(this.traceDir,`${String(n).padStart(6,"0")}-${o}-pre-compaction.json`),i=JSON.stringify(e.preCompactionMessages),a=Buffer.byteLength(i,"utf8"),l=LJ("sha256").update(i).digest("hex");await BJ(s,i,{encoding:"utf8",flag:"w"});let c={path:s,sizeBytes:a,sha256:l};return{trigger:e.trigger,preCompactionMessagesRef:c,summary:e.summary,keptTailCount:e.keptTailCount,keepLastNConfig:e.keepLastNConfig,messagesBefore:e.messagesBefore,messagesAfter:e.messagesAfter,...e.tokensSavedEstimate!==void 0?{tokensSavedEstimate:e.tokensSavedEstimate}:{},...e.summarizationTokens!==void 0?{summarizationTokens:e.summarizationTokens}:{}}}};function Th(t={}){if(S.AFK_TRACE_DISABLED==="1")return null;let e=t.sessionLabel??HJ(),n=_n(e),r=new Xd({traceDir:n});return{writer:r,tracePath:r.getTracePath(),sessionLabel:e}}function NM(t=Th){return t()?.writer??null}function Qd(t,e={}){let n="traceWriter"in e?e.traceWriter??null:(e.createTraceWriter??Th)()?.writer??null,r=n?{traceWriter:n,...t,surface:"telegram"}:{...t,surface:"telegram"};return(e.newSession??(s=>new nr(s)))(r)}import{Client as qM}from"@modelcontextprotocol/sdk/client/index.js";import{CallToolResultSchema as QJ}from"@modelcontextprotocol/sdk/types.js";import{StreamableHTTPError as JM}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{UnauthorizedError as Mh}from"@modelcontextprotocol/sdk/client/auth.js";import{StdioClientTransport as KJ}from"@modelcontextprotocol/sdk/client/stdio.js";import{StreamableHTTPClientTransport as GJ}from"@modelcontextprotocol/sdk/client/streamableHttp.js";import{SSEClientTransport as qJ}from"@modelcontextprotocol/sdk/client/sse.js";var WJ=/\$(\$)?\{([A-Z_][A-Z0-9_]*)\}/gi;function Zd(t,e=process.env){let n=[];return{value:t.replace(WJ,(o,s,i)=>{if(s==="$")return`\${${i}}`;let a=e[i];return a===void 0||a===""?(n.push(i),""):a}),missing:n}}function Rh(t,e=process.env){if(t===void 0)return{value:{},missing:[]};let n={},r=new Set;for(let[o,s]of Object.entries(t)){let{value:i,missing:a}=Zd(s,e);n[o]=i;for(let l of a)r.add(l)}return{value:n,missing:[...r]}}function zJ(t){return t==="localhost"||t==="127.0.0.1"||t==="[::1]"||t==="::1"||t==="0.0.0.0"}function VJ(){let t=["PATH","HOME","USER","USERNAME","LOGNAME","SHELL","TERM","TMPDIR","TEMP","TMP","LANG","LC_ALL","SYSTEMROOT","APPDATA","LOCALAPPDATA","PROGRAMDATA","PROGRAMFILES","NODE_PATH"],e={};for(let n of t){let r=process.env[n];typeof r=="string"&&(e[n]=r)}return e}function $M(t,e=process.env){if(t===void 0)return{headers:{},missing:[]};let n={},r=new Set;for(let[o,s]of Object.entries(t)){let{value:i,missing:a}=Zd(s,e);if(a.length>0)for(let l of a)r.add(l);else n[o]=i}return{headers:n,missing:[...r]}}function eu(t,e,n){let r=e.type??(e.command?"stdio":"streamable-http");if(r==="stdio"){if(typeof e.command!="string"||e.command.length===0)throw new Error(`McpTransport(${t}): stdio requires \`command\``);let{value:o,missing:s}=Rh(e.env);s.length>0&&console.warn(`[mcp:${t}] missing env vars (passing as empty): ${s.join(", ")}`);let i={command:e.command,...e.args?{args:e.args}:{},env:{...VJ(),...o}};return{transport:new KJ(i),isSSE:!1}}if(r==="streamable-http"||r==="sse"){if(typeof e.url!="string"||e.url.length===0)throw new Error(`McpTransport(${t}): ${r} requires \`url\``);let o=new URL(e.url);if(o.protocol!=="https:"&&!zJ(o.hostname))throw new Error(`McpTransport(${t}): refusing ${r} URL ${o.protocol}//${o.hostname} \u2014 credentials and tool I/O would transit in plaintext. Use https:, or point the URL at localhost / 127.0.0.1.`);let{headers:s,missing:i}=$M(e.headers);return i.length>0&&console.warn(`[mcp:${t}] missing header vars (passing as omitted): ${i.join(", ")}`),r==="sse"?(process.stderr.write(`[mcp:${t}] WARNING: SSE transport is deprecated. Upgrade your MCP server to use streamable-HTTP.
1440
1440
  `),{transport:new qJ(o,{...Object.keys(s).length>0?{requestInit:{headers:s}}:{},...n?{authProvider:n}:{}}),isSSE:!0}):{transport:new GJ(o,{...Object.keys(s).length>0?{requestInit:{headers:s}}:{},...n?{authProvider:n}:{}}),isSSE:!1}}throw new Error(`McpTransport(${t}): unknown transport type "${String(r)}"`)}B();import{existsSync as xh,mkdirSync as WM,readFileSync as Ch,writeFileSync as Ph}from"node:fs";import{execFileSync as UM}from"node:child_process";import{randomUUID as JJ}from"node:crypto";import{homedir as BM,userInfo as jM}from"node:os";import{join as HM,dirname as KM}from"node:path";var uEe=600*1e3;function YJ(){let t=process.platform==="darwin",e=process.platform==="linux";return{read(){if(t)try{return UM("security",["find-generic-password","-s","Claude Code-credentials","-a",jM().username,"-w"],{stdio:["ignore","pipe","ignore"],encoding:"utf-8"}).trim()||void 0}catch{return}if(e){let n=HM(BM(),".claude",".credentials.json");if(!xh(n))return;try{return Ch(n,"utf-8")}catch{return}}},write(n){if(t)UM("security",["add-generic-password","-U","-s","Claude Code-credentials","-a",jM().username,"-w",n],{stdio:["ignore","ignore","ignore"]});else if(e){let r=HM(BM(),".claude",".credentials.json");WM(KM(r),{recursive:!0}),Ph(r,n,{encoding:"utf-8",mode:384})}}}}function GM(t){let e=Li();if(!xh(e))return;let n;try{n=JSON.parse(Ch(e,"utf-8"))}catch{return}t in n&&(delete n[t],Ph(e,JSON.stringify(n,null,2),{encoding:"utf-8",mode:384}))}function XJ(t,e){let n=Li();WM(KM(n),{recursive:!0});let r={};if(xh(n))try{r=JSON.parse(Ch(n,"utf-8"))}catch{}let o=new URL(e),s=o.origin+o.pathname;r[t]={status:"oauth_pending",authorizationUrl:s,timestamp:Date.now()},Ph(n,JSON.stringify(r,null,2),{encoding:"utf-8",mode:384})}var gi=class{serverName;backend;constructor(e,n=YJ()){this.serverName=e,this.backend=n}get redirectUrl(){return"http://localhost:3000/oauth/callback"}get clientMetadata(){return{redirect_uris:[this.redirectUrl],client_name:"agent-afk",grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"none"}}clientInformation(){return this._readSlot().clientInfo}saveClientInformation(e){this._updateSlot(n=>({...n,clientInfo:e}))}tokens(){return this._readSlot().tokens}saveTokens(e){this._updateSlot(n=>({...n,tokens:e}));try{GM(this.serverName)}catch{}}saveCodeVerifier(e){this._updateSlot(n=>({...n,codeVerifier:e}))}codeVerifier(){let e=this._readSlot().codeVerifier;if(!e)throw new Error(`[mcp:${this.serverName}] no PKCE code verifier stored`);return e}state(){let e=this._readSlot().state;if(e)return e;let n=JJ();return this._updateSlot(r=>({...r,state:n})),n}saveDiscoveryState(e){this._updateSlot(n=>({...n,discoveryState:e}))}discoveryState(){return this._readSlot().discoveryState}invalidateCredentials(e){this._updateSlot(n=>{if(e==="all")return{};let r={...n};return e==="client"&&delete r.clientInfo,e==="tokens"&&delete r.tokens,e==="verifier"&&(delete r.codeVerifier,delete r.state),e==="discovery"&&delete r.discoveryState,r})}async redirectToAuthorization(e){let n=e.toString(),r=`\u{1F510} MCP server "${this.serverName}" requires authorization.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-afk",
3
- "version": "5.109.0",
3
+ "version": "5.110.0",
4
4
  "description": "Open-source coding-agent harness you can actually change — own the loop (prompts, gates, routing, skills, terminal states), use any model, run long tasks while you're away.",
5
5
  "main": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",