agent-afk 5.83.7 → 5.83.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/telegram.mjs CHANGED
@@ -851,7 +851,7 @@ SECURITY NOTE: upstream node output injected into downstream prompts is user-con
851
851
  `):" (no path captured)";return`Denial circuit breaker: this forked sub-agent hit ${e} consecutive path-approval read denials with no successful tool call in between, and was aborted to avoid burning its wall-clock budget. A fork cannot approve its own reads. Denied paths:
852
852
  ${n}
853
853
 
854
- Remedy: these paths are outside the fork's granted read roots. Re-dispatch with the needed paths inside the child's cwd/worktree, or pass explicit readRoots granting them. If this worker is deliberately confined (e.g. an \`afk farm\` branch worker), this failure is expected \u2014 the paths are outside its assigned scope; widen the scope or narrow the task.`}var yr,Cb,fO,wa=y(()=>{"use strict";yr="denial-breaker",Cb=new Set(["read_file","list_directory","glob","grep"]),fO="Sub-agent path access denied:"});import{createHash as mO}from"node:crypto";function Ob(){return{recent:[],firedFingerprints:new Set}}function Db(t){let e;try{e=hO(t.input)}catch{e=String(t.input)}return mO("sha256").update(t.name).update("\0").update(e).digest("hex")}function hO(t){return JSON.stringify(Su(t))??"null"}function Su(t){if(Array.isArray(t))return t.map(Su);if(t!==null&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=Su(e[r]);return n}return t}function yO(t,e){let n=0;for(let r of t)r===e&&(n+=1);return n}function Fb(t,e){t.recent.push(e),t.recent.length>vu&&t.recent.shift();let n=yO(t.recent,e);return n>=gO&&!t.firedFingerprints.has(e)?(t.firedFingerprints.add(e),{fired:!0,count:n}):{fired:!1,count:n}}var gO,vu,Lb=y(()=>{"use strict";gO=5,vu=20});var wO,SO,vO,Pt,ku=y(()=>{"use strict";me();de();ma();la();fa();hu();Rn();ba();se();wu();Rb();wa();Lb();wu();wO=8,SO=new Set,vO=8,Pt=class{handlers;schemas;hookRegistry;permissions;canUseTool;subagentExecutor;skillExecutor;composeExecutor;classifier;maxConcurrentSafeCalls;resolveBase;_readRoots;_writeRoots;_allowAll;_env;sessionId;parentSessionId;subagentId;sessionGrantManager;traceWriter;readOnlyBash;maxOutputBytes;repeatBreaker=null;denialBreaker=null;suspectedLoopWindow=null;grantManager;constructor(e){this.handlers=e.handlers,this.schemas=e.schemas,this.hookRegistry=e.hookRegistry,this.permissions=e.permissions,this.canUseTool=e.canUseTool,this.subagentExecutor=e.subagentExecutor,this.skillExecutor=e.skillExecutor,this.composeExecutor=e.composeExecutor,this.classifier=e.concurrencyClassifier??bu,this.maxConcurrentSafeCalls=typeof e.maxConcurrentSafeCalls=="number"&&Number.isFinite(e.maxConcurrentSafeCalls)&&e.maxConcurrentSafeCalls>=1?Math.floor(e.maxConcurrentSafeCalls):vO,this.resolveBase=e.cwd,this._env=e.env,this.sessionId=e.sessionId,this.parentSessionId=e.parentSessionId,this.subagentId=e.subagentId,this.sessionGrantManager=e.sessionGrantManager,this.traceWriter=e.traceWriter,this.readOnlyBash=e.readOnlyBash===!0,this.maxOutputBytes=typeof e.maxOutputBytes=="number"&&Number.isFinite(e.maxOutputBytes)&&e.maxOutputBytes>0?e.maxOutputBytes:void 0,this._allowAll=e.allowAll===!0;let n=e.cwd?[e.cwd]:[];this._readRoots=e.readRoots??n.slice(),this._writeRoots=e.writeRoots??n.slice(),this.grantManager=new Jt({getReadRoots:()=>this._readRoots,getWriteRoots:()=>this._writeRoots,getProtectedRoot:()=>this.resolveBase,getAllowAll:()=>this._allowAll,getDefaultSessionId:()=>this.sessionId})}get handlerContext(){return{cwd:this.resolveBase,resolveBase:this.resolveBase,readRoots:this._readRoots.slice(),writeRoots:this._writeRoots.slice(),...this._allowAll?{allowAll:!0}:{},...this._env!==void 0?{env:this._env}:{},...this.sessionId!==void 0?{sessionId:this.sessionId}:{}}}callHandlerContext(e){return{...this.handlerContext,toolUseId:e.id,...this.traceWriter!==void 0?{traceWriter:this.traceWriter}:{}}}addReadRoot(e,n="slash"){this.grantManager.addReadRoot(e,n)}addWriteRoot(e,n="slash"){this.grantManager.addWriteRoot(e,n)}revokeRoot(e,n="slash"){this.grantManager.revokeRoot(e,n)}getGrants(){return this.grantManager.getGrants()}setAllowAll(e){this._allowAll=e}setResolveBase(e){let n=this.resolveBase;if(n!==e){if(this.resolveBase=e,n!==void 0){let r=this._readRoots.indexOf(n);r!==-1?this._readRoots[r]=e:this._readRoots.includes(e)||this._readRoots.push(e);let o=this._writeRoots.indexOf(n);o!==-1?this._writeRoots[o]=e:this._writeRoots.includes(e)||this._writeRoots.push(e)}else this._readRoots.includes(e)||this._readRoots.push(e),this._writeRoots.includes(e)||this._writeRoots.push(e);this.subagentExecutor?.setCwd(e),this.skillExecutor?.setCwd(e),this.composeExecutor?.setCwd(e)}}get toolDefs(){let e=this.permissions?.allowedTools;if(!e)return this.schemas;let n=new Set(e);return this.schemas.filter(r=>n.has(r.name))}async checkReadOnlyBash(e){if(!this.readOnlyBash||e.name!=="bash")return null;let n=e.input,r=typeof n=="object"&&n!==null?n.command:void 0;if(typeof r!="string")return null;let o=ha(r);if(!o.mutating)return null;let s=`Bash command blocked: read-only skill may not run mutating commands (${o.reason??"mutation detected"}). Allowed: read-only recon (git status/log/diff, ls, cat, find, grep).`;return await this.emitPreToolUseBlock(e.name,s),{content:s,isError:!0,failureClass:"permission-denied"}}async emitPreToolUseBlock(e,n){await et(this.traceWriter,{hookEvent:"PreToolUse",decision:"block",blockedTool:e,reason:n,...this.subagentId!==void 0?{subagentId:this.subagentId}:{}})}checkRepeatCircuitBreaker(e){if(SO.has(e.name))return null;let n=xb(e);return this.repeatBreaker!==null&&this.repeatBreaker.fingerprint===n?this.repeatBreaker.count+=1:this.repeatBreaker={fingerprint:n,count:1},this.repeatBreaker.count<wO?null:{content:`Loop circuit breaker: "${e.name}" has been called ${this.repeatBreaker.count} times in a row with byte-identical input. The result will not change. Stop repeating this call \u2014 reuse the previous result, change the input, try a different tool, or end the turn.`,isError:!0,circuitBreaker:!0}}observeSuspectedLoop(e){if(this.parentSessionId===void 0)return;this.suspectedLoopWindow===null&&(this.suspectedLoopWindow=Ob());let n=Db(e),r=Fb(this.suspectedLoopWindow,n);r.fired&&X(this.traceWriter,{phase:"suspected_loop",metadata:{tool:e.name,count:r.count,windowSize:vu}})}recordForkReadDenial(e,n,r){if(this.parentSessionId===void 0||!Cb.has(e.name)||!Ib(n))return r;let o=this.denialBreaker??{count:0,deniedPaths:[]};o.count+=1;let s=Pb(e);return o.deniedPaths.includes(s)||o.deniedPaths.push(s),this.denialBreaker=o,o.count<5?r:{content:Mb(o.deniedPaths,o.count),isError:!0,failureClass:yr}}resetDenialBreaker(){this.denialBreaker=null}async runCanUseTool(e){if(!this.canUseTool)return null;let n;try{n=await this.canUseTool(e.name,e.input??{},{signal:e.signal,toolUseID:e.id})}catch(r){let o=`Tool "${e.name}" denied by canUseTool (threw): ${r instanceof Error?r.message:String(r)}`;return await this.emitPreToolUseBlock(e.name,o),{content:o,isError:!0,failureClass:"permission-denied"}}if(n.behavior==="deny"){let r=n.message||`Tool "${e.name}" denied by permission policy`;return await this.emitPreToolUseBlock(e.name,r),{content:r,isError:!0,failureClass:"permission-denied"}}return n.updatedInput!==void 0&&(e.input=n.updatedInput),null}async execute(e){if(e.signal.aborted)return{content:"Tool call aborted",isError:!0,failureClass:"abort"};if(this.hookRegistry){let a={event:"PreToolUse",toolName:e.name,input:e.input,...this.sessionId!==void 0?{sessionId:this.sessionId}:{},...this.resolveBase!==void 0?{cwd:this.resolveBase}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{}};try{await cu(this.hookRegistry,a,{signal:e.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(l){if(l instanceof ne)return this.recordForkReadDenial(e,l.reason,{content:`Tool "${e.name}" blocked by PreToolUse hook: ${l.message}`,isError:!0,failureClass:"hook-block"});throw l}}let n=mu(e.name,this.permissions);if(!n.allowed){let a=n.reason??`Tool "${e.name}" is not permitted`;return await this.emitPreToolUseBlock(e.name,a),{content:a,isError:!0,failureClass:"permission-denied"}}let r=await this.runCanUseTool(e);if(r)return r;let o=await this.checkReadOnlyBash(e);if(o)return o;let s=this.checkRepeatCircuitBreaker(e);if(s)return s;this.observeSuspectedLoop(e);let i=await this.executeCore(e);return i.isError!==!0&&this.resetDenialBreaker(),i}async executeBatch(e){if(e.length===0)return[];if(e.length===1)return[await this.execute(e[0])];let n=new Array(e.length),r=new Set;for(let i=0;i<e.length;i++){let a=e[i];if(a.signal.aborted){n[i]={content:"Tool call aborted",isError:!0,failureClass:"abort"},r.add(i);continue}if(this.hookRegistry){let p={event:"PreToolUse",toolName:a.name,input:a.input,...this.sessionId!==void 0?{sessionId:this.sessionId}:{},...this.resolveBase!==void 0?{cwd:this.resolveBase}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{}};try{await cu(this.hookRegistry,p,{signal:a.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(f){if(f instanceof ne){n[i]=this.recordForkReadDenial(a,f.reason,{content:`Tool "${a.name}" blocked by PreToolUse hook: ${f.message}`,isError:!0,failureClass:"hook-block"}),r.add(i);continue}throw f}}let l=mu(a.name,this.permissions);if(!l.allowed){let p=l.reason??`Tool "${a.name}" is not permitted`;await this.emitPreToolUseBlock(a.name,p),n[i]={content:p,isError:!0,failureClass:"permission-denied"},r.add(i);continue}let c=await this.runCanUseTool(a);if(c){n[i]=c,r.add(i);continue}let d=await this.checkReadOnlyBash(a);if(d){n[i]=d,r.add(i);continue}let u=this.checkRepeatCircuitBreaker(a);if(u){n[i]=u,r.add(i);continue}this.observeSuspectedLoop(a)}let o=e.map((i,a)=>({call:i,originalIndex:a})).filter((i,a)=>!r.has(a));if(o.length===0)return n;let s=Tb(o.map(i=>i.call),this.classifier);for(let i of s){if(i.isConcurrencySafe){let l=await hr(i.indices,this.maxConcurrentSafeCalls,async c=>{let{call:d,originalIndex:u}=o[c];return d.signal.aborted?{result:{content:"Tool call aborted",isError:!0,failureClass:"abort"},originalIndex:u}:{result:await this.executeCore(d),originalIndex:u}});for(let c of l)if(c.status==="fulfilled")n[c.value.originalIndex]=c.value.result;else{let d=c.reason instanceof Error?c.reason.message:String(c.reason),u=i.indices[l.indexOf(c)];n[o[u].originalIndex]={content:`Tool execution error: ${d}`,isError:!0}}}else for(let l of i.indices){let{call:c,originalIndex:d}=o[l];if(c.signal.aborted){n[d]={content:"Tool call aborted",isError:!0,failureClass:"abort"};continue}n[d]=await this.executeCore(c)}let a=i.indices.length;i.indices.forEach((l,c)=>{let d=n[o[l].originalIndex];d&&(d.batchIndex=c+1,d.batchSize=a)})}return n.some(i=>i!==void 0&&i.isError!==!0)&&this.resetDenialBreaker(),n}async executeCore(e){let n=await this.executeCoreInner(e);return this.applyOutputCap(n)}applyOutputCap(e){let n=this.maxOutputBytes;if(n===void 0)return e;let r=Buffer.byteLength(e.content,"utf8");return r<=n||(e.content=Ct(e.content,n),e.truncated=!0,N(`[output-cap #661] fork tool result capped: original=${r}B capped=${Buffer.byteLength(e.content,"utf8")}B (cap=${n}B)`)),e}async executeCoreInner(e){if(e.name==="agent"){if(!this.subagentExecutor)return{content:"Agent tool is not available in this session configuration",isError:!0};let i,a=!1,l="";try{i=await this.subagentExecutor.execute(e)}catch(c){a=!0,l=c instanceof Error?c.message:String(c),i={content:`Agent tool error: ${l}`,isError:!0}}return a?this.firePostToolUseFailure(e.name,l,e.signal,e.input):this.firePostToolUse(e.name,i.content,e.signal,e.input,i),i}if(e.name==="skill"){if(!this.skillExecutor)return{content:"Skill tool is not available in this session configuration",isError:!0};let i,a=!1,l="";try{i=await this.skillExecutor.execute(e)}catch(c){a=!0,l=c instanceof Error?c.message:String(c),i={content:`Skill tool error: ${l}`,isError:!0}}return a?this.firePostToolUseFailure(e.name,l,e.signal,e.input):this.firePostToolUse(e.name,i.content,e.signal,e.input,i),i}if(e.name==="compose"){let i=await this.executeCompose(e);return this.firePostToolUse(e.name,i.content,e.signal,e.input,i),i}let n=this.handlers.get(e.name);if(!n)return{content:`Unknown tool "${e.name}". Available tools: ${[...this.handlers.keys()].join(", ")}`,isError:!0};let r,o=!1,s="";try{r=await n(e.input,e.signal,this.callHandlerContext(e))}catch(i){o=!0,s=i instanceof Error?i.message:String(i),r={content:`Tool execution error: ${s}`,isError:!0}}return o?this.firePostToolUseFailure(e.name,s,e.signal,e.input):this.firePostToolUse(e.name,r.content,e.signal,e.input,r),r}async executeCompose(e){if(!this.composeExecutor)return{content:"Compose tool is not available in this session configuration",isError:!0};try{return await this.composeExecutor.execute(e)}catch(n){return{content:`Compose tool error: ${n instanceof Error?n.message:String(n)}`,isError:!0}}}firePostToolUse(e,n,r,o,s){if(!this.hookRegistry)return;let i={event:"PostToolUse",toolName:e,output:n,...o!==void 0?{input:o}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{},...s?.incomplete===!0?{incomplete:!0}:{},...s?.incompleteReason?{incompleteReason:s.incompleteReason}:{}};mb(this.hookRegistry,i,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(()=>{})}firePostToolUseFailure(e,n,r,o){if(!this.hookRegistry)return;let s={event:"PostToolUseFailure",toolName:e,error:n,...o!==void 0?{input:o}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{}};gb(this.hookRegistry,s,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(i=>{N(`firePostToolUseFailure outer catch (tool=${e}): ${String(i)}`)})}}});function MO(t){let e=t.match(kO);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10),o=e[3]!==void 0?parseInt(e[3],10):void 0;return{runner:"vitest",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function OO(t){let e=t.match(_O);if(!e)return null;let n=parseInt(e[1]??"0",10);return{runner:"jest",passed:parseInt(e[2]??"0",10),failed:n}}function DO(t){let e=t.match(EO);if(!e)return null;if(e[2]!==void 0){let n=parseInt(e[2],10),r=parseInt(e[1]??"0",10);return{runner:"pytest",passed:n,failed:r}}return e[4]!==void 0?{runner:"pytest",passed:parseInt(e[4],10),failed:0}:null}function FO(t){let e=t.match(AO);if(!e)return null;let n=parseInt(e[1]??"0",10),r=t.match(TO),o=r?parseInt(r[1]??"0",10):0;return{runner:"mocha",passed:n,failed:o}}function LO(t){let e=[...t.matchAll(xO)];if(e.length===0)return null;let n=0,r=0;for(let o of e)o[1]==="ok"?n++:o[1]==="FAIL"&&r++;return{runner:"go-test",passed:n,failed:r}}function NO(t){let e=t.match(RO);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10),o=e[3]!==void 0?parseInt(e[3],10):void 0;return{runner:"cargo",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function $O(t){let e=t.match(CO);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10);return{runner:"rspec",passed:n-r,failed:r}}function UO(t){let e=t.match(IO);if(e)return{runner:"phpunit",passed:parseInt(e[1]??"0",10),failed:0};let n=t.match(PO);if(n){let r=parseInt(n[1]??"0",10),o=parseInt(n[2]??"0",10);return{runner:"phpunit",passed:r-o,failed:o}}return null}function _u(t){return MO(t)??OO(t)??DO(t)??FO(t)??LO(t)??NO(t)??$O(t)??UO(t)??null}var kO,_O,EO,AO,TO,xO,RO,CO,IO,PO,Nb=y(()=>{"use strict";kO=/Tests\s+(\d+)\s+passed(?:\s*\|\s*(\d+)\s+failed)?(?:\s*\|\s*(\d+)\s+skipped)?/,_O=/Tests:\s+(?:(\d+)\s+failed,\s*)?(\d+)\s+passed,\s*\d+\s+total/,EO=/={3,}\s*(?:(\d+)\s+failed,\s*)?(\d+)\s+passed(?:,\s*(\d+)\s+warning)?.*in\s+[\d.]+s\s*={3,}|={3,}\s*(\d+)\s+passed.*in\s+[\d.]+s\s*={3,}/,AO=/(\d+)\s+passing/,TO=/(\d+)\s+failing/,xO=/^(ok|FAIL)\s+\S+\s+[\d.]+s/gm,RO=/test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed(?:; (\d+) ignored)?/,CO=/(\d+) examples?, (\d+) failures?/,IO=/OK \((\d+) tests?/,PO=/Tests:\s*(\d+)[^]*?Failures:\s*(\d+)/});import{statSync as BO}from"node:fs";function xo(t){if(typeof t!="object"||t===null)return!1;let e=t;return e.code==="ENOENT"&&typeof e.syscall=="string"&&e.syscall.startsWith("spawn")}function HO(t){if(t===void 0)return!1;try{return BO(t),!1}catch{return!0}}function br(t,e){let n=t instanceof Error?t.message:typeof t?.message=="string"?String(t.message):String(t);return xo(t)&&HO(e)?`working directory does not exist: ${e} (deleted worktree?) \u2014 underlying: ${n}`:n}var Eu=y(()=>{"use strict"});function yt(t){if($b)return;$b=!0;let e=t instanceof Error?t.message:String(t);console.warn(`[afk-home] Malformed AFK home/state env var ignored while deriving the credential floor: ${e}. The relocated tree is NOT protected \u2014 the default ~/.afk entries still apply. Fix the env var to restore coverage.`)}var $b,Ro=y(()=>{"use strict";$b=!1});import{realpathSync as Ub}from"fs";import{dirname as jO,resolve as Pn,join as Au}from"path";import{homedir as Vt}from"os";function KO(){let t=[];try{let e=oe();t.push(_e(Pn(Au(e,"config")))),t.push(_e(Pn(Au(e,"state"))))}catch(e){yt(e)}try{t.push(_e(Pn(we())))}catch(e){yt(e)}return t}function Tu(){let t=_.AFK_WRITE_DENYLIST,e=t?t.split(":").map(r=>_e(Pn(r))).filter(Boolean):[];return[...[...new Set([...WO.map(r=>_e(Pn(r))),...KO()])],...e]}function _e(t){let e=Pn(t);try{return Ub(e)}catch{}let n=[],r=e;for(let o=0;o<64;o++){let s=jO(r);if(s===r)break;n.unshift(r.slice(s.length+1)),r=s;try{let i=Ub(r);return Au(i,...n)}catch{}}return e}function Sa(t,e="write_file"){let n=_e(Pn(t));for(let r of Tu())if(n===r||n.startsWith(r+"/"))throw new Error(`${e}: refusing to write to protected path: ${n} (matches denylist entry: ${r})`)}var WO,Co=y(()=>{"use strict";H();K();Ro();WO=[`${Vt()}/.ssh`,`${Vt()}/.aws`,`${Vt()}/.gnupg`,`${Vt()}/.config/gcloud`,"/etc","/System","/private/etc","/usr/local/etc",`${Vt()}/.afk/config`,`${Vt()}/.afk/state`,`${Vt()}/.npmrc`,`${Vt()}/.docker/config.json`]});import{basename as GO,dirname as qO,join as va,relative as zO,resolve as wr,sep as Bb}from"path";import{homedir as ge}from"os";function jb(t){let e=wr(t);return va(_e(qO(e)),GO(e))}function Ru(t){return t?t.split(":").map(e=>e.trim()).filter(Boolean).map(e=>e==="~"||e.startsWith("~/")?va(ge(),e.slice(1)):e).map(e=>wr(e)):[]}function VO(){try{return[_e(wr(va(oe(),"config")))]}catch(t){return yt(t),[]}}function YO(){try{let t=oe();return Sr.filter(e=>e.startsWith(Hb)).map(e=>jb(va(t,e.slice(Hb.length))))}catch(t){return yt(t),[]}}function Wb(){let t=`${_.AFK_READ_DENYLIST??""}\0${_.AFK_HOME??""}`;if(Io&&Io.key===t)return Io;let e=Ru(_.AFK_READ_DENYLIST).map(r=>_e(r)).filter(Boolean),n=[...new Set([...xu.map(r=>_e(wr(r))),...VO()])];return Io={key:t,builtins:n,extras:e,allow:[...new Set([...JO.map(jb),...YO()])]},Io}function Cu(){let{builtins:t,extras:e}=Wb();return[...t,...e]}function Kb(t){let e=_e(wr(t));return Cu().map(r=>zO(e,r)).filter(r=>r!==""&&r!==".."&&!r.startsWith(`..${Bb}`)).map(r=>r.split(Bb).join("/"))}function Ye(t){let e=_e(wr(t)),{builtins:n,extras:r,allow:o}=Wb();for(let s of r)if(e===s||e.startsWith(s+"/"))return{denied:!0,matched:s};if(o.includes(e))return{denied:!1};for(let s of n)if(e===s||e.startsWith(s+"/"))return{denied:!0,matched:s};return{denied:!1}}var xu,Sr,JO,Io,Hb,Yt=y(()=>{"use strict";H();Co();K();Ro();xu=[`${ge()}/.ssh`,`${ge()}/.aws`,`${ge()}/.gnupg`,`${ge()}/.config/gcloud`,`${ge()}/.afk/config`,`${ge()}/.npmrc`,`${ge()}/.docker/config.json`,`${ge()}/.git-credentials`,`${ge()}/.netrc`,`${ge()}/.config/gh/hosts.yml`,`${ge()}/.kube/config`,"/etc/shadow","/etc/sudoers","/private/etc/master.passwd",`${ge()}/.password-store`,`${ge()}/Library/Application Support/Google/Chrome`,`${ge()}/Library/Application Support/Chromium`,`${ge()}/Library/Application Support/BraveSoftware`,`${ge()}/Library/Application Support/Microsoft Edge`,`${ge()}/Library/Application Support/Arc`,`${ge()}/Library/Application Support/Firefox`],Sr=[".afk/config/mcp.json"],JO=Sr.map(t=>`${ge()}/${t}`);Hb=".afk/"});import Mn from"path";import{realpathSync as XO}from"fs";function Xe(t){try{return XO.native(t)}catch{let e=Mn.dirname(t),n=Mn.basename(t);return e===t?t:Mn.join(Xe(e),n)}}function QO(t){let e=Gb.get(t);if(e!==void 0)return e;let n=Xe(t);return Gb.set(t,n),n}function qb(t,e,n,r){let o=e?.resolveBase??e?.cwd??r,s=Mn.isAbsolute(t)?t:Mn.resolve(o??process.cwd(),t);if(e?.allowAll===!0)return{restricted:!1,resolved:s,roots:[]};if(o===void 0)return{restricted:!1,resolved:s,roots:[]};let i=Xe(s),a=n==="read"?e?.readRoots??[o]:e?.writeRoots??[o];for(let l of a){let c=QO(l),d=Mn.relative(c,i);if(!d.startsWith("..")&&!Mn.isAbsolute(d))return{restricted:!1,resolved:s,roots:a}}return{restricted:!0,resolved:s,roots:a}}function Qe(t,e,n="read",r){let{restricted:o,resolved:s,roots:i}=qb(t,e,n,r);if(n==="read"){let a=Ye(s);if(a.denied)throw new Error(`Path \`${t}\` is a protected credential/secret path (read-denylist entry: \`${a.matched}\`) and cannot be read.`)}if(o){let a=i.map(c=>`\`${c}\``).join(", "),l=n==="read"?"read roots":"write roots";throw new Error(`Path \`${t}\` is outside the allowed ${l} [${a}].`)}return s}function Po(t,e,n="read",r){return qb(t,e,n,r)}function zb(t){let e=new Set,n=[];for(let r of t.split(/\s+/)){if(r.length===0)continue;let o=r.replace(/^\d*[<>|&]+/,"").replace(/^['"]/,"").replace(/['";,)]+$/,"");if(o.length===0)continue;let s=o.startsWith("/"),i=o==="~"||o.startsWith("~/");!s&&!i||e.has(o)||(e.add(o),n.push(o))}return n}var Gb,ot=y(()=>{"use strict";Yt();Gb=new Map});import{spawn as ZO}from"child_process";import e0 from"os";function t0(t){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let e=t;if(typeof e.command!="string")throw new Error('Input must have a "command" field of type string');let n=12e4;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number")throw new Error("timeout_ms must be a number");if(e.timeout_ms<0||e.timeout_ms>6e5)throw new Error("timeout_ms must be between 0 and 600000");n=e.timeout_ms}return{command:e.command,timeout_ms:n}}function ka(t,e){let n=!1,r=!1;function o(){n||t==="bypassPermissions"&&(n=!0,console.warn("[security] bash handler: shell=true with bypassPermissions \u2014 all shell metacharacters are interpreted without confirmation. Migrate to execFile to eliminate this risk (tracked: C4)."))}function s(i,a){if(r)return;let l=a.resolveBase??a.cwd??e,c=e0.homedir(),d=[];for(let u of zb(i)){let p=u==="~"?c:u.startsWith("~/")?c+u.slice(1):u,f=Po(p,a,"write",l);f.restricted&&d.push(f.resolved)}d.length!==0&&(r=!0,console.warn(`[security] bash: command references path(s) outside writeRoots: ${d.join(", ")} \u2014 bash containment is best-effort (tracked C4); use file tools for contained writes.`),le({event:"tool.bash_path_escape",tool:"bash",restricted_count:d.length,mode:"write"}))}return async(i,a,l)=>{let{command:c,timeout_ms:d}=t0(i);if(a.aborted)return{content:"Command aborted",isError:!0};if(o(),l!==void 0)try{s(c,l)}catch{}return new Promise(u=>{let p=!1;function f(T){p||(p=!0,clearTimeout(g),a.removeEventListener("abort",A),u(T))}let m=ZO(c,{shell:!0,detached:!0,stdio:["ignore","pipe","pipe"],...(l?.resolveBase??l?.cwd??e)!==void 0?{cwd:l?.resolveBase??l?.cwd??e}:{},...l?.env!==void 0?{env:{...process.env,...l.env}}:{}});m.unref();let g=setTimeout(()=>{m.pid!==void 0&&process.kill(-m.pid,"SIGKILL"),f({content:`Command timed out after ${d}ms`,isError:!0})},d),h="",w="",k=0,E=!1;function v(T){if(E||p||k<8e6)return;E=!0,console.warn(`[bash] overflow kill: stream=${T} totalBytes=${k} command="${c}"`),le({event:"tool.overflow_kill",tool:"bash",total_bytes:k,stream:T}),m.kill("SIGKILL");let x=mt((h+w).trimEnd()),S=_u(x)??void 0,R=Ct(x,1e5)+ya;f({content:R,truncated:!0,...S!==void 0?{testResult:S}:{}})}m.stdout.on("data",T=>{let x=8e6-k,S=T.length<=x?T:T.subarray(0,Math.max(0,x));k+=S.length,h+=S.toString("utf8"),v("stdout")}),m.stderr.on("data",T=>{let x=8e6-k,S=T.length<=x?T:T.subarray(0,Math.max(0,x));k+=S.length,w+=S.toString("utf8"),v("stderr")});let A=()=>{m.pid!==void 0&&process.kill(-m.pid,"SIGKILL"),f({content:"Command aborted",isError:!0})};a.addEventListener("abort",A),a.aborted&&A(),m.on("close",T=>{if(a.aborted){f({content:"Command aborted",isError:!0});return}if(T!==null&&T!==0){let I=zt(w.trimEnd()||h.trimEnd());f({content:`Command exited with code ${T}${I.content?`
854
+ Remedy: these paths are outside the fork's granted read roots. Re-dispatch with the needed paths inside the child's cwd/worktree, or pass explicit readRoots granting them. If this worker is deliberately confined (e.g. an \`afk farm\` branch worker), this failure is expected \u2014 the paths are outside its assigned scope; widen the scope or narrow the task.`}var yr,Cb,fO,wa=y(()=>{"use strict";yr="denial-breaker",Cb=new Set(["read_file","list_directory","glob","grep"]),fO="Sub-agent path access denied:"});import{createHash as mO}from"node:crypto";function Ob(){return{recent:[],firedFingerprints:new Set}}function Db(t){let e;try{e=hO(t.input)}catch{e=String(t.input)}return mO("sha256").update(t.name).update("\0").update(e).digest("hex")}function hO(t){return JSON.stringify(Su(t))??"null"}function Su(t){if(Array.isArray(t))return t.map(Su);if(t!==null&&typeof t=="object"){let e=t,n={};for(let r of Object.keys(e).sort())n[r]=Su(e[r]);return n}return t}function yO(t,e){let n=0;for(let r of t)r===e&&(n+=1);return n}function Fb(t,e){t.recent.push(e),t.recent.length>vu&&t.recent.shift();let n=yO(t.recent,e);return n>=gO&&!t.firedFingerprints.has(e)?(t.firedFingerprints.add(e),{fired:!0,count:n}):{fired:!1,count:n}}var gO,vu,Lb=y(()=>{"use strict";gO=5,vu=20});var wO,SO,vO,Pt,ku=y(()=>{"use strict";me();de();ma();la();fa();hu();Rn();ba();se();wu();Rb();wa();Lb();wu();wO=8,SO=new Set,vO=8,Pt=class{handlers;schemas;hookRegistry;permissions;canUseTool;subagentExecutor;skillExecutor;composeExecutor;classifier;maxConcurrentSafeCalls;resolveBase;_readRoots;_writeRoots;_allowAll;_env;sessionId;parentSessionId;subagentId;sessionGrantManager;traceWriter;readOnlyBash;maxOutputBytes;repeatBreaker=null;denialBreaker=null;suspectedLoopWindow=null;grantManager;constructor(e){this.handlers=e.handlers,this.schemas=e.schemas,this.hookRegistry=e.hookRegistry,this.permissions=e.permissions,this.canUseTool=e.canUseTool,this.subagentExecutor=e.subagentExecutor,this.skillExecutor=e.skillExecutor,this.composeExecutor=e.composeExecutor,this.classifier=e.concurrencyClassifier??bu,this.maxConcurrentSafeCalls=typeof e.maxConcurrentSafeCalls=="number"&&Number.isFinite(e.maxConcurrentSafeCalls)&&e.maxConcurrentSafeCalls>=1?Math.floor(e.maxConcurrentSafeCalls):vO,this.resolveBase=e.cwd,this._env=e.env,this.sessionId=e.sessionId,this.parentSessionId=e.parentSessionId,this.subagentId=e.subagentId,this.sessionGrantManager=e.sessionGrantManager,this.traceWriter=e.traceWriter,this.readOnlyBash=e.readOnlyBash===!0,this.maxOutputBytes=typeof e.maxOutputBytes=="number"&&Number.isFinite(e.maxOutputBytes)&&e.maxOutputBytes>0?e.maxOutputBytes:void 0,this._allowAll=e.allowAll===!0;let n=e.cwd?[e.cwd]:[];this._readRoots=e.readRoots??n.slice(),this._writeRoots=e.writeRoots??n.slice(),this.grantManager=new Jt({getReadRoots:()=>this._readRoots,getWriteRoots:()=>this._writeRoots,getProtectedRoot:()=>this.resolveBase,getAllowAll:()=>this._allowAll,getDefaultSessionId:()=>this.sessionId})}get handlerContext(){return{cwd:this.resolveBase,resolveBase:this.resolveBase,readRoots:this._readRoots.slice(),writeRoots:this._writeRoots.slice(),...this._allowAll?{allowAll:!0}:{},...this._env!==void 0?{env:this._env}:{},...this.sessionId!==void 0?{sessionId:this.sessionId}:{}}}callHandlerContext(e){return{...this.handlerContext,toolUseId:e.id,...this.traceWriter!==void 0?{traceWriter:this.traceWriter}:{}}}addReadRoot(e,n="slash"){this.grantManager.addReadRoot(e,n)}addWriteRoot(e,n="slash"){this.grantManager.addWriteRoot(e,n)}revokeRoot(e,n="slash"){this.grantManager.revokeRoot(e,n)}getGrants(){return this.grantManager.getGrants()}setAllowAll(e){this._allowAll=e}setResolveBase(e){let n=this.resolveBase;if(n!==e){if(this.resolveBase=e,n!==void 0){let r=this._readRoots.indexOf(n);r!==-1?this._readRoots[r]=e:this._readRoots.includes(e)||this._readRoots.push(e);let o=this._writeRoots.indexOf(n);o!==-1?this._writeRoots[o]=e:this._writeRoots.includes(e)||this._writeRoots.push(e)}else this._readRoots.includes(e)||this._readRoots.push(e),this._writeRoots.includes(e)||this._writeRoots.push(e);this.subagentExecutor?.setCwd(e),this.skillExecutor?.setCwd(e),this.composeExecutor?.setCwd(e)}}get toolDefs(){let e=this.permissions?.allowedTools;if(!e)return this.schemas;let n=new Set(e);return this.schemas.filter(r=>n.has(r.name))}async checkReadOnlyBash(e){if(!this.readOnlyBash||e.name!=="bash")return null;let n=e.input,r=typeof n=="object"&&n!==null?n.command:void 0;if(typeof r!="string")return null;let o=ha(r);if(!o.mutating)return null;let s=`Bash command blocked: read-only skill may not run mutating commands (${o.reason??"mutation detected"}). Allowed: read-only recon (git status/log/diff, ls, cat, find, grep).`;return await this.emitPreToolUseBlock(e.name,s),{content:s,isError:!0,failureClass:"permission-denied"}}async emitPreToolUseBlock(e,n){await et(this.traceWriter,{hookEvent:"PreToolUse",decision:"block",blockedTool:e,reason:n,...this.subagentId!==void 0?{subagentId:this.subagentId}:{}})}checkRepeatCircuitBreaker(e){if(SO.has(e.name))return null;let n=xb(e);return this.repeatBreaker!==null&&this.repeatBreaker.fingerprint===n?this.repeatBreaker.count+=1:this.repeatBreaker={fingerprint:n,count:1},this.repeatBreaker.count<wO?null:{content:`Loop circuit breaker: "${e.name}" has been called ${this.repeatBreaker.count} times in a row with byte-identical input. The result will not change. Stop repeating this call \u2014 reuse the previous result, change the input, try a different tool, or end the turn.`,isError:!0,circuitBreaker:!0}}observeSuspectedLoop(e){if(this.parentSessionId===void 0)return;this.suspectedLoopWindow===null&&(this.suspectedLoopWindow=Ob());let n=Db(e),r=Fb(this.suspectedLoopWindow,n);r.fired&&X(this.traceWriter,{phase:"suspected_loop",metadata:{tool:e.name,count:r.count,windowSize:vu}})}recordForkReadDenial(e,n,r){if(this.parentSessionId===void 0||!Cb.has(e.name)||!Ib(n))return r;let o=this.denialBreaker??{count:0,deniedPaths:[]};o.count+=1;let s=Pb(e);return o.deniedPaths.includes(s)||o.deniedPaths.push(s),this.denialBreaker=o,o.count<5?r:{content:Mb(o.deniedPaths,o.count),isError:!0,failureClass:yr}}resetDenialBreaker(){this.denialBreaker=null}async runCanUseTool(e){if(!this.canUseTool)return null;let n;try{n=await this.canUseTool(e.name,e.input??{},{signal:e.signal,toolUseID:e.id})}catch(r){let o=`Tool "${e.name}" denied by canUseTool (threw): ${r instanceof Error?r.message:String(r)}`;return await this.emitPreToolUseBlock(e.name,o),{content:o,isError:!0,failureClass:"permission-denied"}}if(n.behavior==="deny"){let r=n.message||`Tool "${e.name}" denied by permission policy`;return await this.emitPreToolUseBlock(e.name,r),{content:r,isError:!0,failureClass:"permission-denied"}}return n.updatedInput!==void 0&&(e.input=n.updatedInput),null}async execute(e){if(e.signal.aborted)return{content:"Tool call aborted",isError:!0,failureClass:"abort"};if(this.hookRegistry){let a={event:"PreToolUse",toolName:e.name,input:e.input,...this.sessionId!==void 0?{sessionId:this.sessionId}:{},...this.resolveBase!==void 0?{cwd:this.resolveBase}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{}};try{await cu(this.hookRegistry,a,{signal:e.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(l){if(l instanceof ne)return this.recordForkReadDenial(e,l.reason,{content:`Tool "${e.name}" blocked by PreToolUse hook: ${l.message}`,isError:!0,failureClass:"hook-block"});throw l}}let n=mu(e.name,this.permissions);if(!n.allowed){let a=n.reason??`Tool "${e.name}" is not permitted`;return await this.emitPreToolUseBlock(e.name,a),{content:a,isError:!0,failureClass:"permission-denied"}}let r=await this.runCanUseTool(e);if(r)return r;let o=await this.checkReadOnlyBash(e);if(o)return o;let s=this.checkRepeatCircuitBreaker(e);if(s)return s;this.observeSuspectedLoop(e);let i=await this.executeCore(e);return i.isError!==!0&&this.resetDenialBreaker(),i}async executeBatch(e){if(e.length===0)return[];if(e.length===1)return[await this.execute(e[0])];let n=new Array(e.length),r=new Set;for(let i=0;i<e.length;i++){let a=e[i];if(a.signal.aborted){n[i]={content:"Tool call aborted",isError:!0,failureClass:"abort"},r.add(i);continue}if(this.hookRegistry){let p={event:"PreToolUse",toolName:a.name,input:a.input,...this.sessionId!==void 0?{sessionId:this.sessionId}:{},...this.resolveBase!==void 0?{cwd:this.resolveBase}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{}};try{await cu(this.hookRegistry,p,{signal:a.signal,...this.traceWriter?{traceWriter:this.traceWriter}:{}})}catch(f){if(f instanceof ne){n[i]=this.recordForkReadDenial(a,f.reason,{content:`Tool "${a.name}" blocked by PreToolUse hook: ${f.message}`,isError:!0,failureClass:"hook-block"}),r.add(i);continue}throw f}}let l=mu(a.name,this.permissions);if(!l.allowed){let p=l.reason??`Tool "${a.name}" is not permitted`;await this.emitPreToolUseBlock(a.name,p),n[i]={content:p,isError:!0,failureClass:"permission-denied"},r.add(i);continue}let c=await this.runCanUseTool(a);if(c){n[i]=c,r.add(i);continue}let d=await this.checkReadOnlyBash(a);if(d){n[i]=d,r.add(i);continue}let u=this.checkRepeatCircuitBreaker(a);if(u){n[i]=u,r.add(i);continue}this.observeSuspectedLoop(a)}let o=e.map((i,a)=>({call:i,originalIndex:a})).filter((i,a)=>!r.has(a));if(o.length===0)return n;let s=Tb(o.map(i=>i.call),this.classifier);for(let i of s){if(i.isConcurrencySafe){let l=await hr(i.indices,this.maxConcurrentSafeCalls,async c=>{let{call:d,originalIndex:u}=o[c];return d.signal.aborted?{result:{content:"Tool call aborted",isError:!0,failureClass:"abort"},originalIndex:u}:{result:await this.executeCore(d),originalIndex:u}});for(let c of l)if(c.status==="fulfilled")n[c.value.originalIndex]=c.value.result;else{let d=c.reason instanceof Error?c.reason.message:String(c.reason),u=i.indices[l.indexOf(c)];n[o[u].originalIndex]={content:`Tool execution error: ${d}`,isError:!0}}}else for(let l of i.indices){let{call:c,originalIndex:d}=o[l];if(c.signal.aborted){n[d]={content:"Tool call aborted",isError:!0,failureClass:"abort"};continue}n[d]=await this.executeCore(c)}let a=i.indices.length;i.indices.forEach((l,c)=>{let d=n[o[l].originalIndex];d&&(d.batchIndex=c+1,d.batchSize=a)})}return n.some(i=>i!==void 0&&i.isError!==!0)&&this.resetDenialBreaker(),n}async executeCore(e){let n=await this.executeCoreInner(e);return this.applyOutputCap(n)}applyOutputCap(e){let n=this.maxOutputBytes;if(n===void 0)return e;let r=Buffer.byteLength(e.content,"utf8");return r<=n||(e.content=Ct(e.content,n),e.truncated=!0,N(`[output-cap #661] fork tool result capped: original=${r}B capped=${Buffer.byteLength(e.content,"utf8")}B (cap=${n}B)`)),e}async executeCoreInner(e){if(e.name==="agent"){if(!this.subagentExecutor)return{content:"Agent tool is not available in this session configuration",isError:!0};let i,a=!1,l="";try{i=await this.subagentExecutor.execute(e)}catch(c){a=!0,l=c instanceof Error?c.message:String(c),i={content:`Agent tool error: ${l}`,isError:!0}}return a?this.firePostToolUseFailure(e.name,l,e.signal,e.input):this.firePostToolUse(e.name,i.content,e.signal,e.input,i),i}if(e.name==="skill"){if(!this.skillExecutor)return{content:"Skill tool is not available in this session configuration",isError:!0};let i,a=!1,l="";try{i=await this.skillExecutor.execute(e)}catch(c){a=!0,l=c instanceof Error?c.message:String(c),i={content:`Skill tool error: ${l}`,isError:!0}}return a?this.firePostToolUseFailure(e.name,l,e.signal,e.input):this.firePostToolUse(e.name,i.content,e.signal,e.input,i),i}if(e.name==="compose"){let i=await this.executeCompose(e);return this.firePostToolUse(e.name,i.content,e.signal,e.input,i),i}let n=this.handlers.get(e.name);if(!n)return{content:`Unknown tool "${e.name}". Available tools: ${[...this.handlers.keys()].join(", ")}`,isError:!0};let r,o=!1,s="";try{r=await n(e.input,e.signal,this.callHandlerContext(e))}catch(i){o=!0,s=i instanceof Error?i.message:String(i),r={content:`Tool execution error: ${s}`,isError:!0}}return o?this.firePostToolUseFailure(e.name,s,e.signal,e.input):this.firePostToolUse(e.name,r.content,e.signal,e.input,r),r}async executeCompose(e){if(!this.composeExecutor)return{content:"Compose tool is not available in this session configuration",isError:!0};try{return await this.composeExecutor.execute(e)}catch(n){return{content:`Compose tool error: ${n instanceof Error?n.message:String(n)}`,isError:!0}}}firePostToolUse(e,n,r,o,s){if(!this.hookRegistry)return;let i={event:"PostToolUse",toolName:e,output:n,...o!==void 0?{input:o}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{},...this.sessionGrantManager!==void 0?{grantManager:this.sessionGrantManager}:{},...s?.incomplete===!0?{incomplete:!0}:{},...s?.incompleteReason?{incompleteReason:s.incompleteReason}:{}};mb(this.hookRegistry,i,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(()=>{})}firePostToolUseFailure(e,n,r,o){if(!this.hookRegistry)return;let s={event:"PostToolUseFailure",toolName:e,error:n,...o!==void 0?{input:o}:{},...this.parentSessionId!==void 0?{parentSessionId:this.parentSessionId}:{}};gb(this.hookRegistry,s,{signal:r,...this.traceWriter?{traceWriter:this.traceWriter}:{}}).catch(i=>{N(`firePostToolUseFailure outer catch (tool=${e}): ${String(i)}`)})}}});function MO(t){let e=t.match(kO);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10),o=e[3]!==void 0?parseInt(e[3],10):void 0;return{runner:"vitest",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function OO(t){let e=t.match(_O);if(!e)return null;let n=parseInt(e[1]??"0",10);return{runner:"jest",passed:parseInt(e[2]??"0",10),failed:n}}function DO(t){let e=t.match(EO);if(!e)return null;if(e[2]!==void 0){let n=parseInt(e[2],10),r=parseInt(e[1]??"0",10);return{runner:"pytest",passed:n,failed:r}}return e[4]!==void 0?{runner:"pytest",passed:parseInt(e[4],10),failed:0}:null}function FO(t){let e=t.match(AO);if(!e)return null;let n=parseInt(e[1]??"0",10),r=t.match(TO),o=r?parseInt(r[1]??"0",10):0;return{runner:"mocha",passed:n,failed:o}}function LO(t){let e=[...t.matchAll(xO)];if(e.length===0)return null;let n=0,r=0;for(let o of e)o[1]==="ok"?n++:o[1]==="FAIL"&&r++;return{runner:"go-test",passed:n,failed:r}}function NO(t){let e=t.match(RO);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10),o=e[3]!==void 0?parseInt(e[3],10):void 0;return{runner:"cargo",passed:n,failed:r,...o!==void 0?{skipped:o}:{}}}function $O(t){let e=t.match(CO);if(!e)return null;let n=parseInt(e[1]??"0",10),r=parseInt(e[2]??"0",10);return{runner:"rspec",passed:n-r,failed:r}}function UO(t){let e=t.match(IO);if(e)return{runner:"phpunit",passed:parseInt(e[1]??"0",10),failed:0};let n=t.match(PO);if(n){let r=parseInt(n[1]??"0",10),o=parseInt(n[2]??"0",10);return{runner:"phpunit",passed:r-o,failed:o}}return null}function _u(t){return MO(t)??OO(t)??DO(t)??FO(t)??LO(t)??NO(t)??$O(t)??UO(t)??null}var kO,_O,EO,AO,TO,xO,RO,CO,IO,PO,Nb=y(()=>{"use strict";kO=/Tests\s+(\d+)\s+passed(?:\s*\|\s*(\d+)\s+failed)?(?:\s*\|\s*(\d+)\s+skipped)?/,_O=/Tests:\s+(?:(\d+)\s+failed,\s*)?(\d+)\s+passed,\s*\d+\s+total/,EO=/={3,}\s*(?:(\d+)\s+failed,\s*)?(\d+)\s+passed(?:,\s*(\d+)\s+warning)?.*in\s+[\d.]+s\s*={3,}|={3,}\s*(\d+)\s+passed.*in\s+[\d.]+s\s*={3,}/,AO=/(\d+)\s+passing/,TO=/(\d+)\s+failing/,xO=/^(ok|FAIL)\s+\S+\s+[\d.]+s/gm,RO=/test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed(?:; (\d+) ignored)?/,CO=/(\d+) examples?, (\d+) failures?/,IO=/OK \((\d+) tests?/,PO=/Tests:\s*(\d+)[^]*?Failures:\s*(\d+)/});import{statSync as BO}from"node:fs";function xo(t){if(typeof t!="object"||t===null)return!1;let e=t;return e.code==="ENOENT"&&typeof e.syscall=="string"&&e.syscall.startsWith("spawn")}function HO(t){if(t===void 0)return!1;try{return BO(t),!1}catch{return!0}}function br(t,e){let n=t instanceof Error?t.message:typeof t?.message=="string"?String(t.message):String(t);return xo(t)&&HO(e)?`working directory does not exist: ${e} (deleted worktree?) \u2014 underlying: ${n}`:n}var Eu=y(()=>{"use strict"});function yt(t){if($b)return;$b=!0;let e=t instanceof Error?t.message:String(t);console.warn(`[afk-home] Malformed AFK home/state env var ignored while deriving the credential floor: ${e}. The relocated tree is NOT protected \u2014 the default ~/.afk entries still apply. Fix the env var to restore coverage.`)}var $b,Ro=y(()=>{"use strict";$b=!1});import{realpathSync as Ub}from"fs";import{dirname as jO,resolve as Pn,join as Au}from"path";import{homedir as Vt}from"os";function KO(){let t=[];try{let e=oe();t.push(_e(Pn(Au(e,"config")))),t.push(_e(Pn(Au(e,"state"))))}catch(e){yt(e)}try{t.push(_e(Pn(we())))}catch(e){yt(e)}return t}function Tu(){let t=_.AFK_WRITE_DENYLIST,e=t?t.split(":").map(r=>_e(Pn(r))).filter(Boolean):[];return[...[...new Set([...WO.map(r=>_e(Pn(r))),...KO()])],...e]}function _e(t){let e=Pn(t);try{return Ub(e)}catch{}let n=[],r=e;for(let o=0;o<64;o++){let s=jO(r);if(s===r)break;n.unshift(r.slice(s.length+1)),r=s;try{let i=Ub(r);return Au(i,...n)}catch{}}return e}function Sa(t,e="write_file"){let n=_e(Pn(t));for(let r of Tu())if(n===r||n.startsWith(r+"/"))throw new Error(`${e}: refusing to write to protected path: ${n} (matches denylist entry: ${r})`)}var WO,Co=y(()=>{"use strict";H();K();Ro();WO=[`${Vt()}/.ssh`,`${Vt()}/.aws`,`${Vt()}/.gnupg`,`${Vt()}/.config/gcloud`,"/etc","/System","/private/etc","/usr/local/etc",`${Vt()}/.afk/config`,`${Vt()}/.afk/state`,`${Vt()}/.npmrc`,`${Vt()}/.docker/config.json`]});import{basename as GO,dirname as qO,join as va,relative as zO,resolve as wr,sep as Bb}from"path";import{homedir as ge}from"os";function jb(t){let e=wr(t);return va(_e(qO(e)),GO(e))}function Ru(t){return t?t.split(":").map(e=>e.trim()).filter(Boolean).map(e=>e==="~"||e.startsWith("~/")?va(ge(),e.slice(1)):e).map(e=>wr(e)):[]}function VO(){try{return[_e(wr(va(oe(),"config")))]}catch(t){return yt(t),[]}}function YO(){try{let t=oe();return Sr.filter(e=>e.startsWith(Hb)).map(e=>jb(va(t,e.slice(Hb.length))))}catch(t){return yt(t),[]}}function Wb(){let t=`${_.AFK_READ_DENYLIST??""}\0${_.AFK_HOME??""}`;if(Io&&Io.key===t)return Io;let e=Ru(_.AFK_READ_DENYLIST).map(r=>_e(r)).filter(Boolean),n=[...new Set([...xu.map(r=>_e(wr(r))),...VO()])];return Io={key:t,builtins:n,extras:e,allow:[...new Set([...JO.map(jb),...YO()])]},Io}function Cu(){let{builtins:t,extras:e}=Wb();return[...t,...e]}function Kb(t){let e=_e(wr(t));return Cu().map(r=>zO(e,r)).filter(r=>r!==""&&r!==".."&&!r.startsWith(`..${Bb}`)).map(r=>r.split(Bb).join("/"))}function Ye(t){let e=_e(wr(t)),{builtins:n,extras:r,allow:o}=Wb();for(let s of r)if(e===s||e.startsWith(s+"/"))return{denied:!0,matched:s};if(o.includes(e))return{denied:!1};for(let s of n)if(e===s||e.startsWith(s+"/"))return{denied:!0,matched:s};return{denied:!1}}var xu,Sr,JO,Io,Hb,Yt=y(()=>{"use strict";H();Co();K();Ro();xu=[`${ge()}/.ssh`,`${ge()}/.aws`,`${ge()}/.gnupg`,`${ge()}/.config/gcloud`,`${ge()}/.afk/config`,`${ge()}/.npmrc`,`${ge()}/.docker/config.json`,`${ge()}/.git-credentials`,`${ge()}/.netrc`,`${ge()}/.config/gh/hosts.yml`,`${ge()}/.kube/config`,"/etc/shadow","/etc/sudoers","/private/etc/master.passwd",`${ge()}/.password-store`,`${ge()}/Library/Application Support/Google/Chrome`,`${ge()}/Library/Application Support/Chromium`,`${ge()}/Library/Application Support/BraveSoftware`,`${ge()}/Library/Application Support/Microsoft Edge`,`${ge()}/Library/Application Support/Arc`,`${ge()}/Library/Application Support/Firefox`],Sr=[".afk/config/mcp.json",".ssh/config",".ssh/known_hosts"],JO=Sr.map(t=>`${ge()}/${t}`);Hb=".afk/"});import Mn from"path";import{realpathSync as XO}from"fs";function Xe(t){try{return XO.native(t)}catch{let e=Mn.dirname(t),n=Mn.basename(t);return e===t?t:Mn.join(Xe(e),n)}}function QO(t){let e=Gb.get(t);if(e!==void 0)return e;let n=Xe(t);return Gb.set(t,n),n}function qb(t,e,n,r){let o=e?.resolveBase??e?.cwd??r,s=Mn.isAbsolute(t)?t:Mn.resolve(o??process.cwd(),t);if(e?.allowAll===!0)return{restricted:!1,resolved:s,roots:[]};if(o===void 0)return{restricted:!1,resolved:s,roots:[]};let i=Xe(s),a=n==="read"?e?.readRoots??[o]:e?.writeRoots??[o];for(let l of a){let c=QO(l),d=Mn.relative(c,i);if(!d.startsWith("..")&&!Mn.isAbsolute(d))return{restricted:!1,resolved:s,roots:a}}return{restricted:!0,resolved:s,roots:a}}function Qe(t,e,n="read",r){let{restricted:o,resolved:s,roots:i}=qb(t,e,n,r);if(n==="read"){let a=Ye(s);if(a.denied)throw new Error(`Path \`${t}\` is a protected credential/secret path (read-denylist entry: \`${a.matched}\`) and cannot be read.`)}if(o){let a=i.map(c=>`\`${c}\``).join(", "),l=n==="read"?"read roots":"write roots";throw new Error(`Path \`${t}\` is outside the allowed ${l} [${a}].`)}return s}function Po(t,e,n="read",r){return qb(t,e,n,r)}function zb(t){let e=new Set,n=[];for(let r of t.split(/\s+/)){if(r.length===0)continue;let o=r.replace(/^\d*[<>|&]+/,"").replace(/^['"]/,"").replace(/['";,)]+$/,"");if(o.length===0)continue;let s=o.startsWith("/"),i=o==="~"||o.startsWith("~/");!s&&!i||e.has(o)||(e.add(o),n.push(o))}return n}var Gb,ot=y(()=>{"use strict";Yt();Gb=new Map});import{spawn as ZO}from"child_process";import e0 from"os";function t0(t){if(typeof t!="object"||t===null)throw new Error("Input must be an object");let e=t;if(typeof e.command!="string")throw new Error('Input must have a "command" field of type string');let n=12e4;if(e.timeout_ms!==void 0){if(typeof e.timeout_ms!="number")throw new Error("timeout_ms must be a number");if(e.timeout_ms<0||e.timeout_ms>6e5)throw new Error("timeout_ms must be between 0 and 600000");n=e.timeout_ms}return{command:e.command,timeout_ms:n}}function ka(t,e){let n=!1,r=!1;function o(){n||t==="bypassPermissions"&&(n=!0,console.warn("[security] bash handler: shell=true with bypassPermissions \u2014 all shell metacharacters are interpreted without confirmation. Migrate to execFile to eliminate this risk (tracked: C4)."))}function s(i,a){if(r)return;let l=a.resolveBase??a.cwd??e,c=e0.homedir(),d=[];for(let u of zb(i)){let p=u==="~"?c:u.startsWith("~/")?c+u.slice(1):u,f=Po(p,a,"write",l);f.restricted&&d.push(f.resolved)}d.length!==0&&(r=!0,console.warn(`[security] bash: command references path(s) outside writeRoots: ${d.join(", ")} \u2014 bash containment is best-effort (tracked C4); use file tools for contained writes.`),le({event:"tool.bash_path_escape",tool:"bash",restricted_count:d.length,mode:"write"}))}return async(i,a,l)=>{let{command:c,timeout_ms:d}=t0(i);if(a.aborted)return{content:"Command aborted",isError:!0};if(o(),l!==void 0)try{s(c,l)}catch{}return new Promise(u=>{let p=!1;function f(T){p||(p=!0,clearTimeout(g),a.removeEventListener("abort",A),u(T))}let m=ZO(c,{shell:!0,detached:!0,stdio:["ignore","pipe","pipe"],...(l?.resolveBase??l?.cwd??e)!==void 0?{cwd:l?.resolveBase??l?.cwd??e}:{},...l?.env!==void 0?{env:{...process.env,...l.env}}:{}});m.unref();let g=setTimeout(()=>{m.pid!==void 0&&process.kill(-m.pid,"SIGKILL"),f({content:`Command timed out after ${d}ms`,isError:!0})},d),h="",w="",k=0,E=!1;function v(T){if(E||p||k<8e6)return;E=!0,console.warn(`[bash] overflow kill: stream=${T} totalBytes=${k} command="${c}"`),le({event:"tool.overflow_kill",tool:"bash",total_bytes:k,stream:T}),m.kill("SIGKILL");let x=mt((h+w).trimEnd()),S=_u(x)??void 0,R=Ct(x,1e5)+ya;f({content:R,truncated:!0,...S!==void 0?{testResult:S}:{}})}m.stdout.on("data",T=>{let x=8e6-k,S=T.length<=x?T:T.subarray(0,Math.max(0,x));k+=S.length,h+=S.toString("utf8"),v("stdout")}),m.stderr.on("data",T=>{let x=8e6-k,S=T.length<=x?T:T.subarray(0,Math.max(0,x));k+=S.length,w+=S.toString("utf8"),v("stderr")});let A=()=>{m.pid!==void 0&&process.kill(-m.pid,"SIGKILL"),f({content:"Command aborted",isError:!0})};a.addEventListener("abort",A),a.aborted&&A(),m.on("close",T=>{if(a.aborted){f({content:"Command aborted",isError:!0});return}if(T!==null&&T!==0){let I=zt(w.trimEnd()||h.trimEnd());f({content:`Command exited with code ${T}${I.content?`
855
855
  `+I.content:""}`,isError:!0,...I.truncated?{truncated:!0}:{}});return}if(E)return;let x=mt((h+w).trimEnd()),S=_u(x)??void 0,R=zt(x);f({content:R.content,...R.truncated?{truncated:!0}:{},...S!==void 0?{testResult:S}:{}})}),m.on("error",T=>{let x=l?.resolveBase??l?.cwd??e,S;if(x===void 0&&xo(T))try{let R=process.cwd();S=br(T,R)}catch{S=`working directory does not exist (process cwd deleted \u2014 deleted worktree?) \u2014 underlying: ${T.message}`}else S=br(T,x);f({content:`Failed to execute: ${S}`,isError:!0})})})}}var Jb,Vb=y(()=>{"use strict";ht();Nb();vn();Eu();Rn();ot();Jb=ka("default")});import{promises as n0}from"fs";function Iu(t){return(e,n,r)=>r0(e,n,r,t)}var r0,Yb,Xb=y(()=>{"use strict";ot();r0=async(t,e,n,r)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected an object",isError:!0};let o=t,s=o.file_path,i=o.offset??1,a=o.limit??2e3;if(typeof s!="string")return{content:"Invalid input: file_path must be a string",isError:!0};if(typeof i!="number"||i<1)return{content:"Invalid input: offset must be a positive number",isError:!0};if(typeof a!="number"||a<1)return{content:"Invalid input: limit must be a positive number",isError:!0};let l;try{l=Qe(s,n,"read",r)}catch(c){return{content:c instanceof Error?c.message:String(c),isError:!0}}try{let c=await n0.readFile(l),d=Math.min(8192,c.length);for(let E=0;E<d;E++)if(c[E]===0)return{content:`File appears to be binary: ${l}`,isError:!0};let u=c.toString("utf-8");if(u.length===0)return{content:""};let p=u.split(`
856
856
  `),f=Math.max(0,i-1),m=Math.min(p.length,f+a),g=p.slice(f,m),h=p.length;if(g.length===0)return{content:`... (offset ${i} is past end of file \u2014 file has ${h} lines)`};let w=String(h).length,k=g.map((E,v)=>{let A=f+v+1;return`${String(A).padStart(w," ")} ${E}`}).join(`
857
857
  `);if(g.length<h){let E=f+1,v=f+g.length,A=v<h?` \u2014 pass offset=${v+1} to continue`:"";return{content:`${k}
@@ -862,7 +862,7 @@ Remedy: these paths are outside the fork's granted read roots. Re-dispatch with
862
862
 
863
863
  `).trim()}function M0(t){return(t?.textContent??"").replace(/\s+/g," ").trim().length}async function hw(t,e){let{JSDOM:n,Readability:r,turndown:o}=await P0(),i=new n(t,{url:e}).window.document,a=(i.title??"").trim(),l=(()=>{try{let p=i.cloneNode(!0);return new r(p).parse()}catch{return null}})();if(l&&typeof l.content=="string"&&l.content.trim().length>0){let p=gw(o.turndown(l.content)),f=(l.title??"").trim()||a,m=typeof l.length=="number"&&l.length>0?l.length:(l.textContent??"").replace(/\s+/g," ").trim().length;return{title:f,markdown:p,textLength:m,usedFallback:!1}}let c=i.body,d=c?.innerHTML??"",u=gw(o.turndown(d));return{title:a,markdown:u,textLength:M0(c),usedFallback:!0}}var Nu,yw=y(()=>{"use strict";Nu=null});function D0(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 bw(t,e,n){let r=Math.min(e*2**t,n);return Math.round(Math.random()*r)}function F0(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 ww(t,e,n={},r={}){let o=r.retries??3,s=r.baseDelayMs??500,i=r.maxDelayMs??1e4,a=r.sleep??D0,l=n.signal??void 0,c;for(let d=0;d<=o;d++){if(l?.aborted)throw l.reason??new Error("aborted");try{let u=await t(e,n);if(!O0.has(u.status)||d===o)return u;let p=F0(u,i)??bw(d,s,i);N("[web/retryFetch] retrying",{url:e,attempt:d,status:u.status,waitMs:p}),await u.body?.cancel().catch(()=>{}),await a(p,l)}catch(u){if(l?.aborted||(c=u,d===o))throw u;let p=bw(d,s,i);N("[web/retryFetch] retrying after error",{url:e,attempt:d,waitMs:p}),await a(p,l)}}throw c??new Error("retryFetch: exhausted without a result")}var O0,Sw=y(()=>{"use strict";me();O0=new Set([429,502,503,504])});import{BlockList as L0,isIP as Uu}from"node:net";import{lookup as N0}from"node:dns/promises";import{Agent as $0}from"undici";function kw(){let t=_.AFK_WEB_ALLOW_PRIVATE_HOSTS?.trim().toLowerCase();return t==="1"||t==="true"}function j0(t){return t.startsWith("[")&&t.endsWith("]")?t.slice(1,-1):t}function $u(t){let e=Uu(t);return e===0?!1:H0.check(t,e===4?"ipv4":"ipv6")}async function _w(t){return N0(t,{all:!0,verbatim:!0})}async function Bu(t,e={}){if(e.allowPrivateHosts??kw())return{allowed:!0};let n;try{n=new URL(t)}catch{return{allowed:!1,reason:`"${t}" is not a valid absolute URL`}}if(n.protocol!=="http:"&&n.protocol!=="https:")return{allowed:!1,reason:`protocol "${n.protocol}" not supported (http/https only)`};let r=j0(n.hostname),o=(a,l)=>`refusing to fetch ${l} \u2014 internal/private address ${a} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`;if(Uu(r)!==0)return $u(r)?{allowed:!1,reason:o(r,r)}:{allowed:!0};let s=e.lookupFn??_w,i;try{i=await s(r)}catch{return{allowed:!0}}for(let a of i)if($u(a.address))return{allowed:!1,reason:o(a.address,`${r} (resolved)`)};return{allowed:!0}}async function Oo(t,e={}){let n=await Bu(t,e);if(!n.allowed)throw new st(n.reason)}async function Ea(t,e,n={},r={}){let o={...r.lookupFn!==void 0?{lookupFn:r.lookupFn}:{},...r.allowPrivateHosts!==void 0?{allowPrivateHosts:r.allowPrivateHosts}:{}},s=e;for(let i=0;i<=vw;i++){await Oo(s,o);let a={...n,redirect:"manual",...t===globalThis.fetch&&!(r.allowPrivateHosts??kw())?{dispatcher:W0}:{}},l=await ww(t,s,a,r.retry??{});if(!K0.has(l.status))return l;let c=l.headers.get("location");if(c===null||c.trim()==="")return l;let d;try{d=new URL(c,l.url||s).toString()}catch{return l}await l.body?.cancel().catch(()=>{}),s=d}throw new st(`too many redirects (>${vw}) starting from ${e}`)}var U0,B0,H0,st,W0,vw,K0,Hu=y(()=>{"use strict";H();Sw();U0=[["0.0.0.0",8],["10.0.0.0",8],["100.64.0.0",10],["127.0.0.0",8],["169.254.0.0",16],["172.16.0.0",12],["192.168.0.0",16]],B0=[["::",96],["64:ff9b::",96],["fc00::",7],["fe80::",10]],H0=(()=>{let t=new L0;for(let[e,n]of U0)t.addSubnet(e,n,"ipv4");for(let[e,n]of B0)t.addSubnet(e,n,"ipv6");return t})(),st=class extends Error{constructor(e){super(e),this.name="EgressBlockedError"}};W0=new $0({connect:{lookup(t,e,n){_w(t).then(r=>{let o=r.find(i=>$u(i.address));if(o!==void 0){n(new st(`refusing to connect to ${t} (resolved) \u2014 internal/private address ${o.address} (loopback, link-local, cloud metadata, or RFC1918 space). Set AFK_WEB_ALLOW_PRIVATE_HOSTS=1 to allow private-host access.`),"",0);return}let s=r[0];if(s===void 0){n(new Error(`DNS lookup returned no addresses for ${t}`),"",0);return}n(null,s.address,Uu(s.address))},r=>n(r,"",0))}}});vw=20,K0=new Set([301,302,303,307,308])});import{readFileSync as G0}from"node:fs";import{join as q0}from"path";function z0(t){let n=t.replace(/[.+?()[\]{}/\\^$|]/g,"\\$&").replace(/\*/g,"[^.]*");return new RegExp(`^${n}$`,"i")}function Ew(t,e){return z0(e).test(t)}function Y0(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(J0.has(e))return!0;if(V0.has(e))return!1}return!1}function Aw(t){return t===void 0||t.trim()===""?[]:t.split(",").map(e=>e.trim().toLowerCase()).filter(e=>e.length>0)}function X0(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 Tw(t){let e=t===void 0||t.trim()===""?"default":t.trim();return zc(e),e}function Q0(t){if(t===void 0)return!1;let e=t.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function Z0(t){try{return G0(t,"utf8")}catch(e){if(e.code==="ENOENT")return;throw e}}function eD(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=Tw(e.defaultProfile)),n}function xw(t){let e=t?.env??_,n=t?.readFileSync??Z0,r=t?.surface??e.AGENT_SURFACE,o=Y0(e.AFK_BROWSER_HEADLESS,r),s=Aw(e.AFK_BROWSER_ALLOWED_DOMAINS),i=Aw(e.AFK_BROWSER_BLOCKED_DOMAINS),a=Q0(e.AFK_BROWSER_DOM_SNAPSHOTS),l=X0(e.AFK_BROWSER_BACKEND),c=Tw(e.AFK_BROWSER_DEFAULT_PROFILE),d={headless:o,allowedDomains:s,blockedDomains:i,domSnapshots:a,backend:l,configPath:null,defaultProfile:c},u=e.AFK_BROWSER_CONFIG,p=u!==void 0&&u.trim()!==""?u.trim():q0(_t(),"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=eD(d,m);return g.configPath=p,g}function Aa(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(Ew(n,r))return{allowed:!1,reason:`blocked by AFK_BROWSER_BLOCKED_DOMAINS: ${r}`};return e.allowedDomains.length>0&&!e.allowedDomains.some(o=>Ew(n,o))?{allowed:!1,reason:"not in AFK_BROWSER_ALLOWED_DOMAINS"}:{allowed:!0}}var J0,V0,Ta=y(()=>{"use strict";H();K();J0=new Set(["daemon","subagent","telegram","afk"]),V0=new Set(["repl","interactive","cli"])});import{existsSync as tD,readFileSync as nD}from"node:fs";import{createRequire as rD}from"node:module";import{dirname as oD,join as sD}from"node:path";function Iw(t){if(typeof t=="string")return t;let e=[],n=t;for(let r=0;r<aD&&n instanceof Error;r++)e.push(n.message),n=n.cause;return e.length>0?e.join(" | "):String(t)}function Pe(t){let e=Iw(t);return Cw.some(n=>e.includes(n))}function lD(){try{let e=rD(import.meta.url).resolve("playwright/package.json"),n=JSON.parse(nD(e,"utf8"));if(typeof n!="object"||n===null)return;let r=n.bin,o=typeof r=="string"?r:typeof r=="object"&&r!==null?r.playwright:void 0;if(typeof o!="string"||o.length===0)return;let s=sD(oD(e),o);return tD(s)?`node ${/\s/.test(s)?`"${s}"`:s} install chromium`:void 0}catch{return}}function Do(){return Rw??=lD()??iD,Rw}function ju(t){return t.includes("install chromium")}function Ze(t,e){let n=Iw(t),r=e?.latched===!0?` ${cD}`:"";if(n.includes("Executable doesn't exist")){let o="";return e?.headless===!0?o=" This launch was headless, which needs the `chromium_headless_shell-*` build.":e?.headless===!1&&(o=" This launch was headed, which needs the full `chromium-*` build \u2014 the headless shell alone does not satisfy it."),`browser tools require the Playwright chromium binary. Install via: ${Do()}.${o}${r}`}return`browser tools require the optional \`playwright\` peer dependency. Install via: pnpm add playwright (then ${Do()}). Or pick a different tool.${r}`}function Wu(t,e,n=!1){if(!Pe(t))return t;let r=t instanceof Error?t.message:String(t);return new Error(`${r}
864
864
 
865
- ${Ze(t,{headless:e,latched:n})}`,{cause:t})}var Cw,iD,aD,Rw,cD,Ku=y(()=>{"use strict";Cw=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],iD="pnpm exec playwright install chromium",aD=4;cD="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import Dn from"node:fs";import xa from"node:path";import{randomBytes as dD}from"node:crypto";import{chromium as uD}from"playwright";function pD(){try{return"5.83.7"}catch{}try{let t=xa.resolve(import.meta.dirname,"../../../package.json"),e=Dn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var fD,Ra,Pw=y(()=>{"use strict";Ku();K();me();fD=pD(),Ra=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=uD.launch({headless:this.config.headless}).then(e=>(this.browser=e,this.launchPromise=void 0,this.clearLaunchFailure(),e)).catch(e=>{this.launchPromise=void 0;let n=Wu(e,this.config.headless,!0);throw this.latchLaunchFailure(n),n}),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(l){s=l,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),l;try{l=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let c=await a.content();if(s!==void 0)throw s;let d=a.url(),u=l!==null?l.status():null;return{html:c,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${fD}`}}loadStorageState(e){let n=Jc(e);try{if(!Dn.existsSync(n))return;let r=JSON.parse(Dn.readFileSync(n,"utf8"));return N("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){N("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Jc(e);if(!Dn.existsSync(r))return;let o=await n.storageState(),s=xa.join(xa.dirname(r),`.${xa.basename(r)}.${process.pid}.${dD(4).toString("hex")}.tmp`);Dn.writeFileSync(s,JSON.stringify(o),{mode:384}),Dn.chmodSync(s,384),Dn.renameSync(s,r),N("[browser/vault] saved session",{profile:e,file:r})}catch(r){N("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as mD}from"crypto";function Mw(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&gD.test(t.label))}function Ow(t){return mD("sha256").update(t,"utf8").digest("hex").slice(0,8)}function Dw(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var gD,Ca=y(()=>{"use strict";gD=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as hD}from"node:crypto";function yD(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function bD(t,e,n){return`el_${hD("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function wD(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Fw(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function Nw(t,e){let n=t.role??"",r=t.name??"";Lw.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])Nw(s,e)}async function SD(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(),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},$w).catch(()=>[])}async function vD(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")??"",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 g=s.type;g==="checkbox"?c="checkbox":g==="radio"?c="radio":g==="button"||g==="submit"||g==="reset"?c="button":g==="search"?c="searchbox":c="textbox"}if(!c)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:c,name:l,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},$w).catch(()=>[])}function kD(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Ia(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=kD(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=SD(t),l=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),c=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,l,c,d]),h,w=!1;u!==null?(h=[],Nw(u,h)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,h=(await vD(t)).filter($=>Lw.has($.role??"")));let k=new Map;for(let P of p){let $=Fw(P.name),G=k.get($);(!G||G.bbox.w===0&&P.bbox.w>0)&&k.set($,P)}let E=h.map(P=>({ax:P,dom:k.get(Fw(P.name??""))})),v=r?E:E.filter(P=>P.dom?P.dom.bbox.w>0||P.dom.bbox.h>0:!0);v.sort((P,$)=>{let G=P.dom?.bbox.y??0,F=$.dom?.bbox.y??0;if(G!==F)return G-F;let B=P.dom?.bbox.x??0,M=$.dom?.bbox.x??0;return B-M}),v.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=v.slice(0,n).map((P,$)=>{let G=P.ax.role??"generic",F=P.ax.name??"",B=bD(G,F,$),M=P.dom?.bbox??{x:0,y:0,w:0,h:0},C=P.dom?.type??null,O=null;P.ax.value!==void 0&&P.ax.value!==null&&(O=String(P.ax.value)),P.ax.checked!==void 0&&(O=String(P.ax.checked)),Mw({role:G,kind:C})&&(O="[redacted]");let U={disabled:P.ax.disabled??!1};P.ax.checked!==void 0&&(U.checked=P.ax.checked===!0||P.ax.checked==="mixed"),P.ax.selected!==void 0&&(U.selected=P.ax.selected),P.ax.expanded!==void 0&&(U.expanded=P.ax.expanded);let q;P.dom?.testId?q=`[data-testid="${P.dom.testId}"]`:P.dom?.id&&(q=`#${P.dom.id}`);let Z={id:B,role:G,label:yD(F),kind:C,value:O,state:U,bbox:M};return q!==void 0&&(Z.selector=q),Z}),x="idle";try{let P=await t.evaluate(()=>document.readyState);P==="loading"?x="loading":P==="interactive"?x="navigating":x="idle"}catch{x="navigating"}x!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),w&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let S=wD(f),R=`obs_${e.observationCounter.toString(36)}`,I=new Date().toISOString();return{observationId:R,url:m,title:g,textSummary:S,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:x,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:I}}var Lw,$w,Uw=y(()=>{"use strict";Ca();Lw=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);$w="a[href], button, input, select, textarea, [role], [tabindex], label"});async function Bw(t,e){try{let n=await t.nth(e).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")??"",d=a.getBoundingClientRect();return{role:l,label:c,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 Gu(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>Bw(t,s)))).filter(o=>o!==null)}async function _D(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 l=a,c=l.getBoundingClientRect();return`${l.tagName}@${Math.round(c.x)},${Math.round(c.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function qu(t,e,n){switch(e.kind){case"element_id":return ED(t,e,n);case"selector":return AD(t,e);case"semantic":return TD(t,e)}}async function ED(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 l=t.locator(r.selector);if(await l.count()===1)return{outcome:"resolved",locator:l}}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 Gu(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function AD(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 Gu(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function TD(t,e){return e.role!==void 0?xD(t,e.text,e.role):RD(t,e.text,e)}async function xD(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 Gu(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function RD(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{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 d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),l>0&&d.push({loc:s,count:l});let u=await _D(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 w=await Bw(h.locator,h.index);if(w!==null){let k=`${w.role}:${w.label}:${g}`,E=0;for(let v=0;v<k.length;v++)E=E*31+k.charCodeAt(v)>>>0;f.push({...w,id:`el_${E.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var Hw=y(()=>{"use strict"});async function zu(t,e,n,r){let o=t.url();if(o===n)return null;let s=Aa(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var jw=y(()=>{"use strict";Ta()});import{randomBytes as CD}from"crypto";import{mkdir as ID,stat as PD,writeFile as MD}from"fs/promises";import{join as Ju}from"path";import{gzip as OD}from"zlib";import{promisify as DD}from"util";function FD(t){return Ju(Ys(t),"browser")}function LD(t){return Ju(FD(t),"screenshots")}function ND(){return new Date().toISOString().replace(/[:.]/g,"-")}function $D(){return CD(3).toString("hex")}async function Vu(t,e,n){if(e.length>Ww)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Ww} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=LD(t);await ID(r,{recursive:!0});let o=`${ND()}-${$D()}-${n}.png`,s=Ju(r,o);await MD(s,e);let{size:i}=await PD(s);return{path:s,bytes:i}}var B5,Ww,Kw=y(()=>{"use strict";K();Ca();B5=DD(OD);Ww=5*1024*1024});var qw={};Bc(qw,{PlaywrightProvider:()=>Yu});function Gw(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 Yu,zw=y(()=>{"use strict";Pw();Uw();Hw();Ta();jw();Kw();Yu=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Ra(e)}async open(e){let n=Aa(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let l=o.url();if(!(a!==null&&(l===""||l==="about:blank"))){let u=await zu(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await Ia(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await Ia(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 qu(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${Gw(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:l}=a,c=null,d=async()=>{switch(e.action){case"click":await l.click({timeout:i});break;case"fill":await l.fill(e.value??"");break;case"press":await l.press(e.value??"");break;case"select":await l.selectOption(e.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 d()}catch(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(h){c=h}else c=g}let u=await zu(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||c!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Ia(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),c!==null)throw c;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await qu(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${Gw(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 Vu(n,s,"browser_screenshot"),l=0,c=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));l=d.w,c=d.h}catch{let d=r.viewportSize();l=d?.width??0,c=d?.height??0}else{let d=r.viewportSize();l=d?.width??0,c=d?.height??0}return{path:i,bytes:a,width:l,height:c,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 Vu(n,o,r);return s}catch{return null}}}});var Ln={};Bc(Ln,{__resetBrowserRegistryForTests:()=>WD,browserProviderActive:()=>HD,closeBrowserProvider:()=>Xu,getBrowserProvider:()=>BD,peekBrowserProvider:()=>jD});function Jw(){Promise.resolve(Xu()).then(()=>{process.exit(130)})}function Vw(){Promise.resolve(Xu()).then(()=>{process.exit(143)})}function Yw(){bt=null}function UD(){Pa||(process.on("SIGINT",Jw),process.on("SIGTERM",Vw),process.on("exit",Yw),Pa=!0)}function Xw(){Pa&&(process.removeListener("SIGINT",Jw),process.removeListener("SIGTERM",Vw),process.removeListener("exit",Yw),Pa=!1)}async function BD(t){return bt!==null?bt:(Fn!==null||(Fn=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(zw(),qw)),n=xw(t),r=new e(n);return UD(),bt=r,Fn=null,r})()),Fn)}async function Xu(){if(bt===null)return;let t=bt;bt=null,Fn=null,Xw(),await t.shutdown()}function HD(){return bt!==null}function jD(){return bt}function WD(){bt=null,Fn=null,Xw()}var bt,Fn,Pa,Nn=y(()=>{"use strict";Ta();bt=null,Fn=null,Pa=!1});async function Qw(t,e){try{return await hw(t,e)}catch(n){return N("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function VD(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Nn(),Ln));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function Zw(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??VD,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i=t,a=null,l=null;try{let d=await Ea(n,t,{headers:JD,signal:e.signal},o);a=d.status,i=d.url||t;let u=d.headers.get("content-type")??"";if(d.ok){if(zD.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 p=await d.text();if(qD.test(u)&&!GD.test(u))return{title:"",markdown:p.trim(),finalUrl:i,usedRender:!1};if(s=await Qw(p,i),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(d){if(e.signal.aborted||d instanceof st||d instanceof Error&&d.message.startsWith("web_scrape markdown mode received binary"))throw d;l=d}if(!(s===null||s.textLength<200)&&s!==null)return{title:s.title,markdown:s.markdown,finalUrl:i,usedRender:!1};try{await Oo(t,o);let d=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:p=>Oo(p,o)});d.finalUrl!==t&&/^https?:\/\//i.test(d.finalUrl)&&await Oo(d.finalUrl,o);let u=await Qw(d.html,d.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||u.textLength>=s.textLength)return{title:u.title,markdown:u.markdown,finalUrl:d.finalUrl,usedRender:!0}}catch(d){if(e.signal.aborted||d instanceof st)throw d;if(s===null){let u=d instanceof Error?d.message:String(d),p=l instanceof Error?l.message:`HTTP ${a??"error"}`,f=new Error(`web_scrape could not retrieve ${t}: fetch failed (${p}) and render failed (${u}).`);throw f.cause=d,f}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:i,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${a??"error"}).`)}var GD,qD,zD,JD,eS=y(()=>{"use strict";yw();Hu();me();GD=/(text\/html|application\/xhtml\+xml)/i,qD=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,zD=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,JD={"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 QD(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(YD,{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),XD),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let l="";try{let d=await s.text(),u=mr(d);u&&(l=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}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 tS(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?QD({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 nS(t,e){if(e.length===0)return`# Search results for "${t}"
865
+ ${Ze(t,{headless:e,latched:n})}`,{cause:t})}var Cw,iD,aD,Rw,cD,Ku=y(()=>{"use strict";Cw=["Cannot find package","ERR_MODULE_NOT_FOUND","Executable doesn't exist"],iD="pnpm exec playwright install chromium",aD=4;cD="This session already latched the failure, so browser tools keep fast-failing with this same error \u2014 after installing, call browser_close once to retry."});import Dn from"node:fs";import xa from"node:path";import{randomBytes as dD}from"node:crypto";import{chromium as uD}from"playwright";function pD(){try{return"5.83.8"}catch{}try{let t=xa.resolve(import.meta.dirname,"../../../package.json"),e=Dn.readFileSync(t,"utf8"),n=JSON.parse(e);return typeof n.version=="string"?n.version:"unknown"}catch{return"unknown"}}var fD,Ra,Pw=y(()=>{"use strict";Ku();K();me();fD=pD(),Ra=class{config;browser;sessions=new Map;launchPromise;launchFailure;shutdownComplete=!1;constructor(e){this.config=e}clearLaunchFailure(){this.launchFailure=void 0}latchLaunchFailure(e){this.launchFailure={error:e}}async ensureBrowser(){if(this.browser!==void 0&&this.browser.isConnected())return this.browser;if(this.launchFailure!==void 0)throw this.launchFailure.error;return this.browser!==void 0&&!this.browser.isConnected()&&(this.browser=void 0,this.launchPromise=void 0),this.launchPromise!==void 0?this.launchPromise:(this.launchPromise=uD.launch({headless:this.config.headless}).then(e=>(this.browser=e,this.launchPromise=void 0,this.clearLaunchFailure(),e)).catch(e=>{this.launchPromise=void 0;let n=Wu(e,this.config.headless,!0);throw this.latchLaunchFailure(n),n}),this.launchPromise)}isBrowserActive(){return this.browser!==void 0&&this.browser.isConnected()}async ensureContext(e){let n=this.sessions.get(e);if(n!==void 0)return n.context;let r=await this.ensureBrowser(),o=this.loadStorageState(this.config.defaultProfile),s=await r.newContext({...this.contextOptions(),...o!==void 0?{storageState:o}:{}}),i={context:s,page:void 0,consoleErrors:0,lastHttpStatus:null,openDialog:void 0};return this.sessions.set(e,i),s}async ensurePage(e){let n=this.sessions.get(e);if(n!==void 0&&n.page!==void 0)return n.page;await this.ensureContext(e);let r=this.sessions.get(e);if(r===void 0)throw new Error(`[BrowserLauncher] session entry disappeared for sessionId=${e}`);if(r.page!==void 0)return r.page;let o=await r.context.newPage();return r.page=o,o.on("console",s=>{s.type()==="error"&&(r.consoleErrors+=1)}),o.on("request",s=>{s.isNavigationRequest()&&s.frame()===o.mainFrame()&&(r.lastHttpStatus=null)}),o.on("response",s=>{s.frame()===o.mainFrame()&&s.request().isNavigationRequest()&&(r.lastHttpStatus=s.status())}),o.on("dialog",s=>{r.openDialog=s}),o}getPage(e){return this.sessions.get(e)?.page}async renderHtml(e,n){let o=await(await this.ensureBrowser()).newContext(this.contextOptions()),s;n.requestGuard!==void 0&&await o.route("**/*",async a=>{try{await n.requestGuard(a.request().url()),await a.continue()}catch(l){s=l,await a.abort("blockedbyclient")}});let i=()=>{o.close().catch(()=>{})};if(n.signal?.aborted===!0)throw await o.close().catch(()=>{}),new Error("render aborted");n.signal!==void 0&&n.signal.addEventListener("abort",i,{once:!0});try{let a=await o.newPage(),l;try{l=await a.goto(e,{timeout:n.timeoutMs,waitUntil:n.waitUntil})}catch(p){throw s??p}if(s!==void 0)throw s;let c=await a.content();if(s!==void 0)throw s;let d=a.url(),u=l!==null?l.status():null;return{html:c,finalUrl:d,httpStatus:u}}finally{n.signal!==void 0&&n.signal.removeEventListener("abort",i),await o.close().catch(()=>{})}}getConsoleErrorCount(e){return this.sessions.get(e)?.consoleErrors??0}getLastHttpStatus(e){return this.sessions.get(e)?.lastHttpStatus??null}hasOpenDialog(e){return this.sessions.get(e)?.openDialog!==void 0}async dismissDialog(e,n=!0){let r=this.sessions.get(e);if(r===void 0||r.openDialog===void 0)return;let o=r.openDialog;r.openDialog=void 0,n?await o.accept():await o.dismiss()}async closeSession(e){this.clearLaunchFailure();let n=this.sessions.get(e);n!==void 0&&(this.sessions.delete(e),await this.saveStorageState(this.config.defaultProfile,n.context),n.page!==void 0&&await n.page.close().catch(()=>{}),await n.context.close().catch(()=>{}))}async shutdown(){if(this.clearLaunchFailure(),this.shutdownComplete)return;this.shutdownComplete=!0;let e=[...this.sessions.keys()];if(await Promise.all(e.map(n=>this.closeSession(n))),this.browser!==void 0){let n=this.browser;this.browser=void 0,await n.close().catch(()=>{})}}activeSessions(){return this.sessions.size}contextOptions(){return{viewport:{width:1280,height:800},userAgent:`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 agent-afk/${fD}`}}loadStorageState(e){let n=Jc(e);try{if(!Dn.existsSync(n))return;let r=JSON.parse(Dn.readFileSync(n,"utf8"));return N("[browser/vault] restored session",{profile:e,file:n}),r}catch(r){N("[browser/vault] ignoring unreadable vault",{profile:e,file:n,err:r});return}}async saveStorageState(e,n){try{let r=Jc(e);if(!Dn.existsSync(r))return;let o=await n.storageState(),s=xa.join(xa.dirname(r),`.${xa.basename(r)}.${process.pid}.${dD(4).toString("hex")}.tmp`);Dn.writeFileSync(s,JSON.stringify(o),{mode:384}),Dn.chmodSync(s,384),Dn.renameSync(s,r),N("[browser/vault] saved session",{profile:e,file:r})}catch(r){N("[browser/vault] save failed",{profile:e,err:r})}}}});import{createHash as mD}from"crypto";function Mw(t){return!!(t.role==="textbox"&&t.kind==="password"||t.label&&gD.test(t.label))}function Ow(t){return mD("sha256").update(t,"utf8").digest("hex").slice(0,8)}function Dw(t){let e=t.replace(/\s+/g," ").trim();return e.length<=80?e:e.slice(0,77)+"..."}var gD,Ca=y(()=>{"use strict";gD=/password|secret|token|api[_-]?key|otp|2fa/i});import{createHash as hD}from"node:crypto";function yD(t){return t?t.replace(/\s+/g," ").trim().slice(0,200):""}function bD(t,e,n){return`el_${hD("sha256").update(`${t}:${e}:${n}`).digest("hex").slice(0,6)}`}function wD(t){let e=t.replace(/\s+/g," ").trim(),n=4e3;return e.length<=n?e:e.slice(0,n)+"\u2026[truncated]"}function Fw(t){return t.replace(/\s+/g," ").trim().toLowerCase().slice(0,100)}function Nw(t,e){let n=t.role??"",r=t.name??"";Lw.has(n)&&(n!=="searchbox"&&n!=="spinbutton"||r!=="")&&e.push(t);for(let s of t.children??[])Nw(s,e)}async function SD(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(),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},$w).catch(()=>[])}async function vD(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")??"",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 g=s.type;g==="checkbox"?c="checkbox":g==="radio"?c="radio":g==="button"||g==="submit"||g==="reset"?c="button":g==="search"?c="searchbox":c="textbox"}if(!c)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:c,name:l,disabled:p};u!==void 0&&(m.value=u),f!==void 0&&(m.checked=f),o.push(m)}return o},$w).catch(()=>[])}function kD(t){let n=t.accessibility;return n!==null&&typeof n=="object"?n:null}async function Ia(t,e){let n=e.maxElements??80,r=e.includeHidden??!1,o=[],s=kD(t),i=s?s.snapshot({interestingOnly:!1}).catch(()=>null):Promise.resolve(null),a=SD(t),l=t.evaluate(()=>document.body?.innerText??"").catch(()=>""),c=Promise.resolve(t.url()),d=t.title().catch(()=>""),[u,p,f,m,g]=await Promise.all([i,a,l,c,d]),h,w=!1;u!==null?(h=[],Nw(u,h)):(o.push("observation skipped accessibility tree (returned null)"),w=!0,h=(await vD(t)).filter($=>Lw.has($.role??"")));let k=new Map;for(let P of p){let $=Fw(P.name),G=k.get($);(!G||G.bbox.w===0&&P.bbox.w>0)&&k.set($,P)}let E=h.map(P=>({ax:P,dom:k.get(Fw(P.name??""))})),v=r?E:E.filter(P=>P.dom?P.dom.bbox.w>0||P.dom.bbox.h>0:!0);v.sort((P,$)=>{let G=P.dom?.bbox.y??0,F=$.dom?.bbox.y??0;if(G!==F)return G-F;let B=P.dom?.bbox.x??0,M=$.dom?.bbox.x??0;return B-M}),v.length>200&&o.push("page has 200+ interactive elements; consider scoping");let T=v.slice(0,n).map((P,$)=>{let G=P.ax.role??"generic",F=P.ax.name??"",B=bD(G,F,$),M=P.dom?.bbox??{x:0,y:0,w:0,h:0},C=P.dom?.type??null,O=null;P.ax.value!==void 0&&P.ax.value!==null&&(O=String(P.ax.value)),P.ax.checked!==void 0&&(O=String(P.ax.checked)),Mw({role:G,kind:C})&&(O="[redacted]");let U={disabled:P.ax.disabled??!1};P.ax.checked!==void 0&&(U.checked=P.ax.checked===!0||P.ax.checked==="mixed"),P.ax.selected!==void 0&&(U.selected=P.ax.selected),P.ax.expanded!==void 0&&(U.expanded=P.ax.expanded);let q;P.dom?.testId?q=`[data-testid="${P.dom.testId}"]`:P.dom?.id&&(q=`#${P.dom.id}`);let Z={id:B,role:G,label:yD(F),kind:C,value:O,state:U,bbox:M};return q!==void 0&&(Z.selector=q),Z}),x="idle";try{let P=await t.evaluate(()=>document.readyState);P==="loading"?x="loading":P==="interactive"?x="navigating":x="idle"}catch{x="navigating"}x!=="idle"&&o.push("page is still loading \u2014 observation may be incomplete"),w&&!o.includes("observation skipped accessibility tree (returned null)")&&o.push("observation skipped accessibility tree (returned null)");let S=wD(f),R=`obs_${e.observationCounter.toString(36)}`,I=new Date().toISOString();return{observationId:R,url:m,title:g,textSummary:S,interactive:T,status:{httpStatus:e.httpStatus??null,loadingState:x,hasDialog:e.hasDialog??!1,consoleErrors:e.consoleErrors??0},warnings:o,screenshotPath:e.screenshotPath??null,capturedAt:I}}var Lw,$w,Uw=y(()=>{"use strict";Ca();Lw=new Set(["button","link","textbox","combobox","checkbox","radio","tab","menuitem","menuitemcheckbox","menuitemradio","switch","option","searchbox","spinbutton"]);$w="a[href], button, input, select, textarea, [role], [tabindex], label"});async function Bw(t,e){try{let n=await t.nth(e).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")??"",d=a.getBoundingClientRect();return{role:l,label:c,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 Gu(t,e){let n=Math.min(e,5);return(await Promise.all(Array.from({length:n},(o,s)=>Bw(t,s)))).filter(o=>o!==null)}async function _D(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 l=a,c=l.getBoundingClientRect();return`${l.tagName}@${Math.round(c.x)},${Math.round(c.y)}`})}catch{continue}e.has(i)||(e.add(i),n.push({key:i,locator:r,index:s}))}return n}async function qu(t,e,n){switch(e.kind){case"element_id":return ED(t,e,n);case"selector":return AD(t,e);case"semantic":return TD(t,e)}}async function ED(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 l=t.locator(r.selector);if(await l.count()===1)return{outcome:"resolved",locator:l}}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 Gu(o,s);return{outcome:"ambiguous_target",query:{text:r.label,role:r.role},candidates:i}}async function AD(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 Gu(n,r);return{outcome:"ambiguous_target",query:{text:`[selector: ${e.selector}]`},candidates:o}}async function TD(t,e){return e.role!==void 0?xD(t,e.text,e.role):RD(t,e.text,e)}async function xD(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 Gu(r,o);return{outcome:"ambiguous_target",query:{text:e,role:n},candidates:s}}async function RD(t,e,n){let r=t.getByRole("button",{name:e}),o=t.getByRole("link",{name:e}),s=t.getByLabel(e,{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 d=[];i>0&&d.push({loc:r,count:i}),a>0&&d.push({loc:o,count:a}),l>0&&d.push({loc:s,count:l});let u=await _D(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 w=await Bw(h.locator,h.index);if(w!==null){let k=`${w.role}:${w.label}:${g}`,E=0;for(let v=0;v<k.length;v++)E=E*31+k.charCodeAt(v)>>>0;f.push({...w,id:`el_${E.toString(16).padStart(6,"0").slice(0,6)}`})}}return{outcome:"ambiguous_target",query:{text:e},candidates:f}}var Hw=y(()=>{"use strict"});async function zu(t,e,n,r){let o=t.url();if(o===n)return null;let s=Aa(o,e);if(s.allowed)return null;try{await t.goBack()}catch{await r()}return{outcome:"blocked_by_policy",url:o,reason:s.reason}}var jw=y(()=>{"use strict";Ta()});import{randomBytes as CD}from"crypto";import{mkdir as ID,stat as PD,writeFile as MD}from"fs/promises";import{join as Ju}from"path";import{gzip as OD}from"zlib";import{promisify as DD}from"util";function FD(t){return Ju(Ys(t),"browser")}function LD(t){return Ju(FD(t),"screenshots")}function ND(){return new Date().toISOString().replace(/[:.]/g,"-")}function $D(){return CD(3).toString("hex")}async function Vu(t,e,n){if(e.length>Ww)throw new Error(`writeScreenshotSidecar: buffer exceeds ${Ww} byte cap (received ${e.length} bytes). Refusing to write oversized screenshot.`);let r=LD(t);await ID(r,{recursive:!0});let o=`${ND()}-${$D()}-${n}.png`,s=Ju(r,o);await MD(s,e);let{size:i}=await PD(s);return{path:s,bytes:i}}var B5,Ww,Kw=y(()=>{"use strict";K();Ca();B5=DD(OD);Ww=5*1024*1024});var qw={};Bc(qw,{PlaywrightProvider:()=>Yu});function Gw(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 Yu,zw=y(()=>{"use strict";Pw();Uw();Hw();Ta();jw();Kw();Yu=class{name="playwright";config;launcher;sessions=new Map;constructor(e){this.config=e,this.launcher=new Ra(e)}async open(e){let n=Aa(e.url,this.config);if(!n.allowed)return{outcome:"blocked_by_policy",url:e.url,reason:n.reason};let{sessionId:r}=e,o=await this.launcher.ensurePage(r),s=this.ensureSessionState(r),i=null,a=null;try{await o.goto(e.url,{timeout:e.timeoutMs??3e4,waitUntil:e.waitFor??"load"})}catch(u){a=u}let l=o.url();if(!(a!==null&&(l===""||l==="about:blank"))){let u=await zu(o,this.config,e.url,()=>this.close({sessionId:r}));if(u!==null)return u}(e.screenshot===!0||a!==null)&&(i=await this.captureScreenshot(o,r,"browser_open")),s.observationCounter+=1;let d=await Ia(o,{observationCounter:s.observationCounter,screenshotPath:i,consoleErrors:this.launcher.getConsoleErrorCount(r),httpStatus:this.launcher.getLastHttpStatus(r),hasDialog:this.launcher.hasOpenDialog(r)});if(this.updateSessionFromObservation(s,d.interactive,d.url,d.title,"browser_open"),a!==null)throw a;return d}async observe(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_observe: no page open for session ${n}`);let o=this.ensureSessionState(n),s=null;e.screenshot===!0&&(s=await this.captureScreenshot(r,n,"browser_observe")),o.observationCounter+=1;let i=await Ia(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 qu(r,e.target,o.knownElements);if(a.outcome==="not_found")throw new Error(`browser_act: target not found: ${Gw(e.target)}`);if(a.outcome==="ambiguous_target")return a;let{locator:l}=a,c=null,d=async()=>{switch(e.action){case"click":await l.click({timeout:i});break;case"fill":await l.fill(e.value??"");break;case"press":await l.press(e.value??"");break;case"select":await l.selectOption(e.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 d()}catch(g){if(g instanceof Error&&/navigation|net::ERR/i.test(g.message))try{await d()}catch(h){c=h}else c=g}let u=await zu(r,this.config,s,()=>this.close({sessionId:n}));if(u!==null)return u;let p=null;(e.screenshot===!0||c!==null)&&(p=await this.captureScreenshot(r,n,"browser_act")),o.observationCounter+=1;let f=await Ia(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),c!==null)throw c;return f}async render(e){return this.launcher.renderHtml(e.url,{timeoutMs:e.timeoutMs??3e4,waitUntil:e.waitFor??"load",signal:e.signal,requestGuard:e.requestGuard})}async screenshot(e){let{sessionId:n}=e,r=this.launcher.getPage(n);if(r===void 0)throw new Error(`browser_screenshot: no page open for session ${n}`);let o=this.ensureSessionState(n),s;if(e.target!==void 0){let d=await qu(r,e.target,o.knownElements);if(d.outcome==="not_found")throw new Error(`browser_screenshot: target not found: ${Gw(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 Vu(n,s,"browser_screenshot"),l=0,c=0;if(e.fullPage===!0)try{let d=await r.evaluate(()=>({w:document.documentElement.scrollWidth,h:document.documentElement.scrollHeight}));l=d.w,c=d.h}catch{let d=r.viewportSize();l=d?.width??0,c=d?.height??0}else{let d=r.viewportSize();l=d?.width??0,c=d?.height??0}return{path:i,bytes:a,width:l,height:c,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 Vu(n,o,r);return s}catch{return null}}}});var Ln={};Bc(Ln,{__resetBrowserRegistryForTests:()=>WD,browserProviderActive:()=>HD,closeBrowserProvider:()=>Xu,getBrowserProvider:()=>BD,peekBrowserProvider:()=>jD});function Jw(){Promise.resolve(Xu()).then(()=>{process.exit(130)})}function Vw(){Promise.resolve(Xu()).then(()=>{process.exit(143)})}function Yw(){bt=null}function UD(){Pa||(process.on("SIGINT",Jw),process.on("SIGTERM",Vw),process.on("exit",Yw),Pa=!0)}function Xw(){Pa&&(process.removeListener("SIGINT",Jw),process.removeListener("SIGTERM",Vw),process.removeListener("exit",Yw),Pa=!1)}async function BD(t){return bt!==null?bt:(Fn!==null||(Fn=(async()=>{let{PlaywrightProvider:e}=await Promise.resolve().then(()=>(zw(),qw)),n=xw(t),r=new e(n);return UD(),bt=r,Fn=null,r})()),Fn)}async function Xu(){if(bt===null)return;let t=bt;bt=null,Fn=null,Xw(),await t.shutdown()}function HD(){return bt!==null}function jD(){return bt}function WD(){bt=null,Fn=null,Xw()}var bt,Fn,Pa,Nn=y(()=>{"use strict";Ta();bt=null,Fn=null,Pa=!1});async function Qw(t,e){try{return await hw(t,e)}catch(n){return N("[web/scrape] extraction failed",{url:e,err:n}),{title:"",markdown:"",textLength:0,usedFallback:!0}}}async function VD(t,e){let{getBrowserProvider:n}=await Promise.resolve().then(()=>(Nn(),Ln));return(await n()).render({url:t,timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:e.requestGuard})}async function Zw(t,e){let n=e.fetchFn??globalThis.fetch,r=e.renderFn??VD,o=e.lookupFn!==void 0?{lookupFn:e.lookupFn}:{},s=null,i=t,a=null,l=null;try{let d=await Ea(n,t,{headers:JD,signal:e.signal},o);a=d.status,i=d.url||t;let u=d.headers.get("content-type")??"";if(d.ok){if(zD.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 p=await d.text();if(qD.test(u)&&!GD.test(u))return{title:"",markdown:p.trim(),finalUrl:i,usedRender:!1};if(s=await Qw(p,i),e.signal.aborted)throw e.signal.reason??new Error("aborted")}}catch(d){if(e.signal.aborted||d instanceof st||d instanceof Error&&d.message.startsWith("web_scrape markdown mode received binary"))throw d;l=d}if(!(s===null||s.textLength<200)&&s!==null)return{title:s.title,markdown:s.markdown,finalUrl:i,usedRender:!1};try{await Oo(t,o);let d=await r(t,{timeoutMs:e.timeoutMs,signal:e.signal,requestGuard:p=>Oo(p,o)});d.finalUrl!==t&&/^https?:\/\//i.test(d.finalUrl)&&await Oo(d.finalUrl,o);let u=await Qw(d.html,d.finalUrl);if(e.signal.aborted)throw e.signal.reason??new Error("aborted");if(s===null||u.textLength>=s.textLength)return{title:u.title,markdown:u.markdown,finalUrl:d.finalUrl,usedRender:!0}}catch(d){if(e.signal.aborted||d instanceof st)throw d;if(s===null){let u=d instanceof Error?d.message:String(d),p=l instanceof Error?l.message:`HTTP ${a??"error"}`,f=new Error(`web_scrape could not retrieve ${t}: fetch failed (${p}) and render failed (${u}).`);throw f.cause=d,f}}if(s!==null)return{title:s.title,markdown:s.markdown,finalUrl:i,usedRender:!1};throw new Error(`web_scrape could not retrieve any content from ${t} (HTTP ${a??"error"}).`)}var GD,qD,zD,JD,eS=y(()=>{"use strict";yw();Hu();me();GD=/(text\/html|application\/xhtml\+xml)/i,qD=/(application\/json|\/xml|\+xml|text\/|application\/(java|ecma)script|csv)/i,zD=/(image\/|audio\/|video\/|application\/pdf|application\/zip|application\/octet-stream|font\/)/i,JD={"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 QD(t){let e=t.fetchFn??globalThis.fetch;return{name:"exa",async search(n,{limit:r,signal:o}){let s=await e(YD,{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),XD),contents:{highlights:{numSentences:3,highlightsPerUrl:1}}}),signal:o});if(!s.ok){let l="";try{let d=await s.text(),u=mr(d);u&&(l=`: ${u.length>200?u.slice(0,200)+"\u2026":u}`)}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 tS(t){return t.exaApiKey!==void 0&&t.exaApiKey.trim()!==""?QD({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 nS(t,e){if(e.length===0)return`# Search results for "${t}"
866
866
 
867
867
  (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(`
868
868
  `).trimEnd()}var YD,XD,rS=y(()=>{"use strict";vn();YD="https://api.exa.ai/search",XD=10});function Ma(t){if(t instanceof Error&&t.name==="TimeoutError")return"timeout";let e=t instanceof Error?t.message:String(t);return/Timeout\s+\d+\s*ms exceeded/i.test(e)?"timeout":void 0}var $n=y(()=>{"use strict";Ku()});function oF(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 l;try{l=new URL(e.url)}catch{return{error:`Invalid input: "${e.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=ZD;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,eF)}let a=tF;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,nF)}return{mode:r,url:o,query:s,timeoutMs:i,maxBytes:a}}function Qu(t,e){return Buffer.byteLength(t,"utf8")<=e?{content:t,truncated:!1}:{content:Ct(t,e),truncated:!0}}function sF(t={}){let e=t.fetchFn??globalThis.fetch,n=t.env??process.env,r=t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{};return async(o,s)=>{if(typeof e!="function")return{content:"web_scrape unavailable: global fetch() is not present in this runtime (agent-afk requires Node 20+).",isError:!0};let i=oF(o);if("error"in i)return{content:i.error,isError:!0};if(s.aborted){let u=s.reason;return{content:`web_scrape aborted: ${u instanceof Error?u.message:String(u??"aborted")}`,isError:!0}}let a=new AbortController,l=()=>{a.abort(s.reason)},c,d=()=>{let u=a.signal.reason;return u instanceof Error?u.message:String(u??"aborted")};try{if(s.addEventListener("abort",l,{once:!0}),c=setTimeout(()=>{a.abort(new Error(`web_scrape timeout after ${i.timeoutMs}ms`))},i.timeoutMs),i.url!==void 0){let p=await Bu(i.url,r);if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(!p.allowed)return{content:`web_scrape blocked: ${p.reason}`,isError:!0}}if(i.mode==="raw"){let p;try{let g={method:"GET",headers:{"User-Agent":"agent-afk/web_scrape",Accept:"*/*"},signal:a.signal};p=await Ea(e,i.url,g,r)}catch(g){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:g instanceof st?{content:`web_scrape blocked: ${g.message}`,isError:!0}:{content:`web_scrape network error: ${g instanceof Error?g.message:String(g)}`,isError:!0}}if(!p.ok)return{content:`web_scrape HTTP ${p.status} ${p.statusText||""}`.trimEnd()+` for ${i.url}`,isError:!0};let f;try{f=await p.text()}catch(g){return{content:`web_scrape read error: ${g instanceof Error?g.message:String(g)}`,isError:!0}}let m=Qu(f,i.maxBytes);return{content:m.content,...m.truncated?{truncated:!0}:{}}}if(i.mode==="markdown")try{let p=await Zw(i.url,{fetchFn:e,renderFn:t.renderFn,timeoutMs:i.timeoutMs,signal:a.signal,...t.lookupFn!==void 0?{lookupFn:t.lookupFn}:{}});if(p.markdown.trim().length===0)return{content:`web_scrape extracted no readable content from ${i.url}.`,isError:!0};let f=Qu(p.markdown,i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){if(a.signal.aborted)return{content:`web_scrape aborted: ${d()}`,isError:!0};if(p instanceof st)return{content:`web_scrape blocked: ${p.message}`,isError:!0};let f=p instanceof Error?p.message:String(p),m=Pe(p)&&!ju(f)?` (the render fallback needs the optional Playwright browser \u2014 run \`${Do()}\`)`:"";return{content:`web_scrape markdown error: ${f}${m}`,isError:!0}}let u=tS({exaApiKey:n.EXA_API_KEY,fetchFn:e});if("error"in u)return{content:u.error,isError:!0};try{let p=await u.search(i.query,{limit:rF,timeoutMs:i.timeoutMs,signal:a.signal}),f=Qu(nS(i.query,p),i.maxBytes);return{content:f.content,...f.truncated?{truncated:!0}:{}}}catch(p){return a.signal.aborted?{content:`web_scrape aborted: ${d()}`,isError:!0}:{content:`web_scrape search error (${u.name}): ${p instanceof Error?p.message:String(p)}`,isError:!0}}}finally{c!==void 0&&clearTimeout(c),s.removeEventListener("abort",l)}}}var ZD,eF,tF,nF,rF,oS,sS=y(()=>{"use strict";eS();rS();Hu();Rn();$n();ZD=3e4,eF=12e4,tF=1e5,nF=1e6,rF=10;oS=sF()});import{existsSync as aS,mkdirSync as iF,readFileSync as aF,renameSync as lF,unlinkSync as cF,writeFileSync as dF}from"node:fs";import{dirname as iS,join as uF}from"node:path";import{randomBytes as pF}from"node:crypto";function vr(t){let e=t??Kc();if(!aS(e))return[];try{let n=aF(e,"utf-8");return JSON.parse(n)}catch(n){let r=n instanceof Error?n.message:String(n);return console.error(`[schedule-store] failed to parse ${e}: ${r}`),[]}}function Oa(t,e){let n=e??Kc();iF(iS(n),{recursive:!0});let r=uF(iS(n),`.schedules.json.${process.pid}.${pF(4).toString("hex")}.tmp`),o=JSON.stringify(t,null,2);try{dF(r,o,"utf-8"),lF(r,n)}catch(s){try{aS(r)&&cF(r)}catch{}throw s}}function lS(t,e){let n=vr(e),r=n.map(l=>l.id),o=fF(t.name),s=mF(o,r),i=new Date().toISOString(),a={...t,notifyOn:t.notifyOn??"failure",id:s,createdAt:i,updatedAt:i};return n.push(a),Oa(n,e),a}function cS(t,e){let n=vr(e),r=n.length,o=n.filter(s=>s.id!==t);return o.length===r?!1:(Oa(o,e),!0)}function dS(t,e){return vr(e).find(n=>n.id===t)}function fF(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"")}function mF(t,e){if(!e.includes(t))return t;let n=2;for(;e.includes(`${t}-${n}`);)n+=1;return`${t}-${n}`}var uS=y(()=>{"use strict";K()});import{existsSync as gF,readFileSync as hF}from"node:fs";import{join as yF}from"node:path";async function Fo(t,e,n){let r;try{let o=yF(Qm("default"),"port");if(!gF(o))return{synced:!1,detail:"daemon-not-detected (no port file)"};let s=hF(o,"utf-8").trim();if(r=parseInt(s,10),Number.isNaN(r))return{synced:!1,detail:"daemon-not-detected (invalid port file)"}}catch{return{synced:!1,detail:"daemon-not-detected (unreadable port file)"}}try{let o=await fetch(`http://localhost:${r}${e}`,{method:t,headers:{"Content-Type":"application/json"},body:n!==void 0?JSON.stringify(n):void 0,signal:AbortSignal.timeout(2e3)});return o.ok?{synced:!0,detail:"synced"}:t==="POST"&&o.status===409?{synced:!0,detail:"already-registered"}:t==="DELETE"&&o.status===404?{synced:!0,detail:"not-registered"}:{synced:!1,detail:`daemon-rejected (HTTP ${o.status})`}}catch{return{synced:!1,detail:"daemon-unreachable (stale port file or network error)"}}}var Zu,pS=y(()=>{"use strict";K();Zu="Change saved to schedules.json, but a running daemon (if any) did not pick it up \u2014 it will apply on the next daemon (re)start."});import{existsSync as bF}from"node:fs";import{readFile as wF}from"node:fs/promises";var fS,mS,gS,hS,yS=y(()=>{"use strict";uS();K();pS();fS=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;if(typeof n.name!="string"||!n.name)return{content:"Invalid input: name required",isError:!0};if(typeof n.command!="string"||!n.command)return{content:"Invalid input: command required",isError:!0};if(typeof n.cron!="string"||!n.cron)return{content:"Invalid input: cron required",isError:!0};let r=n.cron.trim().split(/\s+/);if(r.length!==5&&r.length!==6)return{content:"Invalid input: cron must be a 5 or 6-field expression",isError:!0};let o=n.notifyChat;if(o!==void 0&&typeof o!="number"&&typeof o!="string")return{content:"Invalid input: notifyChat must be a number (chat id) or string (chat id or alias name)",isError:!0};let s=lS({name:n.name,command:n.command,cron:n.cron,trigger:n.trigger??"cron",notifyOn:n.notifyOn,...o!==void 0?{notifyChat:o}:{},enabled:typeof n.enabled=="boolean"?n.enabled:!0}),i=s.enabled?await Fo("POST","/tasks",{taskId:s.id,command:s.command,cron:s.cron,trigger:s.trigger,notifyOn:s.notifyOn,...s.notifyChat!==void 0?{notifyChat:s.notifyChat}:{}}):await Fo("DELETE",`/tasks/${s.id}`);return{content:JSON.stringify({id:s.id,name:s.name,cron:s.cron,enabled:s.enabled,daemonSynced:i.synced,syncDetail:i.detail,...i.synced?{}:{syncNote:Zu}})}},mS=async(t,e)=>{let n=vr();return{content:JSON.stringify(n.map(r=>({id:r.id,name:r.name,cron:r.cron,trigger:r.trigger,enabled:r.enabled,notifyOn:r.notifyOn})))}},gS=async(t,e)=>{if(!t||typeof t!="object")return{content:"Invalid input: expected object",isError:!0};let n=t;if(typeof n.taskId!="string"||!n.taskId)return{content:"Invalid input: taskId required",isError:!0};let r=n.taskId,o=typeof n.limit=="number"?Math.min(Math.max(1,n.limit),50):10,s=Ws();if(!bF(s))return{content:JSON.stringify([])};let i;try{let c=await wF(s);i=(c.length>1048576?c.subarray(c.length-1048576):c).toString("utf-8")}catch{return{content:JSON.stringify([])}}let a=i.split(`
@@ -1255,7 +1255,7 @@ ${k.map(T=>`> - ${T}`).join(`
1255
1255
 
1256
1256
  ${n}${u}
1257
1257
 
1258
- Choose how to handle this and future requests for this path.`,f=await He.route({serverName:"agent-afk",message:p,mode:"form",title:"Path access approval",requestedSchema:{type:"object",properties:{choice:{type:"string",title:"Choose one",enum:["once","session","persist","deny"],description:"'once' allows this single call only. 'session' allows this path until the session ends. 'persist' writes a grant to ~/.afk/config/permissions.json so future sessions inherit it. 'deny' blocks this call and returns an error to the model."}},required:["choice"]}},{signal:l??new AbortController().signal,...c!==void 0?{sessionId:c}:{}});if(f.action!=="accept"){let h=f.action==="cancel"?"cancel":"block";return console.error(`[path-approval] surface=${a} tool=${e} path=${n} outcome=${h}`),{decision:"block",reason:f.action==="cancel"?`User cancelled the access prompt for ${n}`:`User denied access to ${n}`}}let m=String(f.content?.choice??"").toLowerCase(),g=bm(o,n);switch(m){case"once":return o==="write"?s.addWriteRoot(n,"tool"):s.addReadRoot(n,"tool"),i.onceApproved.set(g,{resolvedPath:n,mode:o,capturedCwd:r}),console.error(`[path-approval] surface=${a} tool=${e} path=${n} outcome=once`),{};case"session":return o==="write"?s.addWriteRoot(n,"tool"):s.addReadRoot(n,"tool"),i.sessionApproved.add(g),console.error(`[path-approval] surface=${a} tool=${e} path=${n} outcome=session`),{};case"persist":o==="write"?s.addWriteRoot(n,"tool"):s.addReadRoot(n,"tool"),i.sessionApproved.add(g),console.error(`[path-approval] surface=${a} tool=${e} path=${n} outcome=persist`);try{VT({path:n,mode:o,decision:"allow",source:a==="telegram"?"elicit:telegram":a==="repl"?"elicit:repl":"elicit:unknown",reason:`Approved via ${a} prompt for ${e}`})}catch(h){console.error(`path-approval: failed to persist grant for ${n}:`,h instanceof Error?h.message:String(h))}return{};default:return console.error(`[path-approval] surface=${a} tool=${e} path=${n} outcome=deny`),{decision:"block",reason:`User denied access to ${n}`}}}Yt();H();import{homedir as Xx}from"os";import qn from"path";Yt();K();Ro();import wm from"path";function Sm(){try{return wm.resolve(oe())}catch(t){yt(t);return}}function Vx(t){return Sr.flatMap(e=>{if(!e.startsWith(".afk/"))return[];let n=wm.join(t,e.slice(5));return Ye(n).denied?[]:[n,`$AFK_HOME/${e.slice(5)}`]})}function Yx(){let t=Sm();return t===void 0?[]:[wm.join(t,"config")]}var VK=/\b(python|python3|node|ruby|perl|osascript|sh|bash|zsh|fish|lua)\s+-[cCeE](\s|$)/,YK=/\.ssh\b|\bid_rsa\b|\bid_ed25519\b|\.gnupg\b|\.aws\b|\.config\/gh\b|\.config\/gcloud\b|\.netrc\b|\.password-store\b|\.afk\/config\b|\.npmrc\b|\.docker\/config\.json\b|\.git-credentials\b|\.kube\/config\b|Library\/Application Support\b|\/etc\/shadow\b|\/etc\/sudoers\b|master\.passwd\b/i;function Qx(t){return e=>{if(e.event!=="PreToolUse")return{};if(e.toolName!=="bash")return{};let n=e.input,r=typeof n?.command=="string"?n.command:"";if(!r)return{};let o=e.grantManager??t.getGrantManager(),s=o!==void 0,i=Xx(),a=Sm(),l=n1(XK(r,i,a),i,a),c=o?a1(o.getGrants()):[];if(!t.disableInterpreterGuard&&(s||t.forceInterpreterGuard===!0)&&VK.test(r)&&r1(l,c))return{decision:"block",reason:"Interpreter one-liner (python -c, node -e, sh -c, ...) referencing a sensitive path (SSH keys, cloud credentials, GPG, /etc/shadow, ...) is blocked by the path-approval policy \u2014 an interpreter can assemble a path the shell-substring check cannot see. Use the typed file tools (read_file, write_file, edit_file), which support per-call user approval, or ask the user to run the script themselves. To lift this block \u2014 e.g. headless automation that legitimately reads such paths \u2014 set AFK_DISABLE_BASH_INTERPRETER_GUARD=1, or disable all of path-approval with AFK_DISABLE_PATH_APPROVAL=1."};if(!o)return{};if(c.length===0)return{};for(let u of c)if(l.includes(u))return{decision:"block",reason:`Bash command references a restricted path (${u}). For sensitive paths, use read_file / write_file / edit_file \u2014 those tools support per-call user approval via an inline prompt. If you genuinely need a shell command for this path, ask the user to grant it via \`/allow-dir <path>\` first.`};return{}}}function XK(t,e,n){return(n===void 0?t:t.replace(/\$\{AFK_HOME\}|\$AFK_HOME\b/g,n)).replace(/\$\{HOME\}|\$HOME\b/g,e).replace(/(^|[\s/=:])~(?=$|[/\s])/g,`$1${e}`).replace(QK,o=>qn.posix.normalize(o))}var QK=/\/[^\s'"`;|&()<>]*/g,ZK="<allowlisted-file>";function e1(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function t1(t,e){let n=Sr.flatMap(o=>Ye(qn.join(t,o)).denied?[]:[qn.join(t,o),`~/${o}`,`$HOME/${o}`]);if(e===void 0)return n;let r=Vx(e);return[...new Set([...n,...r])]}function n1(t,e,n){let r=t;for(let o of t1(e,n)){let s=new RegExp(`${e1(o)}(?![\\w./\\\\*?\\[\\]{}-])`,"g");r=r.replace(s,ZK)}return r}function r1(t,e){return e.some(n=>t.includes(n))?!0:YK.test(t)}function o1(){let t=Xx();return i1([qn.join(t,"Library","Application Support"),qn.join(t,".password-store"),qn.join(t,".config","gh"),...xu])}function s1(){return Ru(_.AFK_READ_DENYLIST)}function i1(t){let e=[];for(let n of t)e.push(n),n.startsWith("/etc/")?e.push(`/private${n}`):n.startsWith("/private/etc/")&&e.push(n.slice(8));return e}function a1(t){let e=[...new Set([...o1(),...Cu(),...s1(),...Yx()])],n=new Set([...t.resolveBase!==void 0?[t.resolveBase]:[],...t.readRoots,...t.writeRoots]);return e.filter(r=>{for(let o of n){let s=qn.relative(o,r);if(s===""||!s.startsWith(".."))return!1}return!0})}K();zl();aa();import{existsSync as Dc,readFileSync as l1}from"node:fs";import{join as km}from"node:path";var c1=3e4;function Zx(t){if(t===void 0||t==="*")return()=>!0;let e=/^\/(.+)\/([gimsuy]*)$/.exec(t);if(e!==null){let n=e[1],r=e[2];try{let o=r.replace(/[gy]/g,""),s=new RegExp(n,o);return i=>s.test(i)}catch{}}return n=>n===t}function d1(t){if(t===null||typeof t!="object"||Array.isArray(t))return null;let e=t;if(e.type!=="command"||typeof e.command!="string"||e.command.length===0)return null;let n=typeof e.timeout_ms=="number"&&e.timeout_ms>0?e.timeout_ms:c1,r=Math.min(n,En);return{type:"command",command:e.command,timeoutMs:r}}function vm(t,e,n){let r=[],o=[],s={};if(!Dc(t))return{hooks:s,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r};o.push(t);let i;try{i=JSON.parse(l1(t,"utf-8"))}catch(m){let g=m instanceof Error?m.message:String(m);return r.push(`hooks config at ${t}: parse error \u2014 ${g}`),{hooks:s,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r}}if(i===null||typeof i!="object"||Array.isArray(i))return r.push(`hooks config at ${t}: top-level must be an object`),{hooks:s,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r};let a=i,l=a.enableShellHooks===!0,c=a.allowProjectHooks===!0,d=a.enablePluginHooks===!0,u=a.hooks;if(u==null)return{hooks:s,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r};if(typeof u!="object"||Array.isArray(u))return r.push(`hooks config at ${t}: "hooks" must be an object`),{hooks:s,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r};let p=u,f=["SessionStart","SessionEnd","SubagentStart","SubagentStop","PreToolUse","PostToolUse","PreCompact","PostToolUseFailure","Stop","UserPromptSubmit"];for(let m of f){let g=p[m];if(g===void 0)continue;if(!Array.isArray(g)){r.push(`hooks config at ${t}: hooks.${m} must be an array`);continue}let h=[];for(let w=0;w<g.length;w++){let k=g[w];if(k===null||typeof k!="object"||Array.isArray(k)){r.push(`hooks config at ${t}: hooks.${m}[${w}] must be an object \u2014 skipping`);continue}let E=k,v=typeof E.matcher=="string"?E.matcher:void 0;if(!Array.isArray(E.hooks)){r.push(`hooks config at ${t}: hooks.${m}[${w}].hooks must be an array \u2014 skipping`);continue}let A=E.hooks,T=[];for(let x=0;x<A.length;x++){let S=A[x],R=d1(S);if(R===null){let I=S!==null&&typeof S=="object"&&!Array.isArray(S)?S.type:void 0,P=typeof I=="string"&&I!=="command"?`has unsupported hook type "${I}" (only "command" is honored)`:'is malformed (must have type="command" and non-empty command)';r.push(`hooks config at ${t}: hooks.${m}[${w}].hooks[${x}] ${P} \u2014 skipping`);continue}n!==void 0&&(R.pluginRoot=n),T.push(R)}T.length>0&&h.push({...v!==void 0?{matcher:v}:{},hooks:T,tier:e})}h.length>0&&(s[m]=h)}return{hooks:s,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r}}function u1(t=ct()){if(!Dc(t))return[];let e=[];for(let n of Ft(t)){let r=km(n.path,"hooks","hooks.json");Dc(r)&&e.push({path:r,pluginRoot:n.path})}return e}function eR(t={}){let e=t.cwd??process.cwd(),n=[],r=[],o={},s=!1,i=!1,a=!1,l=[{path:Et(),tier:"user-global"},{path:qc(),tier:"user-global"},{path:km(e,"afk.config.json"),tier:"project-local"},{path:eg(e),tier:"project-local"}],c=new Set,d=l.filter(f=>c.has(f.path)?!1:(c.add(f.path),!0));try{let f=km(oe(),"settings.json");!c.has(f)&&Dc(f)&&r.push(`found ${f} but AFK does not read settings from the AFK-home root; user-global hooks/settings belong in ${qc()} \u2014 the root file is ignored`)}catch{}for(let f of d){if(f.tier!=="user-global")continue;let m=vm(f.path,f.tier);m.enableShellHooks&&(s=!0),m.allowProjectHooks&&(i=!0),m.enablePluginHooks&&(a=!0)}let u=["SessionStart","SessionEnd","SubagentStart","SubagentStop","PreToolUse","PostToolUse","PreCompact","PostToolUseFailure","Stop","UserPromptSubmit"];for(let f of d){let m=vm(f.path,f.tier);for(let g of m.sources)n.includes(g)||n.push(g);for(let g of m.warnings)r.push(g);if(!(f.tier==="project-local"&&!i))for(let g of u){let h=m.hooks[g];if(h===void 0||h.length===0)continue;let w=o[g];w===void 0?o[g]=[...h]:o[g]=[...w,...h]}}let p=u1(t.pluginsDir);if(p.length>0&&!a&&r.push(`found ${p.length} plugin hooks.json file(s) but plugin hooks are disabled; set "enablePluginHooks": true in ${Et()} to run them`),a)for(let{path:f,pluginRoot:m}of p){let g=vm(f,"plugin",m);for(let h of g.sources)n.includes(h)||n.push(h);for(let h of g.warnings)r.push(h);for(let h of u){let w=g.hooks[h];if(w===void 0||w.length===0)continue;let k=o[h];k===void 0?o[h]=[...w]:o[h]=[...k,...w]}}return{hooks:o,userGlobalEnabled:s,allowProjectHooks:i,pluginHooksEnabled:a,sources:n,warnings:r}}import{spawn as p1}from"node:child_process";import{homedir as f1}from"node:os";import{StringDecoder as tR}from"node:string_decoder";async function nR(t){let{context:e,agentCwd:n,sessionId:r,timeoutMs:o}=t,s=t.command.replace(/^~\//,f1()+"/"),i={session_id:r,hook_event_name:e.event,cwd:n};(e.event==="PreToolUse"||e.event==="PostToolUse"||e.event==="PostToolUseFailure")&&(i.tool_name=e.toolName),e.event==="PreToolUse"&&(i.tool_input=e.input),e.event==="PostToolUse"&&e.output!==void 0&&(i.tool_output=typeof e.output=="string"?e.output:JSON.stringify(e.output)),e.event==="PostToolUseFailure"&&(i.error=e.error),e.event==="PreCompact"&&(i.trigger=e.trigger??null),e.event==="UserPromptSubmit"&&(i.prompt=e.prompt),i.transcript_path=null;let a=JSON.stringify(i),l=e.event==="PreToolUse"||e.event==="PostToolUse"||e.event==="PostToolUseFailure"?e.toolName:"",c=["PATH","HOME","SHELL","LANG","TERM","TMPDIR","TMP","TEMP","USER","LOGNAME"],d={};for(let p of c){let f=process.env[p];f!==void 0&&(d[p]=f)}let u=/_(KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|CREDENTIALS)$/i;for(let[p,f]of Object.entries(process.env))!p.startsWith("AFK_")||f===void 0||u.test(p)||(d[p]=f);return d.AFK_PROJECT_DIR=n,d.AFK_SESSION_ID=r??"",d.AFK_HOOK_EVENT=e.event,d.AFK_TOOL_NAME=l,t.pluginRoot!==void 0&&(d.CLAUDE_PLUGIN_ROOT=t.pluginRoot,d.CLAUDE_PROJECT_DIR=n),new Promise(p=>{let f=!1;function m(S){f||(f=!0,p(S))}let g=p1("sh",["-c",s],{stdio:["pipe","pipe","pipe"],cwd:n,env:d,detached:!0});g.unref();let h=64e3,w="",k="",E=0,v=0,A=new tR("utf8"),T=new tR("utf8");g.stdout.on("data",S=>{if(E>=h)return;let R=h-E,I=S.length<=R?S:S.subarray(0,R);E+=I.length,w+=A.write(I)}),g.stderr.on("data",S=>{if(v>=h)return;let R=h-v,I=S.length<=R?S:S.subarray(0,R);v+=I.length,k+=T.write(I)});let x=setTimeout(()=>{if(!f){if(g.pid!==void 0)try{process.kill(-g.pid,"SIGKILL")}catch{}console.warn(`[hooks] command timed out after ${o}ms: ${s}`),m({decision:{}})}},o);x.unref(),g.stdin.on("error",()=>{});try{g.stdin.write(a),g.stdin.end()}catch{}g.on("close",S=>{if(!f){if(clearTimeout(x),w+=A.end(),k+=T.end(),S===0){let R=m1(w);m({decision:R});return}if(S===2){let R=k.trim().slice(0,500)||"hook blocked operation";m({decision:{decision:"block",reason:R}});return}console.warn(`[hooks] command exited with code ${String(S)}: ${s}${k.trim()?`
1258
+ Choose how to handle this and future requests for this path.`,f=await He.route({serverName:"agent-afk",message:p,mode:"form",title:"Path access approval",requestedSchema:{type:"object",properties:{choice:{type:"string",title:"Choose one",enum:["once","session","persist","deny"],description:"'once' allows this single call only. 'session' allows this path until the session ends. 'persist' writes a grant to ~/.afk/config/permissions.json so future sessions inherit it. 'deny' blocks this call and returns an error to the model."}},required:["choice"]}},{signal:l??new AbortController().signal,...c!==void 0?{sessionId:c}:{}});if(f.action!=="accept"){let h=f.action==="cancel"?"cancel":"block";return console.error(`[path-approval] surface=${a} tool=${e} path=${n} outcome=${h}`),{decision:"block",reason:f.action==="cancel"?`User cancelled the access prompt for ${n}`:`User denied access to ${n}`}}let m=String(f.content?.choice??"").toLowerCase(),g=bm(o,n);switch(m){case"once":return o==="write"?s.addWriteRoot(n,"tool"):s.addReadRoot(n,"tool"),i.onceApproved.set(g,{resolvedPath:n,mode:o,capturedCwd:r}),console.error(`[path-approval] surface=${a} tool=${e} path=${n} outcome=once`),{};case"session":return o==="write"?s.addWriteRoot(n,"tool"):s.addReadRoot(n,"tool"),i.sessionApproved.add(g),console.error(`[path-approval] surface=${a} tool=${e} path=${n} outcome=session`),{};case"persist":o==="write"?s.addWriteRoot(n,"tool"):s.addReadRoot(n,"tool"),i.sessionApproved.add(g),console.error(`[path-approval] surface=${a} tool=${e} path=${n} outcome=persist`);try{VT({path:n,mode:o,decision:"allow",source:a==="telegram"?"elicit:telegram":a==="repl"?"elicit:repl":"elicit:unknown",reason:`Approved via ${a} prompt for ${e}`})}catch(h){console.error(`path-approval: failed to persist grant for ${n}:`,h instanceof Error?h.message:String(h))}return{};default:return console.error(`[path-approval] surface=${a} tool=${e} path=${n} outcome=deny`),{decision:"block",reason:`User denied access to ${n}`}}}Yt();H();import{homedir as Xx}from"os";import qn from"path";Yt();K();Ro();import wm from"path";function Sm(){try{return wm.resolve(oe())}catch(t){yt(t);return}}function Vx(t){return Sr.flatMap(e=>{if(!e.startsWith(".afk/"))return[];let n=wm.join(t,e.slice(5));return Ye(n).denied?[]:[n,`$AFK_HOME/${e.slice(5)}`]})}function Yx(){let t=Sm();return t===void 0?[]:[wm.join(t,"config")]}var VK=/\b(python|python3|node|ruby|perl|osascript|sh|bash|zsh|fish|lua)\s+-[cCeE](\s|$)/,YK=/\.ssh\b|\bid_rsa\b|\bid_ed25519\b|\.gnupg\b|\.aws\b|\.config\/gh\b|\.config\/gcloud\b|\.netrc\b|\.password-store\b|\.afk\/config\b|\.npmrc\b|\.docker\/config\.json\b|\.git-credentials\b|\.kube\/config\b|Library\/Application Support\b|\/etc\/shadow\b|\/etc\/sudoers\b|master\.passwd\b/i;function Qx(t){return e=>{if(e.event!=="PreToolUse")return{};if(e.toolName!=="bash")return{};let n=e.input,r=typeof n?.command=="string"?n.command:"";if(!r)return{};let o=e.grantManager??t.getGrantManager(),s=o!==void 0,i=Xx(),a=Sm(),l=n1(XK(r,i,a),i,a),c=o?a1(o.getGrants()):[];if(!t.disableInterpreterGuard&&(s||t.forceInterpreterGuard===!0)&&VK.test(r)&&r1(l,c))return{decision:"block",reason:"Interpreter one-liner (python -c, node -e, sh -c, ...) referencing a sensitive path (SSH keys, cloud credentials, GPG, /etc/shadow, ...) is blocked by the path-approval policy \u2014 an interpreter can assemble a path the shell-substring check cannot see. Use the typed file tools (read_file, write_file, edit_file), which support per-call user approval, or ask the user to run the script themselves. To lift this block \u2014 e.g. headless automation that legitimately reads such paths \u2014 set AFK_DISABLE_BASH_INTERPRETER_GUARD=1, or disable all of path-approval with AFK_DISABLE_PATH_APPROVAL=1."};if(!o)return{};if(c.length===0)return{};for(let u of c)if(l.includes(u))return{decision:"block",reason:`Bash command references a restricted path (${u}). For sensitive paths, use read_file / write_file / edit_file \u2014 those tools support per-call user approval via an inline prompt. If you genuinely need a shell command for this path, ask the user to grant it via \`/allow-dir <path>\` first.`};return{}}}function XK(t,e,n){return(n===void 0?t:t.replace(/\$\{AFK_HOME\}|\$AFK_HOME\b/g,n)).replace(/\$\{HOME\}|\$HOME\b/g,e).replace(/(^|[\s/=:])~(?=$|[/\s])/g,`$1${e}`).replace(QK,o=>qn.posix.normalize(o))}var QK=/\/[^\s'"`;|&()<>]*/g,ZK="<allowlisted-file>";function e1(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function t1(t,e){let n=Sr.flatMap(o=>Ye(qn.join(t,o)).denied?[]:[qn.join(t,o),`~/${o}`,`$HOME/${o}`]);if(e===void 0)return n;let r=Vx(e);return[...new Set([...n,...r])]}function n1(t,e,n){let r=t;for(let o of t1(e,n)){let s=new RegExp(`${e1(o)}(?![\\w./\\\\*?\\[\\]{}-])(?!['"\`][\\w./\\\\*?\\[\\]{}-])`,"g");r=r.replace(s,ZK)}return r}function r1(t,e){return e.some(n=>t.includes(n))?!0:YK.test(t)}function o1(){let t=Xx();return i1([qn.join(t,"Library","Application Support"),qn.join(t,".password-store"),qn.join(t,".config","gh"),...xu])}function s1(){return Ru(_.AFK_READ_DENYLIST)}function i1(t){let e=[];for(let n of t)e.push(n),n.startsWith("/etc/")?e.push(`/private${n}`):n.startsWith("/private/etc/")&&e.push(n.slice(8));return e}function a1(t){let e=[...new Set([...o1(),...Cu(),...s1(),...Yx()])],n=new Set([...t.resolveBase!==void 0?[t.resolveBase]:[],...t.readRoots,...t.writeRoots]);return e.filter(r=>{for(let o of n){let s=qn.relative(o,r);if(s===""||!s.startsWith(".."))return!1}return!0})}K();zl();aa();import{existsSync as Dc,readFileSync as l1}from"node:fs";import{join as km}from"node:path";var c1=3e4;function Zx(t){if(t===void 0||t==="*")return()=>!0;let e=/^\/(.+)\/([gimsuy]*)$/.exec(t);if(e!==null){let n=e[1],r=e[2];try{let o=r.replace(/[gy]/g,""),s=new RegExp(n,o);return i=>s.test(i)}catch{}}return n=>n===t}function d1(t){if(t===null||typeof t!="object"||Array.isArray(t))return null;let e=t;if(e.type!=="command"||typeof e.command!="string"||e.command.length===0)return null;let n=typeof e.timeout_ms=="number"&&e.timeout_ms>0?e.timeout_ms:c1,r=Math.min(n,En);return{type:"command",command:e.command,timeoutMs:r}}function vm(t,e,n){let r=[],o=[],s={};if(!Dc(t))return{hooks:s,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r};o.push(t);let i;try{i=JSON.parse(l1(t,"utf-8"))}catch(m){let g=m instanceof Error?m.message:String(m);return r.push(`hooks config at ${t}: parse error \u2014 ${g}`),{hooks:s,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r}}if(i===null||typeof i!="object"||Array.isArray(i))return r.push(`hooks config at ${t}: top-level must be an object`),{hooks:s,enableShellHooks:!1,allowProjectHooks:!1,enablePluginHooks:!1,sources:o,warnings:r};let a=i,l=a.enableShellHooks===!0,c=a.allowProjectHooks===!0,d=a.enablePluginHooks===!0,u=a.hooks;if(u==null)return{hooks:s,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r};if(typeof u!="object"||Array.isArray(u))return r.push(`hooks config at ${t}: "hooks" must be an object`),{hooks:s,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r};let p=u,f=["SessionStart","SessionEnd","SubagentStart","SubagentStop","PreToolUse","PostToolUse","PreCompact","PostToolUseFailure","Stop","UserPromptSubmit"];for(let m of f){let g=p[m];if(g===void 0)continue;if(!Array.isArray(g)){r.push(`hooks config at ${t}: hooks.${m} must be an array`);continue}let h=[];for(let w=0;w<g.length;w++){let k=g[w];if(k===null||typeof k!="object"||Array.isArray(k)){r.push(`hooks config at ${t}: hooks.${m}[${w}] must be an object \u2014 skipping`);continue}let E=k,v=typeof E.matcher=="string"?E.matcher:void 0;if(!Array.isArray(E.hooks)){r.push(`hooks config at ${t}: hooks.${m}[${w}].hooks must be an array \u2014 skipping`);continue}let A=E.hooks,T=[];for(let x=0;x<A.length;x++){let S=A[x],R=d1(S);if(R===null){let I=S!==null&&typeof S=="object"&&!Array.isArray(S)?S.type:void 0,P=typeof I=="string"&&I!=="command"?`has unsupported hook type "${I}" (only "command" is honored)`:'is malformed (must have type="command" and non-empty command)';r.push(`hooks config at ${t}: hooks.${m}[${w}].hooks[${x}] ${P} \u2014 skipping`);continue}n!==void 0&&(R.pluginRoot=n),T.push(R)}T.length>0&&h.push({...v!==void 0?{matcher:v}:{},hooks:T,tier:e})}h.length>0&&(s[m]=h)}return{hooks:s,enableShellHooks:l,allowProjectHooks:c,enablePluginHooks:d,sources:o,warnings:r}}function u1(t=ct()){if(!Dc(t))return[];let e=[];for(let n of Ft(t)){let r=km(n.path,"hooks","hooks.json");Dc(r)&&e.push({path:r,pluginRoot:n.path})}return e}function eR(t={}){let e=t.cwd??process.cwd(),n=[],r=[],o={},s=!1,i=!1,a=!1,l=[{path:Et(),tier:"user-global"},{path:qc(),tier:"user-global"},{path:km(e,"afk.config.json"),tier:"project-local"},{path:eg(e),tier:"project-local"}],c=new Set,d=l.filter(f=>c.has(f.path)?!1:(c.add(f.path),!0));try{let f=km(oe(),"settings.json");!c.has(f)&&Dc(f)&&r.push(`found ${f} but AFK does not read settings from the AFK-home root; user-global hooks/settings belong in ${qc()} \u2014 the root file is ignored`)}catch{}for(let f of d){if(f.tier!=="user-global")continue;let m=vm(f.path,f.tier);m.enableShellHooks&&(s=!0),m.allowProjectHooks&&(i=!0),m.enablePluginHooks&&(a=!0)}let u=["SessionStart","SessionEnd","SubagentStart","SubagentStop","PreToolUse","PostToolUse","PreCompact","PostToolUseFailure","Stop","UserPromptSubmit"];for(let f of d){let m=vm(f.path,f.tier);for(let g of m.sources)n.includes(g)||n.push(g);for(let g of m.warnings)r.push(g);if(!(f.tier==="project-local"&&!i))for(let g of u){let h=m.hooks[g];if(h===void 0||h.length===0)continue;let w=o[g];w===void 0?o[g]=[...h]:o[g]=[...w,...h]}}let p=u1(t.pluginsDir);if(p.length>0&&!a&&r.push(`found ${p.length} plugin hooks.json file(s) but plugin hooks are disabled; set "enablePluginHooks": true in ${Et()} to run them`),a)for(let{path:f,pluginRoot:m}of p){let g=vm(f,"plugin",m);for(let h of g.sources)n.includes(h)||n.push(h);for(let h of g.warnings)r.push(h);for(let h of u){let w=g.hooks[h];if(w===void 0||w.length===0)continue;let k=o[h];k===void 0?o[h]=[...w]:o[h]=[...k,...w]}}return{hooks:o,userGlobalEnabled:s,allowProjectHooks:i,pluginHooksEnabled:a,sources:n,warnings:r}}import{spawn as p1}from"node:child_process";import{homedir as f1}from"node:os";import{StringDecoder as tR}from"node:string_decoder";async function nR(t){let{context:e,agentCwd:n,sessionId:r,timeoutMs:o}=t,s=t.command.replace(/^~\//,f1()+"/"),i={session_id:r,hook_event_name:e.event,cwd:n};(e.event==="PreToolUse"||e.event==="PostToolUse"||e.event==="PostToolUseFailure")&&(i.tool_name=e.toolName),e.event==="PreToolUse"&&(i.tool_input=e.input),e.event==="PostToolUse"&&e.output!==void 0&&(i.tool_output=typeof e.output=="string"?e.output:JSON.stringify(e.output)),e.event==="PostToolUseFailure"&&(i.error=e.error),e.event==="PreCompact"&&(i.trigger=e.trigger??null),e.event==="UserPromptSubmit"&&(i.prompt=e.prompt),i.transcript_path=null;let a=JSON.stringify(i),l=e.event==="PreToolUse"||e.event==="PostToolUse"||e.event==="PostToolUseFailure"?e.toolName:"",c=["PATH","HOME","SHELL","LANG","TERM","TMPDIR","TMP","TEMP","USER","LOGNAME"],d={};for(let p of c){let f=process.env[p];f!==void 0&&(d[p]=f)}let u=/_(KEY|TOKEN|SECRET|PASSWORD|PASSWD|CREDENTIAL|CREDENTIALS)$/i;for(let[p,f]of Object.entries(process.env))!p.startsWith("AFK_")||f===void 0||u.test(p)||(d[p]=f);return d.AFK_PROJECT_DIR=n,d.AFK_SESSION_ID=r??"",d.AFK_HOOK_EVENT=e.event,d.AFK_TOOL_NAME=l,t.pluginRoot!==void 0&&(d.CLAUDE_PLUGIN_ROOT=t.pluginRoot,d.CLAUDE_PROJECT_DIR=n),new Promise(p=>{let f=!1;function m(S){f||(f=!0,p(S))}let g=p1("sh",["-c",s],{stdio:["pipe","pipe","pipe"],cwd:n,env:d,detached:!0});g.unref();let h=64e3,w="",k="",E=0,v=0,A=new tR("utf8"),T=new tR("utf8");g.stdout.on("data",S=>{if(E>=h)return;let R=h-E,I=S.length<=R?S:S.subarray(0,R);E+=I.length,w+=A.write(I)}),g.stderr.on("data",S=>{if(v>=h)return;let R=h-v,I=S.length<=R?S:S.subarray(0,R);v+=I.length,k+=T.write(I)});let x=setTimeout(()=>{if(!f){if(g.pid!==void 0)try{process.kill(-g.pid,"SIGKILL")}catch{}console.warn(`[hooks] command timed out after ${o}ms: ${s}`),m({decision:{}})}},o);x.unref(),g.stdin.on("error",()=>{});try{g.stdin.write(a),g.stdin.end()}catch{}g.on("close",S=>{if(!f){if(clearTimeout(x),w+=A.end(),k+=T.end(),S===0){let R=m1(w);m({decision:R});return}if(S===2){let R=k.trim().slice(0,500)||"hook blocked operation";m({decision:{decision:"block",reason:R}});return}console.warn(`[hooks] command exited with code ${String(S)}: ${s}${k.trim()?`
1259
1259
  ${k.trim()}`:""}`),m({decision:{}})}}),g.on("error",S=>{f||(clearTimeout(x),console.warn(`[hooks] command error: ${s} \u2014 ${S.message}`),m({decision:{}}))})})}function m1(t){let e=t.trim();if(!e)return{};let n;try{n=JSON.parse(e)}catch{return{}}if(n===null||typeof n!="object"||Array.isArray(n))return{};let r=n,o={};r.continue===!1&&(o.continue=!1),r.decision==="block"?o.decision="block":r.decision==="approve"&&(o.decision="approve"),typeof r.reason=="string"&&(o.reason=r.reason);let s=r.hookSpecificOutput;if(s!==null&&typeof s=="object"&&!Array.isArray(s)){let i=s;typeof i.additionalContext=="string"&&(o.injectContext=i.additionalContext)}return o}function rR(t,e,n){let r=n.cwd??process.cwd(),o=n.sessionId,s=e.userGlobalEnabled,i=["SessionStart","SessionEnd","SubagentStart","SubagentStop","PreToolUse","PostToolUse","PreCompact","PostToolUseFailure","Stop","UserPromptSubmit"];if(!s){let a=[];for(let l of i){let c=e.hooks[l];if(c!==void 0){for(let d of c)if(d.tier!=="plugin")for(let u of d.hooks)a.push(`${l}: ${u.command}`)}}a.length>0&&console.warn(`[hooks] shell hooks are disabled (enableShellHooks not set in user-global config).
1260
1260
  Skipped ${a.length} hook(s):
1261
1261
  `+a.map(l=>` - ${l}`).join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-afk",
3
- "version": "5.83.7",
3
+ "version": "5.83.8",
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",