agent-afk 5.150.1 → 5.151.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/telegram.mjs CHANGED
@@ -280,7 +280,7 @@ ${o}`,paths:[e,n]}:o!==null?s={content:o,paths:[n]}:r!==null?s={content:r,paths:
280
280
 
281
281
  ${e}`}var P1,fg=g(()=>{"use strict";P1=new Set(["script","style","noscript","template","svg"])});function D1(t,e){return new Promise((n,r)=>{if(e?.aborted){r(e.reason??new Error("aborted"));return}let o=()=>{clearTimeout(s),r(e?.reason??new Error("aborted"))},s=setTimeout(()=>{e?.removeEventListener("abort",o),n()},t);e?.addEventListener("abort",o,{once:!0})})}function W_(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function F1(t,e){let n=t.headers.get("retry-after");if(n===null)return null;let r=Number(n.trim());return!Number.isFinite(r)||r<0?null:Math.min(r*1e3,e)}async function K_(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??D1,c=n.signal??void 0,l;for(let d=0;d<=o;d++){if(c?.aborted)throw c.reason??new Error("aborted");try{let u=await t(e,n);if(!O1.has(u.status)||d===o)return u;let p=F1(u,i)??W_(d,s,i);M("[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=W_(d,s,i);M("[web/retryFetch] retrying after error",{url:e,attempt:d,waitMs:p}),await a(p,c)}}throw l??new Error("retryFetch: exhausted without a result")}var O1,G_=g(()=>{"use strict";oe();O1=new Set([429,502,503,504])});import{BlockList as L1,isIP as gg}from"node:net";import{lookup as N1}from"node:dns/promises";import{Agent as U1}from"undici";function X_(){let t=S.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function H1(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function mg(t){let e=gg(t);return e===0?!1:j1.check(t,e===4?"ipv4":"ipv6")}async function z_(t){return N1(t,{all:!0,verbatim:!0})}async function hg(t,e={}){if(e.allowPrivateHosts??X_())return{allowed:!0};let n;try{n=new URL(t)}catch{return{allowed:!1,reason:`"${t}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{allowed:!1,reason:`protocol "${n.protocol}" not supported (http/https only)`};let r=H1(n.hostname),o=(a,c)=>`refusing to fetch ${c} \u2014 internal/private address ${a} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`;if(gg(r)!==0)return mg(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??z_,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(mg(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function fi(t,e={}){let n=await hg(t,e);if(!n.allowed)throw new St(n.reason)}async function Ml(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<=q_;i++){await fi(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??X_())?{dispatcher:W1}:{}},c=await K_(t,s,a,r.retry??{});if(!K1.has(c.status))return c;let l=c.headers.get("location");if(l===null||l.trim()==="")return c;let d;try{d=new URL(l,c.url||s).toString()}catch{return c}await c.body?.cancel().catch(()=>{}),s=d}throw new St(`too many redirects (>${q_}) starting from ${e}`)}var $1,B1,j1,St,W1,q_,K1,yg=g(()=>{"use strict";U();G_();$1=[["0.0.0.0",8],["10.0.0.0",8],["100.64.0.0",10],["127.0.0.0",8],["169.254.0.0",16],["172.16.0.0",12],["192.168.0.0",16]],B1=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],j1=(()=>{let t=new L1;for(let[e,n]of $1)t.addSubnet(e,n,"ipv4");for(let[e,n]of B1)t.addSubnet(e,n,"ipv6");return t})(),St=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};W1=new U1({connect:{lookup(t,e,n){z_(t).then(r=>{let o=r.find(i=>mg(i.address));if(o!==void 0){n(new St(`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,gg(s.address))},r=>n(r,"",0))}}});q_=20,K1=new Set([301,302,303,307,308])});import{readFileSync as G1}from"node:fs";import{join as q1}from"path";function X1(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function V_(t,e){return X1(e).test(t)}function J1(t,e){if(t!==void 0){let n=t.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(e!==void 0){if(z1.has(e))return!0;if(V1.has(e))return!1}return!1}function J_(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function Y1(t){if(t===void 0||t===""||t==="playwright")return"playwright";throw new Error(`AFK_BROWSER_BACKEND: only "playwright" is supported in Phase 1, got: ${t}`)}function Y_(t){let e=t===void 0||t.trim()===""?"default":t.trim();return bf(e),e}function Q1(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function Z1(t){try{return G1(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function eG(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=Y_(e.defaultProfile)),n}function Q_(t){let e=t?.env??S,n=t?.readFileSync??Z1,r=t?.surface??e.AGENT_SURFACE,o=J1(e.AFK_BROWSER_HEADLESS,r),s=J_(e.AFK_BROWSER_ALLOWED_DOMAINS),i=J_(e.AFK_BROWSER_BLOCKED_DOMAINS),a=Q1(e.AFK_BROWSER_DOM_SNAPSHOTS),c=Y1(e.AFK_BROWSER_BACKEND),l=Y_(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():q1(Gt(),"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=eG(d,m);return h.configPath=p,h}function Ol(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(V_(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>V_(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var z1,V1,Dl=g(()=>{"use strict";U();j();z1=new Set(["daemon","subagent","telegram","afk"]),V1=new Set(["repl","interactive","cli"])});import{existsSync as tG,readFileSync as nG}from"node:fs";import{createRequire as rG}from"node:module";import{dirname as oG,join as sG}from"node:path";function tE(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<aG&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function je(t){let e=tE(t);return eE.some(n=>e.includes(n))}function cG(){try{let e=rG(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(nG(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=sG(oG(e),o);return tG(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function mi(){return Z_??=cG()??iG,Z_}function bg(t){return t.includes("install chromium")}function at(t,e){let n=tE(t),r=e?.latched===!0?` ${lG}`:"";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: ${mi()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${mi()}). Or pick a different tool.${r}`}function wg(t,e,n=!1){if(!je(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
282
282
 
283
- ${at(t,{headless:e,latched:n})}`,{cause:t})}var eE,iG,aG,Z_,lG,Sg=g(()=>{"use strict";eE=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],iG="pnpm exec playwright install chromium",aG=4;lG="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import ur from"node:fs";import Fl from"node:path";import{randomBytes as dG}from"node:crypto";import{chromium as uG}from"playwright";function pG(){try{return"5.150.1"}catch{}try{let t=Fl.resolve(import.meta.dirname,"../../../package.json"),e=ur.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var fG,Ll,nE=g(()=>{"use strict";Sg();j();oe();fG=pG(),Ll=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=uG.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=wg(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/${fG}`}}loadStorageState(e){let n=wf(e);try{if(!ur.existsSync(n))return;let r=JSON.parse(ur.readFileSync(n,"utf8"));return M("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){M("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=wf(e);if(!ur.existsSync(r))return;let o=await n.storageState(),s=Fl.join(Fl.dirname(r),`.${Fl.basename(r)}.${process.pid}.${dG(4).toString("hex")}.tmp`);ur.writeFileSync(s,JSON.stringify(o),{mode:384}),ur.chmodSync(s,384),ur.renameSync(s,r),M("[browser/vault] saved session",{profile:e,file:r})}catch(r){M("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as mG}from"crypto";function rE(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&gG.test(t.label))}function oE(t){return mG("sha256").update(t,"utf8").digest("hex").slice(0,8)}function sE(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var gG,Nl=g(()=>{"use strict";gG=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as hG}from"node:crypto";function yG(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function bG(t,e,n){return`el_${hG("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function wG(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function iE(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function cE(t,e){let n=t.role??"",r=t.name??"";aE.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])cE(s,e)}async function SG(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},lE).catch(()=>[])}async function vG(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},lE).catch(()=>[])}function kG(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Ul(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=kG(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=SG(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,b=!1;u!==null?(y=[],cE(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await vG(t)).filter(O=>aE.has(O.role??"")));let k=new Map;for(let C of p){let O=iE(C.name),q=k.get(O);(!q||q.bbox.w===0&&C.bbox.w>0)&&k.set(O,C)}let A=y.map(C=>({ax:C,dom:k.get(iE(C.name??""))})),E=r?A:A.filter(C=>C.dom?C.dom.bbox.w>0||C.dom.bbox.h>0:!0);E.sort((C,O)=>{let q=C.dom?.bbox.y??0,P=O.dom?.bbox.y??0;if(q!==P)return q-P;let $=C.dom?.bbox.x??0,D=O.dom?.bbox.x??0;return $-D}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=E.slice(0,n).map((C,O)=>{let q=C.ax.role??"generic",P=C.ax.name??"",$=bG(q,P,O),D=C.dom?.bbox??{x:0,y:0,w:0,h:0},L=C.dom?.type??null,B=null;C.ax.value!==void 0&&C.ax.value!==null&&(B=String(C.ax.value)),C.ax.checked!==void 0&&(B=String(C.ax.checked)),rE({role:q,kind:L})&&(B="[redacted]");let W={disabled:C.ax.disabled??!1};C.ax.checked!==void 0&&(W.checked=C.ax.checked===!0||C.ax.checked==="mixed"),C.ax.selected!==void 0&&(W.selected=C.ax.selected),C.ax.expanded!==void 0&&(W.expanded=C.ax.expanded);let Q;C.dom?.testId?Q=`[data-testid="${C.dom.testId}"]`:C.dom?.id&&(Q=`#${C.dom.id}`);let Le={id:$,role:q,label:yG(P),kind:L,value:B,state:W,bbox:D};return Q!==void 0&&(Le.selector=Q),Le}),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"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let R=wG(f),v=`obs_${e.observationCounter.toString(36)}`,_=new Date().toISOString();return{observationId:v,url:m,title:h,textSummary:R,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:_}}var aE,lE,dE=g(()=>{"use strict";Nl();aE=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);lE="a[href], button, input, select, textarea, [role], [tabindex], label"});async function uE(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 vg(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>uE(t,s)))).filter(o=>o!==null)}async function AG(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 kg(t,e,n){switch(e.kind){case"element_id":return _G(t,e,n);case"selector":return EG(t,e);case"semantic":return TG(t,e)}}async function _G(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 vg(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function EG(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 vg(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function TG(t,e){return e.role!==void 0?xG(t,e.text,e.role):RG(t,e.text,e)}async function xG(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 vg(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function RG(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 AG(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let b=await uE(y.locator,y.index);if(b!==null){let k=`${b.role}:${b.label}:${h}`,A=0;for(let E=0;E<k.length;E++)A=A*31+k.charCodeAt(E)>>>0;f.push({...b,id:`el_${A.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var pE=g(()=>{"use strict"});async function Ag(t,e,n,r){let o=t.url();if(o===n)return null;let s=Ol(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 fE=g(()=>{"use strict";Dl()});import{randomBytes as IG}from"crypto";import{mkdir as CG,stat as PG,writeFile as MG}from"fs/promises";import{join as _g}from"path";import{gzip as OG}from"zlib";import{promisify as DG}from"util";function FG(t){return _g(xt(t),"browser")}function LG(t){return _g(FG(t),"screenshots")}function NG(){return new Date().toISOString().replace(/[:.]/g,"-")}function UG(){return IG(3).toString("hex")}async function Eg(t,e,n){if(e.length>mE)throw new Error(`writeScreenshotSidecar: buffer exceeds ${mE} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=LG(t);await CG(r,{recursive:!0});let o=`${NG()}-${UG()}-${n}.png`,s=_g(r,o);await MG(s,e);let{size:i}=await PG(s);return{path:s,bytes:i}}var Gce,mE,gE=g(()=>{"use strict";j();Nl();Gce=DG(OG);mE=5*1024*1024});var yE={};uf(yE,{PlaywrightProvider:()=>Tg});function hE(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 Tg,bE=g(()=>{"use strict";nE();dE();pE();Dl();fE();gE();Tg=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Ll(e)}async open(e){let n=Ol(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 Ag(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 Ul(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 Ul(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 kg(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${hE(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 Ag(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 Ul(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 kg(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${hE(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 Eg(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 Eg(n,o,r);return s}catch{return null}}}});var fr={};uf(fr,{__resetBrowserRegistryForTests:()=>WG,browserProviderActive:()=>jG,closeBrowserProvider:()=>xg,getBrowserProvider:()=>BG,peekBrowserProvider:()=>HG});function wE(){Promise.resolve(xg()).then(()=>{process.exit(130)})}function SE(){Promise.resolve(xg()).then(()=>{process.exit(143)})}function vE(){Nt=null}function $G(){$l||(process.on("SIGINT",wE),process.on("SIGTERM",SE),process.on("exit",vE),$l=!0)}function kE(){$l&&(process.removeListener("SIGINT",wE),process.removeListener("SIGTERM",SE),process.removeListener("exit",vE),$l=!1)}async function BG(t){return Nt!==null?Nt:(pr!==null||(pr=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(bE(),yE)),n=Q_(t),r=new e(n);return $G(),Nt=r,pr=null,r})()),pr)}async function xg(){if(Nt===null)return;let t=Nt;Nt=null,pr=null,kE(),await t.shutdown()}function jG(){return Nt!==null}function HG(){return Nt}function WG(){Nt=null,pr=null,kE()}var Nt,pr,$l,mr=g(()=>{"use strict";Dl();Nt=null,pr=null,$l=!1});async function AE(t,e){try{return await B_(t,e)}catch(n){return M("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function VG(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(mr(),fr));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function _E(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??VG,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Ml(n,t,{headers:zG,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(XG.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(qG.test(p)&&!GG.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await AE(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof St||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=pg({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await fi(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>fi(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await fi(u.finalUrl,o);let p=await AE(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=pg({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 St)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 GG,qG,XG,zG,EE=g(()=>{"use strict";j_();fg();yg();oe();GG=/(text\/html|application\/xhtml\+xml)/i,qG=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,XG=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,zG={"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 QG(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(JG,{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),YG),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Z(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function TE(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?QG({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 xE(t,e){if(e.length===0)return`# Search results for "${t}"
283
+ ${at(t,{headless:e,latched:n})}`,{cause:t})}var eE,iG,aG,Z_,lG,Sg=g(()=>{"use strict";eE=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],iG="pnpm exec playwright install chromium",aG=4;lG="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import ur from"node:fs";import Fl from"node:path";import{randomBytes as dG}from"node:crypto";import{chromium as uG}from"playwright";function pG(){try{return"5.151.0"}catch{}try{let t=Fl.resolve(import.meta.dirname,"../../../package.json"),e=ur.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var fG,Ll,nE=g(()=>{"use strict";Sg();j();oe();fG=pG(),Ll=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=uG.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=wg(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/${fG}`}}loadStorageState(e){let n=wf(e);try{if(!ur.existsSync(n))return;let r=JSON.parse(ur.readFileSync(n,"utf8"));return M("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){M("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=wf(e);if(!ur.existsSync(r))return;let o=await n.storageState(),s=Fl.join(Fl.dirname(r),`.${Fl.basename(r)}.${process.pid}.${dG(4).toString("hex")}.tmp`);ur.writeFileSync(s,JSON.stringify(o),{mode:384}),ur.chmodSync(s,384),ur.renameSync(s,r),M("[browser/vault] saved session",{profile:e,file:r})}catch(r){M("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as mG}from"crypto";function rE(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&gG.test(t.label))}function oE(t){return mG("sha256").update(t,"utf8").digest("hex").slice(0,8)}function sE(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var gG,Nl=g(()=>{"use strict";gG=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as hG}from"node:crypto";function yG(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function bG(t,e,n){return`el_${hG("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function wG(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function iE(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function cE(t,e){let n=t.role??"",r=t.name??"";aE.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])cE(s,e)}async function SG(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},lE).catch(()=>[])}async function vG(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},lE).catch(()=>[])}function kG(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Ul(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=kG(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=SG(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,b=!1;u!==null?(y=[],cE(u,y)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,y=(await vG(t)).filter(O=>aE.has(O.role??"")));let k=new Map;for(let C of p){let O=iE(C.name),q=k.get(O);(!q||q.bbox.w===0&&C.bbox.w>0)&&k.set(O,C)}let A=y.map(C=>({ax:C,dom:k.get(iE(C.name??""))})),E=r?A:A.filter(C=>C.dom?C.dom.bbox.w>0||C.dom.bbox.h>0:!0);E.sort((C,O)=>{let q=C.dom?.bbox.y??0,P=O.dom?.bbox.y??0;if(q!==P)return q-P;let $=C.dom?.bbox.x??0,D=O.dom?.bbox.x??0;return $-D}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=E.slice(0,n).map((C,O)=>{let q=C.ax.role??"generic",P=C.ax.name??"",$=bG(q,P,O),D=C.dom?.bbox??{x:0,y:0,w:0,h:0},L=C.dom?.type??null,B=null;C.ax.value!==void 0&&C.ax.value!==null&&(B=String(C.ax.value)),C.ax.checked!==void 0&&(B=String(C.ax.checked)),rE({role:q,kind:L})&&(B="[redacted]");let W={disabled:C.ax.disabled??!1};C.ax.checked!==void 0&&(W.checked=C.ax.checked===!0||C.ax.checked==="mixed"),C.ax.selected!==void 0&&(W.selected=C.ax.selected),C.ax.expanded!==void 0&&(W.expanded=C.ax.expanded);let Q;C.dom?.testId?Q=`[data-testid="${C.dom.testId}"]`:C.dom?.id&&(Q=`#${C.dom.id}`);let Le={id:$,role:q,label:yG(P),kind:L,value:B,state:W,bbox:D};return Q!==void 0&&(Le.selector=Q),Le}),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"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let R=wG(f),v=`obs_${e.observationCounter.toString(36)}`,_=new Date().toISOString();return{observationId:v,url:m,title:h,textSummary:R,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:_}}var aE,lE,dE=g(()=>{"use strict";Nl();aE=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);lE="a[href], button, input, select, textarea, [role], [tabindex], label"});async function uE(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 vg(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>uE(t,s)))).filter(o=>o!==null)}async function AG(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 kg(t,e,n){switch(e.kind){case"element_id":return _G(t,e,n);case"selector":return EG(t,e);case"semantic":return TG(t,e)}}async function _G(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 vg(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function EG(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 vg(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function TG(t,e){return e.role!==void 0?xG(t,e.text,e.role):RG(t,e.text,e)}async function xG(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 vg(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function RG(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 AG(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let b=await uE(y.locator,y.index);if(b!==null){let k=`${b.role}:${b.label}:${h}`,A=0;for(let E=0;E<k.length;E++)A=A*31+k.charCodeAt(E)>>>0;f.push({...b,id:`el_${A.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var pE=g(()=>{"use strict"});async function Ag(t,e,n,r){let o=t.url();if(o===n)return null;let s=Ol(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 fE=g(()=>{"use strict";Dl()});import{randomBytes as IG}from"crypto";import{mkdir as CG,stat as PG,writeFile as MG}from"fs/promises";import{join as _g}from"path";import{gzip as OG}from"zlib";import{promisify as DG}from"util";function FG(t){return _g(xt(t),"browser")}function LG(t){return _g(FG(t),"screenshots")}function NG(){return new Date().toISOString().replace(/[:.]/g,"-")}function UG(){return IG(3).toString("hex")}async function Eg(t,e,n){if(e.length>mE)throw new Error(`writeScreenshotSidecar: buffer exceeds ${mE} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=LG(t);await CG(r,{recursive:!0});let o=`${NG()}-${UG()}-${n}.png`,s=_g(r,o);await MG(s,e);let{size:i}=await PG(s);return{path:s,bytes:i}}var Gce,mE,gE=g(()=>{"use strict";j();Nl();Gce=DG(OG);mE=5*1024*1024});var yE={};uf(yE,{PlaywrightProvider:()=>Tg});function hE(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 Tg,bE=g(()=>{"use strict";nE();dE();pE();Dl();fE();gE();Tg=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Ll(e)}async open(e){let n=Ol(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 Ag(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 Ul(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 Ul(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 kg(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${hE(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 Ag(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 Ul(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 kg(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${hE(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 Eg(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 Eg(n,o,r);return s}catch{return null}}}});var fr={};uf(fr,{__resetBrowserRegistryForTests:()=>WG,browserProviderActive:()=>jG,closeBrowserProvider:()=>xg,getBrowserProvider:()=>BG,peekBrowserProvider:()=>HG});function wE(){Promise.resolve(xg()).then(()=>{process.exit(130)})}function SE(){Promise.resolve(xg()).then(()=>{process.exit(143)})}function vE(){Nt=null}function $G(){$l||(process.on("SIGINT",wE),process.on("SIGTERM",SE),process.on("exit",vE),$l=!0)}function kE(){$l&&(process.removeListener("SIGINT",wE),process.removeListener("SIGTERM",SE),process.removeListener("exit",vE),$l=!1)}async function BG(t){return Nt!==null?Nt:(pr!==null||(pr=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(bE(),yE)),n=Q_(t),r=new e(n);return $G(),Nt=r,pr=null,r})()),pr)}async function xg(){if(Nt===null)return;let t=Nt;Nt=null,pr=null,kE(),await t.shutdown()}function jG(){return Nt!==null}function HG(){return Nt}function WG(){Nt=null,pr=null,kE()}var Nt,pr,$l,mr=g(()=>{"use strict";Dl();Nt=null,pr=null,$l=!1});async function AE(t,e){try{return await B_(t,e)}catch(n){return M("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function VG(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(mr(),fr));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function _E(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??VG,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Ml(n,t,{headers:zG,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(XG.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(qG.test(p)&&!GG.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await AE(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof St||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=pg({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await fi(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>fi(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await fi(u.finalUrl,o);let p=await AE(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=pg({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 St)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 GG,qG,XG,zG,EE=g(()=>{"use strict";j_();fg();yg();oe();GG=/(text\/html|application\/xhtml\+xml)/i,qG=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,XG=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,zG={"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 QG(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(JG,{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),YG),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Z(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function TE(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?QG({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 xE(t,e){if(e.length===0)return`# Search results for "${t}"
284
284
 
285
285
  (no results)`;let n=[`# Search results for "${t}"`,""];return e.forEach((r,o)=>{n.push(`## ${o+1}. ${r.title}`),r.url&&n.push(r.url),r.description&&n.push(r.description),n.push("")}),n.join(`
286
286
  `).trimEnd()}var JG,YG,RE=g(()=>{"use strict";mt();JG="https://api.exa.ai/search",YG=10});function Bl(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 gr=g(()=>{"use strict";Sg()});function oq(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=ZG;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,eq)}let a=tq;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,nq)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Rg(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:er(t,e),truncated:!0}}function sq(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=oq(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 hg(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 Ml(e,i.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:h instanceof St?{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=Rg(f,i.maxBytes);return{content:m.content,...m.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await _E(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=Rg(H_(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 St)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),m=je(p)&&!bg(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${mi()}\`)`:"";return{content:`web_scrape markdown error: ${f}${m}`,isError:!0}}let u=TE({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:rq,timeoutMs:i.timeoutMs,signal:a.signal}),f=Rg(xE(i.query,p),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:{content:`web_scrape search error (${u.name}): ${p instanceof Error?p.message:String(p)}`,isError:!0}}}finally{l!==void 0&&clearTimeout(l),s.removeEventListener("abort",c)}}}var ZG,eq,tq,nq,rq,IE,CE=g(()=>{"use strict";EE();RE();yg();yn();fg();gr();ZG=3e4,eq=12e4,tq=1e5,nq=1e6,rq=10;IE=sq()});import{existsSync as ME,mkdirSync as iq,readFileSync as aq,renameSync as cq,unlinkSync as lq,writeFileSync as dq}from"node:fs";import{dirname as PE,join as uq}from"node:path";import{randomBytes as pq}from"node:crypto";function hr(t){let e=t??gf();if(!ME(e))return[];try{let n=aq(e,"utf-8");return JSON.parse(n)}catch(n){let r=n instanceof Error?n.message:String(n);return console.error(`[schedule-store] failed to parse ${e}: ${r}`),[]}}function gi(t,e){let n=e??gf();iq(PE(n),{recursive:!0});let r=uq(PE(n),`.schedules.json.${process.pid}.${pq(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{dq(r,o,"utf-8"),cq(r,n)}catch(s){try{ME(r)&&lq(r)}catch{}throw s}}function OE(t,e){let n=hr(e),r=n.map(c=>c.id),o=fq(t.name),s=mq(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),gi(n,e),a}function DE(t,e){let n=hr(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(gi(o,e),!0)}function FE(t,e){return hr(e).find(n=>n.id===t)}function fq(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function mq(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}function LE(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 NE=g(()=>{"use strict";j()});import{existsSync as gq,readFileSync as hq}from"node:fs";import{join as yq}from"node:path";async function ho(t,e,n){let r,o;try{let s=yq(Qw("default"),"port");if(!gq(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=hq(s,"utf-8").trim(),a=bq(i);if(!a)return{synced:!1,detail:"daemon-not-detected (invalid port file)"};({host:r,port:o}=a)}catch{return{synced:!1,detail:"daemon-not-detected (unreadable port file)"}}try{let s=r.includes(":")?`[${r}]`:r,i=await fetch(`http://${s}:${o}${e}`,{method:t,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return i.ok?{synced:!0,detail:"synced"}:t==="POST"&&i.status===409?{synced:!0,detail:"already-registered"}:t==="DELETE"&&i.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${i.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}function bq(t){let e=parseInt(t,10);if(String(e)===t&&!Number.isNaN(e))return e<1||e>65535?null:{host:"localhost",port:e};let n=t.lastIndexOf(":");if(n<1)return null;let r=t.slice(0,n),o=t.slice(n+1);if(!/^\d+$/.test(o))return null;let s=parseInt(o,10);return Number.isNaN(s)||s<1||s>65535||/^:+$/.test(r)?null:{host:r.startsWith("[")&&r.endsWith("]")?r.slice(1,-1):r,port:s}}var Ig,UE=g(()=>{"use strict";j();Ig="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 wq}from"node:fs";import{readFile as Sq}from"node:fs/promises";var $E,BE,jE,HE,WE=g(()=>{"use strict";NE();j();UE();$E=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=OE({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 ho("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 ho("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:Ig}})}},BE=async(t,e)=>{let n=hr();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})))}},jE=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;if(typeof n.taskId!="string"||!n.taskId)return{content:"Invalid input: taskId required",isError:!0};let r=n.taskId,o=typeof n.limit=="number"?Math.min(Math.max(1,n.limit),50):10,s=Ga();if(!wq(s))return{content:JSON.stringify([])};let i;try{let l=await Sq(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
@@ -1367,7 +1367,7 @@ Enter a number${_}`}I&&(l.allowSkip?v+=`
1367
1367
  model: ${t.model}${t.cwd?`
1368
1368
  cwd: ${t.cwd}`:""}`;case"user":return`\u{1F464} ${Fa(t.text,IL)}`;case"assistant":return`\u{1F916} ${Fa(t.text,IL)}`;case"tool":return`\u{1F527} ${t.toolName}(${Fa(t.input,fw)})`;case"tool_error":return`\u26A0\uFE0F tool failed: ${Fa(t.content,fw)}`;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: ${Fa(t.message,fw)}`;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 CL(t){let e=Nf(t);return e?.data.sessionId&&await rd(e.data.sessionId)?e.data.sessionId:await rd(t)?t:null}async function PL(){let t=[],n=(await Vs()).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=Hr().filter(s=>s.source!=="telegram").slice(0,8),o=[];for(let s of r)s.sessionId&&await rd(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(`
1369
1369
  `))}var Jp=class{watches=new Map;log;bot;messageHandler;elicitHeartbeatMs;constructor(e=()=>{},n,r,o=PQ){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,o=()=>({chatId:e})){this.stop(e);let s=new AbortController,i=this._run(e,n,r,o,s.signal).catch(a=>{this.log("watch loop error:",a)});this.watches.set(e,{sessionId:n,abort:s,finished:i})}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,s){let i=[],a=null,c=Promise.resolve(),l=this.bot!==void 0&&this.messageHandler!==void 0?Xp(Gp(this.messageHandler,this.bot,o,{ledgerOriginated:!0}),qp(this.bot,new Set([e]),(...u)=>this.log("[elicitation]",...u),o)):void 0,d=()=>{if(a=null,i.length===0)return;let u=i.join(`
1370
- `);i=[],c=c.then(()=>r(u)).catch(p=>this.log("watch send error:",p))};try{for await(let u of VT(n,{signal:s})){if(u.kind==="elicitation"&&l!==void 0){a&&clearTimeout(a),d(),await c;let f=Date.now(),m=0,h=setInterval(()=>{if(m>=MQ){clearInterval(h);return}m+=1;let k=Math.round((Date.now()-f)/6e4);r(`\u23F3 Still waiting on your answer (${k}m elapsed) \u2014 no deadline, reply above whenever you're ready. (Send /unwatch to stop watching this session.)`).catch(()=>{})},this.elicitHeartbeatMs);h.unref?.();let y=await(async()=>{try{return await l(u.request,{signal:s})}finally{clearInterval(h)}})(),b=Vp(n);if(b!==null){let k=TL(b,n,u.reqId,y);new Sn(n).record({kind:"elicitation_response",reqId:u.reqId,result:y,hmac:k})}else this.log("[watch] no session key for",n,"\u2014 skipping elicitation write-back");continue}let p=OQ(u);if(p){if(i.push(p),u.kind==="closed"){d();break}a||(a=setTimeout(d,CQ),a.unref?.())}}a&&clearTimeout(a),d(),await c}finally{a&&clearTimeout(a);let u=this.watches.get(e);u&&u.sessionId===n&&u.abort.signal===s&&this.watches.delete(e)}}};or();Si();Ue();bo();var Yp=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 DQ(e.botToken,{handlerTimeout:1/0}),this.sessionManager=new _c({...e,onResumptionOffer:(n,r)=>{this.bot.telegram.sendMessage(n.chatId,r,dn(n)).catch(()=>{})}}),this.messageHandler=new Hp(this.bot,this.sessionManager,this.registeredCommandChats,this.log.bind(this),e.tagOnlyChats??new Set),this.watchManager=new Jp(this.log.bind(this),this.bot,this.messageHandler),this.setupHandlers()}setupHandlers(){this.bot.use($A(this.options.allowedChatIds,this.log.bind(this))),this.bot.command("start",r=>jf(r)),this.bot.command("help",r=>Hf(r,this.sessionManager)),this.bot.command("clear",async r=>{let o=se(r);if(!o){await r.reply(z("Could not identify chat"));return}(await this.sessionManager.getSession(o)).state!=="idle"?(this.messageHandler.enqueueClear(o,r),await r.reply("Clear queued.")):await Jb(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}),this.bot.command("compact",async r=>{let o=se(r);if(!o){await r.reply(z("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 AF(r,this.sessionManager,this.log.bind(this))}finally{this.messageHandler.drainQueue(o).catch(i=>this.log("Drain error:",i))}}),this.bot.command("model",r=>Yb(r,this.sessionManager,this.log.bind(this))),this.bot.command(["cd","cwd"],r=>_F(r,this.sessionManager,this.log.bind(this))),this.bot.command("name",r=>EF(r,this.sessionManager,this.log.bind(this))),this.bot.command("afk",r=>PF(r,this.sessionManager,this.log.bind(this))),this.bot.command("usage",r=>OF(r,this.log.bind(this))),this.bot.command("sessions",r=>RF(r,this.sessionManager,this.log.bind(this))),this.bot.command("new",r=>IF(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))),this.bot.command("watch",async r=>{let o=se(r);if(!o){await r.reply(z("Could not identify chat"));return}let{chatId:s}=o,i=dn(o),c=((r.message&&"text"in r.message?r.message.text:"")??"").split(/\s+/).slice(1).join(" ").trim();try{if(!c){await r.reply(await PL());return}let l=await CL(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 Ve(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(z(l))}}),this.bot.command("unwatch",async r=>{let o=r.chat?.id;if(!o){await r.reply(z("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(z("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=Vp(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=RL(),c=xL(i,s,a);new Sn(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))),this.bot.on("document",r=>e(this.messageHandler.handleDocument(r)));let n=new RegExp(`^${He(Fp)}`);this.bot.action(n,r=>XF(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=se(r);if(!(!i||!s)&&Kn.includes(s))try{await this.sessionManager.switchModel(i,s);let a=Tc(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 CF(r,this.sessionManager,this.log.bind(this))}),this.bot.catch((r,o)=>{this.log("Bot error:",r),o.reply(z("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 n=e[0],r=Gp(this.messageHandler,this.bot,n),o=qp(this.bot,new Set(this.options.allowedChatIds),(...s)=>this.log("[elicitation]",...s));Qe.install(Xp(r,o))}await t0(),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()}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..."),Qe.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 jf(e)}async handleHelp(e){return Hf(e,this.sessionManager)}async handleClear(e){let n=se(e);if(!n){await e.reply(z("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 Jb(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 handleDocument(e){return this.messageHandler.handleDocument(e)}async handleModelSwitch(e){return Yb(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 Vs()}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=()=>this.sessionManager.getActiveRouteForChat(o)??{chatId:o},c=async l=>{for(let d of Ve(l))await this.bot.telegram.sendMessage(o,d,dn(a()))};this.watchManager.start(o,i,c,a),this.log(`[auto-subscribe] started watch for ${i} on chat ${o}`);break}}}log(...e){this.options.verbose&&console.log("[TelegramBot]",...e)}};si();Gg();j();U();import FFe from"chalk";import N from"chalk";var FQ={brand:N.hex("#E67E4C"),mint:N.hex("#5FE3A1"),goblin:N.hex("#9CB04A"),user:N.cyan,caret:N.hex("#7AA2F7"),tool:N.hex("#DCDCAA"),chrome:N.hex("#B0B8C2"),syntaxString:N.italic.hex("#8AB07A"),toolArg:N.dim.white,thinking:N.italic.hex("#9B8FB5"),success:N.green,error:N.red,warning:N.yellow,plan:N.hex("#9F7CE0"),bypass:N.bold.hex("#FF6AC1"),meta:N.blackBright,info:N.hex("#5BA8FF"),fileRef:N.hex("#56B5A8"),heading:N.bold.white,label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.green,diffRemove:N.red,diffHunk:N.blackBright},UFe={brand:N.hex("#C0562A"),mint:N.hex("#1B9E63"),goblin:N.hex("#6B7D2A"),user:N.hex("#0E7490"),caret:N.hex("#3B5BDB"),tool:N.hex("#7A6E00"),chrome:N.hex("#5A6470"),syntaxString:N.italic.hex("#3F7A3F"),toolArg:N.hex("#6B7280"),thinking:N.italic.hex("#6D5B8E"),success:N.hex("#2E7D32"),error:N.hex("#C62828"),warning:N.hex("#B8860B"),plan:N.hex("#7048C0"),bypass:N.bold.hex("#D6297F"),meta:N.hex("#6B7280"),info:N.hex("#1D6FD6"),fileRef:N.hex("#0F766E"),heading:N.bold.hex("#1F2937"),label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.hex("#2E7D32"),diffRemove:N.hex("#C62828"),diffHunk:N.hex("#6B7280")},$Fe={brand:N.hex("#FF9B5A"),mint:N.hex("#B4FCC3"),goblin:N.hex("#A5AC55"),user:N.hex("#42CBC8"),caret:N.hex("#9DBEFC"),tool:N.hex("#F7D179"),chrome:N.hex("#D3CDC5"),syntaxString:N.italic.hex("#96C182"),toolArg:N.dim.hex("#D3CDC5"),thinking:N.italic.hex("#B49EC4"),success:N.hex("#8AE49E"),error:N.hex("#EF7F74"),warning:N.hex("#D7AA32"),plan:N.hex("#AE93DE"),bypass:N.bold.hex("#FFACE9"),meta:N.hex("#AAA19B"),info:N.hex("#739EF0"),fileRef:N.hex("#80E5E2"),heading:N.bold.hex("#F9F6F2"),label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.hex("#8AE49E"),diffRemove:N.hex("#EF7F74"),diffHunk:N.hex("#AAA19B")};var LQ={...FQ};var NQ="https://api.telegram.org";async function ML(t){try{let e=await fetch(`${NQ}/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}}Rt();ue();fo();j();ue();ve();U();fo();function mw(){return`# Agent AFK
1370
+ `);i=[],c=c.then(()=>r(u)).catch(p=>this.log("watch send error:",p))};try{for await(let u of VT(n,{signal:s})){if(u.kind==="elicitation"&&l!==void 0){a&&clearTimeout(a),d(),await c;let f=Date.now(),m=0,h=setInterval(()=>{if(m>=MQ){clearInterval(h);return}m+=1;let k=Math.round((Date.now()-f)/6e4);r(`\u23F3 Still waiting on your answer (${k}m elapsed) \u2014 no deadline, reply above whenever you're ready. (Send /unwatch to stop watching this session.)`).catch(()=>{})},this.elicitHeartbeatMs);h.unref?.();let y=await(async()=>{try{return await l(u.request,{signal:s})}finally{clearInterval(h)}})(),b=Vp(n);if(b!==null){let k=TL(b,n,u.reqId,y);new Sn(n).record({kind:"elicitation_response",reqId:u.reqId,result:y,hmac:k})}else this.log("[watch] no session key for",n,"\u2014 skipping elicitation write-back");continue}let p=OQ(u);if(p){if(i.push(p),u.kind==="closed"){d();break}a||(a=setTimeout(d,CQ),a.unref?.())}}a&&clearTimeout(a),d(),await c}finally{a&&clearTimeout(a);let u=this.watches.get(e);u&&u.sessionId===n&&u.abort.signal===s&&this.watches.delete(e)}}};or();Si();Ue();bo();var Yp=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 DQ(e.botToken,{handlerTimeout:1/0}),this.sessionManager=new _c({...e,onResumptionOffer:(n,r)=>{this.bot.telegram.sendMessage(n.chatId,r,dn(n)).catch(()=>{})}}),this.messageHandler=new Hp(this.bot,this.sessionManager,this.registeredCommandChats,this.log.bind(this),e.tagOnlyChats??new Set),this.watchManager=new Jp(this.log.bind(this),this.bot,this.messageHandler),this.setupHandlers()}setupHandlers(){this.bot.use($A(this.options.allowedChatIds,this.log.bind(this))),this.bot.command("start",r=>jf(r)),this.bot.command("help",r=>Hf(r,this.sessionManager)),this.bot.command("clear",async r=>{let o=se(r);if(!o){await r.reply(z("Could not identify chat"));return}(await this.sessionManager.getSession(o)).state!=="idle"?(this.messageHandler.enqueueClear(o,r),await r.reply("Clear queued.")):await Jb(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}),this.bot.command("compact",async r=>{let o=se(r);if(!o){await r.reply(z("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 AF(r,this.sessionManager,this.log.bind(this))}finally{this.messageHandler.drainQueue(o).catch(i=>this.log("Drain error:",i))}}),this.bot.command("model",r=>Yb(r,this.sessionManager,this.log.bind(this))),this.bot.command(["cd","cwd"],r=>_F(r,this.sessionManager,this.log.bind(this))),this.bot.command("name",r=>EF(r,this.sessionManager,this.log.bind(this))),this.bot.command("afk",r=>PF(r,this.sessionManager,this.log.bind(this))),this.bot.command("usage",r=>OF(r,this.log.bind(this))),this.bot.command("sessions",r=>RF(r,this.sessionManager,this.log.bind(this))),this.bot.command("new",r=>IF(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))),this.bot.command("watch",async r=>{let o=se(r);if(!o){await r.reply(z("Could not identify chat"));return}let{chatId:s}=o,i=dn(o),c=((r.message&&"text"in r.message?r.message.text:"")??"").split(/\s+/).slice(1).join(" ").trim();try{if(!c){await r.reply(await PL());return}let l=await CL(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 Ve(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(z(l))}}),this.bot.command("unwatch",async r=>{let o=r.chat?.id;if(!o){await r.reply(z("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(z("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=Vp(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=RL(),c=xL(i,s,a);new Sn(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))),this.bot.on("document",r=>e(this.messageHandler.handleDocument(r))),this.bot.on(["voice","video","sticker","video_note","audio"],r=>{r.chat&&r.reply("I can process text, photo, and document messages. Voice and video support is not yet available.").catch(o=>this.log("Failed to send unsupported-type reply:",o))});let n=new RegExp(`^${He(Fp)}`);this.bot.action(n,r=>XF(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=se(r);if(!(!i||!s)&&Kn.includes(s))try{await this.sessionManager.switchModel(i,s);let a=Tc(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 CF(r,this.sessionManager,this.log.bind(this))}),this.bot.catch((r,o)=>{this.log("Bot error:",r),o.chat&&o.reply(z("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 n=e[0],r=Gp(this.messageHandler,this.bot,n),o=qp(this.bot,new Set(this.options.allowedChatIds),(...s)=>this.log("[elicitation]",...s));Qe.install(Xp(r,o))}await t0(),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()}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..."),Qe.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 jf(e)}async handleHelp(e){return Hf(e,this.sessionManager)}async handleClear(e){let n=se(e);if(!n){await e.reply(z("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 Jb(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 handleDocument(e){return this.messageHandler.handleDocument(e)}async handleModelSwitch(e){return Yb(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 Vs()}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=()=>this.sessionManager.getActiveRouteForChat(o)??{chatId:o},c=async l=>{for(let d of Ve(l))await this.bot.telegram.sendMessage(o,d,dn(a()))};this.watchManager.start(o,i,c,a),this.log(`[auto-subscribe] started watch for ${i} on chat ${o}`);break}}}log(...e){this.options.verbose&&console.log("[TelegramBot]",...e)}};si();Gg();j();U();import FFe from"chalk";import N from"chalk";var FQ={brand:N.hex("#E67E4C"),mint:N.hex("#5FE3A1"),goblin:N.hex("#9CB04A"),user:N.cyan,caret:N.hex("#7AA2F7"),tool:N.hex("#DCDCAA"),chrome:N.hex("#B0B8C2"),syntaxString:N.italic.hex("#8AB07A"),toolArg:N.dim.white,thinking:N.italic.hex("#9B8FB5"),success:N.green,error:N.red,warning:N.yellow,plan:N.hex("#9F7CE0"),bypass:N.bold.hex("#FF6AC1"),meta:N.blackBright,info:N.hex("#5BA8FF"),fileRef:N.hex("#56B5A8"),heading:N.bold.white,label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.green,diffRemove:N.red,diffHunk:N.blackBright},UFe={brand:N.hex("#C0562A"),mint:N.hex("#1B9E63"),goblin:N.hex("#6B7D2A"),user:N.hex("#0E7490"),caret:N.hex("#3B5BDB"),tool:N.hex("#7A6E00"),chrome:N.hex("#5A6470"),syntaxString:N.italic.hex("#3F7A3F"),toolArg:N.hex("#6B7280"),thinking:N.italic.hex("#6D5B8E"),success:N.hex("#2E7D32"),error:N.hex("#C62828"),warning:N.hex("#B8860B"),plan:N.hex("#7048C0"),bypass:N.bold.hex("#D6297F"),meta:N.hex("#6B7280"),info:N.hex("#1D6FD6"),fileRef:N.hex("#0F766E"),heading:N.bold.hex("#1F2937"),label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.hex("#2E7D32"),diffRemove:N.hex("#C62828"),diffHunk:N.hex("#6B7280")},$Fe={brand:N.hex("#FF9B5A"),mint:N.hex("#B4FCC3"),goblin:N.hex("#A5AC55"),user:N.hex("#42CBC8"),caret:N.hex("#9DBEFC"),tool:N.hex("#F7D179"),chrome:N.hex("#D3CDC5"),syntaxString:N.italic.hex("#96C182"),toolArg:N.dim.hex("#D3CDC5"),thinking:N.italic.hex("#B49EC4"),success:N.hex("#8AE49E"),error:N.hex("#EF7F74"),warning:N.hex("#D7AA32"),plan:N.hex("#AE93DE"),bypass:N.bold.hex("#FFACE9"),meta:N.hex("#AAA19B"),info:N.hex("#739EF0"),fileRef:N.hex("#80E5E2"),heading:N.bold.hex("#F9F6F2"),label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.hex("#8AE49E"),diffRemove:N.hex("#EF7F74"),diffHunk:N.hex("#AAA19B")};var LQ={...FQ};var NQ="https://api.telegram.org";async function ML(t){try{let e=await fetch(`${NQ}/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}}Rt();ue();fo();j();ue();ve();U();fo();function mw(){return`# Agent AFK
1371
1371
 
1372
1372
  ## What this process is
1373
1373
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-afk",
3
- "version": "5.150.1",
3
+ "version": "5.151.0",
4
4
  "description": "Open-source coding-agent harness you can actually change — own the loop (prompts, gates, routing, skills, terminal states), use any model, run long tasks while you're away.",
5
5
  "main": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",