agent-afk 5.15.1 → 5.15.2

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/cli.mjs CHANGED
@@ -855,7 +855,8 @@ Don't refuse the flow; just clarify where the wizard runs.
855
855
 
856
856
  Be terse and operational. The user is doing one-time setup; they want it done, not narrated. Confirm each step in one line, don't over-explain. Use \`\u2713\` for success, \`\u2717\` for failure, and code fences for any command they should run.
857
857
  `}}});function an(e,t){return t?!0:(e.audience??"public")==="public"}function ht(e){ru.set(e.name,e)}function Ge(e){let t=ru.get(e);if(t)return t;let n=Array.from(ru.keys()).sort(),r=n.length>0?`
858
- Available skills: ${n.join(", ")}`:"";throw new Error(`Skill not found: ${e}${r}`)}function En(){return Array.from(ru.keys()).sort()}function Rg(e){return En().filter(t=>an(Ge(t),e))}var ru,Tt=P(()=>{"use strict";ru=new Map});function SU(e){if(typeof e=="string")return e;if(e instanceof Error)return e.message;try{return JSON.stringify(e)}catch{return String(e)}}var ou,Ok=P(()=>{"use strict";Ne();ou=class{nodes=new Map;traceWriter;constructor(t){this.traceWriter=t}register(t,n){this.nodes.has(t)||this.nodes.set(t,{controller:n,children:new Set,listeners:new Set,cascading:!1})}has(t){return this.nodes.has(t)}getController(t){return this.nodes.get(t)?.controller}childrenOf(t){let n=this.nodes.get(t);return n?Array.from(n.children):[]}linkChild(t,n){let r=this.nodes.get(t),o=this.nodes.get(n);if(!r)throw new Error(`AbortGraph: parent ${t} not registered`);if(!o)throw new Error(`AbortGraph: child ${n} not registered`);if(o.parentId=t,r.children.add(n),r.controller.signal.aborted){o.controller.signal.aborted||(o.cascading=!0,o.controller.abort(r.controller.signal.reason));return}r.controller.signal.addEventListener("abort",()=>{let s=this.nodes.get(n);!s||s.parentId!==t||s.controller.signal.aborted||(s.cascading=!0,s.controller.abort(r.controller.signal.reason))},{once:!0}),o.controller.signal.addEventListener("abort",()=>{let s=this.nodes.get(n);if(!s||s.parentId!==t||s.cascading)return;let i=this.nodes.get(t);if(!i)return;let a={parentId:t,childId:n,reason:s.controller.signal.reason};for(let l of i.listeners)try{l(a)}catch{}},{once:!0})}onChildAborted(t,n){let r=this.nodes.get(t);if(!r)throw new Error(`AbortGraph: ${t} not registered`);return r.listeners.add(n),()=>{r.listeners.delete(n)}}abort(t,n,r="user_signal"){let o=this.nodes.get(t);if(!o||o.controller.signal.aborted)return;let s=[],i=[...o.children],a=new Set;for(;i.length;){let l=i.shift();if(a.has(l))continue;a.add(l);let c=this.nodes.get(l);if(c){c.cascading=!0,s.push(l);for(let u of c.children)i.push(u)}}fk(this.traceWriter,{origin:r,cascadedTo:s,...n!==void 0?{reason:SU(n)}:{}}),o.controller.abort(n);for(let l of s){let c=this.nodes.get(l);c&&!c.controller.signal.aborted&&c.controller.abort(n)}}dispose(t){let n=this.nodes.get(t);if(n){n.parentId&&this.nodes.get(n.parentId)?.children.delete(t);for(let r of n.children){let o=this.nodes.get(r);o&&(o.parentId=void 0)}this.nodes.delete(t)}}}});async function iu(e,t,n={}){if(!Number.isFinite(t)||t<=0)return e;let r,o=new Promise((s,i)=>{r=setTimeout(()=>{let a=n.label?` (${n.label})`:"",l=new Gt(`Operation timed out after ${t}ms${a}`,t);n.controller&&!n.controller.signal.aborted&&n.controller.abort(l),i(l)},t)});try{return await Promise.race([e,o])}finally{r!==void 0&&clearTimeout(r)}}var su,Cg,au=P(()=>{"use strict";vt();su=0,Cg=5e3});function vU(e,t,n){return new Promise((r,o)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,o(new Tn(n,t)))},t);i.unref(),Promise.resolve(e).then(a=>{s||(s=!0,clearTimeout(i),r(a))},a=>{s||(s=!0,clearTimeout(i),o(a))})})}function kU(e){return e.continue===!1||e.decision==="block"}function Ag(e,t){if(e?.aborted){let n=e.reason,r=`aborted during ${t}${n?`: ${String(n)}`:""}`;throw new ut(r)}}function $k(){return new _g}var Co,Tn,_g,Da=P(()=>{"use strict";vt();Co=3e4;Tn=class extends Error{constructor(n,r){super(`hook handler timed out after ${r}ms during ${n}`);this.hookEvent=n;this.timeoutMs=r;this.name="HookHandlerTimeoutError"}hookEvent;timeoutMs;code="HOOK_HANDLER_TIMEOUT"},_g=class{handlers=new Map;register(t,n,r={}){let o=this.handlers.get(t);o||(o=[],this.handlers.set(t,o));let s={handler:n,options:r};return o.push(s),()=>{let i=this.handlers.get(t);if(!i)return;let a=i.indexOf(s);a>=0&&i.splice(a,1)}}count(t){return this.handlers.get(t)?.length??0}async dispatch(t,n,r=Co){Ag(n,t.event);let o=this.handlers.get(t.event);if(!o||o.length===0)return{};let s=o.slice(),i={};for(let a of s){Ag(n,t.event);let l;try{let c=a.handler(t,n);l=!a.options.longRunning&&r>0&&Number.isFinite(r)?await vU(c,r,t.event):await c}catch(c){throw c instanceof Tn?c:new me(`hook handler threw during ${t.event}`,t.event,c instanceof Error?c.message:String(c),{cause:c})}if(Ag(n,t.event),kU(l))throw new me(`hook handler blocked ${t.event}${l.reason?`: ${l.reason}`:""}`,t.event,l.reason);i=l}return i}}});async function xn(e,t,n,r){if(!e)return;if(r.kind==="blocked"){await on(e,{hookEvent:t,decision:"block",...r.err.reason!==void 0?{reason:r.err.reason}:{},...t==="PreToolUse"&&n.toolName!==void 0?{blockedTool:n.toolName}:{}});return}let o=r.decision;await on(e,{hookEvent:t,decision:o.decision,...o.reason!==void 0?{reason:o.reason}:{},...o.injectContext!==void 0?{injectedContextBytes:Buffer.byteLength(o.injectContext,"utf8")}:{}})}async function Dk(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await xn(n.traceWriter,"SubagentStart",{},{kind:"decision",decision:r})}catch(r){throw r instanceof me&&await xn(n.traceWriter,"SubagentStart",{},{kind:"blocked",err:r}),r}}function EU(e,t,n){return new Promise((r,o)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,o(new Tn(n,t)))},t);i.unref(),e.then(a=>{s||(s=!0,clearTimeout(i),r(a))},a=>{s||(s=!0,clearTimeout(i),o(a))})})}async function Fk(e,t,n={}){if(!e)return{};try{let r=await EU(e.dispatch(t,n.signal,Co),Co,"SubagentStop");return await xn(n.traceWriter,"SubagentStop",{},{kind:"decision",decision:r}),r}catch(r){return r instanceof Tn?(console.warn(`[afk] SubagentStop hook timed out after ${Co}ms (subagentId=${t.subagentId}): ${r.message}`),n.onError?.(r),{}):(r instanceof me&&await xn(n.traceWriter,"SubagentStop",{},{kind:"blocked",err:r}),r instanceof me||r instanceof ut?(W(`SubagentStop hook swallowed ${r.name}: ${r.message}`),n.onError?.(r),{}):(W(`SubagentStop hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r))),{}))}}async function Pg(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await xn(n.traceWriter,"PreToolUse",{toolName:t.toolName},{kind:"decision",decision:r})}catch(r){throw r instanceof me&&await xn(n.traceWriter,"PreToolUse",{toolName:t.toolName},{kind:"blocked",err:r}),r}}async function Lk(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await xn(n.traceWriter,"PostToolUse",{toolName:t.toolName},{kind:"decision",decision:r})}catch(r){if(r instanceof me&&await xn(n.traceWriter,"PostToolUse",{toolName:t.toolName},{kind:"blocked",err:r}),r instanceof me||r instanceof ut){W(`PostToolUse hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}W(`PostToolUse hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}async function Nk(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await xn(n.traceWriter,"PostToolUseFailure",{toolName:t.toolName},{kind:"decision",decision:r})}catch(r){if(r instanceof me&&await xn(n.traceWriter,"PostToolUseFailure",{toolName:t.toolName},{kind:"blocked",err:r}),r instanceof me||r instanceof ut){W(`PostToolUseFailure hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}W(`PostToolUseFailure hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}var lu=P(()=>{"use strict";Pe();vt();Da();Ne()});import{mkdir as TU,writeFile as xU}from"fs/promises";import{dirname as RU,join as CU}from"path";function AU(){return CU(Mt(),"routing-decisions.jsonl")}function _U(e){let t={surface:"afk"};for(let[n,r]of Object.entries(e))r!==void 0&&(t[n]=r);return t}async function We(e){if(!(v.VITEST||v.NODE_ENV==="test"))try{let t=AU();await TU(RU(t),{recursive:!0});let n=new Date().toISOString().split(".")[0]+"Z",r=JSON.stringify({ts:n,..._U(e)})+`
858
+ Available skills: ${n.join(", ")}`:"";throw new Error(`Skill not found: ${e}${r}`)}function En(){return Array.from(ru.keys()).sort()}function Rg(e){return En().filter(t=>an(Ge(t),e))}var ru,Tt=P(()=>{"use strict";ru=new Map});function SU(e){if(typeof e=="string")return e;if(e instanceof Error)return e.message;try{return JSON.stringify(e)}catch{return String(e)}}var ou,Ok=P(()=>{"use strict";Ne();ou=class{nodes=new Map;traceWriter;constructor(t){this.traceWriter=t}register(t,n){this.nodes.has(t)||this.nodes.set(t,{controller:n,children:new Set,listeners:new Set,cascading:!1})}has(t){return this.nodes.has(t)}getController(t){return this.nodes.get(t)?.controller}childrenOf(t){let n=this.nodes.get(t);return n?Array.from(n.children):[]}linkChild(t,n){let r=this.nodes.get(t),o=this.nodes.get(n);if(!r)throw new Error(`AbortGraph: parent ${t} not registered`);if(!o)throw new Error(`AbortGraph: child ${n} not registered`);if(o.parentId=t,r.children.add(n),r.controller.signal.aborted){o.controller.signal.aborted||(o.cascading=!0,o.controller.abort(r.controller.signal.reason));return}r.controller.signal.addEventListener("abort",()=>{let s=this.nodes.get(n);!s||s.parentId!==t||s.controller.signal.aborted||(s.cascading=!0,s.controller.abort(r.controller.signal.reason))},{once:!0}),o.controller.signal.addEventListener("abort",()=>{let s=this.nodes.get(n);if(!s||s.parentId!==t||s.cascading)return;let i=this.nodes.get(t);if(!i)return;let a={parentId:t,childId:n,reason:s.controller.signal.reason};for(let l of i.listeners)try{l(a)}catch{}},{once:!0})}onChildAborted(t,n){let r=this.nodes.get(t);if(!r)throw new Error(`AbortGraph: ${t} not registered`);return r.listeners.add(n),()=>{r.listeners.delete(n)}}abort(t,n,r="user_signal"){let o=this.nodes.get(t);if(!o||o.controller.signal.aborted)return;let s=[],i=[...o.children],a=new Set;for(;i.length;){let l=i.shift();if(a.has(l))continue;a.add(l);let c=this.nodes.get(l);if(c){c.cascading=!0,s.push(l);for(let u of c.children)i.push(u)}}fk(this.traceWriter,{origin:r,cascadedTo:s,...n!==void 0?{reason:SU(n)}:{}}),o.controller.abort(n);for(let l of s){let c=this.nodes.get(l);c&&!c.controller.signal.aborted&&c.controller.abort(n)}}dispose(t){let n=this.nodes.get(t);if(n){n.parentId&&this.nodes.get(n.parentId)?.children.delete(t);for(let r of n.children){let o=this.nodes.get(r);o&&(o.parentId=void 0)}this.nodes.delete(t)}}}});async function iu(e,t,n={}){if(!Number.isFinite(t)||t<=0)return e;let r,o=new Promise((s,i)=>{r=setTimeout(()=>{let a=n.label?` (${n.label})`:"",l=new Gt(`Operation timed out after ${t}ms${a}`,t);n.controller&&!n.controller.signal.aborted&&n.controller.abort(l),i(l)},t)});try{return await Promise.race([e,o])}finally{r!==void 0&&clearTimeout(r)}}var su,Cg,au=P(()=>{"use strict";vt();su=0,Cg=5e3});function vU(e,t,n){return new Promise((r,o)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,o(new Tn(n,t)))},t);i.unref(),Promise.resolve(e).then(a=>{s||(s=!0,clearTimeout(i),r(a))},a=>{s||(s=!0,clearTimeout(i),o(a))})})}function kU(e){return e.continue===!1||e.decision==="block"}function Ag(e,t){if(e?.aborted){let n=e.reason,r=`aborted during ${t}${n?`: ${String(n)}`:""}`;throw new ut(r)}}function $k(){return new _g}var Co,Tn,_g,Da=P(()=>{"use strict";vt();Co=3e4;Tn=class extends Error{constructor(n,r){super(`hook handler timed out after ${r}ms during ${n}`);this.hookEvent=n;this.timeoutMs=r;this.name="HookHandlerTimeoutError"}hookEvent;timeoutMs;code="HOOK_HANDLER_TIMEOUT"},_g=class{handlers=new Map;register(t,n,r={}){let o=this.handlers.get(t);o||(o=[],this.handlers.set(t,o));let s={handler:n,options:r};return o.push(s),()=>{let i=this.handlers.get(t);if(!i)return;let a=i.indexOf(s);a>=0&&i.splice(a,1)}}count(t){return this.handlers.get(t)?.length??0}async dispatch(t,n,r=Co){Ag(n,t.event);let o=this.handlers.get(t.event);if(!o||o.length===0)return{};let s=o.slice(),i={};for(let a of s){Ag(n,t.event);let l;try{let u=a.handler(t,n);l=!a.options.longRunning&&r>0&&Number.isFinite(r)?await vU(u,r,t.event):await u}catch(u){throw u instanceof Tn?u:new me(`hook handler threw during ${t.event}`,t.event,u instanceof Error?u.message:String(u),{cause:u})}if(Ag(n,t.event),kU(l))throw new me(`hook handler blocked ${t.event}${l.reason?`: ${l.reason}`:""}`,t.event,l.reason);let c=[i.injectContext,l.injectContext].filter(u=>typeof u=="string"&&u.length>0).join(`
859
+ `);i={...i,...l,...c.length>0?{injectContext:c}:{}}}return i}}});async function xn(e,t,n,r){if(!e)return;if(r.kind==="blocked"){await on(e,{hookEvent:t,decision:"block",...r.err.reason!==void 0?{reason:r.err.reason}:{},...t==="PreToolUse"&&n.toolName!==void 0?{blockedTool:n.toolName}:{}});return}let o=r.decision;await on(e,{hookEvent:t,decision:o.decision,...o.reason!==void 0?{reason:o.reason}:{},...o.injectContext!==void 0?{injectedContextBytes:Buffer.byteLength(o.injectContext,"utf8")}:{}})}async function Dk(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await xn(n.traceWriter,"SubagentStart",{},{kind:"decision",decision:r})}catch(r){throw r instanceof me&&await xn(n.traceWriter,"SubagentStart",{},{kind:"blocked",err:r}),r}}function EU(e,t,n){return new Promise((r,o)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,o(new Tn(n,t)))},t);i.unref(),e.then(a=>{s||(s=!0,clearTimeout(i),r(a))},a=>{s||(s=!0,clearTimeout(i),o(a))})})}async function Fk(e,t,n={}){if(!e)return{};try{let r=await EU(e.dispatch(t,n.signal,Co),Co,"SubagentStop");return await xn(n.traceWriter,"SubagentStop",{},{kind:"decision",decision:r}),r}catch(r){return r instanceof Tn?(console.warn(`[afk] SubagentStop hook timed out after ${Co}ms (subagentId=${t.subagentId}): ${r.message}`),n.onError?.(r),{}):(r instanceof me&&await xn(n.traceWriter,"SubagentStop",{},{kind:"blocked",err:r}),r instanceof me||r instanceof ut?(W(`SubagentStop hook swallowed ${r.name}: ${r.message}`),n.onError?.(r),{}):(W(`SubagentStop hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r))),{}))}}async function Pg(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await xn(n.traceWriter,"PreToolUse",{toolName:t.toolName},{kind:"decision",decision:r})}catch(r){throw r instanceof me&&await xn(n.traceWriter,"PreToolUse",{toolName:t.toolName},{kind:"blocked",err:r}),r}}async function Lk(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await xn(n.traceWriter,"PostToolUse",{toolName:t.toolName},{kind:"decision",decision:r})}catch(r){if(r instanceof me&&await xn(n.traceWriter,"PostToolUse",{toolName:t.toolName},{kind:"blocked",err:r}),r instanceof me||r instanceof ut){W(`PostToolUse hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}W(`PostToolUse hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}async function Nk(e,t,n={}){if(e)try{let r=await e.dispatch(t,n.signal);await xn(n.traceWriter,"PostToolUseFailure",{toolName:t.toolName},{kind:"decision",decision:r})}catch(r){if(r instanceof me&&await xn(n.traceWriter,"PostToolUseFailure",{toolName:t.toolName},{kind:"blocked",err:r}),r instanceof me||r instanceof ut){W(`PostToolUseFailure hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}W(`PostToolUseFailure hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}var lu=P(()=>{"use strict";Pe();vt();Da();Ne()});import{mkdir as TU,writeFile as xU}from"fs/promises";import{dirname as RU,join as CU}from"path";function AU(){return CU(Mt(),"routing-decisions.jsonl")}function _U(e){let t={surface:"afk"};for(let[n,r]of Object.entries(e))r!==void 0&&(t[n]=r);return t}async function We(e){if(!(v.VITEST||v.NODE_ENV==="test"))try{let t=AU();await TU(RU(t),{recursive:!0});let n=new Date().toISOString().split(".")[0]+"Z",r=JSON.stringify({ts:n,..._U(e)})+`
859
860
  `;await xU(t,r,{flag:"a"})}catch{}}var Qn=P(()=>{"use strict";J();q()});import{AsyncLocalStorage as PU}from"node:async_hooks";function js(e,t){return Bk.run(e,t)}function Jt(){return Bk.getStore()}var Bk,er=P(()=>{"use strict";Bk=new PU});function Uk(){return $k()}function cu(e,t){return e??t}var uu=P(()=>{"use strict";Da()});function Ig(e,t){return t?.allowedTools?t.allowedTools.includes(e)?{allowed:!0}:{allowed:!1,reason:`Tool "${e}" is not in the configured allowlist`}:{allowed:!0}}function du(e,t){return jk(e,t)}function pu(e,t){return jk(e,t)}function jk(e,t){if(!e?.allowedTools||t.length===0)return e;let n=new Set(e.allowedTools),r=!1;for(let o of t)n.has(o)||(n.add(o),r=!0);return r?{...e,allowedTools:[...n]}:e}var mu=P(()=>{"use strict"});function mj(e){return e.replace(/'[^']*'/g," ").replace(/"(?:[^"\\]|\\.)*"/g,t=>/\$\(|`/.test(t)?t:" ")}function gu(e){if(typeof e!="string"||e.trim().length===0)return{mutating:!1};let t=e.replace(LU," ");for(let s of dj)if(s.re.test(t))return{mutating:!0,reason:s.reason};let n=e.match(nj)?.[1];if(n&&rj.test(n))return{mutating:!0,reason:"interpreter one-liner file write (`-c`/`-e`)"};let r=mj(e);for(let s of pj)if(s.re.test(r))return{mutating:!0,reason:s.reason};let o=r.replace(cj," ").replace(lj," ").replace(/&(>>?)/g,"$1");return uj.test(o)?{mutating:!0,reason:"output redirection to a file (`>`/`>>`)"}:{mutating:!1}}var IU,MU,OU,$U,DU,FU,LU,NU,BU,UU,jU,HU,WU,KU,GU,qU,zU,fu,JU,VU,YU,XU,ZU,QU,ej,tj,nj,rj,oj,sj,ij,aj,lj,cj,uj,dj,pj,Mg=P(()=>{"use strict";IU=/\bgit\b[^|;&]*\s(commit|push|pull|merge|rebase|reset|checkout|switch|restore|cherry-pick|revert|am|apply|clean|add|rm|mv|init)\b/i,MU=/\bgit\b[^|;&]*\s+tag\s+-/i,OU=/\bgit\b[^|;&]*\s+branch\s+-[dDmM]\b/i,$U=/\bgit\b[^|;&]*\s+remote\s+(add|remove|rm|set-url|rename)\b/i,DU=/\bgit\b[^|;&]*\s+worktree\s+(remove|prune|move|lock|unlock)\b/i,FU=/\bgit\b[^|;&]*\s+stash\b(?!\s+(list|show)\b)/i,LU=/\bstash@\{[^}]*\}/gi,NU=/\bgit\s+config\b[^|;&]*\s(--add|--unset|--unset-all|--replace-all|--rename-section|--remove-section|--edit|-e)\b/i,BU=/\bgit\s+config\s+(?:--(?:global|system|local|worktree)\s+|(?:--file|-f)\s+\S+\s+)*[\w][\w.-]*\s+\S/i,UU=/\bgh\s+\w[\w-]*\s+(create|merge|close|edit|delete|comment|review|reopen|sync|fork|clone|ready)\b/i,jU=/\bgh\s+api\b.*(-X|--method)\s+(POST|PUT|PATCH|DELETE)\b/i,HU=/\bgh\s+api\b.*(\s-f\b|\s-F\b|--field\b)/i,WU=/\bgh\s+(secret|variable|workflow|release|run|cache|ssh-key|gpg-key)\s+(set|run|rerun|cancel|upload|delete|enable|disable)\b/i,KU=/\|\s*(sh|bash|zsh|dash)\b/i,GU=/\b(rm|rmdir|unlink|mv|cp|mkdir|touch|dd|truncate|tee|sponge|ln|chmod|chown|chgrp|shred|rsync)\b/i,qU=/\bfind\b[^|;&]*\s-delete\b/i,zU=/\bfind\b[^|;&]*\s-exec\s+['"]?\s*(rm|rmdir|unlink|mv|cp|dd|truncate|shred|tee|chmod|chown|chgrp|install|patch)\b/i,fu=String.raw`(?:^|[\n;|&(]|\$\()\s*`,JU=new RegExp(fu+String.raw`patch\b`,"i"),VU=new RegExp(fu+String.raw`install\b`,"i"),YU=new RegExp(fu+String.raw`(?:source\b|\.\s+\S)`,"i"),XU=/\btar\s+-?[a-zA-Z]*[cxruA][a-zA-Z]*\b/i,ZU=new RegExp(fu+String.raw`unzip\b`,"i"),QU=/\bcpio\b[^|;&]*\s-[a-zA-Z]*i\b/i,ej=/\bsed\b[^|;&]*\s-[a-zA-Z]*i\b/i,tj=/\bperl\b[^|;&]*\s-[a-zA-Z]*i\b/i,nj=/\b(?:python3?|nodejs|node|bun|ruby|perl|php)\b[^|;&]*?\s-(?:c|e)\b\s*("(?:[^"\\]|\\.)*"|'[^']*'|`[^`]*`)/i,rj=/open\s*\([^)]*,\s*['"][wax]|writeFileSync|writeFile\b|appendFileSync|appendFile\b|createWriteStream|File\.(?:write|delete)\b|IO\.write\b|FileUtils\.|\bBun\.write\b|os\.remove\b|shutil\.\w|\.write_text\b|\.write_bytes\b/i,oj=/\b(npm|pnpm|yarn|pip|pip3|brew|cargo|go|apt|apt-get|gem|poetry|bundle|composer)\s+(install|add|remove|uninstall|i|ci|up|update|upgrade|dlx|get|require)\b/i,sj=/\b(curl|wget)\b[^|;&]*\s(-o\b|-O\b|--output\b)/i,ij=/\bcurl\b[^|;&]*\s-X\s+(POST|PUT|PATCH|DELETE)\b/i,aj=/\bcurl\b[^|;&]*\s(-d\b|--data\b|-F\b|--form\b)/i,lj=/(\d*&?>>?\s*\/dev\/null|\d*>&\d+|&>\s*\/dev\/null|&>>\s*\/dev\/null)/gi,cj=/\$\(\(.*?\)\)/g,uj=/(?<![=<>-])>>?(?!&)/,dj=[{re:IU,reason:"git repository mutation"},{re:MU,reason:"git tag create/delete"},{re:OU,reason:"git branch delete/rename"},{re:$U,reason:"git remote mutation"},{re:FU,reason:"git stash mutation (only `stash list`/`stash show` allowed)"},{re:NU,reason:"git config write flag (only reads allowed)"},{re:BU,reason:"git config set (`<key> <value>`; only reads allowed)"},{re:UU,reason:"gh write operation"},{re:jU,reason:"gh api write method (POST/PUT/PATCH/DELETE)"},{re:HU,reason:"gh api field payload (-f/-F/--field)"},{re:WU,reason:"gh extended write operation (secret/variable/workflow/run/cache)"},{re:DU,reason:"git worktree mutation (remove/prune/move)"},{re:ej,reason:"sed in-place edit (-i)"},{re:tj,reason:"perl in-place edit (-i)"},{re:oj,reason:"package install/modify"},{re:sj,reason:"curl/wget output-to-file"},{re:ij,reason:"curl write method (POST/PUT/PATCH/DELETE)"},{re:aj,reason:"curl data/form payload"},{re:zU,reason:"find -exec with mutating verb"}],pj=[{re:KU,reason:"pipe-to-shell (RCE via piped interpreter)"},{re:GU,reason:"filesystem mutation"},{re:qU,reason:"find -delete (file removal)"},{re:JU,reason:"patch (applies a diff to files)"},{re:VU,reason:"install (writes files)"},{re:YU,reason:"source/dot-source executes a script"},{re:XU,reason:"tar create/extract/append/update (writes files/archive)"},{re:ZU,reason:"unzip (writes files)"},{re:QU,reason:"cpio extract (-i mode writes files)"}]});var fj,gj,hj,yj,bj,wj,Sj,vj,kj,Ao,_o,Po,Ej,Tj,xj,Rj,Cj,Aj,_j,Pj,Ij,Mj,Oj,$j,Dj,tr,Rn,jle,nr=P(()=>{"use strict";fj={name:"bash",category:"shell",concurrencySafe:!1,description:"Execute a shell command and return its stdout and stderr. Use for running programs, installing packages, git operations, and any task that requires a shell. Commands run in the user's default shell. Long-running commands should use timeout_ms. Output is capped at ~100KB; excess is truncated with a notice.",input_schema:{type:"object",properties:{command:{type:"string",description:"The shell command to execute."},timeout_ms:{type:"number",description:"Optional timeout in milliseconds (default 120000, max 600000). The command is killed if it exceeds this duration."}},required:["command"]}},gj={name:"read_file",category:"read",concurrencySafe:!0,description:"Read a file from the filesystem. Returns the file content with line numbers. Use offset and limit to read specific sections of large files. When the read returns a partial view, the response ends with a `... (showing lines X-Y of Z [\u2014 pass offset=N to continue])` annotation indicating the full file size and how to continue. Binary files are detected and rejected. Missing files return an error.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to read."},offset:{type:"number",description:"Line number to start reading from (1-based). Defaults to 1."},limit:{type:"number",description:"Maximum number of lines to read. Defaults to 2000."}},required:["file_path"]}},hj={name:"write_file",category:"write",concurrencySafe:!1,description:"Write content to a file, creating it if it does not exist or overwriting if it does. Parent directories are created automatically. Prefer edit_file for modifying existing files \u2014 use write_file only for new files or complete rewrites.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to write."},content:{type:"string",description:"The full content to write to the file."}},required:["file_path","content"]}},yj={name:"edit_file",category:"write",concurrencySafe:!1,description:"Perform an exact string replacement in a file. Finds old_string and replaces it with new_string. The edit fails if old_string is not found or matches multiple locations (unless replace_all is true). Always use read_file first to verify the exact content before editing.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to edit."},old_string:{type:"string",description:"The exact string to find and replace. Must match file content exactly."},new_string:{type:"string",description:"The replacement string."},replace_all:{type:"boolean",description:"If true, replace all occurrences. If false (default), fail when multiple matches exist."}},required:["file_path","old_string","new_string"]}},bj={name:"glob",category:"read",concurrencySafe:!0,description:'Find files matching a glob pattern. Returns matching file paths, capped at 500 results. Use for discovering files before reading them. Patterns follow standard glob syntax (e.g., "src/**/*.ts", "*.json").',input_schema:{type:"object",properties:{pattern:{type:"string",description:'Glob pattern to match (e.g., "src/**/*.ts").'},path:{type:"string",description:"Base directory to search from. Defaults to the current working directory."}},required:["pattern"]}},wj={name:"grep",category:"read",concurrencySafe:!0,description:"Search file contents for lines matching a pattern. Returns matches in file:line:content format. Runs `grep -rn` in basic-regex (BRE) mode by default, where `|` is a LITERAL pipe \u2014 not alternation; set extended: true for extended-regex (ERE) alternation. A no-match result on a pattern containing `|` is often a false negative \u2014 re-read the returned hint. Output is capped to prevent overflow. Use for finding symbols, strings, or patterns across the codebase.",input_schema:{type:"object",properties:{pattern:{type:"string",description:"Search pattern. Basic regex (BRE) by default: `|` `+` `?` `(` `)` `{` `}` are LITERAL characters. Set extended: true for extended regex (ERE) where `|` means alternation."},path:{type:"string",description:"Directory or file to search. Defaults to current working directory."},include:{type:"string",description:'File glob to restrict search (e.g., "*.ts"). Passed as --include to grep.'},extended:{type:"boolean",description:"Use extended regex (ERE, `grep -E`) so `|` is alternation and `+ ? ( ) { }` are metacharacters. Default false (BRE \u2014 those characters match literally)."}},required:["pattern"]}},Sj={name:"list_directory",category:"read",concurrencySafe:!0,description:"List the contents of a directory. Returns file and subdirectory names with type annotations (directories end with /). Use for exploring project structure.",input_schema:{type:"object",properties:{path:{type:"string",description:"Absolute path to the directory to list."}},required:["path"]}},vj={name:"send_telegram",category:"web",concurrencySafe:!1,riskClass:"caution",description:"Send a Telegram message to the operator. Use to surface terminal-state notifications, blocking questions, or important status updates when the user is away from keyboard (AFK). The message is delivered through the same Telegram bot the operator uses to drive this session. By default the message goes to your primary chat (the first private chat in `AFK_TELEGRAM_ALLOWED_CHAT_IDS`, or `AFK_TELEGRAM_PRIMARY_CHAT_ID` if set); set `telegram.notify` in afk.config.json to broadcast to all allowed chats or target a custom set.\n\nPlain text only \u2014 Telegram's 4096-character limit per message is enforced. Returns an error if Telegram is not configured (missing `TELEGRAM_BOT_TOKEN` or empty allowlist) so the tool is safe to attempt unconditionally.\n\nUse sparingly: this is a real push notification to a human. Reserve for terminal states (Done/Blocked/Asking) and material progress, not running commentary. When running inside the Telegram bot, prefer replying normally \u2014 your response already reaches the operator through the bot. Use this tool only from CLI or daemon sessions.",input_schema:{type:"object",properties:{message:{type:"string",description:"Plain-text message body to send to the operator. Max 4096 characters (Telegram API limit). Must be non-empty."}},required:["message"]}},kj={name:"web_scrape",category:"web",concurrencySafe:!0,description:'Scrape a web page or run a web search and return text content suitable for reasoning over. Three modes:\n\n- `markdown` (default): fetches the URL and extracts the main content as clean markdown (Readability + Turndown). Handles JS-rendered pages: if the plain fetch yields thin content, it escalates to a headless-browser render and re-extracts. Use this for articles, docs, blog posts, and most "I want to read this page" cases. No API key required (the render fallback needs the Playwright chromium binary \u2014 `pnpm exec playwright install chromium`).\n- `raw`: GETs the URL directly with no transformation. Use for JSON APIs, robots.txt, RSS, plain-text endpoints, or when you need the literal bytes. No API key required.\n- `search`: runs a web search and returns ranked markdown results. Use when you need to FIND a URL, not read one. Provide `query` instead of `url`. Requires `EXA_API_KEY` (free tier at https://exa.ai); the handler returns a clear error if it is unset.\n\nOutputs are capped at `max_bytes` UTF-8 bytes (default 1MB, ceiling 10MB) and the request is aborted after `timeout_ms` (default 30000, ceiling 120000).',input_schema:{type:"object",properties:{mode:{type:"string",enum:["markdown","raw","search"],description:'Fetch mode. Defaults to "markdown".'},url:{type:"string",description:"Absolute http(s) URL. Required for markdown and raw modes. Ignored in search mode."},query:{type:"string",description:"Search query string. Required for search mode. Ignored otherwise."},timeout_ms:{type:"number",description:"Request timeout in milliseconds (default 30000, clamped to 120000)."},max_bytes:{type:"number",description:"Maximum UTF-8 bytes returned. Content beyond this is truncated with a marker. Default 1000000, clamped to 10000000."}},required:[]}},Ao={name:"agent",category:"subagent",concurrencySafe:!0,description:`Dispatch an independent subagent with its own context window and tool access. Use for tasks that protect the main session's context: codebase exploration, multi-file inspection, repo search, verification, debugging, failing-test investigation, PR review, parallel hypothesis testing, independent re-derivation of a claim, audit work, stale-path detection, feature-wiring checks, and any research-shaped investigation.
860
861
 
861
862
  Parallelize: dispatch multiple \`agent\` calls in a single tool-use turn to run independent investigations concurrently.
@@ -1078,7 +1079,7 @@ ${o}`;return s.includes("already checked out")||s.includes("is already used by w
1078
1079
  Effective base URL: ${r}`)),r}return t}function VH(){if(ch!==void 0)return ch;if(!YE){let o=[za(process.cwd(),".env"),St(),Fv()];for(let s of o)uh(s)&&zH({path:s,override:!1});YE=!0}let e={},t=v.AFK_MODEL??v.CLAUDE_MODEL;if(t){let o=t.toLowerCase();e.model=wg(o)?o:t}if(se(t)==="anthropic-direct"){let o=dh();o!==void 0&&(e.apiKey=o)}let r=v.AFK_LOCAL_BASE_URL;if(r&&r.length>0&&(e.baseUrl=r,e.apiKey=v.AFK_LOCAL_API_KEY||"local"),v.AFK_MAX_TOKENS&&(e.maxTokens=parseInt(v.AFK_MAX_TOKENS,10)),v.AFK_TEMPERATURE&&(e.temperature=parseFloat(v.AFK_TEMPERATURE)),v.AFK_SYSTEM_PROMPT&&(e.systemPrompt=v.AFK_SYSTEM_PROMPT),v.AFK_AUTO_ROUTING){let o=v.AFK_AUTO_ROUTING.toLowerCase()==="true";e.autoRouting={interactive:o,chat:o,telegram:o,daemon:o}}return v.AFK_OPENAI_BASE_URL&&(e.openaiBaseUrl=JH(v.AFK_OPENAI_BASE_URL)),ch=e,e}function ph(){if(Vs!==void 0)return Vs;let e=[za(process.cwd(),"afk.config.json"),Kt(),Dc()];for(let t of e)if(uh(t))try{let n=ZE(t,"utf-8"),r=JSON.parse(n),o={},s=wk(r.models);if(typeof r.model=="string"&&r.model.length>0){let i=r.model.toLowerCase();o.model=wg(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 l={};if((a.mode==="primary"||a.mode==="broadcast"||a.mode==="custom")&&(l.mode=a.mode),typeof a.primaryChatId=="number"&&Number.isFinite(a.primaryChatId)&&(l.primaryChatId=a.primaryChatId),Array.isArray(a.targets)){let c=a.targets.filter(u=>typeof u=="number"&&Number.isFinite(u));c.length>0&&(l.targets=c)}i.notify=l}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),t!==za(process.cwd(),"afk.config.json")){let i=Ga(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=sh(r.interactive.worktreeBranchPrefix,`${t}#/interactive/worktreeBranchPrefix`)),typeof r.interactive.worktreeBase=="string"&&r.interactive.worktreeBase.trim().length>0&&(ih(r.interactive.worktreeBase,`${t}#/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 Vs={config:o,sourcePath:t,modelsPartial:s},Vs}catch(n){console.error(`Warning: Failed to parse ${t}:`,n)}return Vs={config:{},sourcePath:void 0,modelsPartial:{}},Vs}function YH(){if(Ys!==void 0)return Ys.value;let e=[za(process.cwd(),"AFK.md"),za(Le(),"AFK.md")];for(let t of e)if(uh(t))try{let n=ZE(t,"utf-8").trim();if(n.length>0)return Ys={value:{content:n,path:t}},Ys.value}catch{}return Ys={value:null},Ys.value}function $u(){return ph().config.telegram??{}}function Xs(){return ph().config.permissionMode??QE}function It(e){let t=VH(),{config:n,sourcePath:r,modelsPartial:o}=ph(),s={...qa,...t,...n,...e},i;if(t.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 c=YH();c!==null&&(s.systemPrompt=c.content,i=`afk-md:${c.path}`)}let a={model:s.model??qa.model,maxTokens:s.maxTokens??qa.maxTokens,temperature:s.temperature??qa.temperature,updatePolicy:s.updatePolicy??qa.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??QE,...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}:{}},l=e?.models??hg(o);if(Xc(l),a.models=l,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 qa,QE,YE,ch,XE,Vs,Ys,Ft=P(()=>{"use strict";Zn();sn();it();q();zs();Ka();J();ur();qa={model:"sonnet",maxTokens:4096,temperature:1,updatePolicy:"notify"},QE="bypassPermissions",YE=!1;XE=new Set});function XH(e,t){return t!==void 0&&Number.isFinite(t)&&t!==0?t:e.find(r=>r>0)??e[0]}function ZH(e,t={}){let n=[...e],r=t.mode??"primary";if(r==="broadcast")return n;if(r==="custom"){let s=(t.targets??[]).filter(i=>typeof i=="number"&&Number.isFinite(i)&&i!==0);if(s.length>0)return[...new Set(s)]}let o=XH(n,t.primaryChatId);return o!==void 0?[o]:[]}function QH(e){if(!e)return;let t=e.trim();if(!/^-?\d+$/.test(t))return;let n=Number(t);return Number.isFinite(n)&&n!==0?n:void 0}function eW(e){if(!e)return;let t=e.trim().toLowerCase();return t==="primary"||t==="broadcast"||t==="custom"?t:void 0}function tW(){let e=$u().notify??{},t=e.mode??eW(v.AFK_TELEGRAM_NOTIFY_MODE),n=e.primaryChatId??QH(v.AFK_TELEGRAM_PRIMARY_CHAT_ID);return{...t!==void 0?{mode:t}:{},...n!==void 0?{primaryChatId:n}:{},...e.targets!==void 0?{targets:e.targets}:{}}}function Zs(){let e=ME(v.AFK_TELEGRAM_ALLOWED_CHAT_IDS);return ZH(e,tW())}var Du=P(()=>{"use strict";OE();Ft();J()});function mh(e,t=4096){if(e.length<=t)return[e];let n=[],r=e;for(;r.length>0;){if(r.length<=t){n.push(r);break}let o=t,s=r.lastIndexOf(`
1079
1080
  `,t);if(s>t-500&&s>0)o=s+1;else{let i=r.slice(0,t).match(/[.!?]\s+(?=[A-Z])/g);if(i&&i.length>0){let a=i[i.length-1];if(a){let l=r.lastIndexOf(a,t);l>t-200&&l>0&&(o=l+2)}}else{let a=r.lastIndexOf(" ",t);a>t-100&&a>0&&(o=a+1)}}n.push(r.slice(0,o).trim()),r=r.slice(o).trim()}return n}function eT(e){e=e.replace(/[\x02\x03]/g,"");let t=e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),n=[];t=t.replace(/^ {0,3}```([\w]*)\n([\s\S]*?)```/gm,(o,s,i)=>{let a=n.length;if(i.trim()===""){let l=s?`(empty ${s} block)`:"(empty code block)";n.push(`<i>${l}</i>`)}else n.push(`<pre>${i}</pre>`);return`FENCED${a}`});let r=[];return t=t.replace(/`([^`]+)`/g,(o,s)=>{let i=r.length;return r.push(`<code>${s}</code>`),`CODE${i}`}),t=t.replace(/\*\*([^*]+)\*\*/g,"<b>$1</b>"),t=t.replace(/__([^_]+)__/g,"<b>$1</b>"),t=t.replace(/\*([^*]+)\*/g,"<i>$1</i>"),t=t.replace(/(^|[^\w])_([^_\n]+?)_(?!\w)/gm,"$1<i>$2</i>"),t=t.replace(/~~([^~]+)~~/g,"<s>$1</s>"),t=t.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(o,s,i)=>'<a href="'+i.replace(/"/g,"&quot;")+'">'+s+"</a>"),t=t.replace(/^#{1,6}\s+/gm,""),t=t.replace(/\x02CODE(\d+)\x03/g,(o,s)=>r[Number(s)]??o),t=t.replace(/\x02FENCED(\d+)\x03/g,(o,s)=>n[Number(s)]??o),nW(t)||(t=t.replace(/<\/?[bis]>/g,"")),t}function nW(e){let t=[],n=/<(\/?)([a-zA-Z][a-zA-Z0-9-]*)\b[^>]*>/g,r;for(;(r=n.exec(e))!==null;){let o=(r[2]??"").toLowerCase();if(r[1]==="/"){if(t.pop()!==o)return!1}else t.push(o)}return t.length===0}var tT=P(()=>{"use strict"});var fh={};xc(fh,{push:()=>Qs,pushIfConfigured:()=>An,pushMarkdown:()=>nT});async function Qs(e){if(!e.token)throw new Error("push: token is required");if(e.chatId===""||e.chatId==null||e.chatId===0)throw new Error("push: chatId is required");let t=e.fetchImpl??fetch,r=`${e.apiBase??rW}/bot${e.token}/sendMessage`,o={chat_id:e.chatId,text:e.text.slice(0,4096)};e.parseMode&&(o.parse_mode=e.parseMode),e.replyMarkup&&(o.reply_markup=e.replyMarkup);let s=new AbortController,i=setTimeout(()=>s.abort(),1e4);try{let a=await t(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 l;try{l=(await a.json()).description}catch{l=`HTTP ${a.status}`}return{ok:!1,status:a.status,...l!==void 0?{errorMessage:l}:{}}}catch(a){return{ok:!1,status:0,errorMessage:a instanceof Error?a.message:String(a)}}finally{clearTimeout(i)}}async function nT(e){let t=eT(e.text),n=mh(t),r={ok:!0,status:200};for(let o of n)if(r=await Qs({...e,text:o,parseMode:"HTML"}),!r.ok)return r.status===400&&/can't parse entities/i.test(r.errorMessage??"")?Qs({...e}):r;return r}async function An(e,t={}){let n=v.TELEGRAM_BOT_TOKEN;if(!n)return null;let r=Zs();if(r.length===0)return null;let o=mh(e),s=[];for(let i of r)for(let a=0;a<o.length;a++){let l={token:n,chatId:i,text:o[a]??"",...t.replyMarkup!==void 0&&a===0?{replyMarkup:t.replyMarkup}:{},...t.fetchImpl!==void 0?{fetchImpl:t.fetchImpl}:{}};s.push(t.markdown?await nT(l):await Qs({...l,...t.parseMode!==void 0?{parseMode:t.parseMode}:{}}))}return s}var rW,Nr=P(()=>{"use strict";Du();tT();J();rW="https://api.telegram.org"});function oW(e=Qs){return async(t,n)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected an object",isError:!0};let o=t.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>rT)return{content:`Invalid input: message exceeds Telegram's ${rT}-character limit (got ${o.length}). Split into multiple sends or trim before calling.`,isError:!0};let s=v.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=Zs();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 l of i){let c=await e({token:s,chatId:l,text:o});c.ok||a.push(`chat ${l}: ${c.errorMessage??`HTTP ${c.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 rT,oT,sT=P(()=>{"use strict";J();Nr();Du();rT=4096;oT=oW()});import{JSDOM as sW}from"jsdom";import{Readability as iW}from"@mozilla/readability";import aW from"turndown";function iT(e){return e.replace(/\n{3,}/g,`
1080
1081
 
1081
- `).trim()}function lW(e){return(e?.textContent??"").replace(/\s+/g," ").trim().length}function lT(e,t){let r=new sW(e,{url:t}).window.document,o=(r.title??"").trim(),s=null;try{let c=r.cloneNode(!0);s=new iW(c).parse()}catch{s=null}if(s&&typeof s.content=="string"&&s.content.trim().length>0){let c=iT(gh.turndown(s.content)),u=(s.title??"").trim()||o,d=typeof s.length=="number"&&s.length>0?s.length:(s.textContent??"").replace(/\s+/g," ").trim().length;return{title:u,markdown:c,textLength:d,usedFallback:!1}}let i=r.body,a=i?.innerHTML??"",l=iT(gh.turndown(a));return{title:o,markdown:l,textLength:lW(i),usedFallback:!0}}var aT,gh,cT=P(()=>{"use strict";aT=200,gh=new aW({headingStyle:"atx",codeBlockStyle:"fenced",bulletListMarker:"-"});gh.remove(["script","style","noscript","iframe"])});function uW(e,t){return new Promise((n,r)=>{if(t?.aborted){r(t.reason??new Error("aborted"));return}let o=()=>{clearTimeout(s),r(t?.reason??new Error("aborted"))},s=setTimeout(()=>{t?.removeEventListener("abort",o),n()},e);t?.addEventListener("abort",o,{once:!0})})}function uT(e,t,n){let r=Math.min(t*2**e,n);return Math.round(Math.random()*r)}function dW(e,t){let n=e.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,t)}async function Fu(e,t,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??uW,l=n.signal??void 0,c;for(let u=0;u<=o;u++){if(l?.aborted)throw l.reason??new Error("aborted");try{let d=await e(t,n);if(!cW.has(d.status)||u===o)return d;let p=dW(d,i)??uT(u,s,i);W("[web/retryFetch] retrying",{url:t,attempt:u,status:d.status,waitMs:p}),await d.body?.cancel().catch(()=>{}),await a(p,l)}catch(d){if(l?.aborted||(c=d,u===o))throw d;let p=uT(u,s,i);W("[web/retryFetch] retrying after error",{url:t,attempt:u,waitMs:p}),await a(p,l)}}throw c??new Error("retryFetch: exhausted without a result")}var cW,hh=P(()=>{"use strict";Pe();cW=new Set([429,502,503,504])});import{readFileSync as pW}from"node:fs";import{join as mW}from"path";function fW(e){let n=e.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function dT(e,t){return fW(t).test(e)}function yW(e,t){if(e!==void 0){let n=e.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(t!==void 0){if(gW.has(t))return!0;if(hW.has(t))return!1}return!1}function pT(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0)}function bW(e){if(e===void 0||e===""||e==="playwright")return"playwright";throw new Error(`AFK_BROWSER_BACKEND: only "playwright" is supported in Phase 1, got: ${e}`)}function mT(e){let t=e===void 0||e.trim()===""?"default":e.trim();return Ra(t),t}function wW(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"}function SW(e){try{return pW(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}}function vW(e,t){let n={...e};if(typeof t.headless=="boolean"&&(n.headless=t.headless),Array.isArray(t.allowedDomains)&&(n.allowedDomains=t.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(t.blockedDomains)&&(n.blockedDomains=t.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof t.domSnapshots=="boolean"&&(n.domSnapshots=t.domSnapshots),t.backend==="playwright")n.backend="playwright";else if(t.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: only "playwright" is supported in Phase 1, got: ${String(t.backend)}`);return typeof t.defaultProfile=="string"&&(n.defaultProfile=mT(t.defaultProfile)),n}function fT(e){let t=e?.env??v,n=e?.readFileSync??SW,r=e?.surface??t.AGENT_SURFACE,o=yW(t.AFK_BROWSER_HEADLESS,r),s=pT(t.AFK_BROWSER_ALLOWED_DOMAINS),i=pT(t.AFK_BROWSER_BLOCKED_DOMAINS),a=wW(t.AFK_BROWSER_DOM_SNAPSHOTS),l=bW(t.AFK_BROWSER_BACKEND),c=mT(t.AFK_BROWSER_DEFAULT_PROFILE),u={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:l,configPath:null,defaultProfile:c},d=t.AFK_BROWSER_CONFIG,p=d!==void 0&&d.trim()!==""?d.trim():mW(rn(),"browser.json"),m=n(p);if(m===void 0)return u;let g;try{g=JSON.parse(m)}catch(b){throw new Error(`Failed to parse browser config at ${p}: ${String(b)}`)}if(typeof g!="object"||g===null||Array.isArray(g))throw new Error(`Browser config at ${p} must be a JSON object`);let h=vW(u,g);return h.configPath=p,h}function yh(e,t){let n;try{n=new URL(e).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${e}`}}for(let r of t.blockedDomains)if(dT(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return t.allowedDomains.length>0&&!t.allowedDomains.some(o=>dT(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var gW,hW,bh=P(()=>{"use strict";J();q();gW=new Set(["daemon","subagent","telegram","afk"]),hW=new Set(["repl","interactive","cli"])});import $o from"node:fs";import Lu from"node:path";import{randomBytes as kW}from"node:crypto";import{chromium as EW}from"playwright";function TW(){try{return"5.15.1"}catch{}try{let e=Lu.resolve(import.meta.dirname,"../../../package.json"),t=$o.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var xW,Nu,gT=P(()=>{"use strict";q();Pe();xW=TW(),Nu=class{config;browser;sessions=new Map;launchPromise;shutdownComplete=!1;constructor(t){this.config=t}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=EW.launch({headless:this.config.headless}).then(t=>(this.browser=t,this.launchPromise=void 0,t)).catch(t=>{throw this.launchPromise=void 0,t}),this.launchPromise))}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(t){let n=this.sessions.get(t);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(t,i),s}async ensurePage(t){let n=this.sessions.get(t);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(t);let r=this.sessions.get(t);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${t}`);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(t){return this.sessions.get(t)?.page}async renderHtml(t,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(t,{timeout:n.timeoutMs,waitUntil:n.waitUntil}),l=await i.content(),c=i.url(),u=a!==null?a.status():null;return{html:l,finalUrl:c,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",s),await o.close().catch(()=>{})}}getConsoleErrorCount(t){return this.sessions.get(t)?.consoleErrors??0}getLastHttpStatus(t){return this.sessions.get(t)?.lastHttpStatus??null}hasOpenDialog(t){return this.sessions.get(t)?.openDialog!==void 0}async dismissDialog(t,n=!0){let r=this.sessions.get(t);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(t){let n=this.sessions.get(t);n!==void 0&&(this.sessions.delete(t),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.shutdownComplete)return;this.shutdownComplete=!0;let t=[...this.sessions.keys()];if(await Promise.all(t.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/${xW}`}}loadStorageState(t){let n=Ca(t);try{if(!$o.existsSync(n))return;let r=JSON.parse($o.readFileSync(n,"utf8"));return W("[browser/vault] restored session",{profile:t,file:n}),r}catch(r){W("[browser/vault] ignoring unreadable vault",{profile:t,file:n,err:r});return}}async saveStorageState(t,n){try{let r=Ca(t);if(!$o.existsSync(r))return;let o=await n.storageState(),s=Lu.join(Lu.dirname(r),`.${Lu.basename(r)}.${process.pid}.${kW(4).toString("hex")}.tmp`);$o.writeFileSync(s,JSON.stringify(o),{mode:384}),$o.chmodSync(s,384),$o.renameSync(s,r),W("[browser/vault] saved session",{profile:t,file:r})}catch(r){W("[browser/vault] save failed",{profile:t,err:r})}}}});import{createHash as RW}from"crypto";function wh(e){if(e.length===0)return e;let t=e;for(let{regex:n,name:r}of CW)r==="form-password"?t=t.replace(n,"password=[redacted]"):t=t.replace(n,"[redacted]");return t}function hT(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&AW.test(e.label))}function yT(e){return RW("sha256").update(e,"utf8").digest("hex").slice(0,8)}function bT(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var CW,AW,Ja=P(()=>{"use strict";CW=[{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}];AW=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as _W}from"node:crypto";function PW(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function IW(e,t,n){return`el_${_W("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function MW(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function wT(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function vT(e,t){let n=e.role??"",r=e.name??"";ST.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let s of e.children??[])vT(s,t)}async function OW(e){return e.evaluate(t=>{let n=Array.from(document.querySelectorAll(t)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let u=window.getComputedStyle(i);if(u.display==="none"||u.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),l=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a==="input"?o.type||null:o.getAttribute("type");r.push({name:l,tagName:a,type:c,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},kT).catch(()=>[])}async function $W(e){return e.evaluate(t=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(t)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",l=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a||(n[i]??"");if(i==="input"){let h=s.type;h==="checkbox"?c="checkbox":h==="radio"?c="radio":h==="button"||h==="submit"||h==="reset"?c="button":h==="search"?c="searchbox":c="textbox"}if(!c)continue;let u="value"in s?s.value:void 0,d=u!==void 0?String(u):void 0,p=s.disabled??!1,m=i==="input"?s.checked:void 0,g={role:c,name:l,disabled:p};d!==void 0&&(g.value=d),m!==void 0&&(g.checked=m),o.push(g)}return o},kT).catch(()=>[])}function DW(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function Bu(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],s=DW(e),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=OW(e),l=e.evaluate(()=>document.body?.innerText??"").catch(()=>""),c=Promise.resolve(e.url()),u=e.title().catch(()=>""),[d,p,m,g,h]=await Promise.all([i,a,l,c,u]),b,y=!1;d!==null?(b=[],vT(d,b)):(o.push("observation skipped accessibility tree (returned null)"),y=!0,b=(await $W(e)).filter(L=>ST.has(L.role??"")));let S=new Map;for(let I of p){let L=wT(I.name),N=S.get(L);(!N||N.bbox.w===0&&I.bbox.w>0)&&S.set(L,I)}let w=b.map(I=>({ax:I,dom:S.get(wT(I.name??""))})),k=r?w:w.filter(I=>I.dom?I.dom.bbox.w>0||I.dom.bbox.h>0:!0);k.sort((I,L)=>{let N=I.dom?.bbox.y??0,F=L.dom?.bbox.y??0;if(N!==F)return N-F;let U=I.dom?.bbox.x??0,H=L.dom?.bbox.x??0;return U-H}),k.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=k.slice(0,n).map((I,L)=>{let N=I.ax.role??"generic",F=I.ax.name??"",U=IW(N,F,L),H=I.dom?.bbox??{x:0,y:0,w:0,h:0},D=I.dom?.type??null,C=null;I.ax.value!==void 0&&I.ax.value!==null&&(C=String(I.ax.value)),I.ax.checked!==void 0&&(C=String(I.ax.checked)),hT({role:N,kind:D})&&(C="[redacted]");let B={disabled:I.ax.disabled??!1};I.ax.checked!==void 0&&(B.checked=I.ax.checked===!0||I.ax.checked==="mixed"),I.ax.selected!==void 0&&(B.selected=I.ax.selected),I.ax.expanded!==void 0&&(B.expanded=I.ax.expanded);let M;I.dom?.testId?M=`[data-testid="${I.dom.testId}"]`:I.dom?.id&&(M=`#${I.dom.id}`);let j={id:U,role:N,label:PW(F),kind:D,value:C,state:B,bbox:H};return M!==void 0&&(j.selector=M),j}),A="idle";try{let I=await e.evaluate(()=>document.readyState);I==="loading"?A="loading":I==="interactive"?A="navigating":A="idle"}catch{A="navigating"}A!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),y&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let E=MW(m),O=`obs_${t.observationCounter.toString(36)}`,_=new Date().toISOString();return{observationId:O,url:g,title:h,textSummary:E,interactive:R,status:{httpStatus:t.httpStatus??null,loadingState:A,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:_}}var ST,kT,ET=P(()=>{"use strict";Ja();ST=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);kT="a[href], button, input, select, textarea, [role], [tabindex], label"});async function TT(e,t){try{let n=await e.nth(t).evaluate(i=>{let a=i,l=a.getAttribute("role")??a.tagName.toLowerCase(),c=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",u=a.getBoundingClientRect();return{role:l,label:c,x:Math.round(u.x),y:Math.round(u.y),w:Math.round(u.width),h:Math.round(u.height)}}),r=`${n.role}:${n.label}:${t}`,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 Sh(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,s)=>TT(e,s)))).filter(o=>o!==null)}async function FW(e){let t=new Set,n=[];for(let{loc:r,count:o}of e)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let l=a,c=l.getBoundingClientRect();return`${l.tagName}@${Math.round(c.x)},${Math.round(c.y)}`})}catch{continue}t.has(i)||(t.add(i),n.push({key:i,locator:r,index:s}))}return n}async function vh(e,t,n){switch(t.kind){case"element_id":return LW(e,t,n);case"selector":return NW(e,t);case"semantic":return BW(e,t)}}async function LW(e,t,n){let r=n.get(t.elementId);if(r===void 0)return{outcome:"not_found",query:t};if(r.selector!==void 0){let l=e.locator(r.selector);if(await l.count()===1)return{outcome:"resolved",locator:l}}let o=e.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:t};if(s===1)return{outcome:"resolved",locator:o};let i=await Sh(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function NW(e,t){let n=e.locator(t.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:t};if(r===1)return{outcome:"resolved",locator:n};let o=await Sh(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function BW(e,t){return t.role!==void 0?UW(e,t.text,t.role):jW(e,t.text,t)}async function UW(e,t,n){let r=e.getByRole(n,{name:t}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:t,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await Sh(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:s}}async function jW(e,t,n){let r=e.getByRole("button",{name:t}),o=e.getByRole("link",{name:t}),s=e.getByLabel(t,{exact:!1}),[i,a,l]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+l===0)return{outcome:"not_found",query:n};let u=[];i>0&&u.push({loc:r,count:i}),a>0&&u.push({loc:o,count:a}),l>0&&u.push({loc:s,count:l});let d=await FW(u);if(d.length===0)return{outcome:"not_found",query:n};if(d.length===1){let h=d[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=d.slice(0,5),m=[];for(let h=0;h<p.length;h++){let b=p[h];if(b===void 0)continue;let y=await TT(b.locator,b.index);if(y!==null){let S=`${y.role}:${y.label}:${h}`,w=0;for(let k=0;k<S.length;k++)w=w*31+S.charCodeAt(k)>>>0;m.push({...y,id:`el_${w.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:m}}var xT=P(()=>{"use strict"});import{randomBytes as HW}from"crypto";import{mkdir as WW,stat as KW,writeFile as GW}from"fs/promises";import{join as kh}from"path";import{gzip as qW}from"zlib";import{promisify as zW}from"util";function JW(e){return kh(Cs(e),"browser")}function VW(e){return kh(JW(e),"screenshots")}function YW(){return new Date().toISOString().replace(/[:.]/g,"-")}function XW(){return HW(3).toString("hex")}async function Eh(e,t,n){if(t.length>RT)throw new Error(`writeScreenshotSidecar: buffer exceeds ${RT} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=VW(e);await WW(r,{recursive:!0});let o=`${YW()}-${XW()}-${n}.png`,s=kh(r,o);await GW(s,t);let{size:i}=await KW(s);return{path:s,bytes:i}}var Zde,RT,CT=P(()=>{"use strict";q();Ja();Zde=zW(qW);RT=5*1024*1024});var _T={};xc(_T,{PlaywrightProvider:()=>Th});function AT(e){switch(e.kind){case"semantic":return e.role!==void 0?`semantic('${e.text}', role='${e.role}')`:`semantic('${e.text}')`;case"element_id":return`element_id(${e.elementId})`;case"selector":return`selector(${e.selector})`}}var Th,PT=P(()=>{"use strict";gT();ET();xT();bh();Ja();CT();Th=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new Nu(t)}async open(t){let n=yh(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let{sessionId:r}=t,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(t.url,{timeout:t.timeoutMs??3e4,waitUntil:t.waitFor??"load"})}catch(c){a=c}(t.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let l=await Bu(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,l.interactive,l.url,l.title,"browser_open"),a!==null)throw a;return l}async observe(t){let{sessionId:n}=t,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;t.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await Bu(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:t.includeHidden,maxElements:t.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(t){let{sessionId:n}=t,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=t.timeoutMs??3e4,a=await vh(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${AT(t.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:l}=a,c=null,u=async()=>{switch(t.action){case"click":await l.click({timeout:i});break;case"fill":{let h=wh(t.value??"");await l.fill(t.value??"");break}case"press":await l.press(t.value??"");break;case"select":await l.selectOption(t.value??"");break;case"hover":await l.hover({timeout:i});break;case"scroll_to":await l.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await l.waitFor({timeout:i,state:"visible"});break}};try{await u()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await u()}catch(b){c=b}else c=h}let d=r.url();if(d!==s){let h=yh(d,this.config);if(!h.allowed)return await r.goBack().catch(()=>{}),{outcome:"blocked_by_policy",url:d,reason:h.reason}}let p=null;(t.screenshot===!0||c!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let m=await Bu(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${t.action}`;if(this.updateSessionFromObservation(o,m.interactive,m.url,m.title,g),c!==null)throw c;return m}async render(t){return this.launcher.renderHtml(t.url,{timeoutMs:t.timeoutMs??3e4,waitUntil:t.waitFor??"load",signal:t.signal})}async screenshot(t){let{sessionId:n}=t,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(t.target!==void 0){let u=await vh(r,t.target,o.knownElements);if(u.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${AT(t.target)}`);if(u.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await u.locator.screenshot()}else s=await r.screenshot({fullPage:t.fullPage??!1});let{path:i,bytes:a}=await Eh(n,s,"browser_screenshot"),l=0,c=0;if(t.fullPage===!0)try{let u=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));l=u.w,c=u.h}catch{let u=r.viewportSize();l=u?.width??0,c=u?.height??0}else{let u=r.viewportSize();l=u?.width??0,c=u?.height??0}return{path:i,bytes:a,width:l,height:c,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(t){throw new Error("browser_extract not implemented in Phase 1")}async close(t){await this.launcher.closeSession(t.sessionId),this.sessions.delete(t.sessionId)}describe(t){let n=this.sessions.get(t);if(n===void 0)return null;let r=this.launcher.getPage(t);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(t){let n=this.sessions.get(t);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(t,r),r}updateSessionFromObservation(t,n,r,o,s){t.knownElements=new Map(n.map(i=>[i.id,i])),t.currentUrl=r,t.currentTitle=o,t.lastAction=s,t.lastActionAt=new Date().toISOString()}async captureScreenshot(t,n,r){try{let o=await t.screenshot({fullPage:!1}),{path:s}=await Eh(n,o,r);return s}catch{return null}}}});var Fo={};xc(Fo,{__resetBrowserRegistryForTests:()=>nK,browserProviderActive:()=>eK,closeBrowserProvider:()=>xh,getBrowserProvider:()=>QW,peekBrowserProvider:()=>tK});function IT(){Promise.resolve(xh()).then(()=>{process.exit(130)})}function MT(){Promise.resolve(xh()).then(()=>{process.exit(143)})}function OT(){_n=null}function ZW(){Uu||(process.on("SIGINT",IT),process.on("SIGTERM",MT),process.on("exit",OT),Uu=!0)}function $T(){Uu&&(process.removeListener("SIGINT",IT),process.removeListener("SIGTERM",MT),process.removeListener("exit",OT),Uu=!1)}async function QW(e){return _n!==null?_n:(Do!==null||(Do=(async()=>{let{PlaywrightProvider:t}=await Promise.resolve().then(()=>(PT(),_T)),n=fT(e),r=new t(n);return ZW(),_n=r,Do=null,r})()),Do)}async function xh(){if(_n===null)return;let e=_n;_n=null,Do=null,$T(),await e.shutdown()}function eK(){return _n!==null}function tK(){return _n}function nK(){_n=null,Do=null,$T()}var _n,Do,Uu,Lo=P(()=>{"use strict";bh();_n=null,Do=null,Uu=!1});function DT(e,t){try{return lT(e,t)}catch(n){return W("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function aK(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Lo(),Fo));return(await n()).render({url:e,timeoutMs:t.timeoutMs,signal:t.signal})}async function FT(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??aK,o=null,s=e,i=null,a=null;try{let c=await Fu(n,e,{headers:iK,redirect:"follow",signal:t.signal});i=c.status,s=c.url||e;let u=c.headers.get("content-type")??"";if(c.ok){if(sK.test(u))throw new Error(`web_scrape markdown mode received binary content (${u.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let d=await c.text();if(oK.test(u)&&!rK.test(u))return{title:"",markdown:d.trim(),finalUrl:s,usedRender:!1};o=DT(d,s)}}catch(c){if(t.signal.aborted||c instanceof Error&&c.message.startsWith("web_scrape markdown mode received binary"))throw c;a=c}if(!(o===null||o.textLength<aT)&&o!==null)return{title:o.title,markdown:o.markdown,finalUrl:s,usedRender:!1};try{let c=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal}),u=DT(c.html,c.finalUrl);if(o===null||u.textLength>=o.textLength)return{title:u.title,markdown:u.markdown,finalUrl:c.finalUrl,usedRender:!0}}catch(c){if(t.signal.aborted)throw c;if(o===null){let u=c instanceof Error?c.message:String(c),d=a instanceof Error?a.message:`HTTP ${i??"error"}`,p=new Error(`web_scrape could not retrieve ${e}: fetch failed (${d}) and render failed (${u}).`);throw p.cause=c,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 ${e} (HTTP ${i??"error"}).`)}var rK,oK,sK,iK,LT=P(()=>{"use strict";cT();hh();Pe();rK=/(text\/html|application\/xhtml\+xml)/i,oK=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,sK=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,iK={"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 uK(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await t(lK,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":e.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),cK),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let l="";try{let u=await s.text(),d=Mo(u);d&&(l=`: ${d.length>200?d.slice(0,200)+"\u2026":d}`)}catch{}let c=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${c}${l}`)}let i;try{i=await s.json()}catch(l){throw new Error(`Exa Search response was not JSON: ${l instanceof Error?l.message:String(l)}`)}return(i.results??[]).slice(0,r).map(l=>({title:(l.title??"").trim()||"(untitled)",url:l.url??"",description:(l.highlights?.[0]??"").trim()})).filter(l=>l.url.length>0)}}}function NT(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?uK({apiKey:e.exaApiKey,fetchFn:e.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 BT(e,t){if(t.length===0)return`# Search results for "${e}"
1082
+ `).trim()}function lW(e){return(e?.textContent??"").replace(/\s+/g," ").trim().length}function lT(e,t){let r=new sW(e,{url:t}).window.document,o=(r.title??"").trim(),s=null;try{let c=r.cloneNode(!0);s=new iW(c).parse()}catch{s=null}if(s&&typeof s.content=="string"&&s.content.trim().length>0){let c=iT(gh.turndown(s.content)),u=(s.title??"").trim()||o,d=typeof s.length=="number"&&s.length>0?s.length:(s.textContent??"").replace(/\s+/g," ").trim().length;return{title:u,markdown:c,textLength:d,usedFallback:!1}}let i=r.body,a=i?.innerHTML??"",l=iT(gh.turndown(a));return{title:o,markdown:l,textLength:lW(i),usedFallback:!0}}var aT,gh,cT=P(()=>{"use strict";aT=200,gh=new aW({headingStyle:"atx",codeBlockStyle:"fenced",bulletListMarker:"-"});gh.remove(["script","style","noscript","iframe"])});function uW(e,t){return new Promise((n,r)=>{if(t?.aborted){r(t.reason??new Error("aborted"));return}let o=()=>{clearTimeout(s),r(t?.reason??new Error("aborted"))},s=setTimeout(()=>{t?.removeEventListener("abort",o),n()},e);t?.addEventListener("abort",o,{once:!0})})}function uT(e,t,n){let r=Math.min(t*2**e,n);return Math.round(Math.random()*r)}function dW(e,t){let n=e.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,t)}async function Fu(e,t,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??uW,l=n.signal??void 0,c;for(let u=0;u<=o;u++){if(l?.aborted)throw l.reason??new Error("aborted");try{let d=await e(t,n);if(!cW.has(d.status)||u===o)return d;let p=dW(d,i)??uT(u,s,i);W("[web/retryFetch] retrying",{url:t,attempt:u,status:d.status,waitMs:p}),await d.body?.cancel().catch(()=>{}),await a(p,l)}catch(d){if(l?.aborted||(c=d,u===o))throw d;let p=uT(u,s,i);W("[web/retryFetch] retrying after error",{url:t,attempt:u,waitMs:p}),await a(p,l)}}throw c??new Error("retryFetch: exhausted without a result")}var cW,hh=P(()=>{"use strict";Pe();cW=new Set([429,502,503,504])});import{readFileSync as pW}from"node:fs";import{join as mW}from"path";function fW(e){let n=e.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function dT(e,t){return fW(t).test(e)}function yW(e,t){if(e!==void 0){let n=e.trim().toLowerCase();if(n==="1"||n==="true"||n==="yes")return!0;if(n==="0"||n==="false"||n==="no")return!1}if(t!==void 0){if(gW.has(t))return!0;if(hW.has(t))return!1}return!1}function pT(e){return e===void 0||e.trim()===""?[]:e.split(",").map(t=>t.trim().toLowerCase()).filter(t=>t.length>0)}function bW(e){if(e===void 0||e===""||e==="playwright")return"playwright";throw new Error(`AFK_BROWSER_BACKEND: only "playwright" is supported in Phase 1, got: ${e}`)}function mT(e){let t=e===void 0||e.trim()===""?"default":e.trim();return Ra(t),t}function wW(e){if(e===void 0)return!1;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"}function SW(e){try{return pW(e,"utf8")}catch(t){if(t.code==="ENOENT")return;throw t}}function vW(e,t){let n={...e};if(typeof t.headless=="boolean"&&(n.headless=t.headless),Array.isArray(t.allowedDomains)&&(n.allowedDomains=t.allowedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),Array.isArray(t.blockedDomains)&&(n.blockedDomains=t.blockedDomains.filter(r=>typeof r=="string").map(r=>r.trim().toLowerCase()).filter(r=>r.length>0)),typeof t.domSnapshots=="boolean"&&(n.domSnapshots=t.domSnapshots),t.backend==="playwright")n.backend="playwright";else if(t.backend!==void 0)throw new Error(`AFK_BROWSER_BACKEND: only "playwright" is supported in Phase 1, got: ${String(t.backend)}`);return typeof t.defaultProfile=="string"&&(n.defaultProfile=mT(t.defaultProfile)),n}function fT(e){let t=e?.env??v,n=e?.readFileSync??SW,r=e?.surface??t.AGENT_SURFACE,o=yW(t.AFK_BROWSER_HEADLESS,r),s=pT(t.AFK_BROWSER_ALLOWED_DOMAINS),i=pT(t.AFK_BROWSER_BLOCKED_DOMAINS),a=wW(t.AFK_BROWSER_DOM_SNAPSHOTS),l=bW(t.AFK_BROWSER_BACKEND),c=mT(t.AFK_BROWSER_DEFAULT_PROFILE),u={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:l,configPath:null,defaultProfile:c},d=t.AFK_BROWSER_CONFIG,p=d!==void 0&&d.trim()!==""?d.trim():mW(rn(),"browser.json"),m=n(p);if(m===void 0)return u;let g;try{g=JSON.parse(m)}catch(b){throw new Error(`Failed to parse browser config at ${p}: ${String(b)}`)}if(typeof g!="object"||g===null||Array.isArray(g))throw new Error(`Browser config at ${p} must be a JSON object`);let h=vW(u,g);return h.configPath=p,h}function yh(e,t){let n;try{n=new URL(e).hostname.toLowerCase()}catch{return{allowed:!1,reason:`invalid URL: ${e}`}}for(let r of t.blockedDomains)if(dT(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return t.allowedDomains.length>0&&!t.allowedDomains.some(o=>dT(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var gW,hW,bh=P(()=>{"use strict";J();q();gW=new Set(["daemon","subagent","telegram","afk"]),hW=new Set(["repl","interactive","cli"])});import $o from"node:fs";import Lu from"node:path";import{randomBytes as kW}from"node:crypto";import{chromium as EW}from"playwright";function TW(){try{return"5.15.2"}catch{}try{let e=Lu.resolve(import.meta.dirname,"../../../package.json"),t=$o.readFileSync(e,"utf8"),n=JSON.parse(t);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var xW,Nu,gT=P(()=>{"use strict";q();Pe();xW=TW(),Nu=class{config;browser;sessions=new Map;launchPromise;shutdownComplete=!1;constructor(t){this.config=t}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=EW.launch({headless:this.config.headless}).then(t=>(this.browser=t,this.launchPromise=void 0,t)).catch(t=>{throw this.launchPromise=void 0,t}),this.launchPromise))}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(t){let n=this.sessions.get(t);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(t,i),s}async ensurePage(t){let n=this.sessions.get(t);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(t);let r=this.sessions.get(t);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${t}`);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(t){return this.sessions.get(t)?.page}async renderHtml(t,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(t,{timeout:n.timeoutMs,waitUntil:n.waitUntil}),l=await i.content(),c=i.url(),u=a!==null?a.status():null;return{html:l,finalUrl:c,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",s),await o.close().catch(()=>{})}}getConsoleErrorCount(t){return this.sessions.get(t)?.consoleErrors??0}getLastHttpStatus(t){return this.sessions.get(t)?.lastHttpStatus??null}hasOpenDialog(t){return this.sessions.get(t)?.openDialog!==void 0}async dismissDialog(t,n=!0){let r=this.sessions.get(t);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(t){let n=this.sessions.get(t);n!==void 0&&(this.sessions.delete(t),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.shutdownComplete)return;this.shutdownComplete=!0;let t=[...this.sessions.keys()];if(await Promise.all(t.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/${xW}`}}loadStorageState(t){let n=Ca(t);try{if(!$o.existsSync(n))return;let r=JSON.parse($o.readFileSync(n,"utf8"));return W("[browser/vault] restored session",{profile:t,file:n}),r}catch(r){W("[browser/vault] ignoring unreadable vault",{profile:t,file:n,err:r});return}}async saveStorageState(t,n){try{let r=Ca(t);if(!$o.existsSync(r))return;let o=await n.storageState(),s=Lu.join(Lu.dirname(r),`.${Lu.basename(r)}.${process.pid}.${kW(4).toString("hex")}.tmp`);$o.writeFileSync(s,JSON.stringify(o),{mode:384}),$o.chmodSync(s,384),$o.renameSync(s,r),W("[browser/vault] saved session",{profile:t,file:r})}catch(r){W("[browser/vault] save failed",{profile:t,err:r})}}}});import{createHash as RW}from"crypto";function wh(e){if(e.length===0)return e;let t=e;for(let{regex:n,name:r}of CW)r==="form-password"?t=t.replace(n,"password=[redacted]"):t=t.replace(n,"[redacted]");return t}function hT(e){return!!(e.role==="textbox"&&e.kind==="password"||e.label&&AW.test(e.label))}function yT(e){return RW("sha256").update(e,"utf8").digest("hex").slice(0,8)}function bT(e){let t=e.replace(/\s+/g," ").trim();return t.length<=80?t:t.slice(0,77)+"..."}var CW,AW,Ja=P(()=>{"use strict";CW=[{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}];AW=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as _W}from"node:crypto";function PW(e){return e?e.replace(/\s+/g," ").trim().slice(0,200):""}function IW(e,t,n){return`el_${_W("sha256").update(`${e}:${t}:${n}`).digest("hex").slice(0,6)}`}function MW(e){let t=e.replace(/\s+/g," ").trim(),n=4e3;return t.length<=n?t:t.slice(0,n)+"\u2026[truncated]"}function wT(e){return e.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function vT(e,t){let n=e.role??"",r=e.name??"";ST.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&t.push(e);for(let s of e.children??[])vT(s,t)}async function OW(e){return e.evaluate(t=>{let n=Array.from(document.querySelectorAll(t)),r=[];for(let o of n){let s=o.getBoundingClientRect(),i=o;if(s.width===0&&s.height===0){let u=window.getComputedStyle(i);if(u.display==="none"||u.visibility==="hidden")continue}let a=o.tagName.toLowerCase(),l=o.getAttribute("aria-label")??o.getAttribute("placeholder")??(o.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a==="input"?o.type||null:o.getAttribute("type");r.push({name:l,tagName:a,type:c,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},kT).catch(()=>[])}async function $W(e){return e.evaluate(t=>{let n={button:"button",a:"link",input:"textbox",textarea:"textbox",select:"combobox"},r=Array.from(document.querySelectorAll(t)),o=[];for(let s of r){let i=s.tagName.toLowerCase(),a=s.getAttribute("role")??"",l=s.getAttribute("aria-label")??s.getAttribute("placeholder")??(s.textContent??"").replace(/\s+/g," ").trim().slice(0,100),c=a||(n[i]??"");if(i==="input"){let h=s.type;h==="checkbox"?c="checkbox":h==="radio"?c="radio":h==="button"||h==="submit"||h==="reset"?c="button":h==="search"?c="searchbox":c="textbox"}if(!c)continue;let u="value"in s?s.value:void 0,d=u!==void 0?String(u):void 0,p=s.disabled??!1,m=i==="input"?s.checked:void 0,g={role:c,name:l,disabled:p};d!==void 0&&(g.value=d),m!==void 0&&(g.checked=m),o.push(g)}return o},kT).catch(()=>[])}function DW(e){let n=e.accessibility;return n!==null&&typeof n=="object"?n:null}async function Bu(e,t){let n=t.maxElements??80,r=t.includeHidden??!1,o=[],s=DW(e),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=OW(e),l=e.evaluate(()=>document.body?.innerText??"").catch(()=>""),c=Promise.resolve(e.url()),u=e.title().catch(()=>""),[d,p,m,g,h]=await Promise.all([i,a,l,c,u]),b,y=!1;d!==null?(b=[],vT(d,b)):(o.push("observation skipped accessibility tree (returned null)"),y=!0,b=(await $W(e)).filter(L=>ST.has(L.role??"")));let S=new Map;for(let I of p){let L=wT(I.name),N=S.get(L);(!N||N.bbox.w===0&&I.bbox.w>0)&&S.set(L,I)}let w=b.map(I=>({ax:I,dom:S.get(wT(I.name??""))})),k=r?w:w.filter(I=>I.dom?I.dom.bbox.w>0||I.dom.bbox.h>0:!0);k.sort((I,L)=>{let N=I.dom?.bbox.y??0,F=L.dom?.bbox.y??0;if(N!==F)return N-F;let U=I.dom?.bbox.x??0,H=L.dom?.bbox.x??0;return U-H}),k.length>200&&o.push("page has 200+ interactive elements; consider scoping");let R=k.slice(0,n).map((I,L)=>{let N=I.ax.role??"generic",F=I.ax.name??"",U=IW(N,F,L),H=I.dom?.bbox??{x:0,y:0,w:0,h:0},D=I.dom?.type??null,C=null;I.ax.value!==void 0&&I.ax.value!==null&&(C=String(I.ax.value)),I.ax.checked!==void 0&&(C=String(I.ax.checked)),hT({role:N,kind:D})&&(C="[redacted]");let B={disabled:I.ax.disabled??!1};I.ax.checked!==void 0&&(B.checked=I.ax.checked===!0||I.ax.checked==="mixed"),I.ax.selected!==void 0&&(B.selected=I.ax.selected),I.ax.expanded!==void 0&&(B.expanded=I.ax.expanded);let M;I.dom?.testId?M=`[data-testid="${I.dom.testId}"]`:I.dom?.id&&(M=`#${I.dom.id}`);let j={id:U,role:N,label:PW(F),kind:D,value:C,state:B,bbox:H};return M!==void 0&&(j.selector=M),j}),A="idle";try{let I=await e.evaluate(()=>document.readyState);I==="loading"?A="loading":I==="interactive"?A="navigating":A="idle"}catch{A="navigating"}A!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),y&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let E=MW(m),O=`obs_${t.observationCounter.toString(36)}`,_=new Date().toISOString();return{observationId:O,url:g,title:h,textSummary:E,interactive:R,status:{httpStatus:t.httpStatus??null,loadingState:A,hasDialog:t.hasDialog??!1,consoleErrors:t.consoleErrors??0},warnings:o,screenshotPath:t.screenshotPath??null,capturedAt:_}}var ST,kT,ET=P(()=>{"use strict";Ja();ST=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);kT="a[href], button, input, select, textarea, [role], [tabindex], label"});async function TT(e,t){try{let n=await e.nth(t).evaluate(i=>{let a=i,l=a.getAttribute("role")??a.tagName.toLowerCase(),c=a.getAttribute("aria-label")??a.getAttribute("placeholder")??(a.innerText!=null?a.innerText.trim().slice(0,200):"")??a.getAttribute("title")??"",u=a.getBoundingClientRect();return{role:l,label:c,x:Math.round(u.x),y:Math.round(u.y),w:Math.round(u.width),h:Math.round(u.height)}}),r=`${n.role}:${n.label}:${t}`,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 Sh(e,t){let n=Math.min(t,5);return(await Promise.all(Array.from({length:n},(o,s)=>TT(e,s)))).filter(o=>o!==null)}async function FW(e){let t=new Set,n=[];for(let{loc:r,count:o}of e)for(let s=0;s<o;s++){let i;try{i=await r.nth(s).evaluate(a=>{let l=a,c=l.getBoundingClientRect();return`${l.tagName}@${Math.round(c.x)},${Math.round(c.y)}`})}catch{continue}t.has(i)||(t.add(i),n.push({key:i,locator:r,index:s}))}return n}async function vh(e,t,n){switch(t.kind){case"element_id":return LW(e,t,n);case"selector":return NW(e,t);case"semantic":return BW(e,t)}}async function LW(e,t,n){let r=n.get(t.elementId);if(r===void 0)return{outcome:"not_found",query:t};if(r.selector!==void 0){let l=e.locator(r.selector);if(await l.count()===1)return{outcome:"resolved",locator:l}}let o=e.getByRole(r.role,{name:r.label,exact:!0}),s=await o.count();if(s===0)return{outcome:"not_found",query:t};if(s===1)return{outcome:"resolved",locator:o};let i=await Sh(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function NW(e,t){let n=e.locator(t.selector),r=await n.count();if(r===0)return{outcome:"not_found",query:t};if(r===1)return{outcome:"resolved",locator:n};let o=await Sh(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${t.selector}]`},candidates:o}}async function BW(e,t){return t.role!==void 0?UW(e,t.text,t.role):jW(e,t.text,t)}async function UW(e,t,n){let r=e.getByRole(n,{name:t}),o=await r.count();if(o===0)return{outcome:"not_found",query:{kind:"semantic",text:t,role:n}};if(o===1)return{outcome:"resolved",locator:r};let s=await Sh(r,o);return{outcome:"ambiguous_target",query:{text:t,role:n},candidates:s}}async function jW(e,t,n){let r=e.getByRole("button",{name:t}),o=e.getByRole("link",{name:t}),s=e.getByLabel(t,{exact:!1}),[i,a,l]=await Promise.all([r.count(),o.count(),s.count()]);if(i+a+l===0)return{outcome:"not_found",query:n};let u=[];i>0&&u.push({loc:r,count:i}),a>0&&u.push({loc:o,count:a}),l>0&&u.push({loc:s,count:l});let d=await FW(u);if(d.length===0)return{outcome:"not_found",query:n};if(d.length===1){let h=d[0];return h===void 0?{outcome:"not_found",query:n}:{outcome:"resolved",locator:h.locator.nth(h.index)}}let p=d.slice(0,5),m=[];for(let h=0;h<p.length;h++){let b=p[h];if(b===void 0)continue;let y=await TT(b.locator,b.index);if(y!==null){let S=`${y.role}:${y.label}:${h}`,w=0;for(let k=0;k<S.length;k++)w=w*31+S.charCodeAt(k)>>>0;m.push({...y,id:`el_${w.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:t},candidates:m}}var xT=P(()=>{"use strict"});import{randomBytes as HW}from"crypto";import{mkdir as WW,stat as KW,writeFile as GW}from"fs/promises";import{join as kh}from"path";import{gzip as qW}from"zlib";import{promisify as zW}from"util";function JW(e){return kh(Cs(e),"browser")}function VW(e){return kh(JW(e),"screenshots")}function YW(){return new Date().toISOString().replace(/[:.]/g,"-")}function XW(){return HW(3).toString("hex")}async function Eh(e,t,n){if(t.length>RT)throw new Error(`writeScreenshotSidecar: buffer exceeds ${RT} byte cap (received ${t.length} bytes). Refusing to write oversized screenshot.`);let r=VW(e);await WW(r,{recursive:!0});let o=`${YW()}-${XW()}-${n}.png`,s=kh(r,o);await GW(s,t);let{size:i}=await KW(s);return{path:s,bytes:i}}var Zde,RT,CT=P(()=>{"use strict";q();Ja();Zde=zW(qW);RT=5*1024*1024});var _T={};xc(_T,{PlaywrightProvider:()=>Th});function AT(e){switch(e.kind){case"semantic":return e.role!==void 0?`semantic('${e.text}', role='${e.role}')`:`semantic('${e.text}')`;case"element_id":return`element_id(${e.elementId})`;case"selector":return`selector(${e.selector})`}}var Th,PT=P(()=>{"use strict";gT();ET();xT();bh();Ja();CT();Th=class{name="playwright";config;launcher;sessions=new Map;constructor(t){this.config=t,this.launcher=new Nu(t)}async open(t){let n=yh(t.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:t.url,reason:n.reason};let{sessionId:r}=t,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(t.url,{timeout:t.timeoutMs??3e4,waitUntil:t.waitFor??"load"})}catch(c){a=c}(t.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let l=await Bu(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,l.interactive,l.url,l.title,"browser_open"),a!==null)throw a;return l}async observe(t){let{sessionId:n}=t,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;t.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await Bu(r,{observationCounter:o.observationCounter,screenshotPath:s,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n),includeHidden:t.includeHidden,maxElements:t.maxElements});return this.updateSessionFromObservation(o,i.interactive,i.url,i.title,"browser_observe"),i}async act(t){let{sessionId:n}=t,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=t.timeoutMs??3e4,a=await vh(r,t.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${AT(t.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:l}=a,c=null,u=async()=>{switch(t.action){case"click":await l.click({timeout:i});break;case"fill":{let h=wh(t.value??"");await l.fill(t.value??"");break}case"press":await l.press(t.value??"");break;case"select":await l.selectOption(t.value??"");break;case"hover":await l.hover({timeout:i});break;case"scroll_to":await l.scrollIntoViewIfNeeded({timeout:i});break;case"wait_for":await l.waitFor({timeout:i,state:"visible"});break}};try{await u()}catch(h){if(h instanceof Error&&/navigation|net::ERR/i.test(h.message))try{await u()}catch(b){c=b}else c=h}let d=r.url();if(d!==s){let h=yh(d,this.config);if(!h.allowed)return await r.goBack().catch(()=>{}),{outcome:"blocked_by_policy",url:d,reason:h.reason}}let p=null;(t.screenshot===!0||c!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let m=await Bu(r,{observationCounter:o.observationCounter,screenshotPath:p,consoleErrors:this.launcher.getConsoleErrorCount(n),httpStatus:this.launcher.getLastHttpStatus(n),hasDialog:this.launcher.hasOpenDialog(n)}),g=`browser_act:${t.action}`;if(this.updateSessionFromObservation(o,m.interactive,m.url,m.title,g),c!==null)throw c;return m}async render(t){return this.launcher.renderHtml(t.url,{timeoutMs:t.timeoutMs??3e4,waitUntil:t.waitFor??"load",signal:t.signal})}async screenshot(t){let{sessionId:n}=t,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(t.target!==void 0){let u=await vh(r,t.target,o.knownElements);if(u.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${AT(t.target)}`);if(u.outcome==="ambiguous_target")throw new Error("screenshot target ambiguous; specify element_id or selector");s=await u.locator.screenshot()}else s=await r.screenshot({fullPage:t.fullPage??!1});let{path:i,bytes:a}=await Eh(n,s,"browser_screenshot"),l=0,c=0;if(t.fullPage===!0)try{let u=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));l=u.w,c=u.h}catch{let u=r.viewportSize();l=u?.width??0,c=u?.height??0}else{let u=r.viewportSize();l=u?.width??0,c=u?.height??0}return{path:i,bytes:a,width:l,height:c,dataBase64:s.toString("base64"),mediaType:"image/png"}}async extract(t){throw new Error("browser_extract not implemented in Phase 1")}async close(t){await this.launcher.closeSession(t.sessionId),this.sessions.delete(t.sessionId)}describe(t){let n=this.sessions.get(t);if(n===void 0)return null;let r=this.launcher.getPage(t);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(t){let n=this.sessions.get(t);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(t,r),r}updateSessionFromObservation(t,n,r,o,s){t.knownElements=new Map(n.map(i=>[i.id,i])),t.currentUrl=r,t.currentTitle=o,t.lastAction=s,t.lastActionAt=new Date().toISOString()}async captureScreenshot(t,n,r){try{let o=await t.screenshot({fullPage:!1}),{path:s}=await Eh(n,o,r);return s}catch{return null}}}});var Fo={};xc(Fo,{__resetBrowserRegistryForTests:()=>nK,browserProviderActive:()=>eK,closeBrowserProvider:()=>xh,getBrowserProvider:()=>QW,peekBrowserProvider:()=>tK});function IT(){Promise.resolve(xh()).then(()=>{process.exit(130)})}function MT(){Promise.resolve(xh()).then(()=>{process.exit(143)})}function OT(){_n=null}function ZW(){Uu||(process.on("SIGINT",IT),process.on("SIGTERM",MT),process.on("exit",OT),Uu=!0)}function $T(){Uu&&(process.removeListener("SIGINT",IT),process.removeListener("SIGTERM",MT),process.removeListener("exit",OT),Uu=!1)}async function QW(e){return _n!==null?_n:(Do!==null||(Do=(async()=>{let{PlaywrightProvider:t}=await Promise.resolve().then(()=>(PT(),_T)),n=fT(e),r=new t(n);return ZW(),_n=r,Do=null,r})()),Do)}async function xh(){if(_n===null)return;let e=_n;_n=null,Do=null,$T(),await e.shutdown()}function eK(){return _n!==null}function tK(){return _n}function nK(){_n=null,Do=null,$T()}var _n,Do,Uu,Lo=P(()=>{"use strict";bh();_n=null,Do=null,Uu=!1});function DT(e,t){try{return lT(e,t)}catch(n){return W("[web/scrape] extraction failed",{url:t,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function aK(e,t){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Lo(),Fo));return(await n()).render({url:e,timeoutMs:t.timeoutMs,signal:t.signal})}async function FT(e,t){let n=t.fetchFn??globalThis.fetch,r=t.renderFn??aK,o=null,s=e,i=null,a=null;try{let c=await Fu(n,e,{headers:iK,redirect:"follow",signal:t.signal});i=c.status,s=c.url||e;let u=c.headers.get("content-type")??"";if(c.ok){if(sK.test(u))throw new Error(`web_scrape markdown mode received binary content (${u.split(";")[0]}). Use mode: "raw" to fetch the bytes, or a different tool.`);let d=await c.text();if(oK.test(u)&&!rK.test(u))return{title:"",markdown:d.trim(),finalUrl:s,usedRender:!1};o=DT(d,s)}}catch(c){if(t.signal.aborted||c instanceof Error&&c.message.startsWith("web_scrape markdown mode received binary"))throw c;a=c}if(!(o===null||o.textLength<aT)&&o!==null)return{title:o.title,markdown:o.markdown,finalUrl:s,usedRender:!1};try{let c=await r(e,{timeoutMs:t.timeoutMs,signal:t.signal}),u=DT(c.html,c.finalUrl);if(o===null||u.textLength>=o.textLength)return{title:u.title,markdown:u.markdown,finalUrl:c.finalUrl,usedRender:!0}}catch(c){if(t.signal.aborted)throw c;if(o===null){let u=c instanceof Error?c.message:String(c),d=a instanceof Error?a.message:`HTTP ${i??"error"}`,p=new Error(`web_scrape could not retrieve ${e}: fetch failed (${d}) and render failed (${u}).`);throw p.cause=c,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 ${e} (HTTP ${i??"error"}).`)}var rK,oK,sK,iK,LT=P(()=>{"use strict";cT();hh();Pe();rK=/(text\/html|application\/xhtml\+xml)/i,oK=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,sK=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,iK={"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 uK(e){let t=e.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await t(lK,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json","x-api-key":e.apiKey,"User-Agent":"agent-afk/web_scrape"},body:JSON.stringify({query:n,type:"auto",numResults:Math.min(Math.max(r,1),cK),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let l="";try{let u=await s.text(),d=Mo(u);d&&(l=`: ${d.length>200?d.slice(0,200)+"\u2026":d}`)}catch{}let c=s.statusText?` ${s.statusText}`:"";throw new Error(`Exa Search HTTP ${s.status}${c}${l}`)}let i;try{i=await s.json()}catch(l){throw new Error(`Exa Search response was not JSON: ${l instanceof Error?l.message:String(l)}`)}return(i.results??[]).slice(0,r).map(l=>({title:(l.title??"").trim()||"(untitled)",url:l.url??"",description:(l.highlights?.[0]??"").trim()})).filter(l=>l.url.length>0)}}}function NT(e){return e.exaApiKey!==void 0&&e.exaApiKey.trim()!==""?uK({apiKey:e.exaApiKey,fetchFn:e.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 BT(e,t){if(t.length===0)return`# Search results for "${e}"
1082
1083
 
1083
1084
  (no results)`;let n=[`# Search results for "${e}"`,""];return t.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(`
1084
1085
  `).trimEnd()}var lK,cK,UT=P(()=>{"use strict";Oo();lK="https://api.exa.ai/search",cK=10});function bK(e){if(!e||typeof e!="object")return{error:"Invalid input: expected an object"};let t=e,n=t.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 t.query!="string"||t.query.length===0)return{error:'Invalid input: search mode requires a non-empty "query" string'};s=t.query}else{if(typeof t.url!="string"||t.url.length===0)return{error:`Invalid input: ${r} mode requires a non-empty "url" string`};let l;try{l=new URL(t.url)}catch{return{error:`Invalid input: "${t.url}" is not a valid absolute URL`}}if(l.protocol!=="http:"&&l.protocol!=="https:")return{error:`Invalid input: protocol "${l.protocol}" not supported (http/https only)`};o=l.toString()}let i=dK;if(t.timeout_ms!==void 0){if(typeof t.timeout_ms!="number"||!Number.isFinite(t.timeout_ms)||t.timeout_ms<=0)return{error:"Invalid input: timeout_ms must be a positive finite number"};i=Math.min(t.timeout_ms,pK)}let a=mK;if(t.max_bytes!==void 0){if(typeof t.max_bytes!="number"||!Number.isFinite(t.max_bytes)||t.max_bytes<=0)return{error:"Invalid input: max_bytes must be a positive finite number"};a=Math.min(t.max_bytes,fK)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Rh(e,t){let n=Buffer.from(e,"utf8");return n.byteLength<=t?e:n.subarray(0,t).toString("utf8")+gK}function wK(e){let t=[],n=e;for(let o=0;o<4&&n instanceof Error;o++)t.push(n.message),n=n.cause;let r=t.join(" | ");return yK.some(o=>r.includes(o))}function SK(e={}){let t=e.fetchFn??globalThis.fetch,n=e.env??process.env;return async(r,o)=>{if(typeof t!="function")return{content:"web_scrape unavailable: global fetch() is not present in this runtime (agent-afk requires Node 20+).",isError:!0};let s=bK(r);if("error"in s)return{content:s.error,isError:!0};if(o.aborted){let u=o.reason;return{content:`web_scrape aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0}}let i=new AbortController,a=()=>{i.abort(o.reason)},l,c=()=>{let u=i.signal.reason;return u instanceof Error?u.message:String(u??"aborted")};try{if(o.addEventListener("abort",a,{once:!0}),l=setTimeout(()=>{i.abort(new Error(`web_scrape timeout after ${s.timeoutMs}ms`))},s.timeoutMs),s.mode==="raw"){let d;try{d=await Fu(t,s.url,{method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:i.signal})}catch(m){return i.signal.aborted?{content:`web_scrape aborted: ${c()}`,isError:!0}:{content:`web_scrape network error: ${m instanceof Error?m.message:String(m)}`,isError:!0}}if(!d.ok)return{content:`web_scrape HTTP ${d.status} ${d.statusText||""}`.trimEnd()+` for ${s.url}`,isError:!0};let p;try{p=await d.text()}catch(m){return{content:`web_scrape read error: ${m instanceof Error?m.message:String(m)}`,isError:!0}}return{content:Rh(p,s.maxBytes)}}if(s.mode==="markdown")try{let d=await FT(s.url,{fetchFn:t,renderFn:e.renderFn,timeoutMs:s.timeoutMs,signal:i.signal});return d.markdown.trim().length===0?{content:`web_scrape extracted no readable content from ${s.url}.`,isError:!0}:{content:Rh(d.markdown,s.maxBytes)}}catch(d){if(i.signal.aborted)return{content:`web_scrape aborted: ${c()}`,isError:!0};let p=d instanceof Error?d.message:String(d),m=wK(d)?" (the render fallback needs the optional Playwright browser \u2014 run `pnpm exec playwright install chromium`)":"";return{content:`web_scrape markdown error: ${p}${m}`,isError:!0}}let u=NT({exaApiKey:n.EXA_API_KEY,fetchFn:t});if("error"in u)return{content:u.error,isError:!0};try{let d=await u.search(s.query,{limit:hK,timeoutMs:s.timeoutMs,signal:i.signal});return{content:Rh(BT(s.query,d),s.maxBytes)}}catch(d){return i.signal.aborted?{content:`web_scrape aborted: ${c()}`,isError:!0}:{content:`web_scrape search error (${u.name}): ${d instanceof Error?d.message:String(d)}`,isError:!0}}}finally{l!==void 0&&clearTimeout(l),o.removeEventListener("abort",a)}}}var dK,pK,mK,fK,gK,hK,yK,jT,HT=P(()=>{"use strict";LT();UT();hh();dK=3e4,pK=12e4,mK=1e6,fK=1e7,gK=`
@@ -2011,7 +2012,7 @@ _ended: ${new Date().toISOString()}_
2011
2012
  ${k}${S}
2012
2013
  ${w}
2013
2014
  ${k}`})}return{fileBlocks:a,warnings:l}}async function gD(e,t,n,r,o="summary",s,i){let a=d0(e.text,e.attachments);r.onUserMessage&&await Promise.resolve(r.onUserMessage(a)).catch(()=>{}),r.setInFlight(!0);let l="",c=0,u=!1,d=!1,p=!1,m=!1,g,h=!1,b=!1,y={abort:null},S=0,w=3e3,k=[],T=new Map,R=e.text.startsWith("/")?e.text.split(/[\s:]/)[0]?.slice(1):void 0,A=()=>{let N=r.subagentControl;N?.hasPromotableForeground()&&N.promoteActiveForeground().then(F=>{for(let U of F)(s??{fn:console.log}).fn(f.dim(` \u2192 subagent backgrounded as ${U.jobId}: ${U.label}`))}).catch(()=>{})},E=r.getCompositor?r.getCompositor():null,O=()=>new Xi({out:Zi(s),thinkingMode:o,...R?{activeSkillName:R}:{},onCancel:()=>{t.interrupt().catch(N=>{qe()&&console.error(" "+f.error("session.interrupt() failed:"),N)})},...r.subagentControl?{onBackground:A}:{},...i?.history?{history:i.history}:{},...i?.autocompleteState?{autocompleteState:i.autocompleteState}:{},...i?.promptText!==void 0?{promptText:i.promptText}:{},...r.scrollRegion?{scrollRegion:r.scrollRegion}:{},...E?{compositor:E}:{},...r.onStageChange?{onStageChange:r.onStageChange}:{}}),_=O(),I=async()=>{if(!p){p=!0;try{await _.dispose()}catch{}}},L=async()=>{await _.arm();let N=_.getCompositor();if(s&&N){let F=N;s.fn=U=>F.commitAbove(U)}r.setActiveCompositor?.(N),r.setInterruptNotifier?.(F=>_.setInterrupting(F)),r.rearmStatus?.()};try{E?E.commitAbove(""):console.log(),r.setSoftStopHandler&&r.setSoftStopHandler(()=>{h=!0,t.interrupt().catch(C=>{qe()&&console.error(" "+f.error("soft-stop session.interrupt() failed:"),C)})}),r.setPauseInterruptHandler&&r.setPauseInterruptHandler(()=>{b=!0,t.interrupt().catch(C=>{qe()&&console.error(" "+f.error("pause-interrupt session.interrupt() failed:"),C)})}),await L(),r.setBackgroundHandler&&r.subagentControl&&r.setBackgroundHandler(A);let{fileBlocks:N,warnings:F}=fD(e.text,{rootDir:process.cwd()});for(let C of F)(s??{fn:console.log}).fn(f.dim(` @-file: ${C}`));let U=N.length>0||e.attachments.length>0?pD(e.text,e.attachments,void 0,N):e.text,H=t.sendMessageStream(U);if(await js((C,B)=>{_.process(C,B)},async()=>{for await(let C of H){if(h||b)break;if(C.type==="chunk"&&C.chunk.type==="content"?(l+=C.chunk.content,u=!0):C.type==="message"&&!u&&(l=C.message.content),C.type==="stream_retry"&&(l=l.slice(0,c)),C.type==="chunk"&&C.chunk.type==="tool_use_detail"){let B=C.chunk,M={toolName:B.toolName,toolUseId:B.toolUseId,input:B.toolInput,...B.toolInputRaw!==void 0&&{inputRaw:B.toolInputRaw}};T.set(B.toolUseId,M),k.push(M)}else if(C.type==="chunk"&&C.chunk.type==="tool_result"){let B=C.chunk;c=l.length;let M=T.get(B.toolUseId);if(M&&(M.result=B.content,M.isError=B.isError,T.delete(B.toolUseId)),r.onContextProgress){let j=Date.now();if(j-S>=w){S=j;try{let X=r.onContextProgress();X instanceof Promise&&await X}catch(X){qe()&&console.error(" "+f.error("onContextProgress (status refresh) failed:"),X)}}}}if(C.type==="paused"){if(r.setPausedState?.(!0),await I(),E&&C.autoResume===!0){let B=new AbortController;y.abort=B;let M=C.resetsAt?C.resetsAt.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit"}):null,j=M?`Keep waiting \u2014 auto-resumes at ${M}`:"Keep waiting \u2014 auto-resume in progress",X="Switch model / provider (type /model after)",ie="Stop waiting",Z=[f.warning(" \u23F3 Usage limit reached.")+(M?f.dim(` Auto-resumes at ${M}.`):""),f.dim(" Tip: run `claude login` in another terminal to switch account \u2014 this turn resumes on it automatically."),""];Xm(E,{header:Z,options:[j,X,ie],signal:B.signal,initialIndex:0}).then(fe=>{if(y.abort=null,!fe)return;let V=fe[0];V===void 0||V===j||(b=!0,V===X&&(s??{fn:console.log}).fn(f.dim(" Hint: type /model <name> to switch, then send your message again.")),t.interrupt().catch(_e=>{qe()&&console.error(" "+f.error("picker pause-interrupt session.interrupt() failed:"),_e)}))}).catch(fe=>{qe()&&console.error(" "+f.error("picker promise rejected:"),fe)})}else(s??{fn:console.log}).fn(ik({reason:C.reason,...C.resetsAt!==void 0?{resetsAt:C.resetsAt}:{},...C.accountId!==void 0?{accountId:C.accountId}:{},...C.autoResume!==void 0?{autoResume:C.autoResume}:{}}));continue}if(C.type==="resumed"){r.setPausedState?.(!1),y.abort?.abort(),y.abort=null;let B=C.hotSwapped&&C.accountId?`\u25B6 Resumed on ${C.accountId}`:"\u25B6 Resumed";l="",c=0,u=!1,k.length=0,T.clear(),m=!1,g=void 0,d=!1,_=O(),p=!1,await L(),(s??{fn:console.log}).fn(f.success(B));continue}if(C.type==="error"){await I(),Ms(As(C.error)),d=!0;continue}_.process(C),C.type==="done"&&(m=!0,g=C.metadata)}}),await I(),h){let C=s?s.fn:console.log;C(f.warning("\u23F8 Stopped \u2014 work so far kept.")+f.dim(" Send a message to continue.")),C("")}if(b){let C=s?s.fn:console.log;C(f.dim("\u25B6 Ending wait \u2014 running your next command\u2026")),C("")}if(m&&!h&&!b){Go(n,a,l,g,k),r.onTurnComplete&&await r.onTurnComplete(a,l).catch(()=>{}),Pp(process.stdout);let C=M=>{s?s.fn(M):console.log(M)},B=uD(l);if(B){if(C(dD(B)),C(""),r.onTerminalState)try{r.onTerminalState(B)}catch{}if(n.permissionMode==="autonomous"){let M=B.kind==="done"&&$u().verifyDone===!0&&!LI(k);BI(B,void 0,{unverified:M})}}if(bZ(g,n,C),r.onAfterTurn){let M=r.onAfterTurn();M instanceof Promise&&await M.catch(()=>{})}}}catch(N){await I(),d||Ms(As(N))}finally{await I(),s&&(s.fn=s.idleFn),r.setActiveCompositor?.(null),r.setInterruptNotifier?.(null),r.setBackgroundHandler?.(null),r.setSoftStopHandler?.(null),r.setPausedState?.(!1),r.setPauseInterruptHandler?.(null),y.abort?.abort(),y.abort=null,r.setInFlight(!1),r.rearmStatus?.()}}function bZ(e,t,n=console.log){if(!e)return;let r=[];e.durationMs&&r.push(he(e.durationMs)),e.totalCostUsd!==void 0&&r.push(lt(e.totalCostUsd));let o=Number(e.usage?.input_tokens??0),s=Number(e.usage?.output_tokens??0);o+s>0&&r.push(ae(o+s)+" tok"),r.length>0&&n(f.dim(" \u25E6 "+r.join(" \xB7 ")));let i=Lb(t),a=Lt(t.model);if(i>=1){let l=Math.round((i-1)*a),c=Math.round(a/1e3);n(f.error(` context OVER ${c}k tok by ~${ae(l)} tok \u2014 model output may be silently truncated`))}else if(i>.5){let l=i>.8?f.error:f.warning;n(l(` context ${Math.round(i*100)}% used of ${ae(a)}`))}n("")}var wZ=5e3;async function SZ(e,t){if(e.firstTurnHook&&e.stats.totalTurns===0){let n=e.firstTurnHook;e.firstTurnHook=void 0;try{await n(t)}catch(r){e.completionWriter.fn(f.warning("\u26A0 ")+"first-turn hook failed: "+(r instanceof Error?r.message:String(r)))}}}async function hD(e,t,n,r,o,s,i,a){let{contextPane:l,loopStageBar:c,verdictLedger:u,shellPassthrough:d}=i,p=null,m=[];e.session.current.waitForInitialization().then(async y=>{qe()&&(p=Bp(y)),await Im(e.session.current),qe()&&(m=u$())}).catch(()=>{});let g,h=!1,b=!1;for(;;){if(p&&(e.replRenderer.writeLine(p),e.replRenderer.writeLine(""),p=null),m.length>0){for(let E of m)e.replRenderer.writeLine(E);e.replRenderer.writeLine(""),m=[]}let y=d.drainNotifications();for(let{job:E,result:O}of y){let _=O.errorReason===void 0?"\u2713":"\u2717",I=O.errorReason==="abort"?"killed":O.errorReason==="timeout"?"timed out":O.errorReason==="signal-killed"?"killed by signal":`exit ${O.exitCode??0}`,L=Math.max(0,Math.round(O.durationMs/100)/10);e.replRenderer.writeLine(f.dim(` ${_} [${E.id}] ${I} \xB7 ${L}s \xB7 `)+E.command)}let S=l.renderIfChanged(e.stats.sessionId);if(S.length>0){for(let E of S)e.replRenderer.writeLine(E);e.replRenderer.writeLine("")}let w,k;if(g===void 0){let E=await e.session.current.takePendingPlanExitSeed();E!==void 0&&(g={text:E,attachments:[]})}if(g!==void 0){let E=g;g=void 0;let O=na(e.stats.permissionMode),_=Qo({buffer:E.text,promptText:O,isTTY:!!process.stdout.isTTY,attachmentSummary:Wi([...E.attachments])});e.replRenderer.writeLine(_),w=E.text.trim(),k=E.attachments}else{let E=await o.readLine({promptFn:()=>na(e.stats.permissionMode),onSigint:r,onShiftTab:()=>{Zm(e.slashCtx).catch(()=>{}),e.statusLine.rearm()}});w=E.text.trim(),k=E.attachments}if(!w&&k.length===0)continue;if(w.startsWith("!")){let E=/^(0|false|off|no)$/i.test(v.AFK_SHELL_PASSTHROUGH??"");if(e.options.shellPassthrough!==!1&&!E&&(h||(h=!0,e.replRenderer.writeLine(f.dim(" \u2139 ! prefix shells out. Pass --no-shell-passthrough (or set AFK_SHELL_PASSTHROUGH=0) to send ! text to the model instead."))),await d.dispatch(w))){e.statusLine.rearm();continue}}let T=!1;if(w.startsWith("/")){let E=await _I(w,e.slashCtx,k);if(E.handled){if(E.result==="exit"){e.rl.close();return}if((w==="/clear"||w.startsWith("/clear "))&&(await t.rotateOnClear(),e.replRenderer.writeLine(f.dim(` transcript: ${t.path()}`)),u.reset()),E.result!==null&&typeof E.result=="object"&&"kind"in E.result&&E.result.kind==="submit"){g={text:E.result.message,attachments:k??[]},e.statusLine.rearm();continue}e.statusLine.rearm();continue}T=!0}a.push(w),await SZ(e,w);let R=w;if(T){let E=Fb(w);if(E){let O=E.name.replace(/^\//,"").split(":").pop()??"";if(O&&Hw(O)){let _={skillName:O,rawArgs:E.args,source:"plugin",capabilities:{compose:!0,subagents:!0}},I=e.session.current.sessionId,L=ls(I),N=Date.now();W(`[afk trace] preflight.start commandName=${O}`);let F=!1,U=await as(_,{cwd:e.stats.cwd??process.cwd(),artifactDir:L},H=>{qe()&&e.replRenderer.writeLine(f.warning(`\u26A0 preflight(${O}) failed: `)+(H instanceof Error?H.message:String(H)))});F=U!==null,W(`[afk trace] preflight.end commandName=${O} durationMs=${Date.now()-N} success=${F}`),R=Kw(U?.manifestBlock,w)}}}let A=d.drainInjections();if(A.length>0&&(R=A+R),e.hookRegistry)try{let E={event:"UserPromptSubmit",prompt:R,sessionId:e.stats.sessionId},O=await e.hookRegistry.dispatch(E);O.injectContext&&(R=O.injectContext+R)}catch(E){if(E instanceof me){e.replRenderer.writeLine(f.warning("\u2298 Turn blocked by hook")+(E.reason?f.dim(`: ${Mo(E.reason)}`):"")),e.statusLine.rearm();continue}if(E instanceof Tn){e.replRenderer.writeLine(f.warning("\u2298 Turn blocked by hook")+f.dim(`: handler timed out after ${E.timeoutMs}ms`)),e.statusLine.rearm();continue}throw E}if(await gD({text:R,attachments:k},e.session.current,e.stats,{setInFlight(E){n.turnInFlight=E},...e.subagentControl?{subagentControl:e.subagentControl}:{},async onUserMessage(E){await t.appendUser(E)},async onTurnComplete(E,O){if(await t.appendTurn(E,O),e.stats.sessionId)try{Nn(e.stats)}catch(_){b||(b=!0,e.replRenderer.writeLine(f.warning("\u26A0 ")+"session autosave failed \u2014 this conversation may not be resumable: "+(_ instanceof Error?_.message:String(_))))}},async onAfterTurn(){await e.contextSampler.onTurn(e.stats.totalTurns),await e.gitStatusSampler.refresh(),e.statusLine.rearm(),c?.repaint("observing")},rearmStatus:()=>e.statusLine.rearm(),onTerminalState:E=>u?.push(E),setActiveCompositor:E=>{n.activeCompositor=E},setInterruptNotifier:E=>{n.notifyInterrupting=E},scrollRegion:e.statusLine,getCompositor:()=>o.getCompositor(),setBackgroundHandler:E=>o.setBackgroundHandler(E),setSoftStopHandler:s,setPausedState:E=>o.setPausedState(E),setPauseInterruptHandler:E=>o.setPauseInterruptHandler(E),async onContextProgress(){await e.contextSampler.refresh(),e.statusLine.repaint(jn(e.stats,e.contextSampler,e.gitStatusSampler))},...c?{onStageChange:E=>c.repaint(E)}:{}},e.options.thinkingUi,e.completionWriter,o.toRunTurnRefs(na(e.stats.permissionMode))),e.hookRegistry)try{await e.hookRegistry.dispatch({event:"Stop",sessionId:e.stats.sessionId},void 0,wZ)}catch(E){if(E instanceof ut)throw E;E instanceof Tn?(W("[stop hook] handler timed out"),e.completionWriter.fn(f.dim(" [stop hook] timed out"))):E instanceof me?e.completionWriter.fn(f.dim(` [stop hook] blocked: ${Mo(E.reason??"no reason given")}`)):W("[stop hook] unexpected error: "+String(E))}}}function vZ(e,t){if(e!==void 0){let n=e.toLowerCase();return!(n==="0"||n==="false"||n==="off"||n==="no")}return typeof t=="boolean"?t:!0}async function yD(e,t,n,r){let o=await J$(),s=new Ym({rl:e.rl,history:o,statusLine:e.statusLine}),i=vZ(v.AFK_SUGGEST_GHOST,e.suggestGhostConfig),a;try{let{installSoftStop:l}=await eD(e,s,n,t,r,i,{getLoopStageBar:()=>a?.loopStageBar});a=cD(e,n),await hD(e,t,n,r,s,l,a,o)}finally{n.tryAbortShellForeground=null,a?.shellPassthrough.drainOnExit(),a?.loopStageBar.stop(),a?.bgStatusBar.stop(),a?.verdictLedger.stop(),a?.contextPane.dispose();let l=c=>console.log(c);e.completionWriter.fn=l,e.completionWriter.idleFn=l,await s.dispose(),e.inputSurfaceRef&&(e.inputSurfaceRef.current=null)}}Ka();import{execFile as kZ}from"node:child_process";import{dirname as EZ,isAbsolute as TZ,resolve as xZ}from"node:path";import{promisify as RZ}from"node:util";var bD=RZ(kZ),CZ=3e3,AZ=new Set(["empty","orphaned-dir","orphaned-registration","dead-owner"]);async function _Z(){let t=(await bD("git",["rev-parse","--git-common-dir"])).stdout.trim();if(!t)throw new Error("Not in a git repository.");let n=TZ(t)?t:xZ(process.cwd(),t);return EZ(n)}async function wD(e){if(e?.disabled)return{ran:!1,removedCount:0,skippedReason:"disabled"};let t;try{t=await _Z()}catch{return{ran:!1,removedCount:0,skippedReason:"not-in-repo"}}let n,r=new Promise(o=>{n=setTimeout(()=>o("timeout"),CZ)});try{let o=Wn({execFile:bD,repoRoot:t,dryRun:!1,scope:"interactive",bypassSoftLaunch:!0}),s=await Promise.race([o,r]);if(s==="timeout")return{ran:!1,removedCount:0,skippedReason:"timeout"};let i=s;return i.warnings.some(c=>c.toLowerCase().includes("contested"))?{ran:!1,removedCount:0,skippedReason:"lock-contested"}:{ran:!0,removedCount:i.candidates.filter(c=>AZ.has(c.verdict)&&i.removed.includes(c.path)).length}}catch{return{ran:!1,removedCount:0,skippedReason:"error"}}finally{n&&clearTimeout(n)}}Zc();Ka();import{promises as PZ}from"node:fs";import{dirname as IZ,join as kD}from"node:path";import{randomBytes as MZ}from"node:crypto";var OZ=["Generate a 2-4 word kebab-case slug describing this work request.","Rules:","- ASCII lowercase letters and digits only, separated by single hyphens","- 2 to 4 hyphen-separated words","- Maximum 30 characters total","- No prefix, no quotes, no punctuation other than hyphens","- Output ONLY the slug \u2014 no explanation, no preamble","Examples: fix-cleanup-race, add-telegram-allowlist, refactor-prompt-loader, debug-flaky-test"].join(`
2014
- `),SD=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,pS=30,$Z=1024,DZ=8e3,FZ="haiku";async function LZ(e,t){let n=e.trim();if(n.length===0)return t.onSkip?.("empty-message"),null;if(n.startsWith("/"))return t.onSkip?.("slash-command"),null;let r=jZ(n,$Z),o=new AbortController,s=setTimeout(()=>o.abort(),t.timeoutMs??DZ),i=t.signal?HZ([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,i):a=await Bs({token:t.token,model:t.model??FZ,system:OZ,user:r,maxTokens:32,signal:i})}catch(d){let p=d instanceof Error?d.message:String(d);return t.onSkip?.("slug-generator-error",p.slice(0,200)),null}finally{clearTimeout(s)}let l=NZ(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=IZ(t.worktreePath);return await BZ(l,c)}function NZ(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(SD.test(t)&&t.length<=pS)return t;let n=t.replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if(n.length===0)return null;let r=n.split("-").filter(s=>s.length>0).slice(0,4);if(r.length<2)return null;let o=r[0];for(let s=1;s<r.length;s++){let i=`${o}-${r[s]}`;if(i.length>pS)break;o=i}return SD.test(o)?o:null}async function BZ(e,t){if(!await UZ(kD(t,e)))return e;let n=MZ(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,pS-5)}-${n}`}async function UZ(e){try{return await PZ.access(e),!0}catch{return!1}}function jZ(e,t){let n=Buffer.from(e,"utf8");if(n.length<=t)return e;let r=t;for(;r>0&&n[r]!==void 0&&(n[r]&192)===128;)r--;return n.slice(0,r).toString("utf8")}function HZ(e){let t=AbortSignal.any;if(typeof t=="function")return t.call(AbortSignal,e);let n=new AbortController;for(let r of e){if(r.aborted)return n.abort(r.reason),n.signal;r.addEventListener("abort",()=>n.abort(r.reason),{once:!0})}return n.signal}async function ED(e){let t,n,r=kD(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await LZ(e.message,{token:e.token,...e.model!==void 0?{model:e.model}:{},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},worktreePath:r,...e.signal!==void 0?{signal:e.signal}:{},...e.slugGenerator!==void 0?{slugGenerator:e.slugGenerator}:{},onSkip:(a,l)=>{t=a,n=l}}),s=t??"unknown",i=n;if(o!==null){let l=`${Pu(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return vD(e.session,c.path),{status:"created",path:c.path,branch:c.branch,slug:o}}catch(c){s="create-failed",i=(c instanceof Error?c.message:String(c)).slice(0,200)}}try{let a=await e.deferred.create(!0);return vD(e.session,a.path),{status:"created-fallback",path:a.path,branch:a.branch,reason:s,...i!==void 0?{detail:i}:{}}}catch(a){return{status:"failed",reason:a instanceof Error?a.message:String(a)}}}function vD(e,t){e&&e.setCwd(t),WZ(t)}function WZ(e){try{process.chdir(e)}catch{}}Ve();Ft();q();import{spawn as xD}from"child_process";import{existsSync as RD,mkdirSync as JZ,readFileSync as CD,unlinkSync as TD,writeFileSync as VZ}from"fs";import{get as YZ}from"https";import{join as AD}from"path";import{readFileSync as KZ}from"fs";import{dirname as GZ,join as qZ}from"path";import{fileURLToPath as zZ}from"url";function Cr(){try{return"5.15.1"}catch{}try{let e=GZ(zZ(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(KZ(qZ(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}J();var XZ=64*1024,ZZ=1440*60*1e3,QZ=3600*1e3,eQ="update-check.json",tQ="pending-update.json";function _D(){return AD(Pc(),eQ)}function lc(){return AD(Pc(),tQ)}function PD(){let e=Pc();RD(e)||JZ(e,{recursive:!0})}function nQ(e,t){let n=a=>a.split(/[-+]/,1)[0]??a,r=a=>a.includes("-"),o=n(e).split(".").map(Number),s=n(t).split(".").map(Number),i=Math.max(o.length,s.length);for(let a=0;a<i;a++){let l=o[a]??0,c=s[a]??0;if(c>l)return!0;if(c<l)return!1}return r(e)&&!r(t)}function rQ(){try{let e=CD(_D(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function oQ(){try{PD();let e=`
2015
+ `),SD=/^[a-z0-9]+(-[a-z0-9]+){1,3}$/,pS=30,$Z=1024,DZ=8e3,FZ="haiku";async function LZ(e,t){let n=e.trim();if(n.length===0)return t.onSkip?.("empty-message"),null;if(n.startsWith("/"))return t.onSkip?.("slash-command"),null;let r=jZ(n,$Z),o=new AbortController,s=setTimeout(()=>o.abort(),t.timeoutMs??DZ),i=t.signal?HZ([t.signal,o.signal]):o.signal,a;try{t.slugGenerator?a=await t.slugGenerator(r,i):a=await Bs({token:t.token,model:t.model??FZ,system:OZ,user:r,maxTokens:32,signal:i})}catch(d){let p=d instanceof Error?d.message:String(d);return t.onSkip?.("slug-generator-error",p.slice(0,200)),null}finally{clearTimeout(s)}let l=NZ(a);if(l===null)return t.onSkip?.("invalid-slug-output",a.slice(0,60)),null;let c=IZ(t.worktreePath);return await BZ(l,c)}function NZ(e){let t=e.trim().toLowerCase();if(t.length===0)return null;if(SD.test(t)&&t.length<=pS)return t;let n=t.replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");if(n.length===0)return null;let r=n.split("-").filter(s=>s.length>0).slice(0,4);if(r.length<2)return null;let o=r[0];for(let s=1;s<r.length;s++){let i=`${o}-${r[s]}`;if(i.length>pS)break;o=i}return SD.test(o)?o:null}async function BZ(e,t){if(!await UZ(kD(t,e)))return e;let n=MZ(2).toString("hex");return`${e.split("-").slice(0,3).join("-").slice(0,pS-5)}-${n}`}async function UZ(e){try{return await PZ.access(e),!0}catch{return!1}}function jZ(e,t){let n=Buffer.from(e,"utf8");if(n.length<=t)return e;let r=t;for(;r>0&&n[r]!==void 0&&(n[r]&192)===128;)r--;return n.slice(0,r).toString("utf8")}function HZ(e){let t=AbortSignal.any;if(typeof t=="function")return t.call(AbortSignal,e);let n=new AbortController;for(let r of e){if(r.aborted)return n.abort(r.reason),n.signal;r.addEventListener("abort",()=>n.abort(r.reason),{once:!0})}return n.signal}async function ED(e){let t,n,r=kD(e.deferred.repoRoot,".afk-worktrees","unnamed"),o=await LZ(e.message,{token:e.token,...e.model!==void 0?{model:e.model}:{},...e.timeoutMs!==void 0?{timeoutMs:e.timeoutMs}:{},worktreePath:r,...e.signal!==void 0?{signal:e.signal}:{},...e.slugGenerator!==void 0?{slugGenerator:e.slugGenerator}:{},onSkip:(a,l)=>{t=a,n=l}}),s=t??"unknown",i=n;if(o!==null){let l=`${Pu(e.branchPrefix)}${o}`;try{let c=await e.deferred.create(l);return vD(e.session,c.path),{status:"created",path:c.path,branch:c.branch,slug:o}}catch(c){s="create-failed",i=(c instanceof Error?c.message:String(c)).slice(0,200)}}try{let a=await e.deferred.create(!0);return vD(e.session,a.path),{status:"created-fallback",path:a.path,branch:a.branch,reason:s,...i!==void 0?{detail:i}:{}}}catch(a){return{status:"failed",reason:a instanceof Error?a.message:String(a)}}}function vD(e,t){e&&e.setCwd(t),WZ(t)}function WZ(e){try{process.chdir(e)}catch{}}Ve();Ft();q();import{spawn as xD}from"child_process";import{existsSync as RD,mkdirSync as JZ,readFileSync as CD,unlinkSync as TD,writeFileSync as VZ}from"fs";import{get as YZ}from"https";import{join as AD}from"path";import{readFileSync as KZ}from"fs";import{dirname as GZ,join as qZ}from"path";import{fileURLToPath as zZ}from"url";function Cr(){try{return"5.15.2"}catch{}try{let e=GZ(zZ(import.meta.url));for(let t of["../../package.json","../package.json"])try{let n=JSON.parse(KZ(qZ(e,t),"utf-8"));if(typeof n.version=="string")return n.version}catch{}}catch{}return"0.0.0-unknown"}J();var XZ=64*1024,ZZ=1440*60*1e3,QZ=3600*1e3,eQ="update-check.json",tQ="pending-update.json";function _D(){return AD(Pc(),eQ)}function lc(){return AD(Pc(),tQ)}function PD(){let e=Pc();RD(e)||JZ(e,{recursive:!0})}function nQ(e,t){let n=a=>a.split(/[-+]/,1)[0]??a,r=a=>a.includes("-"),o=n(e).split(".").map(Number),s=n(t).split(".").map(Number),i=Math.max(o.length,s.length);for(let a=0;a<i;a++){let l=o[a]??0,c=s[a]??0;if(c>l)return!0;if(c<l)return!1}return r(e)&&!r(t)}function rQ(){try{let e=CD(_D(),"utf-8"),t=JSON.parse(e);if(typeof t.latestVersion=="string"&&typeof t.checkedAt=="number")return t}catch{}return null}function oQ(){try{PD();let e=`
2015
2016
  const https = require('https');
2016
2017
  const fs = require('fs');
2017
2018
  const url = 'https://registry.npmjs.org/agent-afk/latest';
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  var bm=Object.defineProperty;var me=(t,e)=>()=>(t&&(e=t(t=0)),e);var pa=(t,e)=>{for(var n in e)bm(t,n,{get:e[n],enumerable:!0})};function Gn(t){return Wn.find(e=>e.name===t)}function Jo(t){return process.env[t]!==void 0}var Wn,w,B=me(()=>{"use strict";Wn=[{name:"AFK_COMPACT_KEEP_LAST_TURNS",description:"Number of recent turns the compactor keeps verbatim during /compact. Default tuned in compact-handler.ts.",type:"number",required:!1,example:"6",category:"model"},{name:"AFK_COMPACT_MODEL",description:"Override the model used by the /compact summarizer. Falls back to a cheap default (haiku-class).",type:"string",required:!1,example:"claude-haiku-4-5",category:"model"},{name:"AFK_DEFAULT_SUBAGENT_MODEL",description:"Override the default model used when a subagent is dispatched without an explicit model.",type:"string",required:!1,example:"sonnet",category:"model"},{name:"AFK_DIAGNOSE_BASELINE",description:"Kill switch for /diagnose reproducer baseline execution. When set to '0', the /diagnose skill skips executing the detected reproducer command for a ground-truth baseline; default enabled (runs). Set to '0' to disable.",type:"boolean",required:!1,default:"1",example:"0",category:"debug"},{name:"AFK_DISABLE_PROMPT_CACHE",description:"Disable Anthropic prompt caching when set to 1/true/yes/on. Unset = caching enabled.",type:"boolean",required:!1,default:"0",example:"1",category:"model"},{name:"AFK_DISABLE_BASH_INTERPRETER_GUARD",description:"Skip ONLY the bash interpreter-eval denylist (python -c, node -e, sh -c, ...) when set to 1, leaving the rest of path-approval intact. Applies on interactive surfaces (REPL/Telegram), where the denylist is active but your workflow legitimately runs interpreter one-liners. The restricted-root substring check is unaffected. Default: denylist active on interactive surfaces; headless already fails open (opt in with AFK_FORCE_BASH_INTERPRETER_GUARD=1). To disable all of path-approval + bash restriction instead, use AFK_DISABLE_PATH_APPROVAL=1.",type:"boolean",required:!1,default:"0",example:"1",category:"process"},{name:"AFK_DISABLE_PATH_APPROVAL",description:"Skip the path-approval + bash-restriction hooks entirely when set to 1. Use for headless flows that need wide-open file access (CI scripts, batch jobs). Default: hooks enabled. Note: on headless surfaces (afk chat, daemon) no grant manager is wired, so the interpreter denylist (python -c, node -e, sh -c, ...) fails OPEN by default \u2014 opt headless flows into it with AFK_FORCE_BASH_INTERPRETER_GUARD=1, or set this var to 1 to disable all of path-approval.",type:"boolean",required:!1,default:"0",example:"1",category:"process"},{name:"AFK_FORCE_BASH_INTERPRETER_GUARD",description:"Apply the bash interpreter-eval denylist (python -c, node -e, sh -c, ...) even on headless surfaces (afk chat, daemon) where no grant manager is wired. By default the denylist fires only on interactive surfaces (REPL/Telegram), failing open on headless so legitimate automation is not hard-blocked with no recourse. Set to 1 to opt headless flows back into the guard. Overridden by AFK_DISABLE_BASH_INTERPRETER_GUARD=1. Default: off (headless fails open).",type:"boolean",required:!1,default:"0",example:"1",category:"process"},{name:"AFK_EFFORT",description:"Effort hint guiding adaptive-thinking depth, forwarded as Anthropic output_config.effort (model-gated; ignored where unsupported). Accepts low | medium | high | xhigh | max.",type:"string",required:!1,example:"medium",category:"model"},{name:"AFK_MAX_BUDGET_USD",description:"Cumulative USD budget ceiling for the session. Aborts the turn when the running cost crosses this.",type:"number",required:!1,default:"5.00",example:"10.00",category:"model"},{name:"AFK_MAX_OUTPUT_TOKENS",description:"Cap on output tokens per turn. Falls back to provider default when unset.",type:"number",required:!1,example:"8192",category:"model"},{name:"AFK_MAX_TOKENS",description:"Cap on total tokens per turn (input + output). Default 4096.",type:"number",required:!1,default:"4096",example:"8192",category:"model"},{name:"AFK_MEMORY_EVIDENCE_GATE",description:'Opt-in (set to 1) evidence gate for durable memory writes. When enabled, a codebase fact (memory_update category "convention") stored without an `evidence` citation is recalled as [unverified], and memory_search results carry a verification verdict. User preferences and agent reflections are never gated. Default off \u2014 memory behaves identically to legacy when unset.',type:"boolean",required:!1,example:"1",category:"misc"},{name:"AFK_MODEL",description:"Default model for agent turns. Accepts slot names (local, small, medium, large), legacy aliases (opus, sonnet, haiku), the fixed-id fable alias (Claude Fable 5), or full model IDs.",type:"string",required:!1,default:"sonnet",example:"claude-opus-4-5",category:"model"},{name:"AFK_VISION_MODELS",description:'Comma-separated override for image (vision) capability detection on the openai-compatible provider. Each token force-enables a model id by exact or substring match (e.g. "qwen2.5-vl" matches a local VL id); prefix a token with "!" to force-disable. Use to send images to a local vision-language model AFK does not recognise by name, or to blacklist a mis-detected id. Built-in detection already covers gpt-4o/4.1/5.x, o1/o3/o4-mini, Claude, and common VL families.',type:"string",required:!1,example:"qwen2.5-vl,!gpt-4o-mini",category:"model"},{name:"AFK_MODEL_LOCAL",description:'Bind the "local" capability tier (cheapest/fastest, user-configured) to a model id. Overrides afk.config.json models.local. Point at a local Ollama, LM Studio, or any OpenAI-compatible shim.',type:"string",required:!1,example:"llama3.2:3b",category:"model"},{name:"AFK_MODEL_LOCAL_API_KEY",description:'Per-slot API key for the "local" tier. Overrides global credentials for this tier only.',type:"string",required:!1,category:"model",secret:!0},{name:"AFK_MODEL_LOCAL_BASE_URL",description:'Per-slot endpoint base URL for the "local" tier. Anthropic Messages base or OpenAI-compatible base per the tier provider.',type:"string",required:!1,example:"http://localhost:11434/v1",category:"model"},{name:"AFK_MODEL_LARGE",description:'Bind the "large" capability tier (most capable) to a model id/alias. Overrides afk.config.json models.large.',type:"string",required:!1,example:"claude-opus-4-8",category:"model"},{name:"AFK_MODEL_LARGE_API_KEY",description:'Per-slot API key for the "large" tier (Stage 2). Overrides global credentials for this tier only.',type:"string",required:!1,category:"model",secret:!0},{name:"AFK_MODEL_LARGE_BASE_URL",description:'Per-slot endpoint base URL for the "large" tier (Stage 2). Anthropic Messages base or OpenAI-compatible base per the tier provider.',type:"string",required:!1,example:"http://localhost:8080/v1",category:"model"},{name:"AFK_MODEL_MEDIUM",description:'Bind the "medium" capability tier (general-use) to a model id/alias. Overrides afk.config.json models.medium.',type:"string",required:!1,example:"claude-sonnet-5",category:"model"},{name:"AFK_MODEL_MEDIUM_API_KEY",description:'Per-slot API key for the "medium" tier (Stage 2). Overrides global credentials for this tier only.',type:"string",required:!1,category:"model",secret:!0},{name:"AFK_MODEL_MEDIUM_BASE_URL",description:'Per-slot endpoint base URL for the "medium" tier (Stage 2). Anthropic Messages base or OpenAI-compatible base per the tier provider.',type:"string",required:!1,example:"http://localhost:8080/v1",category:"model"},{name:"AFK_MODEL_SMALL",description:'Bind the "small" capability tier (cheap/fast) to a model id/alias. Overrides afk.config.json models.small.',type:"string",required:!1,example:"gpt-4o-mini",category:"model"},{name:"AFK_MODEL_SMALL_API_KEY",description:'Per-slot API key for the "small" tier (Stage 2). Overrides global credentials for this tier only.',type:"string",required:!1,category:"model",secret:!0},{name:"AFK_MODEL_SMALL_BASE_URL",description:'Per-slot endpoint base URL for the "small" tier (Stage 2). Anthropic Messages base or OpenAI-compatible base per the tier provider.',type:"string",required:!1,example:"http://localhost:8080/v1",category:"model"},{name:"AFK_PROMPT_CACHE_TTL",description:"TTL for Anthropic prompt-cache blocks. Accepts 5m or 1h.",type:"string",required:!1,default:"1h",example:"1h",category:"model"},{name:"AFK_SUGGEST_ENABLED",description:"Enable the LLM-backed ghost-text suggestion tier in the interactive REPL. Set to 1/true/yes/on to activate. Off by default.",type:"boolean",required:!1,category:"model"},{name:"AFK_SUGGEST_GHOST",description:"Enable REPL ghost-text inline suggestions (Tier-1 history/dropdown + optional Tier-2 LLM). 1 = on (default), 0 = off. Set 0/false/off/no to disable all ghost text. Tier-2 LLM is separately gated by AFK_SUGGEST_ENABLED.",type:"boolean",required:!1,default:"1",example:"0",category:"model"},{name:"AFK_SUGGEST_MODEL",description:"Override the small model used for REPL ghost-text suggestions. Falls back to AFK_COMPACT_MODEL or haiku-class for anthropic, or the session model for other providers.",type:"string",required:!1,category:"model"},{name:"AFK_TASK_BUDGET",description:"Per-task token budget ceiling. Aborts when cumulative usage would exceed it.",type:"number",required:!1,default:"100000",example:"200000",category:"model"},{name:"AFK_TEMPERATURE",description:"Numeric temperature override for model sampling. Provider default if unset.",type:"number",required:!1,example:"0.7",category:"model"},{name:"AFK_THINKING",description:"Extended-thinking mode. Accepts adaptive | disabled | enabled:<N> | enabled:max. Defaults to the model-appropriate mode when unset (adaptive on current models).",type:"string",required:!1,default:"adaptive",example:"adaptive",category:"model"},{name:"AFK_TIMEOUT_MS",description:"Per-turn timeout in milliseconds. Provider/SDK default if unset.",type:"number",required:!1,example:"120000",category:"model"},{name:"CLAUDE_MODEL",description:"Legacy alias for AFK_MODEL \u2014 supported for back-compat with pre-AFK_* deployments.",type:"string",required:!1,example:"sonnet",category:"model"},{name:"AFK_SYSTEM_PROMPT",description:'Raw operator-overlay prompt. Highest-priority overlay (over afk.config.json and AFK.md). Appended on top of the framework base (prompts/system-prompt.md) under an "# Operator configuration" header \u2014 it augments, never replaces, the base.',type:"string",required:!1,example:"You are a helpful agent.",category:"model"},{name:"AFK_DUMP_PROMPT",description:"Write the resolved system prompt to a file at startup. Accepts a path or 1 for default location.",type:"string",required:!1,example:"/tmp/afk-prompt.txt",category:"debug"},{name:"ANTHROPIC_API_KEY",description:"Anthropic API key. Tier-1 credential \u2014 overrides keychain OAuth and CLAUDE_CODE_OAUTH_TOKEN.",type:"string",required:!1,category:"auth",secret:!0},{name:"CLAUDE_CODE_OAUTH_TOKEN",description:"Claude Code OAuth token. Tier-2 credential \u2014 used when ANTHROPIC_API_KEY is unset; falls back to keychain.",type:"string",required:!1,category:"auth",secret:!0},{name:"OPENAI_API_KEY",description:"OpenAI API key for the openai-compatible provider (gpt-*, o1*, o3*, o4* models).",type:"string",required:!1,category:"auth",secret:!0},{name:"CODEX_API_KEY",description:"Fallback OpenAI API key for the openai-compatible provider, read after OPENAI_API_KEY. Legacy name from the removed @openai/codex-sdk integration \u2014 prefer OPENAI_API_KEY.",type:"string",required:!1,category:"auth",secret:!0},{name:"AFK_LOCAL_API_KEY",description:"Placeholder API key for local Anthropic-compatible servers (vllm-mlx, etc.). Set when AFK_LOCAL_BASE_URL is configured.",type:"string",required:!1,default:"local",example:"local",category:"auth",secret:!0},{name:"AFK_LOCAL_BASE_URL",description:"Base URL for a self-hosted Anthropic-compatible server. When set, routes traffic away from api.anthropic.com.",type:"string",required:!1,example:"http://127.0.0.1:8080",category:"model"},{name:"AFK_OPENAI_BASE_URL",description:"Base URL override for the OpenAI-compatible provider. Used for local shims (mlx_lm.server, Ollama, vLLM, LM Studio). The OpenAI SDK appends `/chat/completions` itself \u2014 a value ending in `/chat/completions` will be stripped at config-load time with a one-shot warning.",type:"string",required:!1,example:"http://127.0.0.1:8000/v1",category:"model"},{name:"AFK_OPENAI_USE_RESPONSES",description:"Opt the OpenAI-compatible provider into the OpenAI Responses API instead of Chat Completions for API-key sessions. Truthy values: 1, true, yes, on. The ChatGPT-subscription OAuth path uses Responses automatically regardless of this flag.",type:"boolean",required:!1,example:"1",category:"model"},{name:"AFK_OPENAI_CHATGPT_OAUTH",description:"Opt into using ChatGPT-subscription OAuth credentials from ~/.codex/auth.json (auth_mode: chatgpt) as OpenAI provider auth. Off by default. READ-ONLY: AFK never refreshes these tokens \u2014 re-run `codex` when the access token expires. Routes requests over the Responses API to the private ChatGPT backend (chatgpt.com/backend-api).",type:"boolean",required:!1,example:"1",category:"model"},{name:"AFK_PROVIDER",description:"Force provider selection (anthropic | anthropic-direct | openai | openai-compatible | openai-codex). Overrides the model-name heuristic. Same surface as the --provider CLI flag; CLI flag wins when both are set.",type:"string",required:!1,example:"openai-compatible",category:"model"},{name:"EXA_API_KEY",description:"Exa (exa.ai) search API key, enabling web_scrape search mode. Free tier (20k requests/month) available at https://exa.ai. When unset, search mode returns an actionable error; markdown and raw modes are unaffected.",type:"string",required:!1,category:"auth",secret:!0},{name:"TELEGRAM_BOT_TOKEN",description:"Telegram bot token from @BotFather. Required to run the Telegram bot surface.",type:"string",required:!1,category:"telegram",secret:!0},{name:"AFK_TELEGRAM_BOT_TOKEN",description:"Alternative env var name for the Telegram bot token, accepted by the setup wizard.",type:"string",required:!1,category:"telegram",secret:!0},{name:"AFK_TELEGRAM_ALLOWED_CHAT_IDS",description:"Comma-separated list of Telegram chat IDs allowed to interact with the bot. Required when the bot is running.",type:"string",required:!1,example:"123456789,987654321",category:"telegram"},{name:"AFK_TELEGRAM_PRIMARY_CHAT_ID",description:"Default chat ID for outbound notifications (primary-mode routing). When unset, notifications go to the first private/DM chat in AFK_TELEGRAM_ALLOWED_CHAT_IDS. The afk.config.json telegram.notify block takes precedence.",type:"string",required:!1,example:"123456789",category:"telegram"},{name:"AFK_TELEGRAM_NOTIFY_MODE",description:"Outbound notification fan-out: primary (default \u2014 one chat), broadcast (every allowed chat), or custom (afk.config.json telegram.notify.targets). The afk.config.json telegram.notify.mode takes precedence.",type:"string",required:!1,example:"broadcast",category:"telegram"},{name:"TELEGRAM_DATA_DIR",description:"Override the directory where Telegram bot state is stored. Defaults to ~/.afk/state/telegram/.",type:"string",required:!1,category:"telegram"},{name:"TELEGRAM_VERBOSE",description:"Set to 1 to log per-message details from the Telegram bot \u2014 chat IDs, message text, latency.",type:"boolean",required:!1,example:"1",category:"telegram"},{name:"AFK_TELEGRAM_TRACE",description:"Set to 1 to dump raw bridge traffic between the agent and the Telegram bot \u2014 debugging only.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_TELEGRAM_CWD",description:"Override the working directory used by the Telegram bot when spawning agent sessions.",type:"string",required:!1,category:"telegram"},{name:"AFK_HOME",description:"Override the AFK home directory. Default: ~/.afk/.",type:"string",required:!1,default:"~/.afk",example:"/opt/afk",category:"paths"},{name:"AFK_STATE_DIR",description:"Override the entire AFK state tier (sessions/, todos/, transcripts/, memory/, daemon/, etc.), not just one subdirectory. Must be an absolute path (not /). Default: $AFK_HOME/state/.",type:"string",required:!1,category:"paths"},{name:"AFK_FRAMEWORK_DIR",description:"Override the AFK agent-framework directory used for telemetry and briefs. Default: $AFK_HOME/agent-framework/.",type:"string",required:!1,category:"paths"},{name:"HOME",description:"Standard Unix home directory. Used as the fallback when AFK_HOME is unset.",type:"string",required:!1,category:"process"},{name:"PATH",description:"System PATH. Read for executable resolution (git, gh, etc.) in tool handlers.",type:"string",required:!1,category:"process"},{name:"AFK_DAEMON_CWD",description:"Working directory used by the daemon process for spawned agent sessions.",type:"string",required:!1,category:"daemon"},{name:"AFK_DAEMON_TASK",description:"Default task description for the daemon. Falls back to afk.config.json daemon.task.",type:"string",required:!1,category:"daemon"},{name:"AFK_DAEMON_TASK_ID",description:"Task identifier the daemon uses to scope its state directory and telemetry.",type:"string",required:!1,category:"daemon"},{name:"AFK_DAEMON_HOST",description:"Bind address for the daemon control HTTP surface. Defaults to 127.0.0.1 (loopback only). The control surface is unauthenticated, so bind a non-loopback address such as 0.0.0.0 only on a trusted or firewalled network. Overridden by the --host flag.",type:"string",required:!1,category:"daemon"},{name:"AFK_SESSIONSTART_COOLDOWN_MS",description:"Cooldown in milliseconds between SessionStart trigger fires in the daemon. Prevents thundering-herd on rapid restarts.",type:"number",required:!1,category:"daemon"},{name:"AFK_WORKTREE_AUTONAME",description:"Auto-rename worktree branches based on the first user message in interactive mode. 1 = on (default), 0 = off.",type:"boolean",required:!1,default:"1",example:"0",category:"worktree"},{name:"AFK_WORKTREE_BRANCH_PREFIX",description:"Branch-name prefix for AFK-managed worktrees. Default afk/. Set to empty string to drop the prefix.",type:"string",required:!1,default:"afk/",example:"wt/",category:"worktree"},{name:"AFK_WORKTREE_BASE",description:"Override the base git ref for worktrees created with --worktree. By default AFK bases worktrees on the remote's default branch (e.g. origin/main), fetched fresh. Set this to pin a different ref, or to HEAD to base on the local checkout. Overridden per-session by --worktree-base.",type:"string",required:!1,example:"origin/main",category:"worktree"},{name:"AFK_WORKTREE_BOOT_PRUNE",description:"When set, the daemon prunes stale worktrees at boot in addition to the cron-driven sweep.",type:"boolean",required:!1,category:"worktree"},{name:"AFK_WORKTREE_PRUNE_DISABLE",description:"Disable the worktree prune job entirely. Useful for long-running tests.",type:"boolean",required:!1,category:"worktree"},{name:"AFK_WORKTREE_MAX_AGE_CLEAN",description:"Maximum age (in days) before a clean worktree is auto-pruned. Default 14.",type:"number",required:!1,default:"14",category:"worktree"},{name:"AFK_WORKTREE_MAX_AGE_DIRTY",description:"Maximum age (in days) before a dirty worktree is auto-pruned. Default 30.",type:"number",required:!1,default:"30",category:"worktree"},{name:"AFK_WORKTREE_SWEEP_ROOT",description:"Override the root directory under which AFK worktrees are tracked for pruning.",type:"string",required:!1,category:"worktree"},{name:"AFK_ALLOW_PROJECT_MCP",description:"Controls auto-loading of MCP configuration from <cwd>/.mcp.json. Auto-loaded by default \u2014 set to 0 to disable (mitigates config-injection risk in shared/CI environments).",type:"boolean",required:!1,example:"0",category:"mcp"},{name:"AFK_AUTO_ROUTING",description:"Auto-route bare slash inputs to matching skills. Applies to interactive, chat, telegram, and daemon surfaces.",type:"boolean",required:!1,example:"true",category:"routing"},{name:"AFK_INTERNAL",description:'Tier gate. Set to exactly `1` to unlock \u2014 only the literal string "1" unlocks (other truthy values like "true"/"yes" leave the tier locked). When unlocked, skills tagged `audience: \'internal\'` (e.g. /audit-fit, harvest/distill plugins) become visible at end-user surfaces (slash-command list, --help, tab-complete, system-prompt skill manifest). Default unset = public tier \u2014 internal skills are hidden. Not an access-control boundary; it gates surfacing, not the underlying registry.',type:"boolean",required:!1,example:"1",category:"routing"},{name:"AFK_SHELL_PASSTHROUGH",description:"Enable the interactive REPL `!cmd` / `!&cmd` shell-passthrough feature. On by default. Set to 0, false, off, or no (case-insensitive) to disable, so inputs beginning with ! are sent to the model as literal text instead of being executed as shell commands. Equivalent to the --no-shell-passthrough flag.",type:"boolean",required:!1,default:"1",example:"0",category:"misc"},{name:"AFK_BANNER_PLAIN",description:"Suppress the ANSI-colored banner at REPL startup. Useful for non-TTY captures and CI logs.",type:"boolean",required:!1,example:"1",category:"misc"},{name:"AFK_SPINNER_TIPS",description:"Show rotating tips in the loading spinner during long calls. 1 = on, 0 = off.",type:"boolean",required:!1,category:"misc"},{name:"AFK_SHOW_DIFFS",description:"Show inline diffs in the tool-lane output for edit/write tool calls. 1 = on, 0 = off.",type:"boolean",required:!1,category:"misc"},{name:"AFK_SKILL_STREAM_VERBOSE",description:"Verbose streaming output when a skill is dispatched. Logs sub-agent setup, intermediate events, and final result.",type:"boolean",required:!1,category:"debug"},{name:"FORCE_COLOR",description:"Standard Node convention. Force-enable ANSI color output even when stdout is not a TTY.",type:"string",required:!1,example:"1",category:"process"},{name:"NO_COLOR",description:"Standard convention (https://no-color.org). When set to any non-empty value, disables ANSI color output.",type:"string",required:!1,example:"1",category:"process"},{name:"AFK_DEBUG",description:"Enable verbose debug logging across the codebase. Accepts 1 to enable.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_DEBUG_CLIPBOARD",description:"Debug bracketed-paste and image-paste handling in the interactive REPL.",type:"boolean",required:!1,category:"debug"},{name:"AFK_DEBUG_COMPOSITOR",description:"Gate compositor phase-boundary traces to stderr; any truthy value enables.",type:"boolean",required:!1,category:"debug"},{name:"AFK_TRACE_DISABLED",description:"Disable the agent trace subsystem entirely. Set to 1 to skip trace file writes.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_SESSION_LEDGER_DISABLED",description:"Disable the per-session durable event ledger (state/sessions/<id>/events.jsonl). Set to 1 to skip ledger writes; live cross-surface watching (e.g. the Telegram /watch command) will report no activity for sessions started while disabled.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AFK_RUN_RECEIPT_DISABLED",description:"Disable the post-session run receipt (state/receipts/<label>.json and .md). Set to 1 to skip receipt writes; the underlying witness trace is unaffected. Receipts are also implicitly off when AFK_TRACE_DISABLED=1 (no trace to summarize).",type:"boolean",required:!1,example:"1",category:"debug"},{name:"DEBUG",description:"Standard Node `debug`-package convention. When set to 1, enables verbose logging in several modules alongside AFK_DEBUG.",type:"string",required:!1,category:"debug"},{name:"AGENT_AFK_ASCII",description:"Force the interactive REPL tool-lane renderer to ASCII-only glyphs instead of the default Unicode box-drawing set. Accepts 1/true/yes (case-insensitive). Useful for terminals whose font lacks \u2503\u251C\u2570\u251C glyphs.",type:"boolean",required:!1,example:"1",category:"debug"},{name:"AGENT_SURFACE",description:"Internal surface marker propagated to subprocesses. Identifies which AFK surface (cli, telegram, daemon) spawned the process.",type:"string",required:!1,example:"cli",category:"process"},{name:"CI",description:"Standard CI-detection convention. Auto-set by GitHub Actions, CircleCI, etc. Used to switch off TTY-only UX.",type:"string",required:!1,example:"true",category:"process"},{name:"NODE_ENV",description:"Standard Node environment marker. test | development | production. Used by routing-telemetry.ts to suppress test-time writes.",type:"string",required:!1,example:"production",category:"process"},{name:"VITEST",description:"Set automatically by Vitest. Used at runtime to short-circuit code paths that should not fire in tests.",type:"string",required:!1,category:"process"},{name:"NO_UPDATE_NOTIFIER",description:"Disable the update-available notifier on CLI startup. Standard convention shared with many Node CLIs.",type:"boolean",required:!1,category:"process"},{name:"AFK_BROWSER_HEADLESS",description:"Override the default headless mode for native browser-control tools. `1`/`true` forces headless; `0`/`false` forces headed. When unset the default is headless for daemon and subagent surfaces and headed for repl/interactive \u2014 so an operator can watch the agent work in REPL mode.",type:"boolean",required:!1,example:"1",category:"browser"},{name:"AFK_BROWSER_ALLOWED_DOMAINS",description:"Comma-separated allowlist of URL host globs. When set, browser_open and any navigation that targets a host outside the list returns status: blocked_by_policy. Unset means no allowlist (permissive). Patterns use simple `*` glob matching against the URL host. Combines with AFK_BROWSER_BLOCKED_DOMAINS \u2014 block wins.",type:"string",required:!1,example:"github.com,*.atlassian.net",category:"browser"},{name:"AFK_BROWSER_BLOCKED_DOMAINS",description:"Comma-separated blocklist of URL host globs. Browser navigation that matches any entry returns status: blocked_by_policy regardless of the allowlist.",type:"string",required:!1,example:"*.ads.example.com",category:"browser"},{name:"AFK_BROWSER_DOM_SNAPSHOTS",description:"Phase 2 opt-in: when set to 1, every browser_act writes a gzipped DOM snapshot sidecar under ~/.afk/state/witness/<sid>/browser/dom-snapshots/. Off by default because snapshots are large; useful for post-mortem analysis of failed actions.",type:"boolean",required:!1,example:"1",category:"browser"},{name:"AFK_BROWSER_BACKEND",description:"Select the browser provider backend. Phase 1 supports only `playwright`. Reserved for future `cdp` / `mcp` adapters. Unset defaults to `playwright`.",type:"string",required:!1,example:"playwright",category:"browser"},{name:"AFK_BROWSER_CONFIG",description:"Absolute path to an alternate browser config file. Overrides the default ~/.afk/config/browser.json lookup. Useful for per-project overrides in CI.",type:"string",required:!1,example:"/path/to/browser.json",category:"browser"},{name:"AFK_BROWSER_DEFAULT_PROFILE",description:"Name of the persistent session-vault profile the agent reuses for browser sessions. The context restores its login from (and saves it back to) ~/.afk/state/browser/<profile>/storageState.json, so a human runs `afk browser login --profile <name>` once and the agent reuses that authenticated session across unattended runs. Unset defaults to `default` (a fresh, empty profile \u2014 identical to pre-vault behavior). Allowed charset: [A-Za-z0-9_-], max 128 chars.",type:"string",required:!1,example:"work",category:"browser"},{name:"AFK_WRITE_DENYLIST",description:"Comma-separated list of additional path globs that the write_file tool refuses to write to.",type:"string",required:!1,example:"**/.env,**/secrets/**",category:"misc"},{name:"AFK_WRITE_DIFF",description:"Show a diff preview before each write_file tool call. Defaults provider-controlled when unset.",type:"boolean",required:!1,category:"misc"},{name:"AFK_DEMO_CLEAN",description:"Explicit opt-in to capture-mode. When set to 1, suppresses high-frequency repaint drivers (spinner ticker, live thinking-preview) so recorded artifacts contain each state once instead of once per timer tick.",type:"boolean",required:!1,example:"1",category:"misc"},{name:"SCRIPT",description:"Set by script(1) on BSD/macOS/Linux to the typescript filename while a terminal session is being recorded. Presence of a non-empty value triggers capture-mode.",type:"string",required:!1,example:"/tmp/typescript",category:"process"},{name:"ASCIINEMA_REC",description:"Set to 1 by asciinema rec while a session is being recorded. Triggers capture-mode.",type:"boolean",required:!1,example:"1",category:"process"},{name:"AFK_SESSION_ID",description:"Override the browser session ID used by the native browser-control tools. Defaults to 'default' for single-session use. Subagents inherit the parent's session by default. Set this when running multiple concurrent AFK processes that should each manage an isolated browser context.",type:"string",required:!1,default:"default",example:"session-abc123",category:"browser"},{name:"SHELL",description:"Standard POSIX env var pointing to the user's login shell binary. Used by shell-init and worktree commands to auto-detect the correct shell syntax for emitted wrapper code.",type:"string",required:!1,example:"/bin/zsh",category:"process"},{name:"PAGER",description:"Standard POSIX env var naming the user's preferred pager (with optional flags). Used by /transcript to render the full session in a scrollable viewer; falls back to `less -R` when unset.",type:"string",required:!1,example:"less -R",category:"process"},{name:"AFK_DIFF_LINES",description:"Maximum number of diff lines shown in the inline diff render during write_file tool calls. Set to 0 for no cap. Non-integer values are silently ignored and the default applies.",type:"number",required:!1,example:"50",category:"misc"},{name:"AFK_SHELL_WRAPPER",description:"Set to 1 or true by the optional afk shell wrapper function (installed via `afk shell-init`). Signals that the parent shell has the wrapper active so the post-exit cd can fire.",type:"boolean",required:!1,example:"1",category:"process"},{name:"AFK_USER_CARD_MAX_ROWS",description:'Maximum number of visual rows emitted by renderUserCard before collapsing the remainder into a dim "\u2026(N lines collapsed)" summary row. Defaults to 24. Non-integer or non-positive values are silently ignored and the default applies.',type:"number",required:!1,example:"24",category:"misc"}],w={get AFK_COMPACT_KEEP_LAST_TURNS(){return process.env.AFK_COMPACT_KEEP_LAST_TURNS},get AFK_COMPACT_MODEL(){return process.env.AFK_COMPACT_MODEL},get AFK_DEFAULT_SUBAGENT_MODEL(){return process.env.AFK_DEFAULT_SUBAGENT_MODEL},get AFK_DIAGNOSE_BASELINE(){return process.env.AFK_DIAGNOSE_BASELINE},get AFK_DISABLE_BASH_INTERPRETER_GUARD(){return process.env.AFK_DISABLE_BASH_INTERPRETER_GUARD},get AFK_DISABLE_PATH_APPROVAL(){return process.env.AFK_DISABLE_PATH_APPROVAL},get AFK_DISABLE_PROMPT_CACHE(){return process.env.AFK_DISABLE_PROMPT_CACHE},get AFK_EFFORT(){return process.env.AFK_EFFORT},get AFK_FORCE_BASH_INTERPRETER_GUARD(){return process.env.AFK_FORCE_BASH_INTERPRETER_GUARD},get AFK_MAX_BUDGET_USD(){return process.env.AFK_MAX_BUDGET_USD},get AFK_MAX_OUTPUT_TOKENS(){return process.env.AFK_MAX_OUTPUT_TOKENS},get AFK_MAX_TOKENS(){return process.env.AFK_MAX_TOKENS},get AFK_MEMORY_EVIDENCE_GATE(){return process.env.AFK_MEMORY_EVIDENCE_GATE},get AFK_MODEL(){return process.env.AFK_MODEL},get AFK_MODEL_LARGE(){return process.env.AFK_MODEL_LARGE},get AFK_MODEL_LARGE_API_KEY(){return process.env.AFK_MODEL_LARGE_API_KEY},get AFK_MODEL_LARGE_BASE_URL(){return process.env.AFK_MODEL_LARGE_BASE_URL},get AFK_MODEL_LOCAL(){return process.env.AFK_MODEL_LOCAL},get AFK_MODEL_LOCAL_API_KEY(){return process.env.AFK_MODEL_LOCAL_API_KEY},get AFK_MODEL_LOCAL_BASE_URL(){return process.env.AFK_MODEL_LOCAL_BASE_URL},get AFK_MODEL_MEDIUM(){return process.env.AFK_MODEL_MEDIUM},get AFK_MODEL_MEDIUM_API_KEY(){return process.env.AFK_MODEL_MEDIUM_API_KEY},get AFK_MODEL_MEDIUM_BASE_URL(){return process.env.AFK_MODEL_MEDIUM_BASE_URL},get AFK_MODEL_SMALL(){return process.env.AFK_MODEL_SMALL},get AFK_MODEL_SMALL_API_KEY(){return process.env.AFK_MODEL_SMALL_API_KEY},get AFK_MODEL_SMALL_BASE_URL(){return process.env.AFK_MODEL_SMALL_BASE_URL},get AFK_VISION_MODELS(){return process.env.AFK_VISION_MODELS},get AFK_PROMPT_CACHE_TTL(){return process.env.AFK_PROMPT_CACHE_TTL},get AFK_SUGGEST_ENABLED(){return process.env.AFK_SUGGEST_ENABLED},get AFK_SUGGEST_GHOST(){return process.env.AFK_SUGGEST_GHOST},get AFK_SUGGEST_MODEL(){return process.env.AFK_SUGGEST_MODEL},get AFK_TASK_BUDGET(){return process.env.AFK_TASK_BUDGET},get AFK_TEMPERATURE(){return process.env.AFK_TEMPERATURE},get AFK_THINKING(){return process.env.AFK_THINKING},get AFK_TIMEOUT_MS(){return process.env.AFK_TIMEOUT_MS},get CLAUDE_MODEL(){return process.env.CLAUDE_MODEL},get AFK_SYSTEM_PROMPT(){return process.env.AFK_SYSTEM_PROMPT},get AFK_DUMP_PROMPT(){return process.env.AFK_DUMP_PROMPT},get ANTHROPIC_API_KEY(){return process.env.ANTHROPIC_API_KEY},get CLAUDE_CODE_OAUTH_TOKEN(){return process.env.CLAUDE_CODE_OAUTH_TOKEN},get OPENAI_API_KEY(){return process.env.OPENAI_API_KEY},get CODEX_API_KEY(){return process.env.CODEX_API_KEY},get AFK_LOCAL_API_KEY(){return process.env.AFK_LOCAL_API_KEY},get AFK_LOCAL_BASE_URL(){return process.env.AFK_LOCAL_BASE_URL},get AFK_OPENAI_BASE_URL(){return process.env.AFK_OPENAI_BASE_URL},get AFK_OPENAI_USE_RESPONSES(){return process.env.AFK_OPENAI_USE_RESPONSES},get AFK_OPENAI_CHATGPT_OAUTH(){return process.env.AFK_OPENAI_CHATGPT_OAUTH},get AFK_PROVIDER(){return process.env.AFK_PROVIDER},get EXA_API_KEY(){return process.env.EXA_API_KEY},get TELEGRAM_BOT_TOKEN(){return process.env.TELEGRAM_BOT_TOKEN},get AFK_TELEGRAM_BOT_TOKEN(){return process.env.AFK_TELEGRAM_BOT_TOKEN},get AFK_TELEGRAM_ALLOWED_CHAT_IDS(){return process.env.AFK_TELEGRAM_ALLOWED_CHAT_IDS},get AFK_TELEGRAM_PRIMARY_CHAT_ID(){return process.env.AFK_TELEGRAM_PRIMARY_CHAT_ID},get AFK_TELEGRAM_NOTIFY_MODE(){return process.env.AFK_TELEGRAM_NOTIFY_MODE},get TELEGRAM_DATA_DIR(){return process.env.TELEGRAM_DATA_DIR},get TELEGRAM_VERBOSE(){return process.env.TELEGRAM_VERBOSE},get AFK_TELEGRAM_TRACE(){return process.env.AFK_TELEGRAM_TRACE},get AFK_TELEGRAM_CWD(){return process.env.AFK_TELEGRAM_CWD},get AFK_HOME(){return process.env.AFK_HOME},get AFK_STATE_DIR(){return process.env.AFK_STATE_DIR},get AFK_FRAMEWORK_DIR(){return process.env.AFK_FRAMEWORK_DIR},get HOME(){return process.env.HOME},get PATH(){return process.env.PATH},get AFK_DAEMON_CWD(){return process.env.AFK_DAEMON_CWD},get AFK_DAEMON_TASK(){return process.env.AFK_DAEMON_TASK},get AFK_DAEMON_TASK_ID(){return process.env.AFK_DAEMON_TASK_ID},get AFK_DAEMON_HOST(){return process.env.AFK_DAEMON_HOST},get AFK_SESSIONSTART_COOLDOWN_MS(){return process.env.AFK_SESSIONSTART_COOLDOWN_MS},get AFK_WORKTREE_AUTONAME(){return process.env.AFK_WORKTREE_AUTONAME},get AFK_WORKTREE_BRANCH_PREFIX(){return process.env.AFK_WORKTREE_BRANCH_PREFIX},get AFK_WORKTREE_BASE(){return process.env.AFK_WORKTREE_BASE},get AFK_WORKTREE_BOOT_PRUNE(){return process.env.AFK_WORKTREE_BOOT_PRUNE},get AFK_WORKTREE_PRUNE_DISABLE(){return process.env.AFK_WORKTREE_PRUNE_DISABLE},get AFK_WORKTREE_MAX_AGE_CLEAN(){return process.env.AFK_WORKTREE_MAX_AGE_CLEAN},get AFK_WORKTREE_MAX_AGE_DIRTY(){return process.env.AFK_WORKTREE_MAX_AGE_DIRTY},get AFK_WORKTREE_SWEEP_ROOT(){return process.env.AFK_WORKTREE_SWEEP_ROOT},get AFK_ALLOW_PROJECT_MCP(){return process.env.AFK_ALLOW_PROJECT_MCP},get AFK_AUTO_ROUTING(){return process.env.AFK_AUTO_ROUTING},get AFK_INTERNAL(){return process.env.AFK_INTERNAL},get AFK_SHELL_PASSTHROUGH(){return process.env.AFK_SHELL_PASSTHROUGH},get AFK_BANNER_PLAIN(){return process.env.AFK_BANNER_PLAIN},get AFK_SPINNER_TIPS(){return process.env.AFK_SPINNER_TIPS},get AFK_SHOW_DIFFS(){return process.env.AFK_SHOW_DIFFS},get AFK_SKILL_STREAM_VERBOSE(){return process.env.AFK_SKILL_STREAM_VERBOSE},get FORCE_COLOR(){return process.env.FORCE_COLOR},get NO_COLOR(){return process.env.NO_COLOR},get AFK_DEBUG(){return process.env.AFK_DEBUG},get AFK_DEBUG_CLIPBOARD(){return process.env.AFK_DEBUG_CLIPBOARD},get AFK_DEBUG_COMPOSITOR(){return process.env.AFK_DEBUG_COMPOSITOR},get AFK_TRACE_DISABLED(){return process.env.AFK_TRACE_DISABLED},get AFK_SESSION_LEDGER_DISABLED(){return process.env.AFK_SESSION_LEDGER_DISABLED},get AFK_RUN_RECEIPT_DISABLED(){return process.env.AFK_RUN_RECEIPT_DISABLED},get DEBUG(){return process.env.DEBUG},get AGENT_AFK_ASCII(){return process.env.AGENT_AFK_ASCII},get AGENT_SURFACE(){return process.env.AGENT_SURFACE},get CI(){return process.env.CI},get NODE_ENV(){return process.env.NODE_ENV},get VITEST(){return process.env.VITEST},get NO_UPDATE_NOTIFIER(){return process.env.NO_UPDATE_NOTIFIER},get AFK_SESSION_ID(){return process.env.AFK_SESSION_ID},get AFK_BROWSER_HEADLESS(){return process.env.AFK_BROWSER_HEADLESS},get AFK_BROWSER_ALLOWED_DOMAINS(){return process.env.AFK_BROWSER_ALLOWED_DOMAINS},get AFK_BROWSER_BLOCKED_DOMAINS(){return process.env.AFK_BROWSER_BLOCKED_DOMAINS},get AFK_BROWSER_DOM_SNAPSHOTS(){return process.env.AFK_BROWSER_DOM_SNAPSHOTS},get AFK_BROWSER_BACKEND(){return process.env.AFK_BROWSER_BACKEND},get AFK_BROWSER_CONFIG(){return process.env.AFK_BROWSER_CONFIG},get AFK_BROWSER_DEFAULT_PROFILE(){return process.env.AFK_BROWSER_DEFAULT_PROFILE},get AFK_WRITE_DENYLIST(){return process.env.AFK_WRITE_DENYLIST},get AFK_WRITE_DIFF(){return process.env.AFK_WRITE_DIFF},get AFK_DEMO_CLEAN(){return process.env.AFK_DEMO_CLEAN},get SCRIPT(){return process.env.SCRIPT},get ASCIINEMA_REC(){return process.env.ASCIINEMA_REC},get SHELL(){return process.env.SHELL},get PAGER(){return process.env.PAGER},get AFK_DIFF_LINES(){return process.env.AFK_DIFF_LINES},get AFK_SHELL_WRAPPER(){return process.env.AFK_SHELL_WRAPPER},get AFK_USER_CARD_MAX_ROWS(){return process.env.AFK_USER_CARD_MAX_ROWS}};(function(){for(let e of Wn){if(!e.secret)continue;let n=Object.getOwnPropertyDescriptor(w,e.name);n&&Object.defineProperty(w,e.name,{...n,enumerable:!1})}})()});function wm(){return w.AFK_DEBUG==="1"||w.DEBUG==="1"}function M(...t){wm()&&console.log(...t)}var ne=me(()=>{"use strict";B()});import{existsSync as $a,mkdirSync as Km,renameSync as Wm,cpSync as Gm,rmSync as qm}from"fs";import{join as H,dirname as ja,isAbsolute as Ha}from"path";import{homedir as Ka}from"os";import{fileURLToPath as zm}from"url";function ie(){let t=w.AFK_HOME;if(t!==void 0&&t!==""){if(!Ha(t)||t==="/")throw new Error(`AFK_HOME must be an absolute path that is not /, got: ${t}`);return t}return H(Ka(),".afk")}function Ee(){return H(ie(),"agent-framework")}function Wa(){return H(Ee(),"forge-telemetry.jsonl")}function Ga(){return H(Ee(),"briefs")}function qa(){return H(Ee(),"facets")}function Qt(){return H(ie(),"skills")}function bt(){return H(ie(),"plugins")}function za(){return H(process.cwd(),".afk")}function Va(){return H(za(),"skills")}function Ja(){return H(za(),"plugins")}function Ya(t=process.cwd()){return H(t,".afk","plans")}function rr(){return H(bt(),".index.json")}function cs(){return H(Zt(),"schedules.json")}function Xa(){let t=zm(import.meta.url),e=ja(t);return H(e,"bundled-plugins")}function Zt(){return H(ie(),"config")}function He(){let t=w.AFK_STATE_DIR;if(t!==void 0&&t!==""){if(!Ha(t)||t==="/")throw new Error(`AFK_STATE_DIR must be an absolute path that is not /, got: ${t}`);return t}return H(ie(),"state")}function ae(){return H(He(),"sessions")}function or(){return H(He(),"presence")}function sr(){return H(He(),"memory")}function wt(){return H(He(),"session-grants.jsonl")}function Qa(){return H(ie(),"farms")}function Za(t){return H(Qa(),t)}function ir(t){if(!Vm.test(t))throw new Error(`Invalid AFK_SESSION_ID: must match /^[a-zA-Z0-9_-]+$/, got: ${JSON.stringify(t)}`)}function ec(t){return ir(t),H(He(),"witness",t)}function tc(t="default"){return H(He(),"daemon",`agent-afk@${t}`)}function ls(){return H(Zt(),"afk.env")}function St(){return H(Zt(),"afk.config.json")}function ar(){return H(Ka(),".afk.config.json")}function Jm(){return H(ie(),"sessions")}function Ym(t,e){if(t!==e&&$a(t)&&!$a(e))try{Km(ja(e),{recursive:!0});try{Wm(t,e)}catch(n){if(n.code==="EXDEV")try{Gm(t,e,{recursive:!0}),qm(t,{recursive:!0,force:!0})}catch(r){process.stderr.write(`[afk] migrateDirOnce: EXDEV fallback failed for ${t} \u2192 ${e}: ${String(r)}
2
- `)}}}catch{}}function nc(){Ym(Jm(),ae())}function ds(t){if(typeof t!="string"||t.length===0)throw new Error("Invalid browser profile: must be a non-empty string");if(t.length>Ba)throw new Error(`Invalid browser profile: exceeds ${Ba} chars`);if(!Xm.test(t))throw new Error(`Invalid browser profile: ${JSON.stringify(t)} contains characters outside [A-Za-z0-9_-]`)}function Qm(){return H(He(),"browser")}function Zm(t){return ds(t),H(Qm(),t)}function us(t){return H(Zm(t),"storageState.json")}function en(t){return typeof t=="string"&&t.length>0&&t.length<=tg&&eg.test(t)}function tn(t){if(!en(t))throw new Error(`Invalid session id for ledger path: ${JSON.stringify(t)}`);return H(ae(),t)}function cr(t){return H(tn(t),"events.jsonl")}function rc(t){return H(tn(t),"session.key")}var Vm,Xm,Ba,eg,tg,j=me(()=>{"use strict";B();Vm=/^[a-zA-Z0-9_-]+$/;Xm=/^[A-Za-z0-9_-]+$/,Ba=128;eg=/^[A-Za-z0-9_-]+$/,tg=128});import{readFileSync as Eb}from"node:fs";import{join as Ab}from"path";function xb(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function pl(t,e){return xb(e).test(t)}function Pb(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(Tb.has(e))return!0;if(Rb.has(e))return!1}return!1}function fl(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function Ib(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 ml(t){let e=t===void 0||t.trim()===""?"default":t.trim();return ds(e),e}function Cb(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function Mb(t){try{return Eb(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function Ob(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=ml(e.defaultProfile)),n}function gl(t){let e=t?.env??w,n=t?.readFileSync??Mb,r=t?.surface??e.AGENT_SURFACE,o=Pb(e.AFK_BROWSER_HEADLESS,r),s=fl(e.AFK_BROWSER_ALLOWED_DOMAINS),i=fl(e.AFK_BROWSER_BLOCKED_DOMAINS),a=Cb(e.AFK_BROWSER_DOM_SNAPSHOTS),c=Ib(e.AFK_BROWSER_BACKEND),l=ml(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():Ab(Zt(),"browser.json"),f=n(p);if(f===void 0)return d;let m;try{m=JSON.parse(f)}catch(h){throw new Error(`Failed to parse browser config at ${p}: ${String(h)}`)}if(typeof m!="object"||m===null||Array.isArray(m))throw new Error(`Browser config at ${p} must be a JSON object`);let g=Ob(d,m);return g.configPath=p,g}function Os(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(pl(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>pl(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var Tb,Rb,Ds=me(()=>{"use strict";B();j();Tb=new Set(["daemon","subagent","telegram","afk"]),Rb=new Set(["repl","interactive","cli"])});import it from"node:fs";import Cr from"node:path";import{randomBytes as Db}from"node:crypto";import{chromium as Fb}from"playwright";function Lb(){try{return"5.15.1"}catch{}try{let t=Cr.resolve(import.meta.dirname,"../../../package.json"),e=it.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var Nb,Mr,hl=me(()=>{"use strict";j();ne();Nb=Lb(),Mr=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=Fb.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 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=()=>{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),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.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/${Nb}`}}loadStorageState(e){let n=us(e);try{if(!it.existsSync(n))return;let r=JSON.parse(it.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=us(e);if(!it.existsSync(r))return;let o=await n.storageState(),s=Cr.join(Cr.dirname(r),`.${Cr.basename(r)}.${process.pid}.${Db(4).toString("hex")}.tmp`);it.writeFileSync(s,JSON.stringify(o),{mode:384}),it.chmodSync(s,384),it.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 Ub}from"crypto";function Fs(t){if(t.length===0)return t;let e=t;for(let{regex:n,name:r}of $b)r==="form-password"?e=e.replace(n,"password=[redacted]"):e=e.replace(n,"[redacted]");return e}function yl(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&Bb.test(t.label))}function bl(t){return Ub("sha256").update(t,"utf8").digest("hex").slice(0,8)}function wl(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var $b,Bb,gn=me(()=>{"use strict";$b=[{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}];Bb=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as jb}from"node:crypto";function Hb(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function Kb(t,e,n){return`el_${jb("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function Wb(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Sl(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function kl(t,e){let n=t.role??"",r=t.name??"";vl.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])kl(s,e)}async function Gb(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},_l).catch(()=>[])}async function qb(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,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},_l).catch(()=>[])}function zb(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Or(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=zb(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=Gb(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,c,l,d]),h,b=!1;u!==null?(h=[],kl(u,h)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,h=(await qb(t)).filter($=>vl.has($.role??"")));let v=new Map;for(let E of p){let $=Sl(E.name),C=v.get($);(!C||C.bbox.w===0&&E.bbox.w>0)&&v.set($,E)}let y=h.map(E=>({ax:E,dom:v.get(Sl(E.name??""))})),S=r?y:y.filter(E=>E.dom?E.dom.bbox.w>0||E.dom.bbox.h>0:!0);S.sort((E,$)=>{let C=E.dom?.bbox.y??0,N=$.dom?.bbox.y??0;if(C!==N)return C-N;let R=E.dom?.bbox.x??0,P=$.dom?.bbox.x??0;return R-P}),S.length>200&&o.push("page has 200+ interactive elements; consider scoping");let x=S.slice(0,n).map((E,$)=>{let C=E.ax.role??"generic",N=E.ax.name??"",R=Kb(C,N,$),P=E.dom?.bbox??{x:0,y:0,w:0,h:0},I=E.dom?.type??null,A=null;E.ax.value!==void 0&&E.ax.value!==null&&(A=String(E.ax.value)),E.ax.checked!==void 0&&(A=String(E.ax.checked)),yl({role:C,kind:I})&&(A="[redacted]");let D={disabled:E.ax.disabled??!1};E.ax.checked!==void 0&&(D.checked=E.ax.checked===!0||E.ax.checked==="mixed"),E.ax.selected!==void 0&&(D.selected=E.ax.selected),E.ax.expanded!==void 0&&(D.expanded=E.ax.expanded);let K;E.dom?.testId?K=`[data-testid="${E.dom.testId}"]`:E.dom?.id&&(K=`#${E.dom.id}`);let W={id:R,role:C,label:Hb(N),kind:I,value:A,state:D,bbox:P};return K!==void 0&&(W.selector=K),W}),T="idle";try{let E=await t.evaluate(()=>document.readyState);E==="loading"?T="loading":E==="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 F=Wb(f),L=`obs_${e.observationCounter.toString(36)}`,O=new Date().toISOString();return{observationId:L,url:m,title:g,textSummary:F,interactive:x,status:{httpStatus:e.httpStatus??null,loadingState:T,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:O}}var vl,_l,El=me(()=>{"use strict";gn();vl=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);_l="a[href], button, input, select, textarea, [role], [tabindex], label"});async function Al(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 Ls(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>Al(t,s)))).filter(o=>o!==null)}async function Vb(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 Ns(t,e,n){switch(e.kind){case"element_id":return Jb(t,e,n);case"selector":return Yb(t,e);case"semantic":return Xb(t,e)}}async function Jb(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 Ls(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function Yb(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 Ls(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function Xb(t,e){return e.role!==void 0?Qb(t,e.text,e.role):Zb(t,e.text,e)}async function Qb(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 Ls(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function Zb(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 Vb(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 h=p[g];if(h===void 0)continue;let b=await Al(h.locator,h.index);if(b!==null){let v=`${b.role}:${b.label}:${g}`,y=0;for(let S=0;S<v.length;S++)y=y*31+v.charCodeAt(S)>>>0;f.push({...b,id:`el_${y.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var xl=me(()=>{"use strict"});import{randomBytes as ew}from"crypto";import{mkdir as tw,stat as nw,writeFile as rw}from"fs/promises";import{join as Us}from"path";import{gzip as ow}from"zlib";import{promisify as sw}from"util";function iw(t){return Us(ec(t),"browser")}function aw(t){return Us(iw(t),"screenshots")}function cw(){return new Date().toISOString().replace(/[:.]/g,"-")}function lw(){return ew(3).toString("hex")}async function $s(t,e,n){if(e.length>Tl)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Tl} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=aw(t);await tw(r,{recursive:!0});let o=`${cw()}-${lw()}-${n}.png`,s=Us(r,o);await rw(s,e);let{size:i}=await nw(s);return{path:s,bytes:i}}var CI,Tl,Rl=me(()=>{"use strict";j();gn();CI=sw(ow);Tl=5*1024*1024});var Il={};pa(Il,{PlaywrightProvider:()=>Bs});function Pl(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 Bs,Cl=me(()=>{"use strict";hl();El();xl();Ds();gn();Rl();Bs=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Mr(e)}async open(e){let n=Os(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 Or(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 Or(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 Ns(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${Pl(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=Fs(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(h){l=h}else l=g}let u=r.url();if(u!==s){let g=Os(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 Or(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})}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 Ns(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${Pl(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 $s(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 $s(n,o,r);return s}catch{return null}}}});var ct={};pa(ct,{__resetBrowserRegistryForTests:()=>mw,browserProviderActive:()=>pw,closeBrowserProvider:()=>js,getBrowserProvider:()=>uw,peekBrowserProvider:()=>fw});function Ml(){Promise.resolve(js()).then(()=>{process.exit(130)})}function Ol(){Promise.resolve(js()).then(()=>{process.exit(143)})}function Dl(){Te=null}function dw(){Dr||(process.on("SIGINT",Ml),process.on("SIGTERM",Ol),process.on("exit",Dl),Dr=!0)}function Fl(){Dr&&(process.removeListener("SIGINT",Ml),process.removeListener("SIGTERM",Ol),process.removeListener("exit",Dl),Dr=!1)}async function uw(t){return Te!==null?Te:(at!==null||(at=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(Cl(),Il)),n=gl(t),r=new e(n);return dw(),Te=r,at=null,r})()),at)}async function js(){if(Te===null)return;let t=Te;Te=null,at=null,Fl(),await t.shutdown()}function pw(){return Te!==null}function fw(){return Te}function mw(){Te=null,at=null,Fl()}var Te,at,Dr,lt=me(()=>{"use strict";Ds();Te=null,at=null,Dr=!1});ne();var le=class extends Error{constructor(e){super(e),this.name="AbortError"}},je=class extends Error{constructor(n,r){super(n);this.timeoutMs=r;this.name="TimeoutError"}timeoutMs},z=class extends Error{constructor(n,r,o,s){super(n);this.event=r;this.reason=o;this.name="HookBlockedError",s?.cause!==void 0&&(this.cause=s.cause)}event;reason;cause};var mt=class extends Error{constructor(n,r,o){super(o??`Budget ceiling reached: $${n.toFixed(4)} cumulative >= $${r.toFixed(4)} limit`);this.runningCostUsd=n;this.maxBudgetUsd=r;this.name="BudgetExceededError"}runningCostUsd;maxBudgetUsd};ne();async function gt(t,e){if(t)try{await t.write({kind:"tool_call",payload:e})}catch(n){M(`trace.emit tool_call failed: ${Me(n)}`)}}async function Ce(t,e){if(t)try{await t.write({kind:"hook_decision",payload:e})}catch(n){M(`trace.emit hook_decision failed: ${Me(n)}`)}}async function tt(t,e){if(t)try{await t.write({kind:"subagent_lifecycle",payload:e})}catch(n){M(`trace.emit subagent_lifecycle failed: ${Me(n)}`)}}async function fa(t,e){if(t)try{await t.write({kind:"budget",payload:e})}catch(n){M(`trace.emit budget failed: ${Me(n)}`)}}async function ma(t,e){if(t)try{await t.write({kind:"abort",payload:e})}catch(n){M(`trace.emit abort failed: ${Me(n)}`)}}async function ga(t,e){if(t)try{await t.write({kind:"compaction",payload:e})}catch(n){M(`trace.emit compaction failed: ${Me(n)}`)}}async function ha(t,e){if(t)try{await t.write({kind:"closure",payload:e})}catch(n){M(`trace.emit closure failed: ${Me(n)}`)}}async function Z(t,e){if(t)try{await t.write({kind:"browser_event",payload:e})}catch(n){M(`trace.emit browser_event failed: ${Me(n)}`)}}async function de(t,e){if(t)try{await t.write({kind:"session_phase",payload:e})}catch(n){M(`trace.emit session_phase failed: ${Me(n)}`)}}function Me(t){return t instanceof Error?t.message:String(t)}import qi from"path";import{appendFileSync as yE,mkdirSync as bE}from"fs";import{dirname as wE}from"path";import tf from"@anthropic-ai/sdk";var ya="claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,extended-cache-ttl-2025-04-11",Sm="effort-2025-11-24",vm="claude-cli/1.0.0 (external, cli)",km="x-anthropic-billing-header: cc_version=1.0.0.test; cc_entrypoint=cli; cch=00000;";function qn(t){return t.startsWith("sk-ant-oat01-")?"oauth":"api-key"}function qt(t,e,n){let r=e==="oauth"?{authToken:t}:{apiKey:t};return typeof n=="string"&&n.length>0?{...r,baseURL:n}:r}function ve(t,e,n,r){return t!=="oauth"?{}:{"anthropic-beta":r?`${ya},${Sm}`:ya,"x-app":"cli","User-Agent":vm,"X-Claude-Code-Session-Id":e,"x-client-request-id":n}}function ba(t){return t!=="oauth"?null:[{type:"text",text:km}]}import Pm from"@anthropic-ai/sdk";B();var Qo=["local","small","medium","large"],nt={local:{id:""},small:{id:"claude-haiku-4-5-20251001"},medium:{id:"claude-sonnet-5"},large:{id:"claude-opus-4-8"}},_m={haiku:"small",sonnet:"medium",sonnet_1m:"medium",opus:"large",opus_1m:"large"},Em="auto",Zo="claude-fable-5",Am={fable:Zo},Xo;function es(t){Xo=t}function Yo(t){if(t===void 0)return;let e=t.trim();return e.length>0?e:void 0}function zn(t,e,n){let r={},o=Yo(t);o&&(r.id=o);let s=Yo(e);s&&(r.baseUrl=s);let i=Yo(n);return i&&(r.apiKey=i),r}function xm(){return{local:zn(w.AFK_MODEL_LOCAL,w.AFK_MODEL_LOCAL_BASE_URL,w.AFK_MODEL_LOCAL_API_KEY),small:zn(w.AFK_MODEL_SMALL,w.AFK_MODEL_SMALL_BASE_URL,w.AFK_MODEL_SMALL_API_KEY),medium:zn(w.AFK_MODEL_MEDIUM,w.AFK_MODEL_MEDIUM_BASE_URL,w.AFK_MODEL_MEDIUM_API_KEY),large:zn(w.AFK_MODEL_LARGE,w.AFK_MODEL_LARGE_BASE_URL,w.AFK_MODEL_LARGE_API_KEY)}}function wa(t){let e=xm(),n={};for(let r of Qo){let o=nt[r],s=t?.[r],i=e[r],a={id:i.id??s?.id??o.id},c=s?.name;c&&(a.name=c);let l=s?.provider;l&&(a.provider=l);let d=i.baseUrl??s?.baseUrl;d&&(a.baseUrl=d);let u=i.apiKey??s?.apiKey;u&&(a.apiKey=u),n[r]=a}return n}function ht(t){return t||Xo||wa()}function yt(t,e=ht()){let n=t.trim().toLowerCase();if(!n||n===Em)return;for(let o of Qo){let s=e[o].name;if(s&&s.trim().toLowerCase()===n)return o}return n==="local"||n==="small"||n==="medium"||n==="large"?n:_m[n]}function ts(t,e=ht()){if(t===void 0)return{id:""};let n=yt(t,e);if(n)return e[n];let r=Am[t.trim().toLowerCase()];return r?{id:r}:{id:t}}function rt(t,e=ht()){if(t!==void 0)return ts(t,e).id}function Sa(t,e=ht()){if(t===void 0)return;let n=yt(t,e);if(n&&e[n].id.trim()===""){let r=n.toUpperCase();return`The "${n}" model tier is not configured (no model id). Set AFK_MODEL_${r}=<id> (optionally AFK_MODEL_${r}_BASE_URL / AFK_MODEL_${r}_API_KEY) or "models.${n}" in afk.config.json, then retry.`}}function va(t){let e={};if(!t||typeof t!="object")return e;let n=t;for(let r of Qo){let o=Rm(n[r]);o&&(e[r]=o)}return e}function Tm(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();if(e==="anthropic"||e==="anthropic-direct")return"anthropic";if(e==="openai"||e==="openai-compatible")return"openai"}function Vn(t){return typeof t=="string"?t.trim():""}function Rm(t){if(typeof t=="string"){let e=t.trim();return e?{id:e}:void 0}if(t&&typeof t=="object"){let e=t,n=Vn(e.id);if(!n)return;let r={id:n},o=Vn(e.name);o&&(r.name=o);let s=Tm(e.provider);s&&(r.provider=s);let i=Vn(e.baseUrl);i&&(r.baseUrl=i);let a=Vn(e.apiKey);return a&&(r.apiKey=a),r}}var ns={opus:nt.large.id,opus_1m:nt.large.id,sonnet:nt.medium.id,sonnet_1m:nt.medium.id,haiku:nt.small.id,fable:Zo};function ka(t){return t in ns}function oe(t){return rt(t)}import{randomUUID as _a}from"node:crypto";async function Ea(t){let{token:e,model:n,system:r,user:o,maxTokens:s=64,signal:i,clientFactory:a}=t;if(!e)throw new Error("oneShotCompletion: token required");let c=qn(e),l=qt(e,c),d=a?a(l):new Pm(l),u=_a(),p=_a(),f=ve(c,u,p),m=oe(n)??n,g={};Object.keys(f).length>0&&(g.headers=f),i&&(g.signal=i);let h=await d.messages.create({model:m,max_tokens:s,system:r,messages:[{role:"user",content:o}]},Object.keys(g).length>0?g:void 0),b=[];for(let y of h.content)y.type==="text"&&b.push(y.text);let v=b.join("").trim();return v.length===0&&console.warn("oneShotCompletion: response contained no text blocks \u2014 returning empty string"),v}import{execFileSync as Aa}from"child_process";import{existsSync as Im,readFileSync as Cm,writeFileSync as Mm}from"fs";import{homedir as xa,userInfo as Ta}from"os";import{join as Ra}from"path";var Om="9d1c250a-e61b-44d9-88ed-5944d1962f5e",Dm="https://platform.claude.com/v1/oauth/token",Fm=300*1e3;function ge(){let t=Pa();if(t===void 0)return;let e=Ia(t);if(e!==void 0){if(e.expiresAt!==void 0&&e.expiresAt<=Date.now()){process.stderr.write("agent-afk: Claude Code OAuth token in keychain is expired. Run `claude login` to refresh.\n");return}return e.accessToken}}async function rs(){let t=Pa();if(t===void 0)return;let e=Ia(t);if(e===void 0)return;if(e.expiresAt!==void 0&&e.expiresAt>Date.now()+Fm)return e.accessToken;if(!e.refreshToken){process.stderr.write("agent-afk: OAuth token expired and no refresh token available. Run `claude login` to refresh.\n");return}let n=await Lm(e.refreshToken);if(!n){process.stderr.write("agent-afk: OAuth token refresh failed. Run `claude login` to refresh.\n");return}try{let r={};try{r=JSON.parse(t)}catch{}let o=r.claudeAiOauth??{};r.claudeAiOauth={...o,accessToken:n.accessToken,expiresAt:n.expiresAt,...n.refreshToken!==void 0?{refreshToken:n.refreshToken}:{}},Nm(JSON.stringify(r))}catch{process.stderr.write(`agent-afk: Refreshed OAuth token but failed to write back to credential store.
2
+ `)}}}catch{}}function nc(){Ym(Jm(),ae())}function ds(t){if(typeof t!="string"||t.length===0)throw new Error("Invalid browser profile: must be a non-empty string");if(t.length>Ba)throw new Error(`Invalid browser profile: exceeds ${Ba} chars`);if(!Xm.test(t))throw new Error(`Invalid browser profile: ${JSON.stringify(t)} contains characters outside [A-Za-z0-9_-]`)}function Qm(){return H(He(),"browser")}function Zm(t){return ds(t),H(Qm(),t)}function us(t){return H(Zm(t),"storageState.json")}function en(t){return typeof t=="string"&&t.length>0&&t.length<=tg&&eg.test(t)}function tn(t){if(!en(t))throw new Error(`Invalid session id for ledger path: ${JSON.stringify(t)}`);return H(ae(),t)}function cr(t){return H(tn(t),"events.jsonl")}function rc(t){return H(tn(t),"session.key")}var Vm,Xm,Ba,eg,tg,j=me(()=>{"use strict";B();Vm=/^[a-zA-Z0-9_-]+$/;Xm=/^[A-Za-z0-9_-]+$/,Ba=128;eg=/^[A-Za-z0-9_-]+$/,tg=128});import{readFileSync as Eb}from"node:fs";import{join as Ab}from"path";function xb(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function pl(t,e){return xb(e).test(t)}function Pb(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(Tb.has(e))return!0;if(Rb.has(e))return!1}return!1}function fl(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function Ib(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 ml(t){let e=t===void 0||t.trim()===""?"default":t.trim();return ds(e),e}function Cb(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function Mb(t){try{return Eb(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function Ob(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=ml(e.defaultProfile)),n}function gl(t){let e=t?.env??w,n=t?.readFileSync??Mb,r=t?.surface??e.AGENT_SURFACE,o=Pb(e.AFK_BROWSER_HEADLESS,r),s=fl(e.AFK_BROWSER_ALLOWED_DOMAINS),i=fl(e.AFK_BROWSER_BLOCKED_DOMAINS),a=Cb(e.AFK_BROWSER_DOM_SNAPSHOTS),c=Ib(e.AFK_BROWSER_BACKEND),l=ml(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():Ab(Zt(),"browser.json"),f=n(p);if(f===void 0)return d;let m;try{m=JSON.parse(f)}catch(h){throw new Error(`Failed to parse browser config at ${p}: ${String(h)}`)}if(typeof m!="object"||m===null||Array.isArray(m))throw new Error(`Browser config at ${p} must be a JSON object`);let g=Ob(d,m);return g.configPath=p,g}function Os(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(pl(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>pl(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var Tb,Rb,Ds=me(()=>{"use strict";B();j();Tb=new Set(["daemon","subagent","telegram","afk"]),Rb=new Set(["repl","interactive","cli"])});import it from"node:fs";import Cr from"node:path";import{randomBytes as Db}from"node:crypto";import{chromium as Fb}from"playwright";function Lb(){try{return"5.15.2"}catch{}try{let t=Cr.resolve(import.meta.dirname,"../../../package.json"),e=it.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var Nb,Mr,hl=me(()=>{"use strict";j();ne();Nb=Lb(),Mr=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=Fb.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 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=()=>{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),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.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/${Nb}`}}loadStorageState(e){let n=us(e);try{if(!it.existsSync(n))return;let r=JSON.parse(it.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=us(e);if(!it.existsSync(r))return;let o=await n.storageState(),s=Cr.join(Cr.dirname(r),`.${Cr.basename(r)}.${process.pid}.${Db(4).toString("hex")}.tmp`);it.writeFileSync(s,JSON.stringify(o),{mode:384}),it.chmodSync(s,384),it.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 Ub}from"crypto";function Fs(t){if(t.length===0)return t;let e=t;for(let{regex:n,name:r}of $b)r==="form-password"?e=e.replace(n,"password=[redacted]"):e=e.replace(n,"[redacted]");return e}function yl(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&Bb.test(t.label))}function bl(t){return Ub("sha256").update(t,"utf8").digest("hex").slice(0,8)}function wl(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var $b,Bb,gn=me(()=>{"use strict";$b=[{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}];Bb=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as jb}from"node:crypto";function Hb(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function Kb(t,e,n){return`el_${jb("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function Wb(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Sl(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function kl(t,e){let n=t.role??"",r=t.name??"";vl.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])kl(s,e)}async function Gb(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},_l).catch(()=>[])}async function qb(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,m={role:l,name:c,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},_l).catch(()=>[])}function zb(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Or(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=zb(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=Gb(t),c=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),l=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,c,l,d]),h,b=!1;u!==null?(h=[],kl(u,h)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,h=(await qb(t)).filter($=>vl.has($.role??"")));let v=new Map;for(let E of p){let $=Sl(E.name),C=v.get($);(!C||C.bbox.w===0&&E.bbox.w>0)&&v.set($,E)}let y=h.map(E=>({ax:E,dom:v.get(Sl(E.name??""))})),S=r?y:y.filter(E=>E.dom?E.dom.bbox.w>0||E.dom.bbox.h>0:!0);S.sort((E,$)=>{let C=E.dom?.bbox.y??0,N=$.dom?.bbox.y??0;if(C!==N)return C-N;let R=E.dom?.bbox.x??0,P=$.dom?.bbox.x??0;return R-P}),S.length>200&&o.push("page has 200+ interactive elements; consider scoping");let x=S.slice(0,n).map((E,$)=>{let C=E.ax.role??"generic",N=E.ax.name??"",R=Kb(C,N,$),P=E.dom?.bbox??{x:0,y:0,w:0,h:0},I=E.dom?.type??null,A=null;E.ax.value!==void 0&&E.ax.value!==null&&(A=String(E.ax.value)),E.ax.checked!==void 0&&(A=String(E.ax.checked)),yl({role:C,kind:I})&&(A="[redacted]");let D={disabled:E.ax.disabled??!1};E.ax.checked!==void 0&&(D.checked=E.ax.checked===!0||E.ax.checked==="mixed"),E.ax.selected!==void 0&&(D.selected=E.ax.selected),E.ax.expanded!==void 0&&(D.expanded=E.ax.expanded);let K;E.dom?.testId?K=`[data-testid="${E.dom.testId}"]`:E.dom?.id&&(K=`#${E.dom.id}`);let W={id:R,role:C,label:Hb(N),kind:I,value:A,state:D,bbox:P};return K!==void 0&&(W.selector=K),W}),T="idle";try{let E=await t.evaluate(()=>document.readyState);E==="loading"?T="loading":E==="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 F=Wb(f),L=`obs_${e.observationCounter.toString(36)}`,O=new Date().toISOString();return{observationId:L,url:m,title:g,textSummary:F,interactive:x,status:{httpStatus:e.httpStatus??null,loadingState:T,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:O}}var vl,_l,El=me(()=>{"use strict";gn();vl=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);_l="a[href], button, input, select, textarea, [role], [tabindex], label"});async function Al(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 Ls(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>Al(t,s)))).filter(o=>o!==null)}async function Vb(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 Ns(t,e,n){switch(e.kind){case"element_id":return Jb(t,e,n);case"selector":return Yb(t,e);case"semantic":return Xb(t,e)}}async function Jb(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 Ls(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function Yb(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 Ls(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function Xb(t,e){return e.role!==void 0?Qb(t,e.text,e.role):Zb(t,e.text,e)}async function Qb(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 Ls(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function Zb(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 Vb(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 h=p[g];if(h===void 0)continue;let b=await Al(h.locator,h.index);if(b!==null){let v=`${b.role}:${b.label}:${g}`,y=0;for(let S=0;S<v.length;S++)y=y*31+v.charCodeAt(S)>>>0;f.push({...b,id:`el_${y.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var xl=me(()=>{"use strict"});import{randomBytes as ew}from"crypto";import{mkdir as tw,stat as nw,writeFile as rw}from"fs/promises";import{join as Us}from"path";import{gzip as ow}from"zlib";import{promisify as sw}from"util";function iw(t){return Us(ec(t),"browser")}function aw(t){return Us(iw(t),"screenshots")}function cw(){return new Date().toISOString().replace(/[:.]/g,"-")}function lw(){return ew(3).toString("hex")}async function $s(t,e,n){if(e.length>Tl)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Tl} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=aw(t);await tw(r,{recursive:!0});let o=`${cw()}-${lw()}-${n}.png`,s=Us(r,o);await rw(s,e);let{size:i}=await nw(s);return{path:s,bytes:i}}var CI,Tl,Rl=me(()=>{"use strict";j();gn();CI=sw(ow);Tl=5*1024*1024});var Il={};pa(Il,{PlaywrightProvider:()=>Bs});function Pl(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 Bs,Cl=me(()=>{"use strict";hl();El();xl();Ds();gn();Rl();Bs=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Mr(e)}async open(e){let n=Os(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 Or(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 Or(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 Ns(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${Pl(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=Fs(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(h){l=h}else l=g}let u=r.url();if(u!==s){let g=Os(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 Or(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})}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 Ns(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${Pl(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 $s(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 $s(n,o,r);return s}catch{return null}}}});var ct={};pa(ct,{__resetBrowserRegistryForTests:()=>mw,browserProviderActive:()=>pw,closeBrowserProvider:()=>js,getBrowserProvider:()=>uw,peekBrowserProvider:()=>fw});function Ml(){Promise.resolve(js()).then(()=>{process.exit(130)})}function Ol(){Promise.resolve(js()).then(()=>{process.exit(143)})}function Dl(){Te=null}function dw(){Dr||(process.on("SIGINT",Ml),process.on("SIGTERM",Ol),process.on("exit",Dl),Dr=!0)}function Fl(){Dr&&(process.removeListener("SIGINT",Ml),process.removeListener("SIGTERM",Ol),process.removeListener("exit",Dl),Dr=!1)}async function uw(t){return Te!==null?Te:(at!==null||(at=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(Cl(),Il)),n=gl(t),r=new e(n);return dw(),Te=r,at=null,r})()),at)}async function js(){if(Te===null)return;let t=Te;Te=null,at=null,Fl(),await t.shutdown()}function pw(){return Te!==null}function fw(){return Te}function mw(){Te=null,at=null,Fl()}var Te,at,Dr,lt=me(()=>{"use strict";Ds();Te=null,at=null,Dr=!1});ne();var le=class extends Error{constructor(e){super(e),this.name="AbortError"}},je=class extends Error{constructor(n,r){super(n);this.timeoutMs=r;this.name="TimeoutError"}timeoutMs},z=class extends Error{constructor(n,r,o,s){super(n);this.event=r;this.reason=o;this.name="HookBlockedError",s?.cause!==void 0&&(this.cause=s.cause)}event;reason;cause};var mt=class extends Error{constructor(n,r,o){super(o??`Budget ceiling reached: $${n.toFixed(4)} cumulative >= $${r.toFixed(4)} limit`);this.runningCostUsd=n;this.maxBudgetUsd=r;this.name="BudgetExceededError"}runningCostUsd;maxBudgetUsd};ne();async function gt(t,e){if(t)try{await t.write({kind:"tool_call",payload:e})}catch(n){M(`trace.emit tool_call failed: ${Me(n)}`)}}async function Ce(t,e){if(t)try{await t.write({kind:"hook_decision",payload:e})}catch(n){M(`trace.emit hook_decision failed: ${Me(n)}`)}}async function tt(t,e){if(t)try{await t.write({kind:"subagent_lifecycle",payload:e})}catch(n){M(`trace.emit subagent_lifecycle failed: ${Me(n)}`)}}async function fa(t,e){if(t)try{await t.write({kind:"budget",payload:e})}catch(n){M(`trace.emit budget failed: ${Me(n)}`)}}async function ma(t,e){if(t)try{await t.write({kind:"abort",payload:e})}catch(n){M(`trace.emit abort failed: ${Me(n)}`)}}async function ga(t,e){if(t)try{await t.write({kind:"compaction",payload:e})}catch(n){M(`trace.emit compaction failed: ${Me(n)}`)}}async function ha(t,e){if(t)try{await t.write({kind:"closure",payload:e})}catch(n){M(`trace.emit closure failed: ${Me(n)}`)}}async function Z(t,e){if(t)try{await t.write({kind:"browser_event",payload:e})}catch(n){M(`trace.emit browser_event failed: ${Me(n)}`)}}async function de(t,e){if(t)try{await t.write({kind:"session_phase",payload:e})}catch(n){M(`trace.emit session_phase failed: ${Me(n)}`)}}function Me(t){return t instanceof Error?t.message:String(t)}import qi from"path";import{appendFileSync as yE,mkdirSync as bE}from"fs";import{dirname as wE}from"path";import tf from"@anthropic-ai/sdk";var ya="claude-code-20250219,oauth-2025-04-20,interleaved-thinking-2025-05-14,extended-cache-ttl-2025-04-11",Sm="effort-2025-11-24",vm="claude-cli/1.0.0 (external, cli)",km="x-anthropic-billing-header: cc_version=1.0.0.test; cc_entrypoint=cli; cch=00000;";function qn(t){return t.startsWith("sk-ant-oat01-")?"oauth":"api-key"}function qt(t,e,n){let r=e==="oauth"?{authToken:t}:{apiKey:t};return typeof n=="string"&&n.length>0?{...r,baseURL:n}:r}function ve(t,e,n,r){return t!=="oauth"?{}:{"anthropic-beta":r?`${ya},${Sm}`:ya,"x-app":"cli","User-Agent":vm,"X-Claude-Code-Session-Id":e,"x-client-request-id":n}}function ba(t){return t!=="oauth"?null:[{type:"text",text:km}]}import Pm from"@anthropic-ai/sdk";B();var Qo=["local","small","medium","large"],nt={local:{id:""},small:{id:"claude-haiku-4-5-20251001"},medium:{id:"claude-sonnet-5"},large:{id:"claude-opus-4-8"}},_m={haiku:"small",sonnet:"medium",sonnet_1m:"medium",opus:"large",opus_1m:"large"},Em="auto",Zo="claude-fable-5",Am={fable:Zo},Xo;function es(t){Xo=t}function Yo(t){if(t===void 0)return;let e=t.trim();return e.length>0?e:void 0}function zn(t,e,n){let r={},o=Yo(t);o&&(r.id=o);let s=Yo(e);s&&(r.baseUrl=s);let i=Yo(n);return i&&(r.apiKey=i),r}function xm(){return{local:zn(w.AFK_MODEL_LOCAL,w.AFK_MODEL_LOCAL_BASE_URL,w.AFK_MODEL_LOCAL_API_KEY),small:zn(w.AFK_MODEL_SMALL,w.AFK_MODEL_SMALL_BASE_URL,w.AFK_MODEL_SMALL_API_KEY),medium:zn(w.AFK_MODEL_MEDIUM,w.AFK_MODEL_MEDIUM_BASE_URL,w.AFK_MODEL_MEDIUM_API_KEY),large:zn(w.AFK_MODEL_LARGE,w.AFK_MODEL_LARGE_BASE_URL,w.AFK_MODEL_LARGE_API_KEY)}}function wa(t){let e=xm(),n={};for(let r of Qo){let o=nt[r],s=t?.[r],i=e[r],a={id:i.id??s?.id??o.id},c=s?.name;c&&(a.name=c);let l=s?.provider;l&&(a.provider=l);let d=i.baseUrl??s?.baseUrl;d&&(a.baseUrl=d);let u=i.apiKey??s?.apiKey;u&&(a.apiKey=u),n[r]=a}return n}function ht(t){return t||Xo||wa()}function yt(t,e=ht()){let n=t.trim().toLowerCase();if(!n||n===Em)return;for(let o of Qo){let s=e[o].name;if(s&&s.trim().toLowerCase()===n)return o}return n==="local"||n==="small"||n==="medium"||n==="large"?n:_m[n]}function ts(t,e=ht()){if(t===void 0)return{id:""};let n=yt(t,e);if(n)return e[n];let r=Am[t.trim().toLowerCase()];return r?{id:r}:{id:t}}function rt(t,e=ht()){if(t!==void 0)return ts(t,e).id}function Sa(t,e=ht()){if(t===void 0)return;let n=yt(t,e);if(n&&e[n].id.trim()===""){let r=n.toUpperCase();return`The "${n}" model tier is not configured (no model id). Set AFK_MODEL_${r}=<id> (optionally AFK_MODEL_${r}_BASE_URL / AFK_MODEL_${r}_API_KEY) or "models.${n}" in afk.config.json, then retry.`}}function va(t){let e={};if(!t||typeof t!="object")return e;let n=t;for(let r of Qo){let o=Rm(n[r]);o&&(e[r]=o)}return e}function Tm(t){if(typeof t!="string")return;let e=t.trim().toLowerCase();if(e==="anthropic"||e==="anthropic-direct")return"anthropic";if(e==="openai"||e==="openai-compatible")return"openai"}function Vn(t){return typeof t=="string"?t.trim():""}function Rm(t){if(typeof t=="string"){let e=t.trim();return e?{id:e}:void 0}if(t&&typeof t=="object"){let e=t,n=Vn(e.id);if(!n)return;let r={id:n},o=Vn(e.name);o&&(r.name=o);let s=Tm(e.provider);s&&(r.provider=s);let i=Vn(e.baseUrl);i&&(r.baseUrl=i);let a=Vn(e.apiKey);return a&&(r.apiKey=a),r}}var ns={opus:nt.large.id,opus_1m:nt.large.id,sonnet:nt.medium.id,sonnet_1m:nt.medium.id,haiku:nt.small.id,fable:Zo};function ka(t){return t in ns}function oe(t){return rt(t)}import{randomUUID as _a}from"node:crypto";async function Ea(t){let{token:e,model:n,system:r,user:o,maxTokens:s=64,signal:i,clientFactory:a}=t;if(!e)throw new Error("oneShotCompletion: token required");let c=qn(e),l=qt(e,c),d=a?a(l):new Pm(l),u=_a(),p=_a(),f=ve(c,u,p),m=oe(n)??n,g={};Object.keys(f).length>0&&(g.headers=f),i&&(g.signal=i);let h=await d.messages.create({model:m,max_tokens:s,system:r,messages:[{role:"user",content:o}]},Object.keys(g).length>0?g:void 0),b=[];for(let y of h.content)y.type==="text"&&b.push(y.text);let v=b.join("").trim();return v.length===0&&console.warn("oneShotCompletion: response contained no text blocks \u2014 returning empty string"),v}import{execFileSync as Aa}from"child_process";import{existsSync as Im,readFileSync as Cm,writeFileSync as Mm}from"fs";import{homedir as xa,userInfo as Ta}from"os";import{join as Ra}from"path";var Om="9d1c250a-e61b-44d9-88ed-5944d1962f5e",Dm="https://platform.claude.com/v1/oauth/token",Fm=300*1e3;function ge(){let t=Pa();if(t===void 0)return;let e=Ia(t);if(e!==void 0){if(e.expiresAt!==void 0&&e.expiresAt<=Date.now()){process.stderr.write("agent-afk: Claude Code OAuth token in keychain is expired. Run `claude login` to refresh.\n");return}return e.accessToken}}async function rs(){let t=Pa();if(t===void 0)return;let e=Ia(t);if(e===void 0)return;if(e.expiresAt!==void 0&&e.expiresAt>Date.now()+Fm)return e.accessToken;if(!e.refreshToken){process.stderr.write("agent-afk: OAuth token expired and no refresh token available. Run `claude login` to refresh.\n");return}let n=await Lm(e.refreshToken);if(!n){process.stderr.write("agent-afk: OAuth token refresh failed. Run `claude login` to refresh.\n");return}try{let r={};try{r=JSON.parse(t)}catch{}let o=r.claudeAiOauth??{};r.claudeAiOauth={...o,accessToken:n.accessToken,expiresAt:n.expiresAt,...n.refreshToken!==void 0?{refreshToken:n.refreshToken}:{}},Nm(JSON.stringify(r))}catch{process.stderr.write(`agent-afk: Refreshed OAuth token but failed to write back to credential store.
3
3
  `)}return n.accessToken}function Pa(){if(process.platform==="darwin")try{return Aa("security",["find-generic-password","-s","Claude Code-credentials","-a",Ta().username,"-w"],{stdio:["ignore","pipe","ignore"],encoding:"utf-8"}).trim()}catch{return}if(process.platform==="linux"){let t=Ra(xa(),".claude",".credentials.json");if(!Im(t))return;try{return Cm(t,"utf-8")}catch{return}}}function Ia(t){let e;try{e=JSON.parse(t)}catch{return}if(typeof e!="object"||e===null)return;let n=e.claudeAiOauth;if(typeof n!="object"||n===null)return;let r=n,o=r.accessToken;if(typeof o!="string"||o.length===0)return;let s={accessToken:o},i=r.refreshToken;typeof i=="string"&&i.length>0&&(s.refreshToken=i);let a=r.expiresAt;return typeof a=="number"&&(s.expiresAt=a),s}async function Lm(t){try{let e=await fetch(Dm,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:t,client_id:Om})});if(!e.ok)return;let n=await e.json(),r=n.access_token,o=n.expires_in;if(typeof r!="string"||typeof o!="number")return;let s=n.refresh_token;return{accessToken:r,expiresAt:Date.now()+o*1e3,...typeof s=="string"&&s.length>0?{refreshToken:s}:{}}}catch{return}}function zt(t){if(!t||t.length<3)return"token:(unknown)";try{let n=t.split(".");if(n.length<2)throw new Error("not a JWT");let r=Buffer.from(n[1],"base64url").toString("utf-8"),o=JSON.parse(r),s=typeof o.email=="string"&&o.email||typeof o.sub=="string"&&o.sub||typeof o.account_id=="string"&&o.account_id||typeof o.preferred_username=="string"&&o.preferred_username;if(s)return s}catch{}return`token:${t.length>=8?t.slice(-8):t}`}function Nm(t){if(process.platform==="darwin")Aa("security",["add-generic-password","-U","-s","Claude Code-credentials","-a",Ta().username,"-w",t],{stdio:["ignore","ignore","ignore"]});else if(process.platform==="linux"){let e=Ra(xa(),".claude",".credentials.json");Um(e,t)}}function Um(t,e){Mm(t,e,{encoding:"utf-8",mode:384})}import{randomUUID as Yp}from"node:crypto";function ke(t){return t==="bypassPermissions"||t==="autonomous"}B();var $m="1h";function Jn(t){if(typeof t?.baseUrl=="string"&&t.baseUrl.length>0)return!1;let e=w.AFK_DISABLE_PROMPT_CACHE;if(e===void 0||e.length===0)return!0;let n=e.toLowerCase();return!(n==="1"||n==="true"||n==="yes"||n==="on")}function Yn(){let t=w.AFK_PROMPT_CACHE_TTL;return t==="5m"?"5m":t==="1h"?"1h":$m}function Ca(t,e){if(t.length===0)return t;let n=t[t.length-1],r=Oa(n,e);return r===n?t:[...t.slice(0,-1),r]}function Ma(t,e){if(t.length===0)return t;let n=t[t.length-1],r=Bm(n,e);return r===n?t:[...t.slice(0,-1),r]}function Bm(t,e){let n=t.content;if(typeof n=="string")return n.length===0?t:{...t,content:[{type:"text",text:n,cache_control:{type:"ephemeral",ttl:e}}]};if(!Array.isArray(n)||n.length===0)return t;let r=n[n.length-1],o=Oa(r,e);return o===r?t:{...t,content:[...n.slice(0,-1),o]}}function Oa(t,e){return t.type==="thinking"||t.type==="redacted_thinking"?t:{...t,cache_control:{type:"ephemeral",ttl:e}}}var Xn=["## Plan mode is active","","File and memory write tools (`write_file`, `edit_file`, `memory_update`, `procedure_write`) are refused at the hook layer.","`bash` runs for read-only investigation (git status/log/diff, ls, cat, grep, find \u2014 chained or not); state-mutating bash (file writes, rm, installs, commits, pushes) is refused while planning. The user has asked you to plan, not yet to act \u2014 exit plan mode to make changes.","Treat this turn as planning work.","","Traverse the shape that matches the work \u2014 skip steps the terrain already covers, do not skip steps the terrain hides:",""," unknown field \u2192 ground the current terrain \u2192 gather missing codebase context \u2192"," research missing external context \u2192 reveal chaos / constraints / risks \u2192"," name the failure geometry \u2192 form a candidate plan \u2192 apply adversarial pressure \u2192 embody the final plan","","Reach for these skills (invoke via the `skill` tool) when the cost of skipping exceeds the cost of dispatching:"," - `ground-state` \u2014 survey git, infra, memory before non-trivial work"," - `gather` \u2014 parallel context-gathering for a code area"," - `research` \u2014 parallel external + local context for the current task"," - `devils-advocate` \u2014 generate alternatives and rank them before committing"," - `shadow-verify` \u2014 independently re-derive load-bearing claims","","Do not declare readiness silently. When the plan is ready, state: chosen approach, risks named, and alternatives considered.","","Then, IF the task requires implementation (writing code or files), call the `exit_plan_mode` tool to present your plan. The user picks how to proceed (approve and implement, or keep planning). After calling it, END YOUR TURN \u2014 on approval you will receive a separate instruction to save the plan to a file and implement it. Do NOT use `ask_question` to ask whether the plan is OK; that is exactly what `exit_plan_mode` does \u2014 use `ask_question` only to resolve open requirement questions first. For research / read-only tasks that need no code changes, do NOT call `exit_plan_mode` \u2014 just answer.","","Manual fallbacks remain: the user can exit with `/plan off` (same save-and-implement handoff), and Shift+Tab advances the permission-mode ring without saving or implementing. Keep the plan concrete and complete enough to act on directly."].join(`
4
4
  `);function os(t){return t!=="plan"?null:{type:"text",text:Xn}}var Qn=["## AFK mode is active","","The operator is away from keyboard. Your channel to them is Telegram via the `send_telegram` tool \u2014 not this transcript, which no one is watching live. At the end of each turn, push your terminal state (Done / Blocked / Asking) to Telegram so the operator can review asynchronously.","","Posture \u2014 bounded autonomy, not unchecked action:"," - Proceed autonomously on reversible work. Do not stop to confirm actions you are already authorized to take and can undo (edits, reads, tests, local commits, non-force pushes, installs)."," - At a one-way door \u2014 anything irreversible, externally visible, credential- or payment-touching, or where multiple readings lead to materially different work \u2014 do NOT guess. Push a concise Asking summary to Telegram naming the decision and your recommended default, then stop and end the turn in the Asking state."," - A mechanical gate refuses high-risk and irreversible operations at the hook layer regardless of this text. Treat a gate refusal as a signal to surface the decision to the operator, not an obstacle to work around.","","Communication discipline:"," - Batch updates. Send a Telegram message at terminal state (and at a genuinely blocking fork), not a play-by-play \u2014 the operator gets a push notification for every message."," - Keep pushes short and scannable: what happened, what changed, what (if anything) you need. Never paste raw tool output, logs, secrets, or full file contents into a push.","","Exit: the operator returns and runs `/afk off` (or Shift+Tab) to restore default permissions and terminal-channel interaction."].join(`
5
5
  `);function ss(t){return t!=="autonomous"?null:{type:"text",text:Qn}}import{z as J}from"zod";import{mkdir as Fu,appendFile as Lu}from"fs/promises";import{join as vi}from"path";var Da={"audit-fit":{"01-skill-inspector.md":`# Skill Inspector
package/dist/telegram.mjs CHANGED
@@ -1013,7 +1013,8 @@ Available skills: ${n.join(", ")}`:"";throw new Error(`Skill not found: ${t}${r}
1013
1013
  `),this.errored=!0}}async close(e){if(!this.closed)return this.record({kind:"closed",...e!==void 0?{reason:e}:{}}),this.closed=!0,this.readyPromise&&await this.readyPromise,new Promise(n=>{if(!this.stream){n();return}this.stream.end(()=>n())})}};Ak=250});import{mkdir as Tk,writeFile as sp,unlink as vL,readdir as xk,readFile as ip}from"fs/promises";import{unlinkSync as Rk,existsSync as Pk}from"fs";import{join as ap}from"path";function ka(t){return ap(zr(),`${t}.json`)}async function Ik(){try{return await Tk(zr(),{recursive:!0}),!0}catch{return!1}}async function qn(t){try{if(!await Ik())return;let n=ka(t.sessionId);await sp(n,JSON.stringify(t,null,2),"utf8")}catch{}}async function cp(t,e){try{let n=ka(t),r=await ip(n,"utf8"),o=JSON.parse(r);o.cwd=e,await sp(n,JSON.stringify(o,null,2),"utf8")}catch{}}function Ze(t){try{let e=ka(t);Pk(e)&&Rk(e)}catch{}}async function zn(){let t=zr(),e;try{e=await xk(t)}catch{return[]}let n=[];for(let r of e){if(!r.endsWith(".json"))continue;let o=ap(t,r);try{let s=await ip(o,"utf8"),i=JSON.parse(s);i!==null&&typeof i=="object"&&"sessionId"in i&&typeof i.sessionId=="string"&&n.push({...i,path:o})}catch{}}return n}var Vn=y(()=>{"use strict";W()});function lp(t,e,n){t&&(t.aborted?e.abort(t.reason):t.addEventListener("abort",()=>{e.signal.aborted||e.abort(t.reason)},{once:!0})),e.signal.addEventListener("abort",n,{once:!0})}function dp(t,e){let n=t.permissionMode??"default",r=t.persistSession??!0,o={sessionId:t.sessionId,configuredSessionId:t.sessionId,resume:t.resume,resumeSessionAt:t.resumeSessionAt,continue:t.continue,forkSession:t.forkSession,persistSession:r},s={sessionId:t.sessionId,model:e,permissionMode:n};return{sessionIdentity:o,metadata:s}}var up=y(()=>{"use strict"});var Uo,pp=y(()=>{"use strict";Uo=class{initializationPromise;resolveInitialization;rejectInitialization;initializationSettled=!1;sessionMetadata;sessionIdentity;constructor(e,n){this.sessionIdentity=e,this.sessionMetadata=n,this.initializationPromise=new Promise((r,o)=>{this.resolveInitialization=r,this.rejectInitialization=o})}waitForInitialization(){return this.initializationPromise}getSessionIdentity(){return{...this.sessionIdentity,sessionId:this.getSessionId()}}getSessionMetadata(){return{...this.sessionMetadata,sessionId:this.getSessionId()}}getSessionId(){return this.sessionMetadata.sessionId??this.sessionIdentity.sessionId}updateSessionIdentity(e){e&&(this.sessionIdentity={...this.sessionIdentity,sessionId:e},this.sessionMetadata={...this.sessionMetadata,sessionId:e})}setSessionMetadata(e){this.sessionMetadata=e(this.sessionMetadata)}resolveInitializationIfNeeded(){this.initializationSettled||(this.initializationSettled=!0,this.resolveInitialization(this.getSessionMetadata()))}resolveInitializationOnce(){this.initializationSettled||(this.initializationSettled=!0,this.resolveInitialization(this.getSessionMetadata()))}rejectInitializationOnce(e){this.initializationSettled||(this.initializationSettled=!0,this.rejectInitialization(e))}isInitializationSettled(){return this.initializationSettled}}});function fp(t){try{let e=JSON.parse(t);if(!Array.isArray(e))return null;let n=e.length;if(n===0)return"no results";let r=0,o=0;for(let a of e)if(a&&typeof a=="object"){let c=a.type;c==="fact"?r++:c==="procedure"&&o++}let s=`${n} result${n===1?"":"s"}`;if(r+o!==n)return s;let i=[];return r>0&&i.push(`${r} fact${r===1?"":"s"}`),o>0&&i.push(`${o} procedure${o===1?"":"s"}`),i.length===0?s:`${s} (${i.join(", ")})`}catch{return null}}function mp(t){try{let e=JSON.parse(t);if(!e||typeof e!="object")return null;let n=e;if(n.target==="hot"&&n.saved===!0){if(n.truncated===!0)return"hot memory saved (truncated to fit cap)";let r=n.usage;if(r&&typeof r=="object"){let o=r.pct;if(typeof o=="number")return`hot memory saved (${o}% of cap)`}return"hot memory saved"}if(n.target==="fact"){if(n.action==="remove")return n.removed===!0?"fact removed":"fact not found";if(n.action==="set"&&typeof n.id=="number")return`fact #${n.id} set`;if(n.action==="supersede"&&typeof n.id=="number"&&typeof n.supersedes=="number")return`fact #${n.id} supersedes #${n.supersedes}`}return null}catch{return null}}function gp(t){try{let e=JSON.parse(t);if(!e||typeof e!="object")return null;let n=e;return typeof n.name=="string"&&n.written===!0?`wrote procedure '${n.name}'`:null}catch{return null}}var hp=y(()=>{"use strict"});function _a(t){let e=t.trim();if(e.length===0)return null;let n=e[0];if(n!=="{"&&n!=="[")return null;let r=e[e.length-1];if(n==="{"&&r!=="}"||n==="["&&r!=="]")return null;let o;try{o=JSON.parse(e)}catch{return null}return Array.isArray(o)?yp(Ck(o)):o!==null&&typeof o=="object"?yp(Mk(o)):null}function Ck(t){return t.length===0?"[empty array]":t.length===1?"[1 item]":`[${t.length} items]`}function Mk(t){let e=Object.keys(t);if(e.length===0)return"{empty object}";let n=e.slice(0,4),r=e.length>4?", \u2026":"";return`{${n.join(", ")}${r}}`}function yp(t){return t.length<=80?t:t.slice(0,79)+"\u2026"}var bp=y(()=>{"use strict"});function Bo(t){return t.replace(wp,"").replace(Ok," ").trim()}function et(t){return t.replace(wp,"")}var wp,Ok,an=y(()=>{"use strict";wp=/\x1B\][^\x07\x1B]*(?:\x07|\x1B\\)|\x1B[P^_X][^\x1B]*\x1B\\|\x1B\[[0-?]*[ -/]*[@-~]|\x9B[0-?]*[ -/]*[@-~]|\x1B[@-_]/g,Ok=/[\x00-\x1F\x7F-\x9F]/g});function Sp(t,e){if(!t)return null;let n=Dk.get(t);if(!n)return null;try{let r=n(e);if(r===null)return null;let o=Bo(r);return o.length>0?o:null}catch{return null}}var Dk,vp=y(()=>{"use strict";hp();bp();an();Dk=new Map([["memory_search",fp],["memory_update",mp],["procedure_write",gp],["bash",_a],["Bash",_a]])});function Fk(t){let e=/Output too large \((\d+(?:\.\d+)?)\s*(B|KB|MB|GB)\)\.\s*Full output saved to:\s*(\/[^\n]+)/,n=t.match(e);if(!n||!n[1]||!n[2]||!n[3])return null;let r=n[1],o=n[2],s=n[3],i=parseFloat(r),a=i;o==="KB"?a=i*1024:o==="MB"?a=i*1024*1024:o==="GB"&&(a=i*1024*1024*1024);let c=r;return i%1===0&&(c=String(Math.floor(i))),c+=o,{sizeLabel:c,sizeBytes:Math.round(a),absolutePath:s.trim()}}function Lk(t){if(t<1024)return`${t}B`;let e=t/1024;if(e<1024)return e%1===0?`${Math.floor(e)}KB`:`${e.toFixed(1)}KB`;let n=e/1024;if(n<1024)return n%1===0?`${Math.floor(n)}MB`:`${n.toFixed(1)}MB`;let r=n/1024;return r%1===0?`${Math.floor(r)}GB`:`${r.toFixed(1)}GB`}function Nk(t){let e=Buffer.byteLength(t,"utf8"),n=Lk(e),r=t.split(`
1014
1014
  `);if(r.length<=1&&t.length<=80)return{content:t,truncated:!1,sizeBytes:e,sizeLabel:n};if(r.length<=1)return t.length<=80?{content:t,truncated:!1,sizeBytes:e,sizeLabel:n}:{content:t.substring(0,80)+"\u2026",truncated:!0,sizeBytes:e,sizeLabel:n};if(t.length<=80)return{content:t,truncated:!1,sizeBytes:e,sizeLabel:n};let o=r[0]??"",s=o;return o.length>80&&(s=o.substring(0,80)+"\u2026"),{content:s+`\u2026+${r.length} lines`,truncated:!0,lineCount:r.length,sizeBytes:e,sizeLabel:n}}function $k(t,e){let n={...t.raw??{}};return t.inputTokens!==void 0&&(n.input_tokens=t.inputTokens),t.outputTokens!==void 0&&(n.output_tokens=t.outputTokens),t.cachedInputTokens!==void 0&&(n.cache_read_input_tokens=t.cachedInputTokens),t.cacheCreationTokens!==void 0&&(n.cache_creation_input_tokens=t.cacheCreationTokens),t.totalTokens!==void 0&&(n.total_tokens=t.totalTokens),t.contextWindowTokens!==void 0&&(n.context_window_tokens=t.contextWindowTokens),{sessionId:e,stopReason:t.stopReason??void 0,resultSubtype:t.resultSubtype,durationMs:t.durationMs,durationApiMs:t.durationApiMs,totalCostUsd:t.totalCostUsd,isError:t.isError,usage:Object.keys(n).length>0?n:void 0,modelUsage:t.modelUsage,permissionDenials:t.permissionDenials,errors:t.errors}}function Uk(t){let e=t.isError===!0?null:Sp(t.toolName,t.content),n=e!==null?{display:e}:{},r=Fk(t.content);if(r)return{type:"chunk",chunk:{type:"tool_result",toolUseId:t.toolUseId,content:`Output persisted (${r.sizeLabel}) \u2192 ${r.absolutePath}`,isError:t.isError===!0,persistedPath:r.absolutePath,sizeBytes:r.sizeBytes,sizeLabel:r.sizeLabel,...n}};let{content:o,lineCount:s,sizeBytes:i,sizeLabel:a}=Nk(t.content);return{type:"chunk",chunk:{type:"tool_result",toolUseId:t.toolUseId,content:o,isError:t.isError===!0,sizeBytes:i,sizeLabel:a,...t.truncated===!0&&{truncated:!0},...s!==void 0&&{lineCount:s},...n}}}function Ea(t,e){switch(t.type){case"session.init":{let n=t.info;return e.setSessionMetadata(r=>({...r,sessionId:n.sessionId,model:n.model??r.model,...n.permissionMode!==void 0?{permissionMode:n.permissionMode}:{},...n.cwd!==void 0?{cwd:n.cwd}:{},tools:n.tools?[...n.tools]:r.tools,slashCommands:n.slashCommands?[...n.slashCommands]:r.slashCommands,skills:n.skills?[...n.skills]:r.skills,plugins:n.plugins?n.plugins.map(o=>({...o})):r.plugins,mcpServers:n.mcpServers?n.mcpServers.map(o=>({...o})):r.mcpServers,...n.apiKeySource!==void 0?{apiKeySource:n.apiKeySource}:{},...n.version!==void 0?{claudeCodeVersion:n.version}:{},...n.outputStyle!==void 0?{outputStyle:n.outputStyle}:{}})),e.updateSessionIdentity(n.sessionId),e.resolveInitialization(),null}case"session.status":return e.setSessionMetadata(n=>({...n,sessionId:t.sessionId,...t.permissionMode!==void 0?{permissionMode:t.permissionMode}:{permissionMode:n.permissionMode},...t.status!==void 0?{status:t.status}:{}})),null;case"delta.text":return{type:"chunk",chunk:{type:"content",content:t.text,metadata:{eventType:"delta",deltaType:"text_delta"}}};case"delta.reasoning":return{type:"chunk",chunk:{type:"thinking",content:t.text,metadata:{eventType:"delta",deltaType:"thinking_delta"}}};case"assistant.message":if(t.sessionId&&e.updateSessionIdentity(t.sessionId),t.text){let n={role:"assistant",content:t.text,timestamp:new Date};return e.conversationHistory.push(n),{type:"message",message:n}}return null;case"tool.use.start":return{type:"chunk",chunk:{type:"tool_use_detail",toolUseId:t.toolUseId,toolName:t.toolName,toolInput:t.toolInput,toolInputRaw:t.toolInputRaw}};case"tool.use":return{type:"chunk",chunk:{type:"tool_use",content:t.summary,metadata:{eventType:"tool_use_summary",precedingToolUseIds:t.toolUseIds}}};case"tool.output":return Uk(t);case"tool.diff":return{type:"chunk",chunk:{type:"tool_diff",toolUseId:t.toolUseId,diff:t.diff}};case"progress":return{type:"progress",progress:{taskId:t.progress.taskId,description:t.progress.description,...t.progress.summary!==void 0?{summary:t.progress.summary}:{},...t.progress.lastToolName!==void 0?{lastToolName:t.progress.lastToolName}:{},totalTokens:t.progress.totalTokens,toolUses:t.progress.toolUses,durationMs:t.progress.durationMs}};case"suggestion":return{type:"suggestion",suggestion:t.suggestion};case"turn.completed":{let n=$k(t.usage,t.sessionId??e.getSessionMetadata().sessionId);e.setLastResponseMetadata(n);for(let r=e.conversationHistory.length-1;r>=0;r--){let o=e.conversationHistory[r];if(o?.role==="assistant"){o.metadata=n;break}}if(e.maxBudgetUsd!==void 0&&e.abortBudget!==void 0&&typeof n.totalCostUsd=="number"&&(e._runningCostUsd=(e._runningCostUsd??0)+n.totalCostUsd,e._runningCostUsd>=e.maxBudgetUsd)){ju(e.traceWriter,{kind:"monetary",runningCostUsd:e._runningCostUsd,maxBudgetUsd:e.maxBudgetUsd,lastTurnCostUsd:n.totalCostUsd});let r=new Xt(e._runningCostUsd,e.maxBudgetUsd);return e.abortBudget(r.message),{type:"error",error:r}}return{type:"done",metadata:n}}case"error":return{type:"error",error:t.error};case"paused":return{type:"paused",reason:t.reason,...t.resetsAt!==void 0?{resetsAt:t.resetsAt}:{},...t.accountId!==void 0?{accountId:t.accountId}:{},...t.autoResume!==void 0?{autoResume:t.autoResume}:{}};case"resumed":return{type:"resumed",hotSwapped:t.hotSwapped,...t.accountId!==void 0?{accountId:t.accountId}:{}};case"stream.retry":return{type:"stream_retry"};default:return null}}var kp=y(()=>{"use strict";me();ee();vp()});import{z as Bk}from"zod";var Dt,_p=y(()=>{"use strict";le();me();ee();Ee();qu();rn();Oo();Yu();me();Qu();ep();va();ya();$o();j();Ue();pt();Vn();Ye();ba();up();pp();kp();Dt=class{config;_pendingPlanExitSeed;_prePlanPermissionMode;currentState="idle";providerQuery;providerIterator;conversationHistory=[];turnCount=0;lastResponseMetadata=null;initPromise=null;inputStream;abortController;_hookRegistry;sessionEndDispatched=!1;stateManager;sessionRunningCostUsd=0;sessionRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0};lastStopReason;maxTurnsHit=!1;hookBlocked=!1;sawProviderError=!1;sessionStartedAt=Date.now();subagentCompletedCount=0;subagentRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0};subagentRunningCostUsd=0;ledger=null;ledgerInitAttempted=!1;constructor(e){this.config=e.parentSessionId===void 0&&e.planExitControls===void 0?{...e,planExitControls:{setPermissionMode:r=>this.setPermissionMode(r),requestImplementSeed:(r,o)=>{this._pendingPlanExitSeed={message:r,mode:o}},getPrePlanMode:()=>this._prePlanPermissionMode}}:e,this.abortController=new AbortController,this._hookRegistry=e.hookRegistry,lp(e.abortSignal,this.abortController,()=>{this.onAbort()});let n=String(e.model);se(e.traceWriter,{phase:"session_init_start",model:n,resolvedModel:ie(e.model)??n,origin:ut(e.surface),actor:io(e.parentSessionId)}),this.initSdkLifecycle()}initSdkLifecycle(){this.config.models&&ko(this.config.models),Po(this.config);let e=ie(this.config.model)??this.config.model,{sessionIdentity:n,metadata:r}=dp(this.config,e);this.stateManager=new Uo(n,r),this.inputStream=new nn(()=>this.sessionId);let o=this.inputStream.createIterable();if(this.config.provider)U(`\u{1F7E2} AgentSession: Creating query session via injected provider=${this.config.provider.name}`),this.providerQuery=this.config.provider.query({prompt:o,config:this.config});else{U("\u{1F7E2} AgentSession: Creating query session via ProviderRouter");let i=this.config.providerFactory?this.config.providerFactory:a=>Ep(a,void 0,{customTools:this.config.customTools,canUseTool:this.config.canUseTool});this.providerQuery=new Io({prompt:o,config:this.config},{resolveProvider:i,providerNameForModel:a=>X(a),resolveApiKey:a=>Qe(a)})}this.conversationHistory=[],this.turnCount=0,this.lastResponseMetadata=null,this.sessionRunningCostUsd=0,this.sessionRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0},this.lastStopReason=void 0,this.maxTurnsHit=!1,this.hookBlocked=!1,this.sawProviderError=!1,this.sessionEndDispatched=!1,this.currentState="idle",this.subagentCompletedCount=0,this.subagentRunningTokens={input:0,output:0,cacheRead:0,cacheCreation:0},this.subagentRunningCostUsd=0;let s=this.providerQuery;this.providerIterator=s[Symbol.asyncIterator](),this.initPromise=this.pullInitialization()}async pullInitialization(){try{for(await Vu(this._hookRegistry,{event:"SessionStart",sessionId:this.sessionId},{signal:this.abortController.signal,...this.config.traceWriter?{traceWriter:this.config.traceWriter}:{}});;){let e=await this.providerIterator.next();if(e.done){this.stateManager.resolveInitializationIfNeeded();return}let n=e.value,r=Ea(n,this.buildTransformDeps());if(n.type==="session.init"){await se(this.config.traceWriter,{phase:"session_init_done",durationMs:Date.now()-this.sessionStartedAt});return}if(r&&r.type==="error"){this.sawProviderError=!0;return}}}catch(e){let n=e instanceof Error?e:new Error(String(e));n instanceof Y&&(this.hookBlocked=!0),this.stateManager.isInitializationSettled()||this.stateManager.rejectInitializationOnce(n),await this.dispatchSessionEndOnce("error").catch(()=>{})}}buildTransformDeps(){return{conversationHistory:this.conversationHistory,getSessionMetadata:()=>this.stateManager.getSessionMetadata(),setSessionMetadata:e=>this.stateManager.setSessionMetadata(e),updateSessionIdentity:e=>this.stateManager.updateSessionIdentity(e),resolveInitialization:()=>this.stateManager.resolveInitializationOnce(),setLastResponseMetadata:e=>{this.lastResponseMetadata=e,typeof e.totalCostUsd=="number"&&Number.isFinite(e.totalCostUsd)&&(this.sessionRunningCostUsd+=e.totalCostUsd);let n=e.usage;if(n&&typeof n=="object"){let r=n,o=(s,i)=>{let a=r[s];typeof a=="number"&&Number.isFinite(a)&&(this.sessionRunningTokens[i]+=a)};o("input_tokens","input"),o("output_tokens","output"),o("cache_read_input_tokens","cacheRead"),o("cache_creation_input_tokens","cacheCreation")}typeof e.stopReason=="string"&&(this.lastStopReason=e.stopReason)},maxBudgetUsd:this.config.maxBudgetUsd,abortBudget:e=>{this.abortController.signal.aborted||this.abortController.abort(e)},...this.config.traceWriter?{traceWriter:this.config.traceWriter}:{}}}get state(){return this.currentState}get sessionId(){return this.stateManager.getSessionId()}get cwd(){return this.config.cwd}get abortSignal(){return this.abortController.signal}get hookRegistry(){return this._hookRegistry}abort(e){if(e==="closed"||e.startsWith("Budget ")||e.includes("timed out"))throw new Error(`AgentSession.abort: reserved reason "${e}" (use a caller-specific string like 'sigint')`);this.abortController.signal.aborted||this.abortController.abort(e)}async sendMessage(e,n={}){this.assertCanSend();let r=this.config.timeoutMs??Co,o=async()=>{let s=null,i="";this.currentState=n.stream?"streaming":"processing";for await(let a of this.sendMessageStreamInternal(e)){if(a.type==="chunk"&&a.chunk.type==="content"&&(i+=a.chunk.content),a.type==="message"&&a.message.role==="assistant"&&(s=a.message),a.type==="error")throw a.error;if(a.type==="done"){if(s)return{...s,metadata:a.metadata};if(i)return{role:"assistant",content:i,metadata:a.metadata,timestamp:new Date}}}if(s)return s;if(i)return{role:"assistant",content:i,timestamp:new Date};throw new Error("No assistant response received")};try{return await Mo(o(),r,{controller:this.abortController,label:this.sessionId??"session"})}finally{this.currentState==="processing"&&(this.currentState="idle")}}async sendMessageStructured(e,n,r={}){let{maxRetries:o=2,injectSchemaPrompt:s=!0,...i}=r,a=s?"\n\nRespond with ONLY a JSON object (optionally in a ```json fence) that conforms to this JSON Schema:\n```json\n"+JSON.stringify(Bk.toJSONSchema(n,{target:"openapi-3.0"}))+"\n```":"",c="";for(let l=0;l<=o;l++){let d=l===0?e+a:`Your previous response did not match the required JSON schema.
1015
1015
  Validation error: ${c}
1016
- Respond again with ONLY a JSON object (optionally in a \`\`\`json fence) that satisfies the schema.`+a,u=await this.sendMessage(d,i),p=Fo(u.content),f=n.safeParse(p);if(f.success)return f.data;c=f.error.message}throw new Error(`structured output did not match schema after ${o+1} attempt(s): ${c}`)}async*sendMessageStream(e){this.assertCanSend(),this.currentState="streaming";try{yield*this.sendMessageStreamInternal(e)}finally{this.currentState==="streaming"&&(this.currentState="idle")}}async*sendMessageStreamInternal(e){this.initPromise&&await this.initPromise;let n=typeof e=="string"?e:this.summarizeContentBlocks(e),r={role:"user",content:n,timestamp:new Date};this.conversationHistory.push(r),this.inputStream.pushUserMessage(e),this.ensureLedger(),this.ledger?.recordUser(n);let o=this.buildTransformDeps();try{for(;;){let s=await this.providerIterator.next();if(s.done)break;let i=s.value,a=Ea(i,o);if(a&&(a.type==="done"?(this.turnCount++,this.sawProviderError=!1):a.type==="error"&&(this.sawProviderError=!0),this.ledger?.recordEvent(a),yield a,a.type==="done"||a.type==="error"))break}}finally{this.currentState==="streaming"&&(this.currentState="idle")}}ensureLedger(){if(this.ledgerInitAttempted||(this.ledgerInitAttempted=!0,this.config.depth!==void 0||this.config.parentSessionId!==void 0)||k.AFK_SESSION_LEDGER_DISABLED==="1")return;let e=this.sessionId;if(!e)return;let n=new gt(e);if(!n.active)return;this.ledger=n;let r=this.getSessionMetadata();n.record({kind:"meta",sessionId:e,model:r.model??String(this.config.model),...r.cwd!==void 0?{cwd:r.cwd}:{}})}sealLedger(e){let n=this.ledger;return n?(this.ledger=null,this.ledgerInitAttempted=!1,n.close(e)):Promise.resolve()}recordLedgerElicitation(e,n){this.ledger?.record({kind:"elicitation",reqId:e,request:n})}summarizeContentBlocks(e){let n=[],r=0;for(let s of e)s.type==="text"?n.push(s.text):s.type==="image"&&r++;let o=n.join(" ");return r>0&&(o=o?`${o} [+ ${r} image(s)]`:`[+ ${r} image(s)]`),o||"[content block(s)]"}async interrupt(){this.currentState!=="streaming"&&this.currentState!=="processing"||(this.currentState="idle",await this.providerQuery.interrupt())}async reset(){if(this.currentState==="closed")throw new Error("Cannot reset: session is closed");if(this.abortController.signal.aborted)throw new be("Cannot reset: session aborted");if(this.currentState==="processing"||this.currentState==="streaming")try{await this.providerQuery.interrupt()}catch{}await this.dispatchSessionEndOnce("reset"),await this.sealLedger("reset");try{await this.providerQuery.close()}catch{}await this.providerIterator.return?.(),this.initPromise&&await Promise.race([this.initPromise,new Promise(e=>setTimeout(e,Sa))]).catch(()=>{}),this.stateManager.resolveInitializationIfNeeded(),this.config={...this.config},delete this.config.resume,delete this.config.sessionId,delete this.config.resumeHistory,delete this.config.resumeSessionAt,delete this.config.continue,delete this.config.forkSession;try{this.initSdkLifecycle()}catch(e){throw this.currentState="closed",new Error(`Session reset failed during lifecycle rebuild: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}async onAbort(){this.sealLedger("abort");try{await this.providerQuery.interrupt()}catch{}}async setModel(e){let n=ie(e);typeof e=="string"&&e.length>0&&await this.providerQuery.setModel(e),n&&this.stateManager.setSessionMetadata(r=>({...r,model:n}))}async setPermissionMode(e){if(e==="plan"){let n=this.stateManager.getSessionMetadata().permissionMode;n!=="plan"&&(this._prePlanPermissionMode=n==="autonomous"?void 0:n)}await this.providerQuery.setPermissionMode(e),this.stateManager.setSessionMetadata(n=>({...n,permissionMode:e}))}getPrePlanMode(){return this._prePlanPermissionMode}async takePendingPlanExitSeed(){let e=this._pendingPlanExitSeed;if(this._pendingPlanExitSeed=void 0,e!==void 0){try{await this.setPermissionMode(e.mode)}catch(n){U(`\u26A0\uFE0F AgentSession: deferred plan-exit mode flip to '${e.mode}' rejected; dropping implement-seed (staying in plan mode): ${n instanceof Error?n.message:String(n)}`);return}return e.message}}setCwd(e){this.config={...this.config,cwd:e},this.providerQuery.setCwd?.(e),this.config.sessionId!==void 0&&cp(this.config.sessionId,e)}async reauth(){return await this.providerQuery.reauth?.()??null}waitForInitialization(){return this.stateManager.waitForInitialization()}getSessionIdentity(){return this.stateManager.getSessionIdentity()}getSessionMetadata(){return this.stateManager.getSessionMetadata()}getQuery(){return this.providerQuery}supportedCommands(){return this.providerQuery.supportedCommands()}supportedModels(){return this.providerQuery.supportedModels()}supportedAgents(){return this.providerQuery.supportedAgents()}getContextUsage(){return this.providerQuery.getContextUsage()}mcpServerStatus(){return this.providerQuery.mcpServerStatus()}accountInfo(){return this.providerQuery.accountInfo()}rewindFiles(e,n){return this.providerQuery.rewindFiles(e,n)}async compact(){if(this.currentState==="closed")throw new Error("Cannot compact: session is closed");if(this.currentState!=="idle")return{compacted:!1,reason:"session-busy",messagesBefore:0,messagesAfter:0};let e=this.providerQuery.compact?.bind(this.providerQuery);if(!e)return{compacted:!1,reason:"not-supported",messagesBefore:0,messagesAfter:0};this.currentState="compacting";try{return await e()}finally{this.currentState="idle"}}getLastResponseMetadata(){return this.lastResponseMetadata}getOutputStream(){throw new Error("getOutputStream() is not supported \u2014 use sendMessageStream() instead")}getInputStreamRef(){return{pushUserMessage:e=>this.inputStream.pushUserMessage(e)}}getHistory(){return[...this.conversationHistory]}getTurnCount(){return this.turnCount}async close(){if(this.currentState!=="closed"){this.currentState="closed",await this.sealLedger("close"),this.abortController.signal.aborted||this.abortController.abort("closed"),this.stateManager.resolveInitializationIfNeeded();try{await this.providerQuery.close()}catch{}if(await this.providerIterator.return?.(),this.initPromise)try{await Promise.race([this.initPromise,new Promise(e=>setTimeout(e,Sa))])}catch{}await this.dispatchSessionEndOnce("close")}}async dispatchSessionEndOnce(e){this.sessionEndDispatched||(this.sessionEndDispatched=!0,await this.emitClosure(e).catch(()=>{}),await this.sealTraceWriter(e).catch(()=>{}),await Ju(this._hookRegistry,{event:"SessionEnd",sessionId:this.sessionId,reason:e,parentSessionId:this.config.parentSessionId,...this.config.traceWriter?{tracePath:this.config.traceWriter.getTracePath()}:{}},this.config.traceWriter?{traceWriter:this.config.traceWriter}:{}))}async emitClosure(e){let n=this.config.traceWriter;if(!n)return;let r=this.deriveClosureReason(e),o={};this.sessionRunningTokens.input>0&&(o.input=this.sessionRunningTokens.input),this.sessionRunningTokens.output>0&&(o.output=this.sessionRunningTokens.output),this.sessionRunningTokens.cacheRead>0&&(o.cacheRead=this.sessionRunningTokens.cacheRead),this.sessionRunningTokens.cacheCreation>0&&(o.cacheCreation=this.sessionRunningTokens.cacheCreation);let s=Zu(r);await Wu(n,{reason:r,finalTurnCount:this.turnCount,finalCostUsd:this.sessionRunningCostUsd,finalTokens:o,...this.lastStopReason!==void 0?{lastStopReason:this.lastStopReason}:{},...s!==null?{guidance:s}:{}})}deriveClosureReason(e){let n=null,r=this.abortController.signal;if(r.aborted&&r.reason!=="closed"){let o=r.reason;o instanceof Xt?n="budget_exceeded":o instanceof Ne?n="timeout":typeof o=="string"&&o.startsWith("Budget ")?n="budget_exceeded":typeof o=="string"&&o.includes("timed out")?n="timeout":n="abort"}return Xu({dispatchReason:e,maxTurnsHit:this.maxTurnsHit,hookBlocked:this.hookBlocked,abort:n,lastStopReason:this.lastStopReason,sawProviderError:this.sawProviderError})}async sealTraceWriter(e){let n=this.config.traceWriter;if(!n)return;let r=this.deriveSealStatus(e),o=this.subagentCompletedCount>0?this.subagentCompletedCount:void 0,s=this.subagentRunningTokens,a=s.input>0||s.output>0||s.cacheRead>0||s.cacheCreation>0?{...s.input>0?{input:s.input}:{},...s.output>0?{output:s.output}:{},...s.cacheRead>0?{cacheRead:s.cacheRead}:{},...s.cacheCreation>0?{cacheCreation:s.cacheCreation}:{}}:void 0,c=this.subagentRunningCostUsd>0?this.subagentRunningCostUsd:void 0;await n.seal({status:r,finalCostUsd:this.sessionRunningCostUsd,finalTurnCount:this.turnCount,closedAt:new Date().toISOString(),...o!==void 0?{subagentCount:o}:{},...a!==void 0?{subagentTokens:a}:{},...c!==void 0?{subagentCostUsd:c}:{}})}recordSubagentCompletion(e,n){if(this.subagentCompletedCount++,e){let r=(o,s)=>{typeof o=="number"&&Number.isFinite(o)&&o>0&&(this.subagentRunningTokens[s]+=o)};r(e.inputTokens,"input"),r(e.outputTokens,"output"),r(e.cacheReadTokens,"cacheRead"),r(e.cacheCreationTokens,"cacheCreation")}typeof n=="number"&&Number.isFinite(n)&&n>0&&(this.subagentRunningCostUsd+=n)}deriveSealStatus(e){if(e==="error")return"failed";let n=this.abortController.signal;return n.aborted&&n.reason!=="closed"?"cancelled":this.sawProviderError?"failed":"succeeded"}assertCanSend(){if(this.currentState==="closed")throw new Error("Cannot send message: session is closed");if(this.abortController.signal.aborted)throw new be("Cannot send message: session aborted");if(this.currentState==="processing"||this.currentState==="streaming"||this.currentState==="compacting")throw new Error("Cannot send message: session is busy");if(this.config.maxTurns&&this.turnCount>=this.config.maxTurns)throw this.maxTurnsHit=!0,new Error(`Maximum turns (${this.config.maxTurns}) exceeded`)}}});var Aa=y(()=>{"use strict";_p()});function jk(t,e,n){return new Promise((r,o)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,o(new Ft(n,e)))},e);i.unref(),Promise.resolve(t).then(a=>{s||(s=!0,clearTimeout(i),r(a))},a=>{s||(s=!0,clearTimeout(i),o(a))})})}function Hk(t){return t.continue===!1||t.decision==="block"}function Ta(t,e){if(t?.aborted){let n=t.reason,r=`aborted during ${e}${n?`: ${String(n)}`:""}`;throw new be(r)}}function Ap(){return new xa}var Lt,Ft,xa,jo=y(()=>{"use strict";me();Lt=3e4;Ft=class extends Error{constructor(n,r){super(`hook handler timed out after ${r}ms during ${n}`);this.hookEvent=n;this.timeoutMs=r;this.name="HookHandlerTimeoutError"}hookEvent;timeoutMs;code="HOOK_HANDLER_TIMEOUT"},xa=class{handlers=new Map;register(e,n,r={}){let o=this.handlers.get(e);o||(o=[],this.handlers.set(e,o));let s={handler:n,options:r};return o.push(s),()=>{let i=this.handlers.get(e);if(!i)return;let a=i.indexOf(s);a>=0&&i.splice(a,1)}}count(e){return this.handlers.get(e)?.length??0}async dispatch(e,n,r=Lt){Ta(n,e.event);let o=this.handlers.get(e.event);if(!o||o.length===0)return{};let s=o.slice(),i={};for(let a of s){Ta(n,e.event);let c;try{let l=a.handler(e,n);c=!a.options.longRunning&&r>0&&Number.isFinite(r)?await jk(l,r,e.event):await l}catch(l){throw l instanceof Ft?l:new Y(`hook handler threw during ${e.event}`,e.event,l instanceof Error?l.message:String(l),{cause:l})}if(Ta(n,e.event),Hk(c))throw new Y(`hook handler blocked ${e.event}${c.reason?`: ${c.reason}`:""}`,e.event,c.reason);i=c}return i}}});async function je(t,e,n,r){if(!t)return;if(r.kind==="blocked"){await Ie(t,{hookEvent:e,decision:"block",...r.err.reason!==void 0?{reason:r.err.reason}:{},...e==="PreToolUse"&&n.toolName!==void 0?{blockedTool:n.toolName}:{}});return}let o=r.decision;await Ie(t,{hookEvent:e,decision:o.decision,...o.reason!==void 0?{reason:o.reason}:{},...o.injectContext!==void 0?{injectedContextBytes:Buffer.byteLength(o.injectContext,"utf8")}:{}})}async function Tp(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);await je(n.traceWriter,"SubagentStart",{},{kind:"decision",decision:r})}catch(r){throw r instanceof Y&&await je(n.traceWriter,"SubagentStart",{},{kind:"blocked",err:r}),r}}function Kk(t,e,n){return new Promise((r,o)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,o(new Ft(n,e)))},e);i.unref(),t.then(a=>{s||(s=!0,clearTimeout(i),r(a))},a=>{s||(s=!0,clearTimeout(i),o(a))})})}async function xp(t,e,n={}){if(!t)return{};try{let r=await Kk(t.dispatch(e,n.signal,Lt),Lt,"SubagentStop");return await je(n.traceWriter,"SubagentStop",{},{kind:"decision",decision:r}),r}catch(r){return r instanceof Ft?(console.warn(`[afk] SubagentStop hook timed out after ${Lt}ms (subagentId=${e.subagentId}): ${r.message}`),n.onError?.(r),{}):(r instanceof Y&&await je(n.traceWriter,"SubagentStop",{},{kind:"blocked",err:r}),r instanceof Y||r instanceof be?(U(`SubagentStop hook swallowed ${r.name}: ${r.message}`),n.onError?.(r),{}):(U(`SubagentStop hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r))),{}))}}async function Ra(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);await je(n.traceWriter,"PreToolUse",{toolName:e.toolName},{kind:"decision",decision:r})}catch(r){throw r instanceof Y&&await je(n.traceWriter,"PreToolUse",{toolName:e.toolName},{kind:"blocked",err:r}),r}}async function Rp(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);await je(n.traceWriter,"PostToolUse",{toolName:e.toolName},{kind:"decision",decision:r})}catch(r){if(r instanceof Y&&await je(n.traceWriter,"PostToolUse",{toolName:e.toolName},{kind:"blocked",err:r}),r instanceof Y||r instanceof be){U(`PostToolUse hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}U(`PostToolUse hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}async function Pp(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);await je(n.traceWriter,"PostToolUseFailure",{toolName:e.toolName},{kind:"decision",decision:r})}catch(r){if(r instanceof Y&&await je(n.traceWriter,"PostToolUseFailure",{toolName:e.toolName},{kind:"blocked",err:r}),r instanceof Y||r instanceof be){U(`PostToolUseFailure hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}U(`PostToolUseFailure hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}var Ho=y(()=>{"use strict";le();me();jo();ee()});import{mkdir as Wk,writeFile as Gk}from"fs/promises";import{dirname as qk,join as zk}from"path";function Vk(){return zk(Ve(),"routing-decisions.jsonl")}function Jk(t){let e={surface:"afk"};for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}async function te(t){if(!(k.VITEST||k.NODE_ENV==="test"))try{let e=Vk();await Wk(qk(e),{recursive:!0});let n=new Date().toISOString().split(".")[0]+"Z",r=JSON.stringify({ts:n,...Jk(t)})+`
1016
+ Respond again with ONLY a JSON object (optionally in a \`\`\`json fence) that satisfies the schema.`+a,u=await this.sendMessage(d,i),p=Fo(u.content),f=n.safeParse(p);if(f.success)return f.data;c=f.error.message}throw new Error(`structured output did not match schema after ${o+1} attempt(s): ${c}`)}async*sendMessageStream(e){this.assertCanSend(),this.currentState="streaming";try{yield*this.sendMessageStreamInternal(e)}finally{this.currentState==="streaming"&&(this.currentState="idle")}}async*sendMessageStreamInternal(e){this.initPromise&&await this.initPromise;let n=typeof e=="string"?e:this.summarizeContentBlocks(e),r={role:"user",content:n,timestamp:new Date};this.conversationHistory.push(r),this.inputStream.pushUserMessage(e),this.ensureLedger(),this.ledger?.recordUser(n);let o=this.buildTransformDeps();try{for(;;){let s=await this.providerIterator.next();if(s.done)break;let i=s.value,a=Ea(i,o);if(a&&(a.type==="done"?(this.turnCount++,this.sawProviderError=!1):a.type==="error"&&(this.sawProviderError=!0),this.ledger?.recordEvent(a),yield a,a.type==="done"||a.type==="error"))break}}finally{this.currentState==="streaming"&&(this.currentState="idle")}}ensureLedger(){if(this.ledgerInitAttempted||(this.ledgerInitAttempted=!0,this.config.depth!==void 0||this.config.parentSessionId!==void 0)||k.AFK_SESSION_LEDGER_DISABLED==="1")return;let e=this.sessionId;if(!e)return;let n=new gt(e);if(!n.active)return;this.ledger=n;let r=this.getSessionMetadata();n.record({kind:"meta",sessionId:e,model:r.model??String(this.config.model),...r.cwd!==void 0?{cwd:r.cwd}:{}})}sealLedger(e){let n=this.ledger;return n?(this.ledger=null,this.ledgerInitAttempted=!1,n.close(e)):Promise.resolve()}recordLedgerElicitation(e,n){this.ledger?.record({kind:"elicitation",reqId:e,request:n})}summarizeContentBlocks(e){let n=[],r=0;for(let s of e)s.type==="text"?n.push(s.text):s.type==="image"&&r++;let o=n.join(" ");return r>0&&(o=o?`${o} [+ ${r} image(s)]`:`[+ ${r} image(s)]`),o||"[content block(s)]"}async interrupt(){this.currentState!=="streaming"&&this.currentState!=="processing"||(this.currentState="idle",await this.providerQuery.interrupt())}async reset(){if(this.currentState==="closed")throw new Error("Cannot reset: session is closed");if(this.abortController.signal.aborted)throw new be("Cannot reset: session aborted");if(this.currentState==="processing"||this.currentState==="streaming")try{await this.providerQuery.interrupt()}catch{}await this.dispatchSessionEndOnce("reset"),await this.sealLedger("reset");try{await this.providerQuery.close()}catch{}await this.providerIterator.return?.(),this.initPromise&&await Promise.race([this.initPromise,new Promise(e=>setTimeout(e,Sa))]).catch(()=>{}),this.stateManager.resolveInitializationIfNeeded(),this.config={...this.config},delete this.config.resume,delete this.config.sessionId,delete this.config.resumeHistory,delete this.config.resumeSessionAt,delete this.config.continue,delete this.config.forkSession;try{this.initSdkLifecycle()}catch(e){throw this.currentState="closed",new Error(`Session reset failed during lifecycle rebuild: ${e instanceof Error?e.message:String(e)}`,{cause:e})}}async onAbort(){this.sealLedger("abort");try{await this.providerQuery.interrupt()}catch{}}async setModel(e){let n=ie(e);typeof e=="string"&&e.length>0&&await this.providerQuery.setModel(e),n&&this.stateManager.setSessionMetadata(r=>({...r,model:n}))}async setPermissionMode(e){if(e==="plan"){let n=this.stateManager.getSessionMetadata().permissionMode;n!=="plan"&&(this._prePlanPermissionMode=n==="autonomous"?void 0:n)}await this.providerQuery.setPermissionMode(e),this.stateManager.setSessionMetadata(n=>({...n,permissionMode:e}))}getPrePlanMode(){return this._prePlanPermissionMode}async takePendingPlanExitSeed(){let e=this._pendingPlanExitSeed;if(this._pendingPlanExitSeed=void 0,e!==void 0){try{await this.setPermissionMode(e.mode)}catch(n){U(`\u26A0\uFE0F AgentSession: deferred plan-exit mode flip to '${e.mode}' rejected; dropping implement-seed (staying in plan mode): ${n instanceof Error?n.message:String(n)}`);return}return e.message}}setCwd(e){this.config={...this.config,cwd:e},this.providerQuery.setCwd?.(e),this.config.sessionId!==void 0&&cp(this.config.sessionId,e)}async reauth(){return await this.providerQuery.reauth?.()??null}waitForInitialization(){return this.stateManager.waitForInitialization()}getSessionIdentity(){return this.stateManager.getSessionIdentity()}getSessionMetadata(){return this.stateManager.getSessionMetadata()}getQuery(){return this.providerQuery}supportedCommands(){return this.providerQuery.supportedCommands()}supportedModels(){return this.providerQuery.supportedModels()}supportedAgents(){return this.providerQuery.supportedAgents()}getContextUsage(){return this.providerQuery.getContextUsage()}mcpServerStatus(){return this.providerQuery.mcpServerStatus()}accountInfo(){return this.providerQuery.accountInfo()}rewindFiles(e,n){return this.providerQuery.rewindFiles(e,n)}async compact(){if(this.currentState==="closed")throw new Error("Cannot compact: session is closed");if(this.currentState!=="idle")return{compacted:!1,reason:"session-busy",messagesBefore:0,messagesAfter:0};let e=this.providerQuery.compact?.bind(this.providerQuery);if(!e)return{compacted:!1,reason:"not-supported",messagesBefore:0,messagesAfter:0};this.currentState="compacting";try{return await e()}finally{this.currentState="idle"}}getLastResponseMetadata(){return this.lastResponseMetadata}getOutputStream(){throw new Error("getOutputStream() is not supported \u2014 use sendMessageStream() instead")}getInputStreamRef(){return{pushUserMessage:e=>this.inputStream.pushUserMessage(e)}}getHistory(){return[...this.conversationHistory]}getTurnCount(){return this.turnCount}async close(){if(this.currentState!=="closed"){this.currentState="closed",await this.sealLedger("close"),this.abortController.signal.aborted||this.abortController.abort("closed"),this.stateManager.resolveInitializationIfNeeded();try{await this.providerQuery.close()}catch{}if(await this.providerIterator.return?.(),this.initPromise)try{await Promise.race([this.initPromise,new Promise(e=>setTimeout(e,Sa))])}catch{}await this.dispatchSessionEndOnce("close")}}async dispatchSessionEndOnce(e){this.sessionEndDispatched||(this.sessionEndDispatched=!0,await this.emitClosure(e).catch(()=>{}),await this.sealTraceWriter(e).catch(()=>{}),await Ju(this._hookRegistry,{event:"SessionEnd",sessionId:this.sessionId,reason:e,parentSessionId:this.config.parentSessionId,...this.config.traceWriter?{tracePath:this.config.traceWriter.getTracePath()}:{}},this.config.traceWriter?{traceWriter:this.config.traceWriter}:{}))}async emitClosure(e){let n=this.config.traceWriter;if(!n)return;let r=this.deriveClosureReason(e),o={};this.sessionRunningTokens.input>0&&(o.input=this.sessionRunningTokens.input),this.sessionRunningTokens.output>0&&(o.output=this.sessionRunningTokens.output),this.sessionRunningTokens.cacheRead>0&&(o.cacheRead=this.sessionRunningTokens.cacheRead),this.sessionRunningTokens.cacheCreation>0&&(o.cacheCreation=this.sessionRunningTokens.cacheCreation);let s=Zu(r);await Wu(n,{reason:r,finalTurnCount:this.turnCount,finalCostUsd:this.sessionRunningCostUsd,finalTokens:o,...this.lastStopReason!==void 0?{lastStopReason:this.lastStopReason}:{},...s!==null?{guidance:s}:{}})}deriveClosureReason(e){let n=null,r=this.abortController.signal;if(r.aborted&&r.reason!=="closed"){let o=r.reason;o instanceof Xt?n="budget_exceeded":o instanceof Ne?n="timeout":typeof o=="string"&&o.startsWith("Budget ")?n="budget_exceeded":typeof o=="string"&&o.includes("timed out")?n="timeout":n="abort"}return Xu({dispatchReason:e,maxTurnsHit:this.maxTurnsHit,hookBlocked:this.hookBlocked,abort:n,lastStopReason:this.lastStopReason,sawProviderError:this.sawProviderError})}async sealTraceWriter(e){let n=this.config.traceWriter;if(!n)return;let r=this.deriveSealStatus(e),o=this.subagentCompletedCount>0?this.subagentCompletedCount:void 0,s=this.subagentRunningTokens,a=s.input>0||s.output>0||s.cacheRead>0||s.cacheCreation>0?{...s.input>0?{input:s.input}:{},...s.output>0?{output:s.output}:{},...s.cacheRead>0?{cacheRead:s.cacheRead}:{},...s.cacheCreation>0?{cacheCreation:s.cacheCreation}:{}}:void 0,c=this.subagentRunningCostUsd>0?this.subagentRunningCostUsd:void 0;await n.seal({status:r,finalCostUsd:this.sessionRunningCostUsd,finalTurnCount:this.turnCount,closedAt:new Date().toISOString(),...o!==void 0?{subagentCount:o}:{},...a!==void 0?{subagentTokens:a}:{},...c!==void 0?{subagentCostUsd:c}:{}})}recordSubagentCompletion(e,n){if(this.subagentCompletedCount++,e){let r=(o,s)=>{typeof o=="number"&&Number.isFinite(o)&&o>0&&(this.subagentRunningTokens[s]+=o)};r(e.inputTokens,"input"),r(e.outputTokens,"output"),r(e.cacheReadTokens,"cacheRead"),r(e.cacheCreationTokens,"cacheCreation")}typeof n=="number"&&Number.isFinite(n)&&n>0&&(this.subagentRunningCostUsd+=n)}deriveSealStatus(e){if(e==="error")return"failed";let n=this.abortController.signal;return n.aborted&&n.reason!=="closed"?"cancelled":this.sawProviderError?"failed":"succeeded"}assertCanSend(){if(this.currentState==="closed")throw new Error("Cannot send message: session is closed");if(this.abortController.signal.aborted)throw new be("Cannot send message: session aborted");if(this.currentState==="processing"||this.currentState==="streaming"||this.currentState==="compacting")throw new Error("Cannot send message: session is busy");if(this.config.maxTurns&&this.turnCount>=this.config.maxTurns)throw this.maxTurnsHit=!0,new Error(`Maximum turns (${this.config.maxTurns}) exceeded`)}}});var Aa=y(()=>{"use strict";_p()});function jk(t,e,n){return new Promise((r,o)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,o(new Ft(n,e)))},e);i.unref(),Promise.resolve(t).then(a=>{s||(s=!0,clearTimeout(i),r(a))},a=>{s||(s=!0,clearTimeout(i),o(a))})})}function Hk(t){return t.continue===!1||t.decision==="block"}function Ta(t,e){if(t?.aborted){let n=t.reason,r=`aborted during ${e}${n?`: ${String(n)}`:""}`;throw new be(r)}}function Ap(){return new xa}var Lt,Ft,xa,jo=y(()=>{"use strict";me();Lt=3e4;Ft=class extends Error{constructor(n,r){super(`hook handler timed out after ${r}ms during ${n}`);this.hookEvent=n;this.timeoutMs=r;this.name="HookHandlerTimeoutError"}hookEvent;timeoutMs;code="HOOK_HANDLER_TIMEOUT"},xa=class{handlers=new Map;register(e,n,r={}){let o=this.handlers.get(e);o||(o=[],this.handlers.set(e,o));let s={handler:n,options:r};return o.push(s),()=>{let i=this.handlers.get(e);if(!i)return;let a=i.indexOf(s);a>=0&&i.splice(a,1)}}count(e){return this.handlers.get(e)?.length??0}async dispatch(e,n,r=Lt){Ta(n,e.event);let o=this.handlers.get(e.event);if(!o||o.length===0)return{};let s=o.slice(),i={};for(let a of s){Ta(n,e.event);let c;try{let d=a.handler(e,n);c=!a.options.longRunning&&r>0&&Number.isFinite(r)?await jk(d,r,e.event):await d}catch(d){throw d instanceof Ft?d:new Y(`hook handler threw during ${e.event}`,e.event,d instanceof Error?d.message:String(d),{cause:d})}if(Ta(n,e.event),Hk(c))throw new Y(`hook handler blocked ${e.event}${c.reason?`: ${c.reason}`:""}`,e.event,c.reason);let l=[i.injectContext,c.injectContext].filter(d=>typeof d=="string"&&d.length>0).join(`
1017
+ `);i={...i,...c,...l.length>0?{injectContext:l}:{}}}return i}}});async function je(t,e,n,r){if(!t)return;if(r.kind==="blocked"){await Ie(t,{hookEvent:e,decision:"block",...r.err.reason!==void 0?{reason:r.err.reason}:{},...e==="PreToolUse"&&n.toolName!==void 0?{blockedTool:n.toolName}:{}});return}let o=r.decision;await Ie(t,{hookEvent:e,decision:o.decision,...o.reason!==void 0?{reason:o.reason}:{},...o.injectContext!==void 0?{injectedContextBytes:Buffer.byteLength(o.injectContext,"utf8")}:{}})}async function Tp(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);await je(n.traceWriter,"SubagentStart",{},{kind:"decision",decision:r})}catch(r){throw r instanceof Y&&await je(n.traceWriter,"SubagentStart",{},{kind:"blocked",err:r}),r}}function Kk(t,e,n){return new Promise((r,o)=>{let s=!1,i=setTimeout(()=>{s||(s=!0,o(new Ft(n,e)))},e);i.unref(),t.then(a=>{s||(s=!0,clearTimeout(i),r(a))},a=>{s||(s=!0,clearTimeout(i),o(a))})})}async function xp(t,e,n={}){if(!t)return{};try{let r=await Kk(t.dispatch(e,n.signal,Lt),Lt,"SubagentStop");return await je(n.traceWriter,"SubagentStop",{},{kind:"decision",decision:r}),r}catch(r){return r instanceof Ft?(console.warn(`[afk] SubagentStop hook timed out after ${Lt}ms (subagentId=${e.subagentId}): ${r.message}`),n.onError?.(r),{}):(r instanceof Y&&await je(n.traceWriter,"SubagentStop",{},{kind:"blocked",err:r}),r instanceof Y||r instanceof be?(U(`SubagentStop hook swallowed ${r.name}: ${r.message}`),n.onError?.(r),{}):(U(`SubagentStop hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r))),{}))}}async function Ra(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);await je(n.traceWriter,"PreToolUse",{toolName:e.toolName},{kind:"decision",decision:r})}catch(r){throw r instanceof Y&&await je(n.traceWriter,"PreToolUse",{toolName:e.toolName},{kind:"blocked",err:r}),r}}async function Rp(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);await je(n.traceWriter,"PostToolUse",{toolName:e.toolName},{kind:"decision",decision:r})}catch(r){if(r instanceof Y&&await je(n.traceWriter,"PostToolUse",{toolName:e.toolName},{kind:"blocked",err:r}),r instanceof Y||r instanceof be){U(`PostToolUse hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}U(`PostToolUse hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}async function Pp(t,e,n={}){if(t)try{let r=await t.dispatch(e,n.signal);await je(n.traceWriter,"PostToolUseFailure",{toolName:e.toolName},{kind:"decision",decision:r})}catch(r){if(r instanceof Y&&await je(n.traceWriter,"PostToolUseFailure",{toolName:e.toolName},{kind:"blocked",err:r}),r instanceof Y||r instanceof be){U(`PostToolUseFailure hook swallowed ${r.name}: ${r.message}`),n.onError?.(r);return}U(`PostToolUseFailure hook unexpected error: ${String(r)}`),n.onError?.(r instanceof Error?r:new Error(String(r)))}}var Ho=y(()=>{"use strict";le();me();jo();ee()});import{mkdir as Wk,writeFile as Gk}from"fs/promises";import{dirname as qk,join as zk}from"path";function Vk(){return zk(Ve(),"routing-decisions.jsonl")}function Jk(t){let e={surface:"afk"};for(let[n,r]of Object.entries(t))r!==void 0&&(e[n]=r);return e}async function te(t){if(!(k.VITEST||k.NODE_ENV==="test"))try{let e=Vk();await Wk(qk(e),{recursive:!0});let n=new Date().toISOString().split(".")[0]+"Z",r=JSON.stringify({ts:n,...Jk(t)})+`
1017
1018
  `;await Gk(e,r,{flag:"a"})}catch{}}var tt=y(()=>{"use strict";j();W()});import{AsyncLocalStorage as Yk}from"node:async_hooks";function Cp(t,e){return Ip.run(t,e)}function Ae(){return Ip.getStore()}var Ip,Nt=y(()=>{"use strict";Ip=new Yk});function Mp(){return Ap()}function Ko(t,e){return t??e}var Wo=y(()=>{"use strict";jo()});function Pa(t,e){return e?.allowedTools?e.allowedTools.includes(t)?{allowed:!0}:{allowed:!1,reason:`Tool "${t}" is not in the configured allowlist`}:{allowed:!0}}function Go(t,e){return Op(t,e)}function qo(t,e){return Op(t,e)}function Op(t,e){if(!t?.allowedTools||e.length===0)return t;let n=new Set(t.allowedTools),r=!1;for(let o of e)n.has(o)||(n.add(o),r=!0);return r?{...t,allowedTools:[...n]}:t}var zo=y(()=>{"use strict"});function O_(t){return t.replace(/'[^']*'/g," ").replace(/"(?:[^"\\]|\\.)*"/g,e=>/\$\(|`/.test(e)?e:" ")}function Jo(t){if(typeof t!="string"||t.trim().length===0)return{mutating:!1};let e=t.replace(r_," ");for(let s of C_)if(s.re.test(e))return{mutating:!0,reason:s.reason};let n=t.match(k_)?.[1];if(n&&__.test(n))return{mutating:!0,reason:"interpreter one-liner file write (`-c`/`-e`)"};let r=O_(t);for(let s of M_)if(s.re.test(r))return{mutating:!0,reason:s.reason};let o=r.replace(P_," ").replace(R_," ").replace(/&(>>?)/g,"$1");return I_.test(o)?{mutating:!0,reason:"output redirection to a file (`>`/`>>`)"}:{mutating:!1}}var Xk,Qk,Zk,e_,t_,n_,r_,o_,s_,i_,a_,c_,l_,d_,u_,p_,f_,Vo,m_,g_,h_,y_,b_,w_,S_,v_,k_,__,E_,A_,T_,x_,R_,P_,I_,C_,M_,Ia=y(()=>{"use strict";Xk=/\bgit\b[^|;&]*\s(commit|push|pull|merge|rebase|reset|checkout|switch|restore|cherry-pick|revert|am|apply|clean|add|rm|mv|init)\b/i,Qk=/\bgit\b[^|;&]*\s+tag\s+-/i,Zk=/\bgit\b[^|;&]*\s+branch\s+-[dDmM]\b/i,e_=/\bgit\b[^|;&]*\s+remote\s+(add|remove|rm|set-url|rename)\b/i,t_=/\bgit\b[^|;&]*\s+worktree\s+(remove|prune|move|lock|unlock)\b/i,n_=/\bgit\b[^|;&]*\s+stash\b(?!\s+(list|show)\b)/i,r_=/\bstash@\{[^}]*\}/gi,o_=/\bgit\s+config\b[^|;&]*\s(--add|--unset|--unset-all|--replace-all|--rename-section|--remove-section|--edit|-e)\b/i,s_=/\bgit\s+config\s+(?:--(?:global|system|local|worktree)\s+|(?:--file|-f)\s+\S+\s+)*[\w][\w.-]*\s+\S/i,i_=/\bgh\s+\w[\w-]*\s+(create|merge|close|edit|delete|comment|review|reopen|sync|fork|clone|ready)\b/i,a_=/\bgh\s+api\b.*(-X|--method)\s+(POST|PUT|PATCH|DELETE)\b/i,c_=/\bgh\s+api\b.*(\s-f\b|\s-F\b|--field\b)/i,l_=/\bgh\s+(secret|variable|workflow|release|run|cache|ssh-key|gpg-key)\s+(set|run|rerun|cancel|upload|delete|enable|disable)\b/i,d_=/\|\s*(sh|bash|zsh|dash)\b/i,u_=/\b(rm|rmdir|unlink|mv|cp|mkdir|touch|dd|truncate|tee|sponge|ln|chmod|chown|chgrp|shred|rsync)\b/i,p_=/\bfind\b[^|;&]*\s-delete\b/i,f_=/\bfind\b[^|;&]*\s-exec\s+['"]?\s*(rm|rmdir|unlink|mv|cp|dd|truncate|shred|tee|chmod|chown|chgrp|install|patch)\b/i,Vo=String.raw`(?:^|[\n;|&(]|\$\()\s*`,m_=new RegExp(Vo+String.raw`patch\b`,"i"),g_=new RegExp(Vo+String.raw`install\b`,"i"),h_=new RegExp(Vo+String.raw`(?:source\b|\.\s+\S)`,"i"),y_=/\btar\s+-?[a-zA-Z]*[cxruA][a-zA-Z]*\b/i,b_=new RegExp(Vo+String.raw`unzip\b`,"i"),w_=/\bcpio\b[^|;&]*\s-[a-zA-Z]*i\b/i,S_=/\bsed\b[^|;&]*\s-[a-zA-Z]*i\b/i,v_=/\bperl\b[^|;&]*\s-[a-zA-Z]*i\b/i,k_=/\b(?:python3?|nodejs|node|bun|ruby|perl|php)\b[^|;&]*?\s-(?:c|e)\b\s*("(?:[^"\\]|\\.)*"|'[^']*'|`[^`]*`)/i,__=/open\s*\([^)]*,\s*['"][wax]|writeFileSync|writeFile\b|appendFileSync|appendFile\b|createWriteStream|File\.(?:write|delete)\b|IO\.write\b|FileUtils\.|\bBun\.write\b|os\.remove\b|shutil\.\w|\.write_text\b|\.write_bytes\b/i,E_=/\b(npm|pnpm|yarn|pip|pip3|brew|cargo|go|apt|apt-get|gem|poetry|bundle|composer)\s+(install|add|remove|uninstall|i|ci|up|update|upgrade|dlx|get|require)\b/i,A_=/\b(curl|wget)\b[^|;&]*\s(-o\b|-O\b|--output\b)/i,T_=/\bcurl\b[^|;&]*\s-X\s+(POST|PUT|PATCH|DELETE)\b/i,x_=/\bcurl\b[^|;&]*\s(-d\b|--data\b|-F\b|--form\b)/i,R_=/(\d*&?>>?\s*\/dev\/null|\d*>&\d+|&>\s*\/dev\/null|&>>\s*\/dev\/null)/gi,P_=/\$\(\(.*?\)\)/g,I_=/(?<![=<>-])>>?(?!&)/,C_=[{re:Xk,reason:"git repository mutation"},{re:Qk,reason:"git tag create/delete"},{re:Zk,reason:"git branch delete/rename"},{re:e_,reason:"git remote mutation"},{re:n_,reason:"git stash mutation (only `stash list`/`stash show` allowed)"},{re:o_,reason:"git config write flag (only reads allowed)"},{re:s_,reason:"git config set (`<key> <value>`; only reads allowed)"},{re:i_,reason:"gh write operation"},{re:a_,reason:"gh api write method (POST/PUT/PATCH/DELETE)"},{re:c_,reason:"gh api field payload (-f/-F/--field)"},{re:l_,reason:"gh extended write operation (secret/variable/workflow/run/cache)"},{re:t_,reason:"git worktree mutation (remove/prune/move)"},{re:S_,reason:"sed in-place edit (-i)"},{re:v_,reason:"perl in-place edit (-i)"},{re:E_,reason:"package install/modify"},{re:A_,reason:"curl/wget output-to-file"},{re:T_,reason:"curl write method (POST/PUT/PATCH/DELETE)"},{re:x_,reason:"curl data/form payload"},{re:f_,reason:"find -exec with mutating verb"}],M_=[{re:d_,reason:"pipe-to-shell (RCE via piped interpreter)"},{re:u_,reason:"filesystem mutation"},{re:p_,reason:"find -delete (file removal)"},{re:m_,reason:"patch (applies a diff to files)"},{re:g_,reason:"install (writes files)"},{re:h_,reason:"source/dot-source executes a script"},{re:y_,reason:"tar create/extract/append/update (writes files/archive)"},{re:b_,reason:"unzip (writes files)"},{re:w_,reason:"cpio extract (-i mode writes files)"}]});var D_,F_,L_,N_,$_,U_,B_,j_,H_,$t,Ut,Bt,K_,W_,G_,q_,z_,V_,J_,Y_,X_,Q_,Z_,eE,tE,nt,jt,IN,ht=y(()=>{"use strict";D_={name:"bash",category:"shell",concurrencySafe:!1,description:"Execute a shell command and return its stdout and stderr. Use for running programs, installing packages, git operations, and any task that requires a shell. Commands run in the user's default shell. Long-running commands should use timeout_ms. Output is capped at ~100KB; excess is truncated with a notice.",input_schema:{type:"object",properties:{command:{type:"string",description:"The shell command to execute."},timeout_ms:{type:"number",description:"Optional timeout in milliseconds (default 120000, max 600000). The command is killed if it exceeds this duration."}},required:["command"]}},F_={name:"read_file",category:"read",concurrencySafe:!0,description:"Read a file from the filesystem. Returns the file content with line numbers. Use offset and limit to read specific sections of large files. When the read returns a partial view, the response ends with a `... (showing lines X-Y of Z [\u2014 pass offset=N to continue])` annotation indicating the full file size and how to continue. Binary files are detected and rejected. Missing files return an error.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to read."},offset:{type:"number",description:"Line number to start reading from (1-based). Defaults to 1."},limit:{type:"number",description:"Maximum number of lines to read. Defaults to 2000."}},required:["file_path"]}},L_={name:"write_file",category:"write",concurrencySafe:!1,description:"Write content to a file, creating it if it does not exist or overwriting if it does. Parent directories are created automatically. Prefer edit_file for modifying existing files \u2014 use write_file only for new files or complete rewrites.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to write."},content:{type:"string",description:"The full content to write to the file."}},required:["file_path","content"]}},N_={name:"edit_file",category:"write",concurrencySafe:!1,description:"Perform an exact string replacement in a file. Finds old_string and replaces it with new_string. The edit fails if old_string is not found or matches multiple locations (unless replace_all is true). Always use read_file first to verify the exact content before editing.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Absolute path to the file to edit."},old_string:{type:"string",description:"The exact string to find and replace. Must match file content exactly."},new_string:{type:"string",description:"The replacement string."},replace_all:{type:"boolean",description:"If true, replace all occurrences. If false (default), fail when multiple matches exist."}},required:["file_path","old_string","new_string"]}},$_={name:"glob",category:"read",concurrencySafe:!0,description:'Find files matching a glob pattern. Returns matching file paths, capped at 500 results. Use for discovering files before reading them. Patterns follow standard glob syntax (e.g., "src/**/*.ts", "*.json").',input_schema:{type:"object",properties:{pattern:{type:"string",description:'Glob pattern to match (e.g., "src/**/*.ts").'},path:{type:"string",description:"Base directory to search from. Defaults to the current working directory."}},required:["pattern"]}},U_={name:"grep",category:"read",concurrencySafe:!0,description:"Search file contents for lines matching a pattern. Returns matches in file:line:content format. Runs `grep -rn` in basic-regex (BRE) mode by default, where `|` is a LITERAL pipe \u2014 not alternation; set extended: true for extended-regex (ERE) alternation. A no-match result on a pattern containing `|` is often a false negative \u2014 re-read the returned hint. Output is capped to prevent overflow. Use for finding symbols, strings, or patterns across the codebase.",input_schema:{type:"object",properties:{pattern:{type:"string",description:"Search pattern. Basic regex (BRE) by default: `|` `+` `?` `(` `)` `{` `}` are LITERAL characters. Set extended: true for extended regex (ERE) where `|` means alternation."},path:{type:"string",description:"Directory or file to search. Defaults to current working directory."},include:{type:"string",description:'File glob to restrict search (e.g., "*.ts"). Passed as --include to grep.'},extended:{type:"boolean",description:"Use extended regex (ERE, `grep -E`) so `|` is alternation and `+ ? ( ) { }` are metacharacters. Default false (BRE \u2014 those characters match literally)."}},required:["pattern"]}},B_={name:"list_directory",category:"read",concurrencySafe:!0,description:"List the contents of a directory. Returns file and subdirectory names with type annotations (directories end with /). Use for exploring project structure.",input_schema:{type:"object",properties:{path:{type:"string",description:"Absolute path to the directory to list."}},required:["path"]}},j_={name:"send_telegram",category:"web",concurrencySafe:!1,riskClass:"caution",description:"Send a Telegram message to the operator. Use to surface terminal-state notifications, blocking questions, or important status updates when the user is away from keyboard (AFK). The message is delivered through the same Telegram bot the operator uses to drive this session. By default the message goes to your primary chat (the first private chat in `AFK_TELEGRAM_ALLOWED_CHAT_IDS`, or `AFK_TELEGRAM_PRIMARY_CHAT_ID` if set); set `telegram.notify` in afk.config.json to broadcast to all allowed chats or target a custom set.\n\nPlain text only \u2014 Telegram's 4096-character limit per message is enforced. Returns an error if Telegram is not configured (missing `TELEGRAM_BOT_TOKEN` or empty allowlist) so the tool is safe to attempt unconditionally.\n\nUse sparingly: this is a real push notification to a human. Reserve for terminal states (Done/Blocked/Asking) and material progress, not running commentary. When running inside the Telegram bot, prefer replying normally \u2014 your response already reaches the operator through the bot. Use this tool only from CLI or daemon sessions.",input_schema:{type:"object",properties:{message:{type:"string",description:"Plain-text message body to send to the operator. Max 4096 characters (Telegram API limit). Must be non-empty."}},required:["message"]}},H_={name:"web_scrape",category:"web",concurrencySafe:!0,description:'Scrape a web page or run a web search and return text content suitable for reasoning over. Three modes:\n\n- `markdown` (default): fetches the URL and extracts the main content as clean markdown (Readability + Turndown). Handles JS-rendered pages: if the plain fetch yields thin content, it escalates to a headless-browser render and re-extracts. Use this for articles, docs, blog posts, and most "I want to read this page" cases. No API key required (the render fallback needs the Playwright chromium binary \u2014 `pnpm exec playwright install chromium`).\n- `raw`: GETs the URL directly with no transformation. Use for JSON APIs, robots.txt, RSS, plain-text endpoints, or when you need the literal bytes. No API key required.\n- `search`: runs a web search and returns ranked markdown results. Use when you need to FIND a URL, not read one. Provide `query` instead of `url`. Requires `EXA_API_KEY` (free tier at https://exa.ai); the handler returns a clear error if it is unset.\n\nOutputs are capped at `max_bytes` UTF-8 bytes (default 1MB, ceiling 10MB) and the request is aborted after `timeout_ms` (default 30000, ceiling 120000).',input_schema:{type:"object",properties:{mode:{type:"string",enum:["markdown","raw","search"],description:'Fetch mode. Defaults to "markdown".'},url:{type:"string",description:"Absolute http(s) URL. Required for markdown and raw modes. Ignored in search mode."},query:{type:"string",description:"Search query string. Required for search mode. Ignored otherwise."},timeout_ms:{type:"number",description:"Request timeout in milliseconds (default 30000, clamped to 120000)."},max_bytes:{type:"number",description:"Maximum UTF-8 bytes returned. Content beyond this is truncated with a marker. Default 1000000, clamped to 10000000."}},required:[]}},$t={name:"agent",category:"subagent",concurrencySafe:!0,description:`Dispatch an independent subagent with its own context window and tool access. Use for tasks that protect the main session's context: codebase exploration, multi-file inspection, repo search, verification, debugging, failing-test investigation, PR review, parallel hypothesis testing, independent re-derivation of a claim, audit work, stale-path detection, feature-wiring checks, and any research-shaped investigation.
1018
1019
 
1019
1020
  Parallelize: dispatch multiple \`agent\` calls in a single tool-use turn to run independent investigations concurrently.
@@ -1052,7 +1053,7 @@ Note: this search ran in basic-regex (BRE) mode, where '|' is a literal pipe \u2
1052
1053
  `)}}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 ns(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 nf(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 rs=y(()=>{"use strict"});var Ga=y(()=>{"use strict";j();W()});var rf=y(()=>{"use strict";j();Ga()});import{execFile as cA}from"node:child_process";import{promisify as lA}from"node:util";function sf(t,e){if(t.length>of)throw new Error(`Invalid branch prefix from ${e}: length ${t.length} exceeds ${of}.`);if(!dA.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 af(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 pU,dA,of,cf=y(()=>{"use strict";j();Ga();rf();pU=lA(cA),dA=/^[A-Za-z0-9_\-./]*$/,of=64});import{existsSync as os,readdirSync as gU,readFileSync as uA,realpathSync as hU,statSync as yU}from"fs";import{homedir as pA}from"os";import{join as St}from"path";function za(t){if(t===null||typeof t!="object"||Array.isArray(t))return;let e={};for(let n of lf){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 fA(){return[dt(),Xr()]}function Xn(t=fA()){for(let e of t)if(os(e))try{let n=JSON.parse(uA(e,"utf-8")),r=za(n.importFrom);if(r!==void 0)return r}catch{}}function Qn(t,e=pA()){let n={pluginRoots:[],skillRoots:[],mcpConfigs:[]};if(!t)return n;for(let r of lf){let o=t[r];if(!o)continue;let s=qa[r];if(o.plugins)for(let i of s.pluginRoots(e))os(i)&&n.pluginRoots.push(i);if(o.skills){let i=`imported:${r}`;for(let a of s.skillRoots(e))os(a)&&n.skillRoots.push({dir:a,origin:i})}if(o.mcp){let i=mA(s.mcpConfigCandidates(e));i&&n.mcpConfigs.push({source:i,format:s.mcpFormat})}}return n}function mA(t){for(let e of t)if(os(e))return e;return null}var lf,qa,vU,ss=y(()=>{"use strict";W();lf=["claude-code","codex"],qa={"claude-code":{label:"Claude Code",pluginRoots:t=>[St(t,".claude","plugins")],skillRoots:t=>[St(t,".claude","skills")],mcpConfigCandidates:t=>[St(t,".claude","mcp.json"),St(t,".claude",".mcp.json"),St(t,".claude","claude-code","mcp.json")],mcpFormat:"json"},codex:{label:"Codex",pluginRoots:t=>[St(t,".codex","plugins")],skillRoots:t=>[St(t,".codex","skills")],mcpConfigCandidates:t=>[St(t,".codex","config.toml")],mcpFormat:"toml"}},vU={"claude-code":qa["claude-code"].label,codex:qa.codex.label}});import{readFileSync as pf,existsSync as Ja}from"fs";import{join as er}from"path";import{config as gA}from"dotenv";function Ya(){return wa()}function yA(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 uf.has(e)||(uf.add(e),console.warn(`[afk] AFK_OPENAI_BASE_URL: stripped trailing "/chat/completions" \u2014 the OpenAI SDK appends it automatically.
1053
1054
  Effective base URL: ${r}`)),r}return e}function bA(){if(Va!==void 0)return Va;if(!df){let o=[er(process.cwd(),".env"),Rt(),Ld()];for(let s of o)Ja(s)&&gA({path:s,override:!1});df=!0}let t={},e=k.AFK_MODEL??k.CLAUDE_MODEL;if(e){let o=e.toLowerCase();t.model=ca(o)?o:e}if(X(e)==="anthropic-direct"){let o=Ya();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=yA(k.AFK_OPENAI_BASE_URL)),Va=t,t}function ff(){if(pn!==void 0)return pn;let t=[er(process.cwd(),"afk.config.json"),dt(),Xr()];for(let e of t)if(Ja(e))try{let n=pf(e,"utf-8"),r=JSON.parse(n),o={},s=Au(r.models);if(typeof r.model=="string"&&r.model.length>0){let i=r.model.toLowerCase();o.model=ca(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!==er(process.cwd(),"afk.config.json")){let i=za(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=sf(r.interactive.worktreeBranchPrefix,`${e}#/interactive/worktreeBranchPrefix`)),typeof r.interactive.worktreeBase=="string"&&r.interactive.worktreeBase.trim().length>0&&(af(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 pn={config:o,sourcePath:e,modelsPartial:s},pn}catch(n){console.error(`Warning: Failed to parse ${e}:`,n)}return pn={config:{},sourcePath:void 0,modelsPartial:{}},pn}function wA(){if(fn!==void 0)return fn.value;let t=[er(process.cwd(),"AFK.md"),er(fe(),"AFK.md")];for(let e of t)if(Ja(e))try{let n=pf(e,"utf-8").trim();if(n.length>0)return fn={value:{content:n,path:e}},fn.value}catch{}return fn={value:null},fn.value}function mf(){return ff().config.telegram??{}}function Xa(t){let e=bA(),{config:n,sourcePath:r,modelsPartial:o}=ff(),s={...Zn,...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=wA();l!==null&&(s.systemPrompt=l.content,i=`afk-md:${l.path}`)}let a={model:s.model??Zn.model,maxTokens:s.maxTokens??Zn.maxTokens,temperature:s.temperature??Zn.temperature,updatePolicy:s.updatePolicy??Zn.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??hA,...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??sa(o);if(ko(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 Zn,hA,df,Va,uf,pn,fn,is=y(()=>{"use strict";Ue();Ye();Ee();W();rn();cf();j();ss();Zn={model:"sonnet",maxTokens:4096,temperature:1,updatePolicy:"notify"},hA="bypassPermissions",df=!1;uf=new Set});function SA(t,e){return e!==void 0&&Number.isFinite(e)&&e!==0?e:t.find(r=>r>0)??t[0]}function vA(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=SA(n,e.primaryChatId);return o!==void 0?[o]:[]}function kA(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 _A(t){if(!t)return;let e=t.trim().toLowerCase();return e==="primary"||e==="broadcast"||e==="custom"?e:void 0}function EA(){let t=mf().notify??{},e=t.mode??_A(k.AFK_TELEGRAM_NOTIFY_MODE),n=t.primaryChatId??kA(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 as(){let t=ns(k.AFK_TELEGRAM_ALLOWED_CHAT_IDS);return vA(t,EA())}var Qa=y(()=>{"use strict";rs();is();j()});var hf={};Ni(hf,{push:()=>mn,pushIfConfigured:()=>Za,pushMarkdown:()=>gf});async function mn(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??AA}/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 gf(t){let e=Pt(t.text),n=ve(e),r={ok:!0,status:200};for(let o of n)if(r=await mn({...t,text:o,parseMode:"HTML"}),!r.ok)return r.status===400&&/can't parse entities/i.test(r.errorMessage??"")?mn({...t}):r;return r}async function Za(t,e={}){let n=k.TELEGRAM_BOT_TOKEN;if(!n)return null;let r=as();if(r.length===0)return null;let o=ve(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 gf(c):await mn({...c,...e.parseMode!==void 0?{parseMode:e.parseMode}:{}}))}return s}var AA,cs=y(()=>{"use strict";Qa();Le();j();AA="https://api.telegram.org"});function TA(t=mn){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>yf)return{content:`Invalid input: message exceeds Telegram's ${yf}-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=as();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 yf,bf,wf=y(()=>{"use strict";j();cs();Qa();yf=4096;bf=TA()});import{JSDOM as xA}from"jsdom";import{Readability as RA}from"@mozilla/readability";import PA from"turndown";function Sf(t){return t.replace(/\n{3,}/g,`
1054
1055
 
1055
- `).trim()}function IA(t){return(t?.textContent??"").replace(/\s+/g," ").trim().length}function kf(t,e){let r=new xA(t,{url:e}).window.document,o=(r.title??"").trim(),s=null;try{let l=r.cloneNode(!0);s=new RA(l).parse()}catch{s=null}if(s&&typeof s.content=="string"&&s.content.trim().length>0){let l=Sf(ec.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=Sf(ec.turndown(a));return{title:o,markdown:c,textLength:IA(i),usedFallback:!0}}var vf,ec,_f=y(()=>{"use strict";vf=200,ec=new PA({headingStyle:"atx",codeBlockStyle:"fenced",bulletListMarker:"-"});ec.remove(["script","style","noscript","iframe"])});function MA(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 Ef(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function OA(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 ls(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??MA,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(!CA.has(u.status)||d===o)return u;let p=OA(u,i)??Ef(d,s,i);U("[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=Ef(d,s,i);U("[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 CA,tc=y(()=>{"use strict";le();CA=new Set([429,502,503,504])});import{readFileSync as DA}from"node:fs";import{join as FA}from"path";function LA(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function Af(t,e){return LA(e).test(t)}function UA(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(NA.has(e))return!0;if($A.has(e))return!1}return!1}function Tf(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function BA(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 xf(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Hi(e),e}function jA(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function HA(t){try{return DA(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function KA(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=xf(e.defaultProfile)),n}function Rf(t){let e=t?.env??k,n=t?.readFileSync??HA,r=t?.surface??e.AGENT_SURFACE,o=UA(e.AFK_BROWSER_HEADLESS,r),s=Tf(e.AFK_BROWSER_ALLOWED_DOMAINS),i=Tf(e.AFK_BROWSER_BLOCKED_DOMAINS),a=jA(e.AFK_BROWSER_DOM_SNAPSHOTS),c=BA(e.AFK_BROWSER_BACKEND),l=xf(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():FA(Je(),"browser.json"),f=n(p);if(f===void 0)return d;let h;try{h=JSON.parse(f)}catch(S){throw new Error(`Failed to parse browser config at ${p}: ${String(S)}`)}if(typeof h!="object"||h===null||Array.isArray(h))throw new Error(`Browser config at ${p} must be a JSON object`);let g=KA(d,h);return g.configPath=p,g}function nc(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(Af(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>Af(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var NA,$A,rc=y(()=>{"use strict";j();W();NA=new Set(["daemon","subagent","telegram","afk"]),$A=new Set(["repl","interactive","cli"])});import Ht from"node:fs";import ds from"node:path";import{randomBytes as WA}from"node:crypto";import{chromium as GA}from"playwright";function qA(){try{return"5.15.1"}catch{}try{let t=ds.resolve(import.meta.dirname,"../../../package.json"),e=Ht.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var zA,us,Pf=y(()=>{"use strict";W();le();zA=qA(),us=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=GA.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 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=()=>{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),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.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/${zA}`}}loadStorageState(e){let n=Ki(e);try{if(!Ht.existsSync(n))return;let r=JSON.parse(Ht.readFileSync(n,"utf8"));return U("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){U("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Ki(e);if(!Ht.existsSync(r))return;let o=await n.storageState(),s=ds.join(ds.dirname(r),`.${ds.basename(r)}.${process.pid}.${WA(4).toString("hex")}.tmp`);Ht.writeFileSync(s,JSON.stringify(o),{mode:384}),Ht.chmodSync(s,384),Ht.renameSync(s,r),U("[browser/vault] saved session",{profile:e,file:r})}catch(r){U("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as VA}from"crypto";function oc(t){if(t.length===0)return t;let e=t;for(let{regex:n,name:r}of JA)r==="form-password"?e=e.replace(n,"password=[redacted]"):e=e.replace(n,"[redacted]");return e}function If(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&YA.test(t.label))}function Cf(t){return VA("sha256").update(t,"utf8").digest("hex").slice(0,8)}function Mf(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var JA,YA,tr=y(()=>{"use strict";JA=[{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}];YA=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as XA}from"node:crypto";function QA(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function ZA(t,e,n){return`el_${XA("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function eT(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Of(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function Ff(t,e){let n=t.role??"",r=t.name??"";Df.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])Ff(s,e)}async function tT(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},Lf).catch(()=>[])}async function nT(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},Lf).catch(()=>[])}function rT(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function ps(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=rT(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=tT(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]),S,b=!1;u!==null?(S=[],Ff(u,S)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,S=(await nT(t)).filter(N=>Df.has(N.role??"")));let _=new Map;for(let R of p){let N=Of(R.name),F=_.get(N);(!F||F.bbox.w===0&&R.bbox.w>0)&&_.set(N,R)}let w=S.map(R=>({ax:R,dom:_.get(Of(R.name??""))})),v=r?w:w.filter(R=>R.dom?R.dom.bbox.w>0||R.dom.bbox.h>0:!0);v.sort((R,N)=>{let F=R.dom?.bbox.y??0,$=N.dom?.bbox.y??0;if(F!==$)return F-$;let M=R.dom?.bbox.x??0,L=N.dom?.bbox.x??0;return M-L}),v.length>200&&o.push("page has 200+ interactive elements; consider scoping");let x=v.slice(0,n).map((R,N)=>{let F=R.ax.role??"generic",$=R.ax.name??"",M=ZA(F,$,N),L=R.dom?.bbox??{x:0,y:0,w:0,h:0},C=R.dom?.type??null,T=null;R.ax.value!==void 0&&R.ax.value!==null&&(T=String(R.ax.value)),R.ax.checked!==void 0&&(T=String(R.ax.checked)),If({role:F,kind:C})&&(T="[redacted]");let B={disabled:R.ax.disabled??!1};R.ax.checked!==void 0&&(B.checked=R.ax.checked===!0||R.ax.checked==="mixed"),R.ax.selected!==void 0&&(B.selected=R.ax.selected),R.ax.expanded!==void 0&&(B.expanded=R.ax.expanded);let K;R.dom?.testId?K=`[data-testid="${R.dom.testId}"]`:R.dom?.id&&(K=`#${R.dom.id}`);let q={id:M,role:F,label:QA($),kind:C,value:T,state:B,bbox:L};return K!==void 0&&(q.selector=K),q}),A="idle";try{let R=await t.evaluate(()=>document.readyState);R==="loading"?A="loading":R==="interactive"?A="navigating":A="idle"}catch{A="navigating"}A!=="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 I=eT(f),P=`obs_${e.observationCounter.toString(36)}`,O=new Date().toISOString();return{observationId:P,url:h,title:g,textSummary:I,interactive:x,status:{httpStatus:e.httpStatus??null,loadingState:A,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:O}}var Df,Lf,Nf=y(()=>{"use strict";tr();Df=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);Lf="a[href], button, input, select, textarea, [role], [tabindex], label"});async function $f(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 sc(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>$f(t,s)))).filter(o=>o!==null)}async function oT(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 ic(t,e,n){switch(e.kind){case"element_id":return sT(t,e,n);case"selector":return iT(t,e);case"semantic":return aT(t,e)}}async function sT(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 sc(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function iT(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 sc(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function aT(t,e){return e.role!==void 0?cT(t,e.text,e.role):lT(t,e.text,e)}async function cT(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 sc(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function lT(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 oT(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 S=p[g];if(S===void 0)continue;let b=await $f(S.locator,S.index);if(b!==null){let _=`${b.role}:${b.label}:${g}`,w=0;for(let v=0;v<_.length;v++)w=w*31+_.charCodeAt(v)>>>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 Uf=y(()=>{"use strict"});import{randomBytes as dT}from"crypto";import{mkdir as uT,stat as pT,writeFile as fT}from"fs/promises";import{join as ac}from"path";import{gzip as mT}from"zlib";import{promisify as gT}from"util";function hT(t){return ac(Yr(t),"browser")}function yT(t){return ac(hT(t),"screenshots")}function bT(){return new Date().toISOString().replace(/[:.]/g,"-")}function wT(){return dT(3).toString("hex")}async function cc(t,e,n){if(e.length>Bf)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Bf} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=yT(t);await uT(r,{recursive:!0});let o=`${bT()}-${wT()}-${n}.png`,s=ac(r,o);await fT(s,e);let{size:i}=await pT(s);return{path:s,bytes:i}}var EB,Bf,jf=y(()=>{"use strict";W();tr();EB=gT(mT);Bf=5*1024*1024});var Kf={};Ni(Kf,{PlaywrightProvider:()=>lc});function Hf(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 lc,Wf=y(()=>{"use strict";Pf();Nf();Uf();rc();tr();jf();lc=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new us(e)}async open(e){let n=nc(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 ps(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 ps(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 ic(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${Hf(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=oc(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(S){l=S}else l=g}let u=r.url();if(u!==s){let g=nc(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 ps(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 ic(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${Hf(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 cc(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 cc(n,o,r);return s}catch{return null}}}});var Wt={};Ni(Wt,{__resetBrowserRegistryForTests:()=>ET,browserProviderActive:()=>kT,closeBrowserProvider:()=>dc,getBrowserProvider:()=>vT,peekBrowserProvider:()=>_T});function Gf(){Promise.resolve(dc()).then(()=>{process.exit(130)})}function qf(){Promise.resolve(dc()).then(()=>{process.exit(143)})}function zf(){Ke=null}function ST(){fs||(process.on("SIGINT",Gf),process.on("SIGTERM",qf),process.on("exit",zf),fs=!0)}function Vf(){fs&&(process.removeListener("SIGINT",Gf),process.removeListener("SIGTERM",qf),process.removeListener("exit",zf),fs=!1)}async function vT(t){return Ke!==null?Ke:(Kt!==null||(Kt=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(Wf(),Kf)),n=Rf(t),r=new e(n);return ST(),Ke=r,Kt=null,r})()),Kt)}async function dc(){if(Ke===null)return;let t=Ke;Ke=null,Kt=null,Vf(),await t.shutdown()}function kT(){return Ke!==null}function _T(){return Ke}function ET(){Ke=null,Kt=null,Vf()}var Ke,Kt,fs,Gt=y(()=>{"use strict";rc();Ke=null,Kt=null,fs=!1});function Jf(t,e){try{return kf(t,e)}catch(n){return U("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function PT(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Gt(),Wt));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal})}async function Yf(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??PT,o=null,s=t,i=null,a=null;try{let l=await ls(n,t,{headers:RT,redirect:"follow",signal:e.signal});i=l.status,s=l.url||t;let d=l.headers.get("content-type")??"";if(l.ok){if(xT.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(TT.test(d)&&!AT.test(d))return{title:"",markdown:u.trim(),finalUrl:s,usedRender:!1};o=Jf(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<vf)&&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=Jf(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 AT,TT,xT,RT,Xf=y(()=>{"use strict";_f();tc();le();AT=/(text\/html|application\/xhtml\+xml)/i,TT=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,xT=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,RT={"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 MT(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(IT,{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),CT),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Bo(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 Qf(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?MT({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 Zf(t,e){if(e.length===0)return`# Search results for "${t}"
1056
+ `).trim()}function IA(t){return(t?.textContent??"").replace(/\s+/g," ").trim().length}function kf(t,e){let r=new xA(t,{url:e}).window.document,o=(r.title??"").trim(),s=null;try{let l=r.cloneNode(!0);s=new RA(l).parse()}catch{s=null}if(s&&typeof s.content=="string"&&s.content.trim().length>0){let l=Sf(ec.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=Sf(ec.turndown(a));return{title:o,markdown:c,textLength:IA(i),usedFallback:!0}}var vf,ec,_f=y(()=>{"use strict";vf=200,ec=new PA({headingStyle:"atx",codeBlockStyle:"fenced",bulletListMarker:"-"});ec.remove(["script","style","noscript","iframe"])});function MA(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 Ef(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function OA(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 ls(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??MA,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(!CA.has(u.status)||d===o)return u;let p=OA(u,i)??Ef(d,s,i);U("[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=Ef(d,s,i);U("[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 CA,tc=y(()=>{"use strict";le();CA=new Set([429,502,503,504])});import{readFileSync as DA}from"node:fs";import{join as FA}from"path";function LA(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function Af(t,e){return LA(e).test(t)}function UA(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(NA.has(e))return!0;if($A.has(e))return!1}return!1}function Tf(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function BA(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 xf(t){let e=t===void 0||t.trim()===""?"default":t.trim();return Hi(e),e}function jA(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function HA(t){try{return DA(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function KA(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=xf(e.defaultProfile)),n}function Rf(t){let e=t?.env??k,n=t?.readFileSync??HA,r=t?.surface??e.AGENT_SURFACE,o=UA(e.AFK_BROWSER_HEADLESS,r),s=Tf(e.AFK_BROWSER_ALLOWED_DOMAINS),i=Tf(e.AFK_BROWSER_BLOCKED_DOMAINS),a=jA(e.AFK_BROWSER_DOM_SNAPSHOTS),c=BA(e.AFK_BROWSER_BACKEND),l=xf(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():FA(Je(),"browser.json"),f=n(p);if(f===void 0)return d;let h;try{h=JSON.parse(f)}catch(S){throw new Error(`Failed to parse browser config at ${p}: ${String(S)}`)}if(typeof h!="object"||h===null||Array.isArray(h))throw new Error(`Browser config at ${p} must be a JSON object`);let g=KA(d,h);return g.configPath=p,g}function nc(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(Af(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>Af(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var NA,$A,rc=y(()=>{"use strict";j();W();NA=new Set(["daemon","subagent","telegram","afk"]),$A=new Set(["repl","interactive","cli"])});import Ht from"node:fs";import ds from"node:path";import{randomBytes as WA}from"node:crypto";import{chromium as GA}from"playwright";function qA(){try{return"5.15.2"}catch{}try{let t=ds.resolve(import.meta.dirname,"../../../package.json"),e=Ht.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var zA,us,Pf=y(()=>{"use strict";W();le();zA=qA(),us=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=GA.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 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=()=>{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),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.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/${zA}`}}loadStorageState(e){let n=Ki(e);try{if(!Ht.existsSync(n))return;let r=JSON.parse(Ht.readFileSync(n,"utf8"));return U("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){U("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Ki(e);if(!Ht.existsSync(r))return;let o=await n.storageState(),s=ds.join(ds.dirname(r),`.${ds.basename(r)}.${process.pid}.${WA(4).toString("hex")}.tmp`);Ht.writeFileSync(s,JSON.stringify(o),{mode:384}),Ht.chmodSync(s,384),Ht.renameSync(s,r),U("[browser/vault] saved session",{profile:e,file:r})}catch(r){U("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as VA}from"crypto";function oc(t){if(t.length===0)return t;let e=t;for(let{regex:n,name:r}of JA)r==="form-password"?e=e.replace(n,"password=[redacted]"):e=e.replace(n,"[redacted]");return e}function If(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&YA.test(t.label))}function Cf(t){return VA("sha256").update(t,"utf8").digest("hex").slice(0,8)}function Mf(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var JA,YA,tr=y(()=>{"use strict";JA=[{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}];YA=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as XA}from"node:crypto";function QA(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function ZA(t,e,n){return`el_${XA("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function eT(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Of(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function Ff(t,e){let n=t.role??"",r=t.name??"";Df.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])Ff(s,e)}async function tT(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},Lf).catch(()=>[])}async function nT(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},Lf).catch(()=>[])}function rT(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function ps(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=rT(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=tT(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]),S,b=!1;u!==null?(S=[],Ff(u,S)):(o.push("observation skipped accessibility tree (returned null)"),b=!0,S=(await nT(t)).filter(N=>Df.has(N.role??"")));let _=new Map;for(let R of p){let N=Of(R.name),F=_.get(N);(!F||F.bbox.w===0&&R.bbox.w>0)&&_.set(N,R)}let w=S.map(R=>({ax:R,dom:_.get(Of(R.name??""))})),v=r?w:w.filter(R=>R.dom?R.dom.bbox.w>0||R.dom.bbox.h>0:!0);v.sort((R,N)=>{let F=R.dom?.bbox.y??0,$=N.dom?.bbox.y??0;if(F!==$)return F-$;let M=R.dom?.bbox.x??0,L=N.dom?.bbox.x??0;return M-L}),v.length>200&&o.push("page has 200+ interactive elements; consider scoping");let x=v.slice(0,n).map((R,N)=>{let F=R.ax.role??"generic",$=R.ax.name??"",M=ZA(F,$,N),L=R.dom?.bbox??{x:0,y:0,w:0,h:0},C=R.dom?.type??null,T=null;R.ax.value!==void 0&&R.ax.value!==null&&(T=String(R.ax.value)),R.ax.checked!==void 0&&(T=String(R.ax.checked)),If({role:F,kind:C})&&(T="[redacted]");let B={disabled:R.ax.disabled??!1};R.ax.checked!==void 0&&(B.checked=R.ax.checked===!0||R.ax.checked==="mixed"),R.ax.selected!==void 0&&(B.selected=R.ax.selected),R.ax.expanded!==void 0&&(B.expanded=R.ax.expanded);let K;R.dom?.testId?K=`[data-testid="${R.dom.testId}"]`:R.dom?.id&&(K=`#${R.dom.id}`);let q={id:M,role:F,label:QA($),kind:C,value:T,state:B,bbox:L};return K!==void 0&&(q.selector=K),q}),A="idle";try{let R=await t.evaluate(()=>document.readyState);R==="loading"?A="loading":R==="interactive"?A="navigating":A="idle"}catch{A="navigating"}A!=="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 I=eT(f),P=`obs_${e.observationCounter.toString(36)}`,O=new Date().toISOString();return{observationId:P,url:h,title:g,textSummary:I,interactive:x,status:{httpStatus:e.httpStatus??null,loadingState:A,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:O}}var Df,Lf,Nf=y(()=>{"use strict";tr();Df=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);Lf="a[href], button, input, select, textarea, [role], [tabindex], label"});async function $f(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 sc(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>$f(t,s)))).filter(o=>o!==null)}async function oT(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 ic(t,e,n){switch(e.kind){case"element_id":return sT(t,e,n);case"selector":return iT(t,e);case"semantic":return aT(t,e)}}async function sT(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 sc(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function iT(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 sc(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function aT(t,e){return e.role!==void 0?cT(t,e.text,e.role):lT(t,e.text,e)}async function cT(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 sc(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function lT(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 oT(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 S=p[g];if(S===void 0)continue;let b=await $f(S.locator,S.index);if(b!==null){let _=`${b.role}:${b.label}:${g}`,w=0;for(let v=0;v<_.length;v++)w=w*31+_.charCodeAt(v)>>>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 Uf=y(()=>{"use strict"});import{randomBytes as dT}from"crypto";import{mkdir as uT,stat as pT,writeFile as fT}from"fs/promises";import{join as ac}from"path";import{gzip as mT}from"zlib";import{promisify as gT}from"util";function hT(t){return ac(Yr(t),"browser")}function yT(t){return ac(hT(t),"screenshots")}function bT(){return new Date().toISOString().replace(/[:.]/g,"-")}function wT(){return dT(3).toString("hex")}async function cc(t,e,n){if(e.length>Bf)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Bf} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=yT(t);await uT(r,{recursive:!0});let o=`${bT()}-${wT()}-${n}.png`,s=ac(r,o);await fT(s,e);let{size:i}=await pT(s);return{path:s,bytes:i}}var EB,Bf,jf=y(()=>{"use strict";W();tr();EB=gT(mT);Bf=5*1024*1024});var Kf={};Ni(Kf,{PlaywrightProvider:()=>lc});function Hf(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 lc,Wf=y(()=>{"use strict";Pf();Nf();Uf();rc();tr();jf();lc=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new us(e)}async open(e){let n=nc(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 ps(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 ps(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 ic(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${Hf(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=oc(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(S){l=S}else l=g}let u=r.url();if(u!==s){let g=nc(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 ps(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 ic(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${Hf(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 cc(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 cc(n,o,r);return s}catch{return null}}}});var Wt={};Ni(Wt,{__resetBrowserRegistryForTests:()=>ET,browserProviderActive:()=>kT,closeBrowserProvider:()=>dc,getBrowserProvider:()=>vT,peekBrowserProvider:()=>_T});function Gf(){Promise.resolve(dc()).then(()=>{process.exit(130)})}function qf(){Promise.resolve(dc()).then(()=>{process.exit(143)})}function zf(){Ke=null}function ST(){fs||(process.on("SIGINT",Gf),process.on("SIGTERM",qf),process.on("exit",zf),fs=!0)}function Vf(){fs&&(process.removeListener("SIGINT",Gf),process.removeListener("SIGTERM",qf),process.removeListener("exit",zf),fs=!1)}async function vT(t){return Ke!==null?Ke:(Kt!==null||(Kt=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(Wf(),Kf)),n=Rf(t),r=new e(n);return ST(),Ke=r,Kt=null,r})()),Kt)}async function dc(){if(Ke===null)return;let t=Ke;Ke=null,Kt=null,Vf(),await t.shutdown()}function kT(){return Ke!==null}function _T(){return Ke}function ET(){Ke=null,Kt=null,Vf()}var Ke,Kt,fs,Gt=y(()=>{"use strict";rc();Ke=null,Kt=null,fs=!1});function Jf(t,e){try{return kf(t,e)}catch(n){return U("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function PT(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Gt(),Wt));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal})}async function Yf(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??PT,o=null,s=t,i=null,a=null;try{let l=await ls(n,t,{headers:RT,redirect:"follow",signal:e.signal});i=l.status,s=l.url||t;let d=l.headers.get("content-type")??"";if(l.ok){if(xT.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(TT.test(d)&&!AT.test(d))return{title:"",markdown:u.trim(),finalUrl:s,usedRender:!1};o=Jf(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<vf)&&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=Jf(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 AT,TT,xT,RT,Xf=y(()=>{"use strict";_f();tc();le();AT=/(text\/html|application\/xhtml\+xml)/i,TT=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,xT=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,RT={"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 MT(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(IT,{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),CT),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let c="";try{let d=await s.text(),u=Bo(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 Qf(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?MT({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 Zf(t,e){if(e.length===0)return`# Search results for "${t}"
1056
1057
 
1057
1058
  (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
1059
  `).trimEnd()}var IT,CT,em=y(()=>{"use strict";an();IT="https://api.exa.ai/search",CT=10});function BT(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=OT;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,DT)}let a=FT;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,LT)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function uc(t,e){let n=Buffer.from(t,"utf8");return n.byteLength<=e?t:n.subarray(0,e).toString("utf8")+NT}function jT(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 UT.some(o=>r.includes(o))}function HT(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=BT(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 ls(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:uc(p,s.maxBytes)}}if(s.mode==="markdown")try{let u=await Yf(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:uc(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=jT(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=Qf({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:$T,timeoutMs:s.timeoutMs,signal:i.signal});return{content:uc(Zf(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 OT,DT,FT,LT,NT,$T,UT,tm,nm=y(()=>{"use strict";Xf();em();tc();OT=3e4,DT=12e4,FT=1e6,LT=1e7,NT=`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-afk",
3
- "version": "5.15.1",
3
+ "version": "5.15.2",
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",