agent-afk 5.123.0 → 5.123.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/telegram.mjs CHANGED
@@ -213,7 +213,7 @@ ${o}`,paths:[e,n]}:o!==null?s={content:o,paths:[n]}:r!==null?s={content:r,paths:
213
213
 
214
214
  ${e}`}var VH,lm=g(()=>{"use strict";VH=new Set(["script","style","noscript","template","svg"])});function QH(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 Uk(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function ZH(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??QH,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(!YH.has(u.status)||d===o)return u;let p=ZH(u,i)??Uk(d,s,i);$("[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=Uk(d,s,i);$("[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 YH,Bk=g(()=>{"use strict";fe();YH=new Set([429,502,503,504])});import{BlockList as ej,isIP as um}from"node:net";import{lookup as tj}from"node:dns/promises";import{Agent as nj}from"undici";function jk(){let t=v.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function ij(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function dm(t){let e=um(t);return e===0?!1:sj.check(t,e===4?"ipv4":"ipv6")}async function Wk(t){return tj(t,{all:!0,verbatim:!0})}async function pm(t,e={}){if(e.allowPrivateHosts??jk())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=ij(n.hostname),o=(a,c)=>`refusing to fetch ${c} \u2014 internal/private address ${a} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`;if(um(r)!==0)return dm(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??Wk,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(dm(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function Js(t,e={}){let n=await pm(t,e);if(!n.allowed)throw new _t(n.reason)}async function Jc(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<=Hk;i++){await Js(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??jk())?{dispatcher:aj}:{}},c=await $k(t,s,a,r.retry??{});if(!cj.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 _t(`too many redirects (>${Hk}) starting from ${e}`)}var rj,oj,sj,_t,aj,Hk,cj,fm=g(()=>{"use strict";F();Bk();rj=[["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]],oj=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],sj=(()=>{let t=new ej;for(let[e,n]of rj)t.addSubnet(e,n,"ipv4");for(let[e,n]of oj)t.addSubnet(e,n,"ipv6");return t})(),_t=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};aj=new nj({connect:{lookup(t,e,n){Wk(t).then(r=>{let o=r.find(i=>dm(i.address));if(o!==void 0){n(new _t(`refusing to connect to ${t} (resolved) \u2014 internal/private address ${o.address} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`),"",0);return}let s=r[0];if(s===void 0){n(new Error(`DNS lookup returned no addresses for ${t}`),"",0);return}n(null,s.address,um(s.address))},r=>n(r,"",0))}}});Hk=20,cj=new Set([301,302,303,307,308])});import{readFileSync as lj}from"node:fs";import{join as dj}from"path";function uj(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function Kk(t,e){return uj(e).test(t)}function mj(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(pj.has(e))return!0;if(fj.has(e))return!1}return!1}function Gk(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function gj(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 qk(t){let e=t===void 0||t.trim()===""?"default":t.trim();return xp(e),e}function hj(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function yj(t){try{return lj(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function bj(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=qk(e.defaultProfile)),n}function Xk(t){let e=t?.env??v,n=t?.readFileSync??yj,r=t?.surface??e.AGENT_SURFACE,o=mj(e.AFK_BROWSER_HEADLESS,r),s=Gk(e.AFK_BROWSER_ALLOWED_DOMAINS),i=Gk(e.AFK_BROWSER_BLOCKED_DOMAINS),a=hj(e.AFK_BROWSER_DOM_SNAPSHOTS),c=gj(e.AFK_BROWSER_BACKEND),l=qk(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():dj(Xt(),"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=bj(d,m);return h.configPath=p,h}function Yc(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(Kk(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>Kk(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var pj,fj,Qc=g(()=>{"use strict";F();H();pj=new Set(["daemon","subagent","telegram","afk"]),fj=new Set(["repl","interactive","cli"])});import{existsSync as wj,readFileSync as Sj}from"node:fs";import{createRequire as vj}from"node:module";import{dirname as kj,join as Aj}from"node:path";function Jk(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<Tj&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function We(t){let e=Jk(t);return Vk.some(n=>e.includes(n))}function Ej(){try{let e=vj(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(Sj(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=Aj(kj(e),o);return wj(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function Ys(){return zk??=Ej()??_j,zk}function mm(t){return t.includes("install chromium")}function dt(t,e){let n=Jk(t),r=e?.latched===!0?` ${xj}`:"";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: ${Ys()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Ys()}). Or pick a different tool.${r}`}function gm(t,e,n=!1){if(!We(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
215
215
 
216
- ${dt(t,{headless:e,latched:n})}`,{cause:t})}var Vk,_j,Tj,zk,xj,hm=g(()=>{"use strict";Vk=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],_j="pnpm exec playwright install chromium",Tj=4;xj="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 lr from"node:fs";import Zc from"node:path";import{randomBytes as Rj}from"node:crypto";import{chromium as Ij}from"playwright";function Cj(){try{return"5.123.0"}catch{}try{let t=Zc.resolve(import.meta.dirname,"../../../package.json"),e=lr.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var Pj,el,Yk=g(()=>{"use strict";hm();H();fe();Pj=Cj(),el=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=Ij.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=gm(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/${Pj}`}}loadStorageState(e){let n=Rp(e);try{if(!lr.existsSync(n))return;let r=JSON.parse(lr.readFileSync(n,"utf8"));return $("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){$("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Rp(e);if(!lr.existsSync(r))return;let o=await n.storageState(),s=Zc.join(Zc.dirname(r),`.${Zc.basename(r)}.${process.pid}.${Rj(4).toString("hex")}.tmp`);lr.writeFileSync(s,JSON.stringify(o),{mode:384}),lr.chmodSync(s,384),lr.renameSync(s,r),$("[browser/vault] saved session",{profile:e,file:r})}catch(r){$("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as Mj}from"crypto";function Qk(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&Oj.test(t.label))}function Zk(t){return Mj("sha256").update(t,"utf8").digest("hex").slice(0,8)}function eA(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var Oj,tl=g(()=>{"use strict";Oj=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as Dj}from"node:crypto";function Fj(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function Lj(t,e,n){return`el_${Dj("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function Nj(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function tA(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function rA(t,e){let n=t.role??"",r=t.name??"";nA.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])rA(s,e)}async function Uj(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},oA).catch(()=>[])}async function $j(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},oA).catch(()=>[])}function Bj(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function nl(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=Bj(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=Uj(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,h]=await Promise.all([i,a,c,l,d]),y,w=!1;u!==null?(y=[],rA(u,y)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,y=(await $j(t)).filter(L=>nA.has(L.role??"")));let A=new Map;for(let I of p){let L=tA(I.name),z=A.get(L);(!z||z.bbox.w===0&&I.bbox.w>0)&&A.set(L,I)}let _=y.map(I=>({ax:I,dom:A.get(tA(I.name??""))})),k=r?_:_.filter(I=>I.dom?I.dom.bbox.w>0||I.dom.bbox.h>0:!0);k.sort((I,L)=>{let z=I.dom?.bbox.y??0,P=L.dom?.bbox.y??0;if(z!==P)return z-P;let B=I.dom?.bbox.x??0,N=L.dom?.bbox.x??0;return B-N}),k.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=k.slice(0,n).map((I,L)=>{let z=I.ax.role??"generic",P=I.ax.name??"",B=Lj(z,P,L),N=I.dom?.bbox??{x:0,y:0,w:0,h:0},M=I.dom?.type??null,U=null;I.ax.value!==void 0&&I.ax.value!==null&&(U=String(I.ax.value)),I.ax.checked!==void 0&&(U=String(I.ax.checked)),Qk({role:z,kind:M})&&(U="[redacted]");let j={disabled:I.ax.disabled??!1};I.ax.checked!==void 0&&(j.checked=I.ax.checked===!0||I.ax.checked==="mixed"),I.ax.selected!==void 0&&(j.selected=I.ax.selected),I.ax.expanded!==void 0&&(j.expanded=I.ax.expanded);let J;I.dom?.testId?J=`[data-testid="${I.dom.testId}"]`:I.dom?.id&&(J=`#${I.dom.id}`);let te={id:B,role:z,label:Fj(P),kind:M,value:U,state:j,bbox:N};return J!==void 0&&(te.selector=J),te}),C="idle";try{let I=await t.evaluate(()=>document.readyState);I==="loading"?C="loading":I==="interactive"?C="navigating":C="idle"}catch{C="navigating"}C!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),w&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let R=Nj(f),S=`obs_${e.observationCounter.toString(36)}`,x=new Date().toISOString();return{observationId:S,url:m,title:h,textSummary:R,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:C,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:x}}var nA,oA,sA=g(()=>{"use strict";tl();nA=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);oA="a[href], button, input, select, textarea, [role], [tabindex], label"});async function iA(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 ym(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>iA(t,s)))).filter(o=>o!==null)}async function Hj(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 bm(t,e,n){switch(e.kind){case"element_id":return jj(t,e,n);case"selector":return Wj(t,e);case"semantic":return Kj(t,e)}}async function jj(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 ym(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function Wj(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 ym(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function Kj(t,e){return e.role!==void 0?Gj(t,e.text,e.role):qj(t,e.text,e)}async function Gj(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 ym(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function qj(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 Hj(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let w=await iA(y.locator,y.index);if(w!==null){let A=`${w.role}:${w.label}:${h}`,_=0;for(let k=0;k<A.length;k++)_=_*31+A.charCodeAt(k)>>>0;f.push({...w,id:`el_${_.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var aA=g(()=>{"use strict"});async function wm(t,e,n,r){let o=t.url();if(o===n)return null;let s=Yc(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 cA=g(()=>{"use strict";Qc()});import{randomBytes as Xj}from"crypto";import{mkdir as zj,stat as Vj,writeFile as Jj}from"fs/promises";import{join as Sm}from"path";import{gzip as Yj}from"zlib";import{promisify as Qj}from"util";function Zj(t){return Sm(It(t),"browser")}function eW(t){return Sm(Zj(t),"screenshots")}function tW(){return new Date().toISOString().replace(/[:.]/g,"-")}function nW(){return Xj(3).toString("hex")}async function vm(t,e,n){if(e.length>lA)throw new Error(`writeScreenshotSidecar: buffer exceeds ${lA} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=eW(t);await zj(r,{recursive:!0});let o=`${tW()}-${nW()}-${n}.png`,s=Sm(r,o);await Jj(s,e);let{size:i}=await Vj(s);return{path:s,bytes:i}}var Ere,lA,dA=g(()=>{"use strict";H();tl();Ere=Qj(Yj);lA=5*1024*1024});var pA={};Sp(pA,{PlaywrightProvider:()=>km});function uA(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 km,fA=g(()=>{"use strict";Yk();sA();aA();Qc();cA();dA();km=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new el(e)}async open(e){let n=Yc(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 wm(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 nl(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 nl(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 bm(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${uA(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 wm(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 nl(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 bm(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${uA(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 vm(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 vm(n,o,r);return s}catch{return null}}}});var ur={};Sp(ur,{__resetBrowserRegistryForTests:()=>aW,browserProviderActive:()=>sW,closeBrowserProvider:()=>Am,getBrowserProvider:()=>oW,peekBrowserProvider:()=>iW});function mA(){Promise.resolve(Am()).then(()=>{process.exit(130)})}function gA(){Promise.resolve(Am()).then(()=>{process.exit(143)})}function hA(){$t=null}function rW(){rl||(process.on("SIGINT",mA),process.on("SIGTERM",gA),process.on("exit",hA),rl=!0)}function yA(){rl&&(process.removeListener("SIGINT",mA),process.removeListener("SIGTERM",gA),process.removeListener("exit",hA),rl=!1)}async function oW(t){return $t!==null?$t:(dr!==null||(dr=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(fA(),pA)),n=Xk(t),r=new e(n);return rW(),$t=r,dr=null,r})()),dr)}async function Am(){if($t===null)return;let t=$t;$t=null,dr=null,yA(),await t.shutdown()}function sW(){return $t!==null}function iW(){return $t}function aW(){$t=null,dr=null,yA()}var $t,dr,rl,pr=g(()=>{"use strict";Qc();$t=null,dr=null,rl=!1});async function bA(t,e){try{return await Fk(t,e)}catch(n){return $("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function fW(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(pr(),ur));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function wA(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??fW,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Jc(n,t,{headers:pW,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(uW.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(dW.test(p)&&!lW.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await bA(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof _t||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=cm({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await Js(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>Js(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await Js(u.finalUrl,o);let p=await bA(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=cm({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(e.signal.aborted||u instanceof _t)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 lW,dW,uW,pW,SA=g(()=>{"use strict";Lk();lm();fm();fe();lW=/(text\/html|application\/xhtml\+xml)/i,dW=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,uW=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,pW={"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 hW(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(mW,{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),gW),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=ne(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 vA(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?hW({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 kA(t,e){if(e.length===0)return`# Search results for "${t}"
216
+ ${dt(t,{headless:e,latched:n})}`,{cause:t})}var Vk,_j,Tj,zk,xj,hm=g(()=>{"use strict";Vk=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],_j="pnpm exec playwright install chromium",Tj=4;xj="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 lr from"node:fs";import Zc from"node:path";import{randomBytes as Rj}from"node:crypto";import{chromium as Ij}from"playwright";function Cj(){try{return"5.123.1"}catch{}try{let t=Zc.resolve(import.meta.dirname,"../../../package.json"),e=lr.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var Pj,el,Yk=g(()=>{"use strict";hm();H();fe();Pj=Cj(),el=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=Ij.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=gm(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/${Pj}`}}loadStorageState(e){let n=Rp(e);try{if(!lr.existsSync(n))return;let r=JSON.parse(lr.readFileSync(n,"utf8"));return $("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){$("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Rp(e);if(!lr.existsSync(r))return;let o=await n.storageState(),s=Zc.join(Zc.dirname(r),`.${Zc.basename(r)}.${process.pid}.${Rj(4).toString("hex")}.tmp`);lr.writeFileSync(s,JSON.stringify(o),{mode:384}),lr.chmodSync(s,384),lr.renameSync(s,r),$("[browser/vault] saved session",{profile:e,file:r})}catch(r){$("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as Mj}from"crypto";function Qk(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&Oj.test(t.label))}function Zk(t){return Mj("sha256").update(t,"utf8").digest("hex").slice(0,8)}function eA(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var Oj,tl=g(()=>{"use strict";Oj=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as Dj}from"node:crypto";function Fj(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function Lj(t,e,n){return`el_${Dj("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function Nj(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function tA(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function rA(t,e){let n=t.role??"",r=t.name??"";nA.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])rA(s,e)}async function Uj(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},oA).catch(()=>[])}async function $j(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},oA).catch(()=>[])}function Bj(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function nl(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=Bj(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=Uj(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,h]=await Promise.all([i,a,c,l,d]),y,w=!1;u!==null?(y=[],rA(u,y)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,y=(await $j(t)).filter(L=>nA.has(L.role??"")));let A=new Map;for(let I of p){let L=tA(I.name),z=A.get(L);(!z||z.bbox.w===0&&I.bbox.w>0)&&A.set(L,I)}let _=y.map(I=>({ax:I,dom:A.get(tA(I.name??""))})),k=r?_:_.filter(I=>I.dom?I.dom.bbox.w>0||I.dom.bbox.h>0:!0);k.sort((I,L)=>{let z=I.dom?.bbox.y??0,P=L.dom?.bbox.y??0;if(z!==P)return z-P;let B=I.dom?.bbox.x??0,N=L.dom?.bbox.x??0;return B-N}),k.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=k.slice(0,n).map((I,L)=>{let z=I.ax.role??"generic",P=I.ax.name??"",B=Lj(z,P,L),N=I.dom?.bbox??{x:0,y:0,w:0,h:0},M=I.dom?.type??null,U=null;I.ax.value!==void 0&&I.ax.value!==null&&(U=String(I.ax.value)),I.ax.checked!==void 0&&(U=String(I.ax.checked)),Qk({role:z,kind:M})&&(U="[redacted]");let j={disabled:I.ax.disabled??!1};I.ax.checked!==void 0&&(j.checked=I.ax.checked===!0||I.ax.checked==="mixed"),I.ax.selected!==void 0&&(j.selected=I.ax.selected),I.ax.expanded!==void 0&&(j.expanded=I.ax.expanded);let J;I.dom?.testId?J=`[data-testid="${I.dom.testId}"]`:I.dom?.id&&(J=`#${I.dom.id}`);let te={id:B,role:z,label:Fj(P),kind:M,value:U,state:j,bbox:N};return J!==void 0&&(te.selector=J),te}),C="idle";try{let I=await t.evaluate(()=>document.readyState);I==="loading"?C="loading":I==="interactive"?C="navigating":C="idle"}catch{C="navigating"}C!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),w&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let R=Nj(f),S=`obs_${e.observationCounter.toString(36)}`,x=new Date().toISOString();return{observationId:S,url:m,title:h,textSummary:R,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:C,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:x}}var nA,oA,sA=g(()=>{"use strict";tl();nA=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);oA="a[href], button, input, select, textarea, [role], [tabindex], label"});async function iA(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 ym(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>iA(t,s)))).filter(o=>o!==null)}async function Hj(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 bm(t,e,n){switch(e.kind){case"element_id":return jj(t,e,n);case"selector":return Wj(t,e);case"semantic":return Kj(t,e)}}async function jj(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 ym(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function Wj(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 ym(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function Kj(t,e){return e.role!==void 0?Gj(t,e.text,e.role):qj(t,e.text,e)}async function Gj(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 ym(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function qj(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 Hj(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let h=u[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=u.slice(0,5),f=[];for(let h=0;h<p.length;h++){let y=p[h];if(y===void 0)continue;let w=await iA(y.locator,y.index);if(w!==null){let A=`${w.role}:${w.label}:${h}`,_=0;for(let k=0;k<A.length;k++)_=_*31+A.charCodeAt(k)>>>0;f.push({...w,id:`el_${_.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var aA=g(()=>{"use strict"});async function wm(t,e,n,r){let o=t.url();if(o===n)return null;let s=Yc(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 cA=g(()=>{"use strict";Qc()});import{randomBytes as Xj}from"crypto";import{mkdir as zj,stat as Vj,writeFile as Jj}from"fs/promises";import{join as Sm}from"path";import{gzip as Yj}from"zlib";import{promisify as Qj}from"util";function Zj(t){return Sm(It(t),"browser")}function eW(t){return Sm(Zj(t),"screenshots")}function tW(){return new Date().toISOString().replace(/[:.]/g,"-")}function nW(){return Xj(3).toString("hex")}async function vm(t,e,n){if(e.length>lA)throw new Error(`writeScreenshotSidecar: buffer exceeds ${lA} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=eW(t);await zj(r,{recursive:!0});let o=`${tW()}-${nW()}-${n}.png`,s=Sm(r,o);await Jj(s,e);let{size:i}=await Vj(s);return{path:s,bytes:i}}var Ere,lA,dA=g(()=>{"use strict";H();tl();Ere=Qj(Yj);lA=5*1024*1024});var pA={};Sp(pA,{PlaywrightProvider:()=>km});function uA(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 km,fA=g(()=>{"use strict";Yk();sA();aA();Qc();cA();dA();km=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new el(e)}async open(e){let n=Yc(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 wm(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 nl(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 nl(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 bm(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${uA(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 wm(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 nl(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 bm(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${uA(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 vm(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 vm(n,o,r);return s}catch{return null}}}});var ur={};Sp(ur,{__resetBrowserRegistryForTests:()=>aW,browserProviderActive:()=>sW,closeBrowserProvider:()=>Am,getBrowserProvider:()=>oW,peekBrowserProvider:()=>iW});function mA(){Promise.resolve(Am()).then(()=>{process.exit(130)})}function gA(){Promise.resolve(Am()).then(()=>{process.exit(143)})}function hA(){$t=null}function rW(){rl||(process.on("SIGINT",mA),process.on("SIGTERM",gA),process.on("exit",hA),rl=!0)}function yA(){rl&&(process.removeListener("SIGINT",mA),process.removeListener("SIGTERM",gA),process.removeListener("exit",hA),rl=!1)}async function oW(t){return $t!==null?$t:(dr!==null||(dr=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(fA(),pA)),n=Xk(t),r=new e(n);return rW(),$t=r,dr=null,r})()),dr)}async function Am(){if($t===null)return;let t=$t;$t=null,dr=null,yA(),await t.shutdown()}function sW(){return $t!==null}function iW(){return $t}function aW(){$t=null,dr=null,yA()}var $t,dr,rl,pr=g(()=>{"use strict";Qc();$t=null,dr=null,rl=!1});async function bA(t,e){try{return await Fk(t,e)}catch(n){return $("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function fW(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(pr(),ur));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function wA(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??fW,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Jc(n,t,{headers:pW,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(uW.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(dW.test(p)&&!lW.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await bA(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof _t||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=cm({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await Js(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>Js(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await Js(u.finalUrl,o);let p=await bA(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=cm({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(e.signal.aborted||u instanceof _t)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 lW,dW,uW,pW,SA=g(()=>{"use strict";Lk();lm();fm();fe();lW=/(text\/html|application\/xhtml\+xml)/i,dW=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,uW=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,pW={"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 hW(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(mW,{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),gW),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=ne(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 vA(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?hW({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 kA(t,e){if(e.length===0)return`# Search results for "${t}"
217
217
 
218
218
  (no results)`;let n=[`# Search results for "${t}"`,""];return e.forEach((r,o)=>{n.push(`## ${o+1}. ${r.title}`),r.url&&n.push(r.url),r.description&&n.push(r.description),n.push("")}),n.join(`
219
219
  `).trimEnd()}var mW,gW,AA=g(()=>{"use strict";At();mW="https://api.exa.ai/search",gW=10});function ol(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 fr=g(()=>{"use strict";hm()});function kW(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=yW;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,bW)}let a=wW;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,SW)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function _m(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:Yt(t,e),truncated:!0}}function AW(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=kW(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 pm(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 Jc(e,i.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:h instanceof _t?{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=_m(f,i.maxBytes);return{content:m.content,...m.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await wA(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=_m(Nk(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 _t)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),m=We(p)&&!mm(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Ys()}\`)`:"";return{content:`web_scrape markdown error: ${f}${m}`,isError:!0}}let u=vA({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:vW,timeoutMs:i.timeoutMs,signal:a.signal}),f=_m(kA(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 yW,bW,wW,SW,vW,_A,TA=g(()=>{"use strict";SA();AA();fm();yn();lm();fr();yW=3e4,bW=12e4,wW=1e5,SW=1e6,vW=10;_A=AW()});import{existsSync as xA,mkdirSync as _W,readFileSync as TW,renameSync as EW,unlinkSync as xW,writeFileSync as RW}from"node:fs";import{dirname as EA,join as IW}from"node:path";import{randomBytes as CW}from"node:crypto";function mr(t){let e=t??_p();if(!xA(e))return[];try{let n=TW(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 Qs(t,e){let n=e??_p();_W(EA(n),{recursive:!0});let r=IW(EA(n),`.schedules.json.${process.pid}.${CW(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{RW(r,o,"utf-8"),EW(r,n)}catch(s){try{xA(r)&&xW(r)}catch{}throw s}}function RA(t,e){let n=mr(e),r=n.map(c=>c.id),o=PW(t.name),s=MW(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),Qs(n,e),a}function IA(t,e){let n=mr(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(Qs(o,e),!0)}function CA(t,e){return mr(e).find(n=>n.id===t)}function PW(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function MW(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}function PA(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 MA=g(()=>{"use strict";H()});import{existsSync as OW,readFileSync as DW}from"node:fs";import{join as FW}from"node:path";async function to(t,e,n){let r;try{let o=FW($b("default"),"port");if(!OW(o))return{synced:!1,detail:"daemon-not-detected (no port file)"};let s=DW(o,"utf-8").trim();if(r=parseInt(s,10),Number.isNaN(r))return{synced:!1,detail:"daemon-not-detected (invalid port file)"}}catch{return{synced:!1,detail:"daemon-not-detected (unreadable port file)"}}try{let o=await fetch(`http://localhost:${r}${e}`,{method:t,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return o.ok?{synced:!0,detail:"synced"}:t==="POST"&&o.status===409?{synced:!0,detail:"already-registered"}:t==="DELETE"&&o.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${o.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}var Tm,OA=g(()=>{"use strict";H();Tm="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 LW}from"node:fs";import{readFile as NW}from"node:fs/promises";var DA,FA,LA,NA,UA=g(()=>{"use strict";MA();H();OA();DA=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=RA({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 to("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 to("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:Tm}})}},FA=async(t,e)=>{let n=mr();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})))}},LA=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=_a();if(!LW(s))return{content:JSON.stringify([])};let i;try{let l=await NW(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
@@ -1206,7 +1206,7 @@ ${r}
1206
1206
 
1207
1207
  ${o}`};if(s&&typeof s=="object"&&"type"in s&&s.type==="preset"){let i=s.append??"";return{...t,systemPrompt:{...s,append:`${i}
1208
1208
 
1209
- ${o}`}}}return{...t,systemPrompt:o}}function Ga(t){let e=t.toLowerCase().replace(/[`*_~]/g," ").replace(/[^\w\s-]/g," ").replace(/[\s_]+/g," ").trim();return e?e.split(" ").filter(Boolean).slice(0,6).join("-").slice(0,48).replace(/-+$/g,""):""}function bw(t){return{totalTurns:0,totalCostUsd:0,unpricedTurns:0,totalTokens:0,totalDurationMs:0,sessionStartTime:Date.now(),turnCosts:[],turnTokens:[],turns:[],model:t,permissionMode:"default",thinkingUi:"live"}}function ww(t,e,n,r,o){let s=r?.totalCostUsd??0;r?.totalCostUsd===void 0&&(t.unpricedTurns+=1);let i=r?.durationMs??0,a=Number(r?.usage?.input_tokens??0),c=Number(r?.usage?.output_tokens??0),l=a,d=c,u=Number(r?.usage?.cache_read_input_tokens??0)+Number(r?.usage?.cache_creation_input_tokens??0),p=r?.usage?.iterations;if(Array.isArray(p)&&p.length>0){let w=p[p.length-1];if(w&&typeof w=="object"){let A=w;l=Number(A.input_tokens??0),d=Number(A.output_tokens??0),u=Number(A.cache_read_input_tokens??0)+Number(A.cache_creation_input_tokens??0)}}t.totalTurns+=1,t.totalCostUsd+=s,t.totalDurationMs+=i,t.totalTokens+=a+c,t.turnCosts.push(s);let f=Number(r?.usage?.context_window_tokens??NaN),m=Array.isArray(p)&&p.length>0,h=Number.isFinite(f)?f:m?l+d+u:void 0;if(t.turnTokens.push({input:l,output:d,cache:u,...h!==void 0?{footprint:h}:{}}),r?.sessionId&&!t.sessionId&&(t.sessionId=String(r.sessionId)),!t.name){let w=Ga(e);w&&(t.name=w)}let y={user:e,assistant:n,timestamp:Date.now(),costUsd:s,durationMs:i,inputTokens:a,outputTokens:c,...o&&o.length>0?{toolEvents:o}:{}};return t.turns.push(y),y}import{readFileSync as UL,writeFileSync as $L,existsSync as qa,mkdirSync as BL,readdirSync as HL,statSync as jL,realpathSync as Sw}from"fs";import{join as kw,basename as Aw,resolve as vw,sep as WL}from"path";H();import{randomUUID as NL}from"node:crypto";var ds=class extends Error{constructor(e){super(e),this.name="SessionRegistryError"}},Lp=class{byId=new Map;byBinding=new Map;bySdk=new Map;now;constructor(e){this.now=e?.now??Date.now}create(e){let n=this.now(),r=e.id??NL();if(this.byId.has(r))throw new ds(`session handle already exists: ${r}`);let o={surface:e.surface,key:e.key,boundAt:n,lastActiveAt:n},s={id:r,surface:e.surface,model:e.model,createdAt:e.createdAt??n,lastActiveAt:n,status:"active",bindings:[o]};return e.name!==void 0&&(s.name=e.name),e.cwd!==void 0&&(s.cwd=e.cwd),e.sdkSessionId!==void 0&&(s.sdkSessionId=e.sdkSessionId),this.byId.set(r,s),this.pointBinding(this.bindingKey(o.surface,o.key),r),s.sdkSessionId!==void 0&&this.bySdk.set(s.sdkSessionId,r),this.clone(s)}load(e){if(this.byId.has(e.id))throw new ds(`session handle already exists: ${e.id}`);let n=this.clone(e);if(this.byId.set(n.id,n),n.status==="active")for(let r of n.bindings)this.pointBinding(this.bindingKey(r.surface,r.key),n.id);n.sdkSessionId!==void 0&&this.bySdk.set(n.sdkSessionId,n.id)}get(e){let n=this.byId.get(e);return n?this.clone(n):void 0}getBySdkSessionId(e){let n=this.bySdk.get(e);if(n===void 0)return;let r=this.byId.get(n);return r?this.clone(r):void 0}resolve(e,n){let r=this.byBinding.get(this.bindingKey(e,n));if(r===void 0)return;let o=this.byId.get(r);if(!(!o||o.status!=="active"))return this.clone(o)}bind(e,n){let r=this.require(e),o=this.now(),s=this.bindingKey(n.surface,n.key),i=r.bindings.find(a=>this.bindingKey(a.surface,a.key)===s);i?i.lastActiveAt=o:r.bindings.push({surface:n.surface,key:n.key,boundAt:o,lastActiveAt:o}),this.pointBinding(s,e),r.lastActiveAt=o}unbind(e,n){let r=this.bindingKey(e,n),o=this.byBinding.get(r);if(this.byBinding.delete(r),o===void 0)return;let s=this.byId.get(o);s&&(s.bindings=s.bindings.filter(i=>this.bindingKey(i.surface,i.key)!==r))}attachSdkSessionId(e,n){let r=this.require(e);r.sdkSessionId!==void 0&&r.sdkSessionId!==n&&this.bySdk.get(r.sdkSessionId)===e&&this.bySdk.delete(r.sdkSessionId),r.sdkSessionId=n,this.bySdk.set(n,e),r.lastActiveAt=this.now()}rename(e,n){let r=this.require(e);r.name=n,r.lastActiveAt=this.now()}touch(e){let n=this.require(e);n.lastActiveAt=this.now()}archive(e){let n=this.require(e);n.status="archived",n.lastActiveAt=this.now();for(let r of n.bindings){let o=this.bindingKey(r.surface,r.key);this.byBinding.get(o)===e&&this.byBinding.delete(o)}}list(e){let n=[];for(let r of this.byId.values())e?.surface!==void 0&&r.surface!==e.surface||e?.status!==void 0&&r.status!==e.status||n.push(this.clone(r));return n.sort((r,o)=>o.lastActiveAt-r.lastActiveAt),n}bindingKey(e,n){return`${e}\0${n}`}require(e){let n=this.byId.get(e);if(!n)throw new ds(`unknown session handle: ${e}`);return n}pointBinding(e,n){let r=this.byBinding.get(e);if(r!==void 0&&r!==n){let o=this.byId.get(r);o&&(o.bindings=o.bindings.filter(s=>this.bindingKey(s.surface,s.key)!==e))}this.byBinding.set(e,n)}clone(e){return{...e,bindings:e.bindings.map(n=>({...n}))}}};var mQ=new Lp;function us(){return Gb(),Oe()}function KL(t){return kw(us(),`${t}.json`)}function Np(t,{write:e=!1}={}){let n=t.includes("/")?t:KL(t),r,o;if(!e&&qa(n)?(r=Sw(n),o=Sw(us())):(r=vw(n),o=vw(us())),!r.startsWith(o+WL)&&r!==o)throw new Error(`Session path escapes sessions directory: ${t}`);return r}function Up(t,e){let n=us();qa(n)||BL(n,{recursive:!0});let r=e??t.sessionId??`session-${Date.now()}`,o={sessionId:t.sessionId,...t.name?{name:t.name}:{},...t.source?{source:t.source}:{},...t.actor?{actor:t.actor}:{},...t.telegramChatId!==void 0?{telegramChatId:t.telegramChatId}:{},...t.cwd?{cwd:t.cwd}:{},model:t.model,startedAt:t.sessionStartTime,savedAt:Date.now(),totalTurns:t.totalTurns,totalCostUsd:t.totalCostUsd,unpricedTurns:t.unpricedTurns,totalTokens:t.totalTokens,totalDurationMs:t.totalDurationMs,turns:t.turns},s=Np(r,{write:!0});return $L(s,JSON.stringify(o,null,2)),s}function Vt(t){let e;try{e=Np(t)}catch(n){console.warn(`loadSession: rejected unsafe session id ${JSON.stringify(t)}: ${n.message}`);return}if(qa(e))try{let n=UL(e,"utf-8");return JSON.parse(n)}catch(n){console.warn(`loadSession: failed to read/parse ${e}: ${n.message}`);return}}function $p(t){let e;try{e=Np(t)}catch{return}let n=Vt(e);if(n)return{path:e,id:Aw(e,".json"),data:n};let r=Dr();for(let s of r){if(s.id!==t&&s.sessionId!==t&&s.name!==t)continue;let i=Vt(s.path);if(i)return{path:s.path,id:s.id,data:i}}if(t.length>=3){let s=r.filter(i=>i.name!==void 0&&i.name.startsWith(t));if(s.length===1){let i=s[0];if(i){let a=Vt(i.path);if(a)return{path:i.path,id:i.id,data:a}}}}}function Dr(){let t=us();if(!qa(t))return[];let e=[];for(let n of HL(t)){if(!n.endsWith(".json"))continue;let r=kw(t,n);try{if(!jL(r).isFile())continue;let s=Vt(r);if(!s||typeof s.savedAt!="number"||typeof s.model!="string")continue;e.push({path:r,id:Aw(n,".json"),sessionId:s.sessionId,name:s.name,source:s.source,actor:s.actor,telegramChatId:s.telegramChatId,model:s.model,startedAt:s.startedAt,savedAt:s.savedAt,totalTurns:s.totalTurns,totalCostUsd:s.totalCostUsd,cwd:s.cwd})}catch{}}return e.sort((n,r)=>r.savedAt-n.savedAt),e}function _w(t){return t?{resume:t.resumeId,sessionId:t.resumeId,...t.stored?{resumeHistory:t.stored.turns.map(e=>({user:e.user,assistant:e.assistant}))}:{}}:{}}function GL(t){if(t===null||typeof t!="object")return{};let e=t,n=e.message_thread_id,r=e.is_topic_message;return{...typeof n=="number"?{threadId:n}:{},...r===!0?{isTopic:!0}:{}}}function de(t){let e=t.chat?.id;if(typeof e!="number")return;let n=t.message??t.editedMessage??t.callbackQuery?.message,{threadId:r,isTopic:o}=GL(n),s={chatId:e};return r!==void 0&&(s.threadId=r),o&&(s.isTopicMessage=!0),s}function Tw(t){return t.threadId===void 0||t.threadId===1}function Z(t){return Tw(t)?String(t.chatId):`${t.chatId}:${t.threadId}`}function Xa(t){return Tw(t)?{}:{message_thread_id:t.threadId}}import{promises as ps}from"fs";import{join as Ew}from"path";function ze(t){return typeof t=="number"?{chatId:t}:t}var za=class{sessions=new Map;pendingSessions=new Map;sessionData=new Map;sessionStats=new Map;autosaveFailureLogged=new Set;pendingResume=new Map;options;constructor(e){this.options={dataDir:e.dataDir||"./data/telegram-sessions",defaultModel:e.defaultModel||"medium",apiKey:e.apiKey,settingSources:e.settingSources,thinking:e.thinking,effort:e.effort,botCwd:e.botCwd,createSession:e.createSession}}getSessionIfExists(e){return this.sessions.get(Z(ze(e)))}async getSession(e){let n=ze(e),r=Z(n),o=this.sessions.get(r);if(o)return this._touchActivity(r),o;let s=this.pendingSessions.get(r);if(s)try{return await s}finally{this._touchActivity(r)}let i=this.sessionData.get(r)??this._newData(n),a=(async()=>{let c={model:i.model,apiKey:this.options.apiKey};this.options.settingSources?.length&&(c.settingSources=this.options.settingSources),this.options.thinking!==void 0&&(c.thinking=this.options.thinking),this.options.effort!==void 0&&(c.effort=this.options.effort);let l=i.cwd??this.options.botCwd;l!==void 0&&l.length>0&&(c.cwd=l);let d=this.pendingResume.get(r);if(d!==void 0){let p=Vt(d);Object.assign(c,_w({id:d,resumeId:p?.sessionId??d,stored:p}))}let u=await this.options.createSession(Fp(Cp(c)));return this.sessions.set(r,u),this.sessionData.set(r,i),d!==void 0&&this.pendingResume.delete(r),u})();this.pendingSessions.set(r,a);try{let c=await a;return this._touchActivity(r),c}finally{this.pendingSessions.delete(r)}}_newData(e){let n={chatId:e.chatId,model:this.options.defaultModel,createdAt:new Date().toISOString(),lastActivity:new Date().toISOString()};return e.threadId!==void 0&&(n.threadId=e.threadId),n}_touchActivity(e){let n=this.sessionData.get(e);n&&(n.lastActivity=new Date().toISOString())}recordTelegramTurn(e,n,r,o){let s=ze(e),i=Z(s),a=this._getOrCreateStats(s),c=this.sessions.get(i);!a.sessionId&&c?.sessionId&&(a.sessionId=c.sessionId),ww(a,n,r,o),!a.sessionId&&c?.sessionId&&(a.sessionId=c.sessionId);let l=this.sessionData.get(i);if(l&&a.sessionId&&(l.sessionId=a.sessionId),a.sessionId)try{Up(a)}catch(d){this.autosaveFailureLogged.has(i)||(this.autosaveFailureLogged.add(i),console.error(`[session-manager] autosave failed for chat ${s.chatId} \u2014 conversation may not be resumable:`,d))}}_hydrateStatsFromStore(e){let n=Z(e);if(this.sessionStats.has(n))return;let r=this.sessionData.get(n)?.sessionId;if(!r)return;let o=Vt(r);if(!o||o.source!=="telegram"||o.telegramChatId!==e.chatId)return;let s={sessionId:o.sessionId,name:o.name,model:o.model,source:o.source,telegramChatId:o.telegramChatId,sessionStartTime:o.startedAt,totalTurns:o.totalTurns,totalCostUsd:o.totalCostUsd,unpricedTurns:o.unpricedTurns??0,totalTokens:o.totalTokens,totalDurationMs:o.totalDurationMs,turns:o.turns,turnCosts:[],turnTokens:[],permissionMode:"default"},i=this.sessionData.get(n)?.cwd;i!==void 0&&(s.cwd=i),this.sessionStats.set(n,s)}getSessionName(e){let n=ze(e);return this._hydrateStatsFromStore(n),this.sessionStats.get(Z(n))?.name}setSessionName(e,n){let r=ze(e),o=Z(r),s=this._getOrCreateStats(r);s.name=n;let i=this.sessions.get(o);if(!s.sessionId&&i?.sessionId&&(s.sessionId=i.sessionId),s.totalTurns>0&&s.sessionId){let a=this.sessionData.get(o);return a&&(a.sessionId=s.sessionId),Up(s),{persisted:!0}}return{persisted:!1}}_getOrCreateStats(e){let n=Z(e);this._hydrateStatsFromStore(e);let r=this.sessionStats.get(n);if(!r){r=bw(this.getModel(e)),r.source="telegram",r.telegramChatId=e.chatId;let o=this.getCwd(e);o&&(r.cwd=o),this.sessionStats.set(n,r)}return r}_resetStats(e){this.sessionStats.delete(e),this.autosaveFailureLogged.delete(e),this.pendingResume.delete(e);let n=this.sessionData.get(e);n&&delete n.sessionId}async resetSession(e){let n=Z(ze(e)),r=this.sessions.get(n);r&&(await r.close(),this.sessions.delete(n)),this._resetStats(n);let o=this.sessionData.get(n);o&&(o.lastActivity=new Date().toISOString())}async switchModel(e,n){let r=ze(e),o=Z(r),s=this.sessions.get(o);s&&(await s.close(),this.sessions.delete(o)),this._resetStats(o);let i=this.sessionData.get(o);i?(i.model=n,i.lastActivity=new Date().toISOString()):(i=this._newData(r),i.model=n,this.sessionData.set(o,i))}getModel(e){return this.sessionData.get(Z(ze(e)))?.model||this.options.defaultModel}async setCwd(e,n){let r=ze(e),o=Z(r),s=this.sessions.get(o);s&&(await s.close(),this.sessions.delete(o)),this._resetStats(o);let i=this.sessionData.get(o);i?(i.cwd=n,i.lastActivity=new Date().toISOString()):(i=this._newData(r),i.cwd=n,this.sessionData.set(o,i))}getCwd(e){return this.sessionData.get(Z(ze(e)))?.cwd??this.options.botCwd}listChatSessions(e){let n=ze(e),r=this.sessionData.get(Z(n))?.sessionId;return Dr().filter(o=>o.source==="telegram"&&o.telegramChatId===n.chatId&&o.sessionId!==void 0).map(o=>{let s={sessionId:o.sessionId,model:o.model,turns:o.totalTurns,lastActive:o.savedAt,active:o.sessionId===r};return o.name!==void 0&&(s.name=o.name),s}).sort((o,s)=>s.lastActive-o.lastActive)}async switchToSession(e,n){let r=ze(e),o=Z(r),s=this.pendingSessions.get(o);if(s!==void 0&&await s.catch(()=>{}),this.sessions.has(o)&&this.sessionData.get(o)?.sessionId===n)return{ok:!1,reason:"already-active"};let i=Vt(n);if(!i||i.source!=="telegram"||i.telegramChatId!==r.chatId)return{ok:!1,reason:"not-found"};let a=this.sessions.get(o);a&&(await a.close().catch(l=>console.error("Error closing session on switch:",l)),this.sessions.delete(o)),this.sessionStats.delete(o),this.autosaveFailureLogged.delete(o);let c=this.sessionData.get(o);return c?(c.model=i.model,c.lastActivity=new Date().toISOString()):(c=this._newData(r),c.model=i.model,this.sessionData.set(o,c)),c.sessionId=n,i.cwd!==void 0?c.cwd=i.cwd:delete c.cwd,this.pendingResume.set(o,n),i.name!==void 0?{ok:!0,name:i.name}:{ok:!0}}async newSession(e){this.pendingResume.delete(Z(ze(e))),await this.resetSession(e)}sidecarFileName(e){let n={chatId:e.chatId};return e.threadId!==void 0&&(n.threadId=e.threadId),`${Z(n)}.json`}async loadSessions(){try{await ps.mkdir(this.options.dataDir,{recursive:!0});let e=await ps.readdir(this.options.dataDir);for(let n of e)if(n.endsWith(".json")){let r=Ew(this.options.dataDir,n),o=await ps.readFile(r,"utf-8"),s=JSON.parse(o),i={chatId:s.chatId};s.threadId!==void 0&&(i.threadId=s.threadId),this.sessionData.set(Z(i),s)}}catch(e){e.code!=="ENOENT"&&console.error("Failed to load sessions:",e)}}async saveSessions(){try{await ps.mkdir(this.options.dataDir,{recursive:!0});for(let e of this.sessionData.values()){let n=Ew(this.options.dataDir,this.sidecarFileName(e));await ps.writeFile(n,JSON.stringify(e,null,2))}}catch(e){console.error("Failed to save sessions:",e)}}async closeAll(){await this.saveSessions();let e=Array.from(this.sessions.values()).map(n=>n.close().catch(r=>console.error("Error closing session:",r)));await Promise.all(e),this.sessions.clear()}getSessionCount(){return this.sessions.size}getChatCount(){return this.sessionData.size}getBusySessionCount(){let e=0;for(let n of this.sessions.values())n.state!=="idle"&&n.state!=="closed"&&e++;return e}};Je();Je();async function jp(t){await t.reply(Iw())}Je();async function Wp(t,e){let n=de(t),r,o=n?e.getSessionIfExists(n):void 0;if(o)try{await Promise.race([o.waitForInitialization(),new Promise((i,a)=>setTimeout(()=>a(new Error("timeout")),2e3))]);let s=o.getSessionMetadata();s.slashCommands?.length&&(r=s.slashCommands)}catch{}await t.reply(Rw(r))}ue();import{Markup as ZO}from"telegraf";import{promises as H4}from"fs";import{homedir as e0}from"os";import{isAbsolute as j4,resolve as jy}from"path";async function fs(t,e){t.sendChatAction("typing").catch(()=>{});let n=setInterval(()=>{t.sendChatAction("typing").catch(()=>{})},4e3);try{return await e()}finally{clearInterval(n)}}Je();be();De();xe();mi();Ir();function $4(t,e){try{if(!t||t.trim().toLowerCase()==="auto")return{available:!0,needs:"unknown"};let n=Xn(t,e);if(n.id==="")return{available:!1,needs:"local",hint:"not configured (set AFK_MODEL_LOCAL / models.local)"};if(n.provider==="chatgpt-oauth"){let o=In(void 0,{},!0).apiKey!=null;return{available:o,needs:"chatgpt-oauth",hint:o?void 0:"needs ChatGPT sign-in (~/.codex/auth.json)"}}if(n.provider==="xai-oauth"){let o=mt(void 0,"oauth").apiKey!=null;return{available:o,needs:"xai-oauth",hint:o?void 0:"needs SuperGrok OAuth (`afk provider auth xai login`)"}}if(n.provider==="xai"){let o=mt(n.apiKey,"apikey").apiKey!=null;return{available:o,needs:"xai",hint:o?void 0:"needs XAI_API_KEY"}}if(n.apiKey)return{available:!0,needs:"unknown"};let r=X(t,e?{slots:e}:void 0);if(r==="anthropic-direct"){let o=!!Hs();return{available:o,needs:"anthropic",hint:o?void 0:"needs Claude sign-in / ANTHROPIC_API_KEY"}}if(r==="openai-compatible"){if(n.baseUrl)return{available:!0,needs:"local"};let o=!!$c()||In(void 0,{},!1).apiKey!=null;return{available:o,needs:"openai",hint:o?void 0:"needs OPENAI_API_KEY"}}if(r==="xai"||r==="xai-oauth"){let i=mt(void 0,r==="xai-oauth"?"oauth":void 0).apiKey!=null;return{available:i,needs:r==="xai-oauth"?"xai-oauth":"xai",hint:i?void 0:"needs XAI_API_KEY or SuperGrok OAuth (`afk provider auth xai login`)"}}return{available:!0,needs:"unknown"}}catch{return{available:!0,needs:"unknown"}}}function VO(t,e){return $4(t,e).available}De();var B4=/^[A-Za-z0-9_@%+=:,./-]+$/;function JO(t){return B4.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}function YO(t,e){let n=["afk","interactive"];return typeof e=="string"&&e.length>0&&n.push("--model",JO(e)),n.push("--resume",JO(t)),n.join(" ")}be();De();function QO(t){if(qn.includes(t)||$r(t)!==void 0)return!0;let e=X(t);if(e==="openai-compatible"||e==="xai"||e==="xai-oauth")return!0;let n=Xn(t).id.trim().toLowerCase();return n.startsWith("claude-")||n.startsWith("claude_")}async function Wy(t,e,n,r){let o=de(t);if(!o){await t.reply(q("Could not identify chat"));return}try{await e.resetSession(o),n.delete(o.chatId),await t.reply(Qa())}catch(s){r("Clear error:",s),await t.reply(q(s))}}async function t0(t,e,n){let r=de(t);if(!r){await t.reply(q("Could not identify chat"));return}try{let o=await e.getSession(r),s=o.hookRegistry,i=await fs(t,async()=>(s&&await s.dispatch({event:"PreCompact",sessionId:o.sessionId,trigger:"manual"}),o.compact()));i.compacted?await t.reply(Za({before:i.messagesBefore,after:i.messagesAfter,...i.tokensSavedEstimate!==void 0?{tokensSavedEstimate:i.tokensSavedEstimate}:{}})):await t.reply(ec(i.reason??"unknown"))}catch(o){o instanceof ee?await t.reply(`Compaction skipped: ${Ve(o.reason??"blocked by hook")}`):(n("Compact error:",o),await t.reply(q(o)))}}async function Ky(t,e,n){let r=de(t);if(!r){await t.reply(q("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1);if(s.length===0){let l=e.getModel(r),d=qn.map(u=>[ZO.button.callback(VO(u)?u:`${u} \u2014 needs sign-in`,`afk:m:${u}`)]);await t.reply(`Current model: <b>${Ve(l.toUpperCase())}</b>
1209
+ ${o}`}}}return{...t,systemPrompt:o}}function Ga(t){let e=t.toLowerCase().replace(/[`*_~]/g," ").replace(/[^\w\s-]/g," ").replace(/[\s_]+/g," ").trim();return e?e.split(" ").filter(Boolean).slice(0,6).join("-").slice(0,48).replace(/-+$/g,""):""}function bw(t){return{totalTurns:0,totalCostUsd:0,unpricedTurns:0,totalTokens:0,totalDurationMs:0,sessionStartTime:Date.now(),turnCosts:[],turnTokens:[],turns:[],model:t,permissionMode:"default",thinkingUi:"live"}}function ww(t,e,n,r,o){let s=r?.totalCostUsd,i=s??0,a=r?.durationMs??0,c=Number(r?.usage?.input_tokens??0),l=Number(r?.usage?.output_tokens??0),d=c,u=l,p=Number(r?.usage?.cache_read_input_tokens??0)+Number(r?.usage?.cache_creation_input_tokens??0),f=r?.usage?.iterations;if(Array.isArray(f)&&f.length>0){let A=f[f.length-1];if(A&&typeof A=="object"){let _=A;d=Number(_.input_tokens??0),u=Number(_.output_tokens??0),p=Number(_.cache_read_input_tokens??0)+Number(_.cache_creation_input_tokens??0)}}t.totalTurns+=1,t.totalCostUsd+=i,s===void 0&&(t.unpricedTurns+=1),t.totalDurationMs+=a,t.totalTokens+=c+l,t.turnCosts.push(i);let m=Number(r?.usage?.context_window_tokens??NaN),h=Array.isArray(f)&&f.length>0,y=Number.isFinite(m)?m:h?d+u+p:void 0;if(t.turnTokens.push({input:d,output:u,cache:p,...y!==void 0?{footprint:y}:{}}),r?.sessionId&&!t.sessionId&&(t.sessionId=String(r.sessionId)),!t.name){let A=Ga(e);A&&(t.name=A)}let w={user:e,assistant:n,timestamp:Date.now(),costUsd:i,durationMs:a,inputTokens:c,outputTokens:l,...o&&o.length>0?{toolEvents:o}:{}};return t.turns.push(w),w}import{readFileSync as UL,writeFileSync as $L,existsSync as qa,mkdirSync as BL,readdirSync as HL,statSync as jL,realpathSync as Sw}from"fs";import{join as kw,basename as Aw,resolve as vw,sep as WL}from"path";H();import{randomUUID as NL}from"node:crypto";var ds=class extends Error{constructor(e){super(e),this.name="SessionRegistryError"}},Lp=class{byId=new Map;byBinding=new Map;bySdk=new Map;now;constructor(e){this.now=e?.now??Date.now}create(e){let n=this.now(),r=e.id??NL();if(this.byId.has(r))throw new ds(`session handle already exists: ${r}`);let o={surface:e.surface,key:e.key,boundAt:n,lastActiveAt:n},s={id:r,surface:e.surface,model:e.model,createdAt:e.createdAt??n,lastActiveAt:n,status:"active",bindings:[o]};return e.name!==void 0&&(s.name=e.name),e.cwd!==void 0&&(s.cwd=e.cwd),e.sdkSessionId!==void 0&&(s.sdkSessionId=e.sdkSessionId),this.byId.set(r,s),this.pointBinding(this.bindingKey(o.surface,o.key),r),s.sdkSessionId!==void 0&&this.bySdk.set(s.sdkSessionId,r),this.clone(s)}load(e){if(this.byId.has(e.id))throw new ds(`session handle already exists: ${e.id}`);let n=this.clone(e);if(this.byId.set(n.id,n),n.status==="active")for(let r of n.bindings)this.pointBinding(this.bindingKey(r.surface,r.key),n.id);n.sdkSessionId!==void 0&&this.bySdk.set(n.sdkSessionId,n.id)}get(e){let n=this.byId.get(e);return n?this.clone(n):void 0}getBySdkSessionId(e){let n=this.bySdk.get(e);if(n===void 0)return;let r=this.byId.get(n);return r?this.clone(r):void 0}resolve(e,n){let r=this.byBinding.get(this.bindingKey(e,n));if(r===void 0)return;let o=this.byId.get(r);if(!(!o||o.status!=="active"))return this.clone(o)}bind(e,n){let r=this.require(e),o=this.now(),s=this.bindingKey(n.surface,n.key),i=r.bindings.find(a=>this.bindingKey(a.surface,a.key)===s);i?i.lastActiveAt=o:r.bindings.push({surface:n.surface,key:n.key,boundAt:o,lastActiveAt:o}),this.pointBinding(s,e),r.lastActiveAt=o}unbind(e,n){let r=this.bindingKey(e,n),o=this.byBinding.get(r);if(this.byBinding.delete(r),o===void 0)return;let s=this.byId.get(o);s&&(s.bindings=s.bindings.filter(i=>this.bindingKey(i.surface,i.key)!==r))}attachSdkSessionId(e,n){let r=this.require(e);r.sdkSessionId!==void 0&&r.sdkSessionId!==n&&this.bySdk.get(r.sdkSessionId)===e&&this.bySdk.delete(r.sdkSessionId),r.sdkSessionId=n,this.bySdk.set(n,e),r.lastActiveAt=this.now()}rename(e,n){let r=this.require(e);r.name=n,r.lastActiveAt=this.now()}touch(e){let n=this.require(e);n.lastActiveAt=this.now()}archive(e){let n=this.require(e);n.status="archived",n.lastActiveAt=this.now();for(let r of n.bindings){let o=this.bindingKey(r.surface,r.key);this.byBinding.get(o)===e&&this.byBinding.delete(o)}}list(e){let n=[];for(let r of this.byId.values())e?.surface!==void 0&&r.surface!==e.surface||e?.status!==void 0&&r.status!==e.status||n.push(this.clone(r));return n.sort((r,o)=>o.lastActiveAt-r.lastActiveAt),n}bindingKey(e,n){return`${e}\0${n}`}require(e){let n=this.byId.get(e);if(!n)throw new ds(`unknown session handle: ${e}`);return n}pointBinding(e,n){let r=this.byBinding.get(e);if(r!==void 0&&r!==n){let o=this.byId.get(r);o&&(o.bindings=o.bindings.filter(s=>this.bindingKey(s.surface,s.key)!==e))}this.byBinding.set(e,n)}clone(e){return{...e,bindings:e.bindings.map(n=>({...n}))}}};var mQ=new Lp;function us(){return Gb(),Oe()}function KL(t){return kw(us(),`${t}.json`)}function Np(t,{write:e=!1}={}){let n=t.includes("/")?t:KL(t),r,o;if(!e&&qa(n)?(r=Sw(n),o=Sw(us())):(r=vw(n),o=vw(us())),!r.startsWith(o+WL)&&r!==o)throw new Error(`Session path escapes sessions directory: ${t}`);return r}function Up(t,e){let n=us();qa(n)||BL(n,{recursive:!0});let r=e??t.sessionId??`session-${Date.now()}`,o={sessionId:t.sessionId,...t.name?{name:t.name}:{},...t.source?{source:t.source}:{},...t.actor?{actor:t.actor}:{},...t.telegramChatId!==void 0?{telegramChatId:t.telegramChatId}:{},...t.cwd?{cwd:t.cwd}:{},model:t.model,startedAt:t.sessionStartTime,savedAt:Date.now(),totalTurns:t.totalTurns,totalCostUsd:t.totalCostUsd,unpricedTurns:t.unpricedTurns,totalTokens:t.totalTokens,totalDurationMs:t.totalDurationMs,turns:t.turns},s=Np(r,{write:!0});return $L(s,JSON.stringify(o,null,2)),s}function Vt(t){let e;try{e=Np(t)}catch(n){console.warn(`loadSession: rejected unsafe session id ${JSON.stringify(t)}: ${n.message}`);return}if(qa(e))try{let n=UL(e,"utf-8");return JSON.parse(n)}catch(n){console.warn(`loadSession: failed to read/parse ${e}: ${n.message}`);return}}function $p(t){let e;try{e=Np(t)}catch{return}let n=Vt(e);if(n)return{path:e,id:Aw(e,".json"),data:n};let r=Dr();for(let s of r){if(s.id!==t&&s.sessionId!==t&&s.name!==t)continue;let i=Vt(s.path);if(i)return{path:s.path,id:s.id,data:i}}if(t.length>=3){let s=r.filter(i=>i.name!==void 0&&i.name.startsWith(t));if(s.length===1){let i=s[0];if(i){let a=Vt(i.path);if(a)return{path:i.path,id:i.id,data:a}}}}}function Dr(){let t=us();if(!qa(t))return[];let e=[];for(let n of HL(t)){if(!n.endsWith(".json"))continue;let r=kw(t,n);try{if(!jL(r).isFile())continue;let s=Vt(r);if(!s||typeof s.savedAt!="number"||typeof s.model!="string")continue;e.push({path:r,id:Aw(n,".json"),sessionId:s.sessionId,name:s.name,source:s.source,actor:s.actor,telegramChatId:s.telegramChatId,model:s.model,startedAt:s.startedAt,savedAt:s.savedAt,totalTurns:s.totalTurns,totalCostUsd:s.totalCostUsd,cwd:s.cwd})}catch{}}return e.sort((n,r)=>r.savedAt-n.savedAt),e}function _w(t){return t?{resume:t.resumeId,sessionId:t.resumeId,...t.stored?{resumeHistory:t.stored.turns.map(e=>({user:e.user,assistant:e.assistant}))}:{}}:{}}function GL(t){if(t===null||typeof t!="object")return{};let e=t,n=e.message_thread_id,r=e.is_topic_message;return{...typeof n=="number"?{threadId:n}:{},...r===!0?{isTopic:!0}:{}}}function de(t){let e=t.chat?.id;if(typeof e!="number")return;let n=t.message??t.editedMessage??t.callbackQuery?.message,{threadId:r,isTopic:o}=GL(n),s={chatId:e};return r!==void 0&&(s.threadId=r),o&&(s.isTopicMessage=!0),s}function Tw(t){return t.threadId===void 0||t.threadId===1}function Z(t){return Tw(t)?String(t.chatId):`${t.chatId}:${t.threadId}`}function Xa(t){return Tw(t)?{}:{message_thread_id:t.threadId}}import{promises as ps}from"fs";import{join as Ew}from"path";function ze(t){return typeof t=="number"?{chatId:t}:t}var za=class{sessions=new Map;pendingSessions=new Map;sessionData=new Map;sessionStats=new Map;autosaveFailureLogged=new Set;pendingResume=new Map;options;constructor(e){this.options={dataDir:e.dataDir||"./data/telegram-sessions",defaultModel:e.defaultModel||"medium",apiKey:e.apiKey,settingSources:e.settingSources,thinking:e.thinking,effort:e.effort,botCwd:e.botCwd,createSession:e.createSession}}getSessionIfExists(e){return this.sessions.get(Z(ze(e)))}async getSession(e){let n=ze(e),r=Z(n),o=this.sessions.get(r);if(o)return this._touchActivity(r),o;let s=this.pendingSessions.get(r);if(s)try{return await s}finally{this._touchActivity(r)}let i=this.sessionData.get(r)??this._newData(n),a=(async()=>{let c={model:i.model,apiKey:this.options.apiKey};this.options.settingSources?.length&&(c.settingSources=this.options.settingSources),this.options.thinking!==void 0&&(c.thinking=this.options.thinking),this.options.effort!==void 0&&(c.effort=this.options.effort);let l=i.cwd??this.options.botCwd;l!==void 0&&l.length>0&&(c.cwd=l);let d=this.pendingResume.get(r);if(d!==void 0){let p=Vt(d);Object.assign(c,_w({id:d,resumeId:p?.sessionId??d,stored:p}))}let u=await this.options.createSession(Fp(Cp(c)));return this.sessions.set(r,u),this.sessionData.set(r,i),d!==void 0&&this.pendingResume.delete(r),u})();this.pendingSessions.set(r,a);try{let c=await a;return this._touchActivity(r),c}finally{this.pendingSessions.delete(r)}}_newData(e){let n={chatId:e.chatId,model:this.options.defaultModel,createdAt:new Date().toISOString(),lastActivity:new Date().toISOString()};return e.threadId!==void 0&&(n.threadId=e.threadId),n}_touchActivity(e){let n=this.sessionData.get(e);n&&(n.lastActivity=new Date().toISOString())}recordTelegramTurn(e,n,r,o){let s=ze(e),i=Z(s),a=this._getOrCreateStats(s),c=this.sessions.get(i);!a.sessionId&&c?.sessionId&&(a.sessionId=c.sessionId),ww(a,n,r,o),!a.sessionId&&c?.sessionId&&(a.sessionId=c.sessionId);let l=this.sessionData.get(i);if(l&&a.sessionId&&(l.sessionId=a.sessionId),a.sessionId)try{Up(a)}catch(d){this.autosaveFailureLogged.has(i)||(this.autosaveFailureLogged.add(i),console.error(`[session-manager] autosave failed for chat ${s.chatId} \u2014 conversation may not be resumable:`,d))}}_hydrateStatsFromStore(e){let n=Z(e);if(this.sessionStats.has(n))return;let r=this.sessionData.get(n)?.sessionId;if(!r)return;let o=Vt(r);if(!o||o.source!=="telegram"||o.telegramChatId!==e.chatId)return;let s={sessionId:o.sessionId,name:o.name,model:o.model,source:o.source,telegramChatId:o.telegramChatId,sessionStartTime:o.startedAt,totalTurns:o.totalTurns,totalCostUsd:o.totalCostUsd,unpricedTurns:o.unpricedTurns??0,totalTokens:o.totalTokens,totalDurationMs:o.totalDurationMs,turns:o.turns,turnCosts:[],turnTokens:[],permissionMode:"default"},i=this.sessionData.get(n)?.cwd;i!==void 0&&(s.cwd=i),this.sessionStats.set(n,s)}getSessionName(e){let n=ze(e);return this._hydrateStatsFromStore(n),this.sessionStats.get(Z(n))?.name}setSessionName(e,n){let r=ze(e),o=Z(r),s=this._getOrCreateStats(r);s.name=n;let i=this.sessions.get(o);if(!s.sessionId&&i?.sessionId&&(s.sessionId=i.sessionId),s.totalTurns>0&&s.sessionId){let a=this.sessionData.get(o);return a&&(a.sessionId=s.sessionId),Up(s),{persisted:!0}}return{persisted:!1}}_getOrCreateStats(e){let n=Z(e);this._hydrateStatsFromStore(e);let r=this.sessionStats.get(n);if(!r){r=bw(this.getModel(e)),r.source="telegram",r.telegramChatId=e.chatId;let o=this.getCwd(e);o&&(r.cwd=o),this.sessionStats.set(n,r)}return r}_resetStats(e){this.sessionStats.delete(e),this.autosaveFailureLogged.delete(e),this.pendingResume.delete(e);let n=this.sessionData.get(e);n&&delete n.sessionId}async resetSession(e){let n=Z(ze(e)),r=this.sessions.get(n);r&&(await r.close(),this.sessions.delete(n)),this._resetStats(n);let o=this.sessionData.get(n);o&&(o.lastActivity=new Date().toISOString())}async switchModel(e,n){let r=ze(e),o=Z(r),s=this.sessions.get(o);s&&(await s.close(),this.sessions.delete(o)),this._resetStats(o);let i=this.sessionData.get(o);i?(i.model=n,i.lastActivity=new Date().toISOString()):(i=this._newData(r),i.model=n,this.sessionData.set(o,i))}getModel(e){return this.sessionData.get(Z(ze(e)))?.model||this.options.defaultModel}async setCwd(e,n){let r=ze(e),o=Z(r),s=this.sessions.get(o);s&&(await s.close(),this.sessions.delete(o)),this._resetStats(o);let i=this.sessionData.get(o);i?(i.cwd=n,i.lastActivity=new Date().toISOString()):(i=this._newData(r),i.cwd=n,this.sessionData.set(o,i))}getCwd(e){return this.sessionData.get(Z(ze(e)))?.cwd??this.options.botCwd}listChatSessions(e){let n=ze(e),r=this.sessionData.get(Z(n))?.sessionId;return Dr().filter(o=>o.source==="telegram"&&o.telegramChatId===n.chatId&&o.sessionId!==void 0).map(o=>{let s={sessionId:o.sessionId,model:o.model,turns:o.totalTurns,lastActive:o.savedAt,active:o.sessionId===r};return o.name!==void 0&&(s.name=o.name),s}).sort((o,s)=>s.lastActive-o.lastActive)}async switchToSession(e,n){let r=ze(e),o=Z(r),s=this.pendingSessions.get(o);if(s!==void 0&&await s.catch(()=>{}),this.sessions.has(o)&&this.sessionData.get(o)?.sessionId===n)return{ok:!1,reason:"already-active"};let i=Vt(n);if(!i||i.source!=="telegram"||i.telegramChatId!==r.chatId)return{ok:!1,reason:"not-found"};let a=this.sessions.get(o);a&&(await a.close().catch(l=>console.error("Error closing session on switch:",l)),this.sessions.delete(o)),this.sessionStats.delete(o),this.autosaveFailureLogged.delete(o);let c=this.sessionData.get(o);return c?(c.model=i.model,c.lastActivity=new Date().toISOString()):(c=this._newData(r),c.model=i.model,this.sessionData.set(o,c)),c.sessionId=n,i.cwd!==void 0?c.cwd=i.cwd:delete c.cwd,this.pendingResume.set(o,n),i.name!==void 0?{ok:!0,name:i.name}:{ok:!0}}async newSession(e){this.pendingResume.delete(Z(ze(e))),await this.resetSession(e)}sidecarFileName(e){let n={chatId:e.chatId};return e.threadId!==void 0&&(n.threadId=e.threadId),`${Z(n)}.json`}async loadSessions(){try{await ps.mkdir(this.options.dataDir,{recursive:!0});let e=await ps.readdir(this.options.dataDir);for(let n of e)if(n.endsWith(".json")){let r=Ew(this.options.dataDir,n),o=await ps.readFile(r,"utf-8"),s=JSON.parse(o),i={chatId:s.chatId};s.threadId!==void 0&&(i.threadId=s.threadId),this.sessionData.set(Z(i),s)}}catch(e){e.code!=="ENOENT"&&console.error("Failed to load sessions:",e)}}async saveSessions(){try{await ps.mkdir(this.options.dataDir,{recursive:!0});for(let e of this.sessionData.values()){let n=Ew(this.options.dataDir,this.sidecarFileName(e));await ps.writeFile(n,JSON.stringify(e,null,2))}}catch(e){console.error("Failed to save sessions:",e)}}async closeAll(){await this.saveSessions();let e=Array.from(this.sessions.values()).map(n=>n.close().catch(r=>console.error("Error closing session:",r)));await Promise.all(e),this.sessions.clear()}getSessionCount(){return this.sessions.size}getChatCount(){return this.sessionData.size}getBusySessionCount(){let e=0;for(let n of this.sessions.values())n.state!=="idle"&&n.state!=="closed"&&e++;return e}};Je();Je();async function jp(t){await t.reply(Iw())}Je();async function Wp(t,e){let n=de(t),r,o=n?e.getSessionIfExists(n):void 0;if(o)try{await Promise.race([o.waitForInitialization(),new Promise((i,a)=>setTimeout(()=>a(new Error("timeout")),2e3))]);let s=o.getSessionMetadata();s.slashCommands?.length&&(r=s.slashCommands)}catch{}await t.reply(Rw(r))}ue();import{Markup as ZO}from"telegraf";import{promises as H4}from"fs";import{homedir as e0}from"os";import{isAbsolute as j4,resolve as jy}from"path";async function fs(t,e){t.sendChatAction("typing").catch(()=>{});let n=setInterval(()=>{t.sendChatAction("typing").catch(()=>{})},4e3);try{return await e()}finally{clearInterval(n)}}Je();be();De();xe();mi();Ir();function $4(t,e){try{if(!t||t.trim().toLowerCase()==="auto")return{available:!0,needs:"unknown"};let n=Xn(t,e);if(n.id==="")return{available:!1,needs:"local",hint:"not configured (set AFK_MODEL_LOCAL / models.local)"};if(n.provider==="chatgpt-oauth"){let o=In(void 0,{},!0).apiKey!=null;return{available:o,needs:"chatgpt-oauth",hint:o?void 0:"needs ChatGPT sign-in (~/.codex/auth.json)"}}if(n.provider==="xai-oauth"){let o=mt(void 0,"oauth").apiKey!=null;return{available:o,needs:"xai-oauth",hint:o?void 0:"needs SuperGrok OAuth (`afk provider auth xai login`)"}}if(n.provider==="xai"){let o=mt(n.apiKey,"apikey").apiKey!=null;return{available:o,needs:"xai",hint:o?void 0:"needs XAI_API_KEY"}}if(n.apiKey)return{available:!0,needs:"unknown"};let r=X(t,e?{slots:e}:void 0);if(r==="anthropic-direct"){let o=!!Hs();return{available:o,needs:"anthropic",hint:o?void 0:"needs Claude sign-in / ANTHROPIC_API_KEY"}}if(r==="openai-compatible"){if(n.baseUrl)return{available:!0,needs:"local"};let o=!!$c()||In(void 0,{},!1).apiKey!=null;return{available:o,needs:"openai",hint:o?void 0:"needs OPENAI_API_KEY"}}if(r==="xai"||r==="xai-oauth"){let i=mt(void 0,r==="xai-oauth"?"oauth":void 0).apiKey!=null;return{available:i,needs:r==="xai-oauth"?"xai-oauth":"xai",hint:i?void 0:"needs XAI_API_KEY or SuperGrok OAuth (`afk provider auth xai login`)"}}return{available:!0,needs:"unknown"}}catch{return{available:!0,needs:"unknown"}}}function VO(t,e){return $4(t,e).available}De();var B4=/^[A-Za-z0-9_@%+=:,./-]+$/;function JO(t){return B4.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}function YO(t,e){let n=["afk","interactive"];return typeof e=="string"&&e.length>0&&n.push("--model",JO(e)),n.push("--resume",JO(t)),n.join(" ")}be();De();function QO(t){if(qn.includes(t)||$r(t)!==void 0)return!0;let e=X(t);if(e==="openai-compatible"||e==="xai"||e==="xai-oauth")return!0;let n=Xn(t).id.trim().toLowerCase();return n.startsWith("claude-")||n.startsWith("claude_")}async function Wy(t,e,n,r){let o=de(t);if(!o){await t.reply(q("Could not identify chat"));return}try{await e.resetSession(o),n.delete(o.chatId),await t.reply(Qa())}catch(s){r("Clear error:",s),await t.reply(q(s))}}async function t0(t,e,n){let r=de(t);if(!r){await t.reply(q("Could not identify chat"));return}try{let o=await e.getSession(r),s=o.hookRegistry,i=await fs(t,async()=>(s&&await s.dispatch({event:"PreCompact",sessionId:o.sessionId,trigger:"manual"}),o.compact()));i.compacted?await t.reply(Za({before:i.messagesBefore,after:i.messagesAfter,...i.tokensSavedEstimate!==void 0?{tokensSavedEstimate:i.tokensSavedEstimate}:{}})):await t.reply(ec(i.reason??"unknown"))}catch(o){o instanceof ee?await t.reply(`Compaction skipped: ${Ve(o.reason??"blocked by hook")}`):(n("Compact error:",o),await t.reply(q(o)))}}async function Ky(t,e,n){let r=de(t);if(!r){await t.reply(q("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1);if(s.length===0){let l=e.getModel(r),d=qn.map(u=>[ZO.button.callback(VO(u)?u:`${u} \u2014 needs sign-in`,`afk:m:${u}`)]);await t.reply(`Current model: <b>${Ve(l.toUpperCase())}</b>
1210
1210
 
1211
1211
  Switch to:`,{parse_mode:"HTML",reply_markup:ZO.inlineKeyboard(d).reply_markup});return}let i=s[0];if(!i){await t.reply(q("Please specify a model: local, small, medium, large, opus, sonnet, haiku, or an org/model id"));return}let a=i.toLowerCase();if(!QO(a)){await t.reply(q(`Invalid model: ${i}
1212
1212
  Aliases: ${qn.join(", ")}, or a full model id`));return}let c=Vw(a);if(c){await t.reply(q(c));return}try{await e.switchModel(r,a),await t.reply(Ya(a))}catch(l){n("Model switch error:",l),await t.reply(q(l))}}function W4(t,e){let n=t.trim();return n==="~"?e0():n.startsWith("~/")?jy(e0(),n.slice(2)):j4(n)?jy(n):jy(e,n)}async function n0(t,e,n){let r=de(t);if(!r){await t.reply(q("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1).filter(l=>l.length>0);if(s.length===0){let l=e.getCwd(r);await t.reply(Cw(l));return}let i=s[0];if(!i){await t.reply(q("Please specify a directory path"));return}let a=e.getCwd(r)??process.cwd(),c=W4(i,a);try{if(!(await H4.stat(c)).isDirectory()){await t.reply(q(`Not a directory: ${c}`));return}}catch(l){let d=l.code;d==="ENOENT"?await t.reply(Bp("ENOENT",c)):d==="EACCES"?await t.reply(Bp("EACCES",c)):(n("cwd stat error:",l),await t.reply(q(l)));return}try{await e.setCwd(r,c),await t.reply(Pw(c))}catch(l){n("Cwd switch error:",l),await t.reply(q(l))}}async function r0(t,e,n){let r=de(t);if(!r){await t.reply(q("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1).join(" ").trim();if(!s){await t.reply(Mw(e.getSessionName(r)));return}let i=Ga(s);if(!i){await t.reply(Ow());return}try{let{persisted:a}=e.setSessionName(r,i),c=a?YO(i,e.getModel(r)):void 0;await t.reply(Dw(i,c))}catch(a){n("Name set error:",a),await t.reply(`\u{1F3F7}\uFE0F Named "${i}" but couldn't save it \u2014 it'll retry on your next message.`)}}import{Markup as o0}from"telegraf";Je();var Hu="afk:sw:",K4=64;function G4(t){let e=t.callbackQuery;return typeof e=="object"&&e!==null&&"data"in e?e.data:""}function s0(t,e){let n=t.getSessionIfExists(e);return n!==void 0&&n.state!=="idle"}async function i0(t,e,n){let r=de(t);if(!r){await t.reply(q("Could not identify chat"));return}let o=e.listChatSessions(r);if(o.length===0){await t.reply(Nw());return}let s=o.filter(i=>(Hu+i.sessionId).length<=K4).map(i=>[o0.button.callback(`${i.active?"\u2705 ":""}${i.name??"(unnamed)"} \xB7 ${i.turns} turns`,`${Hu}${i.sessionId}`)]);await t.reply(Lw(o),{parse_mode:"HTML",reply_markup:o0.inlineKeyboard(s).reply_markup})}async function a0(t,e,n,r){let o=de(t);if(!o){await t.reply(q("Could not identify chat"));return}if(s0(e,o)){await t.reply(Hp());return}try{await e.newSession(o),n.delete(o.chatId),await t.reply($w())}catch(s){r("New session error:",s),await t.reply(q(s))}}async function c0(t,e,n){let r=de(t),o=G4(t),s=o.startsWith(Hu)?o.slice(Hu.length):"";if(!(!r||!s)){if(s0(e,r)){await t.reply(Hp());return}try{let i=await e.switchToSession(r,s);if(!i.ok){await t.reply(i.reason==="already-active"?Hw():Bw());return}let a=Uw(i.name!==void 0?{name:i.name}:{});await t.editMessageText(a,{parse_mode:"HTML"}).catch(()=>t.reply(a,{parse_mode:"HTML"}))}catch(i){n("Switch callback error:",i),await t.reply(q(i))}}}Je();var q4="\u25D0 AFK mode ON \u2014 I'll work autonomously on reversible tasks and report here. High-risk / irreversible ops are REFUSED (not one-tap approvable) and surfaced as an Asking summary for you to handle deliberately. Send /afk off to stop.",X4="\u25CB AFK mode OFF \u2014 default permissions restored.";async function l0(t,e,n){let r=de(t);if(!r){await t.reply(q("Could not identify chat"));return}let s=(t.message.text??"").split(/\s+/).slice(1).join(" ").trim().toLowerCase();try{let i=await e.getSession(r),a=i.getSessionMetadata().permissionMode==="autonomous",c=s==="on"?!0:s==="off"?!1:!a;if(c===a){await t.reply(c?"\u25D0 AFK mode is already ON.":"\u25CB AFK mode is already OFF.");return}await i.setPermissionMode(c?"autonomous":"default"),await t.reply(c?q4:X4)}catch(i){n("AFK toggle error:",i),await t.reply(q("Could not toggle AFK mode"))}}Zr();F();var z4="https://api.anthropic.com/api/oauth/usage",V4="oauth-2025-04-20",J4=1e4;async function d0(t){let e=t?.fetchImpl??fetch,n=t?.timeoutMs??J4,r=t?.token??(v.CLAUDE_CODE_OAUTH_TOKEN||je());if(!r)return{kind:"unavailable",reason:"no-token",detail:"No Claude Code OAuth token found. Set CLAUDE_CODE_OAUTH_TOKEN or run `claude login` and try again."};let o;try{o=await e(z4,{headers:{Authorization:`Bearer ${r}`,"anthropic-beta":V4},signal:AbortSignal.timeout(n)})}catch(u){return Y4(u)?{kind:"unavailable",reason:"timeout",detail:"Request to the usage endpoint timed out."}:{kind:"unavailable",reason:"network-error",detail:"Network error while contacting the usage endpoint."}}if(!o.ok)return{kind:"unavailable",reason:"http-error",detail:`Usage endpoint returned HTTP ${o.status}.`};let s;try{s=await o.json()}catch{return{kind:"unavailable",reason:"malformed-response",detail:"Usage endpoint returned a response that was not valid JSON."}}if(typeof s!="object"||s===null)return{kind:"unavailable",reason:"malformed-response",detail:"Usage endpoint returned an unexpected response shape."};let i=s,a=ju(i.five_hour),c=ju(i.seven_day),l=ju(i.seven_day_sonnet),d=ju(i.seven_day_opus);return!a&&!c&&!l&&!d?{kind:"unavailable",reason:"malformed-response",detail:"Usage endpoint response contained none of the known usage windows."}:{kind:"ok",...a!==void 0?{fiveHour:a}:{},...c!==void 0?{sevenDay:c}:{},...l!==void 0?{sevenDaySonnet:l}:{},...d!==void 0?{sevenDayOpus:d}:{}}}function Y4(t){return t instanceof Error&&(t.name==="TimeoutError"||t.name==="AbortError")}var Q4=0,Z4=4102444800;function eY(t){if(typeof t=="string"){let e=new Date(t);return Number.isNaN(e.getTime())?void 0:e}if(typeof t=="number")return!Number.isFinite(t)||t<Q4||t>Z4?void 0:new Date(t*1e3)}function ju(t){if(typeof t!="object"||t===null)return;let e=t,n=e.utilization;if(typeof n!="number"||!Number.isFinite(n))return;let r=n>1?n/100:n,o=Math.min(1,Math.max(0,r)),s=eY(e.resets_at);return{utilization:o,...s!==void 0?{resetsAt:s}:{}}}Je();async function u0(t,e){try{let n=await d0();await t.reply(xw(n))}catch(n){e("Usage command error:",n),await t.reply(q("Could not fetch usage"))}}import{execFile as bY,spawn as wY}from"node:child_process";import{promisify as SY}from"node:util";H();import{execFile as tY}from"node:child_process";import{randomBytes as nY}from"node:crypto";import{promises as Wu}from"node:fs";import{join as Ku}from"node:path";import{promisify as rY}from"node:util";var Nxe=rY(tY);var $n=class extends Error{cause;code;constructor(e,n,r){super(e),this.name="WorktreeError",this.cause=n,this.code=r}};function oY(t,e=40){return t.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,e).replace(/-+$/g,"")||"task"}function sY(){return nY(4).toString("hex").slice(0,4)}function iY(t){let e=n=>String(n).padStart(2,"0");return`${t.getUTCFullYear()}${e(t.getUTCMonth()+1)}${e(t.getUTCDate())}T${e(t.getUTCHours())}${e(t.getUTCMinutes())}${e(t.getUTCSeconds())}`}function p0(t,e={}){let n=(e.now??(()=>new Date))(),r=(e.randomSuffix??sY)();return`${iY(n)}-${oY(t,32)}-${r}`}function aY(t){let e=t;return e.respawnedAt===void 0&&(e.respawnedAt=void 0),e.respawnedAs===void 0&&(e.respawnedAs=void 0),e.prUrl===void 0&&(e.prUrl=void 0),e.prCreatedAt===void 0&&(e.prCreatedAt=void 0),e}async function Wo(t){let e=Ku(Fb(t),"farm.json");try{let n=await Wu.readFile(e,"utf8"),r=JSON.parse(n);if(r.schemaVersion!==1&&r.schemaVersion!==2&&r.schemaVersion!==3)throw new $n(`unsupported farm manifest schema: ${r.schemaVersion} (expected 1, 2, or 3)`,void 0,"unsupported-schema");return aY(r)}catch(n){if(n.code==="ENOENT")return null;throw n instanceof $n?n:new $n(`failed to load farm manifest ${e}`,n,"invalid")}}async function f0(t,e){let n=await Wo(t);if(!n)throw new $n(`farm not found: ${t}`);return n.human_decision=e,n.decidedAt=new Date().toISOString(),n.schemaVersion=3,await Wu.writeFile(Ku(n.farmDir,"farm.json"),JSON.stringify(n,null,2)+`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-afk",
3
- "version": "5.123.0",
3
+ "version": "5.123.1",
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",