agent-afk 5.47.0 → 5.48.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
@@ -851,7 +851,7 @@ Remedy: these paths are outside the fork's granted read roots. Re-dispatch with
851
851
  Note: this search ran in basic-regex (BRE) mode, where '|' is a literal pipe \u2014 not alternation. If you intended "A or B", retry with extended: true (extended regex / ERE). If you meant the literal character '|', this empty result stands.`),d({content:k});return}if(v===2){let k=Kn(g.trim());d({content:`grep error: ${k.content}`,isError:!0,...k.truncated?{truncated:!0}:{}});return}let R=dt(m.trimEnd()),T=Kn(R);d({content:T.content,...T.truncated?{truncated:!0}:{}})}),f.on("error",v=>{let R;if(p===void 0&&jr(v))try{R=Wn(v,process.cwd())}catch{R=`working directory does not exist (process cwd deleted \u2014 deleted worktree?) \u2014 underlying: ${v.message}`}else R=Wn(v,p);d({content:`Failed to execute grep: ${R}`,isError:!0})})})}}var vh,kh=b(()=>{"use strict";Ye();ft();Un();Vc();Yc();vh=id()});import{promises as wI}from"fs";function ad(t){return(e,n,r)=>SI(e,n,r,t)}var SI,_h,Eh=b(()=>{"use strict";ft();SI=async(t,e,n,r)=>{if(!t||typeof t!="object")throw new Error("Invalid input: expected an object");let s=t.path;if(typeof s!="string")throw new Error("Invalid input: path must be a string");let i;try{i=Fe(s,n,"read",r)}catch(a){return{content:a instanceof Error?a.message:String(a),isError:!0}}try{let a=await wI.readdir(i,{withFileTypes:!0}),l=a.filter(p=>p.isDirectory()).map(p=>`${p.name}/`),c=a.filter(p=>!p.isDirectory()).map(p=>p.name);l.sort(),c.sort();let d=[...l,...c];return d.length===0?{content:"(empty directory)"}:{content:d.join(`
852
852
  `)}}catch(a){if(a instanceof Error){let l=a;return l.code==="ENOENT"?{content:`Directory not found: ${i}`,isError:!0}:l.code==="ENOTDIR"?{content:`Not a directory: ${i}`,isError:!0}:l.code==="EACCES"?{content:`Permission denied: ${i}`,isError:!0}:{content:`Error listing directory: ${a.message}`,isError:!0}}return{content:"Unknown error listing directory",isError:!0}}};_h=ad()});function vI(t=Mn){return async(e,n)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected an object",isError:!0};let o=e.message;if(typeof o!="string")return{content:"Invalid input: message must be a string",isError:!0};if(o.length===0)return{content:"Invalid input: message must be non-empty",isError:!0};if(o.length>Ah)return{content:`Invalid input: message exceeds Telegram's ${Ah}-character limit (got ${o.length}). Split into multiple sends or trim before calling.`,isError:!0};let s=E.TELEGRAM_BOT_TOKEN;if(!s)return{content:"Telegram is not configured: TELEGRAM_BOT_TOKEN is not set. Run the bot setup wizard or export the env var before using send_telegram.",isError:!0};let i=Us();if(i.length===0)return{content:"Telegram is not configured: AFK_TELEGRAM_ALLOWED_CHAT_IDS is empty or unset. Add the operator chat ID(s) before using send_telegram.",isError:!0};let a=[];for(let l of i){let c=await t({token:s,chatId:l,text:o});c.ok||a.push(`chat ${l}: ${c.errorMessage??`HTTP ${c.status}`}`)}return a.length===i.length?{content:`Failed to send Telegram message to any chat. ${a.join("; ")}`,isError:!0}:a.length>0?{content:`Sent Telegram message to ${i.length-a.length}/${i.length} chat(s); ${a.length} failed: ${a.join("; ")}`}:{content:i.length===1?`Sent Telegram message to chat ${i[0]}.`:`Sent Telegram message to ${i.length} chats.`}}}var Ah,Th,xh=b(()=>{"use strict";H();Dr();yc();Ah=4096;Th=vI()});async function kI(){let[{JSDOM:t},{Readability:e},{default:n}]=await Promise.all([import("jsdom"),import("@mozilla/readability"),import("turndown")]),r=new n({headingStyle:"atx",codeBlockStyle:"fenced",bulletListMarker:"-"});return r.remove(["script","style","noscript","iframe"]),{JSDOM:t,Readability:e,turndown:r}}function _I(){return ld===null&&(ld=kI()),ld}function Rh(t){return t.replace(/\n{3,}/g,`
