agent-afk 5.3.2 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/facets/schema.d.ts +2 -2
- package/dist/cli.mjs +2 -2
- package/dist/index.d.ts +9 -0
- package/dist/index.mjs +179 -178
- package/dist/telegram.mjs +1 -1
- package/package.json +1 -1
package/dist/telegram.mjs
CHANGED
|
@@ -1052,7 +1052,7 @@ Note: this search ran in basic-regex (BRE) mode, where '|' is a literal pipe \u2
|
|
|
1052
1052
|
`)}}catch(i){if(i instanceof Error){let a=i;return a.code==="ENOENT"?{content:`Directory not found: ${s}`,isError:!0}:a.code==="ENOTDIR"?{content:`Not a directory: ${s}`,isError:!0}:a.code==="EACCES"?{content:`Permission denied: ${s}`,isError:!0}:{content:`Error listing directory: ${i.message}`,isError:!0}}return{content:"Unknown error listing directory",isError:!0}}}});function Ko(t,e=()=>{}){let n=new Set;if(!t)return n;for(let r of t.split(",")){let o=r.trim();if(o){if(!/^-?\d+$/.test(o)){e("[allowlist] Ignoring non-numeric chat ID:",o);continue}n.add(Number(o))}}return n}function Ep(t,e=()=>{}){return async(n,r)=>{let o=n.chat?.id;if(o===void 0||!t.has(o)){e("[allowlist] Rejecting update from chat:",o??"<unknown>");return}await r()}}var Wo=y(()=>{"use strict"});var Ea=y(()=>{"use strict";U();H()});var Ap=y(()=>{"use strict";U();Ea()});import{execFile as uE}from"node:child_process";import{promisify as pE}from"node:util";function xp(t,e){if(t.length>Tp)throw new Error(`Invalid branch prefix from ${e}: length ${t.length} exceeds ${Tp}.`);if(!fE.test(t))throw new Error(`Invalid branch prefix from ${e}: '${t}' \u2014 only [A-Za-z0-9_-./] are allowed.`);if(t.startsWith("-"))throw new Error(`Invalid branch prefix from ${e}: '${t}' \u2014 must not start with '-' (would be parsed by git as a flag).`);return t}function Rp(t,e){if(t.trim().length===0)throw new Error(`Invalid worktree base ref from ${e}: '' \u2014 base ref cannot be empty.`);if(t.startsWith("-"))throw new Error(`Invalid worktree base ref from ${e}: '${t}' \u2014 must not start with '-' (would be parsed by git as a flag).`);if(t.includes("\0"))throw new Error(`Invalid worktree base ref from ${e}: contains a NUL byte.`);if(/\s/.test(t))throw new Error(`Invalid worktree base ref from ${e}: '${t}' \u2014 must not contain whitespace.`)}var LN,fE,Tp,Pp=y(()=>{"use strict";U();Ea();Ap();LN=pE(uE),fE=/^[A-Za-z0-9_\-./]*$/,Tp=64});import{existsSync as Go,readdirSync as UN,readFileSync as mE,realpathSync as BN,statSync as HN}from"fs";import{homedir as gE}from"os";import{join as yt}from"path";function Ta(t){if(t===null||typeof t!="object"||Array.isArray(t))return;let e={};for(let n of Ip){let r=t[n];if(r!==void 0){if(r===!0){e[n]={plugins:!0,skills:!0,mcp:!0};continue}if(r!==!1&&typeof r=="object"&&r!==null&&!Array.isArray(r)){let o=r;e[n]={plugins:o.plugins===!0,skills:o.skills===!0,mcp:o.mcp===!0}}}}return Object.keys(e).length>0?e:void 0}function hE(){return[it(),Br()]}function Jn(t=hE()){for(let e of t)if(Go(e))try{let n=JSON.parse(mE(e,"utf-8")),r=Ta(n.importFrom);if(r!==void 0)return r}catch{}}function Yn(t,e=gE()){let n={pluginRoots:[],skillRoots:[],mcpConfigs:[]};if(!t)return n;for(let r of Ip){let o=t[r];if(!o)continue;let s=Aa[r];if(o.plugins)for(let i of s.pluginRoots(e))Go(i)&&n.pluginRoots.push(i);if(o.skills){let i=`imported:${r}`;for(let a of s.skillRoots(e))Go(a)&&n.skillRoots.push({dir:a,origin:i})}if(o.mcp){let i=yE(s.mcpConfigCandidates(e));i&&n.mcpConfigs.push({source:i,format:s.mcpFormat})}}return n}function yE(t){for(let e of t)if(Go(e))return e;return null}var Ip,Aa,GN,qo=y(()=>{"use strict";H();Ip=["claude-code","codex"],Aa={"claude-code":{label:"Claude Code",pluginRoots:t=>[yt(t,".claude","plugins")],skillRoots:t=>[yt(t,".claude","skills")],mcpConfigCandidates:t=>[yt(t,".claude","mcp.json"),yt(t,".claude",".mcp.json"),yt(t,".claude","claude-code","mcp.json")],mcpFormat:"json"},codex:{label:"Codex",pluginRoots:t=>[yt(t,".codex","plugins")],skillRoots:t=>[yt(t,".codex","skills")],mcpConfigCandidates:t=>[yt(t,".codex","config.toml")],mcpFormat:"toml"}},GN={"claude-code":Aa["claude-code"].label,codex:Aa.codex.label}});import{readFileSync as Op,existsSync as Ra}from"fs";import{join as Qn}from"path";import{config as bE}from"dotenv";function Pa(){return Qi()}function vE(t){let e=t.trim();if(!e)return e;let n="/chat/completions";if(e.endsWith(n)){let r=e.slice(0,-n.length);return Mp.has(e)||(Mp.add(e),console.warn(`[afk] AFK_OPENAI_BASE_URL: stripped trailing "/chat/completions" \u2014 the OpenAI SDK appends it automatically.
|
|
1053
1053
|
Effective base URL: ${r}`)),r}return e}function SE(){if(xa!==void 0)return xa;if(!Cp){let o=[Qn(process.cwd(),".env"),_t(),rd()];for(let s of o)Ra(s)&&bE({path:s,override:!1});Cp=!0}let t={},e=k.AFK_MODEL??k.CLAUDE_MODEL;if(e){let o=e.toLowerCase();t.model=ji(o)?o:e}if(z(e)==="anthropic-direct"){let o=Pa();o!==void 0&&(t.apiKey=o)}let r=k.AFK_LOCAL_BASE_URL;if(r&&r.length>0&&(t.baseUrl=r,t.apiKey=k.AFK_LOCAL_API_KEY||"local"),k.AFK_MAX_TOKENS&&(t.maxTokens=parseInt(k.AFK_MAX_TOKENS,10)),k.AFK_TEMPERATURE&&(t.temperature=parseFloat(k.AFK_TEMPERATURE)),k.AFK_SYSTEM_PROMPT&&(t.systemPrompt=k.AFK_SYSTEM_PROMPT),k.AFK_AUTO_ROUTING){let o=k.AFK_AUTO_ROUTING.toLowerCase()==="true";t.autoRouting={interactive:o,chat:o,telegram:o,daemon:o}}return k.AFK_OPENAI_BASE_URL&&(t.openaiBaseUrl=vE(k.AFK_OPENAI_BASE_URL)),xa=t,t}function Dp(){if(dn!==void 0)return dn;let t=[Qn(process.cwd(),"afk.config.json"),it(),Br()];for(let e of t)if(Ra(e))try{let n=Op(e,"utf-8"),r=JSON.parse(n),o={},s=qd(r.models);if(typeof r.model=="string"&&r.model.length>0){let i=r.model.toLowerCase();o.model=ji(i)?i:r.model}if(typeof r.maxTokens=="number"&&(o.maxTokens=r.maxTokens),typeof r.temperature=="number"&&(o.temperature=r.temperature),r.systemPrompt&&(o.systemPrompt=r.systemPrompt),typeof r.permissionMode=="string"){let i=r.permissionMode;(i==="default"||i==="plan"||i==="autonomous"||i==="bypassPermissions")&&(o.permissionMode=i)}if(r.autoRouting&&typeof r.autoRouting=="object"){let i={};typeof r.autoRouting.interactive=="boolean"&&(i.interactive=r.autoRouting.interactive),typeof r.autoRouting.chat=="boolean"&&(i.chat=r.autoRouting.chat),typeof r.autoRouting.telegram=="boolean"&&(i.telegram=r.autoRouting.telegram),typeof r.autoRouting.daemon=="boolean"&&(i.daemon=r.autoRouting.daemon),o.autoRouting=i}if(r.daemon&&typeof r.daemon=="object"){let i={};typeof r.daemon.task=="string"&&(i.task=r.daemon.task),typeof r.daemon.taskId=="string"&&(i.taskId=r.daemon.taskId);let a=r.daemon.worktreePrune;a&&typeof a=="object"&&(i.worktreePrune={enabled:typeof a.enabled=="boolean"?a.enabled:!0,cron:typeof a.cron=="string"?a.cron:"0 4 * * *",maxAgeDaysClean:typeof a.maxAgeDaysClean=="number"?a.maxAgeDaysClean:14,maxAgeDaysDirty:typeof a.maxAgeDaysDirty=="number"?a.maxAgeDaysDirty:30,scope:typeof a.scope=="string"?a.scope:"all"}),o.daemon=i}if(r.telegram&&typeof r.telegram=="object"){let i={},a=r.telegram.notify;if(a&&typeof a=="object"){let c={};if((a.mode==="primary"||a.mode==="broadcast"||a.mode==="custom")&&(c.mode=a.mode),typeof a.primaryChatId=="number"&&Number.isFinite(a.primaryChatId)&&(c.primaryChatId=a.primaryChatId),Array.isArray(a.targets)){let l=a.targets.filter(d=>typeof d=="number"&&Number.isFinite(d));l.length>0&&(c.targets=l)}i.notify=c}typeof r.telegram.verifyDone=="boolean"&&(i.verifyDone=r.telegram.verifyDone),o.telegram=i}if(r.updatePolicy&&["notify","auto","off"].includes(r.updatePolicy)&&(o.updatePolicy=r.updatePolicy),typeof r.autoResumeOnUsageLimit=="boolean"&&(o.autoResumeOnUsageLimit=r.autoResumeOnUsageLimit),typeof r.bgSummaries=="boolean"&&(o.bgSummaries=r.bgSummaries),typeof r.maxSummaryCallsPerSession=="number"&&(o.maxSummaryCallsPerSession=Math.min(500,Math.max(1,r.maxSummaryCallsPerSession))),r.hooks!==null&&typeof r.hooks=="object"&&!Array.isArray(r.hooks)&&(o.hooks=r.hooks),typeof r.enableShellHooks=="boolean"&&(o.enableShellHooks=r.enableShellHooks),e!==Qn(process.cwd(),"afk.config.json")){let i=Ta(r.importFrom);i!==void 0&&(o.importFrom=i)}if(r.interactive&&typeof r.interactive=="object"){let i={};typeof r.interactive.worktreeAutoname=="boolean"&&(i.worktreeAutoname=r.interactive.worktreeAutoname),typeof r.interactive.worktreeBranchPrefix=="string"&&(i.worktreeBranchPrefix=xp(r.interactive.worktreeBranchPrefix,`${e}#/interactive/worktreeBranchPrefix`)),typeof r.interactive.worktreeBase=="string"&&r.interactive.worktreeBase.trim().length>0&&(Rp(r.interactive.worktreeBase,`${e}#/interactive/worktreeBase`),i.worktreeBase=r.interactive.worktreeBase),typeof r.interactive.suggestGhost=="boolean"&&(i.suggestGhost=r.interactive.suggestGhost),Object.keys(i).length>0&&(o.interactive=i)}return dn={config:o,sourcePath:e,modelsPartial:s},dn}catch(n){console.error(`Warning: Failed to parse ${e}:`,n)}return dn={config:{},sourcePath:void 0,modelsPartial:{}},dn}function kE(){if(un!==void 0)return un.value;let t=[Qn(process.cwd(),"AFK.md"),Qn(ce(),"AFK.md")];for(let e of t)if(Ra(e))try{let n=Op(e,"utf-8").trim();if(n.length>0)return un={value:{content:n,path:e}},un.value}catch{}return un={value:null},un.value}function Fp(){return Dp().config.telegram??{}}function Ia(t){let e=SE(),{config:n,sourcePath:r,modelsPartial:o}=Dp(),s={...Xn,...e,...n,...t},i;if(e.systemPrompt!==void 0)i="env:AFK_SYSTEM_PROMPT";else if(n.systemPrompt!==void 0&&r!==void 0)i=`file:${r}`;else if(s.systemPrompt===void 0){let l=kE();l!==null&&(s.systemPrompt=l.content,i=`afk-md:${l.path}`)}let a={model:s.model??Xn.model,maxTokens:s.maxTokens??Xn.maxTokens,temperature:s.temperature??Xn.temperature,updatePolicy:s.updatePolicy??Xn.updatePolicy,...s.apiKey!==void 0?{apiKey:s.apiKey}:{},...s.baseUrl!==void 0?{baseUrl:s.baseUrl}:{},...s.openaiBaseUrl!==void 0?{openaiBaseUrl:s.openaiBaseUrl}:{},...s.systemPrompt!==void 0?{systemPrompt:s.systemPrompt}:{},...i!==void 0?{systemPromptSource:i}:{},permissionMode:s.permissionMode??wE,...s.autoRouting!==void 0?{autoRouting:s.autoRouting}:{},...s.daemon!==void 0?{daemon:s.daemon}:{},...s.telegram!==void 0?{telegram:s.telegram}:{},...s.bgSummaries!==void 0?{bgSummaries:s.bgSummaries}:{},...s.maxSummaryCallsPerSession!==void 0?{maxSummaryCallsPerSession:s.maxSummaryCallsPerSession}:{},...s.interactive!==void 0?{interactive:s.interactive}:{},...s.hooks!==void 0?{hooks:s.hooks}:{},...s.enableShellHooks!==void 0?{enableShellHooks:s.enableShellHooks}:{},...s.importFrom!==void 0?{importFrom:s.importFrom}:{}},c=t?.models??Ui(o);if(uo(c),a.models=c,typeof a.model=="string"&&a.model.toLowerCase().startsWith("local-")&&(a.baseUrl===void 0||a.baseUrl.length===0))throw new Error(`Model '${a.model}' requires AFK_LOCAL_BASE_URL to be set (e.g. AFK_LOCAL_BASE_URL=http://127.0.0.1:8080). Point it at your local Anthropic-Messages-compatible server.`);return a}var Xn,wE,Cp,xa,Mp,dn,un,Vo=y(()=>{"use strict";De();Ve();we();H();tn();Pp();U();qo();Xn={model:"sonnet",maxTokens:4096,temperature:1,updatePolicy:"notify"},wE="bypassPermissions",Cp=!1;Mp=new Set});function _E(t,e){return e!==void 0&&Number.isFinite(e)&&e!==0?e:t.find(r=>r>0)??t[0]}function EE(t,e={}){let n=[...t],r=e.mode??"primary";if(r==="broadcast")return n;if(r==="custom"){let s=(e.targets??[]).filter(i=>typeof i=="number"&&Number.isFinite(i)&&i!==0);if(s.length>0)return[...new Set(s)]}let o=_E(n,e.primaryChatId);return o!==void 0?[o]:[]}function AE(t){if(!t)return;let e=t.trim();if(!/^-?\d+$/.test(e))return;let n=Number(e);return Number.isFinite(n)&&n!==0?n:void 0}function TE(t){if(!t)return;let e=t.trim().toLowerCase();return e==="primary"||e==="broadcast"||e==="custom"?e:void 0}function xE(){let t=Fp().notify??{},e=t.mode??TE(k.AFK_TELEGRAM_NOTIFY_MODE),n=t.primaryChatId??AE(k.AFK_TELEGRAM_PRIMARY_CHAT_ID);return{...e!==void 0?{mode:e}:{},...n!==void 0?{primaryChatId:n}:{},...t.targets!==void 0?{targets:t.targets}:{}}}function zo(){let t=Ko(k.AFK_TELEGRAM_ALLOWED_CHAT_IDS);return EE(t,xE())}var Ca=y(()=>{"use strict";Wo();Vo();U()});var Np={};bi(Np,{push:()=>pn,pushIfConfigured:()=>PE,pushMarkdown:()=>Lp});async function pn(t){if(!t.token)throw new Error("push: token is required");if(t.chatId===""||t.chatId==null||t.chatId===0)throw new Error("push: chatId is required");let e=t.fetchImpl??fetch,r=`${t.apiBase??RE}/bot${t.token}/sendMessage`,o={chat_id:t.chatId,text:t.text.slice(0,4096)};t.parseMode&&(o.parse_mode=t.parseMode),t.replyMarkup&&(o.reply_markup=t.replyMarkup);let s=new AbortController,i=setTimeout(()=>s.abort(),1e4);try{let a=await e(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o),signal:s.signal});if(a.ok)return{ok:!0,status:a.status};let c;try{c=(await a.json()).description}catch{c=`HTTP ${a.status}`}return{ok:!1,status:a.status,...c!==void 0?{errorMessage:c}:{}}}catch(a){return{ok:!1,status:0,errorMessage:a instanceof Error?a.message:String(a)}}finally{clearTimeout(i)}}async function Lp(t){let e=Et(t.text),n=ye(e),r={ok:!0,status:200};for(let o of n)if(r=await pn({...t,text:o,parseMode:"HTML"}),!r.ok)return r.status===400&&/can't parse entities/i.test(r.errorMessage??"")?pn({...t}):r;return r}async function PE(t,e={}){let n=k.TELEGRAM_BOT_TOKEN;if(!n)return null;let r=zo();if(r.length===0)return null;let o=ye(t),s=[];for(let i of r)for(let a=0;a<o.length;a++){let c={token:n,chatId:i,text:o[a]??"",...e.replyMarkup!==void 0&&a===0?{replyMarkup:e.replyMarkup}:{},...e.fetchImpl!==void 0?{fetchImpl:e.fetchImpl}:{}};s.push(e.markdown?await Lp(c):await pn({...c,...e.parseMode!==void 0?{parseMode:e.parseMode}:{}}))}return s}var RE,Ma=y(()=>{"use strict";Ca();Ce();U();RE="https://api.telegram.org"});function IE(t=pn){return async(e,n)=>{if(!e||typeof e!="object")return{content:"Invalid input: expected an object",isError:!0};let o=e.message;if(typeof o!="string")return{content:"Invalid input: message must be a string",isError:!0};if(o.length===0)return{content:"Invalid input: message must be non-empty",isError:!0};if(o.length>$p)return{content:`Invalid input: message exceeds Telegram's ${$p}-character limit (got ${o.length}). Split into multiple sends or trim before calling.`,isError:!0};let s=k.TELEGRAM_BOT_TOKEN;if(!s)return{content:"Telegram is not configured: TELEGRAM_BOT_TOKEN is not set. Run the bot setup wizard or export the env var before using send_telegram.",isError:!0};let i=zo();if(i.length===0)return{content:"Telegram is not configured: AFK_TELEGRAM_ALLOWED_CHAT_IDS is empty or unset. Add the operator chat ID(s) before using send_telegram.",isError:!0};let a=[];for(let c of i){let l=await t({token:s,chatId:c,text:o});l.ok||a.push(`chat ${c}: ${l.errorMessage??`HTTP ${l.status}`}`)}return a.length===i.length?{content:`Failed to send Telegram message to any chat. ${a.join("; ")}`,isError:!0}:a.length>0?{content:`Sent Telegram message to ${i.length-a.length}/${i.length} chat(s); ${a.length} failed: ${a.join("; ")}`}:{content:i.length===1?`Sent Telegram message to chat ${i[0]}.`:`Sent Telegram message to ${i.length} chats.`}}}var $p,Up,Bp=y(()=>{"use strict";U();Ma();Ca();$p=4096;Up=IE()});import{JSDOM as CE}from"jsdom";import{Readability as ME}from"@mozilla/readability";import OE from"turndown";function Hp(t){return t.replace(/\n{3,}/g,`
|
|
1054
1054
|
|
|
1055
|
-
`).trim()}function DE(t){return(t?.textContent??"").replace(/\s+/g," ").trim().length}function Kp(t,e){let r=new CE(t,{url:e}).window.document,o=(r.title??"").trim(),s=null;try{let l=r.cloneNode(!0);s=new ME(l).parse()}catch{s=null}if(s&&typeof s.content=="string"&&s.content.trim().length>0){let l=Hp(Oa.turndown(s.content)),d=(s.title??"").trim()||o,u=typeof s.length=="number"&&s.length>0?s.length:(s.textContent??"").replace(/\s+/g," ").trim().length;return{title:d,markdown:l,textLength:u,usedFallback:!1}}let i=r.body,a=i?.innerHTML??"",c=Hp(Oa.turndown(a));return{title:o,markdown:c,textLength:DE(i),usedFallback:!0}}var jp,Oa,Wp=y(()=>{"use strict";jp=200,Oa=new OE({headingStyle:"atx",codeBlockStyle:"fenced",bulletListMarker:"-"});Oa.remove(["script","style","noscript","iframe"])});import{readFileSync as FE}from"node:fs";import{join as LE}from"path";function NE(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function Gp(t,e){return NE(e).test(t)}function BE(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($E.has(e))return!0;if(UE.has(e))return!1}return!1}function qp(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function HE(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 jE(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function KE(t){try{return FE(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function WE(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 n}function Vp(t){let e=t?.env??k,n=t?.readFileSync??KE,r=t?.surface??e.AGENT_SURFACE,o=BE(e.AFK_BROWSER_HEADLESS,r),s=qp(e.AFK_BROWSER_ALLOWED_DOMAINS),i=qp(e.AFK_BROWSER_BLOCKED_DOMAINS),a=jE(e.AFK_BROWSER_DOM_SNAPSHOTS),c=HE(e.AFK_BROWSER_BACKEND),l={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null},d=e.AFK_BROWSER_CONFIG,u=d!==void 0&&d.trim()!==""?d.trim():LE(We(),"browser.json"),p=n(u);if(p===void 0)return l;let f;try{f=JSON.parse(p)}catch(g){throw new Error(`Failed to parse browser config at ${u}: ${String(g)}`)}if(typeof f!="object"||f===null||Array.isArray(f))throw new Error(`Browser config at ${u} must be a JSON object`);let h=WE(l,f);return h.configPath=u,h}function Da(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(Gp(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>Gp(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var $E,UE,Fa=y(()=>{"use strict";U();H();$E=new Set(["daemon","subagent","telegram","afk"]),UE=new Set(["repl","interactive","cli"])});import GE from"node:fs";import qE from"node:path";import{chromium as VE}from"playwright";function zE(){try{return"5.3.2"}catch{}try{let t=qE.resolve(import.meta.dirname,"../../../package.json"),e=GE.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var JE,Jo,zp=y(()=>{"use strict";JE=zE(),Jo=class{config;browser;sessions=new Map;launchPromise;shutdownComplete=!1;constructor(e){this.config=e}async ensureBrowser(){return this.browser!==void 0&&this.browser.isConnected()?this.browser:(this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=VE.launch({headless:this.config.headless}).then(e=>(this.browser=e,this.launchPromise=void 0,e)).catch(e=>{throw this.launchPromise=void 0,e}),this.launchPromise))}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s={context:o,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,s),o}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",s,{once:!0});try{let i=await o.newPage(),a=await i.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil}),c=await i.content(),l=i.url(),d=a!==null?a.status():null;return{html:c,finalUrl:l,httpStatus:d}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",s),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${JE}`}}}});import{createHash as YE}from"crypto";function La(t){if(t.length===0)return t;let e=t;for(let{regex:n,name:r}of XE)r==="form-password"?e=e.replace(n,"password=[redacted]"):e=e.replace(n,"[redacted]");return e}function Jp(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&QE.test(t.label))}function Yp(t){return YE("sha256").update(t,"utf8").digest("hex").slice(0,8)}function Xp(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var XE,QE,Zn=y(()=>{"use strict";XE=[{name:"aws-access-key",regex:/AKIA[0-9A-Z]{16}/g},{name:"github-pat",regex:/ghp_[a-zA-Z0-9]{36}/g},{name:"openai-bearer",regex:/sk-[a-zA-Z0-9_-]{20,}/g},{name:"slack-token",regex:/xox[abp]-[a-zA-Z0-9-]{10,}/g},{name:"jwt",regex:/eyJ[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}/g},{name:"form-password",regex:/password=[^&\s]+/gi}];QE=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as ZE}from"node:crypto";function eA(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function tA(t,e,n){return`el_${ZE("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function nA(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Qp(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function ef(t,e){let n=t.role??"",r=t.name??"";Zp.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])ef(s,e)}async function rA(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},tf).catch(()=>[])}async function oA(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 g=s.type;g==="checkbox"?l="checkbox":g==="radio"?l="radio":g==="button"||g==="submit"||g==="reset"?l="button":g==="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,h={role:l,name:c,disabled:p};u!==void 0&&(h.value=u),f!==void 0&&(h.checked=f),o.push(h)}return o},tf).catch(()=>[])}function sA(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Yo(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=sA(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=rA(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,h,g]=await Promise.all([i,a,c,l,d]),v,b=!1;u!==null?(v=[],ef(u,v)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,v=(await oA(t)).filter(F=>Zp.has(F.role??"")));let _=new Map;for(let x of p){let F=Qp(x.name),D=_.get(F);(!D||D.bbox.w===0&&x.bbox.w>0)&&_.set(F,x)}let w=v.map(x=>({ax:x,dom:_.get(Qp(x.name??""))})),S=r?w:w.filter(x=>x.dom?x.dom.bbox.w>0||x.dom.bbox.h>0:!0);S.sort((x,F)=>{let D=x.dom?.bbox.y??0,L=F.dom?.bbox.y??0;if(D!==L)return D-L;let M=x.dom?.bbox.x??0,C=F.dom?.bbox.x??0;return M-C}),S.length>200&&o.push("page has 200+ interactive elements; consider scoping");let E=S.slice(0,n).map((x,F)=>{let D=x.ax.role??"generic",L=x.ax.name??"",M=tA(D,L,F),C=x.dom?.bbox??{x:0,y:0,w:0,h:0},R=x.dom?.type??null,N=null;x.ax.value!==void 0&&x.ax.value!==null&&(N=String(x.ax.value)),x.ax.checked!==void 0&&(N=String(x.ax.checked)),Jp({role:D,kind:R})&&(N="[redacted]");let j={disabled:x.ax.disabled??!1};x.ax.checked!==void 0&&(j.checked=x.ax.checked===!0||x.ax.checked==="mixed"),x.ax.selected!==void 0&&(j.selected=x.ax.selected),x.ax.expanded!==void 0&&(j.expanded=x.ax.expanded);let K;x.dom?.testId?K=`[data-testid="${x.dom.testId}"]`:x.dom?.id&&(K=`#${x.dom.id}`);let Y={id:M,role:D,label:eA(L),kind:R,value:N,state:j,bbox:C};return K!==void 0&&(Y.selector=K),Y}),T="idle";try{let x=await t.evaluate(()=>document.readyState);x==="loading"?T="loading":x==="interactive"?T="navigating":T="idle"}catch{T="navigating"}T!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let P=nA(f),I=`obs_${e.observationCounter.toString(36)}`,O=new Date().toISOString();return{observationId:I,url:h,title:g,textSummary:P,interactive:E,status:{httpStatus:e.httpStatus??null,loadingState:T,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:O}}var Zp,tf,nf=y(()=>{"use strict";Zn();Zp=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);tf="a[href], button, input, select, textarea, [role], [tabindex], label"});async function rf(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 Na(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>rf(t,s)))).filter(o=>o!==null)}async function iA(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 $a(t,e,n){switch(e.kind){case"element_id":return aA(t,e,n);case"selector":return cA(t,e);case"semantic":return lA(t,e)}}async function aA(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 Na(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function cA(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 Na(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function lA(t,e){return e.role!==void 0?dA(t,e.text,e.role):uA(t,e.text,e)}async function dA(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 Na(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function uA(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 iA(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let v=p[g];if(v===void 0)continue;let b=await rf(v.locator,v.index);if(b!==null){let _=`${b.role}:${b.label}:${g}`,w=0;for(let S=0;S<_.length;S++)w=w*31+_.charCodeAt(S)>>>0;f.push({...b,id:`el_${w.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var of=y(()=>{"use strict"});import{randomBytes as pA}from"crypto";import{mkdir as fA,stat as mA,writeFile as gA}from"fs/promises";import{join as Ua}from"path";import{gzip as hA}from"zlib";import{promisify as yA}from"util";function bA(t){return Ua(Ur(t),"browser")}function wA(t){return Ua(bA(t),"screenshots")}function vA(){return new Date().toISOString().replace(/[:.]/g,"-")}function SA(){return pA(3).toString("hex")}async function Ba(t,e,n){if(e.length>sf)throw new Error(`writeScreenshotSidecar: buffer exceeds ${sf} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=wA(t);await fA(r,{recursive:!0});let o=`${vA()}-${SA()}-${n}.png`,s=Ua(r,o);await gA(s,e);let{size:i}=await mA(s);return{path:s,bytes:i}}var K$,sf,af=y(()=>{"use strict";H();Zn();K$=yA(hA);sf=5*1024*1024});var lf={};bi(lf,{PlaywrightProvider:()=>Ha});function cf(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 Ha,df=y(()=>{"use strict";zp();nf();of();Fa();Zn();af();Ha=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Jo(e)}async open(e){let n=Da(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(l){a=l}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let c=await Yo(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,c.interactive,c.url,c.title,"browser_open"),a!==null)throw a;return c}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 Yo(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 $a(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${cf(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":{let g=La(e.value??"");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(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(v){l=v}else l=g}let u=r.url();if(u!==s){let g=Da(u,this.config);if(!g.allowed)return await r.goBack().catch(()=>{}),{outcome:"blocked_by_policy",url:u,reason:g.reason}}let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Yo(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),h=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,h),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})}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 $a(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${cf(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 Ba(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 Ba(n,o,r);return s}catch{return null}}}});var $t={};bi($t,{__resetBrowserRegistryForTests:()=>TA,browserProviderActive:()=>EA,closeBrowserProvider:()=>ja,getBrowserProvider:()=>_A,peekBrowserProvider:()=>AA});function uf(){Promise.resolve(ja()).then(()=>{process.exit(130)})}function pf(){Promise.resolve(ja()).then(()=>{process.exit(143)})}function ff(){Ue=null}function kA(){Xo||(process.on("SIGINT",uf),process.on("SIGTERM",pf),process.on("exit",ff),Xo=!0)}function mf(){Xo&&(process.removeListener("SIGINT",uf),process.removeListener("SIGTERM",pf),process.removeListener("exit",ff),Xo=!1)}async function _A(t){return Ue!==null?Ue:(Nt!==null||(Nt=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(df(),lf)),n=Vp(t),r=new e(n);return kA(),Ue=r,Nt=null,r})()),Nt)}async function ja(){if(Ue===null)return;let t=Ue;Ue=null,Nt=null,mf(),await t.shutdown()}function EA(){return Ue!==null}function AA(){return Ue}function TA(){Ue=null,Nt=null,mf()}var Ue,Nt,Xo,Ut=y(()=>{"use strict";Fa();Ue=null,Nt=null,Xo=!1});function gf(t,e){try{return Kp(t,e)}catch(n){return $("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function CA(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Ut(),$t));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal})}async function hf(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??CA,o=null,s=t,i=null,a=null;try{let l=await n(t,{headers:IA,redirect:"follow",signal:e.signal});i=l.status,s=l.url||t;let d=l.headers.get("content-type")??"";if(l.ok){if(PA.test(d))throw new Error(`web_scrape markdown mode received binary content (${d.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let u=await l.text();if(RA.test(d)&&!xA.test(d))return{title:"",markdown:u.trim(),finalUrl:s,usedRender:!1};o=gf(u,s)}}catch(l){if(e.signal.aborted||l instanceof Error&&l.message.startsWith("web_scrape markdown mode received binary"))throw l;a=l}if(!(o===null||o.textLength<jp)&&o!==null)return{title:o.title,markdown:o.markdown,finalUrl:s,usedRender:!1};try{let l=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal}),d=gf(l.html,l.finalUrl);if(o===null||d.textLength>=o.textLength)return{title:d.title,markdown:d.markdown,finalUrl:l.finalUrl,usedRender:!0}}catch(l){if(e.signal.aborted)throw l;if(o===null){let d=l instanceof Error?l.message:String(l),u=a instanceof Error?a.message:`HTTP ${i??"error"}`,p=new Error(`web_scrape could not retrieve ${t}: fetch failed (${u}) and render failed (${d}).`);throw p.cause=l,p}}if(o!==null)return{title:o.title,markdown:o.markdown,finalUrl:s,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${i??"error"}).`)}var xA,RA,PA,IA,yf=y(()=>{"use strict";Wp();le();xA=/(text\/html|application\/xhtml\+xml)/i,RA=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,PA=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,IA={"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 DA(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(MA,{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),OA),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=xo(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 bf(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?DA({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 wf(t,e){if(e.length===0)return`# Search results for "${t}"
|
|
1055
|
+
`).trim()}function DE(t){return(t?.textContent??"").replace(/\s+/g," ").trim().length}function Kp(t,e){let r=new CE(t,{url:e}).window.document,o=(r.title??"").trim(),s=null;try{let l=r.cloneNode(!0);s=new ME(l).parse()}catch{s=null}if(s&&typeof s.content=="string"&&s.content.trim().length>0){let l=Hp(Oa.turndown(s.content)),d=(s.title??"").trim()||o,u=typeof s.length=="number"&&s.length>0?s.length:(s.textContent??"").replace(/\s+/g," ").trim().length;return{title:d,markdown:l,textLength:u,usedFallback:!1}}let i=r.body,a=i?.innerHTML??"",c=Hp(Oa.turndown(a));return{title:o,markdown:c,textLength:DE(i),usedFallback:!0}}var jp,Oa,Wp=y(()=>{"use strict";jp=200,Oa=new OE({headingStyle:"atx",codeBlockStyle:"fenced",bulletListMarker:"-"});Oa.remove(["script","style","noscript","iframe"])});import{readFileSync as FE}from"node:fs";import{join as LE}from"path";function NE(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function Gp(t,e){return NE(e).test(t)}function BE(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($E.has(e))return!0;if(UE.has(e))return!1}return!1}function qp(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function HE(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 jE(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function KE(t){try{return FE(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function WE(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 n}function Vp(t){let e=t?.env??k,n=t?.readFileSync??KE,r=t?.surface??e.AGENT_SURFACE,o=BE(e.AFK_BROWSER_HEADLESS,r),s=qp(e.AFK_BROWSER_ALLOWED_DOMAINS),i=qp(e.AFK_BROWSER_BLOCKED_DOMAINS),a=jE(e.AFK_BROWSER_DOM_SNAPSHOTS),c=HE(e.AFK_BROWSER_BACKEND),l={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:c,configPath:null},d=e.AFK_BROWSER_CONFIG,u=d!==void 0&&d.trim()!==""?d.trim():LE(We(),"browser.json"),p=n(u);if(p===void 0)return l;let f;try{f=JSON.parse(p)}catch(g){throw new Error(`Failed to parse browser config at ${u}: ${String(g)}`)}if(typeof f!="object"||f===null||Array.isArray(f))throw new Error(`Browser config at ${u} must be a JSON object`);let h=WE(l,f);return h.configPath=u,h}function Da(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(Gp(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>Gp(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var $E,UE,Fa=y(()=>{"use strict";U();H();$E=new Set(["daemon","subagent","telegram","afk"]),UE=new Set(["repl","interactive","cli"])});import GE from"node:fs";import qE from"node:path";import{chromium as VE}from"playwright";function zE(){try{return"5.4.0"}catch{}try{let t=qE.resolve(import.meta.dirname,"../../../package.json"),e=GE.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var JE,Jo,zp=y(()=>{"use strict";JE=zE(),Jo=class{config;browser;sessions=new Map;launchPromise;shutdownComplete=!1;constructor(e){this.config=e}async ensureBrowser(){return this.browser!==void 0&&this.browser.isConnected()?this.browser:(this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=VE.launch({headless:this.config.headless}).then(e=>(this.browser=e,this.launchPromise=void 0,e)).catch(e=>{throw this.launchPromise=void 0,e}),this.launchPromise))}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s={context:o,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,s),o}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",s,{once:!0});try{let i=await o.newPage(),a=await i.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil}),c=await i.content(),l=i.url(),d=a!==null?a.status():null;return{html:c,finalUrl:l,httpStatus:d}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",s),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${JE}`}}}});import{createHash as YE}from"crypto";function La(t){if(t.length===0)return t;let e=t;for(let{regex:n,name:r}of XE)r==="form-password"?e=e.replace(n,"password=[redacted]"):e=e.replace(n,"[redacted]");return e}function Jp(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&QE.test(t.label))}function Yp(t){return YE("sha256").update(t,"utf8").digest("hex").slice(0,8)}function Xp(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var XE,QE,Zn=y(()=>{"use strict";XE=[{name:"aws-access-key",regex:/AKIA[0-9A-Z]{16}/g},{name:"github-pat",regex:/ghp_[a-zA-Z0-9]{36}/g},{name:"openai-bearer",regex:/sk-[a-zA-Z0-9_-]{20,}/g},{name:"slack-token",regex:/xox[abp]-[a-zA-Z0-9-]{10,}/g},{name:"jwt",regex:/eyJ[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}/g},{name:"form-password",regex:/password=[^&\s]+/gi}];QE=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as ZE}from"node:crypto";function eA(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function tA(t,e,n){return`el_${ZE("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function nA(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Qp(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function ef(t,e){let n=t.role??"",r=t.name??"";Zp.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])ef(s,e)}async function rA(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},tf).catch(()=>[])}async function oA(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 g=s.type;g==="checkbox"?l="checkbox":g==="radio"?l="radio":g==="button"||g==="submit"||g==="reset"?l="button":g==="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,h={role:l,name:c,disabled:p};u!==void 0&&(h.value=u),f!==void 0&&(h.checked=f),o.push(h)}return o},tf).catch(()=>[])}function sA(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Yo(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=sA(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=rA(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,h,g]=await Promise.all([i,a,c,l,d]),v,b=!1;u!==null?(v=[],ef(u,v)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,v=(await oA(t)).filter(F=>Zp.has(F.role??"")));let _=new Map;for(let x of p){let F=Qp(x.name),D=_.get(F);(!D||D.bbox.w===0&&x.bbox.w>0)&&_.set(F,x)}let w=v.map(x=>({ax:x,dom:_.get(Qp(x.name??""))})),S=r?w:w.filter(x=>x.dom?x.dom.bbox.w>0||x.dom.bbox.h>0:!0);S.sort((x,F)=>{let D=x.dom?.bbox.y??0,L=F.dom?.bbox.y??0;if(D!==L)return D-L;let M=x.dom?.bbox.x??0,C=F.dom?.bbox.x??0;return M-C}),S.length>200&&o.push("page has 200+ interactive elements; consider scoping");let E=S.slice(0,n).map((x,F)=>{let D=x.ax.role??"generic",L=x.ax.name??"",M=tA(D,L,F),C=x.dom?.bbox??{x:0,y:0,w:0,h:0},R=x.dom?.type??null,N=null;x.ax.value!==void 0&&x.ax.value!==null&&(N=String(x.ax.value)),x.ax.checked!==void 0&&(N=String(x.ax.checked)),Jp({role:D,kind:R})&&(N="[redacted]");let j={disabled:x.ax.disabled??!1};x.ax.checked!==void 0&&(j.checked=x.ax.checked===!0||x.ax.checked==="mixed"),x.ax.selected!==void 0&&(j.selected=x.ax.selected),x.ax.expanded!==void 0&&(j.expanded=x.ax.expanded);let K;x.dom?.testId?K=`[data-testid="${x.dom.testId}"]`:x.dom?.id&&(K=`#${x.dom.id}`);let Y={id:M,role:D,label:eA(L),kind:R,value:N,state:j,bbox:C};return K!==void 0&&(Y.selector=K),Y}),T="idle";try{let x=await t.evaluate(()=>document.readyState);x==="loading"?T="loading":x==="interactive"?T="navigating":T="idle"}catch{T="navigating"}T!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),b&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let P=nA(f),I=`obs_${e.observationCounter.toString(36)}`,O=new Date().toISOString();return{observationId:I,url:h,title:g,textSummary:P,interactive:E,status:{httpStatus:e.httpStatus??null,loadingState:T,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:O}}var Zp,tf,nf=y(()=>{"use strict";Zn();Zp=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);tf="a[href], button, input, select, textarea, [role], [tabindex], label"});async function rf(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 Na(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>rf(t,s)))).filter(o=>o!==null)}async function iA(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 $a(t,e,n){switch(e.kind){case"element_id":return aA(t,e,n);case"selector":return cA(t,e);case"semantic":return lA(t,e)}}async function aA(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 Na(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function cA(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 Na(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function lA(t,e){return e.role!==void 0?dA(t,e.text,e.role):uA(t,e.text,e)}async function dA(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 Na(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function uA(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 iA(d);if(u.length===0)return{outcome:"not_found",query:n};if(u.length===1){let g=u[0];return g===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:g.locator.nth(g.index)}}let p=u.slice(0,5),f=[];for(let g=0;g<p.length;g++){let v=p[g];if(v===void 0)continue;let b=await rf(v.locator,v.index);if(b!==null){let _=`${b.role}:${b.label}:${g}`,w=0;for(let S=0;S<_.length;S++)w=w*31+_.charCodeAt(S)>>>0;f.push({...b,id:`el_${w.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var of=y(()=>{"use strict"});import{randomBytes as pA}from"crypto";import{mkdir as fA,stat as mA,writeFile as gA}from"fs/promises";import{join as Ua}from"path";import{gzip as hA}from"zlib";import{promisify as yA}from"util";function bA(t){return Ua(Ur(t),"browser")}function wA(t){return Ua(bA(t),"screenshots")}function vA(){return new Date().toISOString().replace(/[:.]/g,"-")}function SA(){return pA(3).toString("hex")}async function Ba(t,e,n){if(e.length>sf)throw new Error(`writeScreenshotSidecar: buffer exceeds ${sf} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=wA(t);await fA(r,{recursive:!0});let o=`${vA()}-${SA()}-${n}.png`,s=Ua(r,o);await gA(s,e);let{size:i}=await mA(s);return{path:s,bytes:i}}var K$,sf,af=y(()=>{"use strict";H();Zn();K$=yA(hA);sf=5*1024*1024});var lf={};bi(lf,{PlaywrightProvider:()=>Ha});function cf(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 Ha,df=y(()=>{"use strict";zp();nf();of();Fa();Zn();af();Ha=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Jo(e)}async open(e){let n=Da(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(l){a=l}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let c=await Yo(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,c.interactive,c.url,c.title,"browser_open"),a!==null)throw a;return c}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 Yo(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 $a(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${cf(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":{let g=La(e.value??"");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(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(v){l=v}else l=g}let u=r.url();if(u!==s){let g=Da(u,this.config);if(!g.allowed)return await r.goBack().catch(()=>{}),{outcome:"blocked_by_policy",url:u,reason:g.reason}}let p=null;(e.screenshot===!0||l!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Yo(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),h=`browser_act:${e.action}`;if(this.updateSessionFromObservation(o,f.interactive,f.url,f.title,h),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})}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 $a(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${cf(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 Ba(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 Ba(n,o,r);return s}catch{return null}}}});var $t={};bi($t,{__resetBrowserRegistryForTests:()=>TA,browserProviderActive:()=>EA,closeBrowserProvider:()=>ja,getBrowserProvider:()=>_A,peekBrowserProvider:()=>AA});function uf(){Promise.resolve(ja()).then(()=>{process.exit(130)})}function pf(){Promise.resolve(ja()).then(()=>{process.exit(143)})}function ff(){Ue=null}function kA(){Xo||(process.on("SIGINT",uf),process.on("SIGTERM",pf),process.on("exit",ff),Xo=!0)}function mf(){Xo&&(process.removeListener("SIGINT",uf),process.removeListener("SIGTERM",pf),process.removeListener("exit",ff),Xo=!1)}async function _A(t){return Ue!==null?Ue:(Nt!==null||(Nt=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(df(),lf)),n=Vp(t),r=new e(n);return kA(),Ue=r,Nt=null,r})()),Nt)}async function ja(){if(Ue===null)return;let t=Ue;Ue=null,Nt=null,mf(),await t.shutdown()}function EA(){return Ue!==null}function AA(){return Ue}function TA(){Ue=null,Nt=null,mf()}var Ue,Nt,Xo,Ut=y(()=>{"use strict";Fa();Ue=null,Nt=null,Xo=!1});function gf(t,e){try{return Kp(t,e)}catch(n){return $("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function CA(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Ut(),$t));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal})}async function hf(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??CA,o=null,s=t,i=null,a=null;try{let l=await n(t,{headers:IA,redirect:"follow",signal:e.signal});i=l.status,s=l.url||t;let d=l.headers.get("content-type")??"";if(l.ok){if(PA.test(d))throw new Error(`web_scrape markdown mode received binary content (${d.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let u=await l.text();if(RA.test(d)&&!xA.test(d))return{title:"",markdown:u.trim(),finalUrl:s,usedRender:!1};o=gf(u,s)}}catch(l){if(e.signal.aborted||l instanceof Error&&l.message.startsWith("web_scrape markdown mode received binary"))throw l;a=l}if(!(o===null||o.textLength<jp)&&o!==null)return{title:o.title,markdown:o.markdown,finalUrl:s,usedRender:!1};try{let l=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal}),d=gf(l.html,l.finalUrl);if(o===null||d.textLength>=o.textLength)return{title:d.title,markdown:d.markdown,finalUrl:l.finalUrl,usedRender:!0}}catch(l){if(e.signal.aborted)throw l;if(o===null){let d=l instanceof Error?l.message:String(l),u=a instanceof Error?a.message:`HTTP ${i??"error"}`,p=new Error(`web_scrape could not retrieve ${t}: fetch failed (${u}) and render failed (${d}).`);throw p.cause=l,p}}if(o!==null)return{title:o.title,markdown:o.markdown,finalUrl:s,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${i??"error"}).`)}var xA,RA,PA,IA,yf=y(()=>{"use strict";Wp();le();xA=/(text\/html|application\/xhtml\+xml)/i,RA=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,PA=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,IA={"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 DA(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(MA,{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),OA),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=xo(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 bf(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?DA({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 wf(t,e){if(e.length===0)return`# Search results for "${t}"
|
|
1056
1056
|
|
|
1057
1057
|
(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(`
|
|
1058
1058
|
`).trimEnd()}var MA,OA,vf=y(()=>{"use strict";on();MA="https://api.exa.ai/search",OA=10});function jA(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=FA;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,LA)}let a=NA;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,$A)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Ka(t,e){let n=Buffer.from(t,"utf8");return n.byteLength<=e?t:n.subarray(0,e).toString("utf8")+UA}function KA(t){let e=[],n=t;for(let o=0;o<4&&n instanceof Error;o++)e.push(n.message),n=n.cause;let r=e.join(" | ");return HA.some(o=>r.includes(o))}function WA(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env;return async(r,o)=>{if(typeof e!="function")return{content:"web_scrape unavailable: global fetch() is not present in this runtime (agent-afk requires Node 20+).",isError:!0};let s=jA(r);if("error"in s)return{content:s.error,isError:!0};if(o.aborted){let d=o.reason;return{content:`web_scrape aborted: ${d instanceof Error?d.message:String(d??"aborted")}`,isError:!0}}let i=new AbortController,a=()=>{i.abort(o.reason)},c,l=()=>{let d=i.signal.reason;return d instanceof Error?d.message:String(d??"aborted")};try{if(o.addEventListener("abort",a,{once:!0}),c=setTimeout(()=>{i.abort(new Error(`web_scrape timeout after ${s.timeoutMs}ms`))},s.timeoutMs),s.mode==="raw"){let u;try{u=await e(s.url,{method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:i.signal})}catch(f){return i.signal.aborted?{content:`web_scrape aborted: ${l()}`,isError:!0}:{content:`web_scrape network error: ${f instanceof Error?f.message:String(f)}`,isError:!0}}if(!u.ok)return{content:`web_scrape HTTP ${u.status} ${u.statusText||""}`.trimEnd()+` for ${s.url}`,isError:!0};let p;try{p=await u.text()}catch(f){return{content:`web_scrape read error: ${f instanceof Error?f.message:String(f)}`,isError:!0}}return{content:Ka(p,s.maxBytes)}}if(s.mode==="markdown")try{let u=await hf(s.url,{fetchFn:e,renderFn:t.renderFn,timeoutMs:s.timeoutMs,signal:i.signal});return u.markdown.trim().length===0?{content:`web_scrape extracted no readable content from ${s.url}.`,isError:!0}:{content:Ka(u.markdown,s.maxBytes)}}catch(u){if(i.signal.aborted)return{content:`web_scrape aborted: ${l()}`,isError:!0};let p=u instanceof Error?u.message:String(u),f=KA(u)?" (the render fallback needs the optional Playwright browser \u2014 run `pnpm exec playwright install chromium`)":"";return{content:`web_scrape markdown error: ${p}${f}`,isError:!0}}let d=bf({exaApiKey:n.EXA_API_KEY,fetchFn:e});if("error"in d)return{content:d.error,isError:!0};try{let u=await d.search(s.query,{limit:BA,timeoutMs:s.timeoutMs,signal:i.signal});return{content:Ka(wf(s.query,u),s.maxBytes)}}catch(u){return i.signal.aborted?{content:`web_scrape aborted: ${l()}`,isError:!0}:{content:`web_scrape search error (${d.name}): ${u instanceof Error?u.message:String(u)}`,isError:!0}}}finally{c!==void 0&&clearTimeout(c),o.removeEventListener("abort",a)}}}var FA,LA,NA,$A,UA,BA,HA,Sf,kf=y(()=>{"use strict";yf();vf();FA=3e4,LA=12e4,NA=1e6,$A=1e7,UA=`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-afk",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.0",
|
|
4
4
|
"description": "Open-source coding-agent harness you can actually change — own the loop (prompts, gates, routing, skills, terminal states), use any model, run long tasks while you're away.",
|
|
5
5
|
"main": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|