agent-afk 5.127.1 → 5.127.3

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
@@ -213,7 +213,7 @@ ${o}`,paths:[e,n]}:o!==null?s={content:o,paths:[n]}:r!==null?s={content:r,paths:
213
213
 
214
214
  ${e}`}var vj,dm=g(()=>{"use strict";vj=new Set(["script","style","noscript","template","svg"])});function _j(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 Qk(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function Tj(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 Zk(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??_j,c=n.signal??void 0,l;for(let d=0;d<=o;d++){if(c?.aborted)throw c.reason??new Error("aborted");try{let u=await t(e,n);if(!Aj.has(u.status)||d===o)return u;let p=Tj(u,i)??Qk(d,s,i);N("[web/retryFetch] retrying",{url:e,attempt:d,status:u.status,waitMs:p}),await u.body?.cancel().catch(()=>{}),await a(p,c)}catch(u){if(c?.aborted||(l=u,d===o))throw u;let p=Qk(d,s,i);N("[web/retryFetch] retrying after error",{url:e,attempt:d,waitMs:p}),await a(p,c)}}throw l??new Error("retryFetch: exhausted without a result")}var Aj,eA=g(()=>{"use strict";se();Aj=new Set([429,502,503,504])});import{BlockList as Ej,isIP as pm}from"node:net";import{lookup as xj}from"node:dns/promises";import{Agent as Rj}from"undici";function nA(){let t=v.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function Mj(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function um(t){let e=pm(t);return e===0?!1:Pj.check(t,e===4?"ipv4":"ipv6")}async function rA(t){return xj(t,{all:!0,verbatim:!0})}async function fm(t,e={}){if(e.allowPrivateHosts??nA())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=Mj(n.hostname),o=(a,c)=>`refusing to fetch ${c} \u2014 internal/private address ${a} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`;if(pm(r)!==0)return um(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??rA,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(um(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function qs(t,e={}){let n=await fm(t,e);if(!n.allowed)throw new wt(n.reason)}async function Kc(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<=tA;i++){await qs(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??nA())?{dispatcher:Oj}:{}},c=await Zk(t,s,a,r.retry??{});if(!Dj.has(c.status))return c;let l=c.headers.get("location");if(l===null||l.trim()==="")return c;let d;try{d=new URL(l,c.url||s).toString()}catch{return c}await c.body?.cancel().catch(()=>{}),s=d}throw new wt(`too many redirects (>${tA}) starting from ${e}`)}var Ij,Cj,Pj,wt,Oj,tA,Dj,mm=g(()=>{"use strict";L();eA();Ij=[["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]],Cj=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],Pj=(()=>{let t=new Ej;for(let[e,n]of Ij)t.addSubnet(e,n,"ipv4");for(let[e,n]of Cj)t.addSubnet(e,n,"ipv6");return t})(),wt=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};Oj=new Rj({connect:{lookup(t,e,n){rA(t).then(r=>{let o=r.find(i=>um(i.address));if(o!==void 0){n(new wt(`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,pm(s.address))},r=>n(r,"",0))}}});tA=20,Dj=new Set([301,302,303,307,308])});import{readFileSync as Fj}from"node:fs";import{join as Lj}from"path";function Nj(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function oA(t,e){return Nj(e).test(t)}function Bj(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(Uj.has(e))return!0;if($j.has(e))return!1}return!1}function sA(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function Hj(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 iA(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Ep(e),e}function jj(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function Wj(t){try{return Fj(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function Kj(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=iA(e.defaultProfile)),n}function aA(t){let e=t?.env??v,n=t?.readFileSync??Wj,r=t?.surface??e.AGENT_SURFACE,o=Bj(e.AFK_BROWSER_HEADLESS,r),s=sA(e.AFK_BROWSER_ALLOWED_DOMAINS),i=sA(e.AFK_BROWSER_BLOCKED_DOMAINS),a=jj(e.AFK_BROWSER_DOM_SNAPSHOTS),c=Hj(e.AFK_BROWSER_BACKEND),l=iA(e.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null,defaultProfile:l},u=e.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():Lj(Ht(),"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 h=Kj(d,m);return h.configPath=p,h}function Gc(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(oA(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>oA(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var Uj,$j,qc=g(()=>{"use strict";L();B();Uj=new Set(["daemon","subagent","telegram","afk"]),$j=new Set(["repl","interactive","cli"])});import{existsSync as Gj,readFileSync as qj}from"node:fs";import{createRequire as Xj}from"node:module";import{dirname as zj,join as Vj}from"node:path";function dA(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<Yj&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function $e(t){let e=dA(t);return lA.some(n=>e.includes(n))}function Qj(){try{let e=Xj(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(qj(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=Vj(zj(e),o);return Gj(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function Xs(){return cA??=Qj()??Jj,cA}function gm(t){return t.includes("install chromium")}function st(t,e){let n=dA(t),r=e?.latched===!0?` ${Zj}`:"";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: ${Xs()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Xs()}). Or pick a different tool.${r}`}function hm(t,e,n=!1){if(!$e(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
215
215
 
216
- ${st(t,{headless:e,latched:n})}`,{cause:t})}var lA,Jj,Yj,cA,Zj,ym=g(()=>{"use strict";lA=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],Jj="pnpm exec playwright install chromium",Yj=4;Zj="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 tr from"node:fs";import Xc from"node:path";import{randomBytes as eW}from"node:crypto";import{chromium as tW}from"playwright";function nW(){try{return"5.127.1"}catch{}try{let t=Xc.resolve(import.meta.dirname,"../../../package.json"),e=tr.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var rW,zc,uA=g(()=>{"use strict";ym();B();se();rW=nW(),zc=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=tW.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=hm(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(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${rW}`}}loadStorageState(e){let n=xp(e);try{if(!tr.existsSync(n))return;let r=JSON.parse(tr.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=xp(e);if(!tr.existsSync(r))return;let o=await n.storageState(),s=Xc.join(Xc.dirname(r),`.${Xc.basename(r)}.${process.pid}.${eW(4).toString("hex")}.tmp`);tr.writeFileSync(s,JSON.stringify(o),{mode:384}),tr.chmodSync(s,384),tr.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 oW}from"crypto";function pA(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&sW.test(t.label))}function fA(t){return oW("sha256").update(t,"utf8").digest("hex").slice(0,8)}function mA(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var sW,Vc=g(()=>{"use strict";sW=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as iW}from"node:crypto";function aW(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function cW(t,e,n){return`el_${iW("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function lW(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function gA(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function yA(t,e){let n=t.role??"",r=t.name??"";hA.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])yA(s,e)}async function dW(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},bA).catch(()=>[])}async function uW(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let h=s.type;h==="checkbox"?l="checkbox":h==="radio"?l="radio":h==="button"||h==="submit"||h==="reset"?l="button":h==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},bA).catch(()=>[])}function pW(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Jc(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=pW(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=dW(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,h]=await Promise.all([i,a,c,l,d]),y,w=!1;u!==null?(y=[],yA(u,y)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,y=(await uW(t)).filter(M=>hA.has(M.role??"")));let _=new Map;for(let C of p){let M=gA(C.name),X=_.get(M);(!X||X.bbox.w===0&&C.bbox.w>0)&&_.set(M,C)}let E=y.map(C=>({ax:C,dom:_.get(gA(C.name??""))})),k=r?E:E.filter(C=>C.dom?C.dom.bbox.w>0||C.dom.bbox.h>0:!0);k.sort((C,M)=>{let X=C.dom?.bbox.y??0,P=M.dom?.bbox.y??0;if(X!==P)return X-P;let H=C.dom?.bbox.x??0,F=M.dom?.bbox.x??0;return H-F}),k.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=k.slice(0,n).map((C,M)=>{let X=C.ax.role??"generic",P=C.ax.name??"",H=cW(X,P,M),F=C.dom?.bbox??{x:0,y:0,w:0,h:0},U=C.dom?.type??null,$=null;C.ax.value!==void 0&&C.ax.value!==null&&($=String(C.ax.value)),C.ax.checked!==void 0&&($=String(C.ax.checked)),pA({role:X,kind:U})&&($="[redacted]");let K={disabled:C.ax.disabled??!1};C.ax.checked!==void 0&&(K.checked=C.ax.checked===!0||C.ax.checked==="mixed"),C.ax.selected!==void 0&&(K.selected=C.ax.selected),C.ax.expanded!==void 0&&(K.expanded=C.ax.expanded);let Q;C.dom?.testId?Q=`[data-testid="${C.dom.testId}"]`:C.dom?.id&&(Q=`#${C.dom.id}`);let De={id:H,role:X,label:aW(P),kind:U,value:$,state:K,bbox:F};return Q!==void 0&&(De.selector=Q),De}),I="idle";try{let C=await t.evaluate(()=>document.readyState);C==="loading"?I="loading":C==="interactive"?I="navigating":I="idle"}catch{I="navigating"}I!=="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=lW(f),S=`obs_${e.observationCounter.toString(36)}`,A=new Date().toISOString();return{observationId:S,url:m,title:h,textSummary:x,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:A}}var hA,bA,wA=g(()=>{"use strict";Vc();hA=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);bA="a[href], button, input, select, textarea, [role], [tabindex], label"});async function SA(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${e}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function bm(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>SA(t,s)))).filter(o=>o!==null)}async function fW(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function wm(t,e,n){switch(e.kind){case"element_id":return mW(t,e,n);case"selector":return gW(t,e);case"semantic":return hW(t,e)}}async function mW(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await bm(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function gW(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 bm(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function hW(t,e){return e.role!==void 0?yW(t,e.text,e.role):bW(t,e.text,e)}async function yW(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 bm(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function bW(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await fW(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let w=await SA(y.locator,y.index);if(w!==null){let _=`${w.role}:${w.label}:${h}`,E=0;for(let k=0;k<_.length;k++)E=E*31+_.charCodeAt(k)>>>0;f.push({...w,id:`el_${E.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var vA=g(()=>{"use strict"});async function Sm(t,e,n,r){let o=t.url();if(o===n)return null;let s=Gc(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 kA=g(()=>{"use strict";qc()});import{randomBytes as wW}from"crypto";import{mkdir as SW,stat as vW,writeFile as kW}from"fs/promises";import{join as vm}from"path";import{gzip as AW}from"zlib";import{promisify as _W}from"util";function TW(t){return vm(_t(t),"browser")}function EW(t){return vm(TW(t),"screenshots")}function xW(){return new Date().toISOString().replace(/[:.]/g,"-")}function RW(){return wW(3).toString("hex")}async function km(t,e,n){if(e.length>AA)throw new Error(`writeScreenshotSidecar: buffer exceeds ${AA} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=EW(t);await SW(r,{recursive:!0});let o=`${xW()}-${RW()}-${n}.png`,s=vm(r,o);await kW(s,e);let{size:i}=await vW(s);return{path:s,bytes:i}}var coe,AA,_A=g(()=>{"use strict";B();Vc();coe=_W(AW);AA=5*1024*1024});var EA={};wp(EA,{PlaywrightProvider:()=>Am});function TA(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 Am,xA=g(()=>{"use strict";uA();wA();vA();qc();kA();_A();Am=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new zc(e)}async open(e){let n=Gc(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await Sm(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 Jc(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 Jc(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 wm(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${TA(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await d()}catch(y){l=y}else l=h}let u=await Sm(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Jc(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await wm(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${TA(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 km(n,s,"browser_screenshot"),c=0,l=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(e){let n=this.sessions.get(e);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await km(n,o,r);return s}catch{return null}}}});var rr={};wp(rr,{__resetBrowserRegistryForTests:()=>OW,browserProviderActive:()=>PW,closeBrowserProvider:()=>_m,getBrowserProvider:()=>CW,peekBrowserProvider:()=>MW});function RA(){Promise.resolve(_m()).then(()=>{process.exit(130)})}function IA(){Promise.resolve(_m()).then(()=>{process.exit(143)})}function CA(){Ot=null}function IW(){Yc||(process.on("SIGINT",RA),process.on("SIGTERM",IA),process.on("exit",CA),Yc=!0)}function PA(){Yc&&(process.removeListener("SIGINT",RA),process.removeListener("SIGTERM",IA),process.removeListener("exit",CA),Yc=!1)}async function CW(t){return Ot!==null?Ot:(nr!==null||(nr=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(xA(),EA)),n=aA(t),r=new e(n);return IW(),Ot=r,nr=null,r})()),nr)}async function _m(){if(Ot===null)return;let t=Ot;Ot=null,nr=null,PA(),await t.shutdown()}function PW(){return Ot!==null}function MW(){return Ot}function OW(){Ot=null,nr=null,PA()}var Ot,nr,Yc,or=g(()=>{"use strict";qc();Ot=null,nr=null,Yc=!1});async function MA(t,e){try{return await Vk(t,e)}catch(n){return N("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function $W(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(or(),rr));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function OA(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??$W,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Kc(n,t,{headers:UW,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(NW.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(LW.test(p)&&!FW.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await MA(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof wt||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=lm({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await qs(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>qs(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await qs(u.finalUrl,o);let p=await MA(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=lm({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 wt)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${c??"error"}).`)}var FW,LW,NW,UW,DA=g(()=>{"use strict";Jk();dm();mm();se();FW=/(text\/html|application\/xhtml\+xml)/i,LW=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,NW=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,UW={"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 jW(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(BW,{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),HW),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=ee(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function FA(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?jW({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 LA(t,e){if(e.length===0)return`# Search results for "${t}"
216
+ ${st(t,{headless:e,latched:n})}`,{cause:t})}var lA,Jj,Yj,cA,Zj,ym=g(()=>{"use strict";lA=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],Jj="pnpm exec playwright install chromium",Yj=4;Zj="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 tr from"node:fs";import Xc from"node:path";import{randomBytes as eW}from"node:crypto";import{chromium as tW}from"playwright";function nW(){try{return"5.127.3"}catch{}try{let t=Xc.resolve(import.meta.dirname,"../../../package.json"),e=tr.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var rW,zc,uA=g(()=>{"use strict";ym();B();se();rW=nW(),zc=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=tW.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=hm(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(c){s=c,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),c;try{c=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let l=await a.content();if(s!==void 0)throw s;let d=a.url(),u=c!==null?c.status():null;return{html:l,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${rW}`}}loadStorageState(e){let n=xp(e);try{if(!tr.existsSync(n))return;let r=JSON.parse(tr.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=xp(e);if(!tr.existsSync(r))return;let o=await n.storageState(),s=Xc.join(Xc.dirname(r),`.${Xc.basename(r)}.${process.pid}.${eW(4).toString("hex")}.tmp`);tr.writeFileSync(s,JSON.stringify(o),{mode:384}),tr.chmodSync(s,384),tr.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 oW}from"crypto";function pA(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&sW.test(t.label))}function fA(t){return oW("sha256").update(t,"utf8").digest("hex").slice(0,8)}function mA(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var sW,Vc=g(()=>{"use strict";sW=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as iW}from"node:crypto";function aW(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function cW(t,e,n){return`el_${iW("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function lW(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function gA(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function yA(t,e){let n=t.role??"",r=t.name??"";hA.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])yA(s,e)}async function dW(t){return t.evaluate(e=>{let n=Array.from(document.querySelectorAll(e)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let d=window.getComputedStyle(i);if(d.display==="none"||d.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),c=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a==="input"?o.type||null:o.getAttribute("type");r.push({name:c,tagName:a,type:l,id:o.id||null,testId:o.getAttribute("data-testid"),bbox:{x:Math.round(s.left),y:Math.round(s.top),w:Math.round(s.width),h:Math.round(s.height)}})}return r},bA).catch(()=>[])}async function uW(t){return t.evaluate(e=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(e)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",c=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),l=a||(n[i]??"");if(i==="input"){let h=s.type;h==="checkbox"?l="checkbox":h==="radio"?l="radio":h==="button"||h==="submit"||h==="reset"?l="button":h==="search"?l="searchbox":l="textbox"}if(!l)continue;let d="value"in s?s.value:void 0,u=d!==void 0?String(d):void 0,p=s.disabled??!1,f=i==="input"?s.checked:void 0,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},bA).catch(()=>[])}function pW(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Jc(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=pW(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=dW(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,h]=await Promise.all([i,a,c,l,d]),y,w=!1;u!==null?(y=[],yA(u,y)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,y=(await uW(t)).filter(M=>hA.has(M.role??"")));let _=new Map;for(let C of p){let M=gA(C.name),X=_.get(M);(!X||X.bbox.w===0&&C.bbox.w>0)&&_.set(M,C)}let E=y.map(C=>({ax:C,dom:_.get(gA(C.name??""))})),k=r?E:E.filter(C=>C.dom?C.dom.bbox.w>0||C.dom.bbox.h>0:!0);k.sort((C,M)=>{let X=C.dom?.bbox.y??0,P=M.dom?.bbox.y??0;if(X!==P)return X-P;let H=C.dom?.bbox.x??0,F=M.dom?.bbox.x??0;return H-F}),k.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=k.slice(0,n).map((C,M)=>{let X=C.ax.role??"generic",P=C.ax.name??"",H=cW(X,P,M),F=C.dom?.bbox??{x:0,y:0,w:0,h:0},U=C.dom?.type??null,$=null;C.ax.value!==void 0&&C.ax.value!==null&&($=String(C.ax.value)),C.ax.checked!==void 0&&($=String(C.ax.checked)),pA({role:X,kind:U})&&($="[redacted]");let K={disabled:C.ax.disabled??!1};C.ax.checked!==void 0&&(K.checked=C.ax.checked===!0||C.ax.checked==="mixed"),C.ax.selected!==void 0&&(K.selected=C.ax.selected),C.ax.expanded!==void 0&&(K.expanded=C.ax.expanded);let Q;C.dom?.testId?Q=`[data-testid="${C.dom.testId}"]`:C.dom?.id&&(Q=`#${C.dom.id}`);let De={id:H,role:X,label:aW(P),kind:U,value:$,state:K,bbox:F};return Q!==void 0&&(De.selector=Q),De}),I="idle";try{let C=await t.evaluate(()=>document.readyState);C==="loading"?I="loading":C==="interactive"?I="navigating":I="idle"}catch{I="navigating"}I!=="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=lW(f),S=`obs_${e.observationCounter.toString(36)}`,A=new Date().toISOString();return{observationId:S,url:m,title:h,textSummary:x,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:A}}var hA,bA,wA=g(()=>{"use strict";Vc();hA=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);bA="a[href], button, input, select, textarea, [role], [tabindex], label"});async function SA(t,e){try{let n=await t.nth(e).evaluate(i=>{let a=i,c=a.getAttribute("role")??a.tagName.toLowerCase(),l=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",d=a.getBoundingClientRect();return{role:c,label:l,x:Math.round(d.x),y:Math.round(d.y),w:Math.round(d.width),h:Math.round(d.height)}}),r=`${n.role}:${n.label}:${e}`,o=0;for(let i=0;i<r.length;i++)o=o*31+r.charCodeAt(i)>>>0;return{id:`el_${o.toString(16).padStart(6,"0").slice(0,6)}`,role:n.role,label:n.label,kind:null,value:null,state:{disabled:!1},bbox:{x:n.x,y:n.y,w:n.w,h:n.h}}}catch{return null}}async function bm(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>SA(t,s)))).filter(o=>o!==null)}async function fW(t){let e=new Set,n=[];for(let{loc:r,count:o}of t)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let c=a,l=c.getBoundingClientRect();return`${c.tagName}@${Math.round(l.x)},${Math.round(l.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function wm(t,e,n){switch(e.kind){case"element_id":return mW(t,e,n);case"selector":return gW(t,e);case"semantic":return hW(t,e)}}async function mW(t,e,n){let r=n.get(e.elementId);if(r===void 0)return{outcome:"not_found",query:e};if(r.selector!==void 0){let c=t.locator(r.selector);if(await c.count()===1)return{outcome:"resolved",locator:c}}let o=t.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:e};if(s===1)return{outcome:"resolved",locator:o};let i=await bm(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function gW(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 bm(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function hW(t,e){return e.role!==void 0?yW(t,e.text,e.role):bW(t,e.text,e)}async function yW(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 bm(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function bW(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{exact:!1}),[i,a,c]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+c===0)return{outcome:"not_found",query:n};let d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),c>0&&d.push({loc:s,count:c});let u=await fW(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let w=await SA(y.locator,y.index);if(w!==null){let _=`${w.role}:${w.label}:${h}`,E=0;for(let k=0;k<_.length;k++)E=E*31+_.charCodeAt(k)>>>0;f.push({...w,id:`el_${E.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var vA=g(()=>{"use strict"});async function Sm(t,e,n,r){let o=t.url();if(o===n)return null;let s=Gc(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 kA=g(()=>{"use strict";qc()});import{randomBytes as wW}from"crypto";import{mkdir as SW,stat as vW,writeFile as kW}from"fs/promises";import{join as vm}from"path";import{gzip as AW}from"zlib";import{promisify as _W}from"util";function TW(t){return vm(_t(t),"browser")}function EW(t){return vm(TW(t),"screenshots")}function xW(){return new Date().toISOString().replace(/[:.]/g,"-")}function RW(){return wW(3).toString("hex")}async function km(t,e,n){if(e.length>AA)throw new Error(`writeScreenshotSidecar: buffer exceeds ${AA} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=EW(t);await SW(r,{recursive:!0});let o=`${xW()}-${RW()}-${n}.png`,s=vm(r,o);await kW(s,e);let{size:i}=await vW(s);return{path:s,bytes:i}}var coe,AA,_A=g(()=>{"use strict";B();Vc();coe=_W(AW);AA=5*1024*1024});var EA={};wp(EA,{PlaywrightProvider:()=>Am});function TA(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 Am,xA=g(()=>{"use strict";uA();wA();vA();qc();kA();_A();Am=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new zc(e)}async open(e){let n=Gc(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let c=o.url();if(!(a!==null&&(c===""||c==="about:blank"))){let u=await Sm(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 Jc(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 Jc(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 wm(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${TA(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:c}=a,l=null,d=async()=>{switch(e.action){case"click":await c.click({timeout:i});break;case"fill":await c.fill(e.value??"");break;case"press":await c.press(e.value??"");break;case"select":await c.selectOption(e.value??"");break;case"hover":await c.hover({timeout:i});break;case"scroll_to":await c.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await c.waitFor({timeout:i,state:"visible"});break}};try{await d()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await d()}catch(y){l=y}else l=h}let u=await Sm(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Jc(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),m=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,m),l!==null)throw l;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await wm(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${TA(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 km(n,s,"browser_screenshot"),c=0,l=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));c=d.w,l=d.h}catch{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}else{let d=r.viewportSize();c=d?.width??0,l=d?.height??0}return{path:i,bytes:a,width:c,height:l,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(e){throw new Error("browser_extract not implemented in Phase 1")}async close(e){await this.launcher.closeSession(e.sessionId),this.sessions.delete(e.sessionId)}describe(e){let n=this.sessions.get(e);if(n===void 0)return null;let r=this.launcher.getPage(e);return{active:r!==void 0,url:n.currentUrl,title:n.currentTitle,lastAction:n.lastAction,lastActionAt:n.lastActionAt,openTabs:r!==void 0?1:0}}async shutdown(){this.sessions.clear(),await this.launcher.shutdown()}ensureSessionState(e){let n=this.sessions.get(e);if(n!==void 0)return n;let r={observationCounter:0,knownElements:new Map,lastAction:null,lastActionAt:null,currentUrl:null,currentTitle:null};return this.sessions.set(e,r),r}updateSessionFromObservation(e,n,r,o,s){e.knownElements=new Map(n.map(i=>[i.id,i])),e.currentUrl=r,e.currentTitle=o,e.lastAction=s,e.lastActionAt=new Date().toISOString()}async captureScreenshot(e,n,r){try{let o=await e.screenshot({fullPage:!1}),{path:s}=await km(n,o,r);return s}catch{return null}}}});var rr={};wp(rr,{__resetBrowserRegistryForTests:()=>OW,browserProviderActive:()=>PW,closeBrowserProvider:()=>_m,getBrowserProvider:()=>CW,peekBrowserProvider:()=>MW});function RA(){Promise.resolve(_m()).then(()=>{process.exit(130)})}function IA(){Promise.resolve(_m()).then(()=>{process.exit(143)})}function CA(){Ot=null}function IW(){Yc||(process.on("SIGINT",RA),process.on("SIGTERM",IA),process.on("exit",CA),Yc=!0)}function PA(){Yc&&(process.removeListener("SIGINT",RA),process.removeListener("SIGTERM",IA),process.removeListener("exit",CA),Yc=!1)}async function CW(t){return Ot!==null?Ot:(nr!==null||(nr=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(xA(),EA)),n=aA(t),r=new e(n);return IW(),Ot=r,nr=null,r})()),nr)}async function _m(){if(Ot===null)return;let t=Ot;Ot=null,nr=null,PA(),await t.shutdown()}function PW(){return Ot!==null}function MW(){return Ot}function OW(){Ot=null,nr=null,PA()}var Ot,nr,Yc,or=g(()=>{"use strict";qc();Ot=null,nr=null,Yc=!1});async function MA(t,e){try{return await Vk(t,e)}catch(n){return N("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function $W(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(or(),rr));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function OA(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??$W,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Kc(n,t,{headers:UW,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(NW.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(LW.test(p)&&!FW.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await MA(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof wt||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=lm({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await qs(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>qs(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await qs(u.finalUrl,o);let p=await MA(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=lm({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 wt)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${c??"error"}).`)}var FW,LW,NW,UW,DA=g(()=>{"use strict";Jk();dm();mm();se();FW=/(text\/html|application\/xhtml\+xml)/i,LW=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,NW=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,UW={"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 jW(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(BW,{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),HW),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=ee(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function FA(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?jW({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 LA(t,e){if(e.length===0)return`# Search results for "${t}"
217
217
 
218
218
  (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(`
219
219
  `).trimEnd()}var BW,HW,NA=g(()=>{"use strict";bt();BW="https://api.exa.ai/search",HW=10});function Qc(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 sr=g(()=>{"use strict";ym()});function zW(t){if(!t||typeof t!="object")return{error:"Invalid input: expected an object"};let e=t,n=e.mode??"markdown";if(n!=="markdown"&&n!=="raw"&&n!=="search")return{error:`Invalid input: mode must be one of "markdown", "raw", "search" (got ${JSON.stringify(n)})`};let r=n,o,s;if(r==="search"){if(typeof e.query!="string"||e.query.length===0)return{error:'Invalid input: search mode requires a non-empty "query" string'};s=e.query}else{if(typeof e.url!="string"||e.url.length===0)return{error:`Invalid input: ${r} mode requires a non-empty "url" string`};let c;try{c=new URL(e.url)}catch{return{error:`Invalid input: "${e.url}" is not a valid absolute URL`}}if(c.protocol!=="http:"&&c.protocol!=="https:")return{error:`Invalid input: protocol "${c.protocol}" not supported (http/https only)`};o=c.toString()}let i=WW;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,KW)}let a=GW;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,qW)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Tm(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:Gt(t,e),truncated:!0}}function VW(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=zW(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let u=s.reason;return{content:`web_scrape aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0}}let a=new AbortController,c=()=>{a.abort(s.reason)},l,d=()=>{let u=a.signal.reason;return u instanceof Error?u.message:String(u??"aborted")};try{if(s.addEventListener("abort",c,{once:!0}),l=setTimeout(()=>{a.abort(new Error(`web_scrape timeout after ${i.timeoutMs}ms`))},i.timeoutMs),i.url!==void 0){let p=await fm(i.url,r);if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(!p.allowed)return{content:`web_scrape blocked: ${p.reason}`,isError:!0}}if(i.mode==="raw"){let p;try{let h={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};p=await Kc(e,i.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:h instanceof wt?{content:`web_scrape blocked: ${h.message}`,isError:!0}:{content:`web_scrape network error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}if(!p.ok)return{content:`web_scrape HTTP ${p.status} ${p.statusText||""}`.trimEnd()+` for ${i.url}`,isError:!0};let f;try{f=await p.text()}catch(h){return{content:`web_scrape read error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}let m=Tm(f,i.maxBytes);return{content:m.content,...m.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await OA(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=Tm(Yk(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 wt)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),m=$e(p)&&!gm(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Xs()}\`)`:"";return{content:`web_scrape markdown error: ${f}${m}`,isError:!0}}let u=FA({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:XW,timeoutMs:i.timeoutMs,signal:a.signal}),f=Tm(LA(i.query,p),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:{content:`web_scrape search error (${u.name}): ${p instanceof Error?p.message:String(p)}`,isError:!0}}}finally{l!==void 0&&clearTimeout(l),s.removeEventListener("abort",c)}}}var WW,KW,GW,qW,XW,UA,$A=g(()=>{"use strict";DA();NA();mm();pn();dm();sr();WW=3e4,KW=12e4,GW=1e5,qW=1e6,XW=10;UA=VW()});import{existsSync as HA,mkdirSync as JW,readFileSync as YW,renameSync as QW,unlinkSync as ZW,writeFileSync as eK}from"node:fs";import{dirname as BA,join as tK}from"node:path";import{randomBytes as nK}from"node:crypto";function ir(t){let e=t??Ap();if(!HA(e))return[];try{let n=YW(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 zs(t,e){let n=e??Ap();JW(BA(n),{recursive:!0});let r=tK(BA(n),`.schedules.json.${process.pid}.${nK(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{eK(r,o,"utf-8"),QW(r,n)}catch(s){try{HA(r)&&ZW(r)}catch{}throw s}}function jA(t,e){let n=ir(e),r=n.map(c=>c.id),o=rK(t.name),s=oK(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),zs(n,e),a}function WA(t,e){let n=ir(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(zs(o,e),!0)}function KA(t,e){return ir(e).find(n=>n.id===t)}function rK(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function oK(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}function GA(t){return{taskId:t.id,command:t.command,trigger:t.trigger??"cron",...t.cron!==void 0?{cronExpression:t.cron}:{},...t.notifyOn!==void 0?{notifyOn:t.notifyOn}:{},...t.notifyChat!==void 0?{notifyChat:t.notifyChat}:{}}}var qA=g(()=>{"use strict";B()});import{existsSync as sK,readFileSync as iK}from"node:fs";import{join as aK}from"node:path";async function Yr(t,e,n){let r;try{let o=aK(Xb("default"),"port");if(!sK(o))return{synced:!1,detail:"daemon-not-detected (no port file)"};let s=iK(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 Em,XA=g(()=>{"use strict";B();Em="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 cK}from"node:fs";import{readFile as lK}from"node:fs/promises";var zA,VA,JA,YA,QA=g(()=>{"use strict";qA();B();XA();zA=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=jA({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 Yr("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 Yr("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:Em}})}},VA=async(t,e)=>{let n=ir();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})))}},JA=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=wa();if(!cK(s))return{content:JSON.stringify([])};let i;try{let l=await lK(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
@@ -1286,7 +1286,7 @@ Enter a number${A}`}I&&(l.allowSkip?S+=`
1286
1286
  model: ${t.model}${t.cwd?`
1287
1287
  cwd: ${t.cwd}`:""}`;case"user":return`\u{1F464} ${la(t.text,TD)}`;case"assistant":return`\u{1F916} ${la(t.text,TD)}`;case"tool":return`\u{1F527} ${t.toolName}(${la(t.input,db)})`;case"tool_error":return`\u26A0\uFE0F tool failed: ${la(t.content,db)}`;case"done":{let e=[];return typeof t.durationMs=="number"&&e.push(`${(t.durationMs/1e3).toFixed(1)}s`),typeof t.costUsd=="number"&&e.push(`$${t.costUsd.toFixed(4)}`),`\u2705 turn done${e.length?` (${e.join(", ")})`:""}`}case"error":return`\u274C error: ${la(t.message,db)}`;case"paused":return`\u23F8\uFE0F paused on usage limit${t.resetsAt?` (resets ${t.resetsAt})`:""}`;case"resumed":return"\u25B6\uFE0F resumed";case"closed":return`\u{1F3C1} session closed${t.reason?` (${t.reason})`:""} \u2014 watch ended`;default:return null}}async function ED(t){let e=Bp(t);return e?.data.sessionId&&await ml(e.data.sessionId)?e.data.sessionId:await ml(t)?t:null}async function xD(){let t=[],n=(await Es()).filter(s=>s.surface!=="telegram");if(n.length>0){t.push("\u{1F7E2} Live sessions:");for(let s of n)t.push(` ${s.sessionId} (${s.surface}, ${s.cwd})`)}let r=Rr().filter(s=>s.source!=="telegram").slice(0,8),o=[];for(let s of r)s.sessionId&&await ml(s.sessionId)&&o.push(` ${s.name??s.id} (${s.model})`);return o.length>0&&(t.length>0&&t.push(""),t.push("\u{1F4BE} Recent sessions with activity logs:",...o)),t.length===0?"No watchable sessions found. Start one with `afk i` on your machine, then /watch <session-id-or-name>.":(t.push("","Watch one with /watch <session-id-or-name>."),t.join(`
1288
1288
  `))}var ip=class{watches=new Map;log;bot;messageHandler;elicitHeartbeatMs;constructor(e=()=>{},n,r,o=J5){this.log=e,this.bot=n,this.messageHandler=r,this.elicitHeartbeatMs=o}watching(e){return this.watches.get(e)?.sessionId}getWatched(e){return this.watches.get(e)?.sessionId}start(e,n,r){this.stop(e);let o=new AbortController,s=this._run(e,n,r,o.signal).catch(i=>{this.log("watch loop error:",i)});this.watches.set(e,{sessionId:n,abort:o,finished:s})}stop(e){let n=this.watches.get(e);if(n)return this.watches.delete(e),n.abort.abort(),n.sessionId}async stopAll(){let e=[...this.watches.values()];this.watches.clear();for(let n of e)n.abort.abort();await Promise.allSettled(e.map(n=>n.finished))}async _run(e,n,r,o){let s=[],i=null,a=Promise.resolve(),c=this.bot!==void 0&&this.messageHandler!==void 0?rp(tp(this.messageHandler,this.bot,e,{ledgerOriginated:!0}),np(this.bot,new Set([e]),(...d)=>this.log("[elicitation]",...d))):void 0,l=()=>{if(i=null,s.length===0)return;let d=s.join(`
1289
- `);s=[],a=a.then(()=>r(d)).catch(u=>this.log("watch send error:",u))};try{for await(let d of sT(n,{signal:o})){if(d.kind==="elicitation"&&c!==void 0){i&&clearTimeout(i),l(),await a;let p=Date.now(),f=0,m=setInterval(()=>{if(f>=Y5){clearInterval(m);return}f+=1;let w=Math.round((Date.now()-p)/6e4);r(`\u23F3 Still waiting on your answer (${w}m elapsed) \u2014 no deadline, reply above whenever you're ready. (Send /unwatch to stop watching this session.)`).catch(()=>{})},this.elicitHeartbeatMs);m.unref?.();let h=await(async()=>{try{return await c(d.request,{signal:o})}finally{clearInterval(m)}})(),y=sp(n);if(y!==null){let w=kD(y,n,d.reqId,h);new yn(n).record({kind:"elicitation_response",reqId:d.reqId,result:h,hmac:w})}else this.log("[watch] no session key for",n,"\u2014 skipping elicitation write-back");continue}let u=Q5(d);if(u){if(s.push(u),d.kind==="closed"){l();break}i||(i=setTimeout(l,V5),i.unref?.())}}i&&clearTimeout(i),l(),await a}finally{i&&clearTimeout(i);let d=this.watches.get(e);d&&d.sessionId===n&&d.abort.signal===o&&this.watches.delete(e)}}};Vn();Qs();Le();Zr();var ap=class t{bot;sessionManager;options;running=!1;registeredCommandChats=new Set;messageHandler;watchManager;autoSubscribeInterval=null;static AUTO_SUBSCRIBE_INTERVAL_MS=5e3;constructor(e){this.options=e,this.bot=new Z5(e.botToken,{handlerTimeout:1/0}),this.sessionManager=new Wa(e),this.messageHandler=new Qu(this.bot,this.sessionManager,this.registeredCommandChats,this.log.bind(this),e.tagOnlyChats??new Set),this.watchManager=new ip(this.log.bind(this),this.bot,this.messageHandler),this.setupHandlers()}setupHandlers(){this.bot.use(Vv(this.options.allowedChatIds,this.log.bind(this))),this.bot.command("start",r=>Wp(r)),this.bot.command("help",r=>Kp(r,this.sessionManager)),this.bot.command("clear",async r=>{let o=ie(r);if(!o){await r.reply(q("Could not identify chat"));return}(await this.sessionManager.getSession(o)).state!=="idle"?(this.messageHandler.enqueueClear(o,r),await r.reply("Clear queued.")):await qy(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}),this.bot.command("compact",async r=>{let o=ie(r);if(!o){await r.reply(q("Could not identify chat"));return}if((await this.sessionManager.getSession(o)).state!=="idle")this.messageHandler.enqueueCompact(o,r),await r.reply("Compact queued.");else try{await v0(r,this.sessionManager,this.log.bind(this))}finally{this.messageHandler.drainQueue(o).catch(i=>this.log("Drain error:",i))}}),this.bot.command("model",r=>Xy(r,this.sessionManager,this.log.bind(this))),this.bot.command(["cd","cwd"],r=>k0(r,this.sessionManager,this.log.bind(this))),this.bot.command("name",r=>A0(r,this.sessionManager,this.log.bind(this))),this.bot.command("afk",r=>I0(r,this.sessionManager,this.log.bind(this))),this.bot.command("usage",r=>P0(r,this.log.bind(this))),this.bot.command("sessions",r=>E0(r,this.sessionManager,this.log.bind(this))),this.bot.command("new",r=>x0(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))),this.bot.command("watch",async r=>{let o=ie(r);if(!o){await r.reply(q("Could not identify chat"));return}let{chatId:s}=o,i=as(o),c=((r.message&&"text"in r.message?r.message.text:"")??"").split(/\s+/).slice(1).join(" ").trim();try{if(!c){await r.reply(await xD());return}let l=await ED(c);if(!l){await r.reply(`No session ledger found for "${c}". Use /watch with no argument to list watchable sessions.`);return}let d=async u=>{for(let p of qe(u))await r.telegram.sendMessage(s,p,i)};this.watchManager.start(s,l,d),await r.reply(`\u{1F4E1} Watching ${l} \u2014 new activity will stream here. /unwatch to stop.`)}catch(l){this.log("Watch error:",l),await r.reply(q(l))}}),this.bot.command("unwatch",async r=>{let o=r.chat?.id;if(!o){await r.reply(q("Could not identify chat"));return}let s=this.watchManager.stop(o);await r.reply(s?`Stopped watching ${s}.`:"Not watching anything.")}),this.bot.command("abort",async r=>{let o=r.chat?.id;if(!o){await r.reply(q("Could not identify chat"));return}let s=this.watchManager.getWatched(o);if(!s){await r.reply("Not watching any session. Use /watch <session-id> to watch a REPL session first, then /abort to stop it.");return}let i=sp(s);if(i===null){await r.reply("Session key not found \u2014 the REPL may not have enabled AFK mode (/afk on). Cannot send a verified abort.");return}let a=_D(),c=AD(i,s,a);new yn(s).record({kind:"abort_request",nonce:a,hmac:c}),await r.reply(`\u270B Abort sent to session ${s}.`)});let e=r=>{r.catch(o=>{let i=(o instanceof Error?o.message:String(o)).replace(/\/bot[^/]+\//g,"/bot[REDACTED]/");this.log("Detached update handler error:",i)})};this.bot.on("text",r=>e(this.messageHandler.handle(r))),this.bot.on("photo",r=>e(this.messageHandler.handlePhoto(r)));let n=new RegExp(`^${Be(Gu)}`);this.bot.action(n,r=>G0(r,{log:this.log.bind(this)})),this.bot.action(/^afk:m:/,async r=>{if(await r.answerCbQuery().catch(()=>{}),r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))return;let s=(typeof r.callbackQuery=="object"&&"data"in r.callbackQuery?r.callbackQuery.data:"").replace("afk:m:",""),i=ie(r);if(!(!i||!s)&&$n.includes(s))try{await this.sessionManager.switchModel(i,s);let a=qa(s);await r.editMessageText(a).catch(()=>r.reply(a))}catch(a){this.log("Model action error:",a)}}),this.bot.action(/^afk:sw:/,async r=>{await r.answerCbQuery().catch(()=>{}),!(r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))&&await R0(r,this.sessionManager,this.log.bind(this))}),this.bot.catch((r,o)=>{this.log("Bot error:",r),o.reply(q("An unexpected error occurred. Please try again.")).catch(s=>this.log("Failed to send error message:",s))})}async start(){if(this.running)throw new Error("Bot is already running");this.log("Loading sessions..."),await this.sessionManager.loadSessions();let e=[...this.options.allowedChatIds];if(e.length>0){let r=e[0],o=tp(this.messageHandler,this.bot,r),s=np(this.bot,new Set(this.options.allowedChatIds),(...i)=>this.log("[elicitation]",...i));Je.install(rp(o,s))}await ZP(),this.log("Starting bot..."),await this.bot.launch(),this.log("Registering bot commands..."),await this.bot.telegram.setMyCommands([{command:"start",description:"Show welcome and command list"},{command:"help",description:"Show this command list"},{command:"clear",description:"Clear conversation history"},{command:"compact",description:"Compact conversation history"},{command:"model",description:"Switch Claude model (opus/sonnet/haiku)"},{command:"cd",description:"Show or change session working directory"},{command:"name",description:"Show or set the session name"},{command:"afk",description:"Toggle autonomous (AFK) mode for this chat"},{command:"usage",description:"Show Claude subscription usage"},{command:"watch",description:"Live-tail a CLI session from this chat"},{command:"unwatch",description:"Stop watching a session"}]),this.running=!0,this.log("Bot started successfully"),this.startAutoSubscribe();let n=async r=>{this.log(`Received ${r}, shutting down...`),await this.stop(),process.exit(0)};process.once("SIGINT",()=>n("SIGINT")),process.once("SIGTERM",()=>n("SIGTERM"))}async stop(){if(this.running){this.log("Stopping bot..."),this.running=!1,this.log("Stopping auto-subscribe loop..."),this.stopAutoSubscribe(),this.log("Uninstalling elicitation handler..."),Je.uninstall(),this.log("Stopping session watches..."),await this.watchManager.stopAll(),this.log("Closing sessions..."),await this.sessionManager.closeAll(),this.log("Stopping bot polling...");try{this.bot.stop()}catch(e){this.log("Error stopping bot (may not have been started):",e)}this.log("Bot stopped")}}getStats(){return{running:this.running,activeSessions:this.sessionManager.getSessionCount(),totalChats:this.sessionManager.getChatCount()}}getBusySessionCount(){return this.sessionManager.getBusySessionCount()}async handleStart(e){return Wp(e)}async handleHelp(e){return Kp(e,this.sessionManager)}async handleClear(e){let n=ie(e);if(!n){await e.reply(q("Could not identify chat"));return}if((await this.sessionManager.getSession(n)).state!=="idle")this.messageHandler.enqueueClear(n,e),await e.reply("Clear queued.");else return qy(e,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}async handleMessage(e){return this.messageHandler.handle(e)}async handlePhoto(e){return this.messageHandler.handlePhoto(e)}async handleModelSwitch(e){return Xy(e,this.sessionManager,this.log.bind(this))}startAutoSubscribe(){if(this.autoSubscribeInterval!==null)return;let e=()=>{this.runAutoSubscribeTick().catch(n=>this.log("auto-subscribe tick error:",n))};this.autoSubscribeInterval=setInterval(e,t.AUTO_SUBSCRIBE_INTERVAL_MS),this.autoSubscribeInterval.unref?.(),e()}stopAutoSubscribe(){this.autoSubscribeInterval!==null&&(clearInterval(this.autoSubscribeInterval),this.autoSubscribeInterval=null)}async runAutoSubscribeTick(){let e=[...this.options.allowedChatIds];if(e.length===0)return;let n;try{n=await Es()}catch{return}let r=new Set(n.filter(o=>o.surface==="cli"&&o.afk===!0&&o.sessionId).map(o=>o.sessionId));for(let o of e){let s=this.watchManager.getWatched(o);s!==void 0&&!r.has(s)&&(this.watchManager.stop(o),this.log(`[auto-subscribe] stopped watch for ${s} (afk cleared)`));for(let i of r){if(this.watchManager.watching(o)===i)continue;let c=as({chatId:o}),l=async d=>{for(let u of qe(d))await this.bot.telegram.sendMessage(o,u,c)};this.watchManager.start(o,i,l),this.log(`[auto-subscribe] started watch for ${i} on chat ${o}`);break}}}log(...e){this.options.verbose&&console.log("[TelegramBot]",...e)}};Ls();jm();B();L();import mPe from"chalk";import D from"chalk";var e6={brand:D.hex("#E67E4C"),mint:D.hex("#5FE3A1"),goblin:D.hex("#9CB04A"),user:D.cyan,caret:D.hex("#7AA2F7"),tool:D.hex("#DCDCAA"),chrome:D.hex("#B0B8C2"),syntaxString:D.italic.hex("#8AB07A"),toolArg:D.dim.white,thinking:D.italic.hex("#9B8FB5"),success:D.green,error:D.red,warning:D.yellow,plan:D.hex("#9F7CE0"),bypass:D.bold.hex("#FF6AC1"),meta:D.blackBright,info:D.hex("#5BA8FF"),fileRef:D.hex("#56B5A8"),heading:D.bold.white,label:D.dim,dim:D.dim,bold:D.bold,italic:D.italic,diffAdd:D.green,diffRemove:D.red,diffHunk:D.blackBright},yPe={brand:D.hex("#C0562A"),mint:D.hex("#1B9E63"),goblin:D.hex("#6B7D2A"),user:D.hex("#0E7490"),caret:D.hex("#3B5BDB"),tool:D.hex("#7A6E00"),chrome:D.hex("#5A6470"),syntaxString:D.italic.hex("#3F7A3F"),toolArg:D.hex("#6B7280"),thinking:D.italic.hex("#6D5B8E"),success:D.hex("#2E7D32"),error:D.hex("#C62828"),warning:D.hex("#B8860B"),plan:D.hex("#7048C0"),bypass:D.bold.hex("#D6297F"),meta:D.hex("#6B7280"),info:D.hex("#1D6FD6"),fileRef:D.hex("#0F766E"),heading:D.bold.hex("#1F2937"),label:D.dim,dim:D.dim,bold:D.bold,italic:D.italic,diffAdd:D.hex("#2E7D32"),diffRemove:D.hex("#C62828"),diffHunk:D.hex("#6B7280")},bPe={brand:D.hex("#FF9B5A"),mint:D.hex("#B4FCC3"),goblin:D.hex("#A5AC55"),user:D.hex("#42CBC8"),caret:D.hex("#9DBEFC"),tool:D.hex("#F7D179"),chrome:D.hex("#D3CDC5"),syntaxString:D.italic.hex("#96C182"),toolArg:D.dim.hex("#D3CDC5"),thinking:D.italic.hex("#B49EC4"),success:D.hex("#8AE49E"),error:D.hex("#EF7F74"),warning:D.hex("#D7AA32"),plan:D.hex("#AE93DE"),bypass:D.bold.hex("#FFACE9"),meta:D.hex("#AAA19B"),info:D.hex("#739EF0"),fileRef:D.hex("#80E5E2"),heading:D.bold.hex("#F9F6F2"),label:D.dim,dim:D.dim,bold:D.bold,italic:D.italic,diffAdd:D.hex("#8AE49E"),diffRemove:D.hex("#EF7F74"),diffHunk:D.hex("#AAA19B")};var t6={...e6};var n6="https://api.telegram.org";async function RD(t){try{let e=await fetch(`${n6}/bot${t}/getMe`);if(!e.ok)return null;let n=await e.json();return!n.ok||!n.result?.id||!n.result?.first_name?null:{id:n.result.id,...n.result.username!==void 0?{username:n.result.username}:{},firstName:n.result.first_name}}catch{return null}}Tt();ue();Vr();B();ue();we();L();Vr();function ub(){return`# Agent AFK
1289
+ `);s=[],a=a.then(()=>r(d)).catch(u=>this.log("watch send error:",u))};try{for await(let d of sT(n,{signal:o})){if(d.kind==="elicitation"&&c!==void 0){i&&clearTimeout(i),l(),await a;let p=Date.now(),f=0,m=setInterval(()=>{if(f>=Y5){clearInterval(m);return}f+=1;let w=Math.round((Date.now()-p)/6e4);r(`\u23F3 Still waiting on your answer (${w}m elapsed) \u2014 no deadline, reply above whenever you're ready. (Send /unwatch to stop watching this session.)`).catch(()=>{})},this.elicitHeartbeatMs);m.unref?.();let h=await(async()=>{try{return await c(d.request,{signal:o})}finally{clearInterval(m)}})(),y=sp(n);if(y!==null){let w=kD(y,n,d.reqId,h);new yn(n).record({kind:"elicitation_response",reqId:d.reqId,result:h,hmac:w})}else this.log("[watch] no session key for",n,"\u2014 skipping elicitation write-back");continue}let u=Q5(d);if(u){if(s.push(u),d.kind==="closed"){l();break}i||(i=setTimeout(l,V5),i.unref?.())}}i&&clearTimeout(i),l(),await a}finally{i&&clearTimeout(i);let d=this.watches.get(e);d&&d.sessionId===n&&d.abort.signal===o&&this.watches.delete(e)}}};Vn();Qs();Le();Zr();var ap=class t{bot;sessionManager;options;running=!1;registeredCommandChats=new Set;messageHandler;watchManager;autoSubscribeInterval=null;static AUTO_SUBSCRIBE_INTERVAL_MS=5e3;constructor(e){this.options=e,this.bot=new Z5(e.botToken,{handlerTimeout:1/0}),this.sessionManager=new Wa(e),this.messageHandler=new Qu(this.bot,this.sessionManager,this.registeredCommandChats,this.log.bind(this),e.tagOnlyChats??new Set),this.watchManager=new ip(this.log.bind(this),this.bot,this.messageHandler),this.setupHandlers()}setupHandlers(){this.bot.use(Vv(this.options.allowedChatIds,this.log.bind(this))),this.bot.command("start",r=>Wp(r)),this.bot.command("help",r=>Kp(r,this.sessionManager)),this.bot.command("clear",async r=>{let o=ie(r);if(!o){await r.reply(q("Could not identify chat"));return}(await this.sessionManager.getSession(o)).state!=="idle"?(this.messageHandler.enqueueClear(o,r),await r.reply("Clear queued.")):await qy(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}),this.bot.command("compact",async r=>{let o=ie(r);if(!o){await r.reply(q("Could not identify chat"));return}if((await this.sessionManager.getSession(o)).state!=="idle")this.messageHandler.enqueueCompact(o,r),await r.reply("Compact queued.");else try{await v0(r,this.sessionManager,this.log.bind(this))}finally{this.messageHandler.drainQueue(o).catch(i=>this.log("Drain error:",i))}}),this.bot.command("model",r=>Xy(r,this.sessionManager,this.log.bind(this))),this.bot.command(["cd","cwd"],r=>k0(r,this.sessionManager,this.log.bind(this))),this.bot.command("name",r=>A0(r,this.sessionManager,this.log.bind(this))),this.bot.command("afk",r=>I0(r,this.sessionManager,this.log.bind(this))),this.bot.command("usage",r=>P0(r,this.log.bind(this))),this.bot.command("sessions",r=>E0(r,this.sessionManager,this.log.bind(this))),this.bot.command("new",r=>x0(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))),this.bot.command("watch",async r=>{let o=ie(r);if(!o){await r.reply(q("Could not identify chat"));return}let{chatId:s}=o,i=as(o),c=((r.message&&"text"in r.message?r.message.text:"")??"").split(/\s+/).slice(1).join(" ").trim();try{if(!c){await r.reply(await xD());return}let l=await ED(c);if(!l){await r.reply(`No session ledger found for "${c}". Use /watch with no argument to list watchable sessions.`);return}let d=async u=>{for(let p of qe(u))await r.telegram.sendMessage(s,p,i)};this.watchManager.start(s,l,d),await r.reply(`\u{1F4E1} Watching ${l} \u2014 new activity will stream here. /unwatch to stop.`)}catch(l){this.log("Watch error:",l),await r.reply(q(l))}}),this.bot.command("unwatch",async r=>{let o=r.chat?.id;if(!o){await r.reply(q("Could not identify chat"));return}let s=this.watchManager.stop(o);await r.reply(s?`Stopped watching ${s}.`:"Not watching anything.")}),this.bot.command("abort",async r=>{let o=r.chat?.id;if(!o){await r.reply(q("Could not identify chat"));return}let s=this.watchManager.getWatched(o);if(!s){await r.reply("Not watching any session. Use /watch <session-id> to watch a REPL session first, then /abort to stop it.");return}let i=sp(s);if(i===null){await r.reply("Session key not found \u2014 the REPL may not have enabled AFK mode (/afk on). Cannot send a verified abort.");return}let a=_D(),c=AD(i,s,a);new yn(s).record({kind:"abort_request",nonce:a,hmac:c}),await r.reply(`\u270B Abort sent to session ${s}.`)});let e=r=>{r.catch(o=>{let i=(o instanceof Error?o.message:String(o)).replace(/\/bot[^/]+\//g,"/bot[REDACTED]/");this.log("Detached update handler error:",i)})};this.bot.on("text",r=>e(this.messageHandler.handle(r))),this.bot.on("photo",r=>e(this.messageHandler.handlePhoto(r)));let n=new RegExp(`^${Be(Gu)}`);this.bot.action(n,r=>G0(r,{log:this.log.bind(this)})),this.bot.action(/^afk:m:/,async r=>{if(await r.answerCbQuery().catch(()=>{}),r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))return;let s=(typeof r.callbackQuery=="object"&&"data"in r.callbackQuery?r.callbackQuery.data:"").replace("afk:m:",""),i=ie(r);if(!(!i||!s)&&$n.includes(s))try{await this.sessionManager.switchModel(i,s);let a=qa(s);await r.editMessageText(a).catch(()=>r.reply(a))}catch(a){this.log("Model action error:",a)}}),this.bot.action(/^afk:sw:/,async r=>{await r.answerCbQuery().catch(()=>{}),!(r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))&&await R0(r,this.sessionManager,this.log.bind(this))}),this.bot.catch((r,o)=>{this.log("Bot error:",r),o.reply(q("An unexpected error occurred. Please try again.")).catch(s=>this.log("Failed to send error message:",s))})}async start(){if(this.running)throw new Error("Bot is already running");this.log("Loading sessions..."),await this.sessionManager.loadSessions();let e=[...this.options.allowedChatIds];if(e.length>0){let r=e[0],o=tp(this.messageHandler,this.bot,r),s=np(this.bot,new Set(this.options.allowedChatIds),(...i)=>this.log("[elicitation]",...i));Je.install(rp(o,s))}await ZP(),this.log("Starting bot..."),await this.bot.launch(),this.log("Registering bot commands..."),await this.bot.telegram.setMyCommands([{command:"start",description:"Show welcome and command list"},{command:"help",description:"Show this command list"},{command:"clear",description:"Clear conversation history"},{command:"compact",description:"Compact conversation history"},{command:"model",description:"Switch Claude model (opus/sonnet/haiku)"},{command:"cd",description:"Show or change session working directory"},{command:"name",description:"Show or set the session name"},{command:"afk",description:"Toggle autonomous (AFK) mode for this chat"},{command:"usage",description:"Show Claude subscription usage"},{command:"watch",description:"Live-tail a CLI session from this chat"},{command:"unwatch",description:"Stop watching a session"}]),this.running=!0,this.log("Bot started successfully"),this.startAutoSubscribe();let n=async r=>{this.log(`Received ${r}, shutting down...`),await this.stop(),process.exit(0)};process.once("SIGINT",()=>n("SIGINT")),process.once("SIGTERM",()=>n("SIGTERM"))}async stop(){if(this.running){this.log("Stopping bot..."),this.running=!1,this.log("Stopping auto-subscribe loop..."),this.stopAutoSubscribe(),this.log("Uninstalling elicitation handler..."),Je.uninstall(),this.log("Stopping session watches..."),await this.watchManager.stopAll(),this.log("Closing sessions..."),await this.sessionManager.closeAll(),this.log("Stopping bot polling...");try{this.bot.stop()}catch(e){this.log("Error stopping bot (may not have been started):",e)}this.log("Bot stopped")}}getStats(){return{running:this.running,activeSessions:this.sessionManager.getSessionCount(),totalChats:this.sessionManager.getChatCount()}}getBusySessionCount(){return this.sessionManager.getBusySessionCount()}async handleStart(e){return Wp(e)}async handleHelp(e){return Kp(e,this.sessionManager)}async handleClear(e){let n=ie(e);if(!n){await e.reply(q("Could not identify chat"));return}if((await this.sessionManager.getSession(n)).state!=="idle")this.messageHandler.enqueueClear(n,e),await e.reply("Clear queued.");else return qy(e,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}async handleMessage(e){return this.messageHandler.handle(e)}async handlePhoto(e){return this.messageHandler.handlePhoto(e)}async handleModelSwitch(e){return Xy(e,this.sessionManager,this.log.bind(this))}startAutoSubscribe(){if(this.autoSubscribeInterval!==null)return;let e=()=>{this.runAutoSubscribeTick().catch(n=>this.log("auto-subscribe tick error:",n))};this.autoSubscribeInterval=setInterval(e,t.AUTO_SUBSCRIBE_INTERVAL_MS),this.autoSubscribeInterval.unref?.(),e()}stopAutoSubscribe(){this.autoSubscribeInterval!==null&&(clearInterval(this.autoSubscribeInterval),this.autoSubscribeInterval=null)}async runAutoSubscribeTick(){let e=[...this.options.allowedChatIds];if(e.length===0)return;let n;try{n=await Es()}catch{return}let r=new Set(n.filter(o=>o.surface==="cli"&&o.afk===!0&&o.sessionId).map(o=>o.sessionId));for(let o of e){let s=this.watchManager.getWatched(o);s!==void 0&&!r.has(s)&&(this.watchManager.stop(o),this.log(`[auto-subscribe] stopped watch for ${s} (afk cleared)`));for(let i of r){if(this.watchManager.watching(o)===i)continue;let a=async c=>{for(let l of qe(c))await this.bot.telegram.sendMessage(o,l,as({chatId:o}))};this.watchManager.start(o,i,a),this.log(`[auto-subscribe] started watch for ${i} on chat ${o}`);break}}}log(...e){this.options.verbose&&console.log("[TelegramBot]",...e)}};Ls();jm();B();L();import mPe from"chalk";import D from"chalk";var e6={brand:D.hex("#E67E4C"),mint:D.hex("#5FE3A1"),goblin:D.hex("#9CB04A"),user:D.cyan,caret:D.hex("#7AA2F7"),tool:D.hex("#DCDCAA"),chrome:D.hex("#B0B8C2"),syntaxString:D.italic.hex("#8AB07A"),toolArg:D.dim.white,thinking:D.italic.hex("#9B8FB5"),success:D.green,error:D.red,warning:D.yellow,plan:D.hex("#9F7CE0"),bypass:D.bold.hex("#FF6AC1"),meta:D.blackBright,info:D.hex("#5BA8FF"),fileRef:D.hex("#56B5A8"),heading:D.bold.white,label:D.dim,dim:D.dim,bold:D.bold,italic:D.italic,diffAdd:D.green,diffRemove:D.red,diffHunk:D.blackBright},yPe={brand:D.hex("#C0562A"),mint:D.hex("#1B9E63"),goblin:D.hex("#6B7D2A"),user:D.hex("#0E7490"),caret:D.hex("#3B5BDB"),tool:D.hex("#7A6E00"),chrome:D.hex("#5A6470"),syntaxString:D.italic.hex("#3F7A3F"),toolArg:D.hex("#6B7280"),thinking:D.italic.hex("#6D5B8E"),success:D.hex("#2E7D32"),error:D.hex("#C62828"),warning:D.hex("#B8860B"),plan:D.hex("#7048C0"),bypass:D.bold.hex("#D6297F"),meta:D.hex("#6B7280"),info:D.hex("#1D6FD6"),fileRef:D.hex("#0F766E"),heading:D.bold.hex("#1F2937"),label:D.dim,dim:D.dim,bold:D.bold,italic:D.italic,diffAdd:D.hex("#2E7D32"),diffRemove:D.hex("#C62828"),diffHunk:D.hex("#6B7280")},bPe={brand:D.hex("#FF9B5A"),mint:D.hex("#B4FCC3"),goblin:D.hex("#A5AC55"),user:D.hex("#42CBC8"),caret:D.hex("#9DBEFC"),tool:D.hex("#F7D179"),chrome:D.hex("#D3CDC5"),syntaxString:D.italic.hex("#96C182"),toolArg:D.dim.hex("#D3CDC5"),thinking:D.italic.hex("#B49EC4"),success:D.hex("#8AE49E"),error:D.hex("#EF7F74"),warning:D.hex("#D7AA32"),plan:D.hex("#AE93DE"),bypass:D.bold.hex("#FFACE9"),meta:D.hex("#AAA19B"),info:D.hex("#739EF0"),fileRef:D.hex("#80E5E2"),heading:D.bold.hex("#F9F6F2"),label:D.dim,dim:D.dim,bold:D.bold,italic:D.italic,diffAdd:D.hex("#8AE49E"),diffRemove:D.hex("#EF7F74"),diffHunk:D.hex("#AAA19B")};var t6={...e6};var n6="https://api.telegram.org";async function RD(t){try{let e=await fetch(`${n6}/bot${t}/getMe`);if(!e.ok)return null;let n=await e.json();return!n.ok||!n.result?.id||!n.result?.first_name?null:{id:n.result.id,...n.result.username!==void 0?{username:n.result.username}:{},firstName:n.result.first_name}}catch{return null}}Tt();ue();Vr();B();ue();we();L();Vr();function ub(){return`# Agent AFK
1290
1290
 
1291
1291
  ## What this process is
1292
1292
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-afk",
3
- "version": "5.127.1",
3
+ "version": "5.127.3",
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",