853
853
 
854
- `).trim()}function EI(t){return(t?.textContent??"").replace(/\s+/g," ").trim().length}async function Ch(t,e){let{JSDOM:n,Readability:r,turndown:o}=await _I(),i=new n(t,{url:e}).window.document,a=(i.title??"").trim(),l=(()=>{try{let p=i.cloneNode(!0);return new r(p).parse()}catch{return null}})();if(l&&typeof l.content=="string"&&l.content.trim().length>0){let p=Rh(o.turndown(l.content)),f=(l.title??"").trim()||a,m=typeof l.length=="number"&&l.length>0?l.length:(l.textContent??"").replace(/\s+/g," ").trim().length;return{title:f,markdown:p,textLength:m,usedFallback:!1}}let c=i.body,d=c?.innerHTML??"",u=Rh(o.turndown(d));return{title:a,markdown:u,textLength:EI(c),usedFallback:!0}}var ld,Ih=b(()=>{"use strict";ld=null});function TI(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 Ph(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function xI(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 ki(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??TI,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(!AI.has(u.status)||d===o)return u;let p=xI(u,i)??Ph(d,s,i);U("[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=Ph(d,s,i);U("[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 AI,cd=b(()=>{"use strict";oe();AI=new Set([429,502,503,504])});import{readFileSync as RI}from"node:fs";import{join as CI}from"path";function II(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function Mh(t,e){return II(e).test(t)}function OI(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(PI.has(e))return!0;if(MI.has(e))return!1}return!1}function Oh(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function DI(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 Dh(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Pl(e),e}function FI(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function LI(t){try{return RI(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function NI(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=Dh(e.defaultProfile)),n}function Fh(t){let e=t?.env??E,n=t?.readFileSync??LI,r=t?.surface??e.AGENT_SURFACE,o=OI(e.AFK_BROWSER_HEADLESS,r),s=Oh(e.AFK_BROWSER_ALLOWED_DOMAINS),i=Oh(e.AFK_BROWSER_BLOCKED_DOMAINS),a=FI(e.AFK_BROWSER_DOM_SNAPSHOTS),l=DI(e.AFK_BROWSER_BACKEND),c=Dh(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():CI(ot(),"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=NI(d,m);return g.configPath=p,g}function dd(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(Mh(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>Mh(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var PI,MI,ud=b(()=>{"use strict";H();W();PI=new Set(["daemon","subagent","telegram","afk"]),MI=new Set(["repl","interactive","cli"])});import dn from"node:fs";import _i from"node:path";import{randomBytes as $I}from"node:crypto";import{chromium as UI}from"playwright";function BI(){try{return"5.47.0"}catch{}try{let t=_i.resolve(import.meta.dirname,"../../../package.json"),e=dn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var jI,Ei,Lh=b(()=>{"use strict";W();oe();jI=BI(),Ei=class{config;browser;sessions=new Map;launchPromise;shutdownComplete=!1;constructor(e){this.config=e}async ensureBrowser(){return this.browser!==void 0&&this.browser.isConnected()?this.browser:(this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=UI.launch({headless:this.config.headless}).then(e=>(this.browser=e,this.launchPromise=void 0,e)).catch(e=>{throw this.launchPromise=void 0,e}),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=()=>{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",s,{once:!0});try{let i=await o.newPage(),a=await i.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil}),l=await i.content(),c=i.url(),d=a!==null?a.status():null;return{html:l,finalUrl:c,httpStatus:d}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",s),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){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.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/${jI}`}}loadStorageState(e){let n=Ml(e);try{if(!dn.existsSync(n))return;let r=JSON.parse(dn.readFileSync(n,"utf8"));return U("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){U("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Ml(e);if(!dn.existsSync(r))return;let o=await n.storageState(),s=_i.join(_i.dirname(r),`.${_i.basename(r)}.${process.pid}.${$I(4).toString("hex")}.tmp`);dn.writeFileSync(s,JSON.stringify(o),{mode:384}),dn.chmodSync(s,384),dn.renameSync(s,r),U("[browser/vault] saved session",{profile:e,file:r})}catch(r){U("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as HI}from"crypto";function pd(t){if(t.length===0)return t;let e=t;for(let{regex:n,name:r}of WI)r==="form-password"?e=e.replace(n,"password=[redacted]"):e=e.replace(n,"[redacted]");return e}function Nh(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&KI.test(t.label))}function $h(t){return HI("sha256").update(t,"utf8").digest("hex").slice(0,8)}function Uh(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var WI,KI,qr=b(()=>{"use strict";WI=[{name:"aws-access-key",regex:/AKIA[0-9A-Z]{16}/g},{name:"github-pat",regex:/ghp_[a-zA-Z0-9]{36}/g},{name:"openai-bearer",regex:/sk-[a-zA-Z0-9_-]{20,}/g},{name:"slack-token",regex:/xox[abp]-[a-zA-Z0-9-]{10,}/g},{name:"jwt",regex:/eyJ[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}/g},{name:"form-password",regex:/password=[^&\s]+/gi}];KI=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as GI}from"node:crypto";function qI(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function zI(t,e,n){return`el_${GI("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function JI(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Bh(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function Hh(t,e){let n=t.role??"",r=t.name??"";jh.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])Hh(s,e)}async function VI(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},Wh).catch(()=>[])}async function YI(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},Wh).catch(()=>[])}function XI(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Ai(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=XI(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=VI(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,S=!1;u!==null?(y=[],Hh(u,y)):(o.push("observation skipped accessibility tree (returned null)"),S=!0,y=(await YI(t)).filter(B=>jh.has(B.role??"")));let w=new Map;for(let x of p){let B=Bh(x.name),j=w.get(B);(!j||j.bbox.w===0&&x.bbox.w>0)&&w.set(B,x)}let _=y.map(x=>({ax:x,dom:w.get(Bh(x.name??""))})),v=r?_:_.filter(x=>x.dom?x.dom.bbox.w>0||x.dom.bbox.h>0:!0);v.sort((x,B)=>{let j=x.dom?.bbox.y??0,F=B.dom?.bbox.y??0;if(j!==F)return j-F;let N=x.dom?.bbox.x??0,O=B.dom?.bbox.x??0;return N-O}),v.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=v.slice(0,n).map((x,B)=>{let j=x.ax.role??"generic",F=x.ax.name??"",N=zI(j,F,B),O=x.dom?.bbox??{x:0,y:0,w:0,h:0},I=x.dom?.type??null,P=null;x.ax.value!==void 0&&x.ax.value!==null&&(P=String(x.ax.value)),x.ax.checked!==void 0&&(P=String(x.ax.checked)),Nh({role:j,kind:I})&&(P="[redacted]");let L={disabled:x.ax.disabled??!1};x.ax.checked!==void 0&&(L.checked=x.ax.checked===!0||x.ax.checked==="mixed"),x.ax.selected!==void 0&&(L.selected=x.ax.selected),x.ax.expanded!==void 0&&(L.expanded=x.ax.expanded);let $;x.dom?.testId?$=`[data-testid="${x.dom.testId}"]`:x.dom?.id&&($=`#${x.dom.id}`);let G={id:N,role:j,label:qI(F),kind:I,value:P,state:L,bbox:O};return $!==void 0&&(G.selector=$),G}),k="idle";try{let x=await t.evaluate(()=>document.readyState);x==="loading"?k="loading":x==="interactive"?k="navigating":k="idle"}catch{k="navigating"}k!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),S&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let A=JI(f),M=`obs_${e.observationCounter.toString(36)}`,C=new Date().toISOString();return{observationId:M,url:m,title:g,textSummary:A,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:k,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:C}}var jh,Wh,Kh=b(()=>{"use strict";qr();jh=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);Wh="a[href], button, input, select, textarea, [role], [tabindex], label"});async function Gh(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 fd(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>Gh(t,s)))).filter(o=>o!==null)}async function QI(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 md(t,e,n){switch(e.kind){case"element_id":return ZI(t,e,n);case"selector":return eP(t,e);case"semantic":return tP(t,e)}}async function ZI(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 fd(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function eP(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 fd(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function tP(t,e){return e.role!==void 0?nP(t,e.text,e.role):rP(t,e.text,e)}async function nP(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 fd(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function rP(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 QI(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 S=await Gh(y.locator,y.index);if(S!==null){let w=`${S.role}:${S.label}:${g}`,_=0;for(let v=0;v<w.length;v++)_=_*31+w.charCodeAt(v)>>>0;f.push({...S,id:`el_${_.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var qh=b(()=>{"use strict"});import{randomBytes as oP}from"crypto";import{mkdir as sP,stat as iP,writeFile as aP}from"fs/promises";import{join as gd}from"path";import{gzip as lP}from"zlib";import{promisify as cP}from"util";function dP(t){return gd(Qo(t),"browser")}function uP(t){return gd(dP(t),"screenshots")}function pP(){return new Date().toISOString().replace(/[:.]/g,"-")}function fP(){return oP(3).toString("hex")}async function hd(t,e,n){if(e.length>zh)throw new Error(`writeScreenshotSidecar: buffer exceeds ${zh} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=uP(t);await sP(r,{recursive:!0});let o=`${pP()}-${fP()}-${n}.png`,s=gd(r,o);await aP(s,e);let{size:i}=await iP(s);return{path:s,bytes:i}}var lz,zh,Jh=b(()=>{"use strict";W();qr();lz=cP(lP);zh=5*1024*1024});var Yh={};El(Yh,{PlaywrightProvider:()=>yd});function Vh(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 yd,Xh=b(()=>{"use strict";Lh();Kh();qh();ud();qr();Jh();yd=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Ei(e)}async open(e){let n=dd(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(c){a=c}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let l=await Ai(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,l.interactive,l.url,l.title,"browser_open"),a!==null)throw a;return l}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 Ai(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 md(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${Vh(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":{let g=pd(e.value??"");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=r.url();if(u!==s){let g=dd(u,this.config);if(!g.allowed)return await r.goBack().catch(()=>{}),{outcome:"blocked_by_policy",url:u,reason:g.reason}}let p=null;(e.screenshot===!0||c!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Ai(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})}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 md(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${Vh(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 hd(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 hd(n,o,r);return s}catch{return null}}}});var pn={};El(pn,{__resetBrowserRegistryForTests:()=>bP,browserProviderActive:()=>hP,closeBrowserProvider:()=>bd,getBrowserProvider:()=>gP,peekBrowserProvider:()=>yP});function Qh(){Promise.resolve(bd()).then(()=>{process.exit(130)})}function Zh(){Promise.resolve(bd()).then(()=>{process.exit(143)})}function ey(){Ze=null}function mP(){Ti||(process.on("SIGINT",Qh),process.on("SIGTERM",Zh),process.on("exit",ey),Ti=!0)}function ty(){Ti&&(process.removeListener("SIGINT",Qh),process.removeListener("SIGTERM",Zh),process.removeListener("exit",ey),Ti=!1)}async function gP(t){return Ze!==null?Ze:(un!==null||(un=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(Xh(),Yh)),n=Fh(t),r=new e(n);return mP(),Ze=r,un=null,r})()),un)}async function bd(){if(Ze===null)return;let t=Ze;Ze=null,un=null,ty(),await t.shutdown()}function hP(){return Ze!==null}function yP(){return Ze}function bP(){Ze=null,un=null,ty()}var Ze,un,Ti,fn=b(()=>{"use strict";ud();Ze=null,un=null,Ti=!1});async function ny(t,e){try{return await Ch(t,e)}catch(n){return U("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function EP(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(fn(),pn));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal})}async function ry(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??EP,o=null,s=t,i=null,a=null;try{let c=await ki(n,t,{headers:_P,redirect:"follow",signal:e.signal});i=c.status,s=c.url||t;let d=c.headers.get("content-type")??"";if(c.ok){if(kP.test(d))throw new Error(`web_scrape markdown mode received binary content (${d.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let u=await c.text();if(vP.test(d)&&!SP.test(d))return{title:"",markdown:u.trim(),finalUrl:s,usedRender:!1};if(o=await ny(u,s),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(c){if(e.signal.aborted||c instanceof Error&&c.message.startsWith("web_scrape markdown mode received binary"))throw c;a=c}if(!(o===null||o.textLength<200)&&o!==null)return{title:o.title,markdown:o.markdown,finalUrl:s,usedRender:!1};try{let c=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal}),d=await ny(c.html,c.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(o===null||d.textLength>=o.textLength)return{title:d.title,markdown:d.markdown,finalUrl:c.finalUrl,usedRender:!0}}catch(c){if(e.signal.aborted)throw c;if(o===null){let d=c instanceof Error?c.message:String(c),u=a instanceof Error?a.message:`HTTP ${i??"error"}`,p=new Error(`web_scrape could not retrieve ${t}: fetch failed (${u}) and render failed (${d}).`);throw p.cause=c,p}}if(o!==null)return{title:o.title,markdown:o.markdown,finalUrl:s,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${i??"error"}).`)}var SP,vP,kP,_P,oy=b(()=>{"use strict";Ih();cd();oe();SP=/(text\/html|application\/xhtml\+xml)/i,vP=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,kP=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,_P={"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 xP(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(AP,{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),TP),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let l="";try{let d=await s.text(),u=ei(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 sy(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?xP({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 iy(t,e){if(e.length===0)return`# Search results for "${t}"
854
+ `).trim()}function EI(t){return(t?.textContent??"").replace(/\s+/g," ").trim().length}async function Ch(t,e){let{JSDOM:n,Readability:r,turndown:o}=await _I(),i=new n(t,{url:e}).window.document,a=(i.title??"").trim(),l=(()=>{try{let p=i.cloneNode(!0);return new r(p).parse()}catch{return null}})();if(l&&typeof l.content=="string"&&l.content.trim().length>0){let p=Rh(o.turndown(l.content)),f=(l.title??"").trim()||a,m=typeof l.length=="number"&&l.length>0?l.length:(l.textContent??"").replace(/\s+/g," ").trim().length;return{title:f,markdown:p,textLength:m,usedFallback:!1}}let c=i.body,d=c?.innerHTML??"",u=Rh(o.turndown(d));return{title:a,markdown:u,textLength:EI(c),usedFallback:!0}}var ld,Ih=b(()=>{"use strict";ld=null});function TI(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 Ph(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function xI(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 ki(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??TI,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(!AI.has(u.status)||d===o)return u;let p=xI(u,i)??Ph(d,s,i);U("[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=Ph(d,s,i);U("[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 AI,cd=b(()=>{"use strict";oe();AI=new Set([429,502,503,504])});import{readFileSync as RI}from"node:fs";import{join as CI}from"path";function II(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function Mh(t,e){return II(e).test(t)}function OI(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(PI.has(e))return!0;if(MI.has(e))return!1}return!1}function Oh(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function DI(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 Dh(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Pl(e),e}function FI(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function LI(t){try{return RI(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function NI(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=Dh(e.defaultProfile)),n}function Fh(t){let e=t?.env??E,n=t?.readFileSync??LI,r=t?.surface??e.AGENT_SURFACE,o=OI(e.AFK_BROWSER_HEADLESS,r),s=Oh(e.AFK_BROWSER_ALLOWED_DOMAINS),i=Oh(e.AFK_BROWSER_BLOCKED_DOMAINS),a=FI(e.AFK_BROWSER_DOM_SNAPSHOTS),l=DI(e.AFK_BROWSER_BACKEND),c=Dh(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():CI(ot(),"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=NI(d,m);return g.configPath=p,g}function dd(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(Mh(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>Mh(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var PI,MI,ud=b(()=>{"use strict";H();W();PI=new Set(["daemon","subagent","telegram","afk"]),MI=new Set(["repl","interactive","cli"])});import dn from"node:fs";import _i from"node:path";import{randomBytes as $I}from"node:crypto";import{chromium as UI}from"playwright";function BI(){try{return"5.48.0"}catch{}try{let t=_i.resolve(import.meta.dirname,"../../../package.json"),e=dn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var jI,Ei,Lh=b(()=>{"use strict";W();oe();jI=BI(),Ei=class{config;browser;sessions=new Map;launchPromise;shutdownComplete=!1;constructor(e){this.config=e}async ensureBrowser(){return this.browser!==void 0&&this.browser.isConnected()?this.browser:(this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=UI.launch({headless:this.config.headless}).then(e=>(this.browser=e,this.launchPromise=void 0,e)).catch(e=>{throw this.launchPromise=void 0,e}),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=()=>{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",s,{once:!0});try{let i=await o.newPage(),a=await i.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil}),l=await i.content(),c=i.url(),d=a!==null?a.status():null;return{html:l,finalUrl:c,httpStatus:d}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",s),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){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.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/${jI}`}}loadStorageState(e){let n=Ml(e);try{if(!dn.existsSync(n))return;let r=JSON.parse(dn.readFileSync(n,"utf8"));return U("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){U("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Ml(e);if(!dn.existsSync(r))return;let o=await n.storageState(),s=_i.join(_i.dirname(r),`.${_i.basename(r)}.${process.pid}.${$I(4).toString("hex")}.tmp`);dn.writeFileSync(s,JSON.stringify(o),{mode:384}),dn.chmodSync(s,384),dn.renameSync(s,r),U("[browser/vault] saved session",{profile:e,file:r})}catch(r){U("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as HI}from"crypto";function pd(t){if(t.length===0)return t;let e=t;for(let{regex:n,name:r}of WI)r==="form-password"?e=e.replace(n,"password=[redacted]"):e=e.replace(n,"[redacted]");return e}function Nh(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&KI.test(t.label))}function $h(t){return HI("sha256").update(t,"utf8").digest("hex").slice(0,8)}function Uh(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var WI,KI,qr=b(()=>{"use strict";WI=[{name:"aws-access-key",regex:/AKIA[0-9A-Z]{16}/g},{name:"github-pat",regex:/ghp_[a-zA-Z0-9]{36}/g},{name:"openai-bearer",regex:/sk-[a-zA-Z0-9_-]{20,}/g},{name:"slack-token",regex:/xox[abp]-[a-zA-Z0-9-]{10,}/g},{name:"jwt",regex:/eyJ[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}/g},{name:"form-password",regex:/password=[^&\s]+/gi}];KI=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as GI}from"node:crypto";function qI(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function zI(t,e,n){return`el_${GI("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function JI(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Bh(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function Hh(t,e){let n=t.role??"",r=t.name??"";jh.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])Hh(s,e)}async function VI(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},Wh).catch(()=>[])}async function YI(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},Wh).catch(()=>[])}function XI(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Ai(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=XI(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=VI(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,S=!1;u!==null?(y=[],Hh(u,y)):(o.push("observation skipped accessibility tree (returned null)"),S=!0,y=(await YI(t)).filter(B=>jh.has(B.role??"")));let w=new Map;for(let x of p){let B=Bh(x.name),j=w.get(B);(!j||j.bbox.w===0&&x.bbox.w>0)&&w.set(B,x)}let _=y.map(x=>({ax:x,dom:w.get(Bh(x.name??""))})),v=r?_:_.filter(x=>x.dom?x.dom.bbox.w>0||x.dom.bbox.h>0:!0);v.sort((x,B)=>{let j=x.dom?.bbox.y??0,F=B.dom?.bbox.y??0;if(j!==F)return j-F;let N=x.dom?.bbox.x??0,O=B.dom?.bbox.x??0;return N-O}),v.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=v.slice(0,n).map((x,B)=>{let j=x.ax.role??"generic",F=x.ax.name??"",N=zI(j,F,B),O=x.dom?.bbox??{x:0,y:0,w:0,h:0},I=x.dom?.type??null,P=null;x.ax.value!==void 0&&x.ax.value!==null&&(P=String(x.ax.value)),x.ax.checked!==void 0&&(P=String(x.ax.checked)),Nh({role:j,kind:I})&&(P="[redacted]");let L={disabled:x.ax.disabled??!1};x.ax.checked!==void 0&&(L.checked=x.ax.checked===!0||x.ax.checked==="mixed"),x.ax.selected!==void 0&&(L.selected=x.ax.selected),x.ax.expanded!==void 0&&(L.expanded=x.ax.expanded);let $;x.dom?.testId?$=`[data-testid="${x.dom.testId}"]`:x.dom?.id&&($=`#${x.dom.id}`);let G={id:N,role:j,label:qI(F),kind:I,value:P,state:L,bbox:O};return $!==void 0&&(G.selector=$),G}),k="idle";try{let x=await t.evaluate(()=>document.readyState);x==="loading"?k="loading":x==="interactive"?k="navigating":k="idle"}catch{k="navigating"}k!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),S&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let A=JI(f),M=`obs_${e.observationCounter.toString(36)}`,C=new Date().toISOString();return{observationId:M,url:m,title:g,textSummary:A,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:k,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:C}}var jh,Wh,Kh=b(()=>{"use strict";qr();jh=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);Wh="a[href], button, input, select, textarea, [role], [tabindex], label"});async function Gh(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 fd(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>Gh(t,s)))).filter(o=>o!==null)}async function QI(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 md(t,e,n){switch(e.kind){case"element_id":return ZI(t,e,n);case"selector":return eP(t,e);case"semantic":return tP(t,e)}}async function ZI(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 fd(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function eP(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 fd(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function tP(t,e){return e.role!==void 0?nP(t,e.text,e.role):rP(t,e.text,e)}async function nP(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 fd(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function rP(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 QI(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 S=await Gh(y.locator,y.index);if(S!==null){let w=`${S.role}:${S.label}:${g}`,_=0;for(let v=0;v<w.length;v++)_=_*31+w.charCodeAt(v)>>>0;f.push({...S,id:`el_${_.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var qh=b(()=>{"use strict"});import{randomBytes as oP}from"crypto";import{mkdir as sP,stat as iP,writeFile as aP}from"fs/promises";import{join as gd}from"path";import{gzip as lP}from"zlib";import{promisify as cP}from"util";function dP(t){return gd(Qo(t),"browser")}function uP(t){return gd(dP(t),"screenshots")}function pP(){return new Date().toISOString().replace(/[:.]/g,"-")}function fP(){return oP(3).toString("hex")}async function hd(t,e,n){if(e.length>zh)throw new Error(`writeScreenshotSidecar: buffer exceeds ${zh} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=uP(t);await sP(r,{recursive:!0});let o=`${pP()}-${fP()}-${n}.png`,s=gd(r,o);await aP(s,e);let{size:i}=await iP(s);return{path:s,bytes:i}}var lz,zh,Jh=b(()=>{"use strict";W();qr();lz=cP(lP);zh=5*1024*1024});var Yh={};El(Yh,{PlaywrightProvider:()=>yd});function Vh(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 yd,Xh=b(()=>{"use strict";Lh();Kh();qh();ud();qr();Jh();yd=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Ei(e)}async open(e){let n=dd(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(c){a=c}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let l=await Ai(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,l.interactive,l.url,l.title,"browser_open"),a!==null)throw a;return l}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 Ai(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 md(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${Vh(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":{let g=pd(e.value??"");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=r.url();if(u!==s){let g=dd(u,this.config);if(!g.allowed)return await r.goBack().catch(()=>{}),{outcome:"blocked_by_policy",url:u,reason:g.reason}}let p=null;(e.screenshot===!0||c!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Ai(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})}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 md(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${Vh(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 hd(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 hd(n,o,r);return s}catch{return null}}}});var pn={};El(pn,{__resetBrowserRegistryForTests:()=>bP,browserProviderActive:()=>hP,closeBrowserProvider:()=>bd,getBrowserProvider:()=>gP,peekBrowserProvider:()=>yP});function Qh(){Promise.resolve(bd()).then(()=>{process.exit(130)})}function Zh(){Promise.resolve(bd()).then(()=>{process.exit(143)})}function ey(){Ze=null}function mP(){Ti||(process.on("SIGINT",Qh),process.on("SIGTERM",Zh),process.on("exit",ey),Ti=!0)}function ty(){Ti&&(process.removeListener("SIGINT",Qh),process.removeListener("SIGTERM",Zh),process.removeListener("exit",ey),Ti=!1)}async function gP(t){return Ze!==null?Ze:(un!==null||(un=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(Xh(),Yh)),n=Fh(t),r=new e(n);return mP(),Ze=r,un=null,r})()),un)}async function bd(){if(Ze===null)return;let t=Ze;Ze=null,un=null,ty(),await t.shutdown()}function hP(){return Ze!==null}function yP(){return Ze}function bP(){Ze=null,un=null,ty()}var Ze,un,Ti,fn=b(()=>{"use strict";ud();Ze=null,un=null,Ti=!1});async function ny(t,e){try{return await Ch(t,e)}catch(n){return U("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function EP(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(fn(),pn));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal})}async function ry(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??EP,o=null,s=t,i=null,a=null;try{let c=await ki(n,t,{headers:_P,redirect:"follow",signal:e.signal});i=c.status,s=c.url||t;let d=c.headers.get("content-type")??"";if(c.ok){if(kP.test(d))throw new Error(`web_scrape markdown mode received binary content (${d.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let u=await c.text();if(vP.test(d)&&!SP.test(d))return{title:"",markdown:u.trim(),finalUrl:s,usedRender:!1};if(o=await ny(u,s),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(c){if(e.signal.aborted||c instanceof Error&&c.message.startsWith("web_scrape markdown mode received binary"))throw c;a=c}if(!(o===null||o.textLength<200)&&o!==null)return{title:o.title,markdown:o.markdown,finalUrl:s,usedRender:!1};try{let c=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal}),d=await ny(c.html,c.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(o===null||d.textLength>=o.textLength)return{title:d.title,markdown:d.markdown,finalUrl:c.finalUrl,usedRender:!0}}catch(c){if(e.signal.aborted)throw c;if(o===null){let d=c instanceof Error?c.message:String(c),u=a instanceof Error?a.message:`HTTP ${i??"error"}`,p=new Error(`web_scrape could not retrieve ${t}: fetch failed (${u}) and render failed (${d}).`);throw p.cause=c,p}}if(o!==null)return{title:o.title,markdown:o.markdown,finalUrl:s,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${i??"error"}).`)}var SP,vP,kP,_P,oy=b(()=>{"use strict";Ih();cd();oe();SP=/(text\/html|application\/xhtml\+xml)/i,vP=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,kP=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,_P={"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 xP(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(AP,{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),TP),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let l="";try{let d=await s.text(),u=ei(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 sy(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?xP({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 iy(t,e){if(e.length===0)return`# Search results for "${t}"
855
855
 
856
856
  (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(`
857
857
  `).trimEnd()}var AP,TP,ay=b(()=>{"use strict";Un();AP="https://api.exa.ai/search",TP=10});function FP(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=RP;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,CP)}let a=IP;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,PP)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function wd(t,e){let n=Buffer.from(t,"utf8");return n.byteLength<=e?t:n.subarray(0,e).toString("utf8")+MP}function LP(t){let e=[],n=t;for(let o=0;o<4&&n instanceof Error;o++)e.push(n.message),n=n.cause;let r=e.join(" | ");return DP.some(o=>r.includes(o))}function NP(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env;return async(r,o)=>{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 s=FP(r);if("error"in s)return{content:s.error,isError:!0};if(o.aborted){let d=o.reason;return{content:`web_scrape aborted: ${d instanceof Error?d.message:String(d??"aborted")}`,isError:!0}}let i=new AbortController,a=()=>{i.abort(o.reason)},l,c=()=>{let d=i.signal.reason;return d instanceof Error?d.message:String(d??"aborted")};try{if(o.addEventListener("abort",a,{once:!0}),l=setTimeout(()=>{i.abort(new Error(`web_scrape timeout after ${s.timeoutMs}ms`))},s.timeoutMs),s.mode==="raw"){let u;try{u=await ki(e,s.url,{method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:i.signal})}catch(f){return i.signal.aborted?{content:`web_scrape aborted: ${c()}`,isError:!0}:{content:`web_scrape network error: ${f instanceof Error?f.message:String(f)}`,isError:!0}}if(!u.ok)return{content:`web_scrape HTTP ${u.status} ${u.statusText||""}`.trimEnd()+` for ${s.url}`,isError:!0};let p;try{p=await u.text()}catch(f){return{content:`web_scrape read error: ${f instanceof Error?f.message:String(f)}`,isError:!0}}return{content:wd(p,s.maxBytes)}}if(s.mode==="markdown")try{let u=await ry(s.url,{fetchFn:e,renderFn:t.renderFn,timeoutMs:s.timeoutMs,signal:i.signal});return u.markdown.trim().length===0?{content:`web_scrape extracted no readable content from ${s.url}.`,isError:!0}:{content:wd(u.markdown,s.maxBytes)}}catch(u){if(i.signal.aborted)return{content:`web_scrape aborted: ${c()}`,isError:!0};let p=u instanceof Error?u.message:String(u),f=LP(u)?" (the render fallback needs the optional Playwright browser \u2014 run `pnpm exec playwright install chromium`)":"";return{content:`web_scrape markdown error: ${p}${f}`,isError:!0}}let d=sy({exaApiKey:n.EXA_API_KEY,fetchFn:e});if("error"in d)return{content:d.error,isError:!0};try{let u=await d.search(s.query,{limit:OP,timeoutMs:s.timeoutMs,signal:i.signal});return{content:wd(iy(s.query,u),s.maxBytes)}}catch(u){return i.signal.aborted?{content:`web_scrape aborted: ${c()}`,isError:!0}:{content:`web_scrape search error (${d.name}): ${u instanceof Error?u.message:String(u)}`,isError:!0}}}finally{l!==void 0&&clearTimeout(l),o.removeEventListener("abort",a)}}}var RP,CP,IP,PP,MP,OP,DP,ly,cy=b(()=>{"use strict";oy();ay();cd();RP=3e4,CP=12e4,IP=1e6,PP=1e7,MP=`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-afk",
3
- "version": "5.47.0",
3
+ "version": "5.48.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",