agent-afk 5.149.2 → 5.149.4

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
@@ -279,7 +279,7 @@ ${o}`,paths:[e,n]}:o!==null?s={content:o,paths:[n]}:r!==null?s={content:r,paths:
279
279
 
280
280
  ${e}`}var o1,ag=g(()=>{"use strict";o1=new Set(["script","style","noscript","template","svg"])});function a1(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 M_(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function c1(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 O_(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??a1,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(!i1.has(u.status)||d===o)return u;let p=c1(u,i)??M_(d,s,i);M("[web/retryFetch] retrying",{url:e,attempt:d,status:u.status,waitMs:p}),await u.body?.cancel().catch(()=>{}),await a(p,c)}catch(u){if(c?.aborted||(l=u,d===o))throw u;let p=M_(d,s,i);M("[web/retryFetch] retrying after error",{url:e,attempt:d,waitMs:p}),await a(p,c)}}throw l??new Error("retryFetch: exhausted without a result")}var i1,D_=g(()=>{"use strict";oe();i1=new Set([429,502,503,504])});import{BlockList as l1,isIP as lg}from"node:net";import{lookup as d1}from"node:dns/promises";import{Agent as u1}from"undici";function L_(){let t=S.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function g1(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function cg(t){let e=lg(t);return e===0?!1:m1.check(t,e===4?"ipv4":"ipv6")}async function N_(t){return d1(t,{all:!0,verbatim:!0})}async function dg(t,e={}){if(e.allowPrivateHosts??L_())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=g1(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(lg(r)!==0)return cg(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??N_,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if(cg(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function fi(t,e={}){let n=await dg(t,e);if(!n.allowed)throw new St(n.reason)}async function Tl(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<=F_;i++){await fi(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??L_())?{dispatcher:h1}:{}},c=await O_(t,s,a,r.retry??{});if(!y1.has(c.status))return c;let l=c.headers.get("location");if(l===null||l.trim()==="")return c;let d;try{d=new URL(l,c.url||s).toString()}catch{return c}await c.body?.cancel().catch(()=>{}),s=d}throw new St(`too many redirects (>${F_}) starting from ${e}`)}var p1,f1,m1,St,h1,F_,y1,ug=g(()=>{"use strict";U();D_();p1=[["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]],f1=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],m1=(()=>{let t=new l1;for(let[e,n]of p1)t.addSubnet(e,n,"ipv4");for(let[e,n]of f1)t.addSubnet(e,n,"ipv6");return t})(),St=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};h1=new u1({connect:{lookup(t,e,n){N_(t).then(r=>{let o=r.find(i=>cg(i.address));if(o!==void 0){n(new St(`refusing to connect to ${t} (resolved) \u2014 internal/private address ${o.address} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`),"",0);return}let s=r[0];if(s===void 0){n(new Error(`DNS lookup returned no addresses for ${t}`),"",0);return}n(null,s.address,lg(s.address))},r=>n(r,"",0))}}});F_=20,y1=new Set([301,302,303,307,308])});import{readFileSync as b1}from"node:fs";import{join as w1}from"path";function S1(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function U_(t,e){return S1(e).test(t)}function A1(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(v1.has(e))return!0;if(k1.has(e))return!1}return!1}function $_(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function _1(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 B_(t){let e=t===void 0||t.trim()===""?"default":t.trim();return yf(e),e}function E1(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function T1(t){try{return b1(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function x1(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=B_(e.defaultProfile)),n}function j_(t){let e=t?.env??S,n=t?.readFileSync??T1,r=t?.surface??e.AGENT_SURFACE,o=A1(e.AFK_BROWSER_HEADLESS,r),s=$_(e.AFK_BROWSER_ALLOWED_DOMAINS),i=$_(e.AFK_BROWSER_BLOCKED_DOMAINS),a=E1(e.AFK_BROWSER_DOM_SNAPSHOTS),c=_1(e.AFK_BROWSER_BACKEND),l=B_(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():w1(Gt(),"browser.json"),f=n(p);if(f===void 0)return d;let m;try{m=JSON.parse(f)}catch(y){throw new Error(`Failed to parse browser config at ${p}: ${String(y)}`)}if(typeof m!="object"||m===null||Array.isArray(m))throw new Error(`Browser config at ${p} must be a JSON object`);let h=x1(d,m);return h.configPath=p,h}function xl(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(U_(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>U_(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var v1,k1,Rl=g(()=>{"use strict";U();j();v1=new Set(["daemon","subagent","telegram","afk"]),k1=new Set(["repl","interactive","cli"])});import{existsSync as R1,readFileSync as I1}from"node:fs";import{createRequire as C1}from"node:module";import{dirname as P1,join as M1}from"node:path";function K_(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<D1&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function je(t){let e=K_(t);return W_.some(n=>e.includes(n))}function F1(){try{let e=C1(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(I1(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=M1(P1(e),o);return R1(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function mi(){return H_??=F1()??O1,H_}function pg(t){return t.includes("install chromium")}function it(t,e){let n=K_(t),r=e?.latched===!0?` ${L1}`:"";if(n.includes("Executable doesn't exist")){let o="";return e?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":e?.headless===!1&&(o=" This launch was headed, which needs the full `chromium-*` build \u2014 the headless shell alone does not satisfy it."),`browser tools require the Playwright chromium binary. Install via: ${mi()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${mi()}). Or pick a different tool.${r}`}function fg(t,e,n=!1){if(!je(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
281
281
 
282
- ${it(t,{headless:e,latched:n})}`,{cause:t})}var W_,O1,D1,H_,L1,mg=g(()=>{"use strict";W_=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],O1="pnpm exec playwright install chromium",D1=4;L1="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 dr from"node:fs";import Il from"node:path";import{randomBytes as N1}from"node:crypto";import{chromium as U1}from"playwright";function $1(){try{return"5.149.2"}catch{}try{let t=Il.resolve(import.meta.dirname,"../../../package.json"),e=dr.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var B1,Cl,G_=g(()=>{"use strict";mg();j();oe();B1=$1(),Cl=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=U1.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=fg(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/${B1}`}}loadStorageState(e){let n=bf(e);try{if(!dr.existsSync(n))return;let r=JSON.parse(dr.readFileSync(n,"utf8"));return M("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){M("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=bf(e);if(!dr.existsSync(r))return;let o=await n.storageState(),s=Il.join(Il.dirname(r),`.${Il.basename(r)}.${process.pid}.${N1(4).toString("hex")}.tmp`);dr.writeFileSync(s,JSON.stringify(o),{mode:384}),dr.chmodSync(s,384),dr.renameSync(s,r),M("[browser/vault] saved session",{profile:e,file:r})}catch(r){M("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as j1}from"crypto";function q_(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&H1.test(t.label))}function X_(t){return j1("sha256").update(t,"utf8").digest("hex").slice(0,8)}function z_(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var H1,Pl=g(()=>{"use strict";H1=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as W1}from"node:crypto";function K1(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function G1(t,e,n){return`el_${W1("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function q1(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function V_(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function Y_(t,e){let n=t.role??"",r=t.name??"";J_.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])Y_(s,e)}async function X1(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},Q_).catch(()=>[])}async function z1(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},Q_).catch(()=>[])}function V1(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Ml(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=V1(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=X1(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=[],Y_(u,y)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,y=(await z1(t)).filter(O=>J_.has(O.role??"")));let _=new Map;for(let C of p){let O=V_(C.name),q=_.get(O);(!q||q.bbox.w===0&&C.bbox.w>0)&&_.set(O,C)}let A=y.map(C=>({ax:C,dom:_.get(V_(C.name??""))})),E=r?A:A.filter(C=>C.dom?C.dom.bbox.w>0||C.dom.bbox.h>0:!0);E.sort((C,O)=>{let q=C.dom?.bbox.y??0,P=O.dom?.bbox.y??0;if(q!==P)return q-P;let $=C.dom?.bbox.x??0,D=O.dom?.bbox.x??0;return $-D}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=E.slice(0,n).map((C,O)=>{let q=C.ax.role??"generic",P=C.ax.name??"",$=G1(q,P,O),D=C.dom?.bbox??{x:0,y:0,w:0,h:0},L=C.dom?.type??null,B=null;C.ax.value!==void 0&&C.ax.value!==null&&(B=String(C.ax.value)),C.ax.checked!==void 0&&(B=String(C.ax.checked)),q_({role:q,kind:L})&&(B="[redacted]");let W={disabled:C.ax.disabled??!1};C.ax.checked!==void 0&&(W.checked=C.ax.checked===!0||C.ax.checked==="mixed"),C.ax.selected!==void 0&&(W.selected=C.ax.selected),C.ax.expanded!==void 0&&(W.expanded=C.ax.expanded);let Q;C.dom?.testId?Q=`[data-testid="${C.dom.testId}"]`:C.dom?.id&&(Q=`#${C.dom.id}`);let Le={id:$,role:q,label:K1(P),kind:L,value:B,state:W,bbox:D};return Q!==void 0&&(Le.selector=Q),Le}),I="idle";try{let C=await t.evaluate(()=>document.readyState);C==="loading"?I="loading":C==="interactive"?I="navigating":I="idle"}catch{I="navigating"}I!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),w&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let R=q1(f),v=`obs_${e.observationCounter.toString(36)}`,k=new Date().toISOString();return{observationId:v,url:m,title:h,textSummary:R,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:k}}var J_,Q_,Z_=g(()=>{"use strict";Pl();J_=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);Q_="a[href], button, input, select, textarea, [role], [tabindex], label"});async function eE(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 gg(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>eE(t,s)))).filter(o=>o!==null)}async function J1(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 hg(t,e,n){switch(e.kind){case"element_id":return Y1(t,e,n);case"selector":return Q1(t,e);case"semantic":return Z1(t,e)}}async function Y1(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 gg(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function Q1(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 gg(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function Z1(t,e){return e.role!==void 0?eG(t,e.text,e.role):tG(t,e.text,e)}async function eG(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 gg(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function tG(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 J1(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 eE(y.locator,y.index);if(w!==null){let _=`${w.role}:${w.label}:${h}`,A=0;for(let E=0;E<_.length;E++)A=A*31+_.charCodeAt(E)>>>0;f.push({...w,id:`el_${A.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var tE=g(()=>{"use strict"});async function yg(t,e,n,r){let o=t.url();if(o===n)return null;let s=xl(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 nE=g(()=>{"use strict";Rl()});import{randomBytes as nG}from"crypto";import{mkdir as rG,stat as oG,writeFile as sG}from"fs/promises";import{join as bg}from"path";import{gzip as iG}from"zlib";import{promisify as aG}from"util";function cG(t){return bg(xt(t),"browser")}function lG(t){return bg(cG(t),"screenshots")}function dG(){return new Date().toISOString().replace(/[:.]/g,"-")}function uG(){return nG(3).toString("hex")}async function wg(t,e,n){if(e.length>rE)throw new Error(`writeScreenshotSidecar: buffer exceeds ${rE} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=lG(t);await rG(r,{recursive:!0});let o=`${dG()}-${uG()}-${n}.png`,s=bg(r,o);await sG(s,e);let{size:i}=await oG(s);return{path:s,bytes:i}}var uce,rE,oE=g(()=>{"use strict";j();Pl();uce=aG(iG);rE=5*1024*1024});var iE={};df(iE,{PlaywrightProvider:()=>Sg});function sE(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 Sg,aE=g(()=>{"use strict";G_();Z_();tE();Rl();nE();oE();Sg=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Cl(e)}async open(e){let n=xl(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 yg(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 Ml(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 Ml(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 hg(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${sE(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 yg(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 Ml(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 hg(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${sE(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 wg(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 wg(n,o,r);return s}catch{return null}}}});var pr={};df(pr,{__resetBrowserRegistryForTests:()=>hG,browserProviderActive:()=>mG,closeBrowserProvider:()=>vg,getBrowserProvider:()=>fG,peekBrowserProvider:()=>gG});function cE(){Promise.resolve(vg()).then(()=>{process.exit(130)})}function lE(){Promise.resolve(vg()).then(()=>{process.exit(143)})}function dE(){Nt=null}function pG(){Ol||(process.on("SIGINT",cE),process.on("SIGTERM",lE),process.on("exit",dE),Ol=!0)}function uE(){Ol&&(process.removeListener("SIGINT",cE),process.removeListener("SIGTERM",lE),process.removeListener("exit",dE),Ol=!1)}async function fG(t){return Nt!==null?Nt:(ur!==null||(ur=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(aE(),iE)),n=j_(t),r=new e(n);return pG(),Nt=r,ur=null,r})()),ur)}async function vg(){if(Nt===null)return;let t=Nt;Nt=null,ur=null,uE(),await t.shutdown()}function mG(){return Nt!==null}function gG(){return Nt}function hG(){Nt=null,ur=null,uE()}var Nt,ur,Ol,fr=g(()=>{"use strict";Rl();Nt=null,ur=null,Ol=!1});async function pE(t,e){try{return await I_(t,e)}catch(n){return M("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function kG(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(fr(),pr));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function fE(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??kG,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Tl(n,t,{headers:vG,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(SG.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(wG.test(p)&&!bG.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await pE(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof St||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=ig({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await fi(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>fi(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await fi(u.finalUrl,o);let p=await pE(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=ig({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(e.signal.aborted||u instanceof St)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${c??"error"}).`)}var bG,wG,SG,vG,mE=g(()=>{"use strict";C_();ag();ug();oe();bG=/(text\/html|application\/xhtml\+xml)/i,wG=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,SG=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,vG={"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 EG(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(AG,{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),_G),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Z(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function gE(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?EG({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 hE(t,e){if(e.length===0)return`# Search results for "${t}"
282
+ ${it(t,{headless:e,latched:n})}`,{cause:t})}var W_,O1,D1,H_,L1,mg=g(()=>{"use strict";W_=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],O1="pnpm exec playwright install chromium",D1=4;L1="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 dr from"node:fs";import Il from"node:path";import{randomBytes as N1}from"node:crypto";import{chromium as U1}from"playwright";function $1(){try{return"5.149.4"}catch{}try{let t=Il.resolve(import.meta.dirname,"../../../package.json"),e=dr.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var B1,Cl,G_=g(()=>{"use strict";mg();j();oe();B1=$1(),Cl=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=U1.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=fg(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/${B1}`}}loadStorageState(e){let n=bf(e);try{if(!dr.existsSync(n))return;let r=JSON.parse(dr.readFileSync(n,"utf8"));return M("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){M("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=bf(e);if(!dr.existsSync(r))return;let o=await n.storageState(),s=Il.join(Il.dirname(r),`.${Il.basename(r)}.${process.pid}.${N1(4).toString("hex")}.tmp`);dr.writeFileSync(s,JSON.stringify(o),{mode:384}),dr.chmodSync(s,384),dr.renameSync(s,r),M("[browser/vault] saved session",{profile:e,file:r})}catch(r){M("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as j1}from"crypto";function q_(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&H1.test(t.label))}function X_(t){return j1("sha256").update(t,"utf8").digest("hex").slice(0,8)}function z_(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var H1,Pl=g(()=>{"use strict";H1=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as W1}from"node:crypto";function K1(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function G1(t,e,n){return`el_${W1("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function q1(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function V_(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function Y_(t,e){let n=t.role??"",r=t.name??"";J_.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])Y_(s,e)}async function X1(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},Q_).catch(()=>[])}async function z1(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},Q_).catch(()=>[])}function V1(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Ml(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=V1(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=X1(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=[],Y_(u,y)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,y=(await z1(t)).filter(O=>J_.has(O.role??"")));let _=new Map;for(let C of p){let O=V_(C.name),q=_.get(O);(!q||q.bbox.w===0&&C.bbox.w>0)&&_.set(O,C)}let A=y.map(C=>({ax:C,dom:_.get(V_(C.name??""))})),E=r?A:A.filter(C=>C.dom?C.dom.bbox.w>0||C.dom.bbox.h>0:!0);E.sort((C,O)=>{let q=C.dom?.bbox.y??0,P=O.dom?.bbox.y??0;if(q!==P)return q-P;let $=C.dom?.bbox.x??0,D=O.dom?.bbox.x??0;return $-D}),E.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=E.slice(0,n).map((C,O)=>{let q=C.ax.role??"generic",P=C.ax.name??"",$=G1(q,P,O),D=C.dom?.bbox??{x:0,y:0,w:0,h:0},L=C.dom?.type??null,B=null;C.ax.value!==void 0&&C.ax.value!==null&&(B=String(C.ax.value)),C.ax.checked!==void 0&&(B=String(C.ax.checked)),q_({role:q,kind:L})&&(B="[redacted]");let W={disabled:C.ax.disabled??!1};C.ax.checked!==void 0&&(W.checked=C.ax.checked===!0||C.ax.checked==="mixed"),C.ax.selected!==void 0&&(W.selected=C.ax.selected),C.ax.expanded!==void 0&&(W.expanded=C.ax.expanded);let Q;C.dom?.testId?Q=`[data-testid="${C.dom.testId}"]`:C.dom?.id&&(Q=`#${C.dom.id}`);let Le={id:$,role:q,label:K1(P),kind:L,value:B,state:W,bbox:D};return Q!==void 0&&(Le.selector=Q),Le}),I="idle";try{let C=await t.evaluate(()=>document.readyState);C==="loading"?I="loading":C==="interactive"?I="navigating":I="idle"}catch{I="navigating"}I!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),w&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let R=q1(f),v=`obs_${e.observationCounter.toString(36)}`,k=new Date().toISOString();return{observationId:v,url:m,title:h,textSummary:R,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:I,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:k}}var J_,Q_,Z_=g(()=>{"use strict";Pl();J_=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);Q_="a[href], button, input, select, textarea, [role], [tabindex], label"});async function eE(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 gg(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>eE(t,s)))).filter(o=>o!==null)}async function J1(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 hg(t,e,n){switch(e.kind){case"element_id":return Y1(t,e,n);case"selector":return Q1(t,e);case"semantic":return Z1(t,e)}}async function Y1(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 gg(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function Q1(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 gg(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function Z1(t,e){return e.role!==void 0?eG(t,e.text,e.role):tG(t,e.text,e)}async function eG(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 gg(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function tG(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 J1(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 eE(y.locator,y.index);if(w!==null){let _=`${w.role}:${w.label}:${h}`,A=0;for(let E=0;E<_.length;E++)A=A*31+_.charCodeAt(E)>>>0;f.push({...w,id:`el_${A.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var tE=g(()=>{"use strict"});async function yg(t,e,n,r){let o=t.url();if(o===n)return null;let s=xl(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 nE=g(()=>{"use strict";Rl()});import{randomBytes as nG}from"crypto";import{mkdir as rG,stat as oG,writeFile as sG}from"fs/promises";import{join as bg}from"path";import{gzip as iG}from"zlib";import{promisify as aG}from"util";function cG(t){return bg(xt(t),"browser")}function lG(t){return bg(cG(t),"screenshots")}function dG(){return new Date().toISOString().replace(/[:.]/g,"-")}function uG(){return nG(3).toString("hex")}async function wg(t,e,n){if(e.length>rE)throw new Error(`writeScreenshotSidecar: buffer exceeds ${rE} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=lG(t);await rG(r,{recursive:!0});let o=`${dG()}-${uG()}-${n}.png`,s=bg(r,o);await sG(s,e);let{size:i}=await oG(s);return{path:s,bytes:i}}var uce,rE,oE=g(()=>{"use strict";j();Pl();uce=aG(iG);rE=5*1024*1024});var iE={};df(iE,{PlaywrightProvider:()=>Sg});function sE(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 Sg,aE=g(()=>{"use strict";G_();Z_();tE();Rl();nE();oE();Sg=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Cl(e)}async open(e){let n=xl(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 yg(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 Ml(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 Ml(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 hg(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${sE(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 yg(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 Ml(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 hg(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${sE(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 wg(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 wg(n,o,r);return s}catch{return null}}}});var pr={};df(pr,{__resetBrowserRegistryForTests:()=>hG,browserProviderActive:()=>mG,closeBrowserProvider:()=>vg,getBrowserProvider:()=>fG,peekBrowserProvider:()=>gG});function cE(){Promise.resolve(vg()).then(()=>{process.exit(130)})}function lE(){Promise.resolve(vg()).then(()=>{process.exit(143)})}function dE(){Nt=null}function pG(){Ol||(process.on("SIGINT",cE),process.on("SIGTERM",lE),process.on("exit",dE),Ol=!0)}function uE(){Ol&&(process.removeListener("SIGINT",cE),process.removeListener("SIGTERM",lE),process.removeListener("exit",dE),Ol=!1)}async function fG(t){return Nt!==null?Nt:(ur!==null||(ur=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(aE(),iE)),n=j_(t),r=new e(n);return pG(),Nt=r,ur=null,r})()),ur)}async function vg(){if(Nt===null)return;let t=Nt;Nt=null,ur=null,uE(),await t.shutdown()}function mG(){return Nt!==null}function gG(){return Nt}function hG(){Nt=null,ur=null,uE()}var Nt,ur,Ol,fr=g(()=>{"use strict";Rl();Nt=null,ur=null,Ol=!1});async function pE(t,e){try{return await I_(t,e)}catch(n){return M("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function kG(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(fr(),pr));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function fE(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??kG,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i="",a=t,c=null,l=null;try{let u=await Tl(n,t,{headers:vG,signal:e.signal},o);c=u.status,a=u.url||t;let p=u.headers.get("content-type")??"";if(u.ok){if(SG.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(wG.test(p)&&!bG.test(p))return{title:"",markdown:f.trim(),finalUrl:a,usedRender:!1};if(i=f,s=await pE(f,a),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(u){if(e.signal.aborted||u instanceof St||u instanceof Error&&u.message.startsWith("web_scrape markdown mode received binary"))throw u;l=u}if(!(s===null||s.textLength<200)&&s!==null){let u=ig({html:i,extractedTextLength:s.textLength});return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1,...u!==void 0?{advisory:u}:{}}}try{await fi(t,o);let u=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:f=>fi(f,o)});u.finalUrl!==t&&/^https?:\/\//i.test(u.finalUrl)&&await fi(u.finalUrl,o);let p=await pE(u.html,u.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||p.textLength>=s.textLength){let f=ig({html:u.html,extractedTextLength:p.textLength});return{title:p.title,markdown:p.markdown,finalUrl:u.finalUrl,usedRender:!0,...f!==void 0?{advisory:f}:{}}}}catch(u){if(e.signal.aborted||u instanceof St)throw u;if(s===null){let p=u instanceof Error?u.message:String(u),f=l instanceof Error?l.message:`HTTP ${c??"error"}`,m=new Error(`web_scrape could not retrieve ${t}: fetch failed (${f}) and render failed (${p}).`);throw m.cause=u,m}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:a,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${c??"error"}).`)}var bG,wG,SG,vG,mE=g(()=>{"use strict";C_();ag();ug();oe();bG=/(text\/html|application\/xhtml\+xml)/i,wG=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,SG=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,vG={"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 EG(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(AG,{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),_G),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Z(d);u&&(c=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}catch{}let l=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${l}${c}`)}let i;try{i=await s.json()}catch(c){throw new Error(`Exa Search response was not JSON: ${c instanceof Error?c.message:String(c)}`)}return(i.results??[]).slice(0,r).map(c=>({title:(c.title??"").trim()||"(untitled)",url:c.url??"",description:(c.highlights?.[0]??"").trim()})).filter(c=>c.url.length>0)}}}function gE(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?EG({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 hE(t,e){if(e.length===0)return`# Search results for "${t}"
283
283
 
284
284
  (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(`
285
285
  `).trimEnd()}var AG,_G,yE=g(()=>{"use strict";wt();AG="https://api.exa.ai/search",_G=10});function Dl(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 mr=g(()=>{"use strict";mg()});function PG(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=TG;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,xG)}let a=RG;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,IG)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function kg(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:Zn(t,e),truncated:!0}}function MG(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=PG(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 dg(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 Tl(e,i.url,h,r)}catch(h){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:h instanceof St?{content:`web_scrape blocked: ${h.message}`,isError:!0}:{content:`web_scrape network error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}if(!p.ok)return{content:`web_scrape HTTP ${p.status} ${p.statusText||""}`.trimEnd()+` for ${i.url}`,isError:!0};let f;try{f=await p.text()}catch(h){return{content:`web_scrape read error: ${h instanceof Error?h.message:String(h)}`,isError:!0}}let m=kg(f,i.maxBytes);return{content:m.content,...m.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await fE(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=kg(P_(p.markdown,p.advisory),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(p instanceof St)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),m=je(p)&&!pg(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${mi()}\`)`:"";return{content:`web_scrape markdown error: ${f}${m}`,isError:!0}}let u=gE({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:CG,timeoutMs:i.timeoutMs,signal:a.signal}),f=kg(hE(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 TG,xG,RG,IG,CG,bE,wE=g(()=>{"use strict";mE();yE();ug();hn();ag();mr();TG=3e4,xG=12e4,RG=1e5,IG=1e6,CG=10;bE=MG()});import{existsSync as vE,mkdirSync as OG,readFileSync as DG,renameSync as FG,unlinkSync as LG,writeFileSync as NG}from"node:fs";import{dirname as SE,join as UG}from"node:path";import{randomBytes as $G}from"node:crypto";function gr(t){let e=t??mf();if(!vE(e))return[];try{let n=DG(e,"utf-8");return JSON.parse(n)}catch(n){let r=n instanceof Error?n.message:String(n);return console.error(`[schedule-store] failed to parse ${e}: ${r}`),[]}}function gi(t,e){let n=e??mf();OG(SE(n),{recursive:!0});let r=UG(SE(n),`.schedules.json.${process.pid}.${$G(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{NG(r,o,"utf-8"),FG(r,n)}catch(s){try{vE(r)&&LG(r)}catch{}throw s}}function kE(t,e){let n=gr(e),r=n.map(c=>c.id),o=BG(t.name),s=jG(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),gi(n,e),a}function AE(t,e){let n=gr(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(gi(o,e),!0)}function _E(t,e){return gr(e).find(n=>n.id===t)}function BG(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function jG(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}function EE(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 TE=g(()=>{"use strict";j()});import{existsSync as HG,readFileSync as WG}from"node:fs";import{join as KG}from"node:path";async function mo(t,e,n){let r,o;try{let s=KG(Yw("default"),"port");if(!HG(s))return{synced:!1,detail:"daemon-not-detected (no port file)"};let i=WG(s,"utf-8").trim(),a=GG(i);if(!a)return{synced:!1,detail:"daemon-not-detected (invalid port file)"};({host:r,port:o}=a)}catch{return{synced:!1,detail:"daemon-not-detected (unreadable port file)"}}try{let s=r.includes(":")?`[${r}]`:r,i=await fetch(`http://${s}:${o}${e}`,{method:t,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return i.ok?{synced:!0,detail:"synced"}:t==="POST"&&i.status===409?{synced:!0,detail:"already-registered"}:t==="DELETE"&&i.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${i.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}function GG(t){let e=parseInt(t,10);if(String(e)===t&&!Number.isNaN(e))return e<1||e>65535?null:{host:"localhost",port:e};let n=t.lastIndexOf(":");if(n<1)return null;let r=t.slice(0,n),o=t.slice(n+1);if(!/^\d+$/.test(o))return null;let s=parseInt(o,10);return Number.isNaN(s)||s<1||s>65535||/^:+$/.test(r)?null:{host:r.startsWith("[")&&r.endsWith("]")?r.slice(1,-1):r,port:s}}var Ag,xE=g(()=>{"use strict";j();Ag="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 qG}from"node:fs";import{readFile as XG}from"node:fs/promises";var RE,IE,CE,PE,ME=g(()=>{"use strict";TE();j();xE();RE=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=kE({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 mo("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 mo("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:Ag}})}},IE=async(t,e)=>{let n=gr();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})))}},CE=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;if(typeof n.taskId!="string"||!n.taskId)return{content:"Invalid input: taskId required",isError:!0};let r=n.taskId,o=typeof n.limit=="number"?Math.min(Math.max(1,n.limit),50):10,s=Ga();if(!qG(s))return{content:JSON.stringify([])};let i;try{let l=await XG(s);i=(l.length>1048576?l.subarray(l.length-1048576):l).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
@@ -1285,7 +1285,7 @@ ${r}
1285
1285
  ${o}`};if(s&&typeof s=="object"&&"type"in s&&s.type==="preset"){let i=s.append??"";return{...t,systemPrompt:{...s,append:`${i}
1286
1286
 
1287
1287
  ${o}`}}}return{...t,systemPrompt:o}}var Tf=new Map;function xf(t,e){Tf.set(t,e)}function mc(t){return Tf.get(t)}function MS(t){Tf.delete(t)}function gc(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 OS(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 DS(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 _=f[f.length-1];if(_&&typeof _=="object"){let A=_;d=Number(A.input_tokens??0),u=Number(A.output_tokens??0),p=Number(A.cache_read_input_tokens??0)+Number(A.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 _=gc(e);_&&(t.name=_)}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 d$,writeFileSync as u$,existsSync as yc,mkdirSync as p$,readdirSync as f$,statSync as m$,realpathSync as FS}from"fs";import{join as NS,basename as US,resolve as LS,sep as g$}from"path";j();import{randomUUID as c$}from"node:crypto";var Es=class extends Error{constructor(e){super(e),this.name="SessionRegistryError"}},Rf=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??c$();if(this.byId.has(r))throw new Es(`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 Es(`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 Es(`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 hc=new Rf;function Ts(){return rS(),be()}function h$(t){return NS(Ts(),`${t}.json`)}function If(t,{write:e=!1}={}){let n=t.includes("/")?t:h$(t),r,o;if(!e&&yc(n)?(r=FS(n),o=FS(Ts())):(r=LS(n),o=LS(Ts())),!r.startsWith(o+g$)&&r!==o)throw new Error(`Session path escapes sessions directory: ${t}`);return r}function Cf(t,e){let n=Ts();yc(n)||p$(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=If(r,{write:!0});return u$(s,JSON.stringify(o,null,2)),s}function Xt(t){let e;try{e=If(t)}catch(n){console.warn(`loadSession: rejected unsafe session id ${JSON.stringify(t)}: ${n.message}`);return}if(yc(e))try{let n=d$(e,"utf-8");return JSON.parse(n)}catch(n){console.warn(`loadSession: failed to read/parse ${e}: ${n.message}`);return}}function Pf(t){let e;try{e=If(t)}catch{return}let n=Xt(e);if(n)return{path:e,id:US(e,".json"),data:n};let r=Br();for(let s of r){if(s.id!==t&&s.sessionId!==t&&s.name!==t)continue;let i=Xt(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=Xt(i.path);if(a)return{path:i.path,id:i.id,data:a}}}}}function Br(){let t=Ts();if(!yc(t))return[];let e=[];for(let n of f$(t)){if(!n.endsWith(".json"))continue;let r=NS(t,n);try{if(!m$(r).isFile())continue;let s=Xt(r);if(!s||typeof s.savedAt!="number"||typeof s.model!="string")continue;e.push({path:r,id:US(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 y$(t){let e=new Map,n=[];for(let r of t)r.toolUseId===void 0?n.push(r):e.set(r.toolUseId,r);return[...e.values(),...n]}function $S(t){return!t||t.length===0?"":`
1288
- [Tools used: ${y$(t).map(r=>{let o=r.isError?"\u2717":"\u2713",s=r.input||r.inputRaw||"",i=s.length>80?s.slice(0,77)+"\u2026":s;return`${r.toolName}(${i})${o}`}).join(", ")}]`}function BS(t){return t?{resume:t.resumeId,sessionId:t.resumeId,...t.stored?{resumeHistory:t.stored.turns.map(e=>({user:e.user,assistant:(e.assistant??"")+$S(e.toolEvents)}))}:{}}:{}}function b$(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 se(t){let e=t.chat?.id;if(typeof e!="number")return;let n=t.message??t.editedMessage??t.callbackQuery?.message,{threadId:r,isTopic:o}=b$(n),s={chatId:e};return r!==void 0&&(s.threadId=r),o&&(s.isTopicMessage=!0),s}function jS(t){return t.threadId===void 0||t.threadId===1}function X(t){return jS(t)?String(t.chatId):`${t.chatId}:${t.threadId}`}function jn(t){return jS(t)?{}:{message_thread_id:t.threadId}}function HS(t,e,n,r){let o=X(e),s=o,i=t.resolve("telegram",o);if(i){t.touch(i.id),n.sessionId&&t.attachSdkSessionId(i.id,n.sessionId);return}let a=t.get(s);if(a&&a.status==="active"){t.bind(s,{surface:"telegram",key:o}),n.sessionId&&t.attachSdkSessionId(s,n.sessionId);return}let c=a===void 0?s:void 0;t.create({surface:"telegram",key:o,model:n.model??r,id:c,sdkSessionId:n.sessionId})}function Mf(t,e){t.archive(e)}import{promises as xs}from"fs";import{join as WS}from"path";function qe(t){return typeof t=="number"?{chatId:t}:t}var bc=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,registry:e.registry}}getSessionIfExists(e){return this.sessions.get(X(qe(e)))}async getSession(e){let n=qe(e),r=X(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,telegramChatId:n.chatId,...n.threadId!==void 0?{telegramThreadId:n.threadId}:{}};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=Xt(d);Object.assign(c,BS({id:d,resumeId:p?.sessionId??d,stored:p}))}let u=await this.options.createSession(Ef(Sf(c)));this.sessions.set(r,u),this.sessionData.set(r,i);try{this._ensureRegistryHandle(n,i)}catch{}return u.sessionId&&(xf(u.sessionId,n),i.sessionId=u.sessionId),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())}_ensureRegistryHandle(e,n){HS(this.options.registry??hc,e,n,this.options.defaultModel)}recordTelegramTurn(e,n,r,o){let s=qe(e),i=X(s),a=this._getOrCreateStats(s),c=this.sessions.get(i);!a.sessionId&&c?.sessionId&&(a.sessionId=c.sessionId),DS(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&&xf(a.sessionId,s),a.sessionId)try{Cf(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=X(e);if(this.sessionStats.has(n))return;let r=this.sessionData.get(n)?.sessionId;if(!r)return;let o=Xt(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=qe(e);return this._hydrateStatsFromStore(n),this.sessionStats.get(X(n))?.name}setSessionName(e,n){let r=qe(e),o=X(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),Cf(s),{persisted:!0}}return{persisted:!1}}_getOrCreateStats(e){let n=X(e);this._hydrateStatsFromStore(e);let r=this.sessionStats.get(n);if(!r){r=OS(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){let n=this.sessionStats.get(e)?.sessionId??this.sessionData.get(e)?.sessionId;n&&MS(n),this.sessionStats.delete(e),this.autosaveFailureLogged.delete(e),this.pendingResume.delete(e);let r=this.sessionData.get(e);r&&delete r.sessionId}async resetSession(e){let n=qe(e),r=X(n);try{Mf(this.options.registry??hc,r)}catch{}let o=this.sessions.get(r);o&&(await o.close(),this.sessions.delete(r)),this._resetStats(r);let s=this.sessionData.get(r);s&&(s.lastActivity=new Date().toISOString())}async switchModel(e,n){let r=qe(e),o=X(r);try{Mf(this.options.registry??hc,o)}catch{}let 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));try{this._ensureRegistryHandle(r,i)}catch{}}getModel(e){return this.sessionData.get(X(qe(e)))?.model||this.options.defaultModel}async setCwd(e,n){let r=qe(e),o=X(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(X(qe(e)))?.cwd??this.options.botCwd}listChatSessions(e){let n=qe(e),r=this.sessionData.get(X(n))?.sessionId;return Br().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=qe(e),o=X(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=Xt(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(X(qe(e))),await this.resetSession(e)}sidecarFileName(e){let n={chatId:e.chatId};return e.threadId!==void 0&&(n.threadId=e.threadId),`${X(n)}.json`}async loadSessions(){try{await xs.mkdir(this.options.dataDir,{recursive:!0});let e=await xs.readdir(this.options.dataDir);for(let n of e)if(n.endsWith(".json")){let r=WS(this.options.dataDir,n),o=await xs.readFile(r,"utf-8"),s=JSON.parse(o),i={chatId:s.chatId};s.threadId!==void 0&&(i.threadId=s.threadId),this.sessionData.set(X(i),s);try{this._ensureRegistryHandle(i,s)}catch{}}}catch(e){e.code!=="ENOENT"&&console.error("Failed to load sessions:",e)}}async saveSessions(){try{await xs.mkdir(this.options.dataDir,{recursive:!0});for(let e of this.sessionData.values()){let n=WS(this.options.dataDir,this.sidecarFileName(e));await xs.writeFile(n,JSON.stringify(e,null,2))}}catch(e){console.error("Failed to save sessions:",e)}}_evictStaleSessionData(e=1440*60*1e3){let n=Date.now();for(let[r,o]of this.sessionData){if(this.sessions.has(r))continue;n-new Date(o.lastActivity).getTime()>e&&this.sessionData.delete(r)}}async closeAll(){this._evictStaleSessionData(),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}};Ue();Ue();async function Ff(t){await t.reply(qS())}Ue();async function Lf(t,e){let n=se(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(GS(r))}ie();import{Markup as fF}from"telegraf";import{promises as x8}from"fs";import{homedir as mF}from"os";import{isAbsolute as R8,resolve as zb}from"path";async function Is(t,e){t.sendChatAction("typing").catch(()=>{});let n=setInterval(()=>{t.sendChatAction("typing").catch(()=>{})},4e3);try{return await e()}finally{clearInterval(n)}}Ue();ue();Ie();ve();Mi();Mr();function E8(t,e){try{if(!t||t.trim().toLowerCase()==="auto")return{available:!0,needs:"unknown"};let n=Kn(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=Tn(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=dt(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=dt(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=G(t,e?{slots:e}:void 0);if(r==="anthropic-direct"){let o=!!ai();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=!!hl()||Tn(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=dt(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 cF(t,e){return E8(t,e).available}Ie();var T8=/^[A-Za-z0-9_@%+=:,./-]+$/;function lF(t){return T8.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}function dF(t,e){let n=["afk","interactive"];return typeof e=="string"&&e.length>0&&n.push("--model",lF(e)),n.push("--resume",lF(t)),n.join(" ")}ue();Ie();function uF(t){if(Wn.includes(t)||Gr(t)!==void 0)return!0;let e=G(t);if(e==="openai-compatible"||e==="xai"||e==="xai-oauth")return!0;let n=Kn(t).id.trim().toLowerCase();return n.startsWith("claude-")||n.startsWith("claude_")}function pF(t){return uF(t)}async function Vb(t,e,n,r){let o=se(t);if(!o){await t.reply(z("Could not identify chat"));return}try{await e.resetSession(o),n.delete(o.chatId),await t.reply(vc())}catch(s){r("Clear error:",s),await t.reply(z(s))}}async function gF(t,e,n){let r=se(t);if(!r){await t.reply(z("Could not identify chat"));return}try{let o=await e.getSession(r),s=o.hookRegistry,i=await Is(t,async()=>(s&&await s.dispatch({event:"PreCompact",sessionId:o.sessionId,trigger:"manual"}),o.compact()));i.compacted?await t.reply(kc({before:i.messagesBefore,after:i.messagesAfter,...i.tokensSavedEstimate!==void 0?{tokensSavedEstimate:i.tokensSavedEstimate}:{}})):await t.reply(Ac(i.reason??"unknown"))}catch(o){o instanceof Y?await t.reply(`Compaction skipped: ${Xe(o.reason??"blocked by hook")}`):(n("Compact error:",o),await t.reply(z(o)))}}async function Jb(t,e,n){let r=se(t);if(!r){await t.reply(z("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1);if(s.length===0){let l=e.getModel(r),d=Wn.map(u=>[fF.button.callback(cF(u)?u:`${u} \u2014 needs sign-in`,`afk:m:${u}`)]);await t.reply(`Current model: <b>${Xe(l.toUpperCase())}</b>
1288
+ [Tools used: ${y$(t).map(r=>{let o=r.isError?"\u2717":"\u2713",s=r.input||r.inputRaw||"",i=s.length>80?s.slice(0,77)+"\u2026":s;return`${r.toolName}(${i})${o}`}).join(", ")}]`}function BS(t){return t?{resume:t.resumeId,sessionId:t.resumeId,...t.stored?{resumeHistory:t.stored.turns.map(e=>({user:e.user,assistant:(e.assistant??"")+$S(e.toolEvents)}))}:{}}:{}}function b$(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 se(t){let e=t.chat?.id;if(typeof e!="number")return;let n=t.message??t.editedMessage??t.callbackQuery?.message,{threadId:r,isTopic:o}=b$(n),s={chatId:e};return r!==void 0&&(s.threadId=r),o&&(s.isTopicMessage=!0),s}function jS(t){return t.threadId===void 0||t.threadId===1}function X(t){return jS(t)?String(t.chatId):`${t.chatId}:${t.threadId}`}function jn(t){return jS(t)?{}:{message_thread_id:t.threadId}}function HS(t,e,n,r){let o=X(e),s=o,i=t.resolve("telegram",o);if(i){t.touch(i.id),n.sessionId&&t.attachSdkSessionId(i.id,n.sessionId);return}let a=t.get(s);if(a&&a.status==="active"){t.bind(s,{surface:"telegram",key:o}),n.sessionId&&t.attachSdkSessionId(s,n.sessionId);return}let c=a===void 0?s:void 0;t.create({surface:"telegram",key:o,model:n.model??r,id:c,sdkSessionId:n.sessionId})}function Mf(t,e){t.archive(e)}import{promises as xs}from"fs";import{join as WS}from"path";function qe(t){return typeof t=="number"?{chatId:t}:t}var bc=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,registry:e.registry}}getSessionIfExists(e){return this.sessions.get(X(qe(e)))}async getSession(e){let n=qe(e),r=X(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,telegramChatId:n.chatId,...n.threadId!==void 0?{telegramThreadId:n.threadId}:{}};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=Xt(d);Object.assign(c,BS({id:d,resumeId:p?.sessionId??d,stored:p}))}let u=await this.options.createSession(Ef(Sf(c)));this.sessions.set(r,u),this.sessionData.set(r,i);try{this._ensureRegistryHandle(n,i)}catch{}return u.sessionId&&(xf(u.sessionId,n),i.sessionId=u.sessionId),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())}_ensureRegistryHandle(e,n){HS(this.options.registry??hc,e,n,this.options.defaultModel)}recordTelegramTurn(e,n,r,o){let s=qe(e),i=X(s),a=this._getOrCreateStats(s),c=this.sessions.get(i);!a.sessionId&&c?.sessionId&&(a.sessionId=c.sessionId),DS(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&&xf(a.sessionId,s),a.sessionId)try{Cf(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=X(e);if(this.sessionStats.has(n))return;let r=this.sessionData.get(n)?.sessionId;if(!r)return;let o=Xt(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=qe(e);return this._hydrateStatsFromStore(n),this.sessionStats.get(X(n))?.name}setSessionName(e,n){let r=qe(e),o=X(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),Cf(s),{persisted:!0}}return{persisted:!1}}_getOrCreateStats(e){let n=X(e);this._hydrateStatsFromStore(e);let r=this.sessionStats.get(n);if(!r){r=OS(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){let n=this.sessionStats.get(e)?.sessionId??this.sessionData.get(e)?.sessionId;n&&MS(n),this.sessionStats.delete(e),this.autosaveFailureLogged.delete(e),this.pendingResume.delete(e);let r=this.sessionData.get(e);r&&delete r.sessionId}async resetSession(e){let n=qe(e),r=X(n);try{Mf(this.options.registry??hc,r)}catch{}let o=this.sessions.get(r);o&&(await o.close(),this.sessions.delete(r)),this._resetStats(r);let s=this.sessionData.get(r);s&&(s.lastActivity=new Date().toISOString())}async switchModel(e,n){let r=qe(e),o=X(r);try{Mf(this.options.registry??hc,o)}catch{}let 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));try{this._ensureRegistryHandle(r,i)}catch{}}getModel(e){return this.sessionData.get(X(qe(e)))?.model||this.options.defaultModel}async setCwd(e,n){let r=qe(e),o=X(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(X(qe(e)))?.cwd??this.options.botCwd}listChatSessions(e){let n=qe(e),r=this.sessionData.get(X(n))?.sessionId;return Br().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=qe(e),o=X(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=Xt(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(X(qe(e))),await this.resetSession(e)}sidecarFileName(e){let n={chatId:e.chatId};return e.threadId!==void 0&&(n.threadId=e.threadId),`${X(n)}.json`}async loadSessions(){try{await xs.mkdir(this.options.dataDir,{recursive:!0});let e=await xs.readdir(this.options.dataDir);for(let n of e)if(n.endsWith(".json")){let r=WS(this.options.dataDir,n),o=await xs.readFile(r,"utf-8"),s=JSON.parse(o),i={chatId:s.chatId};s.threadId!==void 0&&(i.threadId=s.threadId),this.sessionData.set(X(i),s);try{this._ensureRegistryHandle(i,s)}catch{}}}catch(e){e.code!=="ENOENT"&&console.error("Failed to load sessions:",e)}}async saveSessions(){try{await xs.mkdir(this.options.dataDir,{recursive:!0});for(let e of this.sessionData.values()){let n=WS(this.options.dataDir,this.sidecarFileName(e));await xs.writeFile(n,JSON.stringify(e,null,2))}}catch(e){console.error("Failed to save sessions:",e)}}_evictStaleSessionData(e=1440*60*1e3){let n=Date.now();for(let[r,o]of this.sessionData){if(this.sessions.has(r))continue;n-new Date(o.lastActivity).getTime()>e&&this.sessionData.delete(r)}}async closeAll(){this._evictStaleSessionData(),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}getActiveThreadId(e){let n;for(let r of this.sessionData.values())r.chatId!==e||r.threadId===void 0||(n===void 0||r.lastActivity>n.lastActivity)&&(n=r);return n?.threadId}getBusySessionCount(){let e=0;for(let n of this.sessions.values())n.state!=="idle"&&n.state!=="closed"&&e++;return e}};Ue();Ue();async function Ff(t){await t.reply(qS())}Ue();async function Lf(t,e){let n=se(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(GS(r))}ie();import{Markup as fF}from"telegraf";import{promises as x8}from"fs";import{homedir as mF}from"os";import{isAbsolute as R8,resolve as zb}from"path";async function Is(t,e){t.sendChatAction("typing").catch(()=>{});let n=setInterval(()=>{t.sendChatAction("typing").catch(()=>{})},4e3);try{return await e()}finally{clearInterval(n)}}Ue();ue();Ie();ve();Mi();Mr();function E8(t,e){try{if(!t||t.trim().toLowerCase()==="auto")return{available:!0,needs:"unknown"};let n=Kn(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=Tn(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=dt(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=dt(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=G(t,e?{slots:e}:void 0);if(r==="anthropic-direct"){let o=!!ai();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=!!hl()||Tn(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=dt(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 cF(t,e){return E8(t,e).available}Ie();var T8=/^[A-Za-z0-9_@%+=:,./-]+$/;function lF(t){return T8.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}function dF(t,e){let n=["afk","interactive"];return typeof e=="string"&&e.length>0&&n.push("--model",lF(e)),n.push("--resume",lF(t)),n.join(" ")}ue();Ie();function uF(t){if(Wn.includes(t)||Gr(t)!==void 0)return!0;let e=G(t);if(e==="openai-compatible"||e==="xai"||e==="xai-oauth")return!0;let n=Kn(t).id.trim().toLowerCase();return n.startsWith("claude-")||n.startsWith("claude_")}function pF(t){return uF(t)}async function Vb(t,e,n,r){let o=se(t);if(!o){await t.reply(z("Could not identify chat"));return}try{await e.resetSession(o),n.delete(o.chatId),await t.reply(vc())}catch(s){r("Clear error:",s),await t.reply(z(s))}}async function gF(t,e,n){let r=se(t);if(!r){await t.reply(z("Could not identify chat"));return}try{let o=await e.getSession(r),s=o.hookRegistry,i=await Is(t,async()=>(s&&await s.dispatch({event:"PreCompact",sessionId:o.sessionId,trigger:"manual"}),o.compact()));i.compacted?await t.reply(kc({before:i.messagesBefore,after:i.messagesAfter,...i.tokensSavedEstimate!==void 0?{tokensSavedEstimate:i.tokensSavedEstimate}:{}})):await t.reply(Ac(i.reason??"unknown"))}catch(o){o instanceof Y?await t.reply(`Compaction skipped: ${Xe(o.reason??"blocked by hook")}`):(n("Compact error:",o),await t.reply(z(o)))}}async function Jb(t,e,n){let r=se(t);if(!r){await t.reply(z("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1);if(s.length===0){let l=e.getModel(r),d=Wn.map(u=>[fF.button.callback(cF(u)?u:`${u} \u2014 needs sign-in`,`afk:m:${u}`)]);await t.reply(`Current model: <b>${Xe(l.toUpperCase())}</b>
1289
1289
 
1290
1290
  Switch to:`,{parse_mode:"HTML",reply_markup:fF.inlineKeyboard(d).reply_markup});return}let i=s[0];if(!i){await t.reply(z("Please specify a model: local, small, medium, large, opus, sonnet, haiku, or an org/model id"));return}let a=i.toLowerCase();if(!pF(a)){await t.reply(z(`Invalid model: ${i}
1291
1291
  Aliases: ${Wn.join(", ")}, or a full model id`));return}let c=pv(a);if(c){await t.reply(z(c));return}try{await e.switchModel(r,a),await t.reply(Sc(a))}catch(l){n("Model switch error:",l),await t.reply(z(l))}}function I8(t,e){let n=t.trim();return n==="~"?mF():n.startsWith("~/")?zb(mF(),n.slice(2)):R8(n)?zb(n):zb(e,n)}async function hF(t,e,n){let r=se(t);if(!r){await t.reply(z("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(XS(l));return}let i=s[0];if(!i){await t.reply(z("Please specify a directory path"));return}let a=e.getCwd(r)??process.cwd(),c=I8(i,a);try{if(!(await x8.stat(c)).isDirectory()){await t.reply(z(`Not a directory: ${c}`));return}}catch(l){let d=l.code;d==="ENOENT"?await t.reply(Of("ENOENT",c)):d==="EACCES"?await t.reply(Of("EACCES",c)):(n("cwd stat error:",l),await t.reply(z(l)));return}try{await e.setCwd(r,c),await t.reply(zS(c))}catch(l){n("Cwd switch error:",l),await t.reply(z(l))}}async function yF(t,e,n){let r=se(t);if(!r){await t.reply(z("Could not identify chat"));return}let s=t.message.text.split(/\s+/).slice(1).join(" ").trim();if(!s){await t.reply(VS(e.getSessionName(r)));return}let i=gc(s);if(!i){await t.reply(JS());return}try{let{persisted:a}=e.setSessionName(r,i),c=a?dF(i,e.getModel(r)):void 0;await t.reply(YS(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 bF}from"telegraf";Ue();var Rp="afk:sw:",C8=64;function P8(t){let e=t.callbackQuery;return typeof e=="object"&&e!==null&&"data"in e?e.data:""}function wF(t,e){let n=t.getSessionIfExists(e);return n!==void 0&&n.state!=="idle"}async function SF(t,e,n){let r=se(t);if(!r){await t.reply(z("Could not identify chat"));return}let o=e.listChatSessions(r);if(o.length===0){await t.reply(ev());return}let s=o.filter(i=>(Rp+i.sessionId).length<=C8).map(i=>[bF.button.callback(`${i.active?"\u2705 ":""}${i.name??"(unnamed)"} \xB7 ${i.turns} turns`,`${Rp}${i.sessionId}`)]);await t.reply(ZS(o),{parse_mode:"HTML",reply_markup:bF.inlineKeyboard(s).reply_markup})}async function vF(t,e,n,r){let o=se(t);if(!o){await t.reply(z("Could not identify chat"));return}if(wF(e,o)){await t.reply(Df());return}try{await e.newSession(o),n.delete(o.chatId),await t.reply(nv())}catch(s){r("New session error:",s),await t.reply(z(s))}}async function kF(t,e,n){let r=se(t),o=P8(t),s=o.startsWith(Rp)?o.slice(Rp.length):"";if(!(!r||!s)){if(wF(e,r)){await t.reply(Df());return}try{let i=await e.switchToSession(r,s);if(!i.ok){await t.reply(i.reason==="already-active"?ov():rv());return}let a=tv(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(z(i))}}}Ue();var M8="\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.",O8="\u25CB AFK mode OFF \u2014 default permissions restored.";async function AF(t,e,n){let r=se(t);if(!r){await t.reply(z("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?M8:O8)}catch(i){n("AFK toggle error:",i),await t.reply(z("Could not toggle AFK mode"))}}co();U();var D8="https://api.anthropic.com/api/oauth/usage",F8="oauth-2025-04-20",L8=1e4;async function _F(t){let e=t?.fetchImpl??fetch,n=t?.timeoutMs??L8,r=t?.token??(S.CLAUDE_CODE_OAUTH_TOKEN||Be());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(D8,{headers:{Authorization:`Bearer ${r}`,"anthropic-beta":F8},signal:AbortSignal.timeout(n)})}catch(u){return N8(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=Ip(i.five_hour),c=Ip(i.seven_day),l=Ip(i.seven_day_sonnet),d=Ip(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 N8(t){return t instanceof Error&&(t.name==="TimeoutError"||t.name==="AbortError")}var U8=0,$8=4102444800;function B8(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<U8||t>$8?void 0:new Date(t*1e3)}function Ip(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=B8(e.resets_at);return{utilization:o,...s!==void 0?{resetsAt:s}:{}}}Ue();async function EF(t,e){try{let n=await _F();await t.reply(KS(n))}catch(n){e("Usage command error:",n),await t.reply(z("Could not fetch usage"))}}import{execFile as o3,spawn as s3}from"node:child_process";import{promisify as i3}from"node:util";j();import{execFile as j8}from"node:child_process";import{randomBytes as H8}from"node:crypto";import{promises as Cp}from"node:fs";import{join as Pp}from"node:path";import{promisify as W8}from"node:util";var EOe=W8(j8);var Nn=class extends Error{cause;code;constructor(e,n,r){super(e),this.name="WorktreeError",this.cause=n,this.code=r}};function K8(t,e=40){return t.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,e).replace(/-+$/g,"")||"task"}function G8(){return H8(4).toString("hex").slice(0,4)}function q8(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 TF(t,e={}){let n=(e.now??(()=>new Date))(),r=(e.randomSuffix??G8)();return`${q8(n)}-${K8(t,32)}-${r}`}function X8(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 rs(t){let e=Pp(Xw(t),"farm.json");try{let n=await Cp.readFile(e,"utf8"),r=JSON.parse(n);if(r.schemaVersion!==1&&r.schemaVersion!==2&&r.schemaVersion!==3)throw new Nn(`unsupported farm manifest schema: ${r.schemaVersion} (expected 1, 2, or 3)`,void 0,"unsupported-schema");return X8(r)}catch(n){if(n.code==="ENOENT")return null;throw n instanceof Nn?n:new Nn(`failed to load farm manifest ${e}`,n,"invalid")}}async function xF(t,e){let n=await rs(t);if(!n)throw new Nn(`farm not found: ${t}`);return n.human_decision=e,n.decidedAt=new Date().toISOString(),n.schemaVersion=3,await Cp.writeFile(Pp(n.farmDir,"farm.json"),JSON.stringify(n,null,2)+`
@@ -1366,7 +1366,7 @@ Enter a number${k}`}I&&(l.allowSkip?v+=`
1366
1366
  model: ${t.model}${t.cwd?`
1367
1367
  cwd: ${t.cwd}`:""}`;case"user":return`\u{1F464} ${Fa(t.text,vL)}`;case"assistant":return`\u{1F916} ${Fa(t.text,vL)}`;case"tool":return`\u{1F527} ${t.toolName}(${Fa(t.input,pw)})`;case"tool_error":return`\u26A0\uFE0F tool failed: ${Fa(t.content,pw)}`;case"done":{let e=[];return typeof t.durationMs=="number"&&e.push(`${(t.durationMs/1e3).toFixed(1)}s`),typeof t.costUsd=="number"&&e.push(`$${t.costUsd.toFixed(4)}`),`\u2705 turn done${e.length?` (${e.join(", ")})`:""}`}case"error":return`\u274C error: ${Fa(t.message,pw)}`;case"paused":return`\u23F8\uFE0F paused on usage limit${t.resetsAt?` (resets ${t.resetsAt})`:""}`;case"resumed":return"\u25B6\uFE0F resumed";case"closed":return`\u{1F3C1} session closed${t.reason?` (${t.reason})`:""} \u2014 watch ended`;default:return null}}async function kL(t){let e=Pf(t);return e?.data.sessionId&&await Yl(e.data.sessionId)?e.data.sessionId:await Yl(t)?t:null}async function AL(){let t=[],n=(await Vs()).filter(s=>s.surface!=="telegram");if(n.length>0){t.push("\u{1F7E2} Live sessions:");for(let s of n)t.push(` ${s.sessionId} (${s.surface}, ${s.cwd})`)}let r=Br().filter(s=>s.source!=="telegram").slice(0,8),o=[];for(let s of r)s.sessionId&&await Yl(s.sessionId)&&o.push(` ${s.name??s.id} (${s.model})`);return o.length>0&&(t.length>0&&t.push(""),t.push("\u{1F4BE} Recent sessions with activity logs:",...o)),t.length===0?"No watchable sessions found. Start one with `afk i` on your machine, then /watch <session-id-or-name>.":(t.push("","Watch one with /watch <session-id-or-name>."),t.join(`
1368
1368
  `))}var Vp=class{watches=new Map;log;bot;messageHandler;elicitHeartbeatMs;constructor(e=()=>{},n,r,o=SQ){this.log=e,this.bot=n,this.messageHandler=r,this.elicitHeartbeatMs=o}watching(e){return this.watches.get(e)?.sessionId}getWatched(e){return this.watches.get(e)?.sessionId}start(e,n,r){this.stop(e);let o=new AbortController,s=this._run(e,n,r,o.signal).catch(i=>{this.log("watch loop error:",i)});this.watches.set(e,{sessionId:n,abort:o,finished:s})}stop(e){let n=this.watches.get(e);if(n)return this.watches.delete(e),n.abort.abort(),n.sessionId}async stopAll(){let e=[...this.watches.values()];this.watches.clear();for(let n of e)n.abort.abort();await Promise.allSettled(e.map(n=>n.finished))}async _run(e,n,r,o){let s=[],i=null,a=Promise.resolve(),c=this.bot!==void 0&&this.messageHandler!==void 0?qp(Kp(this.messageHandler,this.bot,e,{ledgerOriginated:!0}),Gp(this.bot,new Set([e]),(...d)=>this.log("[elicitation]",...d))):void 0,l=()=>{if(i=null,s.length===0)return;let d=s.join(`
1369
- `);s=[],a=a.then(()=>r(d)).catch(u=>this.log("watch send error:",u))};try{for await(let d of UT(n,{signal:o})){if(d.kind==="elicitation"&&c!==void 0){i&&clearTimeout(i),l(),await a;let p=Date.now(),f=0,m=setInterval(()=>{if(f>=vQ){clearInterval(m);return}f+=1;let w=Math.round((Date.now()-p)/6e4);r(`\u23F3 Still waiting on your answer (${w}m elapsed) \u2014 no deadline, reply above whenever you're ready. (Send /unwatch to stop watching this session.)`).catch(()=>{})},this.elicitHeartbeatMs);m.unref?.();let h=await(async()=>{try{return await c(d.request,{signal:o})}finally{clearInterval(m)}})(),y=zp(n);if(y!==null){let w=bL(y,n,d.reqId,h);new wn(n).record({kind:"elicitation_response",reqId:d.reqId,result:h,hmac:w})}else this.log("[watch] no session key for",n,"\u2014 skipping elicitation write-back");continue}let u=kQ(d);if(u){if(s.push(u),d.kind==="closed"){l();break}i||(i=setTimeout(l,wQ),i.unref?.())}}i&&clearTimeout(i),l(),await a}finally{i&&clearTimeout(i);let d=this.watches.get(e);d&&d.sessionId===n&&d.abort.signal===o&&this.watches.delete(e)}}};rr();Si();Ue();ho();var Jp=class t{bot;sessionManager;options;running=!1;registeredCommandChats=new Set;messageHandler;watchManager;autoSubscribeInterval=null;static AUTO_SUBSCRIBE_INTERVAL_MS=5e3;constructor(e){this.options=e,this.bot=new AQ(e.botToken,{handlerTimeout:1/0}),this.sessionManager=new bc(e),this.messageHandler=new jp(this.bot,this.sessionManager,this.registeredCommandChats,this.log.bind(this),e.tagOnlyChats??new Set),this.watchManager=new Vp(this.log.bind(this),this.bot,this.messageHandler),this.setupHandlers()}setupHandlers(){this.bot.use(RA(this.options.allowedChatIds,this.log.bind(this))),this.bot.command("start",r=>Ff(r)),this.bot.command("help",r=>Lf(r,this.sessionManager)),this.bot.command("clear",async r=>{let o=se(r);if(!o){await r.reply(z("Could not identify chat"));return}(await this.sessionManager.getSession(o)).state!=="idle"?(this.messageHandler.enqueueClear(o,r),await r.reply("Clear queued.")):await Vb(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}),this.bot.command("compact",async r=>{let o=se(r);if(!o){await r.reply(z("Could not identify chat"));return}if((await this.sessionManager.getSession(o)).state!=="idle")this.messageHandler.enqueueCompact(o,r),await r.reply("Compact queued.");else try{await gF(r,this.sessionManager,this.log.bind(this))}finally{this.messageHandler.drainQueue(o).catch(i=>this.log("Drain error:",i))}}),this.bot.command("model",r=>Jb(r,this.sessionManager,this.log.bind(this))),this.bot.command(["cd","cwd"],r=>hF(r,this.sessionManager,this.log.bind(this))),this.bot.command("name",r=>yF(r,this.sessionManager,this.log.bind(this))),this.bot.command("afk",r=>AF(r,this.sessionManager,this.log.bind(this))),this.bot.command("usage",r=>EF(r,this.log.bind(this))),this.bot.command("sessions",r=>SF(r,this.sessionManager,this.log.bind(this))),this.bot.command("new",r=>vF(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))),this.bot.command("watch",async r=>{let o=se(r);if(!o){await r.reply(z("Could not identify chat"));return}let{chatId:s}=o,i=jn(o),c=((r.message&&"text"in r.message?r.message.text:"")??"").split(/\s+/).slice(1).join(" ").trim();try{if(!c){await r.reply(await AL());return}let l=await kL(c);if(!l){await r.reply(`No session ledger found for "${c}". Use /watch with no argument to list watchable sessions.`);return}let d=async u=>{for(let p of ze(u))await r.telegram.sendMessage(s,p,i)};this.watchManager.start(s,l,d),await r.reply(`\u{1F4E1} Watching ${l} \u2014 new activity will stream here. /unwatch to stop.`)}catch(l){this.log("Watch error:",l),await r.reply(z(l))}}),this.bot.command("unwatch",async r=>{let o=r.chat?.id;if(!o){await r.reply(z("Could not identify chat"));return}let s=this.watchManager.stop(o);await r.reply(s?`Stopped watching ${s}.`:"Not watching anything.")}),this.bot.command("abort",async r=>{let o=r.chat?.id;if(!o){await r.reply(z("Could not identify chat"));return}let s=this.watchManager.getWatched(o);if(!s){await r.reply("Not watching any session. Use /watch <session-id> to watch a REPL session first, then /abort to stop it.");return}let i=zp(s);if(i===null){await r.reply("Session key not found \u2014 the REPL may not have enabled AFK mode (/afk on). Cannot send a verified abort.");return}let a=SL(),c=wL(i,s,a);new wn(s).record({kind:"abort_request",nonce:a,hmac:c}),await r.reply(`\u270B Abort sent to session ${s}.`)});let e=r=>{r.catch(o=>{let i=(o instanceof Error?o.message:String(o)).replace(/\/bot[^/]+\//g,"/bot[REDACTED]/");this.log("Detached update handler error:",i)})};this.bot.on("text",r=>e(this.messageHandler.handle(r))),this.bot.on("photo",r=>e(this.messageHandler.handlePhoto(r))),this.bot.on("document",r=>e(this.messageHandler.handleDocument(r)));let n=new RegExp(`^${He(Dp)}`);this.bot.action(n,r=>$F(r,{log:this.log.bind(this)})),this.bot.action(/^afk:m:/,async r=>{if(await r.answerCbQuery().catch(()=>{}),r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))return;let s=(typeof r.callbackQuery=="object"&&"data"in r.callbackQuery?r.callbackQuery.data:"").replace("afk:m:",""),i=se(r);if(!(!i||!s)&&Wn.includes(s))try{await this.sessionManager.switchModel(i,s);let a=Sc(s);await r.editMessageText(a).catch(()=>r.reply(a))}catch(a){this.log("Model action error:",a)}}),this.bot.action(/^afk:sw:/,async r=>{await r.answerCbQuery().catch(()=>{}),!(r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))&&await kF(r,this.sessionManager,this.log.bind(this))}),this.bot.catch((r,o)=>{this.log("Bot error:",r),o.reply(z("An unexpected error occurred. Please try again.")).catch(s=>this.log("Failed to send error message:",s))})}async start(){if(this.running)throw new Error("Bot is already running");this.log("Loading sessions..."),await this.sessionManager.loadSessions();let e=[...this.options.allowedChatIds];if(e.length>0){let n=e[0],r=Kp(this.messageHandler,this.bot,n),o=Gp(this.bot,new Set(this.options.allowedChatIds),(...s)=>this.log("[elicitation]",...s));Ye.install(qp(r,o))}await XO(),this.log("Starting bot..."),await this.bot.launch(),this.log("Registering bot commands..."),await this.bot.telegram.setMyCommands([{command:"start",description:"Show welcome and command list"},{command:"help",description:"Show this command list"},{command:"clear",description:"Clear conversation history"},{command:"compact",description:"Compact conversation history"},{command:"model",description:"Switch Claude model (opus/sonnet/haiku)"},{command:"cd",description:"Show or change session working directory"},{command:"name",description:"Show or set the session name"},{command:"afk",description:"Toggle autonomous (AFK) mode for this chat"},{command:"usage",description:"Show Claude subscription usage"},{command:"watch",description:"Live-tail a CLI session from this chat"},{command:"unwatch",description:"Stop watching a session"}]),this.running=!0,this.log("Bot started successfully"),this.startAutoSubscribe()}async stop(){if(this.running){this.log("Stopping bot..."),this.running=!1,this.log("Stopping auto-subscribe loop..."),this.stopAutoSubscribe(),this.log("Uninstalling elicitation handler..."),Ye.uninstall(),this.log("Stopping session watches..."),await this.watchManager.stopAll(),this.log("Closing sessions..."),await this.sessionManager.closeAll(),this.log("Stopping bot polling...");try{this.bot.stop()}catch(e){this.log("Error stopping bot (may not have been started):",e)}this.log("Bot stopped")}}getStats(){return{running:this.running,activeSessions:this.sessionManager.getSessionCount(),totalChats:this.sessionManager.getChatCount()}}getBusySessionCount(){return this.sessionManager.getBusySessionCount()}async handleStart(e){return Ff(e)}async handleHelp(e){return Lf(e,this.sessionManager)}async handleClear(e){let n=se(e);if(!n){await e.reply(z("Could not identify chat"));return}if((await this.sessionManager.getSession(n)).state!=="idle")this.messageHandler.enqueueClear(n,e),await e.reply("Clear queued.");else return Vb(e,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}async handleMessage(e){return this.messageHandler.handle(e)}async handlePhoto(e){return this.messageHandler.handlePhoto(e)}async handleDocument(e){return this.messageHandler.handleDocument(e)}async handleModelSwitch(e){return Jb(e,this.sessionManager,this.log.bind(this))}startAutoSubscribe(){if(this.autoSubscribeInterval!==null)return;let e=()=>{this.runAutoSubscribeTick().catch(n=>this.log("auto-subscribe tick error:",n))};this.autoSubscribeInterval=setInterval(e,t.AUTO_SUBSCRIBE_INTERVAL_MS),this.autoSubscribeInterval.unref?.(),e()}stopAutoSubscribe(){this.autoSubscribeInterval!==null&&(clearInterval(this.autoSubscribeInterval),this.autoSubscribeInterval=null)}async runAutoSubscribeTick(){let e=[...this.options.allowedChatIds];if(e.length===0)return;let n;try{n=await Vs()}catch{return}let r=new Set(n.filter(o=>o.surface==="cli"&&o.afk===!0&&o.sessionId).map(o=>o.sessionId));for(let o of e){let s=this.watchManager.getWatched(o);s!==void 0&&!r.has(s)&&(this.watchManager.stop(o),this.log(`[auto-subscribe] stopped watch for ${s} (afk cleared)`));for(let i of r){if(this.watchManager.watching(o)===i)continue;let a=async c=>{for(let l of ze(c))await this.bot.telegram.sendMessage(o,l,jn({chatId:o}))};this.watchManager.start(o,i,a),this.log(`[auto-subscribe] started watch for ${i} on chat ${o}`);break}}}log(...e){this.options.verbose&&console.log("[TelegramBot]",...e)}};si();$g();j();U();import SFe from"chalk";import N from"chalk";var _Q={brand:N.hex("#E67E4C"),mint:N.hex("#5FE3A1"),goblin:N.hex("#9CB04A"),user:N.cyan,caret:N.hex("#7AA2F7"),tool:N.hex("#DCDCAA"),chrome:N.hex("#B0B8C2"),syntaxString:N.italic.hex("#8AB07A"),toolArg:N.dim.white,thinking:N.italic.hex("#9B8FB5"),success:N.green,error:N.red,warning:N.yellow,plan:N.hex("#9F7CE0"),bypass:N.bold.hex("#FF6AC1"),meta:N.blackBright,info:N.hex("#5BA8FF"),fileRef:N.hex("#56B5A8"),heading:N.bold.white,label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.green,diffRemove:N.red,diffHunk:N.blackBright},AFe={brand:N.hex("#C0562A"),mint:N.hex("#1B9E63"),goblin:N.hex("#6B7D2A"),user:N.hex("#0E7490"),caret:N.hex("#3B5BDB"),tool:N.hex("#7A6E00"),chrome:N.hex("#5A6470"),syntaxString:N.italic.hex("#3F7A3F"),toolArg:N.hex("#6B7280"),thinking:N.italic.hex("#6D5B8E"),success:N.hex("#2E7D32"),error:N.hex("#C62828"),warning:N.hex("#B8860B"),plan:N.hex("#7048C0"),bypass:N.bold.hex("#D6297F"),meta:N.hex("#6B7280"),info:N.hex("#1D6FD6"),fileRef:N.hex("#0F766E"),heading:N.bold.hex("#1F2937"),label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.hex("#2E7D32"),diffRemove:N.hex("#C62828"),diffHunk:N.hex("#6B7280")},_Fe={brand:N.hex("#FF9B5A"),mint:N.hex("#B4FCC3"),goblin:N.hex("#A5AC55"),user:N.hex("#42CBC8"),caret:N.hex("#9DBEFC"),tool:N.hex("#F7D179"),chrome:N.hex("#D3CDC5"),syntaxString:N.italic.hex("#96C182"),toolArg:N.dim.hex("#D3CDC5"),thinking:N.italic.hex("#B49EC4"),success:N.hex("#8AE49E"),error:N.hex("#EF7F74"),warning:N.hex("#D7AA32"),plan:N.hex("#AE93DE"),bypass:N.bold.hex("#FFACE9"),meta:N.hex("#AAA19B"),info:N.hex("#739EF0"),fileRef:N.hex("#80E5E2"),heading:N.bold.hex("#F9F6F2"),label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.hex("#8AE49E"),diffRemove:N.hex("#EF7F74"),diffHunk:N.hex("#AAA19B")};var EQ={..._Q};var TQ="https://api.telegram.org";async function _L(t){try{let e=await fetch(`${TQ}/bot${t}/getMe`);if(!e.ok)return null;let n=await e.json();return!n.ok||!n.result?.id||!n.result?.first_name?null:{id:n.result.id,...n.result.username!==void 0?{username:n.result.username}:{},firstName:n.result.first_name}}catch{return null}}Rt();ue();uo();j();ue();ve();U();uo();function fw(){return`# Agent AFK
1369
+ `);s=[],a=a.then(()=>r(d)).catch(u=>this.log("watch send error:",u))};try{for await(let d of UT(n,{signal:o})){if(d.kind==="elicitation"&&c!==void 0){i&&clearTimeout(i),l(),await a;let p=Date.now(),f=0,m=setInterval(()=>{if(f>=vQ){clearInterval(m);return}f+=1;let w=Math.round((Date.now()-p)/6e4);r(`\u23F3 Still waiting on your answer (${w}m elapsed) \u2014 no deadline, reply above whenever you're ready. (Send /unwatch to stop watching this session.)`).catch(()=>{})},this.elicitHeartbeatMs);m.unref?.();let h=await(async()=>{try{return await c(d.request,{signal:o})}finally{clearInterval(m)}})(),y=zp(n);if(y!==null){let w=bL(y,n,d.reqId,h);new wn(n).record({kind:"elicitation_response",reqId:d.reqId,result:h,hmac:w})}else this.log("[watch] no session key for",n,"\u2014 skipping elicitation write-back");continue}let u=kQ(d);if(u){if(s.push(u),d.kind==="closed"){l();break}i||(i=setTimeout(l,wQ),i.unref?.())}}i&&clearTimeout(i),l(),await a}finally{i&&clearTimeout(i);let d=this.watches.get(e);d&&d.sessionId===n&&d.abort.signal===o&&this.watches.delete(e)}}};rr();Si();Ue();ho();var Jp=class t{bot;sessionManager;options;running=!1;registeredCommandChats=new Set;messageHandler;watchManager;autoSubscribeInterval=null;static AUTO_SUBSCRIBE_INTERVAL_MS=5e3;constructor(e){this.options=e,this.bot=new AQ(e.botToken,{handlerTimeout:1/0}),this.sessionManager=new bc(e),this.messageHandler=new jp(this.bot,this.sessionManager,this.registeredCommandChats,this.log.bind(this),e.tagOnlyChats??new Set),this.watchManager=new Vp(this.log.bind(this),this.bot,this.messageHandler),this.setupHandlers()}setupHandlers(){this.bot.use(RA(this.options.allowedChatIds,this.log.bind(this))),this.bot.command("start",r=>Ff(r)),this.bot.command("help",r=>Lf(r,this.sessionManager)),this.bot.command("clear",async r=>{let o=se(r);if(!o){await r.reply(z("Could not identify chat"));return}(await this.sessionManager.getSession(o)).state!=="idle"?(this.messageHandler.enqueueClear(o,r),await r.reply("Clear queued.")):await Vb(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}),this.bot.command("compact",async r=>{let o=se(r);if(!o){await r.reply(z("Could not identify chat"));return}if((await this.sessionManager.getSession(o)).state!=="idle")this.messageHandler.enqueueCompact(o,r),await r.reply("Compact queued.");else try{await gF(r,this.sessionManager,this.log.bind(this))}finally{this.messageHandler.drainQueue(o).catch(i=>this.log("Drain error:",i))}}),this.bot.command("model",r=>Jb(r,this.sessionManager,this.log.bind(this))),this.bot.command(["cd","cwd"],r=>hF(r,this.sessionManager,this.log.bind(this))),this.bot.command("name",r=>yF(r,this.sessionManager,this.log.bind(this))),this.bot.command("afk",r=>AF(r,this.sessionManager,this.log.bind(this))),this.bot.command("usage",r=>EF(r,this.log.bind(this))),this.bot.command("sessions",r=>SF(r,this.sessionManager,this.log.bind(this))),this.bot.command("new",r=>vF(r,this.sessionManager,this.registeredCommandChats,this.log.bind(this))),this.bot.command("watch",async r=>{let o=se(r);if(!o){await r.reply(z("Could not identify chat"));return}let{chatId:s}=o,i=jn(o),c=((r.message&&"text"in r.message?r.message.text:"")??"").split(/\s+/).slice(1).join(" ").trim();try{if(!c){await r.reply(await AL());return}let l=await kL(c);if(!l){await r.reply(`No session ledger found for "${c}". Use /watch with no argument to list watchable sessions.`);return}let d=async u=>{for(let p of ze(u))await r.telegram.sendMessage(s,p,i)};this.watchManager.start(s,l,d),await r.reply(`\u{1F4E1} Watching ${l} \u2014 new activity will stream here. /unwatch to stop.`)}catch(l){this.log("Watch error:",l),await r.reply(z(l))}}),this.bot.command("unwatch",async r=>{let o=r.chat?.id;if(!o){await r.reply(z("Could not identify chat"));return}let s=this.watchManager.stop(o);await r.reply(s?`Stopped watching ${s}.`:"Not watching anything.")}),this.bot.command("abort",async r=>{let o=r.chat?.id;if(!o){await r.reply(z("Could not identify chat"));return}let s=this.watchManager.getWatched(o);if(!s){await r.reply("Not watching any session. Use /watch <session-id> to watch a REPL session first, then /abort to stop it.");return}let i=zp(s);if(i===null){await r.reply("Session key not found \u2014 the REPL may not have enabled AFK mode (/afk on). Cannot send a verified abort.");return}let a=SL(),c=wL(i,s,a);new wn(s).record({kind:"abort_request",nonce:a,hmac:c}),await r.reply(`\u270B Abort sent to session ${s}.`)});let e=r=>{r.catch(o=>{let i=(o instanceof Error?o.message:String(o)).replace(/\/bot[^/]+\//g,"/bot[REDACTED]/");this.log("Detached update handler error:",i)})};this.bot.on("text",r=>e(this.messageHandler.handle(r))),this.bot.on("photo",r=>e(this.messageHandler.handlePhoto(r))),this.bot.on("document",r=>e(this.messageHandler.handleDocument(r)));let n=new RegExp(`^${He(Dp)}`);this.bot.action(n,r=>$F(r,{log:this.log.bind(this)})),this.bot.action(/^afk:m:/,async r=>{if(await r.answerCbQuery().catch(()=>{}),r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))return;let s=(typeof r.callbackQuery=="object"&&"data"in r.callbackQuery?r.callbackQuery.data:"").replace("afk:m:",""),i=se(r);if(!(!i||!s)&&Wn.includes(s))try{await this.sessionManager.switchModel(i,s);let a=Sc(s);await r.editMessageText(a).catch(()=>r.reply(a))}catch(a){this.log("Model action error:",a)}}),this.bot.action(/^afk:sw:/,async r=>{await r.answerCbQuery().catch(()=>{}),!(r.chat?.id!==void 0&&!this.options.allowedChatIds.has(r.chat.id))&&await kF(r,this.sessionManager,this.log.bind(this))}),this.bot.catch((r,o)=>{this.log("Bot error:",r),o.reply(z("An unexpected error occurred. Please try again.")).catch(s=>this.log("Failed to send error message:",s))})}async start(){if(this.running)throw new Error("Bot is already running");this.log("Loading sessions..."),await this.sessionManager.loadSessions();let e=[...this.options.allowedChatIds];if(e.length>0){let n=e[0],r=Kp(this.messageHandler,this.bot,n),o=Gp(this.bot,new Set(this.options.allowedChatIds),(...s)=>this.log("[elicitation]",...s));Ye.install(qp(r,o))}await XO(),this.log("Starting bot..."),await this.bot.launch(),this.log("Registering bot commands..."),await this.bot.telegram.setMyCommands([{command:"start",description:"Show welcome and command list"},{command:"help",description:"Show this command list"},{command:"clear",description:"Clear conversation history"},{command:"compact",description:"Compact conversation history"},{command:"model",description:"Switch Claude model (opus/sonnet/haiku)"},{command:"cd",description:"Show or change session working directory"},{command:"name",description:"Show or set the session name"},{command:"afk",description:"Toggle autonomous (AFK) mode for this chat"},{command:"usage",description:"Show Claude subscription usage"},{command:"watch",description:"Live-tail a CLI session from this chat"},{command:"unwatch",description:"Stop watching a session"}]),this.running=!0,this.log("Bot started successfully"),this.startAutoSubscribe()}async stop(){if(this.running){this.log("Stopping bot..."),this.running=!1,this.log("Stopping auto-subscribe loop..."),this.stopAutoSubscribe(),this.log("Uninstalling elicitation handler..."),Ye.uninstall(),this.log("Stopping session watches..."),await this.watchManager.stopAll(),this.log("Closing sessions..."),await this.sessionManager.closeAll(),this.log("Stopping bot polling...");try{this.bot.stop()}catch(e){this.log("Error stopping bot (may not have been started):",e)}this.log("Bot stopped")}}getStats(){return{running:this.running,activeSessions:this.sessionManager.getSessionCount(),totalChats:this.sessionManager.getChatCount()}}getBusySessionCount(){return this.sessionManager.getBusySessionCount()}async handleStart(e){return Ff(e)}async handleHelp(e){return Lf(e,this.sessionManager)}async handleClear(e){let n=se(e);if(!n){await e.reply(z("Could not identify chat"));return}if((await this.sessionManager.getSession(n)).state!=="idle")this.messageHandler.enqueueClear(n,e),await e.reply("Clear queued.");else return Vb(e,this.sessionManager,this.registeredCommandChats,this.log.bind(this))}async handleMessage(e){return this.messageHandler.handle(e)}async handlePhoto(e){return this.messageHandler.handlePhoto(e)}async handleDocument(e){return this.messageHandler.handleDocument(e)}async handleModelSwitch(e){return Jb(e,this.sessionManager,this.log.bind(this))}startAutoSubscribe(){if(this.autoSubscribeInterval!==null)return;let e=()=>{this.runAutoSubscribeTick().catch(n=>this.log("auto-subscribe tick error:",n))};this.autoSubscribeInterval=setInterval(e,t.AUTO_SUBSCRIBE_INTERVAL_MS),this.autoSubscribeInterval.unref?.(),e()}stopAutoSubscribe(){this.autoSubscribeInterval!==null&&(clearInterval(this.autoSubscribeInterval),this.autoSubscribeInterval=null)}async runAutoSubscribeTick(){let e=[...this.options.allowedChatIds];if(e.length===0)return;let n;try{n=await Vs()}catch{return}let r=new Set(n.filter(o=>o.surface==="cli"&&o.afk===!0&&o.sessionId).map(o=>o.sessionId));for(let o of e){let s=this.watchManager.getWatched(o);s!==void 0&&!r.has(s)&&(this.watchManager.stop(o),this.log(`[auto-subscribe] stopped watch for ${s} (afk cleared)`));for(let i of r){if(this.watchManager.watching(o)===i)continue;let a=this.sessionManager.getActiveThreadId(o),c=a!==void 0?{chatId:o,threadId:a}:{chatId:o},l=async d=>{for(let u of ze(d))await this.bot.telegram.sendMessage(o,u,jn(c))};this.watchManager.start(o,i,l),this.log(`[auto-subscribe] started watch for ${i} on chat ${o}`);break}}}log(...e){this.options.verbose&&console.log("[TelegramBot]",...e)}};si();$g();j();U();import SFe from"chalk";import N from"chalk";var _Q={brand:N.hex("#E67E4C"),mint:N.hex("#5FE3A1"),goblin:N.hex("#9CB04A"),user:N.cyan,caret:N.hex("#7AA2F7"),tool:N.hex("#DCDCAA"),chrome:N.hex("#B0B8C2"),syntaxString:N.italic.hex("#8AB07A"),toolArg:N.dim.white,thinking:N.italic.hex("#9B8FB5"),success:N.green,error:N.red,warning:N.yellow,plan:N.hex("#9F7CE0"),bypass:N.bold.hex("#FF6AC1"),meta:N.blackBright,info:N.hex("#5BA8FF"),fileRef:N.hex("#56B5A8"),heading:N.bold.white,label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.green,diffRemove:N.red,diffHunk:N.blackBright},AFe={brand:N.hex("#C0562A"),mint:N.hex("#1B9E63"),goblin:N.hex("#6B7D2A"),user:N.hex("#0E7490"),caret:N.hex("#3B5BDB"),tool:N.hex("#7A6E00"),chrome:N.hex("#5A6470"),syntaxString:N.italic.hex("#3F7A3F"),toolArg:N.hex("#6B7280"),thinking:N.italic.hex("#6D5B8E"),success:N.hex("#2E7D32"),error:N.hex("#C62828"),warning:N.hex("#B8860B"),plan:N.hex("#7048C0"),bypass:N.bold.hex("#D6297F"),meta:N.hex("#6B7280"),info:N.hex("#1D6FD6"),fileRef:N.hex("#0F766E"),heading:N.bold.hex("#1F2937"),label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.hex("#2E7D32"),diffRemove:N.hex("#C62828"),diffHunk:N.hex("#6B7280")},_Fe={brand:N.hex("#FF9B5A"),mint:N.hex("#B4FCC3"),goblin:N.hex("#A5AC55"),user:N.hex("#42CBC8"),caret:N.hex("#9DBEFC"),tool:N.hex("#F7D179"),chrome:N.hex("#D3CDC5"),syntaxString:N.italic.hex("#96C182"),toolArg:N.dim.hex("#D3CDC5"),thinking:N.italic.hex("#B49EC4"),success:N.hex("#8AE49E"),error:N.hex("#EF7F74"),warning:N.hex("#D7AA32"),plan:N.hex("#AE93DE"),bypass:N.bold.hex("#FFACE9"),meta:N.hex("#AAA19B"),info:N.hex("#739EF0"),fileRef:N.hex("#80E5E2"),heading:N.bold.hex("#F9F6F2"),label:N.dim,dim:N.dim,bold:N.bold,italic:N.italic,diffAdd:N.hex("#8AE49E"),diffRemove:N.hex("#EF7F74"),diffHunk:N.hex("#AAA19B")};var EQ={..._Q};var TQ="https://api.telegram.org";async function _L(t){try{let e=await fetch(`${TQ}/bot${t}/getMe`);if(!e.ok)return null;let n=await e.json();return!n.ok||!n.result?.id||!n.result?.first_name?null:{id:n.result.id,...n.result.username!==void 0?{username:n.result.username}:{},firstName:n.result.first_name}}catch{return null}}Rt();ue();uo();j();ue();ve();U();uo();function fw(){return`# Agent AFK
1370
1370
 
1371
1371
  ## What this process is
1372
1372